Emu/source/common/mutex.h
2025-09-06 21:43:05 -05:00

84 lines
1.7 KiB
C++

// Copyright (C) 2007-2025 EQ2EMulator
// Licensed under GPL v3
#pragma once
#include <shared_mutex>
#include <mutex>
#include <string>
#include <map>
#include <cstdint>
#include <memory>
#include <chrono>
#define MUTEX_ATTRIBUTE_FAST 1
#define MUTEX_ATTRIBUTE_RECURSIVE 2
#define MUTEX_ATTRIBUTE_ERRORCHK 3
#define MUTEX_TIMEOUT_MILLISECONDS 10000
class CriticalSection
{
public:
CriticalSection(int attribute = MUTEX_ATTRIBUTE_FAST);
~CriticalSection() = default;
void lock();
void unlock();
bool trylock();
private:
std::unique_ptr<std::mutex> regular_mutex;
std::unique_ptr<std::recursive_mutex> recursive_mutex;
int mutex_type;
};
class Mutex
{
public:
Mutex();
~Mutex() = default;
void lock();
void unlock();
bool trylock();
void readlock(const char* function = nullptr, std::int32_t line = 0);
void releasereadlock(const char* function = nullptr, std::int32_t line = 0);
bool tryreadlock(const char* function = nullptr);
void writelock(const char* function = nullptr, std::int32_t line = 0);
void releasewritelock(const char* function = nullptr, std::int32_t line = 0);
bool trywritelock(const char* function = nullptr);
void waitReaders(const char* function = nullptr, std::int32_t line = 0);
void SetName(std::string in_name);
private:
std::shared_mutex rw_mutex;
std::mutex basic_mutex;
std::string name;
#ifdef DEBUG
std::mutex debug_mutex;
std::map<std::string, std::int32_t> stack;
void addDebugLock(const char* function);
void removeDebugLock(const char* function);
void logDeadlock(const char* function, std::int32_t line, const char* lock_type);
#endif
};
class LockMutex
{
public:
LockMutex(Mutex* in_mut, bool iLock = true);
~LockMutex();
void unlock();
void lock();
private:
bool locked;
Mutex* mut;
};