simplify switch_core_service_session to protect against a race condition

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@10136 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2008-10-23 23:48:11 +00:00
parent e520638b92
commit 42dd42ebb6
7 changed files with 42 additions and 52 deletions

View File

@ -740,18 +740,15 @@ SWITCH_DECLARE(void) switch_core_session_launch_thread(_In_ switch_core_session_
/*! /*!
\brief Signal a thread using a thread session to terminate \brief Signal a thread using a thread session to terminate
\param thread_session the thread_session to indicate to \param session the session to indicate to
*/ */
SWITCH_DECLARE(void) switch_core_thread_session_end(_In_ switch_core_thread_session_t *thread_session); SWITCH_DECLARE(void) switch_core_thread_session_end(_In_ switch_core_session_t *session);
/*! /*!
\brief Launch a service thread on a session to drop inbound data \brief Launch a service thread on a session to drop inbound data
\param session the session the launch thread on \param session the session the launch thread on
\param stream_id which logical media channel to use
\param thread_session the thread_session to use
*/ */
SWITCH_DECLARE(void) switch_core_service_session(_In_ switch_core_session_t *session, SWITCH_DECLARE(void) switch_core_service_session(_In_ switch_core_session_t *session);
_In_ switch_core_thread_session_t *thread_session, _In_ int stream_id);
/*! /*!
\brief Request an outgoing session spawned from an existing session using a desired endpoing module \brief Request an outgoing session spawned from an existing session using a desired endpoing module

View File

@ -169,7 +169,6 @@ SWITCH_STANDARD_APP(rss_function)
char *timer_name = NULL; char *timer_name = NULL;
switch_speech_handle_t sh; switch_speech_handle_t sh;
switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_NONE; switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_NONE;
switch_core_thread_session_t thread_session;
switch_timer_t timer = { 0 }, *timerp = NULL; switch_timer_t timer = { 0 }, *timerp = NULL;
uint32_t last; uint32_t last;
char *mydata = NULL; char *mydata = NULL;
@ -293,7 +292,7 @@ SWITCH_STANDARD_APP(rss_function)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Setup timer success %u bytes per %d ms!\n", (rate / 50) * 2, interval); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Setup timer success %u bytes per %d ms!\n", (rate / 50) * 2, interval);
/* start a thread to absorb incoming audio */ /* start a thread to absorb incoming audio */
switch_core_service_session(session, &thread_session, 0); switch_core_service_session(session);
timerp = &timer; timerp = &timer;
} }
@ -615,7 +614,7 @@ SWITCH_STANDARD_APP(rss_function)
if (timerp) { if (timerp) {
/* End the audio absorbing thread */ /* End the audio absorbing thread */
switch_core_thread_session_end(&thread_session); switch_core_thread_session_end(session);
switch_core_timer_destroy(&timer); switch_core_timer_destroy(&timer);
} }

View File

@ -5441,22 +5441,18 @@ SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_session_launch_thread(void * jarg
SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_thread_session_end(void * jarg1) { SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_thread_session_end(void * jarg1) {
switch_core_thread_session_t *arg1 = (switch_core_thread_session_t *) 0 ; switch_core_session_t *arg1 = (switch_core_session_t *) 0 ;
arg1 = (switch_core_thread_session_t *)jarg1; arg1 = (switch_core_session_t *)jarg1;
switch_core_thread_session_end(arg1); switch_core_thread_session_end(arg1);
} }
SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_service_session(void * jarg1, void * jarg2, int jarg3) { SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_service_session(void * jarg1) {
switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; switch_core_session_t *arg1 = (switch_core_session_t *) 0 ;
switch_core_thread_session_t *arg2 = (switch_core_thread_session_t *) 0 ;
int arg3 ;
arg1 = (switch_core_session_t *)jarg1; arg1 = (switch_core_session_t *)jarg1;
arg2 = (switch_core_thread_session_t *)jarg2; switch_core_service_session(arg1);
arg3 = (int)jarg3;
switch_core_service_session(arg1,arg2,arg3);
} }

View File

@ -1262,12 +1262,12 @@ public class freeswitch {
freeswitchPINVOKE.switch_core_session_launch_thread(SWIGTYPE_p_switch_core_session.getCPtr(session), SWIGTYPE_p_f_p_switch_thread_t_p_void__p_void.getCPtr(func), SWIGTYPE_p_void.getCPtr(obj)); freeswitchPINVOKE.switch_core_session_launch_thread(SWIGTYPE_p_switch_core_session.getCPtr(session), SWIGTYPE_p_f_p_switch_thread_t_p_void__p_void.getCPtr(func), SWIGTYPE_p_void.getCPtr(obj));
} }
public static void switch_core_thread_session_end(switch_core_thread_session thread_session) { public static void switch_core_thread_session_end(SWIGTYPE_p_switch_core_session session) {
freeswitchPINVOKE.switch_core_thread_session_end(switch_core_thread_session.getCPtr(thread_session)); freeswitchPINVOKE.switch_core_thread_session_end(SWIGTYPE_p_switch_core_session.getCPtr(session));
} }
public static void switch_core_service_session(SWIGTYPE_p_switch_core_session session, switch_core_thread_session thread_session, int stream_id) { public static void switch_core_service_session(SWIGTYPE_p_switch_core_session session) {
freeswitchPINVOKE.switch_core_service_session(SWIGTYPE_p_switch_core_session.getCPtr(session), switch_core_thread_session.getCPtr(thread_session), stream_id); freeswitchPINVOKE.switch_core_service_session(SWIGTYPE_p_switch_core_session.getCPtr(session));
} }
public static switch_call_cause_t switch_core_session_outgoing_channel(SWIGTYPE_p_switch_core_session session, switch_event var_event, string endpoint_name, switch_caller_profile caller_profile, SWIGTYPE_p_p_switch_core_session new_session, SWIGTYPE_p_p_apr_pool_t pool, uint flags) { public static switch_call_cause_t switch_core_session_outgoing_channel(SWIGTYPE_p_switch_core_session session, switch_event var_event, string endpoint_name, switch_caller_profile caller_profile, SWIGTYPE_p_p_switch_core_session new_session, SWIGTYPE_p_p_apr_pool_t pool, uint flags) {
@ -5449,7 +5449,7 @@ class freeswitchPINVOKE {
public static extern void switch_core_thread_session_end(HandleRef jarg1); public static extern void switch_core_thread_session_end(HandleRef jarg1);
[DllImport("mod_managed", EntryPoint="CSharp_switch_core_service_session")] [DllImport("mod_managed", EntryPoint="CSharp_switch_core_service_session")]
public static extern void switch_core_service_session(HandleRef jarg1, HandleRef jarg2, int jarg3); public static extern void switch_core_service_session(HandleRef jarg1);
[DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_outgoing_channel")] [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_outgoing_channel")]
public static extern int switch_core_session_outgoing_channel(HandleRef jarg1, HandleRef jarg2, string jarg3, HandleRef jarg4, HandleRef jarg5, HandleRef jarg6, uint jarg7); public static extern int switch_core_session_outgoing_channel(HandleRef jarg1, HandleRef jarg2, string jarg3, HandleRef jarg4, HandleRef jarg5, HandleRef jarg6, uint jarg7);

View File

@ -209,7 +209,6 @@ static JSBool teletone_generate(JSContext * cx, JSObject * obj, uintN argc, jsva
switch_frame_t write_frame = { 0 }; switch_frame_t write_frame = { 0 };
unsigned char *fdata[1024]; unsigned char *fdata[1024];
switch_frame_t *read_frame; switch_frame_t *read_frame;
switch_core_thread_session_t thread_session = { 0 };
switch_channel_t *channel; switch_channel_t *channel;
if (argc > 1) { if (argc > 1) {
@ -237,7 +236,7 @@ static JSBool teletone_generate(JSContext * cx, JSObject * obj, uintN argc, jsva
channel = switch_core_session_get_channel(session); channel = switch_core_session_get_channel(session);
if (tto->timer) { if (tto->timer) {
switch_core_service_session(session, &thread_session, 0); switch_core_service_session(session);
} }
if (loops) { if (loops) {
@ -291,7 +290,7 @@ static JSBool teletone_generate(JSContext * cx, JSObject * obj, uintN argc, jsva
} }
if (tto->timer) { if (tto->timer) {
switch_core_thread_session_end(&thread_session); switch_core_thread_session_end(session);
} }
return JS_TRUE; return JS_TRUE;
} }

View File

@ -271,53 +271,54 @@ SWITCH_DECLARE(char *) switch_core_get_uuid(void)
static void *switch_core_service_thread(switch_thread_t *thread, void *obj) static void *switch_core_service_thread(switch_thread_t *thread, void *obj)
{ {
switch_core_thread_session_t *data = obj; switch_core_session_t *session = obj;
switch_core_session_t *session = data->objs[0];
int *stream_id_p = data->objs[1];
switch_channel_t *channel; switch_channel_t *channel;
switch_frame_t *read_frame; switch_frame_t *read_frame;
int stream_id = *stream_id_p;
switch_assert(thread != NULL); switch_assert(thread != NULL);
switch_assert(session != NULL); switch_assert(session != NULL);
switch_core_session_read_lock(session);
channel = switch_core_session_get_channel(session); channel = switch_core_session_get_channel(session);
switch_channel_set_flag(channel, CF_SERVICE); switch_channel_set_flag(channel, CF_SERVICE);
while (data->running > 0) { while (switch_channel_test_flag(channel, CF_SERVICE)) {
switch (switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, stream_id)) { switch (switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0)) {
case SWITCH_STATUS_SUCCESS: case SWITCH_STATUS_SUCCESS:
case SWITCH_STATUS_TIMEOUT: case SWITCH_STATUS_TIMEOUT:
case SWITCH_STATUS_BREAK: case SWITCH_STATUS_BREAK:
break; break;
default: default:
data->running = -1; switch_channel_clear_flag(channel, CF_SERVICE);
continue; continue;
} }
} }
switch_channel_clear_flag(channel, CF_SERVICE); switch_core_session_rwunlock(session);
data->running = 0;
return NULL; return NULL;
} }
/* Either add a timeout here or make damn sure the thread cannot get hung somehow (my preference) */ /* Either add a timeout here or make damn sure the thread cannot get hung somehow (my preference) */
SWITCH_DECLARE(void) switch_core_thread_session_end(switch_core_thread_session_t *thread_session) SWITCH_DECLARE(void) switch_core_thread_session_end(switch_core_session_t *session)
{ {
if (thread_session->running > 0) { switch_channel_t *channel;
thread_session->running = -1; switch_assert(session);
while (thread_session->running) { channel = switch_core_session_get_channel(session);
switch_yield(1000); switch_assert(channel);
}
} switch_channel_clear_flag(channel, CF_SERVICE);
} }
SWITCH_DECLARE(void) switch_core_service_session(switch_core_session_t *session, switch_core_thread_session_t *thread_session, int stream_id) SWITCH_DECLARE(void) switch_core_service_session(switch_core_session_t *session)
{ {
thread_session->running = 1; switch_channel_t *channel;
thread_session->objs[0] = session; switch_assert(session);
thread_session->objs[1] = &stream_id;
switch_core_session_launch_thread(session, switch_core_service_thread, thread_session); channel = switch_core_session_get_channel(session);
switch_assert(channel);
switch_core_session_launch_thread(session, switch_core_service_thread, session);
} }
/* This function abstracts the thread creation for modules by allowing you to pass a function ptr and /* This function abstracts the thread creation for modules by allowing you to pass a function ptr and

View File

@ -729,7 +729,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
switch_size_t olen = 0, llen = 0; switch_size_t olen = 0, llen = 0;
switch_frame_t write_frame = { 0 }; switch_frame_t write_frame = { 0 };
switch_timer_t timer = { 0 }; switch_timer_t timer = { 0 };
switch_core_thread_session_t thread_session = { 0 };
switch_codec_t codec; switch_codec_t codec;
switch_memory_pool_t *pool = switch_core_session_get_pool(session); switch_memory_pool_t *pool = switch_core_session_get_pool(session);
char *codec_name; char *codec_name;
@ -963,7 +962,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
if (timer_name) { if (timer_name) {
/* start a thread to absorb incoming audio */ /* start a thread to absorb incoming audio */
switch_core_service_session(session, &thread_session, 0); switch_core_service_session(session);
} }
ilen = samples; ilen = samples;
@ -1230,7 +1229,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
} }
if (timer_name) { if (timer_name) {
/* End the audio absorbing thread */ /* End the audio absorbing thread */
switch_core_thread_session_end(&thread_session); switch_core_thread_session_end(session);
switch_core_timer_destroy(&timer); switch_core_timer_destroy(&timer);
} }
@ -1842,7 +1841,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text(switch_core_session_t *ses
int interval = 0; int interval = 0;
switch_frame_t write_frame = { 0 }; switch_frame_t write_frame = { 0 };
switch_timer_t ltimer, *timer; switch_timer_t ltimer, *timer;
switch_core_thread_session_t thread_session = { 0 };
switch_codec_t lcodec, *codec; switch_codec_t lcodec, *codec;
switch_memory_pool_t *pool = switch_core_session_get_pool(session); switch_memory_pool_t *pool = switch_core_session_get_pool(session);
char *codec_name; char *codec_name;
@ -1948,7 +1946,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text(switch_core_session_t *ses
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Setup timer success %u bytes per %d ms!\n", sh->samples * 2, interval); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Setup timer success %u bytes per %d ms!\n", sh->samples * 2, interval);
} }
/* start a thread to absorb incoming audio */ /* start a thread to absorb incoming audio */
switch_core_service_session(session, &thread_session, 0); switch_core_service_session(session);
} }
@ -1962,7 +1960,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text(switch_core_session_t *ses
if (timer_name) { if (timer_name) {
/* End the audio absorbing thread */ /* End the audio absorbing thread */
switch_core_thread_session_end(&thread_session); switch_core_thread_session_end(session);
if (!cache_obj) { if (!cache_obj) {
switch_core_timer_destroy(timer); switch_core_timer_destroy(timer);
} }