ACE_TP_Reactor Class Reference

Specialization of Select Reactor to support thread-pool based event dispatching. More...

#include <TP_Reactor.h>

Inheritance diagram for ACE_TP_Reactor:

Inheritance graph
[legend]
Collaboration diagram for ACE_TP_Reactor:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 ACE_TP_Reactor (ACE_Sig_Handler *=0, ACE_Timer_Queue *=0, int mask_signals=1, int s_queue=ACE_Select_Reactor_Token::FIFO)
 Initialize ACE_TP_Reactor with the default size.

 ACE_TP_Reactor (size_t max_number_of_handles, int restart=0, ACE_Sig_Handler *sh=0, ACE_Timer_Queue *tq=0, int mask_signals=1, int s_queue=ACE_Select_Reactor_Token::FIFO)
virtual int handle_events (ACE_Time_Value *max_wait_time=0)
virtual int handle_events (ACE_Time_Value &max_wait_time)
virtual int register_handler (int signum, ACE_Event_Handler *new_sh, ACE_Sig_Action *new_disp=0, ACE_Event_Handler **old_sh=0, ACE_Sig_Action *old_disp=0)
virtual int register_handler (const ACE_Sig_Set &sigset, ACE_Event_Handler *new_sh, ACE_Sig_Action *new_disp=0)
virtual int resumable_handler (void)
virtual int owner (ACE_thread_t n_id, ACE_thread_t *o_id=0)
 Set the new owner of the thread and return the old owner.

virtual int owner (ACE_thread_t *t_id)
 Return the current owner of the thread.

virtual int register_handler (ACE_Event_Handler *eh, ACE_Reactor_Mask mask)
virtual int register_handler (ACE_HANDLE handle, ACE_Event_Handler *eh, ACE_Reactor_Mask mask)
virtual int register_handler (ACE_Event_Handler *event_handler, ACE_HANDLE event_handle=ACE_INVALID_HANDLE)
virtual int register_handler (ACE_HANDLE event_handle, ACE_HANDLE io_handle, ACE_Event_Handler *event_handler, ACE_Reactor_Mask mask)
virtual int register_handler (const ACE_Handle_Set &handles, ACE_Event_Handler *eh, ACE_Reactor_Mask mask)

Static Public Member Functions

void no_op_sleep_hook (void *)
 Called from handle events.


Public Attributes

 ACE_ALLOC_HOOK_DECLARE
 Declare the dynamic allocation hooks.


Protected Member Functions

virtual void clear_dispatch_mask (ACE_HANDLE handle, ACE_Reactor_Mask mask)
 Template method from the base class.

int dispatch_i (ACE_Time_Value *max_wait_time, ACE_TP_Token_Guard &guard)
 Dispatch just 1 signal, timer, notification handlers.

int get_event_for_dispatching (ACE_Time_Value *max_wait_time)
int handle_signals (int &event_count, ACE_TP_Token_Guard &g)
int handle_timer_events (int &event_count, ACE_TP_Token_Guard &g)
 Handle timer events.

int handle_notify_events (int &event_count, ACE_TP_Token_Guard &g)
 Handle notify events.

int handle_socket_events (int &event_count, ACE_TP_Token_Guard &g)
 handle socket events

virtual void notify_handle (ACE_HANDLE handle, ACE_Reactor_Mask mask, ACE_Handle_Set &, ACE_Event_Handler *eh, ACE_EH_PTMF callback)
 This method shouldn't get called.


Private Member Functions

ACE_HANDLE get_notify_handle (void)
int get_socket_event_info (ACE_EH_Dispatch_Info &info)
 Get socket event dispatch information.

int dispatch_socket_event (ACE_EH_Dispatch_Info &dispatch_info)
void clear_handle_read_set (ACE_HANDLE handle)
 Clear the handle from the read_set.

int post_process_socket_event (ACE_EH_Dispatch_Info &dispatch_info, int status)
 ACE_TP_Reactor (const ACE_TP_Reactor &)
 Deny access since member-wise won't work...

ACE_TP_Reactoroperator= (const ACE_TP_Reactor &)

Detailed Description

Specialization of Select Reactor to support thread-pool based event dispatching.

One of the short comings of the Select_Reactor in ACE is that it did not support a thread pool based event dispatching model, similar to the one in WFMO_Reactor. In Select_Reactor, only thread can be blocked in at any given time.

A new Reactor has been added to ACE that removes this short-coming. TP_Reactor is a specialization of Select Reactor to support thread-pool based event dispatching. This Reactor takes advantage of the fact that events reported by are persistent if not acted upon immediately. It works by remembering the event handler that just got activated, releasing the internal lock (so that some other thread can start waiting in the event loop) and then dispatching the event handler outside the context of the Reactor lock. After the event handler has been dispatched the event handler is resumed again. Don't call remove_handler() from the handle_x methods, instead return -1.

This Reactor is best suited for situations when the callbacks to event handlers can take arbitrarily long and/or a number of threads are available to run the event loops. Note that callback code in Event Handlers (e.g. Event_Handler::handle_input) does not have to be modified or made thread-safe for this Reactor. This is because an activated Event Handler is suspended in the Reactor before the upcall is made and resumed after the upcall completes. Therefore, one Event Handler cannot be called by multiple threads simultaneously.

Definition at line 173 of file TP_Reactor.h.


Constructor & Destructor Documentation

ACE_TP_Reactor::ACE_TP_Reactor ACE_Sig_Handler = 0,
ACE_Timer_Queue = 0,
int  mask_signals = 1,
int  s_queue = ACE_Select_Reactor_Token::FIFO
 

Initialize ACE_TP_Reactor with the default size.

Definition at line 101 of file TP_Reactor.cpp.

References ACE_Select_Reactor, ACE_Timer_Queue, ACE_TRACE, and ACE_Select_Reactor_Impl::supress_notify_renew().

00105   : ACE_Select_Reactor (sh, tq, 0, 0, mask_signals, s_queue)
00106 {
00107   ACE_TRACE ("ACE_TP_Reactor::ACE_TP_Reactor");
00108   this->supress_notify_renew (1);
00109 }

ACE_TP_Reactor::ACE_TP_Reactor size_t  max_number_of_handles,
int  restart = 0,
ACE_Sig_Handler sh = 0,
ACE_Timer_Queue tq = 0,
int  mask_signals = 1,
int  s_queue = ACE_Select_Reactor_Token::FIFO
 

Initialize the ACE_TP_Reactor to manage max_number_of_handles. If restart is non-0 then the ACE_Reactor's method will be restarted automatically when occurs. If or are non-0 they are used as the signal handler and timer queue, respectively.

Definition at line 111 of file TP_Reactor.cpp.

References ACE_Select_Reactor, ACE_Timer_Queue, ACE_TRACE, and ACE_Select_Reactor_Impl::supress_notify_renew().

00117   : ACE_Select_Reactor (max_number_of_handles, restart, sh, tq, 0, 0, mask_signals, s_queue)
00118 {
00119   ACE_TRACE ("ACE_TP_Reactor::ACE_TP_Reactor");
00120   this->supress_notify_renew (1);
00121 }

ACE_TP_Reactor::ACE_TP_Reactor const ACE_TP_Reactor  )  [private]
 

Deny access since member-wise won't work...


Member Function Documentation

ACE_INLINE void ACE_TP_Reactor::clear_dispatch_mask ACE_HANDLE  handle,
ACE_Reactor_Mask  mask
[protected, virtual]
 

Template method from the base class.

Reimplemented from ACE_Select_Reactor_Impl.

Definition at line 106 of file TP_Reactor.inl.

References ACE_Reactor_Mask, ACE_Select_Reactor_Handle_Set::ex_mask_, ACE_Select_Reactor_Handle_Set::rd_mask_, ACE_Handle_Set::reset(), and ACE_Select_Reactor_Handle_Set::wr_mask_.

00108 {
00109   this->ready_set_.rd_mask_.reset ();
00110   this->ready_set_.wr_mask_.reset ();
00111   this->ready_set_.ex_mask_.reset ();
00112 }

ACE_INLINE void ACE_TP_Reactor::clear_handle_read_set ACE_HANDLE  handle  )  [private]
 

Clear the handle from the read_set.

Definition at line 98 of file TP_Reactor.inl.

References ACE_Handle_Set::clr_bit(), ACE_Select_Reactor_Handle_Set::ex_mask_, ACE_Select_Reactor_Handle_Set::rd_mask_, and ACE_Select_Reactor_Handle_Set::wr_mask_.

Referenced by get_socket_event_info().

00099 {
00100   this->ready_set_.wr_mask_.clr_bit (handle);
00101   this->ready_set_.ex_mask_.clr_bit (handle);
00102   this->ready_set_.rd_mask_.clr_bit (handle);
00103 }

int ACE_TP_Reactor::dispatch_i ACE_Time_Value max_wait_time,
ACE_TP_Token_Guard guard
[protected]
 

Dispatch just 1 signal, timer, notification handlers.

Definition at line 252 of file TP_Reactor.cpp.

References get_event_for_dispatching(), handle_notify_events(), handle_signals(), handle_socket_events(), and handle_timer_events().

Referenced by handle_events().

00254 {
00255   int event_count =
00256     this->get_event_for_dispatching (max_wait_time);
00257 
00258   int result = 0;
00259 
00260   // Note: We are passing the <event_count> around, to have record of
00261   // how many events still need processing. May be this could be
00262   // useful in future.
00263 
00264   // Dispatch signals
00265   if (event_count == -1)
00266     {
00267       // Looks like we dont do any upcalls in dispatch signals. If at
00268       // a later point of time, we decide to handle signals we have to
00269       // release the lock before we make any upcalls.. What is here
00270       // now is not the right thing...
00271       //
00272       // @@ We need to do better..
00273       return this->handle_signals (event_count,
00274                                    guard);
00275     }
00276 
00277   // If there are no signals and if we had received a proper
00278   // event_count then first look at dispatching timeouts. We need to
00279   // handle timers early since they may have higher latency
00280   // constraints than I/O handlers.  Ideally, the order of dispatching
00281   // should be a strategy...
00282 
00283   // NOTE: The event count does not have the number of timers that
00284   // needs dispatching. But we are still passing this along. We dont
00285   // need to do that. In the future we *may* have the timers also
00286   // returned through the <event_count>. Just passing that along for
00287   // that day.
00288   result = this->handle_timer_events (event_count,
00289                                       guard);
00290 
00291   if (result > 0)
00292     return result;
00293 
00294   // Else just go ahead fall through for further handling.
00295 
00296   if (event_count > 0)
00297     {
00298       // Next dispatch the notification handlers (if there are any to
00299       // dispatch).  These are required to handle multiple-threads
00300       // that are trying to update the <Reactor>.
00301       result = this->handle_notify_events (event_count,
00302                                            guard);
00303 
00304       if (result > 0)
00305         return result;
00306 
00307       // Else just fall through for further handling
00308     }
00309 
00310   if (event_count > 0)
00311     {
00312       // Handle socket events
00313       return this->handle_socket_events (event_count,
00314                                          guard);
00315     }
00316 
00317   return 0;
00318 }

int ACE_TP_Reactor::dispatch_socket_event ACE_EH_Dispatch_Info dispatch_info  )  [private]
 

Notify the appropriate in the context of the associated with that a particular event has occurred.

Definition at line 616 of file TP_Reactor.cpp.

References ACE_EH_PTMF, ACE_TRACE, ACE_EH_Dispatch_Info::callback_, ACE_EH_Dispatch_Info::event_handler_, ACE_EH_Dispatch_Info::handle_, and post_process_socket_event().

Referenced by handle_socket_events().

00617 {
00618   ACE_TRACE ("ACE_TP_Reactor::dispatch_socket_event");
00619 
00620   ACE_Event_Handler * const event_handler = dispatch_info.event_handler_;
00621   ACE_EH_PTMF const callback = dispatch_info.callback_;
00622 
00623   // Check for removed handlers.
00624   if (event_handler == 0)
00625     return -1;
00626 
00627   // Upcall. If the handler returns positive value (requesting a
00628   // reactor callback) don't set the ready-bit because it will be
00629   // ignored if the reactor state has changed. Just call back
00630   // as many times as the handler requests it. Other threads are off
00631   // handling other things.
00632   int status = 1;
00633   while (status > 0)
00634     status = (event_handler->*callback) (dispatch_info.handle_);
00635 
00636   // Post process socket event
00637   return this->post_process_socket_event (dispatch_info, status);
00638 }

int ACE_TP_Reactor::get_event_for_dispatching ACE_Time_Value max_wait_time  )  [protected]
 

Get the event that needs dispatching. It could be either a signal, timer, notification handlers or return possibly 1 I/O handler for dispatching. In the most common use case, this would return 1 I/O handler for dispatching

Definition at line 510 of file TP_Reactor.cpp.

References ACE_Select_Reactor_Handle_Set::ex_mask_, ACE_Select_Reactor_Handle_Set::rd_mask_, ACE_Handle_Set::reset(), ACE_Handle_Set::sync(), ACE_Select_Reactor_T< ACE_SELECT_REACTOR_TOKEN >::wait_for_multiple_events(), and ACE_Select_Reactor_Handle_Set::wr_mask_.

Referenced by dispatch_i().

00511 {
00512   // If the reactor handler state has changed, clear any remembered
00513   // ready bits and re-scan from the master wait_set.
00514   if (this->state_changed_)
00515     {
00516       this->ready_set_.rd_mask_.reset ();
00517       this->ready_set_.wr_mask_.reset ();
00518       this->ready_set_.ex_mask_.reset ();
00519 
00520       this->state_changed_ = false;
00521     }
00522   else
00523     {
00524       // This is a hack... somewhere, under certain conditions (which
00525       // I don't understand...) the mask will have all of its bits clear,
00526       // yet have a size_ > 0. This is an attempt to remedy the affect,
00527       // without knowing why it happens.
00528 
00529       this->ready_set_.rd_mask_.sync (this->ready_set_.rd_mask_.max_set ());
00530       this->ready_set_.wr_mask_.sync (this->ready_set_.wr_mask_.max_set ());
00531       this->ready_set_.ex_mask_.sync (this->ready_set_.ex_mask_.max_set ());
00532     }
00533 
00534   return this->wait_for_multiple_events (this->ready_set_,
00535                                          max_wait_time);
00536 }

ACE_HANDLE ACE_TP_Reactor::get_notify_handle void   )  [private]
 

Get the handle of the notify pipe from the ready set if there is an event in the notify pipe.

Definition at line 713 of file TP_Reactor.cpp.

References ACE_Handle_Set::is_set(), ACE_Reactor_Notify::notify_handle(), and ACE_Select_Reactor_Handle_Set::rd_mask_.

Referenced by handle_notify_events().

00714 {
00715   // Call the notify handler to get a handle on which we would have a
00716   // notify waiting
00717   ACE_HANDLE const read_handle =
00718     this->notify_handler_->notify_handle ();
00719 
00720   // Check whether the rd_mask has been set on that handle. If so
00721   // return the handle.
00722   if (read_handle != ACE_INVALID_HANDLE &&
00723       this->ready_set_.rd_mask_.is_set (read_handle))
00724     {
00725       return read_handle;
00726     }
00727 
00728   // None found..
00729   return ACE_INVALID_HANDLE;
00730 }

int ACE_TP_Reactor::get_socket_event_info ACE_EH_Dispatch_Info info  )  [private]
 

Get socket event dispatch information.

Definition at line 539 of file TP_Reactor.cpp.

References clear_handle_read_set(), ACE_Select_Reactor_T< ACE_SELECT_REACTOR_TOKEN >::is_suspended_i(), and ACE_EH_Dispatch_Info::set().

Referenced by handle_socket_events().

00540 {
00541   // Check for dispatch in write, except, read. Only catch one, but if
00542   // one is caught, be sure to clear the handle from each mask in case
00543   // there is more than one mask set for it. This would cause problems
00544   // if the handler is suspended for dispatching, but its set bit in
00545   // another part of ready_set_ kept it from being dispatched.
00546   int found_io = 0;
00547   ACE_HANDLE handle;
00548 
00549   // @@todo: We can do quite a bit of code reduction here. Let me get
00550   // it to work before I do this.
00551   {
00552     ACE_Handle_Set_Iterator handle_iter (this->ready_set_.wr_mask_);
00553 
00554     while (!found_io && (handle = handle_iter ()) != ACE_INVALID_HANDLE)
00555       {
00556         if (this->is_suspended_i (handle))
00557           continue;
00558 
00559         // Remember this info
00560         event.set (handle,
00561                    this->handler_rep_.find (handle),
00562                    ACE_Event_Handler::WRITE_MASK,
00563                    &ACE_Event_Handler::handle_output);
00564 
00565         this->clear_handle_read_set (handle);
00566         found_io = 1;
00567       }
00568   }
00569 
00570   if (!found_io)
00571     {
00572       ACE_Handle_Set_Iterator handle_iter (this->ready_set_.ex_mask_);
00573 
00574       while (!found_io && (handle = handle_iter ()) != ACE_INVALID_HANDLE)
00575         {
00576           if (this->is_suspended_i (handle))
00577             continue;
00578 
00579           // Remember this info
00580           event.set (handle,
00581                      this->handler_rep_.find (handle),
00582                      ACE_Event_Handler::EXCEPT_MASK,
00583                      &ACE_Event_Handler::handle_exception);
00584 
00585           this->clear_handle_read_set (handle);
00586 
00587           found_io = 1;
00588         }
00589     }
00590 
00591   if (!found_io)
00592     {
00593       ACE_Handle_Set_Iterator handle_iter (this->ready_set_.rd_mask_);
00594 
00595       while (!found_io && (handle = handle_iter ()) != ACE_INVALID_HANDLE)
00596         {
00597           if (this->is_suspended_i (handle))
00598             continue;
00599 
00600           // Remember this info
00601           event.set (handle,
00602                      this->handler_rep_.find (handle),
00603                      ACE_Event_Handler::READ_MASK,
00604                      &ACE_Event_Handler::handle_input);
00605 
00606           this->clear_handle_read_set (handle);
00607           found_io = 1;
00608         }
00609     }
00610 
00611   return found_io;
00612 }

int ACE_TP_Reactor::handle_events ACE_Time_Value max_wait_time  )  [virtual]
 

This method is just like the one above, except the max_wait_time value is a reference and can therefore never be NULL.

Current is identical to .

Reimplemented from ACE_Select_Reactor_T< ACE_SELECT_REACTOR_TOKEN >.

Definition at line 692 of file TP_Reactor.cpp.

References handle_events().

00693 {
00694   return this->handle_events (&max_wait_time);
00695 }

int ACE_TP_Reactor::handle_events ACE_Time_Value max_wait_time = 0  )  [virtual]
 

This event loop driver that blocks for before returning. It will return earlier if timer events, I/O events, or signal events occur. Note that can be 0, in which case this method blocks indefinitely until events occur.

is decremented to reflect how much time this call took. For instance, if a time value of 3 seconds is passed to handle_events and an event occurs after 2 seconds, will equal 1 second. This can be used if an application wishes to handle events for some fixed amount of time.

Returns the total number of ACE_Event_Handlers that were dispatched, 0 if the elapsed without dispatching any handlers, or -1 if something goes wrong.

Reimplemented from ACE_Select_Reactor_T< ACE_SELECT_REACTOR_TOKEN >.

Definition at line 143 of file TP_Reactor.cpp.

References ACE_TRACE, ACE_TP_Token_Guard::acquire_read_token(), dispatch_i(), ACE_TP_Token_Guard::is_owner(), and ACE_Countdown_Time::update().

Referenced by handle_events().

00144 {
00145   ACE_TRACE ("ACE_TP_Reactor::handle_events");
00146 
00147   // Stash the current time -- the destructor of this object will
00148   // automatically compute how much time elapsed since this method was
00149   // called.
00150   ACE_Countdown_Time countdown (max_wait_time);
00151 
00152   //
00153   // The order of these events is very subtle, modify with care.
00154   //
00155 
00156   // Instantiate the token guard which will try grabbing the token for
00157   // this thread.
00158   ACE_TP_Token_Guard guard (this->token_);
00159 
00160   int const result = guard.acquire_read_token (max_wait_time);
00161 
00162   // If the guard is NOT the owner just return the retval
00163   if (!guard.is_owner ())
00164     return result;
00165 
00166   // After getting the lock just just for deactivation..
00167   if (this->deactivated_)
00168     return -1;
00169 
00170   // Update the countdown to reflect time waiting for the token.
00171   countdown.update ();
00172 
00173   return this->dispatch_i (max_wait_time,
00174                            guard);
00175 }

int ACE_TP_Reactor::handle_notify_events int &  event_count,
ACE_TP_Token_Guard g
[protected]
 

Handle notify events.

Definition at line 411 of file TP_Reactor.cpp.

References ACE_Handle_Set::clr_bit(), ACE_Reactor_Notify::dispatch_notify(), get_notify_handle(), ACE_Reactor_Notify::is_dispatchable(), ACE_Select_Reactor_Handle_Set::rd_mask_, ACE_Reactor_Notify::read_notify_pipe(), and ACE_TP_Token_Guard::release_token().

Referenced by dispatch_i().

00413 {
00414   // Get the handle on which notify calls could have occured
00415   ACE_HANDLE notify_handle =
00416     this->get_notify_handle ();
00417 
00418   int result = 0;
00419 
00420   // The notify was not in the list returned by
00421   // wait_for_multiple_events ().
00422   if (notify_handle == ACE_INVALID_HANDLE)
00423     return result;
00424 
00425   // Now just do a read on the pipe..
00426   ACE_Notification_Buffer buffer;
00427 
00428   // Clear the handle of the read_mask of our <ready_set_>
00429   this->ready_set_.rd_mask_.clr_bit (notify_handle);
00430 
00431   // Keep reading notifies till we empty it or till we have a
00432   // dispatchable buffer
00433   while (this->notify_handler_->read_notify_pipe (notify_handle,
00434                                                   buffer) > 0)
00435     {
00436       // Just figure out whether we can read any buffer that has
00437       // dispatchable info. If not we have just been unblocked by
00438       // another thread trying to update the reactor. If we get any
00439       // buffer that needs dispatching we will dispatch that after
00440       // releasing the lock
00441       if (this->notify_handler_->is_dispatchable (buffer) > 0)
00442         {
00443           // Release the token before dispatching notifies...
00444           guard.release_token ();
00445 
00446           // Dispatch the upcall for the notify
00447           this->notify_handler_->dispatch_notify (buffer);
00448 
00449           // We had a successful dispatch.
00450           result = 1;
00451 
00452           // break out of the while loop
00453           break;
00454         }
00455     }
00456 
00457   // If we did some work, then we just return 1 which will allow us
00458   // to get out of here. If we return 0, then we will be asked to do
00459   // some work ie. dispacth socket events
00460   return result;
00461 }

int ACE_TP_Reactor::handle_signals int &  event_count,
ACE_TP_Token_Guard g
[protected]
 

Method to handle signals

Note:
It is just busted at this point in time.

Definition at line 321 of file TP_Reactor.cpp.

References ACE_TRACE, ACE_Select_Reactor_T< ACE_SELECT_REACTOR_TOKEN >::any_ready(), and ACE_Sig_Handler::sig_pending().

Referenced by dispatch_i().

00323 {
00324   ACE_TRACE ("ACE_TP_Reactor::handle_signals");
00325 
00326   /*
00327    *
00328    *             THIS METHOD SEEMS BROKEN
00329    *
00330    *
00331    */
00332   // First check for interrupts.
00333   // Bail out -- we got here since <select> was interrupted.
00334   if (ACE_Sig_Handler::sig_pending () != 0)
00335     {
00336       ACE_Sig_Handler::sig_pending (0);
00337 
00338       // This piece of code comes from the old TP_Reactor. We did not
00339       // handle signals at all then. If we happen to handle signals
00340       // in the TP_Reactor, we should then start worryiung about this
00341       // - Bala 21-Aug- 01
00342 #if 0
00343       // Not sure if this should be done in the TP_Reactor
00344       // case... leave it out for now.   -Steve Huston 22-Aug-00
00345 
00346       // If any HANDLES in the <ready_set_> are activated as a
00347       // result of signals they should be dispatched since
00348       // they may be time critical...
00349       active_handle_count = this->any_ready (dispatch_set);
00350 #else
00351       // active_handle_count = 0;
00352 #endif
00353 
00354       // Record the fact that the Reactor has dispatched a
00355       // handle_signal() method.  We need this to return the
00356       // appropriate count.
00357       return 1;
00358     }
00359 
00360   return -1;
00361 }

int ACE_TP_Reactor::handle_socket_events int &  event_count,
ACE_TP_Token_Guard g
[protected]
 

handle socket events

Definition at line 464 of file TP_Reactor.cpp.

References ACE_Event_Handler::add_reference(), ACE_EH_Dispatch_Info::dispatch(), dispatch_socket_event(), ACE_EH_Dispatch_Info::event_handler_, get_socket_event_info(), ACE_EH_Dispatch_Info::handle_, ACE_EH_Dispatch_Info::reference_counting_required_, ACE_TP_Token_Guard::release_token(), and ACE_Select_Reactor_T< ACE_SELECT_REACTOR_TOKEN >::suspend_i().

Referenced by dispatch_i().

00466 {
00467 
00468   // We got the lock, lets handle some I/O events.
00469   ACE_EH_Dispatch_Info dispatch_info;
00470 
00471   this->get_socket_event_info (dispatch_info);
00472 
00473   // If there is any event handler that is ready to be dispatched, the
00474   // dispatch information is recorded in dispatch_info.
00475   if (!dispatch_info.dispatch ())
00476     {
00477       return 0;
00478     }
00479 
00480   // Suspend the handler so that other threads don't start dispatching
00481   // it, if we can't suspend then return directly
00482   //
00483   // NOTE: This check was performed in older versions of the
00484   // TP_Reactor. Looks like it is a waste..
00485   if (dispatch_info.event_handler_ != this->notify_handler_)
00486     if (this->suspend_i (dispatch_info.handle_) == -1)
00487       return 0;
00488 
00489   // Call add_reference() if needed.
00490   if (dispatch_info.reference_counting_required_)
00491     dispatch_info.event_handler_->add_reference ();
00492 
00493   // Release the lock.  Others threads can start waiting.
00494   guard.release_token ();
00495 
00496   int result = 0;
00497 
00498   // If there was an event handler ready, dispatch it.
00499   // Decrement the event left
00500   --event_count;
00501 
00502   // Dispatched an event
00503   if (this->dispatch_socket_event (dispatch_info) == 0)
00504     ++result;
00505 
00506   return result;
00507 }

int ACE_TP_Reactor::handle_timer_events int &  event_count,
ACE_TP_Token_Guard g
[protected]
 

Handle timer events.

Definition at line 365 of file TP_Reactor.cpp.

References ACE_Timer_Node_Dispatch_Info, ACE_Timer_Queue_T< TYPE, FUNCTOR, ACE_LOCK >::dispatch_info(), ACE_Timer_Queue_T< TYPE, FUNCTOR, ACE_LOCK >::is_empty(), ACE_Timer_Queue_T< TYPE, FUNCTOR, ACE_LOCK >::postinvoke(), ACE_Timer_Queue_T< TYPE, FUNCTOR, ACE_LOCK >::preinvoke(), ACE_TP_Token_Guard::release_token(), ACE_Timer_Queue_T< TYPE, FUNCTOR, ACE_LOCK >::timer_skew(), and ACE_Timer_Queue_T< TYPE, FUNCTOR, ACE_LOCK >::upcall().

Referenced by dispatch_i().

00367 {
00368   if (this->timer_queue_->is_empty())
00369     { // Empty timer queue so cannot have any expired timers.
00370       return 0;
00371     }
00372 
00373   // Get the current time
00374   ACE_Time_Value cur_time (this->timer_queue_->gettimeofday () +
00375                            this->timer_queue_->timer_skew ());
00376 
00377   // Look for a node in the timer queue whose timer <= the present
00378   // time.
00379   ACE_Timer_Node_Dispatch_Info info;
00380 
00381   if (this->timer_queue_->dispatch_info (cur_time,
00382                                          info))
00383     {
00384       const void *upcall_act = 0;
00385 
00386       // Preinvoke.
00387       this->timer_queue_->preinvoke (info,
00388                                      cur_time,
00389                                      upcall_act);
00390 
00391       // Release the token before dispatching notifies...
00392       guard.release_token ();
00393 
00394       // call the functor
00395       this->timer_queue_->upcall (info,
00396                                   cur_time);
00397 
00398       // Postinvoke
00399       this->timer_queue_->postinvoke (info,
00400                                       cur_time,
00401                                       upcall_act);
00402 
00403       // We have dispatched a timer
00404       return 1;
00405     }
00406 
00407   return 0;
00408 }

ACE_INLINE void ACE_TP_Reactor::no_op_sleep_hook void *   )  [static]
 

Called from handle events.

Definition at line 93 of file TP_Reactor.inl.

00094 {
00095 }

void ACE_TP_Reactor::notify_handle ACE_HANDLE  handle,
ACE_Reactor_Mask  mask,
ACE_Handle_Set ,
ACE_Event_Handler eh,
ACE_EH_PTMF  callback
[protected, virtual]
 

This method shouldn't get called.

Reimplemented from ACE_Select_Reactor_T< ACE_SELECT_REACTOR_TOKEN >.

Definition at line 698 of file TP_Reactor.cpp.

References ACE_ASSERT, ACE_EH_PTMF, ACE_ERROR, ACE_LIB_TEXT, ACE_Reactor_Mask, and LM_ERROR.

00703 {
00704   ACE_ERROR ((LM_ERROR,
00705               ACE_LIB_TEXT ("ACE_TP_Reactor::notify_handle: ")
00706               ACE_LIB_TEXT ("Wrong version of notify_handle() got called \n")));
00707 
00708   ACE_ASSERT (eh == 0);
00709   ACE_UNUSED_ARG (eh);
00710 }

ACE_TP_Reactor& ACE_TP_Reactor::operator= const ACE_TP_Reactor  )  [private]
 

int ACE_TP_Reactor::owner ACE_thread_t t_id  )  [virtual]
 

Return the current owner of the thread.

Reimplemented from ACE_Select_Reactor_T< ACE_SELECT_REACTOR_TOKEN >.

Definition at line 134 of file TP_Reactor.cpp.

References ACE_TRACE, and ACE_Thread::self().

00135 {
00136   ACE_TRACE ("ACE_TP_Reactor::owner");
00137   *t_id = ACE_Thread::self ();
00138 
00139   return 0;
00140 }

int ACE_TP_Reactor::owner ACE_thread_t  n_id,
ACE_thread_t o_id = 0
[virtual]
 

Set the new owner of the thread and return the old owner.

Reimplemented from ACE_Select_Reactor_T< ACE_SELECT_REACTOR_TOKEN >.

Definition at line 124 of file TP_Reactor.cpp.

References ACE_TRACE, and ACE_Thread::self().

00125 {
00126   ACE_TRACE ("ACE_TP_Reactor::owner");
00127   if (o_id)
00128     *o_id = ACE_Thread::self ();
00129 
00130   return 0;
00131 }

int ACE_TP_Reactor::post_process_socket_event ACE_EH_Dispatch_Info dispatch_info,
int  status
[private]
 

Definition at line 641 of file TP_Reactor.cpp.

References ACE_TP_Token_Guard::acquire_token(), ACE_EH_Dispatch_Info::event_handler_, ACE_EH_Dispatch_Info::handle_, ACE_TP_Token_Guard::is_owner(), ACE_EH_Dispatch_Info::mask_, ACE_EH_Dispatch_Info::reference_counting_required_, ACE_Select_Reactor_T< ACE_SELECT_REACTOR_TOKEN >::remove_handler_i(), ACE_Event_Handler::remove_reference(), ACE_EH_Dispatch_Info::resume_flag_, and ACE_Select_Reactor_T< ACE_SELECT_REACTOR_TOKEN >::resume_i().

Referenced by dispatch_socket_event().

00643 {
00644   int result = 0;
00645 
00646   // First check if we really have to post process something, if not, then
00647   // we don't acquire the token which saves us a lot of time.
00648   if (status < 0 ||
00649      (dispatch_info.event_handler_ != this->notify_handler_ &&
00650       dispatch_info.resume_flag_ ==
00651         ACE_Event_Handler::ACE_REACTOR_RESUMES_HANDLER))
00652     {
00653       // Get the reactor token and with this token acquired remove first the
00654       // handler and resume it at the same time. This must be atomic, see also
00655       // bugzilla 2395. When this is not atomic it can be that we resume the
00656       // handle after it is reused by the OS.
00657       ACE_TP_Token_Guard guard (this->token_);
00658 
00659       result = guard.acquire_token ();
00660 
00661       // If the guard is NOT the owner just return the retval
00662       if (!guard.is_owner ())
00663         return result;
00664 
00665       if (status < 0)
00666         {
00667           result =
00668             this->remove_handler_i (dispatch_info.handle_, dispatch_info.mask_);
00669         }
00670 
00671       // Resume handler if required.
00672       if (dispatch_info.event_handler_ != this->notify_handler_ &&
00673           dispatch_info.resume_flag_ ==
00674             ACE_Event_Handler::ACE_REACTOR_RESUMES_HANDLER)
00675         this->resume_i (dispatch_info.handle_);
00676     }
00677 
00678   // Call remove_reference() if needed.
00679   if (dispatch_info.reference_counting_required_)
00680     dispatch_info.event_handler_->remove_reference ();
00681 
00682   return result;
00683 }

int ACE_TP_Reactor::register_handler const ACE_Handle_Set handles,
ACE_Event_Handler eh,
ACE_Reactor_Mask  mask
[virtual]
 

The following template methods have been declared here to avoid some compilers complaining that we have hidden some of the other virtual functions. We need to override functions with signal handlers and return -1 since the TP_Reactor does not support signals. The definition of the following functions is just a side-effect. The actual definitions will just call the base class method. For detailed documentation of these methods please see Select_Reactor_T.h.

Reimplemented from ACE_Select_Reactor_T< ACE_SELECT_REACTOR_TOKEN >.

Definition at line 242 of file TP_Reactor.cpp.

References ACE_Reactor_Mask, and ACE_Select_Reactor_T< ACE_SELECT_REACTOR_TOKEN >::register_handler().

00245 {
00246   return ACE_Select_Reactor::register_handler (handles,
00247                                                eh,
00248                                                mask);
00249 }

int ACE_TP_Reactor::register_handler ACE_HANDLE  event_handle,
ACE_HANDLE  io_handle,
ACE_Event_Handler event_handler,
ACE_Reactor_Mask  mask
[virtual]
 

The following template methods have been declared here to avoid some compilers complaining that we have hidden some of the other virtual functions. We need to override functions with signal handlers and return -1 since the TP_Reactor does not support signals. The definition of the following functions is just a side-effect. The actual definitions will just call the base class method. For detailed documentation of these methods please see Select_Reactor_T.h.

Reimplemented from ACE_Select_Reactor_T< ACE_SELECT_REACTOR_TOKEN >.

Definition at line 230 of file TP_Reactor.cpp.

References ACE_Reactor_Mask, and ACE_Select_Reactor_T< ACE_SELECT_REACTOR_TOKEN >::register_handler().

00234 {
00235   return ACE_Select_Reactor::register_handler (event_handle,
00236                                                io_handle,
00237                                                event_handler,
00238                                                mask);
00239 }

int ACE_TP_Reactor::register_handler ACE_Event_Handler event_handler,
ACE_HANDLE  event_handle = ACE_INVALID_HANDLE
[virtual]
 

The following template methods have been declared here to avoid some compilers complaining that we have hidden some of the other virtual functions. We need to override functions with signal handlers and return -1 since the TP_Reactor does not support signals. The definition of the following functions is just a side-effect. The actual definitions will just call the base class method. For detailed documentation of these methods please see Select_Reactor_T.h.

Reimplemented from ACE_Select_Reactor_T< ACE_SELECT_REACTOR_TOKEN >.

Definition at line 221 of file TP_Reactor.cpp.

References ACE_Select_Reactor_T< ACE_SELECT_REACTOR_TOKEN >::register_handler().

00223 {
00224   return ACE_Select_Reactor::register_handler (eh,
00225                                                h);
00226 }

int ACE_TP_Reactor::register_handler ACE_HANDLE  handle,
ACE_Event_Handler eh,
ACE_Reactor_Mask  mask
[virtual]
 

The following template methods have been declared here to avoid some compilers complaining that we have hidden some of the other virtual functions. We need to override functions with signal handlers and return -1 since the TP_Reactor does not support signals. The definition of the following functions is just a side-effect. The actual definitions will just call the base class method. For detailed documentation of these methods please see Select_Reactor_T.h.

Reimplemented from ACE_Select_Reactor_T< ACE_SELECT_REACTOR_TOKEN >.

Definition at line 209 of file TP_Reactor.cpp.

References ACE_Reactor_Mask, and ACE_Select_Reactor_T< ACE_SELECT_REACTOR_TOKEN >::register_handler().

00212 {
00213   return ACE_Select_Reactor::register_handler (handle,
00214                                                eh,
00215                                                mask);
00216 }

int ACE_TP_Reactor::register_handler ACE_Event_Handler eh,
ACE_Reactor_Mask  mask
[virtual]
 

The following template methods have been declared here to avoid some compilers complaining that we have hidden some of the other virtual functions. We need to override functions with signal handlers and return -1 since the TP_Reactor does not support signals. The definition of the following functions is just a side-effect. The actual definitions will just call the base class method. For detailed documentation of these methods please see Select_Reactor_T.h.

Reimplemented from ACE_Select_Reactor_T< ACE_SELECT_REACTOR_TOKEN >.

Definition at line 201 of file TP_Reactor.cpp.

References ACE_Reactor_Mask, and ACE_Select_Reactor_T< ACE_SELECT_REACTOR_TOKEN >::register_handler().

00203 {
00204   return ACE_Select_Reactor::register_handler (eh,
00205                                                mask);
00206 }

int ACE_TP_Reactor::register_handler const ACE_Sig_Set sigset,
ACE_Event_Handler new_sh,
ACE_Sig_Action new_disp = 0
[virtual]
 

Registers to handle a set of signals using the .

Reimplemented from ACE_Select_Reactor_T< ACE_SELECT_REACTOR_TOKEN >.

Definition at line 193 of file TP_Reactor.cpp.

References ACE_NOTSUP_RETURN.

00196 {
00197   ACE_NOTSUP_RETURN (-1);
00198 }

int ACE_TP_Reactor::register_handler int  signum,
ACE_Event_Handler new_sh,
ACE_Sig_Action new_disp = 0,
ACE_Event_Handler **  old_sh = 0,
ACE_Sig_Action old_disp = 0
[virtual]
 

Register to handle the signal using the . Returns the that was previously registered (if any), along with the of the signal handler.

Reimplemented from ACE_Select_Reactor_T< ACE_SELECT_REACTOR_TOKEN >.

Definition at line 182 of file TP_Reactor.cpp.

References ACE_NOTSUP_RETURN.

00187 {
00188   ACE_NOTSUP_RETURN (-1);
00189 }

int ACE_TP_Reactor::resumable_handler void   )  [virtual]
 

Does the reactor allow the application to resume the handle on its own ie. can it pass on the control of handle resumption to the application. The TP reactor has can allow applications to resume handles. So return a positive value.

Reimplemented from ACE_Select_Reactor_Impl.

Definition at line 686 of file TP_Reactor.cpp.

00687 {
00688   return 1;
00689 }


Member Data Documentation

ACE_TP_Reactor::ACE_ALLOC_HOOK_DECLARE
 

Declare the dynamic allocation hooks.

Reimplemented from ACE_Select_Reactor_T< ACE_SELECT_REACTOR_TOKEN >.

Definition at line 296 of file TP_Reactor.h.


The documentation for this class was generated from the following files:
Generated on Thu Nov 9 11:31:55 2006 for ACE by doxygen 1.3.6