ctdb-protocol: Add marshalling for tdb_data with size
[Samba.git] / lib / pthreadpool / tests.c
blobc4d2e6a138236d3dd5b528875fd58797899a1eeb
1 #include <stdio.h>
2 #include <string.h>
3 #include <poll.h>
4 #include <errno.h>
5 #include <stdlib.h>
6 #include <pthread.h>
7 #include <unistd.h>
8 #include <sys/types.h>
9 #include <sys/wait.h>
10 #include "pthreadpool_pipe.h"
11 #include "pthreadpool_tevent.h"
13 static int test_init(void)
15 struct pthreadpool_pipe *p;
16 int ret;
18 ret = pthreadpool_pipe_init(1, &p);
19 if (ret != 0) {
20 fprintf(stderr, "pthreadpool_pipe_init failed: %s\n",
21 strerror(ret));
22 return -1;
24 ret = pthreadpool_pipe_destroy(p);
25 if (ret != 0) {
26 fprintf(stderr, "pthreadpool_pipe_destroy failed: %s\n",
27 strerror(ret));
28 return -1;
30 return 0;
33 static void test_sleep(void *ptr)
35 int *ptimeout = (int *)ptr;
36 int ret;
37 ret = poll(NULL, 0, *ptimeout);
38 if (ret != 0) {
39 fprintf(stderr, "poll returned %d (%s)\n",
40 ret, strerror(errno));
44 static int test_jobs(int num_threads, int num_jobs)
46 char *finished;
47 struct pthreadpool_pipe *p;
48 int timeout = 1;
49 int i, ret;
51 finished = (char *)calloc(1, num_jobs);
52 if (finished == NULL) {
53 fprintf(stderr, "calloc failed\n");
54 return -1;
57 ret = pthreadpool_pipe_init(num_threads, &p);
58 if (ret != 0) {
59 fprintf(stderr, "pthreadpool_pipe_init failed: %s\n",
60 strerror(ret));
61 return -1;
64 for (i=0; i<num_jobs; i++) {
65 ret = pthreadpool_pipe_add_job(p, i, test_sleep, &timeout);
66 if (ret != 0) {
67 fprintf(stderr, "pthreadpool_pipe_add_job failed: "
68 "%s\n", strerror(ret));
69 return -1;
73 for (i=0; i<num_jobs; i++) {
74 int jobid = -1;
75 ret = pthreadpool_pipe_finished_jobs(p, &jobid, 1);
76 if (ret < 0) {
77 fprintf(stderr, "pthreadpool_pipe_finished_jobs "
78 "failed: %s\n", strerror(-ret));
79 return -1;
81 if ((ret != 1) || (jobid >= num_jobs)) {
82 fprintf(stderr, "invalid job number %d\n", jobid);
83 return -1;
85 finished[jobid] += 1;
88 for (i=0; i<num_jobs; i++) {
89 if (finished[i] != 1) {
90 fprintf(stderr, "finished[%d] = %d\n",
91 i, finished[i]);
92 return -1;
96 ret = pthreadpool_pipe_destroy(p);
97 if (ret != 0) {
98 fprintf(stderr, "pthreadpool_pipe_destroy failed: %s\n",
99 strerror(ret));
100 return -1;
103 free(finished);
104 return 0;
107 static int test_busydestroy(void)
109 struct pthreadpool_pipe *p;
110 int timeout = 50;
111 struct pollfd pfd;
112 int ret, jobid;
114 ret = pthreadpool_pipe_init(1, &p);
115 if (ret != 0) {
116 fprintf(stderr, "pthreadpool_pipe_init failed: %s\n",
117 strerror(ret));
118 return -1;
120 ret = pthreadpool_pipe_add_job(p, 1, test_sleep, &timeout);
121 if (ret != 0) {
122 fprintf(stderr, "pthreadpool_pipe_add_job failed: %s\n",
123 strerror(ret));
124 return -1;
126 ret = pthreadpool_pipe_destroy(p);
127 if (ret != EBUSY) {
128 fprintf(stderr, "Could destroy a busy pool\n");
129 return -1;
132 pfd.fd = pthreadpool_pipe_signal_fd(p);
133 pfd.events = POLLIN|POLLERR;
135 do {
136 ret = poll(&pfd, 1, -1);
137 } while ((ret == -1) && (errno == EINTR));
139 ret = pthreadpool_pipe_finished_jobs(p, &jobid, 1);
140 if (ret < 0) {
141 fprintf(stderr, "pthreadpool_pipe_finished_jobs failed: %s\n",
142 strerror(-ret));
143 return -1;
146 ret = pthreadpool_pipe_destroy(p);
147 if (ret != 0) {
148 fprintf(stderr, "pthreadpool_pipe_destroy failed: %s\n",
149 strerror(ret));
150 return -1;
152 return 0;
155 static int test_fork(void)
157 struct pthreadpool_pipe *p;
158 pid_t child, waited;
159 int status, ret;
161 ret = pthreadpool_pipe_init(1, &p);
162 if (ret != 0) {
163 fprintf(stderr, "pthreadpool_pipe_init failed: %s\n",
164 strerror(ret));
165 return -1;
167 ret = pthreadpool_pipe_destroy(p);
168 if (ret != 0) {
169 fprintf(stderr, "pthreadpool_pipe_destroy failed: %s\n",
170 strerror(ret));
171 return -1;
174 child = fork();
175 if (child < 0) {
176 perror("fork failed");
177 return -1;
179 if (child == 0) {
180 exit(0);
182 waited = wait(&status);
183 if (waited == -1) {
184 perror("wait failed");
185 return -1;
187 if (waited != child) {
188 fprintf(stderr, "expected child %d, got %d\n",
189 (int)child, (int)waited);
190 return -1;
192 return 0;
195 static void test_tevent_wait(void *private_data)
197 int *timeout = private_data;
198 poll(NULL, 0, *timeout);
201 static int test_tevent_1(void)
203 struct tevent_context *ev;
204 struct pthreadpool_tevent *pool;
205 struct tevent_req *req1, *req2;
206 int timeout10 = 10;
207 int timeout100 = 100;
208 int ret;
209 bool ok;
211 ev = tevent_context_init(NULL);
212 if (ev == NULL) {
213 ret = errno;
214 fprintf(stderr, "tevent_context_init failed: %s\n",
215 strerror(ret));
216 return ret;
218 ret = pthreadpool_tevent_init(ev, 0, &pool);
219 if (ret != 0) {
220 fprintf(stderr, "pthreadpool_tevent_init failed: %s\n",
221 strerror(ret));
222 TALLOC_FREE(ev);
223 return ret;
225 req1 = pthreadpool_tevent_job_send(
226 ev, ev, pool, test_tevent_wait, &timeout10);
227 if (req1 == NULL) {
228 fprintf(stderr, "pthreadpool_tevent_job_send failed\n");
229 TALLOC_FREE(ev);
230 return ENOMEM;
232 req2 = pthreadpool_tevent_job_send(
233 ev, ev, pool, test_tevent_wait, &timeout100);
234 if (req2 == NULL) {
235 fprintf(stderr, "pthreadpool_tevent_job_send failed\n");
236 TALLOC_FREE(ev);
237 return ENOMEM;
239 ok = tevent_req_poll(req2, ev);
240 if (!ok) {
241 ret = errno;
242 fprintf(stderr, "tevent_req_poll failed: %s\n",
243 strerror(ret));
244 TALLOC_FREE(ev);
245 return ret;
247 ret = pthreadpool_tevent_job_recv(req1);
248 TALLOC_FREE(req1);
249 if (ret != 0) {
250 fprintf(stderr, "tevent_req_poll failed: %s\n",
251 strerror(ret));
252 TALLOC_FREE(ev);
253 return ret;
256 TALLOC_FREE(req2);
258 ret = tevent_loop_wait(ev);
259 if (ret != 0) {
260 fprintf(stderr, "tevent_loop_wait failed\n");
261 return ret;
264 TALLOC_FREE(pool);
265 TALLOC_FREE(ev);
266 return 0;
269 int main(void)
271 int ret;
273 ret = test_tevent_1();
274 if (ret != 0) {
275 fprintf(stderr, "test_event_1 failed: %s\n",
276 strerror(ret));
277 return 1;
280 ret = test_init();
281 if (ret != 0) {
282 fprintf(stderr, "test_init failed\n");
283 return 1;
286 ret = test_fork();
287 if (ret != 0) {
288 fprintf(stderr, "test_fork failed\n");
289 return 1;
292 ret = test_jobs(10, 10000);
293 if (ret != 0) {
294 fprintf(stderr, "test_jobs failed\n");
295 return 1;
298 ret = test_busydestroy();
299 if (ret != 0) {
300 fprintf(stderr, "test_busydestroy failed\n");
301 return 1;
304 printf("success\n");
305 return 0;