summaryrefslogtreecommitdiff
path: root/ace/Event_Handler_T.h
blob: c78ace076099fa3f2f3dd326188c03bc55cb5e90 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/* -*- 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 T> 
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 <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.
{
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 <op_handler>

  // = Override all the ACE_Event_Handler methods and have them call
  // through 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-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 */