NotificationQueue.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. //
  2. // NotificationQueue.h
  3. //
  4. // $Id: //poco/1.4/Foundation/include/Poco/NotificationQueue.h#1 $
  5. //
  6. // Library: Foundation
  7. // Package: Notifications
  8. // Module: NotificationQueue
  9. //
  10. // Definition of the NotificationQueue class.
  11. //
  12. // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
  13. // and Contributors.
  14. //
  15. // SPDX-License-Identifier: BSL-1.0
  16. //
  17. #ifndef Foundation_NotificationQueue_INCLUDED
  18. #define Foundation_NotificationQueue_INCLUDED
  19. #include "Poco/Foundation.h"
  20. #include "Poco/Notification.h"
  21. #include "Poco/Mutex.h"
  22. #include "Poco/Event.h"
  23. #include <deque>
  24. namespace Poco {
  25. class NotificationCenter;
  26. class Foundation_API NotificationQueue
  27. /// A NotificationQueue object provides a way to implement asynchronous
  28. /// notifications. This is especially useful for sending notifications
  29. /// from one thread to another, for example from a background thread to
  30. /// the main (user interface) thread.
  31. ///
  32. /// The NotificationQueue can also be used to distribute work from
  33. /// a controlling thread to one or more worker threads. Each worker thread
  34. /// repeatedly calls waitDequeueNotification() and processes the
  35. /// returned notification. Special care must be taken when shutting
  36. /// down a queue with worker threads waiting for notifications.
  37. /// The recommended sequence to shut down and destroy the queue is to
  38. /// 1. set a termination flag for every worker thread
  39. /// 2. call the wakeUpAll() method
  40. /// 3. join each worker thread
  41. /// 4. destroy the notification queue.
  42. {
  43. public:
  44. NotificationQueue();
  45. /// Creates the NotificationQueue.
  46. ~NotificationQueue();
  47. /// Destroys the NotificationQueue.
  48. void enqueueNotification(Notification::Ptr pNotification);
  49. /// Enqueues the given notification by adding it to
  50. /// the end of the queue (FIFO).
  51. /// The queue takes ownership of the notification, thus
  52. /// a call like
  53. /// notificationQueue.enqueueNotification(new MyNotification);
  54. /// does not result in a memory leak.
  55. void enqueueUrgentNotification(Notification::Ptr pNotification);
  56. /// Enqueues the given notification by adding it to
  57. /// the front of the queue (LIFO). The event therefore gets processed
  58. /// before all other events already in the queue.
  59. /// The queue takes ownership of the notification, thus
  60. /// a call like
  61. /// notificationQueue.enqueueUrgentNotification(new MyNotification);
  62. /// does not result in a memory leak.
  63. Notification* dequeueNotification();
  64. /// Dequeues the next pending notification.
  65. /// Returns 0 (null) if no notification is available.
  66. /// The caller gains ownership of the notification and
  67. /// is expected to release it when done with it.
  68. ///
  69. /// It is highly recommended that the result is immediately
  70. /// assigned to a Notification::Ptr, to avoid potential
  71. /// memory management issues.
  72. Notification* waitDequeueNotification();
  73. /// Dequeues the next pending notification.
  74. /// If no notification is available, waits for a notification
  75. /// to be enqueued.
  76. /// The caller gains ownership of the notification and
  77. /// is expected to release it when done with it.
  78. /// This method returns 0 (null) if wakeUpWaitingThreads()
  79. /// has been called by another thread.
  80. ///
  81. /// It is highly recommended that the result is immediately
  82. /// assigned to a Notification::Ptr, to avoid potential
  83. /// memory management issues.
  84. Notification* waitDequeueNotification(long milliseconds);
  85. /// Dequeues the next pending notification.
  86. /// If no notification is available, waits for a notification
  87. /// to be enqueued up to the specified time.
  88. /// Returns 0 (null) if no notification is available.
  89. /// The caller gains ownership of the notification and
  90. /// is expected to release it when done with it.
  91. ///
  92. /// It is highly recommended that the result is immediately
  93. /// assigned to a Notification::Ptr, to avoid potential
  94. /// memory management issues.
  95. void dispatch(NotificationCenter& notificationCenter);
  96. /// Dispatches all queued notifications to the given
  97. /// notification center.
  98. void wakeUpAll();
  99. /// Wakes up all threads that wait for a notification.
  100. bool empty() const;
  101. /// Returns true iff the queue is empty.
  102. int size() const;
  103. /// Returns the number of notifications in the queue.
  104. void clear();
  105. /// Removes all notifications from the queue.
  106. bool hasIdleThreads() const;
  107. /// Returns true if the queue has at least one thread waiting
  108. /// for a notification.
  109. static NotificationQueue& defaultQueue();
  110. /// Returns a reference to the default
  111. /// NotificationQueue.
  112. protected:
  113. Notification::Ptr dequeueOne();
  114. private:
  115. typedef std::deque<Notification::Ptr> NfQueue;
  116. struct WaitInfo
  117. {
  118. Notification::Ptr pNf;
  119. Event nfAvailable;
  120. };
  121. typedef std::deque<WaitInfo*> WaitQueue;
  122. NfQueue _nfQueue;
  123. WaitQueue _waitQueue;
  124. mutable FastMutex _mutex;
  125. };
  126. } // namespace Poco
  127. #endif // Foundation_NotificationQueue_INCLUDED