tst-cancel25.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. #include <pthreadP.h>
  2. #include <signal.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. static pthread_barrier_t b;
  6. static pthread_t th2;
  7. static void *
  8. tf2 (void *arg)
  9. {
  10. sigset_t mask;
  11. if (pthread_sigmask (SIG_SETMASK, NULL, &mask) != 0)
  12. {
  13. puts ("pthread_sigmask failed");
  14. exit (1);
  15. }
  16. if (sigismember (&mask, SIGCANCEL))
  17. {
  18. puts ("SIGCANCEL blocked in new thread");
  19. exit (1);
  20. }
  21. /* Sync with the main thread so that we do not test anything else. */
  22. int e = pthread_barrier_wait (&b);
  23. if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
  24. {
  25. puts ("barrier_wait failed");
  26. exit (1);
  27. }
  28. while (1)
  29. {
  30. /* Just a cancelable call. */
  31. struct timespec ts = { 10000, 0 };
  32. nanosleep (&ts, 0);
  33. }
  34. return NULL;
  35. }
  36. static void
  37. unwhand (void *arg)
  38. {
  39. if (pthread_create (&th2, NULL, tf2, NULL) != 0)
  40. {
  41. puts ("unwhand: create failed");
  42. exit (1);
  43. }
  44. }
  45. static void *
  46. tf (void *arg)
  47. {
  48. pthread_cleanup_push (unwhand, NULL);
  49. /* Sync with the main thread so that we do not test anything else. */
  50. int e = pthread_barrier_wait (&b);
  51. if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
  52. {
  53. puts ("barrier_wait failed");
  54. exit (1);
  55. }
  56. while (1)
  57. {
  58. /* Just a cancelable call. */
  59. struct timespec ts = { 10000, 0 };
  60. nanosleep (&ts, 0);
  61. }
  62. pthread_cleanup_pop (0);
  63. return NULL;
  64. }
  65. static int
  66. do_test (void)
  67. {
  68. if (pthread_barrier_init (&b, NULL, 2) != 0)
  69. {
  70. puts ("barrier_init failed");
  71. return 1;
  72. }
  73. pthread_t th1;
  74. if (pthread_create (&th1, NULL, tf, NULL) != 0)
  75. {
  76. puts ("create failed");
  77. return 1;
  78. }
  79. int e = pthread_barrier_wait (&b);
  80. if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
  81. {
  82. puts ("barrier_wait failed");
  83. return 1;
  84. }
  85. /* Make sure tf1 enters nanosleep. */
  86. struct timespec ts = { 0, 500000000 };
  87. while (nanosleep (&ts, &ts) != 0)
  88. ;
  89. if (pthread_cancel (th1) != 0)
  90. {
  91. puts ("1st cancel failed");
  92. return 1;
  93. }
  94. void *res;
  95. if (pthread_join (th1, &res) != 0)
  96. {
  97. puts ("1st join failed");
  98. return 1;
  99. }
  100. if (res != PTHREAD_CANCELED)
  101. {
  102. puts ("1st thread not canceled");
  103. return 1;
  104. }
  105. e = pthread_barrier_wait (&b);
  106. if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
  107. {
  108. puts ("barrier_wait failed");
  109. return 1;
  110. }
  111. /* Make sure tf2 enters nanosleep. */
  112. ts.tv_sec = 0;
  113. ts.tv_nsec = 500000000;
  114. while (nanosleep (&ts, &ts) != 0)
  115. ;
  116. puts ("calling pthread_cancel the second time");
  117. if (pthread_cancel (th2) != 0)
  118. {
  119. puts ("2nd cancel failed");
  120. return 1;
  121. }
  122. puts ("calling pthread_join the second time");
  123. if (pthread_join (th2, &res) != 0)
  124. {
  125. puts ("2nd join failed");
  126. return 1;
  127. }
  128. if (res != PTHREAD_CANCELED)
  129. {
  130. puts ("2nd thread not canceled");
  131. return 1;
  132. }
  133. if (pthread_barrier_destroy (&b) != 0)
  134. {
  135. puts ("barrier_destroy failed");
  136. return 0;
  137. }
  138. return 0;
  139. }
  140. #define TEST_FUNCTION do_test ()
  141. #define TIMEOUT 4
  142. #include "../test-skeleton.c"