1251875Speter/* Licensed to the Apache Software Foundation (ASF) under one or more
2251875Speter * contributor license agreements.  See the NOTICE file distributed with
3251875Speter * this work for additional information regarding copyright ownership.
4251875Speter * The ASF licenses this file to You under the Apache License, Version 2.0
5251875Speter * (the "License"); you may not use this file except in compliance with
6251875Speter * the License.  You may obtain a copy of the License at
7251875Speter *
8251875Speter *     http://www.apache.org/licenses/LICENSE-2.0
9251875Speter *
10251875Speter * Unless required by applicable law or agreed to in writing, software
11251875Speter * distributed under the License is distributed on an "AS IS" BASIS,
12251875Speter * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13251875Speter * See the License for the specific language governing permissions and
14251875Speter * limitations under the License.
15251875Speter */
16251875Speter
17251875Speter#include "apr_arch_thread_rwlock.h"
18251875Speter#include "apr_private.h"
19251875Speter
20251875Speter#if APR_HAS_THREADS
21251875Speter
22251875Speter#ifdef HAVE_PTHREAD_RWLOCKS
23251875Speter
24251875Speter/* The rwlock must be initialized but not locked by any thread when
25251875Speter * cleanup is called. */
26251875Speterstatic apr_status_t thread_rwlock_cleanup(void *data)
27251875Speter{
28251875Speter    apr_thread_rwlock_t *rwlock = (apr_thread_rwlock_t *)data;
29251875Speter    apr_status_t stat;
30251875Speter
31251875Speter    stat = pthread_rwlock_destroy(&rwlock->rwlock);
32251875Speter#ifdef HAVE_ZOS_PTHREADS
33251875Speter    if (stat) {
34251875Speter        stat = errno;
35251875Speter    }
36251875Speter#endif
37251875Speter    return stat;
38251875Speter}
39251875Speter
40251875SpeterAPR_DECLARE(apr_status_t) apr_thread_rwlock_create(apr_thread_rwlock_t **rwlock,
41251875Speter                                                   apr_pool_t *pool)
42251875Speter{
43251875Speter    apr_thread_rwlock_t *new_rwlock;
44251875Speter    apr_status_t stat;
45251875Speter
46251875Speter    new_rwlock = apr_palloc(pool, sizeof(apr_thread_rwlock_t));
47251875Speter    new_rwlock->pool = pool;
48251875Speter
49251875Speter    if ((stat = pthread_rwlock_init(&new_rwlock->rwlock, NULL))) {
50251875Speter#ifdef HAVE_ZOS_PTHREADS
51251875Speter        stat = errno;
52251875Speter#endif
53251875Speter        return stat;
54251875Speter    }
55251875Speter
56251875Speter    apr_pool_cleanup_register(new_rwlock->pool,
57251875Speter                              (void *)new_rwlock, thread_rwlock_cleanup,
58251875Speter                              apr_pool_cleanup_null);
59251875Speter
60251875Speter    *rwlock = new_rwlock;
61251875Speter    return APR_SUCCESS;
62251875Speter}
63251875Speter
64251875SpeterAPR_DECLARE(apr_status_t) apr_thread_rwlock_rdlock(apr_thread_rwlock_t *rwlock)
65251875Speter{
66251875Speter    apr_status_t stat;
67251875Speter
68251875Speter    stat = pthread_rwlock_rdlock(&rwlock->rwlock);
69251875Speter#ifdef HAVE_ZOS_PTHREADS
70251875Speter    if (stat) {
71251875Speter        stat = errno;
72251875Speter    }
73251875Speter#endif
74251875Speter    return stat;
75251875Speter}
76251875Speter
77251875SpeterAPR_DECLARE(apr_status_t) apr_thread_rwlock_tryrdlock(apr_thread_rwlock_t *rwlock)
78251875Speter{
79251875Speter    apr_status_t stat;
80251875Speter
81251875Speter    stat = pthread_rwlock_tryrdlock(&rwlock->rwlock);
82251875Speter#ifdef HAVE_ZOS_PTHREADS
83251875Speter    if (stat) {
84251875Speter        stat = errno;
85251875Speter    }
86251875Speter#endif
87251875Speter    /* Normalize the return code. */
88251875Speter    if (stat == EBUSY)
89251875Speter        stat = APR_EBUSY;
90251875Speter    return stat;
91251875Speter}
92251875Speter
93251875SpeterAPR_DECLARE(apr_status_t) apr_thread_rwlock_wrlock(apr_thread_rwlock_t *rwlock)
94251875Speter{
95251875Speter    apr_status_t stat;
96251875Speter
97251875Speter    stat = pthread_rwlock_wrlock(&rwlock->rwlock);
98251875Speter#ifdef HAVE_ZOS_PTHREADS
99251875Speter    if (stat) {
100251875Speter        stat = errno;
101251875Speter    }
102251875Speter#endif
103251875Speter    return stat;
104251875Speter}
105251875Speter
106251875SpeterAPR_DECLARE(apr_status_t) apr_thread_rwlock_trywrlock(apr_thread_rwlock_t *rwlock)
107251875Speter{
108251875Speter    apr_status_t stat;
109251875Speter
110251875Speter    stat = pthread_rwlock_trywrlock(&rwlock->rwlock);
111251875Speter#ifdef HAVE_ZOS_PTHREADS
112251875Speter    if (stat) {
113251875Speter        stat = errno;
114251875Speter    }
115251875Speter#endif
116251875Speter    /* Normalize the return code. */
117251875Speter    if (stat == EBUSY)
118251875Speter        stat = APR_EBUSY;
119251875Speter    return stat;
120251875Speter}
121251875Speter
122251875SpeterAPR_DECLARE(apr_status_t) apr_thread_rwlock_unlock(apr_thread_rwlock_t *rwlock)
123251875Speter{
124251875Speter    apr_status_t stat;
125251875Speter
126251875Speter    stat = pthread_rwlock_unlock(&rwlock->rwlock);
127251875Speter#ifdef HAVE_ZOS_PTHREADS
128251875Speter    if (stat) {
129251875Speter        stat = errno;
130251875Speter    }
131251875Speter#endif
132251875Speter    return stat;
133251875Speter}
134251875Speter
135251875SpeterAPR_DECLARE(apr_status_t) apr_thread_rwlock_destroy(apr_thread_rwlock_t *rwlock)
136251875Speter{
137251875Speter    return apr_pool_cleanup_run(rwlock->pool, rwlock, thread_rwlock_cleanup);
138251875Speter}
139251875Speter
140251875Speter#else  /* HAVE_PTHREAD_RWLOCKS */
141251875Speter
142251875SpeterAPR_DECLARE(apr_status_t) apr_thread_rwlock_create(apr_thread_rwlock_t **rwlock,
143251875Speter                                                   apr_pool_t *pool)
144251875Speter{
145251875Speter    return APR_ENOTIMPL;
146251875Speter}
147251875Speter
148251875SpeterAPR_DECLARE(apr_status_t) apr_thread_rwlock_rdlock(apr_thread_rwlock_t *rwlock)
149251875Speter{
150251875Speter    return APR_ENOTIMPL;
151251875Speter}
152251875Speter
153251875SpeterAPR_DECLARE(apr_status_t) apr_thread_rwlock_tryrdlock(apr_thread_rwlock_t *rwlock)
154251875Speter{
155251875Speter    return APR_ENOTIMPL;
156251875Speter}
157251875Speter
158251875SpeterAPR_DECLARE(apr_status_t) apr_thread_rwlock_wrlock(apr_thread_rwlock_t *rwlock)
159251875Speter{
160251875Speter    return APR_ENOTIMPL;
161251875Speter}
162251875Speter
163251875SpeterAPR_DECLARE(apr_status_t) apr_thread_rwlock_trywrlock(apr_thread_rwlock_t *rwlock)
164251875Speter{
165251875Speter    return APR_ENOTIMPL;
166251875Speter}
167251875Speter
168251875SpeterAPR_DECLARE(apr_status_t) apr_thread_rwlock_unlock(apr_thread_rwlock_t *rwlock)
169251875Speter{
170251875Speter    return APR_ENOTIMPL;
171251875Speter}
172251875Speter
173251875SpeterAPR_DECLARE(apr_status_t) apr_thread_rwlock_destroy(apr_thread_rwlock_t *rwlock)
174251875Speter{
175251875Speter    return APR_ENOTIMPL;
176251875Speter}
177251875Speter
178251875Speter#endif /* HAVE_PTHREAD_RWLOCKS */
179251875SpeterAPR_POOL_IMPLEMENT_ACCESSOR(thread_rwlock)
180251875Speter
181251875Speter#endif /* APR_HAS_THREADS */
182