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

Dev_Poll_Reactor.inl

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // $Id: Dev_Poll_Reactor.inl,v 1.1.1.1 2003/02/21 18:36:32 chad Exp $
00004 
00005 ACE_INLINE
00006 ACE_Dev_Poll_Event_Tuple::ACE_Dev_Poll_Event_Tuple (void)
00007   : event_handler (0),
00008     mask (ACE_Event_Handler::NULL_MASK),
00009     suspended (0),
00010     refcount (1)
00011 {
00012 }
00013 
00014 // ---------------------------------------------------------------------
00015 
00016 #if 0
00017 ACE_INLINE
00018 ACE_Dev_Poll_Ready_Set::ACE_Dev_Poll_Ready_Set (void)
00019   : pfds (0),
00020     nfds (0)
00021 {
00022 }
00023 #endif  /* 0 */
00024 
00025 // ---------------------------------------------------------------------
00026 
00027 ACE_INLINE void
00028 ACE_Dev_Poll_Reactor_Handler_Repository::mask (ACE_HANDLE handle,
00029                                                ACE_Reactor_Mask mask)
00030 {
00031   ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::mask");
00032 
00033   // Only bother to search for the handle if it's in range.
00034   if (this->handle_in_range (handle))
00035     this->handlers_[handle].mask = mask;
00036 }
00037 
00038 ACE_INLINE ACE_Reactor_Mask
00039 ACE_Dev_Poll_Reactor_Handler_Repository::mask (ACE_HANDLE handle)
00040 {
00041   ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::mask");
00042 
00043   ACE_Reactor_Mask mask = ACE_Event_Handler::NULL_MASK;
00044 
00045   // Only bother to search for the handle if it's in range.
00046   if (this->handle_in_range (handle))
00047     mask = this->handlers_[handle].mask;
00048 
00049   if (mask == ACE_Event_Handler::NULL_MASK)
00050     errno = ENOENT;
00051 
00052   return mask;
00053 }
00054 
00055 ACE_INLINE void
00056 ACE_Dev_Poll_Reactor_Handler_Repository::suspend (ACE_HANDLE handle)
00057 {
00058   ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::suspend");
00059 
00060   // Only bother to search for the handle if it's in range.
00061   if (this->handle_in_range (handle))
00062     this->handlers_[handle].suspended = 1;
00063 }
00064 
00065 ACE_INLINE void
00066 ACE_Dev_Poll_Reactor_Handler_Repository::resume (ACE_HANDLE handle)
00067 {
00068   ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::resume");
00069 
00070   // Only bother to search for the handle if it's in range.
00071   if (this->handle_in_range (handle))
00072     this->handlers_[handle].suspended = 0;
00073 }
00074 
00075 ACE_INLINE int
00076 ACE_Dev_Poll_Reactor_Handler_Repository::suspended (ACE_HANDLE handle) const
00077 {
00078   ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::suspended");
00079 
00080   if (this->handle_in_range (handle))
00081     return this->handlers_[handle].suspended;
00082 
00083   return -1;
00084 }
00085 
00086 ACE_INLINE size_t
00087 ACE_Dev_Poll_Reactor_Handler_Repository::size (void) const
00088 {
00089   ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::size");
00090 
00091   return this->max_size_;
00092 }
00093 
00094 ACE_INLINE unsigned long
00095 ACE_Dev_Poll_Reactor_Handler_Repository::add_ref (ACE_HANDLE handle)
00096 {
00097   // ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::add_ref");
00098 
00099   // Caller provides synchronization
00100 
00101   if (this->handle_in_range (handle))
00102     return this->handlers_[handle].refcount++;
00103 
00104   return 0;
00105 }
00106 
00107 ACE_INLINE unsigned long
00108 ACE_Dev_Poll_Reactor_Handler_Repository::remove_ref (ACE_HANDLE handle)
00109 {
00110   // ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::remove_ref");
00111 
00112   // Caller provides synchronization
00113 
00114   if (this->handle_in_range (handle))
00115     {
00116       unsigned long & refcount = this->handlers_[handle].refcount;
00117 
00118       ACE_ASSERT  (refcount > 0);
00119 
00120       refcount--;
00121 
00122       if (refcount != 0)
00123         return refcount;
00124 
00125       // Reference count dropped to zero.  Remove the event handler
00126       // from the repository.
00127       this->unbind (handle);
00128     }
00129 
00130   return 0;
00131 }
00132 
00133 // -----------------------------------------------------------------
00134 
00135 ACE_INLINE
00136 ACE_Dev_Poll_Handler_Guard::ACE_Dev_Poll_Handler_Guard (
00137   ACE_Dev_Poll_Reactor_Handler_Repository &repository,
00138   ACE_HANDLE handle)
00139   : repository_ (repository),
00140     handle_ (handle)
00141 {
00142   // Caller must provide synchronization.
00143 
00144   (void) repository.add_ref (handle);
00145 
00146   /**
00147    * @todo Suspend the handler so that other threads will not cause
00148    *       an event that is already in an upcall from being dispatched
00149    *       again.
00150    *
00151    * @note The naive approach would be to simply call
00152    *       suspend_handler_i() on the reactor.  However, that would
00153    *       cause a system call (write()) to occur.  Obviously this
00154    *       can potentially have an adverse affect on performance.
00155    *       Ideally, the handler would only be marked as "suspended" in
00156    *       the handler repository.  If an event arrives for a
00157    *       suspended handler that event can be "queued" in a
00158    *       "handle readiness queue."  "Queued" is quoted since a real
00159    *       queue need not be used since duplicate events can be
00160    *       coalesced, thus avoiding unbounded queue growth.  Event
00161    *       coalescing is already done by Linux's event poll driver
00162    *       (/dev/epoll) so Solaris' poll driver (/dev/poll) is the
00163    *       main concern here.  The largest the queue can be is the
00164    *       same size as the number of handlers stored in the handler
00165    *       repository.
00166    */
00167 }
00168 
00169 ACE_INLINE
00170 ACE_Dev_Poll_Handler_Guard::~ACE_Dev_Poll_Handler_Guard (void)
00171 {
00172   // Caller must provide synchronization.
00173 
00174   (void) this->repository_.remove_ref (this->handle_);
00175 
00176   /**
00177    * @todo Resume the handler so that other threads will be allowed to
00178    *       dispatch the handler.
00179    */
00180 }
00181 
00182 // ---------------------------------------------------------------------
00183 
00184 ACE_INLINE int
00185 ACE_Dev_Poll_Reactor::upcall (ACE_Event_Handler *event_handler,
00186                               int (ACE_Event_Handler::*callback)(ACE_HANDLE),
00187                               ACE_HANDLE handle)
00188 {
00189   // If the handler returns positive value (requesting a reactor
00190   // callback) just call back as many times as the handler requests
00191   // it.  Other threads are off handling other things.
00192   int status = 0;
00193 
00194   do
00195     {
00196       status = (event_handler->*callback) (handle);
00197     }
00198   while (status > 0);
00199 
00200   return status;
00201 }

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