ACE_Select_Reactor_Handler_Repository Class Reference

Used to map ACE_HANDLEs onto the appropriate ACE_Event_Handler *. More...

#include <Select_Reactor_Base.h>

Collaboration diagram for ACE_Select_Reactor_Handler_Repository:

Collaboration graph
[legend]
List of all members.

Public Types

typedef ACE_HANDLE key_type
typedef ACE_Event_Handlervalue_type
typedef ACE_Array_Base< value_typemap_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_Handlerfind (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_Implselect_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

Detailed Description

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 282 of file Select_Reactor_Base.h.


Member Typedef Documentation

typedef ACE_HANDLE ACE_Select_Reactor_Handler_Repository::key_type

Definition at line 287 of file Select_Reactor_Base.h.

typedef ACE_Array_Base<value_type> ACE_Select_Reactor_Handler_Repository::map_type

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.

typedef map_type::size_type ACE_Select_Reactor_Handler_Repository::size_type

Definition at line 315 of file Select_Reactor_Base.h.

typedef ACE_Event_Handler* ACE_Select_Reactor_Handler_Repository::value_type

Definition at line 288 of file Select_Reactor_Base.h.


Constructor & Destructor Documentation

ACE_Select_Reactor_Handler_Repository::ACE_Select_Reactor_Handler_Repository ( ACE_Select_Reactor_Impl  ) 

Default "do-nothing" constructor.


Member Function Documentation

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]

Returns:
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 }


Friends And Related Function Documentation

friend class ACE_Select_Reactor_Handler_Repository_Iterator [friend]

Definition at line 285 of file Select_Reactor_Base.h.


Member Data Documentation

ACE_Select_Reactor_Handler_Repository::ACE_ALLOC_HOOK_DECLARE

Declare the dynamic allocation hooks.

Definition at line 377 of file Select_Reactor_Base.h.

map_type ACE_Select_Reactor_Handler_Repository::event_handlers_ [private]

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().

max_handlep1_type ACE_Select_Reactor_Handler_Repository::max_handlep1_ [private]

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().

ACE_Select_Reactor_Impl& ACE_Select_Reactor_Handler_Repository::select_reactor_ [private]

Reference to our Select_Reactor.

Definition at line 395 of file Select_Reactor_Base.h.

Referenced by bind(), and unbind().


The documentation for this class was generated from the following files:
Generated on Tue Feb 2 17:35:32 2010 for ACE by  doxygen 1.4.7