tst-cancel25.c 3.1 KB

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