]>
Commit | Line | Data |
---|---|---|
2546420a A |
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 | ||
a0619f9c | 21 | #include "darwintest_defaults.h" |
2546420a A |
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 | } |