RWLock_WINCE.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. //
  2. // RWLock_WINCE.cpp
  3. //
  4. // $Id: //poco/1.4/Foundation/src/RWLock_WINCE.cpp#1 $
  5. //
  6. // Library: Foundation
  7. // Package: Threading
  8. // Module: RWLock
  9. //
  10. // Copyright (c) 2009-2010, Applied Informatics Software Engineering GmbH.
  11. // and Contributors.
  12. //
  13. // SPDX-License-Identifier: BSL-1.0
  14. //
  15. #include "Poco/RWLock_WINCE.h"
  16. #include "Poco/Thread.h"
  17. namespace Poco {
  18. RWLockImpl::RWLockImpl():
  19. _readerCount(0),
  20. _readerWaiting(0),
  21. _writerCount(0),
  22. _writerWaiting(0),
  23. _writeLock(false)
  24. {
  25. InitializeCriticalSection(&_cs);
  26. _readerGreen = CreateEventW(NULL, FALSE, TRUE, NULL);
  27. if (!_readerGreen) throw SystemException("Cannot create RWLock");
  28. _writerGreen = CreateEventW(NULL, FALSE, TRUE, NULL);
  29. if (!_writerGreen)
  30. {
  31. CloseHandle(_readerGreen);
  32. throw SystemException("Cannot create RWLock");
  33. }
  34. }
  35. RWLockImpl::~RWLockImpl()
  36. {
  37. CloseHandle(_readerGreen);
  38. CloseHandle(_writerGreen);
  39. DeleteCriticalSection(&_cs);
  40. }
  41. void RWLockImpl::readLockImpl()
  42. {
  43. tryReadLockImpl(INFINITE);
  44. }
  45. bool RWLockImpl::tryReadLockImpl(DWORD timeout)
  46. {
  47. bool wait = false;
  48. do
  49. {
  50. EnterCriticalSection(&_cs);
  51. if (!_writerCount && !_writerWaiting)
  52. {
  53. if (wait)
  54. {
  55. _readerWaiting--;
  56. wait = false;
  57. }
  58. _readerCount++;
  59. }
  60. else
  61. {
  62. if (!wait)
  63. {
  64. _readerWaiting++;
  65. wait = true;
  66. }
  67. ResetEvent(_readerGreen);
  68. }
  69. LeaveCriticalSection(&_cs);
  70. if (wait)
  71. {
  72. if (WaitForSingleObject(_readerGreen, timeout) != WAIT_OBJECT_0)
  73. {
  74. EnterCriticalSection(&_cs);
  75. _readerWaiting--;
  76. SetEvent(_readerGreen);
  77. SetEvent(_writerGreen);
  78. LeaveCriticalSection(&_cs);
  79. return false;
  80. }
  81. }
  82. }
  83. while (wait);
  84. return true;
  85. }
  86. void RWLockImpl::writeLockImpl()
  87. {
  88. tryWriteLockImpl(INFINITE);
  89. }
  90. bool RWLockImpl::tryWriteLockImpl(DWORD timeout)
  91. {
  92. bool wait = false;
  93. do
  94. {
  95. EnterCriticalSection(&_cs);
  96. if (!_readerCount && !_writerCount)
  97. {
  98. if (wait)
  99. {
  100. _writerWaiting--;
  101. wait = false;
  102. }
  103. _writerCount++;
  104. }
  105. else
  106. {
  107. if (!wait)
  108. {
  109. _writerWaiting++;
  110. wait = true;
  111. }
  112. ResetEvent(_writerGreen);
  113. }
  114. LeaveCriticalSection(&_cs);
  115. if (wait)
  116. {
  117. if (WaitForSingleObject(_writerGreen, timeout) != WAIT_OBJECT_0)
  118. {
  119. EnterCriticalSection(&_cs);
  120. _writerWaiting--;
  121. SetEvent(_readerGreen);
  122. SetEvent(_writerGreen);
  123. LeaveCriticalSection(&_cs);
  124. return false;
  125. }
  126. }
  127. }
  128. while (wait);
  129. _writeLock = true;
  130. return true;
  131. }
  132. void RWLockImpl::unlockImpl()
  133. {
  134. EnterCriticalSection(&_cs);
  135. if (_writeLock)
  136. {
  137. _writeLock = false;
  138. _writerCount--;
  139. }
  140. else
  141. {
  142. _readerCount--;
  143. }
  144. if (_writerWaiting)
  145. SetEvent(_writerGreen);
  146. else if (_readerWaiting)
  147. SetEvent(_readerGreen);
  148. LeaveCriticalSection(&_cs);
  149. }
  150. } // namespace Poco