From: Jonathan Rose Date: Mon, 14 Mar 2011 21:17:13 +0000 (+0000) Subject: Moves data store destruction from channel destruction to hangup in channel.c X-Git-Tag: 1.8.5-rc1~11^2~274 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=89eaad8ab8a26890d873aaeb55a99960dceb970f;p=thirdparty%2Fasterisk.git Moves data store destruction from channel destruction to hangup in channel.c This moves the data store destruction and app signaling events for a call to ast_hangup so that threads which wait for data store destruction don't become stuck forever when attached to an application/function/etc that keeps the channel open. (closes issue #18742) Reported by: jkister Patches: patch.diff uploaded by jrose (license 1225) Tested by: jkister, jcovert, jrose Review: https://reviewboard.asterisk.org/r/1136/ git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@310726 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- diff --git a/main/channel.c b/main/channel.c index cada40f858..90d72aaa69 100644 --- a/main/channel.c +++ b/main/channel.c @@ -2313,7 +2313,6 @@ static void ast_channel_destructor(void *obj) struct ast_var_t *vardata; struct ast_frame *f; struct varshead *headp; - struct ast_datastore *datastore; char device_name[AST_CHANNEL_NAME]; if (chan->name) { @@ -2322,18 +2321,6 @@ static void ast_channel_destructor(void *obj) ast_cel_check_retire_linkedid(chan); } - /* Get rid of each of the data stores on the channel */ - ast_channel_lock(chan); - while ((datastore = AST_LIST_REMOVE_HEAD(&chan->datastores, entry))) - /* Free the data store */ - ast_datastore_free(datastore); - ast_channel_unlock(chan); - - /* Lock and unlock the channel just to be sure nobody has it locked still - due to a reference that was stored in a datastore. (i.e. app_chanspy) */ - ast_channel_lock(chan); - ast_channel_unlock(chan); - if (chan->tech_pvt) { ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name); ast_free(chan->tech_pvt); @@ -2684,6 +2671,7 @@ int ast_hangup(struct ast_channel *chan) { int res = 0; char extra_str[64]; /* used for cel logging below */ + struct ast_datastore *datastore; /* Don't actually hang up a channel that will masquerade as someone else, or if someone is going to masquerade as us */ @@ -2790,6 +2778,15 @@ int ast_hangup(struct ast_channel *chan) ast_channel_unlock(chan); } + /* Get rid of each of the data stores on the channel */ + ast_channel_lock(chan); + while ((datastore = AST_LIST_REMOVE_HEAD(&chan->datastores, entry))) { + /* Free the data store */ + ast_datastore_free(datastore); + } + ast_channel_unlock(chan); + + chan = ast_channel_release(chan); return res;