#include <Select_Reactor_Base.h>
Collaboration diagram for ACE_Select_Reactor_Handler_Repository:
Public Types | |
typedef ACE_HANDLE | key_type |
typedef ACE_Event_Handler * | value_type |
typedef ACE_Array_Base< value_type > | map_type |
typedef ACE_HANDLE | max_handlep1_type |
typedef map_type::size_type | size_type |
Public Member Functions | |
ACE_Select_Reactor_Handler_Repository (ACE_Select_Reactor_Impl &) | |
Default "do-nothing" constructor. | |
int | open (size_type size) |
Initialize a repository of the appropriate size. | |
int | close (void) |
Close down the repository. | |
ACE_Event_Handler * | find (ACE_HANDLE handle) |
int | bind (ACE_HANDLE, ACE_Event_Handler *, ACE_Reactor_Mask) |
int | unbind (ACE_HANDLE, ACE_Reactor_Mask mask) |
Remove the binding of ACE_HANDLE in accordance with the mask. | |
int | unbind_all (void) |
Remove all the <ACE_HANDLE, ACE_Event_Handler> tuples. | |
bool | invalid_handle (ACE_HANDLE handle) |
bool | handle_in_range (ACE_HANDLE handle) |
size_type | size (void) const |
Returns the current table size. | |
max_handlep1_type | max_handlep1 (void) const |
Maximum ACE_HANDLE value, plus 1. | |
void | dump (void) const |
Dump the state of an object. | |
Public Attributes | |
ACE_ALLOC_HOOK_DECLARE | |
Declare the dynamic allocation hooks. | |
Private Member Functions | |
int | unbind (ACE_HANDLE handle, map_type::iterator pos, ACE_Reactor_Mask mask) |
map_type::iterator | find_eh (ACE_HANDLE handle) |
Private Attributes | |
ACE_Select_Reactor_Impl & | select_reactor_ |
Reference to our Select_Reactor . | |
max_handlep1_type | max_handlep1_ |
map_type | event_handlers_ |
Underlying table of event handlers. | |
Friends | |
class | ACE_Select_Reactor_Handler_Repository_Iterator |
This class is necessary to shield differences between UNIX and Win32. In UNIX, ACE_HANDLE is an int, whereas in Win32 it's a void *. This class hides all these details from the bulk of the ACE_Select_Reactor code. All of these methods are called with the main <Select_Reactor> token lock held.
Definition at line 282 of file Select_Reactor_Base.h.
typedef ACE_HANDLE ACE_Select_Reactor_Handler_Repository::key_type |
Definition at line 287 of file Select_Reactor_Base.h.
The UNIX version implements this via a dynamically allocated array of ACE_Event_Handler*
that is indexed directly using the ACE_HANDLE
value.
Definition at line 311 of file Select_Reactor_Base.h.
typedef ACE_HANDLE ACE_Select_Reactor_Handler_Repository::max_handlep1_type |
Definition at line 312 of file Select_Reactor_Base.h.
Definition at line 315 of file Select_Reactor_Base.h.
Definition at line 288 of file Select_Reactor_Base.h.
ACE_Select_Reactor_Handler_Repository::ACE_Select_Reactor_Handler_Repository | ( | ACE_Select_Reactor_Impl & | ) |
Default "do-nothing" constructor.
int ACE_Select_Reactor_Handler_Repository::bind | ( | ACE_HANDLE | , | |
ACE_Event_Handler * | , | |||
ACE_Reactor_Mask | ||||
) |
Bind the ACE_Event_Handler * to the ACE_HANDLE with the appropriate ACE_Reactor_Mask settings.
Definition at line 193 of file Select_Reactor_Base.cpp.
References ACE_TRACE, ACE_Reactor::ADD_MASK, ACE_Event_Handler::add_reference(), ACE_Select_Reactor_Impl::bit_ops(), event_handlers_, ACE_Event_Handler::get_handle(), max_handlep1_, and select_reactor_.
00196 { 00197 ACE_TRACE ("ACE_Select_Reactor_Handler_Repository::bind"); 00198 00199 if (event_handler == 0) 00200 return -1; 00201 00202 if (handle == ACE_INVALID_HANDLE) 00203 handle = event_handler->get_handle (); 00204 00205 if (this->invalid_handle (handle)) 00206 return -1; 00207 00208 // Is this handle already in the Reactor? 00209 bool existing_handle = false; 00210 00211 #if defined (ACE_WIN32) 00212 00213 map_type::ENTRY * entry = 0; 00214 00215 int const result = 00216 this->event_handlers_.bind (handle, event_handler, entry); 00217 00218 if (result == -1) 00219 { 00220 return -1; 00221 } 00222 else if (result == 1) // Entry already exists. 00223 { 00224 // Cannot use a different handler for an existing handle. 00225 if (event_handler != entry->item ()) 00226 { 00227 return -1; 00228 } 00229 else 00230 { 00231 // Remember that this handle is already registered in the 00232 // Reactor. 00233 existing_handle = true; 00234 } 00235 } 00236 00237 #else 00238 00239 // Check if this handle is already registered. 00240 ACE_Event_Handler * const current_handler = 00241 this->event_handlers_[handle]; 00242 00243 if (current_handler) 00244 { 00245 // Cannot use a different handler for an existing handle. 00246 if (current_handler != event_handler) 00247 return -1; 00248 00249 // Remember that this handle is already registered in the 00250 // Reactor. 00251 existing_handle = true; 00252 } 00253 00254 this->event_handlers_[handle] = event_handler; 00255 00256 if (this->max_handlep1_ < handle + 1) 00257 this->max_handlep1_ = handle + 1; 00258 00259 #endif /* ACE_WIN32 */ 00260 00261 if (this->select_reactor_.is_suspended_i (handle)) 00262 { 00263 this->select_reactor_.bit_ops (handle, 00264 mask, 00265 this->select_reactor_.suspend_set_, 00266 ACE_Reactor::ADD_MASK); 00267 } 00268 else 00269 { 00270 this->select_reactor_.bit_ops (handle, 00271 mask, 00272 this->select_reactor_.wait_set_, 00273 ACE_Reactor::ADD_MASK); 00274 00275 // Note the fact that we've changed the state of the <wait_set_>, 00276 // which is used by the dispatching loop to determine whether it can 00277 // keep going or if it needs to reconsult select(). 00278 // this->select_reactor_.state_changed_ = 1; 00279 } 00280 00281 // If new entry, call add_reference() if needed. 00282 if (!existing_handle) 00283 event_handler->add_reference (); 00284 00285 return 0; 00286 }
int ACE_Select_Reactor_Handler_Repository::close | ( | void | ) |
Close down the repository.
Definition at line 164 of file Select_Reactor_Base.cpp.
References ACE_TRACE, and unbind_all().
Referenced by ACE_Select_Reactor_T< ACE_SELECT_REACTOR_TOKEN >::close().
00165 { 00166 ACE_TRACE ("ACE_Select_Reactor_Handler_Repository::close"); 00167 00168 return this->unbind_all (); 00169 }
void ACE_Select_Reactor_Handler_Repository::dump | ( | void | ) | const |
Dump the state of an object.
Definition at line 496 of file Select_Reactor_Base.cpp.
References ACE_BEGIN_DUMP, ACE_DEBUG, ACE_END_DUMP, ACE_TEXT, ACE_TRACE, and LM_DEBUG.
Referenced by ACE_Select_Reactor_T< ACE_SELECT_REACTOR_TOKEN >::dump().
00497 { 00498 #if defined (ACE_HAS_DUMP) 00499 ACE_TRACE ("ACE_Select_Reactor_Handler_Repository::dump"); 00500 00501 # ifdef ACE_WIN32 00502 # define ACE_HANDLE_FORMAT_SPECIFIER ACE_TEXT("%@") # define ACE_MAX_HANDLEP1_FORMAT_SPECIFIER ACE_TEXT("%u") 00503 # else 00504 # define ACE_HANDLE_FORMAT_SPECIFIER ACE_TEXT("%d") 00505 # define ACE_MAX_HANDLEP1_FORMAT_SPECIFIER ACE_TEXT("%d") 00506 # endif /* ACE_WIN32 */ 00507 00508 ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); 00509 ACE_DEBUG ((LM_DEBUG, 00510 ACE_TEXT ("max_handlep1_ = ") 00511 ACE_MAX_HANDLEP1_FORMAT_SPECIFIER 00512 ACE_TEXT ("\n"), 00513 this->max_handlep1 ())); 00514 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("["))); 00515 00516 ACE_Event_Handler *event_handler = 0; 00517 00518 for (ACE_Select_Reactor_Handler_Repository_Iterator iter (this); 00519 iter.next (event_handler) != 0; 00520 iter.advance ()) 00521 ACE_DEBUG ((LM_DEBUG, 00522 ACE_TEXT (" (event_handler = %@,") 00523 ACE_TEXT (" event_handler->handle_ = ") 00524 ACE_HANDLE_FORMAT_SPECIFIER 00525 ACE_TEXT ("\n"), 00526 event_handler, 00527 event_handler->get_handle ())); 00528 00529 ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" ]\n"))); 00530 ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); 00531 #endif /* ACE_HAS_DUMP */ 00532 } 00533
ACE_INLINE ACE_Event_Handler * ACE_Select_Reactor_Handler_Repository::find | ( | ACE_HANDLE | handle | ) |
Return the ACE_Event_Handler*
associated with ACE_HANDLE
.
Definition at line 44 of file Select_Reactor_Base.inl.
References ACE_TRACE.
Referenced by ACE_TP_Reactor::post_process_socket_event().
00045 { 00046 ACE_TRACE ("ACE_Select_Reactor_Handler_Repository::find"); 00047 00048 ACE_Event_Handler * eh = 0; 00049 00050 if (this->handle_in_range (handle)) 00051 { 00052 map_type::iterator const pos = this->find_eh (handle); 00053 00054 if (pos != this->event_handlers_.end ()) 00055 { 00056 #ifdef ACE_WIN32 00057 eh = (*pos).item (); 00058 #else 00059 eh = *pos; 00060 #endif /* ACE_WIN32 */ 00061 } 00062 } 00063 // Don't bother setting errno. It isn't used in the select()-based 00064 // reactors and incurs a TSS access. 00065 // else 00066 // { 00067 // errno = ENOENT; 00068 // } 00069 00070 return eh; 00071 }
ACE_Select_Reactor_Handler_Repository::map_type::iterator ACE_Select_Reactor_Handler_Repository::find_eh | ( | ACE_HANDLE | handle | ) | [private] |
iterator
corresponding ACE_Event_Handler*
associated with ACE_HANDLE
. Definition at line 172 of file Select_Reactor_Base.cpp.
References ACE_TRACE, and event_handlers_.
00173 { 00174 ACE_TRACE ("ACE_Select_Reactor_Handler_Repository::find_eh"); 00175 00176 map_type::iterator pos (this->event_handlers_.end ()); 00177 00178 // this code assumes the handle is in range. 00179 #if defined (ACE_WIN32) 00180 this->event_handlers_.find (handle, pos); 00181 #else 00182 map_type::iterator const tmp = &this->event_handlers_[handle]; 00183 00184 if (*tmp != 0) 00185 pos = tmp; 00186 #endif /* ACE_WIN32 */ 00187 00188 return pos; 00189 }
bool ACE_Select_Reactor_Handler_Repository::handle_in_range | ( | ACE_HANDLE | handle | ) |
Referenced by unbind().
bool ACE_Select_Reactor_Handler_Repository::invalid_handle | ( | ACE_HANDLE | handle | ) |
ACE_INLINE ACE_Select_Reactor_Handler_Repository::max_handlep1_type ACE_Select_Reactor_Handler_Repository::max_handlep1 | ( | void | ) | const |
Maximum ACE_HANDLE value, plus 1.
Definition at line 20 of file Select_Reactor_Base.inl.
References event_handlers_, and max_handlep1_.
Referenced by ACE_Select_Reactor_Handler_Repository_Iterator::advance(), and ACE_Select_Reactor_Handler_Repository_Iterator::done().
00021 { 00022 #ifdef ACE_WIN32 00023 return this->event_handlers_.current_size (); 00024 #else 00025 return this->max_handlep1_; 00026 #endif /* ACE_WIN32 */ 00027 }
int ACE_Select_Reactor_Handler_Repository::open | ( | size_type | size | ) |
Initialize a repository of the appropriate size.
On Unix platforms, the size parameter should be as large as the maximum number of file descriptors allowed for a given process. This is necessary since a file descriptor is used to directly index the array of event handlers maintained by the Reactor's handler repository. Direct indexing is used for efficiency reasons.
ACE_BEGIN_VERSIONED_NAMESPACE_DECL ACE_INLINE ACE_Select_Reactor_Handler_Repository::size_type ACE_Select_Reactor_Handler_Repository::size | ( | void | ) | const |
Returns the current table size.
Definition at line 10 of file Select_Reactor_Base.inl.
References event_handlers_, and ACE_Array_Base< T >::size().
Referenced by ACE_Select_Reactor_T< ACE_SELECT_REACTOR_TOKEN >::size().
00011 { 00012 #ifdef ACE_WIN32 00013 return this->event_handlers_.total_size (); 00014 #else 00015 return this->event_handlers_.size (); 00016 #endif /* ACE_WIN32 */ 00017 }
int ACE_Select_Reactor_Handler_Repository::unbind | ( | ACE_HANDLE | handle, | |
map_type::iterator | pos, | |||
ACE_Reactor_Mask | mask | |||
) | [private] |
Remove the binding of handle corresponding to position pos in accordance with the mask.
Definition at line 291 of file Select_Reactor_Base.cpp.
References ACE_BIT_ENABLED, ACE_TRACE, ACE_Select_Reactor_Impl::bit_ops(), ACE_Reactor::CLR_MASK, ACE_Event_Handler::DONT_CALL, ACE_Event_Handler::Reference_Counting_Policy::ENABLED, ACE_Array_Base< T >::end(), event_handlers_, ACE_Select_Reactor_Handle_Set::ex_mask_, ACE_Event_Handler::handle_close(), ACE_Handle_Set::is_set(), max_handlep1_, ACE_Handle_Set::max_set(), ACE_Select_Reactor_Handle_Set::rd_mask_, ACE_Event_Handler::reference_counting_policy(), ACE_Event_Handler::remove_reference(), select_reactor_, ACE_Select_Reactor_Impl::suspend_set_, ACE_Select_Reactor_Impl::wait_set_, and ACE_Select_Reactor_Handle_Set::wr_mask_.
00295 { 00296 ACE_TRACE ("ACE_Select_Reactor_Handler_Repository::unbind"); 00297 00298 // Retrieve event handler before unbinding it from the map. The 00299 // iterator pointing to it will no longer be valid once the handler 00300 // is unbound. 00301 ACE_Event_Handler * const event_handler = 00302 (pos == this->event_handlers_.end () 00303 ? 0 00304 : ACE_SELECT_REACTOR_EVENT_HANDLER (pos)); 00305 00306 // Clear out the <mask> bits in the Select_Reactor's wait_set. 00307 this->select_reactor_.bit_ops (handle, 00308 mask, 00309 this->select_reactor_.wait_set_, 00310 ACE_Reactor::CLR_MASK); 00311 00312 // And suspend_set. 00313 this->select_reactor_.bit_ops (handle, 00314 mask, 00315 this->select_reactor_.suspend_set_, 00316 ACE_Reactor::CLR_MASK); 00317 00318 // Note the fact that we've changed the state of the <wait_set_>, 00319 // which is used by the dispatching loop to determine whether it can 00320 // keep going or if it needs to reconsult select(). 00321 // this->select_reactor_.state_changed_ = 1; 00322 00323 // If there are no longer any outstanding events on this <handle> 00324 // then we can totally shut down the Event_Handler. 00325 00326 bool const has_any_wait_mask = 00327 (this->select_reactor_.wait_set_.rd_mask_.is_set (handle) 00328 || this->select_reactor_.wait_set_.wr_mask_.is_set (handle) 00329 || this->select_reactor_.wait_set_.ex_mask_.is_set (handle)); 00330 bool const has_any_suspend_mask = 00331 (this->select_reactor_.suspend_set_.rd_mask_.is_set (handle) 00332 || this->select_reactor_.suspend_set_.wr_mask_.is_set (handle) 00333 || this->select_reactor_.suspend_set_.ex_mask_.is_set (handle)); 00334 00335 bool complete_removal = false; 00336 00337 if (!has_any_wait_mask && !has_any_suspend_mask) 00338 { 00339 #if defined (ACE_WIN32) 00340 if (event_handler != 0 && this->event_handlers_.unbind (pos) == -1) 00341 return -1; // Should not happen! 00342 #else 00343 this->event_handlers_[handle] = 0; 00344 00345 if (this->max_handlep1_ == handle + 1) 00346 { 00347 // We've deleted the last entry, so we need to figure out 00348 // the last valid place in the array that is worth looking 00349 // at. 00350 ACE_HANDLE const wait_rd_max = 00351 this->select_reactor_.wait_set_.rd_mask_.max_set (); 00352 ACE_HANDLE const wait_wr_max = 00353 this->select_reactor_.wait_set_.wr_mask_.max_set (); 00354 ACE_HANDLE const wait_ex_max = 00355 this->select_reactor_.wait_set_.ex_mask_.max_set (); 00356 00357 ACE_HANDLE const suspend_rd_max = 00358 this->select_reactor_.suspend_set_.rd_mask_.max_set (); 00359 ACE_HANDLE const suspend_wr_max = 00360 this->select_reactor_.suspend_set_.wr_mask_.max_set (); 00361 ACE_HANDLE const suspend_ex_max = 00362 this->select_reactor_.suspend_set_.ex_mask_.max_set (); 00363 00364 // Compute the maximum of six values. 00365 this->max_handlep1_ = wait_rd_max; 00366 if (this->max_handlep1_ < wait_wr_max) 00367 this->max_handlep1_ = wait_wr_max; 00368 if (this->max_handlep1_ < wait_ex_max) 00369 this->max_handlep1_ = wait_ex_max; 00370 00371 if (this->max_handlep1_ < suspend_rd_max) 00372 this->max_handlep1_ = suspend_rd_max; 00373 if (this->max_handlep1_ < suspend_wr_max) 00374 this->max_handlep1_ = suspend_wr_max; 00375 if (this->max_handlep1_ < suspend_ex_max) 00376 this->max_handlep1_ = suspend_ex_max; 00377 00378 ++this->max_handlep1_; 00379 } 00380 00381 #endif /* ACE_WIN32 */ 00382 00383 // The handle has been completely removed. 00384 complete_removal = true; 00385 } 00386 00387 if (event_handler == 0) 00388 return -1; 00389 00390 bool const requires_reference_counting = 00391 event_handler->reference_counting_policy ().value () == 00392 ACE_Event_Handler::Reference_Counting_Policy::ENABLED; 00393 00394 // Close down the <Event_Handler> unless we've been instructed not 00395 // to. 00396 if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::DONT_CALL) == 0) 00397 (void) event_handler->handle_close (handle, mask); 00398 00399 // Call remove_reference() if the removal is complete and reference 00400 // counting is needed. 00401 if (complete_removal && requires_reference_counting) 00402 { 00403 (void) event_handler->remove_reference (); 00404 } 00405 00406 return 0; 00407 }
ACE_INLINE int ACE_Select_Reactor_Handler_Repository::unbind | ( | ACE_HANDLE | , | |
ACE_Reactor_Mask | mask | |||
) |
Remove the binding of ACE_HANDLE in accordance with the mask.
Definition at line 30 of file Select_Reactor_Base.inl.
References handle_in_range().
Referenced by ACE_TP_Reactor::handle_socket_events().
00032 { 00033 // Do not refactor this code to optimize the call to the unbind impl. 00034 // To resolve bug 2653, unbind must be called even when find_eh returns 00035 // event_handlers_.end(). 00036 00037 return !this->handle_in_range (handle) ? -1 00038 : this->unbind (handle, 00039 this->find_eh (handle), 00040 mask); 00041 }
int ACE_Select_Reactor_Handler_Repository::unbind_all | ( | void | ) |
Remove all the <ACE_HANDLE, ACE_Event_Handler> tuples.
Definition at line 123 of file Select_Reactor_Base.cpp.
References ACE_Event_Handler::ALL_EVENTS_MASK, ACE_Array_Base< T >::begin(), ACE_Array_Base< T >::end(), event_handlers_, and max_handlep1_.
Referenced by close().
00124 { 00125 // Unbind all of the <handle, ACE_Event_Handler>s. 00126 #ifdef ACE_WIN32 00127 map_type::iterator const end = this->event_handlers_.end (); 00128 for (map_type::iterator pos = this->event_handlers_.begin (); 00129 pos != end; 00130 ) 00131 { 00132 // Post-increment (*not* pre-increment) before unbind()ing since 00133 // the current iterator will be invalidated during the unbind() 00134 // operation. 00135 map_type::iterator const the_pos (pos++); 00136 00137 ACE_HANDLE const handle = (*the_pos).key (); 00138 (void) this->unbind (handle, 00139 the_pos, 00140 ACE_Event_Handler::ALL_EVENTS_MASK); 00141 } 00142 #else 00143 // We could use the "end()" iterator but leveraging max_handlep1_ 00144 // allows us to optimize away unnecessary accesses of nil event 00145 // handler pointers. 00146 map_type::iterator pos = 00147 this->event_handlers_.begin (); // iterator == ACE_Event_Handler* 00148 00149 for (ACE_HANDLE handle = 0; 00150 handle < this->max_handlep1_; 00151 ++handle) 00152 { 00153 (void) this->unbind (handle, 00154 pos, 00155 ACE_Event_Handler::ALL_EVENTS_MASK); 00156 ++pos; 00157 } 00158 #endif /* ACE_WIN32 */ 00159 00160 return 0; 00161 }
friend class ACE_Select_Reactor_Handler_Repository_Iterator [friend] |
Definition at line 285 of file Select_Reactor_Base.h.
Underlying table of event handlers.
Definition at line 404 of file Select_Reactor_Base.h.
Referenced by ACE_Select_Reactor_Handler_Repository_Iterator::advance(), bind(), ACE_Select_Reactor_Handler_Repository_Iterator::done(), find_eh(), max_handlep1(), size(), unbind(), and unbind_all().
The highest currently active handle, plus 1 (ranges between 0 and max_size_
.
Definition at line 400 of file Select_Reactor_Base.h.
Referenced by bind(), max_handlep1(), unbind(), and unbind_all().