From 2294d90653a7328b5d31502d0a7a2205db875ca2 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 11 Mar 2008 16:55:58 +0000 Subject: [PATCH] fix a bunch more stuff that broke from fixing it yesterday! git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@7857 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/include/switch_core.h | 5 ++- src/include/switch_module_interfaces.h | 6 +++- src/switch_core_timer.c | 33 ++++++++++++------- src/switch_ivr_play_say.c | 2 +- src/switch_rtp.c | 26 +++++++-------- src/switch_time.c | 44 ++++++++++++++++++++------ 6 files changed, 79 insertions(+), 37 deletions(-) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 0a00129c20..cf184a3220 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -977,12 +977,15 @@ SWITCH_DECLARE(switch_status_t) switch_core_timer_next(switch_timer_t *timer); */ SWITCH_DECLARE(switch_status_t) switch_core_timer_step(switch_timer_t *timer); +SWITCH_DECLARE(switch_status_t) switch_core_timer_sync(switch_timer_t *timer); + /*! \brief Check if the current step has been exceeded \param timer the timer to wait on + \param step increment timer if a tick was detected \return the newest sample count */ -SWITCH_DECLARE(switch_status_t) switch_core_timer_check(switch_timer_t *timer); +SWITCH_DECLARE(switch_status_t) switch_core_timer_check(switch_timer_t *timer, switch_bool_t step); /*! \brief Destroy an allocated timer diff --git a/src/include/switch_module_interfaces.h b/src/include/switch_module_interfaces.h index 2fdb28437d..26a375467c 100644 --- a/src/include/switch_module_interfaces.h +++ b/src/include/switch_module_interfaces.h @@ -202,12 +202,14 @@ struct switch_timer { void *private_info; /*! remaining time from last call to _check()*/ switch_size_t diff; + switch_size_t tick; }; typedef enum { SWITCH_TIMER_FUNC_TIMER_INIT, SWITCH_TIMER_FUNC_TIMER_NEXT, SWITCH_TIMER_FUNC_TIMER_STEP, + SWITCH_TIMER_FUNC_TIMER_SYNC, SWITCH_TIMER_FUNC_TIMER_CHECK, SWITCH_TIMER_FUNC_TIMER_DESTROY } switch_timer_func_name_t; @@ -222,8 +224,10 @@ struct switch_timer_interface { switch_status_t (*timer_next) (switch_timer_t *); /*! function to step the timer one step */ switch_status_t (*timer_step) (switch_timer_t *); + /*! function to reset the timer */ + switch_status_t (*timer_sync) (switch_timer_t *); /*! function to check if the current step has expired */ - switch_status_t (*timer_check) (switch_timer_t *); + switch_status_t (*timer_check) (switch_timer_t *, switch_bool_t); /*! function to deallocate the timer */ switch_status_t (*timer_destroy) (switch_timer_t *); struct switch_timer_interface *next; diff --git a/src/switch_core_timer.c b/src/switch_core_timer.c index 9c3d1bd26a..158306ef2e 100644 --- a/src/switch_core_timer.c +++ b/src/switch_core_timer.c @@ -40,7 +40,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_timer_init(switch_timer_t *timer, co switch_timer_interface_t *timer_interface; switch_status_t status; memset(timer, 0, sizeof(*timer)); - if ((timer_interface = switch_loadable_module_get_timer_interface(timer_name)) == 0) { + if ((timer_interface = switch_loadable_module_get_timer_interface(timer_name)) == 0 || !timer_interface->timer_init) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "invalid timer %s!\n", timer_name); return SWITCH_STATUS_GENERR; } @@ -66,8 +66,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_timer_init(switch_timer_t *timer, co SWITCH_DECLARE(switch_status_t) switch_core_timer_next(switch_timer_t *timer) { - if (!timer->timer_interface) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Timer is not initialized!\n"); + if (!timer->timer_interface || !timer->timer_interface->timer_next) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Timer is not properly configured.\n"); return SWITCH_STATUS_GENERR; } @@ -81,29 +81,40 @@ SWITCH_DECLARE(switch_status_t) switch_core_timer_next(switch_timer_t *timer) SWITCH_DECLARE(switch_status_t) switch_core_timer_step(switch_timer_t *timer) { - if (!timer->timer_interface) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Timer is not initialized!\n"); + if (!timer->timer_interface || !timer->timer_interface->timer_step) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Timer is not properly configured.\n"); return SWITCH_STATUS_GENERR; } return timer->timer_interface->timer_step(timer); } -SWITCH_DECLARE(switch_status_t) switch_core_timer_check(switch_timer_t *timer) + +SWITCH_DECLARE(switch_status_t) switch_core_timer_sync(switch_timer_t *timer) { - if (!timer->timer_interface) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Timer is not initialized!\n"); + if (!timer->timer_interface || !timer->timer_interface->timer_sync) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Timer is not properly configured.\n"); return SWITCH_STATUS_GENERR; } - return timer->timer_interface->timer_check(timer); + return timer->timer_interface->timer_sync(timer); +} + +SWITCH_DECLARE(switch_status_t) switch_core_timer_check(switch_timer_t *timer, switch_bool_t step) +{ + if (!timer->timer_interface || !timer->timer_interface->timer_check) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Timer is not properly configured.\n"); + return SWITCH_STATUS_GENERR; + } + + return timer->timer_interface->timer_check(timer, step); } SWITCH_DECLARE(switch_status_t) switch_core_timer_destroy(switch_timer_t *timer) { - if (!timer->timer_interface) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Timer is not initialized!\n"); + if (!timer->timer_interface || !timer->timer_interface->timer_destroy) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Timer is not properly configured.\n"); return SWITCH_STATUS_GENERR; } diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c index 5e213e9298..6189da51a7 100644 --- a/src/switch_ivr_play_say.c +++ b/src/switch_ivr_play_say.c @@ -1057,7 +1057,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess while (switch_channel_ready(channel) && switch_channel_test_flag(channel, CF_HOLD)) { switch_yield(10000); } - + tstatus = switch_core_session_read_frame(session, &read_frame, -1, 0); if (!SWITCH_READ_ACCEPTABLE(tstatus)) { diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 902600e6d6..06d1fdf8f3 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -1032,7 +1032,6 @@ static void do_2833(switch_rtp_t *rtp_session) rtp_session->last_write_ts = rtp_session->dtmf_data.timestamp_dtmf + rtp_session->dtmf_data.out_digit_sub_sofar; rtp_session->sending_dtmf = 0; if (rtp_session->timer.interval) { - switch_core_timer_check(&rtp_session->timer); rtp_session->last_write_samplecount = rtp_session->timer.samplecount; rtp_session->next_write_samplecount = rtp_session->timer.samplecount + samples * 5; } @@ -1044,7 +1043,6 @@ static void do_2833(switch_rtp_t *rtp_session) void *pop; if (rtp_session->timer.interval) { - switch_core_timer_check(&rtp_session->timer); if (rtp_session->timer.samplecount < rtp_session->next_write_samplecount) { return; } @@ -1069,7 +1067,6 @@ static void do_2833(switch_rtp_t *rtp_session) rtp_session->dtmf_data.timestamp_dtmf = rtp_session->last_write_ts + samples; if (rtp_session->timer.interval) { - switch_core_timer_check(&rtp_session->timer); offset = rtp_session->timer.samplecount - rtp_session->last_write_samplecount; if (offset > 0) { rtp_session->dtmf_data.timestamp_dtmf = (uint32_t)(rtp_session->dtmf_data.timestamp_dtmf + offset); @@ -1121,6 +1118,11 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ bytes = sizeof(rtp_msg_t); status = switch_socket_recvfrom(rtp_session->from_addr, rtp_session->sock, 0, (void *) &rtp_session->recv_msg, &bytes); + if (bytes < 0) { + ret = (int) bytes; + goto end; + } + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_BREAK)) { switch_clear_flag_locked(rtp_session, SWITCH_RTP_FLAG_BREAK); bytes = 0; @@ -1134,9 +1136,13 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ ret = (int) bytes; goto end; } - - if (!SWITCH_STATUS_IS_BREAK(status) && rtp_session->timer.interval) { - switch_core_timer_step(&rtp_session->timer); + + if (rtp_session->timer.interval) { + if (bytes) { + check++; + switch_core_timer_sync(&rtp_session->timer); + } + check = (uint8_t) (switch_core_timer_check(&rtp_session->timer, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS); } if (bytes && rtp_session->recv_msg.header.version != 2) { @@ -1284,14 +1290,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ goto end; } - if (bytes < 0) { - ret = (int) bytes; - goto end; - } - if (rtp_session->timer.interval) { - check = (uint8_t) (switch_core_timer_check(&rtp_session->timer) == SWITCH_STATUS_SUCCESS); - if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_AUTO_CNG) && rtp_session->timer.samplecount >= (rtp_session->last_write_samplecount + (rtp_session->samples_per_interval * 50))) { uint8_t data[10] = { 0 }; @@ -1804,7 +1803,6 @@ static int rtp_common_write(switch_rtp_t *rtp_session, } if (rtp_session->timer.interval) { - switch_core_timer_check(&rtp_session->timer); rtp_session->last_write_samplecount = rtp_session->timer.samplecount; } rtp_session->last_write_ts = this_ts; diff --git a/src/switch_time.c b/src/switch_time.c index de4c8a1154..eed551ec8f 100644 --- a/src/switch_time.c +++ b/src/switch_time.c @@ -184,6 +184,7 @@ static switch_status_t timer_init(switch_timer_t *timer) private_info->reference = private_info->start = TIMER_MATRIX[timer->interval].tick;\ }\ + static switch_status_t timer_step(switch_timer_t *timer) { timer_private_t *private_info = timer->private_info; @@ -202,11 +203,32 @@ static switch_status_t timer_step(switch_timer_t *timer) } timer->samplecount = (uint32_t) samples; - private_info->reference = TIMER_MATRIX[timer->interval].tick + 1; - + private_info->reference++; + return SWITCH_STATUS_SUCCESS; } +static switch_status_t timer_sync(switch_timer_t *timer) +{ + timer_private_t *private_info = timer->private_info; + + if (globals.RUNNING != 1 || private_info->ready == 0) { + return SWITCH_STATUS_FALSE; + } + + /* sync the clock */ + private_info->reference = timer->tick = TIMER_MATRIX[timer->interval].tick; + + /* apply timestamp */ + if (timer_step(timer) == SWITCH_STATUS_SUCCESS) { + /* push the reference into the future 2 more intervals to prevent collision */ + private_info->reference += 2; + } + + return SWITCH_STATUS_SUCCESS; +} + + static switch_status_t timer_next(switch_timer_t *timer) { timer_private_t *private_info = timer->private_info; @@ -225,7 +247,7 @@ static switch_status_t timer_next(switch_timer_t *timer) return SWITCH_STATUS_FALSE; } -static switch_status_t timer_check(switch_timer_t *timer) +static switch_status_t timer_check(switch_timer_t *timer, switch_bool_t step) { timer_private_t *private_info = timer->private_info; switch_status_t status = SWITCH_STATUS_SUCCESS; @@ -236,18 +258,21 @@ static switch_status_t timer_check(switch_timer_t *timer) check_roll(); - if (TIMER_MATRIX[timer->interval].tick < private_info->reference) { - timer->diff = private_info->reference - TIMER_MATRIX[timer->interval].tick; + timer->tick = TIMER_MATRIX[timer->interval].tick; + + if (timer->tick < private_info->reference) { + timer->diff = private_info->reference - timer->tick; } else { timer->diff = 0; } - - if (timer->diff) { + + if (timer->diff) { status = SWITCH_STATUS_FALSE; - } else { + } else if (step) { timer_step(timer); } + return status; } @@ -348,7 +373,7 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime) } index = (current_ms % i == 0) ? i : 0; - + if (TIMER_MATRIX[index].count) { TIMER_MATRIX[index].tick++; if (TIMER_MATRIX[x].tick == MAX_TICK) { @@ -382,6 +407,7 @@ SWITCH_MODULE_LOAD_FUNCTION(softtimer_load) timer_interface->timer_init = timer_init; timer_interface->timer_next = timer_next; timer_interface->timer_step = timer_step; + timer_interface->timer_sync = timer_sync; timer_interface->timer_check = timer_check; timer_interface->timer_destroy = timer_destroy;