]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
mod_freetdm: Fix several leaks on module shutdown
authorMoises Silva <moy@sangoma.com>
Sun, 13 Jul 2014 04:34:04 +0000 (00:34 -0400)
committerMoises Silva <moy@sangoma.com>
Sun, 13 Jul 2014 04:35:48 +0000 (00:35 -0400)
libs/freetdm/mod_freetdm/mod_freetdm.c
libs/freetdm/src/ftdm_io.c
libs/freetdm/src/ftdm_sched.c
libs/freetdm/src/ftmod/ftmod_gsm/ftmod_gsm.c
libs/freetdm/src/include/private/ftdm_sched.h

index cdab6adb87f45503fb273c0b5aae8c077c93dfa9..846f9cb7899d29ca9cbfa39be3b55e295d9e8128 100644 (file)
@@ -5538,6 +5538,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_freetdm_shutdown)
                ftdm_conf_node_destroy(val);
        }
 
+       switch_core_hash_destroy(&globals.ss7_configs);
        ftdm_global_destroy();
 
        // this breaks pika but they are MIA so *shrug*
index 42f348617b003571bf439c7da41e6d20def878cb..58fa9983902ba844a845a3476a6bb515cbb0e009 100644 (file)
@@ -690,14 +690,10 @@ static ftdm_status_t ftdm_span_destroy(ftdm_span_t *span)
        ftdm_status_t status = FTDM_SUCCESS;
        unsigned j;
 
-       ftdm_mutex_lock(span->mutex);
-
-       /* stop the signaling */
+       /* The signaling must be already stopped (this is just a sanity check, should never happen) */
+       ftdm_assert_return(!ftdm_test_flag(span, FTDM_SPAN_STARTED), FTDM_FAIL, "Signaling for span %s has not been stopped, refusing to destroy span\n");
 
-       /* This is a forced stopped */
-       ftdm_clear_flag(span, FTDM_SPAN_NON_STOPPABLE);
-       
-       ftdm_span_stop(span);
+       ftdm_mutex_lock(span->mutex);
 
        /* destroy the channels */
        ftdm_clear_flag(span, FTDM_SPAN_CONFIGURED);
@@ -6040,6 +6036,17 @@ FT_DECLARE(ftdm_status_t) ftdm_group_create(ftdm_group_t **group, const char *na
        return status;
 }
 
+static void ftdm_group_destroy(ftdm_group_t **group)
+{
+       ftdm_group_t *grp = NULL;
+       ftdm_assert(group != NULL, "Group must not be null\n");
+       grp = *group;
+       ftdm_mutex_destroy(&grp->mutex);
+       ftdm_safe_free(grp->name);
+       ftdm_safe_free(grp);
+       *group = NULL;
+}
+
 static ftdm_status_t ftdm_span_trigger_signal(const ftdm_span_t *span, ftdm_sigmsg_t *sigmsg)
 {
        if (!span->signal_cb) {
@@ -6376,10 +6383,37 @@ FT_DECLARE(uint32_t) ftdm_running(void)
        return globals.running;
 }
 
+static void destroy_span(ftdm_span_t *span)
+{
+       if (ftdm_test_flag(span, FTDM_SPAN_CONFIGURED)) {
+               ftdm_span_destroy(span);
+       }
+       hashtable_remove(globals.span_hash, (void *)span->name);
+       ftdm_safe_free(span->dtmf_hangup);
+       ftdm_safe_free(span->type);
+       ftdm_safe_free(span->name);
+       ftdm_safe_free(span);
+}
+
+static void force_stop_span(ftdm_span_t *span)
+{
+       /* This is a forced stop */
+       ftdm_clear_flag(span, FTDM_SPAN_NON_STOPPABLE);
+       ftdm_span_stop(span);
+}
+
+static void span_for_each(void (*func)(ftdm_span_t *span))
+{
+       ftdm_span_t *sp = NULL, *next = NULL;
+       for (sp = globals.spans; sp; sp = next) {
+               next = sp->next;
+               func(sp);
+       }
+}
 
 FT_DECLARE(ftdm_status_t) ftdm_global_destroy(void)
 {
-       ftdm_span_t *sp;
+       ftdm_group_t *grp = NULL, *next_grp = NULL;
 
        time_end();
 
@@ -6397,45 +6431,49 @@ FT_DECLARE(ftdm_status_t) ftdm_global_destroy(void)
 
        ftdm_span_close_all();
        
+       /* Stop and destroy alls pans */
        ftdm_mutex_lock(globals.span_mutex);
-       for (sp = globals.spans; sp;) {
-               ftdm_span_t *cur_span = sp;
-               sp = sp->next;
 
-               if (cur_span) {
-                       if (ftdm_test_flag(cur_span, FTDM_SPAN_CONFIGURED)) {
-                               ftdm_span_destroy(cur_span);
-                       }
-
-                       hashtable_remove(globals.span_hash, (void *)cur_span->name);
-                       ftdm_safe_free(cur_span->dtmf_hangup);
-                       ftdm_safe_free(cur_span->type);
-                       ftdm_safe_free(cur_span->name);
-                       ftdm_safe_free(cur_span);
-                       cur_span = NULL;
-               }
-       }
+       span_for_each(force_stop_span);
+       span_for_each(destroy_span);
        globals.spans = NULL;
+
        ftdm_mutex_unlock(globals.span_mutex);
 
        /* destroy signaling and io modules */
        ftdm_unload_modules();
 
-       ftdm_global_set_logger( NULL );
+       /* Destroy hunting groups */
+       ftdm_mutex_lock(globals.group_mutex);
+       grp = globals.groups;
+       while (grp) {
+               next_grp = grp->next;
+               ftdm_group_destroy(&grp);
+               grp = next_grp;
+       }
+       ftdm_mutex_unlock(globals.group_mutex);
 
        /* finally destroy the globals */
        ftdm_mutex_lock(globals.mutex);
+
        ftdm_sched_destroy(&globals.timingsched);
+
        hashtable_destroy(globals.interface_hash);
        hashtable_destroy(globals.module_hash); 
        hashtable_destroy(globals.span_hash);
        hashtable_destroy(globals.group_hash);
-       ftdm_mutex_unlock(globals.mutex);
-       ftdm_mutex_destroy(&globals.mutex);
+
        ftdm_mutex_destroy(&globals.span_mutex);
        ftdm_mutex_destroy(&globals.group_mutex);
        ftdm_mutex_destroy(&globals.call_id_mutex);
 
+       ftdm_mutex_unlock(globals.mutex);
+
+       ftdm_mutex_destroy(&globals.mutex);
+
+       ftdm_sched_global_destroy();
+
+       ftdm_global_set_logger(NULL);
        memset(&globals, 0, sizeof(globals));
        return FTDM_SUCCESS;
 }
index cc639fa62401a4ce9804f45a795d51df9034887f..324073976ca323f5cd186622d6109aa3fdcca8dd 100644 (file)
@@ -166,6 +166,13 @@ FT_DECLARE(ftdm_status_t) ftdm_sched_global_init()
        return FTDM_FAIL;
 }
 
+FT_DECLARE(ftdm_status_t) ftdm_sched_global_destroy()
+{
+       ftdm_mutex_destroy(&sched_globals.mutex);
+       memset(&sched_globals, 0, sizeof(sched_globals));
+       return FTDM_SUCCESS;
+}
+
 FT_DECLARE(ftdm_status_t) ftdm_sched_free_run(ftdm_sched_t *sched)
 {
        ftdm_status_t status = FTDM_FAIL;
index 676302400e82a40c3cb4117aa9a82cea2cb611d5..689156919fc136ab53eabfd29cd2f443a1f8d4d6 100755 (executable)
@@ -547,7 +547,7 @@ static ftdm_status_t ftdm_gsm_start(ftdm_span_t *span)
 {
        if (wat_span_start(span->span_id)) {
                ftdm_log(FTDM_LOG_ERROR, "Failed to start span %s!\n", span->name);
-               return FTDM_SUCCESS;
+               return FTDM_FAIL;
        }
 
        return ftdm_thread_create_detached(ftdm_gsm_run, span);
@@ -555,6 +555,10 @@ static ftdm_status_t ftdm_gsm_start(ftdm_span_t *span)
 
 static ftdm_status_t ftdm_gsm_stop(ftdm_span_t *span)
 {
+       if (wat_span_stop(span->span_id)) {
+               ftdm_log(FTDM_LOG_ERROR, "Failed to stop span %s!\n", span->name);
+               return FTDM_FAIL;
+       }
        return FTDM_SUCCESS;
 }
 
index 2d414a045b8a5a77a3b7d4b4d4428eb5784a0ffc..020da9fb3bdd26aa5f0e7d1cd21aeb6d6e6493f5 100644 (file)
@@ -92,6 +92,9 @@ FT_DECLARE(ftdm_status_t) ftdm_sched_get_time_to_next_timer(const ftdm_sched_t *
 /*! \brief Global initialization, called just once, this is called by FreeTDM core, other users MUST not call it */
 FT_DECLARE(ftdm_status_t) ftdm_sched_global_init(void);
 
+/*! \brief Global destroy, called just once, this is called by FreeTDM core, other users MUST not call it */
+FT_DECLARE(ftdm_status_t) ftdm_sched_global_destroy(void);
+
 /*! \brief Checks if the main scheduling thread is running */
 FT_DECLARE(ftdm_bool_t) ftdm_free_sched_running(void);