From 585ac6895e783012152df6e44f91ffff89f27a0b Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Thu, 5 Mar 2026 12:46:31 -0500 Subject: [PATCH] kernel/user_mutex: Let single-threaded applications sleep on mutexes. It seems some single-threaded applications do use them, which doesn't result in a deadlock because they use timeouts (or maybe wait on signals, too.) --- src/system/kernel/locks/user_mutex.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/system/kernel/locks/user_mutex.cpp b/src/system/kernel/locks/user_mutex.cpp index 759b4dd7a0..c430008e59 100644 --- a/src/system/kernel/locks/user_mutex.cpp +++ b/src/system/kernel/locks/user_mutex.cpp @@ -223,7 +223,8 @@ status_t allocate_team_user_mutex_context(Team* team) { team->AssertLocked(); - ASSERT(team->user_mutex_context == NULL); + if (team->user_mutex_context != NULL) + return B_OK; struct user_mutex_context* context = new(std::nothrow) user_mutex_context; if (context == NULL) @@ -465,9 +466,15 @@ struct UserMutexContextFetcher { if (!fShared) { fContext = thread_get_current_thread()->team->user_mutex_context; if (fContext == NULL) { - _user_debugger("single-threaded team attempted mutex operation"); - fInitStatus = EDEADLK; - return; + // This should only happen for single-threaded applications (some + // appear to use mutexes as a sleep mechanism), as the context gets + // allocated on the creation of a second thread. + Team* team = thread_get_current_thread()->team; + team->Lock(); + fInitStatus = allocate_team_user_mutex_context(team); + team->Unlock(); + if (fInitStatus != B_OK) + return; } fAddress = (addr_t)mutex;