#pragma once #include #include #include "OperatingSystem.h" namespace Framework { class Thread; class Lock { public: virtual void lock() = 0; virtual bool tryLock() = 0; virtual void unlock() = 0; }; class Critical : public Lock { private: CRITICAL_SECTION cs; int lockCount; public: //! Constructor DLLEXPORT Critical(); //! Destructor DLLEXPORT ~Critical(); //! Locks the object DLLEXPORT void lock() override; //! Tries to lock the object DLLEXPORT bool tryLock() override; //! Unlocks the object DLLEXPORT void unlock() override; //! Returns true if the object is locked DLLEXPORT bool isLocked() const; }; class StackLock { private: Lock** locks; int size; public: DLLEXPORT StackLock(std::initializer_list locks); DLLEXPORT ~StackLock(); }; #define LOCK(x) Framework::StackLock _lock(x) #define LOCKN(x, i) Framework::StackLock _lock_##i(x) class Synchronizer { private: std::condition_variable block; std::mutex mutex; int numWaiting; bool skip; public: DLLEXPORT Synchronizer(); DLLEXPORT ~Synchronizer(); DLLEXPORT bool wait(); DLLEXPORT bool wait(int milisec); DLLEXPORT void notify(); DLLEXPORT void notify(int amount); DLLEXPORT void notifyAll(); DLLEXPORT int getNumberOfWaitingThreads() const; }; class InternalReadLock; class InternalWriteLock; class ReadWriteLock { private: int* readerThreads; int* readCounters; int maxSize; int readerThreadCount; int writerThread; int writerCount; int waitingReaders; int waitingWriters; Critical cs; Synchronizer readerBlock; Synchronizer writerBlock; InternalReadLock* readLock; InternalWriteLock* writeLock; public: DLLEXPORT ReadWriteLock(int initialMaxSize = 10); DLLEXPORT ~ReadWriteLock(); DLLEXPORT void lockRead(); DLLEXPORT void lockWrite(); DLLEXPORT void unlockRead(); DLLEXPORT void unlockWrite(); DLLEXPORT bool tryLockRead(); DLLEXPORT bool tryLockWrite(); DLLEXPORT Lock& getReadLock() const; DLLEXPORT Lock& getWriteLock() const; }; } // namespace Framework