Back to index

glibc  2.9
tst-cancel1.c
Go to the documentation of this file.
00001 /* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
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 <pthread.h>
00021 #include <signal.h>
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <string.h>
00025 
00026 
00027 static pthread_mutex_t m1 = PTHREAD_MUTEX_INITIALIZER;
00028 static pthread_mutex_t m2 = PTHREAD_MUTEX_INITIALIZER;
00029 
00030 static int cntr;
00031 
00032 
00033 static void
00034 cleanup (void *arg)
00035 {
00036   if (arg != (void *) 42l)
00037     cntr = 42;
00038   else
00039     cntr = 1;
00040 }
00041 
00042 
00043 static void *
00044 tf (void *arg)
00045 {
00046   /* Ignore all signals.  This must not have any effect on delivering
00047      the cancellation signal.  */
00048   sigset_t ss;
00049 
00050   sigfillset (&ss);
00051 
00052   if (pthread_sigmask (SIG_BLOCK, &ss, NULL) != 0)
00053     {
00054       puts ("pthread_sigmask failed");
00055       exit (1);
00056     }
00057 
00058   pthread_cleanup_push (cleanup, (void *) 42l);
00059 
00060   int err = pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
00061   if (err != 0)
00062     {
00063       printf ("setcanceltype failed: %s\n", strerror (err));
00064       exit (1);
00065     }
00066   /* The following code is not standard compliant: the mutex functions
00067      must not be called with asynchronous cancellation enabled.  */
00068 
00069   err = pthread_mutex_unlock (&m2);
00070   if (err != 0)
00071     {
00072       printf ("child: mutex_unlock failed: %s\n", strerror (err));
00073       exit (1);
00074     }
00075 
00076   err = pthread_mutex_lock (&m1);
00077   if (err != 0)
00078     {
00079       printf ("child: 1st mutex_lock failed: %s\n", strerror (err));
00080       exit (1);
00081     }
00082 
00083   /* We should never come here.  */
00084 
00085   pthread_cleanup_pop (0);
00086 
00087   return NULL;
00088 }
00089 
00090 
00091 static int
00092 do_test (void)
00093 {
00094   int err;
00095   pthread_t th;
00096   int result = 0;
00097   void *retval;
00098 
00099   /* Get the mutexes.  */
00100   err = pthread_mutex_lock (&m1);
00101   if (err != 0)
00102     {
00103       printf ("parent: 1st mutex_lock failed: %s\n", strerror (err));
00104       return 1;
00105     }
00106   err = pthread_mutex_lock (&m2);
00107   if (err != 0)
00108     {
00109       printf ("parent: 2nd mutex_lock failed: %s\n", strerror (err));
00110       return 1;
00111     }
00112 
00113   err = pthread_create (&th, NULL, tf, NULL);
00114   if (err != 0)
00115     {
00116       printf ("create failed: %s\n", strerror (err));
00117       return 1;
00118     }
00119 
00120   err = pthread_mutex_lock (&m2);
00121   if (err != 0)
00122     {
00123       printf ("parent: 3rd mutex_lock failed: %s\n", strerror (err));
00124       return 1;
00125     }
00126 
00127   err = pthread_cancel (th);
00128   if (err != 0)
00129     {
00130       printf ("cancel failed: %s\n", strerror (err));
00131       return 1;
00132     }
00133 
00134   err = pthread_join (th, &retval);
00135   if (err != 0)
00136     {
00137       printf ("join failed: %s\n", strerror (err));
00138       return 1;
00139     }
00140 
00141   if (retval != PTHREAD_CANCELED)
00142     {
00143       printf ("wrong return value: %p\n", retval);
00144       result = 1;
00145     }
00146 
00147   if (cntr == 42)
00148     {
00149       puts ("cleanup handler called with wrong argument");
00150       result = 1;
00151     }
00152   else if (cntr != 1)
00153     {
00154       puts ("cleanup handling not called");
00155       result = 1;
00156     }
00157 
00158   return result;
00159 }
00160 
00161 
00162 #define TEST_FUNCTION do_test ()
00163 #include "../test-skeleton.c"