Critical.cpp 3.0 KB

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