## NAME

ACE_TP_Reactor -

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

## SYNOPSIS

    #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 max_number_of_handles,
            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 &);
    };

## DESCRIPTION

TP_Reactor (ala, Thread Pool Reactor) uses the leader-follower model to demultiplex requests among a bunch of threads. Basically, when using thread pool reactor, one will pre-spawn a _fixed_ number of threads. When you issue the run_event_loop () method, one of the thread will become the leader thread and wait for an event. The other threads (followers) will be lined up and waiting for their turns to become the leader. When an event occurs, the leader will pick a follower to become the leader and go on to handle the event. The consequence of using TP_Reactor is the amortization of the costs used to creating threads. The context switching cost will also reduce. More over, the total resources used by threads are bounded (because there are only so many threads.)

## Initialization and termination methods.

    ACE_TP_Reactor (ACE_Sig_Handler * = 0, ACE_Timer_Queue * = 0);

Initialize `ACE_TP_Reactor` with the default size.

    ACE_TP_Reactor (
        size_t max_number_of_handles,
        int restart = 0,
        ACE_Sig_Handler * = 0,
        ACE_Timer_Queue * = 0
        );

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

## Event loop drivers.

    virtual int handle_events (ACE_Time_Value *max_wait_time = 0);

This event loop driver that blocks for `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 *);

Called from handle events

    virtual void wakeup_all_threads (void);

Wake up all threads in waiting in the event loop

    ACE_ALLOC_HOOK_DECLARE;

Declare the dynamic allocation hooks.

## Internal methods that do the actual work.

    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
        );

Overwrites ACE_Select_Reactor::dispatch_io_set() to *not* dispatch any event handlers. The information of one activated event handler is stored away, so that the event handler can be dispatch later.

    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.

    virtual int notify_handle (ACE_EH_Dispatch_Info &dispatch_info);

Notify the appropriate `callback` in the context of the `eh` associated with `handle` that a particular event has occurred.

    ACE_EH_Dispatch_Info dispatch_info_;

Dispatch information of the activated event handler

## AUTHOR

Irfan Pyarali Nanbor Wang

## LIBRARY

ace