Critical.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #include "Critical.h"
  2. #include "Globals.h"
  3. #include "Thread.h"
  4. #include <iostream>
  5. #include <time.h>
  6. using namespace Framework;
  7. // Inhalt der Critical class aus Critical.h
  8. // Konstructor
  9. Critical::Critical()
  10. {
  11. InitializeCriticalSection( &cs );
  12. owner = 0;
  13. lockCount = 0;
  14. id = (int)time( 0 );
  15. }
  16. // Destructor
  17. Critical::~Critical()
  18. {
  19. DeleteCriticalSection( &cs );
  20. }
  21. // sperrt das Objekt
  22. void Critical::lock()
  23. {
  24. pthread_t t = GetCurrentThread();
  25. getThreadRegister()->lock();
  26. Thread* tmp = getThreadRegister()->zThread( t );
  27. if( tmp )
  28. tmp->addCriticalLock();
  29. getThreadRegister()->unlock();
  30. EnterCriticalSection( &cs );
  31. if( !owner )
  32. owner = tmp;
  33. lockCount++;
  34. }
  35. // versucht das Objekt zu sperren
  36. bool Critical::tryLock()
  37. {
  38. if( lockCount > 0 )
  39. return false;
  40. getThreadRegister()->lock();
  41. Thread* tmp = getThreadRegister()->zThread( GetCurrentThread() );
  42. if( tmp )
  43. tmp->addCriticalLock();
  44. getThreadRegister()->unlock();
  45. EnterCriticalSection( &cs );
  46. if( !owner )
  47. owner = tmp;
  48. lockCount++;
  49. return true;
  50. }
  51. // entsperrt das Objekt
  52. void Critical::unlock()
  53. {
  54. getThreadRegister()->lock();
  55. Thread* tmp = 0;
  56. if( getThreadRegister()->isThread( owner ) )
  57. {
  58. if( owner && GetThreadId( owner->getThreadHandle() ) != GetThreadId( GetCurrentThread() ) )
  59. throw std::runtime_error( "A Thread that does not own a Critical Object trys to unlock it" );
  60. tmp = owner;
  61. }
  62. getThreadRegister()->unlock();
  63. if( !--lockCount )
  64. owner = 0;
  65. LeaveCriticalSection( &cs );
  66. getThreadRegister()->lock();
  67. if( tmp && getThreadRegister()->isThread( tmp ) )
  68. tmp->removeCriticalLock();
  69. getThreadRegister()->unlock();
  70. }
  71. // gibt true zurück, wenn das Objekt gesperrt ist
  72. bool Critical::isLocked() const
  73. {
  74. return lockCount > 0;
  75. }
  76. // gibt einen Zeiger auf den Thread zurück, der das Objekt gesperrt hat
  77. const Thread* Critical::zOwner() const
  78. {
  79. return owner;
  80. }
  81. Synchronizer::Synchronizer()
  82. : numWaiting( 0 ),
  83. skip( 0 )
  84. {}
  85. Synchronizer::~Synchronizer()
  86. {
  87. skip = 1;
  88. std::unique_lock<std::mutex> lk( mutex );
  89. if( numWaiting > 0 )
  90. {
  91. lk.unlock();
  92. block.notify_all();
  93. }
  94. else
  95. lk.unlock();
  96. while( numWaiting > 0 )
  97. Sleep( 10 );
  98. lk.lock();
  99. }
  100. bool Synchronizer::wait()
  101. {
  102. std::unique_lock<std::mutex> lk( mutex );
  103. if( skip )
  104. return false;
  105. numWaiting++;
  106. block.wait( lk );
  107. numWaiting--;
  108. return !skip;
  109. }
  110. bool Synchronizer::wait( int milisec )
  111. {
  112. std::unique_lock<std::mutex> lk( mutex );
  113. if( skip )
  114. return false;
  115. numWaiting++;
  116. std::cv_status status = block.wait_for( lk, std::chrono::milliseconds( milisec ) );
  117. numWaiting--;
  118. return !skip && status == std::cv_status::no_timeout;
  119. }
  120. void Synchronizer::notify()
  121. {
  122. block.notify_one();
  123. }
  124. void Synchronizer::notify( int amount )
  125. {
  126. while( amount-- )
  127. block.notify_one();
  128. }
  129. void Synchronizer::notifyAll()
  130. {
  131. block.notify_all();
  132. }
  133. int Synchronizer::getNumberOfWaitingThreads() const
  134. {
  135. return numWaiting;
  136. }