Document return values
[ACE_TAO.git] / ACE / ace / Svc_Handler.cpp
blob0c6a147c824aa842b2307bc1cdc03c012062314b
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"
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)");
21 return p;
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)");
28 return;
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 ();
47 else
49 // Allocate the memory and store it (usually in thread-specific
50 // storage, depending on config flags).
51 dynamic_instance->set ();
53 return ::new char[n];
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);
72 return 0;
74 else
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
103 // during cleanup.
104 delete this;
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),
113 // so we use a cast:
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),
124 closing_ (false),
125 recycler_ (0),
126 recycling_act_ (0)
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
138 // class.
139 this->dynamic_ = ACE_Dynamic::instance ()->is_dynamic ();
141 if (this->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,
159 ACE_TEXT ("%p\n"),
160 ACE_TEXT ("get_remote_addr")),
161 -1);
162 else if (client_addr.addr_to_string (buf, sizeof buf) == -1)
163 ACELIB_ERROR_RETURN ((LM_ERROR,
164 ACE_TEXT ("%p\n"),
165 ACE_TEXT ("can't obtain peer's address")),
166 -1);
167 ACELIB_DEBUG ((LM_DEBUG,
168 ACE_TEXT ("connected to %s on fd %d\n"),
169 buf,
170 this->peer_.get_handle ()));
171 #endif /* ACELIB_DEBUGGING */
172 if (this->reactor ()
173 && this->reactor ()->register_handler
174 (this,
175 ACE_Event_Handler::READ_MASK) == -1)
176 ACELIB_ERROR_RETURN ((LM_ERROR,
177 ACE_TEXT ("%p\n"),
178 ACE_TEXT ("unable to register client handler")),
179 -1);
180 return 0;
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");
216 // Remove as hint.
217 if (this->recycler ())
218 this->recycler ()->cleanup_hint (this->recycling_act_,
219 act_holder);
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");
228 this->peer_.dump ();
229 ACELIB_DEBUG ((LM_DEBUG,
230 "dynamic_ = %d\n",
231 this->dynamic_));
232 ACELIB_DEBUG ((LM_DEBUG,
233 "closing_ = %d\n",
234 this->closing_));
235 ACELIB_DEBUG ((LM_DEBUG,
236 "recycler_ = %d\n",
237 this->recycler_));
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
278 // Timer_Queue).
279 this->closing_ = true;
281 this->shutdown ();
285 template <typename PEER_STREAM, typename SYNCH_TRAITS> int
286 ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::handle_close (ACE_HANDLE,
287 ACE_Reactor_Mask)
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)
294 this->destroy ();
297 return 0;
300 template <typename PEER_STREAM, typename SYNCH_TRAITS> int
301 ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::handle_timeout (const ACE_Time_Value &,
302 const void *)
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");
320 return -1;
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");
327 return -1;
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");
334 return -1;
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_);
342 else
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_,
351 new_state);
353 return 0;
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.
393 return 0;
396 template <typename PEER_STREAM, typename SYNCH_TRAITS>
397 ACE_Buffered_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::~ACE_Buffered_Svc_Handler ()
399 this->flush ();
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),
411 timeoutp_ (timeout)
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,
424 ACE_Time_Value *tv)
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)
430 return -1;
431 else
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 ();
442 else
443 return 0;
447 // Flush the buffer.
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;
462 ssize_t result = 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!
470 if (result != -1)
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;
479 return result;
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 &,
505 const void *)
507 ACE_TRACE ("ACE_Buffered_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::handle_timeout");
508 return 0;
511 ACE_END_VERSIONED_NAMESPACE_DECL
513 #endif /* ACE_SVC_HANDLER_CPP */