diff --git a/src/switch_time.c b/src/switch_time.c index 4a70b60fca..fef5cfd3d7 100644 --- a/src/switch_time.c +++ b/src/switch_time.c @@ -38,6 +38,7 @@ #ifdef HAVE_TIMERFD_CREATE #include +#include #endif //#if defined(DARWIN) @@ -497,27 +498,27 @@ static switch_status_t _timerfd_next(switch_timer_t *timer) static switch_status_t _timerfd_check(switch_timer_t *timer, switch_bool_t step) { interval_timer_t *it = timer->private_info; - struct itimerspec val; - int diff; + struct pollfd pfd = { .events = POLLIN }; if (!it) { return SWITCH_STATUS_GENERR; } - timerfd_gettime(it->fd, &val); - diff = val.it_value.tv_nsec / 1000; + pfd.fd = it->fd; - if (diff > 0) { - /* still pending */ - timer->diff = diff; - return SWITCH_STATUS_FALSE; - } else { - /* timer pending */ + if (poll(&pfd, 1, 0) > 0) { + /* timer has fired */ timer->diff = 0; if (step) { _timerfd_step(timer); } + return SWITCH_STATUS_SUCCESS; + } else { + /* still pending */ + timer->diff = 1; + + return SWITCH_STATUS_FALSE; } } diff --git a/tests/unit/.gitignore b/tests/unit/.gitignore index 966fc80eb9..37a7064a16 100644 --- a/tests/unit/.gitignore +++ b/tests/unit/.gitignore @@ -36,6 +36,7 @@ switch_ulp_recover1 switch_ulp_recover2 switch_ulp_recover3 switch_ulp_recover4 +switch_timer switch_utils switch_vad switch_vpx diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am index a3c59059b3..cb974ee3a1 100644 --- a/tests/unit/Makefile.am +++ b/tests/unit/Makefile.am @@ -9,6 +9,7 @@ noinst_PROGRAMS+= switch_hold switch_sip noinst_PROGRAMS += switch_core_media noinst_PROGRAMS += test_mod_verto noinst_PROGRAMS += test_mod_event_socket +noinst_PROGRAMS += switch_timer if HAVE_PCAP noinst_PROGRAMS += switch_rtp_pcap diff --git a/tests/unit/switch_timer.c b/tests/unit/switch_timer.c new file mode 100644 index 0000000000..73e1bcb3e1 --- /dev/null +++ b/tests/unit/switch_timer.c @@ -0,0 +1,116 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2026, Anthony Minessale II + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is + * Anthony Minessale II + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Dmitry Verenitsin + * + * + * switch_timer.c -- timer tests + * + */ +#include +#include + +static int module_loaded = 0; + +FST_MINCORE_BEGIN("./conf") + +FST_SUITE_BEGIN(switch_timer) + +FST_SETUP_BEGIN() +{ + if (!module_loaded) { + const char *err = NULL; + switch_loadable_module_init(SWITCH_FALSE); + switch_loadable_module_load_module("", "CORE_SOFTTIMER_MODULE", SWITCH_TRUE, &err); + module_loaded = 1; + } +} +FST_SETUP_END() + +FST_TEARDOWN_BEGIN() +{ +} +FST_TEARDOWN_END() + +/* timer_check returns FALSE with non-zero diff when no tick has elapsed, + * returns SUCCESS with diff=0 after sleeping past the interval */ +FST_TEST_BEGIN(test_timer_check) +{ + switch_timer_t timer = { 0 }; + switch_status_t status; + + fst_requires(switch_core_timer_init(&timer, "soft", 20, 160, fst_pool) == SWITCH_STATUS_SUCCESS); + + /* immediately after init - no tick yet */ + status = switch_core_timer_check(&timer, SWITCH_FALSE); + fst_check(status == SWITCH_STATUS_FALSE); + fst_check(timer.diff != 0); + + /* sleep past the 20ms interval */ + switch_sleep(50000); /* 50ms */ + + /* now the tick should be detected */ + status = switch_core_timer_check(&timer, SWITCH_FALSE); + fst_check(status == SWITCH_STATUS_SUCCESS); + fst_check(timer.diff == 0); + + switch_core_timer_destroy(&timer); +} +FST_TEST_END() + +/* step=FALSE does not advance tick/samplecount, step=TRUE advances by exactly 1 tick */ +FST_TEST_BEGIN(test_timer_check_step) +{ + switch_timer_t timer = { 0 }; + switch_size_t tick_before; + uint32_t samplecount_before; + switch_status_t status; + + fst_requires(switch_core_timer_init(&timer, "soft", 20, 160, fst_pool) == SWITCH_STATUS_SUCCESS); + + switch_sleep(50000); /* 50ms - let the timer tick */ + + tick_before = timer.tick; + samplecount_before = timer.samplecount; + + /* step=FALSE: reports ready but does not advance */ + status = switch_core_timer_check(&timer, SWITCH_FALSE); + fst_check(status == SWITCH_STATUS_SUCCESS); + fst_check(timer.tick == tick_before); + fst_check(timer.samplecount == samplecount_before); + + /* step=TRUE: advances tick by 1, samplecount by samples */ + status = switch_core_timer_check(&timer, SWITCH_TRUE); + fst_check(status == SWITCH_STATUS_SUCCESS); + fst_check(timer.tick == tick_before + 1); + fst_check(timer.samplecount == samplecount_before + 160); + + switch_core_timer_destroy(&timer); +} +FST_TEST_END() + +FST_SUITE_END() + +FST_MINCORE_END()