|
1 | 1 | use std::cell::{Cell, UnsafeCell};
|
2 | 2 | use std::sync::atomic::{AtomicU8, Ordering};
|
3 | 3 | use std::sync::{Arc, Condvar, Mutex};
|
4 |
| -use std::thread::{self, Builder, LocalKey}; |
| 4 | +use std::thread::{self, LocalKey}; |
5 | 5 | use std::thread_local;
|
6 | 6 |
|
7 | 7 | #[derive(Clone, Default)]
|
@@ -345,8 +345,27 @@ fn join_orders_after_tls_destructors() {
|
345 | 345 | }
|
346 | 346 |
|
347 | 347 | // Test that thread::current is still available in TLS destructors.
|
| 348 | +// |
| 349 | +// The test won't currently work without target_thread_local, aka with slow tls. |
| 350 | +// The runtime tries very hard to drop last the TLS variable that keeps the information about the |
| 351 | +// current thread, by using several tricks like deffering the drop to a later round of TLS destruction. |
| 352 | +// However, this only seems to work with fast tls. |
| 353 | +// |
| 354 | +// With slow TLS, it seems that multiple libc implementations will just set the value to null the first |
| 355 | +// time they encounter it, regardless of it having a destructor or not. This means that trying to |
| 356 | +// retrieve it later in a drop impl of another TLS variable will not work. |
| 357 | +// |
| 358 | +// ** Apple libc: https://github.com/apple-oss-distributions/libpthread/blob/c032e0b076700a0a47db75528a282b8d3a06531a/src/pthread_tsd.c#L293 |
| 359 | +// Sets the variable to null if it has a destructor and the value is not null. However, all variables |
| 360 | +// created with pthread_key_create are marked as having a destructor, even if the fn ptr called with |
| 361 | +// it is null. |
| 362 | +// ** glibc: https://github.com/bminor/glibc/blob/e5893e6349541d871e8a25120bca014551d13ff5/nptl/nptl_deallocate_tsd.c#L59 |
| 363 | +// ** musl: https://github.com/kraj/musl/blob/1880359b54ff7dd9f5016002bfdae4b136007dde/src/thread/pthread_key_create.c#L87 |
| 364 | +#[cfg(target_thread_local)] |
348 | 365 | #[test]
|
349 | 366 | fn thread_current_in_dtor() {
|
| 367 | + use std::thread::Builder; |
| 368 | + |
350 | 369 | // Go through one round of TLS destruction first.
|
351 | 370 | struct Defer;
|
352 | 371 | impl Drop for Defer {
|
|
0 commit comments