tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

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 }