Yes, on_call_state, sorry. I did do some reordering, but could not strictly do it without having a call to lock the PJ mutex myself via the PJSUA library (didn't know how before, but thanks for the info!) I was able to unlock my lock before calling any PJ functions, and that seemed to have worked. At least in my case where I didn't manipulate any of my data structures after calling a PJ function. (I was just doing a test operation, which I could calculate before releasing the lock then do the "if" after.) Norman Franke ASD, Inc. On Dec 22, 2007, at 4:35 AM, Benny Prijono wrote: > 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. > > > _______________________________________________ > Visit our blog: http://blog.pjsip.org > > pjsip mailing list > pjsip at lists.pjsip.org > http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org Norman Franke ASD, Inc. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.pjsip.org/pipermail/pjsip_lists.pjsip.org/attachments/20080102/1f957375/attachment.html