kernel: Allocate user_mutex_contexts when adding the second thread to a team.

This allows us to gracefully fail if memory allocation fails,
rather than panic()ing. If a single-threaded application tries
to wait on a non-shared user_mutex in single-threaded mode, it
will now be dropped into the debugger.
This commit is contained in:
Augustin Cavalier
2026-03-04 21:42:03 -05:00
parent e6569ec320
commit 7ef695df5c
3 changed files with 23 additions and 19 deletions
+2
View File
@@ -7,6 +7,7 @@
#include <SupportDefs.h>
#include <thread_types.h>
#ifdef __cplusplus
@@ -17,6 +18,7 @@ struct user_mutex_context;
void user_mutex_init();
void delete_user_mutex_context(struct user_mutex_context* context);
status_t allocate_team_user_mutex_context(Team* team);
status_t _user_mutex_lock(int32* mutex, const char* name, uint32 flags,
bigtime_t timeout);
+13 -19
View File
@@ -219,31 +219,25 @@ user_mutex_init()
}
struct user_mutex_context*
get_team_user_mutex_context()
status_t
allocate_team_user_mutex_context(Team* team)
{
struct user_mutex_context* context =
thread_get_current_thread()->team->user_mutex_context;
if (context != NULL)
return context;
team->AssertLocked();
ASSERT(team->user_mutex_context == NULL);
Team* team = thread_get_current_thread()->team;
TeamLocker teamLocker(team);
if (team->user_mutex_context != NULL)
return team->user_mutex_context;
context = new(std::nothrow) user_mutex_context;
struct user_mutex_context* context = new(std::nothrow) user_mutex_context;
if (context == NULL)
return NULL;
return B_NO_MEMORY;
context->lock = RW_LOCK_INITIALIZER("user mutex table");
if (context->table.Init() != B_OK) {
status_t status = context->table.Init();
if (status != B_OK) {
delete context;
return NULL;
return status;
}
team->user_mutex_context = context;
return context;
return B_OK;
}
@@ -469,10 +463,10 @@ struct UserMutexContextFetcher {
fAddress(0)
{
if (!fShared) {
fContext = get_team_user_mutex_context();
fContext = thread_get_current_thread()->team->user_mutex_context;
if (fContext == NULL) {
panic("UserMutexContext allocation failed!");
fInitStatus = B_NO_MEMORY;
_user_debugger("single-threaded team attempted mutex operation");
fInitStatus = EDEADLK;
return;
}
+8
View File
@@ -46,6 +46,7 @@
#include <tls.h>
#include <user_runtime.h>
#include <user_thread.h>
#include <user_mutex.h>
#include <vfs.h>
#include <vm/vm.h>
#include <vm/VMAddressSpace.h>
@@ -1084,6 +1085,13 @@ thread_create_thread(const ThreadCreationAttributes& attributes, bool kernel)
bool debugNewThread = false;
if (!kernel) {
// ensure there's a user_mutex_context, if this isn't the main thread
if (team->main_thread != NULL && team->user_mutex_context == NULL) {
status_t status = allocate_team_user_mutex_context(team);
if (status != B_OK)
return status;
}
// allocate the user_thread structure, if not already allocated
if (thread->user_thread == NULL) {
thread->user_thread = team_allocate_user_thread(team);