Skip to content

Commit 8bf5153

Browse files
committed
std: abort the process on failure to allocate a TLS key
The panic machinery uses TLS, so panicking if no TLS keys are left can lead to infinite recursion (see rust-lang#140798 (comment)). Rather than having separate logic for the panic count and the thread name, just always abort the process if a TLS key allocation fails. This also has the benefit of aligning the key-based TLS implementation with the documentation, which does not mention that a panic could also occur because of resource exhaustion.
1 parent 163cb4e commit 8bf5153

File tree

2 files changed

+10
-11
lines changed

2 files changed

+10
-11
lines changed

library/std/src/sys/thread_local/key/unix.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ pub type Key = libc::pthread_key_t;
2525
#[inline]
2626
pub fn create(dtor: Option<unsafe extern "C" fn(*mut u8)>) -> Key {
2727
let mut key = 0;
28-
assert_eq!(unsafe { libc::pthread_key_create(&mut key, mem::transmute(dtor)) }, 0);
28+
if unsafe { libc::pthread_key_create(&mut key, mem::transmute(dtor)) } != 0 {
29+
rtabort!("out of TLS keys");
30+
}
2931
key
3032
}
3133

library/std/src/sys/thread_local/key/windows.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -81,15 +81,10 @@ impl LazyKey {
8181
} else {
8282
let key = unsafe { c::TlsAlloc() };
8383
if key == c::TLS_OUT_OF_INDEXES {
84-
// Wakeup the waiting threads before panicking to avoid deadlock.
85-
unsafe {
86-
c::InitOnceComplete(
87-
self.once.get(),
88-
c::INIT_ONCE_INIT_FAILED,
89-
ptr::null_mut(),
90-
);
91-
}
92-
panic!("out of TLS indexes");
84+
// Since we abort the process, there is no need to wake up
85+
// the waiting threads. If this were a panic, the wakeup
86+
// would need to occur first in order to avoid deadlock.
87+
rtabort!("out of TLS indexes");
9388
}
9489

9590
unsafe {
@@ -112,7 +107,9 @@ impl LazyKey {
112107
// If there is no destructor to clean up, we can use racy initialization.
113108

114109
let key = unsafe { c::TlsAlloc() };
115-
assert_ne!(key, c::TLS_OUT_OF_INDEXES, "out of TLS indexes");
110+
if key == c::TLS_OUT_OF_INDEXES {
111+
rtabort!("out of TLS indexes");
112+
}
116113

117114
match self.key.compare_exchange(0, key + 1, AcqRel, Acquire) {
118115
Ok(_) => key,

0 commit comments

Comments
 (0)