## NAME

ACE_Event_Handler_T - Enable a class that doesn't inherit from the ACE_Event_Handler to be incorporated into the ACE_Reactor framework. Thanks to Greg Lavender (g.lavender@isode.com) for sharing this idea.

## SYNOPSIS

    #include <ace/Event_Handler_T.h>

    template<class T>
    class ACE_Event_Handler_T : public ACE_Event_Handler
    {
      public:
        typedef ACE_HANDLE (T::*GET_HANDLE) (void) const;
        typedef void (T::*SET_HANDLE) (ACE_HANDLE);
        typedef int (T::*IO_HANDLER) (ACE_HANDLE);
        typedef int (
            T::*TO_HANDLER) (const ACE_Time_Value &,
            const void *
            );
        typedef int (T::*CL_HANDLER) (ACE_HANDLE, ACE_Reactor_Mask);
        typedef int (
            T::*SIG_HANDLER) (ACE_HANDLE,
            siginfo_t*,
            ucontext_t*
            );
        ACE_Event_Handler_T (
            T *op_handler,
            int delete_handler,
            GET_HANDLE get_handle = 0,
            IO_HANDLER input = 0,
            CL_HANDLER close = 0,
            SIG_HANDLER sig = 0,
            TO_HANDLER timeout = 0,
            IO_HANDLER output = 0,
            SET_HANDLE set_handle = 0,
            IO_HANDLER except = 0
            );
        ~ACE_Event_Handler_T (void);
        virtual ACE_HANDLE get_handle (void) const;
        virtual void set_handle (ACE_HANDLE);
        virtual int handle_input (ACE_HANDLE fd = -1);
        virtual int handle_output (ACE_HANDLE fd = -1);
        virtual int handle_exception (ACE_HANDLE fd = -1);
        virtual int handle_timeout (
            const ACE_Time_Value &tv,
            const void *arg = 0
            );
        virtual int handle_close (
            ACE_HANDLE fd,
            ACE_Reactor_Mask close_mask
            );
        virtual int handle_signal (
            ACE_HANDLE signum,
            siginfo_t * = 0,
            ucontext_t * = 0
            );
        T *op_handler (void);
        void op_handler (T *);
        GET_HANDLE handle_get (void);
        void handle_get (GET_HANDLE);
        SET_HANDLE handle_set (void);
        void handle_set (SET_HANDLE);
        IO_HANDLER input_handler (void);
        void input_handler (IO_HANDLER);
        IO_HANDLER output_handler (void);
        void output_handler (IO_HANDLER);
        IO_HANDLER except_handler (void);
        void except_handler (IO_HANDLER);
        TO_HANDLER to_handler (void);
        void to_handler (TO_HANDLER);
        CL_HANDLER cl_handler (void);
        void cl_handler (CL_HANDLER);
        SIG_HANDLER sig_handler (void);
        void sig_handler (SIG_HANDLER);
        void dump (void) const;
        ACE_ALLOC_HOOK_DECLARE;
      protected:
        T *op_handler_;
        IO_HANDLER input_handler_;
        IO_HANDLER output_handler_;
        IO_HANDLER except_handler_;
        TO_HANDLER to_handler_;
        CL_HANDLER cl_handler_;
        SIG_HANDLER sig_handler_;
        int delete_handler_;
        SET_HANDLE set_handle_;
        GET_HANDLE get_handle_;
    };

## DESCRIPTION

It is sometimes the case that an application has a hierarchy of operation dispatcher classes that have their own inheritance hierarchy but also would like to integrate with the ACE_Reactor. Rather than adopt a "mixin" approach, it is often cleaner to define a template as a subclass of ACE_Event_Handler and paramterize it with an operation dispatcher type.

When constructing an instantiation of the ACE_Event_Handler_T object, a set of pointers to member functions must be provided so that when one of the handle_* methods is called by the ACE_Reactor, the appropriate method is called on the underlying operations object. This is done since in some cases it is useful to map any event that happens to the same method on an object.

The ACE_Event_Handler_T template is instantiated by an operations object and registered with the ACE_Reactor, and it then calls the appropriate op_handler. So, it's basically just another level of indirection in event dispatching. The coupling betweent the ultimate handler of the event and the ACE_Event_Handler class is relaxed a bit by have this intermediate `op_handler_` object of type `T` around. The client object can then dynamically change the bindings for the various handlers so that during the life of one of the operation objects, it can change how it wants events to be handled. It just instantiates a new instance of the template with different bindings and reregisters this new object with the ACE_Reactor.

## Typedefs to simplify pointer-to-member-function registration.

Get/set the underlying handle.

    typedef ACE_HANDLE (T::*GET_HANDLE) (void) const;

    typedef void (T::*SET_HANDLE) (ACE_HANDLE);

    typedef int (T::*IO_HANDLER) (ACE_HANDLE);

Handle I/O events.

    typedef int (T::*TO_HANDLER) (const ACE_Time_Value &, const void *);

Handle timeout events.

    typedef int (T::*CL_HANDLER) (ACE_HANDLE, ACE_Reactor_Mask);

Handle close events.

    typedef int (T::*SIG_HANDLER) (ACE_HANDLE, siginfo_t*, ucontext_t*);

    ACE_Event_Handler_T (
        T *op_handler,
        int delete_handler,
        GET_HANDLE get_handle = 0,
        IO_HANDLER input = 0,
        CL_HANDLER close = 0,
        SIG_HANDLER sig = 0,
        TO_HANDLER timeout = 0,
        IO_HANDLER output = 0,
        SET_HANDLE set_handle = 0,
        IO_HANDLER except = 0
        );

Initialize the op_handler.

    ~ACE_Event_Handler_T (void);

Close down and delete the `op_handler`

## Override all the ACE_Event_Handler methods.

These methods all delegate down to the `T` operations handler.

    virtual ACE_HANDLE get_handle (void) const;

    virtual void set_handle (ACE_HANDLE);

    virtual int handle_input (ACE_HANDLE fd = -1);

    virtual int handle_output (ACE_HANDLE fd = -1);

    virtual int handle_exception (ACE_HANDLE fd = -1);

    virtual int handle_timeout (
        const ACE_Time_Value &tv,
        const void *arg = 0
        );

    virtual int handle_close (ACE_HANDLE fd, ACE_Reactor_Mask close_mask);

    virtual int handle_signal (
        ACE_HANDLE signum,
        siginfo_t * = 0,
        ucontext_t * = 0
        );

## Get/set the operations handler.

    T *op_handler (void);

    void op_handler (T *);

## Get/set the target pointer-to-method used for dispatching.

    GET_HANDLE handle_get (void);

    void handle_get (GET_HANDLE);

    SET_HANDLE handle_set (void);

    void handle_set (SET_HANDLE);

    IO_HANDLER input_handler (void);

    void input_handler (IO_HANDLER);

    IO_HANDLER output_handler (void);

    void output_handler (IO_HANDLER);

    IO_HANDLER except_handler (void);

    void except_handler (IO_HANDLER);

    TO_HANDLER to_handler (void);

    void to_handler (TO_HANDLER);

    CL_HANDLER cl_handler (void);

    void cl_handler (CL_HANDLER);

    SIG_HANDLER sig_handler (void);

    void sig_handler (SIG_HANDLER);

    void dump (void) const;

Dump the state of an object.

    ACE_ALLOC_HOOK_DECLARE;

Declare the dynamic allocation hooks.

## Handle input, output, and exception events.

    IO_HANDLER input_handler_;

    IO_HANDLER output_handler_;

    IO_HANDLER except_handler_;

    TO_HANDLER to_handler_;

Handle timeout events.

    CL_HANDLER cl_handler_;

Handle close events.

    SIG_HANDLER sig_handler_;

Handle signal events.

    int delete_handler_;

Keeps track of whether we need to delete the handler in the destructor.

## Get/set underlying handle.

    SET_HANDLE set_handle_;

    GET_HANDLE get_handle_;

## AUTHOR

Doug Schmidt

## LIBRARY

ace