From 269bb08ea290cbdb677892ed6b20885112ee1c62 Mon Sep 17 00:00:00 2001 From: George Joseph Date: Tue, 2 Mar 2021 11:55:38 -0700 Subject: [PATCH] res_pjsip_refer: Move the progress dlg release to a serializer Although the dlg session count was incremented in a pjsip servant thread, there's no guarantee that the last thread to unref this progress object was one. Before we decrement, we need to make sure that this is either a servant thread or that we push the decrement to a serializer that is one. Because pjsip_dlg_dec_session requires the dialog lock, we don't want to wait on the task to complete if we had to push it to a serializer. Change-Id: I8ff2d5d94be3ff04298394070434e22a7d3cbc41 --- res/res_pjsip_refer.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/res/res_pjsip_refer.c b/res/res_pjsip_refer.c index 07fe23d78d..8890d235b5 100644 --- a/res/res_pjsip_refer.c +++ b/res/res_pjsip_refer.c @@ -340,6 +340,11 @@ static pjsip_evsub_user refer_progress_evsub_cb = { .on_evsub_state = refer_progress_on_evsub_state, }; +static int dlg_releaser_task(void *data) { + pjsip_dlg_dec_session((pjsip_dialog *)data, &refer_progress_module); + return 0; +} + /*! \brief Destructor for REFER progress sutrcture */ static void refer_progress_destroy(void *obj) { @@ -350,7 +355,21 @@ static void refer_progress_destroy(void *obj) } if (progress->dlg) { - pjsip_dlg_dec_session(progress->dlg, &refer_progress_module); + /* + * Although the dlg session count was incremented in a pjsip servant + * thread, there's no guarantee that the last thread to unref this progress + * object was one. Before we decrement, we need to make sure that this + * is either a servant thread or that we push the decrement to a + * serializer that is one. + * + * Because pjsip_dlg_dec_session requires the dialog lock, we don't want + * to wait on the task to complete if we had to push it to a serializer. + */ + if (ast_sip_thread_is_servant()) { + pjsip_dlg_dec_session(progress->dlg, &refer_progress_module); + } else { + ast_sip_push_task(NULL, dlg_releaser_task, progress->dlg); + } } ao2_cleanup(progress->transfer_data);