summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/app_chanspy.c4
-rw-r--r--main/channel.c21
2 files changed, 16 insertions, 9 deletions
diff --git a/apps/app_chanspy.c b/apps/app_chanspy.c
index 0bf676891..d7047d047 100644
--- a/apps/app_chanspy.c
+++ b/apps/app_chanspy.c
@@ -2,7 +2,7 @@
* Asterisk -- An open source telephony toolkit.
*
* Copyright (C) 2005 Anthony Minessale II (anthmct@yahoo.com)
- * Copyright (C) 2005 - 2006, Digium, Inc.
+ * Copyright (C) 2005 - 2008, Digium, Inc.
*
* A license has been granted to Digium (via disclaimer) for the use of
* this code.
@@ -23,6 +23,8 @@
* \brief ChanSpy: Listen in on any channel.
*
* \author Anthony Minessale II <anthmct@yahoo.com>
+ * \author Joshua Colp <jcolp@digium.com>
+ * \author Russell Bryant <russell@digium.com>
*
* \ingroup applications
*/
diff --git a/main/channel.c b/main/channel.c
index 19d7a7c2c..93f6f58f3 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -1257,10 +1257,21 @@ void ast_channel_free(struct ast_channel *chan)
AST_RWLIST_UNLOCK(&channels);
ast_log(LOG_ERROR, "Unable to find channel in list to free. Assuming it has already been done.\n");
}
- /* Lock and unlock the channel just to be sure nobody
- has it locked still */
+ /* Lock and unlock the channel just to be sure nobody has it locked still
+ due to a reference retrieved from the channel list. */
ast_channel_lock(chan);
ast_channel_unlock(chan);
+
+ /* Get rid of each of the data stores on the channel */
+ while ((datastore = AST_LIST_REMOVE_HEAD(&chan->datastores, entry)))
+ /* Free the data store */
+ ast_channel_datastore_free(datastore);
+
+ /* 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);
@@ -1304,12 +1315,6 @@ void ast_channel_free(struct ast_channel *chan)
while ((f = AST_LIST_REMOVE_HEAD(&chan->readq, frame_list)))
ast_frfree(f);
- /* Get rid of each of the data stores on the channel */
- while ((datastore = AST_LIST_REMOVE_HEAD(&chan->datastores, entry)))
- /* Free the data store */
- ast_channel_datastore_free(datastore);
- AST_LIST_HEAD_INIT_NOLOCK(&chan->datastores);
-
/* loop over the variables list, freeing all data and deleting list items */
/* no need to lock the list, as the channel is already locked */