Svc_Handler.cpp

Go to the documentation of this file.
00001 // Svc_Handler.cpp,v 4.76 2006/06/02 10:00:02 jwillemsen Exp
00002 
00003 #ifndef ACE_SVC_HANDLER_CPP
00004 #define ACE_SVC_HANDLER_CPP
00005 
00006 #include "ace/Svc_Handler.h"
00007 
00008 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00009 # pragma once
00010 #endif /* ACE_LACKS_PRAGMA_ONCE */
00011 
00012 #include "ace/OS_NS_sys_time.h"
00013 #include "ace/Object_Manager.h"
00014 #include "ace/Connection_Recycling_Strategy.h"
00015 
00016 #include "ace/Dynamic.h"
00017 
00018 #define PR_ST_1 ACE_PEER_STREAM_1
00019 #define PR_ST_2 ACE_PEER_STREAM_2
00020 
00021 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00022 
00023 template <PR_ST_1, ACE_SYNCH_DECL> void *
00024 ACE_Svc_Handler<PR_ST_2,  ACE_SYNCH_USE>::operator new (size_t,
00025                                                         void *p)
00026 {
00027   ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::operator new (NOOP, 2 parameters)");
00028   return p;
00029 }
00030 
00031 #if !defined (ACE_LACKS_PLACEMENT_OPERATOR_DELETE)
00032 template <PR_ST_1, ACE_SYNCH_DECL> void
00033 ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::operator delete (void *,
00034                                                           void *)
00035 {
00036   ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::operator delete (NOOP, 2 parameters)");
00037   return;
00038 }
00039 #endif /* ACE_LACKS_PLACEMENT_OPERATOR_DELETE */
00040 
00041 template <PR_ST_1, ACE_SYNCH_DECL> void *
00042 ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::operator new (size_t n)
00043 {
00044   ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::operator new");
00045 
00046   ACE_Dynamic *const dynamic_instance = ACE_Dynamic::instance ();
00047 
00048   if (dynamic_instance == 0)
00049     {
00050       // If this ACE_ASSERT fails, it may be due to running of out TSS
00051       // keys.  Try using ACE_HAS_TSS_EMULATION, or increasing
00052       // ACE_DEFAULT_THREAD_KEYS if already using TSS emulation.
00053       ACE_ASSERT (dynamic_instance != 0);
00054 
00055       ACE_throw_bad_alloc;
00056     }
00057   else
00058     {
00059       // Allocate the memory and store it (usually in thread-specific
00060       // storage, depending on config flags).
00061       dynamic_instance->set ();
00062 
00063       return ::new char[n];
00064     }
00065 }
00066 
00067 #if defined (ACE_HAS_NEW_NOTHROW)
00068 template <PR_ST_1, ACE_SYNCH_DECL> void *
00069 ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::operator new (size_t n,
00070                                                        const ACE_nothrow_t&) throw()
00071 {
00072   ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::operator new(nothrow)");
00073 
00074   ACE_Dynamic *const dynamic_instance = ACE_Dynamic::instance ();
00075 
00076   if (dynamic_instance == 0)
00077     {
00078       // If this ACE_ASSERT fails, it may be due to running of out TSS
00079       // keys.  Try using ACE_HAS_TSS_EMULATION, or increasing
00080       // ACE_DEFAULT_THREAD_KEYS if already using TSS emulation.
00081       ACE_ASSERT (dynamic_instance != 0);
00082 
00083       return 0;
00084     }
00085   else
00086     {
00087       // Allocate the memory and store it (usually in thread-specific
00088       // storage, depending on config flags).
00089       dynamic_instance->set ();
00090 
00091       return ::new(ACE_nothrow) char[n];
00092     }
00093 }
00094 
00095 #if !defined (ACE_LACKS_PLACEMENT_OPERATOR_DELETE)
00096 template <PR_ST_1, ACE_SYNCH_DECL> void
00097 ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::operator delete (void *p,
00098                                          const ACE_nothrow_t&) throw()
00099 {
00100   ACE_TRACE
00101     ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::operator delete(nothrow)");
00102   ::delete [] static_cast <char *> (p);
00103 }
00104 #endif /* ACE_LACKS_PLACEMENT_OPERATOR_DELETE */
00105 
00106 #endif /* ACE_HAS_NEW_NOTHROW */
00107 
00108 template <PR_ST_1, ACE_SYNCH_DECL> void
00109 ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::destroy (void)
00110 {
00111   ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::destroy");
00112 
00113   // Only delete ourselves if we're not owned by a module and have
00114   // been allocated dynamically.
00115   if (this->mod_ == 0 && this->dynamic_ && this->closing_ == 0)
00116     // Will call the destructor, which automatically calls <shutdown>.
00117     // Note that if we are *not* allocated dynamically then the
00118     // destructor will call <shutdown> automatically when it gets run
00119     // during cleanup.
00120     delete this;
00121 }
00122 
00123 template <PR_ST_1, ACE_SYNCH_DECL> void
00124 ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::operator delete (void *obj)
00125 {
00126   ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::operator delete");
00127   // You cannot delete a 'void*' (X3J16/95-0087 5.3.5.3), but we know
00128   // the pointer was created using new char[] (see operator new code),
00129   // so we use a cast:
00130   ::delete [] static_cast <char *> (obj);
00131 }
00132 
00133 // Default constructor.
00134 
00135 template <PR_ST_1, ACE_SYNCH_DECL>
00136 ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::ACE_Svc_Handler (ACE_Thread_Manager *tm,
00137                                                           ACE_Message_Queue<ACE_SYNCH_USE> *mq,
00138                                                           ACE_Reactor *reactor)
00139   : ACE_Task<ACE_SYNCH_USE> (tm, mq),
00140     closing_ (0),
00141     recycler_ (0),
00142     recycling_act_ (0)
00143 {
00144   ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::ACE_Svc_Handler");
00145 
00146   this->reactor (reactor);
00147 
00148   // This clever idiom transparently checks if we were allocated
00149   // dynamically.  This information is used by the <destroy> method to
00150   // decide if we need to delete <this>...  The idiom is based on a
00151   // paper by Michael van Rooyen (mrooyen@cellnet.co.uk) that appeared
00152   // in the April '96 issue of the C++ Report.  We've spruced it up to
00153   // work correctly in multi-threaded programs by using our ACE_TSS
00154   // class.
00155   this->dynamic_ = ACE_Dynamic::instance ()->is_dynamic ();
00156 
00157   if (this->dynamic_ != 0)
00158     // Make sure to reset the flag.
00159     ACE_Dynamic::instance ()->reset ();
00160 }
00161 
00162 // Default behavior for a ACE_Svc_Handler object is to be registered
00163 // with the ACE_Reactor (thereby ensuring single threading).
00164 
00165 template <PR_ST_1, ACE_SYNCH_DECL> int
00166 ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::open (void *)
00167 {
00168   ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::open");
00169 #if defined (ACE_DEBUGGING)
00170   ACE_TCHAR buf[BUFSIZ];
00171   ACE_PEER_STREAM_ADDR client_addr;
00172 
00173   if (this->peer_.get_remote_addr (client_addr) == -1)
00174     ACE_ERROR_RETURN ((LM_ERROR,
00175                        ACE_LIB_TEXT ("%p\n"),
00176                        ACE_LIB_TEXT ("get_remote_addr")),
00177                       -1);
00178   else if (client_addr.addr_to_string (buf, sizeof buf) == -1)
00179     ACE_ERROR_RETURN ((LM_ERROR,
00180                        ACE_LIB_TEXT ("%p\n"),
00181                        ACE_LIB_TEXT ("can't obtain peer's address")),
00182                       -1);
00183   ACE_DEBUG ((LM_DEBUG,
00184               ACE_LIB_TEXT ("connected to %s on fd %d\n"),
00185               buf,
00186               this->peer_.get_handle ()));
00187 #endif /* ACE_DEBUGGING */
00188   if (this->reactor ()
00189       && this->reactor ()->register_handler
00190       (this,
00191        ACE_Event_Handler::READ_MASK) == -1)
00192     ACE_ERROR_RETURN ((LM_ERROR,
00193                        ACE_LIB_TEXT ("%p\n"),
00194                        ACE_LIB_TEXT ("unable to register client handler")),
00195                       -1);
00196   return 0;
00197 }
00198 
00199 // Perform termination activities.
00200 
00201 template <PR_ST_1, ACE_SYNCH_DECL> void
00202 ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::shutdown (void)
00203 {
00204   ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::shutdown");
00205 
00206   // Deregister this handler with the ACE_Reactor.
00207   if (this->reactor ())
00208     {
00209       ACE_Reactor_Mask mask = ACE_Event_Handler::ALL_EVENTS_MASK |
00210         ACE_Event_Handler::DONT_CALL;
00211 
00212       // Make sure there are no timers.
00213       this->reactor ()->cancel_timer (this);
00214 
00215       if (this->peer ().get_handle () != ACE_INVALID_HANDLE)
00216         // Remove self from reactor.
00217         this->reactor ()->remove_handler (this, mask);
00218     }
00219 
00220   // Remove self from the recycler.
00221   if (this->recycler ())
00222     this->recycler ()->purge (this->recycling_act_);
00223 
00224   this->peer ().close ();
00225 }
00226 
00227 template <PR_ST_1, ACE_SYNCH_DECL> void
00228 ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::cleanup_hint (void **act_holder)
00229 {
00230   ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::cleanup_hint");
00231 
00232   // Remove as hint.
00233   if (this->recycler ())
00234     this->recycler ()->cleanup_hint (this->recycling_act_,
00235                                      act_holder);
00236 }
00237 
00238 template <PR_ST_1, ACE_SYNCH_DECL> void
00239 ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::dump (void) const
00240 {
00241 #if defined (ACE_HAS_DUMP)
00242   ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::dump");
00243 
00244   this->peer_.dump ();
00245   ACE_DEBUG ((LM_DEBUG,
00246               "dynamic_ = %d\n",
00247               this->dynamic_));
00248   ACE_DEBUG ((LM_DEBUG,
00249               "closing_ = %d\n",
00250               this->closing_));
00251   ACE_DEBUG ((LM_DEBUG,
00252               "recycler_ = %d\n",
00253               this->recycler_));
00254   ACE_DEBUG ((LM_DEBUG,
00255               "recycling_act_ = %d\n",
00256               this->recycling_act_));
00257 #endif /* ACE_HAS_DUMP */
00258 }
00259 
00260 template <PR_ST_1, ACE_SYNCH_DECL> ACE_PEER_STREAM &
00261 ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::peer (void) const
00262 {
00263   ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::peer");
00264   return (ACE_PEER_STREAM &) this->peer_;
00265 }
00266 
00267 // Extract the underlying I/O descriptor.
00268 
00269 template <PR_ST_1, ACE_SYNCH_DECL> ACE_HANDLE
00270 ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::get_handle (void) const
00271 {
00272   ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::get_handle");
00273   return this->peer_.get_handle ();
00274 }
00275 
00276 // Set the underlying I/O descriptor.
00277 
00278 template <PR_ST_1, ACE_SYNCH_DECL> void
00279 ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::set_handle (ACE_HANDLE h)
00280 {
00281   ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::set_handle");
00282   this->peer_.set_handle (h);
00283 }
00284 
00285 template <PR_ST_1, ACE_SYNCH_DECL>
00286 ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::~ACE_Svc_Handler (void)
00287 {
00288   ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::~ACE_Svc_Handler");
00289 
00290   if (this->closing_ == 0)
00291     {
00292       // We're closing down now, so make sure not to call ourselves
00293       // recursively via other calls to handle_close() (e.g., from the
00294       // Timer_Queue).
00295       this->closing_ = 1;
00296 
00297       this->shutdown ();
00298     }
00299 }
00300 
00301 template <PR_ST_1, ACE_SYNCH_DECL> int
00302 ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::handle_close (ACE_HANDLE,
00303                                                        ACE_Reactor_Mask)
00304 {
00305   ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::handle_close");
00306 
00307   this->destroy ();
00308   return 0;
00309 }
00310 
00311 template <PR_ST_1, ACE_SYNCH_DECL> int
00312 ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::handle_timeout (const ACE_Time_Value &,
00313                                                          const void *)
00314 {
00315   ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::handle_timeout");
00316   return this->handle_close ();
00317 }
00318 
00319 template <PR_ST_1, ACE_SYNCH_DECL> int
00320 ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::close (u_long)
00321 {
00322   ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::close");
00323   return this->handle_close ();
00324 }
00325 
00326 template <PR_ST_1, ACE_SYNCH_DECL> int
00327 ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::init (int argc, ACE_TCHAR *argv[])
00328 {
00329   ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::init");
00330   ACE_UNUSED_ARG (argc);
00331   ACE_UNUSED_ARG (argv);
00332   return -1;
00333 }
00334 
00335 template <PR_ST_1, ACE_SYNCH_DECL> int
00336 ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::fini (void)
00337 {
00338   ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::fini");
00339   return -1;
00340 }
00341 
00342 template <PR_ST_1, ACE_SYNCH_DECL> int
00343 ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::info (ACE_TCHAR **, size_t) const
00344 {
00345   ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::info");
00346   return -1;
00347 }
00348 
00349 template <PR_ST_1, ACE_SYNCH_DECL> int
00350 ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::idle (u_long flags)
00351 {
00352   if (this->recycler ())
00353     return this->recycler ()->cache (this->recycling_act_);
00354   else
00355     return this->close (flags);
00356 }
00357 
00358 template <PR_ST_1, ACE_SYNCH_DECL> int
00359 ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::recycle_state (ACE_Recyclable_State new_state)
00360 {
00361   if (this->recycler ())
00362     return this->recycler ()->recycle_state (this->recycling_act_,
00363                                              new_state);
00364 
00365   return 0;
00366 }
00367 
00368 template <PR_ST_1, ACE_SYNCH_DECL> ACE_Recyclable_State
00369 ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::recycle_state (void) const
00370 {
00371   if (this->recycler ())
00372     return this->recycler ()->recycle_state (this->recycling_act_);
00373 
00374   return ACE_RECYCLABLE_UNKNOWN;
00375 }
00376 
00377 template <PR_ST_1, ACE_SYNCH_DECL> void
00378 ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::recycler (ACE_Connection_Recycling_Strategy *recycler,
00379                                                    const void *recycling_act)
00380 {
00381   ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::recycler");
00382   this->recycler_ = recycler;
00383   this->recycling_act_ = recycling_act;
00384 }
00385 
00386 template <PR_ST_1, ACE_SYNCH_DECL> ACE_Connection_Recycling_Strategy *
00387 ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::recycler (void) const
00388 {
00389   ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::recycler");
00390   return this->recycler_;
00391 }
00392 
00393 template <PR_ST_1, ACE_SYNCH_DECL> const void *
00394 ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::recycling_act (void) const
00395 {
00396   ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::recycling_act");
00397   return this->recycling_act_;
00398 }
00399 
00400 template <PR_ST_1, ACE_SYNCH_DECL> int
00401 ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::recycle (void *)
00402 {
00403   ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::recycle");
00404   // By default, the object is ready and willing to be recycled.
00405   return 0;
00406 }
00407 
00408 template <PR_ST_1, ACE_SYNCH_DECL>
00409 ACE_Buffered_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::~ACE_Buffered_Svc_Handler (void)
00410 {
00411   this->flush ();
00412 }
00413 
00414 template <PR_ST_1, ACE_SYNCH_DECL>
00415 ACE_Buffered_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::ACE_Buffered_Svc_Handler (ACE_Thread_Manager *tm,
00416                                                                             ACE_Message_Queue<ACE_SYNCH_USE> *mq,
00417                                                                             ACE_Reactor *reactor,
00418                                                                             size_t maximum_buffer_size,
00419                                                                             ACE_Time_Value *timeout)
00420   : ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE> (tm, mq, reactor),
00421     maximum_buffer_size_ (maximum_buffer_size),
00422     current_buffer_size_ (0),
00423     timeoutp_ (timeout)
00424 {
00425   ACE_TRACE ("ACE_Buffered_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::ACE_Buffered_Svc_Handler");
00426 
00427   if (this->timeoutp_ != 0)
00428     {
00429       this->interval_ = *timeout;
00430       this->next_timeout_ = ACE_OS::gettimeofday () + this->interval_;
00431     }
00432 }
00433 
00434 template <PR_ST_1, ACE_SYNCH_DECL> int
00435 ACE_Buffered_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::put (ACE_Message_Block *mb,
00436                                                        ACE_Time_Value *tv)
00437 {
00438   ACE_GUARD_RETURN (ACE_SYNCH_MUTEX_T, m, this->msg_queue ()->lock (), -1);
00439 
00440   // Enqueue <mb> onto the message queue.
00441   if (this->putq (mb, tv) == -1)
00442     return -1;
00443   else
00444     {
00445       // Update the current number of bytes on the queue.
00446       this->current_buffer_size_ += mb->total_size ();
00447 
00448       // Flush the buffer when the number of bytes exceeds the maximum
00449       // buffer size or when the timeout period has elapsed.
00450       if (this->current_buffer_size_ >= this->maximum_buffer_size_
00451           || (this->timeoutp_ != 0
00452               && this->next_timeout_ <= ACE_OS::gettimeofday ()))
00453         return this->flush_i ();
00454       else
00455         return 0;
00456     }
00457 }
00458 
00459 // Flush the buffer.
00460 
00461 template <PR_ST_1, ACE_SYNCH_DECL> int
00462 ACE_Buffered_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::flush (void)
00463 {
00464   ACE_GUARD_RETURN (ACE_SYNCH_MUTEX_T, m, this->msg_queue ()->lock (), -1);
00465 
00466   return this->flush_i ();
00467 }
00468 
00469 template <PR_ST_1, ACE_SYNCH_DECL> int
00470 ACE_Buffered_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::flush_i (void)
00471 {
00472   ACE_Message_Queue_Iterator<ACE_SYNCH_USE> iterator (*this->msg_queue ());
00473   ACE_Message_Block *mblk = 0;
00474   ssize_t result = 0;
00475 
00476   // Get the first <ACE_Message_Block> so that we can write everything
00477   // out via the <send_n>.
00478   if (iterator.next (mblk) != 0)
00479     result = this->peer ().send_n (mblk);
00480 
00481   // This method assumes the caller holds the queue's lock!
00482   if (result != -1)
00483     this->msg_queue ()->flush_i ();
00484 
00485   if (this->timeoutp_ != 0)
00486     // Update the next timeout period by adding the interval.
00487     this->next_timeout_ += this->interval_;
00488 
00489   this->current_buffer_size_ = 0;
00490 
00491   return result;
00492 }
00493 
00494 template <PR_ST_1, ACE_SYNCH_DECL> void
00495 ACE_Buffered_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::dump (void) const
00496 {
00497 #if defined (ACE_HAS_DUMP)
00498   ACE_TRACE ("ACE_Buffered_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::dump");
00499 
00500   ACE_Buffered_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::dump ();
00501   ACE_DEBUG ((LM_DEBUG,
00502               "maximum_buffer_size_ = %d\n",
00503               this->maximum_buffer_size_));
00504   ACE_DEBUG ((LM_DEBUG,
00505               "current_buffer_size_ = %d\n",
00506               this->current_buffer_size_));
00507   if (this->timeoutp_ != 0)
00508     ACE_DEBUG ((LM_DEBUG,
00509                 "next_timeout_.sec = %d, next_timeout_.usec = %d\n",
00510                 this->next_timeout_.sec (),
00511                 this->next_timeout_.usec ()));
00512 #endif /* ACE_HAS_DUMP */
00513 }
00514 
00515 template <PR_ST_1, ACE_SYNCH_DECL> int
00516 ACE_Buffered_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::handle_timeout (const ACE_Time_Value &,
00517                                                                   const void *)
00518 {
00519   ACE_TRACE ("ACE_Buffered_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::handle_timeout");
00520   return 0;
00521 }
00522 
00523 ACE_END_VERSIONED_NAMESPACE_DECL
00524 
00525 #undef PR_ST_1
00526 #undef PR_ST_2
00527 #endif /* ACE_SVC_HANDLER_CPP */

Generated on Thu Nov 9 09:42:06 2006 for ACE by doxygen 1.3.6