1/* 2 * svn_mutex.c: routines for mutual exclusion. 3 * 4 * ==================================================================== 5 * Licensed to the Apache Software Foundation (ASF) under one 6 * or more contributor license agreements. See the NOTICE file 7 * distributed with this work for additional information 8 * regarding copyright ownership. The ASF licenses this file 9 * to you under the Apache License, Version 2.0 (the 10 * "License"); you may not use this file except in compliance 11 * with the License. You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, 16 * software distributed under the License is distributed on an 17 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 18 * KIND, either express or implied. See the License for the 19 * specific language governing permissions and limitations 20 * under the License. 21 * ==================================================================== 22 */ 23 24#include <apr_portable.h> 25 26#include "svn_private_config.h" 27#include "private/svn_atomic.h" 28#include "private/svn_mutex.h" 29 30/* With CHECKED set to TRUE, LOCKED and OWNER must be set *after* acquiring 31 * the MUTEX and be reset *before* releasing it again. This is sufficient 32 * because we only want to check whether the current thread already holds 33 * the lock. And the current thread cannot be acquiring / releasing a lock 34 * *while* checking for recursion at the same time. 35 */ 36struct svn_mutex__t 37{ 38#if APR_HAS_THREADS 39 40 apr_thread_mutex_t *mutex; 41 42#else 43 44 /* Truly empty structs are not allowed. */ 45 int dummy; 46 47#endif 48}; 49 50svn_error_t * 51svn_mutex__init(svn_mutex__t **mutex_p, 52 svn_boolean_t mutex_required, 53 apr_pool_t *result_pool) 54{ 55 /* always initialize the mutex pointer, even though it is not 56 strictly necessary if APR_HAS_THREADS has not been set */ 57 *mutex_p = NULL; 58 59 if (mutex_required) 60 { 61 svn_mutex__t *mutex = apr_pcalloc(result_pool, sizeof(*mutex)); 62 63#if APR_HAS_THREADS 64 apr_status_t status = 65 apr_thread_mutex_create(&mutex->mutex, 66 APR_THREAD_MUTEX_DEFAULT, 67 result_pool); 68 if (status) 69 return svn_error_wrap_apr(status, _("Can't create mutex")); 70#endif 71 72 *mutex_p = mutex; 73 } 74 75 return SVN_NO_ERROR; 76} 77 78svn_error_t * 79svn_mutex__lock(svn_mutex__t *mutex) 80{ 81 if (mutex) 82 { 83#if APR_HAS_THREADS 84 apr_status_t status = apr_thread_mutex_lock(mutex->mutex); 85 if (status) 86 return svn_error_wrap_apr(status, _("Can't lock mutex")); 87#endif 88 } 89 90 return SVN_NO_ERROR; 91} 92 93svn_error_t * 94svn_mutex__unlock(svn_mutex__t *mutex, 95 svn_error_t *err) 96{ 97 if (mutex) 98 { 99#if APR_HAS_THREADS 100 apr_status_t status = apr_thread_mutex_unlock(mutex->mutex); 101 if (status && !err) 102 return svn_error_wrap_apr(status, _("Can't unlock mutex")); 103#endif 104 } 105 106 return err; 107} 108 109#if APR_HAS_THREADS 110 111apr_thread_mutex_t * 112svn_mutex__get(svn_mutex__t *mutex) 113{ 114 return mutex->mutex; 115} 116 117#endif 118