[svn-commits] mmichelson: branch mmichelson/chan_fixup r173349 - /team/mmichelson/chan_fixu...
SVN commits to the Digium repositories
svn-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 svn-commits
mailing list