Author: bebuild
Date: Thu Nov 20 11:01:04 2014
New Revision: 428441

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=428441
Log:
Merge r428300 for AST-2014-014

Modified:
    certified/tags/11.6-cert8/   (props changed)
    certified/tags/11.6-cert8/ChangeLog
    certified/tags/11.6-cert8/main/bridging.c

Propchange: certified/tags/11.6-cert8/
------------------------------------------------------------------------------
Binary property 'branch-11-merged' - no diff available.

Propchange: certified/tags/11.6-cert8/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Nov 20 11:01:04 2014
@@ -1,3 +1,3 @@
 /branches/11:399513,401167,401179,401182,415825
 /certified/branches/1.8.15:382389
-/certified/branches/11.6:423426,426053,428397,428432
+/certified/branches/11.6:423426,426053,428300,428397,428432

Modified: certified/tags/11.6-cert8/ChangeLog
URL: 
http://svnview.digium.com/svn/asterisk/certified/tags/11.6-cert8/ChangeLog?view=diff&rev=428441&r1=428440&r2=428441
==============================================================================
--- certified/tags/11.6-cert8/ChangeLog (original)
+++ certified/tags/11.6-cert8/ChangeLog Thu Nov 20 11:01:04 2014
@@ -10,6 +10,22 @@
 
          ASTERISK-24469 #close
          Reported by Matt Jordan
+
+       * AST-2014-014: Fix race condition where channels may get stuck in
+         ConfBridge under load.
+
+         Under load it was possible for the bridging API, and thus ConfBridge,
+         to get channels that may have hung up stuck in it. This is because
+         handling of state transitions for a bridged channel within a bridge
+         was not protected and simply set the new state without regard to the
+         existing state. If the existing state had been hung up this would get
+         overwritten.
+
+         This change adds locking to protect changing of the state and also
+         takes into consideration the existing state.
+
+         ASTERISK-24440 #close
+         Reported by: Ben Klang
 
        * AST-2014-018 - func_db: DB Dialplan function permission escalation
          via AMI.

Modified: certified/tags/11.6-cert8/main/bridging.c
URL: 
http://svnview.digium.com/svn/asterisk/certified/tags/11.6-cert8/main/bridging.c?view=diff&rev=428441&r1=428440&r2=428441
==============================================================================
--- certified/tags/11.6-cert8/main/bridging.c (original)
+++ certified/tags/11.6-cert8/main/bridging.c Thu Nov 20 11:01:04 2014
@@ -120,8 +120,22 @@
 
 void ast_bridge_change_state(struct ast_bridge_channel *bridge_channel, enum 
ast_bridge_channel_state new_state)
 {
-       /* Change the state on the bridge channel */
-       bridge_channel->state = new_state;
+       /* Change the state on the bridge channel with some manner of 
intelligence. */
+       ao2_lock(bridge_channel);
+       switch (bridge_channel->state) {
+       case AST_BRIDGE_CHANNEL_STATE_DEPART:
+               break;
+       case AST_BRIDGE_CHANNEL_STATE_END:
+       case AST_BRIDGE_CHANNEL_STATE_HANGUP:
+               if (new_state != AST_BRIDGE_CHANNEL_STATE_DEPART) {
+                       break;
+               }
+               /* Fall through */
+       default:
+               bridge_channel->state = new_state;
+               break;
+       }
+       ao2_unlock(bridge_channel);
 
        /* Only poke the channel's thread if it is not us */
        if (!pthread_equal(pthread_self(), bridge_channel->thread)) {
@@ -130,8 +144,6 @@
                ast_cond_signal(&bridge_channel->cond);
                ao2_unlock(bridge_channel);
        }
-
-       return;
 }
 
 /*! \brief Helper function to poke the bridge thread */
@@ -1147,8 +1159,12 @@
        state = bridge_channel_join(bridge_channel);
 
        /* If no other thread is going to take the channel then hang it up, or 
else we would have to service it until something else came along */
-       if (bridge_channel->allow_impart_hangup && (state == 
AST_BRIDGE_CHANNEL_STATE_END || state == AST_BRIDGE_CHANNEL_STATE_HANGUP)) {
+       if (bridge_channel->allow_impart_hangup
+               && state != AST_BRIDGE_CHANNEL_STATE_DEPART) {
                ast_hangup(bridge_channel->chan);
+
+               /* nobody is waiting to join me. */
+               pthread_detach(pthread_self());
        }
 
        /* cleanup */


-- 
_____________________________________________________________________
-- Bandwidth and Colocation Provided by http://www.api-digital.com --

svn-commits mailing list
To UNSUBSCRIBE or update options visit:
   http://lists.digium.com/mailman/listinfo/svn-commits

Reply via email to