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