43#define CATEGORY "/res/res_pjsip/scheduler/"
60#define S2U(x) (long int)(x * 1000 * 1000)
61#define M2U(x) (long int)(x * 1000)
67 if (!
test->no_clear_done) {
71 test->tid = pthread_self();
81 return test->interval;
94 ast_mutex_lock(&(x)->lock); \
95 while (!(x)->done) { \
96 ast_cond_wait(&(x)->cond, &(x)->lock); \
99 ast_mutex_unlock(&(x)->lock); \
111 struct timeval task1_start;
113 ast_test_validate(
test, test_data1 !=
NULL);
114 ast_test_validate(
test, test_data2 !=
NULL);
116 test_data1->test =
test;
118 test_data1->interval = 2000;
119 test_data1->sleep = 1000;
123 test_data2->test =
test;
125 test_data2->interval = 2000;
126 test_data2->sleep = 1000;
132 (test_data1->interval + test_data1->sleep + (
MAX(test_data1->interval - test_data2->interval, 0)) + test_data2->sleep) / 1000.0);
134 ast_test_validate(
test, (tp1 !=
NULL));
137 ((
MAX(test_data1->interval, test_data2->interval) +
MAX(test_data1->sleep, test_data2->sleep)) / 1000.0));
141 ast_test_validate(
test, task1 !=
NULL);
144 ast_test_validate(
test, task2 !=
NULL);
148 ast_test_validate(
test, test_data1->is_servant);
150 duration =
ast_tvdiff_ms(test_data1->task_end, test_data1->test_start);
151 ast_test_validate(
test, (duration > ((test_data1->interval + test_data1->sleep) * 0.9))
152 && (duration < ((test_data1->interval + test_data1->sleep) * 1.1)));
156 ast_test_validate(
test, (delay > (test_data1->interval * 0.9)
157 && (delay < (test_data1->interval * 1.1))));
161 ast_test_validate(
test, test_data2->is_servant);
164 ast_test_validate(
test, test_data1->tid == test_data2->tid);
165 ast_test_validate(
test,
ast_tvdiff_ms(test_data2->task_start, test_data1->task_end) >= 0);
167 ast_test_validate(
test, test_data1->tid != test_data2->tid);
178 info->name = __func__;
180 info->summary =
"Test res_pjsip serialized scheduler";
181 info->description =
"Test res_pjsip serialized scheduler";
195 info->name = __func__;
197 info->summary =
"Test res_pjsip unserialized scheduler";
198 info->description =
"Test res_pjsip unserialized scheduler";
234 info->name = __func__;
236 info->summary =
"Test res_pjsip scheduler cleanup";
237 info->description =
"Test res_pjsip scheduler cleanup";
247 ast_test_validate(
test, sleep !=
NULL);
251 ((interval * 1.1) + *sleep) / 1000.0);
256 usleep(
M2U(interval * 0.5));
258 ast_test_validate(
test, (when > (interval * 0.4) && when < (interval * 0.6)));
259 usleep(
M2U(interval * 0.6));
266 ast_test_validate(
test, (when < 0), res,
error);
285 info->name = __func__;
287 info->summary =
"Test res_pjsip scheduler cancel task";
288 info->description =
"Test res_pjsip scheduler cancel task";
298 ast_test_validate(
test, sleep !=
NULL);
302 (interval + *sleep) / 1000.0);
307 usleep(
M2U(interval * 0.5));
309 ast_test_validate(
test, (when > (interval * 0.4) && when < (interval * 0.6)));
316 ast_test_validate(
test, when < 0);
318 usleep(
M2U(interval));
334 info->name = __func__;
336 info->summary =
"Test res_pjsip scheduler cancel task";
337 info->description =
"Test res_pjsip scheduler cancel task";
343 ast_test_validate(
test, test_data1 !=
NULL);
347 test_data1->test =
test;
349 test_data1->interval = 1000;
350 test_data1->sleep = 500;
351 test_data1->no_clear_done = 1;
356 ((test_data1->interval * 4) + test_data1->sleep) / 1000.0);
363 when =
ast_tvdiff_ms(test_data1->task_start, test_data1->test_start);
364 ast_test_validate(
test, when > test_data1->interval * 0.9 && when < test_data1->interval * 1.1);
367 when =
ast_tvdiff_ms(test_data1->task_start, test_data1->test_start);
368 ast_test_validate(
test, when > test_data1->interval * 2 * 0.9 && when < test_data1->interval * 2 * 1.1);
371 when =
ast_tvdiff_ms(test_data1->task_start, test_data1->test_start);
372 ast_test_validate(
test, when > test_data1->interval * 3 * 0.9 && when < test_data1->interval * 3 * 1.1);
377 usleep(
M2U(test_data1->interval));
380 if (test_data1->done) {
381 int done = test_data1->done;
383 test_data1->done = 0;
389 usleep(
M2U(test_data1->interval * 2));
392 if (test_data1->done != 0) {
430 .
requires =
"res_pjsip",
Asterisk main include file. File version handling, generic pbx functions.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define ao2_alloc(data_size, destructor_fn)
int ast_sip_sched_task_cancel_by_name(const char *name)
Cancels the next invocation of a task by name.
struct ast_taskprocessor * ast_sip_create_serializer(const char *name)
Create a new serializer for SIP tasks.
struct ast_sip_sched_task * ast_sip_schedule_task(struct ast_taskprocessor *serializer, int interval, ast_sip_task sip_task, const char *name, void *task_data, enum ast_sip_scheduler_task_flags flags)
Schedule a task to run in the res_pjsip thread pool.
int ast_sip_sched_task_cancel(struct ast_sip_sched_task *schtd)
Cancels the next invocation of a task.
int ast_sip_sched_is_task_running(struct ast_sip_sched_task *schtd)
Checks if the task is currently running.
int ast_sip_thread_is_servant(void)
Determine if the current thread is a SIP servant thread.
int ast_sip_sched_task_get_next_run(struct ast_sip_sched_task *schtd)
Gets the number of milliseconds until the next invocation.
int ast_sip_sched_task_get_times(struct ast_sip_sched_task *schtd, struct timeval *when_queued, struct timeval *last_start, struct timeval *last_end)
Gets the last start and end times of the task.
int ast_sip_sched_task_get_next_run_by_name(const char *name)
Gets the number of milliseconds until the next invocation.
int ast_sip_sched_is_task_running_by_name(const char *name)
Checks if the task is currently running.
@ AST_SIP_SCHED_TASK_FIXED
@ AST_SIP_SCHED_TASK_PERIODIC
The task is scheduled at multiples of interval.
@ AST_SIP_SCHED_TASK_DATA_AO2
@ AST_SIP_SCHED_TASK_DATA_FREE
@ AST_SIP_SCHED_TASK_DATA_NO_CLEANUP
#define ast_cond_destroy(cond)
#define ast_cond_init(cond, attr)
#define ast_mutex_init(pmutex)
#define ast_mutex_unlock(a)
pthread_cond_t ast_cond_t
#define ast_mutex_destroy(a)
#define ast_mutex_lock(a)
#define ast_cond_signal(cond)
Asterisk module definitions.
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
@ AST_MODULE_SUPPORT_CORE
#define ASTERISK_GPL_KEY
The text the key() function should return.
@ AST_MODULE_LOAD_SUCCESS
Structure for mutex and tracking information.
A ast_taskprocessor structure is a singleton by name.
Sorcery object created based on backend data.
struct timeval task_start
struct timeval test_start
An API for managing task processing threads that can be shared across modules.
void * ast_taskprocessor_unreference(struct ast_taskprocessor *tps)
Unreference the specified taskprocessor and its reference count will decrement.
#define AST_TEST_REGISTER(cb)
#define ast_test_status_update(a, b, c...)
#define AST_TEST_UNREGISTER(cb)
AST_TEST_DEFINE(serialized_scheduler)
static int task_1(void *data)
static int destruct_count
static int dummy_task(void *data)
static void test_destructor(void *data)
static void data_cleanup(void *data)
static int load_module(void)
static int unload_module(void)
static int scheduler(struct ast_test *test, int serialized)
static int task(void *data)
Queued task for baseline test.
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
int error(const char *format,...)
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.