NotificationQueue.h 4.8 KB

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