]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
unit-tests: Fix cancel_onoff test
authorTobias Brunner <tobias@strongswan.org>
Mon, 20 Jul 2020 09:45:54 +0000 (11:45 +0200)
committerTobias Brunner <tobias@strongswan.org>
Mon, 20 Jul 2020 13:49:44 +0000 (15:49 +0200)
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.

src/libstrongswan/tests/suites/test_threading.c

index 34d06ac24603764ca8ecd8641eab3a2194493e35..140c4fd394cc2ec96534fed8b75d9a56a079dd65 100644 (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