2 * @file Notification_Queue.h
4 * @author Carlos O'Ryan <coryan@atdesk.com>
7 #ifndef ACE_NOTIFICATION_QUEUE_H
8 #define ACE_NOTIFICATION_QUEUE_H
10 #include /**/ "ace/pre.h"
12 #include "ace/Event_Handler.h"
13 #include "ace/Intrusive_List.h"
14 #include "ace/Intrusive_List_Node.h"
15 #include "ace/Unbounded_Queue.h"
17 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
20 * @class ACE_Notification_Queue_Node
24 class ACE_Export ACE_Notification_Queue_Node
25 : public ACE_Intrusive_List_Node
<ACE_Notification_Queue_Node
>
31 ACE_Notification_Queue_Node();
34 * @brief Modifier change the contained buffer
36 void set(ACE_Notification_Buffer
const & rhs
);
39 * @brief Accessor, fetch the contained buffer
41 ACE_Notification_Buffer
const & get() const;
44 * @brief Checks if the event handler matches the purge condition
46 bool matches_for_purging(ACE_Event_Handler
* eh
) const;
49 * @brief Return true if clearing the mask would leave no
50 * notifications to deliver.
52 bool mask_disables_all_notifications(ACE_Reactor_Mask mask
);
55 * @brief Clear the notifications specified by @c mask
57 void clear_mask(ACE_Reactor_Mask mask
);
59 ACE_ALLOC_HOOK_DECLARE
;
62 ACE_Notification_Buffer contents_
;
66 * @class ACE_Notification_Queue
68 * @brief Implements a user-space queue to send Reactor notifications.
70 * The ACE_Reactor uses a pipe to send wake up the thread running the
71 * event loop from other threads. This pipe can be limited in size
72 * under some operating systems. For some applications, this limit
73 * presents a problem. A user-space notification queue is used to
74 * overcome those limitations. The queue tries to use as few
75 * resources on the pipe as possible, while keeping all the data in
78 * This code was refactored from Select_Reactor_Base.
80 class ACE_Export ACE_Notification_Queue
83 ACE_Notification_Queue();
84 ~ACE_Notification_Queue();
87 * @brief Pre-allocate resources in the queue
92 * @brief Release all resources in the queue
97 * @brief Remove all elements in the queue matching @c eh and @c mask
99 * I suggest reading the documentation in ACE_Reactor to find a more
100 * detailed description. This is just a helper function.
102 int purge_pending_notifications(ACE_Event_Handler
* eh
,
103 ACE_Reactor_Mask mask
);
106 * @brief Add a new notification to the queue
108 * @return -1 on failure, 1 if a new message should be sent through
109 * the pipe and 0 otherwise.
111 int push_new_notification(ACE_Notification_Buffer
const & buffer
);
114 * @brief Extract the next notification from the queue
116 * @return -1 on failure, 1 if a message was popped, 0 otherwise
118 int pop_next_notification(
119 ACE_Notification_Buffer
& current
,
120 bool & more_messages_queued
,
121 ACE_Notification_Buffer
& next
);
125 * @brief Allocate more memory for the queue
127 int allocate_more_buffers();
129 ACE_Notification_Queue (const ACE_Notification_Queue
&) = delete;
130 ACE_Notification_Queue (ACE_Notification_Queue
&&) = delete;
131 ACE_Notification_Queue
&operator= (const ACE_Notification_Queue
&) = delete;
132 ACE_Notification_Queue
&operator= (ACE_Notification_Queue
&&) = delete;
135 /// Keeps track of allocated arrays of type
136 /// ACE_Notification_Buffer. The idea is to amortize allocation
137 /// costs by allocating multiple ACE_Notification_Buffer objects at
139 ACE_Unbounded_Queue
<ACE_Notification_Queue_Node
*> alloc_queue_
;
141 typedef ACE_Intrusive_List
<ACE_Notification_Queue_Node
> Buffer_List
;
143 /// Keeps track of all pending notifications.
144 Buffer_List notify_queue_
;
146 /// Keeps track of all free buffers.
147 Buffer_List free_queue_
;
149 /// Synchronization for handling of queues.
150 ACE_SYNCH_MUTEX notify_queue_lock_
;
153 ACE_END_VERSIONED_NAMESPACE_DECL
155 #if defined (__ACE_INLINE__)
156 #include "ace/Notification_Queue.inl"
157 #endif /* __ACE_INLINE__ */
159 #include /**/ "ace/post.h"
161 #endif /* ACE_NOTIFICATION_QUEUE_H */