1/* Licensed to the Apache Software Foundation (ASF) under one or more 2 * contributor license agreements. See the NOTICE file distributed with 3 * this work for additional information regarding copyright ownership. 4 * The ASF licenses this file to You under the Apache License, Version 2.0 5 * (the "License"); you may not use this file except in compliance with 6 * the License. You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "apr_arch_thread_rwlock.h" 18#include "apr_private.h" 19 20#if APR_HAS_THREADS 21 22#ifdef HAVE_PTHREAD_RWLOCKS 23 24/* The rwlock must be initialized but not locked by any thread when 25 * cleanup is called. */ 26static apr_status_t thread_rwlock_cleanup(void *data) 27{ 28 apr_thread_rwlock_t *rwlock = (apr_thread_rwlock_t *)data; 29 apr_status_t stat; 30 31 stat = pthread_rwlock_destroy(&rwlock->rwlock); 32#ifdef HAVE_ZOS_PTHREADS 33 if (stat) { 34 stat = errno; 35 } 36#endif 37 return stat; 38} 39 40APR_DECLARE(apr_status_t) apr_thread_rwlock_create(apr_thread_rwlock_t **rwlock, 41 apr_pool_t *pool) 42{ 43 apr_thread_rwlock_t *new_rwlock; 44 apr_status_t stat; 45 46 new_rwlock = apr_palloc(pool, sizeof(apr_thread_rwlock_t)); 47 new_rwlock->pool = pool; 48 49 if ((stat = pthread_rwlock_init(&new_rwlock->rwlock, NULL))) { 50#ifdef HAVE_ZOS_PTHREADS 51 stat = errno; 52#endif 53 return stat; 54 } 55 56 apr_pool_cleanup_register(new_rwlock->pool, 57 (void *)new_rwlock, thread_rwlock_cleanup, 58 apr_pool_cleanup_null); 59 60 *rwlock = new_rwlock; 61 return APR_SUCCESS; 62} 63 64APR_DECLARE(apr_status_t) apr_thread_rwlock_rdlock(apr_thread_rwlock_t *rwlock) 65{ 66 apr_status_t stat; 67 68 stat = pthread_rwlock_rdlock(&rwlock->rwlock); 69#ifdef HAVE_ZOS_PTHREADS 70 if (stat) { 71 stat = errno; 72 } 73#endif 74 return stat; 75} 76 77APR_DECLARE(apr_status_t) apr_thread_rwlock_tryrdlock(apr_thread_rwlock_t *rwlock) 78{ 79 apr_status_t stat; 80 81 stat = pthread_rwlock_tryrdlock(&rwlock->rwlock); 82#ifdef HAVE_ZOS_PTHREADS 83 if (stat) { 84 stat = errno; 85 } 86#endif 87 /* Normalize the return code. */ 88 if (stat == EBUSY) 89 stat = APR_EBUSY; 90 return stat; 91} 92 93APR_DECLARE(apr_status_t) apr_thread_rwlock_wrlock(apr_thread_rwlock_t *rwlock) 94{ 95 apr_status_t stat; 96 97 stat = pthread_rwlock_wrlock(&rwlock->rwlock); 98#ifdef HAVE_ZOS_PTHREADS 99 if (stat) { 100 stat = errno; 101 } 102#endif 103 return stat; 104} 105 106APR_DECLARE(apr_status_t) apr_thread_rwlock_trywrlock(apr_thread_rwlock_t *rwlock) 107{ 108 apr_status_t stat; 109 110 stat = pthread_rwlock_trywrlock(&rwlock->rwlock); 111#ifdef HAVE_ZOS_PTHREADS 112 if (stat) { 113 stat = errno; 114 } 115#endif 116 /* Normalize the return code. */ 117 if (stat == EBUSY) 118 stat = APR_EBUSY; 119 return stat; 120} 121 122APR_DECLARE(apr_status_t) apr_thread_rwlock_unlock(apr_thread_rwlock_t *rwlock) 123{ 124 apr_status_t stat; 125 126 stat = pthread_rwlock_unlock(&rwlock->rwlock); 127#ifdef HAVE_ZOS_PTHREADS 128 if (stat) { 129 stat = errno; 130 } 131#endif 132 return stat; 133} 134 135APR_DECLARE(apr_status_t) apr_thread_rwlock_destroy(apr_thread_rwlock_t *rwlock) 136{ 137 return apr_pool_cleanup_run(rwlock->pool, rwlock, thread_rwlock_cleanup); 138} 139 140#else /* HAVE_PTHREAD_RWLOCKS */ 141 142APR_DECLARE(apr_status_t) apr_thread_rwlock_create(apr_thread_rwlock_t **rwlock, 143 apr_pool_t *pool) 144{ 145 return APR_ENOTIMPL; 146} 147 148APR_DECLARE(apr_status_t) apr_thread_rwlock_rdlock(apr_thread_rwlock_t *rwlock) 149{ 150 return APR_ENOTIMPL; 151} 152 153APR_DECLARE(apr_status_t) apr_thread_rwlock_tryrdlock(apr_thread_rwlock_t *rwlock) 154{ 155 return APR_ENOTIMPL; 156} 157 158APR_DECLARE(apr_status_t) apr_thread_rwlock_wrlock(apr_thread_rwlock_t *rwlock) 159{ 160 return APR_ENOTIMPL; 161} 162 163APR_DECLARE(apr_status_t) apr_thread_rwlock_trywrlock(apr_thread_rwlock_t *rwlock) 164{ 165 return APR_ENOTIMPL; 166} 167 168APR_DECLARE(apr_status_t) apr_thread_rwlock_unlock(apr_thread_rwlock_t *rwlock) 169{ 170 return APR_ENOTIMPL; 171} 172 173APR_DECLARE(apr_status_t) apr_thread_rwlock_destroy(apr_thread_rwlock_t *rwlock) 174{ 175 return APR_ENOTIMPL; 176} 177 178#endif /* HAVE_PTHREAD_RWLOCKS */ 179APR_POOL_IMPLEMENT_ACCESSOR(thread_rwlock) 180 181#endif /* APR_HAS_THREADS */ 182