1 #include "ace/Notification_Queue.h"
3 #if !defined (__ACE_INLINE__)
4 #include "ace/Notification_Queue.inl"
5 #endif /* __ACE_INLINE__ */
7 #include "ace/Guard_T.h"
9 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
11 ACE_ALLOC_HOOK_DEFINE(ACE_Notification_Queue_Node
)
13 ACE_Notification_Queue::ACE_Notification_Queue()
20 ACE_Notification_Queue::~ACE_Notification_Queue()
26 ACE_Notification_Queue::open()
28 ACE_TRACE ("ACE_Notification_Queue::open");
30 ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, mon
, this->notify_queue_lock_
, -1);
32 if (!this->free_queue_
.is_empty ())
35 return allocate_more_buffers();
39 ACE_Notification_Queue::reset()
41 ACE_TRACE ("ACE_Notification_Queue::reset");
43 // Release all the event handlers still in the queue ...
44 for (ACE_Notification_Queue_Node
* node
= notify_queue_
.head();
48 if (node
->get().eh_
== 0)
52 (void) node
->get().eh_
->remove_reference();
55 // ... free up the dynamically allocated resources ...
56 ACE_Notification_Queue_Node
**b
= 0;
57 for (ACE_Unbounded_Queue_Iterator
<ACE_Notification_Queue_Node
*> alloc_iter (this->alloc_queue_
);
58 alloc_iter
.next (b
) != 0;
59 alloc_iter
.advance ())
65 // ... cleanup the list of allocated blocks ...
66 this->alloc_queue_
.reset ();
68 // ... swap with empty lists to reset the contents ...
69 Buffer_List().swap(notify_queue_
);
70 Buffer_List().swap(free_queue_
);
74 ACE_Notification_Queue::allocate_more_buffers()
76 ACE_TRACE ("ACE_Notification_Queue::allocate_more_buffers");
78 ACE_Notification_Queue_Node
*temp
= 0;
81 ACE_Notification_Queue_Node
[ACE_REACTOR_NOTIFICATION_ARRAY_SIZE
],
84 if (this->alloc_queue_
.enqueue_head (temp
) == -1)
90 for (size_t i
= 0; i
< ACE_REACTOR_NOTIFICATION_ARRAY_SIZE
; ++i
)
92 free_queue_
.push_front(temp
+ i
);
99 ACE_Notification_Queue::purge_pending_notifications(
100 ACE_Event_Handler
* eh
,
101 ACE_Reactor_Mask mask
)
103 ACE_TRACE ("ACE_Notification_Queue::purge_pending_notifications");
105 ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, mon
, this->notify_queue_lock_
, -1);
107 if (this->notify_queue_
.is_empty ())
110 int number_purged
= 0;
111 ACE_Notification_Queue_Node
* node
= notify_queue_
.head();
114 if (!node
->matches_for_purging(eh
))
116 // Easy case, skip to the next node
121 if (!node
->mask_disables_all_notifications(mask
))
123 // ... another easy case, skip this node too, but clear the
125 node
->clear_mask(mask
);
130 // ... this is the more complicated case, we want to remove the
131 // node from the notify_queue_ list. First save the next node
133 ACE_Notification_Queue_Node
* next
= node
->next();
135 // ... then remove it ...
136 notify_queue_
.unsafe_remove(node
);
139 // ... release resources ...
140 ACE_Event_Handler
*event_handler
= node
->get().eh_
;
141 event_handler
->remove_reference ();
143 // ... now this is a free node ...
144 free_queue_
.push_front(node
);
146 // ... go to the next node, if there is one ...
150 return number_purged
;
154 ACE_Notification_Queue::push_new_notification(
155 ACE_Notification_Buffer
const & buffer
)
157 ACE_TRACE ("ACE_Notification_Queue::push_new_notification");
159 bool notification_required
= false;
161 ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, mon
, this->notify_queue_lock_
, -1);
163 // No pending notifications.
164 if (this->notify_queue_
.is_empty ())
165 notification_required
= true;
167 if (free_queue_
.is_empty())
169 if (allocate_more_buffers() == -1)
175 ACE_Notification_Queue_Node
* node
=
176 free_queue_
.pop_front();
178 ACE_ASSERT (node
!= 0);
181 notify_queue_
.push_back(node
);
183 if (!notification_required
)
192 ACE_Notification_Queue::pop_next_notification(
193 ACE_Notification_Buffer
& current
,
194 bool & more_messages_queued
,
195 ACE_Notification_Buffer
& next
)
197 ACE_TRACE ("ACE_Notification_Queue::pop_next_notification");
199 more_messages_queued
= false;
201 ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, mon
, this->notify_queue_lock_
, -1);
203 if (notify_queue_
.is_empty ())
208 ACE_Notification_Queue_Node
* node
= notify_queue_
.pop_front();
210 current
= node
->get();
211 free_queue_
.push_front(node
);
213 if(!this->notify_queue_
.is_empty())
215 more_messages_queued
= true;
216 next
= notify_queue_
.head()->get();
222 ACE_END_VERSIONED_NAMESPACE_DECL