Back to index

glibc  2.9
tst-cancel22.c
Go to the documentation of this file.
00001 /* Copyright (C) 2003 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003    Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 #include <errno.h>
00021 #include <pthread.h>
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <unistd.h>
00025 
00026 pthread_barrier_t b;
00027 int seen;
00028 
00029 static void *
00030 tf (void *arg)
00031 {
00032   int old;
00033   int r = pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &old);
00034   if (r != 0)
00035     {
00036       puts ("setcancelstate failed");
00037       exit (1);
00038     }
00039 
00040   r = pthread_barrier_wait (&b);
00041   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00042     {
00043       puts ("barrier_wait failed");
00044       exit (1);
00045     }
00046 
00047   for (int i = 0; i < 10; ++i)
00048     {
00049       struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 };
00050       TEMP_FAILURE_RETRY (nanosleep (&ts, &ts));
00051     }
00052 
00053   seen = 1;
00054   pthread_setcancelstate (old, NULL);
00055 
00056   struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 };
00057   TEMP_FAILURE_RETRY (nanosleep (&ts, &ts));
00058 
00059   exit (1);
00060 }
00061 
00062 
00063 static int
00064 do_test (void)
00065 {
00066   if (pthread_barrier_init (&b, NULL, 2) != 0)
00067    {
00068      puts ("barrier init failed");
00069      return 1;
00070    }
00071 
00072   pthread_t th;
00073   if (pthread_create (&th, NULL, tf, NULL) != 0)
00074     {
00075       puts ("thread creation failed");
00076       return 1;
00077     }
00078 
00079   int r = pthread_barrier_wait (&b);
00080   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00081     {
00082       puts ("barrier_wait failed");
00083       return 1;
00084     }
00085 
00086   if (pthread_cancel (th) != 0)
00087     {
00088       puts ("cancel failed");
00089       return 1;
00090     }
00091 
00092   void *status;
00093   if (pthread_join (th, &status) != 0)
00094     {
00095       puts ("join failed");
00096       return 1;
00097     }
00098   if (status != PTHREAD_CANCELED)
00099     {
00100       puts ("thread not canceled");
00101       return 1;
00102     }
00103 
00104   if (pthread_barrier_destroy (&b) != 0)
00105     {
00106       puts ("barrier_destroy failed");
00107       return 1;
00108     }
00109 
00110   if (seen != 1)
00111     {
00112       puts ("thread cancelled when PTHREAD_CANCEL_DISABLED");
00113       return 1;
00114     }
00115 
00116   return 0;
00117 }
00118 
00119 #define TIMEOUT 5
00120 #define TEST_FUNCTION do_test ()
00121 #include "../test-skeleton.c"