oops.. forgot to unlock the mutex below.. Benny Prijono wrote: > Norman Franke wrote: >> OK, I think I tracked this one down. >> >> on_call_state has the PJ lock. I use a lock on my structure that >> manages what call slots are active and related information. >> Sometimes, I need to count the active calls. To do this, I lock my >> lock then call pjsua_call_get_conf_port (which locks the PJ lock) to >> make sure it has a valid port. No port, no active call (i..e. could >> be just recently terminated or on hold.) >> >> Another routine locks my lock, then calls any PJ function (locking >> the PJ lock.) Thus we get deadlock. >> >> Does PJ really need to maintain the lock while calling my on_call_setup? > > on_call_setup()? did you mean on_call_state()? > > Yes I think so. The only solution I think is to make the order of > locking uniform in your application, perhaps by using something like > this: > > struct app_lock_data > { > pjsua_call *call; > pjsip_dialog *dlg; > }; > > pj_status_t app_lock(app_lock_data *lck, pjsua_call_id cid) > { > pj_status_t status; > > lck->call = NULL; > lck->dlg = NULL; > > if (cid != PJSUA_INVALID_ID) { > status=acquire_call("app_lock()", cid, &lck->call, &lck->dlg); > if (status == PJ_SUCCESS) { > status = pj_mutex_lock(your_app_mutex); > if (status != PJ_SUCCESS) { > pjsip_dlg_dec_lock(lck->dlg); > } > } > } else { > status = PJSUA_LOCK(); > if (status == PJ_SUCCESS) { > status = pj_mutex_lock(your_app_mutex); > if (status != PJ_SUCCESS) { > PJSUA_UNLOCK(); > } > } > } > > return status; > } > > void app_unlock(app_lock_data *lck) > { > if (lck->dlg) { > pjsip_dlg_dec_lock(lck->dlg); > lck->call = NULL; > lck->dlg = NULL; > } else { > PJSUA_UNLOCK(); > } pj_mutex_unlock(your_app_mutex); > } > > In your other thread that needs acquiring mutex, use app_lock() and > app_unlock() with something like this: > > { > app_lock_data lck; > > app_lock(&lck, PJSUA_INVALID_ID); > // or > // app_lock(&lck, call_id); > > .. access the protected data .. > > app_unlock(&lck); > } > > In the callback context, we don't need to use app_lock() and > app_unlock() and you can just lock your mutex as usual (although > using app_lock() and app_unlock() here should be okay too I think). > > cheers, > -benny > > >> -Norman >> >> On Dec 20, 2007, at 2:49 PM, Norman Franke wrote: >> >>> Any idea what can cause this? It dies in pjsip_inv_answer called by >>> pjsua_call_answer while sending a code 180. >>> >>> 14:09:35.234 pjsua_call.c Timed-out trying to acquire PJSUA mutex >>> (possibly system has deadlocked) in pjsua_call_get_conf_port() >>> ../src/pjsip-ua/sip_inv.c:1666: failed assertion `inv->invite_tsx' >>> Program received signal: "SIGABRT". >>> >>> Norman Franke >>> ASD, Inc.