Modified: freeswitch/trunk/src/include/switch_core.h (15586 => 15587)
--- freeswitch/trunk/src/include/switch_core.h 2009-11-21 00:04:27 UTC (rev 15586)
+++ freeswitch/trunk/src/include/switch_core.h 2009-11-21 01:00:58 UTC (rev 15587)
@@ -217,6 +217,7 @@
\return SWITCH_STATUS_SUCCESS if the operation was a success
*/
SWITCH_DECLARE(switch_status_t) switch_core_media_bug_remove(_In_ switch_core_session_t *session, _Inout_ switch_media_bug_t **bug);
+SWITCH_DECLARE(uint32_t) switch_core_media_bug_prune(switch_core_session_t *session);
/*!
\brief Remove media bug callback
Modified: freeswitch/trunk/src/include/switch_types.h (15586 => 15587)
--- freeswitch/trunk/src/include/switch_types.h 2009-11-21 00:04:27 UTC (rev 15586)
+++ freeswitch/trunk/src/include/switch_types.h 2009-11-21 01:00:58 UTC (rev 15587)
@@ -1141,7 +1141,8 @@
SMBF_READ_PING = (1 << 4),
SMBF_STEREO = (1 << 5),
SMBF_ANSWER_REQ = (1 << 6),
- SMBF_THREAD_LOCK = (1 << 7)
+ SMBF_THREAD_LOCK = (1 << 7),
+ SMBF_PRUNE = (1 << 8)
} switch_media_bug_flag_enum_t;
typedef uint32_t switch_media_bug_flag_t;
Modified: freeswitch/trunk/src/switch_core_io.c (15586 => 15587)
--- freeswitch/trunk/src/switch_core_io.c 2009-11-21 00:04:27 UTC (rev 15586)
+++ freeswitch/trunk/src/switch_core_io.c 2009-11-21 01:00:58 UTC (rev 15587)
@@ -330,13 +330,19 @@
}
if (session->bugs && !switch_channel_test_flag(session->channel, CF_PAUSE_BUGS)) {
- switch_media_bug_t *bp, *dp, *last = NULL;
+ switch_media_bug_t *bp;
switch_bool_t ok = SWITCH_TRUE;
switch_thread_rwlock_rdlock(session->bug_rwlock);
+ int prune = 0;
+
for (bp = session->bugs; bp; bp = bp->next) {
if (!switch_channel_test_flag(session->channel, CF_ANSWERED) && switch_core_media_bug_test_flag(bp, SMBF_ANSWER_REQ)) {
continue;
}
+ if (switch_test_flag(bp, SMBF_PRUNE)) {
+ prune++;
+ continue;
+ }
if (bp->ready && switch_test_flag(bp, SMBF_READ_STREAM)) {
switch_mutex_lock(bp->read_mutex);
@@ -358,28 +364,17 @@
}
}
- if (bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL)) {
- ok = SWITCH_FALSE;
+ if ((bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL)) || ok == SWITCH_FALSE) {
+ switch_set_flag(bp, SMBF_PRUNE);
+ prune++;
}
-
- if (ok == SWITCH_FALSE) {
- bp->ready = 0;
- if (last) {
- last->next = bp->next;
- } else {
- session->bugs = bp->next;
- }
- dp = bp;
- bp = last;
- switch_core_media_bug_close(&dp);
- if (!bp) {
- break;
- }
- continue;
- }
- last = bp;
+
+
}
switch_thread_rwlock_unlock(session->bug_rwlock);
+ if (prune) {
+ switch_core_media_bug_prune(session);
+ }
}
if (do_bugs) {
@@ -496,14 +491,20 @@
switch_set_flag((*frame), SFF_CNG);
}
if (session->bugs && !switch_channel_test_flag(session->channel, CF_PAUSE_BUGS)) {
- switch_media_bug_t *bp, *dp, *last = NULL;
+ switch_media_bug_t *bp;
switch_bool_t ok = SWITCH_TRUE;
+ int prune = 0;
switch_thread_rwlock_rdlock(session->bug_rwlock);
for (bp = session->bugs; bp; bp = bp->next) {
if (!switch_channel_test_flag(session->channel, CF_ANSWERED) && switch_core_media_bug_test_flag(bp, SMBF_ANSWER_REQ)) {
continue;
}
+ if (switch_test_flag(bp, SMBF_PRUNE)) {
+ prune++;
+ continue;
+ }
+
if (bp->ready && switch_test_flag(bp, SMBF_READ_PING)) {
switch_mutex_lock(bp->read_mutex);
if (bp->callback) {
@@ -516,23 +517,14 @@
}
if (ok == SWITCH_FALSE) {
- bp->ready = 0;
- if (last) {
- last->next = bp->next;
- } else {
- session->bugs = bp->next;
- }
- dp = bp;
- bp = last;
- switch_core_media_bug_close(&dp);
- if (!bp) {
- break;
- }
- continue;
+ switch_set_flag(bp, SMBF_PRUNE);
+ prune++;
}
- last = bp;
}
switch_thread_rwlock_unlock(session->bug_rwlock);
+ if (prune) {
+ switch_core_media_bug_prune(session);
+ }
}
}
@@ -760,8 +752,9 @@
if (session->bugs && !switch_channel_test_flag(session->channel, CF_PAUSE_BUGS)) {
- switch_media_bug_t *bp, *dp, *last = NULL;
-
+ switch_media_bug_t *bp;
+ int prune = 0;
+
switch_thread_rwlock_rdlock(session->bug_rwlock);
for (bp = session->bugs; bp; bp = bp->next) {
switch_bool_t ok = SWITCH_TRUE;
@@ -773,6 +766,11 @@
continue;
}
+ if (switch_test_flag(bp, SMBF_PRUNE)) {
+ prune++;
+ continue;
+ }
+
if (switch_test_flag(bp, SMBF_WRITE_STREAM)) {
switch_mutex_lock(bp->write_mutex);
@@ -800,23 +798,14 @@
if (ok == SWITCH_FALSE) {
- bp->ready = 0;
- if (last) {
- last->next = bp->next;
- } else {
- session->bugs = bp->next;
- }
- dp = bp;
- bp = last;
- switch_core_media_bug_close(&dp);
- if (!bp) {
- break;
- }
- continue;
+ switch_set_flag(bp, SMBF_PRUNE);
+ prune++;
}
- last = bp;
}
switch_thread_rwlock_unlock(session->bug_rwlock);
+ if (prune) {
+ switch_core_media_bug_prune(session);
+ }
}
if (do_bugs) {
Modified: freeswitch/trunk/src/switch_core_media_bug.c (15586 => 15587)
--- freeswitch/trunk/src/switch_core_media_bug.c 2009-11-21 00:04:27 UTC (rev 15586)
+++ freeswitch/trunk/src/switch_core_media_bug.c 2009-11-21 01:00:58 UTC (rev 15587)
@@ -437,6 +437,46 @@
}
+SWITCH_DECLARE(uint32_t) switch_core_media_bug_prune(switch_core_session_t *session)
+{
+ switch_media_bug_t *bp = NULL, *last = NULL;
+ switch_status_t status = SWITCH_STATUS_FALSE;
+ int ttl = 0;
+
+
+ top:
+
+ if (session->bugs) {
+ switch_thread_rwlock_wrlock(session->bug_rwlock);
+ for (bp = session->bugs; bp; bp = bp->next) {
+ if (switch_core_media_bug_test_flag(bp, SMBF_PRUNE)) {
+ if (last) {
+ last->next = bp->next;
+ } else {
+ session->bugs = bp->next;
+ }
+ break;
+ }
+
+ last = bp;
+ }
+ switch_thread_rwlock_unlock(session->bug_rwlock);
+ if (bp) {
+ status = switch_core_media_bug_close(&bp);
+ ttl++;
+ goto top;
+ }
+ }
+
+ if (!session->bugs && switch_core_codec_ready(&session->bug_codec)) {
+ switch_core_codec_destroy(&session->bug_codec);
+ memset(&session->bug_codec, 0, sizeof(session->bug_codec));
+ }
+
+ return ttl;
+}
+
+
SWITCH_DECLARE(switch_status_t) switch_core_media_bug_remove_callback(switch_core_session_t *session, switch_media_bug_callback_t callback)
{
switch_media_bug_t *cur = NULL, *bp = NULL, *last = NULL;