Back to index

glibc  2.9
tst-mutex8.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 Ulrich Drepper <drepper@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 /* This test checks behavior not required by POSIX.  */
00021 #include <errno.h>
00022 #include <pthread.h>
00023 #include <stdbool.h>
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 
00027 
00028 static pthread_mutex_t *m;
00029 static pthread_barrier_t b;
00030 static pthread_cond_t c;
00031 static bool done;
00032 
00033 
00034 static void
00035 cl (void *arg)
00036 {
00037   if (pthread_mutex_unlock (m) != 0)
00038     {
00039       puts ("cl: mutex_unlocked failed");
00040       exit (1);
00041     }
00042 }
00043 
00044 
00045 static void *
00046 tf (void *arg)
00047 {
00048   if (pthread_mutex_lock (m) != 0)
00049     {
00050       puts ("tf: mutex_lock failed");
00051       return (void *) 1l;
00052     }
00053 
00054   int e = pthread_barrier_wait (&b);
00055   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
00056     {
00057       puts ("barrier_wait failed");
00058       return (void *) 1l;
00059     }
00060 
00061   if (arg == NULL)
00062     do
00063       if (pthread_cond_wait (&c, m) != 0)
00064        {
00065          puts ("tf: cond_wait failed");
00066          return (void *) 1l;
00067        }
00068     while (! done);
00069   else
00070     do
00071       {
00072        pthread_cleanup_push (cl, NULL);
00073 
00074        if (pthread_cond_wait (&c, m) != 0)
00075          {
00076            puts ("tf: cond_wait failed");
00077            return (void *) 1l;
00078          }
00079 
00080        pthread_cleanup_pop (0);
00081       }
00082     while (! done);
00083 
00084   if (pthread_mutex_unlock (m) != 0)
00085     {
00086       puts ("tf: mutex_unlock failed");
00087       return (void *) 1l;
00088     }
00089 
00090   return NULL;
00091 }
00092 
00093 
00094 static int
00095 check_type (const char *mas, pthread_mutexattr_t *ma)
00096 {
00097   if (pthread_mutex_init (m, ma) != 0)
00098     {
00099       printf ("1st mutex_init failed for %s\n", mas);
00100       return 1;
00101     }
00102 
00103   if (pthread_mutex_destroy (m) != 0)
00104     {
00105       printf ("immediate mutex_destroy failed for %s\n", mas);
00106       return 1;
00107     }
00108 
00109   if (pthread_mutex_init (m, ma) != 0)
00110     {
00111       printf ("2nd mutex_init failed for %s\n", mas);
00112       return 1;
00113     }
00114 
00115   if (pthread_mutex_lock (m) != 0)
00116     {
00117       printf ("1st mutex_lock failed for %s\n", mas);
00118       return 1;
00119     }
00120 
00121   int e = pthread_mutex_destroy (m);
00122   if (e == 0)
00123     {
00124       printf ("mutex_destroy of self-locked mutex succeeded for %s\n", mas);
00125       return 1;
00126     }
00127   if (e != EBUSY)
00128     {
00129       printf ("mutex_destroy of self-locked mutex did not return EBUSY %s\n",
00130              mas);
00131       return 1;
00132     }
00133 
00134   if (pthread_mutex_unlock (m) != 0)
00135     {
00136       printf ("1st mutex_unlock failed for %s\n", mas);
00137       return 1;
00138     }
00139 
00140   if (pthread_mutex_trylock (m) != 0)
00141     {
00142       printf ("mutex_trylock failed for %s\n", mas);
00143       return 1;
00144     }
00145 
00146   e = pthread_mutex_destroy (m);
00147   if (e == 0)
00148     {
00149       printf ("mutex_destroy of self-trylocked mutex succeeded for %s\n", mas);
00150       return 1;
00151     }
00152   if (e != EBUSY)
00153     {
00154       printf ("\
00155 mutex_destroy of self-trylocked mutex did not return EBUSY %s\n",
00156              mas);
00157       return 1;
00158     }
00159 
00160   if (pthread_mutex_unlock (m) != 0)
00161     {
00162       printf ("2nd mutex_unlock failed for %s\n", mas);
00163       return 1;
00164     }
00165 
00166   pthread_t th;
00167   if (pthread_create (&th, NULL, tf, NULL) != 0)
00168     {
00169       puts ("1st create failed");
00170       return 1;
00171     }
00172   done = false;
00173 
00174   e = pthread_barrier_wait (&b);
00175   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
00176     {
00177       puts ("1st barrier_wait failed");
00178       return 1;
00179     }
00180 
00181   if (pthread_mutex_lock (m) != 0)
00182     {
00183       printf ("2nd mutex_lock failed for %s\n", mas);
00184       return 1;
00185     }
00186 
00187   if (pthread_mutex_unlock (m) != 0)
00188     {
00189       printf ("3rd mutex_unlock failed for %s\n", mas);
00190       return 1;
00191     }
00192 
00193   e = pthread_mutex_destroy (m);
00194   if (e == 0)
00195     {
00196       printf ("mutex_destroy of condvar-used mutex succeeded for %s\n", mas);
00197       return 1;
00198     }
00199   if (e != EBUSY)
00200     {
00201       printf ("\
00202 mutex_destroy of condvar-used mutex did not return EBUSY for %s\n", mas);
00203       return 1;
00204     }
00205 
00206   done = true;
00207   if (pthread_cond_signal (&c) != 0)
00208     {
00209       puts ("cond_signal failed");
00210       return 1;
00211     }
00212 
00213   void *r;
00214   if (pthread_join (th, &r) != 0)
00215     {
00216       puts ("join failed");
00217       return 1;
00218     }
00219   if (r != NULL)
00220     {
00221       puts ("thread didn't return NULL");
00222       return 1;
00223     }
00224 
00225   if (pthread_mutex_destroy (m) != 0)
00226     {
00227       printf ("mutex_destroy after condvar-use failed for %s\n", mas);
00228       return 1;
00229     }
00230 
00231   if (pthread_mutex_init (m, ma) != 0)
00232     {
00233       printf ("3rd mutex_init failed for %s\n", mas);
00234       return 1;
00235     }
00236 
00237   if (pthread_create (&th, NULL, tf, (void *) 1) != 0)
00238     {
00239       puts ("2nd create failed");
00240       return 1;
00241     }
00242   done = false;
00243 
00244   e = pthread_barrier_wait (&b);
00245   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
00246     {
00247       puts ("2nd barrier_wait failed");
00248       return 1;
00249     }
00250 
00251   if (pthread_mutex_lock (m) != 0)
00252     {
00253       printf ("3rd mutex_lock failed for %s\n", mas);
00254       return 1;
00255     }
00256 
00257   if (pthread_mutex_unlock (m) != 0)
00258     {
00259       printf ("4th mutex_unlock failed for %s\n", mas);
00260       return 1;
00261     }
00262 
00263   e = pthread_mutex_destroy (m);
00264   if (e == 0)
00265     {
00266       printf ("2nd mutex_destroy of condvar-used mutex succeeded for %s\n",
00267              mas);
00268       return 1;
00269     }
00270   if (e != EBUSY)
00271     {
00272       printf ("\
00273 2nd mutex_destroy of condvar-used mutex did not return EBUSY for %s\n",
00274              mas);
00275       return 1;
00276     }
00277 
00278   if (pthread_cancel (th) != 0)
00279     {
00280       puts ("cond_cancel failed");
00281       return 1;
00282     }
00283 
00284   if (pthread_join (th, &r) != 0)
00285     {
00286       puts ("join failed");
00287       return 1;
00288     }
00289   if (r != PTHREAD_CANCELED)
00290     {
00291       puts ("thread not canceled");
00292       return 1;
00293     }
00294 
00295   if (pthread_mutex_destroy (m) != 0)
00296     {
00297       printf ("mutex_destroy after condvar-canceled failed for %s\n", mas);
00298       return 1;
00299     }
00300 
00301   return 0;
00302 }
00303 
00304 
00305 static int
00306 do_test (void)
00307 {
00308   pthread_mutex_t mm;
00309   m = &mm;
00310 
00311   if (pthread_barrier_init (&b, NULL, 2) != 0)
00312     {
00313       puts ("barrier_init failed");
00314       return 1;
00315     }
00316 
00317   if (pthread_cond_init (&c, NULL) != 0)
00318     {
00319       puts ("cond_init failed");
00320       return 1;
00321     }
00322 
00323   puts ("check normal mutex");
00324   int res = check_type ("normal", NULL);
00325 
00326   pthread_mutexattr_t ma;
00327   if (pthread_mutexattr_init (&ma) != 0)
00328     {
00329       puts ("1st mutexattr_init failed");
00330       return 1;
00331     }
00332   if (pthread_mutexattr_settype (&ma, PTHREAD_MUTEX_RECURSIVE) != 0)
00333     {
00334       puts ("1st mutexattr_settype failed");
00335       return 1;
00336     }
00337   puts ("check recursive mutex");
00338   res |= check_type ("recursive", &ma);
00339   if (pthread_mutexattr_destroy (&ma) != 0)
00340     {
00341       puts ("1st mutexattr_destroy failed");
00342       return 1;
00343     }
00344 
00345   if (pthread_mutexattr_init (&ma) != 0)
00346     {
00347       puts ("2nd mutexattr_init failed");
00348       return 1;
00349     }
00350   if (pthread_mutexattr_settype (&ma, PTHREAD_MUTEX_ERRORCHECK) != 0)
00351     {
00352       puts ("2nd mutexattr_settype failed");
00353       return 1;
00354     }
00355   puts ("check error-checking mutex");
00356   res |= check_type ("error-checking", &ma);
00357   if (pthread_mutexattr_destroy (&ma) != 0)
00358     {
00359       puts ("2nd mutexattr_destroy failed");
00360       return 1;
00361     }
00362 
00363   return res;
00364 }
00365 
00366 #define TEST_FUNCTION do_test ()
00367 #include "../test-skeleton.c"