compat_mutex_winthreads.c (2187B)
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 */ 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 33 tor_locking_init(void) 34 { 35 } 36 37 void 38 tor_mutex_init(tor_mutex_t *m) 39 { 40 m->type = RECURSIVE; 41 m->lock_owner = 0; 42 m->lock_count = 0; 43 InitializeSRWLock(&m->mutex); 44 } 45 void 46 tor_mutex_init_nonrecursive(tor_mutex_t *m) 47 { 48 m->type = NON_RECURSIVE; 49 InitializeSRWLock(&m->mutex); 50 } 51 52 void 53 tor_mutex_uninit(tor_mutex_t *m) 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 80 tor_mutex_acquire(tor_mutex_t *m) 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 107 tor_mutex_release(tor_mutex_t *m) 108 { 109 if (m->type == NON_RECURSIVE) { 110 tor_mutex_release_nonrecursive(m); 111 } else { 112 tor_mutex_release_recursive(m); 113 } 114 }