#include "Critical.h" #include "Globals.h" #include "Thread.h" #include #include 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 ); } // sperrt das Objekt void Critical::lock() { pthread_t t = GetCurrentThread(); getThreadRegister()->lock(); Thread* tmp = getThreadRegister()->zThread( t ); 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( GetCurrentThread() ); 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( GetCurrentThread() ) ) 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; }