root/maint/gnulib/lib/pthread-mutex.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pthread_mutexattr_init
  2. pthread_mutexattr_gettype
  3. pthread_mutexattr_settype
  4. pthread_mutexattr_getrobust
  5. pthread_mutexattr_setrobust
  6. pthread_mutexattr_destroy
  7. pthread_mutexattr_getrobust
  8. pthread_mutexattr_setrobust
  9. pthread_mutex_init
  10. pthread_mutex_lock
  11. pthread_mutex_trylock
  12. pthread_mutex_timedlock
  13. pthread_mutex_unlock
  14. pthread_mutex_destroy
  15. pthread_mutex_init
  16. pthread_mutex_lock
  17. pthread_mutex_trylock
  18. pthread_mutex_timedlock
  19. pthread_mutex_unlock
  20. pthread_mutex_destroy

   1 /* POSIX mutexes (locks).
   2    Copyright (C) 2010-2021 Free Software Foundation, Inc.
   3 
   4    This file is free software: you can redistribute it and/or modify
   5    it under the terms of the GNU Lesser General Public License as
   6    published by the Free Software Foundation; either version 2.1 of the
   7    License, or (at your option) any later version.
   8 
   9    This file is distributed in the hope that it will be useful,
  10    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12    GNU Lesser General Public License for more details.
  13 
  14    You should have received a copy of the GNU Lesser General Public License
  15    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
  16 
  17 /* Written by Paul Eggert, 2010, and Bruno Haible <bruno@clisp.org>, 2019.  */
  18 
  19 #include <config.h>
  20 
  21 /* Specification.  */
  22 #include <pthread.h>
  23 
  24 #if (defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS
  25 # include "windows-timedmutex.h"
  26 # include "windows-timedrecmutex.h"
  27 #else
  28 # include <stdlib.h>
  29 #endif
  30 
  31 #if ((defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS) || !HAVE_PTHREAD_H
  32 
  33 int
  34 pthread_mutexattr_init (pthread_mutexattr_t *attr)
     /* [previous][next][first][last][top][bottom][index][help] */
  35 {
  36   *attr = (PTHREAD_MUTEX_STALLED << 2) | PTHREAD_MUTEX_DEFAULT;
  37   return 0;
  38 }
  39 
  40 int
  41 pthread_mutexattr_gettype (const pthread_mutexattr_t *attr, int *typep)
     /* [previous][next][first][last][top][bottom][index][help] */
  42 {
  43   *typep = *attr & (PTHREAD_MUTEX_DEFAULT | PTHREAD_MUTEX_NORMAL
  44                     | PTHREAD_MUTEX_ERRORCHECK | PTHREAD_MUTEX_RECURSIVE);
  45   return 0;
  46 }
  47 
  48 int
  49 pthread_mutexattr_settype (pthread_mutexattr_t *attr, int type)
     /* [previous][next][first][last][top][bottom][index][help] */
  50 {
  51   if (!(type == PTHREAD_MUTEX_DEFAULT
  52         || type == PTHREAD_MUTEX_NORMAL
  53         || type == PTHREAD_MUTEX_ERRORCHECK
  54         || type == PTHREAD_MUTEX_RECURSIVE))
  55     return EINVAL;
  56   *attr ^= (*attr ^ type)
  57            & (PTHREAD_MUTEX_DEFAULT | PTHREAD_MUTEX_NORMAL
  58               | PTHREAD_MUTEX_ERRORCHECK | PTHREAD_MUTEX_RECURSIVE);
  59   return 0;
  60 }
  61 
  62 int
  63 pthread_mutexattr_getrobust (const pthread_mutexattr_t *attr, int *robustp)
     /* [previous][next][first][last][top][bottom][index][help] */
  64 {
  65   *robustp = (*attr >> 2) & (PTHREAD_MUTEX_STALLED | PTHREAD_MUTEX_ROBUST);
  66   return 0;
  67 }
  68 
  69 int
  70 pthread_mutexattr_setrobust (pthread_mutexattr_t *attr, int robust)
     /* [previous][next][first][last][top][bottom][index][help] */
  71 {
  72   if (!(robust == PTHREAD_MUTEX_STALLED || robust == PTHREAD_MUTEX_ROBUST))
  73     return EINVAL;
  74   *attr ^= (*attr ^ (robust << 2))
  75            & ((PTHREAD_MUTEX_STALLED | PTHREAD_MUTEX_ROBUST) << 2);
  76   return 0;
  77 }
  78 
  79 int
  80 pthread_mutexattr_destroy (_GL_UNUSED pthread_mutexattr_t *attr)
     /* [previous][next][first][last][top][bottom][index][help] */
  81 {
  82   return 0;
  83 }
  84 
  85 #elif PTHREAD_MUTEXATTR_ROBUST_UNIMPLEMENTED
  86 
  87 int
  88 pthread_mutexattr_getrobust (const pthread_mutexattr_t *attr, int *robustp)
     /* [previous][next][first][last][top][bottom][index][help] */
  89 {
  90   *robustp = PTHREAD_MUTEX_STALLED;
  91   return 0;
  92 }
  93 
  94 int
  95 pthread_mutexattr_setrobust (pthread_mutexattr_t *attr, int robust)
     /* [previous][next][first][last][top][bottom][index][help] */
  96 {
  97   if (!(robust == PTHREAD_MUTEX_STALLED || robust == PTHREAD_MUTEX_ROBUST))
  98     return EINVAL;
  99   if (!(robust == PTHREAD_MUTEX_STALLED))
 100     return ENOTSUP;
 101   return 0;
 102 }
 103 
 104 #endif
 105 
 106 #if (defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS
 107 /* Use Windows threads.  */
 108 
 109 int
 110 pthread_mutex_init (pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
     /* [previous][next][first][last][top][bottom][index][help] */
 111 {
 112   /* This implementation does not support PTHREAD_MUTEX_ERRORCHECK
 113      and ignores the 'robust' attribute.  */
 114   if (attr != NULL
 115       && (*attr & (PTHREAD_MUTEX_DEFAULT | PTHREAD_MUTEX_NORMAL
 116                    | PTHREAD_MUTEX_ERRORCHECK | PTHREAD_MUTEX_RECURSIVE))
 117          == PTHREAD_MUTEX_RECURSIVE)
 118     {
 119       mutex->type = 2;
 120       return glwthread_timedrecmutex_init (&mutex->u.u_timedrecmutex);
 121     }
 122   else
 123     {
 124       mutex->type = 1;
 125       return glwthread_timedmutex_init (&mutex->u.u_timedmutex);
 126     }
 127 }
 128 
 129 int
 130 pthread_mutex_lock (pthread_mutex_t *mutex)
     /* [previous][next][first][last][top][bottom][index][help] */
 131 {
 132   switch (mutex->type)
 133     {
 134     case 1:
 135       return glwthread_timedmutex_lock (&mutex->u.u_timedmutex);
 136     case 2:
 137       return glwthread_timedrecmutex_lock (&mutex->u.u_timedrecmutex);
 138     default:
 139       abort ();
 140     }
 141 }
 142 
 143 int
 144 pthread_mutex_trylock (pthread_mutex_t *mutex)
     /* [previous][next][first][last][top][bottom][index][help] */
 145 {
 146   switch (mutex->type)
 147     {
 148     case 1:
 149       return glwthread_timedmutex_trylock (&mutex->u.u_timedmutex);
 150     case 2:
 151       return glwthread_timedrecmutex_trylock (&mutex->u.u_timedrecmutex);
 152     default:
 153       abort ();
 154     }
 155 }
 156 
 157 int
 158 pthread_mutex_timedlock (pthread_mutex_t *mutex, const struct timespec *abstime)
     /* [previous][next][first][last][top][bottom][index][help] */
 159 {
 160   switch (mutex->type)
 161     {
 162     case 1:
 163       return glwthread_timedmutex_timedlock (&mutex->u.u_timedmutex, abstime);
 164     case 2:
 165       return glwthread_timedrecmutex_timedlock (&mutex->u.u_timedrecmutex,
 166                                                 abstime);
 167     default:
 168       abort ();
 169     }
 170 }
 171 
 172 int
 173 pthread_mutex_unlock (pthread_mutex_t *mutex)
     /* [previous][next][first][last][top][bottom][index][help] */
 174 {
 175   switch (mutex->type)
 176     {
 177     case 1:
 178       return glwthread_timedmutex_unlock (&mutex->u.u_timedmutex);
 179     case 2:
 180       return glwthread_timedrecmutex_unlock (&mutex->u.u_timedrecmutex);
 181     default:
 182       abort ();
 183     }
 184 }
 185 
 186 int
 187 pthread_mutex_destroy (pthread_mutex_t *mutex)
     /* [previous][next][first][last][top][bottom][index][help] */
 188 {
 189   switch (mutex->type)
 190     {
 191     case 1:
 192       return glwthread_timedmutex_destroy (&mutex->u.u_timedmutex);
 193     case 2:
 194       return glwthread_timedrecmutex_destroy (&mutex->u.u_timedrecmutex);
 195     default:
 196       abort ();
 197     }
 198 }
 199 
 200 #elif HAVE_PTHREAD_H
 201 /* Provide workarounds for POSIX threads.  */
 202 
 203 /* pthread_mutex_timedlock is defined by the 'pthread_mutex_timedlock'
 204    module.  */
 205 
 206 #else
 207 /* Provide a dummy implementation for single-threaded applications.  */
 208 
 209 int
 210 pthread_mutex_init (_GL_UNUSED pthread_mutex_t *mutex,
     /* [previous][next][first][last][top][bottom][index][help] */
 211                     _GL_UNUSED const pthread_mutexattr_t *attr)
 212 {
 213   /* MUTEX is never seriously used.  */
 214   return 0;
 215 }
 216 
 217 int
 218 pthread_mutex_lock (_GL_UNUSED pthread_mutex_t *mutex)
     /* [previous][next][first][last][top][bottom][index][help] */
 219 {
 220   /* There is only one thread, so it always gets the lock.  This
 221      implementation does not support PTHREAD_MUTEX_ERRORCHECK.  */
 222   return 0;
 223 }
 224 
 225 int
 226 pthread_mutex_trylock (_GL_UNUSED pthread_mutex_t *mutex)
     /* [previous][next][first][last][top][bottom][index][help] */
 227 {
 228   /* There is only one thread, so it always gets the lock.  This
 229      implementation does not support PTHREAD_MUTEX_ERRORCHECK.  */
 230   return 0;
 231 }
 232 
 233 int
 234 pthread_mutex_timedlock (_GL_UNUSED pthread_mutex_t *mutex,
     /* [previous][next][first][last][top][bottom][index][help] */
 235                          _GL_UNUSED const struct timespec *abstime)
 236 {
 237   /* There is only one thread, so it always gets the lock.  This
 238      implementation does not support PTHREAD_MUTEX_ERRORCHECK.  */
 239   return 0;
 240 }
 241 
 242 int
 243 pthread_mutex_unlock (_GL_UNUSED pthread_mutex_t *mutex)
     /* [previous][next][first][last][top][bottom][index][help] */
 244 {
 245   /* There is only one thread, so it always unlocks successfully.
 246      This implementation does not support robust mutexes or
 247      PTHREAD_MUTEX_ERRORCHECK.  */
 248   return 0;
 249 }
 250 
 251 int
 252 pthread_mutex_destroy (_GL_UNUSED pthread_mutex_t *mutex)
     /* [previous][next][first][last][top][bottom][index][help] */
 253 {
 254   /* MUTEX is never seriously used.  */
 255   return 0;
 256 }
 257 
 258 #endif

/* [previous][next][first][last][top][bottom][index][help] */