Back to index

glibc  2.9
tst-cancel24.cc
Go to the documentation of this file.
00001 #include <pthread.h>
00002 #include <semaphore.h>
00003 #include <stdlib.h>
00004 #include <stdio.h>
00005 #include <unistd.h>
00006 
00007 
00008 static volatile bool destr_called;
00009 static volatile bool except_caught;
00010 
00011 static pthread_barrier_t b;
00012 
00013 
00014 struct monitor
00015 {
00016   // gcc is broken and would generate a warning without this dummy
00017   // constructor.
00018   monitor () { }
00019   ~monitor() { destr_called = true; }
00020 };
00021 
00022 
00023 static void *
00024 tf (void *arg)
00025 {
00026   sem_t *s = static_cast<sem_t *> (arg);
00027 
00028   try
00029     {
00030       monitor m;
00031 
00032       pthread_barrier_wait (&b);
00033 
00034       while (1)
00035       sem_wait (s);
00036     }
00037   catch (...)
00038     {
00039       except_caught = true;
00040       throw;
00041     }
00042 
00043   return NULL;
00044 }
00045 
00046 
00047 static int
00048 do_test ()
00049 {
00050   if (pthread_barrier_init (&b, NULL, 2) != 0)
00051     {
00052       puts ("barrier_init failed");
00053       return 1;
00054     }
00055 
00056   sem_t s;
00057   if (sem_init (&s, 0, 0) != 0)
00058     {
00059       puts ("sem_init failed");
00060       return 1;
00061     }
00062 
00063   pthread_t th;
00064   if (pthread_create (&th, NULL, tf, &s) != 0)
00065     {
00066       puts ("pthread_create failed");
00067       return 1;
00068     }
00069 
00070   pthread_barrier_wait (&b);
00071 
00072   /* There is unfortunately no better method to try to assure the
00073      child thread reached the sem_wait call and is actually waiting
00074      than to sleep here.  */
00075   sleep (1);
00076 
00077   if (pthread_cancel (th) != 0)
00078     {
00079       puts ("cancel failed");
00080       return 1;
00081     }
00082 
00083   void *res;
00084   if (pthread_join (th, &res) != 0)
00085     {
00086       puts ("join failed");
00087       return 1;
00088     }
00089 
00090   if (res != PTHREAD_CANCELED)
00091     {
00092       puts ("thread was not canceled");
00093       return 1;
00094     }
00095 
00096   if (! except_caught)
00097     {
00098       puts ("exception not caught");
00099       return 1;
00100     }
00101 
00102   if (! destr_called)
00103     {
00104       puts ("destructor not called");
00105       return 1;
00106     }
00107 
00108   return 0;
00109 }
00110 
00111 #define TEST_FUNCTION do_test ()
00112 #define TIMEOUT 3
00113 #include "../test-skeleton.c"