Skip to content

Commit e31f65b

Browse files
committed
Rollup merge of rust-lang#31292 - alexcrichton:osx-dtors-in-dtors-in-dtors, r=aturon
This test has been deadlocking and causing problems on the bots basically since its inception. Some memory safety issues were fixed in 987dc84, but the deadlocks remained afterwards unfortunately. After some investigation, I've concluded that this is just a situation where OSX is not guaranteed to run destructors. The fix in 987dc84 observed that OSX was rewriting the backing TLS memory to its initial state during destruction while we weren't looking, and this would have the effect of canceling the destructors of any other initialized TLS slots. While very difficult to pin down, this is basically what I assume is happening here, so there doesn't seem to really be anythig we can do to ensure the test robustly passes on OSX, so just ignore it for now.
2 parents 5ff52db + b960de0 commit e31f65b

File tree

1 file changed

+25
-0
lines changed

1 file changed

+25
-0
lines changed

src/libstd/thread/local.rs

+25
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,26 @@ use mem;
5656
/// assert_eq!(*f.borrow(), 2);
5757
/// });
5858
/// ```
59+
///
60+
/// # Platform-specific behavior
61+
///
62+
/// Note that a "best effort" is made to ensure that destructors for types
63+
/// stored in thread local storage are run, but not all platforms can gurantee
64+
/// that destructors will be run for all types in thread local storage. For
65+
/// example, there are a number of known caveats where destructors are not run:
66+
///
67+
/// 1. On Unix systems when pthread-based TLS is being used, destructors will
68+
/// not be run for TLS values on the main thread when it exits. Note that the
69+
/// application will exit immediately after the main thread exits as well.
70+
/// 2. On all platforms it's possible for TLS to re-initialize other TLS slots
71+
/// during destruction. Some platforms ensure that this cannot happen
72+
/// infinitely by preventing re-initialization of any slot that has been
73+
/// destroyed, but not all platforms have this guard. Those platforms that do
74+
/// not guard typically have a synthetic limit after which point no more
75+
/// destructors are run.
76+
/// 3. On OSX, initializing TLS during destruction of other TLS slots can
77+
/// sometimes cancel *all* destructors for the current thread, whether or not
78+
/// the slots have already had their destructors run or not.
5979
#[stable(feature = "rust1", since = "1.0.0")]
6080
pub struct LocalKey<T: 'static> {
6181
// This outer `LocalKey<T>` type is what's going to be stored in statics,
@@ -602,7 +622,12 @@ mod tests {
602622
}).join().ok().unwrap();
603623
}
604624

625+
// Note that this test will deadlock if TLS destructors aren't run (this
626+
// requires the destructor to be run to pass the test). OSX has a known bug
627+
// where dtors-in-dtors may cancel other destructors, so we just ignore this
628+
// test on OSX.
605629
#[test]
630+
#[cfg_attr(target_os = "macos", ignore)]
606631
fn dtors_in_dtors_in_dtors() {
607632
struct S1(Sender<()>);
608633
thread_local!(static K1: UnsafeCell<Option<S1>> = UnsafeCell::new(None));

0 commit comments

Comments
 (0)