3 //=============================================================================
7 * @author Douglas Schmidt <d.schmidt@vanderbilt.edu>
8 * @author Irfan Pyarali <irfan@cs.wustl.edu>
10 //=============================================================================
12 #ifndef ACE_SVC_HANDLER_H
13 #define ACE_SVC_HANDLER_H
15 #include /**/ "ace/pre.h"
17 #include "ace/Synch_Options.h"
19 #if !defined (ACE_LACKS_PRAGMA_ONCE)
21 #endif /* ACE_LACKS_PRAGMA_ONCE */
24 #include "ace/Recyclable.h"
25 #include "ace/Reactor.h"
27 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
30 class ACE_Connection_Recycling_Strategy
;
32 // This enum is used as the flags parameter when calling the close()
33 // method on the ACE_Svc_Handler.
34 enum ACE_Svc_Handler_Close
{ NORMAL_CLOSE_OPERATION
= 0x00,
35 CLOSE_DURING_NEW_CONNECTION
= 0x01
39 * @class ACE_Svc_Handler
41 * @brief Defines the interface for a service that exchanges data with
44 * This class provides a well-defined interface that the ACE_Acceptor
45 * and ACE_Connector factories use as their target. Typically, client
46 * applications will subclass ACE_Svc_Handler and do all the
47 * interesting work in the subclass. An ACE_Svc_Handler is
48 * parameterized by concrete types that conform to the interfaces of
49 * PEER_ACCEPTOR and SYNCH_TRAITS described below.
51 * @tparam PEER_STREAM The name of the class that implements the
52 * PEER_STREAM endpoint (e.g., ACE_SOCK_Stream) that is
53 * contained in an ACE_Svc_Handler and initialized by an
54 * ACE_Acceptor or ACE_Connector when a connection is
55 * established successfully. A PEER_STREAM implementation
56 * must provide a PEER_ADDR trait (e.g., ACE_INET_Addr to
57 * identify the type of address used by the endpoint. This
58 * endpoint is used to exchange data between a ACE_Svc_Handler
59 * and the peer it is connected with.
61 * @tparam SYNCH_TRAITS The name of the synchronization traits class
62 * that will be used by the ACE_Svc_Handler (e.g.,
63 * ACE_NULL_SYNCH or ACE_MT_SYNCH). The synchronization traits
64 * class provides typedefs for the mutex, condition, and
65 * semaphore implementations the ACE_Svc_Handler will
66 * use. @see Synch_Traits.h.
68 template <typename PEER_STREAM
, typename SYNCH_TRAITS
>
69 class ACE_Svc_Handler
: public ACE_Task
<SYNCH_TRAITS
>
72 // Useful STL-style traits.
73 typedef typename
PEER_STREAM::PEER_ADDR addr_type
;
74 typedef PEER_STREAM stream_type
;
77 * Constructor initializes the @a thr_mgr and @a mq by passing them
78 * down to the ACE_Task base class. The @a reactor is passed to
79 * the ACE_Event_Handler.
81 ACE_Svc_Handler (ACE_Thread_Manager
*thr_mgr
= 0,
82 ACE_Message_Queue
<SYNCH_TRAITS
> *mq
= 0,
83 ACE_Reactor
*reactor
= ACE_Reactor::instance ());
86 virtual ~ACE_Svc_Handler ();
88 /// Activate the client handler. This is typically called by the
89 /// ACE_Acceptor or ACE_Connector, which passes "this" in as the
90 /// parameter to open. If this method returns -1 the Svc_Handler's
91 /// close() method is automatically called.
92 virtual int open (void *acceptor_or_connector
= 0);
95 * Object termination hook -- application-specific cleanup code goes
96 * here. This function is called by the idle() function if the object
97 * does not have a ACE_Connection_Recycling_Strategy associated with it.
98 * Also, due to this class's derivation from ACE_Task, close() is
99 * also called when a thread activated with this object exits. See
100 * ACE_Task::close() for further details. The default action of this
101 * function is to call handle_close() with the default arguments.
103 virtual int close (u_long flags
= 0);
106 * Call this method if you want to recycling the @c Svc_Handler
107 * instead of closing it. If the object does not have a recycler,
110 virtual int idle (u_long flags
= 0);
113 * Call this method if you want to get/set the state of the
114 * @c Svc_Handler. If the object does not have a recycler, this call
115 * will have no effect (and the accessor will return
116 * ACE_RECYCLABLE_UNKNOWN).
118 virtual ACE_Recyclable_State
recycle_state () const;
119 virtual int recycle_state (ACE_Recyclable_State new_state
);
122 * When the svc_handle is no longer needed around as a hint, call
123 * this method. In addition, reset @c *act_holder to zero if
124 * @a act_holder != 0.
126 virtual void cleanup_hint (void **act_holder
= 0);
128 // = Dynamic linking hooks.
129 /// Default version does no work and returns -1. Must be overloaded
130 /// by application developer to do anything meaningful.
131 virtual int init (int argc
, ACE_TCHAR
*argv
[]);
133 /// Default version does no work and returns -1. Must be overloaded
134 /// by application developer to do anything meaningful.
137 /// Default version does no work and returns -1. Must be overloaded
138 /// by application developer to do anything meaningful.
139 virtual int info (ACE_TCHAR
**info_string
, size_t length
) const;
141 // = Demultiplexing hooks.
144 * Perform termination activities on the SVC_HANDLER. The default
145 * behavior is to close down the <peer_> (to avoid descriptor leaks)
146 * and to <destroy> this object (to avoid memory leaks)! If you
147 * don't want this behavior make sure you override this method...
149 virtual int handle_close (ACE_HANDLE
= ACE_INVALID_HANDLE
,
150 ACE_Reactor_Mask
= ACE_Event_Handler::ALL_EVENTS_MASK
);
152 /// Default behavior when timeouts occur is to close down the
153 /// <Svc_Handler> by calling <handle_close>.
154 virtual int handle_timeout (const ACE_Time_Value
&time
,
157 /// Get the underlying handle associated with the <peer_>.
158 virtual ACE_HANDLE
get_handle () const;
160 /// Set the underlying handle associated with the <peer_>.
161 virtual void set_handle (ACE_HANDLE
);
163 /// Returns the underlying PEER_STREAM. Used by
164 /// <ACE_Acceptor::accept> and <ACE_Connector::connect> factories.
165 PEER_STREAM
&peer () const;
167 /// Overloaded new operator. This method unobtrusively records if a
168 /// <Svc_Handler> is allocated dynamically, which allows it to clean
169 /// itself up correctly whether or not it's allocated statically or
171 void *operator new (size_t n
);
173 /// Overloaded new operator, nothrow_t variant. Unobtrusively records if a
174 /// <Svc_Handler> is allocated dynamically, which allows it to clean
175 /// itself up correctly whether or not it's allocated statically or
177 void *operator new (size_t n
, const std::nothrow_t
&) noexcept
;
178 void operator delete (void *p
, const std::nothrow_t
&) noexcept
;
180 /// This operator permits "placement new" on a per-object basis.
181 void * operator new (size_t n
, void *p
);
184 * Call this to free up dynamically allocated <Svc_Handlers>
185 * (otherwise you will get memory leaks). In general, you should
186 * call this method rather than <delete> since this method knows
187 * whether or not the object was allocated dynamically, and can act
188 * accordingly (i.e., deleting it if it was allocated dynamically).
190 virtual void destroy ();
193 * This really should be private so that users are forced to call
194 * <destroy>. Unfortunately, the C++ standard doesn't allow there
195 * to be a public new and a private delete. It is a bad idea to
196 * call this method directly, so use <destroy> instead, unless you
197 * know for sure that you've allocated the object dynamically.
199 void operator delete (void *);
202 * This operator is necessary to complement the class-specific
203 * operator new above. Unfortunately, it's not portable to all C++
206 void operator delete (void *, void *);
208 /// Close down the descriptor and unregister from the Reactor
211 /// Dump the state of an object.
215 // = The following methods are not suppose to be public.
217 // Because friendship is *not* inherited in C++, these methods have
220 // = Accessors to set/get the connection recycler.
222 /// Set the recycler and the @a recycling_act that is used during
223 /// purging and caching.
224 virtual void recycler (ACE_Connection_Recycling_Strategy
*recycler
,
225 const void *recycling_act
);
227 /// Get the recycler.
228 virtual ACE_Connection_Recycling_Strategy
*recycler () const;
230 /// Get the recycling act.
231 virtual const void *recycling_act () const;
234 * Upcall made by the recycler when it is about to recycle the
235 * connection. This gives the object a chance to prepare itself for
236 * recycling. Return 0 if the object is ready for recycling, -1 on
239 virtual int recycle (void * = 0);
242 /// Maintain connection with client.
245 /// Have we been dynamically created?
248 /// Keeps track of whether we are in the process of closing (required
249 /// to avoid circular calls to <handle_close>).
252 /// Pointer to the connection recycler.
253 ACE_Connection_Recycling_Strategy
*recycler_
;
255 /// Asynchronous Completion Token (ACT) to be used to when talking to
257 const void *recycling_act_
;
261 * @class ACE_Buffered_Svc_Handler
263 * @brief Defines the interface for a service that exchanges data with
264 * its connected peer and supports buffering.
266 * The buffering feature makes it possible to queue up
267 * ACE_Message_Blocks in an ACE_Message_Queue until (1) the
268 * queue is "full" or (2) a period of time elapses, at which
269 * point the queue is "flushed" via <sendv_n> to the peer.
271 template <typename PEER_STREAM
, typename SYNCH_TRAITS
>
272 class ACE_Buffered_Svc_Handler
: public ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>
276 * Constructor initializes the @a thr_mgr and @a mq by passing them
277 * down to the ACE_Task base class. The @a reactor is passed to
278 * the ACE_Event_Handler. The @a max_buffer_size and
279 * @a relative_timeout are used to determine at what point to flush
280 * the @a mq. By default, there's no buffering at all. The
281 * @a relative_timeout value is interpreted to be in a unit that's
282 * relative to the current time returned by <ACE_OS::gettimeofday>.
284 ACE_Buffered_Svc_Handler (ACE_Thread_Manager
*thr_mgr
= 0,
285 ACE_Message_Queue
<SYNCH_TRAITS
> *mq
= 0,
286 ACE_Reactor
*reactor
= ACE_Reactor::instance (),
287 size_t max_buffer_size
= 0,
288 ACE_Time_Value
*relative_timeout
= 0);
290 /// Destructor, which calls <flush>.
291 virtual ~ACE_Buffered_Svc_Handler ();
294 * Insert the ACE_Message_Block chain rooted at @a message_block
295 * into the ACE_Message_Queue with the designated @a timeout. The
296 * <flush> method will be called if this <put> causes the number of
297 * bytes to exceed the maximum buffer size or if the timeout period
300 virtual int put (ACE_Message_Block
*message_block
,
301 ACE_Time_Value
*timeout
= 0);
303 /// Flush the ACE_Message_Queue, which writes all the queued
304 /// ACE_Message_Blocks to the <PEER_STREAM>.
305 virtual int flush ();
307 /// This method is not currently implemented -- this is where the
308 /// integration with the <Reactor> would occur.
309 virtual int handle_timeout (const ACE_Time_Value
&time
,
312 /// Dump the state of an object.
316 /// Implement the flush operation on the ACE_Message_Queue, which
317 /// writes all the queued ACE_Message_Blocks to the <PEER_STREAM>.
318 /// Assumes that the caller holds the lock.
319 virtual int flush_i ();
321 /// Maximum size the <Message_Queue> can be before we have to flush
323 size_t maximum_buffer_size_
;
325 /// Current size in bytes of the <Message_Queue> contents.
326 size_t current_buffer_size_
;
328 /// Timeout value used to control when the buffer is flushed.
329 ACE_Time_Value next_timeout_
;
331 /// Interval of the timeout.
332 ACE_Time_Value interval_
;
335 ACE_Time_Value
*timeoutp_
;
338 ACE_END_VERSIONED_NAMESPACE_DECL
340 #include "ace/Svc_Handler.cpp"
342 #include /**/ "ace/post.h"
344 #endif /* ACE_SVC_HANDLER_H */