Also use Objects as part of an operation but as a result don't generate Any operation...
[ACE_TAO.git] / ACE / ace / Svc_Handler.cpp
blob1774e0188da2190b5c0847d786e5891b53c430a6
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)
7 # 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)");
22 return p;
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)");
30 return;
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);
48 ACE_throw_bad_alloc;
50 else
52 // Allocate the memory and store it (usually in thread-specific
53 // storage, depending on config flags).
54 dynamic_instance->set ();
56 return ::new char[n];
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);
76 return 0;
78 else
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
111 // during cleanup.
112 delete this;
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),
121 // so we use a cast:
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),
132 closing_ (false),
133 recycler_ (0),
134 recycling_act_ (0)
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
146 // class.
147 this->dynamic_ = ACE_Dynamic::instance ()->is_dynamic ();
149 if (this->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,
167 ACE_TEXT ("%p\n"),
168 ACE_TEXT ("get_remote_addr")),
169 -1);
170 else if (client_addr.addr_to_string (buf, sizeof buf) == -1)
171 ACELIB_ERROR_RETURN ((LM_ERROR,
172 ACE_TEXT ("%p\n"),
173 ACE_TEXT ("can't obtain peer's address")),
174 -1);
175 ACELIB_DEBUG ((LM_DEBUG,
176 ACE_TEXT ("connected to %s on fd %d\n"),
177 buf,
178 this->peer_.get_handle ()));
179 #endif /* ACELIB_DEBUGGING */
180 if (this->reactor ()
181 && this->reactor ()->register_handler
182 (this,
183 ACE_Event_Handler::READ_MASK) == -1)
184 ACELIB_ERROR_RETURN ((LM_ERROR,
185 ACE_TEXT ("%p\n"),
186 ACE_TEXT ("unable to register client handler")),
187 -1);
188 return 0;
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");
224 // Remove as hint.
225 if (this->recycler ())
226 this->recycler ()->cleanup_hint (this->recycling_act_,
227 act_holder);
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");
236 this->peer_.dump ();
237 ACELIB_DEBUG ((LM_DEBUG,
238 "dynamic_ = %d\n",
239 this->dynamic_));
240 ACELIB_DEBUG ((LM_DEBUG,
241 "closing_ = %d\n",
242 this->closing_));
243 ACELIB_DEBUG ((LM_DEBUG,
244 "recycler_ = %d\n",
245 this->recycler_));
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
286 // Timer_Queue).
287 this->closing_ = true;
289 this->shutdown ();
293 template <typename PEER_STREAM, typename SYNCH_TRAITS> int
294 ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::handle_close (ACE_HANDLE,
295 ACE_Reactor_Mask)
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)
302 this->destroy ();
305 return 0;
308 template <typename PEER_STREAM, typename SYNCH_TRAITS> int
309 ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::handle_timeout (const ACE_Time_Value &,
310 const void *)
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");
328 return -1;
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");
335 return -1;
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");
342 return -1;
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_);
350 else
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_,
359 new_state);
361 return 0;
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.
401 return 0;
404 template <typename PEER_STREAM, typename SYNCH_TRAITS>
405 ACE_Buffered_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::~ACE_Buffered_Svc_Handler (void)
407 this->flush ();
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),
419 timeoutp_ (timeout)
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,
432 ACE_Time_Value *tv)
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)
438 return -1;
439 else
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 ();
450 else
451 return 0;
455 // Flush the buffer.
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;
470 ssize_t result = 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!
478 if (result != -1)
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;
487 return result;
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 &,
513 const void *)
515 ACE_TRACE ("ACE_Buffered_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::handle_timeout");
516 return 0;
519 ACE_END_VERSIONED_NAMESPACE_DECL
521 #endif /* ACE_SVC_HANDLER_CPP */