summaryrefslogtreecommitdiff
path: root/lib/pthreadpool
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2018-06-22 08:39:36 +0200
committerStefan Metzmacher <metze@samba.org>2018-07-12 14:25:18 +0200
commit76474a6fad43c791293f4fb30dc7c155619c5dec (patch)
treef33b9155b215bad9d474090f498d37cb3b045665 /lib/pthreadpool
parentf1dac71a866857bc70a0477861997cc6174a00d9 (diff)
downloadsamba-76474a6fad43c791293f4fb30dc7c155619c5dec.tar.gz
pthreadpool: expand test_create() to check unlimited, sync and one thread pool
Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Ralph Boehme <slow@samba.org>
Diffstat (limited to 'lib/pthreadpool')
-rw-r--r--lib/pthreadpool/tests_cmocka.c83
1 files changed, 70 insertions, 13 deletions
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);
}