[asterisk-commits] rmudgett: branch rmudgett/bridge_phase r395201 - in /team/rmudgett/bridge_pha...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Jul 23 15:50:01 CDT 2013
Author: rmudgett
Date: Tue Jul 23 15:49:59 2013
New Revision: 395201
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=395201
Log:
Collapse the hangup_hooks, join_hooks, and leave_hooks containers into the other_hooks container.
Modified:
team/rmudgett/bridge_phase/include/asterisk/bridging_features.h
team/rmudgett/bridge_phase/main/bridging.c
Modified: team/rmudgett/bridge_phase/include/asterisk/bridging_features.h
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_phase/include/asterisk/bridging_features.h?view=diff&rev=395201&r1=395200&r2=395201
==============================================================================
--- team/rmudgett/bridge_phase/include/asterisk/bridging_features.h (original)
+++ team/rmudgett/bridge_phase/include/asterisk/bridging_features.h Tue Jul 23 15:49:59 2013
@@ -187,6 +187,16 @@
AST_BRIDGE_HOOK_REMOVE_ON_PERSONALITY_CHANGE = (1 << 1),
};
+enum ast_bridge_hook_type {
+ /*! The hook type has not been specified. */
+ AST_BRIDGE_HOOK_TYPE_NONE,
+ AST_BRIDGE_HOOK_TYPE_DTMF,
+ AST_BRIDGE_HOOK_TYPE_TIMER,
+ AST_BRIDGE_HOOK_TYPE_HANGUP,
+ AST_BRIDGE_HOOK_TYPE_JOIN,
+ AST_BRIDGE_HOOK_TYPE_LEAVE,
+};
+
/* BUGBUG Need to be able to selectively remove DTMF, hangup, and interval hooks. */
/*! \brief Structure that is the essence of a feature hook. */
struct ast_bridge_hook {
@@ -198,6 +208,8 @@
void *hook_pvt;
/*! Flags determining when hooks should be removed from a bridge channel */
struct ast_flags remove_flags;
+ /*! What kind of hook this is. */
+ enum ast_bridge_hook_type type;
/*! Extra hook parameters. */
union {
/*! Extra parameters for a DTMF feature hook. */
@@ -224,12 +236,8 @@
struct ast_bridge_features {
/*! Attached DTMF feature hooks */
struct ao2_container *dtmf_hooks;
- /*! Attached hangup interception hooks container */
- struct ao2_container *hangup_hooks;
- /*! Attached bridge channel join interception hooks container */
- struct ao2_container *join_hooks;
- /*! Attached bridge channel leave interception hooks container */
- struct ao2_container *leave_hooks;
+ /*! Attached miscellaneous other hooks. */
+ struct ao2_container *other_hooks;
/*! Attached interval hooks */
struct ast_heap *interval_hooks;
/*! Used to determine when interval based features should be checked */
Modified: team/rmudgett/bridge_phase/main/bridging.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_phase/main/bridging.c?view=diff&rev=395201&r1=395200&r2=395201
==============================================================================
--- team/rmudgett/bridge_phase/main/bridging.c (original)
+++ team/rmudgett/bridge_phase/main/bridging.c Tue Jul 23 15:49:59 2013
@@ -832,15 +832,18 @@
struct ao2_iterator iter;
/* Run any hangup hooks. */
- iter = ao2_iterator_init(features->hangup_hooks, 0);
+ iter = ao2_iterator_init(features->other_hooks, 0);
for (; (hook = ao2_iterator_next(&iter)); ao2_ref(hook, -1)) {
int remove_me;
+ if (hook->type != AST_BRIDGE_HOOK_TYPE_HANGUP) {
+ continue;
+ }
remove_me = hook->callback(bridge_channel->bridge, bridge_channel, hook->hook_pvt);
if (remove_me) {
ast_debug(1, "Hangup hook %p is being removed from %p(%s)\n",
hook, bridge_channel, ast_channel_name(bridge_channel->chan));
- ao2_unlink(features->hangup_hooks, hook);
+ ao2_unlink(features->other_hooks, hook);
}
}
ao2_iterator_destroy(&iter);
@@ -2984,58 +2987,36 @@
/*!
* \internal
- * \brief Handle bridge channel join event.
+ * \brief Handle bridge channel join/leave event.
* \since 12.0.0
*
- * \param bridge_channel Which channel is joining.
+ * \param bridge_channel Which channel is involved.
+ * \param type Specified join/leave event.
*
* \return Nothing
*/
-static void bridge_channel_handle_join(struct ast_bridge_channel *bridge_channel)
+static void bridge_channel_event_join_leave(struct ast_bridge_channel *bridge_channel, enum ast_bridge_hook_type type)
{
struct ast_bridge_features *features = bridge_channel->features;
struct ast_bridge_hook *hook;
struct ao2_iterator iter;
- /* Run any join hooks. */
- iter = ao2_iterator_init(features->join_hooks, AO2_ITERATOR_UNLINK);
- hook = ao2_iterator_next(&iter);
+ /* Run the specified hooks. */
+ iter = ao2_iterator_init(features->other_hooks, 0);
+ for (; (hook = ao2_iterator_next(&iter)); ao2_ref(hook, -1)) {
+ if (hook->type == type) {
+ break;
+ }
+ }
if (hook) {
+ /* Found the first specified hook to run. */
bridge_channel_suspend(bridge_channel);
ast_indicate(bridge_channel->chan, AST_CONTROL_SRCUPDATE);
do {
- hook->callback(bridge_channel->bridge, bridge_channel, hook->hook_pvt);
- ao2_ref(hook, -1);
- } while ((hook = ao2_iterator_next(&iter)));
- ast_indicate(bridge_channel->chan, AST_CONTROL_SRCUPDATE);
- bridge_channel_unsuspend(bridge_channel);
- }
- ao2_iterator_destroy(&iter);
-}
-
-/*!
- * \internal
- * \brief Handle bridge channel leave event.
- * \since 12.0.0
- *
- * \param bridge_channel Which channel is leaving.
- *
- * \return Nothing
- */
-static void bridge_channel_handle_leave(struct ast_bridge_channel *bridge_channel)
-{
- struct ast_bridge_features *features = bridge_channel->features;
- struct ast_bridge_hook *hook;
- struct ao2_iterator iter;
-
- /* Run any leave hooks. */
- iter = ao2_iterator_init(features->leave_hooks, AO2_ITERATOR_UNLINK);
- hook = ao2_iterator_next(&iter);
- if (hook) {
- bridge_channel_suspend(bridge_channel);
- ast_indicate(bridge_channel->chan, AST_CONTROL_SRCUPDATE);
- do {
- hook->callback(bridge_channel->bridge, bridge_channel, hook->hook_pvt);
+ if (hook->type == type) {
+ hook->callback(bridge_channel->bridge, bridge_channel, hook->hook_pvt);
+ ao2_unlink(features->other_hooks, hook);
+ }
ao2_ref(hook, -1);
} while ((hook = ao2_iterator_next(&iter)));
ast_indicate(bridge_channel->chan, AST_CONTROL_SRCUPDATE);
@@ -3092,12 +3073,12 @@
}
ast_bridge_unlock(bridge_channel->bridge);
- bridge_channel_handle_join(bridge_channel);
+ bridge_channel_event_join_leave(bridge_channel, AST_BRIDGE_HOOK_TYPE_JOIN);
while (bridge_channel->state == AST_BRIDGE_CHANNEL_STATE_WAIT) {
/* Wait for something to do. */
bridge_channel_wait(bridge_channel);
}
- bridge_channel_handle_leave(bridge_channel);
+ bridge_channel_event_join_leave(bridge_channel, AST_BRIDGE_HOOK_TYPE_LEAVE);
ast_bridge_channel_lock_bridge(bridge_channel);
}
@@ -5293,6 +5274,7 @@
if (!hook) {
return -1;
}
+ hook->type = AST_BRIDGE_HOOK_TYPE_DTMF;
ast_copy_string(hook->parms.dtmf.code, dtmf, sizeof(hook->parms.dtmf.code));
/* Once done we put it in the container. */
@@ -5311,11 +5293,26 @@
return res;
}
-int ast_bridge_hangup_hook(struct ast_bridge_features *features,
+/*!
+ * \internal
+ * \brief Attach an other hook to a bridge features structure
+ *
+ * \param features Bridge features structure
+ * \param callback Function to execute upon activation
+ * \param hook_pvt Unique data
+ * \param destructor Optional destructor callback for hook_pvt data
+ * \param remove_flags Dictates what situations the hook should be removed.
+ * \param type What type of hook is being attached.
+ *
+ * \retval 0 on success
+ * \retval -1 on failure (The caller must cleanup any hook_pvt resources.)
+ */
+static int bridge_other_hook(struct ast_bridge_features *features,
ast_bridge_hook_callback callback,
void *hook_pvt,
ast_bridge_hook_pvt_destructor destructor,
- enum ast_bridge_hook_remove_flags remove_flags)
+ enum ast_bridge_hook_remove_flags remove_flags,
+ enum ast_bridge_hook_type type)
{
struct ast_bridge_hook *hook;
int res;
@@ -5326,9 +5323,10 @@
if (!hook) {
return -1;
}
+ hook->type = type;
/* Once done we put it in the container. */
- res = ao2_link(features->hangup_hooks, hook) ? 0 : -1;
+ res = ao2_link(features->other_hooks, hook) ? 0 : -1;
if (res) {
/*
* Could not link the hook into the container.
@@ -5343,36 +5341,24 @@
return res;
}
+int ast_bridge_hangup_hook(struct ast_bridge_features *features,
+ ast_bridge_hook_callback callback,
+ void *hook_pvt,
+ ast_bridge_hook_pvt_destructor destructor,
+ enum ast_bridge_hook_remove_flags remove_flags)
+{
+ return bridge_other_hook(features, callback, hook_pvt, destructor, remove_flags,
+ AST_BRIDGE_HOOK_TYPE_HANGUP);
+}
+
int ast_bridge_join_hook(struct ast_bridge_features *features,
ast_bridge_hook_callback callback,
void *hook_pvt,
ast_bridge_hook_pvt_destructor destructor,
enum ast_bridge_hook_remove_flags remove_flags)
{
- struct ast_bridge_hook *hook;
- int res;
-
- /* Allocate new hook and setup it's various variables */
- hook = bridge_hook_generic(sizeof(*hook), callback, hook_pvt, destructor,
- remove_flags);
- if (!hook) {
- return -1;
- }
-
- /* Once done we put it in the container. */
- res = ao2_link(features->join_hooks, hook) ? 0 : -1;
- if (res) {
- /*
- * Could not link the hook into the container.
- *
- * Remove the hook_pvt destructor call from the hook since we
- * are returning failure to install the hook.
- */
- hook->destructor = NULL;
- }
- ao2_ref(hook, -1);
-
- return res;
+ return bridge_other_hook(features, callback, hook_pvt, destructor, remove_flags,
+ AST_BRIDGE_HOOK_TYPE_JOIN);
}
int ast_bridge_leave_hook(struct ast_bridge_features *features,
@@ -5381,30 +5367,8 @@
ast_bridge_hook_pvt_destructor destructor,
enum ast_bridge_hook_remove_flags remove_flags)
{
- struct ast_bridge_hook *hook;
- int res;
-
- /* Allocate new hook and setup it's various variables */
- hook = bridge_hook_generic(sizeof(*hook), callback, hook_pvt, destructor,
- remove_flags);
- if (!hook) {
- return -1;
- }
-
- /* Once done we put it in the container. */
- res = ao2_link(features->leave_hooks, hook) ? 0 : -1;
- if (res) {
- /*
- * Could not link the hook into the container.
- *
- * Remove the hook_pvt destructor call from the hook since we
- * are returning failure to install the hook.
- */
- hook->destructor = NULL;
- }
- ao2_ref(hook, -1);
-
- return res;
+ return bridge_other_hook(features, callback, hook_pvt, destructor, remove_flags,
+ AST_BRIDGE_HOOK_TYPE_LEAVE);
}
void ast_bridge_features_set_talk_detector(struct ast_bridge_features *features,
@@ -5445,6 +5409,7 @@
if (!hook) {
return -1;
}
+ hook->type = AST_BRIDGE_HOOK_TYPE_TIMER;
hook->parms.timer.interval = interval;
hook->parms.timer.trip_time = ast_tvadd(ast_tvnow(), ast_samp2tv(hook->parms.timer.interval, 1000));
hook->parms.timer.seqno = ast_atomic_fetchadd_int((int *) &features->interval_sequence, +1);
@@ -5611,9 +5576,7 @@
void ast_bridge_features_remove(struct ast_bridge_features *features, enum ast_bridge_hook_remove_flags remove_flags)
{
hooks_remove_container(features->dtmf_hooks, remove_flags);
- hooks_remove_container(features->hangup_hooks, remove_flags);
- hooks_remove_container(features->join_hooks, remove_flags);
- hooks_remove_container(features->leave_hooks, remove_flags);
+ hooks_remove_container(features->other_hooks, remove_flags);
hooks_remove_heap(features->interval_hooks, remove_flags);
}
@@ -5683,24 +5646,10 @@
return -1;
}
- /* Initialize the hangup hooks container */
- features->hangup_hooks = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_MUTEX, 0, NULL,
+ /* Initialize the miscellaneous other hooks container */
+ features->other_hooks = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_MUTEX, 0, NULL,
NULL);
- if (!features->hangup_hooks) {
- return -1;
- }
-
- /* Initialize the join hooks container */
- features->join_hooks = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_MUTEX, 0, NULL,
- NULL);
- if (!features->join_hooks) {
- return -1;
- }
-
- /* Initialize the leave hooks container */
- features->leave_hooks = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_MUTEX, 0, NULL,
- NULL);
- if (!features->leave_hooks) {
+ if (!features->other_hooks) {
return -1;
}
@@ -5744,17 +5693,9 @@
features->talker_hook.pvt_data = NULL;
}
- /* Destroy the leave hooks container. */
- ao2_cleanup(features->leave_hooks);
- features->leave_hooks = NULL;
-
- /* Destroy the join hooks container. */
- ao2_cleanup(features->join_hooks);
- features->join_hooks = NULL;
-
- /* Destroy the hangup hooks container. */
- ao2_cleanup(features->hangup_hooks);
- features->hangup_hooks = NULL;
+ /* Destroy the miscellaneous other hooks container. */
+ ao2_cleanup(features->other_hooks);
+ features->other_hooks = NULL;
/* Destroy the DTMF hooks container. */
ao2_cleanup(features->dtmf_hooks);
More information about the asterisk-commits
mailing list