1 // $Id: Notification_Queue.cpp 81315 2008-04-10 07:14:15Z johnnyw $
3 #include "ace/Notification_Queue.h"
5 #if !defined (__ACE_INLINE__)
6 #include "ace/Notification_Queue.inl"
7 #endif /* __ACE_INLINE__ */
9 #include "ace/Guard_T.h"
11 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
13 ACE_Notification_Queue::
14 ACE_Notification_Queue()
22 ACE_Notification_Queue::
23 ~ACE_Notification_Queue()
29 ACE_Notification_Queue::
32 ACE_TRACE ("ACE_Notification_Queue::open");
34 ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, mon
, this->notify_queue_lock_
, -1);
36 if (!this->free_queue_
.is_empty ())
39 return allocate_more_buffers();
43 ACE_Notification_Queue::
46 ACE_TRACE ("ACE_Notification_Queue::reset");
48 // Release all the event handlers still in the queue ...
49 for (ACE_Notification_Queue_Node
* node
= notify_queue_
.head();
53 if (node
->get().eh_
== 0)
57 (void) node
->get().eh_
->remove_reference();
60 // ... free up the dynamically allocated resources ...
61 ACE_Notification_Queue_Node
**b
= 0;
62 for (ACE_Unbounded_Queue_Iterator
<ACE_Notification_Queue_Node
*> alloc_iter (this->alloc_queue_
);
63 alloc_iter
.next (b
) != 0;
64 alloc_iter
.advance ())
70 // ... cleanup the list of allocated blocks ...
71 this->alloc_queue_
.reset ();
73 // ... swap with empty lists to reset the contents ...
74 Buffer_List().swap(notify_queue_
);
75 Buffer_List().swap(free_queue_
);
78 int ACE_Notification_Queue::
79 allocate_more_buffers()
81 ACE_TRACE ("ACE_Notification_Queue::allocate_more_buffers");
83 ACE_Notification_Queue_Node
*temp
= 0;
86 ACE_Notification_Queue_Node
[ACE_REACTOR_NOTIFICATION_ARRAY_SIZE
],
89 if (this->alloc_queue_
.enqueue_head (temp
) == -1)
95 for (size_t i
= 0; i
< ACE_REACTOR_NOTIFICATION_ARRAY_SIZE
; ++i
)
97 free_queue_
.push_front(temp
+ i
);
104 ACE_Notification_Queue::
105 purge_pending_notifications(ACE_Event_Handler
* eh
,
106 ACE_Reactor_Mask mask
)
108 ACE_TRACE ("ACE_Notification_Queue::purge_pending_notifications");
110 ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, mon
, this->notify_queue_lock_
, -1);
112 if (this->notify_queue_
.is_empty ())
115 int number_purged
= 0;
116 ACE_Notification_Queue_Node
* node
= notify_queue_
.head();
119 if (!node
->matches_for_purging(eh
))
121 // Easy case, skip to the next node
126 if (!node
->mask_disables_all_notifications(mask
))
128 // ... another easy case, skip this node too, but clear the
130 node
->clear_mask(mask
);
135 // ... this is the more complicated case, we want to remove the
136 // node from the notify_queue_ list. First save the next node
138 ACE_Notification_Queue_Node
* next
= node
->next();
140 // ... then remove it ...
141 notify_queue_
.unsafe_remove(node
);
144 // ... release resources ...
145 ACE_Event_Handler
*event_handler
= node
->get().eh_
;
146 event_handler
->remove_reference ();
148 // ... now this is a free node ...
149 free_queue_
.push_front(node
);
151 // ... go to the next node, if there is one ...
155 return number_purged
;
158 int ACE_Notification_Queue::
159 push_new_notification(
160 ACE_Notification_Buffer
const & buffer
)
162 ACE_TRACE ("ACE_Notification_Queue::push_new_notification");
164 bool notification_required
= false;
166 ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, mon
, this->notify_queue_lock_
, -1);
168 // No pending notifications.
169 if (this->notify_queue_
.is_empty ())
170 notification_required
= true;
172 if (free_queue_
.is_empty())
174 if (allocate_more_buffers() == -1)
180 ACE_Notification_Queue_Node
* node
=
181 free_queue_
.pop_front();
183 ACE_ASSERT (node
!= 0);
186 notify_queue_
.push_back(node
);
188 if (!notification_required
)
197 ACE_Notification_Queue::pop_next_notification(
198 ACE_Notification_Buffer
& current
,
199 bool & more_messages_queued
,
200 ACE_Notification_Buffer
& next
)
202 ACE_TRACE ("ACE_Notification_Queue::pop_next_notification");
204 more_messages_queued
= false;
206 ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, mon
, this->notify_queue_lock_
, -1);
208 if (notify_queue_
.is_empty ())
213 ACE_Notification_Queue_Node
* node
=
214 notify_queue_
.pop_front();
216 current
= node
->get();
217 free_queue_
.push_front(node
);
219 if(!this->notify_queue_
.is_empty())
221 more_messages_queued
= true;
222 next
= notify_queue_
.head()->get();
228 ACE_END_VERSIONED_NAMESPACE_DECL