#include "Critical.h" #include #include #include "Globals.h" #include "Thread.h" using namespace Framework; // Inhalt der Critical class aus Critical.h // Konstructor Critical::Critical() { InitializeCriticalSection(&cs); owner = 0; lockCount = 0; id = (int)time(0); } // Destructor Critical::~Critical() { DeleteCriticalSection(&cs); } pthread_t CachedCurrentThread() { volatile thread_local static pthread_t t = GetCurrentThread(); return (pthread_t)t; } // sperrt das Objekt void Critical::lock() { getThreadRegister()->lock(); Thread* tmp = getThreadRegister()->zThread(CachedCurrentThread()); if (tmp) tmp->addCriticalLock(); getThreadRegister()->unlock(); EnterCriticalSection(&cs); if (!owner) owner = tmp; lockCount++; } // versucht das Objekt zu sperren bool Critical::tryLock() { if (lockCount > 0) return false; getThreadRegister()->lock(); Thread* tmp = getThreadRegister()->zThread(CachedCurrentThread()); if (tmp) tmp->addCriticalLock(); getThreadRegister()->unlock(); EnterCriticalSection(&cs); if (!owner) owner = tmp; lockCount++; return true; } // entsperrt das Objekt void Critical::unlock() { getThreadRegister()->lock(); Thread* tmp = 0; if (getThreadRegister()->isThread(owner)) { if (owner && GetThreadId(owner->getThreadHandle()) != GetThreadId(CachedCurrentThread())) throw std::runtime_error("A Thread that does not own a Critical " "Object trys to unlock it"); tmp = owner; } getThreadRegister()->unlock(); if (!--lockCount) owner = 0; LeaveCriticalSection(&cs); getThreadRegister()->lock(); if (tmp && getThreadRegister()->isThread(tmp)) tmp->removeCriticalLock(); getThreadRegister()->unlock(); } // gibt true zurück, wenn das Objekt gesperrt ist bool Critical::isLocked() const { return lockCount > 0; } // gibt einen Zeiger auf den Thread zurück, der das Objekt gesperrt hat const Thread* Critical::zOwner() const { return owner; } Synchronizer::Synchronizer() : numWaiting(0), skip(0) {} Synchronizer::~Synchronizer() { skip = 1; std::unique_lock lk(mutex); if (numWaiting > 0) { lk.unlock(); block.notify_all(); } else lk.unlock(); while (numWaiting > 0) Sleep(10); lk.lock(); } bool Synchronizer::wait() { std::unique_lock lk(mutex); if (skip) return false; numWaiting++; block.wait(lk); numWaiting--; return !skip; } bool Synchronizer::wait(int milisec) { std::unique_lock lk(mutex); if (skip) return false; numWaiting++; std::cv_status status = block.wait_for(lk, std::chrono::milliseconds(milisec)); numWaiting--; return !skip && status == std::cv_status::no_timeout; } void Synchronizer::notify() { block.notify_one(); } void Synchronizer::notify(int amount) { while (amount--) block.notify_one(); } void Synchronizer::notifyAll() { block.notify_all(); } int Synchronizer::getNumberOfWaitingThreads() const { return numWaiting; }