]>
Commit | Line | Data |
---|---|---|
687a72a0 JF |
1 | /* |
2 | * Copyright (c) 2015-2020 Red Hat, Inc. | |
3 | * | |
4 | * All rights reserved. | |
5 | * | |
6 | * Author: Jan Friesse (jfriesse@redhat.com) | |
7 | * | |
8 | * This software licensed under BSD license, the text of which follows: | |
9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions are met: | |
12 | * | |
13 | * - Redistributions of source code must retain the above copyright notice, | |
14 | * this list of conditions and the following disclaimer. | |
15 | * - Redistributions in binary form must reproduce the above copyright notice, | |
16 | * this list of conditions and the following disclaimer in the documentation | |
17 | * and/or other materials provided with the distribution. | |
18 | * - Neither the name of the Red Hat, Inc. nor the names of its | |
19 | * contributors may be used to endorse or promote products derived from this | |
20 | * software without specific prior written permission. | |
21 | * | |
22 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
23 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |
26 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
29 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
30 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
31 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | |
32 | * THE POSSIBILITY OF SUCH DAMAGE. | |
33 | */ | |
34 | ||
35 | #include <stdio.h> | |
36 | #include <assert.h> | |
37 | #include <string.h> | |
38 | #include <errno.h> | |
39 | #include <unistd.h> | |
40 | ||
41 | #include "pr-poll-loop.h" | |
42 | ||
43 | /* | |
44 | * Needed for creating nspr handle from unix fd | |
45 | */ | |
46 | #include <private/pprio.h> | |
47 | ||
48 | #define BUF_SIZE 256 | |
49 | ||
50 | #define TIMER_TIMEOUT 10000 | |
51 | #define TIMER_TEST_TIMEOUT 100 | |
52 | /* | |
53 | * Must be smaller than BUF_SIZE | |
54 | */ | |
55 | #define READ_STR "test" | |
56 | ||
ea6d7a90 JF |
57 | static int fd_set_events_cb1_return_called = -1; |
58 | static int fd_set_events_cb2_return_called = -1; | |
59 | static int fd_read_cb1_called = -1; | |
60 | static int fd_read_cb2_called = -1; | |
61 | static int fd_write_cb1_called = -1; | |
62 | static int fd_err_cb1_called = -1; | |
63 | static int timeout_cb_called = -1; | |
64 | ||
65 | static int prfd_set_events_cb1_return_called = -1; | |
66 | static int prfd_set_events_cb2_return_called = -1; | |
67 | static int prfd_read_cb1_called = -1; | |
68 | static int prfd_read_cb2_called = -1; | |
69 | static int prfd_write_cb1_called = -1; | |
70 | static int prfd_err_cb1_called = -1; | |
71 | ||
72 | static int test_complex_state = -1; | |
73 | static int test_complex_set_events_pipe1_read_called = -1; | |
74 | static int test_complex_read_pipe1_read_called = -1; | |
75 | static int test_complex_set_events_pipe1_write_called = -1; | |
76 | static int test_complex_write_pipe1_write_called = -1; | |
77 | static int test_complex_set_events_pipe2_read_called = -1; | |
78 | static int test_complex_read_pipe2_read_called = -1; | |
79 | static int test_complex_set_events_pipe2_write_called = -1; | |
80 | static int test_complex_write_pipe2_write_called = -1; | |
81 | static int test_complex_read_pipe1_fd = -1; | |
82 | ||
83 | static int pre_poll_cb1_called = -1; | |
84 | static int pre_poll_cb2_called = -1; | |
85 | static int pre_poll_cb_return_called = -1; | |
e7ef3641 | 86 | |
687a72a0 JF |
87 | static int |
88 | timeout_cb(void *data1, void *data2) | |
89 | { | |
90 | ||
91 | timeout_cb_called = 1; | |
92 | ||
93 | return (0); | |
94 | } | |
95 | ||
96 | static int | |
97 | fd_set_events_cb1_return(int fd, short *events, void *user_data1, void *user_data2) | |
98 | { | |
99 | ||
100 | fd_set_events_cb1_return_called++; | |
101 | ||
102 | assert(user_data1 == &fd_set_events_cb1_return_called); | |
103 | assert(user_data2 == NULL); | |
104 | ||
105 | return (-2); | |
106 | } | |
107 | ||
108 | static int | |
109 | fd_set_events_cb2_return(int fd, short *events, void *user_data1, void *user_data2) | |
110 | { | |
111 | ||
112 | fd_set_events_cb2_return_called++; | |
113 | ||
114 | assert(user_data1 == NULL); | |
115 | assert(user_data2 == &fd_set_events_cb2_return_called); | |
116 | ||
117 | return (-2); | |
118 | } | |
119 | ||
120 | static int | |
121 | fd_read_cb1(int fd, void *user_data1, void *user_data2) | |
122 | { | |
123 | char buf[BUF_SIZE]; | |
124 | ||
125 | assert(user_data1 == &fd_read_cb1_called); | |
126 | assert(user_data2 == fd_read_cb1); | |
127 | ||
128 | fd_read_cb1_called++; | |
129 | ||
130 | assert(read(fd, buf, BUF_SIZE) == strlen(READ_STR) + 1); | |
131 | assert(memcmp(buf, READ_STR, strlen(READ_STR) + 1) == 0); | |
132 | ||
133 | return (0); | |
134 | } | |
135 | ||
136 | static int | |
137 | fd_read_cb2(int fd, void *user_data1, void *user_data2) | |
138 | { | |
139 | char buf[BUF_SIZE]; | |
140 | ||
141 | assert(user_data1 == &fd_read_cb2_called); | |
142 | assert(user_data2 == fd_read_cb2); | |
143 | ||
144 | fd_read_cb2_called++; | |
145 | ||
146 | assert(read(fd, buf, BUF_SIZE) == strlen(READ_STR) + 1); | |
147 | assert(memcmp(buf, READ_STR, strlen(READ_STR) + 1) == 0); | |
148 | ||
149 | return (-1); | |
150 | } | |
151 | ||
152 | static int | |
153 | fd_write_cb1(int fd, void *user_data1, void *user_data2) | |
154 | { | |
155 | ||
156 | assert(user_data1 == &fd_write_cb1_called); | |
157 | assert(user_data2 == fd_write_cb1); | |
158 | ||
159 | fd_write_cb1_called++; | |
160 | ||
161 | return (0); | |
162 | } | |
163 | ||
164 | static int | |
165 | fd_err_cb1(int fd, short revents, void *user_data1, void *user_data2) | |
166 | { | |
167 | ||
168 | assert(user_data1 == &fd_err_cb1_called); | |
169 | assert(user_data2 == fd_err_cb1); | |
170 | ||
171 | fd_err_cb1_called++; | |
172 | ||
173 | return (0); | |
174 | } | |
175 | ||
176 | static int | |
177 | prfd_set_events_cb1_return(PRFileDesc *prfd, short *events, void *user_data1, void *user_data2) | |
178 | { | |
179 | ||
180 | prfd_set_events_cb1_return_called++; | |
181 | ||
182 | assert(user_data1 == &prfd_set_events_cb1_return_called); | |
183 | assert(user_data2 == NULL); | |
184 | ||
185 | return (-2); | |
186 | } | |
187 | ||
188 | static int | |
189 | prfd_set_events_cb2_return(PRFileDesc *prfd, short *events, void *user_data1, void *user_data2) | |
190 | { | |
191 | ||
192 | prfd_set_events_cb2_return_called++; | |
193 | ||
194 | assert(user_data1 == NULL); | |
195 | assert(user_data2 == &prfd_set_events_cb2_return_called); | |
196 | ||
197 | return (-2); | |
198 | } | |
199 | ||
200 | static int | |
01a63aae | 201 | prfd_read_cb1(PRFileDesc *prfd, const PRPollDesc *pd, void *user_data1, void *user_data2) |
687a72a0 JF |
202 | { |
203 | char buf[BUF_SIZE]; | |
204 | ||
205 | assert(user_data1 == &prfd_read_cb1_called); | |
206 | assert(user_data2 == prfd_read_cb1); | |
207 | ||
208 | prfd_read_cb1_called++; | |
209 | ||
210 | assert(PR_Read(prfd, buf, BUF_SIZE) == strlen(READ_STR) + 1); | |
211 | assert(memcmp(buf, READ_STR, strlen(READ_STR) + 1) == 0); | |
212 | ||
213 | return (0); | |
214 | } | |
215 | ||
216 | static int | |
01a63aae | 217 | prfd_read_cb2(PRFileDesc *prfd, const PRPollDesc *pd, void *user_data1, void *user_data2) |
687a72a0 JF |
218 | { |
219 | char buf[BUF_SIZE]; | |
220 | ||
221 | assert(user_data1 == &prfd_read_cb2_called); | |
222 | assert(user_data2 == prfd_read_cb2); | |
223 | ||
224 | prfd_read_cb2_called++; | |
225 | ||
226 | assert(PR_Read(prfd, buf, BUF_SIZE) == strlen(READ_STR) + 1); | |
227 | assert(memcmp(buf, READ_STR, strlen(READ_STR) + 1) == 0); | |
228 | ||
229 | return (-1); | |
230 | } | |
231 | ||
232 | static int | |
01a63aae | 233 | prfd_write_cb1(PRFileDesc *prfd, const PRPollDesc *pd, void *user_data1, void *user_data2) |
687a72a0 JF |
234 | { |
235 | ||
236 | assert(user_data1 == &prfd_write_cb1_called); | |
237 | assert(user_data2 == prfd_write_cb1); | |
238 | ||
239 | prfd_write_cb1_called++; | |
240 | ||
241 | return (0); | |
242 | } | |
243 | ||
244 | static int | |
01a63aae | 245 | prfd_err_cb1(PRFileDesc *prfd, short revents, const PRPollDesc *pd, void *user_data1, void *user_data2) |
687a72a0 JF |
246 | { |
247 | ||
248 | assert(user_data1 == &prfd_err_cb1_called); | |
249 | assert(user_data2 == prfd_err_cb1); | |
250 | ||
251 | prfd_err_cb1_called++; | |
252 | ||
253 | return (0); | |
254 | } | |
255 | ||
e7ef3641 JF |
256 | static int |
257 | test_complex_set_events_pipe1_read_cb(PRFileDesc *prfd, short *events, void *user_data1, void *user_data2) | |
258 | { | |
259 | ||
260 | test_complex_set_events_pipe1_read_called++; | |
261 | ||
262 | assert(user_data1 == &test_complex_set_events_pipe1_read_called); | |
263 | assert(user_data2 == test_complex_set_events_pipe1_read_cb); | |
264 | assert(*events == 0); | |
265 | ||
266 | if (test_complex_state == 2) { | |
267 | *events = POLLIN; | |
268 | } | |
269 | ||
270 | return (0); | |
271 | } | |
272 | ||
273 | static int | |
01a63aae | 274 | test_complex_read_pipe1_read_cb(PRFileDesc *prfd, const PRPollDesc *pd, void *user_data1, void *user_data2) |
e7ef3641 JF |
275 | { |
276 | char buf[BUF_SIZE]; | |
277 | ||
278 | assert(user_data1 == &test_complex_set_events_pipe1_read_called); | |
279 | assert(user_data2 == test_complex_set_events_pipe1_read_cb); | |
280 | ||
281 | test_complex_read_pipe1_read_called++; | |
282 | ||
283 | /* | |
284 | * prfd for this case is just a wrapper, we need to use real fd | |
285 | */ | |
286 | assert(read(test_complex_read_pipe1_fd, buf, BUF_SIZE) == strlen(READ_STR) + 1); | |
287 | assert(memcmp(buf, READ_STR, strlen(READ_STR) + 1) == 0); | |
288 | ||
289 | return (0); | |
290 | } | |
291 | ||
292 | static int | |
01a63aae | 293 | test_complex_write_pipe1_read_cb(PRFileDesc *prfd, const PRPollDesc *pd, void *user_data1, void *user_data2) |
e7ef3641 JF |
294 | { |
295 | ||
296 | assert(0); | |
297 | ||
298 | return (-1); | |
299 | } | |
300 | ||
301 | static int | |
302 | test_complex_set_events_pipe1_write_cb(int fd, short *events, void *user_data1, void *user_data2) | |
303 | { | |
304 | ||
305 | test_complex_set_events_pipe1_write_called++; | |
306 | ||
307 | assert(user_data1 == &test_complex_set_events_pipe1_write_called); | |
308 | assert(user_data2 == test_complex_set_events_pipe1_write_cb); | |
309 | assert(*events == 0); | |
310 | ||
311 | if (test_complex_state == 1) { | |
312 | *events = POLLOUT; | |
313 | } | |
314 | ||
315 | return (0); | |
316 | } | |
317 | ||
318 | static int | |
319 | test_complex_read_pipe1_write_cb(int fd, void *user_data1, void *user_data2) | |
320 | { | |
321 | ||
322 | assert(0); | |
323 | ||
324 | return (-1); | |
325 | } | |
326 | ||
327 | static int | |
328 | test_complex_write_pipe1_write_cb(int fd, void *user_data1, void *user_data2) | |
329 | { | |
330 | ||
331 | assert(user_data1 == &test_complex_set_events_pipe1_write_called); | |
332 | assert(user_data2 == test_complex_set_events_pipe1_write_cb); | |
333 | test_complex_write_pipe1_write_called++; | |
334 | ||
335 | return (0); | |
336 | } | |
337 | ||
338 | static int | |
339 | test_complex_set_events_pipe2_read_cb(int fd, short *events, void *user_data1, void *user_data2) | |
340 | { | |
341 | ||
342 | test_complex_set_events_pipe2_read_called++; | |
343 | ||
344 | assert(user_data1 == &test_complex_set_events_pipe2_read_called); | |
345 | assert(user_data2 == test_complex_set_events_pipe2_read_cb); | |
346 | assert(*events == POLLIN); | |
347 | ||
348 | return (0); | |
349 | } | |
350 | ||
351 | static int | |
352 | test_complex_read_pipe2_read_cb(int fd, void *user_data1, void *user_data2) | |
353 | { | |
354 | char buf[BUF_SIZE]; | |
355 | ||
356 | assert(user_data1 == &test_complex_set_events_pipe2_read_called); | |
357 | assert(user_data2 == test_complex_set_events_pipe2_read_cb); | |
358 | ||
359 | test_complex_read_pipe2_read_called++; | |
360 | ||
361 | assert(read(fd, buf, BUF_SIZE) == strlen(READ_STR) + 1); | |
362 | assert(memcmp(buf, READ_STR, strlen(READ_STR) + 1) == 0); | |
363 | ||
364 | return (0); | |
365 | } | |
366 | ||
367 | static int | |
368 | test_complex_write_pipe2_read_cb(int fd, void *user_data1, void *user_data2) | |
369 | { | |
370 | ||
371 | assert(0); | |
372 | ||
373 | return (-1); | |
374 | } | |
375 | ||
376 | static int | |
377 | test_complex_set_events_pipe2_write_cb(PRFileDesc *prfd, short *events, void *user_data1, void *user_data2) | |
378 | { | |
379 | ||
380 | test_complex_set_events_pipe2_write_called++; | |
381 | ||
382 | assert(user_data1 == &test_complex_set_events_pipe2_write_called); | |
383 | assert(user_data2 == test_complex_set_events_pipe2_write_cb); | |
384 | assert(*events == POLLOUT); | |
385 | ||
386 | return (0); | |
387 | } | |
388 | ||
389 | static int | |
01a63aae | 390 | test_complex_read_pipe2_write_cb(PRFileDesc *prfd, const PRPollDesc *pd, void *user_data1, void *user_data2) |
e7ef3641 JF |
391 | { |
392 | ||
393 | assert(0); | |
394 | ||
395 | return (-1); | |
396 | } | |
397 | ||
398 | static int | |
01a63aae | 399 | test_complex_write_pipe2_write_cb(PRFileDesc *prfd, const PRPollDesc *pd, void *user_data1, void *user_data2) |
e7ef3641 JF |
400 | { |
401 | ||
402 | assert(user_data1 == &test_complex_set_events_pipe2_write_called); | |
403 | assert(user_data2 == test_complex_set_events_pipe2_write_cb); | |
404 | test_complex_write_pipe2_write_called++; | |
405 | ||
406 | return (0); | |
407 | } | |
408 | ||
ea6d7a90 JF |
409 | static int |
410 | test_pre_poll_cb1(void *user_data1, void *user_data2) | |
411 | { | |
412 | ||
413 | assert(user_data1 == &pre_poll_cb1_called); | |
414 | assert(user_data2 == test_pre_poll_cb1); | |
415 | pre_poll_cb1_called++; | |
416 | ||
417 | return (0); | |
418 | } | |
419 | ||
420 | static int | |
421 | test_pre_poll_cb2(void *user_data1, void *user_data2) | |
422 | { | |
423 | ||
424 | assert(user_data1 == &pre_poll_cb2_called); | |
425 | assert(user_data2 == test_pre_poll_cb2); | |
426 | pre_poll_cb2_called++; | |
427 | ||
428 | return (0); | |
429 | } | |
430 | ||
431 | static int | |
432 | test_pre_poll_cb_return(void *user_data1, void *user_data2) | |
433 | { | |
434 | ||
435 | assert(user_data1 == &pre_poll_cb_return_called); | |
436 | assert(user_data2 == test_pre_poll_cb_return); | |
437 | pre_poll_cb_return_called++; | |
438 | ||
439 | return (-1); | |
440 | } | |
441 | ||
687a72a0 JF |
442 | static void |
443 | init_global_vars(void) | |
444 | { | |
445 | fd_set_events_cb1_return_called = -1; | |
446 | fd_set_events_cb2_return_called = -1; | |
447 | fd_read_cb1_called = -1; | |
448 | fd_read_cb2_called = -1; | |
449 | fd_write_cb1_called = -1; | |
450 | fd_err_cb1_called = -1; | |
451 | timeout_cb_called = -1; | |
452 | ||
453 | prfd_set_events_cb1_return_called = -1; | |
454 | prfd_set_events_cb2_return_called = -1; | |
455 | prfd_read_cb1_called = -1; | |
456 | prfd_read_cb2_called = -1; | |
457 | prfd_write_cb1_called = -1; | |
458 | prfd_err_cb1_called = -1; | |
ea6d7a90 JF |
459 | |
460 | test_complex_set_events_pipe1_read_called = -1; | |
461 | test_complex_read_pipe1_read_called = -1; | |
462 | test_complex_set_events_pipe1_write_called = -1; | |
463 | test_complex_write_pipe1_write_called = -1; | |
464 | test_complex_set_events_pipe2_read_called = -1; | |
465 | test_complex_read_pipe2_read_called = -1; | |
466 | test_complex_set_events_pipe2_write_called = -1; | |
467 | test_complex_write_pipe2_write_called = -1; | |
468 | test_complex_read_pipe1_fd = -1; | |
687a72a0 JF |
469 | } |
470 | ||
471 | static void | |
472 | test_fd_basics(struct pr_poll_loop *poll_loop) | |
473 | { | |
474 | int pipe_fd1[2]; | |
475 | struct timer_list_entry *timeout_timer; | |
476 | ||
477 | init_global_vars(); | |
478 | ||
ea6d7a90 JF |
479 | assert(pipe(pipe_fd1) == 0); |
480 | ||
687a72a0 JF |
481 | /* |
482 | * Add POLLNVAL -> failure | |
483 | */ | |
ea6d7a90 | 484 | assert(pr_poll_loop_add_fd(poll_loop, pipe_fd1[0], POLLNVAL, NULL, NULL, NULL, NULL, |
687a72a0 JF |
485 | NULL, NULL) == -1); |
486 | /* | |
487 | * Del non-existing fdL -> failure | |
488 | */ | |
ea6d7a90 | 489 | assert(pr_poll_loop_del_fd(poll_loop, pipe_fd1[0]) == -1); |
687a72a0 JF |
490 | |
491 | /* | |
492 | * Add and delete fd twice | |
493 | */ | |
ea6d7a90 | 494 | assert(pr_poll_loop_add_fd(poll_loop, pipe_fd1[0], 0, NULL, NULL, NULL, NULL, |
687a72a0 | 495 | NULL, NULL) == 0); |
ea6d7a90 | 496 | assert(pr_poll_loop_add_fd(poll_loop, pipe_fd1[0], 0, NULL, NULL, NULL, NULL, |
687a72a0 | 497 | NULL, NULL) == -1); |
ea6d7a90 JF |
498 | assert(pr_poll_loop_del_fd(poll_loop, pipe_fd1[0]) == 0); |
499 | assert(pr_poll_loop_del_fd(poll_loop, pipe_fd1[0]) == -1); | |
687a72a0 JF |
500 | |
501 | /* | |
502 | * Test timeout timer | |
503 | * with empty list | |
504 | */ | |
505 | assert((timeout_timer = timer_list_add( | |
506 | pr_poll_loop_get_timer_list(poll_loop), TIMER_TEST_TIMEOUT, timeout_cb, NULL, NULL)) != NULL); | |
507 | timeout_cb_called = 0; | |
508 | assert(pr_poll_loop_exec(poll_loop) == 0); | |
509 | assert(timeout_cb_called == 1); | |
510 | ||
511 | /* | |
512 | * Test user_data passing | |
513 | */ | |
687a72a0 JF |
514 | assert(pr_poll_loop_add_fd(poll_loop, pipe_fd1[0], POLLIN, fd_set_events_cb1_return, |
515 | NULL, NULL, NULL, (void *)&fd_set_events_cb1_return_called, NULL) == 0); | |
516 | ||
517 | fd_set_events_cb1_return_called = 0; | |
518 | ||
519 | assert((timeout_timer = timer_list_add( | |
520 | pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL); | |
521 | assert(pr_poll_loop_exec(poll_loop) == -1); | |
522 | ||
523 | assert(fd_set_events_cb1_return_called == 1); | |
524 | timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer); | |
525 | ||
07a7e8a7 JF |
526 | /* |
527 | * Remove entry and try with zero events and -2 return callback | |
528 | */ | |
529 | assert(pr_poll_loop_del_fd(poll_loop, pipe_fd1[0]) == 0); | |
530 | assert(pr_poll_loop_add_fd(poll_loop, pipe_fd1[0], 0, fd_set_events_cb1_return, | |
531 | NULL, NULL, NULL, (void *)&fd_set_events_cb1_return_called, NULL) == 0); | |
532 | ||
533 | fd_set_events_cb1_return_called = 0; | |
534 | ||
535 | assert((timeout_timer = timer_list_add( | |
536 | pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL); | |
537 | assert(pr_poll_loop_exec(poll_loop) == -1); | |
538 | ||
539 | assert(fd_set_events_cb1_return_called == 1); | |
540 | timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer); | |
541 | ||
687a72a0 JF |
542 | /* |
543 | * Remove entry and try different cb | |
544 | */ | |
545 | assert(pr_poll_loop_del_fd(poll_loop, pipe_fd1[0]) == 0); | |
546 | assert(pr_poll_loop_add_fd(poll_loop, pipe_fd1[1], POLLOUT, fd_set_events_cb2_return, | |
547 | NULL, NULL, NULL, NULL, (void *)&fd_set_events_cb2_return_called) == 0); | |
548 | ||
549 | fd_set_events_cb1_return_called = 0; | |
550 | fd_set_events_cb2_return_called = 0; | |
551 | ||
552 | assert((timeout_timer = timer_list_add( | |
553 | pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL); | |
554 | assert(pr_poll_loop_exec(poll_loop) == -1); | |
555 | ||
556 | assert(fd_set_events_cb1_return_called == 0); | |
557 | assert(fd_set_events_cb2_return_called == 1); | |
558 | timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer); | |
559 | ||
560 | /* | |
561 | * Delete entry and try timeout again | |
562 | */ | |
563 | assert(pr_poll_loop_del_fd(poll_loop, pipe_fd1[0]) == -1); | |
564 | assert(pr_poll_loop_del_fd(poll_loop, pipe_fd1[1]) == 0); | |
565 | ||
566 | assert((timeout_timer = timer_list_add( | |
567 | pr_poll_loop_get_timer_list(poll_loop), TIMER_TEST_TIMEOUT, timeout_cb, NULL, NULL)) != NULL); | |
568 | timeout_cb_called = 0; | |
569 | assert(pr_poll_loop_exec(poll_loop) == 0); | |
570 | assert(timeout_cb_called == 1); | |
571 | ||
572 | /* | |
573 | * Try reading | |
574 | */ | |
575 | assert(write(pipe_fd1[1], READ_STR, strlen(READ_STR) + 1) == strlen(READ_STR) + 1); | |
576 | ||
577 | assert(pr_poll_loop_add_fd(poll_loop, pipe_fd1[0], POLLIN, NULL, | |
578 | fd_read_cb1, NULL, NULL, | |
579 | &fd_read_cb1_called, fd_read_cb1) == 0); | |
580 | ||
581 | fd_read_cb1_called = 0; | |
582 | timeout_cb_called = 0; | |
583 | ||
584 | assert((timeout_timer = timer_list_add( | |
585 | pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL); | |
586 | assert(pr_poll_loop_exec(poll_loop) == 0); | |
587 | ||
588 | assert(fd_read_cb1_called == 1); | |
589 | assert(timeout_cb_called == 0); | |
590 | timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer); | |
591 | ||
592 | /* | |
593 | * Try timeout with valid entry | |
594 | */ | |
595 | assert((timeout_timer = timer_list_add( | |
596 | pr_poll_loop_get_timer_list(poll_loop), TIMER_TEST_TIMEOUT, timeout_cb, NULL, NULL)) != NULL); | |
597 | timeout_cb_called = 0; | |
598 | fd_read_cb1_called = 0; | |
599 | ||
600 | assert(pr_poll_loop_exec(poll_loop) == 0); | |
601 | ||
602 | assert(timeout_cb_called == 1); | |
603 | assert(fd_read_cb1_called == 0); | |
604 | ||
605 | /* | |
606 | * Try reading where cb returns err | |
607 | */ | |
608 | assert(pr_poll_loop_del_fd(poll_loop, pipe_fd1[0]) == 0); | |
609 | assert(write(pipe_fd1[1], READ_STR, strlen(READ_STR) + 1) == strlen(READ_STR) + 1); | |
610 | ||
611 | assert(pr_poll_loop_add_fd(poll_loop, pipe_fd1[0], POLLIN, NULL, | |
612 | fd_read_cb2, NULL, NULL, | |
613 | &fd_read_cb2_called, fd_read_cb2) == 0); | |
614 | ||
615 | fd_read_cb1_called = 0; | |
616 | fd_read_cb2_called = 0; | |
617 | timeout_cb_called = 0; | |
618 | ||
619 | assert((timeout_timer = timer_list_add( | |
620 | pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL); | |
621 | assert(pr_poll_loop_exec(poll_loop) == -1); | |
622 | ||
623 | assert(fd_read_cb1_called == 0); | |
624 | assert(fd_read_cb2_called == 1); | |
625 | assert(timeout_cb_called == 0); | |
626 | timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer); | |
627 | ||
628 | /* | |
629 | * Try writing | |
630 | */ | |
631 | assert(pr_poll_loop_del_fd(poll_loop, pipe_fd1[0]) == 0); | |
632 | ||
633 | assert(pr_poll_loop_add_fd(poll_loop, pipe_fd1[1], POLLOUT, NULL, | |
634 | NULL, fd_write_cb1, NULL, | |
635 | &fd_write_cb1_called, fd_write_cb1) == 0); | |
636 | ||
637 | fd_write_cb1_called = 0; | |
638 | timeout_cb_called = 0; | |
639 | ||
640 | assert((timeout_timer = timer_list_add( | |
641 | pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL); | |
642 | assert(pr_poll_loop_exec(poll_loop) == 0); | |
643 | ||
644 | assert(fd_write_cb1_called == 1); | |
645 | assert(timeout_cb_called == 0); | |
646 | timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer); | |
647 | ||
648 | /* | |
649 | * Try err cb | |
650 | */ | |
651 | assert(pr_poll_loop_del_fd(poll_loop, pipe_fd1[1]) == 0); | |
652 | ||
653 | assert(pr_poll_loop_add_fd(poll_loop, pipe_fd1[0], POLLIN, NULL, | |
654 | NULL, NULL, fd_err_cb1, | |
655 | &fd_err_cb1_called, fd_err_cb1) == 0); | |
656 | ||
657 | assert(close(pipe_fd1[0]) == 0); | |
658 | assert(close(pipe_fd1[1]) == 0); | |
659 | fd_err_cb1_called = 0; | |
660 | timeout_cb_called = 0; | |
661 | fd_write_cb1_called = 0; | |
662 | ||
663 | assert((timeout_timer = timer_list_add( | |
664 | pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL); | |
665 | assert(pr_poll_loop_exec(poll_loop) == 0); | |
666 | ||
667 | assert(fd_err_cb1_called == 1); | |
668 | assert(fd_write_cb1_called == 0); | |
669 | assert(timeout_cb_called == 0); | |
670 | assert(pr_poll_loop_del_fd(poll_loop, pipe_fd1[0]) == 0); | |
671 | timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer); | |
672 | } | |
673 | ||
674 | static void | |
675 | test_prfd_basics(struct pr_poll_loop *poll_loop) | |
676 | { | |
677 | PRFileDesc *read_pipe; | |
678 | PRFileDesc *write_pipe; | |
679 | struct timer_list_entry *timeout_timer; | |
680 | int pipe_fd1[2]; | |
681 | ||
682 | init_global_vars(); | |
683 | ||
684 | assert(PR_CreatePipe(&read_pipe, &write_pipe) == PR_SUCCESS); | |
685 | ||
686 | /* | |
687 | * Add POLLNVAL -> failure | |
688 | */ | |
689 | assert(pr_poll_loop_add_prfd(poll_loop, read_pipe, POLLNVAL, NULL, NULL, NULL, NULL, | |
690 | NULL, NULL) == -1); | |
691 | /* | |
692 | * Del non-existing fdL -> failure | |
693 | */ | |
694 | assert(pr_poll_loop_del_prfd(poll_loop, read_pipe) == -1); | |
695 | ||
696 | /* | |
697 | * Add and delete fd twice | |
698 | */ | |
699 | assert(pr_poll_loop_add_prfd(poll_loop, read_pipe, 0, NULL, NULL, NULL, NULL, | |
700 | NULL, NULL) == 0); | |
701 | assert(pr_poll_loop_add_prfd(poll_loop, read_pipe, 0, NULL, NULL, NULL, NULL, | |
702 | NULL, NULL) == -1); | |
703 | assert(pr_poll_loop_del_prfd(poll_loop, read_pipe) == 0); | |
704 | assert(pr_poll_loop_del_prfd(poll_loop, read_pipe) == -1); | |
705 | ||
706 | /* | |
707 | * Test user_data passing | |
708 | */ | |
709 | assert(pr_poll_loop_add_prfd(poll_loop, read_pipe, POLLIN, prfd_set_events_cb1_return, | |
710 | NULL, NULL, NULL, (void *)&prfd_set_events_cb1_return_called, NULL) == 0); | |
711 | ||
712 | prfd_set_events_cb1_return_called = 0; | |
713 | ||
714 | assert((timeout_timer = timer_list_add( | |
715 | pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL); | |
716 | assert(pr_poll_loop_exec(poll_loop) == -1); | |
717 | ||
718 | assert(prfd_set_events_cb1_return_called == 1); | |
719 | timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer); | |
720 | ||
721 | /* | |
722 | * Remove entry and try different cb | |
723 | */ | |
724 | assert(pr_poll_loop_del_prfd(poll_loop, read_pipe) == 0); | |
725 | assert(pr_poll_loop_add_prfd(poll_loop, write_pipe, POLLOUT, prfd_set_events_cb2_return, | |
726 | NULL, NULL, NULL, NULL, (void *)&prfd_set_events_cb2_return_called) == 0); | |
727 | ||
728 | prfd_set_events_cb1_return_called = 0; | |
729 | prfd_set_events_cb2_return_called = 0; | |
730 | ||
731 | assert((timeout_timer = timer_list_add( | |
732 | pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL); | |
733 | assert(pr_poll_loop_exec(poll_loop) == -1); | |
734 | ||
735 | assert(prfd_set_events_cb1_return_called == 0); | |
736 | assert(prfd_set_events_cb2_return_called == 1); | |
737 | timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer); | |
738 | ||
739 | /* | |
740 | * Delete entry and try timeout again | |
741 | */ | |
742 | assert(pr_poll_loop_del_prfd(poll_loop, read_pipe) == -1); | |
743 | assert(pr_poll_loop_del_prfd(poll_loop, write_pipe) == 0); | |
744 | ||
745 | assert((timeout_timer = timer_list_add( | |
746 | pr_poll_loop_get_timer_list(poll_loop), TIMER_TEST_TIMEOUT, timeout_cb, NULL, NULL)) != NULL); | |
747 | timeout_cb_called = 0; | |
748 | assert(pr_poll_loop_exec(poll_loop) == 0); | |
749 | assert(timeout_cb_called == 1); | |
750 | ||
751 | /* | |
752 | * Try reading | |
753 | */ | |
754 | assert(PR_Write(write_pipe, READ_STR, strlen(READ_STR) + 1) == strlen(READ_STR) + 1); | |
755 | ||
756 | assert(pr_poll_loop_add_prfd(poll_loop, read_pipe, POLLIN, NULL, | |
757 | prfd_read_cb1, NULL, NULL, | |
758 | &prfd_read_cb1_called, prfd_read_cb1) == 0); | |
759 | ||
760 | prfd_read_cb1_called = 0; | |
761 | timeout_cb_called = 0; | |
762 | ||
763 | assert((timeout_timer = timer_list_add( | |
764 | pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL); | |
765 | assert(pr_poll_loop_exec(poll_loop) == 0); | |
766 | ||
767 | assert(prfd_read_cb1_called == 1); | |
768 | assert(timeout_cb_called == 0); | |
769 | timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer); | |
770 | ||
771 | /* | |
772 | * Try timeout with valid entry | |
773 | */ | |
774 | assert((timeout_timer = timer_list_add( | |
775 | pr_poll_loop_get_timer_list(poll_loop), TIMER_TEST_TIMEOUT, timeout_cb, NULL, NULL)) != NULL); | |
776 | timeout_cb_called = 0; | |
777 | prfd_read_cb1_called = 0; | |
778 | ||
779 | assert(pr_poll_loop_exec(poll_loop) == 0); | |
780 | ||
781 | assert(timeout_cb_called == 1); | |
782 | assert(prfd_read_cb1_called == 0); | |
783 | ||
784 | /* | |
785 | * Try reading where cb returns err | |
786 | */ | |
787 | assert(pr_poll_loop_del_prfd(poll_loop, read_pipe) == 0); | |
788 | assert(PR_Write(write_pipe, READ_STR, strlen(READ_STR) + 1) == strlen(READ_STR) + 1); | |
789 | ||
790 | assert(pr_poll_loop_add_prfd(poll_loop, read_pipe, POLLIN, NULL, | |
791 | prfd_read_cb2, NULL, NULL, | |
792 | &prfd_read_cb2_called, prfd_read_cb2) == 0); | |
793 | ||
794 | prfd_read_cb1_called = 0; | |
795 | prfd_read_cb2_called = 0; | |
796 | timeout_cb_called = 0; | |
797 | ||
798 | assert((timeout_timer = timer_list_add( | |
799 | pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL); | |
800 | assert(pr_poll_loop_exec(poll_loop) == -1); | |
801 | ||
802 | assert(prfd_read_cb1_called == 0); | |
803 | assert(prfd_read_cb2_called == 1); | |
804 | assert(timeout_cb_called == 0); | |
805 | timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer); | |
806 | ||
807 | /* | |
808 | * Try writing | |
809 | */ | |
810 | assert(pr_poll_loop_del_prfd(poll_loop, read_pipe) == 0); | |
811 | ||
812 | assert(pr_poll_loop_add_prfd(poll_loop, write_pipe, POLLOUT, NULL, | |
813 | NULL, prfd_write_cb1, NULL, | |
814 | &prfd_write_cb1_called, prfd_write_cb1) == 0); | |
815 | ||
816 | prfd_write_cb1_called = 0; | |
817 | timeout_cb_called = 0; | |
818 | ||
819 | assert((timeout_timer = timer_list_add( | |
820 | pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL); | |
821 | assert(pr_poll_loop_exec(poll_loop) == 0); | |
822 | ||
823 | assert(prfd_write_cb1_called == 1); | |
824 | assert(timeout_cb_called == 0); | |
825 | timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer); | |
826 | ||
827 | assert(PR_Close(read_pipe) == 0); | |
828 | assert(PR_Close(write_pipe) == 0); | |
829 | ||
830 | /* | |
831 | * Try err cb | |
832 | */ | |
833 | assert(pr_poll_loop_del_prfd(poll_loop, write_pipe) == 0); | |
834 | ||
835 | /* | |
836 | * Must use native pipe, because PR_Close deallocate PRFileDesc completelly | |
837 | */ | |
838 | assert(pipe(pipe_fd1) == 0); | |
839 | assert((read_pipe = PR_CreateSocketPollFd(pipe_fd1[0])) != NULL); | |
840 | ||
841 | assert(close(pipe_fd1[0]) == 0); | |
842 | assert(close(pipe_fd1[1]) == 0); | |
843 | ||
844 | assert(pr_poll_loop_add_prfd(poll_loop, read_pipe, POLLIN, NULL, | |
845 | NULL, NULL, prfd_err_cb1, | |
846 | &prfd_err_cb1_called, prfd_err_cb1) == 0); | |
847 | ||
848 | prfd_err_cb1_called = 0; | |
849 | timeout_cb_called = 0; | |
850 | prfd_write_cb1_called = 0; | |
851 | ||
852 | assert((timeout_timer = timer_list_add( | |
853 | pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL); | |
854 | assert(pr_poll_loop_exec(poll_loop) == 0); | |
855 | ||
856 | assert(prfd_err_cb1_called == 1); | |
857 | assert(prfd_write_cb1_called == 0); | |
858 | assert(timeout_cb_called == 0); | |
859 | assert(pr_poll_loop_del_prfd(poll_loop, read_pipe) == 0); | |
860 | timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer); | |
861 | ||
862 | assert(PR_DestroySocketPollFd(read_pipe) == PR_SUCCESS); | |
863 | } | |
864 | ||
e7ef3641 JF |
865 | static void |
866 | test_complex(struct pr_poll_loop *poll_loop) | |
867 | { | |
868 | int pipe_fd1[2], pipe_fd2[2]; | |
869 | PRFileDesc *read_pipe1; | |
870 | PRFileDesc *write_pipe2; | |
871 | struct timer_list_entry *timeout_timer; | |
872 | ||
ea6d7a90 JF |
873 | init_global_vars(); |
874 | ||
e7ef3641 JF |
875 | assert(pipe(pipe_fd1) == 0); |
876 | assert(pipe(pipe_fd2) == 0); | |
877 | ||
878 | test_complex_read_pipe1_fd = pipe_fd1[0]; | |
879 | ||
ea6d7a90 JF |
880 | /* |
881 | * Add pre poll cb1 | |
882 | */ | |
883 | assert(pr_poll_loop_add_pre_poll_cb(poll_loop, test_pre_poll_cb1, | |
884 | &pre_poll_cb1_called, test_pre_poll_cb1) == 0); | |
885 | ||
e7ef3641 JF |
886 | assert((read_pipe1 = PR_CreateSocketPollFd(pipe_fd1[0])) != NULL); |
887 | assert((write_pipe2 = PR_CreateSocketPollFd(pipe_fd2[1])) != NULL); | |
888 | ||
889 | assert(pr_poll_loop_add_prfd(poll_loop, read_pipe1, 0, test_complex_set_events_pipe1_read_cb, | |
890 | test_complex_read_pipe1_read_cb, test_complex_write_pipe1_read_cb, NULL, | |
891 | &test_complex_set_events_pipe1_read_called, test_complex_set_events_pipe1_read_cb) == 0); | |
892 | ||
893 | assert(pr_poll_loop_add_fd(poll_loop, pipe_fd1[1], 0, test_complex_set_events_pipe1_write_cb, | |
894 | test_complex_read_pipe1_write_cb, test_complex_write_pipe1_write_cb, NULL, | |
895 | &test_complex_set_events_pipe1_write_called, test_complex_set_events_pipe1_write_cb) == 0); | |
896 | ||
897 | assert(pr_poll_loop_add_fd(poll_loop, pipe_fd2[0], POLLIN, test_complex_set_events_pipe2_read_cb, | |
898 | test_complex_read_pipe2_read_cb, test_complex_write_pipe2_read_cb, NULL, | |
899 | &test_complex_set_events_pipe2_read_called, test_complex_set_events_pipe2_read_cb) == 0); | |
900 | ||
901 | assert(pr_poll_loop_add_prfd(poll_loop, write_pipe2, POLLOUT, test_complex_set_events_pipe2_write_cb, | |
902 | test_complex_read_pipe2_write_cb, test_complex_write_pipe2_write_cb, NULL, | |
903 | &test_complex_set_events_pipe2_write_called, test_complex_set_events_pipe2_write_cb) == 0); | |
904 | ||
ea6d7a90 JF |
905 | timeout_cb_called = 0; |
906 | test_complex_set_events_pipe1_read_called = 0; | |
907 | test_complex_read_pipe1_read_called = 0; | |
908 | test_complex_set_events_pipe1_write_called = 0; | |
909 | test_complex_write_pipe1_write_called = 0; | |
910 | test_complex_set_events_pipe2_read_called = 0; | |
911 | test_complex_read_pipe2_read_called = 0; | |
912 | test_complex_set_events_pipe2_write_called = 0; | |
913 | test_complex_write_pipe2_write_called = 0; | |
914 | pre_poll_cb1_called = 0; | |
915 | pre_poll_cb2_called = 0; | |
916 | ||
e7ef3641 JF |
917 | /* |
918 | * Call for first time -> all set_events should be called and pipe2_write should be called | |
919 | */ | |
920 | assert((timeout_timer = timer_list_add( | |
921 | pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL); | |
922 | assert(pr_poll_loop_exec(poll_loop) == 0); | |
923 | ||
ea6d7a90 JF |
924 | assert(pre_poll_cb1_called == 1); |
925 | assert(pre_poll_cb2_called == 0); | |
e7ef3641 JF |
926 | assert(test_complex_set_events_pipe1_read_called == 1); |
927 | assert(test_complex_read_pipe1_read_called == 0); | |
928 | assert(test_complex_set_events_pipe1_write_called == 1); | |
929 | assert(test_complex_write_pipe1_write_called == 0); | |
930 | assert(test_complex_set_events_pipe2_read_called == 1); | |
931 | assert(test_complex_read_pipe2_read_called == 0); | |
932 | assert(test_complex_set_events_pipe2_write_called == 1); | |
933 | assert(test_complex_write_pipe2_write_called == 1); | |
934 | ||
935 | assert(timeout_cb_called == 0); | |
936 | timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer); | |
937 | ||
938 | /* | |
939 | * Call for second time -> same as first time | |
940 | */ | |
941 | assert((timeout_timer = timer_list_add( | |
942 | pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL); | |
943 | assert(pr_poll_loop_exec(poll_loop) == 0); | |
944 | ||
ea6d7a90 JF |
945 | assert(pre_poll_cb1_called == 2); |
946 | assert(pre_poll_cb2_called == 0); | |
e7ef3641 JF |
947 | assert(test_complex_set_events_pipe1_read_called == 2); |
948 | assert(test_complex_read_pipe1_read_called == 0); | |
949 | assert(test_complex_set_events_pipe1_write_called == 2); | |
950 | assert(test_complex_write_pipe1_write_called == 0); | |
951 | assert(test_complex_set_events_pipe2_read_called == 2); | |
952 | assert(test_complex_read_pipe2_read_called == 0); | |
953 | assert(test_complex_set_events_pipe2_write_called == 2); | |
954 | assert(test_complex_write_pipe2_write_called == 2); | |
955 | ||
956 | assert(timeout_cb_called == 0); | |
957 | timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer); | |
958 | ||
959 | /* | |
960 | * Change state to prepare for writing | |
961 | */ | |
962 | test_complex_state = 1; | |
963 | assert((timeout_timer = timer_list_add( | |
964 | pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL); | |
965 | assert(pr_poll_loop_exec(poll_loop) == 0); | |
966 | ||
ea6d7a90 JF |
967 | assert(pre_poll_cb1_called == 3); |
968 | assert(pre_poll_cb2_called == 0); | |
e7ef3641 JF |
969 | assert(test_complex_set_events_pipe1_read_called == 3); |
970 | assert(test_complex_read_pipe1_read_called == 0); | |
971 | assert(test_complex_set_events_pipe1_write_called == 3); | |
972 | assert(test_complex_write_pipe1_write_called == 1); | |
973 | assert(test_complex_set_events_pipe2_read_called == 3); | |
974 | assert(test_complex_read_pipe2_read_called == 0); | |
975 | assert(test_complex_set_events_pipe2_write_called == 3); | |
976 | assert(test_complex_write_pipe2_write_called == 3); | |
977 | ||
978 | assert(timeout_cb_called == 0); | |
979 | timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer); | |
980 | ||
981 | /* | |
982 | * Write to first pipe | |
983 | */ | |
984 | assert(write(pipe_fd1[1], READ_STR, strlen(READ_STR) + 1) == strlen(READ_STR) + 1); | |
985 | ||
986 | assert((timeout_timer = timer_list_add( | |
987 | pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL); | |
988 | assert(pr_poll_loop_exec(poll_loop) == 0); | |
989 | ||
ea6d7a90 JF |
990 | assert(pre_poll_cb1_called == 4); |
991 | assert(pre_poll_cb2_called == 0); | |
e7ef3641 JF |
992 | assert(test_complex_set_events_pipe1_read_called == 4); |
993 | assert(test_complex_read_pipe1_read_called == 0); | |
994 | assert(test_complex_set_events_pipe1_write_called == 4); | |
995 | assert(test_complex_write_pipe1_write_called == 2); | |
996 | assert(test_complex_set_events_pipe2_read_called == 4); | |
997 | assert(test_complex_read_pipe2_read_called == 0); | |
998 | assert(test_complex_set_events_pipe2_write_called == 4); | |
999 | assert(test_complex_write_pipe2_write_called == 4); | |
1000 | ||
1001 | assert(timeout_cb_called == 0); | |
1002 | timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer); | |
1003 | ||
ea6d7a90 JF |
1004 | /* |
1005 | * Delete pre poll cb | |
1006 | */ | |
1007 | assert(pr_poll_loop_del_pre_poll_cb(poll_loop, test_pre_poll_cb1) == 0); | |
1008 | ||
e7ef3641 JF |
1009 | /* |
1010 | * Change state so write can propagate | |
1011 | */ | |
1012 | test_complex_state = 2; | |
1013 | assert((timeout_timer = timer_list_add( | |
1014 | pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL); | |
1015 | assert(pr_poll_loop_exec(poll_loop) == 0); | |
1016 | ||
ea6d7a90 JF |
1017 | assert(pre_poll_cb1_called == 4); |
1018 | assert(pre_poll_cb2_called == 0); | |
e7ef3641 JF |
1019 | assert(test_complex_set_events_pipe1_read_called == 5); |
1020 | assert(test_complex_read_pipe1_read_called == 1); | |
1021 | assert(test_complex_set_events_pipe1_write_called == 5); | |
1022 | assert(test_complex_write_pipe1_write_called == 2); | |
1023 | assert(test_complex_set_events_pipe2_read_called == 5); | |
1024 | assert(test_complex_read_pipe2_read_called == 0); | |
1025 | assert(test_complex_set_events_pipe2_write_called == 5); | |
1026 | assert(test_complex_write_pipe2_write_called == 5); | |
1027 | ||
1028 | assert(timeout_cb_called == 0); | |
1029 | timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer); | |
1030 | ||
ea6d7a90 JF |
1031 | /* |
1032 | * Add pre poll cb 1 and 2 | |
1033 | */ | |
1034 | assert(pr_poll_loop_add_pre_poll_cb(poll_loop, test_pre_poll_cb1, | |
1035 | &pre_poll_cb1_called, test_pre_poll_cb1) == 0); | |
1036 | assert(pr_poll_loop_add_pre_poll_cb(poll_loop, test_pre_poll_cb2, | |
1037 | &pre_poll_cb2_called, test_pre_poll_cb2) == 0); | |
1038 | ||
e7ef3641 JF |
1039 | /* |
1040 | * Change state so pipe1 events are not called any longer | |
1041 | */ | |
1042 | test_complex_state = 4; | |
1043 | assert((timeout_timer = timer_list_add( | |
1044 | pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL); | |
1045 | assert(pr_poll_loop_exec(poll_loop) == 0); | |
1046 | ||
ea6d7a90 JF |
1047 | assert(pre_poll_cb1_called == 5); |
1048 | assert(pre_poll_cb2_called == 1); | |
e7ef3641 JF |
1049 | assert(test_complex_set_events_pipe1_read_called == 6); |
1050 | assert(test_complex_read_pipe1_read_called == 1); | |
1051 | assert(test_complex_set_events_pipe1_write_called == 6); | |
1052 | assert(test_complex_write_pipe1_write_called == 2); | |
1053 | assert(test_complex_set_events_pipe2_read_called == 6); | |
1054 | assert(test_complex_read_pipe2_read_called == 0); | |
1055 | assert(test_complex_set_events_pipe2_write_called == 6); | |
1056 | assert(test_complex_write_pipe2_write_called == 6); | |
1057 | ||
1058 | assert(timeout_cb_called == 0); | |
1059 | timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer); | |
1060 | ||
1061 | /* | |
1062 | * Write to second pipe | |
1063 | */ | |
1064 | assert(write(pipe_fd2[1], READ_STR, strlen(READ_STR) + 1) == strlen(READ_STR) + 1); | |
1065 | ||
1066 | assert((timeout_timer = timer_list_add( | |
1067 | pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL); | |
1068 | assert(pr_poll_loop_exec(poll_loop) == 0); | |
1069 | ||
ea6d7a90 JF |
1070 | assert(pre_poll_cb1_called == 6); |
1071 | assert(pre_poll_cb2_called == 2); | |
e7ef3641 JF |
1072 | assert(test_complex_set_events_pipe1_read_called == 7); |
1073 | assert(test_complex_read_pipe1_read_called == 1); | |
1074 | assert(test_complex_set_events_pipe1_write_called == 7); | |
1075 | assert(test_complex_write_pipe1_write_called == 2); | |
1076 | assert(test_complex_set_events_pipe2_read_called == 7); | |
1077 | assert(test_complex_read_pipe2_read_called == 1); | |
1078 | assert(test_complex_set_events_pipe2_write_called == 7); | |
1079 | assert(test_complex_write_pipe2_write_called == 7); | |
1080 | ||
1081 | assert(timeout_cb_called == 0); | |
1082 | timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer); | |
1083 | ||
1084 | /* | |
1085 | * And call again | |
1086 | */ | |
1087 | assert((timeout_timer = timer_list_add( | |
1088 | pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL); | |
1089 | assert(pr_poll_loop_exec(poll_loop) == 0); | |
1090 | ||
ea6d7a90 JF |
1091 | assert(pre_poll_cb1_called == 7); |
1092 | assert(pre_poll_cb2_called == 3); | |
e7ef3641 JF |
1093 | assert(test_complex_set_events_pipe1_read_called == 8); |
1094 | assert(test_complex_read_pipe1_read_called == 1); | |
1095 | assert(test_complex_set_events_pipe1_write_called == 8); | |
1096 | assert(test_complex_write_pipe1_write_called == 2); | |
1097 | assert(test_complex_set_events_pipe2_read_called == 8); | |
1098 | assert(test_complex_read_pipe2_read_called == 1); | |
1099 | assert(test_complex_set_events_pipe2_write_called == 8); | |
1100 | assert(test_complex_write_pipe2_write_called == 8); | |
1101 | ||
1102 | assert(timeout_cb_called == 0); | |
1103 | timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer); | |
1104 | ||
1105 | assert(PR_DestroySocketPollFd(read_pipe1) == PR_SUCCESS); | |
1106 | assert(PR_DestroySocketPollFd(write_pipe2) == PR_SUCCESS); | |
1107 | ||
1108 | assert(close(pipe_fd1[0]) == 0); | |
1109 | assert(close(pipe_fd1[1]) == 0); | |
1110 | ||
1111 | assert(close(pipe_fd2[0]) == 0); | |
1112 | assert(close(pipe_fd2[1]) == 0); | |
ea6d7a90 JF |
1113 | |
1114 | assert(pr_poll_loop_del_pre_poll_cb(poll_loop, test_pre_poll_cb1) == 0); | |
1115 | assert(pr_poll_loop_del_pre_poll_cb(poll_loop, test_pre_poll_cb2) == 0); | |
1116 | ||
1117 | assert(pr_poll_loop_del_prfd(poll_loop, read_pipe1) == 0); | |
1118 | assert(pr_poll_loop_del_fd(poll_loop, pipe_fd1[1]) == 0); | |
1119 | assert(pr_poll_loop_del_fd(poll_loop, pipe_fd2[0]) == 0); | |
1120 | assert(pr_poll_loop_del_prfd(poll_loop, write_pipe2) == 0); | |
1121 | } | |
1122 | ||
1123 | static void | |
1124 | test_pre_poll_cb(struct pr_poll_loop *poll_loop) | |
1125 | { | |
1126 | struct timer_list_entry *timeout_timer; | |
1127 | ||
1128 | init_global_vars(); | |
1129 | ||
1130 | assert(pr_poll_loop_add_pre_poll_cb(poll_loop, test_pre_poll_cb1, | |
1131 | &pre_poll_cb1_called, test_pre_poll_cb1) == 0); | |
1132 | assert(pr_poll_loop_add_pre_poll_cb(poll_loop, test_pre_poll_cb1, | |
1133 | &pre_poll_cb1_called, test_pre_poll_cb1) == -1); | |
1134 | ||
1135 | assert(pr_poll_loop_del_pre_poll_cb(poll_loop, test_pre_poll_cb1) == 0); | |
1136 | assert(pr_poll_loop_del_pre_poll_cb(poll_loop, test_pre_poll_cb1) == -1); | |
1137 | assert(pr_poll_loop_del_pre_poll_cb(poll_loop, test_pre_poll_cb2) == -1); | |
1138 | ||
1139 | /* | |
1140 | * Just one pre poll cb | |
1141 | */ | |
1142 | pre_poll_cb1_called = 0; | |
1143 | pre_poll_cb2_called = 0; | |
1144 | pre_poll_cb_return_called = 0; | |
1145 | ||
1146 | assert(pr_poll_loop_add_pre_poll_cb(poll_loop, test_pre_poll_cb1, | |
1147 | &pre_poll_cb1_called, test_pre_poll_cb1) == 0); | |
1148 | ||
1149 | assert((timeout_timer = timer_list_add( | |
1150 | pr_poll_loop_get_timer_list(poll_loop), TIMER_TEST_TIMEOUT, timeout_cb, NULL, NULL)) != NULL); | |
1151 | timeout_cb_called = 0; | |
1152 | ||
1153 | assert(pr_poll_loop_exec(poll_loop) == 0); | |
1154 | assert(timeout_cb_called == 1); | |
1155 | assert(pre_poll_cb1_called == 1); | |
1156 | assert(pre_poll_cb2_called == 0); | |
1157 | assert(pre_poll_cb_return_called == 0); | |
1158 | ||
1159 | /* | |
1160 | * Test again | |
1161 | */ | |
1162 | assert((timeout_timer = timer_list_add( | |
1163 | pr_poll_loop_get_timer_list(poll_loop), TIMER_TEST_TIMEOUT, timeout_cb, NULL, NULL)) != NULL); | |
1164 | timeout_cb_called = 0; | |
1165 | ||
1166 | assert(pr_poll_loop_exec(poll_loop) == 0); | |
1167 | assert(timeout_cb_called == 1); | |
1168 | assert(pre_poll_cb1_called == 2); | |
1169 | assert(pre_poll_cb2_called == 0); | |
1170 | assert(pre_poll_cb_return_called == 0); | |
1171 | ||
1172 | /* | |
1173 | * Add second cb | |
1174 | */ | |
1175 | assert(pr_poll_loop_add_pre_poll_cb(poll_loop, test_pre_poll_cb2, | |
1176 | &pre_poll_cb2_called, test_pre_poll_cb2) == 0); | |
1177 | ||
1178 | assert((timeout_timer = timer_list_add( | |
1179 | pr_poll_loop_get_timer_list(poll_loop), TIMER_TEST_TIMEOUT, timeout_cb, NULL, NULL)) != NULL); | |
1180 | timeout_cb_called = 0; | |
1181 | ||
1182 | assert(pr_poll_loop_exec(poll_loop) == 0); | |
1183 | assert(timeout_cb_called == 1); | |
1184 | assert(pre_poll_cb1_called == 3); | |
1185 | assert(pre_poll_cb2_called == 1); | |
1186 | assert(pre_poll_cb_return_called == 0); | |
1187 | ||
1188 | /* | |
1189 | * Remove cb1 | |
1190 | */ | |
1191 | assert(pr_poll_loop_del_pre_poll_cb(poll_loop, test_pre_poll_cb1) == 0); | |
1192 | ||
1193 | assert((timeout_timer = timer_list_add( | |
1194 | pr_poll_loop_get_timer_list(poll_loop), TIMER_TEST_TIMEOUT, timeout_cb, NULL, NULL)) != NULL); | |
1195 | timeout_cb_called = 0; | |
1196 | ||
1197 | assert(pr_poll_loop_exec(poll_loop) == 0); | |
1198 | assert(timeout_cb_called == 1); | |
1199 | assert(pre_poll_cb1_called == 3); | |
1200 | assert(pre_poll_cb2_called == 2); | |
1201 | assert(pre_poll_cb_return_called == 0); | |
1202 | ||
1203 | /* | |
1204 | * Add cb1 and cb return | |
1205 | */ | |
1206 | assert(pr_poll_loop_add_pre_poll_cb(poll_loop, test_pre_poll_cb1, | |
1207 | &pre_poll_cb1_called, test_pre_poll_cb1) == 0); | |
1208 | assert(pr_poll_loop_add_pre_poll_cb(poll_loop, test_pre_poll_cb_return, | |
1209 | &pre_poll_cb_return_called, test_pre_poll_cb_return) == 0); | |
1210 | ||
1211 | assert((timeout_timer = timer_list_add( | |
1212 | pr_poll_loop_get_timer_list(poll_loop), TIMER_TEST_TIMEOUT, timeout_cb, NULL, NULL)) != NULL); | |
1213 | timeout_cb_called = 0; | |
1214 | ||
1215 | assert(pr_poll_loop_exec(poll_loop) == -1); | |
1216 | assert(timeout_cb_called == 0); | |
1217 | assert(pre_poll_cb1_called == 4); | |
1218 | assert(pre_poll_cb2_called == 3); | |
1219 | assert(pre_poll_cb_return_called == 1); | |
1220 | timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer); | |
1221 | ||
1222 | /* | |
1223 | * Remove cb_return | |
1224 | */ | |
1225 | assert(pr_poll_loop_del_pre_poll_cb(poll_loop, test_pre_poll_cb_return) == 0); | |
1226 | ||
1227 | assert((timeout_timer = timer_list_add( | |
1228 | pr_poll_loop_get_timer_list(poll_loop), TIMER_TEST_TIMEOUT, timeout_cb, NULL, NULL)) != NULL); | |
1229 | timeout_cb_called = 0; | |
1230 | ||
1231 | assert(pr_poll_loop_exec(poll_loop) == 0); | |
1232 | ||
1233 | assert(timeout_cb_called == 1); | |
1234 | assert(pre_poll_cb1_called == 5); | |
1235 | assert(pre_poll_cb2_called == 4); | |
1236 | assert(pre_poll_cb_return_called == 1); | |
1237 | ||
1238 | /* | |
1239 | * Cleanup | |
1240 | */ | |
1241 | assert(pr_poll_loop_del_pre_poll_cb(poll_loop, test_pre_poll_cb1) == 0); | |
1242 | assert(pr_poll_loop_del_pre_poll_cb(poll_loop, test_pre_poll_cb2) == 0); | |
1243 | assert(pr_poll_loop_del_pre_poll_cb(poll_loop, test_pre_poll_cb_return) == -1); | |
1244 | assert(pr_poll_loop_del_pre_poll_cb(poll_loop, test_pre_poll_cb1) == -1); | |
1245 | assert(pr_poll_loop_del_pre_poll_cb(poll_loop, test_pre_poll_cb2) == -1); | |
1246 | assert(pr_poll_loop_del_pre_poll_cb(poll_loop, test_pre_poll_cb_return) == -1); | |
e7ef3641 JF |
1247 | } |
1248 | ||
687a72a0 JF |
1249 | int |
1250 | main(void) | |
1251 | { | |
1252 | struct pr_poll_loop poll_loop; | |
1253 | ||
1254 | PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); | |
1255 | ||
1256 | pr_poll_loop_init(&poll_loop); | |
1257 | ||
1258 | test_fd_basics(&poll_loop); | |
1259 | ||
1260 | test_prfd_basics(&poll_loop); | |
1261 | ||
ea6d7a90 JF |
1262 | test_pre_poll_cb(&poll_loop); |
1263 | ||
e7ef3641 JF |
1264 | test_complex(&poll_loop); |
1265 | ||
687a72a0 JF |
1266 | pr_poll_loop_destroy(&poll_loop); |
1267 | ||
1268 | assert(PR_Cleanup() == PR_SUCCESS); | |
1269 | ||
1270 | return (0); | |
1271 | } |