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 }
1.2.14 written by Dimitri van Heesch,
© 1997-2002