mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-16 06:48:25 +00:00
res_pjsip_pubsub: Ensure dialog manipulation happens on proper thread.
When destroying a subscription we remove the serializer from its dialog and decrease its reference count. Depending on which thread dropped the subscription reference count to 0 it was possible for this to occur in a thread where it is not possible. (closes issue ASTERISK-22952) Reported by: Matt Jordan git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/12@404553 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -303,6 +303,25 @@ static int datastore_cmp(void *obj, void *arg, int flags)
|
|||||||
return strcmp(datastore1->uid, uid2) ? 0 : CMP_MATCH | CMP_STOP;
|
return strcmp(datastore1->uid, uid2) ? 0 : CMP_MATCH | CMP_STOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int subscription_remove_serializer(void *obj)
|
||||||
|
{
|
||||||
|
struct ast_sip_subscription *sub = obj;
|
||||||
|
|
||||||
|
/* This is why we keep the dialog on the subscription. When the subscription
|
||||||
|
* is destroyed, there is no guarantee that the underlying dialog is ready
|
||||||
|
* to be destroyed. Furthermore, there's no guarantee in the opposite direction
|
||||||
|
* either. The dialog could be destroyed before our subscription is. We fix
|
||||||
|
* this problem by keeping a reference to the dialog until it is time to
|
||||||
|
* destroy the subscription. We need to have the dialog available when the
|
||||||
|
* subscription is destroyed so that we can guarantee that our attempt to
|
||||||
|
* remove the serializer will be successful.
|
||||||
|
*/
|
||||||
|
ast_sip_dialog_set_serializer(sub->dlg, NULL);
|
||||||
|
pjsip_dlg_dec_session(sub->dlg, &pubsub_module);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void subscription_destructor(void *obj)
|
static void subscription_destructor(void *obj)
|
||||||
{
|
{
|
||||||
struct ast_sip_subscription *sub = obj;
|
struct ast_sip_subscription *sub = obj;
|
||||||
@@ -314,17 +333,7 @@ static void subscription_destructor(void *obj)
|
|||||||
ao2_cleanup(sub->endpoint);
|
ao2_cleanup(sub->endpoint);
|
||||||
|
|
||||||
if (sub->dlg) {
|
if (sub->dlg) {
|
||||||
/* This is why we keep the dialog on the subscription. When the subscription
|
ast_sip_push_task_synchronous(NULL, subscription_remove_serializer, sub);
|
||||||
* is destroyed, there is no guarantee that the underlying dialog is ready
|
|
||||||
* to be destroyed. Furthermore, there's no guarantee in the opposite direction
|
|
||||||
* either. The dialog could be destroyed before our subscription is. We fix
|
|
||||||
* this problem by keeping a reference to the dialog until it is time to
|
|
||||||
* destroy the subscription. We need to have the dialog available when the
|
|
||||||
* subscription is destroyed so that we can guarantee that our attempt to
|
|
||||||
* remove the serializer will be successful.
|
|
||||||
*/
|
|
||||||
ast_sip_dialog_set_serializer(sub->dlg, NULL);
|
|
||||||
pjsip_dlg_dec_session(sub->dlg, &pubsub_module);
|
|
||||||
}
|
}
|
||||||
ast_taskprocessor_unreference(sub->serializer);
|
ast_taskprocessor_unreference(sub->serializer);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user