diff --git a/test/test-barrier.c b/test/test-barrier.c index dfd2dbde..89858db5 100644 --- a/test/test-barrier.c +++ b/test/test-barrier.c @@ -104,3 +104,45 @@ TEST_IMPL(barrier_3) { return 0; } + +static void serial_worker(void* data) { + uv_barrier_t* barrier; + + barrier = data; + if (uv_barrier_wait(barrier) > 0) + uv_barrier_destroy(barrier); + + uv_sleep(100); /* Wait a bit before terminating. */ +} + +/* Ensure that uv_barrier_wait returns positive only after all threads have + * exited the barrier. If this value is returned too early and the barrier is + * destroyed prematurely, then this test may see a crash. */ +TEST_IMPL(barrier_serial_thread) { + uv_thread_t threads[4]; + uv_barrier_t barrier; + unsigned i; + + ASSERT(0 == uv_barrier_init(&barrier, ARRAY_SIZE(threads) + 1)); + + for (i = 0; i < ARRAY_SIZE(threads); ++i) + ASSERT(0 == uv_thread_create(&threads[i], serial_worker, &barrier)); + + if (uv_barrier_wait(&barrier) > 0) + uv_barrier_destroy(&barrier); + + for (i = 0; i < ARRAY_SIZE(threads); ++i) + ASSERT(0 == uv_thread_join(&threads[i])); + + return 0; +} + +/* Single thread uv_barrier_wait should return correct return value. */ +TEST_IMPL(barrier_serial_thread_single) { + uv_barrier_t barrier; + + ASSERT(0 == uv_barrier_init(&barrier, 1)); + ASSERT(0 < uv_barrier_wait(&barrier)); + uv_barrier_destroy(&barrier); + return 0; +} diff --git a/test/test-list.h b/test/test-list.h index 75fbe9e4..1bd062da 100644 --- a/test/test-list.h +++ b/test/test-list.h @@ -37,6 +37,8 @@ TEST_DECLARE (default_loop_close) TEST_DECLARE (barrier_1) TEST_DECLARE (barrier_2) TEST_DECLARE (barrier_3) +TEST_DECLARE (barrier_serial_thread) +TEST_DECLARE (barrier_serial_thread_single) TEST_DECLARE (condvar_1) TEST_DECLARE (condvar_2) TEST_DECLARE (condvar_3) @@ -459,6 +461,8 @@ TASK_LIST_START TEST_ENTRY (barrier_1) TEST_ENTRY (barrier_2) TEST_ENTRY (barrier_3) + TEST_ENTRY (barrier_serial_thread) + TEST_ENTRY (barrier_serial_thread_single) TEST_ENTRY (condvar_1) TEST_ENTRY (condvar_2) TEST_ENTRY (condvar_3)