]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/subversion/subversion/libsvn_subr/mutex.c
MFC r275385 (by bapt):
[FreeBSD/stable/10.git] / contrib / subversion / subversion / libsvn_subr / mutex.c
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  */
36 struct 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
50 svn_error_t *
51 svn_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
78 svn_error_t *
79 svn_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
93 svn_error_t *
94 svn_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 }