summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Michelson <mmichelson@digium.com>2015-01-14 20:27:18 +0000
committerMark Michelson <mmichelson@digium.com>2015-01-14 20:27:18 +0000
commite370c9e68e802708f18dd5c4f0abd2cb690bd287 (patch)
tree46a21af0eb5d47696f0ff29d50097e38f3adab28
parent89a431df8475df407a9e305e4cd8a16e6d231e93 (diff)
Prevent slow graceful shutdown when outbound publications never started.
The code was missing the case for explicitly destroying an outbound publication when Asterisk had never actually published anything. The result was that Asterisk would hang for a while on a graceful shutdown. With this change, the case is taken into account, and on a graceful shutdown, these publications are destroyed without the need to actually send a PUBLISH request. ASTERISK-24655 #close Reported by Kevin Harwell Review: https://reviewboard.asterisk.org/r/4325 git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/13@430608 65c4cc65-6c06-0410-ace0-fbb531ad65f3
-rw-r--r--res/res_pjsip_outbound_publish.c39
1 files changed, 27 insertions, 12 deletions
diff --git a/res/res_pjsip_outbound_publish.c b/res/res_pjsip_outbound_publish.c
index c79e42847..9073f7c4f 100644
--- a/res/res_pjsip_outbound_publish.c
+++ b/res/res_pjsip_outbound_publish.c
@@ -662,25 +662,40 @@ static void sip_outbound_publish_client_destroy(void *obj)
}
}
+static int explicit_publish_destroy(void *data)
+{
+ struct ast_sip_outbound_publish_client *client = data;
+
+ pjsip_publishc_destroy(client->client);
+ ao2_ref(client, -1);
+
+ return 0;
+}
+
/*! \brief Helper function which cancels and un-publishes a no longer used client */
static int cancel_and_unpublish(struct ast_sip_outbound_publish_client *client)
{
+ struct ast_sip_event_publisher_handler *handler;
SCOPED_AO2LOCK(lock, client);
- /* If this publish client is currently publishing stop and terminate any refresh timer */
- if (client->started) {
- struct ast_sip_event_publisher_handler *handler = find_publisher_handler_for_event_name(client->publish->event);
+ if (!client->started) {
+ /* If the client was never started, there's nothing to unpublish, so just
+ * destroy the publication and remove its reference to the client.
+ */
+ ast_sip_push_task(NULL, explicit_publish_destroy, client);
+ return 0;
+ }
- if (handler) {
- handler->stop_publishing(client);
- }
+ handler = find_publisher_handler_for_event_name(client->publish->event);
+ if (handler) {
+ handler->stop_publishing(client);
+ }
- client->started = 0;
- if (ast_sip_push_task(NULL, cancel_refresh_timer_task, ao2_bump(client))) {
- ast_log(LOG_WARNING, "Could not stop refresh timer on outbound publish '%s'\n",
- ast_sorcery_object_get_id(client->publish));
- ao2_ref(client, -1);
- }
+ client->started = 0;
+ if (ast_sip_push_task(NULL, cancel_refresh_timer_task, ao2_bump(client))) {
+ ast_log(LOG_WARNING, "Could not stop refresh timer on outbound publish '%s'\n",
+ ast_sorcery_object_get_id(client->publish));
+ ao2_ref(client, -1);
}
/* If nothing is being sent right now send the unpublish - the destroy will happen in the subsequent callback */