]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
make local_stream more solid
authorAnthony Minessale <anthony.minessale@gmail.com>
Wed, 28 May 2008 15:14:18 +0000 (15:14 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Wed, 28 May 2008 15:14:18 +0000 (15:14 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@8706 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/mod/formats/mod_local_stream/mod_local_stream.c
src/switch_core_file.c
src/switch_ivr_play_say.c

index f0b0a5a10020dc4db9f8b85b360a05bb98a918c1..d7dc1b1fcb05d98a863ff09cb0f2bc4e8baac9e3 100644 (file)
@@ -75,6 +75,8 @@ struct local_stream_source {
        switch_mutex_t *mutex;
        switch_memory_pool_t *pool;
        int shuffle;
+       switch_thread_rwlock_t *rwlock;
+       int ready;
 };
 
 typedef struct local_stream_source local_stream_source_t;
@@ -115,11 +117,18 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
                skip = do_rand();
        }
 
-       switch_core_hash_insert(globals.source_hash, source->name, source);
+       switch_thread_rwlock_create(&source->rwlock, source->pool);
+       
+       if (RUNNING) {
+               switch_mutex_lock(globals.mutex);
+               switch_core_hash_insert(globals.source_hash, source->name, source);
+               switch_mutex_unlock(globals.mutex);
+               source->ready = 1;
+       }
 
        while (RUNNING) {
                const char *fname;
-
+               
                if (switch_dir_open(&source->dir_handle, source->location, source->pool) != SWITCH_STATUS_SUCCESS) {
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Can't open directory: %s\n", source->location);
                        goto done;
@@ -231,8 +240,14 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
        }
 
   done:
+       source->ready = 0;
+       switch_mutex_lock(globals.mutex);
        switch_core_hash_delete(globals.source_hash, source->name);
+       switch_mutex_unlock(globals.mutex);
 
+       switch_thread_rwlock_wrlock(source->rwlock);
+       switch_thread_rwlock_unlock(source->rwlock);
+       
        switch_buffer_destroy(&audio_buffer);
 
        if (fd > -1) {
@@ -264,6 +279,11 @@ static switch_status_t local_stream_file_open(switch_file_handle_t *handle, cons
        } else {
                source = switch_core_hash_find(globals.source_hash, path);
        }
+       if (source) {
+               if (switch_thread_rwlock_tryrdlock(source->rwlock) != SWITCH_STATUS_SUCCESS) {
+                       source = NULL;
+               }
+       }
        switch_mutex_unlock(globals.mutex);
 
        if (!source) {
@@ -330,7 +350,8 @@ static switch_status_t local_stream_file_close(switch_file_handle_t *handle)
        context->source->total--;
        switch_mutex_unlock(context->source->mutex);
        switch_buffer_destroy(&context->audio_buffer);
-
+       switch_thread_rwlock_unlock(context->source->rwlock);
+       
        return SWITCH_STATUS_SUCCESS;
 }
 
@@ -340,6 +361,11 @@ static switch_status_t local_stream_file_read(switch_file_handle_t *handle, void
        switch_size_t bytes = 0;
        size_t need = *len * 2;
 
+       if (!context->source->ready) {
+               *len = 0;
+               return SWITCH_STATUS_FALSE;
+       }
+
        switch_mutex_lock(context->audio_mutex);
        if ((bytes = switch_buffer_read(context->audio_buffer, data, need))) {
                *len = bytes / 2;
index 95fe12897d3ae26bdde65956392a9eb6f20a8c49..cd01523898001f5c13b09a294a64b619690d81e1 100644 (file)
@@ -133,6 +133,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_read(switch_file_handle_t *fh,
        }
 
        if ((status = fh->file_interface->file_read(fh, data, len)) != SWITCH_STATUS_SUCCESS) {
+               *len = 0;
                goto done;
        }
 
index 341c02d2dfe20a22f1417762053f1f0878105cd6..4656f8b42055e26bc2161d01691894c5d6f63e38 100644 (file)
@@ -1021,7 +1021,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
                        if (!asis) {
                                olen /= 2;
                        }
-                       switch_core_file_read(fh, abuf, &olen);
+                       if (switch_core_file_read(fh, abuf, &olen) != SWITCH_STATUS_SUCCESS) {
+                               break;
+                       }
                        switch_buffer_write(fh->audio_buffer, abuf, asis ? olen : olen * 2);
                        olen = switch_buffer_read(fh->audio_buffer, abuf, framelen);
                        if (!asis) {