1//
2// PriorityNotificationQueue.h
3//
4// Library: Foundation
5// Package: Notifications
6// Module: PriorityNotificationQueue
7//
8// Definition of the PriorityNotificationQueue class.
9//
10// Copyright (c) 2009, Applied Informatics Software Engineering GmbH.
11// and Contributors.
12//
13// SPDX-License-Identifier: BSL-1.0
14//
15
16
17#ifndef Foundation_PriorityNotificationQueue_INCLUDED
18#define Foundation_PriorityNotificationQueue_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 <map>
26#include <deque>
27
28
29namespace Poco {
30
31
32class NotificationCenter;
33
34
35class Foundation_API PriorityNotificationQueue
36 /// A PriorityNotificationQueue object provides a way to implement asynchronous
37 /// notifications. This is especially useful for sending notifications
38 /// from one thread to another, for example from a background thread to
39 /// the main (user interface) thread.
40 ///
41 /// The PriorityNotificationQueue is quite similar to the NotificationQueue class.
42 /// The only difference to NotificationQueue is that each Notification is tagged
43 /// with a priority value. When inserting a Notification into the queue, the
44 /// Notification is inserted according to the given priority value, with
45 /// lower priority values being inserted before higher priority
46 /// values. Therefore, the lower the numerical priority value, the higher
47 /// the actual notification priority.
48 ///
49 /// Notifications are dequeued in order of their priority.
50 ///
51 /// The PriorityNotificationQueue can also be used to distribute work from
52 /// a controlling thread to one or more worker threads. Each worker thread
53 /// repeatedly calls waitDequeueNotification() and processes the
54 /// returned notification. Special care must be taken when shutting
55 /// down a queue with worker threads waiting for notifications.
56 /// The recommended sequence to shut down and destroy the queue is to
57 /// 1. set a termination flag for every worker thread
58 /// 2. call the wakeUpAll() method
59 /// 3. join each worker thread
60 /// 4. destroy the notification queue.
61{
62public:
63 PriorityNotificationQueue();
64 /// Creates the PriorityNotificationQueue.
65
66 ~PriorityNotificationQueue();
67 /// Destroys the PriorityNotificationQueue.
68
69 void enqueueNotification(Notification::Ptr pNotification, int priority);
70 /// Enqueues the given notification by adding it to
71 /// the queue according to the given priority.
72 /// Lower priority values are inserted before higher priority values.
73 /// The queue takes ownership of the notification, thus
74 /// a call like
75 /// notificationQueue.enqueueNotification(new MyNotification, 1);
76 /// does not result in a memory leak.
77
78 Notification* dequeueNotification();
79 /// Dequeues the next pending notification.
80 /// Returns 0 (null) if no notification is available.
81 /// The caller gains ownership of the notification and
82 /// is expected to release it when done with it.
83 ///
84 /// It is highly recommended that the result is immediately
85 /// assigned to a Notification::Ptr, to avoid potential
86 /// memory management issues.
87
88 Notification* waitDequeueNotification();
89 /// Dequeues the next pending notification.
90 /// If no notification is available, waits for a notification
91 /// to be enqueued.
92 /// The caller gains ownership of the notification and
93 /// is expected to release it when done with it.
94 /// This method returns 0 (null) if wakeUpAll()
95 /// has been called by another thread.
96 ///
97 /// It is highly recommended that the result is immediately
98 /// assigned to a Notification::Ptr, to avoid potential
99 /// memory management issues.
100
101 Notification* waitDequeueNotification(long milliseconds);
102 /// Dequeues the next pending notification.
103 /// If no notification is available, waits for a notification
104 /// to be enqueued up to the specified time.
105 /// Returns 0 (null) if no notification is available.
106 /// The caller gains ownership of the notification and
107 /// is expected to release it when done with it.
108 ///
109 /// It is highly recommended that the result is immediately
110 /// assigned to a Notification::Ptr, to avoid potential
111 /// memory management issues.
112
113 void dispatch(NotificationCenter& notificationCenter);
114 /// Dispatches all queued notifications to the given
115 /// notification center.
116
117 void wakeUpAll();
118 /// Wakes up all threads that wait for a notification.
119
120 bool empty() const;
121 /// Returns true iff the queue is empty.
122
123 int size() const;
124 /// Returns the number of notifications in the queue.
125
126 void clear();
127 /// Removes all notifications from the queue.
128
129 bool hasIdleThreads() const;
130 /// Returns true if the queue has at least one thread waiting
131 /// for a notification.
132
133 static PriorityNotificationQueue& defaultQueue();
134 /// Returns a reference to the default
135 /// PriorityNotificationQueue.
136
137protected:
138 Notification::Ptr dequeueOne();
139
140private:
141 typedef std::multimap<int, Notification::Ptr> NfQueue;
142 struct WaitInfo
143 {
144 Notification::Ptr pNf;
145 Event nfAvailable;
146 };
147 typedef std::deque<WaitInfo*> WaitQueue;
148
149 NfQueue _nfQueue;
150 WaitQueue _waitQueue;
151 mutable FastMutex _mutex;
152};
153
154
155} // namespace Poco
156
157
158#endif // Foundation_PriorityNotificationQueue_INCLUDED
159