about summary refs log tree commit diff
path: root/library/std/src/sync/once.rs
diff options
context:
space:
mode:
Diffstat (limited to 'library/std/src/sync/once.rs')
-rw-r--r--library/std/src/sync/once.rs123
1 files changed, 3 insertions, 120 deletions
diff --git a/library/std/src/sync/once.rs b/library/std/src/sync/once.rs
index 714ec3e8786..8fed369bffc 100644
--- a/library/std/src/sync/once.rs
+++ b/library/std/src/sync/once.rs
@@ -84,6 +84,9 @@
 //   processor. Because both use Acquire ordering such a reordering is not
 //   allowed, so no need for SeqCst.
 
+#[cfg(all(test, not(target_os = "emscripten")))]
+mod tests;
+
 use crate::cell::Cell;
 use crate::fmt;
 use crate::marker;
@@ -568,123 +571,3 @@ impl OnceState {
         self.set_state_on_drop_to.set(POISONED);
     }
 }
-
-#[cfg(all(test, not(target_os = "emscripten")))]
-mod tests {
-    use super::Once;
-    use crate::panic;
-    use crate::sync::mpsc::channel;
-    use crate::thread;
-
-    #[test]
-    fn smoke_once() {
-        static O: Once = Once::new();
-        let mut a = 0;
-        O.call_once(|| a += 1);
-        assert_eq!(a, 1);
-        O.call_once(|| a += 1);
-        assert_eq!(a, 1);
-    }
-
-    #[test]
-    fn stampede_once() {
-        static O: Once = Once::new();
-        static mut RUN: bool = false;
-
-        let (tx, rx) = channel();
-        for _ in 0..10 {
-            let tx = tx.clone();
-            thread::spawn(move || {
-                for _ in 0..4 {
-                    thread::yield_now()
-                }
-                unsafe {
-                    O.call_once(|| {
-                        assert!(!RUN);
-                        RUN = true;
-                    });
-                    assert!(RUN);
-                }
-                tx.send(()).unwrap();
-            });
-        }
-
-        unsafe {
-            O.call_once(|| {
-                assert!(!RUN);
-                RUN = true;
-            });
-            assert!(RUN);
-        }
-
-        for _ in 0..10 {
-            rx.recv().unwrap();
-        }
-    }
-
-    #[test]
-    fn poison_bad() {
-        static O: Once = Once::new();
-
-        // poison the once
-        let t = panic::catch_unwind(|| {
-            O.call_once(|| panic!());
-        });
-        assert!(t.is_err());
-
-        // poisoning propagates
-        let t = panic::catch_unwind(|| {
-            O.call_once(|| {});
-        });
-        assert!(t.is_err());
-
-        // we can subvert poisoning, however
-        let mut called = false;
-        O.call_once_force(|p| {
-            called = true;
-            assert!(p.poisoned())
-        });
-        assert!(called);
-
-        // once any success happens, we stop propagating the poison
-        O.call_once(|| {});
-    }
-
-    #[test]
-    fn wait_for_force_to_finish() {
-        static O: Once = Once::new();
-
-        // poison the once
-        let t = panic::catch_unwind(|| {
-            O.call_once(|| panic!());
-        });
-        assert!(t.is_err());
-
-        // make sure someone's waiting inside the once via a force
-        let (tx1, rx1) = channel();
-        let (tx2, rx2) = channel();
-        let t1 = thread::spawn(move || {
-            O.call_once_force(|p| {
-                assert!(p.poisoned());
-                tx1.send(()).unwrap();
-                rx2.recv().unwrap();
-            });
-        });
-
-        rx1.recv().unwrap();
-
-        // put another waiter on the once
-        let t2 = thread::spawn(|| {
-            let mut called = false;
-            O.call_once(|| {
-                called = true;
-            });
-            assert!(!called);
-        });
-
-        tx2.send(()).unwrap();
-
-        assert!(t1.join().is_ok());
-        assert!(t2.join().is_ok());
-    }
-}