Document return values
[ACE_TAO.git] / ACE / ace / Notification_Queue.cpp
blobdc250d5047642ad94328ae45faee50f0b270810c
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()
14 : alloc_queue_()
15 , notify_queue_()
16 , free_queue_()
20 ACE_Notification_Queue::~ACE_Notification_Queue()
22 reset();
25 int
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 ())
33 return 0;
35 return allocate_more_buffers();
38 void
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();
45 node != 0;
46 node = node->next())
48 if (node->get().eh_ == 0)
50 continue;
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 ())
61 delete [] *b;
62 *b = 0;
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_);
73 int
74 ACE_Notification_Queue::allocate_more_buffers()
76 ACE_TRACE ("ACE_Notification_Queue::allocate_more_buffers");
78 ACE_Notification_Queue_Node *temp = 0;
80 ACE_NEW_RETURN (temp,
81 ACE_Notification_Queue_Node[ACE_REACTOR_NOTIFICATION_ARRAY_SIZE],
82 -1);
84 if (this->alloc_queue_.enqueue_head (temp) == -1)
86 delete [] temp;
87 return -1;
90 for (size_t i = 0; i < ACE_REACTOR_NOTIFICATION_ARRAY_SIZE; ++i)
92 free_queue_.push_front(temp + i);
95 return 0;
98 int
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 ())
108 return 0;
110 int number_purged = 0;
111 ACE_Notification_Queue_Node * node = notify_queue_.head();
112 while(node != 0)
114 if (!node->matches_for_purging(eh))
116 // Easy case, skip to the next node
117 node = node->next();
118 continue;
121 if (!node->mask_disables_all_notifications(mask))
123 // ... another easy case, skip this node too, but clear the
124 // mask first ...
125 node->clear_mask(mask);
126 node = node->next();
127 continue;
130 // ... this is the more complicated case, we want to remove the
131 // node from the notify_queue_ list. First save the next node
132 // on the list:
133 ACE_Notification_Queue_Node * next = node->next();
135 // ... then remove it ...
136 notify_queue_.unsafe_remove(node);
137 ++number_purged;
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 ...
147 node = next;
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)
171 return -1;
175 ACE_Notification_Queue_Node * node =
176 free_queue_.pop_front();
178 ACE_ASSERT (node != 0);
179 node->set(buffer);
181 notify_queue_.push_back(node);
183 if (!notification_required)
185 return 0;
188 return 1;
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 ())
205 return 0;
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();
219 return 1;
222 ACE_END_VERSIONED_NAMESPACE_DECL