From 4e8199b572f2035b7749cba276ece3a26630d23e Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:18:21 +0200 Subject: Adding upstream version 1.67.1+dfsg1. Signed-off-by: Daniel Baumann --- library/std/src/thread/local/tests.rs | 66 +++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 22 deletions(-) (limited to 'library/std/src/thread/local') diff --git a/library/std/src/thread/local/tests.rs b/library/std/src/thread/local/tests.rs index 1df1ca758..80dc4c038 100644 --- a/library/std/src/thread/local/tests.rs +++ b/library/std/src/thread/local/tests.rs @@ -1,15 +1,34 @@ use crate::cell::{Cell, UnsafeCell}; use crate::sync::atomic::{AtomicU8, Ordering}; -use crate::sync::mpsc::{channel, Sender}; +use crate::sync::{Arc, Condvar, Mutex}; use crate::thread::{self, LocalKey}; use crate::thread_local; -struct Foo(Sender<()>); +#[derive(Clone, Default)] +struct Signal(Arc<(Mutex, Condvar)>); + +impl Signal { + fn notify(&self) { + let (set, cvar) = &*self.0; + *set.lock().unwrap() = true; + cvar.notify_one(); + } + + fn wait(&self) { + let (set, cvar) = &*self.0; + let mut set = set.lock().unwrap(); + while !*set { + set = cvar.wait(set).unwrap(); + } + } +} + +struct Foo(Signal); impl Drop for Foo { fn drop(&mut self) { - let Foo(ref s) = *self; - s.send(()).unwrap(); + let Foo(ref f) = *self; + f.notify(); } } @@ -69,14 +88,15 @@ fn smoke_dtor() { run(&FOO2); fn run(key: &'static LocalKey>>) { - let (tx, rx) = channel(); + let signal = Signal::default(); + let signal2 = signal.clone(); let t = thread::spawn(move || unsafe { - let mut tx = Some(tx); + let mut signal = Some(signal2); key.with(|f| { - *f.get() = Some(Foo(tx.take().unwrap())); + *f.get() = Some(Foo(signal.take().unwrap())); }); }); - rx.recv().unwrap(); + signal.wait(); t.join().unwrap(); } } @@ -165,48 +185,50 @@ fn self_referential() { // requires the destructor to be run to pass the test). #[test] fn dtors_in_dtors_in_dtors() { - struct S1(Sender<()>); + struct S1(Signal); thread_local!(static K1: UnsafeCell> = UnsafeCell::new(None)); thread_local!(static K2: UnsafeCell> = UnsafeCell::new(None)); impl Drop for S1 { fn drop(&mut self) { - let S1(ref tx) = *self; + let S1(ref signal) = *self; unsafe { - let _ = K2.try_with(|s| *s.get() = Some(Foo(tx.clone()))); + let _ = K2.try_with(|s| *s.get() = Some(Foo(signal.clone()))); } } } - let (tx, rx) = channel(); + let signal = Signal::default(); + let signal2 = signal.clone(); let _t = thread::spawn(move || unsafe { - let mut tx = Some(tx); - K1.with(|s| *s.get() = Some(S1(tx.take().unwrap()))); + let mut signal = Some(signal2); + K1.with(|s| *s.get() = Some(S1(signal.take().unwrap()))); }); - rx.recv().unwrap(); + signal.wait(); } #[test] fn dtors_in_dtors_in_dtors_const_init() { - struct S1(Sender<()>); + struct S1(Signal); thread_local!(static K1: UnsafeCell> = const { UnsafeCell::new(None) }); thread_local!(static K2: UnsafeCell> = const { UnsafeCell::new(None) }); impl Drop for S1 { fn drop(&mut self) { - let S1(ref tx) = *self; + let S1(ref signal) = *self; unsafe { - let _ = K2.try_with(|s| *s.get() = Some(Foo(tx.clone()))); + let _ = K2.try_with(|s| *s.get() = Some(Foo(signal.clone()))); } } } - let (tx, rx) = channel(); + let signal = Signal::default(); + let signal2 = signal.clone(); let _t = thread::spawn(move || unsafe { - let mut tx = Some(tx); - K1.with(|s| *s.get() = Some(S1(tx.take().unwrap()))); + let mut signal = Some(signal2); + K1.with(|s| *s.get() = Some(S1(signal.take().unwrap()))); }); - rx.recv().unwrap(); + signal.wait(); } // This test tests that TLS destructors have run before the thread joins. The -- cgit v1.2.3