1 #ifndef ACE_SVC_HANDLER_CPP
2 #define ACE_SVC_HANDLER_CPP
4 #include "ace/Svc_Handler.h"
6 #if !defined (ACE_LACKS_PRAGMA_ONCE)
8 #endif /* ACE_LACKS_PRAGMA_ONCE */
10 #include "ace/OS_NS_sys_time.h"
11 #include "ace/Object_Manager.h"
12 #include "ace/Connection_Recycling_Strategy.h"
14 #include "ace/Dynamic.h"
16 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
18 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> void *
19 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::operator new (size_t, void *p
)
21 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::operator new (NOOP, 2 parameters)");
25 #if !defined (ACE_LACKS_PLACEMENT_OPERATOR_DELETE)
26 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> void
27 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::operator delete (void *, void *)
29 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::operator delete (NOOP, 2 parameters)");
32 #endif /* ACE_LACKS_PLACEMENT_OPERATOR_DELETE */
34 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> void *
35 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::operator new (size_t n
)
37 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::operator new");
39 ACE_Dynamic
*const dynamic_instance
= ACE_Dynamic::instance ();
41 if (dynamic_instance
== 0)
43 // If this ACE_ASSERT fails, it may be due to running of out TSS
44 // keys. Try using ACE_HAS_TSS_EMULATION, or increasing
45 // ACE_DEFAULT_THREAD_KEYS if already using TSS emulation.
46 ACE_ASSERT (dynamic_instance
!= 0);
52 // Allocate the memory and store it (usually in thread-specific
53 // storage, depending on config flags).
54 dynamic_instance
->set ();
60 #if defined (ACE_HAS_NEW_NOTHROW)
61 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> void *
62 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::operator new (size_t n
,
63 const ACE_nothrow_t
&) throw()
65 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::operator new(nothrow)");
67 ACE_Dynamic
*const dynamic_instance
= ACE_Dynamic::instance ();
69 if (dynamic_instance
== 0)
71 // If this ACE_ASSERT fails, it may be due to running of out TSS
72 // keys. Try using ACE_HAS_TSS_EMULATION, or increasing
73 // ACE_DEFAULT_THREAD_KEYS if already using TSS emulation.
74 ACE_ASSERT (dynamic_instance
!= 0);
80 // Allocate the memory and store it (usually in thread-specific
81 // storage, depending on config flags).
82 dynamic_instance
->set ();
84 return ::new(ACE_nothrow
) char[n
];
88 #if !defined (ACE_LACKS_PLACEMENT_OPERATOR_DELETE)
89 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> void
90 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::operator delete (void *p
,
91 const ACE_nothrow_t
&) throw()
93 ACE_TRACE("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::operator delete(nothrow)");
94 ::delete [] static_cast <char *> (p
);
96 #endif /* ACE_LACKS_PLACEMENT_OPERATOR_DELETE */
98 #endif /* ACE_HAS_NEW_NOTHROW */
100 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> void
101 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::destroy (void)
103 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::destroy");
105 // Only delete ourselves if we're not owned by a module and have
106 // been allocated dynamically.
107 if (this->mod_
== 0 && this->dynamic_
&& this->closing_
== false)
108 // Will call the destructor, which automatically calls <shutdown>.
109 // Note that if we are *not* allocated dynamically then the
110 // destructor will call <shutdown> automatically when it gets run
115 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> void
116 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::operator delete (void *obj
)
118 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::operator delete");
119 // You cannot delete a 'void*' (X3J16/95-0087 5.3.5.3), but we know
120 // the pointer was created using new char[] (see operator new code),
122 ::delete [] static_cast <char *> (obj
);
125 // Default constructor.
127 template <typename PEER_STREAM
, typename SYNCH_TRAITS
>
128 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::ACE_Svc_Handler (ACE_Thread_Manager
*tm
,
129 ACE_Message_Queue
<SYNCH_TRAITS
> *mq
,
130 ACE_Reactor
*reactor
)
131 : ACE_Task
<SYNCH_TRAITS
> (tm
, mq
),
136 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::ACE_Svc_Handler");
138 this->reactor (reactor
);
140 // This clever idiom transparently checks if we were allocated
141 // dynamically. This information is used by the <destroy> method to
142 // decide if we need to delete <this>... The idiom is based on a
143 // paper by Michael van Rooyen (mrooyen@cellnet.co.uk) that appeared
144 // in the April '96 issue of the C++ Report. We've spruced it up to
145 // work correctly in multi-threaded programs by using our ACE_TSS
147 this->dynamic_
= ACE_Dynamic::instance ()->is_dynamic ();
150 // Make sure to reset the flag.
151 ACE_Dynamic::instance ()->reset ();
154 // Default behavior for a ACE_Svc_Handler object is to be registered
155 // with the ACE_Reactor (thereby ensuring single threading).
157 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> int
158 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::open (void *)
160 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::open");
161 #if defined (ACELIB_DEBUGGING)
162 ACE_TCHAR buf
[BUFSIZ
];
163 ACE_PEER_STREAM_ADDR client_addr
;
165 if (this->peer_
.get_remote_addr (client_addr
) == -1)
166 ACELIB_ERROR_RETURN ((LM_ERROR
,
168 ACE_TEXT ("get_remote_addr")),
170 else if (client_addr
.addr_to_string (buf
, sizeof buf
) == -1)
171 ACELIB_ERROR_RETURN ((LM_ERROR
,
173 ACE_TEXT ("can't obtain peer's address")),
175 ACELIB_DEBUG ((LM_DEBUG
,
176 ACE_TEXT ("connected to %s on fd %d\n"),
178 this->peer_
.get_handle ()));
179 #endif /* ACELIB_DEBUGGING */
181 && this->reactor ()->register_handler
183 ACE_Event_Handler::READ_MASK
) == -1)
184 ACELIB_ERROR_RETURN ((LM_ERROR
,
186 ACE_TEXT ("unable to register client handler")),
191 // Perform termination activities.
193 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> void
194 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::shutdown (void)
196 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::shutdown");
198 // Deregister this handler with the ACE_Reactor.
199 if (this->reactor ())
201 ACE_Reactor_Mask mask
= ACE_Event_Handler::ALL_EVENTS_MASK
|
202 ACE_Event_Handler::DONT_CALL
;
204 // Make sure there are no timers.
205 this->reactor ()->cancel_timer (this);
207 if (this->peer ().get_handle () != ACE_INVALID_HANDLE
)
208 // Remove self from reactor.
209 this->reactor ()->remove_handler (this, mask
);
212 // Remove self from the recycler.
213 if (this->recycler ())
214 this->recycler ()->purge (this->recycling_act_
);
216 this->peer ().close ();
219 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> void
220 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::cleanup_hint (void **act_holder
)
222 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::cleanup_hint");
225 if (this->recycler ())
226 this->recycler ()->cleanup_hint (this->recycling_act_
,
230 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> void
231 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::dump (void) const
233 #if defined (ACE_HAS_DUMP)
234 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::dump");
237 ACELIB_DEBUG ((LM_DEBUG
,
240 ACELIB_DEBUG ((LM_DEBUG
,
243 ACELIB_DEBUG ((LM_DEBUG
,
246 ACELIB_DEBUG ((LM_DEBUG
,
247 "recycling_act_ = %d\n",
248 this->recycling_act_
));
249 #endif /* ACE_HAS_DUMP */
252 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> PEER_STREAM
&
253 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::peer (void) const
255 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::peer");
256 return (PEER_STREAM
&) this->peer_
;
259 // Extract the underlying I/O descriptor.
261 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> ACE_HANDLE
262 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::get_handle (void) const
264 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::get_handle");
265 return this->peer_
.get_handle ();
268 // Set the underlying I/O descriptor.
270 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> void
271 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::set_handle (ACE_HANDLE h
)
273 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::set_handle");
274 this->peer_
.set_handle (h
);
277 template <typename PEER_STREAM
, typename SYNCH_TRAITS
>
278 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::~ACE_Svc_Handler (void)
280 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::~ACE_Svc_Handler");
282 if (this->closing_
== false)
284 // We're closing down now, so make sure not to call ourselves
285 // recursively via other calls to handle_close() (e.g., from the
287 this->closing_
= true;
293 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> int
294 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::handle_close (ACE_HANDLE
,
297 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::handle_close");
299 if (this->reference_counting_policy ().value () ==
300 ACE_Event_Handler::Reference_Counting_Policy::DISABLED
)
308 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> int
309 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::handle_timeout (const ACE_Time_Value
&,
312 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::handle_timeout");
313 return this->handle_close ();
316 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> int
317 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::close (u_long
)
319 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::close");
320 return this->handle_close ();
323 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> int
324 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::init (int /* argc */,
325 ACE_TCHAR
* /* argv */[])
327 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::init");
331 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> int
332 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::fini (void)
334 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::fini");
338 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> int
339 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::info (ACE_TCHAR
**, size_t) const
341 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::info");
345 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> int
346 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::idle (u_long flags
)
348 if (this->recycler ())
349 return this->recycler ()->cache (this->recycling_act_
);
351 return this->close (flags
);
354 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> int
355 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::recycle_state (ACE_Recyclable_State new_state
)
357 if (this->recycler ())
358 return this->recycler ()->recycle_state (this->recycling_act_
,
364 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> ACE_Recyclable_State
365 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::recycle_state (void) const
367 if (this->recycler ())
368 return this->recycler ()->recycle_state (this->recycling_act_
);
370 return ACE_RECYCLABLE_UNKNOWN
;
373 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> void
374 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::recycler (ACE_Connection_Recycling_Strategy
*recycler
,
375 const void *recycling_act
)
377 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::recycler");
378 this->recycler_
= recycler
;
379 this->recycling_act_
= recycling_act
;
382 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> ACE_Connection_Recycling_Strategy
*
383 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::recycler (void) const
385 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::recycler");
386 return this->recycler_
;
389 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> const void *
390 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::recycling_act (void) const
392 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::recycling_act");
393 return this->recycling_act_
;
396 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> int
397 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::recycle (void *)
399 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::recycle");
400 // By default, the object is ready and willing to be recycled.
404 template <typename PEER_STREAM
, typename SYNCH_TRAITS
>
405 ACE_Buffered_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::~ACE_Buffered_Svc_Handler (void)
410 template <typename PEER_STREAM
, typename SYNCH_TRAITS
>
411 ACE_Buffered_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::ACE_Buffered_Svc_Handler (ACE_Thread_Manager
*tm
,
412 ACE_Message_Queue
<SYNCH_TRAITS
> *mq
,
413 ACE_Reactor
*reactor
,
414 size_t maximum_buffer_size
,
415 ACE_Time_Value
*timeout
)
416 : ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
> (tm
, mq
, reactor
),
417 maximum_buffer_size_ (maximum_buffer_size
),
418 current_buffer_size_ (0),
421 ACE_TRACE ("ACE_Buffered_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::ACE_Buffered_Svc_Handler");
423 if (this->timeoutp_
!= 0)
425 this->interval_
= *timeout
;
426 this->next_timeout_
= ACE_OS::gettimeofday () + this->interval_
;
430 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> int
431 ACE_Buffered_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::put (ACE_Message_Block
*mb
,
434 ACE_GUARD_RETURN (typename
SYNCH_TRAITS::MUTEX
, m
, this->msg_queue ()->lock (), -1);
436 // Enqueue <mb> onto the message queue.
437 if (this->putq (mb
, tv
) == -1)
441 // Update the current number of bytes on the queue.
442 this->current_buffer_size_
+= mb
->total_size ();
444 // Flush the buffer when the number of bytes exceeds the maximum
445 // buffer size or when the timeout period has elapsed.
446 if (this->current_buffer_size_
>= this->maximum_buffer_size_
447 || (this->timeoutp_
!= 0
448 && this->next_timeout_
<= ACE_OS::gettimeofday ()))
449 return this->flush_i ();
457 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> int
458 ACE_Buffered_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::flush (void)
460 ACE_GUARD_RETURN (typename
SYNCH_TRAITS::MUTEX
, m
, this->msg_queue ()->lock (), -1);
462 return this->flush_i ();
465 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> int
466 ACE_Buffered_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::flush_i (void)
468 ACE_Message_Queue_Iterator
<SYNCH_TRAITS
> iterator (*this->msg_queue ());
469 ACE_Message_Block
*mblk
= 0;
472 // Get the first <ACE_Message_Block> so that we can write everything
473 // out via the <send_n>.
474 if (iterator
.next (mblk
) != 0)
475 result
= this->peer ().send_n (mblk
);
477 // This method assumes the caller holds the queue's lock!
479 this->msg_queue ()->flush_i ();
481 if (this->timeoutp_
!= 0)
482 // Update the next timeout period by adding the interval.
483 this->next_timeout_
+= this->interval_
;
485 this->current_buffer_size_
= 0;
490 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> void
491 ACE_Buffered_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::dump (void) const
493 #if defined (ACE_HAS_DUMP)
494 ACE_TRACE ("ACE_Buffered_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::dump");
496 ACE_Buffered_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::dump ();
497 ACELIB_DEBUG ((LM_DEBUG
,
498 "maximum_buffer_size_ = %d\n",
499 this->maximum_buffer_size_
));
500 ACELIB_DEBUG ((LM_DEBUG
,
501 "current_buffer_size_ = %d\n",
502 this->current_buffer_size_
));
503 if (this->timeoutp_
!= 0)
504 ACELIB_DEBUG ((LM_DEBUG
,
505 "next_timeout_.sec = %d, next_timeout_.usec = %d\n",
506 this->next_timeout_
.sec (),
507 this->next_timeout_
.usec ()));
508 #endif /* ACE_HAS_DUMP */
511 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> int
512 ACE_Buffered_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::handle_timeout (const ACE_Time_Value
&,
515 ACE_TRACE ("ACE_Buffered_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::handle_timeout");
519 ACE_END_VERSIONED_NAMESPACE_DECL
521 #endif /* ACE_SVC_HANDLER_CPP */