diff options
author | Benny Prijono <bennylp@teluu.com> | 2013-02-21 16:43:24 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2013-02-21 16:43:24 +0000 |
commit | be38b8c18e6c57ab7acb2fdef6f1a399a8f5d889 (patch) | |
tree | 54cefc46436bd93c853d35257f0aa59ca594af24 /pjsip | |
parent | 57ea4f8e4354e9bb5ac0d4ae11d06f194b78bf01 (diff) |
Re #1623: fixed deadlock between conference mutex and ICE. Scenario:
- sound device thread calls put_frame() which gets the conf mutex, and is calling transport sendto() to send RTP packet which requires ICE mutex.
- The worker thread finished ICE negotiation and notifies PJSUA-LIB and application while holding ICE group lock, app then do conf_connect() which causes deadlock.
This fix defer the callback to a timer.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@4363 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip')
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_media.c | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/pjsip/src/pjsua-lib/pjsua_media.c b/pjsip/src/pjsua-lib/pjsua_media.c index d18703ca..bc979153 100644 --- a/pjsip/src/pjsua-lib/pjsua_media.c +++ b/pjsip/src/pjsua-lib/pjsua_media.c @@ -552,7 +552,8 @@ on_error: } #endif -static void med_tp_timer_cb(void *user_data) +/* Deferred callback to notify ICE init complete */ +static void ice_init_complete_cb(void *user_data) { pjsua_call_media *call_med = (pjsua_call_media*)user_data; @@ -570,7 +571,7 @@ static void med_tp_timer_cb(void *user_data) pjsua_call *call = NULL; pjsip_dialog *dlg = NULL; - if (acquire_call("med_tp_timer_cb", call_med->call->index, + if (acquire_call("ice_init_complete_cb", call_med->call->index, &call, &dlg) != PJ_SUCCESS) { /* Call have been terminated */ @@ -585,6 +586,26 @@ static void med_tp_timer_cb(void *user_data) } } +/* Deferred callback to notify ICE negotiation failure */ +static void ice_failed_nego_cb(void *user_data) +{ + int call_id = (int)(long)user_data; + pjsua_call *call = NULL; + pjsip_dialog *dlg = NULL; + + if (acquire_call("ice_failed_nego_cb", call_id, + &call, &dlg) != PJ_SUCCESS) + { + /* Call have been terminated */ + return; + } + + pjsua_var.ua_cfg.cb.on_call_media_state(call_id); + + if (dlg) + pjsip_dlg_dec_lock(dlg); + +} /* This callback is called when ICE negotiation completes */ static void on_ice_complete(pjmedia_transport *tp, @@ -602,7 +623,7 @@ static void on_ice_complete(pjmedia_transport *tp, switch (op) { case PJ_ICE_STRANS_OP_INIT: call_med->tp_result = result; - pjsua_schedule_timer2(&med_tp_timer_cb, call_med, 1); + pjsua_schedule_timer2(&ice_init_complete_cb, call_med, 1); break; case PJ_ICE_STRANS_OP_NEGOTIATION: if (result == PJ_SUCCESS) { @@ -615,7 +636,9 @@ static void on_ice_complete(pjmedia_transport *tp, call_med->state = PJSUA_CALL_MEDIA_ERROR; call_med->dir = PJMEDIA_DIR_NONE; if (call && pjsua_var.ua_cfg.cb.on_call_media_state) { - pjsua_var.ua_cfg.cb.on_call_media_state(call->index); + /* Defer the callback to a timer */ + pjsua_schedule_timer2(&ice_failed_nego_cb, + (void*)(long)call->index, 1); } } /* Check if default ICE transport address is changed */ |