@ -53,6 +53,7 @@ struct test_data {
int interval ;
int sleep ;
int done ;
int no_clear_done ;
struct ast_test * test ;
} ;
@ -63,7 +64,9 @@ static int task_1(void *data)
{
struct test_data * test = data ;
test - > done = 0 ;
if ( ! test - > no_clear_done ) {
test - > done = 0 ;
}
test - > task_start = ast_tvnow ( ) ;
test - > tid = pthread_self ( ) ;
test - > is_servant = ast_sip_thread_is_servant ( ) ;
@ -71,7 +74,7 @@ static int task_1(void *data)
test - > task_end = ast_tvnow ( ) ;
ast_mutex_lock ( & test - > lock ) ;
test - > done = 1 ;
test - > done + + ;
ast_mutex_unlock ( & test - > lock ) ;
ast_cond_signal ( & test - > cond ) ;
@ -345,11 +348,12 @@ AST_TEST_DEFINE(scheduler_policy)
test_data1 - > test_start = ast_tvnow ( ) ;
test_data1 - > interval = 1000 ;
test_data1 - > sleep = 500 ;
test_data1 - > no_clear_done = 1 ;
ast_mutex_init ( & test_data1 - > lock ) ;
ast_cond_init ( & test_data1 - > cond , NULL ) ;
ast_test_status_update ( test , " This test will take about %3.1f seconds \n " ,
( ( test_data1 - > interval * 3 ) + test_data1 - > sleep ) / 1000.0 ) ;
( ( test_data1 - > interval * 4 ) + test_data1 - > sleep ) / 1000.0 ) ;
task = ast_sip_schedule_task ( NULL , test_data1 - > interval , task_1 , " test_1 " , test_data1 ,
AST_SIP_SCHED_TASK_DATA_NO_CLEANUP | AST_SIP_SCHED_TASK_PERIODIC ) ;
@ -368,8 +372,33 @@ AST_TEST_DEFINE(scheduler_policy)
ast_test_validate ( test , when > test_data1 - > interval * 3 * 0.9 & & when < test_data1 - > interval * 3 * 1.1 ) ;
ast_sip_sched_task_cancel ( task ) ;
ao2_ref ( task , - 1 ) ;
task = NULL ;
/* Wait a full interval in case a 4th call to test_1 happened before the cancel */
usleep ( M2U ( test_data1 - > interval ) ) ;
ast_mutex_lock ( & test_data1 - > lock ) ;
if ( test_data1 - > done ) {
int done = test_data1 - > done ;
test_data1 - > done = 0 ;
ast_mutex_unlock ( & test_data1 - > lock ) ;
ast_test_validate ( test , done = = 1 ) ;
/* Wait two full intervals to be certain no further calls to test_1. */
usleep ( M2U ( test_data1 - > interval * 2 ) ) ;
ast_mutex_lock ( & test_data1 - > lock ) ;
if ( test_data1 - > done ! = 0 ) {
ast_mutex_unlock ( & test_data1 - > lock ) ;
/* The cancelation failed so we need to prevent cleanup of
* test_data1 to prevent a crash from write - after - free . */
test_data1 = NULL ;
ast_test_status_update ( test , " Failed to cancel task " ) ;
return AST_TEST_FAIL ;
}
}
ast_mutex_unlock ( & test_data1 - > lock ) ;
return AST_TEST_PASS ;
}