[7297] Fixed profession spells sorting in trainer spell list at client.
[getmangos.git] / dep / ACE_wrappers / ace / Notification_Queue.cpp
blob09d9934a2183ceb3cdf10d4326895170ff42b184
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()
15 : ACE_Copy_Disabled()
16 , alloc_queue_()
17 , notify_queue_()
18 , free_queue_()
22 ACE_Notification_Queue::
23 ~ACE_Notification_Queue()
25 reset();
28 int
29 ACE_Notification_Queue::
30 open()
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 ())
37 return 0;
39 return allocate_more_buffers();
42 void
43 ACE_Notification_Queue::
44 reset()
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();
50 node != 0;
51 node = node->next())
53 if (node->get().eh_ == 0)
55 continue;
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 ())
66 delete [] *b;
67 *b = 0;
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;
85 ACE_NEW_RETURN (temp,
86 ACE_Notification_Queue_Node[ACE_REACTOR_NOTIFICATION_ARRAY_SIZE],
87 -1);
89 if (this->alloc_queue_.enqueue_head (temp) == -1)
91 delete [] temp;
92 return -1;
95 for (size_t i = 0; i < ACE_REACTOR_NOTIFICATION_ARRAY_SIZE; ++i)
97 free_queue_.push_front(temp + i);
100 return 0;
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 ())
113 return 0;
115 int number_purged = 0;
116 ACE_Notification_Queue_Node * node = notify_queue_.head();
117 while(node != 0)
119 if (!node->matches_for_purging(eh))
121 // Easy case, skip to the next node
122 node = node->next();
123 continue;
126 if (!node->mask_disables_all_notifications(mask))
128 // ... another easy case, skip this node too, but clear the
129 // mask first ...
130 node->clear_mask(mask);
131 node = node->next();
132 continue;
135 // ... this is the more complicated case, we want to remove the
136 // node from the notify_queue_ list. First save the next node
137 // on the list:
138 ACE_Notification_Queue_Node * next = node->next();
140 // ... then remove it ...
141 notify_queue_.unsafe_remove(node);
142 ++number_purged;
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 ...
152 node = next;
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)
176 return -1;
180 ACE_Notification_Queue_Node * node =
181 free_queue_.pop_front();
183 ACE_ASSERT (node != 0);
184 node->set(buffer);
186 notify_queue_.push_back(node);
188 if (!notification_required)
190 return 0;
193 return 1;
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 ())
210 return 0;
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();
225 return 1;
228 ACE_END_VERSIONED_NAMESPACE_DECL