[asterisk-commits] rmudgett: branch rmudgett/bridge_phase r384483 - in /team/rmudgett/bridge_pha...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Apr 1 12:56:51 CDT 2013
Author: rmudgett
Date: Mon Apr 1 12:56:47 2013
New Revision: 384483
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=384483
Log:
* Made pulling a channel check if the bridge needs to be dissolved.
* Add AST_BRIDGE_FLAG_DISSOLVE_EMPTY support.
* Add dissolving bridge method to eliminate external references to a
bridge that is being dissolved.
* Fix ast_channel bridg_channel pointer after a DTMF atxfer.
Modified:
team/rmudgett/bridge_phase/bridges/bridge_builtin_features.c
team/rmudgett/bridge_phase/include/asterisk/bridging.h
team/rmudgett/bridge_phase/main/bridging.c
team/rmudgett/bridge_phase/main/features.c
Modified: team/rmudgett/bridge_phase/bridges/bridge_builtin_features.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_phase/bridges/bridge_builtin_features.c?view=diff&rev=384483&r1=384482&r2=384483
==============================================================================
--- team/rmudgett/bridge_phase/bridges/bridge_builtin_features.c (original)
+++ team/rmudgett/bridge_phase/bridges/bridge_builtin_features.c Mon Apr 1 12:56:47 2013
@@ -329,6 +329,18 @@
*/
ast_bridge_join(attended_bridge, bridge_channel->chan, NULL, &caller_features, NULL, 0);
+/*
+ * BUGBUG there is a small window where the channel does not point to the bridge_channel.
+ *
+ * This window is expected to go away when atxfer is redesigned
+ * to fully support existing functionality. There will be one
+ * and only one ast_bridge_channel structure per channel.
+ */
+ /* Point the channel back to the original bridge_channel. */
+ ast_channel_lock(bridge_channel->chan);
+ ast_channel_internal_bridge_channel_set(bridge_channel->chan, bridge_channel);
+ ast_channel_unlock(bridge_channel->chan);
+
/* Wait for peer thread to exit bridge and die. */
if (!ast_autoservice_start(bridge_channel->chan)) {
ast_bridge_depart(peer);
Modified: team/rmudgett/bridge_phase/include/asterisk/bridging.h
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_phase/include/asterisk/bridging.h?view=diff&rev=384483&r1=384482&r2=384483
==============================================================================
--- team/rmudgett/bridge_phase/include/asterisk/bridging.h (original)
+++ team/rmudgett/bridge_phase/include/asterisk/bridging.h Mon Apr 1 12:56:47 2013
@@ -246,6 +246,19 @@
typedef void (*ast_bridge_destructor_fn)(struct ast_bridge *self);
/*!
+ * \brief The bridge is being dissolved.
+ *
+ * \param self Bridge to operate upon.
+ *
+ * \details
+ * The bridge is being dissolved. Remove any external
+ * references to the bridge so it can be destroyed.
+ *
+ * \return Nothing
+ */
+typedef void (*ast_bridge_dissolving_fn)(struct ast_bridge *self);
+
+/*!
* \brief Can this channel be pushed into the bridge.
*
* \param self Bridge to operate upon.
@@ -322,6 +335,8 @@
const char *name;
/*! Destroy the bridge. */
ast_bridge_destructor_fn destroy;
+ /*! The bridge is being dissolved. Remove any references to the bridge. */
+ ast_bridge_dissolving_fn dissolving;
/*! TRUE if can push the bridge channel into the bridge. */
ast_bridge_can_push_channel_fn can_push;
/*! Push the bridge channel into the bridge. */
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=384483&r1=384482&r2=384483
==============================================================================
--- team/rmudgett/bridge_phase/main/bridging.c (original)
+++ team/rmudgett/bridge_phase/main/bridging.c Mon Apr 1 12:56:47 2013
@@ -379,6 +379,82 @@
/*!
* \internal
+ * \brief Dissolve the bridge.
+ * \since 12.0.0
+ *
+ * \param bridge Bridge to eject all channels
+ *
+ * \details
+ * Force out all channels that are not already going out of the
+ * bridge. Any new channels joining will leave immediately.
+ *
+ * \note On entry, bridge is already locked.
+ *
+ * \return Nothing
+ */
+static void bridge_dissolve(struct ast_bridge *bridge)
+{
+ struct ast_bridge_channel *bridge_channel;
+
+ if (bridge->dissolved) {
+ return;
+ }
+ bridge->dissolved = 1;
+
+ ast_debug(1, "Bridge %s: dissolving bridge\n", bridge->uniqueid);
+
+/* BUGBUG need a cause code on the bridge for the later ejected channels. */
+ AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
+ ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_HANGUP);
+ }
+ bridge->v_table->dissolving(bridge);
+}
+
+/*!
+ * \internal
+ * \brief Check if a bridge should dissolve and do it.
+ * \since 12.0.0
+ *
+ * \param bridge_channel Channel causing the check.
+ *
+ * \note On entry, bridge_channel->bridge is already locked.
+ *
+ * \return Nothing
+ */
+static void bridge_dissolve_check(struct ast_bridge_channel *bridge_channel)
+{
+ struct ast_bridge *bridge = bridge_channel->bridge;
+
+ if (bridge->dissolved) {
+ return;
+ }
+
+ if (!bridge->num_channels
+ && ast_test_flag(&bridge->feature_flags, AST_BRIDGE_FLAG_DISSOLVE_EMPTY)) {
+ /* Last channel leaving the bridge turns off the lights. */
+ bridge_dissolve(bridge);
+ return;
+ }
+
+ switch (bridge_channel->state) {
+ case AST_BRIDGE_CHANNEL_STATE_END:
+ /* Do we need to dissolve the bridge because this channel hung up? */
+ if (ast_test_flag(&bridge->feature_flags, AST_BRIDGE_FLAG_DISSOLVE_HANGUP)
+ || (bridge_channel->features
+ && bridge_channel->features->usable
+ && ast_test_flag(&bridge_channel->features->feature_flags,
+ AST_BRIDGE_FLAG_DISSOLVE_HANGUP))) {
+ bridge_dissolve(bridge);
+ return;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ * \internal
* \brief Pull the bridge channel out of its current bridge.
* \since 12.0.0
*
@@ -420,6 +496,8 @@
AST_LIST_REMOVE(&bridge->channels, bridge_channel, entry);
bridge->v_table->pull(bridge, bridge_channel);
+ bridge_dissolve_check(bridge_channel);
+
bridge->reconfigured = 1;
}
@@ -492,53 +570,6 @@
}
bridge->reconfigured = 1;
-}
-
-/*!
- * \internal
- * \brief Force out all channels that are not already going out of the bridge.
- * \since 12.0.0
- *
- * \param bridge Bridge to eject all channels
- *
- * \note On entry, bridge is already locked.
- *
- * \return Nothing
- */
-static void bridge_force_out_all(struct ast_bridge *bridge)
-{
- struct ast_bridge_channel *bridge_channel;
-
- bridge->dissolved = 1;
-
-/* BUGBUG need a cause code on the bridge for the later ejected channels. */
- AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
- ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_HANGUP);
- }
-}
-
-/*!
- * \internal
- * \brief Check if a bridge should dissolve and then do it.
- * \since 12.0.0
- *
- * \param bridge_channel Channel causing the check.
- *
- * \note On entry, bridge_channel->bridge is already locked.
- *
- * \return Nothing
- */
-static void bridge_check_dissolve(struct ast_bridge_channel *bridge_channel)
-{
- if (!ast_test_flag(&bridge_channel->bridge->feature_flags, AST_BRIDGE_FLAG_DISSOLVE_HANGUP)
- && (!bridge_channel->features
- || !bridge_channel->features->usable
- || !ast_test_flag(&bridge_channel->features->feature_flags, AST_BRIDGE_FLAG_DISSOLVE_HANGUP))) {
- return;
- }
-
- ast_debug(1, "Bridge %s: dissolving bridge\n", bridge_channel->bridge->uniqueid);
- bridge_force_out_all(bridge_channel->bridge);
}
/*! \brief Internal function to handle DTMF from a channel */
@@ -929,6 +960,7 @@
if (!v_table
|| !v_table->name
|| !v_table->destroy
+ || !v_table->dissolving
|| !v_table->can_push
|| !v_table->push
|| !v_table->pull
@@ -1007,6 +1039,21 @@
/*!
* \internal
+ * \brief The bridge is being dissolved.
+ * \since 12.0.0
+ *
+ * \param self Bridge to operate upon.
+ *
+ * \return Nothing
+ */
+static void bridge_base_dissolving(struct ast_bridge *self)
+{
+/* BUGBUG unlink from the global bridges container. */
+ /*! \todo BUGBUG bridge_base_dissolving() not written */
+}
+
+/*!
+ * \internal
* \brief ast_bridge base can_push method.
* \since 12.0.0
*
@@ -1081,6 +1128,7 @@
struct ast_bridge_methods ast_bridge_base_v_table = {
.name = "base",
.destroy = bridge_base_destroy,
+ .dissolving = bridge_base_dissolving,
.can_push = bridge_base_can_push,
.push = bridge_base_push,
.pull = bridge_base_pull,
@@ -1113,7 +1161,7 @@
{
ast_debug(1, "Bridge %s: telling all channels to leave the party\n", bridge->uniqueid);
ast_bridge_lock(bridge);
- bridge_force_out_all(bridge);
+ bridge_dissolve(bridge);
ast_bridge_unlock(bridge);
ao2_ref(bridge, -1);
@@ -1388,8 +1436,8 @@
bridge->reconfigured = 0;
if (ast_test_flag(&bridge->feature_flags, AST_BRIDGE_FLAG_SMART)
&& smart_bridge_operation(bridge)) {
- /* Smart bridge failed. Dissolve the bridge. */
- bridge_force_out_all(bridge);
+ /* Smart bridge failed. */
+ bridge_dissolve(bridge);
return;
}
bridge_complete_join(bridge);
@@ -1975,15 +2023,6 @@
ast_bridge_channel_pull(bridge_channel);
ast_bridge_reconfigured(bridge_channel->bridge);
- /* See if we need to dissolve the bridge itself if they hung up */
- switch (bridge_channel->state) {
- case AST_BRIDGE_CHANNEL_STATE_END:
- bridge_check_dissolve(bridge_channel);
- break;
- default:
- break;
- }
-
ast_bridge_unlock(bridge_channel->bridge);
/* Flush any unhandled wr_queue frames. */
Modified: team/rmudgett/bridge_phase/main/features.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_phase/main/features.c?view=diff&rev=384483&r1=384482&r2=384483
==============================================================================
--- team/rmudgett/bridge_phase/main/features.c (original)
+++ team/rmudgett/bridge_phase/main/features.c Mon Apr 1 12:56:47 2013
@@ -4542,7 +4542,7 @@
/* BUGBUG need to create the basic bridge class that will manage the DTMF feature hooks. */
bridge = ast_bridge_base_new(
AST_BRIDGE_CAPABILITY_NATIVE | AST_BRIDGE_CAPABILITY_1TO1MIX | AST_BRIDGE_CAPABILITY_MULTIMIX,
- AST_BRIDGE_FLAG_DISSOLVE_HANGUP | AST_BRIDGE_FLAG_SMART);
+ AST_BRIDGE_FLAG_DISSOLVE_HANGUP | AST_BRIDGE_FLAG_DISSOLVE_EMPTY | AST_BRIDGE_FLAG_SMART);
if (!bridge) {
ast_bridge_features_destroy(peer_features);
ast_bridge_features_cleanup(&chan_features);
More information about the asterisk-commits
mailing list