1*062c5bc4SJason Schmidlapp /* 2*062c5bc4SJason Schmidlapp * pthread_rwlock_rdlock.c 3*062c5bc4SJason Schmidlapp * 4*062c5bc4SJason Schmidlapp * Description: 5*062c5bc4SJason Schmidlapp * This translation unit implements read/write lock primitives. 6*062c5bc4SJason Schmidlapp * 7*062c5bc4SJason Schmidlapp * -------------------------------------------------------------------------- 8*062c5bc4SJason Schmidlapp * 9*062c5bc4SJason Schmidlapp * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems 10*062c5bc4SJason Schmidlapp * Copyright(C) 2008 Jason Schmidlapp 11*062c5bc4SJason Schmidlapp * 12*062c5bc4SJason Schmidlapp * Contact Email: jschmidlapp@users.sourceforge.net 13*062c5bc4SJason Schmidlapp * 14*062c5bc4SJason Schmidlapp * 15*062c5bc4SJason Schmidlapp * Based upon Pthreads-win32 - POSIX Threads Library for Win32 16*062c5bc4SJason Schmidlapp * Copyright(C) 1998 John E. Bossom 17*062c5bc4SJason Schmidlapp * Copyright(C) 1999,2005 Pthreads-win32 contributors 18*062c5bc4SJason Schmidlapp * 19*062c5bc4SJason Schmidlapp * Contact Email: rpj@callisto.canberra.edu.au 20*062c5bc4SJason Schmidlapp * 21*062c5bc4SJason Schmidlapp * The original list of contributors to the Pthreads-win32 project 22*062c5bc4SJason Schmidlapp * is contained in the file CONTRIBUTORS.ptw32 included with the 23*062c5bc4SJason Schmidlapp * source code distribution. The list can also be seen at the 24*062c5bc4SJason Schmidlapp * following World Wide Web location: 25*062c5bc4SJason Schmidlapp * http://sources.redhat.com/pthreads-win32/contributors.html 26*062c5bc4SJason Schmidlapp * 27*062c5bc4SJason Schmidlapp * This library is free software; you can redistribute it and/or 28*062c5bc4SJason Schmidlapp * modify it under the terms of the GNU Lesser General Public 29*062c5bc4SJason Schmidlapp * License as published by the Free Software Foundation; either 30*062c5bc4SJason Schmidlapp * version 2 of the License, or (at your option) any later version. 31*062c5bc4SJason Schmidlapp * 32*062c5bc4SJason Schmidlapp * This library is distributed in the hope that it will be useful, 33*062c5bc4SJason Schmidlapp * but WITHOUT ANY WARRANTY; without even the implied warranty of 34*062c5bc4SJason Schmidlapp * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 35*062c5bc4SJason Schmidlapp * Lesser General Public License for more details. 36*062c5bc4SJason Schmidlapp * 37*062c5bc4SJason Schmidlapp * You should have received a copy of the GNU Lesser General Public 38*062c5bc4SJason Schmidlapp * License along with this library in the file COPYING.LIB; 39*062c5bc4SJason Schmidlapp * if not, write to the Free Software Foundation, Inc., 40*062c5bc4SJason Schmidlapp * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 41*062c5bc4SJason Schmidlapp */ 42*062c5bc4SJason Schmidlapp 43*062c5bc4SJason Schmidlapp #include <errno.h> 44*062c5bc4SJason Schmidlapp #include <limits.h> 45*062c5bc4SJason Schmidlapp 46*062c5bc4SJason Schmidlapp #include "pthread.h" 47*062c5bc4SJason Schmidlapp #include "implement.h" 48*062c5bc4SJason Schmidlapp 49*062c5bc4SJason Schmidlapp int pthread_rwlock_rdlock(pthread_rwlock_t * rwlock)50*062c5bc4SJason Schmidlapppthread_rwlock_rdlock (pthread_rwlock_t * rwlock) 51*062c5bc4SJason Schmidlapp { 52*062c5bc4SJason Schmidlapp int result; 53*062c5bc4SJason Schmidlapp pthread_rwlock_t rwl; 54*062c5bc4SJason Schmidlapp 55*062c5bc4SJason Schmidlapp if (rwlock == NULL || *rwlock == NULL) 56*062c5bc4SJason Schmidlapp { 57*062c5bc4SJason Schmidlapp return EINVAL; 58*062c5bc4SJason Schmidlapp } 59*062c5bc4SJason Schmidlapp 60*062c5bc4SJason Schmidlapp /* 61*062c5bc4SJason Schmidlapp * We do a quick check to see if we need to do more work 62*062c5bc4SJason Schmidlapp * to initialise a static rwlock. We check 63*062c5bc4SJason Schmidlapp * again inside the guarded section of pte_rwlock_check_need_init() 64*062c5bc4SJason Schmidlapp * to avoid race conditions. 65*062c5bc4SJason Schmidlapp */ 66*062c5bc4SJason Schmidlapp if (*rwlock == PTHREAD_RWLOCK_INITIALIZER) 67*062c5bc4SJason Schmidlapp { 68*062c5bc4SJason Schmidlapp result = pte_rwlock_check_need_init (rwlock); 69*062c5bc4SJason Schmidlapp 70*062c5bc4SJason Schmidlapp if (result != 0 && result != EBUSY) 71*062c5bc4SJason Schmidlapp { 72*062c5bc4SJason Schmidlapp return result; 73*062c5bc4SJason Schmidlapp } 74*062c5bc4SJason Schmidlapp } 75*062c5bc4SJason Schmidlapp 76*062c5bc4SJason Schmidlapp rwl = *rwlock; 77*062c5bc4SJason Schmidlapp 78*062c5bc4SJason Schmidlapp if (rwl->nMagic != PTE_RWLOCK_MAGIC) 79*062c5bc4SJason Schmidlapp { 80*062c5bc4SJason Schmidlapp return EINVAL; 81*062c5bc4SJason Schmidlapp } 82*062c5bc4SJason Schmidlapp 83*062c5bc4SJason Schmidlapp if ((result = pthread_mutex_lock (&(rwl->mtxExclusiveAccess))) != 0) 84*062c5bc4SJason Schmidlapp { 85*062c5bc4SJason Schmidlapp return result; 86*062c5bc4SJason Schmidlapp } 87*062c5bc4SJason Schmidlapp 88*062c5bc4SJason Schmidlapp if (++rwl->nSharedAccessCount == INT_MAX) 89*062c5bc4SJason Schmidlapp { 90*062c5bc4SJason Schmidlapp if ((result = 91*062c5bc4SJason Schmidlapp pthread_mutex_lock (&(rwl->mtxSharedAccessCompleted))) != 0) 92*062c5bc4SJason Schmidlapp { 93*062c5bc4SJason Schmidlapp (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess)); 94*062c5bc4SJason Schmidlapp return result; 95*062c5bc4SJason Schmidlapp } 96*062c5bc4SJason Schmidlapp 97*062c5bc4SJason Schmidlapp rwl->nSharedAccessCount -= rwl->nCompletedSharedAccessCount; 98*062c5bc4SJason Schmidlapp rwl->nCompletedSharedAccessCount = 0; 99*062c5bc4SJason Schmidlapp 100*062c5bc4SJason Schmidlapp if ((result = 101*062c5bc4SJason Schmidlapp pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted))) != 0) 102*062c5bc4SJason Schmidlapp { 103*062c5bc4SJason Schmidlapp (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess)); 104*062c5bc4SJason Schmidlapp return result; 105*062c5bc4SJason Schmidlapp } 106*062c5bc4SJason Schmidlapp } 107*062c5bc4SJason Schmidlapp 108*062c5bc4SJason Schmidlapp return (pthread_mutex_unlock (&(rwl->mtxExclusiveAccess))); 109*062c5bc4SJason Schmidlapp } 110