Back to index

glibc  2.9
tst-cancel25.c
Go to the documentation of this file.
00001 #include <pthreadP.h>
00002 #include <signal.h>
00003 #include <stdio.h>
00004 #include <stdlib.h>
00005 
00006 
00007 static pthread_barrier_t b;
00008 static pthread_t th2;
00009 
00010 
00011 static void *
00012 tf2 (void *arg)
00013 {
00014   sigset_t mask;
00015   if (pthread_sigmask (SIG_SETMASK, NULL, &mask) != 0)
00016     {
00017       puts ("pthread_sigmask failed");
00018       exit (1);
00019     }
00020   if (sigismember (&mask, SIGCANCEL))
00021     {
00022       puts ("SIGCANCEL blocked in new thread");
00023       exit (1);
00024     }
00025 
00026   /* Sync with the main thread so that we do not test anything else.  */
00027   int e = pthread_barrier_wait (&b);
00028   if (e != 0  && e != PTHREAD_BARRIER_SERIAL_THREAD)
00029     {
00030       puts ("barrier_wait failed");
00031       exit (1);
00032     }
00033 
00034   while (1)
00035     {
00036       /* Just a cancelable call.  */
00037       struct timespec ts = { 10000, 0 };
00038       nanosleep (&ts, 0);
00039     }
00040 
00041   return NULL;
00042 }
00043 
00044 
00045 static void
00046 unwhand (void *arg)
00047 {
00048   if (pthread_create (&th2, NULL, tf2, NULL) != 0)
00049     {
00050       puts ("unwhand: create failed");
00051       exit (1);
00052     }
00053 }
00054 
00055 
00056 static void *
00057 tf (void *arg)
00058 {
00059   pthread_cleanup_push (unwhand, NULL);
00060 
00061   /* Sync with the main thread so that we do not test anything else.  */
00062   int e = pthread_barrier_wait (&b);
00063   if (e != 0  && e != PTHREAD_BARRIER_SERIAL_THREAD)
00064     {
00065       puts ("barrier_wait failed");
00066       exit (1);
00067     }
00068 
00069   while (1)
00070     {
00071       /* Just a cancelable call.  */
00072       struct timespec ts = { 10000, 0 };
00073       nanosleep (&ts, 0);
00074     }
00075 
00076   pthread_cleanup_pop (0);
00077 
00078   return NULL;
00079 }
00080 
00081 
00082 static int
00083 do_test (void)
00084 {
00085   if (pthread_barrier_init (&b, NULL, 2) != 0)
00086     {
00087       puts ("barrier_init failed");
00088       return 1;
00089     }
00090 
00091   pthread_t th1;
00092   if (pthread_create (&th1, NULL, tf, NULL) != 0)
00093     {
00094       puts ("create failed");
00095       return 1;
00096     }
00097 
00098   int e = pthread_barrier_wait (&b);
00099   if (e != 0  && e != PTHREAD_BARRIER_SERIAL_THREAD)
00100     {
00101       puts ("barrier_wait failed");
00102       return 1;
00103     }
00104 
00105   /* Make sure tf1 enters nanosleep.  */
00106   struct timespec ts = { 0, 500000000 };
00107   while (nanosleep (&ts, &ts) != 0)
00108     ;
00109 
00110   if (pthread_cancel (th1) != 0)
00111     {
00112       puts ("1st cancel failed");
00113       return 1;
00114     }
00115 
00116   void *res;
00117   if (pthread_join (th1, &res) != 0)
00118     {
00119       puts ("1st join failed");
00120       return 1;
00121     }
00122   if (res != PTHREAD_CANCELED)
00123     {
00124       puts ("1st thread not canceled");
00125       return 1;
00126     }
00127 
00128   e = pthread_barrier_wait (&b);
00129   if (e != 0  && e != PTHREAD_BARRIER_SERIAL_THREAD)
00130     {
00131       puts ("barrier_wait failed");
00132       return 1;
00133     }
00134 
00135   /* Make sure tf2 enters nanosleep.  */
00136   ts.tv_sec = 0;
00137   ts.tv_nsec = 500000000;
00138   while (nanosleep (&ts, &ts) != 0)
00139     ;
00140 
00141   puts ("calling pthread_cancel the second time");
00142   if (pthread_cancel (th2) != 0)
00143     {
00144       puts ("2nd cancel failed");
00145       return 1;
00146     }
00147 
00148   puts ("calling pthread_join the second time");
00149   if (pthread_join (th2, &res) != 0)
00150     {
00151       puts ("2nd join failed");
00152       return 1;
00153     }
00154   if (res != PTHREAD_CANCELED)
00155     {
00156       puts ("2nd thread not canceled");
00157       return 1;
00158     }
00159 
00160   if (pthread_barrier_destroy (&b) != 0)
00161     {
00162       puts ("barrier_destroy failed");
00163       return 0;
00164     }
00165 
00166   return 0;
00167 }
00168 
00169 #define TEST_FUNCTION do_test ()
00170 #define TIMEOUT 4
00171 #include "../test-skeleton.c"