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, ¬estcancel_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