[asterisk-commits] mmichelson: branch mmichelson/chan_fixup r173349 - /team/mmichelson/chan_fixu...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Feb 3 20:17:01 CST 2009


Author: mmichelson
Date: Tue Feb  3 20:17:01 2009
New Revision: 173349

URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=173349
Log:
Initial change of app_chanspy to use autochan

This is an "it compiles" type checkin. I have not looked very 
closely at app_chanspy to see if more can be removed as a result
of this change, nor have I run any tests to be sure that everything
still works as it should.

One thing I know is off here is that app_chanspy follows the exact
opposite of the locking order described in autochan.h so that should
be addressed.


Modified:
    team/mmichelson/chan_fixup/apps/app_chanspy.c

Modified: team/mmichelson/chan_fixup/apps/app_chanspy.c
URL: http://svn.digium.com/svn-view/asterisk/team/mmichelson/chan_fixup/apps/app_chanspy.c?view=diff&rev=173349&r1=173348&r2=173349
==============================================================================
--- team/mmichelson/chan_fixup/apps/app_chanspy.c (original)
+++ team/mmichelson/chan_fixup/apps/app_chanspy.c Tue Feb  3 20:17:01 2009
@@ -53,6 +53,7 @@
 #include "asterisk/translate.h"
 #include "asterisk/module.h"
 #include "asterisk/lock.h"
+#include "asterisk/autochan.h"
 
 #define AST_NAME_STRLEN 256
 
@@ -147,8 +148,6 @@
 	AST_APP_OPTION_ARG('r', OPTION_RECORD, OPT_ARG_RECORD),
 });
 
-static int next_unique_id_to_use = 0;
-
 struct chanspy_translation_helper {
 	/* spy data */
 	struct ast_audiohook spy_audiohook;
@@ -223,13 +222,7 @@
 	return res;
 }
 
-struct chanspy_ds {
-	struct ast_channel *chan;
-	char unique_id[20];
-	ast_mutex_t lock;
-};
-
-static int channel_spy(struct ast_channel *chan, struct chanspy_ds *spyee_chanspy_ds, 
+static int channel_spy(struct ast_channel *chan, struct ast_autochan *spyee_chanspy_autochan, 
 	int *volfactor, int fd, const struct ast_flags *flags) 
 {
 	struct chanspy_translation_helper csth;
@@ -245,12 +238,12 @@
 	spyer_name = ast_strdupa(chan->name);
 	ast_channel_unlock(chan);
 
-	ast_mutex_lock(&spyee_chanspy_ds->lock);
-	if (spyee_chanspy_ds->chan) {
-		spyee = spyee_chanspy_ds->chan;
+	ast_autochan_lock(spyee_chanspy_autochan);
+	if (spyee_chanspy_autochan->chan) {
+		spyee = spyee_chanspy_autochan->chan;
 		ast_channel_lock(spyee);
 	}
-	ast_mutex_unlock(&spyee_chanspy_ds->lock);
+	ast_autochan_unlock(spyee_chanspy_autochan);
 
 	if (!spyee)
 		return 0;
@@ -386,87 +379,36 @@
 
 /*!
  * \note This relies on the embedded lock to be recursive, as it may be called
- * due to a call to chanspy_ds_free with the lock held there.
+ * due to a call to autochan_null with the lock held there.
  */
-static void chanspy_ds_destroy(void *data)
-{
-	struct chanspy_ds *chanspy_ds = data;
+static void autochan_null(struct ast_autochan *autochan)
+{
+	if (!autochan) {
+		return;
+	}
 
 	/* Setting chan to be NULL is an atomic operation, but we don't want this
 	 * value to change while this lock is held.  The lock is held elsewhere
 	 * while it performs non-atomic operations with this channel pointer */
 
-	ast_mutex_lock(&chanspy_ds->lock);
-	chanspy_ds->chan = NULL;
-	ast_mutex_unlock(&chanspy_ds->lock);
-}
-
-static void chanspy_ds_chan_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)
-{
-	struct chanspy_ds *chanspy_ds = data;
-	
-	ast_mutex_lock(&chanspy_ds->lock);
-	chanspy_ds->chan = new_chan;
-	ast_mutex_unlock(&chanspy_ds->lock);
-}
-
-static const struct ast_datastore_info chanspy_ds_info = {
-	.type = "chanspy",
-	.destroy = chanspy_ds_destroy,
-	.chan_fixup = chanspy_ds_chan_fixup,
-};
-
-static struct chanspy_ds *chanspy_ds_free(struct chanspy_ds *chanspy_ds)
-{
-	if (!chanspy_ds)
-		return NULL;
-
-	ast_mutex_lock(&chanspy_ds->lock);
-	if (chanspy_ds->chan) {
-		struct ast_datastore *datastore;
-		struct ast_channel *chan;
-
-		chan = chanspy_ds->chan;
-
-		ast_channel_lock(chan);
-		if ((datastore = ast_channel_datastore_find(chan, &chanspy_ds_info, chanspy_ds->unique_id))) {
-			ast_channel_datastore_remove(chan, datastore);
-			/* chanspy_ds->chan is NULL after this call */
-			chanspy_ds_destroy(datastore->data);
-			datastore->data = NULL;
-			ast_channel_datastore_free(datastore);
-		}
-		ast_channel_unlock(chan);
-	}
-	ast_mutex_unlock(&chanspy_ds->lock);
-
-	return NULL;
-}
-
-/*! \note Returns the channel in the chanspy_ds locked as well as the chanspy_ds locked */
-static struct chanspy_ds *setup_chanspy_ds(struct ast_channel *chan, struct chanspy_ds *chanspy_ds)
-{
-	struct ast_datastore *datastore = NULL;
-
-	ast_mutex_lock(&chanspy_ds->lock);
-
-	if (!(datastore = ast_channel_datastore_alloc(&chanspy_ds_info, chanspy_ds->unique_id))) {
-		ast_mutex_unlock(&chanspy_ds->lock);
-		chanspy_ds = chanspy_ds_free(chanspy_ds);
-		ast_channel_unlock(chan);
-		return NULL;
-	}
-	
-	chanspy_ds->chan = chan;
-	datastore->data = chanspy_ds;
-	ast_channel_datastore_add(chan, datastore);
-
-	return chanspy_ds;
-}
-
-static struct chanspy_ds *next_channel(struct ast_channel *chan,
+	ast_autochan_lock(autochan);
+	autochan->chan = NULL;
+	ast_autochan_unlock(autochan);
+}
+
+/*! \note Returns the channel in the chanspy_autochan locked as well as the chanspy_autochan locked */
+static struct ast_autochan *setup_chanspy_autochan(struct ast_channel *chan, struct ast_autochan *autochan)
+{
+
+	ast_autochan_lock(autochan);
+	autochan->chan = chan;
+
+	return autochan;
+}
+
+static struct ast_autochan *next_channel(struct ast_channel *chan,
 	const struct ast_channel *last, const char *spec,
-	const char *exten, const char *context, struct chanspy_ds *chanspy_ds)
+	const char *exten, const char *context, struct ast_autochan *autochan)
 {
 	struct ast_channel *this;
 	char channel_name[AST_CHANNEL_NAME];
@@ -498,7 +440,7 @@
 		goto redo;
 	}
 
-	return setup_chanspy_ds(this, chanspy_ds);
+	return setup_chanspy_autochan(this, autochan);
 }
 
 static int common_exec(struct ast_channel *chan, const struct ast_flags *flags,
@@ -513,11 +455,11 @@
 	char *ptr;
 	int num;
 	int num_spyed_upon = 1;
-	struct chanspy_ds chanspy_ds = { 0, };
-
-	ast_mutex_init(&chanspy_ds.lock);
-
-	snprintf(chanspy_ds.unique_id, sizeof(chanspy_ds.unique_id), "%d", ast_atomic_fetchadd_int(&next_unique_id_to_use, +1));
+	struct ast_autochan *autochan;
+
+	if (!(autochan = ast_autochan_setup(NULL))) {
+		return -1;
+	}
 
 	if (chan->_state != AST_STATE_UP)
 		ast_answer(chan);
@@ -527,7 +469,7 @@
 	waitms = 100;
 
 	for (;;) {
-		struct chanspy_ds *peer_chanspy_ds = NULL, *next_chanspy_ds = NULL;
+		struct ast_autochan *peer_chanspy_autochan = NULL, *next_chanspy_autochan = NULL;
 		struct ast_channel *prev = NULL, *peer = NULL;
 
 		if (!ast_test_flag(flags, OPTION_QUIET) && num_spyed_upon) {
@@ -550,11 +492,11 @@
 		waitms = 100;
 		num_spyed_upon = 0;
 
-		for (peer_chanspy_ds = next_channel(chan, prev, spec, exten, context, &chanspy_ds);
-		     peer_chanspy_ds;
-			 chanspy_ds_free(peer_chanspy_ds), prev = peer,
-		     peer_chanspy_ds = next_chanspy_ds ? next_chanspy_ds : 
-			 	next_channel(chan, prev, spec, exten, context, &chanspy_ds), next_chanspy_ds = NULL) {
+		for (peer_chanspy_autochan = next_channel(chan, prev, spec, exten, context, autochan);
+		     peer_chanspy_autochan;
+			 autochan_null(peer_chanspy_autochan), prev = peer,
+		     peer_chanspy_autochan = next_chanspy_autochan ? next_chanspy_autochan : 
+			 	next_channel(chan, prev, spec, exten, context, autochan), next_chanspy_autochan = NULL) {
 			const char *group;
 			int igrp = !mygroup;
 			char *groups[25];
@@ -563,19 +505,19 @@
 			int x;
 			char *s;
 
-			peer = peer_chanspy_ds->chan;
-
-			ast_mutex_unlock(&peer_chanspy_ds->lock);
+			peer = peer_chanspy_autochan->chan;
+
+			ast_autochan_unlock(peer_chanspy_autochan);
 
 			if (peer == prev) {
 				ast_channel_unlock(peer);
-				chanspy_ds_free(peer_chanspy_ds);
+				autochan_null(peer_chanspy_autochan);
 				break;
 			}
 
 			if (ast_check_hangup(chan)) {
 				ast_channel_unlock(peer);
-				chanspy_ds_free(peer_chanspy_ds);
+				autochan_null(peer_chanspy_autochan);
 				break;
 			}
 
@@ -619,7 +561,7 @@
 
 			/* We have to unlock the peer channel here to avoid a deadlock.
 			 * So, when we need to dereference it again, we have to lock the 
-			 * datastore and get the pointer from there to see if the channel 
+			 * autochan and get the pointer from there to see if the channel 
 			 * is still valid. */
 			ast_channel_unlock(peer);
 
@@ -629,7 +571,7 @@
 					if (!res)
 						res = ast_waitstream(chan, "");
 					if (res) {
-						chanspy_ds_free(peer_chanspy_ds);
+						autochan_null(peer_chanspy_autochan);
 						break;
 					}
 				} else
@@ -638,11 +580,11 @@
 					ast_say_digits(chan, atoi(ptr), "", chan->language);
 			}
 			
-			res = channel_spy(chan, peer_chanspy_ds, &volfactor, fd, flags);
+			res = channel_spy(chan, peer_chanspy_autochan, &volfactor, fd, flags);
 			num_spyed_upon++;	
 
 			if (res == -1) {
-				chanspy_ds_free(peer_chanspy_ds);
+				autochan_null(peer_chanspy_autochan);
 				break;
 			} else if (res > 1 && spec) {
 				struct ast_channel *next;
@@ -650,20 +592,20 @@
 				snprintf(nameprefix, AST_NAME_STRLEN, "%s/%d", spec, res);
 
 				if ((next = ast_get_channel_by_name_prefix_locked(nameprefix, strlen(nameprefix)))) {
-					peer_chanspy_ds = chanspy_ds_free(peer_chanspy_ds);
-					next_chanspy_ds = setup_chanspy_ds(next, &chanspy_ds);
+					autochan_null(peer_chanspy_autochan);
+					next_chanspy_autochan = setup_chanspy_autochan(next, autochan);
 				} else {
 					/* stay on this channel, if it is still valid */
 
-					ast_mutex_lock(&peer_chanspy_ds->lock);
-					if (peer_chanspy_ds->chan) {
-						ast_channel_lock(peer_chanspy_ds->chan);
-						next_chanspy_ds = peer_chanspy_ds;
-						peer_chanspy_ds = NULL;
+					ast_autochan_lock(peer_chanspy_autochan);
+					if (peer_chanspy_autochan->chan) {
+						ast_channel_lock(peer_chanspy_autochan->chan);
+						next_chanspy_autochan = peer_chanspy_autochan;
+						peer_chanspy_autochan = NULL;
 					} else {
 						/* the channel is gone */
-						ast_mutex_unlock(&peer_chanspy_ds->lock);
-						next_chanspy_ds = NULL;
+						ast_autochan_unlock(peer_chanspy_autochan);
+						next_chanspy_autochan = NULL;
 					}
 				}
 
@@ -678,9 +620,7 @@
 
 	ast_channel_setoption(chan, AST_OPTION_TXGAIN, &zero_volume, sizeof(zero_volume), 0);
 
-	ast_mutex_lock(&chanspy_ds.lock);
-	ast_mutex_unlock(&chanspy_ds.lock);
-	ast_mutex_destroy(&chanspy_ds.lock);
+	ast_autochan_destroy(autochan);
 
 	return res;
 }




More information about the asterisk-commits mailing list