summaryrefslogtreecommitdiff
path: root/pjsip
diff options
context:
space:
mode:
authorLiong Sauw Ming <ming@teluu.com>2015-09-17 06:11:01 +0000
committerLiong Sauw Ming <ming@teluu.com>2015-09-17 06:11:01 +0000
commitf116a4fa292bcf4f84392286427e16d443e072f0 (patch)
treee1e7bee6dc6dda156cd147f71197e22fa3ef306e /pjsip
parent2f953e004a63bada508be75fb9c7a3faa1924132 (diff)
Fixed #1886: Ddestruction of locked mutex in SIP dialog
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@5180 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip')
-rw-r--r--pjsip/src/pjsip/sip_dialog.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/pjsip/src/pjsip/sip_dialog.c b/pjsip/src/pjsip/sip_dialog.c
index 4066d738..d158bc3d 100644
--- a/pjsip/src/pjsip/sip_dialog.c
+++ b/pjsip/src/pjsip/sip_dialog.c
@@ -108,9 +108,10 @@ on_error:
return status;
}
-static void destroy_dialog( pjsip_dialog *dlg )
+static void destroy_dialog( pjsip_dialog *dlg, pj_bool_t unlock_mutex )
{
if (dlg->mutex_) {
+ if (unlock_mutex) pj_mutex_unlock(dlg->mutex_);
pj_mutex_destroy(dlg->mutex_);
dlg->mutex_ = NULL;
}
@@ -302,7 +303,7 @@ PJ_DEF(pj_status_t) pjsip_dlg_create_uac( pjsip_user_agent *ua,
return PJ_SUCCESS;
on_error:
- destroy_dialog(dlg);
+ destroy_dialog(dlg, PJ_FALSE);
return status;
}
@@ -551,7 +552,7 @@ on_error:
--dlg->tsx_count;
}
- destroy_dialog(dlg);
+ destroy_dialog(dlg, PJ_FALSE);
return status;
}
@@ -725,7 +726,7 @@ PJ_DEF(pj_status_t) pjsip_dlg_fork( const pjsip_dialog *first_dlg,
return PJ_SUCCESS;
on_error:
- destroy_dialog(dlg);
+ destroy_dialog(dlg, PJ_FALSE);
return status;
}
@@ -733,7 +734,8 @@ on_error:
/*
* Destroy dialog.
*/
-static pj_status_t unregister_and_destroy_dialog( pjsip_dialog *dlg )
+static pj_status_t unregister_and_destroy_dialog( pjsip_dialog *dlg,
+ pj_bool_t unlock_mutex )
{
pj_status_t status;
@@ -757,7 +759,7 @@ static pj_status_t unregister_and_destroy_dialog( pjsip_dialog *dlg )
PJ_LOG(5,(dlg->obj_name, "Dialog destroyed"));
/* Destroy this dialog. */
- destroy_dialog(dlg);
+ destroy_dialog(dlg, unlock_mutex);
return PJ_SUCCESS;
}
@@ -774,7 +776,7 @@ PJ_DEF(pj_status_t) pjsip_dlg_terminate( pjsip_dialog *dlg )
/* MUST not have pending transactions. */
PJ_ASSERT_RETURN(dlg->tsx_count==0, PJ_EINVALIDOP);
- return unregister_and_destroy_dialog(dlg);
+ return unregister_and_destroy_dialog(dlg, PJ_FALSE);
}
@@ -893,7 +895,11 @@ PJ_DEF(void) pjsip_dlg_dec_lock(pjsip_dialog *dlg)
if (dlg->sess_count==0 && dlg->tsx_count==0) {
pj_mutex_unlock(dlg->mutex_);
pj_mutex_lock(dlg->mutex_);
- unregister_and_destroy_dialog(dlg);
+ /* We are holding the dialog mutex here, so before we destroy
+ * the dialog, make sure that we unlock it first to avoid
+ * undefined behaviour on some platforms. See ticket #1886.
+ */
+ unregister_and_destroy_dialog(dlg, PJ_TRUE);
} else {
pj_mutex_unlock(dlg->mutex_);
}