From 3a31f3dd9eb31278b974d49cf1cea4d484396cca Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Wed, 8 Apr 2026 08:46:33 -0400 Subject: [PATCH] MT#55283 fix possible deadlock Change-Id: I35aa96f09639cab4eb57dd834f3570e9cdca33b2 --- daemon/call.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/daemon/call.c b/daemon/call.c index 4e817c4a7..4bd978fde 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -5524,32 +5524,40 @@ call_t *call_get(const str *callid) { } // obtain a reference to a second call while holding a lock to another call -// may intermittently release lock on the first call! +// intermittently releases lock on the first call! // return return another reference to the same call call_t *call_get2(call_t *call1, const str *callid2) { - call_t *ret; + call_t *ret = NULL; + + rwlock_unlock_w(&call1->master_lock); while (true) { RWLOCK_R(&rtpe_callhash_lock); ret = t_hash_table_lookup(rtpe_callhash, callid2); if (!ret) - return NULL; + goto out; if (ret == call1) { obj_hold(ret); - return ret; + goto out; } + rwlock_lock_w(&call1->master_lock); + if (!rwlock_trylock_w(&ret->master_lock)) { obj_hold(ret); return ret; } - // try again after releasing lock rwlock_unlock_w(&call1->master_lock); - rwlock_lock_w(&call1->master_lock); + // try again } + +out: + rwlock_lock_w(&call1->master_lock); + + return ret; } static gboolean fragment_move(str *key, fragment_q *q, void *c) {