mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-20 20:22:38 +02:00
sessionmgr: fix deadlock with multiple waiters (fix #556)
This commit is contained in:
parent
b17873d071
commit
982aef9ea5
@ -12,7 +12,7 @@ typedef struct SessionMgr
|
||||
u32 free_mask;
|
||||
Mutex mutex;
|
||||
CondVar condvar;
|
||||
bool is_waiting;
|
||||
u32 num_waiters;
|
||||
} SessionMgr;
|
||||
|
||||
Result sessionmgrCreate(SessionMgr* mgr, Handle root_session, u32 num_sessions);
|
||||
|
@ -43,8 +43,9 @@ int sessionmgrAttachClient(SessionMgr* mgr) {
|
||||
for (;;) {
|
||||
slot = __builtin_ffs(mgr->free_mask)-1;
|
||||
if (slot >= 0) break;
|
||||
mgr->is_waiting = true;
|
||||
mgr->num_waiters ++;
|
||||
condvarWait(&mgr->condvar, &mgr->mutex);
|
||||
mgr->num_waiters --;
|
||||
}
|
||||
mgr->free_mask &= ~(1U << slot);
|
||||
mutexUnlock(&mgr->mutex);
|
||||
@ -54,9 +55,7 @@ int sessionmgrAttachClient(SessionMgr* mgr) {
|
||||
void sessionmgrDetachClient(SessionMgr* mgr, int slot) {
|
||||
mutexLock(&mgr->mutex);
|
||||
mgr->free_mask |= 1U << slot;
|
||||
if (mgr->is_waiting) {
|
||||
mgr->is_waiting = false;
|
||||
if (mgr->num_waiters)
|
||||
condvarWakeOne(&mgr->condvar);
|
||||
}
|
||||
mutexUnlock(&mgr->mutex);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user