]> git.saurik.com Git - apple/libpthread.git/blob - tests/add_timer_termination.c
libpthread-330.230.1.tar.gz
[apple/libpthread.git] / tests / add_timer_termination.c
1 #include <assert.h>
2 #include <errno.h>
3 #include <stdatomic.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <unistd.h>
8 #include <time.h>
9 #include <sys/types.h>
10 #include <sys/sysctl.h>
11 #include <sys/qos.h>
12 #include <mach/mach_time.h>
13
14 #include <pthread.h>
15 #include <pthread/tsd_private.h>
16 #include <pthread/qos_private.h>
17 #include <pthread/workqueue_private.h>
18
19 #include <dispatch/dispatch.h>
20
21 #include "darwintest_defaults.h"
22 #include <darwintest_utils.h>
23
24 extern void __exit(int) __attribute__((noreturn));
25
26 static void __attribute__((noreturn))
27 run_add_timer_termination(void)
28 {
29 const int SOURCES = 32;
30 static unsigned int time_to_sleep; time_to_sleep = (unsigned int)(arc4random() % 5000 + 500);
31
32 static int pipes[SOURCES][2];
33 static dispatch_source_t s[SOURCES];
34 for (int i = 0; i < SOURCES; i++) {
35 pipe(pipes[i]);
36 s[i] = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, (uintptr_t)pipes[i][0], 0, NULL);
37 dispatch_source_set_event_handler(s[i], ^{
38 while(1) pause();
39 });
40 dispatch_resume(s[i]);
41 }
42
43 dispatch_async(dispatch_get_global_queue(0,0), ^{
44 for (int i = 1; i < SOURCES; i++){
45 write(pipes[i][1], &SOURCES, 1);
46 usleep(1);
47 }
48 while(1) pause();
49 });
50
51 usleep(time_to_sleep);
52 __exit(0);
53 }
54
55 T_DECL(add_timer_termination, "termination during add timer",
56 T_META_CHECK_LEAKS(NO))
57 {
58 const int ROUNDS = 128;
59 const int TIMEOUT = 5;
60 for (int i = 0; i < ROUNDS; i++){
61 pid_t pid = fork();
62 T_QUIET; T_ASSERT_POSIX_SUCCESS(pid, "fork");
63 if (pid == 0) { // child
64 run_add_timer_termination();
65 } else { // parent
66 bool success = dt_waitpid(pid, NULL, NULL, TIMEOUT);
67 T_ASSERT_TRUE(success, "Child %d exits successfully", i);
68 }
69 }
70 }