1251876Speter/* Licensed to the Apache Software Foundation (ASF) under one or more
2251876Speter * contributor license agreements.  See the NOTICE file distributed with
3251876Speter * this work for additional information regarding copyright ownership.
4251876Speter * The ASF licenses this file to You under the Apache License, Version 2.0
5251876Speter * (the "License"); you may not use this file except in compliance with
6251876Speter * the License.  You may obtain a copy of the License at
7251876Speter *
8251876Speter *     http://www.apache.org/licenses/LICENSE-2.0
9251876Speter *
10251876Speter * Unless required by applicable law or agreed to in writing, software
11251876Speter * distributed under the License is distributed on an "AS IS" BASIS,
12251876Speter * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13251876Speter * See the License for the specific language governing permissions and
14251876Speter * limitations under the License.
15251876Speter */
16251876Speter
17251876Speter/**
18251876Speter * @file apr_anylock.h
19251876Speter * @brief APR-Util transparent any lock flavor wrapper
20251876Speter */
21251876Speter#ifndef APR_ANYLOCK_H
22251876Speter#define APR_ANYLOCK_H
23251876Speter
24251876Speter#include "apr_proc_mutex.h"
25251876Speter#include "apr_thread_mutex.h"
26251876Speter#include "apr_thread_rwlock.h"
27251876Speter
28251876Speter/** Structure that may contain any APR lock type */
29251876Spetertypedef struct apr_anylock_t {
30251876Speter    /** Indicates what type of lock is in lock */
31251876Speter    enum tm_lock {
32251876Speter        apr_anylock_none,           /**< None */
33251876Speter        apr_anylock_procmutex,      /**< Process-based */
34251876Speter        apr_anylock_threadmutex,    /**< Thread-based */
35251876Speter        apr_anylock_readlock,       /**< Read lock */
36251876Speter        apr_anylock_writelock       /**< Write lock */
37251876Speter    } type;
38251876Speter    /** Union of all possible APR locks */
39251876Speter    union apr_anylock_u_t {
40251876Speter        apr_proc_mutex_t *pm;       /**< Process mutex */
41251876Speter#if APR_HAS_THREADS
42251876Speter        apr_thread_mutex_t *tm;     /**< Thread mutex */
43251876Speter        apr_thread_rwlock_t *rw;    /**< Read-write lock */
44251876Speter#endif
45251876Speter    } lock;
46251876Speter} apr_anylock_t;
47251876Speter
48251876Speter#if APR_HAS_THREADS
49251876Speter
50251876Speter/** Lock an apr_anylock_t structure */
51251876Speter#define APR_ANYLOCK_LOCK(lck)                \
52251876Speter    (((lck)->type == apr_anylock_none)         \
53251876Speter      ? APR_SUCCESS                              \
54251876Speter      : (((lck)->type == apr_anylock_threadmutex)  \
55251876Speter          ? apr_thread_mutex_lock((lck)->lock.tm)    \
56251876Speter          : (((lck)->type == apr_anylock_procmutex)    \
57251876Speter              ? apr_proc_mutex_lock((lck)->lock.pm)      \
58251876Speter              : (((lck)->type == apr_anylock_readlock)     \
59251876Speter                  ? apr_thread_rwlock_rdlock((lck)->lock.rw) \
60251876Speter                  : (((lck)->type == apr_anylock_writelock)    \
61251876Speter                      ? apr_thread_rwlock_wrlock((lck)->lock.rw) \
62251876Speter                      : APR_EINVAL)))))
63251876Speter
64251876Speter#else /* APR_HAS_THREADS */
65251876Speter
66251876Speter#define APR_ANYLOCK_LOCK(lck)                \
67251876Speter    (((lck)->type == apr_anylock_none)         \
68251876Speter      ? APR_SUCCESS                              \
69251876Speter          : (((lck)->type == apr_anylock_procmutex)    \
70251876Speter              ? apr_proc_mutex_lock((lck)->lock.pm)      \
71251876Speter                      : APR_EINVAL))
72251876Speter
73251876Speter#endif /* APR_HAS_THREADS */
74251876Speter
75251876Speter#if APR_HAS_THREADS
76251876Speter
77251876Speter/** Try to lock an apr_anylock_t structure */
78251876Speter#define APR_ANYLOCK_TRYLOCK(lck)                \
79251876Speter    (((lck)->type == apr_anylock_none)            \
80251876Speter      ? APR_SUCCESS                                 \
81251876Speter      : (((lck)->type == apr_anylock_threadmutex)     \
82251876Speter          ? apr_thread_mutex_trylock((lck)->lock.tm)    \
83251876Speter          : (((lck)->type == apr_anylock_procmutex)       \
84251876Speter              ? apr_proc_mutex_trylock((lck)->lock.pm)      \
85251876Speter              : (((lck)->type == apr_anylock_readlock)        \
86251876Speter                  ? apr_thread_rwlock_tryrdlock((lck)->lock.rw) \
87251876Speter                  : (((lck)->type == apr_anylock_writelock)       \
88251876Speter                      ? apr_thread_rwlock_trywrlock((lck)->lock.rw) \
89251876Speter                          : APR_EINVAL)))))
90251876Speter
91251876Speter#else /* APR_HAS_THREADS */
92251876Speter
93251876Speter#define APR_ANYLOCK_TRYLOCK(lck)                \
94251876Speter    (((lck)->type == apr_anylock_none)            \
95251876Speter      ? APR_SUCCESS                                 \
96251876Speter          : (((lck)->type == apr_anylock_procmutex)       \
97251876Speter              ? apr_proc_mutex_trylock((lck)->lock.pm)      \
98251876Speter                          : APR_EINVAL))
99251876Speter
100251876Speter#endif /* APR_HAS_THREADS */
101251876Speter
102251876Speter#if APR_HAS_THREADS
103251876Speter
104251876Speter/** Unlock an apr_anylock_t structure */
105251876Speter#define APR_ANYLOCK_UNLOCK(lck)              \
106251876Speter    (((lck)->type == apr_anylock_none)         \
107251876Speter      ? APR_SUCCESS                              \
108251876Speter      : (((lck)->type == apr_anylock_threadmutex)  \
109251876Speter          ? apr_thread_mutex_unlock((lck)->lock.tm)  \
110251876Speter          : (((lck)->type == apr_anylock_procmutex)    \
111251876Speter              ? apr_proc_mutex_unlock((lck)->lock.pm)    \
112251876Speter              : ((((lck)->type == apr_anylock_readlock) || \
113251876Speter                  ((lck)->type == apr_anylock_writelock))    \
114251876Speter                  ? apr_thread_rwlock_unlock((lck)->lock.rw)   \
115251876Speter                      : APR_EINVAL))))
116251876Speter
117251876Speter#else /* APR_HAS_THREADS */
118251876Speter
119251876Speter#define APR_ANYLOCK_UNLOCK(lck)              \
120251876Speter    (((lck)->type == apr_anylock_none)         \
121251876Speter      ? APR_SUCCESS                              \
122251876Speter          : (((lck)->type == apr_anylock_procmutex)    \
123251876Speter              ? apr_proc_mutex_unlock((lck)->lock.pm)    \
124251876Speter                      : APR_EINVAL))
125251876Speter
126251876Speter#endif /* APR_HAS_THREADS */
127251876Speter
128251876Speter#endif /* !APR_ANYLOCK_H */
129