]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
leak protection, better than mighty putty
authorAnthony Minessale <anthony.minessale@gmail.com>
Tue, 8 Jan 2008 18:35:51 +0000 (18:35 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Tue, 8 Jan 2008 18:35:51 +0000 (18:35 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@7141 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/include/switch_core.h
src/include/switch_module_interfaces.h
src/mod/applications/mod_conference/mod_conference.c
src/mod/formats/mod_local_stream/mod_local_stream.c
src/switch_core_file.c

index 50125b558ca4f4c502c2605b4669f988aa98e23c..226b3409a26eb8fbeb0021f0273e05fb65c8d5ab 100644 (file)
@@ -1135,12 +1135,16 @@ SWITCH_DECLARE(void) switch_core_db_test_reactive(switch_core_db_t *db, char *te
   \return SWITCH_STATUS_SUCCESS if the file is opened
   \note the loadable module used is chosen based on the file extension
 */
-SWITCH_DECLARE(switch_status_t) switch_core_file_open(_In_ switch_file_handle_t *fh,
-                                                                                                         _In_z_ const char *file_path,
-                                                                                                         _In_ uint8_t channels,
-                                                                                                         _In_ uint32_t rate,
-                                                                                                         _In_ unsigned int flags,
-                                                                                                         _In_opt_ switch_memory_pool_t *pool);
+SWITCH_DECLARE(switch_status_t) switch_core_perform_file_open(const char *file, const char *func, int line,
+                                                                                                                         _In_ switch_file_handle_t *fh,
+                                                                                                                         _In_z_ const char *file_path,
+                                                                                                                         _In_ uint8_t channels,
+                                                                                                                         _In_ uint32_t rate,
+                                                                                                                         _In_ unsigned int flags,
+                                                                                                                         _In_opt_ switch_memory_pool_t *pool);
+#define switch_core_file_open(_fh, _file_path, _channels, _rate, _flags, _pool) \
+       switch_core_perform_file_open(__FILE__, __SWITCH_FUNC__, __LINE__, _fh, _file_path, _channels, _rate, _flags, _pool)
+
 /*! 
   \brief Read media from a file handle
   \param fh the file handle to read from (must be initilized by you memset all 0 for read, fill in channels and rate for write)
index cc9e5cdf2937914f3b457db458a043c568e3515e..62bb76766d3bcd6bdbec08069e5a38df06f27d84 100644 (file)
@@ -301,6 +301,9 @@ struct switch_file_handle {
        switch_buffer_t *buffer;
        switch_byte_t *dbuf;
        switch_size_t dbuflen;
+       const char *file;
+       const char *func;
+       int line;
 };
 
 /*! \brief Abstract interface to an asr module */
index 6a9e0341b67e5a7e907a56a53042e7281995ec14..976803aae0be1052e208cf77d8f6be4158d65cb3 100644 (file)
@@ -979,64 +979,63 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t * thread,
                switch_event_fire(&event);
        }
 
-       switch_core_timer_destroy(&timer);
-
-       if (switch_test_flag(conference, CFLAG_DESTRUCT)) {
-
-               switch_mutex_lock(conference->mutex);
-               conference_stop_file(conference, FILE_STOP_ASYNC);
-               conference_stop_file(conference, FILE_STOP_ALL);
-               /* Close Unused Handles */
-               if (conference->fnode) {
-                       conference_file_node_t *fnode, *cur;
-                       switch_memory_pool_t *pool;
+       
 
-                       fnode = conference->fnode;
-                       while (fnode) {
-                               cur = fnode;
-                               fnode = fnode->next;
+       switch_mutex_lock(conference->mutex);
+       conference_stop_file(conference, FILE_STOP_ASYNC);
+       conference_stop_file(conference, FILE_STOP_ALL);
+       /* Close Unused Handles */
+       if (conference->fnode) {
+               conference_file_node_t *fnode, *cur;
+               switch_memory_pool_t *pool;
 
-                               if (cur->type != NODE_TYPE_SPEECH) {
-                                       switch_core_file_close(&cur->fh);
-                               }
+               fnode = conference->fnode;
+               while (fnode) {
+                       cur = fnode;
+                       fnode = fnode->next;
 
-                               pool = cur->pool;
-                               switch_core_destroy_memory_pool(&pool);
+                       if (cur->type != NODE_TYPE_SPEECH) {
+                               switch_core_file_close(&cur->fh);
                        }
-                       conference->fnode = NULL;
-               }
 
-               if (conference->async_fnode) {
-                       switch_memory_pool_t *pool;
-            switch_core_file_close(&conference->async_fnode->fh);
-            pool = conference->async_fnode->pool;
-            conference->async_fnode = NULL;
-            switch_core_destroy_memory_pool(&pool);
+                       pool = cur->pool;
+                       switch_core_destroy_memory_pool(&pool);
                }
+               conference->fnode = NULL;
+       }
 
-               switch_mutex_lock(conference->member_mutex);
-               for (imember = conference->members; imember; imember = imember->next) {
-                       switch_channel_t *channel;
+       if (conference->async_fnode) {
+               switch_memory_pool_t *pool;
+               switch_core_file_close(&conference->async_fnode->fh);
+               pool = conference->async_fnode->pool;
+               conference->async_fnode = NULL;
+               switch_core_destroy_memory_pool(&pool);
+       }
+
+       switch_mutex_lock(conference->member_mutex);
+       for (imember = conference->members; imember; imember = imember->next) {
+               switch_channel_t *channel;
 
-                       if (!switch_test_flag(imember, MFLAG_NOCHANNEL)) {
-                               channel = switch_core_session_get_channel(imember->session);
+               if (!switch_test_flag(imember, MFLAG_NOCHANNEL)) {
+                       channel = switch_core_session_get_channel(imember->session);
 
-                               /* add this little bit to preserve the bridge cause code in case of an early media call that */
-                               /* never answers */
-                               if (switch_test_flag(conference, CFLAG_ANSWERED)) {
-                                       switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
-                               } else {
-                                       /* put actual cause code from outbound channel hangup here */
-                                       switch_channel_hangup(channel, conference->bridge_hangup_cause);
-                               }
+                       /* add this little bit to preserve the bridge cause code in case of an early media call that */
+                       /* never answers */
+                       if (switch_test_flag(conference, CFLAG_ANSWERED)) {
+                               switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
+                       } else {
+                               /* put actual cause code from outbound channel hangup here */
+                               switch_channel_hangup(channel, conference->bridge_hangup_cause);
                        }
-
-                       switch_clear_flag_locked(imember, MFLAG_RUNNING);
                }
-               switch_mutex_unlock(conference->member_mutex);
 
-               switch_mutex_unlock(conference->mutex);
+               switch_clear_flag_locked(imember, MFLAG_RUNNING);
+       }
+       switch_mutex_unlock(conference->member_mutex);
+       switch_mutex_unlock(conference->mutex);
 
+       if (switch_test_flag(conference, CFLAG_DESTRUCT)) {
+               switch_core_timer_destroy(&timer);
                switch_mutex_lock(globals.hash_mutex);
                switch_core_hash_delete(globals.conference_hash, conference->name);
                switch_mutex_unlock(globals.hash_mutex);
index ce5c33c981b2275a0d830f694a9747f1f7df77d8..9275d9cb7ab58c38841e422c6888aa033de2380c 100644 (file)
@@ -51,6 +51,9 @@ struct local_stream_context {
        switch_mutex_t *audio_mutex;
        switch_buffer_t *audio_buffer;
        int err;        
+       const char *file;
+       const char *func;
+       int line;
        struct local_stream_context *next;
 };
 typedef struct local_stream_context local_stream_context_t;
@@ -191,14 +194,20 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
 
                                switch_buffer_write(audio_buffer, abuf, olen * 2);
                                used = switch_buffer_inuse(audio_buffer);
-
+                               
                                if (used >= source->prebuf || (source->total && used > source->samples * 2)) {
                                        used = switch_buffer_read(audio_buffer, dist_buf, source->samples * 2);
                                        if (source->total) {
+                                               
                                                switch_mutex_lock(source->mutex);
                                                for (cp = source->context_list; cp; cp = cp->next) {
                                                        switch_mutex_lock(cp->audio_mutex);
-                                                       switch_buffer_write(cp->audio_buffer, dist_buf, used);
+                                                       if (switch_buffer_inuse(cp->audio_buffer) > source->samples * 128) {
+                                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Leaking stream handle! [%s() %s:%d]\n", cp->func, cp->file, cp->line);
+                                                               switch_buffer_zero(cp->audio_buffer);
+                                                       } else {
+                                                               switch_buffer_write(cp->audio_buffer, dist_buf, used);
+                                                       }
                                                        switch_mutex_unlock(cp->audio_mutex);
                                                }
                                                switch_mutex_unlock(source->mutex);
@@ -277,6 +286,9 @@ static switch_status_t local_stream_file_open(switch_file_handle_t *handle, cons
        }
        
        context->source = source;
+       context->file = handle->file;
+       context->func = handle->func;
+       context->line = handle->line;
 
        switch_mutex_lock(source->mutex);
        context->next = source->context_list;
index 0b1c5d74b1ab1d4166b0f0ca0dfd429482ba5d14..2d053284494f7d011797ee465d4532b87cb77aac 100644 (file)
 #include <switch.h>
 #include "private/switch_core_pvt.h"
 
-SWITCH_DECLARE(switch_status_t) switch_core_file_open(switch_file_handle_t *fh,
-                                                                                                         const char *file_path, uint8_t channels, uint32_t rate, unsigned int flags, switch_memory_pool_t *pool)
+SWITCH_DECLARE(switch_status_t) switch_core_perform_file_open(const char *file, const char *func, int line,
+                                                                                                                         switch_file_handle_t *fh,
+                                                                                                                         const char *file_path, 
+                                                                                                                         uint8_t channels, 
+                                                                                                                         uint32_t rate, 
+                                                                                                                         unsigned int flags, 
+                                                                                                                         switch_memory_pool_t *pool)
 {
        char *ext;
        switch_status_t status;
@@ -63,6 +68,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_open(switch_file_handle_t *fh,
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "invalid file format [%s] for [%s]!\n", ext, file_path);
                return SWITCH_STATUS_GENERR;
        }
+       
+       fh->file = file;
+       fh->func = func;
+       fh->line = line;
 
        fh->flags = flags;
        if (pool) {