Update copyrights to 2021, using "make update-copyright"
[tor.git] / src / lib / lock / compat_mutex_winthreads.c
blob8a101e0d259708a2dd41911b130fd22c9a4c35b5
1 /* Copyright (c) 2003-2004, Roger Dingledine
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2021, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
6 /**
7 * \file compat_mutex_winthreads.c
9 * \brief Implement the tor_mutex API using CRITICAL_SECTION.
10 **/
12 #include "orconfig.h"
14 /* For SRW locks support */
15 #ifndef WINVER
16 #error "orconfig.h didn't define WINVER"
17 #endif
18 #ifndef _WIN32_WINNT
19 #error "orconfig.h didn't define _WIN32_WINNT"
20 #endif
21 #if WINVER < 0x0600
22 #error "winver too low"
23 #endif
24 #if _WIN32_WINNT < 0x0600
25 #error "winver too low"
26 #endif
28 #include <windows.h>
29 #include "lib/lock/compat_mutex.h"
30 #include "lib/err/torerr.h"
32 void
33 tor_locking_init(void)
37 void
38 tor_mutex_init(tor_mutex_t *m)
40 m->type = RECURSIVE;
41 m->lock_owner = 0;
42 m->lock_count = 0;
43 InitializeSRWLock(&m->mutex);
45 void
46 tor_mutex_init_nonrecursive(tor_mutex_t *m)
48 m->type = NON_RECURSIVE;
49 InitializeSRWLock(&m->mutex);
52 void
53 tor_mutex_uninit(tor_mutex_t *m)
55 (void) m;
58 static void
59 tor_mutex_acquire_recursive(tor_mutex_t *m)
61 LONG thread_id = GetCurrentThreadId();
62 // use InterlockedCompareExchange to perform an atomic read
63 LONG lock_owner = InterlockedCompareExchange(&m->lock_owner, 0, 0);
64 if (thread_id == lock_owner) {
65 ++m->lock_count;
66 return;
68 AcquireSRWLockExclusive(&m->mutex);
69 InterlockedExchange(&m->lock_owner, thread_id);
70 m->lock_count = 1;
73 static void
74 tor_mutex_acquire_nonrecursive(tor_mutex_t *m)
76 AcquireSRWLockExclusive(&m->mutex);
79 void
80 tor_mutex_acquire(tor_mutex_t *m)
82 raw_assert(m);
83 if (m->type == NON_RECURSIVE) {
84 tor_mutex_acquire_nonrecursive(m);
85 } else {
86 tor_mutex_acquire_recursive(m);
90 static void
91 tor_mutex_release_recursive(tor_mutex_t *m)
93 if (--m->lock_count) {
94 return;
96 InterlockedExchange(&m->lock_owner, 0);
97 ReleaseSRWLockExclusive(&m->mutex);
100 static void
101 tor_mutex_release_nonrecursive(tor_mutex_t *m)
103 ReleaseSRWLockExclusive(&m->mutex);
106 void
107 tor_mutex_release(tor_mutex_t *m)
109 if (m->type == NON_RECURSIVE) {
110 tor_mutex_release_nonrecursive(m);
111 } else {
112 tor_mutex_release_recursive(m);