Skip to content

Commit a2f58ab

Browse files
committed
avoid using channels in thread-local tests
1 parent a224269 commit a2f58ab

File tree

1 file changed

+44
-22
lines changed

1 file changed

+44
-22
lines changed

library/std/src/thread/local/tests.rs

+44-22
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,34 @@
11
use crate::cell::{Cell, UnsafeCell};
22
use crate::sync::atomic::{AtomicU8, Ordering};
3-
use crate::sync::mpsc::{channel, Sender};
3+
use crate::sync::{Arc, Condvar, Mutex};
44
use crate::thread::{self, LocalKey};
55
use crate::thread_local;
66

7-
struct Foo(Sender<()>);
7+
#[derive(Clone, Default)]
8+
struct Signal(Arc<(Mutex<bool>, Condvar)>);
9+
10+
impl Signal {
11+
fn notify(&self) {
12+
let (set, cvar) = &*self.0;
13+
*set.lock().unwrap() = true;
14+
cvar.notify_one();
15+
}
16+
17+
fn wait(&self) {
18+
let (set, cvar) = &*self.0;
19+
let mut set = set.lock().unwrap();
20+
while !*set {
21+
set = cvar.wait(set).unwrap();
22+
}
23+
}
24+
}
25+
26+
struct Foo(Signal);
827

928
impl Drop for Foo {
1029
fn drop(&mut self) {
11-
let Foo(ref s) = *self;
12-
s.send(()).unwrap();
30+
let Foo(ref f) = *self;
31+
f.notify();
1332
}
1433
}
1534

@@ -69,14 +88,15 @@ fn smoke_dtor() {
6988
run(&FOO2);
7089

7190
fn run(key: &'static LocalKey<UnsafeCell<Option<Foo>>>) {
72-
let (tx, rx) = channel();
91+
let signal = Signal::default();
92+
let signal2 = signal.clone();
7393
let t = thread::spawn(move || unsafe {
74-
let mut tx = Some(tx);
94+
let mut signal = Some(signal2);
7595
key.with(|f| {
76-
*f.get() = Some(Foo(tx.take().unwrap()));
96+
*f.get() = Some(Foo(signal.take().unwrap()));
7797
});
7898
});
79-
rx.recv().unwrap();
99+
signal.wait();
80100
t.join().unwrap();
81101
}
82102
}
@@ -165,48 +185,50 @@ fn self_referential() {
165185
// requires the destructor to be run to pass the test).
166186
#[test]
167187
fn dtors_in_dtors_in_dtors() {
168-
struct S1(Sender<()>);
188+
struct S1(Signal);
169189
thread_local!(static K1: UnsafeCell<Option<S1>> = UnsafeCell::new(None));
170190
thread_local!(static K2: UnsafeCell<Option<Foo>> = UnsafeCell::new(None));
171191

172192
impl Drop for S1 {
173193
fn drop(&mut self) {
174-
let S1(ref tx) = *self;
194+
let S1(ref signal) = *self;
175195
unsafe {
176-
let _ = K2.try_with(|s| *s.get() = Some(Foo(tx.clone())));
196+
let _ = K2.try_with(|s| *s.get() = Some(Foo(signal.clone())));
177197
}
178198
}
179199
}
180200

181-
let (tx, rx) = channel();
201+
let signal = Signal::default();
202+
let signal2 = signal.clone();
182203
let _t = thread::spawn(move || unsafe {
183-
let mut tx = Some(tx);
184-
K1.with(|s| *s.get() = Some(S1(tx.take().unwrap())));
204+
let mut signal = Some(signal2);
205+
K1.with(|s| *s.get() = Some(S1(signal.take().unwrap())));
185206
});
186-
rx.recv().unwrap();
207+
signal.wait();
187208
}
188209

189210
#[test]
190211
fn dtors_in_dtors_in_dtors_const_init() {
191-
struct S1(Sender<()>);
212+
struct S1(Signal);
192213
thread_local!(static K1: UnsafeCell<Option<S1>> = const { UnsafeCell::new(None) });
193214
thread_local!(static K2: UnsafeCell<Option<Foo>> = const { UnsafeCell::new(None) });
194215

195216
impl Drop for S1 {
196217
fn drop(&mut self) {
197-
let S1(ref tx) = *self;
218+
let S1(ref signal) = *self;
198219
unsafe {
199-
let _ = K2.try_with(|s| *s.get() = Some(Foo(tx.clone())));
220+
let _ = K2.try_with(|s| *s.get() = Some(Foo(signal.clone())));
200221
}
201222
}
202223
}
203224

204-
let (tx, rx) = channel();
225+
let signal = Signal::default();
226+
let signal2 = signal.clone();
205227
let _t = thread::spawn(move || unsafe {
206-
let mut tx = Some(tx);
207-
K1.with(|s| *s.get() = Some(S1(tx.take().unwrap())));
228+
let mut signal = Some(signal2);
229+
K1.with(|s| *s.get() = Some(S1(signal.take().unwrap())));
208230
});
209-
rx.recv().unwrap();
231+
signal.wait();
210232
}
211233

212234
// This test tests that TLS destructors have run before the thread joins. The

0 commit comments

Comments
 (0)