#include "orconfig.h"
#ifndef WINVER
#error "orconfig.h didn't define WINVER"
#endif
#ifndef _WIN32_WINNT
#error "orconfig.h didn't define _WIN32_WINNT"
#endif
#if WINVER < 0x0600
#error "winver too low"
#endif
#if _WIN32_WINNT < 0x0600
#error "winver too low"
#endif
#include <windows.h>
#include "lib/lock/compat_mutex.h"
#include "lib/err/torerr.h"
void
tor_locking_init(void)
{
}
void
tor_mutex_init(tor_mutex_t *m)
{
m->type = RECURSIVE;
m->lock_owner = 0;
m->lock_count = 0;
InitializeSRWLock(&m->mutex);
}
void
tor_mutex_init_nonrecursive(tor_mutex_t *m)
{
m->type = NON_RECURSIVE;
InitializeSRWLock(&m->mutex);
}
void
tor_mutex_uninit(tor_mutex_t *m)
{
(void) m;
}
static void
tor_mutex_acquire_recursive(tor_mutex_t *m)
{
LONG thread_id = GetCurrentThreadId();
LONG lock_owner = InterlockedCompareExchange(&m->lock_owner, 0, 0);
if (thread_id == lock_owner) {
++m->lock_count;
return;
}
AcquireSRWLockExclusive(&m->mutex);
InterlockedExchange(&m->lock_owner, thread_id);
m->lock_count = 1;
}
static void
tor_mutex_acquire_nonrecursive(tor_mutex_t *m)
{
AcquireSRWLockExclusive(&m->mutex);
}
void
tor_mutex_acquire(tor_mutex_t *m)
{
raw_assert(m);
if (m->type == NON_RECURSIVE) {
tor_mutex_acquire_nonrecursive(m);
} else {
tor_mutex_acquire_recursive(m);
}
}
static void
tor_mutex_release_recursive(tor_mutex_t *m)
{
if (--m->lock_count) {
return;
}
InterlockedExchange(&m->lock_owner, 0);
ReleaseSRWLockExclusive(&m->mutex);
}
static void
tor_mutex_release_nonrecursive(tor_mutex_t *m)
{
ReleaseSRWLockExclusive(&m->mutex);
}
void
tor_mutex_release(tor_mutex_t *m)
{
if (m->type == NON_RECURSIVE) {
tor_mutex_release_nonrecursive(m);
} else {
tor_mutex_release_recursive(m);
}
}