Used to map ACE_HANDLEs onto the appropriate ACE_Event_Handler *. More...
#include <Select_Reactor_Base.h>
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 |
Used to map ACE_HANDLEs onto the appropriate ACE_Event_Handler *.
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 287 of file Select_Reactor_Base.h.
typedef ACE_HANDLE ACE_Select_Reactor_Handler_Repository::key_type |
Definition at line 292 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 316 of file Select_Reactor_Base.h.
typedef ACE_HANDLE ACE_Select_Reactor_Handler_Repository::max_handlep1_type |
Definition at line 317 of file Select_Reactor_Base.h.
Definition at line 320 of file Select_Reactor_Base.h.
Definition at line 293 of file Select_Reactor_Base.h.
ACE_Select_Reactor_Handler_Repository::ACE_Select_Reactor_Handler_Repository | ( | ACE_Select_Reactor_Impl & | select_reactor | ) |
Default "do-nothing" constructor.
Definition at line 112 of file Select_Reactor_Base.cpp.
: select_reactor_ (select_reactor), #ifndef ACE_WIN32 max_handlep1_ (0), #endif /* !ACE_WIN32 */ event_handlers_ () { ACE_TRACE ("ACE_Select_Reactor_Handler_Repository::ACE_Select_Reactor_Handler_Repository"); }
int ACE_Select_Reactor_Handler_Repository::bind | ( | ACE_HANDLE | handle, | |
ACE_Event_Handler * | event_handler, | |||
ACE_Reactor_Mask | 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.
{ ACE_TRACE ("ACE_Select_Reactor_Handler_Repository::bind"); if (event_handler == 0) return -1; if (handle == ACE_INVALID_HANDLE) handle = event_handler->get_handle (); if (this->invalid_handle (handle)) return -1; // Is this handle already in the Reactor? bool existing_handle = false; #if defined (ACE_WIN32) map_type::ENTRY * entry = 0; int const result = this->event_handlers_.bind (handle, event_handler, entry); if (result == -1) { return -1; } else if (result == 1) // Entry already exists. { // Cannot use a different handler for an existing handle. if (event_handler != entry->item ()) { return -1; } else { // Remember that this handle is already registered in the // Reactor. existing_handle = true; } } #else // Check if this handle is already registered. ACE_Event_Handler * const current_handler = this->event_handlers_[handle]; if (current_handler) { // Cannot use a different handler for an existing handle. if (current_handler != event_handler) return -1; // Remember that this handle is already registered in the // Reactor. existing_handle = true; } this->event_handlers_[handle] = event_handler; if (this->max_handlep1_ < handle + 1) this->max_handlep1_ = handle + 1; #endif /* ACE_WIN32 */ if (this->select_reactor_.is_suspended_i (handle)) { this->select_reactor_.bit_ops (handle, mask, this->select_reactor_.suspend_set_, ACE_Reactor::ADD_MASK); } else { this->select_reactor_.bit_ops (handle, mask, this->select_reactor_.wait_set_, ACE_Reactor::ADD_MASK); // Note the fact that we've changed the state of the <wait_set_>, // which is used by the dispatching loop to determine whether it can // keep going or if it needs to reconsult select(). // this->select_reactor_.state_changed_ = 1; } // If new entry, call add_reference() if needed. if (!existing_handle) event_handler->add_reference (); return 0; }
int ACE_Select_Reactor_Handler_Repository::close | ( | void | ) |
Close down the repository.
Definition at line 164 of file Select_Reactor_Base.cpp.
{ ACE_TRACE ("ACE_Select_Reactor_Handler_Repository::close"); return this->unbind_all (); }
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.
{ #if defined (ACE_HAS_DUMP) ACE_TRACE ("ACE_Select_Reactor_Handler_Repository::dump"); # ifdef ACE_WIN32 # define ACE_HANDLE_FORMAT_SPECIFIER ACE_TEXT("%@") # define ACE_MAX_HANDLEP1_FORMAT_SPECIFIER ACE_TEXT("%u") # else # define ACE_HANDLE_FORMAT_SPECIFIER ACE_TEXT("%d") # define ACE_MAX_HANDLEP1_FORMAT_SPECIFIER ACE_TEXT("%d") # endif /* ACE_WIN32 */ ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("max_handlep1_ = ") ACE_MAX_HANDLEP1_FORMAT_SPECIFIER ACE_TEXT ("\n"), this->max_handlep1 ())); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("["))); ACE_Event_Handler *event_handler = 0; for (ACE_Select_Reactor_Handler_Repository_Iterator iter (this); iter.next (event_handler) != 0; iter.advance ()) ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" (event_handler = %@,") ACE_TEXT (" event_handler->handle_ = ") ACE_HANDLE_FORMAT_SPECIFIER ACE_TEXT ("\n"), event_handler, event_handler->get_handle ())); ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" ]\n"))); ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); #endif /* ACE_HAS_DUMP */ }
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.
{ ACE_TRACE ("ACE_Select_Reactor_Handler_Repository::find"); ACE_Event_Handler * eh = 0; if (this->handle_in_range (handle)) { map_type::iterator const pos = this->find_eh (handle); if (pos != this->event_handlers_.end ()) { #ifdef ACE_WIN32 eh = (*pos).item (); #else eh = *pos; #endif /* ACE_WIN32 */ } } // Don't bother setting errno. It isn't used in the select()-based // reactors and incurs a TSS access. // else // { // errno = ENOENT; // } return eh; }
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.
{ ACE_TRACE ("ACE_Select_Reactor_Handler_Repository::find_eh"); map_type::iterator pos (this->event_handlers_.end ()); // this code assumes the handle is in range. #if defined (ACE_WIN32) this->event_handlers_.find (handle, pos); #else map_type::iterator const tmp = &this->event_handlers_[handle]; if (*tmp != 0) pos = tmp; #endif /* ACE_WIN32 */ return pos; }
bool ACE_Select_Reactor_Handler_Repository::handle_in_range | ( | ACE_HANDLE | handle | ) |
Definition at line 64 of file Select_Reactor_Base.cpp.
{ ACE_TRACE ("ACE_Select_Reactor_Handler_Repository::handle_in_range"); #if defined (ACE_WIN32) // It's too expensive to perform more exhaustive validity checks on // Win32 due to the way that they implement SOCKET HANDLEs. if (handle != ACE_INVALID_HANDLE) #else /* !ACE_WIN32 */ if (handle >= 0 && handle < this->max_handlep1_) #endif /* ACE_WIN32 */ { return true; } // Don't bother setting errno. It isn't used in the select()-based // reactors and incurs a TSS access. // errno = EINVAL; return false; }
bool ACE_Select_Reactor_Handler_Repository::invalid_handle | ( | ACE_HANDLE | handle | ) |
Definition at line 42 of file Select_Reactor_Base.cpp.
{ ACE_TRACE ("ACE_Select_Reactor_Handler_Repository::invalid_handle"); #if defined (ACE_WIN32) // It's too expensive to perform more exhaustive validity checks on // Win32 due to the way that they implement SOCKET HANDLEs. if (handle == ACE_INVALID_HANDLE) #else /* !ACE_WIN32 */ if (handle < 0 || static_cast<size_type> (handle) >= this->event_handlers_.size ()) #endif /* ACE_WIN32 */ { errno = EINVAL; return true; } return false; }
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.
{ #ifdef ACE_WIN32 return this->event_handlers_.current_size (); #else return this->max_handlep1_; #endif /* ACE_WIN32 */ }
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.
Definition at line 86 of file Select_Reactor_Base.cpp.
{ ACE_TRACE ("ACE_Select_Reactor_Handler_Repository::open"); #if defined (ACE_WIN32) if (this->event_handlers_.open (size) == -1) return -1; #else if (this->event_handlers_.size (size) == -1) return -1; // Initialize the ACE_Event_Handler pointers to 0. std::fill (this->event_handlers_.begin (), this->event_handlers_.end (), static_cast<ACE_Event_Handler *> (0)); this->max_handlep1_ = 0; #endif /* ACE_WIN32 */ // Try to increase the number of handles if <size> is greater than // the current limit. return ACE::set_handle_limit (static_cast<int> (size), 1); }
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.
{ #ifdef ACE_WIN32 return this->event_handlers_.total_size (); #else return this->event_handlers_.size (); #endif /* ACE_WIN32 */ }
int ACE_Select_Reactor_Handler_Repository::unbind | ( | ACE_HANDLE | 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.
{ // Do not refactor this code to optimize the call to the unbind impl. // To resolve bug 2653, unbind must be called even when find_eh returns // event_handlers_.end(). return !this->handle_in_range (handle) ? -1 : this->unbind (handle, this->find_eh (handle), mask); }
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.
{ ACE_TRACE ("ACE_Select_Reactor_Handler_Repository::unbind"); // Retrieve event handler before unbinding it from the map. The // iterator pointing to it will no longer be valid once the handler // is unbound. ACE_Event_Handler * const event_handler = (pos == this->event_handlers_.end () ? 0 : ACE_SELECT_REACTOR_EVENT_HANDLER (pos)); // Clear out the <mask> bits in the Select_Reactor's wait_set. this->select_reactor_.bit_ops (handle, mask, this->select_reactor_.wait_set_, ACE_Reactor::CLR_MASK); // And suspend_set. this->select_reactor_.bit_ops (handle, mask, this->select_reactor_.suspend_set_, ACE_Reactor::CLR_MASK); // Note the fact that we've changed the state of the <wait_set_>, // which is used by the dispatching loop to determine whether it can // keep going or if it needs to reconsult select(). // this->select_reactor_.state_changed_ = 1; // If there are no longer any outstanding events on this <handle> // then we can totally shut down the Event_Handler. bool const has_any_wait_mask = (this->select_reactor_.wait_set_.rd_mask_.is_set (handle) || this->select_reactor_.wait_set_.wr_mask_.is_set (handle) || this->select_reactor_.wait_set_.ex_mask_.is_set (handle)); bool const has_any_suspend_mask = (this->select_reactor_.suspend_set_.rd_mask_.is_set (handle) || this->select_reactor_.suspend_set_.wr_mask_.is_set (handle) || this->select_reactor_.suspend_set_.ex_mask_.is_set (handle)); bool complete_removal = false; if (!has_any_wait_mask && !has_any_suspend_mask) { #if defined (ACE_WIN32) if (event_handler != 0 && this->event_handlers_.unbind (pos) == -1) return -1; // Should not happen! #else this->event_handlers_[handle] = 0; if (this->max_handlep1_ == handle + 1) { // We've deleted the last entry, so we need to figure out // the last valid place in the array that is worth looking // at. ACE_HANDLE const wait_rd_max = this->select_reactor_.wait_set_.rd_mask_.max_set (); ACE_HANDLE const wait_wr_max = this->select_reactor_.wait_set_.wr_mask_.max_set (); ACE_HANDLE const wait_ex_max = this->select_reactor_.wait_set_.ex_mask_.max_set (); ACE_HANDLE const suspend_rd_max = this->select_reactor_.suspend_set_.rd_mask_.max_set (); ACE_HANDLE const suspend_wr_max = this->select_reactor_.suspend_set_.wr_mask_.max_set (); ACE_HANDLE const suspend_ex_max = this->select_reactor_.suspend_set_.ex_mask_.max_set (); // Compute the maximum of six values. this->max_handlep1_ = wait_rd_max; if (this->max_handlep1_ < wait_wr_max) this->max_handlep1_ = wait_wr_max; if (this->max_handlep1_ < wait_ex_max) this->max_handlep1_ = wait_ex_max; if (this->max_handlep1_ < suspend_rd_max) this->max_handlep1_ = suspend_rd_max; if (this->max_handlep1_ < suspend_wr_max) this->max_handlep1_ = suspend_wr_max; if (this->max_handlep1_ < suspend_ex_max) this->max_handlep1_ = suspend_ex_max; ++this->max_handlep1_; } #endif /* ACE_WIN32 */ // The handle has been completely removed. complete_removal = true; } if (event_handler == 0) return -1; bool const requires_reference_counting = event_handler->reference_counting_policy ().value () == ACE_Event_Handler::Reference_Counting_Policy::ENABLED; // Close down the <Event_Handler> unless we've been instructed not // to. if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::DONT_CALL) == 0) (void) event_handler->handle_close (handle, mask); // Call remove_reference() if the removal is complete and reference // counting is needed. if (complete_removal && requires_reference_counting) { (void) event_handler->remove_reference (); } return 0; }
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.
{ // Unbind all of the <handle, ACE_Event_Handler>s. #ifdef ACE_WIN32 map_type::iterator const end = this->event_handlers_.end (); for (map_type::iterator pos = this->event_handlers_.begin (); pos != end; ) { // Post-increment (*not* pre-increment) before unbind()ing since // the current iterator will be invalidated during the unbind() // operation. map_type::iterator const the_pos (pos++); ACE_HANDLE const handle = (*the_pos).key (); (void) this->unbind (handle, the_pos, ACE_Event_Handler::ALL_EVENTS_MASK); } #else // We could use the "end()" iterator but leveraging max_handlep1_ // allows us to optimize away unnecessary accesses of nil event // handler pointers. map_type::iterator pos = this->event_handlers_.begin (); // iterator == ACE_Event_Handler* for (ACE_HANDLE handle = 0; handle < this->max_handlep1_; ++handle) { (void) this->unbind (handle, pos, ACE_Event_Handler::ALL_EVENTS_MASK); ++pos; } #endif /* ACE_WIN32 */ return 0; }
friend class ACE_Select_Reactor_Handler_Repository_Iterator [friend] |
Definition at line 290 of file Select_Reactor_Base.h.
Declare the dynamic allocation hooks.
Definition at line 382 of file Select_Reactor_Base.h.
Underlying table of event handlers.
Definition at line 409 of file Select_Reactor_Base.h.
The highest currently active handle, plus 1 (ranges between 0 and max_size_
.
Definition at line 405 of file Select_Reactor_Base.h.
Reference to our Select_Reactor
.
Definition at line 400 of file Select_Reactor_Base.h.