From 76474a6fad43c791293f4fb30dc7c155619c5dec Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 22 Jun 2018 08:39:36 +0200 Subject: pthreadpool: expand test_create() to check unlimited, sync and one thread pool Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme --- lib/pthreadpool/tests_cmocka.c | 83 +++++++++++++++++++++++++++++++++++------- 1 file changed, 70 insertions(+), 13 deletions(-) (limited to 'lib/pthreadpool') diff --git a/lib/pthreadpool/tests_cmocka.c b/lib/pthreadpool/tests_cmocka.c index d80b8c8f775..677800892f6 100644 --- a/lib/pthreadpool/tests_cmocka.c +++ b/lib/pthreadpool/tests_cmocka.c @@ -33,7 +33,9 @@ struct pthreadpool_tevent_test { struct tevent_context *ev; - struct pthreadpool_tevent *pool; + struct pthreadpool_tevent *upool; + struct pthreadpool_tevent *spool; + struct pthreadpool_tevent *opool; }; static int setup_pthreadpool_tevent(void **state) @@ -47,7 +49,13 @@ static int setup_pthreadpool_tevent(void **state) t->ev = tevent_context_init(t); assert_non_null(t->ev); - ret = pthreadpool_tevent_init(t->ev, UINT_MAX, &t->pool); + ret = pthreadpool_tevent_init(t->ev, UINT_MAX, &t->upool); + assert_return_code(ret, 0); + + ret = pthreadpool_tevent_init(t->ev, 1, &t->opool); + assert_return_code(ret, 0); + + ret = pthreadpool_tevent_init(t->ev, 0, &t->spool); assert_return_code(ret, 0); *state = t; @@ -91,20 +99,27 @@ static void test_job_threadid(void *ptr) static int test_create_do(struct tevent_context *ev, struct pthreadpool_tevent *pool, + bool *executed, bool *in_main_thread) { struct tevent_req *req; - pthread_t main_thread, worker_thread; + pthread_t zero_thread; + pthread_t main_thread; + pthread_t worker_thread; bool ok; int ret; + *executed = false; + *in_main_thread = false; + + memset(&zero_thread, 0, sizeof(zero_thread)); main_thread = pthread_self(); + worker_thread = zero_thread; req = pthreadpool_tevent_job_send( ev, ev, pool, test_job_threadid, &worker_thread); if (req == NULL) { fprintf(stderr, "pthreadpool_tevent_job_send failed\n"); - TALLOC_FREE(ev); return ENOMEM; } @@ -113,20 +128,21 @@ static int test_create_do(struct tevent_context *ev, ret = errno; fprintf(stderr, "tevent_req_poll failed: %s\n", strerror(ret)); - TALLOC_FREE(ev); + *executed = !pthread_equal(worker_thread, zero_thread); + *in_main_thread = pthread_equal(worker_thread, main_thread); return ret; } ret = pthreadpool_tevent_job_recv(req); TALLOC_FREE(req); + *executed = !pthread_equal(worker_thread, zero_thread); + *in_main_thread = pthread_equal(worker_thread, main_thread); if (ret != 0) { fprintf(stderr, "tevent_req_recv failed: %s\n", strerror(ret)); - TALLOC_FREE(ev); return ret; } - *in_main_thread = pthread_equal(worker_thread, main_thread); return 0; } @@ -134,6 +150,7 @@ static int test_create_do(struct tevent_context *ev, static void test_create(void **state) { struct pthreadpool_tevent_test *t = *state; + bool executed; bool in_main_thread; int ret; @@ -142,16 +159,34 @@ static void test_create(void **state) * this job will run in the sync fallback in the main thread. */ will_return(__wrap_pthread_create, EAGAIN); - ret = test_create_do(t->ev, t->pool, &in_main_thread); - assert_return_code(ret, 0); + ret = test_create_do(t->ev, t->upool, &executed, &in_main_thread); + assert_int_equal(ret, EAGAIN); + assert_false(executed); + assert_false(in_main_thread); + + /* + * The sync pool won't trigger pthread_create() + * It will be triggered by the one pool. + */ + will_return(__wrap_pthread_create, EAGAIN); + + ret = test_create_do(t->ev, t->spool, &executed, &in_main_thread); + assert_int_equal(ret, 0); + assert_true(executed); assert_true(in_main_thread); + ret = test_create_do(t->ev, t->opool, &executed, &in_main_thread); + assert_int_equal(ret, EAGAIN); + assert_false(executed); + assert_false(in_main_thread); + /* * When a thread can be created, the job will run in the worker thread. */ will_return(__wrap_pthread_create, 0); - ret = test_create_do(t->ev, t->pool, &in_main_thread); - assert_return_code(ret, 0); + ret = test_create_do(t->ev, t->upool, &executed, &in_main_thread); + assert_int_equal(ret, 0); + assert_true(executed); assert_false(in_main_thread); poll(NULL, 0, 10); @@ -161,8 +196,30 @@ static void test_create(void **state) * running another job will also use the worker thread, even * if a new thread cannot be created. */ - ret = test_create_do(t->ev, t->pool, &in_main_thread); - assert_return_code(ret, 0); + ret = test_create_do(t->ev, t->upool, &executed, &in_main_thread); + assert_int_equal(ret, 0); + assert_true(executed); + assert_false(in_main_thread); + + /* + * When a thread can be created, the job will run in the worker thread. + */ + will_return(__wrap_pthread_create, 0); + ret = test_create_do(t->ev, t->opool, &executed, &in_main_thread); + assert_int_equal(ret, 0); + assert_true(executed); + assert_false(in_main_thread); + + poll(NULL, 0, 10); + + /* + * Workerthread will still be active for a second; immediately + * running another job will also use the worker thread, even + * if a new thread cannot be created. + */ + ret = test_create_do(t->ev, t->opool, &executed, &in_main_thread); + assert_int_equal(ret, 0); + assert_true(executed); assert_false(in_main_thread); } -- cgit v1.2.1