|
1 | 1 | #![allow(dead_code)] // stack_guard isn't used right now on all platforms |
2 | 2 |
|
3 | | -use crate::cell::Cell; |
| 3 | +use crate::cell::OnceCell; |
4 | 4 | use crate::sys::thread::guard::Guard; |
5 | 5 | use crate::thread::Thread; |
6 | 6 |
|
7 | 7 | thread_local! { |
8 | | - static THREAD: Cell<Option<Thread>> = const { Cell::new(None) }; |
| 8 | + static THREAD: OnceCell<Thread> = const { OnceCell::new() }; |
9 | 9 | // Use a separate thread local for the stack guard page location. |
10 | 10 | // Since `Guard` does not implement drop, this is always available |
11 | 11 | // on systems with ELF-TLS, in particular during TLS destruction. |
12 | | - static STACK_GUARD: Cell<Option<Guard>> = const { Cell::new(None) }; |
| 12 | + static STACK_GUARD: OnceCell<Guard> = const { OnceCell::new() }; |
13 | 13 | } |
14 | 14 |
|
15 | 15 | pub fn current_thread() -> Option<Thread> { |
16 | | - THREAD |
17 | | - .try_with(|thread| { |
18 | | - let t = thread.take().unwrap_or_else(|| Thread::new(None)); |
19 | | - let t2 = t.clone(); |
20 | | - thread.set(Some(t)); |
21 | | - t2 |
22 | | - }) |
23 | | - .ok() |
| 16 | + THREAD.try_with(|thread| thread.get_or_init(|| Thread::new(None)).clone()).ok() |
24 | 17 | } |
25 | 18 |
|
26 | 19 | pub fn stack_guard() -> Option<Guard> { |
27 | | - STACK_GUARD |
28 | | - .try_with(|guard| { |
29 | | - let g = guard.take(); |
30 | | - let g2 = g.clone(); |
31 | | - guard.set(g); |
32 | | - g2 |
33 | | - }) |
34 | | - .ok() |
35 | | - .flatten() |
| 20 | + STACK_GUARD.try_with(|guard| guard.get().cloned()).ok().flatten() |
36 | 21 | } |
37 | 22 |
|
38 | 23 | pub fn set(stack_guard: Option<Guard>, thread: Thread) { |
39 | | - rtassert!(STACK_GUARD.replace(stack_guard).is_none()); |
40 | | - rtassert!(THREAD.replace(Some(thread)).is_none()); |
| 24 | + #[allow(unreachable_patterns, unreachable_code)] // On some platforms, `Guard` is `!`. |
| 25 | + if let Some(guard) = stack_guard { |
| 26 | + rtassert!(STACK_GUARD.with(|s| s.set(guard)).is_ok()); |
| 27 | + } |
| 28 | + rtassert!(THREAD.with(|t| t.set(thread)).is_ok()); |
41 | 29 | } |
0 commit comments