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 "svn_error.h" 31 32#ifdef __cplusplus 33extern "C" { 34#endif /* __cplusplus */ 35 36/** 37 * This is a simple wrapper around @c apr_thread_mutex_t and will be a 38 * valid identifier even if APR does not support threading. 39 */ 40 41/** A mutex for synchronization between threads. It may be NULL, in 42 * which case no synchronization will take place. The latter is useful 43 * when implementing some functionality with optional synchronization. 44 */ 45typedef struct svn_mutex__t svn_mutex__t; 46 47/** Initialize the @a *mutex. If @a mutex_required is TRUE, the mutex will 48 * actually be created with a lifetime defined by @a result_pool. Otherwise, 49 * the pointer will be set to @c NULL and svn_mutex__lock() as well as 50 * svn_mutex__unlock() will be no-ops. 51 * 52 * We don't support recursive locks, i.e. a thread may not acquire the same 53 * mutex twice without releasing it in between. Attempts to lock a mutex 54 * recursively will cause lock ups and other undefined behavior on some 55 * systems. 56 * 57 * If threading is not supported by APR, this function is a no-op. 58 */ 59svn_error_t * 60svn_mutex__init(svn_mutex__t **mutex, 61 svn_boolean_t mutex_required, 62 apr_pool_t *result_pool); 63 64/** Acquire the @a mutex, if that has been enabled in svn_mutex__init(). 65 * Make sure to call svn_mutex__unlock() some time later in the same 66 * thread to release the mutex again. Recursive locking are not supported. 67 * 68 * @note You should use #SVN_MUTEX__WITH_LOCK instead of explicit lock 69 * acquisition and release. 70 */ 71svn_error_t * 72svn_mutex__lock(svn_mutex__t *mutex); 73 74/** Release the @a mutex, previously acquired using svn_mutex__lock() 75 * that has been enabled in svn_mutex__init(). 76 * 77 * Since this is often used as part of the calling function's exit 78 * sequence, we accept that function's current return code in @a err. 79 * If it is not #SVN_NO_ERROR, it will be used as the return value - 80 * irrespective of the possible internal failures during unlock. If @a err 81 * is #SVN_NO_ERROR, internal failures of this function will be 82 * reported in the return value. 83 * 84 * @note You should use #SVN_MUTEX__WITH_LOCK instead of explicit lock 85 * acquisition and release. 86 */ 87svn_error_t * 88svn_mutex__unlock(svn_mutex__t *mutex, 89 svn_error_t *err); 90 91/** Acquires the @a mutex, executes the expression @a expr and finally 92 * releases the @a mutex. If any of these steps fail, the function using 93 * this macro will return an #svn_error_t. This macro guarantees that 94 * the @a mutex will always be unlocked again if it got locked successfully 95 * by the first step. 96 * 97 * @note Prefer using this macro instead of explicit lock acquisition and 98 * release. 99 */ 100#define SVN_MUTEX__WITH_LOCK(mutex, expr) \ 101do { \ 102 svn_mutex__t *svn_mutex__m = (mutex); \ 103 SVN_ERR(svn_mutex__lock(svn_mutex__m)); \ 104 SVN_ERR(svn_mutex__unlock(svn_mutex__m, (expr))); \ 105} while (0) 106 107#if APR_HAS_THREADS 108 109/** Return the APR mutex encapsulated in @a mutex. 110 * 111 * @note This function should only be called by APR wrapper code. 112 */ 113apr_thread_mutex_t * 114svn_mutex__get(svn_mutex__t *mutex); 115 116#endif 117 118#ifdef __cplusplus 119} 120#endif /* __cplusplus */ 121 122#endif /* SVN_MUTEX_H */ 123