Tor  0.4.6.0-alpha-dev
compat_mutex_winthreads.c
Go to the documentation of this file.
1 /* Copyright (c) 2003-2004, Roger Dingledine
2  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3  * Copyright (c) 2007-2020, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
5 
6 /**
7  * \file compat_mutex_winthreads.c
8  *
9  * \brief Implement the tor_mutex API using CRITICAL_SECTION.
10  **/
11 
12 #include "orconfig.h"
13 
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
27 
28 #include <windows.h>
29 #include "lib/lock/compat_mutex.h"
30 #include "lib/err/torerr.h"
31 
32 void
34 {
35 }
36 
37 void
39 {
40  m->type = RECURSIVE;
41  m->lock_owner = 0;
42  m->lock_count = 0;
43  InitializeSRWLock(&m->mutex);
44 }
45 void
47 {
48  m->type = NON_RECURSIVE;
49  InitializeSRWLock(&m->mutex);
50 }
51 
52 void
54 {
55  (void) m;
56 }
57 
58 static void
59 tor_mutex_acquire_recursive(tor_mutex_t *m)
60 {
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;
67  }
68  AcquireSRWLockExclusive(&m->mutex);
69  InterlockedExchange(&m->lock_owner, thread_id);
70  m->lock_count = 1;
71 }
72 
73 static void
74 tor_mutex_acquire_nonrecursive(tor_mutex_t *m)
75 {
76  AcquireSRWLockExclusive(&m->mutex);
77 }
78 
79 void
81 {
82  raw_assert(m);
83  if (m->type == NON_RECURSIVE) {
84  tor_mutex_acquire_nonrecursive(m);
85  } else {
86  tor_mutex_acquire_recursive(m);
87  }
88 }
89 
90 static void
91 tor_mutex_release_recursive(tor_mutex_t *m)
92 {
93  if (--m->lock_count) {
94  return;
95  }
96  InterlockedExchange(&m->lock_owner, 0);
97  ReleaseSRWLockExclusive(&m->mutex);
98 }
99 
100 static void
101 tor_mutex_release_nonrecursive(tor_mutex_t *m)
102 {
103  ReleaseSRWLockExclusive(&m->mutex);
104 }
105 
106 void
108 {
109  if (m->type == NON_RECURSIVE) {
110  tor_mutex_release_nonrecursive(m);
111  } else {
112  tor_mutex_release_recursive(m);
113  }
114 }
tor_locking_init
void tor_locking_init(void)
Definition: compat_mutex_winthreads.c:33
tor_mutex_uninit
void tor_mutex_uninit(tor_mutex_t *m)
Definition: compat_mutex_winthreads.c:53
tor_mutex_t
Definition: compat_mutex.h:40
tor_mutex_acquire
void tor_mutex_acquire(tor_mutex_t *m)
Definition: compat_mutex_winthreads.c:80
tor_mutex_init_nonrecursive
void tor_mutex_init_nonrecursive(tor_mutex_t *m)
Definition: compat_mutex_winthreads.c:46
compat_mutex.h
Header for compat_mutex.c.
tor_mutex_init
void tor_mutex_init(tor_mutex_t *m)
Definition: compat_mutex_winthreads.c:38
torerr.h
Headers for torerr.c.
tor_mutex_release
void tor_mutex_release(tor_mutex_t *m)
Definition: compat_mutex_winthreads.c:107