Back to index

glibc  2.9
tst-cond22.c
Go to the documentation of this file.
00001 #include <pthread.h>
00002 #include <stdio.h>
00003 #include <stdlib.h>
00004 
00005 
00006 static pthread_barrier_t b;
00007 static pthread_cond_t c = PTHREAD_COND_INITIALIZER;
00008 static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
00009 
00010 
00011 static void
00012 cl (void *arg)
00013 {
00014   pthread_mutex_unlock (&m);
00015 }
00016 
00017 
00018 static void *
00019 tf (void *arg)
00020 {
00021   if (pthread_mutex_lock (&m) != 0)
00022     {
00023       printf ("%s: mutex_lock failed\n", __func__);
00024       exit (1);
00025     }
00026   int e = pthread_barrier_wait (&b);
00027   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
00028     {
00029       printf ("%s: barrier_wait failed\n", __func__);
00030       exit (1);
00031     }
00032   pthread_cleanup_push (cl, NULL);
00033   /* We have to loop here because the cancellation might come after
00034      the cond_wait call left the cancelable area and is then waiting
00035      on the mutex.  In this case the beginning of the second cond_wait
00036      call will cause the cancellation to happen.  */
00037   do
00038     if (pthread_cond_wait (&c, &m) != 0)
00039       {
00040        printf ("%s: cond_wait failed\n", __func__);
00041        exit (1);
00042       }
00043   while (arg == NULL);
00044   pthread_cleanup_pop (0);
00045   if (pthread_mutex_unlock (&m) != 0)
00046     {
00047       printf ("%s: mutex_unlock failed\n", __func__);
00048       exit (1);
00049     }
00050   return NULL;
00051 }
00052 
00053 
00054 static int
00055 do_test (void)
00056 {
00057   int status = 0;
00058 
00059   if (pthread_barrier_init (&b, NULL, 2) != 0)
00060     {
00061       puts ("barrier_init failed");
00062       return 1;
00063     }
00064 
00065   pthread_t th;
00066   if (pthread_create (&th, NULL, tf, NULL) != 0)
00067     {
00068       puts ("1st create failed");
00069       return 1;
00070     }
00071   int e = pthread_barrier_wait (&b);
00072   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
00073     {
00074       puts ("1st barrier_wait failed");
00075       return 1;
00076     }
00077   if (pthread_mutex_lock (&m) != 0)
00078     {
00079       puts ("1st mutex_lock failed");
00080       return 1;
00081     }
00082   if (pthread_cond_signal (&c) != 0)
00083     {
00084       puts ("1st cond_signal failed");
00085       return 1;
00086     }
00087   if (pthread_cancel (th) != 0)
00088     {
00089       puts ("cancel failed");
00090       return 1;
00091     }
00092   if (pthread_mutex_unlock (&m) != 0)
00093     {
00094       puts ("1st mutex_unlock failed");
00095       return 1;
00096     }
00097   void *res;
00098   if (pthread_join (th, &res) != 0)
00099     {
00100       puts ("1st join failed");
00101       return 1;
00102     }
00103   if (res != PTHREAD_CANCELED)
00104     {
00105       puts ("first thread not canceled");
00106       status = 1;
00107     }
00108 
00109   printf ("cond = { %d, %x, %lld, %lld, %lld, %p, %u, %u }\n",
00110          c.__data.__lock, c.__data.__futex, c.__data.__total_seq,
00111          c.__data.__wakeup_seq, c.__data.__woken_seq, c.__data.__mutex,
00112          c.__data.__nwaiters, c.__data.__broadcast_seq);
00113 
00114   if (pthread_create (&th, NULL, tf, (void *) 1l) != 0)
00115     {
00116       puts ("2nd create failed");
00117       return 1;
00118     }
00119   e = pthread_barrier_wait (&b);
00120   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
00121     {
00122       puts ("2nd barrier_wait failed");
00123       return 1;
00124     }
00125   if (pthread_mutex_lock (&m) != 0)
00126     {
00127       puts ("2nd mutex_lock failed");
00128       return 1;
00129     }
00130   if (pthread_cond_signal (&c) != 0)
00131     {
00132       puts ("2nd cond_signal failed");
00133       return 1;
00134     }
00135   if (pthread_mutex_unlock (&m) != 0)
00136     {
00137       puts ("2nd mutex_unlock failed");
00138       return 1;
00139     }
00140   if (pthread_join (th, &res) != 0)
00141     {
00142       puts ("2nd join failed");
00143       return 1;
00144     }
00145   if (res != NULL)
00146     {
00147       puts ("2nd thread canceled");
00148       status = 1;
00149     }
00150 
00151   printf ("cond = { %d, %x, %lld, %lld, %lld, %p, %u, %u }\n",
00152          c.__data.__lock, c.__data.__futex, c.__data.__total_seq,
00153          c.__data.__wakeup_seq, c.__data.__woken_seq, c.__data.__mutex,
00154          c.__data.__nwaiters, c.__data.__broadcast_seq);
00155 
00156   return status;
00157 }
00158 
00159 #define TEST_FUNCTION do_test ()
00160 #include "../test-skeleton.c"