2 Unix SMB/CIFS implementation.
4 testing of the events subsystem
6 Copyright (C) Stefan Metzmacher 2006-2009
7 Copyright (C) Jeremy Allison 2013
9 ** NOTE! The following LGPL license applies to the tevent
10 ** library. This does NOT imply that all of Samba is released
13 This library is free software; you can redistribute it and/or
14 modify it under the terms of the GNU Lesser General Public
15 License as published by the Free Software Foundation; either
16 version 3 of the License, or (at your option) any later version.
18 This library is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 Lesser General Public License for more details.
23 You should have received a copy of the GNU Lesser General Public
24 License along with this library; if not, see <http://www.gnu.org/licenses/>.
28 #define TEVENT_DEPRECATED 1
30 #include "system/filesys.h"
31 #include "system/select.h"
32 #include "system/network.h"
33 #include "torture/torture.h"
34 #include "torture/local/proto.h"
35 #include "lib/util/blocking.h"
37 #include "system/threads.h"
41 static struct tevent_context
*
42 test_tevent_context_init(TALLOC_CTX
*mem_ctx
)
44 struct tevent_context
*ev
= NULL
;
46 ev
= tevent_context_init(mem_ctx
);
48 samba_tevent_set_debug(ev
, "<default>");
54 static struct tevent_context
*
55 test_tevent_context_init_byname(TALLOC_CTX
*mem_ctx
, const char *name
)
57 struct tevent_context
*ev
= NULL
;
59 ev
= tevent_context_init_byname(mem_ctx
, name
);
61 samba_tevent_set_debug(ev
, name
);
69 static void do_read(int fd
, void *buf
, size_t count
)
74 ret
= read(fd
, buf
, count
);
75 } while (ret
== -1 && errno
== EINTR
);
78 static void fde_handler_read(struct tevent_context
*ev_ctx
, struct tevent_fd
*f
,
79 uint16_t flags
, void *private_data
)
81 int *fd
= (int *)private_data
;
84 kill(getpid(), SIGUSR1
);
86 kill(getpid(), SIGALRM
);
88 do_read(fd
[0], &c
, 1);
92 static void do_write(int fd
, void *buf
, size_t count
)
97 ret
= write(fd
, buf
, count
);
98 } while (ret
== -1 && errno
== EINTR
);
101 static void do_fill(int fd
)
103 uint8_t buf
[1024] = {0, };
106 set_blocking(fd
, false);
110 ret
= write(fd
, buf
, ARRAY_SIZE(buf
));
111 } while (ret
== -1 && errno
== EINTR
);
112 } while (ret
== ARRAY_SIZE(buf
));
114 set_blocking(fd
, true);
117 static void fde_handler_write(struct tevent_context
*ev_ctx
, struct tevent_fd
*f
,
118 uint16_t flags
, void *private_data
)
120 int *fd
= (int *)private_data
;
123 do_write(fd
[1], &c
, 1);
127 /* This will only fire if the fd's returned from pipe() are bi-directional. */
128 static void fde_handler_read_1(struct tevent_context
*ev_ctx
, struct tevent_fd
*f
,
129 uint16_t flags
, void *private_data
)
131 int *fd
= (int *)private_data
;
134 kill(getpid(), SIGUSR1
);
136 kill(getpid(), SIGALRM
);
138 do_read(fd
[1], &c
, 1);
142 /* This will only fire if the fd's returned from pipe() are bi-directional. */
143 static void fde_handler_write_1(struct tevent_context
*ev_ctx
, struct tevent_fd
*f
,
144 uint16_t flags
, void *private_data
)
146 int *fd
= (int *)private_data
;
148 do_write(fd
[0], &c
, 1);
151 static void finished_handler(struct tevent_context
*ev_ctx
, struct tevent_timer
*te
,
152 struct timeval tval
, void *private_data
)
154 int *finished
= (int *)private_data
;
158 static void count_handler(struct tevent_context
*ev_ctx
, struct tevent_signal
*te
,
159 int signum
, int count
, void *info
, void *private_data
)
161 int *countp
= (int *)private_data
;
165 static bool test_event_context(struct torture_context
*test
,
166 const void *test_data
)
168 struct tevent_context
*ev_ctx
;
169 int fd
[2] = { -1, -1 };
170 const char *backend
= (const char *)test_data
;
171 int alarm_count
=0, info_count
=0;
172 struct tevent_fd
*fde_read
;
173 struct tevent_fd
*fde_read_1
;
174 struct tevent_fd
*fde_write
;
175 struct tevent_fd
*fde_write_1
;
177 struct tevent_signal
*se1
= NULL
;
180 struct tevent_signal
*se2
= NULL
;
183 struct tevent_signal
*se3
= NULL
;
189 ev_ctx
= test_tevent_context_init_byname(test
, backend
);
190 if (ev_ctx
== NULL
) {
191 torture_comment(test
, "event backend '%s' not supported\n", backend
);
195 torture_comment(test
, "backend '%s' - %s\n",
196 backend
, __FUNCTION__
);
203 torture_assert_int_equal(test
, ret
, 0, "pipe failed");
205 fde_read
= tevent_add_fd(ev_ctx
, ev_ctx
, fd
[0], TEVENT_FD_READ
,
206 fde_handler_read
, fd
);
207 fde_write_1
= tevent_add_fd(ev_ctx
, ev_ctx
, fd
[0], TEVENT_FD_WRITE
,
208 fde_handler_write_1
, fd
);
210 fde_write
= tevent_add_fd(ev_ctx
, ev_ctx
, fd
[1], TEVENT_FD_WRITE
,
211 fde_handler_write
, fd
);
212 fde_read_1
= tevent_add_fd(ev_ctx
, ev_ctx
, fd
[1], TEVENT_FD_READ
,
213 fde_handler_read_1
, fd
);
215 tevent_fd_set_auto_close(fde_read
);
216 tevent_fd_set_auto_close(fde_write
);
218 tevent_add_timer(ev_ctx
, ev_ctx
, timeval_current_ofs(2,0),
219 finished_handler
, &finished
);
222 se1
= tevent_add_signal(ev_ctx
, ev_ctx
, SIGALRM
, SA_RESTART
, count_handler
, &alarm_count
);
223 torture_assert(test
, se1
!= NULL
, "failed to setup se1");
226 se2
= tevent_add_signal(ev_ctx
, ev_ctx
, SIGALRM
, SA_RESETHAND
, count_handler
, &alarm_count
);
227 torture_assert(test
, se2
!= NULL
, "failed to setup se2");
230 se3
= tevent_add_signal(ev_ctx
, ev_ctx
, SIGUSR1
, SA_SIGINFO
, count_handler
, &info_count
);
231 torture_assert(test
, se3
!= NULL
, "failed to setup se3");
234 t
= timeval_current();
237 if (tevent_loop_once(ev_ctx
) == -1) {
239 torture_fail(test
, talloc_asprintf(test
, "Failed event loop %s\n", strerror(errno
)));
244 talloc_free(fde_read_1
);
245 talloc_free(fde_write_1
);
246 talloc_free(fde_read
);
247 talloc_free(fde_write
);
249 while (alarm_count
< fde_count
+1) {
250 if (tevent_loop_once(ev_ctx
) == -1) {
255 torture_comment(test
, "Got %.2f pipe events/sec\n", fde_count
/timeval_elapsed(&t
));
261 torture_assert_int_equal(test
, alarm_count
, 1+fde_count
, "alarm count mismatch");
265 * we do not call talloc_free(se2)
266 * because it is already gone,
267 * after triggering the event handler.
273 torture_assert_int_equal(test
, info_count
, fde_count
, "info count mismatch");
281 static void fde_handler_do_read(struct tevent_context
*ev_ctx
, struct tevent_fd
*f
,
282 uint16_t flags
, void *private_data
)
284 int *fd
= (int *)private_data
;
287 do_read(fd
[0], &c
, 1);
291 static void fde_handler_do_write(struct tevent_context
*ev_ctx
, struct tevent_fd
*f
,
292 uint16_t flags
, void *private_data
)
294 int *fd
= (int *)private_data
;
297 do_write(fd
[1], &c
, 1);
300 static void fde_handler_ignore(struct tevent_context
*ev_ctx
, struct tevent_fd
*f
,
301 uint16_t flags
, void *private_data
)
305 static bool test_fd_speedX(struct torture_context
*test
,
306 const void *test_data
,
307 size_t additional_fdes
)
309 struct tevent_context
*ev_ctx
= NULL
;
310 int fd
[2] = { -1, -1 };
311 const char *backend
= (const char *)test_data
;
312 struct tevent_fd
*fde_read
= NULL
;
313 struct tevent_fd
*fde_write
= NULL
;
319 ev_ctx
= test_tevent_context_init_byname(test
, backend
);
320 if (ev_ctx
== NULL
) {
321 torture_comment(test
, "event backend '%s' not supported\n", backend
);
325 torture_comment(test
, "backend '%s' - test_fd_speed%zu\n",
326 backend
, 1 + additional_fdes
);
333 torture_assert_int_equal(test
, ret
, 0, "pipe failed");
335 fde_read
= tevent_add_fd(ev_ctx
, ev_ctx
, fd
[0], TEVENT_FD_READ
,
336 fde_handler_do_read
, fd
);
338 fde_write
= tevent_add_fd(ev_ctx
, ev_ctx
, fd
[1], TEVENT_FD_WRITE
,
339 fde_handler_do_write
, fd
);
341 for (i
= 0; i
< additional_fdes
; i
++) {
342 tevent_add_fd(ev_ctx
, ev_ctx
, fd
[0], TEVENT_FD_WRITE
,
343 fde_handler_ignore
, fd
);
344 tevent_add_fd(ev_ctx
, ev_ctx
, fd
[1], TEVENT_FD_READ
,
345 fde_handler_ignore
, fd
);
348 tevent_fd_set_auto_close(fde_read
);
349 tevent_fd_set_auto_close(fde_write
);
351 tevent_add_timer(ev_ctx
, ev_ctx
, timeval_current_ofs(600,0),
352 finished_handler
, &finished
);
354 t
= timeval_current();
355 while (!finished
&& fde_count
< 1000000) {
357 if (tevent_loop_once(ev_ctx
) == -1) {
359 torture_fail(test
, talloc_asprintf(test
, "Failed event loop %s\n", strerror(errno
)));
364 talloc_free(fde_read
);
365 talloc_free(fde_write
);
367 torture_comment(test
, "Got %.2f pipe events\n", (double)fde_count
);
368 torture_comment(test
, "Got %.2f pipe events/sec\n", fde_count
/timeval_elapsed(&t
));
375 static bool test_fd_speed1(struct torture_context
*test
,
376 const void *test_data
)
378 return test_fd_speedX(test
, test_data
, 0);
381 static bool test_fd_speed2(struct torture_context
*test
,
382 const void *test_data
)
384 return test_fd_speedX(test
, test_data
, 1);
387 static bool test_fd_speed3(struct torture_context
*test
,
388 const void *test_data
)
390 return test_fd_speedX(test
, test_data
, 2);
393 struct test_event_fd1_state
{
394 struct torture_context
*tctx
;
396 struct tevent_context
*ev
;
398 struct tevent_timer
*te
;
399 struct tevent_fd
*fde0
;
400 struct tevent_fd
*fde1
;
410 static void test_event_fd1_fde_handler(struct tevent_context
*ev_ctx
,
411 struct tevent_fd
*fde
,
415 struct test_event_fd1_state
*state
=
416 (struct test_event_fd1_state
*)private_data
;
418 if (state
->drain_done
) {
419 state
->finished
= true;
420 state
->error
= __location__
;
428 if (!(flags
& TEVENT_FD_READ
)) {
429 state
->finished
= true;
430 state
->error
= __location__
;
434 ret
= read(state
->sock
[0], &c
, 1);
442 tevent_fd_set_flags(fde
, 0);
443 state
->drain_done
= true;
447 if (!state
->got_write
) {
450 if (flags
!= TEVENT_FD_WRITE
) {
451 state
->finished
= true;
452 state
->error
= __location__
;
455 state
->got_write
= true;
458 * we write to the other socket...
460 do_write(state
->sock
[1], &c
, 1);
461 TEVENT_FD_NOT_WRITEABLE(fde
);
462 TEVENT_FD_READABLE(fde
);
466 if (!state
->got_read
) {
467 if (flags
!= TEVENT_FD_READ
) {
468 state
->finished
= true;
469 state
->error
= __location__
;
472 state
->got_read
= true;
474 TEVENT_FD_NOT_READABLE(fde
);
478 state
->finished
= true;
479 state
->error
= __location__
;
483 static void test_event_fd1_finished(struct tevent_context
*ev_ctx
,
484 struct tevent_timer
*te
,
488 struct test_event_fd1_state
*state
=
489 (struct test_event_fd1_state
*)private_data
;
491 if (state
->drain_done
) {
492 state
->finished
= true;
496 if (!state
->got_write
) {
497 state
->finished
= true;
498 state
->error
= __location__
;
502 if (!state
->got_read
) {
503 state
->finished
= true;
504 state
->error
= __location__
;
509 if (state
->loop_count
> 3) {
510 state
->finished
= true;
511 state
->error
= __location__
;
515 state
->got_write
= false;
516 state
->got_read
= false;
518 tevent_fd_set_flags(state
->fde0
, TEVENT_FD_WRITE
);
520 if (state
->loop_count
> 2) {
522 TALLOC_FREE(state
->fde1
);
523 TEVENT_FD_READABLE(state
->fde0
);
526 state
->te
= tevent_add_timer(state
->ev
, state
->ev
,
527 timeval_current_ofs(0,2000),
528 test_event_fd1_finished
, state
);
531 static bool test_event_fd1(struct torture_context
*tctx
,
532 const void *test_data
)
534 struct test_event_fd1_state state
;
539 state
.backend
= (const char *)test_data
;
541 state
.ev
= test_tevent_context_init_byname(tctx
, state
.backend
);
542 if (state
.ev
== NULL
) {
543 torture_skip(tctx
, talloc_asprintf(tctx
,
544 "event backend '%s' not supported\n",
549 torture_comment(tctx
, "backend '%s' - %s\n",
550 state
.backend
, __FUNCTION__
);
553 * This tests the following:
555 * It monitors the state of state.sock[0]
556 * with tevent_fd, but we never read/write on state.sock[0]
557 * while state.sock[1] * is only used to write a few bytes.
560 * - we wait only for TEVENT_FD_WRITE on state.sock[0]
561 * - we write 1 byte to state.sock[1]
562 * - we wait only for TEVENT_FD_READ on state.sock[0]
563 * - we disable events on state.sock[0]
564 * - the timer event restarts the loop
565 * Then we close state.sock[1]
567 * - we wait for TEVENT_FD_READ/WRITE on state.sock[0]
568 * - we try to read 1 byte
569 * - if the read gets an error of returns 0
570 * we disable the event handler
571 * - the timer finishes the test
576 ret
= socketpair(AF_UNIX
, SOCK_STREAM
, 0, state
.sock
);
577 torture_assert(tctx
, ret
== 0, "socketpair() failed");
579 state
.te
= tevent_add_timer(state
.ev
, state
.ev
,
580 timeval_current_ofs(0,10000),
581 test_event_fd1_finished
, &state
);
582 state
.fde0
= tevent_add_fd(state
.ev
, state
.ev
,
583 state
.sock
[0], TEVENT_FD_WRITE
,
584 test_event_fd1_fde_handler
, &state
);
585 /* state.fde1 is only used to auto close */
586 state
.fde1
= tevent_add_fd(state
.ev
, state
.ev
,
588 test_event_fd1_fde_handler
, &state
);
590 tevent_fd_set_auto_close(state
.fde0
);
591 tevent_fd_set_auto_close(state
.fde1
);
593 while (!state
.finished
) {
595 if (tevent_loop_once(state
.ev
) == -1) {
596 talloc_free(state
.ev
);
597 torture_fail(tctx
, talloc_asprintf(tctx
,
598 "Failed event loop %s\n",
603 talloc_free(state
.ev
);
605 torture_assert(tctx
, state
.error
== NULL
, talloc_asprintf(tctx
,
611 struct test_event_fd2_state
{
612 struct torture_context
*tctx
;
614 struct tevent_context
*ev
;
615 struct tevent_timer
*te
;
616 struct test_event_fd2_sock
{
617 struct test_event_fd2_state
*state
;
619 struct tevent_fd
*fde
;
628 static void test_event_fd2_sock_handler(struct tevent_context
*ev_ctx
,
629 struct tevent_fd
*fde
,
633 struct test_event_fd2_sock
*cur_sock
=
634 (struct test_event_fd2_sock
*)private_data
;
635 struct test_event_fd2_state
*state
= cur_sock
->state
;
636 struct test_event_fd2_sock
*oth_sock
= NULL
;
640 if (cur_sock
== &state
->sock0
) {
641 oth_sock
= &state
->sock1
;
643 oth_sock
= &state
->sock0
;
646 if (oth_sock
->num_written
== 1) {
647 if (flags
!= (TEVENT_FD_READ
| TEVENT_FD_WRITE
)) {
648 state
->finished
= true;
649 state
->error
= __location__
;
654 if (cur_sock
->num_read
== oth_sock
->num_written
) {
655 state
->finished
= true;
656 state
->error
= __location__
;
660 if (!(flags
& TEVENT_FD_READ
)) {
661 state
->finished
= true;
662 state
->error
= __location__
;
666 if (oth_sock
->num_read
>= PIPE_BUF
) {
668 * On Linux we become writable once we've read
669 * one byte. On Solaris we only become writable
670 * again once we've read 4096 bytes. PIPE_BUF
671 * is probably a safe bet to test against.
673 * There should be room to write a byte again
675 if (!(flags
& TEVENT_FD_WRITE
)) {
676 state
->finished
= true;
677 state
->error
= __location__
;
682 if ((flags
& TEVENT_FD_WRITE
) && !cur_sock
->got_full
) {
683 v
= (uint8_t)cur_sock
->num_written
;
684 ret
= write(cur_sock
->fd
, &v
, 1);
686 state
->finished
= true;
687 state
->error
= __location__
;
690 cur_sock
->num_written
++;
691 if (cur_sock
->num_written
> 0x80000000) {
692 state
->finished
= true;
693 state
->error
= __location__
;
699 if (!cur_sock
->got_full
) {
700 cur_sock
->got_full
= true;
702 if (!oth_sock
->got_full
) {
705 * lets wait for oth_sock
708 tevent_fd_set_flags(cur_sock
->fde
, 0);
713 * oth_sock waited for cur_sock,
716 tevent_fd_set_flags(oth_sock
->fde
,
717 TEVENT_FD_READ
|TEVENT_FD_WRITE
);
720 ret
= read(cur_sock
->fd
, &v
, 1);
722 state
->finished
= true;
723 state
->error
= __location__
;
726 c
= (uint8_t)cur_sock
->num_read
;
728 state
->finished
= true;
729 state
->error
= __location__
;
732 cur_sock
->num_read
++;
734 if (cur_sock
->num_read
< oth_sock
->num_written
) {
735 /* there is more to read */
739 * we read everything, we need to remove TEVENT_FD_WRITE
742 TEVENT_FD_NOT_WRITEABLE(cur_sock
->fde
);
744 if (oth_sock
->num_read
== cur_sock
->num_written
) {
746 * both directions are finished
748 state
->finished
= true;
754 static void test_event_fd2_finished(struct tevent_context
*ev_ctx
,
755 struct tevent_timer
*te
,
759 struct test_event_fd2_state
*state
=
760 (struct test_event_fd2_state
*)private_data
;
763 * this should never be triggered
765 state
->finished
= true;
766 state
->error
= __location__
;
769 static bool test_event_fd2(struct torture_context
*tctx
,
770 const void *test_data
)
772 struct test_event_fd2_state state
;
778 state
.backend
= (const char *)test_data
;
780 state
.ev
= test_tevent_context_init_byname(tctx
, state
.backend
);
781 if (state
.ev
== NULL
) {
782 torture_skip(tctx
, talloc_asprintf(tctx
,
783 "event backend '%s' not supported\n",
788 torture_comment(tctx
, "backend '%s' - %s\n",
789 state
.backend
, __FUNCTION__
);
792 * This tests the following
794 * - We write 1 byte to each socket
795 * - We wait for TEVENT_FD_READ/WRITE on both sockets
796 * - When we get TEVENT_FD_WRITE we write 1 byte
797 * until both socket buffers are full, which
798 * means both sockets only get TEVENT_FD_READ.
799 * - Then we read 1 byte until we have consumed
800 * all bytes the other end has written.
804 socketpair(AF_UNIX
, SOCK_STREAM
, 0, sock
);
807 * the timer should never expire
809 state
.te
= tevent_add_timer(state
.ev
, state
.ev
,
810 timeval_current_ofs(600, 0),
811 test_event_fd2_finished
, &state
);
812 state
.sock0
.state
= &state
;
813 state
.sock0
.fd
= sock
[0];
814 state
.sock0
.fde
= tevent_add_fd(state
.ev
, state
.ev
,
816 TEVENT_FD_READ
| TEVENT_FD_WRITE
,
817 test_event_fd2_sock_handler
,
819 state
.sock1
.state
= &state
;
820 state
.sock1
.fd
= sock
[1];
821 state
.sock1
.fde
= tevent_add_fd(state
.ev
, state
.ev
,
823 TEVENT_FD_READ
| TEVENT_FD_WRITE
,
824 test_event_fd2_sock_handler
,
827 tevent_fd_set_auto_close(state
.sock0
.fde
);
828 tevent_fd_set_auto_close(state
.sock1
.fde
);
830 do_write(state
.sock0
.fd
, &c
, 1);
831 state
.sock0
.num_written
++;
832 do_write(state
.sock1
.fd
, &c
, 1);
833 state
.sock1
.num_written
++;
835 while (!state
.finished
) {
837 if (tevent_loop_once(state
.ev
) == -1) {
838 talloc_free(state
.ev
);
839 torture_fail(tctx
, talloc_asprintf(tctx
,
840 "Failed event loop %s\n",
845 talloc_free(state
.ev
);
847 torture_assert(tctx
, state
.error
== NULL
, talloc_asprintf(tctx
,
853 struct test_event_fd3_state
{
854 struct torture_context
*tctx
;
856 struct tevent_context
*ev
;
857 struct timeval start_time
;
858 struct tevent_timer
*te1
, *te2
, *te3
, *te4
, *te5
;
859 struct test_event_fd3_sock
{
860 struct test_event_fd3_state
*state
;
861 const char *sock_name
;
863 const char *phase_name
;
864 uint64_t iteration_id
;
865 uint64_t max_iterations
;
866 uint16_t expected_flags
;
867 uint8_t expected_count
;
868 uint8_t actual_count
;
869 struct test_event_fd3_fde
{
870 struct test_event_fd3_sock
*sock
;
871 struct tevent_fd
*fde
;
872 uint64_t last_iteration_id
;
873 } fde1
, fde2
, fde3
, fde4
, fde5
, fde6
, fde7
, fde8
, fde9
;
874 void (*fde_callback
)(struct test_event_fd3_fde
*tfde
,
881 static void test_event_fd3_fde_callback(struct test_event_fd3_fde
*tfde
,
884 struct test_event_fd3_sock
*sock
= tfde
->sock
;
885 struct test_event_fd3_state
*state
= sock
->state
;
886 uint16_t fde_flags
= tevent_fd_get_flags(tfde
->fde
);
887 uint16_t expected_flags
= sock
->expected_flags
& fde_flags
;
889 if (expected_flags
== 0) {
890 state
->finished
= true;
891 state
->error
= __location__
;
895 if (flags
!= expected_flags
) {
896 state
->finished
= true;
897 state
->error
= __location__
;
901 if (tfde
->last_iteration_id
== sock
->iteration_id
) {
902 state
->finished
= true;
903 state
->error
= __location__
;
907 tfde
->last_iteration_id
= sock
->iteration_id
;
909 sock
->actual_count
+= 1;
911 if (sock
->actual_count
> sock
->expected_count
) {
912 state
->finished
= true;
913 state
->error
= __location__
;
917 if (sock
->actual_count
== sock
->expected_count
) {
918 sock
->actual_count
= 0;
919 sock
->iteration_id
+= 1;
922 if (sock
->iteration_id
> sock
->max_iterations
) {
923 torture_comment(state
->tctx
,
924 "%s: phase[%s] finished with %"PRIu64
" iterations\n",
927 sock
->max_iterations
);
928 tevent_fd_set_flags(sock
->fde1
.fde
, 0);
929 tevent_fd_set_flags(sock
->fde2
.fde
, 0);
930 tevent_fd_set_flags(sock
->fde3
.fde
, 0);
931 tevent_fd_set_flags(sock
->fde4
.fde
, 0);
932 tevent_fd_set_flags(sock
->fde5
.fde
, 0);
933 tevent_fd_set_flags(sock
->fde6
.fde
, 0);
934 tevent_fd_set_flags(sock
->fde7
.fde
, 0);
935 tevent_fd_set_flags(sock
->fde8
.fde
, 0);
936 tevent_fd_set_flags(sock
->fde9
.fde
, 0);
937 sock
->fde_callback
= NULL
;
941 static void test_event_fd3_prepare_phase(struct test_event_fd3_sock
*sock
,
942 const char *phase_name
,
943 uint64_t max_iterations
,
944 uint16_t expected_flags
,
945 uint8_t expected_count
,
956 struct test_event_fd3_state
*state
= sock
->state
;
958 if (sock
->fde_callback
!= NULL
) {
959 state
->finished
= true;
960 state
->error
= __location__
;
964 sock
->phase_name
= phase_name
;
965 sock
->max_iterations
= max_iterations
;
966 sock
->expected_flags
= expected_flags
;
967 sock
->expected_count
= expected_count
;
968 sock
->iteration_id
= 1;
969 sock
->actual_count
= 0;
971 tevent_fd_set_flags(sock
->fde1
.fde
, flags1
);
972 sock
->fde1
.last_iteration_id
= 0;
973 tevent_fd_set_flags(sock
->fde2
.fde
, flags2
);
974 sock
->fde2
.last_iteration_id
= 0;
975 tevent_fd_set_flags(sock
->fde3
.fde
, flags3
);
976 sock
->fde3
.last_iteration_id
= 0;
977 tevent_fd_set_flags(sock
->fde4
.fde
, flags4
);
978 sock
->fde4
.last_iteration_id
= 0;
979 tevent_fd_set_flags(sock
->fde5
.fde
, flags5
);
980 sock
->fde5
.last_iteration_id
= 0;
981 tevent_fd_set_flags(sock
->fde6
.fde
, flags6
);
982 sock
->fde6
.last_iteration_id
= 0;
983 tevent_fd_set_flags(sock
->fde7
.fde
, flags7
);
984 sock
->fde7
.last_iteration_id
= 0;
985 tevent_fd_set_flags(sock
->fde8
.fde
, flags8
);
986 sock
->fde8
.last_iteration_id
= 0;
987 tevent_fd_set_flags(sock
->fde9
.fde
, flags9
);
988 sock
->fde9
.last_iteration_id
= 0;
990 sock
->fde_callback
= test_event_fd3_fde_callback
;
993 static void test_event_fd3_sock_handler(struct tevent_context
*ev_ctx
,
994 struct tevent_fd
*fde
,
998 struct test_event_fd3_fde
*tfde
=
999 (struct test_event_fd3_fde
*)private_data
;
1000 struct test_event_fd3_sock
*sock
= tfde
->sock
;
1001 struct test_event_fd3_state
*state
= sock
->state
;
1003 if (sock
->fd
== -1) {
1004 state
->finished
= true;
1005 state
->error
= __location__
;
1009 if (sock
->fde_callback
== NULL
) {
1010 state
->finished
= true;
1011 state
->error
= __location__
;
1015 sock
->fde_callback(tfde
, flags
);
1019 static bool test_event_fd3_assert_timeout(struct test_event_fd3_state
*state
,
1020 double expected_elapsed
,
1023 double e
= timeval_elapsed(&state
->start_time
);
1024 double max_latency
= 0.05;
1026 if (e
< expected_elapsed
) {
1027 torture_comment(state
->tctx
,
1028 "%s: elapsed=%.6f < expected_elapsed=%.6f\n",
1029 func
, e
, expected_elapsed
);
1030 state
->finished
= true;
1031 state
->error
= __location__
;
1035 if (e
> (expected_elapsed
+ max_latency
)) {
1036 torture_comment(state
->tctx
,
1037 "%s: elapsed=%.6f > "
1038 "(expected_elapsed=%.6f + max_latency=%.6f)\n",
1039 func
, e
, expected_elapsed
, max_latency
);
1040 state
->finished
= true;
1041 state
->error
= __location__
;
1045 torture_comment(state
->tctx
, "%s: elapsed=%.6f\n", __func__
, e
);
1049 static void test_event_fd3_writeable(struct tevent_context
*ev_ctx
,
1050 struct tevent_timer
*te
,
1051 struct timeval tval
,
1054 struct test_event_fd3_state
*state
=
1055 (struct test_event_fd3_state
*)private_data
;
1057 if (!test_event_fd3_assert_timeout(state
, 1, __func__
)) {
1061 test_event_fd3_prepare_phase(&state
->sock0
,
1070 TEVENT_FD_READ
|TEVENT_FD_WRITE
,
1073 TEVENT_FD_READ
|TEVENT_FD_WRITE
,
1076 test_event_fd3_prepare_phase(&state
->sock1
,
1081 TEVENT_FD_READ
|TEVENT_FD_WRITE
|TEVENT_FD_ERROR
,
1082 TEVENT_FD_READ
|TEVENT_FD_WRITE
|TEVENT_FD_ERROR
,
1083 TEVENT_FD_READ
|TEVENT_FD_WRITE
|TEVENT_FD_ERROR
,
1084 TEVENT_FD_READ
|TEVENT_FD_WRITE
|TEVENT_FD_ERROR
,
1085 TEVENT_FD_READ
|TEVENT_FD_WRITE
|TEVENT_FD_ERROR
,
1086 TEVENT_FD_READ
|TEVENT_FD_WRITE
|TEVENT_FD_ERROR
,
1087 TEVENT_FD_READ
|TEVENT_FD_WRITE
|TEVENT_FD_ERROR
,
1088 TEVENT_FD_READ
|TEVENT_FD_WRITE
|TEVENT_FD_ERROR
,
1089 TEVENT_FD_READ
|TEVENT_FD_WRITE
|TEVENT_FD_ERROR
);
1092 static void test_event_fd3_readable(struct tevent_context
*ev_ctx
,
1093 struct tevent_timer
*te
,
1094 struct timeval tval
,
1097 struct test_event_fd3_state
*state
=
1098 (struct test_event_fd3_state
*)private_data
;
1101 if (!test_event_fd3_assert_timeout(state
, 2, __func__
)) {
1105 do_write(state
->sock0
.fd
, &c
, 1);
1106 do_write(state
->sock1
.fd
, &c
, 1);
1108 test_event_fd3_prepare_phase(&state
->sock0
,
1111 TEVENT_FD_READ
|TEVENT_FD_WRITE
,
1113 TEVENT_FD_READ
|TEVENT_FD_WRITE
|TEVENT_FD_ERROR
,
1114 TEVENT_FD_READ
|TEVENT_FD_WRITE
|TEVENT_FD_ERROR
,
1115 TEVENT_FD_READ
|TEVENT_FD_WRITE
|TEVENT_FD_ERROR
,
1116 TEVENT_FD_READ
|TEVENT_FD_WRITE
|TEVENT_FD_ERROR
,
1117 TEVENT_FD_READ
|TEVENT_FD_WRITE
|TEVENT_FD_ERROR
,
1118 TEVENT_FD_READ
|TEVENT_FD_WRITE
|TEVENT_FD_ERROR
,
1119 TEVENT_FD_READ
|TEVENT_FD_WRITE
|TEVENT_FD_ERROR
,
1120 TEVENT_FD_READ
|TEVENT_FD_WRITE
|TEVENT_FD_ERROR
,
1121 TEVENT_FD_READ
|TEVENT_FD_WRITE
|TEVENT_FD_ERROR
);
1123 test_event_fd3_prepare_phase(&state
->sock1
,
1126 TEVENT_FD_READ
|TEVENT_FD_WRITE
,
1129 TEVENT_FD_READ
|TEVENT_FD_WRITE
,
1130 TEVENT_FD_READ
|TEVENT_FD_WRITE
|TEVENT_FD_ERROR
,
1135 TEVENT_FD_WRITE
|TEVENT_FD_ERROR
,
1136 TEVENT_FD_READ
|TEVENT_FD_WRITE
);
1139 static void test_event_fd3_not_writeable(struct tevent_context
*ev_ctx
,
1140 struct tevent_timer
*te
,
1141 struct timeval tval
,
1144 struct test_event_fd3_state
*state
=
1145 (struct test_event_fd3_state
*)private_data
;
1147 if (!test_event_fd3_assert_timeout(state
, 3, __func__
)) {
1151 do_fill(state
->sock0
.fd
);
1152 do_fill(state
->sock1
.fd
);
1154 test_event_fd3_prepare_phase(&state
->sock0
,
1159 TEVENT_FD_READ
|TEVENT_FD_WRITE
,
1163 TEVENT_FD_READ
|TEVENT_FD_WRITE
|TEVENT_FD_ERROR
,
1164 TEVENT_FD_WRITE
|TEVENT_FD_ERROR
,
1165 TEVENT_FD_READ
|TEVENT_FD_ERROR
,
1169 test_event_fd3_prepare_phase(&state
->sock1
,
1174 TEVENT_FD_READ
|TEVENT_FD_WRITE
|TEVENT_FD_ERROR
,
1175 TEVENT_FD_READ
|TEVENT_FD_WRITE
|TEVENT_FD_ERROR
,
1176 TEVENT_FD_READ
|TEVENT_FD_WRITE
|TEVENT_FD_ERROR
,
1177 TEVENT_FD_READ
|TEVENT_FD_WRITE
|TEVENT_FD_ERROR
,
1178 TEVENT_FD_READ
|TEVENT_FD_WRITE
|TEVENT_FD_ERROR
,
1179 TEVENT_FD_READ
|TEVENT_FD_WRITE
|TEVENT_FD_ERROR
,
1180 TEVENT_FD_READ
|TEVENT_FD_WRITE
|TEVENT_FD_ERROR
,
1181 TEVENT_FD_READ
|TEVENT_FD_WRITE
|TEVENT_FD_ERROR
,
1182 TEVENT_FD_READ
|TEVENT_FD_WRITE
|TEVENT_FD_ERROR
);
1185 static void test_event_fd3_off(struct tevent_context
*ev_ctx
,
1186 struct tevent_timer
*te
,
1187 struct timeval tval
,
1190 struct test_event_fd3_state
*state
=
1191 (struct test_event_fd3_state
*)private_data
;
1193 if (!test_event_fd3_assert_timeout(state
, 4, __func__
)) {
1197 TALLOC_FREE(state
->sock0
.fde1
.fde
);
1198 state
->sock0
.fd
= -1;
1200 test_event_fd3_prepare_phase(&state
->sock1
,
1203 TEVENT_FD_READ
|TEVENT_FD_WRITE
|TEVENT_FD_ERROR
,
1205 TEVENT_FD_READ
|TEVENT_FD_WRITE
,
1209 TEVENT_FD_READ
|TEVENT_FD_WRITE
|TEVENT_FD_ERROR
,
1210 TEVENT_FD_WRITE
|TEVENT_FD_ERROR
,
1211 TEVENT_FD_READ
|TEVENT_FD_ERROR
,
1216 static void test_event_fd3_finished(struct tevent_context
*ev_ctx
,
1217 struct tevent_timer
*te
,
1218 struct timeval tval
,
1221 struct test_event_fd3_state
*state
=
1222 (struct test_event_fd3_state
*)private_data
;
1224 if (!test_event_fd3_assert_timeout(state
, 5, __func__
)) {
1229 * this should never be triggered
1231 if (state
->sock0
.fde_callback
!= NULL
) {
1232 state
->finished
= true;
1233 state
->error
= __location__
;
1236 if (state
->sock1
.fde_callback
!= NULL
) {
1237 state
->finished
= true;
1238 state
->error
= __location__
;
1242 state
->finished
= true;
1245 static bool test_event_fd3(struct torture_context
*tctx
,
1246 const void *test_data
)
1248 struct test_event_fd3_state state
= {
1250 .backend
= (const char *)test_data
,
1255 state
.ev
= test_tevent_context_init_byname(tctx
, state
.backend
);
1256 if (state
.ev
== NULL
) {
1257 torture_skip(tctx
, talloc_asprintf(tctx
,
1258 "event backend '%s' not supported\n",
1263 torture_comment(tctx
, "backend '%s' - %s\n",
1264 state
.backend
, __FUNCTION__
);
1268 rc
= socketpair(AF_UNIX
, SOCK_STREAM
, 0, sock
);
1269 torture_assert_int_equal(tctx
, rc
, 0, "socketpair()");
1271 state
.start_time
= timeval_current();
1272 state
.te1
= tevent_add_timer(state
.ev
, state
.ev
,
1273 timeval_add(&state
.start_time
, 5, 0),
1274 test_event_fd3_finished
, &state
);
1275 torture_assert(tctx
, state
.te1
!= NULL
, "tevent_add_timer()");
1276 state
.te2
= tevent_add_timer(state
.ev
, state
.ev
,
1277 timeval_add(&state
.start_time
, 1, 0),
1278 test_event_fd3_writeable
, &state
);
1279 torture_assert(tctx
, state
.te2
!= NULL
, "tevent_add_timer()");
1280 state
.te3
= tevent_add_timer(state
.ev
, state
.ev
,
1281 timeval_add(&state
.start_time
, 2, 0),
1282 test_event_fd3_readable
, &state
);
1283 torture_assert(tctx
, state
.te3
!= NULL
, "tevent_add_timer()");
1284 state
.te4
= tevent_add_timer(state
.ev
, state
.ev
,
1285 timeval_add(&state
.start_time
, 3, 0),
1286 test_event_fd3_not_writeable
, &state
);
1287 torture_assert(tctx
, state
.te4
!= NULL
, "tevent_add_timer()");
1288 state
.te5
= tevent_add_timer(state
.ev
, state
.ev
,
1289 timeval_add(&state
.start_time
, 4, 0),
1290 test_event_fd3_off
, &state
);
1291 torture_assert(tctx
, state
.te5
!= NULL
, "tevent_add_timer()");
1293 state
.sock0
.state
= &state
;
1294 state
.sock0
.sock_name
= "sock0";
1295 state
.sock0
.fd
= sock
[0];
1296 state
.sock0
.fde1
.sock
= &state
.sock0
;
1297 state
.sock0
.fde1
.fde
= tevent_add_fd(state
.ev
, state
.ev
,
1300 test_event_fd3_sock_handler
,
1302 torture_assert(tctx
, state
.sock0
.fde1
.fde
!= NULL
, "tevent_add_fd()");
1303 tevent_fd_set_auto_close(state
.sock0
.fde1
.fde
);
1304 state
.sock0
.fde2
.sock
= &state
.sock0
;
1305 state
.sock0
.fde2
.fde
= tevent_add_fd(state
.ev
, state
.ev
,
1308 test_event_fd3_sock_handler
,
1310 torture_assert(tctx
, state
.sock0
.fde2
.fde
!= NULL
, "tevent_add_fd()");
1311 state
.sock0
.fde3
.sock
= &state
.sock0
;
1312 state
.sock0
.fde3
.fde
= tevent_add_fd(state
.ev
, state
.ev
,
1315 test_event_fd3_sock_handler
,
1317 torture_assert(tctx
, state
.sock0
.fde3
.fde
!= NULL
, "tevent_add_fd()");
1318 state
.sock0
.fde4
.sock
= &state
.sock0
;
1319 state
.sock0
.fde4
.fde
= tevent_add_fd(state
.ev
, state
.ev
,
1322 test_event_fd3_sock_handler
,
1324 torture_assert(tctx
, state
.sock0
.fde4
.fde
!= NULL
, "tevent_add_fd()");
1325 state
.sock0
.fde5
.sock
= &state
.sock0
;
1326 state
.sock0
.fde5
.fde
= tevent_add_fd(state
.ev
, state
.ev
,
1329 test_event_fd3_sock_handler
,
1331 torture_assert(tctx
, state
.sock0
.fde5
.fde
!= NULL
, "tevent_add_fd()");
1332 state
.sock0
.fde6
.sock
= &state
.sock0
;
1333 state
.sock0
.fde6
.fde
= tevent_add_fd(state
.ev
, state
.ev
,
1336 test_event_fd3_sock_handler
,
1338 torture_assert(tctx
, state
.sock0
.fde6
.fde
!= NULL
, "tevent_add_fd()");
1339 state
.sock0
.fde7
.sock
= &state
.sock0
;
1340 state
.sock0
.fde7
.fde
= tevent_add_fd(state
.ev
, state
.ev
,
1343 test_event_fd3_sock_handler
,
1345 torture_assert(tctx
, state
.sock0
.fde7
.fde
!= NULL
, "tevent_add_fd()");
1346 state
.sock0
.fde8
.sock
= &state
.sock0
;
1347 state
.sock0
.fde8
.fde
= tevent_add_fd(state
.ev
, state
.ev
,
1350 test_event_fd3_sock_handler
,
1352 torture_assert(tctx
, state
.sock0
.fde8
.fde
!= NULL
, "tevent_add_fd()");
1353 state
.sock0
.fde9
.sock
= &state
.sock0
;
1354 state
.sock0
.fde9
.fde
= tevent_add_fd(state
.ev
, state
.ev
,
1357 test_event_fd3_sock_handler
,
1359 torture_assert(tctx
, state
.sock0
.fde9
.fde
!= NULL
, "tevent_add_fd()");
1361 state
.sock1
.state
= &state
;
1362 state
.sock1
.sock_name
= "sock1";
1363 state
.sock1
.fd
= sock
[1];
1364 state
.sock1
.fde1
.sock
= &state
.sock1
;
1365 state
.sock1
.fde1
.fde
= tevent_add_fd(state
.ev
, state
.ev
,
1368 test_event_fd3_sock_handler
,
1370 torture_assert(tctx
, state
.sock1
.fde1
.fde
!= NULL
, "tevent_add_fd()");
1371 tevent_fd_set_auto_close(state
.sock1
.fde1
.fde
);
1372 state
.sock1
.fde2
.sock
= &state
.sock1
;
1373 state
.sock1
.fde2
.fde
= tevent_add_fd(state
.ev
, state
.ev
,
1376 test_event_fd3_sock_handler
,
1378 torture_assert(tctx
, state
.sock1
.fde2
.fde
!= NULL
, "tevent_add_fd()");
1379 state
.sock1
.fde3
.sock
= &state
.sock1
;
1380 state
.sock1
.fde3
.fde
= tevent_add_fd(state
.ev
, state
.ev
,
1383 test_event_fd3_sock_handler
,
1385 torture_assert(tctx
, state
.sock1
.fde3
.fde
!= NULL
, "tevent_add_fd()");
1386 state
.sock1
.fde4
.sock
= &state
.sock1
;
1387 state
.sock1
.fde4
.fde
= tevent_add_fd(state
.ev
, state
.ev
,
1390 test_event_fd3_sock_handler
,
1392 torture_assert(tctx
, state
.sock1
.fde4
.fde
!= NULL
, "tevent_add_fd()");
1393 state
.sock1
.fde5
.sock
= &state
.sock1
;
1394 state
.sock1
.fde5
.fde
= tevent_add_fd(state
.ev
, state
.ev
,
1397 test_event_fd3_sock_handler
,
1399 torture_assert(tctx
, state
.sock1
.fde5
.fde
!= NULL
, "tevent_add_fd()");
1400 state
.sock1
.fde6
.sock
= &state
.sock1
;
1401 state
.sock1
.fde6
.fde
= tevent_add_fd(state
.ev
, state
.ev
,
1404 test_event_fd3_sock_handler
,
1406 torture_assert(tctx
, state
.sock1
.fde6
.fde
!= NULL
, "tevent_add_fd()");
1407 state
.sock1
.fde7
.sock
= &state
.sock1
;
1408 state
.sock1
.fde7
.fde
= tevent_add_fd(state
.ev
, state
.ev
,
1411 test_event_fd3_sock_handler
,
1413 torture_assert(tctx
, state
.sock1
.fde7
.fde
!= NULL
, "tevent_add_fd()");
1414 state
.sock1
.fde8
.sock
= &state
.sock1
;
1415 state
.sock1
.fde8
.fde
= tevent_add_fd(state
.ev
, state
.ev
,
1418 test_event_fd3_sock_handler
,
1420 torture_assert(tctx
, state
.sock1
.fde8
.fde
!= NULL
, "tevent_add_fd()");
1421 state
.sock1
.fde9
.sock
= &state
.sock1
;
1422 state
.sock1
.fde9
.fde
= tevent_add_fd(state
.ev
, state
.ev
,
1425 test_event_fd3_sock_handler
,
1427 torture_assert(tctx
, state
.sock1
.fde9
.fde
!= NULL
, "tevent_add_fd()");
1429 while (!state
.finished
) {
1431 if (tevent_loop_once(state
.ev
) == -1) {
1432 talloc_free(state
.ev
);
1433 torture_fail(tctx
, talloc_asprintf(tctx
,
1434 "Failed event loop %s\n",
1439 talloc_free(state
.ev
);
1441 torture_assert(tctx
, state
.error
== NULL
, talloc_asprintf(tctx
,
1442 "%s", state
.error
));
1447 struct test_wrapper_state
{
1448 struct torture_context
*tctx
;
1450 int num_wrap_handlers
;
1453 static bool test_wrapper_before_use(struct tevent_context
*wrap_ev
,
1455 struct tevent_context
*main_ev
,
1456 const char *location
)
1458 struct test_wrapper_state
*state
=
1459 talloc_get_type_abort(private_data
,
1460 struct test_wrapper_state
);
1462 torture_comment(state
->tctx
, "%s\n", __func__
);
1463 state
->num_wrap_handlers
++;
1467 static void test_wrapper_after_use(struct tevent_context
*wrap_ev
,
1469 struct tevent_context
*main_ev
,
1470 const char *location
)
1472 struct test_wrapper_state
*state
=
1473 talloc_get_type_abort(private_data
,
1474 struct test_wrapper_state
);
1476 torture_comment(state
->tctx
, "%s\n", __func__
);
1477 state
->num_wrap_handlers
++;
1480 static void test_wrapper_before_fd_handler(struct tevent_context
*wrap_ev
,
1482 struct tevent_context
*main_ev
,
1483 struct tevent_fd
*fde
,
1485 const char *handler_name
,
1486 const char *location
)
1488 struct test_wrapper_state
*state
=
1489 talloc_get_type_abort(private_data
,
1490 struct test_wrapper_state
);
1492 torture_comment(state
->tctx
, "%s\n", __func__
);
1493 state
->num_wrap_handlers
++;
1496 static void test_wrapper_after_fd_handler(struct tevent_context
*wrap_ev
,
1498 struct tevent_context
*main_ev
,
1499 struct tevent_fd
*fde
,
1501 const char *handler_name
,
1502 const char *location
)
1504 struct test_wrapper_state
*state
=
1505 talloc_get_type_abort(private_data
,
1506 struct test_wrapper_state
);
1508 torture_comment(state
->tctx
, "%s\n", __func__
);
1509 state
->num_wrap_handlers
++;
1512 static void test_wrapper_before_timer_handler(struct tevent_context
*wrap_ev
,
1514 struct tevent_context
*main_ev
,
1515 struct tevent_timer
*te
,
1516 struct timeval requested_time
,
1517 struct timeval trigger_time
,
1518 const char *handler_name
,
1519 const char *location
)
1521 struct test_wrapper_state
*state
=
1522 talloc_get_type_abort(private_data
,
1523 struct test_wrapper_state
);
1525 torture_comment(state
->tctx
, "%s\n", __func__
);
1526 state
->num_wrap_handlers
++;
1529 static void test_wrapper_after_timer_handler(struct tevent_context
*wrap_ev
,
1531 struct tevent_context
*main_ev
,
1532 struct tevent_timer
*te
,
1533 struct timeval requested_time
,
1534 struct timeval trigger_time
,
1535 const char *handler_name
,
1536 const char *location
)
1538 struct test_wrapper_state
*state
=
1539 talloc_get_type_abort(private_data
,
1540 struct test_wrapper_state
);
1542 torture_comment(state
->tctx
, "%s\n", __func__
);
1543 state
->num_wrap_handlers
++;
1546 static void test_wrapper_before_immediate_handler(struct tevent_context
*wrap_ev
,
1548 struct tevent_context
*main_ev
,
1549 struct tevent_immediate
*im
,
1550 const char *handler_name
,
1551 const char *location
)
1553 struct test_wrapper_state
*state
=
1554 talloc_get_type_abort(private_data
,
1555 struct test_wrapper_state
);
1557 torture_comment(state
->tctx
, "%s\n", __func__
);
1558 state
->num_wrap_handlers
++;
1561 static void test_wrapper_after_immediate_handler(struct tevent_context
*wrap_ev
,
1563 struct tevent_context
*main_ev
,
1564 struct tevent_immediate
*im
,
1565 const char *handler_name
,
1566 const char *location
)
1568 struct test_wrapper_state
*state
=
1569 talloc_get_type_abort(private_data
,
1570 struct test_wrapper_state
);
1572 torture_comment(state
->tctx
, "%s\n", __func__
);
1573 state
->num_wrap_handlers
++;
1576 static void test_wrapper_before_signal_handler(struct tevent_context
*wrap_ev
,
1578 struct tevent_context
*main_ev
,
1579 struct tevent_signal
*se
,
1583 const char *handler_name
,
1584 const char *location
)
1586 struct test_wrapper_state
*state
=
1587 talloc_get_type_abort(private_data
,
1588 struct test_wrapper_state
);
1590 torture_comment(state
->tctx
, "%s\n", __func__
);
1591 state
->num_wrap_handlers
++;
1594 static void test_wrapper_after_signal_handler(struct tevent_context
*wrap_ev
,
1596 struct tevent_context
*main_ev
,
1597 struct tevent_signal
*se
,
1601 const char *handler_name
,
1602 const char *location
)
1604 struct test_wrapper_state
*state
=
1605 talloc_get_type_abort(private_data
,
1606 struct test_wrapper_state
);
1608 torture_comment(state
->tctx
, "%s\n", __func__
);
1609 state
->num_wrap_handlers
++;
1612 static const struct tevent_wrapper_ops test_wrapper_ops
= {
1613 .name
= "test_wrapper",
1614 .before_use
= test_wrapper_before_use
,
1615 .after_use
= test_wrapper_after_use
,
1616 .before_fd_handler
= test_wrapper_before_fd_handler
,
1617 .after_fd_handler
= test_wrapper_after_fd_handler
,
1618 .before_timer_handler
= test_wrapper_before_timer_handler
,
1619 .after_timer_handler
= test_wrapper_after_timer_handler
,
1620 .before_immediate_handler
= test_wrapper_before_immediate_handler
,
1621 .after_immediate_handler
= test_wrapper_after_immediate_handler
,
1622 .before_signal_handler
= test_wrapper_before_signal_handler
,
1623 .after_signal_handler
= test_wrapper_after_signal_handler
,
1626 static void test_wrapper_timer_handler(struct tevent_context
*ev
,
1627 struct tevent_timer
*te
,
1631 struct test_wrapper_state
*state
=
1632 (struct test_wrapper_state
*)private_data
;
1635 torture_comment(state
->tctx
, "timer handler\n");
1637 state
->num_events
++;
1642 static void test_wrapper_fd_handler(struct tevent_context
*ev
,
1643 struct tevent_fd
*fde
,
1644 unsigned short fd_flags
,
1647 struct test_wrapper_state
*state
=
1648 (struct test_wrapper_state
*)private_data
;
1650 torture_comment(state
->tctx
, "fd handler\n");
1652 state
->num_events
++;
1657 static void test_wrapper_immediate_handler(struct tevent_context
*ev
,
1658 struct tevent_immediate
*im
,
1661 struct test_wrapper_state
*state
=
1662 (struct test_wrapper_state
*)private_data
;
1664 state
->num_events
++;
1667 torture_comment(state
->tctx
, "immediate handler\n");
1671 static void test_wrapper_signal_handler(struct tevent_context
*ev
,
1672 struct tevent_signal
*se
,
1678 struct test_wrapper_state
*state
=
1679 (struct test_wrapper_state
*)private_data
;
1681 torture_comment(state
->tctx
, "signal handler\n");
1683 state
->num_events
++;
1688 static bool test_wrapper(struct torture_context
*tctx
,
1689 const void *test_data
)
1691 struct test_wrapper_state
*state
= NULL
;
1692 int sock
[2] = { -1, -1};
1694 const int num_events
= 4;
1695 const char *backend
= (const char *)test_data
;
1696 struct tevent_context
*ev
= NULL
;
1697 struct tevent_context
*wrap_ev
= NULL
;
1698 struct tevent_fd
*fde
= NULL
;
1699 struct tevent_timer
*te
= NULL
;
1700 struct tevent_signal
*se
= NULL
;
1701 struct tevent_immediate
*im
= NULL
;
1706 ev
= test_tevent_context_init_byname(tctx
, backend
);
1708 torture_skip(tctx
, talloc_asprintf(tctx
,
1709 "event backend '%s' not supported\n",
1714 torture_comment(tctx
, "tevent backend '%s'\n", backend
);
1716 wrap_ev
= tevent_context_wrapper_create(
1717 ev
, ev
, &test_wrapper_ops
, &state
, struct test_wrapper_state
);
1718 torture_assert_not_null_goto(tctx
, wrap_ev
, ok
, done
,
1719 "tevent_context_wrapper_create failed\n");
1720 *state
= (struct test_wrapper_state
) {
1724 ret
= socketpair(AF_UNIX
, SOCK_STREAM
, 0, sock
);
1725 torture_assert_goto(tctx
, ret
== 0, ok
, done
, "socketpair failed\n");
1727 te
= tevent_add_timer(wrap_ev
, wrap_ev
,
1728 timeval_current_ofs(0, 0),
1729 test_wrapper_timer_handler
, state
);
1730 torture_assert_not_null_goto(tctx
, te
, ok
, done
,
1731 "tevent_add_timer failed\n");
1733 fde
= tevent_add_fd(wrap_ev
, wrap_ev
,
1736 test_wrapper_fd_handler
,
1738 torture_assert_not_null_goto(tctx
, fde
, ok
, done
,
1739 "tevent_add_fd failed\n");
1741 im
= tevent_create_immediate(wrap_ev
);
1742 torture_assert_not_null_goto(tctx
, im
, ok
, done
,
1743 "tevent_create_immediate failed\n");
1745 se
= tevent_add_signal(wrap_ev
, wrap_ev
,
1748 test_wrapper_signal_handler
,
1750 torture_assert_not_null_goto(tctx
, se
, ok
, done
,
1751 "tevent_add_signal failed\n");
1753 do_write(sock
[0], &c
, 1);
1754 kill(getpid(), SIGUSR1
);
1755 tevent_schedule_immediate(im
,
1757 test_wrapper_immediate_handler
,
1760 ret2
= tevent_context_push_use(wrap_ev
);
1761 torture_assert_goto(tctx
, ret2
, ok
, done
, "tevent_context_push_use(wrap_ev) failed\n");
1762 ret2
= tevent_context_push_use(ev
);
1763 torture_assert_goto(tctx
, ret2
, ok
, pop_use
, "tevent_context_push_use(ev) failed\n");
1764 tevent_context_pop_use(ev
);
1765 tevent_context_pop_use(wrap_ev
);
1767 ret
= tevent_loop_wait(ev
);
1768 torture_assert_int_equal_goto(tctx
, ret
, 0, ok
, done
, "tevent_loop_wait failed\n");
1770 torture_comment(tctx
, "Num events: %d\n", state
->num_events
);
1771 torture_comment(tctx
, "Num wrap handlers: %d\n",
1772 state
->num_wrap_handlers
);
1774 torture_assert_int_equal_goto(tctx
, state
->num_events
, num_events
, ok
, done
,
1775 "Wrong event count\n");
1776 torture_assert_int_equal_goto(tctx
, state
->num_wrap_handlers
,
1778 ok
, done
, "Wrong wrapper count\n");
1783 TALLOC_FREE(wrap_ev
);
1786 if (sock
[0] != -1) {
1789 if (sock
[1] != -1) {
1794 tevent_context_pop_use(wrap_ev
);
1798 static void test_free_wrapper_signal_handler(struct tevent_context
*ev
,
1799 struct tevent_signal
*se
,
1805 struct torture_context
*tctx
=
1806 talloc_get_type_abort(private_data
,
1807 struct torture_context
);
1809 torture_comment(tctx
, "signal handler\n");
1814 * signal handlers have highest priority in tevent, so this signal
1815 * handler will always be started before the other handlers
1816 * below. Freeing the (wrapper) event context here tests that the
1817 * wrapper implementation correctly handles the wrapper ev going away
1818 * with pending events.
1824 static void test_free_wrapper_fd_handler(struct tevent_context
*ev
,
1825 struct tevent_fd
*fde
,
1826 unsigned short fd_flags
,
1830 * This should never be called as
1831 * test_free_wrapper_signal_handler()
1832 * already destroyed the wrapper tevent_context.
1837 static void test_free_wrapper_immediate_handler(struct tevent_context
*ev
,
1838 struct tevent_immediate
*im
,
1842 * This should never be called as
1843 * test_free_wrapper_signal_handler()
1844 * already destroyed the wrapper tevent_context.
1849 static void test_free_wrapper_timer_handler(struct tevent_context
*ev
,
1850 struct tevent_timer
*te
,
1855 * This should never be called as
1856 * test_free_wrapper_signal_handler()
1857 * already destroyed the wrapper tevent_context.
1862 static bool test_free_wrapper(struct torture_context
*tctx
,
1863 const void *test_data
)
1865 struct test_wrapper_state
*state
= NULL
;
1866 int sock
[2] = { -1, -1};
1868 const char *backend
= (const char *)test_data
;
1869 TALLOC_CTX
*frame
= talloc_stackframe();
1870 struct tevent_context
*ev
= NULL
;
1871 struct tevent_context
*wrap_ev
= NULL
;
1872 struct tevent_fd
*fde
= NULL
;
1873 struct tevent_timer
*te
= NULL
;
1874 struct tevent_signal
*se
= NULL
;
1875 struct tevent_immediate
*im
= NULL
;
1879 ev
= test_tevent_context_init_byname(frame
, backend
);
1881 torture_skip(tctx
, talloc_asprintf(tctx
,
1882 "event backend '%s' not supported\n",
1887 torture_comment(tctx
, "tevent backend '%s'\n", backend
);
1889 wrap_ev
= tevent_context_wrapper_create(
1890 ev
, ev
, &test_wrapper_ops
, &state
, struct test_wrapper_state
);
1891 torture_assert_not_null_goto(tctx
, wrap_ev
, ok
, done
,
1892 "tevent_context_wrapper_create failed\n");
1893 *state
= (struct test_wrapper_state
) {
1897 ret
= socketpair(AF_UNIX
, SOCK_STREAM
, 0, sock
);
1898 torture_assert_goto(tctx
, ret
== 0, ok
, done
, "socketpair failed\n");
1900 fde
= tevent_add_fd(wrap_ev
, frame
,
1903 test_free_wrapper_fd_handler
,
1905 torture_assert_not_null_goto(tctx
, fde
, ok
, done
,
1906 "tevent_add_fd failed\n");
1908 te
= tevent_add_timer(wrap_ev
, frame
,
1909 timeval_current_ofs(0, 0),
1910 test_free_wrapper_timer_handler
, NULL
);
1911 torture_assert_not_null_goto(tctx
, te
, ok
, done
,
1912 "tevent_add_timer failed\n");
1914 im
= tevent_create_immediate(frame
);
1915 torture_assert_not_null_goto(tctx
, im
, ok
, done
,
1916 "tevent_create_immediate failed\n");
1918 se
= tevent_add_signal(wrap_ev
, frame
,
1921 test_free_wrapper_signal_handler
,
1923 torture_assert_not_null_goto(tctx
, se
, ok
, done
,
1924 "tevent_add_signal failed\n");
1926 do_write(sock
[0], &c
, 1);
1927 kill(getpid(), SIGUSR1
);
1928 tevent_schedule_immediate(im
,
1930 test_free_wrapper_immediate_handler
,
1933 ret
= tevent_loop_wait(ev
);
1934 torture_assert_goto(tctx
, ret
== 0, ok
, done
, "tevent_loop_wait failed\n");
1941 if (sock
[0] != -1) {
1944 if (sock
[1] != -1) {
1952 static pthread_mutex_t threaded_mutex
= PTHREAD_MUTEX_INITIALIZER
;
1953 static bool do_shutdown
= false;
1955 static void test_event_threaded_lock(void)
1958 ret
= pthread_mutex_lock(&threaded_mutex
);
1962 static void test_event_threaded_unlock(void)
1965 ret
= pthread_mutex_unlock(&threaded_mutex
);
1969 static void test_event_threaded_trace(enum tevent_trace_point point
,
1973 case TEVENT_TRACE_BEFORE_WAIT
:
1974 test_event_threaded_unlock();
1976 case TEVENT_TRACE_AFTER_WAIT
:
1977 test_event_threaded_lock();
1979 case TEVENT_TRACE_BEFORE_LOOP_ONCE
:
1980 case TEVENT_TRACE_AFTER_LOOP_ONCE
:
1985 static void test_event_threaded_timer(struct tevent_context
*ev
,
1986 struct tevent_timer
*te
,
1987 struct timeval current_time
,
1993 static void *test_event_poll_thread(void *private_data
)
1995 struct tevent_context
*ev
= (struct tevent_context
*)private_data
;
1997 test_event_threaded_lock();
2001 ret
= tevent_loop_once(ev
);
2004 test_event_threaded_unlock();
2011 static void test_event_threaded_read_handler(struct tevent_context
*ev
,
2012 struct tevent_fd
*fde
,
2016 int *pfd
= (int *)private_data
;
2020 if ((flags
& TEVENT_FD_READ
) == 0) {
2025 nread
= read(*pfd
, &c
, 1);
2026 } while ((nread
== -1) && (errno
== EINTR
));
2031 static bool test_event_context_threaded(struct torture_context
*test
,
2032 const void *test_data
)
2034 struct tevent_context
*ev
;
2035 struct tevent_timer
*te
;
2036 struct tevent_fd
*fde
;
2037 pthread_t poll_thread
;
2042 ev
= test_tevent_context_init_byname(test
, "poll_mt");
2043 torture_assert(test
, ev
!= NULL
, "poll_mt not supported");
2045 tevent_set_trace_callback(ev
, test_event_threaded_trace
, NULL
);
2047 te
= tevent_add_timer(ev
, ev
, timeval_current_ofs(5, 0),
2048 test_event_threaded_timer
, NULL
);
2049 torture_assert(test
, te
!= NULL
, "Could not add timer");
2051 ret
= pthread_create(&poll_thread
, NULL
, test_event_poll_thread
, ev
);
2052 torture_assert(test
, ret
== 0, "Could not create poll thread");
2055 torture_assert(test
, ret
== 0, "Could not create pipe");
2059 test_event_threaded_lock();
2061 fde
= tevent_add_fd(ev
, ev
, fds
[0], TEVENT_FD_READ
,
2062 test_event_threaded_read_handler
, &fds
[0]);
2063 torture_assert(test
, fde
!= NULL
, "Could not add fd event");
2065 test_event_threaded_unlock();
2069 do_write(fds
[1], &c
, 1);
2073 test_event_threaded_lock();
2075 test_event_threaded_unlock();
2077 do_write(fds
[1], &c
, 1);
2079 ret
= pthread_join(poll_thread
, NULL
);
2080 torture_assert(test
, ret
== 0, "pthread_join failed");
2085 #define NUM_TEVENT_THREADS 100
2087 /* Ugly, but needed for torture_comment... */
2088 static struct torture_context
*thread_test_ctx
;
2089 static pthread_t thread_map
[NUM_TEVENT_THREADS
];
2090 static unsigned thread_counter
;
2092 /* Called in master thread context */
2093 static void callback_nowait(struct tevent_context
*ev
,
2094 struct tevent_immediate
*im
,
2097 pthread_t
*thread_id_ptr
=
2098 talloc_get_type_abort(private_ptr
, pthread_t
);
2101 for (i
= 0; i
< NUM_TEVENT_THREADS
; i
++) {
2102 if (pthread_equal(*thread_id_ptr
,
2107 torture_comment(thread_test_ctx
,
2108 "Callback %u from thread %u\n",
2114 /* Blast the master tevent_context with a callback, no waiting. */
2115 static void *thread_fn_nowait(void *private_ptr
)
2117 struct tevent_thread_proxy
*master_tp
=
2118 talloc_get_type_abort(private_ptr
, struct tevent_thread_proxy
);
2119 struct tevent_immediate
*im
;
2120 pthread_t
*thread_id_ptr
;
2122 im
= tevent_create_immediate(NULL
);
2126 thread_id_ptr
= talloc(NULL
, pthread_t
);
2127 if (thread_id_ptr
== NULL
) {
2130 *thread_id_ptr
= pthread_self();
2132 tevent_thread_proxy_schedule(master_tp
,
2139 static void timeout_fn(struct tevent_context
*ev
,
2140 struct tevent_timer
*te
,
2141 struct timeval tv
, void *p
)
2143 thread_counter
= NUM_TEVENT_THREADS
* 10;
2146 static bool test_multi_tevent_threaded(struct torture_context
*test
,
2147 const void *test_data
)
2150 struct tevent_context
*master_ev
;
2151 struct tevent_thread_proxy
*tp
;
2153 talloc_disable_null_tracking();
2155 /* Ugly global stuff. */
2156 thread_test_ctx
= test
;
2159 master_ev
= test_tevent_context_init(NULL
);
2160 if (master_ev
== NULL
) {
2164 tp
= tevent_thread_proxy_create(master_ev
);
2167 talloc_asprintf(test
,
2168 "tevent_thread_proxy_create failed\n"));
2169 talloc_free(master_ev
);
2173 for (i
= 0; i
< NUM_TEVENT_THREADS
; i
++) {
2174 int ret
= pthread_create(&thread_map
[i
],
2180 talloc_asprintf(test
,
2181 "Failed to create thread %i, %d\n",
2187 /* Ensure we don't wait more than 10 seconds. */
2188 tevent_add_timer(master_ev
,
2190 timeval_current_ofs(10,0),
2194 while (thread_counter
< NUM_TEVENT_THREADS
) {
2195 int ret
= tevent_loop_once(master_ev
);
2196 torture_assert(test
, ret
== 0, "tevent_loop_once failed");
2199 torture_assert(test
, thread_counter
== NUM_TEVENT_THREADS
,
2200 "thread_counter fail\n");
2202 talloc_free(master_ev
);
2206 struct reply_state
{
2207 struct tevent_thread_proxy
*reply_tp
;
2208 pthread_t thread_id
;
2212 static void thread_timeout_fn(struct tevent_context
*ev
,
2213 struct tevent_timer
*te
,
2214 struct timeval tv
, void *p
)
2216 int *p_finished
= (int *)p
;
2221 /* Called in child-thread context */
2222 static void thread_callback(struct tevent_context
*ev
,
2223 struct tevent_immediate
*im
,
2226 struct reply_state
*rsp
=
2227 talloc_get_type_abort(private_ptr
, struct reply_state
);
2229 talloc_steal(ev
, rsp
);
2230 *rsp
->p_finished
= 1;
2233 /* Called in master thread context */
2234 static void master_callback(struct tevent_context
*ev
,
2235 struct tevent_immediate
*im
,
2238 struct reply_state
*rsp
=
2239 talloc_get_type_abort(private_ptr
, struct reply_state
);
2242 talloc_steal(ev
, rsp
);
2244 for (i
= 0; i
< NUM_TEVENT_THREADS
; i
++) {
2245 if (pthread_equal(rsp
->thread_id
,
2250 torture_comment(thread_test_ctx
,
2251 "Callback %u from thread %u\n",
2254 /* Now reply to the thread ! */
2255 tevent_thread_proxy_schedule(rsp
->reply_tp
,
2263 static void *thread_fn_1(void *private_ptr
)
2265 struct tevent_thread_proxy
*master_tp
=
2266 talloc_get_type_abort(private_ptr
, struct tevent_thread_proxy
);
2267 struct tevent_thread_proxy
*tp
;
2268 struct tevent_immediate
*im
;
2269 struct tevent_context
*ev
;
2270 struct reply_state
*rsp
;
2274 ev
= tevent_context_init(NULL
);
2279 tp
= tevent_thread_proxy_create(ev
);
2285 im
= tevent_create_immediate(ev
);
2291 rsp
= talloc(ev
, struct reply_state
);
2297 rsp
->thread_id
= pthread_self();
2299 rsp
->p_finished
= &finished
;
2301 /* Introduce a little randomness into the mix.. */
2302 usleep(random() % 7000);
2304 tevent_thread_proxy_schedule(master_tp
,
2309 /* Ensure we don't wait more than 10 seconds. */
2310 tevent_add_timer(ev
,
2312 timeval_current_ofs(10,0),
2316 while (finished
== 0) {
2317 ret
= tevent_loop_once(ev
);
2327 * NB. We should talloc_free(ev) here, but if we do
2328 * we currently get hit by helgrind Fix #323432
2329 * "When calling pthread_cond_destroy or pthread_mutex_destroy
2330 * with initializers as argument Helgrind (incorrectly) reports errors."
2332 * http://valgrind.10908.n7.nabble.com/Helgrind-3-9-0-false-positive-
2333 * with-pthread-mutex-destroy-td47757.html
2335 * Helgrind doesn't understand that the request/reply
2336 * messages provide synchronization between the lock/unlock
2337 * in tevent_thread_proxy_schedule(), and the pthread_destroy()
2338 * when the struct tevent_thread_proxy object is talloc_free'd.
2340 * As a work-around for now return ev for the parent thread to free.
2345 static bool test_multi_tevent_threaded_1(struct torture_context
*test
,
2346 const void *test_data
)
2349 struct tevent_context
*master_ev
;
2350 struct tevent_thread_proxy
*master_tp
;
2353 talloc_disable_null_tracking();
2355 /* Ugly global stuff. */
2356 thread_test_ctx
= test
;
2359 master_ev
= test_tevent_context_init(NULL
);
2360 if (master_ev
== NULL
) {
2364 master_tp
= tevent_thread_proxy_create(master_ev
);
2365 if (master_tp
== NULL
) {
2367 talloc_asprintf(test
,
2368 "tevent_thread_proxy_create failed\n"));
2369 talloc_free(master_ev
);
2373 for (i
= 0; i
< NUM_TEVENT_THREADS
; i
++) {
2374 ret
= pthread_create(&thread_map
[i
],
2380 talloc_asprintf(test
,
2381 "Failed to create thread %i, %d\n",
2387 while (thread_counter
< NUM_TEVENT_THREADS
) {
2388 ret
= tevent_loop_once(master_ev
);
2389 torture_assert(test
, ret
== 0, "tevent_loop_once failed");
2392 /* Wait for all the threads to finish - join 'em. */
2393 for (i
= 0; i
< NUM_TEVENT_THREADS
; i
++) {
2395 ret
= pthread_join(thread_map
[i
], &retval
);
2396 torture_assert(test
, ret
== 0, "pthread_join failed");
2397 /* Free the child thread event context. */
2398 talloc_free(retval
);
2401 talloc_free(master_ev
);
2405 struct threaded_test_2
{
2406 struct tevent_threaded_context
*tctx
;
2407 struct tevent_immediate
*im
;
2408 pthread_t thread_id
;
2411 static void master_callback_2(struct tevent_context
*ev
,
2412 struct tevent_immediate
*im
,
2413 void *private_data
);
2415 static void *thread_fn_2(void *private_data
)
2417 struct threaded_test_2
*state
= private_data
;
2419 state
->thread_id
= pthread_self();
2421 usleep(random() % 7000);
2423 tevent_threaded_schedule_immediate(
2424 state
->tctx
, state
->im
, master_callback_2
, state
);
2429 static void master_callback_2(struct tevent_context
*ev
,
2430 struct tevent_immediate
*im
,
2433 struct threaded_test_2
*state
= private_data
;
2436 for (i
= 0; i
< NUM_TEVENT_THREADS
; i
++) {
2437 if (pthread_equal(state
->thread_id
, thread_map
[i
])) {
2441 torture_comment(thread_test_ctx
,
2442 "Callback_2 %u from thread %u\n",
2448 static bool test_multi_tevent_threaded_2(struct torture_context
*test
,
2449 const void *test_data
)
2453 struct tevent_context
*ev
;
2454 struct tevent_threaded_context
*tctx
;
2457 thread_test_ctx
= test
;
2460 ev
= test_tevent_context_init(test
);
2461 torture_assert(test
, ev
!= NULL
, "tevent_context_init failed");
2464 * tevent_re_initialise used to have a bug where it did not
2465 * re-initialise the thread support after taking it
2466 * down. Exercise that code path.
2468 ret
= tevent_re_initialise(ev
);
2469 torture_assert(test
, ret
== 0, "tevent_re_initialise failed");
2471 tctx
= tevent_threaded_context_create(ev
, ev
);
2472 torture_assert(test
, tctx
!= NULL
,
2473 "tevent_threaded_context_create failed");
2475 for (i
=0; i
<NUM_TEVENT_THREADS
; i
++) {
2476 struct threaded_test_2
*state
;
2478 state
= talloc(ev
, struct threaded_test_2
);
2479 torture_assert(test
, state
!= NULL
, "talloc failed");
2482 state
->im
= tevent_create_immediate(state
);
2483 torture_assert(test
, state
->im
!= NULL
,
2484 "tevent_create_immediate failed");
2486 ret
= pthread_create(&thread_map
[i
], NULL
, thread_fn_2
, state
);
2487 torture_assert(test
, ret
== 0, "pthread_create failed");
2490 while (thread_counter
< NUM_TEVENT_THREADS
) {
2491 ret
= tevent_loop_once(ev
);
2492 torture_assert(test
, ret
== 0, "tevent_loop_once failed");
2495 /* Wait for all the threads to finish - join 'em. */
2496 for (i
= 0; i
< NUM_TEVENT_THREADS
; i
++) {
2498 ret
= pthread_join(thread_map
[i
], &retval
);
2499 torture_assert(test
, ret
== 0, "pthread_join failed");
2500 /* Free the child thread event context. */
2508 struct test_cached_pid_thread_state
{
2509 pid_t thread_cached_pid
;
2513 static void *test_cached_pid_thread(void *private_data
)
2515 struct test_cached_pid_thread_state
*state
=
2516 (struct test_cached_pid_thread_state
*)private_data
;
2518 state
->thread_cached_pid
= tevent_cached_getpid();
2519 state
->thread_pid
= getpid();
2525 static bool test_cached_pid(struct torture_context
*test
,
2526 const void *test_data
)
2528 pid_t parent_pid
= getpid();
2533 torture_assert(test
, tevent_cached_getpid() == parent_pid
, "tevent_cached_getpid()");
2537 struct test_cached_pid_thread_state state
= { .thread_cached_pid
= -1, };
2539 void *retval
= NULL
;
2542 ret
= pthread_create(&thread
, NULL
, test_cached_pid_thread
, &state
);
2543 torture_assert(test
, ret
== 0, "pthread_create failed");
2545 ret
= pthread_join(thread
, &retval
);
2546 torture_assert(test
, ret
== 0, "pthread_join failed");
2548 torture_assert(test
, state
.thread_pid
== parent_pid
, "getpid() in thread");
2549 torture_assert(test
, state
.thread_cached_pid
== parent_pid
, "tevent_cached_getpid() in thread");
2551 #endif /* HAVE_PTHREAD */
2554 if (child_pid
== 0) {
2556 pid_t pid
= getpid();
2557 pid_t cached_pid
= tevent_cached_getpid();
2559 if (parent_pid
== pid
) {
2562 if (pid
!= cached_pid
) {
2567 torture_assert(test
, child_pid
> 0, "fork failed");
2569 finished_pid
= waitpid(child_pid
, &child_status
, 0);
2570 torture_assert(test
, finished_pid
== child_pid
, "wrong child");
2571 torture_assert(test
, child_status
== 0, "child_status");
2576 struct torture_suite
*torture_local_event(TALLOC_CTX
*mem_ctx
)
2578 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "event");
2579 const char **list
= tevent_backend_list(suite
);
2582 for (i
=0;list
&& list
[i
];i
++) {
2583 struct torture_suite
*backend_suite
;
2585 backend_suite
= torture_suite_create(mem_ctx
, list
[i
]);
2587 torture_suite_add_simple_tcase_const(backend_suite
,
2590 (const void *)list
[i
]);
2591 torture_suite_add_simple_tcase_const(backend_suite
,
2594 (const void *)list
[i
]);
2595 torture_suite_add_simple_tcase_const(backend_suite
,
2598 (const void *)list
[i
]);
2599 torture_suite_add_simple_tcase_const(backend_suite
,
2602 (const void *)list
[i
]);
2603 torture_suite_add_simple_tcase_const(backend_suite
,
2606 (const void *)list
[i
]);
2607 torture_suite_add_simple_tcase_const(backend_suite
,
2610 (const void *)list
[i
]);
2611 torture_suite_add_simple_tcase_const(backend_suite
,
2614 (const void *)list
[i
]);
2615 torture_suite_add_simple_tcase_const(backend_suite
,
2618 (const void *)list
[i
]);
2619 torture_suite_add_simple_tcase_const(backend_suite
,
2622 (const void *)list
[i
]);
2624 torture_suite_add_suite(suite
, backend_suite
);
2628 torture_suite_add_simple_tcase_const(suite
, "threaded_poll_mt",
2629 test_event_context_threaded
,
2632 torture_suite_add_simple_tcase_const(suite
, "multi_tevent_threaded",
2633 test_multi_tevent_threaded
,
2636 torture_suite_add_simple_tcase_const(suite
, "multi_tevent_threaded_1",
2637 test_multi_tevent_threaded_1
,
2640 torture_suite_add_simple_tcase_const(suite
, "multi_tevent_threaded_2",
2641 test_multi_tevent_threaded_2
,
2646 torture_suite_add_simple_tcase_const(suite
, "tevent_cached_getpid",