| //@ run-pass |
| #![allow(stable_features)] |
| //@ needs-threads |
| #![feature(thread_local_try_with)] |
| |
| use std::sync::atomic::{AtomicUsize, Ordering}; |
| use std::thread; |
| |
| struct Foo { |
| cnt: usize, |
| } |
| |
| thread_local!(static FOO: Foo = Foo::init()); |
| |
| static CNT: AtomicUsize = AtomicUsize::new(0); |
| |
| impl Foo { |
| fn init() -> Foo { |
| let cnt = CNT.fetch_add(1, Ordering::SeqCst); |
| if cnt == 0 { |
| FOO.with(|_| {}); |
| } |
| Foo { cnt: cnt } |
| } |
| } |
| |
| impl Drop for Foo { |
| fn drop(&mut self) { |
| if self.cnt == 1 { |
| FOO.with(|foo| assert_eq!(foo.cnt, 0)); |
| } else { |
| assert_eq!(self.cnt, 0); |
| if FOO.try_with(|_| ()).is_ok() { |
| panic!("should not be in valid state"); |
| } |
| } |
| } |
| } |
| |
| fn main() { |
| thread::spawn(|| { |
| FOO.with(|_| {}); |
| }) |
| .join() |
| .unwrap(); |
| } |