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 https://github.com/rust-lang/rust/issues/140798#issuecomment-2872307377). 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.
This commit is contained in:
parent
163cb4ea3f
commit
8bf515330f
2 changed files with 10 additions and 11 deletions
|
|
@ -25,7 +25,9 @@ pub type Key = libc::pthread_key_t;
|
|||
#[inline]
|
||||
pub fn create(dtor: Option<unsafe extern "C" fn(*mut u8)>) -> Key {
|
||||
let mut key = 0;
|
||||
assert_eq!(unsafe { libc::pthread_key_create(&mut key, mem::transmute(dtor)) }, 0);
|
||||
if unsafe { libc::pthread_key_create(&mut key, mem::transmute(dtor)) } != 0 {
|
||||
rtabort!("out of TLS keys");
|
||||
}
|
||||
key
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -81,15 +81,10 @@ impl LazyKey {
|
|||
} else {
|
||||
let key = unsafe { c::TlsAlloc() };
|
||||
if key == c::TLS_OUT_OF_INDEXES {
|
||||
// Wakeup the waiting threads before panicking to avoid deadlock.
|
||||
unsafe {
|
||||
c::InitOnceComplete(
|
||||
self.once.get(),
|
||||
c::INIT_ONCE_INIT_FAILED,
|
||||
ptr::null_mut(),
|
||||
);
|
||||
}
|
||||
panic!("out of TLS indexes");
|
||||
// Since we abort the process, there is no need to wake up
|
||||
// the waiting threads. If this were a panic, the wakeup
|
||||
// would need to occur first in order to avoid deadlock.
|
||||
rtabort!("out of TLS indexes");
|
||||
}
|
||||
|
||||
unsafe {
|
||||
|
|
@ -112,7 +107,9 @@ impl LazyKey {
|
|||
// If there is no destructor to clean up, we can use racy initialization.
|
||||
|
||||
let key = unsafe { c::TlsAlloc() };
|
||||
assert_ne!(key, c::TLS_OUT_OF_INDEXES, "out of TLS indexes");
|
||||
if key == c::TLS_OUT_OF_INDEXES {
|
||||
rtabort!("out of TLS indexes");
|
||||
}
|
||||
|
||||
match self.key.compare_exchange(0, key + 1, AcqRel, Acquire) {
|
||||
Ok(_) => key,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue