@ -70,107 +70,107 @@ struct multiplexed_thread {
} ;
/*! \brief Container of all operating multiplexed threads */
static struct ao2_container * mu ltiple xed_threads;
static struct ao2_container * mu xed_threads;
/*! \brief Callback function for finding a free multiplexed thread */
static int find_multiplexed_thread ( void * obj , void * arg , int flags )
{
struct multiplexed_thread * mu ltiple xed_thread = obj ;
return ( mu ltiple xed_thread- > count < = ( MULTIPLEXED_MAX_CHANNELS - 2 ) ) ? CMP_MATCH | CMP_STOP : 0 ;
struct multiplexed_thread * mu xed_thread = obj ;
return ( mu xed_thread- > count < = ( MULTIPLEXED_MAX_CHANNELS - 2 ) ) ? CMP_MATCH | CMP_STOP : 0 ;
}
/*! \brief Destroy callback for a multiplexed thread structure */
static void destroy_multiplexed_thread ( void * obj )
{
struct multiplexed_thread * mu ltiple xed_thread = obj ;
struct multiplexed_thread * mu xed_thread = obj ;
if ( mu ltiple xed_thread- > pipe [ 0 ] > - 1 ) {
close ( mu ltiple xed_thread- > pipe [ 0 ] ) ;
if ( mu xed_thread- > pipe [ 0 ] > - 1 ) {
close ( mu xed_thread- > pipe [ 0 ] ) ;
}
if ( mu ltiple xed_thread- > pipe [ 1 ] > - 1 ) {
close ( mu ltiple xed_thread- > pipe [ 1 ] ) ;
if ( mu xed_thread- > pipe [ 1 ] > - 1 ) {
close ( mu xed_thread- > pipe [ 1 ] ) ;
}
}
/*! \brief Create function which finds/reserves/references a multiplexed thread structure */
static int multiplexed_bridge_create ( struct ast_bridge * bridge )
{
struct multiplexed_thread * mu ltiple xed_thread;
struct multiplexed_thread * mu xed_thread;
ao2_lock ( mu ltiple xed_threads) ;
ao2_lock ( mu xed_threads) ;
/* Try to find an existing thread to handle our additional channels */
mu ltiple xed_thread = ao2_callback ( mu ltiple xed_threads, 0 , find_multiplexed_thread , NULL ) ;
if ( ! mu ltiple xed_thread) {
mu xed_thread = ao2_callback ( mu xed_threads, 0 , find_multiplexed_thread , NULL ) ;
if ( ! mu xed_thread) {
int flags ;
/* If we failed we will have to create a new one from scratch */
mu ltiple xed_thread = ao2_alloc ( sizeof ( * mu ltiple xed_thread) , destroy_multiplexed_thread ) ;
if ( ! mu ltiple xed_thread) {
mu xed_thread = ao2_alloc ( sizeof ( * mu xed_thread) , destroy_multiplexed_thread ) ;
if ( ! mu xed_thread) {
ast_debug ( 1 , " Failed to find or create a new multiplexed thread for bridge '%p' \n " , bridge ) ;
ao2_unlock ( mu ltiple xed_threads) ;
ao2_unlock ( mu xed_threads) ;
return - 1 ;
}
mu ltiple xed_thread- > pipe [ 0 ] = mu ltiple xed_thread- > pipe [ 1 ] = - 1 ;
mu xed_thread- > pipe [ 0 ] = mu xed_thread- > pipe [ 1 ] = - 1 ;
/* Setup a pipe so we can poke the thread itself when needed */
if ( pipe ( mu ltiple xed_thread- > pipe ) ) {
if ( pipe ( mu xed_thread- > pipe ) ) {
ast_debug ( 1 , " Failed to create a pipe for poking a multiplexed thread for bridge '%p' \n " , bridge ) ;
ao2_ref ( mu ltiple xed_thread, - 1 ) ;
ao2_unlock ( mu ltiple xed_threads) ;
ao2_ref ( mu xed_thread, - 1 ) ;
ao2_unlock ( mu xed_threads) ;
return - 1 ;
}
/* Setup each pipe for non-blocking operation */
flags = fcntl ( mu ltiple xed_thread- > pipe [ 0 ] , F_GETFL ) ;
if ( fcntl ( mu ltiple xed_thread- > pipe [ 0 ] , F_SETFL , flags | O_NONBLOCK ) < 0 ) {
flags = fcntl ( mu xed_thread- > pipe [ 0 ] , F_GETFL ) ;
if ( fcntl ( mu xed_thread- > pipe [ 0 ] , F_SETFL , flags | O_NONBLOCK ) < 0 ) {
ast_log ( LOG_WARNING , " Failed to setup first nudge pipe for non-blocking operation on %p (%d: %s) \n " , bridge , errno , strerror ( errno ) ) ;
ao2_ref ( mu ltiple xed_thread, - 1 ) ;
ao2_unlock ( mu ltiple xed_threads) ;
ao2_ref ( mu xed_thread, - 1 ) ;
ao2_unlock ( mu xed_threads) ;
return - 1 ;
}
flags = fcntl ( mu ltiple xed_thread- > pipe [ 1 ] , F_GETFL ) ;
if ( fcntl ( mu ltiple xed_thread- > pipe [ 1 ] , F_SETFL , flags | O_NONBLOCK ) < 0 ) {
flags = fcntl ( mu xed_thread- > pipe [ 1 ] , F_GETFL ) ;
if ( fcntl ( mu xed_thread- > pipe [ 1 ] , F_SETFL , flags | O_NONBLOCK ) < 0 ) {
ast_log ( LOG_WARNING , " Failed to setup second nudge pipe for non-blocking operation on %p (%d: %s) \n " , bridge , errno , strerror ( errno ) ) ;
ao2_ref ( mu ltiple xed_thread, - 1 ) ;
ao2_unlock ( mu ltiple xed_threads) ;
ao2_ref ( mu xed_thread, - 1 ) ;
ao2_unlock ( mu xed_threads) ;
return - 1 ;
}
/* Set up default parameters */
mu ltiple xed_thread- > thread = AST_PTHREADT_NULL ;
mu xed_thread- > thread = AST_PTHREADT_NULL ;
/* Finally link us into the container so others may find us */
ao2_link ( mu ltiple xed_threads, mu ltiple xed_thread) ;
ast_debug ( 1 , " Created multiplexed thread '%p' for bridge '%p' \n " , mu ltiple xed_thread, bridge ) ;
ao2_link ( mu xed_threads, mu xed_thread) ;
ast_debug ( 1 , " Created multiplexed thread '%p' for bridge '%p' \n " , mu xed_thread, bridge ) ;
} else {
ast_debug ( 1 , " Found multiplexed thread '%p' for bridge '%p' \n " , mu ltiple xed_thread, bridge ) ;
ast_debug ( 1 , " Found multiplexed thread '%p' for bridge '%p' \n " , mu xed_thread, bridge ) ;
}
/* Bump the count of the thread structure up by two since the channels for this bridge will be joining shortly */
mu ltiple xed_thread- > count + = 2 ;
mu xed_thread- > count + = 2 ;
ao2_unlock ( mu ltiple xed_threads) ;
ao2_unlock ( mu xed_threads) ;
bridge - > bridge_pvt = mu ltiple xed_thread;
bridge - > bridge_pvt = mu xed_thread;
return 0 ;
}
/*! \brief Internal function which nudges the thread */
static void multiplexed_nudge ( struct multiplexed_thread * mu ltiple xed_thread)
static void multiplexed_nudge ( struct multiplexed_thread * mu xed_thread)
{
int nudge = 0 ;
if ( mu ltiple xed_thread- > thread = = AST_PTHREADT_NULL ) {
if ( mu xed_thread- > thread = = AST_PTHREADT_NULL ) {
return ;
}
if ( write ( mu ltiple xed_thread- > pipe [ 1 ] , & nudge , sizeof ( nudge ) ) ! = sizeof ( nudge ) ) {
ast_log ( LOG_ERROR , " We couldn't poke multiplexed thread '%p'... something is VERY wrong \n " , mu ltiple xed_thread) ;
if ( write ( mu xed_thread- > pipe [ 1 ] , & nudge , sizeof ( nudge ) ) ! = sizeof ( nudge ) ) {
ast_log ( LOG_ERROR , " We couldn't poke multiplexed thread '%p'... something is VERY wrong \n " , mu xed_thread) ;
}
while ( mu ltiple xed_thread- > waiting ) {
while ( mu xed_thread- > waiting ) {
sched_yield ( ) ;
}
}
@ -178,27 +178,27 @@ static void multiplexed_nudge(struct multiplexed_thread *multiplexed_thread)
/*! \brief Destroy function which unreserves/unreferences/removes a multiplexed thread structure */
static int multiplexed_bridge_destroy ( struct ast_bridge * bridge )
{
struct multiplexed_thread * mu ltiple xed_thread;
struct multiplexed_thread * mu xed_thread;
mu ltiple xed_thread = bridge - > bridge_pvt ;
if ( ! mu ltiple xed_thread) {
mu xed_thread = bridge - > bridge_pvt ;
if ( ! mu xed_thread) {
return - 1 ;
}
ao2_lock ( mu ltiple xed_threads) ;
ao2_lock ( mu xed_threads) ;
mu ltiple xed_thread- > count - = 2 ;
mu xed_thread- > count - = 2 ;
if ( ! mu ltiple xed_thread- > count ) {
ast_debug ( 1 , " Unlinking multiplexed thread '%p' since nobody is using it anymore \n " , mu ltiple xed_thread) ;
ao2_unlink ( mu ltiple xed_threads, mu ltiple xed_thread) ;
if ( ! mu xed_thread- > count ) {
ast_debug ( 1 , " Unlinking multiplexed thread '%p' since nobody is using it anymore \n " , mu xed_thread) ;
ao2_unlink ( mu xed_threads, mu xed_thread) ;
}
multiplexed_nudge ( mu ltiple xed_thread) ;
multiplexed_nudge ( mu xed_thread) ;
ao2_unlock ( mu ltiple xed_threads) ;
ao2_unlock ( mu xed_threads) ;
ao2_ref ( mu ltiple xed_thread, - 1 ) ;
ao2_ref ( mu xed_thread, - 1 ) ;
bridge - > bridge_pvt = NULL ;
return 0 ;
@ -207,39 +207,39 @@ static int multiplexed_bridge_destroy(struct ast_bridge *bridge)
/*! \brief Thread function that executes for multiplexed threads */
static void * multiplexed_thread_function ( void * data )
{
struct multiplexed_thread * mu ltiple xed_thread = data ;
int fds = mu ltiple xed_thread- > pipe [ 0 ] ;
struct multiplexed_thread * mu xed_thread = data ;
int fds = mu xed_thread- > pipe [ 0 ] ;
ao2_lock ( mu ltiple xed_thread) ;
ao2_lock ( mu xed_thread) ;
ast_debug ( 1 , " Starting actual thread for multiplexed thread '%p' \n " , mu ltiple xed_thread) ;
ast_debug ( 1 , " Starting actual thread for multiplexed thread '%p' \n " , mu xed_thread) ;
while ( mu ltiple xed_thread- > thread ! = AST_PTHREADT_STOP ) {
while ( mu xed_thread- > thread ! = AST_PTHREADT_STOP ) {
struct ast_channel * winner ;
struct ast_channel * first = mu ltiple xed_thread- > chans [ 0 ] ;
struct ast_channel * first = mu xed_thread- > chans [ 0 ] ;
int to = - 1 ;
int outfd = - 1 ;
/* Move channels around so not just the first one gets priority */
memmove ( mu ltiple xed_thread- > chans , mu ltiple xed_thread- > chans + 1 ,
sizeof ( struct ast_channel * ) * ( mu ltiple xed_thread- > service_count - 1 ) ) ;
mu ltiple xed_thread- > chans [ mu ltiple xed_thread- > service_count - 1 ] = first ;
mu ltiple xed_thread- > waiting = 1 ;
ao2_unlock ( mu ltiple xed_thread) ;
winner = ast_waitfor_nandfds ( mu ltiple xed_thread- > chans , mu ltiple xed_thread- > service_count , & fds , 1 , NULL , & outfd , & to ) ;
mu ltiple xed_thread- > waiting = 0 ;
ao2_lock ( mu ltiple xed_thread) ;
if ( mu ltiple xed_thread- > thread = = AST_PTHREADT_STOP ) {
memmove ( mu xed_thread- > chans , mu xed_thread- > chans + 1 ,
sizeof ( struct ast_channel * ) * ( mu xed_thread- > service_count - 1 ) ) ;
mu xed_thread- > chans [ mu xed_thread- > service_count - 1 ] = first ;
mu xed_thread- > waiting = 1 ;
ao2_unlock ( mu xed_thread) ;
winner = ast_waitfor_nandfds ( mu xed_thread- > chans , mu xed_thread- > service_count , & fds , 1 , NULL , & outfd , & to ) ;
mu xed_thread- > waiting = 0 ;
ao2_lock ( mu xed_thread) ;
if ( mu xed_thread- > thread = = AST_PTHREADT_STOP ) {
break ;
}
if ( outfd > - 1 ) {
int nudge ;
if ( read ( mu ltiple xed_thread- > pipe [ 0 ] , & nudge , sizeof ( nudge ) ) < 0 ) {
if ( read ( mu xed_thread- > pipe [ 0 ] , & nudge , sizeof ( nudge ) ) < 0 ) {
if ( errno ! = EINTR & & errno ! = EAGAIN ) {
ast_log ( LOG_WARNING , " read() failed for pipe on multiplexed thread '%p': %s \n " , mu ltiple xed_thread, strerror ( errno ) ) ;
ast_log ( LOG_WARNING , " read() failed for pipe on multiplexed thread '%p': %s \n " , mu xed_thread, strerror ( errno ) ) ;
}
}
}
@ -247,10 +247,10 @@ static void *multiplexed_thread_function(void *data)
struct ast_bridge * bridge ;
int stop = 0 ;
ao2_unlock ( mu ltiple xed_thread) ;
ao2_unlock ( mu xed_thread) ;
while ( ( bridge = ast_channel_internal_bridge ( winner ) ) & & ao2_trylock ( bridge ) ) {
sched_yield ( ) ;
if ( mu ltiple xed_thread- > thread = = AST_PTHREADT_STOP ) {
if ( mu xed_thread- > thread = = AST_PTHREADT_STOP ) {
stop = 1 ;
break ;
}
@ -259,70 +259,70 @@ static void *multiplexed_thread_function(void *data)
ast_bridge_handle_trip ( bridge , NULL , winner , - 1 ) ;
ao2_unlock ( bridge ) ;
}
ao2_lock ( mu ltiple xed_thread) ;
ao2_lock ( mu xed_thread) ;
}
}
mu ltiple xed_thread- > thread = AST_PTHREADT_NULL ;
mu xed_thread- > thread = AST_PTHREADT_NULL ;
ast_debug ( 1 , " Stopping actual thread for multiplexed thread '%p' \n " , mu ltiple xed_thread) ;
ast_debug ( 1 , " Stopping actual thread for multiplexed thread '%p' \n " , mu xed_thread) ;
ao2_unlock ( mu ltiple xed_thread) ;
ao2_ref ( mu ltiple xed_thread, - 1 ) ;
ao2_unlock ( mu xed_thread) ;
ao2_ref ( mu xed_thread, - 1 ) ;
return NULL ;
}
/*! \brief Helper function which adds or removes a channel and nudges the thread */
static void multiplexed_add_or_remove ( struct multiplexed_thread * mu ltiple xed_thread, struct ast_channel * chan , int add )
static void multiplexed_add_or_remove ( struct multiplexed_thread * mu xed_thread, struct ast_channel * chan , int add )
{
int idx ;
pthread_t thread = AST_PTHREADT_NULL ;
ao2_lock ( mu ltiple xed_thread) ;
ao2_lock ( mu xed_thread) ;
multiplexed_nudge ( mu ltiple xed_thread) ;
multiplexed_nudge ( mu xed_thread) ;
for ( idx = 0 ; idx < ARRAY_LEN ( mu ltiple xed_thread- > chans ) ; + + idx ) {
if ( mu ltiple xed_thread- > chans [ idx ] = = chan ) {
for ( idx = 0 ; idx < ARRAY_LEN ( mu xed_thread- > chans ) ; + + idx ) {
if ( mu xed_thread- > chans [ idx ] = = chan ) {
if ( ! add ) {
memmove ( mu ltiple xed_thread- > chans + idx ,
mu ltiple xed_thread- > chans + idx + 1 ,
sizeof ( struct ast_channel * ) * ( ARRAY_LEN ( mu ltiple xed_thread- > chans ) - ( idx + 1 ) ) ) ;
mu ltiple xed_thread- > chans [ ARRAY_LEN ( mu ltiple xed_thread- > chans ) - 1 ] = NULL ;
- - mu ltiple xed_thread- > service_count ;
memmove ( mu xed_thread- > chans + idx ,
mu xed_thread- > chans + idx + 1 ,
sizeof ( struct ast_channel * ) * ( ARRAY_LEN ( mu xed_thread- > chans ) - ( idx + 1 ) ) ) ;
mu xed_thread- > chans [ ARRAY_LEN ( mu xed_thread- > chans ) - 1 ] = NULL ;
- - mu xed_thread- > service_count ;
}
break ;
}
if ( ! mu ltiple xed_thread- > chans [ idx ] ) {
if ( ! mu xed_thread- > chans [ idx ] ) {
if ( add ) {
mu ltiple xed_thread- > chans [ idx ] = chan ;
+ + mu ltiple xed_thread- > service_count ;
mu xed_thread- > chans [ idx ] = chan ;
+ + mu xed_thread- > service_count ;
}
break ;
}
}
if ( ARRAY_LEN ( mu ltiple xed_thread- > chans ) = = idx & & add ) {
if ( ARRAY_LEN ( mu xed_thread- > chans ) = = idx & & add ) {
ast_log ( LOG_ERROR , " Could not add channel %s to multiplexed thread %p. Array not large enough. \n " ,
ast_channel_name ( chan ) , mu ltiple xed_thread) ;
ast_channel_name ( chan ) , mu xed_thread) ;
ast_assert ( 0 ) ;
}
if ( mu ltiple xed_thread- > service_count & & mu ltiple xed_thread- > thread = = AST_PTHREADT_NULL ) {
ao2_ref ( mu ltiple xed_thread, + 1 ) ;
if ( ast_pthread_create ( & mu ltiple xed_thread- > thread , NULL , multiplexed_thread_function , mu ltiple xed_thread) ) {
ao2_ref ( mu ltiple xed_thread, - 1 ) ;
if ( mu xed_thread- > service_count & & mu xed_thread- > thread = = AST_PTHREADT_NULL ) {
ao2_ref ( mu xed_thread, + 1 ) ;
if ( ast_pthread_create ( & mu xed_thread- > thread , NULL , multiplexed_thread_function , mu xed_thread) ) {
ao2_ref ( mu xed_thread, - 1 ) ;
ast_log ( LOG_WARNING , " Failed to create the bridge thread for multiplexed thread '%p', trying next time \n " ,
mu ltiple xed_thread) ;
mu xed_thread) ;
}
} else if ( ! mu ltiple xed_thread- > service_count
& & mu ltiple xed_thread- > thread ! = AST_PTHREADT_NULL
& & mu ltiple xed_thread- > thread ! = AST_PTHREADT_STOP ) {
thread = mu ltiple xed_thread- > thread ;
mu ltiple xed_thread- > thread = AST_PTHREADT_STOP ;
} else if ( ! mu xed_thread- > service_count
& & mu xed_thread- > thread ! = AST_PTHREADT_NULL
& & mu xed_thread- > thread ! = AST_PTHREADT_STOP ) {
thread = mu xed_thread- > thread ;
mu xed_thread- > thread = AST_PTHREADT_STOP ;
}
ao2_unlock ( mu ltiple xed_thread) ;
ao2_unlock ( mu xed_thread) ;
if ( thread ! = AST_PTHREADT_NULL ) {
pthread_join ( thread , NULL ) ;
@ -334,11 +334,11 @@ static int multiplexed_bridge_join(struct ast_bridge *bridge, struct ast_bridge_
{
struct ast_channel * c0 = AST_LIST_FIRST ( & bridge - > channels ) - > chan ;
struct ast_channel * c1 = AST_LIST_LAST ( & bridge - > channels ) - > chan ;
struct multiplexed_thread * mu ltiple xed_thread = bridge - > bridge_pvt ;
struct multiplexed_thread * mu xed_thread = bridge - > bridge_pvt ;
ast_debug ( 1 , " Adding channel '%s' to multiplexed thread '%p' for monitoring \n " , ast_channel_name ( bridge_channel - > chan ) , mu ltiple xed_thread) ;
ast_debug ( 1 , " Adding channel '%s' to multiplexed thread '%p' for monitoring \n " , ast_channel_name ( bridge_channel - > chan ) , mu xed_thread) ;
multiplexed_add_or_remove ( mu ltiple xed_thread, bridge_channel - > chan , 1 ) ;
multiplexed_add_or_remove ( mu xed_thread, bridge_channel - > chan , 1 ) ;
/* If the second channel has not yet joined do not make things compatible */
if ( c0 = = c1 ) {
@ -357,11 +357,11 @@ static int multiplexed_bridge_join(struct ast_bridge *bridge, struct ast_bridge_
/*! \brief Leave function which actually removes the channel from the array */
static int multiplexed_bridge_leave ( struct ast_bridge * bridge , struct ast_bridge_channel * bridge_channel )
{
struct multiplexed_thread * mu ltiple xed_thread = bridge - > bridge_pvt ;
struct multiplexed_thread * mu xed_thread = bridge - > bridge_pvt ;
ast_debug ( 1 , " Removing channel '%s' from multiplexed thread '%p' \n " , ast_channel_name ( bridge_channel - > chan ) , mu ltiple xed_thread) ;
ast_debug ( 1 , " Removing channel '%s' from multiplexed thread '%p' \n " , ast_channel_name ( bridge_channel - > chan ) , mu xed_thread) ;
multiplexed_add_or_remove ( mu ltiple xed_thread, bridge_channel - > chan , 0 ) ;
multiplexed_add_or_remove ( mu xed_thread, bridge_channel - > chan , 0 ) ;
return 0 ;
}
@ -369,21 +369,21 @@ static int multiplexed_bridge_leave(struct ast_bridge *bridge, struct ast_bridge
/*! \brief Suspend function which means control of the channel is going elsewhere */
static void multiplexed_bridge_suspend ( struct ast_bridge * bridge , struct ast_bridge_channel * bridge_channel )
{
struct multiplexed_thread * mu ltiple xed_thread = bridge - > bridge_pvt ;
struct multiplexed_thread * mu xed_thread = bridge - > bridge_pvt ;
ast_debug ( 1 , " Suspending channel '%s' from multiplexed thread '%p' \n " , ast_channel_name ( bridge_channel - > chan ) , mu ltiple xed_thread) ;
ast_debug ( 1 , " Suspending channel '%s' from multiplexed thread '%p' \n " , ast_channel_name ( bridge_channel - > chan ) , mu xed_thread) ;
multiplexed_add_or_remove ( mu ltiple xed_thread, bridge_channel - > chan , 0 ) ;
multiplexed_add_or_remove ( mu xed_thread, bridge_channel - > chan , 0 ) ;
}
/*! \brief Unsuspend function which means control of the channel is coming back to us */
static void multiplexed_bridge_unsuspend ( struct ast_bridge * bridge , struct ast_bridge_channel * bridge_channel )
{
struct multiplexed_thread * mu ltiple xed_thread = bridge - > bridge_pvt ;
struct multiplexed_thread * mu xed_thread = bridge - > bridge_pvt ;
ast_debug ( 1 , " Unsuspending channel '%s' from multiplexed thread '%p' \n " , ast_channel_name ( bridge_channel - > chan ) , mu ltiple xed_thread) ;
ast_debug ( 1 , " Unsuspending channel '%s' from multiplexed thread '%p' \n " , ast_channel_name ( bridge_channel - > chan ) , mu xed_thread) ;
multiplexed_add_or_remove ( mu ltiple xed_thread, bridge_channel - > chan , 1 ) ;
multiplexed_add_or_remove ( mu xed_thread, bridge_channel - > chan , 1 ) ;
}
/*! \brief Write function for writing frames into the bridge */
@ -426,7 +426,7 @@ static int unload_module(void)
{
int res = ast_bridge_technology_unregister ( & multiplexed_bridge ) ;
ao2_ref ( mu ltiple xed_threads, - 1 ) ;
ao2_ref ( mu xed_threads, - 1 ) ;
multiplexed_bridge . format_capabilities = ast_format_cap_destroy ( multiplexed_bridge . format_capabilities ) ;
return res ;
@ -434,7 +434,7 @@ static int unload_module(void)
static int load_module ( void )
{
if ( ! ( mu ltiple xed_threads = ao2_container_alloc ( MULTIPLEXED_BUCKETS , NULL , NULL ) ) ) {
if ( ! ( mu xed_threads = ao2_container_alloc ( MULTIPLEXED_BUCKETS , NULL , NULL ) ) ) {
return AST_MODULE_LOAD_DECLINE ;
}
if ( ! ( multiplexed_bridge . format_capabilities = ast_format_cap_alloc ( ) ) ) {