1 /* 2 * pthread_rwlock_timedrdlock.c 3 * 4 * Description: 5 * This translation unit implements read/write lock primitives. 6 * 7 * -------------------------------------------------------------------------- 8 * 9 * Pthreads4w - POSIX Threads for Windows 10 * Copyright 1998 John E. Bossom 11 * Copyright 1999-2018, Pthreads4w contributors 12 * 13 * Homepage: https://sourceforge.net/projects/pthreads4w/ 14 * 15 * The current list of contributors is contained 16 * in the file CONTRIBUTORS included with the source 17 * code distribution. The list can also be seen at the 18 * following World Wide Web location: 19 * 20 * https://sourceforge.net/p/pthreads4w/wiki/Contributors/ 21 * 22 * Licensed under the Apache License, Version 2.0 (the "License"); 23 * you may not use this file except in compliance with the License. 24 * You may obtain a copy of the License at 25 * 26 * http://www.apache.org/licenses/LICENSE-2.0 27 * 28 * Unless required by applicable law or agreed to in writing, software 29 * distributed under the License is distributed on an "AS IS" BASIS, 30 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 31 * See the License for the specific language governing permissions and 32 * limitations under the License. 33 */ 34 35 #ifdef HAVE_CONFIG_H 36 # include <config.h> 37 #endif 38 39 #include <limits.h> 40 41 #include "pthread.h" 42 #include "implement.h" 43 44 int pthread_rwlock_timedrdlock(pthread_rwlock_t * rwlock,const struct timespec * abstime)45pthread_rwlock_timedrdlock (pthread_rwlock_t * rwlock, 46 const struct timespec *abstime) 47 { 48 int result; 49 pthread_rwlock_t rwl; 50 51 if (rwlock == NULL || *rwlock == NULL) 52 { 53 return EINVAL; 54 } 55 56 /* 57 * We do a quick check to see if we need to do more work 58 * to initialise a static rwlock. We check 59 * again inside the guarded section of __ptw32_rwlock_check_need_init() 60 * to avoid race conditions. 61 */ 62 if (*rwlock == PTHREAD_RWLOCK_INITIALIZER) 63 { 64 result = __ptw32_rwlock_check_need_init (rwlock); 65 66 if (result != 0 && result != EBUSY) 67 { 68 return result; 69 } 70 } 71 72 rwl = *rwlock; 73 74 if (rwl->nMagic != __PTW32_RWLOCK_MAGIC) 75 { 76 return EINVAL; 77 } 78 79 if ((result = 80 pthread_mutex_timedlock (&(rwl->mtxExclusiveAccess), abstime)) != 0) 81 { 82 return result; 83 } 84 85 if (++rwl->nSharedAccessCount == INT_MAX) 86 { 87 if ((result = 88 pthread_mutex_timedlock (&(rwl->mtxSharedAccessCompleted), 89 abstime)) != 0) 90 { 91 if (result == ETIMEDOUT) 92 { 93 ++rwl->nCompletedSharedAccessCount; 94 } 95 (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess)); 96 return result; 97 } 98 99 rwl->nSharedAccessCount -= rwl->nCompletedSharedAccessCount; 100 rwl->nCompletedSharedAccessCount = 0; 101 102 if ((result = 103 pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted))) != 0) 104 { 105 (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess)); 106 return result; 107 } 108 } 109 110 return (pthread_mutex_unlock (&(rwl->mtxExclusiveAccess))); 111 } 112