svn_mutex.h revision 299742
1/**
2 * @copyright
3 * ====================================================================
4 *    Licensed to the Apache Software Foundation (ASF) under one
5 *    or more contributor license agreements.  See the NOTICE file
6 *    distributed with this work for additional information
7 *    regarding copyright ownership.  The ASF licenses this file
8 *    to you under the Apache License, Version 2.0 (the
9 *    "License"); you may not use this file except in compliance
10 *    with the License.  You may obtain a copy of the License at
11 *
12 *      http://www.apache.org/licenses/LICENSE-2.0
13 *
14 *    Unless required by applicable law or agreed to in writing,
15 *    software distributed under the License is distributed on an
16 *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 *    KIND, either express or implied.  See the License for the
18 *    specific language governing permissions and limitations
19 *    under the License.
20 * ====================================================================
21 * @endcopyright
22 *
23 * @file svn_mutex.h
24 * @brief Structures and functions for mutual exclusion
25 */
26
27#ifndef SVN_MUTEX_H
28#define SVN_MUTEX_H
29
30#include <apr_thread_mutex.h>
31
32#include "svn_error.h"
33
34#ifdef __cplusplus
35extern "C" {
36#endif /* __cplusplus */
37
38/**
39 * This is a simple wrapper around @c apr_thread_mutex_t and will be a
40 * valid identifier even if APR does not support threading.
41 */
42
43/** A mutex for synchronization between threads. It may be NULL, in
44 * which case no synchronization will take place. The latter is useful
45 * when implementing some functionality with optional synchronization.
46 */
47typedef struct svn_mutex__t svn_mutex__t;
48
49/** Initialize the @a *mutex. If @a mutex_required is TRUE, the mutex will
50 * actually be created with a lifetime defined by @a result_pool. Otherwise,
51 * the pointer will be set to @c NULL and svn_mutex__lock() as well as
52 * svn_mutex__unlock() will be no-ops.
53 *
54 * We don't support recursive locks, i.e. a thread may not acquire the same
55 * mutex twice without releasing it in between.  Attempts to lock a mutex
56 * recursively will cause lock ups and other undefined behavior on some
57 * systems.
58 *
59 * If threading is not supported by APR, this function is a no-op.
60 */
61svn_error_t *
62svn_mutex__init(svn_mutex__t **mutex,
63                svn_boolean_t mutex_required,
64                apr_pool_t *result_pool);
65
66/** Acquire the @a mutex, if that has been enabled in svn_mutex__init().
67 * Make sure to call svn_mutex__unlock() some time later in the same
68 * thread to release the mutex again. Recursive locking are not supported.
69 *
70 * @note You should use #SVN_MUTEX__WITH_LOCK instead of explicit lock
71 * acquisition and release.
72 */
73svn_error_t *
74svn_mutex__lock(svn_mutex__t *mutex);
75
76/** Release the @a mutex, previously acquired using svn_mutex__lock()
77 * that has been enabled in svn_mutex__init().
78 *
79 * Since this is often used as part of the calling function's exit
80 * sequence, we accept that function's current return code in @a err.
81 * If it is not #SVN_NO_ERROR, it will be used as the return value -
82 * irrespective of the possible internal failures during unlock. If @a err
83 * is #SVN_NO_ERROR, internal failures of this function will be
84 * reported in the return value.
85 *
86 * @note You should use #SVN_MUTEX__WITH_LOCK instead of explicit lock
87 * acquisition and release.
88 */
89svn_error_t *
90svn_mutex__unlock(svn_mutex__t *mutex,
91                  svn_error_t *err);
92
93/** Acquires the @a mutex, executes the expression @a expr and finally
94 * releases the @a mutex. If any of these steps fail, the function using
95 * this macro will return an #svn_error_t. This macro guarantees that
96 * the @a mutex will always be unlocked again if it got locked successfully
97 * by the first step.
98 *
99 * @note Prefer using this macro instead of explicit lock acquisition and
100 * release.
101 */
102#define SVN_MUTEX__WITH_LOCK(mutex, expr)               \
103do {                                                    \
104  svn_mutex__t *svn_mutex__m = (mutex);                 \
105  SVN_ERR(svn_mutex__lock(svn_mutex__m));               \
106  SVN_ERR(svn_mutex__unlock(svn_mutex__m, (expr)));     \
107} while (0)
108
109#ifdef __cplusplus
110}
111#endif /* __cplusplus */
112
113#endif /* SVN_MUTEX_H */
114