NotificationQueue.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. //
  2. // NotificationQueue.cpp
  3. //
  4. // $Id: //poco/1.4/Foundation/src/NotificationQueue.cpp#1 $
  5. //
  6. // Library: Foundation
  7. // Package: Notifications
  8. // Module: NotificationQueue
  9. //
  10. // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
  11. // and Contributors.
  12. //
  13. // SPDX-License-Identifier: BSL-1.0
  14. //
  15. #include "Poco/NotificationQueue.h"
  16. #include "Poco/NotificationCenter.h"
  17. #include "Poco/Notification.h"
  18. #include "Poco/SingletonHolder.h"
  19. namespace Poco {
  20. NotificationQueue::NotificationQueue()
  21. {
  22. }
  23. NotificationQueue::~NotificationQueue()
  24. {
  25. try
  26. {
  27. clear();
  28. }
  29. catch (...)
  30. {
  31. poco_unexpected();
  32. }
  33. }
  34. void NotificationQueue::enqueueNotification(Notification::Ptr pNotification)
  35. {
  36. poco_check_ptr (pNotification);
  37. FastMutex::ScopedLock lock(_mutex);
  38. if (_waitQueue.empty())
  39. {
  40. _nfQueue.push_back(pNotification);
  41. }
  42. else
  43. {
  44. WaitInfo* pWI = _waitQueue.front();
  45. _waitQueue.pop_front();
  46. pWI->pNf = pNotification;
  47. pWI->nfAvailable.set();
  48. }
  49. }
  50. void NotificationQueue::enqueueUrgentNotification(Notification::Ptr pNotification)
  51. {
  52. poco_check_ptr (pNotification);
  53. FastMutex::ScopedLock lock(_mutex);
  54. if (_waitQueue.empty())
  55. {
  56. _nfQueue.push_front(pNotification);
  57. }
  58. else
  59. {
  60. WaitInfo* pWI = _waitQueue.front();
  61. _waitQueue.pop_front();
  62. pWI->pNf = pNotification;
  63. pWI->nfAvailable.set();
  64. }
  65. }
  66. Notification* NotificationQueue::dequeueNotification()
  67. {
  68. FastMutex::ScopedLock lock(_mutex);
  69. return dequeueOne().duplicate();
  70. }
  71. Notification* NotificationQueue::waitDequeueNotification()
  72. {
  73. Notification::Ptr pNf;
  74. WaitInfo* pWI = 0;
  75. {
  76. FastMutex::ScopedLock lock(_mutex);
  77. pNf = dequeueOne();
  78. if (pNf) return pNf.duplicate();
  79. pWI = new WaitInfo;
  80. _waitQueue.push_back(pWI);
  81. }
  82. pWI->nfAvailable.wait();
  83. pNf = pWI->pNf;
  84. delete pWI;
  85. return pNf.duplicate();
  86. }
  87. Notification* NotificationQueue::waitDequeueNotification(long milliseconds)
  88. {
  89. Notification::Ptr pNf;
  90. WaitInfo* pWI = 0;
  91. {
  92. FastMutex::ScopedLock lock(_mutex);
  93. pNf = dequeueOne();
  94. if (pNf) return pNf.duplicate();
  95. pWI = new WaitInfo;
  96. _waitQueue.push_back(pWI);
  97. }
  98. if (pWI->nfAvailable.tryWait(milliseconds))
  99. {
  100. pNf = pWI->pNf;
  101. }
  102. else
  103. {
  104. FastMutex::ScopedLock lock(_mutex);
  105. pNf = pWI->pNf;
  106. for (WaitQueue::iterator it = _waitQueue.begin(); it != _waitQueue.end(); ++it)
  107. {
  108. if (*it == pWI)
  109. {
  110. _waitQueue.erase(it);
  111. break;
  112. }
  113. }
  114. }
  115. delete pWI;
  116. return pNf.duplicate();
  117. }
  118. void NotificationQueue::dispatch(NotificationCenter& notificationCenter)
  119. {
  120. FastMutex::ScopedLock lock(_mutex);
  121. Notification::Ptr pNf = dequeueOne();
  122. while (pNf)
  123. {
  124. notificationCenter.postNotification(pNf);
  125. pNf = dequeueOne();
  126. }
  127. }
  128. void NotificationQueue::wakeUpAll()
  129. {
  130. FastMutex::ScopedLock lock(_mutex);
  131. for (WaitQueue::iterator it = _waitQueue.begin(); it != _waitQueue.end(); ++it)
  132. {
  133. (*it)->nfAvailable.set();
  134. }
  135. _waitQueue.clear();
  136. }
  137. bool NotificationQueue::empty() const
  138. {
  139. FastMutex::ScopedLock lock(_mutex);
  140. return _nfQueue.empty();
  141. }
  142. int NotificationQueue::size() const
  143. {
  144. FastMutex::ScopedLock lock(_mutex);
  145. return static_cast<int>(_nfQueue.size());
  146. }
  147. void NotificationQueue::clear()
  148. {
  149. FastMutex::ScopedLock lock(_mutex);
  150. _nfQueue.clear();
  151. }
  152. bool NotificationQueue::hasIdleThreads() const
  153. {
  154. FastMutex::ScopedLock lock(_mutex);
  155. return !_waitQueue.empty();
  156. }
  157. Notification::Ptr NotificationQueue::dequeueOne()
  158. {
  159. Notification::Ptr pNf;
  160. if (!_nfQueue.empty())
  161. {
  162. pNf = _nfQueue.front();
  163. _nfQueue.pop_front();
  164. }
  165. return pNf;
  166. }
  167. namespace
  168. {
  169. static SingletonHolder<NotificationQueue> sh;
  170. }
  171. NotificationQueue& NotificationQueue::defaultQueue()
  172. {
  173. return *sh.get();
  174. }
  175. } // namespace Poco