diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index cdab6adb87..846f9cb789 100644 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -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* diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 42f348617b..58fa998390 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -690,15 +690,11 @@ static ftdm_status_t ftdm_span_destroy(ftdm_span_t *span) ftdm_status_t status = FTDM_SUCCESS; unsigned j; + /* 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"); + ftdm_mutex_lock(span->mutex); - /* stop the signaling */ - - /* This is a forced stopped */ - ftdm_clear_flag(span, FTDM_SPAN_NON_STOPPABLE); - - ftdm_span_stop(span); - /* destroy the channels */ ftdm_clear_flag(span, FTDM_SPAN_CONFIGURED); for(j = 1; j <= span->chan_count && span->channels[j]; j++) { @@ -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; } diff --git a/libs/freetdm/src/ftdm_sched.c b/libs/freetdm/src/ftdm_sched.c index cc639fa624..324073976c 100644 --- a/libs/freetdm/src/ftdm_sched.c +++ b/libs/freetdm/src/ftdm_sched.c @@ -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; diff --git a/libs/freetdm/src/ftmod/ftmod_gsm/ftmod_gsm.c b/libs/freetdm/src/ftmod/ftmod_gsm/ftmod_gsm.c index 676302400e..689156919f 100755 --- a/libs/freetdm/src/ftmod/ftmod_gsm/ftmod_gsm.c +++ b/libs/freetdm/src/ftmod/ftmod_gsm/ftmod_gsm.c @@ -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; } diff --git a/libs/freetdm/src/include/private/ftdm_sched.h b/libs/freetdm/src/include/private/ftdm_sched.h index 2d414a045b..020da9fb3b 100644 --- a/libs/freetdm/src/include/private/ftdm_sched.h +++ b/libs/freetdm/src/include/private/ftdm_sched.h @@ -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);