]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
fix race
authorAnthony Minessale <anthm@freeswitch.org>
Wed, 1 Jun 2011 22:40:56 +0000 (17:40 -0500)
committerAnthony Minessale <anthm@freeswitch.org>
Wed, 1 Jun 2011 22:40:56 +0000 (17:40 -0500)
src/mod/endpoints/mod_loopback/mod_loopback.c

index 8fb8384e6b50bbddf4a92ca8e79da4f4c94e59e2..97684b6f10ce01b75e99f22ed08f10ffbaac74ac 100644 (file)
@@ -54,7 +54,8 @@ typedef enum {
        TFLAG_BLEG = (1 << 6),
        TFLAG_APP = (1 << 7),
        TFLAG_RUNNING_APP = (1 << 8),
-       TFLAG_BOWOUT_USED = (1 << 9)
+       TFLAG_BOWOUT_USED = (1 << 9),
+       TFLAG_CLEAR = (1 << 10)
 } TFLAGS;
 
 struct private_object {
@@ -105,6 +106,17 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
 static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id);
 static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig);
 
+
+static void clear_queue(private_t *tech_pvt)
+{
+       void *pop;
+
+       while (switch_queue_trypop(tech_pvt->frame_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) {
+               switch_frame_t *frame = (switch_frame_t *) pop;
+               switch_frame_free(&frame);
+       }
+}
+
 static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *session, switch_codec_t *codec)
 {
        const char *iananame = "L16";
@@ -566,6 +578,12 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
        mutex = tech_pvt->mutex;
        switch_mutex_lock(mutex);
 
+
+       if (switch_test_flag(tech_pvt, TFLAG_CLEAR)) {
+               clear_queue(tech_pvt);
+               switch_clear_flag(tech_pvt, TFLAG_CLEAR);
+       }
+
        if (switch_queue_trypop(tech_pvt->frame_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) {
                if (tech_pvt->write_frame) {
                        switch_frame_free(&tech_pvt->write_frame);
@@ -599,17 +617,6 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
        return status;
 }
 
-static void clear_queue(private_t *tech_pvt)
-{
-       void *pop;
-
-       while (switch_queue_trypop(tech_pvt->frame_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) {
-               switch_frame_t *frame = (switch_frame_t *) pop;
-               switch_frame_free(&frame);
-       }
-}
-
-
 static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
 {
        switch_channel_t *channel = NULL;
@@ -750,9 +757,9 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s
                {
 
                        done = 1;
+                       switch_set_flag(tech_pvt, TFLAG_CLEAR);
+                       switch_set_flag(tech_pvt->other_tech_pvt, TFLAG_CLEAR);
 
-                       clear_queue(tech_pvt);
-                       clear_queue(tech_pvt->other_tech_pvt);
                        switch_core_timer_sync(&tech_pvt->timer);
                        switch_core_timer_sync(&tech_pvt->other_tech_pvt->timer);
                }