Dev_Poll_Reactor.inl

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Dev_Poll_Reactor.inl,v 4.8 2005/10/28 16:14:52 ossama Exp
00004 
00005 #include "ace/Log_Msg.h"
00006 
00007 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00008 
00009 ACE_INLINE
00010 ACE_Dev_Poll_Event_Tuple::ACE_Dev_Poll_Event_Tuple (void)
00011   : event_handler (0),
00012     mask (ACE_Event_Handler::NULL_MASK),
00013     suspended (0)
00014 {
00015 }
00016 
00017 // ---------------------------------------------------------------------
00018 
00019 #if 0
00020 ACE_INLINE
00021 ACE_Dev_Poll_Ready_Set::ACE_Dev_Poll_Ready_Set (void)
00022   : pfds (0),
00023     nfds (0)
00024 {
00025 }
00026 #endif  /* 0 */
00027 
00028 // ---------------------------------------------------------------------
00029 
00030 ACE_INLINE void
00031 ACE_Dev_Poll_Reactor_Handler_Repository::mask (ACE_HANDLE handle,
00032                                                ACE_Reactor_Mask mask)
00033 {
00034   ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::mask");
00035 
00036   // Only bother to search for the handle if it's in range.
00037   if (this->handle_in_range (handle))
00038     this->handlers_[handle].mask = mask;
00039 }
00040 
00041 ACE_INLINE ACE_Reactor_Mask
00042 ACE_Dev_Poll_Reactor_Handler_Repository::mask (ACE_HANDLE handle)
00043 {
00044   ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::mask");
00045 
00046   ACE_Reactor_Mask mask = ACE_Event_Handler::NULL_MASK;
00047 
00048   // Only bother to search for the handle if it's in range.
00049   if (this->handle_in_range (handle))
00050     mask = this->handlers_[handle].mask;
00051 
00052   if (mask == ACE_Event_Handler::NULL_MASK)
00053     errno = ENOENT;
00054 
00055   return mask;
00056 }
00057 
00058 ACE_INLINE void
00059 ACE_Dev_Poll_Reactor_Handler_Repository::suspend (ACE_HANDLE handle)
00060 {
00061   ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::suspend");
00062 
00063   // Only bother to search for the handle if it's in range.
00064   if (this->handle_in_range (handle))
00065     this->handlers_[handle].suspended = 1;
00066 }
00067 
00068 ACE_INLINE void
00069 ACE_Dev_Poll_Reactor_Handler_Repository::resume (ACE_HANDLE handle)
00070 {
00071   ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::resume");
00072 
00073   // Only bother to search for the handle if it's in range.
00074   if (this->handle_in_range (handle))
00075     this->handlers_[handle].suspended = 0;
00076 }
00077 
00078 ACE_INLINE int
00079 ACE_Dev_Poll_Reactor_Handler_Repository::suspended (ACE_HANDLE handle) const
00080 {
00081   ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::suspended");
00082 
00083   if (this->handle_in_range (handle))
00084     return this->handlers_[handle].suspended;
00085 
00086   return -1;
00087 }
00088 
00089 ACE_INLINE size_t
00090 ACE_Dev_Poll_Reactor_Handler_Repository::size (void) const
00091 {
00092   ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::size");
00093 
00094   return this->max_size_;
00095 }
00096 
00097 // -----------------------------------------------------------------
00098 
00099 ACE_INLINE
00100 ACE_Dev_Poll_Handler_Guard::ACE_Dev_Poll_Handler_Guard
00101   (ACE_Event_Handler *eh,
00102    bool do_incr)
00103   : eh_ (eh),
00104     refcounted_ (false)
00105 {
00106   if (eh == 0)
00107     return;
00108 
00109   this->refcounted_ =
00110     eh->reference_counting_policy ().value () ==
00111     ACE_Event_Handler::Reference_Counting_Policy::ENABLED;
00112 
00113   if (do_incr && this->refcounted_)
00114     eh->add_reference ();
00115 
00116   /**
00117    * The below comments were here when I replaced the old refcount
00118    * scheme was replaced. They may still need addressing.   -Steve Huston
00119    */
00120 
00121   /**
00122    * @todo Suspend the handler so that other threads will not cause
00123    *       an event that is already in an upcall from being dispatched
00124    *       again.
00125    *
00126    * @note The naive approach would be to simply call
00127    *       suspend_handler_i() on the reactor.  However, that would
00128    *       cause a system call (write()) to occur.  Obviously this
00129    *       can potentially have an adverse affect on performance.
00130    *       Ideally, the handler would only be marked as "suspended" in
00131    *       the handler repository.  If an event arrives for a
00132    *       suspended handler that event can be "queued" in a
00133    *       "handle readiness queue."  "Queued" is quoted since a real
00134    *       queue need not be used since duplicate events can be
00135    *       coalesced, thus avoiding unbounded queue growth.  Event
00136    *       coalescing is already done by Linux's event poll driver
00137    *       (/dev/epoll) so Solaris' poll driver (/dev/poll) is the
00138    *       main concern here.  The largest the queue can be is the
00139    *       same size as the number of handlers stored in the handler
00140    *       repository.
00141    */
00142 }
00143 
00144 ACE_INLINE
00145 ACE_Dev_Poll_Handler_Guard::~ACE_Dev_Poll_Handler_Guard (void)
00146 {
00147   if (this->refcounted_ && this->eh_ != 0)
00148     this->eh_->remove_reference ();
00149 
00150   /**
00151    * The below comments were here when I replaced the old refcount
00152    * scheme was replaced. They may still need addressing.   -Steve Huston
00153    */
00154   /**
00155    * @todo Resume the handler so that other threads will be allowed to
00156    *       dispatch the handler.
00157    */
00158 }
00159 
00160 ACE_INLINE void
00161 ACE_Dev_Poll_Handler_Guard::release (void)
00162 {
00163   this->eh_ = 0;
00164 }
00165 
00166 // ---------------------------------------------------------------------
00167 
00168 ACE_INLINE int
00169 ACE_Dev_Poll_Reactor::upcall (ACE_Event_Handler *event_handler,
00170                               int (ACE_Event_Handler::*callback)(ACE_HANDLE),
00171                               ACE_HANDLE handle)
00172 {
00173   // If the handler returns positive value (requesting a reactor
00174   // callback) just call back as many times as the handler requests
00175   // it.  Other threads are off handling other things.
00176   int status = 0;
00177 
00178   do
00179     {
00180       status = (event_handler->*callback) (handle);
00181     }
00182   while (status > 0);
00183 
00184   return status;
00185 }
00186 
00187 
00188 /************************************************************************/
00189 // Methods for ACE_Dev_Poll_Reactor::Token_Guard
00190 /************************************************************************/
00191 
00192 ACE_INLINE
00193 ACE_Dev_Poll_Reactor::Token_Guard::Token_Guard (ACE_Dev_Poll_Reactor_Token &token)
00194 
00195   : token_ (token),
00196     owner_ (0)
00197 {
00198 }
00199 
00200 ACE_INLINE
00201 ACE_Dev_Poll_Reactor::Token_Guard::~Token_Guard (void)
00202 {
00203   if (this->owner_ == 1)
00204     {
00205       ACE_MT (this->token_.release ());
00206       this->owner_ = 0;
00207     }
00208 }
00209 
00210 ACE_INLINE void
00211 ACE_Dev_Poll_Reactor::Token_Guard::release_token (void)
00212 {
00213   if (this->owner_)
00214     {
00215       ACE_MT (this->token_.release ());
00216 
00217       // We are not the owner anymore..
00218       this->owner_ = 0;
00219     }
00220 }
00221 
00222 ACE_INLINE int
00223 ACE_Dev_Poll_Reactor::Token_Guard::is_owner (void)
00224 {
00225   return this->owner_;
00226 }
00227 
00228 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Thu Nov 9 09:41:50 2006 for ACE by doxygen 1.3.6