unit-tests: Fix cancel_onoff test

If it takes a while to start one of the threads, another thread might already
have passed the usleep() call previously used and re-enabled cancelability
so that the loop that checked for it would never terminate.
This commit is contained in:
Tobias Brunner 2020-07-20 11:45:54 +02:00
parent 8a4e30ccef
commit edc7752802
1 changed files with 27 additions and 13 deletions

View File

@ -1118,17 +1118,22 @@ START_TEST(test_cancel)
}
END_TEST
static void *cancel_onoff_run(void *data)
typedef struct {
semaphore_t *sem;
bool cancellable;
} cancel_onoff_data_t;
static void *cancel_onoff_run(void *data_in)
{
bool *cancellable = (bool*)data;
cancel_onoff_data_t *data = (cancel_onoff_data_t*)data_in;
thread_cancelability(FALSE);
*cancellable = FALSE;
data->cancellable = FALSE;
/* we should not get cancelled here */
usleep(50000);
data->sem->wait(data->sem);
*cancellable = TRUE;
data->cancellable = TRUE;
thread_cancelability(TRUE);
/* but here */
@ -1142,28 +1147,37 @@ static void *cancel_onoff_run(void *data)
START_TEST(test_cancel_onoff)
{
thread_t *threads[THREADS];
bool cancellable[THREADS];
cancel_onoff_data_t data[THREADS];
semaphore_t *sem;
int i;
sem = semaphore_create(0);
for (i = 0; i < THREADS; i++)
{
cancellable[i] = TRUE;
threads[i] = thread_create(cancel_onoff_run, &cancellable[i]);
}
for (i = 0; i < THREADS; i++)
{
data[i].sem = sem;
data[i].cancellable = TRUE;
threads[i] = thread_create(cancel_onoff_run, &data[i]);
/* wait until thread has cleared its cancelability */
while (cancellable[i])
while (data[i].cancellable)
{
sched_yield();
}
}
for (i = 0; i < THREADS; i++)
{
threads[i]->cancel(threads[i]);
}
/* let all threads continue */
for (i = 0; i < THREADS; i++)
{
sem->post(sem);
}
for (i = 0; i < THREADS; i++)
{
threads[i]->join(threads[i]);
ck_assert(cancellable[i]);
ck_assert(data[i].cancellable);
}
sem->destroy(sem);
}
END_TEST