From 9774052fd11afdda3562d03421b7e417c97cf6e3 Mon Sep 17 00:00:00 2001 From: Red Bear OS Date: Thu, 2 Jul 2026 16:39:27 +0300 Subject: [PATCH] Fix non-robust mutex ENOTRECOVERABLE false positive For non-robust mutexes, never check mutex_owner_id_is_live or return ENOTRECOVERABLE when the owner appears dead. POSIX leaves behavior undefined for non-robust mutexes when the owner dies; the correct default is to treat it as normal contention (spin/futex wait), not to return an error. This was causing xhcid (which uses Rust std::sync::Mutex) to crash on every boot. Also add stdint.h to sched.h sys_includes for cpu_set_t uint64_t. --- src/header/sched/cbindgen.toml | 2 +- src/sync/pthread_mutex.rs | 16 ++-------------- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/src/header/sched/cbindgen.toml b/src/header/sched/cbindgen.toml index 570e8f6f0b..c54d4ec488 100644 --- a/src/header/sched/cbindgen.toml +++ b/src/header/sched/cbindgen.toml @@ -5,7 +5,7 @@ # - "[SS|TSP] The header shall define the time_t type as described in ." # - "The header shall define the timespec structure as described in ." # - "Inclusion of the header may make visible all symbols from the header." -sys_includes = ["sys/types.h"] +sys_includes = ["sys/types.h", "stdint.h"] include_guard = "_RELIBC_SCHED_H" after_includes = """ #include // for timespec diff --git a/src/sync/pthread_mutex.rs b/src/sync/pthread_mutex.rs index b108f2ee6f..aa91bc20f7 100644 --- a/src/sync/pthread_mutex.rs +++ b/src/sync/pthread_mutex.rs @@ -136,11 +136,7 @@ impl RlctMutex { Err(thread) => { let owner = thread & INDEX_MASK; - if !crate::pthread::mutex_owner_id_is_live(owner) { - if !self.robust { - return Err(Errno(ENOTRECOVERABLE)); - } - + if self.robust && !crate::pthread::mutex_owner_id_is_live(owner) { let new_value = (thread & WAITING_BIT) | FUTEX_OWNER_DIED | this_thread; match self.inner.compare_exchange( thread, @@ -234,15 +230,7 @@ impl RlctMutex { return Err(Errno(EDEADLK)); } - if current & FUTEX_OWNER_DIED != 0 && owner == 0 { - return Err(Errno(ENOTRECOVERABLE)); - } - - if current & FUTEX_OWNER_DIED != 0 || (owner != 0 && !crate::pthread::mutex_owner_id_is_live(owner)) { - if !self.robust { - return Err(Errno(ENOTRECOVERABLE)); - } - + if self.robust && (current & FUTEX_OWNER_DIED != 0 || (owner != 0 && !crate::pthread::mutex_owner_id_is_live(owner))) { let new_value = (current & WAITING_BIT) | FUTEX_OWNER_DIED | this_thread; match self.inner.compare_exchange( current,