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"
13 #include "ace/Dynamic.h"
15 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
17 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> void *
18 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::operator new (size_t, void *p
)
20 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::operator new (NOOP, 2 parameters)");
24 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> void
25 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::operator delete (void *, void *)
27 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::operator delete (NOOP, 2 parameters)");
31 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> void *
32 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::operator new (size_t n
)
34 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::operator new");
36 ACE_Dynamic
*const dynamic_instance
= ACE_Dynamic::instance ();
38 if (!dynamic_instance
)
40 // If this ACE_ASSERT fails, it may be due to running of out TSS
41 // keys. Try using ACE_HAS_TSS_EMULATION, or increasing
42 // ACE_DEFAULT_THREAD_KEYS if already using TSS emulation.
43 ACE_ASSERT (dynamic_instance
!= 0);
45 throw std::bad_alloc ();
49 // Allocate the memory and store it (usually in thread-specific
50 // storage, depending on config flags).
51 dynamic_instance
->set ();
57 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> void *
58 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::operator new (size_t n
,
59 const std::nothrow_t
&) noexcept
61 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::operator new(nothrow)");
63 ACE_Dynamic
*const dynamic_instance
= ACE_Dynamic::instance ();
65 if (dynamic_instance
== 0)
67 // If this ACE_ASSERT fails, it may be due to running of out TSS
68 // keys. Try using ACE_HAS_TSS_EMULATION, or increasing
69 // ACE_DEFAULT_THREAD_KEYS if already using TSS emulation.
70 ACE_ASSERT (dynamic_instance
!= 0);
76 // Allocate the memory and store it (usually in thread-specific
77 // storage, depending on config flags).
78 dynamic_instance
->set ();
80 return ::new(std::nothrow
) char[n
];
84 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> void
85 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::operator delete (void *p
,
86 const std::nothrow_t
&) noexcept
88 ACE_TRACE("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::operator delete(nothrow)");
89 ::delete [] static_cast <char *> (p
);
92 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> void
93 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::destroy ()
95 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::destroy");
97 // Only delete ourselves if we're not owned by a module and have
98 // been allocated dynamically.
99 if (this->mod_
== 0 && this->dynamic_
&& this->closing_
== false)
100 // Will call the destructor, which automatically calls <shutdown>.
101 // Note that if we are *not* allocated dynamically then the
102 // destructor will call <shutdown> automatically when it gets run
107 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> void
108 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::operator delete (void *obj
)
110 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::operator delete");
111 // You cannot delete a 'void*' (X3J16/95-0087 5.3.5.3), but we know
112 // the pointer was created using new char[] (see operator new code),
114 ::delete [] static_cast <char *> (obj
);
117 // Default constructor.
119 template <typename PEER_STREAM
, typename SYNCH_TRAITS
>
120 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::ACE_Svc_Handler (ACE_Thread_Manager
*tm
,
121 ACE_Message_Queue
<SYNCH_TRAITS
> *mq
,
122 ACE_Reactor
*reactor
)
123 : ACE_Task
<SYNCH_TRAITS
> (tm
, mq
),
128 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::ACE_Svc_Handler");
130 this->reactor (reactor
);
132 // This clever idiom transparently checks if we were allocated
133 // dynamically. This information is used by the <destroy> method to
134 // decide if we need to delete <this>... The idiom is based on a
135 // paper by Michael van Rooyen (mrooyen@cellnet.co.uk) that appeared
136 // in the April '96 issue of the C++ Report. We've spruced it up to
137 // work correctly in multi-threaded programs by using our ACE_TSS
139 this->dynamic_
= ACE_Dynamic::instance ()->is_dynamic ();
142 // Make sure to reset the flag.
143 ACE_Dynamic::instance ()->reset ();
146 // Default behavior for a ACE_Svc_Handler object is to be registered
147 // with the ACE_Reactor (thereby ensuring single threading).
149 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> int
150 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::open (void *)
152 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::open");
153 #if defined (ACELIB_DEBUGGING)
154 ACE_TCHAR buf
[BUFSIZ
];
155 ACE_PEER_STREAM_ADDR client_addr
;
157 if (this->peer_
.get_remote_addr (client_addr
) == -1)
158 ACELIB_ERROR_RETURN ((LM_ERROR
,
160 ACE_TEXT ("get_remote_addr")),
162 else if (client_addr
.addr_to_string (buf
, sizeof buf
) == -1)
163 ACELIB_ERROR_RETURN ((LM_ERROR
,
165 ACE_TEXT ("can't obtain peer's address")),
167 ACELIB_DEBUG ((LM_DEBUG
,
168 ACE_TEXT ("connected to %s on fd %d\n"),
170 this->peer_
.get_handle ()));
171 #endif /* ACELIB_DEBUGGING */
173 && this->reactor ()->register_handler
175 ACE_Event_Handler::READ_MASK
) == -1)
176 ACELIB_ERROR_RETURN ((LM_ERROR
,
178 ACE_TEXT ("unable to register client handler")),
183 // Perform termination activities.
185 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> void
186 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::shutdown ()
188 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::shutdown");
190 // Deregister this handler with the ACE_Reactor.
191 if (this->reactor ())
193 ACE_Reactor_Mask mask
= ACE_Event_Handler::ALL_EVENTS_MASK
|
194 ACE_Event_Handler::DONT_CALL
;
196 // Make sure there are no timers.
197 this->reactor ()->cancel_timer (this);
199 if (this->peer ().get_handle () != ACE_INVALID_HANDLE
)
200 // Remove self from reactor.
201 this->reactor ()->remove_handler (this, mask
);
204 // Remove self from the recycler.
205 if (this->recycler ())
206 this->recycler ()->purge (this->recycling_act_
);
208 this->peer ().close ();
211 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> void
212 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::cleanup_hint (void **act_holder
)
214 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::cleanup_hint");
217 if (this->recycler ())
218 this->recycler ()->cleanup_hint (this->recycling_act_
,
222 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> void
223 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::dump () const
225 #if defined (ACE_HAS_DUMP)
226 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::dump");
229 ACELIB_DEBUG ((LM_DEBUG
,
232 ACELIB_DEBUG ((LM_DEBUG
,
235 ACELIB_DEBUG ((LM_DEBUG
,
238 ACELIB_DEBUG ((LM_DEBUG
,
239 "recycling_act_ = %d\n",
240 this->recycling_act_
));
241 #endif /* ACE_HAS_DUMP */
244 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> PEER_STREAM
&
245 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::peer () const
247 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::peer");
248 return (PEER_STREAM
&) this->peer_
;
251 // Extract the underlying I/O descriptor.
253 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> ACE_HANDLE
254 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::get_handle () const
256 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::get_handle");
257 return this->peer_
.get_handle ();
260 // Set the underlying I/O descriptor.
262 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> void
263 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::set_handle (ACE_HANDLE h
)
265 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::set_handle");
266 this->peer_
.set_handle (h
);
269 template <typename PEER_STREAM
, typename SYNCH_TRAITS
>
270 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::~ACE_Svc_Handler ()
272 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::~ACE_Svc_Handler");
274 if (this->closing_
== false)
276 // We're closing down now, so make sure not to call ourselves
277 // recursively via other calls to handle_close() (e.g., from the
279 this->closing_
= true;
285 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> int
286 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::handle_close (ACE_HANDLE
,
289 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::handle_close");
291 if (this->reference_counting_policy ().value () ==
292 ACE_Event_Handler::Reference_Counting_Policy::DISABLED
)
300 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> int
301 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::handle_timeout (const ACE_Time_Value
&,
304 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::handle_timeout");
305 return this->handle_close ();
308 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> int
309 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::close (u_long
)
311 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::close");
312 return this->handle_close ();
315 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> int
316 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::init (int /* argc */,
317 ACE_TCHAR
* /* argv */[])
319 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::init");
323 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> int
324 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::fini ()
326 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::fini");
330 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> int
331 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::info (ACE_TCHAR
**, size_t) const
333 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::info");
337 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> int
338 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::idle (u_long flags
)
340 if (this->recycler ())
341 return this->recycler ()->cache (this->recycling_act_
);
343 return this->close (flags
);
346 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> int
347 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::recycle_state (ACE_Recyclable_State new_state
)
349 if (this->recycler ())
350 return this->recycler ()->recycle_state (this->recycling_act_
,
356 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> ACE_Recyclable_State
357 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::recycle_state () const
359 if (this->recycler ())
360 return this->recycler ()->recycle_state (this->recycling_act_
);
362 return ACE_RECYCLABLE_UNKNOWN
;
365 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> void
366 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::recycler (ACE_Connection_Recycling_Strategy
*recycler
,
367 const void *recycling_act
)
369 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::recycler");
370 this->recycler_
= recycler
;
371 this->recycling_act_
= recycling_act
;
374 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> ACE_Connection_Recycling_Strategy
*
375 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::recycler () const
377 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::recycler");
378 return this->recycler_
;
381 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> const void *
382 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::recycling_act () const
384 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::recycling_act");
385 return this->recycling_act_
;
388 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> int
389 ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::recycle (void *)
391 ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::recycle");
392 // By default, the object is ready and willing to be recycled.
396 template <typename PEER_STREAM
, typename SYNCH_TRAITS
>
397 ACE_Buffered_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::~ACE_Buffered_Svc_Handler ()
402 template <typename PEER_STREAM
, typename SYNCH_TRAITS
>
403 ACE_Buffered_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::ACE_Buffered_Svc_Handler (ACE_Thread_Manager
*tm
,
404 ACE_Message_Queue
<SYNCH_TRAITS
> *mq
,
405 ACE_Reactor
*reactor
,
406 size_t maximum_buffer_size
,
407 ACE_Time_Value
*timeout
)
408 : ACE_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
> (tm
, mq
, reactor
),
409 maximum_buffer_size_ (maximum_buffer_size
),
410 current_buffer_size_ (0),
413 ACE_TRACE ("ACE_Buffered_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::ACE_Buffered_Svc_Handler");
415 if (this->timeoutp_
!= 0)
417 this->interval_
= *timeout
;
418 this->next_timeout_
= ACE_OS::gettimeofday () + this->interval_
;
422 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> int
423 ACE_Buffered_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::put (ACE_Message_Block
*mb
,
426 ACE_GUARD_RETURN (typename
SYNCH_TRAITS::MUTEX
, m
, this->msg_queue ()->lock (), -1);
428 // Enqueue <mb> onto the message queue.
429 if (this->putq (mb
, tv
) == -1)
433 // Update the current number of bytes on the queue.
434 this->current_buffer_size_
+= mb
->total_size ();
436 // Flush the buffer when the number of bytes exceeds the maximum
437 // buffer size or when the timeout period has elapsed.
438 if (this->current_buffer_size_
>= this->maximum_buffer_size_
439 || (this->timeoutp_
!= 0
440 && this->next_timeout_
<= ACE_OS::gettimeofday ()))
441 return this->flush_i ();
449 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> int
450 ACE_Buffered_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::flush ()
452 ACE_GUARD_RETURN (typename
SYNCH_TRAITS::MUTEX
, m
, this->msg_queue ()->lock (), -1);
454 return this->flush_i ();
457 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> int
458 ACE_Buffered_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::flush_i ()
460 ACE_Message_Queue_Iterator
<SYNCH_TRAITS
> iterator (*this->msg_queue ());
461 ACE_Message_Block
*mblk
= 0;
464 // Get the first <ACE_Message_Block> so that we can write everything
465 // out via the <send_n>.
466 if (iterator
.next (mblk
) != 0)
467 result
= this->peer ().send_n (mblk
);
469 // This method assumes the caller holds the queue's lock!
471 this->msg_queue ()->flush_i ();
473 if (this->timeoutp_
!= 0)
474 // Update the next timeout period by adding the interval.
475 this->next_timeout_
+= this->interval_
;
477 this->current_buffer_size_
= 0;
482 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> void
483 ACE_Buffered_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::dump () const
485 #if defined (ACE_HAS_DUMP)
486 ACE_TRACE ("ACE_Buffered_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::dump");
488 ACE_Buffered_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::dump ();
489 ACELIB_DEBUG ((LM_DEBUG
,
490 "maximum_buffer_size_ = %d\n",
491 this->maximum_buffer_size_
));
492 ACELIB_DEBUG ((LM_DEBUG
,
493 "current_buffer_size_ = %d\n",
494 this->current_buffer_size_
));
495 if (this->timeoutp_
!= 0)
496 ACELIB_DEBUG ((LM_DEBUG
,
497 "next_timeout_.sec = %d, next_timeout_.usec = %d\n",
498 this->next_timeout_
.sec (),
499 this->next_timeout_
.usec ()));
500 #endif /* ACE_HAS_DUMP */
503 template <typename PEER_STREAM
, typename SYNCH_TRAITS
> int
504 ACE_Buffered_Svc_Handler
<PEER_STREAM
, SYNCH_TRAITS
>::handle_timeout (const ACE_Time_Value
&,
507 ACE_TRACE ("ACE_Buffered_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::handle_timeout");
511 ACE_END_VERSIONED_NAMESPACE_DECL
513 #endif /* ACE_SVC_HANDLER_CPP */