11 #include "pthreadpool_pipe.h"
12 #include "pthreadpool_tevent.h"
14 static int test_init(void)
16 struct pthreadpool_pipe *p;
19 ret = pthreadpool_pipe_init(1, &p);
21 fprintf(stderr, "pthreadpool_pipe_init failed: %s\n",
25 ret = pthreadpool_pipe_destroy(p);
27 fprintf(stderr, "pthreadpool_pipe_destroy failed: %s\n",
34 static void test_sleep(void *ptr)
36 int *ptimeout = (int *)ptr;
38 ret = poll(NULL, 0, *ptimeout);
40 fprintf(stderr, "poll returned %d (%s)\n",
41 ret, strerror(errno));
45 static int test_jobs(int num_threads, int num_jobs)
48 struct pthreadpool_pipe *p;
52 finished = (char *)calloc(1, num_jobs);
53 if (finished == NULL) {
54 fprintf(stderr, "calloc failed\n");
58 ret = pthreadpool_pipe_init(num_threads, &p);
60 fprintf(stderr, "pthreadpool_pipe_init failed: %s\n",
65 for (i=0; i<num_jobs; i++) {
66 ret = pthreadpool_pipe_add_job(p, i, test_sleep, &timeout);
68 fprintf(stderr, "pthreadpool_pipe_add_job failed: "
69 "%s\n", strerror(ret));
74 for (i=0; i<num_jobs; i++) {
76 ret = pthreadpool_pipe_finished_jobs(p, &jobid, 1);
78 fprintf(stderr, "pthreadpool_pipe_finished_jobs "
79 "failed: %s\n", strerror(-ret));
82 if ((ret != 1) || (jobid >= num_jobs)) {
83 fprintf(stderr, "invalid job number %d\n", jobid);
89 for (i=0; i<num_jobs; i++) {
90 if (finished[i] != 1) {
91 fprintf(stderr, "finished[%d] = %d\n",
97 ret = pthreadpool_pipe_destroy(p);
99 fprintf(stderr, "pthreadpool_pipe_destroy failed: %s\n",
108 static int test_busydestroy(void)
110 struct pthreadpool_pipe *p;
115 ret = pthreadpool_pipe_init(1, &p);
117 fprintf(stderr, "pthreadpool_pipe_init failed: %s\n",
121 ret = pthreadpool_pipe_add_job(p, 1, test_sleep, &timeout);
123 fprintf(stderr, "pthreadpool_pipe_add_job failed: %s\n",
127 ret = pthreadpool_pipe_destroy(p);
129 fprintf(stderr, "Could destroy a busy pool\n");
133 pfd.fd = pthreadpool_pipe_signal_fd(p);
134 pfd.events = POLLIN|POLLERR;
137 ret = poll(&pfd, 1, -1);
138 } while ((ret == -1) && (errno == EINTR));
140 ret = pthreadpool_pipe_finished_jobs(p, &jobid, 1);
142 fprintf(stderr, "pthreadpool_pipe_finished_jobs failed: %s\n",
147 ret = pthreadpool_pipe_destroy(p);
149 fprintf(stderr, "pthreadpool_pipe_destroy failed: %s\n",
156 static int test_fork(void)
158 struct pthreadpool_pipe *p;
162 ret = pthreadpool_pipe_init(1, &p);
164 fprintf(stderr, "pthreadpool_pipe_init failed: %s\n",
168 ret = pthreadpool_pipe_destroy(p);
170 fprintf(stderr, "pthreadpool_pipe_destroy failed: %s\n",
177 perror("fork failed");
183 waited = wait(&status);
185 perror("wait failed");
188 if (waited != child) {
189 fprintf(stderr, "expected child %d, got %d\n",
190 (int)child, (int)waited);
196 static void busyfork_job(void *private_data)
201 static int test_busyfork(void)
203 struct pthreadpool_pipe *p;
206 pid_t child, waitret;
207 int ret, jobnum, wstatus;
211 perror("pipe failed");
215 ret = pthreadpool_pipe_init(1, &p);
217 fprintf(stderr, "pthreadpool_pipe_init failed: %s\n",
222 ret = pthreadpool_pipe_add_job(p, 1, busyfork_job, NULL);
224 fprintf(stderr, "pthreadpool_add_job failed: %s\n",
229 ret = pthreadpool_pipe_finished_jobs(p, &jobnum, 1);
231 fprintf(stderr, "pthreadpool_pipe_finished_jobs failed\n");
235 ret = poll(NULL, 0, 200);
237 perror("poll failed");
243 perror("fork failed");
248 ret = pthreadpool_pipe_destroy(p);
250 fprintf(stderr, "pthreadpool_pipe_destroy failed: "
251 "%s\n", strerror(ret));
259 perror("close failed");
263 pfd = (struct pollfd) { .fd = fds[0], .events = POLLIN };
265 ret = poll(&pfd, 1, 5000);
267 perror("poll failed");
271 fprintf(stderr, "Child did not exit for 5 seconds\n");
273 * The child might hang forever in
274 * pthread_cond_destroy for example. Be kind to the
275 * system and kill it.
277 kill(child, SIGTERM);
281 fprintf(stderr, "poll returned %d -- huh??\n", ret);
285 ret = poll(NULL, 0, 200);
287 perror("poll failed");
291 waitret = waitpid(child, &wstatus, WNOHANG);
292 if (waitret != child) {
293 fprintf(stderr, "waitpid returned %d\n", (int)waitret);
297 if (!WIFEXITED(wstatus)) {
298 fprintf(stderr, "child did not properly exit\n");
302 ret = WEXITSTATUS(wstatus);
304 fprintf(stderr, "child returned %d\n", ret);
311 static void test_tevent_wait(void *private_data)
313 int *timeout = private_data;
314 poll(NULL, 0, *timeout);
317 static int test_tevent_1(void)
319 struct tevent_context *ev;
320 struct pthreadpool_tevent *pool;
321 struct tevent_req *req1, *req2;
323 int timeout100 = 100;
327 ev = tevent_context_init(NULL);
330 fprintf(stderr, "tevent_context_init failed: %s\n",
334 ret = pthreadpool_tevent_init(ev, 0, &pool);
336 fprintf(stderr, "pthreadpool_tevent_init failed: %s\n",
341 req1 = pthreadpool_tevent_job_send(
342 ev, ev, pool, test_tevent_wait, &timeout10);
344 fprintf(stderr, "pthreadpool_tevent_job_send failed\n");
348 req2 = pthreadpool_tevent_job_send(
349 ev, ev, pool, test_tevent_wait, &timeout100);
351 fprintf(stderr, "pthreadpool_tevent_job_send failed\n");
355 ok = tevent_req_poll(req2, ev);
358 fprintf(stderr, "tevent_req_poll failed: %s\n",
363 ret = pthreadpool_tevent_job_recv(req1);
366 fprintf(stderr, "tevent_req_poll failed: %s\n",
374 ret = tevent_loop_wait(ev);
376 fprintf(stderr, "tevent_loop_wait failed\n");
389 ret = test_tevent_1();
391 fprintf(stderr, "test_event_1 failed: %s\n",
398 fprintf(stderr, "test_init failed\n");
404 fprintf(stderr, "test_fork failed\n");
408 ret = test_jobs(10, 10000);
410 fprintf(stderr, "test_jobs failed\n");
414 ret = test_busydestroy();
416 fprintf(stderr, "test_busydestroy failed\n");
420 ret = test_busyfork();
422 fprintf(stderr, "test_busyfork failed\n");