From ab6c4f1a6d09209c26fa803f9a9dce4d2b3b3ce0 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 10 Apr 2009 17:43:18 +0000 Subject: [PATCH] change CS_DONE to CS_DESTROY and add state handler for destroy and tear down critical parts of the channel from this method which is not called until it's impossible for anything to be referencing the channel (after final write lock and before destroying the pool) git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@12986 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/include/switch_core.h | 2 + src/include/switch_module_interfaces.h | 5 +- src/include/switch_types.h | 4 +- src/mod/endpoints/mod_alsa/mod_alsa.c | 25 +++++++++- .../endpoints/mod_dingaling/mod_dingaling.c | 50 +++++++++++++------ src/mod/endpoints/mod_iax/mod_iax.c | 34 +++++++++---- src/mod/endpoints/mod_loopback/mod_loopback.c | 45 ++++++++++++----- src/mod/endpoints/mod_opal/mod_opal.cpp | 45 +++++++++++------ .../endpoints/mod_portaudio/mod_portaudio.c | 17 ++++++- .../endpoints/mod_reference/mod_reference.c | 42 ++++++++++++---- src/mod/endpoints/mod_skypiax/mod_skypiax.c | 39 ++++++++++++--- src/mod/endpoints/mod_sofia/mod_sofia.c | 50 ++++++++++++------- src/mod/endpoints/mod_unicall/mod_unicall.c | 32 ++++++++++-- src/switch_channel.c | 16 +++--- src/switch_core_io.c | 4 -- src/switch_core_rwlock.c | 2 +- src/switch_core_session.c | 4 +- src/switch_core_sqldb.c | 4 +- src/switch_core_state_machine.c | 43 ++++++++++++++-- 19 files changed, 346 insertions(+), 117 deletions(-) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 15c5c48c38..78f566b739 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -578,6 +578,8 @@ SWITCH_DECLARE(void) switch_core_session_perform_destroy(_Inout_ switch_core_ses */ #define switch_core_session_destroy(session) switch_core_session_perform_destroy(session, __FILE__, __SWITCH_FUNC__, __LINE__) +SWITCH_DECLARE(void) switch_core_session_destroy_state(switch_core_session_t *session); + /*! \brief Provide the total number of sessions \return the total number of allocated sessions diff --git a/src/include/switch_module_interfaces.h b/src/include/switch_module_interfaces.h index fa85ce42e2..13a5b7a1e7 100644 --- a/src/include/switch_module_interfaces.h +++ b/src/include/switch_module_interfaces.h @@ -56,7 +56,8 @@ typedef enum { SWITCH_SHN_ON_HIBERNATE, SWITCH_SHN_ON_RESET, SWITCH_SHN_ON_PARK, - SWITCH_SHN_ON_REPORTING + SWITCH_SHN_ON_REPORTING, + SWITCH_SHN_ON_DESTROY } switch_state_handler_name_t; struct switch_state_handler_table { @@ -82,6 +83,8 @@ struct switch_state_handler_table { switch_state_handler_t on_park; /*! executed when the state changes to reporting */ switch_state_handler_t on_reporting; + /*! executed when the state changes to destroy */ + switch_state_handler_t on_destroy; void *padding[10]; }; diff --git a/src/include/switch_types.h b/src/include/switch_types.h index a9617174b6..67ff017887 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -787,7 +787,7 @@ CS_HIBERNATE - Channel is in a sleep state. CS_RESET - Channel is in a reset state. CS_HANGUP - Channel is flagged for hangup and ready to end. CS_REPORTING - Channel is ready to collect call detail. -CS_DONE - Channel is ready to be destroyed and out of the state machine +CS_DESTROY - Channel is ready to be destroyed and out of the state machine */ typedef enum { @@ -803,7 +803,7 @@ typedef enum { CS_RESET, CS_HANGUP, CS_REPORTING, - CS_DONE, + CS_DESTROY, CS_NONE } switch_channel_state_t; diff --git a/src/mod/endpoints/mod_alsa/mod_alsa.c b/src/mod/endpoints/mod_alsa/mod_alsa.c index a0260c0886..7e215f3426 100644 --- a/src/mod/endpoints/mod_alsa/mod_alsa.c +++ b/src/mod/endpoints/mod_alsa/mod_alsa.c @@ -143,6 +143,7 @@ static void add_pvt(private_t *tech_pvt, int master); static void remove_pvt(private_t *tech_pvt); static switch_status_t channel_on_init(switch_core_session_t *session); static switch_status_t channel_on_hangup(switch_core_session_t *session); +static switch_status_t channel_on_destroy(switch_core_session_t *session); static switch_status_t channel_on_routing(switch_core_session_t *session); static switch_status_t channel_on_exchange_media(switch_core_session_t *session); static switch_status_t channel_on_soft_execute(switch_core_session_t *session); @@ -425,6 +426,22 @@ static void remove_pvt(private_t *tech_pvt) switch_mutex_unlock(globals.pvt_lock); } +static switch_status_t channel_on_destroy(switch_core_session_t *session) +{ + switch_channel_t *channel = NULL; + private_t *tech_pvt = NULL; + + channel = switch_core_session_get_channel(session); + assert(channel != NULL); + + tech_pvt = switch_core_session_get_private(session); + assert(tech_pvt != NULL); + + return SWITCH_STATUS_SUCCESS; +} + + + static switch_status_t channel_on_hangup(switch_core_session_t *session) { switch_channel_t *channel = NULL; @@ -719,7 +736,13 @@ static switch_state_handler_table_t channel_event_handlers = { /*.on_execute */ channel_on_execute, /*.on_hangup */ channel_on_hangup, /*.on_exchange_media */ channel_on_exchange_media, - /*.on_soft_execute */ channel_on_soft_execute + /*.on_soft_execute */ channel_on_soft_execute, + /*.on_consume_media*/ NULL, + /*.on_hibernate*/ NULL, + /*.on_reset*/ NULL, + /*.on_park*/ NULL, + /*.on_reporting*/ NULL, + /*.on_destroy*/ channel_on_destroy }; static switch_io_routines_t channel_io_routines = { diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index dc033325ac..998a829a9d 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -206,6 +206,7 @@ SWITCH_STANDARD_API(dl_pres); SWITCH_STANDARD_API(dl_debug); static switch_status_t channel_on_init(switch_core_session_t *session); static switch_status_t channel_on_hangup(switch_core_session_t *session); +static switch_status_t channel_on_destroy(switch_core_session_t *session); static switch_status_t channel_on_routing(switch_core_session_t *session); static switch_status_t channel_on_exchange_media(switch_core_session_t *session); static switch_status_t channel_on_soft_execute(switch_core_session_t *session); @@ -1207,6 +1208,33 @@ static switch_status_t channel_on_execute(switch_core_session_t *session) return SWITCH_STATUS_SUCCESS; } +static switch_status_t channel_on_destroy(switch_core_session_t *session) +{ + //switch_channel_t *channel = switch_core_session_get_channel(session); + struct private_object *tech_pvt = NULL; + + tech_pvt = switch_core_session_get_private(session); + switch_assert(tech_pvt != NULL); + + if (tech_pvt->rtp_session) { + switch_rtp_destroy(&tech_pvt->rtp_session); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "NUKE RTP\n"); + tech_pvt->rtp_session = NULL; + } + + if (switch_core_codec_ready(&tech_pvt->read_codec)) { + switch_core_codec_destroy(&tech_pvt->read_codec); + } + + if (switch_core_codec_ready(&tech_pvt->write_codec)) { + switch_core_codec_destroy(&tech_pvt->write_codec); + } + + + return SWITCH_STATUS_SUCCESS; +} + + static switch_status_t channel_on_hangup(switch_core_session_t *session) { switch_channel_t *channel = switch_core_session_get_channel(session); @@ -1238,20 +1266,6 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session) ldl_session_destroy(&tech_pvt->dlsession); } - if (tech_pvt->rtp_session) { - switch_rtp_destroy(&tech_pvt->rtp_session); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "NUKE RTP\n"); - tech_pvt->rtp_session = NULL; - } - - if (switch_core_codec_ready(&tech_pvt->read_codec)) { - switch_core_codec_destroy(&tech_pvt->read_codec); - } - - if (switch_core_codec_ready(&tech_pvt->write_codec)) { - switch_core_codec_destroy(&tech_pvt->write_codec); - } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL HANGUP\n", switch_channel_get_name(channel)); return SWITCH_STATUS_SUCCESS; @@ -1554,7 +1568,13 @@ switch_state_handler_table_t dingaling_event_handlers = { /*.on_execute */ channel_on_execute, /*.on_hangup */ channel_on_hangup, /*.on_exchange_media */ channel_on_exchange_media, - /*.on_soft_execute */ channel_on_soft_execute + /*.on_soft_execute */ channel_on_soft_execute, + /*.on_consume_media*/ NULL, + /*.on_hibernate*/ NULL, + /*.on_reset*/ NULL, + /*.on_park*/ NULL, + /*.on_reporting*/ NULL, + /*.on_destroy*/ channel_on_destroy }; switch_io_routines_t dingaling_io_routines = { diff --git a/src/mod/endpoints/mod_iax/mod_iax.c b/src/mod/endpoints/mod_iax/mod_iax.c index 7749a95aa6..78368e12a4 100644 --- a/src/mod/endpoints/mod_iax/mod_iax.c +++ b/src/mod/endpoints/mod_iax/mod_iax.c @@ -416,6 +416,7 @@ static switch_status_t iax_set_codec(private_t *tech_pvt, struct iax_session *ia static switch_status_t channel_on_init(switch_core_session_t *session); static switch_status_t channel_on_hangup(switch_core_session_t *session); +static switch_status_t channel_on_destroy(switch_core_session_t *session); static switch_status_t channel_on_routing(switch_core_session_t *session); static switch_status_t channel_on_exchange_media(switch_core_session_t *session); static switch_status_t channel_on_soft_execute(switch_core_session_t *session); @@ -488,6 +489,23 @@ static switch_status_t channel_on_execute(switch_core_session_t *session) return SWITCH_STATUS_SUCCESS; } +static switch_status_t channel_on_destroy(switch_core_session_t *session) +{ + private_t *tech_pvt = switch_core_session_get_private(session); + + switch_assert(tech_pvt != NULL); + + if (switch_core_codec_ready(&tech_pvt->read_codec)) { + switch_core_codec_destroy(&tech_pvt->read_codec); + } + + if (!switch_core_codec_ready(&tech_pvt->write_codec)) { + switch_core_codec_destroy(&tech_pvt->write_codec); + } + + return SWITCH_STATUS_SUCCESS; +} + static switch_status_t channel_on_hangup(switch_core_session_t *session) { private_t *tech_pvt = switch_core_session_get_private(session); @@ -498,14 +516,6 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session) switch_clear_flag_locked(tech_pvt, TFLAG_VOICE); switch_clear_flag_locked(tech_pvt, TFLAG_CODEC); - if (switch_core_codec_ready(&tech_pvt->read_codec)) { - switch_core_codec_destroy(&tech_pvt->read_codec); - } - - if (!switch_core_codec_ready(&tech_pvt->write_codec)) { - switch_core_codec_destroy(&tech_pvt->write_codec); - } - switch_mutex_lock(globals.mutex); if (tech_pvt->iax_session) { if (!switch_test_flag(tech_pvt, TFLAG_HANGUP)) { @@ -787,7 +797,13 @@ switch_state_handler_table_t iax_state_handlers = { /*.on_execute */ channel_on_execute, /*.on_hangup */ channel_on_hangup, /*.on_exchange_media */ channel_on_exchange_media, - /*.on_soft_execute */ channel_on_soft_execute + /*.on_soft_execute */ channel_on_soft_execute, + /*.on_consume_media*/ NULL, + /*.on_hibernate*/ NULL, + /*.on_reset*/ NULL, + /*.on_park*/ NULL, + /*.on_reporting*/ NULL, + /*.on_destroy*/ channel_on_destroy }; switch_io_routines_t iax_io_routines = { diff --git a/src/mod/endpoints/mod_loopback/mod_loopback.c b/src/mod/endpoints/mod_loopback/mod_loopback.c index 82d8aaebdd..ebb890aabd 100644 --- a/src/mod/endpoints/mod_loopback/mod_loopback.c +++ b/src/mod/endpoints/mod_loopback/mod_loopback.c @@ -88,6 +88,7 @@ static struct { static switch_status_t channel_on_init(switch_core_session_t *session); static switch_status_t channel_on_hangup(switch_core_session_t *session); +static switch_status_t channel_on_destroy(switch_core_session_t *session); static switch_status_t channel_on_routing(switch_core_session_t *session); static switch_status_t channel_on_exchange_media(switch_core_session_t *session); static switch_status_t channel_on_soft_execute(switch_core_session_t *session); @@ -339,10 +340,36 @@ static switch_status_t channel_on_execute(switch_core_session_t *session) assert(tech_pvt != NULL); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL EXECUTE\n", switch_channel_get_name(channel)); + + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t channel_on_destroy(switch_core_session_t *session) +{ + switch_channel_t *channel = NULL; + private_t *tech_pvt = NULL; + + channel = switch_core_session_get_channel(session); + switch_assert(channel != NULL); + + tech_pvt = switch_core_session_get_private(session); + switch_assert(tech_pvt != NULL); + + switch_core_timer_destroy(&tech_pvt->timer); + + if (switch_core_codec_ready(&tech_pvt->read_codec)) { + switch_core_codec_destroy(&tech_pvt->read_codec); + } + + if (switch_core_codec_ready(&tech_pvt->write_codec)) { + switch_core_codec_destroy(&tech_pvt->write_codec); + } + return SWITCH_STATUS_SUCCESS; } + static switch_status_t channel_on_hangup(switch_core_session_t *session) { switch_channel_t *channel = NULL; @@ -370,17 +397,7 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session) tech_pvt->other_session = NULL; } switch_mutex_unlock(tech_pvt->mutex); - - switch_core_timer_destroy(&tech_pvt->timer); - - if (switch_core_codec_ready(&tech_pvt->read_codec)) { - switch_core_codec_destroy(&tech_pvt->read_codec); - } - - if (switch_core_codec_ready(&tech_pvt->write_codec)) { - switch_core_codec_destroy(&tech_pvt->write_codec); - } - + return SWITCH_STATUS_SUCCESS; } @@ -754,7 +771,11 @@ static switch_state_handler_table_t channel_event_handlers = { /*.on_soft_execute */ channel_on_soft_execute, /*.on_consume_media */ channel_on_consume_media, /*.on_hibernate */ channel_on_hibernate, - /*.on_reset */ channel_on_reset + /*.on_reset */ channel_on_reset, + /*.on_park*/ NULL, + /*.on_reporting*/ NULL, + /*.on_destroy*/ channel_on_destroy + }; static switch_io_routines_t channel_io_routines = { diff --git a/src/mod/endpoints/mod_opal/mod_opal.cpp b/src/mod/endpoints/mod_opal/mod_opal.cpp index c1213bc792..38c93ab929 100644 --- a/src/mod/endpoints/mod_opal/mod_opal.cpp +++ b/src/mod/endpoints/mod_opal/mod_opal.cpp @@ -70,7 +70,14 @@ static switch_state_handler_table_t opalfs_event_handlers = { /*.on_execute */ FSConnection::on_execute, /*.on_hangup */ on_hangup, /*.on_loopback */ FSConnection::on_loopback, - /*.on_transmit */ FSConnection::on_transmit + /*.on_transmit */ FSConnection::on_transmit, + /*.on_soft_execute */ NULL, + /*.on_consume_media*/ NULL, + /*.on_hibernate*/ NULL, + /*.on_reset*/ NULL, + /*.on_park*/ NULL, + /*.on_reporting*/ NULL, + /*.on_destroy*/ on_destroy }; @@ -826,23 +833,11 @@ switch_status_t FSConnection::on_execute() return SWITCH_STATUS_SUCCESS; } - -/* this function has to be called with the original session beause the FSConnection might already be destroyed and we - will can't have it be a method of a dead object - */ -static switch_status_t on_hangup(switch_core_session_t *session) +static switch_status_t on_destroy(switch_core_session_t *session) { switch_channel_t *channel = switch_core_session_get_channel(session); opal_private_t *tech_pvt = (opal_private_t *) switch_core_session_get_private(session); - - /* if this is still here it was our idea to hangup not opal's */ - if (tech_pvt->me) { - Q931::CauseValues cause = (Q931::CauseValues)switch_channel_get_cause_q850(channel); - tech_pvt->me->SetQ931Cause(cause); - tech_pvt->me->ClearCallSynchronous(NULL, H323TranslateToCallEndReason(cause, UINT_MAX)); - tech_pvt->me = NULL; - } - + if (tech_pvt->read_codec.implementation) { switch_core_codec_destroy(&tech_pvt->read_codec); } @@ -869,7 +864,27 @@ static switch_status_t on_hangup(switch_core_session_t *session) switch_core_session_unset_read_codec(session); switch_core_session_unset_write_codec(session); + + return SWITCH_STATUS_SUCCESS; +} + +/* this function has to be called with the original session beause the FSConnection might already be destroyed and we + will can't have it be a method of a dead object + */ +static switch_status_t on_hangup(switch_core_session_t *session) +{ + switch_channel_t *channel = switch_core_session_get_channel(session); + opal_private_t *tech_pvt = (opal_private_t *) switch_core_session_get_private(session); + + /* if this is still here it was our idea to hangup not opal's */ + if (tech_pvt->me) { + Q931::CauseValues cause = (Q931::CauseValues)switch_channel_get_cause_q850(channel); + tech_pvt->me->SetQ931Cause(cause); + tech_pvt->me->ClearCallSynchronous(NULL, H323TranslateToCallEndReason(cause, UINT_MAX)); + tech_pvt->me = NULL; + } + return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/endpoints/mod_portaudio/mod_portaudio.c b/src/mod/endpoints/mod_portaudio/mod_portaudio.c index af2109c09b..b6936e6704 100644 --- a/src/mod/endpoints/mod_portaudio/mod_portaudio.c +++ b/src/mod/endpoints/mod_portaudio/mod_portaudio.c @@ -148,6 +148,7 @@ static void add_pvt(private_t *tech_pvt, int master); static void remove_pvt(private_t *tech_pvt); static switch_status_t channel_on_init(switch_core_session_t *session); static switch_status_t channel_on_hangup(switch_core_session_t *session); +static switch_status_t channel_on_destroy(switch_core_session_t *session); static switch_status_t channel_on_routing(switch_core_session_t *session); static switch_status_t channel_on_exchange_media(switch_core_session_t *session); static switch_status_t channel_on_soft_execute(switch_core_session_t *session); @@ -469,6 +470,13 @@ static void tech_close_file(private_t *tech_pvt) } } +static switch_status_t channel_on_destroy(switch_core_session_t *session) +{ + //private_t *tech_pvt = switch_core_session_get_private(session); + //switch_assert(tech_pvt != NULL); + return SWITCH_STATUS_SUCCESS; +} + static switch_status_t channel_on_hangup(switch_core_session_t *session) { private_t *tech_pvt = switch_core_session_get_private(session); @@ -692,7 +700,14 @@ switch_state_handler_table_t portaudio_event_handlers = { /*.on_execute */ channel_on_execute, /*.on_hangup */ channel_on_hangup, /*.on_exchange_media */ channel_on_exchange_media, - /*.on_soft_execute */ channel_on_soft_execute + /*.on_soft_execute */ channel_on_soft_execute, + /*.on_consume_media*/ NULL, + /*.on_hibernate*/ NULL, + /*.on_reset*/ NULL, + /*.on_park*/ NULL, + /*.on_reporting*/ NULL, + /*.on_destroy*/ channel_on_destroy + }; switch_io_routines_t portaudio_io_routines = { diff --git a/src/mod/endpoints/mod_reference/mod_reference.c b/src/mod/endpoints/mod_reference/mod_reference.c index 6d264ea50b..c6bcb17556 100644 --- a/src/mod/endpoints/mod_reference/mod_reference.c +++ b/src/mod/endpoints/mod_reference/mod_reference.c @@ -100,6 +100,7 @@ SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_ip, globals.ip); static switch_status_t channel_on_init(switch_core_session_t *session); static switch_status_t channel_on_hangup(switch_core_session_t *session); +static switch_status_t channel_on_destroy(switch_core_session_t *session); static switch_status_t channel_on_routing(switch_core_session_t *session); static switch_status_t channel_on_exchange_media(switch_core_session_t *session); static switch_status_t channel_on_soft_execute(switch_core_session_t *session); @@ -185,6 +186,30 @@ static switch_status_t channel_on_execute(switch_core_session_t *session) return SWITCH_STATUS_SUCCESS; } +static switch_status_t channel_on_destroy(switch_core_session_t *session) +{ + switch_channel_t *channel = NULL; + private_t *tech_pvt = NULL; + + channel = switch_core_session_get_channel(session); + assert(channel != NULL); + + tech_pvt = switch_core_session_get_private(session); + assert(tech_pvt != NULL); + + + if (switch_core_codec_ready(&tech_pvt->read_codec)) { + switch_core_codec_destroy(&tech_pvt->read_codec); + } + + if (switch_core_codec_ready(&tech_pvt->write_codec)) { + switch_core_codec_destroy(&tech_pvt->write_codec); + } + + return SWITCH_STATUS_SUCCESS; +} + + static switch_status_t channel_on_hangup(switch_core_session_t *session) { switch_channel_t *channel = NULL; @@ -200,14 +225,6 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session) switch_clear_flag_locked(tech_pvt, TFLAG_VOICE); //switch_thread_cond_signal(tech_pvt->cond); - if (switch_core_codec_ready(&tech_pvt->read_codec)) { - switch_core_codec_destroy(&tech_pvt->read_codec); - } - - if (switch_core_codec_ready(&tech_pvt->write_codec)) { - switch_core_codec_destroy(&tech_pvt->write_codec); - } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL HANGUP\n", switch_channel_get_name(channel)); switch_mutex_lock(globals.mutex); @@ -462,7 +479,14 @@ switch_state_handler_table_t reference_state_handlers = { /*.on_execute */ channel_on_execute, /*.on_hangup */ channel_on_hangup, /*.on_exchange_media */ channel_on_exchange_media, - /*.on_soft_execute */ channel_on_soft_execute + /*.on_soft_execute */ channel_on_soft_execute, + /*.on_consume_media*/ NULL, + /*.on_hibernate*/ NULL, + /*.on_reset*/ NULL, + /*.on_park*/ NULL, + /*.on_reporting*/ NULL, + /*.on_destroy*/ channel_on_destroy + }; switch_io_routines_t reference_io_routines = { diff --git a/src/mod/endpoints/mod_skypiax/mod_skypiax.c b/src/mod/endpoints/mod_skypiax/mod_skypiax.c index d90b24f19d..33f10e88b2 100644 --- a/src/mod/endpoints/mod_skypiax/mod_skypiax.c +++ b/src/mod/endpoints/mod_skypiax/mod_skypiax.c @@ -79,6 +79,7 @@ SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_codec_rates_string, static switch_status_t channel_on_init(switch_core_session_t * session); static switch_status_t channel_on_hangup(switch_core_session_t * session); +static switch_status_t channel_on_destroy(switch_core_session_t * session); static switch_status_t channel_on_routing(switch_core_session_t * session); static switch_status_t channel_on_exchange_media(switch_core_session_t * session); static switch_status_t channel_on_soft_execute(switch_core_session_t * session); @@ -182,6 +183,29 @@ static switch_status_t channel_on_init(switch_core_session_t * session) return SWITCH_STATUS_SUCCESS; } +static switch_status_t channel_on_hangup(switch_core_session_t * session) +{ + switch_channel_t *channel = NULL; + private_t *tech_pvt = NULL; + + channel = switch_core_session_get_channel(session); + switch_assert(channel != NULL); + + tech_pvt = switch_core_session_get_private(session); + switch_assert(tech_pvt != NULL); + + if (switch_core_codec_ready(&tech_pvt->read_codec)) { + switch_core_codec_destroy(&tech_pvt->read_codec); + } + + if (switch_core_codec_ready(&tech_pvt->write_codec)) { + switch_core_codec_destroy(&tech_pvt->write_codec); + } + + return SWITCH_STATUS_SUCCESS; +} + + static switch_status_t channel_on_hangup(switch_core_session_t * session) { switch_channel_t *channel = NULL; @@ -205,13 +229,6 @@ static switch_status_t channel_on_hangup(switch_core_session_t * session) skypiax_signaling_write(tech_pvt, msg_to_skype); } - if (switch_core_codec_ready(&tech_pvt->read_codec)) { - switch_core_codec_destroy(&tech_pvt->read_codec); - } - - if (switch_core_codec_ready(&tech_pvt->write_codec)) { - switch_core_codec_destroy(&tech_pvt->write_codec); - } memset(tech_pvt->session_uuid_str, '\0', sizeof(tech_pvt->session_uuid_str)); DEBUGA_SKYPE("%s CHANNEL HANGUP\n", SKYPIAX_P_LOG, switch_channel_get_name(channel)); @@ -490,7 +507,13 @@ switch_state_handler_table_t skypiax_state_handlers = { /*.on_execute */ channel_on_execute, /*.on_hangup */ channel_on_hangup, /*.on_exchange_media */ channel_on_exchange_media, - /*.on_soft_execute */ channel_on_soft_execute + /*.on_soft_execute */ channel_on_soft_execute, + /*.on_consume_media*/ NULL, + /*.on_hibernate*/ NULL, + /*.on_reset*/ NULL, + /*.on_park*/ NULL, + /*.on_reporting*/ NULL, + /*.on_destroy*/ channel_on_destroy }; switch_io_routines_t skypiax_io_routines = { diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index f256622de9..2053e1f6ad 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -232,6 +232,34 @@ static int hangup_cause_to_sip(switch_call_cause_t cause) } } +switch_status_t sofia_on_destroy(switch_core_session_t *session) +{ + private_object_t *tech_pvt = (private_object_t *) switch_core_session_get_private(session); + switch_channel_t *channel = switch_core_session_get_channel(session); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s SOFIA DESTROY\n", switch_channel_get_name(channel)); + + if (switch_core_codec_ready(&tech_pvt->read_codec)) { + switch_core_codec_destroy(&tech_pvt->read_codec); + } + + if (switch_core_codec_ready(&tech_pvt->write_codec)) { + switch_core_codec_destroy(&tech_pvt->write_codec); + } + + switch_core_session_unset_read_codec(session); + switch_core_session_unset_write_codec(session); + + switch_mutex_lock(tech_pvt->profile->flag_mutex); + tech_pvt->profile->inuse--; + switch_mutex_unlock(tech_pvt->profile->flag_mutex); + + sofia_glue_deactivate_rtp(tech_pvt); + + return SWITCH_STATUS_SUCCESS; + +} + switch_status_t sofia_on_hangup(switch_core_session_t *session) { switch_core_session_t *a_session; @@ -282,8 +310,6 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session) sofia_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD); } - sofia_glue_deactivate_rtp(tech_pvt); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Channel %s hanging up, cause: %s\n", switch_channel_get_name(channel), switch_channel_cause2str(cause)); @@ -379,21 +405,6 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session) sofia_clear_flag(tech_pvt, TFLAG_IO); - if (switch_core_codec_ready(&tech_pvt->read_codec)) { - switch_core_codec_destroy(&tech_pvt->read_codec); - } - - if (switch_core_codec_ready(&tech_pvt->write_codec)) { - switch_core_codec_destroy(&tech_pvt->write_codec); - } - - switch_core_session_unset_read_codec(session); - switch_core_session_unset_write_codec(session); - - switch_mutex_lock(tech_pvt->profile->flag_mutex); - tech_pvt->profile->inuse--; - switch_mutex_unlock(tech_pvt->profile->flag_mutex); - if (tech_pvt->sofia_private) { *tech_pvt->sofia_private->uuid = '\0'; } @@ -2378,7 +2389,10 @@ switch_state_handler_table_t sofia_event_handlers = { /*.on_soft_execute */ sofia_on_soft_execute, /*.on_consume_media */ NULL, /*.on_hibernate */ sofia_on_hibernate, - /*.on_reset */ sofia_on_reset + /*.on_reset */ sofia_on_reset, + /*.on_park*/ NULL, + /*.on_reporting*/ NULL, + /*.on_destroy*/ sofia_on_destroy }; static switch_status_t sofia_manage(char *relative_oid, switch_management_action_t action, char *data, switch_size_t datalen) diff --git a/src/mod/endpoints/mod_unicall/mod_unicall.c b/src/mod/endpoints/mod_unicall/mod_unicall.c index 55ff75a9dc..da9907dc5a 100644 --- a/src/mod/endpoints/mod_unicall/mod_unicall.c +++ b/src/mod/endpoints/mod_unicall/mod_unicall.c @@ -932,6 +932,25 @@ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "unicall_on_execute(%p)\n return SWITCH_STATUS_SUCCESS; } +static switch_status_t unicall_on_destroy(switch_core_session_t *session) +{ + switch_channel_t *channel; + private_t *tech_pvt; + + channel = switch_core_session_get_channel(session); + assert(channel != NULL); + tech_pvt = switch_core_session_get_private(session); + assert(tech_pvt != NULL); + + if (switch_core_codec_ready(&tech_pvt->read_codec)) + switch_core_codec_destroy(&tech_pvt->read_codec); + if (switch_core_codec_ready(&tech_pvt->write_codec)) + switch_core_codec_destroy(&tech_pvt->write_codec); + + return SWITCH_STATUS_SUCCESS; + +} + static switch_status_t unicall_on_hangup(switch_core_session_t *session) { switch_channel_t *channel; @@ -948,10 +967,6 @@ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "unicall_on_hangup(%p)\n" switch_clear_flag_locked(tech_pvt, TFLAG_VOICE); //switch_thread_cond_signal(tech_pvt->cond); - if (switch_core_codec_ready(&tech_pvt->read_codec)) - switch_core_codec_destroy(&tech_pvt->read_codec); - if (switch_core_codec_ready(&tech_pvt->write_codec) - switch_core_codec_destroy(&tech_pvt->write_codec); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s channel hangup\n", switch_channel_get_name(channel)); @@ -1722,7 +1737,14 @@ switch_state_handler_table_t unicall_state_handlers = /*.on_execute */ unicall_on_execute, /*.on_hangup */ unicall_on_hangup, /*.on_exchange_media */ unicall_on_exchange_media, - /*.on_soft_execute */ unicall_on_soft_execute + /*.on_soft_execute */ unicall_on_soft_execute, + /*.on_consume_media*/ NULL, + /*.on_hibernate*/ NULL, + /*.on_reset*/ NULL, + /*.on_park*/ NULL, + /*.on_reporting*/ NULL, + /*.on_destroy*/ unicall_on_destroy + }; switch_io_routines_t unicall_io_routines = diff --git a/src/switch_channel.c b/src/switch_channel.c index c671f33c6c..67fe38f682 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -931,7 +931,7 @@ static const char *state_names[] = { "CS_RESET", "CS_HANGUP", "CS_REPORTING", - "CS_DONE", + "CS_DESTROY", NULL }; @@ -950,7 +950,7 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_name_state(const char *nam } } - return CS_DONE; + return CS_DESTROY; } SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_running_state(switch_channel_t *channel, switch_channel_state_t state, @@ -1015,11 +1015,11 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_state(switch_c int ok = 0; switch_assert(channel != NULL); - switch_assert(state <= CS_DONE); + switch_assert(state <= CS_DESTROY); switch_mutex_lock(channel->state_mutex); last_state = channel->state; - switch_assert(last_state <= CS_DONE); + switch_assert(last_state <= CS_DESTROY); if (last_state == state) { goto done; @@ -1040,7 +1040,7 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_state(switch_c case CS_ROUTING: case CS_EXECUTE: case CS_HANGUP: - case CS_DONE: + case CS_DESTROY: default: break; @@ -1182,7 +1182,7 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_state(switch_c case CS_HANGUP: switch (state) { case CS_REPORTING: - case CS_DONE: + case CS_DESTROY: ok++; default: break; @@ -1191,7 +1191,7 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_state(switch_c case CS_REPORTING: switch (state) { - case CS_DONE: + case CS_DESTROY: ok++; default: break; @@ -1213,7 +1213,7 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_state(switch_c channel->hangup_cause = SWITCH_CAUSE_NORMAL_CLEARING; } - if (state < CS_DONE) { + if (state < CS_DESTROY) { switch_core_session_signal_state_change(channel->session); } } else { diff --git a/src/switch_core_io.c b/src/switch_core_io.c index 221d1d71f8..d15512e8b0 100644 --- a/src/switch_core_io.c +++ b/src/switch_core_io.c @@ -202,16 +202,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi switch_assert((*frame)->codec != NULL); - - switch_mutex_lock((*frame)->codec->mutex); if (!(session->read_codec && (*frame)->codec && (*frame)->codec->implementation) && switch_core_codec_ready((*frame)->codec)) { status = SWITCH_STATUS_FALSE; - switch_mutex_unlock((*frame)->codec->mutex); goto done; } codec_impl = *(*frame)->codec->implementation; - switch_mutex_unlock((*frame)->codec->mutex); if (session->read_codec->implementation->impl_id != codec_impl.impl_id) { need_codec = TRUE; diff --git a/src/switch_core_rwlock.c b/src/switch_core_rwlock.c index aba781614b..1c91389e5e 100644 --- a/src/switch_core_rwlock.c +++ b/src/switch_core_rwlock.c @@ -73,7 +73,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_lock_hangup(switch_core switch_status_t status = SWITCH_STATUS_FALSE; if (session->rwlock) { - if (switch_test_flag(session, SSF_DESTROYED) || switch_channel_get_state(session->channel) >= CS_DONE) { + if (switch_test_flag(session, SSF_DESTROYED) || switch_channel_get_state(session->channel) >= CS_DESTROY) { status = SWITCH_STATUS_FALSE; #ifdef SWITCH_DEBUG_RWLOCKS switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "%s Read lock FAIL\n", diff --git a/src/switch_core_session.c b/src/switch_core_session.c index 965cffe472..aeaa099fda 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -874,7 +874,6 @@ SWITCH_DECLARE(unsigned int) switch_core_session_running(switch_core_session_t * return session->thread_running; } - SWITCH_DECLARE(void) switch_core_session_perform_destroy(switch_core_session_t **session, const char *file, const char *func, int line) { switch_memory_pool_t *pool; @@ -905,6 +904,7 @@ SWITCH_DECLARE(void) switch_core_session_perform_destroy(switch_core_session_t * switch_event_fire(&event); } + switch_core_session_destroy_state(*session); switch_buffer_destroy(&(*session)->raw_read_buffer); switch_buffer_destroy(&(*session)->raw_write_buffer); @@ -921,6 +921,8 @@ SWITCH_DECLARE(void) switch_core_session_perform_destroy(switch_core_session_t * UNPROTECT_INTERFACE(endpoint_interface); } + + SWITCH_STANDARD_SCHED_FUNC(sch_heartbeat_callback) { switch_event_t *event; diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 6335eaba11..2b31e27b13 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -309,7 +309,7 @@ static void core_event_handler(switch_event_t *event) case SWITCH_EVENT_CHANNEL_STATE: { char *state = switch_event_get_header_nil(event, "channel-state-number"); - switch_channel_state_t state_i = CS_DONE; + switch_channel_state_t state_i = CS_DESTROY; if (!switch_strlen_zero(state)) { state_i = atoi(state); @@ -317,7 +317,7 @@ static void core_event_handler(switch_event_t *event) switch (state_i) { case CS_HANGUP: - case CS_DONE: + case CS_DESTROY: break; case CS_ROUTING: sql = switch_mprintf("update channels set state='%s',cid_name='%q',cid_num='%q',ip_addr='%s',dest='%q',dialplan='%q',context='%q' " diff --git a/src/switch_core_state_machine.c b/src/switch_core_state_machine.c index ceae777675..a97fedb9f0 100644 --- a/src/switch_core_state_machine.c +++ b/src/switch_core_state_machine.c @@ -54,6 +54,13 @@ static void switch_core_standard_on_reporting(switch_core_session_t *session) switch_channel_get_name(session->channel), switch_channel_cause2str(switch_channel_get_cause(session->channel))); } +static void switch_core_standard_on_destroy(switch_core_session_t *session) +{ + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Standard DESTROY\n", + switch_channel_get_name(session->channel)); +} + static void switch_core_standard_on_reset(switch_core_session_t *session) { @@ -318,7 +325,7 @@ void switch_core_state_machine_init(switch_memory_pool_t *pool) SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session) { - switch_channel_state_t state = CS_NEW, midstate = CS_DONE, endstate; + switch_channel_state_t state = CS_NEW, midstate = CS_DESTROY, endstate; const switch_endpoint_interface_t *endpoint_interface; const switch_state_handler_table_t *driver_state_handler = NULL; const switch_state_handler_table_t *application_state_handler = NULL; @@ -376,7 +383,7 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session) switch_mutex_lock(session->mutex); - while ((state = switch_channel_get_state(session->channel)) != CS_DONE) { + while ((state = switch_channel_get_state(session->channel)) != CS_DESTROY) { switch_channel_wait_for_flag(session->channel, CF_BLOCK_STATE, SWITCH_FALSE, 0, NULL); @@ -395,7 +402,7 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session) case CS_NEW: /* Just created, Waiting for first instructions */ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) State NEW\n", switch_channel_get_name(session->channel)); break; - case CS_DONE: + case CS_DESTROY: goto done; case CS_REPORTING: /* Call Detail */ { @@ -417,7 +424,7 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session) STATE_MACRO(reporting, "REPORTING"); - switch_channel_set_state(session->channel, CS_DONE); + switch_channel_set_state(session->channel, CS_DESTROY); } goto done; case CS_HANGUP: /* Deactivate and end the thread */ @@ -517,7 +524,7 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session) break; } - if (midstate == CS_DONE) { + if (midstate == CS_DESTROY) { break; } @@ -543,6 +550,32 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session) session->thread_running = 0; } +SWITCH_DECLARE(void) switch_core_session_destroy_state(switch_core_session_t *session) +{ + switch_channel_state_t state = CS_DESTROY, midstate = CS_DESTROY; + const switch_endpoint_interface_t *endpoint_interface; + const switch_state_handler_table_t *driver_state_handler = NULL; + const switch_state_handler_table_t *application_state_handler = NULL; + int proceed = 1; + int global_proceed = 1; + int do_extra_handlers = 1; + int silly = 0; + int index = 0; + + switch_assert(session != NULL); + + session->thread_running = 1; + endpoint_interface = session->endpoint_interface; + switch_assert(endpoint_interface != NULL); + + driver_state_handler = endpoint_interface->state_handler; + switch_assert(driver_state_handler != NULL); + + STATE_MACRO(destroy, "DESTROY"); + + return; +} + /* For Emacs: * Local Variables: * mode:c