/* -*- C++ -*- */ // $Id$ // ============================================================================ // // = LIBRARY // ace // // = FILENAME // Event_Handler_T.h // // = AUTHOR // Doug Schmidt // // ============================================================================ #if !defined (ACE_EVENT_HANDLER_T_H) #define ACE_EVENT_HANDLER_T_H #include "ace/Event_Handler.h" #if defined (ACE_HAS_TEMPLATE_TYPEDEFS) template class ACE_Export ACE_Event_Handler_T : public ACE_Event_Handler // = TITLE // 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. // // = 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 object of type 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. { public: // = 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 #if defined(ACE_HAS_SIGINFO_T) , siginfo_t*, ucontext_t* #endif /* ACE_HAS_SIGINFO_T */ ); // = Initialization and termination methods. 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 // = Override all the ACE_Event_Handler methods and have them call // through to the 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-member-function 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. protected: T *op_handler_; // Pointer to the object that handles all the delegated operations. // = 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_; }; #if defined (__ACE_INLINE__) #include "ace/Event_Handler_T.i" #endif /* __ACE_INLINE__ */ #endif /* ACE_HAS_TEMPLATE_TYPEDEFS */ #endif /* ACE_EVENT_HANDLER_H */