Home | History | Annotate | Line # | Download | only in libpthread
t_cancellation.c revision 1.4
      1 /*	$NetBSD: t_cancellation.c,v 1.4 2025/04/05 11:22:32 riastradh Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2025 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     17  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     18  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     19  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     26  * POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 #include <sys/cdefs.h>
     30 __RCSID("$NetBSD: t_cancellation.c,v 1.4 2025/04/05 11:22:32 riastradh Exp $");
     31 
     32 #include <sys/event.h>
     33 #include <sys/mman.h>
     34 #include <sys/msg.h>
     35 #include <sys/socket.h>
     36 #include <sys/un.h>
     37 #include <sys/wait.h>
     38 
     39 #include <aio.h>
     40 #include <atf-c.h>
     41 #include <fcntl.h>
     42 #include <mqueue.h>
     43 #include <paths.h>
     44 #include <poll.h>
     45 #include <pthread.h>
     46 #include <signal.h>
     47 #include <stdatomic.h>
     48 #include <string.h>
     49 #include <termios.h>
     50 #include <threads.h>
     51 #include <time.h>
     52 #include <unistd.h>
     53 
     54 #include "cancelpoint.h"
     55 #include "h_macros.h"
     56 
     57 static const char *
     58 c11thrd_err(int error)
     59 {
     60 	static char buf[32];
     61 
     62 	switch (error) {
     63 	case thrd_busy:		return "thrd_busy";
     64 	case thrd_nomem:	return "thrd_nomem";
     65 	case thrd_success:	return "thrd_success";
     66 	case thrd_timedout:	return "thrd_timedout";
     67 	default:
     68 		snprintf(buf, sizeof(buf), "thrd_%d", error);
     69 		return buf;
     70 	}
     71 }
     72 
     73 #define	RT(x) do							      \
     74 {									      \
     75 	int RT_rv = (x);						      \
     76 	ATF_REQUIRE_MSG(RT_rv == 0, "%s: %d (%s)",			      \
     77 	    #x, RT_rv, c11thrd_err(RT_rv));				      \
     78 } while (0)
     79 
     80 pthread_barrier_t bar;
     81 bool cleanup_done;
     82 
     83 /* POSIX style */
     84 static void *
     85 emptythread(void *cookie)
     86 {
     87 	return NULL;
     88 }
     89 
     90 /* C11 style */
     91 static int
     92 emptythrd(void *cookie)
     93 {
     94 	return 123;
     95 }
     96 
     97 static void
     98 cleanup_pthread_join(void *cookie)
     99 {
    100 	pthread_t *tp = cookie;
    101 	void *result;
    102 
    103 	RZ(pthread_join(*tp, &result));
    104 	ATF_CHECK_MSG(result == NULL, "result=%p", result);
    105 }
    106 
    107 static void
    108 cleanup_thrd_join(void *cookie)
    109 {
    110 	thrd_t *tp = cookie;
    111 	int result;
    112 
    113 	RT(thrd_join(*tp, &result));
    114 	ATF_CHECK_MSG(result == 123, "result=%d", result);
    115 }
    116 
    117 static void
    118 cleanup_msgid(void *cookie)
    119 {
    120 	int *msgidp = cookie;
    121 
    122 	/*
    123 	 * These message queue identifiers are persistent, so make sure
    124 	 * to clean them up; otherwise the operator will have to run
    125 	 * `ipcrm -q all' from time to time or else the tests will fail
    126 	 * with ENOSPC.
    127 	 */
    128 	RL(msgctl(*msgidp, IPC_RMID, NULL));
    129 }
    130 
    131 /*
    132  * List of cancellation points in POSIX:
    133  *
    134  * https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/V2_chap02.html#tag_16_09_05_02
    135  */
    136 
    137 static int
    138 acceptsetup(void)
    139 {
    140 	struct sockaddr_un sun = { .sun_family = AF_LOCAL };
    141 	int sock;
    142 
    143 	strncpy(sun.sun_path, "sock", sizeof(sun.sun_path));
    144 	RL(sock = socket(PF_LOCAL, SOCK_STREAM, 0));
    145 	RL(bind(sock, (const struct sockaddr *)&sun, sizeof(sun)));
    146 	RL(listen(sock, 1));
    147 
    148 	return sock;
    149 }
    150 
    151 static void
    152 cancelpoint_accept(void)
    153 {
    154 	const int sock = acceptsetup();
    155 
    156 	cancelpointready();
    157 	RL(accept(sock, NULL, NULL));
    158 }
    159 
    160 static void
    161 cancelpoint_accept4(void)
    162 {
    163 	const int sock = acceptsetup();
    164 
    165 	cancelpointready();
    166 	RL(accept4(sock, NULL, NULL, O_CLOEXEC));
    167 }
    168 
    169 static void
    170 cancelpoint_aio_suspend(void)
    171 {
    172 	int fd[2];
    173 	char buf[32];
    174 	struct aiocb aio = {
    175 		.aio_offset = 0,
    176 		.aio_buf = buf,
    177 		.aio_nbytes = sizeof(buf),
    178 		.aio_fildes = -1,
    179 	};
    180 	const struct aiocb *const aiolist[] = { &aio };
    181 
    182 	RL(pipe(fd));
    183 	aio.aio_fildes = fd[0];
    184 	RL(aio_read(&aio));
    185 	cancelpointready();
    186 	RL(aio_suspend(aiolist, __arraycount(aiolist), NULL));
    187 }
    188 
    189 static void
    190 cancelpoint_clock_nanosleep(void)
    191 {
    192 	/* XXX test all CLOCK_*? */
    193 	struct timespec t = {.tv_sec = 1, .tv_nsec = 0};
    194 
    195 	cancelpointready();
    196 	RL(clock_nanosleep(CLOCK_MONOTONIC, 0, &t, NULL));
    197 }
    198 
    199 static void
    200 cancelpoint_close(void)
    201 {
    202 	int fd;
    203 
    204 	RL(fd = open("/dev/null", O_RDWR));
    205 	cancelpointready();
    206 	RL(close(fd));
    207 }
    208 
    209 static void
    210 cancelpoint_cnd_timedwait(void)
    211 {
    212 	cnd_t cnd;
    213 	mtx_t mtx;
    214 	struct timespec t = {.tv_sec = 1, .tv_nsec = 0};
    215 
    216 	RT(cnd_init(&cnd));
    217 	RT(mtx_init(&mtx, mtx_plain));
    218 	cancelpointready();
    219 	RT(mtx_lock(&mtx));
    220 	RT(cnd_timedwait(&cnd, &mtx, &t));
    221 	RT(mtx_unlock(&mtx));
    222 }
    223 
    224 static void
    225 cancelpoint_cnd_wait(void)
    226 {
    227 	cnd_t cnd;
    228 	mtx_t mtx;
    229 
    230 	RT(cnd_init(&cnd));
    231 	RT(mtx_init(&mtx, mtx_plain));
    232 	cancelpointready();
    233 	RT(mtx_lock(&mtx));
    234 	RT(cnd_wait(&cnd, &mtx));
    235 	RT(mtx_unlock(&mtx));
    236 }
    237 
    238 static void
    239 cancelpoint_connect(void)
    240 {
    241 	struct sockaddr_un sun = { .sun_family = AF_LOCAL };
    242 	int sock;
    243 
    244 	strncpy(sun.sun_path, "sock", sizeof(sun.sun_path));
    245 	RL(sock = socket(PF_LOCAL, SOCK_STREAM, 0));
    246 	cancelpointready();
    247 	RL(connect(sock, (const struct sockaddr *)&sun, sizeof(sun)));
    248 }
    249 
    250 static void
    251 cancelpoint_creat(void)
    252 {
    253 
    254 	cancelpointready();
    255 	RL(creat("file", 0666));
    256 }
    257 
    258 static void
    259 cancelpoint_fcntl_F_SETLKW(void)
    260 {
    261 	int fd;
    262 	struct flock fl = {
    263 		.l_start = 0,
    264 		.l_len = 0,
    265 		.l_type = F_WRLCK,
    266 		.l_whence = SEEK_SET,
    267 	};
    268 
    269 	RL(fd = open("file", O_RDWR|O_CREAT, 0666));
    270 	cancelpointready();
    271 	RL(fcntl(fd, F_SETLKW, &fl));
    272 }
    273 
    274 static void
    275 cancelpoint_fcntl_F_OFD_SETLKW(void)
    276 {
    277 #ifdef F_OFD_SETLKW
    278 	int fd;
    279 	struct flock fl = {
    280 		.l_start = 0,
    281 		.l_len = 0,
    282 		.l_type = F_WRLCK,
    283 		.l_whence = SEEK_SET,
    284 	};
    285 
    286 	RL(fd = open("file", O_RDWR|O_CREAT, 0666));
    287 	cancelpointready();
    288 	RL(fcntl(fd, F_OFD_SETLKW, &fl));
    289 #else
    290 	atf_tc_expect_fail("PR kern/59241: POSIX.1-2024:"
    291 	    " OFD-owned file locks");
    292 	atf_tc_fail("no F_OFD_SETLKW");
    293 #endif
    294 }
    295 
    296 static void
    297 cancelpoint_fdatasync(void)
    298 {
    299 	int fd;
    300 
    301 	RL(fd = open("file", O_RDWR|O_CREAT, 0666));
    302 	cancelpointready();
    303 	RL(fdatasync(fd));
    304 }
    305 
    306 static void
    307 cancelpoint_fsync(void)
    308 {
    309 	int fd;
    310 
    311 	RL(fd = open("file", O_RDWR|O_CREAT, 0666));
    312 	cancelpointready();
    313 	RL(fsync(fd));
    314 }
    315 
    316 static void
    317 cancelpoint_kevent(void)
    318 {
    319 	int kq;
    320 	struct kevent ev;
    321 
    322 	EV_SET(&ev, SIGUSR1, EVFILT_SIGNAL, EV_ADD|EV_ENABLE,
    323 	    /*fflags*/0, /*data*/0, /*udata*/0);
    324 
    325 	RL(kq = kqueue());
    326 	RL(kevent(kq, &ev, 1, NULL, 1, &(const struct timespec){0,0}));
    327 	cancelpointready();
    328 	RL(kevent(kq, NULL, 0, &ev, 1, NULL));
    329 }
    330 
    331 static void
    332 cancelpoint_lockf_F_LOCK(void)
    333 {
    334 	int fd;
    335 
    336 	RL(fd = open("file", O_RDWR|O_CREAT, 0666));
    337 	cancelpointready();
    338 	RL(lockf(fd, F_LOCK, 0));
    339 }
    340 
    341 static void
    342 cancelpoint_mq_receive(void)
    343 {
    344 	mqd_t mq;
    345 	char buf[32];
    346 
    347 	RL(mq = mq_open("mq", O_RDWR|O_CREAT, 0666, NULL));
    348 	cancelpointready();
    349 	RL(mq_receive(mq, buf, sizeof(buf), NULL));
    350 }
    351 
    352 static void
    353 cancelpoint_mq_send(void)
    354 {
    355 	mqd_t mq;
    356 	char buf[32] = {0};
    357 
    358 	RL(mq = mq_open("mq", O_RDWR|O_CREAT, 0666, NULL));
    359 	cancelpointready();
    360 	RL(mq_send(mq, buf, sizeof(buf), 0));
    361 }
    362 
    363 static void
    364 cancelpoint_mq_timedreceive(void)
    365 {
    366 	mqd_t mq;
    367 	char buf[32];
    368 	struct timespec t = {.tv_sec = 1, .tv_nsec = 0};
    369 
    370 	RL(mq = mq_open("mq", O_RDWR|O_CREAT, 0666, NULL));
    371 	cancelpointready();
    372 	RL(mq_timedreceive(mq, buf, sizeof(buf), NULL, &t));
    373 }
    374 
    375 static void
    376 cancelpoint_mq_timedsend(void)
    377 {
    378 	mqd_t mq;
    379 	char buf[32] = {0};
    380 	struct timespec t = {.tv_sec = 1, .tv_nsec = 0};
    381 
    382 	RL(mq = mq_open("mq", O_RDWR|O_CREAT, 0666, NULL));
    383 	cancelpointready();
    384 	RL(mq_timedsend(mq, buf, sizeof(buf), 0, &t));
    385 }
    386 
    387 static void
    388 cancelpoint_msgrcv(void)
    389 {
    390 	int msgid;
    391 	char buf[32];
    392 
    393 	RL(msgid = msgget(IPC_PRIVATE, IPC_CREAT));
    394 	pthread_cleanup_push(&cleanup_msgid, &msgid);
    395 	cancelpointready();
    396 	RL(msgrcv(msgid, buf, sizeof(buf), 0, 0));
    397 	pthread_cleanup_pop(/*execute*/1);
    398 }
    399 
    400 static void
    401 cancelpoint_msgsnd(void)
    402 {
    403 	int msgid;
    404 	char buf[32] = {0};
    405 
    406 	RL(msgid = msgget(IPC_PRIVATE, IPC_CREAT));
    407 	pthread_cleanup_push(&cleanup_msgid, &msgid);
    408 	cancelpointready();
    409 	RL(msgsnd(msgid, buf, sizeof(buf), 0));
    410 	pthread_cleanup_pop(/*execute*/1);
    411 }
    412 
    413 static void
    414 cancelpoint_msync(void)
    415 {
    416 	const unsigned long pagesize = sysconf(_SC_PAGESIZE);
    417 	int fd;
    418 	void *map;
    419 
    420 	RL(fd = open("file", O_RDWR|O_CREAT, 0666));
    421 	RL(ftruncate(fd, pagesize));
    422 	REQUIRE_LIBC(map = mmap(NULL, pagesize, PROT_READ|PROT_WRITE,
    423 		MAP_SHARED, fd, 0),
    424 	    MAP_FAILED);
    425 	cancelpointready();
    426 	RL(msync(map, pagesize, MS_SYNC));
    427 }
    428 
    429 static void
    430 cancelpoint_nanosleep(void)
    431 {
    432 	/* XXX test all CLOCK_*? */
    433 	struct timespec t = {.tv_sec = 1, .tv_nsec = 0};
    434 
    435 	cancelpointready();
    436 	RL(nanosleep(&t, NULL));
    437 }
    438 
    439 static void
    440 cancelpoint_open(void)
    441 {
    442 
    443 	cancelpointready();
    444 	RL(open("file", O_RDWR));
    445 }
    446 
    447 static void
    448 cancelpoint_openat(void)
    449 {
    450 
    451 	cancelpointready();
    452 	RL(openat(AT_FDCWD, "file", O_RDWR));
    453 }
    454 
    455 static void
    456 cancelpoint_pause(void)
    457 {
    458 
    459 	cancelpointready();
    460 	RL(pause());
    461 }
    462 
    463 static void
    464 cancelpoint_poll(void)
    465 {
    466 	int fd[2];
    467 	struct pollfd pfd;
    468 
    469 	RL(pipe(fd));
    470 	pfd.fd = fd[0];
    471 	pfd.events = POLLIN;
    472 	cancelpointready();
    473 	RL(poll(&pfd, 1, 1000));
    474 }
    475 
    476 static void
    477 cancelpoint_posix_close(void)
    478 {
    479 #if 0
    480 	int fd;
    481 
    482 	RL(fd = open("file", O_RDWR|O_CREAT, 0666));
    483 	cancelpointready();
    484 	RL(posix_close(fd, POSIX_CLOSE_RESTART));
    485 #else
    486 	atf_tc_expect_fail("PR kern/58929: POSIX.1-2024 compliance:"
    487 	    " posix_close, POSIX_CLOSE_RESTART");
    488 	atf_tc_fail("no posix_close");
    489 #endif
    490 }
    491 
    492 static void
    493 cancelpoint_ppoll(void)
    494 {
    495 	int fd[2];
    496 	struct pollfd pfd;
    497 	struct timespec t = {.tv_sec = 1, .tv_nsec = 0};
    498 
    499 	RL(pipe(fd));
    500 	pfd.fd = fd[0];
    501 	pfd.events = POLLIN;
    502 	cancelpointready();
    503 	RL(ppoll(&pfd, 1, &t, NULL));
    504 }
    505 
    506 static void
    507 cancelpoint_pread(void)
    508 {
    509 	int fd;
    510 	char buf[1];
    511 
    512 	RL(fd = open("file", O_RDWR|O_CREAT, 0666));
    513 	cancelpointready();
    514 	RL(pread(fd, buf, sizeof(buf), 1));
    515 }
    516 
    517 
    518 static void
    519 cancelpoint_pselect(void)
    520 {
    521 	int fd[2];
    522 	fd_set readfd;
    523 	struct timespec t = {.tv_sec = 1, .tv_nsec = 0};
    524 
    525 	FD_ZERO(&readfd);
    526 
    527 	RL(pipe(fd));
    528 	FD_SET(fd[0], &readfd);
    529 	cancelpointready();
    530 	RL(pselect(fd[0] + 1, &readfd, NULL, NULL, &t, NULL));
    531 }
    532 
    533 static void
    534 cancelpoint_pthread_cond_clockwait(void)
    535 {
    536 #if 0
    537 	pthread_cond_t cond;
    538 	pthread_mutex_t mutex;
    539 	struct timespec t = {.tv_sec = 1, .tv_nsec = 0};
    540 
    541 	RZ(pthread_cond_init(&cond, NULL));
    542 	RZ(pthread_mutex_init(&mutex, NULL));
    543 	cancelpointready();
    544 	RZ(pthread_mutex_lock(&mutex));
    545 	RZ(pthread_cond_clockwait(&cond, &mutex, CLOCK_MONOTONIC, &t));
    546 	RZ(pthread_mutex_unlock(&mutex));
    547 #else
    548 	atf_tc_expect_fail("PR lib/59142: POSIX.1-2024:"
    549 	    " pthread_cond_clockwait and company");
    550 	atf_tc_fail("no posix_cond_clockwait");
    551 #endif
    552 }
    553 
    554 static void
    555 cancelpoint_pthread_cond_timedwait(void)
    556 {
    557 	pthread_cond_t cond;
    558 	pthread_mutex_t mutex;
    559 	struct timespec t = {.tv_sec = 1, .tv_nsec = 0};
    560 
    561 	RZ(pthread_cond_init(&cond, NULL));
    562 	RZ(pthread_mutex_init(&mutex, NULL));
    563 	cancelpointready();
    564 	RZ(pthread_mutex_lock(&mutex));
    565 	RZ(pthread_cond_timedwait(&cond, &mutex, &t));
    566 	RZ(pthread_mutex_unlock(&mutex));
    567 }
    568 
    569 static void
    570 cancelpoint_pthread_cond_wait(void)
    571 {
    572 	pthread_cond_t cond;
    573 	pthread_mutex_t mutex;
    574 
    575 	RZ(pthread_cond_init(&cond, NULL));
    576 	RZ(pthread_mutex_init(&mutex, NULL));
    577 	cancelpointready();
    578 	RZ(pthread_mutex_lock(&mutex));
    579 	RZ(pthread_cond_wait(&cond, &mutex));
    580 	RZ(pthread_mutex_unlock(&mutex));
    581 }
    582 
    583 static void
    584 cancelpoint_pthread_join(void)
    585 {
    586 	pthread_t t;
    587 
    588 	RZ(pthread_create(&t, NULL, &emptythread, NULL));
    589 	pthread_cleanup_push(&cleanup_pthread_join, &t);
    590 	cancelpointready();
    591 	RZ(pthread_join(t, NULL));
    592 	pthread_cleanup_pop(/*execute*/0);
    593 }
    594 
    595 static void
    596 cancelpoint_pthread_testcancel(void)
    597 {
    598 
    599 	cancelpointready();
    600 	pthread_testcancel();
    601 }
    602 
    603 static void
    604 cancelpoint_pwrite(void)
    605 {
    606 	int fd;
    607 	char buf[1] = {0};
    608 
    609 	RL(fd = open("file", O_RDWR|O_CREAT, 0666));
    610 	cancelpointready();
    611 	RL(pwrite(fd, buf, sizeof(buf), 1));
    612 }
    613 
    614 static void
    615 cancelpoint_read(void)
    616 {
    617 	int fd;
    618 	char buf[1];
    619 
    620 	RL(fd = open("file", O_RDWR|O_CREAT, 0666));
    621 	cancelpointready();
    622 	RL(read(fd, buf, sizeof(buf)));
    623 }
    624 
    625 static void
    626 cancelpoint_readv(void)
    627 {
    628 	int fd;
    629 	char buf[1];
    630 	struct iovec iov = { .iov_base = buf, .iov_len = sizeof(buf) };
    631 
    632 	RL(fd = open("file", O_RDWR|O_CREAT, 0666));
    633 	cancelpointready();
    634 	RL(readv(fd, &iov, 1));
    635 }
    636 
    637 static void
    638 cancelpoint_recv(void)
    639 {
    640 	struct sockaddr_un sun = { .sun_family = AF_LOCAL };
    641 	int sock;
    642 	char buf[1];
    643 
    644 	strncpy(sun.sun_path, "sock", sizeof(sun.sun_path));
    645 	RL(sock = socket(PF_LOCAL, SOCK_DGRAM, 0));
    646 	RL(bind(sock, (const struct sockaddr *)&sun, sizeof(sun)));
    647 	cancelpointready();
    648 	RL(recv(sock, buf, sizeof(buf), 0));
    649 }
    650 
    651 static void
    652 cancelpoint_recvfrom(void)
    653 {
    654 	struct sockaddr_un sun = { .sun_family = AF_LOCAL };
    655 	int sock;
    656 	char buf[1];
    657 	struct sockaddr_storage ss;
    658 	socklen_t len = sizeof(ss);
    659 
    660 	strncpy(sun.sun_path, "sock", sizeof(sun.sun_path));
    661 	RL(sock = socket(PF_LOCAL, SOCK_DGRAM, 0));
    662 	RL(bind(sock, (const struct sockaddr *)&sun, sizeof(sun)));
    663 	cancelpointready();
    664 	RL(recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *)&ss, &len));
    665 }
    666 
    667 static void
    668 cancelpoint_recvmsg(void)
    669 {
    670 	struct sockaddr_un sun = { .sun_family = AF_LOCAL };
    671 	int sock;
    672 	char buf[1];
    673 	struct iovec iov = { .iov_base = buf, .iov_len = sizeof(buf) };
    674 	struct msghdr msg = {
    675 		.msg_iov = &iov,
    676 		.msg_iovlen = 1,
    677 	};
    678 
    679 	strncpy(sun.sun_path, "sock", sizeof(sun.sun_path));
    680 	RL(sock = socket(PF_LOCAL, SOCK_DGRAM, 0));
    681 	RL(bind(sock, (const struct sockaddr *)&sun, sizeof(sun)));
    682 	cancelpointready();
    683 	RL(recvmsg(sock, &msg, 0));
    684 }
    685 
    686 static void
    687 cancelpoint_select(void)
    688 {
    689 	int fd[2];
    690 	fd_set readfd;
    691 	struct timeval t = {.tv_sec = 1, .tv_usec = 0};
    692 
    693 	FD_ZERO(&readfd);
    694 
    695 	RL(pipe(fd));
    696 	FD_SET(fd[0], &readfd);
    697 	cancelpointready();
    698 	RL(select(fd[0] + 1, &readfd, NULL, NULL, &t));
    699 }
    700 
    701 static void
    702 cancelpoint_send(void)
    703 {
    704 	struct sockaddr_un sun = { .sun_family = AF_LOCAL };
    705 	int sock;
    706 	char buf[1] = {0};
    707 
    708 	strncpy(sun.sun_path, "sock", sizeof(sun.sun_path));
    709 	RL(sock = socket(PF_LOCAL, SOCK_DGRAM, 0));
    710 	RL(bind(sock, (const struct sockaddr *)&sun, sizeof(sun)));
    711 	cancelpointready();
    712 	RL(send(sock, buf, sizeof(buf), 0));
    713 }
    714 
    715 static void
    716 cancelpoint_sendto(void)
    717 {
    718 	struct sockaddr_un sun = { .sun_family = AF_LOCAL };
    719 	int sock;
    720 	char buf[1] = {0};
    721 
    722 	strncpy(sun.sun_path, "sock", sizeof(sun.sun_path));
    723 	RL(sock = socket(PF_LOCAL, SOCK_DGRAM, 0));
    724 	cancelpointready();
    725 	RL(sendto(sock, buf, sizeof(buf), 0, (const struct sockaddr *)&sun,
    726 		sizeof(sun)));
    727 }
    728 
    729 static void
    730 cancelpoint_sendmsg(void)
    731 {
    732 	struct sockaddr_un sun = { .sun_family = AF_LOCAL };
    733 	int sock;
    734 	char buf[1] = {0};
    735 	struct iovec iov = { .iov_base = buf, .iov_len = sizeof(buf) };
    736 	struct msghdr msg = {
    737 		.msg_name = (struct sockaddr *)&sun,
    738 		.msg_namelen = sizeof(sun),
    739 		.msg_iov = &iov,
    740 		.msg_iovlen = 1,
    741 	};
    742 
    743 	strncpy(sun.sun_path, "sock", sizeof(sun.sun_path));
    744 	RL(sock = socket(PF_LOCAL, SOCK_DGRAM, 0));
    745 	cancelpointready();
    746 	RL(sendmsg(sock, &msg, 0));
    747 }
    748 
    749 static void
    750 cancelpoint_sigsuspend(void)
    751 {
    752 	sigset_t mask, omask;
    753 
    754 	RL(sigfillset(&mask));
    755 	RL(sigprocmask(SIG_BLOCK, &mask, &omask));
    756 	cancelpointready();
    757 	RL(sigsuspend(&omask));
    758 }
    759 
    760 static void
    761 cancelpoint_sigtimedwait(void)
    762 {
    763 	sigset_t mask, omask;
    764 	siginfo_t info;
    765 	struct timespec t = {.tv_sec = 1, .tv_nsec = 0};
    766 
    767 	RL(sigfillset(&mask));
    768 	RL(sigprocmask(SIG_BLOCK, &mask, &omask));
    769 	cancelpointready();
    770 	RL(sigtimedwait(&omask, &info, &t));
    771 }
    772 
    773 static void
    774 cancelpoint_sigwait(void)
    775 {
    776 	sigset_t mask, omask;
    777 	int sig;
    778 
    779 	RL(sigfillset(&mask));
    780 	RL(sigprocmask(SIG_BLOCK, &mask, &omask));
    781 	cancelpointready();
    782 	RL(sigwait(&omask, &sig));
    783 }
    784 
    785 static void
    786 cancelpoint_sigwaitinfo(void)
    787 {
    788 	sigset_t mask, omask;
    789 	siginfo_t info;
    790 
    791 	RL(sigfillset(&mask));
    792 	RL(sigprocmask(SIG_BLOCK, &mask, &omask));
    793 	cancelpointready();
    794 	RL(sigwaitinfo(&omask, &info));
    795 }
    796 
    797 static void
    798 cancelpoint_sleep(void)
    799 {
    800 
    801 	cancelpointready();
    802 	(void)sleep(1);
    803 }
    804 
    805 static void
    806 cancelpoint_tcdrain(void)
    807 {
    808 	int hostfd, appfd;
    809 	char *pts;
    810 
    811 	RL(hostfd = posix_openpt(O_RDWR|O_NOCTTY));
    812 	RL(grantpt(hostfd));
    813 	RL(unlockpt(hostfd));
    814 	REQUIRE_LIBC(pts = ptsname(hostfd), NULL);
    815 	RL(appfd = open(pts, O_RDWR|O_NOCTTY));
    816 	cancelpointready();
    817 	RL(tcdrain(appfd));
    818 }
    819 
    820 static void
    821 cancelpoint_thrd_join(void)
    822 {
    823 	thrd_t t;
    824 
    825 	RT(thrd_create(&t, &emptythrd, NULL));
    826 	pthread_cleanup_push(&cleanup_thrd_join, &t);
    827 	cancelpointready();
    828 	RT(thrd_join(t, NULL));
    829 	pthread_cleanup_pop(/*execute*/0);
    830 }
    831 
    832 static void
    833 cancelpoint_thrd_sleep(void)
    834 {
    835 	struct timespec t = {.tv_sec = 1, .tv_nsec = 0};
    836 
    837 	cancelpointready();
    838 	RT(thrd_sleep(&t, NULL));
    839 }
    840 
    841 static void
    842 cancelpoint_wait(void)
    843 {
    844 
    845 	cancelpointready();
    846 	RL(wait(NULL));
    847 }
    848 
    849 static void
    850 cancelpoint_waitid(void)
    851 {
    852 
    853 	cancelpointready();
    854 	RL(waitid(P_ALL, 0, NULL, 0));
    855 }
    856 
    857 static void
    858 cancelpoint_waitpid(void)
    859 {
    860 
    861 	cancelpointready();
    862 	RL(waitpid(-1, NULL, 0));
    863 }
    864 
    865 static void
    866 cancelpoint_write(void)
    867 {
    868 	int fd;
    869 	char buf[1] = {0};
    870 
    871 	RL(fd = open("file", O_RDWR|O_CREAT, 0666));
    872 	cancelpointready();
    873 	RL(write(fd, buf, sizeof(buf)));
    874 }
    875 
    876 static void
    877 cancelpoint_writev(void)
    878 {
    879 	int fd;
    880 	char buf[1] = {0};
    881 	struct iovec iov = { .iov_base = buf, .iov_len = sizeof(buf) };
    882 
    883 	RL(fd = open("file", O_RDWR|O_CREAT, 0666));
    884 	cancelpointready();
    885 	RL(writev(fd, &iov, 1));
    886 }
    887 
    888 TEST_CANCELPOINT(cancelpoint_accept, __nothing)
    889 TEST_CANCELPOINT(cancelpoint_accept4, __nothing)
    890 TEST_CANCELPOINT(cancelpoint_aio_suspend, __nothing)
    891 TEST_CANCELPOINT(cancelpoint_clock_nanosleep, __nothing)
    892 TEST_CANCELPOINT(cancelpoint_close, __nothing)
    893 TEST_CANCELPOINT(cancelpoint_cnd_timedwait, __nothing)
    894 TEST_CANCELPOINT(cancelpoint_cnd_wait, __nothing)
    895 TEST_CANCELPOINT(cancelpoint_connect, __nothing)
    896 TEST_CANCELPOINT(cancelpoint_creat, __nothing)
    897 TEST_CANCELPOINT(cancelpoint_fcntl_F_SETLKW, __nothing)
    898 TEST_CANCELPOINT(cancelpoint_fcntl_F_OFD_SETLKW, __nothing)
    899 TEST_CANCELPOINT(cancelpoint_fdatasync, __nothing)
    900 TEST_CANCELPOINT(cancelpoint_fsync, __nothing)
    901 TEST_CANCELPOINT(cancelpoint_kevent, __nothing)
    902 TEST_CANCELPOINT(cancelpoint_lockf_F_LOCK, __nothing)
    903 TEST_CANCELPOINT(cancelpoint_mq_receive, __nothing)
    904 TEST_CANCELPOINT(cancelpoint_mq_send, __nothing)
    905 TEST_CANCELPOINT(cancelpoint_mq_timedreceive, __nothing)
    906 TEST_CANCELPOINT(cancelpoint_mq_timedsend, __nothing)
    907 TEST_CANCELPOINT(cancelpoint_msgrcv, __nothing)
    908 TEST_CANCELPOINT(cancelpoint_msgsnd, __nothing)
    909 TEST_CANCELPOINT(cancelpoint_msync, __nothing)
    910 TEST_CANCELPOINT(cancelpoint_nanosleep, __nothing)
    911 TEST_CANCELPOINT(cancelpoint_open, __nothing)
    912 TEST_CANCELPOINT(cancelpoint_openat, __nothing)
    913 TEST_CANCELPOINT(cancelpoint_pause, __nothing)
    914 TEST_CANCELPOINT(cancelpoint_poll, __nothing)
    915 TEST_CANCELPOINT(cancelpoint_posix_close, __nothing)
    916 TEST_CANCELPOINT(cancelpoint_ppoll, __nothing)
    917 TEST_CANCELPOINT(cancelpoint_pread, __nothing)
    918 TEST_CANCELPOINT(cancelpoint_pselect, __nothing)
    919 TEST_CANCELPOINT(cancelpoint_pthread_cond_clockwait, __nothing)
    920 TEST_CANCELPOINT(cancelpoint_pthread_cond_timedwait, __nothing)
    921 TEST_CANCELPOINT(cancelpoint_pthread_cond_wait, __nothing)
    922 TEST_CANCELPOINT(cancelpoint_pthread_join, __nothing)
    923 TEST_CANCELPOINT(cancelpoint_pthread_testcancel, __nothing)
    924 TEST_CANCELPOINT(cancelpoint_pwrite, __nothing)
    925 TEST_CANCELPOINT(cancelpoint_read, __nothing)
    926 TEST_CANCELPOINT(cancelpoint_readv, __nothing)
    927 TEST_CANCELPOINT(cancelpoint_recv, __nothing)
    928 TEST_CANCELPOINT(cancelpoint_recvfrom, __nothing)
    929 TEST_CANCELPOINT(cancelpoint_recvmsg, __nothing)
    930 TEST_CANCELPOINT(cancelpoint_select, __nothing)
    931 TEST_CANCELPOINT(cancelpoint_send, __nothing)
    932 TEST_CANCELPOINT(cancelpoint_sendto, __nothing)
    933 TEST_CANCELPOINT(cancelpoint_sendmsg, __nothing)
    934 TEST_CANCELPOINT(cancelpoint_sigsuspend, __nothing)
    935 TEST_CANCELPOINT(cancelpoint_sigtimedwait, __nothing)
    936 TEST_CANCELPOINT(cancelpoint_sigwait, __nothing)
    937 TEST_CANCELPOINT(cancelpoint_sigwaitinfo, __nothing)
    938 TEST_CANCELPOINT(cancelpoint_sleep, __nothing)
    939 TEST_CANCELPOINT(cancelpoint_tcdrain, __nothing)
    940 TEST_CANCELPOINT(cancelpoint_thrd_join, __nothing)
    941 TEST_CANCELPOINT(cancelpoint_thrd_sleep, __nothing)
    942 TEST_CANCELPOINT(cancelpoint_wait, __nothing)
    943 TEST_CANCELPOINT(cancelpoint_waitid, __nothing)
    944 TEST_CANCELPOINT(cancelpoint_waitpid, __nothing)
    945 TEST_CANCELPOINT(cancelpoint_write, __nothing)
    946 TEST_CANCELPOINT(cancelpoint_writev, __nothing)
    947 
    948 ATF_TC(cleanuppop0);
    949 ATF_TC_HEAD(cleanuppop0, tc)
    950 {
    951 	atf_tc_set_md_var(tc, "descr", "Test pthread_cleanup_pop(0)");
    952 }
    953 ATF_TC_BODY(cleanuppop0, tc)
    954 {
    955 
    956 	pthread_cleanup_push(&cleanup, &cleanup_done);
    957 	pthread_cleanup_pop(/*execute*/0);
    958 	ATF_CHECK(!cleanup_done);
    959 }
    960 
    961 ATF_TC(cleanuppop1);
    962 ATF_TC_HEAD(cleanuppop1, tc)
    963 {
    964 	atf_tc_set_md_var(tc, "descr", "Test pthread_cleanup_pop(1)");
    965 }
    966 ATF_TC_BODY(cleanuppop1, tc)
    967 {
    968 
    969 	pthread_cleanup_push(&cleanup, &cleanup_done);
    970 	pthread_cleanup_pop(/*execute*/1);
    971 	ATF_CHECK(cleanup_done);
    972 }
    973 
    974 static void *
    975 cancelself_async(void *cookie)
    976 {
    977 	int *n = cookie;
    978 
    979 	RZ(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL));
    980 
    981 	pthread_cleanup_push(&cleanup, &cleanup_done);
    982 
    983 	*n = 1;
    984 	RZ(pthread_cancel(pthread_self())); /* cancel */
    985 	*n = 2;
    986 	RZ(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL));
    987 	pthread_testcancel();
    988 	*n = 3;
    989 	RZ(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL));
    990 	pthread_testcancel();
    991 	*n = 4;
    992 
    993 	pthread_cleanup_pop(/*execute*/0);
    994 	return NULL;
    995 }
    996 
    997 ATF_TC(cancelself_async);
    998 ATF_TC_HEAD(cancelself_async, tc)
    999 {
   1000 	atf_tc_set_md_var(tc, "descr",
   1001 	    "Test pthread_cancel(pthread_self()) async");
   1002 }
   1003 ATF_TC_BODY(cancelself_async, tc)
   1004 {
   1005 	int n = 0;
   1006 	pthread_t t;
   1007 
   1008 	RZ(pthread_create(&t, NULL, &cancelself_async, &n));
   1009 
   1010 	alarm(1);
   1011 	RZ(pthread_join(t, NULL));
   1012 
   1013 	atf_tc_expect_fail("lib/59135: PTHREAD_CANCEL_ASYNCHRONOUS"
   1014 	    " doesn't do much");
   1015 	ATF_CHECK_MSG(n == 1, "n=%d", n);
   1016 	atf_tc_expect_pass();
   1017 	ATF_CHECK(cleanup_done);
   1018 }
   1019 
   1020 static void *
   1021 cancelself_deferred(void *cookie)
   1022 {
   1023 	int *n = cookie;
   1024 
   1025 	/* PTHREAD_CANCEL_DEFERRED by default */
   1026 
   1027 	pthread_cleanup_push(&cleanup, &cleanup_done);
   1028 
   1029 	*n = 1;
   1030 	RZ(pthread_cancel(pthread_self()));
   1031 	*n = 2;
   1032 	RZ(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL));
   1033 	*n = 3;
   1034 	pthread_testcancel();
   1035 	*n = 4;
   1036 	RZ(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL));
   1037 	*n = 5;
   1038 	pthread_testcancel(); /* cancel */
   1039 	*n = 6;
   1040 
   1041 	pthread_cleanup_pop(/*execute*/0);
   1042 	return NULL;
   1043 }
   1044 
   1045 ATF_TC(cancelself_deferred);
   1046 ATF_TC_HEAD(cancelself_deferred, tc)
   1047 {
   1048 	atf_tc_set_md_var(tc, "descr",
   1049 	    "Test pthread_cancel(pthread_self()) deferred");
   1050 }
   1051 ATF_TC_BODY(cancelself_deferred, tc)
   1052 {
   1053 	int n = 0;
   1054 	pthread_t t;
   1055 
   1056 	RZ(pthread_create(&t, NULL, &cancelself_deferred, &n));
   1057 
   1058 	alarm(1);
   1059 	RZ(pthread_join(t, NULL));
   1060 
   1061 	ATF_CHECK_MSG(n == 5, "n=%d", n);
   1062 	ATF_CHECK(cleanup_done);
   1063 }
   1064 
   1065 static void *
   1066 defaults(void *cookie)
   1067 {
   1068 	int state, type;
   1069 
   1070 	fprintf(stderr, "created thread\n");
   1071 
   1072 	RZ(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &state));
   1073 	RZ(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &type));
   1074 
   1075 	ATF_CHECK_MSG(state == PTHREAD_CANCEL_ENABLE,
   1076 	    "state=%d PTHREAD_CANCEL_ENABLE=%d PTHREAD_CANCEL_DISABLE=%d",
   1077 	    state, PTHREAD_CANCEL_ENABLE, PTHREAD_CANCEL_DISABLE);
   1078 
   1079 	ATF_CHECK_MSG(type == PTHREAD_CANCEL_DEFERRED,
   1080 	    "type=%d"
   1081 	    " PTHREAD_CANCEL_DEFERRED=%d PTHREAD_CANCEL_ASYNCHRONOUS=%d",
   1082 	    type, PTHREAD_CANCEL_DEFERRED, PTHREAD_CANCEL_ASYNCHRONOUS);
   1083 
   1084 	return NULL;
   1085 }
   1086 
   1087 ATF_TC(defaults);
   1088 ATF_TC_HEAD(defaults, tc)
   1089 {
   1090 	atf_tc_set_md_var(tc, "descr", "Test default cancelability");
   1091 }
   1092 ATF_TC_BODY(defaults, tc)
   1093 {
   1094 	pthread_t t;
   1095 
   1096 	fprintf(stderr, "initial thread\n");
   1097 	(void)defaults(NULL);
   1098 
   1099 	RZ(pthread_create(&t, NULL, &defaults, NULL));
   1100 
   1101 	alarm(1);
   1102 	RZ(pthread_join(t, NULL));
   1103 }
   1104 
   1105 static void *
   1106 disable_enable(void *cookie)
   1107 {
   1108 	int *n = cookie;
   1109 
   1110 	pthread_cleanup_push(&cleanup, &cleanup_done);
   1111 
   1112 	*n = 1;
   1113 	pthread_testcancel();
   1114 	*n = 2;
   1115 	RZ(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL));
   1116 	*n = 3;
   1117 	(void)pthread_barrier_wait(&bar);
   1118 	*n = 4;
   1119 	pthread_testcancel();
   1120 	*n = 5;
   1121 	(void)pthread_barrier_wait(&bar);
   1122 	*n = 6;
   1123 	pthread_testcancel();
   1124 	*n = 7;
   1125 	RZ(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL));
   1126 	*n = 8;
   1127 	pthread_testcancel(); /* cancel */
   1128 	*n = 9;
   1129 
   1130 	pthread_cleanup_pop(/*execute*/0);
   1131 	return NULL;
   1132 }
   1133 
   1134 ATF_TC(disable_enable);
   1135 ATF_TC_HEAD(disable_enable, tc)
   1136 {
   1137 	atf_tc_set_md_var(tc, "descr",
   1138 	    "Test disabling and re-enabling cancellation");
   1139 }
   1140 ATF_TC_BODY(disable_enable, tc)
   1141 {
   1142 	int n = 0;
   1143 	pthread_t t;
   1144 
   1145 	RZ(pthread_barrier_init(&bar, NULL, 2));
   1146 
   1147 	RZ(pthread_create(&t, NULL, &disable_enable, &n));
   1148 
   1149 	(void)pthread_barrier_wait(&bar);
   1150 	RZ(pthread_cancel(t));
   1151 	(void)pthread_barrier_wait(&bar);
   1152 
   1153 	alarm(1);
   1154 	RZ(pthread_join(t, NULL));
   1155 
   1156 	ATF_CHECK_MSG(n == 8, "n=%d", n);
   1157 	ATF_CHECK(cleanup_done);
   1158 }
   1159 
   1160 static void *
   1161 notestcancel_loop_async(void *cookie)
   1162 {
   1163 
   1164 	RZ(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL));
   1165 
   1166 	pthread_cleanup_push(&cleanup, &cleanup_done);
   1167 	(void)pthread_barrier_wait(&bar);
   1168 	for (;;)
   1169 		__insn_barrier();
   1170 	pthread_cleanup_pop(/*execute*/0);
   1171 
   1172 	return NULL;
   1173 }
   1174 
   1175 ATF_TC(notestcancel_loop_async);
   1176 ATF_TC_HEAD(notestcancel_loop_async, tc)
   1177 {
   1178 	atf_tc_set_md_var(tc, "descr",
   1179 	    "Test nothing in a loop with PTHREAD_CANCEL_ASYNCHRONOUS");
   1180 }
   1181 ATF_TC_BODY(notestcancel_loop_async, tc)
   1182 {
   1183 	pthread_t t;
   1184 	void *result;
   1185 
   1186 	RZ(pthread_barrier_init(&bar, NULL, 2));
   1187 	RZ(pthread_create(&t, NULL, &notestcancel_loop_async, NULL));
   1188 
   1189 	(void)pthread_barrier_wait(&bar);
   1190 	RZ(pthread_cancel(t));
   1191 
   1192 	atf_tc_expect_signal(SIGALRM, "lib/59135: PTHREAD_CANCEL_ASYNCHRONOUS"
   1193 	    " doesn't do much");
   1194 	alarm(1);
   1195 	RZ(pthread_join(t, &result));
   1196 	ATF_CHECK_MSG(result == PTHREAD_CANCELED,
   1197 	    "result=%p PTHREAD_CANCELED=%p", result, PTHREAD_CANCELED);
   1198 	ATF_CHECK(cleanup_done);
   1199 }
   1200 
   1201 static void *
   1202 disable_enable_async(void *cookie)
   1203 {
   1204 	int *n = cookie;
   1205 
   1206 	pthread_cleanup_push(&cleanup, &cleanup_done);
   1207 
   1208 	RZ(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL));
   1209 
   1210 	*n = 1;
   1211 	pthread_testcancel();
   1212 	*n = 2;
   1213 	RZ(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL));
   1214 	*n = 3;
   1215 	(void)pthread_barrier_wait(&bar);
   1216 	*n = 4;
   1217 	pthread_testcancel();
   1218 	*n = 5;
   1219 	(void)pthread_barrier_wait(&bar);
   1220 	*n = 6;
   1221 	pthread_testcancel();
   1222 	*n = 7;
   1223 	RZ(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL)); /* cancel */
   1224 	*n = 8;
   1225 	pthread_testcancel();
   1226 	*n = 9;
   1227 
   1228 	pthread_cleanup_pop(/*execute*/0);
   1229 	return NULL;
   1230 }
   1231 
   1232 ATF_TC(disable_enable_async);
   1233 ATF_TC_HEAD(disable_enable_async, tc)
   1234 {
   1235 	atf_tc_set_md_var(tc, "descr",
   1236 	    "Test disabling and re-enabling cancellation when asynchronous");
   1237 }
   1238 ATF_TC_BODY(disable_enable_async, tc)
   1239 {
   1240 	int n = 0;
   1241 	pthread_t t;
   1242 
   1243 	RZ(pthread_barrier_init(&bar, NULL, 2));
   1244 
   1245 	RZ(pthread_create(&t, NULL, &disable_enable_async, &n));
   1246 
   1247 	(void)pthread_barrier_wait(&bar);
   1248 	RZ(pthread_cancel(t));
   1249 	(void)pthread_barrier_wait(&bar);
   1250 
   1251 	alarm(1);
   1252 	RZ(pthread_join(t, NULL));
   1253 
   1254 	ATF_CHECK_MSG(n == 7, "n=%d", n);
   1255 	ATF_CHECK(cleanup_done);
   1256 }
   1257 
   1258 static void *
   1259 disable_enable_setcanceltype_async(void *cookie)
   1260 {
   1261 	int *n = cookie;
   1262 
   1263 	pthread_cleanup_push(&cleanup, &cleanup_done);
   1264 
   1265 	*n = 1;
   1266 	pthread_testcancel();
   1267 	*n = 2;
   1268 	RZ(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL));
   1269 	*n = 3;
   1270 	(void)pthread_barrier_wait(&bar);
   1271 	*n = 4;
   1272 	pthread_testcancel();
   1273 	*n = 5;
   1274 	(void)pthread_barrier_wait(&bar);
   1275 	*n = 6;
   1276 	pthread_testcancel();
   1277 	*n = 7;
   1278 	RZ(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL));
   1279 	*n = 8;
   1280 	pthread_testcancel();
   1281 	*n = 9;
   1282 	RZ(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL)); /* cancel */
   1283 	*n = 10;
   1284 	pthread_testcancel();
   1285 	*n = 11;
   1286 
   1287 	pthread_cleanup_pop(/*execute*/0);
   1288 	return NULL;
   1289 }
   1290 
   1291 ATF_TC(disable_enable_setcanceltype_async);
   1292 ATF_TC_HEAD(disable_enable_setcanceltype_async, tc)
   1293 {
   1294 	atf_tc_set_md_var(tc, "descr",
   1295 	    "Test disabling cancellation, setting it async, and re-enabling");
   1296 }
   1297 ATF_TC_BODY(disable_enable_setcanceltype_async, tc)
   1298 {
   1299 	int n = 0;
   1300 	pthread_t t;
   1301 
   1302 	RZ(pthread_barrier_init(&bar, NULL, 2));
   1303 
   1304 	RZ(pthread_create(&t, NULL, &disable_enable_setcanceltype_async, &n));
   1305 
   1306 	(void)pthread_barrier_wait(&bar);
   1307 	RZ(pthread_cancel(t));
   1308 	(void)pthread_barrier_wait(&bar);
   1309 
   1310 	alarm(1);
   1311 	RZ(pthread_join(t, NULL));
   1312 
   1313 	ATF_CHECK_MSG(n == 9, "n=%d", n);
   1314 	ATF_CHECK(cleanup_done);
   1315 }
   1316 
   1317 static void *
   1318 setcanceltype_async(void *cookie)
   1319 {
   1320 	int *n = cookie;
   1321 
   1322 	pthread_cleanup_push(&cleanup, &cleanup_done);
   1323 
   1324 	*n = 1;
   1325 	pthread_testcancel();
   1326 	*n = 2;
   1327 	(void)pthread_barrier_wait(&bar);
   1328 	*n = 3;
   1329 	(void)pthread_barrier_wait(&bar);
   1330 	*n = 4;
   1331 	RZ(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,
   1332 		NULL)); /* cancel */
   1333 	*n = 5;
   1334 
   1335 	pthread_cleanup_pop(/*execute*/0);
   1336 	return NULL;
   1337 }
   1338 
   1339 ATF_TC(setcanceltype_async);
   1340 ATF_TC_HEAD(setcanceltype_async, tc)
   1341 {
   1342 	atf_tc_set_md_var(tc, "descr",
   1343 	    "Test disabling cancellation, setting it async, and re-enabling");
   1344 }
   1345 ATF_TC_BODY(setcanceltype_async, tc)
   1346 {
   1347 	int n = 0;
   1348 	pthread_t t;
   1349 
   1350 	RZ(pthread_barrier_init(&bar, NULL, 2));
   1351 
   1352 	RZ(pthread_create(&t, NULL, &setcanceltype_async, &n));
   1353 
   1354 	(void)pthread_barrier_wait(&bar);
   1355 	RZ(pthread_cancel(t));
   1356 	(void)pthread_barrier_wait(&bar);
   1357 
   1358 	alarm(1);
   1359 	RZ(pthread_join(t, NULL));
   1360 
   1361 	ATF_CHECK_MSG(n == 4, "n=%d", n);
   1362 	ATF_CHECK(cleanup_done);
   1363 }
   1364 
   1365 static void
   1366 sighandler(int signo)
   1367 {
   1368 	int state;
   1369 
   1370 	RZ(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state));
   1371 	RZ(pthread_setcancelstate(state, NULL));
   1372 }
   1373 
   1374 static void *
   1375 sigsafecancelstate(void *cookie)
   1376 {
   1377 	atomic_ulong *n = cookie;
   1378 	char name[128];
   1379 
   1380 	pthread_cleanup_push(&cleanup, &cleanup_done);
   1381 	REQUIRE_LIBC(signal(SIGUSR1, &sighandler), SIG_ERR);
   1382 
   1383 	(void)pthread_barrier_wait(&bar);
   1384 
   1385 	while (atomic_load_explicit(n, memory_order_relaxed) != 0) {
   1386 		/*
   1387 		 * Do some things that might take the same lock as
   1388 		 * pthread_setcancelstate.
   1389 		 */
   1390 		RZ(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL));
   1391 		RZ(pthread_getname_np(pthread_self(), name, sizeof(name)));
   1392 		RZ(pthread_setname_np(pthread_self(), "%s", name));
   1393 	}
   1394 
   1395 	pthread_cleanup_pop(/*execute*/1);
   1396 	return NULL;
   1397 }
   1398 
   1399 ATF_TC(sigsafecancelstate);
   1400 ATF_TC_HEAD(sigsafecancelstate, tc)
   1401 {
   1402 	atf_tc_set_md_var(tc, "descr",
   1403 	    "Test pthread_setcancelstate async-signal-safety");
   1404 }
   1405 ATF_TC_BODY(sigsafecancelstate, tc)
   1406 {
   1407 	pthread_t t;
   1408 	atomic_ulong n = 10000;
   1409 	void *result;
   1410 
   1411 	RZ(pthread_barrier_init(&bar, NULL, 2));
   1412 	RZ(pthread_create(&t, NULL, &sigsafecancelstate, &n));
   1413 
   1414 	(void)pthread_barrier_wait(&bar);
   1415 
   1416 	while (atomic_load_explicit(&n, memory_order_relaxed)) {
   1417 		pthread_kill(t, SIGUSR1);
   1418 		atomic_store_explicit(&n,
   1419 		    atomic_load_explicit(&n, memory_order_relaxed) - 1,
   1420 		    memory_order_relaxed);
   1421 	}
   1422 
   1423 	alarm(1);
   1424 	RZ(pthread_join(t, &result));
   1425 	ATF_CHECK_MSG(result == NULL, "result=%p", result);
   1426 	ATF_CHECK(cleanup_done);
   1427 }
   1428 
   1429 static void *
   1430 testcancel_loop(void *cookie)
   1431 {
   1432 
   1433 	pthread_cleanup_push(&cleanup, &cleanup_done);
   1434 	(void)pthread_barrier_wait(&bar);
   1435 	for (;;)
   1436 		pthread_testcancel();
   1437 	pthread_cleanup_pop(/*execute*/0);
   1438 
   1439 	return NULL;
   1440 }
   1441 
   1442 ATF_TC(testcancel_loop);
   1443 ATF_TC_HEAD(testcancel_loop, tc)
   1444 {
   1445 	atf_tc_set_md_var(tc, "descr",
   1446 	    "Test pthread_testcancel in a loop");
   1447 }
   1448 ATF_TC_BODY(testcancel_loop, tc)
   1449 {
   1450 	pthread_t t;
   1451 	void *result;
   1452 
   1453 	RZ(pthread_barrier_init(&bar, NULL, 2));
   1454 	RZ(pthread_create(&t, NULL, &testcancel_loop, NULL));
   1455 
   1456 	(void)pthread_barrier_wait(&bar);
   1457 	RZ(pthread_cancel(t));
   1458 
   1459 	alarm(1);
   1460 	RZ(pthread_join(t, &result));
   1461 	ATF_CHECK_MSG(result == PTHREAD_CANCELED,
   1462 	    "result=%p PTHREAD_CANCELED=%p", result, PTHREAD_CANCELED);
   1463 	ATF_CHECK(cleanup_done);
   1464 }
   1465 
   1466 ATF_TP_ADD_TCS(tp)
   1467 {
   1468 
   1469 	ADD_TEST_CANCELPOINT(cancelpoint_accept);
   1470 	ADD_TEST_CANCELPOINT(cancelpoint_accept4);
   1471 	ADD_TEST_CANCELPOINT(cancelpoint_aio_suspend);
   1472 	ADD_TEST_CANCELPOINT(cancelpoint_clock_nanosleep);
   1473 	ADD_TEST_CANCELPOINT(cancelpoint_close);
   1474 	ADD_TEST_CANCELPOINT(cancelpoint_cnd_timedwait);
   1475 	ADD_TEST_CANCELPOINT(cancelpoint_cnd_wait);
   1476 	ADD_TEST_CANCELPOINT(cancelpoint_connect);
   1477 	ADD_TEST_CANCELPOINT(cancelpoint_creat);
   1478 	ADD_TEST_CANCELPOINT(cancelpoint_fcntl_F_SETLKW);
   1479 	ADD_TEST_CANCELPOINT(cancelpoint_fcntl_F_OFD_SETLKW);
   1480 	ADD_TEST_CANCELPOINT(cancelpoint_fdatasync);
   1481 	ADD_TEST_CANCELPOINT(cancelpoint_fsync);
   1482 	ADD_TEST_CANCELPOINT(cancelpoint_kevent);
   1483 	ADD_TEST_CANCELPOINT(cancelpoint_lockf_F_LOCK);
   1484 	ADD_TEST_CANCELPOINT(cancelpoint_mq_receive);
   1485 	ADD_TEST_CANCELPOINT(cancelpoint_mq_send);
   1486 	ADD_TEST_CANCELPOINT(cancelpoint_mq_timedreceive);
   1487 	ADD_TEST_CANCELPOINT(cancelpoint_mq_timedsend);
   1488 	ADD_TEST_CANCELPOINT(cancelpoint_msgrcv);
   1489 	ADD_TEST_CANCELPOINT(cancelpoint_msgsnd);
   1490 	ADD_TEST_CANCELPOINT(cancelpoint_msync);
   1491 	ADD_TEST_CANCELPOINT(cancelpoint_nanosleep);
   1492 	ADD_TEST_CANCELPOINT(cancelpoint_open);
   1493 	ADD_TEST_CANCELPOINT(cancelpoint_openat);
   1494 	ADD_TEST_CANCELPOINT(cancelpoint_pause);
   1495 	ADD_TEST_CANCELPOINT(cancelpoint_poll);
   1496 	ADD_TEST_CANCELPOINT(cancelpoint_posix_close);
   1497 	ADD_TEST_CANCELPOINT(cancelpoint_ppoll);
   1498 	ADD_TEST_CANCELPOINT(cancelpoint_pread);
   1499 	ADD_TEST_CANCELPOINT(cancelpoint_pselect);
   1500 	ADD_TEST_CANCELPOINT(cancelpoint_pthread_cond_clockwait);
   1501 	ADD_TEST_CANCELPOINT(cancelpoint_pthread_cond_timedwait);
   1502 	ADD_TEST_CANCELPOINT(cancelpoint_pthread_cond_wait);
   1503 	ADD_TEST_CANCELPOINT(cancelpoint_pthread_join);
   1504 	ADD_TEST_CANCELPOINT(cancelpoint_pthread_testcancel);
   1505 	ADD_TEST_CANCELPOINT(cancelpoint_pwrite);
   1506 	ADD_TEST_CANCELPOINT(cancelpoint_read);
   1507 	ADD_TEST_CANCELPOINT(cancelpoint_readv);
   1508 	ADD_TEST_CANCELPOINT(cancelpoint_recv);
   1509 	ADD_TEST_CANCELPOINT(cancelpoint_recvfrom);
   1510 	ADD_TEST_CANCELPOINT(cancelpoint_recvmsg);
   1511 	ADD_TEST_CANCELPOINT(cancelpoint_select);
   1512 	ADD_TEST_CANCELPOINT(cancelpoint_send);
   1513 	ADD_TEST_CANCELPOINT(cancelpoint_sendto);
   1514 	ADD_TEST_CANCELPOINT(cancelpoint_sendmsg);
   1515 	ADD_TEST_CANCELPOINT(cancelpoint_sigsuspend);
   1516 	ADD_TEST_CANCELPOINT(cancelpoint_sigtimedwait);
   1517 	ADD_TEST_CANCELPOINT(cancelpoint_sigwait);
   1518 	ADD_TEST_CANCELPOINT(cancelpoint_sigwaitinfo);
   1519 	ADD_TEST_CANCELPOINT(cancelpoint_sleep);
   1520 	ADD_TEST_CANCELPOINT(cancelpoint_tcdrain);
   1521 	ADD_TEST_CANCELPOINT(cancelpoint_thrd_join);
   1522 	ADD_TEST_CANCELPOINT(cancelpoint_thrd_sleep);
   1523 	ADD_TEST_CANCELPOINT(cancelpoint_wait);
   1524 	ADD_TEST_CANCELPOINT(cancelpoint_waitid);
   1525 	ADD_TEST_CANCELPOINT(cancelpoint_waitpid);
   1526 	ADD_TEST_CANCELPOINT(cancelpoint_write);
   1527 	ADD_TEST_CANCELPOINT(cancelpoint_writev);
   1528 
   1529 	ATF_TP_ADD_TC(tp, cleanuppop0);
   1530 	ATF_TP_ADD_TC(tp, cleanuppop1);
   1531 	ATF_TP_ADD_TC(tp, cancelself_async);
   1532 	ATF_TP_ADD_TC(tp, cancelself_deferred);
   1533 	ATF_TP_ADD_TC(tp, defaults);
   1534 	ATF_TP_ADD_TC(tp, disable_enable);
   1535 	ATF_TP_ADD_TC(tp, disable_enable_async);
   1536 	ATF_TP_ADD_TC(tp, disable_enable_setcanceltype_async);
   1537 	ATF_TP_ADD_TC(tp, setcanceltype_async);
   1538 	ATF_TP_ADD_TC(tp, notestcancel_loop_async);
   1539 	ATF_TP_ADD_TC(tp, sigsafecancelstate);
   1540 	ATF_TP_ADD_TC(tp, testcancel_loop);
   1541 
   1542 	return atf_no_error();
   1543 }
   1544