sessionmgr: fix deadlock with multiple waiters (fix #556)

This commit is contained in:
fincs 2021-06-20 12:39:42 +02:00
parent b17873d071
commit 982aef9ea5
No known key found for this signature in database
GPG Key ID: 62C7609ADA219C60
2 changed files with 4 additions and 5 deletions

View File

@ -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);

View File

@ -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);
}