2 * Make sure functions marked as cancellation points actually are.
3 * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_09.html#tag_02_09_05
14 #include <sys/socket.h>
15 #include <sys/types.h>
21 #include <semaphore.h>
30 /* take care of optional things ... */
31 #define STUB(func, args) static void func args { sleep(0); }
32 #if defined(__UCLIBC_AIO__)
35 STUB(aio_suspend
, (void *p
, int n
, const void *p2
))
37 #if defined(__UCLIBC_STROPTS__)
40 STUB(getmsg
, (int f
, void *p
, void *p2
, void *p3
))
41 STUB(getpmsg
, (int f
, void *p
, void *p2
, void *p3
, void *p4
))
42 STUB(putmsg
, (int f
, void *p
, void *p2
, void *p3
))
43 STUB(putpmsg
, (int f
, void *p
, void *p2
, void *p3
, void *p4
))
45 #if defined(__UCLIBC__)
46 STUB(clock_nanosleep
, (int i
, int f
, const void *p
, void *p2
))
52 void cancel_timeout(int sig
)
56 void cancel_thread_cleanup(void *arg
)
61 /* some funcs need some help as they wont take NULL args ... */
62 const struct timespec zero_sec
= { .tv_sec
= 0, .tv_nsec
= 0 };
65 void help_sem_setup(void)
67 if (sem_init(&sem
, 0, 1) == -1) {
68 perror("sem_init() failed");
73 pthread_cond_t cond
= PTHREAD_COND_INITIALIZER
;
74 pthread_mutex_t mutex
;
75 void help_pthread_setup(void)
77 pthread_mutex_init(&mutex
, NULL
);
78 pthread_mutex_lock(&mutex
);
81 /* the pthread function that will call the cancellable function over and over */
82 #define _MAKE_CANCEL_THREAD_FUNC_EX(func, sysfunc, args, setup) \
83 void *cancel_thread_##func(void *arg) \
85 if (pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL)) { \
86 perror("unable to set cancel type to deferred; something is seriously broken"); \
89 pthread_cleanup_push(cancel_thread_cleanup, NULL); \
94 pthread_cleanup_pop(1); \
97 #define MAKE_CANCEL_THREAD_FUNC_RE(func, sysfunc, args) _MAKE_CANCEL_THREAD_FUNC_EX(func, sysfunc, args, (void)0)
98 #define MAKE_CANCEL_THREAD_FUNC_EX(func, args, setup) _MAKE_CANCEL_THREAD_FUNC_EX(func, func, args, setup)
99 #define MAKE_CANCEL_THREAD_FUNC(func, args) _MAKE_CANCEL_THREAD_FUNC_EX(func, func, args, (void)0)
101 MAKE_CANCEL_THREAD_FUNC(accept
, (-1, NULL
, NULL
))
102 MAKE_CANCEL_THREAD_FUNC(aio_suspend
, (NULL
, 0, &zero_sec
))
103 MAKE_CANCEL_THREAD_FUNC(clock_nanosleep
, (0, 0, NULL
, NULL
))
104 MAKE_CANCEL_THREAD_FUNC(close
, (-1))
105 MAKE_CANCEL_THREAD_FUNC(connect
, (-1, NULL
, 0))
106 MAKE_CANCEL_THREAD_FUNC(creat
, ("", 0))
107 MAKE_CANCEL_THREAD_FUNC(fcntl
, (0, F_SETLKW
, NULL
))
108 MAKE_CANCEL_THREAD_FUNC(fdatasync
, (-1))
109 MAKE_CANCEL_THREAD_FUNC(fsync
, (0))
110 MAKE_CANCEL_THREAD_FUNC(getmsg
, (-1, NULL
, NULL
, NULL
))
111 MAKE_CANCEL_THREAD_FUNC(getpmsg
, (-1, NULL
, NULL
, NULL
, NULL
))
112 MAKE_CANCEL_THREAD_FUNC(lockf
, (-1, F_TEST
, 0))
113 MAKE_CANCEL_THREAD_FUNC(mq_receive
, (0, NULL
, 0, NULL
))
114 MAKE_CANCEL_THREAD_FUNC(mq_send
, (0, NULL
, 0, 0))
115 MAKE_CANCEL_THREAD_FUNC(mq_timedreceive
, (0, NULL
, 0, NULL
, NULL
))
116 MAKE_CANCEL_THREAD_FUNC(mq_timedsend
, (0, NULL
, 0, 0, NULL
))
117 MAKE_CANCEL_THREAD_FUNC(msgrcv
, (-1, NULL
, 0, 0, 0))
118 MAKE_CANCEL_THREAD_FUNC(msgsnd
, (-1, NULL
, 0, 0))
119 MAKE_CANCEL_THREAD_FUNC(msync
, (NULL
, 0, 0))
120 MAKE_CANCEL_THREAD_FUNC(nanosleep
, (NULL
, NULL
))
121 MAKE_CANCEL_THREAD_FUNC(open
, ("", 0))
122 MAKE_CANCEL_THREAD_FUNC(pause
, ())
123 MAKE_CANCEL_THREAD_FUNC(poll
, (NULL
, 0, 0))
124 MAKE_CANCEL_THREAD_FUNC(pread
, (-1, NULL
, 0, 0))
125 MAKE_CANCEL_THREAD_FUNC(pselect
, (0, NULL
, NULL
, NULL
, NULL
, NULL
))
126 MAKE_CANCEL_THREAD_FUNC_EX(pthread_cond_timedwait
, (&cond
, &mutex
, &zero_sec
), help_pthread_setup())
127 MAKE_CANCEL_THREAD_FUNC_EX(pthread_cond_wait
, (&cond
, &mutex
), help_pthread_setup())
128 /*MAKE_CANCEL_THREAD_FUNC_EX(pthread_join, (0, NULL))*/
129 MAKE_CANCEL_THREAD_FUNC(pthread_testcancel
, ())
130 MAKE_CANCEL_THREAD_FUNC(putmsg
, (-1, NULL
, NULL
, 0))
131 MAKE_CANCEL_THREAD_FUNC(putpmsg
, (-1, NULL
, NULL
, 0, 0))
132 MAKE_CANCEL_THREAD_FUNC(pwrite
, (-1, NULL
, 0, 0))
133 MAKE_CANCEL_THREAD_FUNC(read
, (-1, NULL
, 0))
134 MAKE_CANCEL_THREAD_FUNC(readv
, (-1, NULL
, 0))
135 MAKE_CANCEL_THREAD_FUNC(recv
, (-1, NULL
, 0, 0))
136 MAKE_CANCEL_THREAD_FUNC(recvfrom
, (-1, NULL
, 0, 0, NULL
, NULL
))
137 MAKE_CANCEL_THREAD_FUNC(recvmsg
, (-1, NULL
, 0))
138 MAKE_CANCEL_THREAD_FUNC(select
, (0, NULL
, NULL
, NULL
, NULL
))
139 MAKE_CANCEL_THREAD_FUNC_EX(sem_timedwait
, (&sem
, &zero_sec
), help_sem_setup())
140 MAKE_CANCEL_THREAD_FUNC_EX(sem_wait
, (&sem
), help_sem_setup())
141 MAKE_CANCEL_THREAD_FUNC(send
, (-1, NULL
, 0, 0))
142 MAKE_CANCEL_THREAD_FUNC(sendmsg
, (-1, NULL
, 0))
143 MAKE_CANCEL_THREAD_FUNC(sendto
, (-1, NULL
, 0, 0, NULL
, 0))
144 #ifdef __UCLIBC_SUSV4_LEGACY__
145 MAKE_CANCEL_THREAD_FUNC(sigpause
, (0))
147 MAKE_CANCEL_THREAD_FUNC(sigsuspend
, (NULL
))
148 MAKE_CANCEL_THREAD_FUNC(sigtimedwait
, (NULL
, NULL
, NULL
))
149 MAKE_CANCEL_THREAD_FUNC(sigwait
, (NULL
, NULL
))
150 MAKE_CANCEL_THREAD_FUNC(sigwaitinfo
, (NULL
, NULL
))
151 MAKE_CANCEL_THREAD_FUNC(sleep
, (0))
152 MAKE_CANCEL_THREAD_FUNC(system
, (""))
153 MAKE_CANCEL_THREAD_FUNC(tcdrain
, (-1))
154 #ifdef __UCLIBC_SUSV3_LEGACY__
155 MAKE_CANCEL_THREAD_FUNC(usleep
, (0))
157 MAKE_CANCEL_THREAD_FUNC(wait
, (NULL
))
158 MAKE_CANCEL_THREAD_FUNC(waitid
, (0, 0, NULL
, 0))
159 MAKE_CANCEL_THREAD_FUNC(waitpid
, (-1, NULL
, 0))
160 MAKE_CANCEL_THREAD_FUNC(write
, (-1, NULL
, 0))
161 MAKE_CANCEL_THREAD_FUNC(writev
, (-1, NULL
, 0))
163 /* test a few variations that should not cancel ... */
164 MAKE_CANCEL_THREAD_FUNC_RE(fcntl_another
, fcntl
, (0, F_GETFD
))
166 /* main test that creates thread, cancels it, etc... */
167 int _test_func(const char *func_name
, void *(*func
)(void*), const int should_cancel
)
170 pthread_t cancel_thread_id
;
174 printf("testing %-30s ", func_name
);
177 if (signal(SIGALRM
, cancel_timeout
) == SIG_ERR
) {
178 perror("unable to bind SIGALRM");
184 pthread_create(&cancel_thread_id
, NULL
, func
, NULL
);
191 if (pthread_cancel(cancel_thread_id
)) {
192 perror("unable to cancel thread");
202 ret
= (!!!alarm(0) == should_cancel
);
205 printf(" failed ;(\n");
211 #define TEST_FUNC(f) _test_func(#f, cancel_thread_##f, 1)
212 #define TEST_FUNC_RE(f) _test_func(#f, cancel_thread_##f, 0)
214 int main(int argc
, char *argv
[])
217 setbuf(stdout
, NULL
);
220 ret
+= TEST_FUNC(accept
);
221 ret
+= TEST_FUNC(aio_suspend
);
222 ret
+= TEST_FUNC(clock_nanosleep
);
223 ret
+= TEST_FUNC(close
);
224 ret
+= TEST_FUNC(connect
);
225 ret
+= TEST_FUNC(creat
);
226 ret
+= TEST_FUNC(fcntl
);
227 ret
+= TEST_FUNC(fdatasync
);
228 ret
+= TEST_FUNC(fsync
);
229 ret
+= TEST_FUNC(getmsg
);
230 ret
+= TEST_FUNC(getpmsg
);
231 ret
+= TEST_FUNC(lockf
);
232 ret
+= TEST_FUNC(mq_receive
);
233 ret
+= TEST_FUNC(mq_send
);
234 ret
+= TEST_FUNC(mq_timedreceive
);
235 ret
+= TEST_FUNC(mq_timedsend
);
236 ret
+= TEST_FUNC(msgrcv
);
237 ret
+= TEST_FUNC(msgsnd
);
238 ret
+= TEST_FUNC(msync
);
239 ret
+= TEST_FUNC(nanosleep
);
240 ret
+= TEST_FUNC(open
);
241 ret
+= TEST_FUNC(pause
);
242 ret
+= TEST_FUNC(poll
);
243 ret
+= TEST_FUNC(pread
);
244 ret
+= TEST_FUNC(pselect
);
245 ret
+= TEST_FUNC(pthread_cond_timedwait
);
246 ret
+= TEST_FUNC(pthread_cond_wait
);
247 /*ret += TEST_FUNC(pthread_join);*/
248 ret
+= TEST_FUNC(pthread_testcancel
);
249 ret
+= TEST_FUNC(putmsg
);
250 ret
+= TEST_FUNC(putpmsg
);
251 ret
+= TEST_FUNC(pwrite
);
252 ret
+= TEST_FUNC(read
);
253 ret
+= TEST_FUNC(readv
);
254 ret
+= TEST_FUNC(recv
);
255 ret
+= TEST_FUNC(recvfrom
);
256 ret
+= TEST_FUNC(recvmsg
);
257 ret
+= TEST_FUNC(select
);
258 ret
+= TEST_FUNC(sem_timedwait
);
259 ret
+= TEST_FUNC(sem_wait
);
260 ret
+= TEST_FUNC(send
);
261 ret
+= TEST_FUNC(sendmsg
);
262 ret
+= TEST_FUNC(sendto
);
263 ret
+= TEST_FUNC(sigpause
);
264 ret
+= TEST_FUNC(sigsuspend
);
265 ret
+= TEST_FUNC(sigtimedwait
);
266 ret
+= TEST_FUNC(sigwait
);
267 ret
+= TEST_FUNC(sigwaitinfo
);
268 ret
+= TEST_FUNC(sleep
);
269 ret
+= TEST_FUNC(system
);
270 ret
+= TEST_FUNC(tcdrain
);
271 #ifdef __UCLIBC_SUSV3_LEGACY__
272 ret
+= TEST_FUNC(usleep
);
274 ret
+= TEST_FUNC(wait
);
275 ret
+= TEST_FUNC(waitid
);
276 ret
+= TEST_FUNC(waitpid
);
277 ret
+= TEST_FUNC(write
);
278 ret
+= TEST_FUNC(writev
);
280 ret
+= TEST_FUNC_RE(fcntl_another
);
283 printf("!!! %i / %i tests failed\n", ret
, cnt
);