summaryrefslogtreecommitdiff
path: root/subversion/libsvn_subr/mutex.c
diff options
context:
space:
mode:
Diffstat (limited to 'subversion/libsvn_subr/mutex.c')
-rw-r--r--subversion/libsvn_subr/mutex.c46
1 files changed, 35 insertions, 11 deletions
diff --git a/subversion/libsvn_subr/mutex.c b/subversion/libsvn_subr/mutex.c
index 04988eb..3c348df 100644
--- a/subversion/libsvn_subr/mutex.c
+++ b/subversion/libsvn_subr/mutex.c
@@ -21,9 +21,32 @@
* ====================================================================
*/
+#include <apr_portable.h>
+
#include "svn_private_config.h"
+#include "private/svn_atomic.h"
#include "private/svn_mutex.h"
+/* With CHECKED set to TRUE, LOCKED and OWNER must be set *after* acquiring
+ * the MUTEX and be reset *before* releasing it again. This is sufficient
+ * because we only want to check whether the current thread already holds
+ * the lock. And the current thread cannot be acquiring / releasing a lock
+ * *while* checking for recursion at the same time.
+ */
+struct svn_mutex__t
+{
+#if APR_HAS_THREADS
+
+ apr_thread_mutex_t *mutex;
+
+#else
+
+ /* Truly empty structs are not allowed. */
+ int dummy;
+
+#endif
+};
+
svn_error_t *
svn_mutex__init(svn_mutex__t **mutex_p,
svn_boolean_t mutex_required,
@@ -33,20 +56,21 @@ svn_mutex__init(svn_mutex__t **mutex_p,
strictly necessary if APR_HAS_THREADS has not been set */
*mutex_p = NULL;
-#if APR_HAS_THREADS
if (mutex_required)
{
- apr_thread_mutex_t *apr_mutex;
+ svn_mutex__t *mutex = apr_pcalloc(result_pool, sizeof(*mutex));
+
+#if APR_HAS_THREADS
apr_status_t status =
- apr_thread_mutex_create(&apr_mutex,
+ apr_thread_mutex_create(&mutex->mutex,
APR_THREAD_MUTEX_DEFAULT,
result_pool);
if (status)
return svn_error_wrap_apr(status, _("Can't create mutex"));
+#endif
- *mutex_p = apr_mutex;
+ *mutex_p = mutex;
}
-#endif
return SVN_NO_ERROR;
}
@@ -54,14 +78,14 @@ svn_mutex__init(svn_mutex__t **mutex_p,
svn_error_t *
svn_mutex__lock(svn_mutex__t *mutex)
{
-#if APR_HAS_THREADS
if (mutex)
{
- apr_status_t status = apr_thread_mutex_lock(mutex);
+#if APR_HAS_THREADS
+ apr_status_t status = apr_thread_mutex_lock(mutex->mutex);
if (status)
return svn_error_wrap_apr(status, _("Can't lock mutex"));
- }
#endif
+ }
return SVN_NO_ERROR;
}
@@ -70,14 +94,14 @@ svn_error_t *
svn_mutex__unlock(svn_mutex__t *mutex,
svn_error_t *err)
{
-#if APR_HAS_THREADS
if (mutex)
{
- apr_status_t status = apr_thread_mutex_unlock(mutex);
+#if APR_HAS_THREADS
+ apr_status_t status = apr_thread_mutex_unlock(mutex->mutex);
if (status && !err)
return svn_error_wrap_apr(status, _("Can't unlock mutex"));
- }
#endif
+ }
return err;
}