Specialization of Select Reactor to support thread-pool based event dispatching.
#include <ace/TP_Reactor.h>
class ACE_TP_Reactor : public ACE_Select_Reactor {
public:
ACE_TP_Reactor (ACE_Sig_Handler * = 0, ACE_Timer_Queue * = 0);
ACE_TP_Reactor ( size_t size, int restart = 0, ACE_Sig_Handler * = 0, ACE_Timer_Queue * = 0 );
virtual int handle_events (ACE_Time_Value *max_wait_time = 0);
virtual int handle_events (ACE_Time_Value &max_wait_time);
static void no_op_sleep_hook (void *);
virtual void wakeup_all_threads (void);
ACE_ALLOC_HOOK_DECLARE;
protected:
virtual int dispatch_io_set ( int number_of_active_handles, int& number_dispatched, int mask, ACE_Handle_Set& dispatch_mask, ACE_Handle_Set& ready_mask, ACE_EH_PTMF callback );
virtual void notify_handle ( ACE_HANDLE handle, ACE_Reactor_Mask mask, ACE_Handle_Set &, ACE_Event_Handler *eh, ACE_EH_PTMF callback );
virtual int notify_handle (ACE_EH_Dispatch_Info &dispatch_info);
ACE_EH_Dispatch_Info dispatch_info_;
private:
ACE_TP_Reactor (const ACE_TP_Reactor &);
ACE_TP_Reactor &operator = (const ACE_TP_Reactor &);
};
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 handle_events() 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 select() 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.
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.
ACE_TP_Reactor (ACE_Sig_Handler * = 0, ACE_Timer_Queue * = 0);
ACE_TP_Reactor
with the default size.
ACE_TP_Reactor (
size_t size,
int restart = 0,
ACE_Sig_Handler * = 0,
ACE_Timer_Queue * = 0
);
ACE_TP_Reactor
with size size
.
virtual int handle_events (ACE_Time_Value *max_wait_time = 0);
max_wait_time
before
returning. It will return earlier if timer events, I/O events,
or signal events occur. Note that max_wait_time
can be 0, in
which case this method blocks indefinitely until events occur.
max_wait_time
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,
max_wait_time
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_Handler
s that were
dispatched, 0 if the max_wait_time
elapsed without dispatching
any handlers, or -1 if something goes wrong.
virtual int handle_events (ACE_Time_Value &max_wait_time);
static void no_op_sleep_hook (void *);
virtual void wakeup_all_threads (void);
ACE_ALLOC_HOOK_DECLARE;
virtual int dispatch_io_set (
int number_of_active_handles,
int& number_dispatched,
int mask,
ACE_Handle_Set& dispatch_mask,
ACE_Handle_Set& ready_mask,
ACE_EH_PTMF callback
);
virtual void notify_handle (
ACE_HANDLE handle,
ACE_Reactor_Mask mask,
ACE_Handle_Set &,
ACE_Event_Handler *eh,
ACE_EH_PTMF callback
);
virtual int notify_handle (ACE_EH_Dispatch_Info &dispatch_info);
callback
in the context of the eh
associated with handle
that a particular event has occurred.
ACE_EH_Dispatch_Info dispatch_info_;