// Copyright (C) 2007-2025 EQ2EMulator // Licensed under GPL v3 #pragma once #include #include #include #include #include #include #include #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 regular_mutex; std::unique_ptr 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 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; };