#pragma once #include #include #define MUTEX_ATTRIBUTE_FAST 1 #define MUTEX_ATTRIBUTE_RECURSIVE 2 #define MUTEX_ATTRIBUTE_ERRORCHK 3 class CriticalSection { public: explicit CriticalSection(int attribute = MUTEX_ATTRIBUTE_FAST) : is_recursive(attribute == MUTEX_ATTRIBUTE_RECURSIVE) {} void lock() { if (is_recursive) { recursive_mutex.lock(); } else { regular_mutex.lock(); } } void unlock() { if (is_recursive) { recursive_mutex.unlock(); } else { regular_mutex.unlock(); } } bool trylock() { return is_recursive ? recursive_mutex.try_lock() : regular_mutex.try_lock(); } private: std::mutex regular_mutex; std::recursive_mutex recursive_mutex; bool is_recursive; }; class Mutex { public: Mutex() = default; void lock() { main_mutex.lock(); } void unlock() { main_mutex.unlock(); } bool trylock() { return main_mutex.try_lock(); } void readlock(const char* = nullptr, int = 0) { while (true) { std::unique_lock read_lock(read_mutex); if (!writing.load()) { readers.fetch_add(1); return; } } } void releasereadlock(const char* = nullptr, int = 0) { readers.fetch_sub(1); } bool tryreadlock(const char* = nullptr) { std::lock_guard read_lock(read_mutex); if (!writing.load()) { readers.fetch_add(1); return true; } return false; } void writelock(const char* = nullptr, int = 0) { write_mutex.lock(); waitReaders(); } void releasewritelock(const char* = nullptr, int = 0) { writing.store(false); write_mutex.unlock(); } bool trywritelock(const char* = nullptr) { if (!write_mutex.try_lock()) return false; if (readers.load() == 0) { writing.store(true); return true; } write_mutex.unlock(); return false; } void waitReaders(const char* = nullptr, int = 0) { while (readers.load() > 0) {} writing.store(true); } void SetName(const std::string&) {} private: std::mutex read_mutex; std::mutex write_mutex; std::mutex main_mutex; std::atomic readers{0}; std::atomic writing{false}; }; class LockMutex { public: explicit LockMutex(Mutex* mutex, bool lock_immediately = true) : mut(mutex), locked(lock_immediately) { if (locked) mut->lock(); } ~LockMutex() { if (locked) mut->unlock(); } void unlock() { if (locked) { mut->unlock(); locked = false; } } void lock() { if (!locked) { mut->lock(); locked = true; } } private: Mutex* mut; bool locked; };