1 /* Check if a thread that disables cancellation and which call functions
2 that might be interrupted by a signal do not see the internal SIGCANCEL.
4 Copyright (C) 2022 Free Software Foundation, Inc.
5 This file is part of the GNU C Library.
7 The GNU C Library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
12 The GNU C Library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public
18 License along with the GNU C Library; if not, see
19 <https://www.gnu.org/licenses/>. */
21 #include <array_length.h>
25 #include <support/check.h>
26 #include <support/support.h>
27 #include <support/temp_file.h>
28 #include <support/xthread.h>
29 #include <sys/socket.h>
34 /* On Linux some interfaces are never restarted after being interrupted by
35 a signal handler, regardless of the use of SA_RESTART. It means that
36 if asynchronous cancellation is not enabled, the pthread_cancel can not
37 set the internal SIGCANCEL otherwise the interface might see a spurious
40 static pthread_barrier_t b
;
42 /* Cleanup handling test. */
51 tf_sigtimedwait (void *arg
)
53 pthread_setcancelstate (PTHREAD_CANCEL_DISABLE
, NULL
);
54 xpthread_barrier_wait (&b
);
57 pthread_cleanup_push (cl
, NULL
);
61 r
= sigtimedwait (&mask
, NULL
, &(struct timespec
) { 0, 250000000 });
67 pthread_cleanup_pop (0);
74 pthread_setcancelstate (PTHREAD_CANCEL_DISABLE
, NULL
);
75 xpthread_barrier_wait (&b
);
78 pthread_cleanup_push (cl
, NULL
);
80 r
= poll (NULL
, 0, 250);
84 pthread_cleanup_pop (0);
91 pthread_setcancelstate (PTHREAD_CANCEL_DISABLE
, NULL
);
93 xpthread_barrier_wait (&b
);
96 pthread_cleanup_push (cl
, NULL
);
98 r
= ppoll (NULL
, 0, &(struct timespec
) { 0, 250000000 }, NULL
);
102 pthread_cleanup_pop (0);
107 tf_select (void *arg
)
109 pthread_setcancelstate (PTHREAD_CANCEL_DISABLE
, NULL
);
110 xpthread_barrier_wait (&b
);
113 pthread_cleanup_push (cl
, NULL
);
115 r
= select (0, NULL
, NULL
, NULL
, &(struct timeval
) { 0, 250000 });
119 pthread_cleanup_pop (0);
124 tf_pselect (void *arg
)
126 pthread_setcancelstate (PTHREAD_CANCEL_DISABLE
, NULL
);
127 xpthread_barrier_wait (&b
);
130 pthread_cleanup_push (cl
, NULL
);
132 r
= pselect (0, NULL
, NULL
, NULL
, &(struct timespec
) { 0, 250000000 }, NULL
);
136 pthread_cleanup_pop (0);
141 tf_clock_nanosleep (void *arg
)
143 pthread_setcancelstate (PTHREAD_CANCEL_DISABLE
, NULL
);
144 xpthread_barrier_wait (&b
);
147 pthread_cleanup_push (cl
, NULL
);
149 r
= clock_nanosleep (CLOCK_REALTIME
, 0, &(struct timespec
) { 0, 250000000 },
154 pthread_cleanup_pop (0);
161 void * (*cf
) (void *);
164 { "sigtimedwait", tf_sigtimedwait
, },
165 { "poll", tf_poll
, },
166 { "ppoll", tf_ppoll
, },
167 { "select", tf_select
, },
168 { "pselect", tf_pselect
, },
169 { "clock_nanosleep", tf_clock_nanosleep
, },
175 for (int i
= 0; i
< array_length (tests
); i
++)
177 xpthread_barrier_init (&b
, NULL
, 2);
181 pthread_t th
= xpthread_create (NULL
, tests
[i
].cf
, NULL
);
183 xpthread_barrier_wait (&b
);
185 struct timespec ts
= { .tv_sec
= 0, .tv_nsec
= 100000000 };
186 while (nanosleep (&ts
, &ts
) != 0)
189 xpthread_cancel (th
);
191 void *status
= xpthread_join (th
);
193 printf ("test '%s' failed: %" PRIdPTR
"\n", tests
[i
].name
,
195 TEST_VERIFY (status
== NULL
);
197 xpthread_barrier_destroy (&b
);
199 TEST_COMPARE (cl_called
, 0);
201 printf ("in-time cancel test of '%s' successful\n", tests
[i
].name
);
207 #include <support/test-driver.c>