3 //=============================================================================
7 * $Id: Svc_Handler.h 81740 2008-05-20 17:56:02Z elliott_c $
9 * @author Douglas Schmidt <schmidt@uci.edu>
10 * @author Irfan Pyarali <irfan@cs.wustl.edu>
12 //=============================================================================
14 #ifndef ACE_SVC_HANDLER_H
15 #define ACE_SVC_HANDLER_H
17 #include /**/ "ace/pre.h"
19 #include "ace/Synch_Options.h"
21 #if !defined (ACE_LACKS_PRAGMA_ONCE)
23 #endif /* ACE_LACKS_PRAGMA_ONCE */
26 #include "ace/Recyclable.h"
27 #include "ace/Reactor.h"
29 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
32 class ACE_Connection_Recycling_Strategy
;
34 // This enum is used as the flags parameter when calling the close()
35 // method on the ACE_Svc_Handler.
36 enum ACE_Svc_Handler_Close
{ NORMAL_CLOSE_OPERATION
= 0x00,
37 CLOSE_DURING_NEW_CONNECTION
= 0x01
41 * @class ACE_Svc_Handler
43 * @brief Defines the interface for a service that exchanges data with
46 * This class provides a well-defined interface that the
47 * Acceptor and Connector pattern factories use as their target.
48 * Typically, client applications will subclass ACE_Svc_Handler
49 * and do all the interesting work in the subclass. One thing
50 * that the ACE_Svc_Handler does contain is a PEER_STREAM
51 * endpoint that is initialized by an ACE_Acceptor or
52 * ACE_Connector when a connection is established successfully.
53 * This endpoint is used to exchange data between a
54 * ACE_Svc_Handler and the peer it is connected with.
56 template <ACE_PEER_STREAM_1
, ACE_SYNCH_DECL
>
57 class ACE_Svc_Handler
: public ACE_Task
<ACE_SYNCH_USE
>
61 // Useful STL-style traits.
62 typedef ACE_PEER_STREAM_ADDR addr_type
;
63 typedef ACE_PEER_STREAM stream_type
;
66 * Constructor initializes the @a thr_mgr and @a mq by passing them
67 * down to the ACE_Task base class. The @a reactor is passed to
68 * the ACE_Event_Handler.
70 ACE_Svc_Handler (ACE_Thread_Manager
*thr_mgr
= 0,
71 ACE_Message_Queue
<ACE_SYNCH_USE
> *mq
= 0,
72 ACE_Reactor
*reactor
= ACE_Reactor::instance ());
75 virtual ~ACE_Svc_Handler (void);
77 /// Activate the client handler. This is typically called by the
78 /// ACE_Acceptor or ACE_Connector.
79 virtual int open (void * = 0);
82 * Object termination hook -- application-specific cleanup code goes
83 * here. This function is called by the idle() function if the object
84 * does not have a ACE_Connection_Recycling_Strategy associated with it.
85 * Also, due to this class's derivation from ACE_Task, close() is
86 * also called when a thread activated with this object exits. See
87 * ACE_Task::close() for further details. The default action of this
88 * function is to call handle_close() with the default arguments.
90 virtual int close (u_long flags
= 0);
93 * Call this method if you want to recycling the @c Svc_Handler
94 * instead of closing it. If the object does not have a recycler,
97 virtual int idle (u_long flags
= 0);
100 * Call this method if you want to get/set the state of the
101 * @c Svc_Handler. If the object does not have a recycler, this call
102 * will have no effect (and the accessor will return
103 * ACE_RECYCLABLE_UNKNOWN).
105 virtual ACE_Recyclable_State
recycle_state (void) const;
106 virtual int recycle_state (ACE_Recyclable_State new_state
);
109 * When the svc_handle is no longer needed around as a hint, call
110 * this method. In addition, reset @c *act_holder to zero if
111 * @a act_holder != 0.
113 virtual void cleanup_hint (void **act_holder
= 0);
115 // = Dynamic linking hooks.
116 /// Default version does no work and returns -1. Must be overloaded
117 /// by application developer to do anything meaningful.
118 virtual int init (int argc
, ACE_TCHAR
*argv
[]);
120 /// Default version does no work and returns -1. Must be overloaded
121 /// by application developer to do anything meaningful.
122 virtual int fini (void);
124 /// Default version does no work and returns -1. Must be overloaded
125 /// by application developer to do anything meaningful.
126 virtual int info (ACE_TCHAR
**info_string
, size_t length
) const;
128 // = Demultiplexing hooks.
131 * Perform termination activities on the SVC_HANDLER. The default
132 * behavior is to close down the <peer_> (to avoid descriptor leaks)
133 * and to <destroy> this object (to avoid memory leaks)! If you
134 * don't want this behavior make sure you override this method...
136 virtual int handle_close (ACE_HANDLE
= ACE_INVALID_HANDLE
,
137 ACE_Reactor_Mask
= ACE_Event_Handler::ALL_EVENTS_MASK
);
139 /// Default behavior when timeouts occur is to close down the
140 /// <Svc_Handler> by calling <handle_close>.
141 virtual int handle_timeout (const ACE_Time_Value
&time
,
144 /// Get the underlying handle associated with the <peer_>.
145 virtual ACE_HANDLE
get_handle (void) const;
147 /// Set the underlying handle associated with the <peer_>.
148 virtual void set_handle (ACE_HANDLE
);
150 /// Returns the underlying PEER_STREAM. Used by
151 /// <ACE_Acceptor::accept> and <ACE_Connector::connect> factories
152 ACE_PEER_STREAM
&peer (void) const;
154 /// Overloaded new operator. This method unobtrusively records if a
155 /// <Svc_Handler> is allocated dynamically, which allows it to clean
156 /// itself up correctly whether or not it's allocated statically or
158 void *operator new (size_t n
);
160 #if defined (ACE_HAS_NEW_NOTHROW)
161 /// Overloaded new operator, nothrow_t variant. Unobtrusively records if a
162 /// <Svc_Handler> is allocated dynamically, which allows it to clean
163 /// itself up correctly whether or not it's allocated statically or
165 void *operator new (size_t n
, const ACE_nothrow_t
&) throw();
166 #if !defined (ACE_LACKS_PLACEMENT_OPERATOR_DELETE)
167 void operator delete (void *p
, const ACE_nothrow_t
&) throw ();
168 #endif /* ACE_LACKS_PLACEMENT_OPERATOR_DELETE */
171 /// This operator permits "placement new" on a per-object basis.
172 void * operator new (size_t n
, void *p
);
175 * Call this to free up dynamically allocated <Svc_Handlers>
176 * (otherwise you will get memory leaks). In general, you should
177 * call this method rather than <delete> since this method knows
178 * whether or not the object was allocated dynamically, and can act
179 * accordingly (i.e., deleting it if it was allocated dynamically).
181 virtual void destroy (void);
184 * This really should be private so that users are forced to call
185 * <destroy>. Unfortunately, the C++ standard doesn't allow there
186 * to be a public new and a private delete. It is a bad idea to
187 * call this method directly, so use <destroy> instead, unless you
188 * know for sure that you've allocated the object dynamically.
190 void operator delete (void *);
192 #if !defined (ACE_LACKS_PLACEMENT_OPERATOR_DELETE)
194 * This operator is necessary to complement the class-specific
195 * operator new above. Unfortunately, it's not portable to all C++
198 void operator delete (void *, void *);
199 #endif /* ACE_LACKS_PLACEMENT_OPERATOR_DELETE */
201 /// Close down the descriptor and unregister from the Reactor
202 void shutdown (void);
204 /// Dump the state of an object.
205 void dump (void) const;
209 // = The following methods are not suppose to be public.
211 // Because friendship is *not* inherited in C++, these methods have
214 // = Accessors to set/get the connection recycler.
216 /// Set the recycler and the @a recycling_act that is used during
217 /// purging and caching.
218 virtual void recycler (ACE_Connection_Recycling_Strategy
*recycler
,
219 const void *recycling_act
);
221 /// Get the recycler.
222 virtual ACE_Connection_Recycling_Strategy
*recycler (void) const;
224 /// Get the recycling act.
225 virtual const void *recycling_act (void) const;
228 * Upcall made by the recycler when it is about to recycle the
229 * connection. This gives the object a chance to prepare itself for
230 * recycling. Return 0 if the object is ready for recycling, -1 on
233 virtual int recycle (void * = 0);
236 /// Maintain connection with client.
237 ACE_PEER_STREAM peer_
;
239 /// Have we been dynamically created?
242 /// Keeps track of whether we are in the process of closing (required
243 /// to avoid circular calls to <handle_close>).
246 /// Pointer to the connection recycler.
247 ACE_Connection_Recycling_Strategy
*recycler_
;
249 /// Asynchronous Completion Token (ACT) to be used to when talking to
251 const void *recycling_act_
;
255 * @class ACE_Buffered_Svc_Handler
257 * @brief Defines the interface for a service that exchanges data with
258 * its connected peer and supports buffering.
260 * The buffering feature makes it possible to queue up
261 * ACE_Message_Blocks in an ACE_Message_Queue until (1) the
262 * queue is "full" or (2) a period of time elapses, at which
263 * point the queue is "flushed" via <sendv_n> to the peer.
265 template <ACE_PEER_STREAM_1
, ACE_SYNCH_DECL
>
266 class ACE_Buffered_Svc_Handler
: public ACE_Svc_Handler
<ACE_PEER_STREAM_2
, ACE_SYNCH_USE
>
269 // = Initialization and termination methods.
271 * Constructor initializes the @a thr_mgr and @a mq by passing them
272 * down to the ACE_Task base class. The @a reactor is passed to
273 * the ACE_Event_Handler. The @a max_buffer_size and
274 * @a relative_timeout are used to determine at what point to flush
275 * the @a mq. By default, there's no buffering at all. The
276 * @a relative_timeout value is interpreted to be in a unit that's
277 * relative to the current time returned by <ACE_OS::gettimeofday>.
279 ACE_Buffered_Svc_Handler (ACE_Thread_Manager
*thr_mgr
= 0,
280 ACE_Message_Queue
<ACE_SYNCH_USE
> *mq
= 0,
281 ACE_Reactor
*reactor
= ACE_Reactor::instance (),
282 size_t max_buffer_size
= 0,
283 ACE_Time_Value
*relative_timeout
= 0);
285 /// Destructor, which calls <flush>.
286 virtual ~ACE_Buffered_Svc_Handler (void);
289 * Insert the ACE_Message_Block chain rooted at @a message_block
290 * into the ACE_Message_Queue with the designated @a timeout. The
291 * <flush> method will be called if this <put> causes the number of
292 * bytes to exceed the maximum buffer size or if the timeout period
295 virtual int put (ACE_Message_Block
*message_block
,
296 ACE_Time_Value
*timeout
= 0);
298 /// Flush the ACE_Message_Queue, which writes all the queued
299 /// ACE_Message_Blocks to the <PEER_STREAM>.
300 virtual int flush (void);
302 /// This method is not currently implemented -- this is where the
303 /// integration with the <Reactor> would occur.
304 virtual int handle_timeout (const ACE_Time_Value
&time
,
307 /// Dump the state of an object.
308 void dump (void) const;
311 /// Implement the flush operation on the ACE_Message_Queue, which
312 /// writes all the queued ACE_Message_Blocks to the <PEER_STREAM>.
313 /// Assumes that the caller holds the lock.
314 virtual int flush_i (void);
316 /// Maximum size the <Message_Queue> can be before we have to flush
318 size_t maximum_buffer_size_
;
320 /// Current size in bytes of the <Message_Queue> contents.
321 size_t current_buffer_size_
;
323 /// Timeout value used to control when the buffer is flushed.
324 ACE_Time_Value next_timeout_
;
326 /// Interval of the timeout.
327 ACE_Time_Value interval_
;
330 ACE_Time_Value
*timeoutp_
;
333 ACE_END_VERSIONED_NAMESPACE_DECL
335 #if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
336 #include "ace/Svc_Handler.cpp"
337 #endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
339 #if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
340 #pragma implementation ("Svc_Handler.cpp")
341 #endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
343 #include /**/ "ace/post.h"
345 #endif /* ACE_SVC_HANDLER_H */