diff options
author | Richard Mudgett <rmudgett@digium.com> | 2013-01-25 20:00:21 +0000 |
---|---|---|
committer | Richard Mudgett <rmudgett@digium.com> | 2013-01-25 20:00:21 +0000 |
commit | 97dcd1d9350d66f1d5d9a081c0ab9a074e9ce1c8 (patch) | |
tree | c955b42b1394a1bde0d644bae9eec1ae411cb6be /bridges | |
parent | 7bb540dc8099b000ffef973dca8a0dd701fc47d6 (diff) |
Misc bridge code improvements
* Made multiplexed_bridge_destroy() check if anything to destroy and
cleared bridge_pvt pointer after destruction.
* Made multiplexed_add_or_remove() handling of the chans array simpler.
* Extracted bridge_channel_poke().
* Simplified bridge_array_remove() handling of the bridge->array[]. The
array does not have a NULL sentinel pointer.
* Made ast_bridge_new() not create a temporary bridge just to see if it
can be done. Only need to check if there is an appropriate bridge tech
available.
* Made ast_bridge_new() clean up on allocation failures.
* Made destroy_bridge() free resources in the opposite order of creation.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@380109 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'bridges')
-rw-r--r-- | bridges/bridge_multiplexed.c | 42 |
1 files changed, 29 insertions, 13 deletions
diff --git a/bridges/bridge_multiplexed.c b/bridges/bridge_multiplexed.c index c251e2d26..2f8dd9754 100644 --- a/bridges/bridge_multiplexed.c +++ b/bridges/bridge_multiplexed.c @@ -178,7 +178,12 @@ 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 *multiplexed_thread = bridge->bridge_pvt; + struct multiplexed_thread *multiplexed_thread; + + multiplexed_thread = bridge->bridge_pvt; + if (!multiplexed_thread) { + return -1; + } ao2_lock(multiplexed_threads); @@ -194,6 +199,7 @@ static int multiplexed_bridge_destroy(struct ast_bridge *bridge) ao2_unlock(multiplexed_threads); ao2_ref(multiplexed_thread, -1); + bridge->bridge_pvt = NULL; return 0; } @@ -270,27 +276,37 @@ static void *multiplexed_thread_function(void *data) /*! \brief Helper function which adds or removes a channel and nudges the thread */ static void multiplexed_add_or_remove(struct multiplexed_thread *multiplexed_thread, struct ast_channel *chan, int add) { - int i, removed = 0; + int idx; pthread_t thread = AST_PTHREADT_NULL; ao2_lock(multiplexed_thread); multiplexed_nudge(multiplexed_thread); - for (i = 0; i < MULTIPLEXED_MAX_CHANNELS; i++) { - if (multiplexed_thread->chans[i] == chan) { + for (idx = 0; idx < ARRAY_LEN(multiplexed_thread->chans); ++idx) { + if (multiplexed_thread->chans[idx] == chan) { if (!add) { - multiplexed_thread->chans[i] = NULL; - multiplexed_thread->service_count--; - removed = 1; + memmove(multiplexed_thread->chans + idx, + multiplexed_thread->chans + idx + 1, + sizeof(struct ast_channel *) * (ARRAY_LEN(multiplexed_thread->chans) - (idx + 1))); + multiplexed_thread->chans[ARRAY_LEN(multiplexed_thread->chans) - 1] = NULL; + --multiplexed_thread->service_count; } break; - } else if (!multiplexed_thread->chans[i] && add) { - multiplexed_thread->chans[i] = chan; - multiplexed_thread->service_count++; + } + if (!multiplexed_thread->chans[idx]) { + if (add) { + multiplexed_thread->chans[idx] = chan; + ++multiplexed_thread->service_count; + } break; } } + if (ARRAY_LEN(multiplexed_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), multiplexed_thread); + ast_assert(0); + } if (multiplexed_thread->service_count && multiplexed_thread->thread == AST_PTHREADT_NULL) { ao2_ref(multiplexed_thread, +1); @@ -299,11 +315,11 @@ static void multiplexed_add_or_remove(struct multiplexed_thread *multiplexed_thr ast_log(LOG_WARNING, "Failed to create the bridge thread for multiplexed thread '%p', trying next time\n", multiplexed_thread); } - } else if (!multiplexed_thread->service_count && multiplexed_thread->thread != AST_PTHREADT_NULL) { + } else if (!multiplexed_thread->service_count + && multiplexed_thread->thread != AST_PTHREADT_NULL + && multiplexed_thread->thread != AST_PTHREADT_STOP) { thread = multiplexed_thread->thread; multiplexed_thread->thread = AST_PTHREADT_STOP; - } else if (!add && removed) { - memmove(multiplexed_thread->chans + i, multiplexed_thread->chans + i + 1, sizeof(struct ast_channel *) * (MULTIPLEXED_MAX_CHANNELS - (i + 1))); } ao2_unlock(multiplexed_thread); |