Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

Priority_Reactor.cpp

Go to the documentation of this file.
00001 #include "ace_pch.h"
00002 // $Id: Priority_Reactor.cpp,v 1.1.1.3.40.1 2003/03/13 19:44:22 chad Exp $
00003 
00004 #include "ace/Priority_Reactor.h"
00005 #include "ace/Malloc_T.h"
00006 
00007 ACE_RCSID(ace, Priority_Reactor, "$Id: Priority_Reactor.cpp,v 1.1.1.3.40.1 2003/03/13 19:44:22 chad Exp $")
00008 
00009 typedef ACE_Unbounded_Queue_Iterator<ACE_Event_Tuple> QUEUE_ITERATOR;
00010 // Its iterator.
00011 
00012 typedef ACE_Cached_Allocator<ACE_Node<ACE_Event_Tuple>, ACE_SYNCH_NULL_MUTEX> TUPLE_ALLOCATOR;
00013 // Defines the memory allocator used, no need for locking because it
00014 // is only used in one thread of control.
00015 
00016 ACE_ALLOC_HOOK_DEFINE(ACE_Priority_Reactor)
00017 
00018 // Initialize ACE_Select_Reactor.
00019 
00020 #define npriorities \
00021         ACE_Event_Handler::HI_PRIORITY-ACE_Event_Handler::LO_PRIORITY+1
00022 
00023 void
00024 ACE_Priority_Reactor::init_bucket (void)
00025 {
00026   // Allocate enough space for all the handles.
00027   // TODO: This can be wrong, maybe we should use other kind of
00028   // allocator here?
00029   ACE_NEW (this->tuple_allocator_,
00030            TUPLE_ALLOCATOR (ACE_Select_Reactor::DEFAULT_SIZE));
00031 
00032   // The event handlers are assigned to a new As the Event
00033   ACE_NEW (this->bucket_,
00034            QUEUE *[npriorities]);
00035 
00036   // This loops "ensures" exception safety.
00037   for (int i = 0; i < npriorities; ++i)
00038     ACE_NEW (this->bucket_[i],
00039              QUEUE (this->tuple_allocator_));
00040 }
00041 
00042 ACE_Priority_Reactor::ACE_Priority_Reactor (ACE_Sig_Handler *sh,
00043                                             ACE_Timer_Queue *tq)
00044   : ACE_Select_Reactor(sh, tq),
00045     bucket_ (0),
00046     tuple_allocator_ (0)
00047 {
00048   ACE_TRACE ("ACE_Priority_Reactor::ACE_Priority_Reactor");
00049   this->init_bucket ();
00050 }
00051 
00052 ACE_Priority_Reactor::ACE_Priority_Reactor (size_t size,
00053                                             int rs,
00054                                             ACE_Sig_Handler *sh,
00055                                             ACE_Timer_Queue *tq)
00056   : ACE_Select_Reactor (size, rs, sh, tq),
00057     bucket_ (0),
00058     tuple_allocator_ (0)
00059 {
00060   ACE_TRACE ("ACE_Priority_Reactor::ACE_Priority_Reactor");
00061   this->init_bucket ();
00062 }
00063 
00064 ACE_Priority_Reactor::~ACE_Priority_Reactor (void)
00065 {
00066   ACE_TRACE ("ACE_Priority_Reactor::~ACE_Priority_Reactor");
00067 
00068   for (int i = 0; i < npriorities; ++i)
00069     delete this->bucket_[i];
00070 
00071   delete[] this->bucket_;
00072   delete tuple_allocator_;
00073 }
00074 
00075 int
00076 ACE_Priority_Reactor::dispatch_io_set (int number_of_active_handles,
00077                                        int& number_dispatched,
00078                                        int mask,
00079                                        ACE_Handle_Set& dispatch_mask,
00080                                        ACE_Handle_Set& ready_mask,
00081                                        ACE_EH_PTMF callback)
00082 {
00083   ACE_TRACE ("ACE_Priority_Reactor::dispatch_io_set");
00084 
00085   if (number_of_active_handles == 0)
00086     return 0;
00087 
00088   // The range for which there exists any Event_Tuple is computed on
00089   // the ordering loop, minimizing iterations on the dispatching loop.
00090   int min_priority = ACE_Event_Handler::HI_PRIORITY;
00091   int max_priority = ACE_Event_Handler::LO_PRIORITY;
00092 
00093   ACE_Handle_Set_Iterator handle_iter (dispatch_mask);
00094 
00095   for (ACE_HANDLE handle;
00096        (handle = handle_iter ()) != ACE_INVALID_HANDLE;
00097        )
00098     {
00099       ACE_Event_Tuple et (this->handler_rep_.find (handle),
00100                           handle);
00101       int prio = et.event_handler_->priority ();
00102 
00103       // If the priority is out of range assign the minimum priority.
00104       if (prio < ACE_Event_Handler::LO_PRIORITY
00105           || prio > ACE_Event_Handler::HI_PRIORITY)
00106         prio = ACE_Event_Handler::LO_PRIORITY;
00107 
00108       bucket_[prio]->enqueue_tail (et);
00109 
00110       // Update the priority ranges....
00111       if (min_priority > prio)
00112         min_priority = prio;
00113       if (max_priority < prio)
00114         max_priority = prio;
00115     }
00116 
00117   for (int i = max_priority; i >= min_priority; --i)
00118     {
00119       // Remove all the entries from the wrappers
00120       while (!bucket_[i]->is_empty ()
00121              && number_dispatched < number_of_active_handles
00122              && this->state_changed_ == 0)
00123         {
00124           ACE_Event_Tuple et;
00125           bucket_[i]->dequeue_head (et);
00126           this->notify_handle (et.handle_,
00127                                mask,
00128                                ready_mask,
00129                                et.event_handler_,
00130                                callback);
00131           number_dispatched++;
00132         }
00133       // Even if we are aborting the loop due to this->state_changed
00134       // or another error we still want to cleanup the buckets.
00135       bucket_[i]->reset ();
00136     }
00137 
00138   if (number_dispatched > 0 && this->state_changed_)
00139     return -1;
00140 
00141   return 0;
00142 }
00143 
00144 void
00145 ACE_Priority_Reactor::dump (void) const
00146 {
00147   ACE_TRACE ("ACE_Priority_Reactor::dump");
00148 
00149   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00150 
00151   ACE_Select_Reactor::dump ();
00152 
00153   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00154 }
00155 
00156 #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
00157 template class ACE_Unbounded_Queue<ACE_Event_Tuple>;
00158 template class ACE_Unbounded_Queue_Iterator<ACE_Event_Tuple>;
00159 template class ACE_Node<ACE_Event_Tuple>;
00160 template class ACE_Cached_Allocator<ACE_Node<ACE_Event_Tuple>, ACE_SYNCH_NULL_MUTEX>;
00161 template class ACE_Locked_Free_List<ACE_Cached_Mem_Pool_Node<ACE_Node<ACE_Event_Tuple> >,ACE_SYNCH_NULL_MUTEX>;
00162 template class ACE_Free_List<ACE_Cached_Mem_Pool_Node<ACE_Node<ACE_Event_Tuple> > >;
00163 template class ACE_Cached_Mem_Pool_Node<ACE_Node<ACE_Event_Tuple> >;
00164 #elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
00165 #pragma instantiate ACE_Unbounded_Queue<ACE_Event_Tuple>
00166 #pragma instantiate ACE_Unbounded_Queue_Iterator<ACE_Event_Tuple>
00167 #pragma instantiate ACE_Node<ACE_Event_Tuple>
00168 #pragma instantiate ACE_Cached_Allocator<ACE_Node<ACE_Event_Tuple>, ACE_SYNCH_NULL_MUTEX>
00169 #pragma instantiate ACE_Locked_Free_List<ACE_Cached_Mem_Pool_Node<ACE_Node<ACE_Event_Tuple> >,ACE_SYNCH_NULL_MUTEX>
00170 #pragma instantiate ACE_Free_List<ACE_Cached_Mem_Pool_Node<ACE_Node<ACE_Event_Tuple> > >
00171 #pragma instantiate ACE_Cached_Mem_Pool_Node<ACE_Node<ACE_Event_Tuple> >
00172 #endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */

Generated on Mon Jun 16 11:20:52 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002