Select_Reactor_T.cpp

Go to the documentation of this file.
00001 // $Id: Select_Reactor_T.cpp 79134 2007-07-31 18:23:50Z johnnyw $
00002 
00003 #ifndef ACE_SELECT_REACTOR_T_CPP
00004 #define ACE_SELECT_REACTOR_T_CPP
00005 
00006 #include "ace/Select_Reactor_T.h"
00007 
00008 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00009 # pragma once
00010 #endif /* ACE_LACKS_PRAGMA_ONCE */
00011 
00012 #include "ace/ACE.h"
00013 #include "ace/Guard_T.h"
00014 #include "ace/Log_Msg.h"
00015 #include "ace/Signal.h"
00016 #include "ace/Sig_Handler.h"
00017 #include "ace/Thread.h"
00018 #include "ace/Timer_Heap.h"
00019 #include "ace/OS_NS_errno.h"
00020 #include "ace/OS_NS_sys_select.h"
00021 #include "ace/OS_NS_sys_stat.h"
00022 
00023 // For timer_queue_
00024 #include "ace/Recursive_Thread_Mutex.h"
00025 
00026 /*
00027  * ACE Reactor specialization hook.
00028  */
00029 //@@ REACTOR_SPL_INCLUDE_FORWARD_DECL_ADD_HOOK
00030 
00031 #if !defined (__ACE_INLINE__)
00032 #include "ace/Select_Reactor_T.inl"
00033 #endif /* __ACE_INLINE__ */
00034 
00035 ACE_RCSID (ace,
00036            Select_Reactor_T,
00037            "$Id: Select_Reactor_T.cpp 79134 2007-07-31 18:23:50Z johnnyw $")
00038 
00039 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00040 
00041 ACE_ALLOC_HOOK_DEFINE(ACE_Select_Reactor_T)
00042 
00043 template <class ACE_SELECT_REACTOR_TOKEN> int
00044 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::any_ready
00045   (ACE_Select_Reactor_Handle_Set &wait_set)
00046 {
00047   ACE_TRACE ("ACE_Select_Reactor_T::any_ready");
00048 
00049   if (this->mask_signals_)
00050     {
00051 #if !defined (ACE_WIN32)
00052       // Make this call signal safe.
00053       ACE_Sig_Guard sb;
00054 #endif /* ACE_WIN32 */
00055 
00056       return this->any_ready_i (wait_set);
00057     }
00058   return this->any_ready_i (wait_set);
00059 }
00060 
00061 template <class ACE_SELECT_REACTOR_TOKEN> int
00062 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::any_ready_i
00063   (ACE_Select_Reactor_Handle_Set &wait_set)
00064 {
00065   ACE_TRACE ("ACE_Select_Reactor_T::any_ready_i");
00066 
00067   int number_ready = this->ready_set_.rd_mask_.num_set ()
00068     + this->ready_set_.wr_mask_.num_set ()
00069     + this->ready_set_.ex_mask_.num_set ();
00070 
00071   // number_ready > 0 meaning there are handles in the ready_set
00072   // &wait_set != &(this->ready_set_) means that we need to copy
00073   // the handles from the ready_set to the wait set because the
00074   // wait_set_ doesn't contain all the handles in the ready_set_
00075   if (number_ready > 0 && &wait_set != &(this->ready_set_))
00076     {
00077       wait_set.rd_mask_ = this->ready_set_.rd_mask_;
00078       wait_set.wr_mask_ = this->ready_set_.wr_mask_;
00079       wait_set.ex_mask_ = this->ready_set_.ex_mask_;
00080 
00081       this->ready_set_.rd_mask_.reset ();
00082       this->ready_set_.wr_mask_.reset ();
00083       this->ready_set_.ex_mask_.reset ();
00084     }
00085 
00086   return number_ready;
00087 }
00088 
00089 template <class ACE_SELECT_REACTOR_TOKEN> int
00090 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::handler_i (int signum,
00091                                                            ACE_Event_Handler **eh)
00092 {
00093   ACE_TRACE ("ACE_Select_Reactor_T::handler_i");
00094   ACE_Event_Handler *handler = this->signal_handler_->handler (signum);
00095 
00096   if (handler == 0)
00097     return -1;
00098   else if (eh != 0)
00099     *eh = handler;
00100   return 0;
00101 }
00102 
00103 template <class ACE_SELECT_REACTOR_TOKEN> bool
00104 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::initialized (void)
00105 {
00106   ACE_TRACE ("ACE_Select_Reactor_T::initialized");
00107   ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, false));
00108   return this->initialized_;
00109 }
00110 
00111 
00112 template <class ACE_SELECT_REACTOR_TOKEN> int
00113 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::owner (ACE_thread_t tid,
00114                                                        ACE_thread_t *o_id)
00115 {
00116   ACE_TRACE ("ACE_Select_Reactor_T::owner");
00117   ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
00118 
00119   if (o_id)
00120     *o_id = this->owner_;
00121 
00122   this->owner_ = tid;
00123 
00124   return 0;
00125 }
00126 
00127 template <class ACE_SELECT_REACTOR_TOKEN> int
00128 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::owner (ACE_thread_t *t_id)
00129 {
00130   ACE_TRACE ("ACE_Select_Reactor_T::owner");
00131   ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
00132   *t_id = this->owner_;
00133   return 0;
00134 }
00135 
00136 template <class ACE_SELECT_REACTOR_TOKEN> int
00137 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::restart (void)
00138 {
00139   ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
00140   return this->restart_;
00141 }
00142 
00143 template <class ACE_SELECT_REACTOR_TOKEN> int
00144 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::restart (int r)
00145 {
00146   ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
00147   int const current_value = this->restart_;
00148   this->restart_ = r;
00149   return current_value;
00150 }
00151 
00152 template <class ACE_SELECT_REACTOR_TOKEN> void
00153 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::requeue_position (int rp)
00154 {
00155   ACE_TRACE ("ACE_Select_Reactor_T::requeue_position");
00156   ACE_MT (ACE_GUARD (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_));
00157 #if defined (ACE_WIN32)
00158   ACE_UNUSED_ARG (rp);
00159   // Must always requeue ourselves "next" on Win32.
00160   this->requeue_position_ = 0;
00161 #else
00162   this->requeue_position_ = rp;
00163 #endif /* ACE_WIN32 */
00164 }
00165 
00166 template <class ACE_SELECT_REACTOR_TOKEN> int
00167 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::requeue_position (void)
00168 {
00169   ACE_TRACE ("ACE_Select_Reactor_T::requeue_position");
00170   ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
00171   return this->requeue_position_;
00172 }
00173 
00174 template <class ACE_SELECT_REACTOR_TOKEN> void
00175 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::max_notify_iterations (int iterations)
00176 {
00177   ACE_TRACE ("ACE_Select_Reactor_T::max_notify_iterations");
00178   ACE_MT (ACE_GUARD (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_));
00179 
00180   this->notify_handler_->max_notify_iterations (iterations);
00181 }
00182 
00183 template <class ACE_SELECT_REACTOR_TOKEN> int
00184 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::max_notify_iterations (void)
00185 {
00186   ACE_TRACE ("ACE_Select_Reactor_T::max_notify_iterations");
00187   ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
00188   return this->notify_handler_->max_notify_iterations ();
00189 }
00190 
00191 // Enqueue ourselves into the list of waiting threads.
00192 template <class ACE_SELECT_REACTOR_TOKEN> void
00193 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::renew (void)
00194 {
00195   ACE_TRACE ("ACE_Select_Reactor_T::renew");
00196 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00197   if (this->supress_notify_renew () == 0)
00198     this->token_.renew (this->requeue_position_);
00199 #endif /* defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) */
00200 }
00201 
00202 template <class ACE_SELECT_REACTOR_TOKEN> int
00203 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::notify (ACE_Event_Handler *eh,
00204                                                         ACE_Reactor_Mask mask,
00205                                                         ACE_Time_Value *timeout)
00206 {
00207   ACE_TRACE ("ACE_Select_Reactor_T::notify");
00208 
00209   // Pass over both the Event_Handler *and* the mask to allow the
00210   // caller to dictate which Event_Handler method the receiver
00211   // invokes.  Note that this call can timeout.
00212 
00213   ssize_t const n = this->notify_handler_->notify (eh, mask, timeout);
00214   return n == -1 ? -1 : 0;
00215 }
00216 
00217 template <class ACE_SELECT_REACTOR_TOKEN> int
00218 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::resume_handler (ACE_HANDLE handle)
00219 {
00220   ACE_TRACE ("ACE_Select_Reactor_T::resume_handler");
00221   ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
00222   return this->resume_i (handle);
00223 }
00224 
00225 template <class ACE_SELECT_REACTOR_TOKEN> int
00226 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::suspend_handler (ACE_HANDLE handle)
00227 {
00228   ACE_TRACE ("ACE_Select_Reactor_T::suspend_handler");
00229   ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
00230   return this->suspend_i (handle);
00231 }
00232 
00233 template <class ACE_SELECT_REACTOR_TOKEN> int
00234 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::suspend_handlers (void)
00235 {
00236   ACE_TRACE ("ACE_Select_Reactor_T::suspend_handlers");
00237   ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
00238 
00239   ACE_Event_Handler *eh = 0;
00240 
00241   for (ACE_Select_Reactor_Handler_Repository_Iterator iter (&this->handler_rep_);
00242        iter.next (eh) != 0;
00243        iter.advance ())
00244     this->suspend_i (eh->get_handle ());
00245 
00246   return 0;
00247 }
00248 
00249 template <class ACE_SELECT_REACTOR_TOKEN> int
00250 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::resume_handlers (void)
00251 {
00252   ACE_TRACE ("ACE_Select_Reactor_T::resume_handlers");
00253   ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
00254 
00255   ACE_Event_Handler *eh = 0;
00256 
00257   for (ACE_Select_Reactor_Handler_Repository_Iterator iter (&this->handler_rep_);
00258        iter.next (eh) != 0;
00259        iter.advance ())
00260     this->resume_i (eh->get_handle ());
00261 
00262   return 0;
00263 }
00264 
00265 template <class ACE_SELECT_REACTOR_TOKEN> int
00266 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::register_handler
00267   (ACE_Event_Handler *handler,
00268    ACE_Reactor_Mask mask)
00269 {
00270   ACE_TRACE ("ACE_Select_Reactor_T::register_handler");
00271   ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
00272   return this->register_handler_i (handler->get_handle (), handler, mask);
00273 }
00274 
00275 template <class ACE_SELECT_REACTOR_TOKEN> int
00276 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::register_handler
00277   (ACE_HANDLE handle,
00278    ACE_Event_Handler *handler,
00279    ACE_Reactor_Mask mask)
00280 {
00281   ACE_TRACE ("ACE_Select_Reactor_T::register_handler");
00282   ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
00283   return this->register_handler_i (handle, handler, mask);
00284 }
00285 
00286 template <class ACE_SELECT_REACTOR_TOKEN> int
00287 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::register_handler
00288   (const ACE_Handle_Set &handles,
00289    ACE_Event_Handler *handler,
00290    ACE_Reactor_Mask mask)
00291 {
00292   ACE_TRACE ("ACE_Select_Reactor_T::register_handler");
00293   ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
00294   return this->register_handler_i (handles, handler, mask);
00295 }
00296 
00297 template <class ACE_SELECT_REACTOR_TOKEN> ACE_Event_Handler *
00298 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::find_handler
00299   (ACE_HANDLE handle)
00300 {
00301   ACE_TRACE ("ACE_Select_Reactor_T::find_handler");
00302   ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, 0));
00303   return this->find_handler_i (handle);
00304 }
00305 
00306 template <class ACE_SELECT_REACTOR_TOKEN> int
00307 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::handler
00308   (ACE_HANDLE handle,
00309    ACE_Reactor_Mask mask,
00310    ACE_Event_Handler **handler)
00311 {
00312   ACE_TRACE ("ACE_Select_Reactor_T::handler");
00313   ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
00314   return this->handler_i (handle, mask, handler);
00315 }
00316 
00317 template <class ACE_SELECT_REACTOR_TOKEN> int
00318 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::remove_handler
00319   (const ACE_Handle_Set &handles,
00320    ACE_Reactor_Mask mask)
00321 {
00322   ACE_TRACE ("ACE_Select_Reactor_T::remove_handler");
00323   ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
00324   return this->remove_handler_i (handles, mask);
00325 }
00326 
00327 template <class ACE_SELECT_REACTOR_TOKEN> int
00328 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::remove_handler
00329   (ACE_Event_Handler *handler,
00330    ACE_Reactor_Mask mask)
00331 {
00332   ACE_TRACE ("ACE_Select_Reactor_T::remove_handler");
00333   ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
00334   return this->remove_handler_i (handler->get_handle (), mask);
00335 }
00336 
00337 template <class ACE_SELECT_REACTOR_TOKEN> int
00338 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::remove_handler
00339   (ACE_HANDLE handle,
00340    ACE_Reactor_Mask mask)
00341 {
00342   ACE_TRACE ("ACE_Select_Reactor_T::remove_handler");
00343   ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
00344   return this->remove_handler_i (handle, mask);
00345 }
00346 
00347 // Performs operations on the "ready" bits.
00348 
00349 template <class ACE_SELECT_REACTOR_TOKEN> int
00350 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::ready_ops
00351   (ACE_HANDLE handle,
00352    ACE_Reactor_Mask mask,
00353    int ops)
00354 {
00355   ACE_TRACE ("ACE_Select_Reactor_T::ready_ops");
00356   ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
00357   return this->bit_ops (handle,
00358                         mask,
00359                         this->ready_set_,
00360                         ops);
00361 }
00362 
00363 template <class ACE_SELECT_REACTOR_TOKEN> int
00364 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::open
00365   (size_t size,
00366    int restart,
00367    ACE_Sig_Handler *sh,
00368    ACE_Timer_Queue *tq,
00369    int disable_notify_pipe,
00370    ACE_Reactor_Notify *notify)
00371 {
00372   ACE_TRACE ("ACE_Select_Reactor_T::open");
00373   ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
00374 
00375   // Can't initialize ourselves more than once.
00376   if (this->initialized_)
00377     return -1;
00378 
00379   this->owner_ = ACE_Thread::self ();
00380   this->restart_ = restart;
00381   this->signal_handler_ = sh;
00382   this->timer_queue_ = tq;
00383   this->notify_handler_ = notify;
00384 
00385   int result = 0;
00386 
00387   // Allows the signal handler to be overridden.
00388   if (this->signal_handler_ == 0)
00389     {
00390       ACE_NEW_RETURN (this->signal_handler_,
00391                       ACE_Sig_Handler,
00392                       -1);
00393 
00394       if (this->signal_handler_ == 0)
00395         result = -1;
00396       else
00397         this->delete_signal_handler_ = 1;
00398     }
00399 
00400   // Allows the timer queue to be overridden.
00401   if (result != -1 && this->timer_queue_ == 0)
00402     {
00403       ACE_NEW_RETURN (this->timer_queue_,
00404                       ACE_Timer_Heap,
00405                       -1);
00406 
00407       if (this->timer_queue_ == 0)
00408         result = -1;
00409       else
00410         this->delete_timer_queue_ = true;
00411     }
00412 
00413   // Allows the Notify_Handler to be overridden.
00414   if (result != -1 && this->notify_handler_ == 0)
00415     {
00416       ACE_NEW_RETURN (this->notify_handler_,
00417                       ACE_Select_Reactor_Notify,
00418                       -1);
00419 
00420       if (this->notify_handler_ == 0)
00421         result = -1;
00422       else
00423         this->delete_notify_handler_ = true;
00424     }
00425 
00426   if (result != -1 && this->handler_rep_.open (size) == -1)
00427     result = -1;
00428   else if (this->notify_handler_->open (this,
00429                                         0,
00430                                         disable_notify_pipe) == -1)
00431     {
00432       ACE_ERROR ((LM_ERROR,
00433                   ACE_TEXT ("%p\n"),
00434                   ACE_TEXT ("notification pipe open failed")));
00435       result = -1;
00436     }
00437 
00438   if (result != -1)
00439     // We're all set to go.
00440     this->initialized_ = true;
00441   else
00442     // This will close down all the allocated resources properly.
00443     this->close ();
00444 
00445   return result;
00446 }
00447 
00448 template <class ACE_SELECT_REACTOR_TOKEN> int
00449 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::set_sig_handler
00450   (ACE_Sig_Handler *signal_handler)
00451 {
00452   if (this->delete_signal_handler_)
00453     delete this->signal_handler_;
00454   this->signal_handler_ = signal_handler;
00455   this->delete_signal_handler_ = false;
00456   return 0;
00457 }
00458 
00459 template <class ACE_SELECT_REACTOR_TOKEN> ACE_Timer_Queue *
00460 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::timer_queue (void) const
00461 {
00462   return this->timer_queue_;
00463 }
00464 
00465 template <class ACE_SELECT_REACTOR_TOKEN> int
00466 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::timer_queue
00467   (ACE_Timer_Queue *tq)
00468 {
00469   if (this->delete_timer_queue_)
00470     delete this->timer_queue_;
00471   this->timer_queue_ = tq;
00472   this->delete_timer_queue_ = false;
00473   return 0;
00474 }
00475 
00476 template <class ACE_SELECT_REACTOR_TOKEN>
00477 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::ACE_Select_Reactor_T
00478   (ACE_Sig_Handler *sh,
00479    ACE_Timer_Queue *tq,
00480    int disable_notify_pipe,
00481    ACE_Reactor_Notify *notify,
00482    int mask_signals,
00483    int s_queue)
00484     : ACE_Select_Reactor_Impl (mask_signals)
00485     , token_ (s_queue)
00486     , lock_adapter_ (token_)
00487     , deactivated_ (0)
00488 {
00489   ACE_TRACE ("ACE_Select_Reactor_T::ACE_Select_Reactor_T");
00490 
00491   this->token_.reactor (*this);
00492   // First try to open the Reactor with the hard-coded default.
00493   if (this->open (ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::DEFAULT_SIZE,
00494                   0,
00495                   sh,
00496                   tq,
00497                   disable_notify_pipe,
00498                   notify) == -1)
00499     {
00500       // The hard-coded default Reactor size failed, so attempt to
00501       // determine the size at run-time by checking the process file
00502       // descriptor limit on platforms that support this feature.
00503 
00504       // There is no need to deallocate resources from previous open()
00505       // call since the open() method deallocates any resources prior
00506       // to exiting if an error was encountered.
00507 
00508       // Set the default reactor size to be the current limit on the
00509       // number of file descriptors available to the process.  This
00510       // size is not necessarily the maximum limit.
00511       if (this->open (ACE::max_handles (),
00512                      0,
00513                      sh,
00514                      tq,
00515                      disable_notify_pipe,
00516                      notify) == -1)
00517         ACE_ERROR ((LM_ERROR,
00518                     ACE_TEXT ("%p\n"),
00519                     ACE_TEXT ("ACE_Select_Reactor_T::open ")
00520                     ACE_TEXT ("failed inside ")
00521                     ACE_TEXT ("ACE_Select_Reactor_T::CTOR")));
00522     }
00523 }
00524 
00525 // Initialize ACE_Select_Reactor_T.
00526 
00527 template <class ACE_SELECT_REACTOR_TOKEN>
00528 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::ACE_Select_Reactor_T
00529   (size_t size,
00530    int rs,
00531    ACE_Sig_Handler *sh,
00532    ACE_Timer_Queue *tq,
00533    int disable_notify_pipe,
00534    ACE_Reactor_Notify *notify,
00535    int mask_signals,
00536    int s_queue)
00537     : ACE_Select_Reactor_Impl (mask_signals)
00538     , token_ (s_queue)
00539     , lock_adapter_ (token_)
00540     , deactivated_ (0)
00541 {
00542   ACE_TRACE ("ACE_Select_Reactor_T::ACE_Select_Reactor_T");
00543 
00544   this->token_.reactor (*this);
00545   if (this->open (size,
00546                   rs,
00547                   sh,
00548                   tq,
00549                   disable_notify_pipe,
00550                   notify) == -1)
00551     ACE_ERROR ((LM_ERROR,
00552                 ACE_TEXT ("%p\n"),
00553                 ACE_TEXT ("ACE_Select_Reactor_T::open ")
00554                 ACE_TEXT ("failed inside ACE_Select_Reactor_T::CTOR")));
00555 }
00556 
00557 // Close down the ACE_Select_Reactor_T instance, detaching any
00558 // remaining Event_Handers.  This had better be called from the main
00559 // event loop thread...
00560 
00561 template <class ACE_SELECT_REACTOR_TOKEN> int
00562 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::close (void)
00563 {
00564   ACE_TRACE ("ACE_Select_Reactor_T::close");
00565   ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
00566 
00567   if (this->delete_signal_handler_)
00568     {
00569       delete this->signal_handler_;
00570       this->signal_handler_ = 0;
00571       this->delete_signal_handler_ = false;
00572     }
00573 
00574   this->handler_rep_.close ();
00575 
00576   if (this->delete_timer_queue_)
00577     {
00578       delete this->timer_queue_;
00579       this->timer_queue_ = 0;
00580       this->delete_timer_queue_ = false;
00581     }
00582 
00583   if (this->notify_handler_ != 0)
00584     this->notify_handler_->close ();
00585 
00586   if (this->delete_notify_handler_)
00587     {
00588       delete this->notify_handler_;
00589       this->notify_handler_ = 0;
00590       this->delete_notify_handler_ = false;
00591     }
00592 
00593   this->initialized_ = false;
00594 
00595   return 0;
00596 }
00597 
00598 template <class ACE_SELECT_REACTOR_TOKEN> int
00599 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::current_info
00600   (ACE_HANDLE, size_t &)
00601 {
00602   return -1;
00603 }
00604 
00605 template <class ACE_SELECT_REACTOR_TOKEN>
00606 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::~ACE_Select_Reactor_T (void)
00607 {
00608   ACE_TRACE ("ACE_Select_Reactor_T::~ACE_Select_Reactor_T");
00609   this->close ();
00610 }
00611 
00612 template <class ACE_SELECT_REACTOR_TOKEN> int
00613 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::remove_handler_i
00614   (const ACE_Handle_Set &handles,
00615    ACE_Reactor_Mask mask)
00616 {
00617   ACE_TRACE ("ACE_Select_Reactor_T::remove_handler_i");
00618   ACE_HANDLE h;
00619 
00620   ACE_Handle_Set_Iterator handle_iter (handles);
00621 
00622   while ((h = handle_iter ()) != ACE_INVALID_HANDLE)
00623     if (this->remove_handler_i (h, mask) == -1)
00624       return -1;
00625 
00626   return 0;
00627 }
00628 
00629 template <class ACE_SELECT_REACTOR_TOKEN> int
00630 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::register_handler_i
00631   (const ACE_Handle_Set &handles,
00632    ACE_Event_Handler *handler,
00633    ACE_Reactor_Mask mask)
00634 {
00635   ACE_TRACE ("ACE_Select_Reactor_T::register_handler_i");
00636   ACE_HANDLE h;
00637 
00638   ACE_Handle_Set_Iterator handle_iter (handles);
00639   while ((h = handle_iter ()) != ACE_INVALID_HANDLE)
00640     if (this->register_handler_i (h, handler, mask) == -1)
00641       return -1;
00642 
00643   return 0;
00644 }
00645 
00646 template <class ACE_SELECT_REACTOR_TOKEN> int
00647 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::register_handler
00648   (const ACE_Sig_Set &sigset,
00649    ACE_Event_Handler *new_sh,
00650    ACE_Sig_Action *new_disp)
00651 {
00652   ACE_TRACE ("ACE_Select_Reactor_T::register_handler");
00653 
00654   int result = 0;
00655 
00656 #if (ACE_NSIG > 0)
00657   for (int s = 1; s < ACE_NSIG; ++s)
00658     if ((sigset.is_member (s) == 1)
00659         && this->signal_handler_->register_handler (s,
00660                                                     new_sh,
00661                                                     new_disp) == -1)
00662       result = -1;
00663 #else  /* ACE_NSIG <= 0 */
00664   ACE_UNUSED_ARG (sigset);
00665   ACE_UNUSED_ARG (new_sh);
00666   ACE_UNUSED_ARG (new_disp);
00667 #endif /* ACE_NSIG <= 0 */
00668   return result;
00669 }
00670 
00671 template <class ACE_SELECT_REACTOR_TOKEN> int
00672 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::remove_handler
00673   (const ACE_Sig_Set &sigset)
00674 {
00675   ACE_TRACE ("ACE_Select_Reactor_T::remove_handler");
00676   int result = 0;
00677 
00678 #if (ACE_NSIG > 0)
00679   for (int s = 1; s < ACE_NSIG; ++s)
00680     if ((sigset.is_member (s) == 1)
00681         && this->signal_handler_->remove_handler (s) == -1)
00682       result = -1;
00683 #else  /* ACE_NSIG <= 0 */
00684   ACE_UNUSED_ARG (sigset);
00685 #endif /* ACE_NSIG <= 0 */
00686 
00687   return result;
00688 }
00689 
00690 template <class ACE_SELECT_REACTOR_TOKEN> int
00691 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::cancel_timer (ACE_Event_Handler *handler,
00692                                                               int dont_call_handle_close)
00693 {
00694   ACE_TRACE ("ACE_Select_Reactor_T::cancel_timer");
00695   ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
00696 
00697   if (this->timer_queue_ != 0)
00698     return this->timer_queue_->cancel (handler, dont_call_handle_close);
00699   else
00700     return 0;
00701 }
00702 
00703 template <class ACE_SELECT_REACTOR_TOKEN> int
00704 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::cancel_timer (long timer_id,
00705                                                               const void **arg,
00706                                                               int dont_call_handle_close)
00707 {
00708   ACE_TRACE ("ACE_Select_Reactor_T::cancel_timer");
00709   ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
00710 
00711   if (this->timer_queue_ != 0)
00712     return this->timer_queue_->cancel (timer_id,
00713                                        arg,
00714                                        dont_call_handle_close);
00715   else
00716     return 0;
00717 }
00718 
00719 template <class ACE_SELECT_REACTOR_TOKEN> long
00720 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::schedule_timer
00721   (ACE_Event_Handler *handler,
00722    const void *arg,
00723    const ACE_Time_Value &delay_time,
00724    const ACE_Time_Value &interval)
00725 {
00726   ACE_TRACE ("ACE_Select_Reactor_T::schedule_timer");
00727   ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
00728 
00729   if (0 != this->timer_queue_)
00730     return this->timer_queue_->schedule
00731       (handler,
00732        arg,
00733        timer_queue_->gettimeofday () + delay_time,
00734        interval);
00735 
00736   errno = ESHUTDOWN;
00737   return -1;
00738 }
00739 
00740 template <class ACE_SELECT_REACTOR_TOKEN> int
00741 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::reset_timer_interval
00742   (long timer_id,
00743    const ACE_Time_Value &interval)
00744 {
00745   ACE_TRACE ("ACE_Select_Reactor_T::reset_timer_interval");
00746   ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
00747 
00748   if (0 != this->timer_queue_)
00749     return this->timer_queue_->reset_interval (timer_id, interval);
00750 
00751   errno = ESHUTDOWN;
00752   return -1;
00753 }
00754 
00755 // Main event loop driver that blocks for <max_wait_time> before
00756 // returning (will return earlier if I/O or signal events occur).
00757 
00758 template <class ACE_SELECT_REACTOR_TOKEN> int
00759 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::handle_events
00760   (ACE_Time_Value &max_wait_time)
00761 {
00762   ACE_TRACE ("ACE_Select_Reactor_T::handle_events");
00763 
00764   return this->handle_events (&max_wait_time);
00765 }
00766 
00767 template <class ACE_SELECT_REACTOR_TOKEN> int
00768 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::handle_error (void)
00769 {
00770   ACE_TRACE ("ACE_Select_Reactor_T::handle_error");
00771 #if defined (linux) && defined (ERESTARTNOHAND)
00772   int const error = errno; // Avoid multiple TSS accesses.
00773   if (error == EINTR || error == ERESTARTNOHAND)
00774     return this->restart_;
00775 #else
00776   if (errno == EINTR)
00777     return this->restart_;
00778 #endif /* linux && ERESTARTNOHAND */
00779 #if defined (__MVS__) || defined (ACE_WIN32) || defined (ACE_VXWORKS)
00780   // On MVS Open Edition and Win32, there can be a number of failure
00781   // codes on a bad socket, so check_handles on anything other than
00782   // EINTR.  VxWorks doesn't even bother to always set errno on error
00783   // in select (specifically, it doesn't return EBADF for bad FDs).
00784   else
00785     return this->check_handles ();
00786 #else
00787   else if (errno == EBADF)
00788     return this->check_handles ();
00789   else
00790     return -1;
00791 #endif  /* __MVS__ || ACE_WIN32 */
00792 }
00793 
00794 template <class ACE_SELECT_REACTOR_TOKEN> void
00795 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::notify_handle
00796   (ACE_HANDLE handle,
00797    ACE_Reactor_Mask mask,
00798    ACE_Handle_Set &ready_mask,
00799    ACE_Event_Handler *event_handler,
00800    ACE_EH_PTMF ptmf)
00801 {
00802   ACE_TRACE ("ACE_Select_Reactor_T::notify_handle");
00803   // Check for removed handlers.
00804   if (event_handler == 0)
00805     return;
00806 
00807   bool const reference_counting_required =
00808     event_handler->reference_counting_policy ().value () ==
00809     ACE_Event_Handler::Reference_Counting_Policy::ENABLED;
00810 
00811   // Call add_reference() if needed.
00812   if (reference_counting_required)
00813     {
00814       event_handler->add_reference ();
00815     }
00816 
00817   int status = (event_handler->*ptmf) (handle);
00818 
00819   if (status < 0)
00820     this->remove_handler_i (handle, mask);
00821   else if (status > 0)
00822     ready_mask.set_bit (handle);
00823 
00824   // Call remove_reference() if needed.
00825   if (reference_counting_required)
00826     event_handler->remove_reference ();
00827 }
00828 
00829 // Perform GET, CLR, SET, and ADD operations on the select()
00830 // Handle_Sets.
00831 //
00832 // GET = 1, Retrieve current value
00833 // SET = 2, Set value of bits to new mask (changes the entire mask)
00834 // ADD = 3, Bitwise "or" the value into the mask (only changes
00835 //          enabled bits)
00836 // CLR = 4  Bitwise "and" the negation of the value out of the mask
00837 //          (only changes enabled bits)
00838 //
00839 // Returns the original mask.
00840 
00841 template <class ACE_SELECT_REACTOR_TOKEN> int
00842 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::mask_ops
00843   (ACE_HANDLE handle,
00844    ACE_Reactor_Mask mask,
00845    int ops)
00846 {
00847   ACE_TRACE ("ACE_Select_Reactor_T::mask_ops");
00848   ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
00849 
00850   // If the handle is not suspended, then set the ops on the
00851   // <wait_set_>, otherwise set the <suspend_set_>.
00852 
00853   if (this->is_suspended_i (handle))
00854     return this->bit_ops (handle, mask,
00855                           this->suspend_set_,
00856                           ops);
00857   else
00858     return this->bit_ops (handle, mask,
00859                           this->wait_set_,
00860                           ops);
00861 }
00862 
00863 template <class ACE_SELECT_REACTOR_TOKEN> ACE_Event_Handler *
00864 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::find_handler_i
00865   (ACE_HANDLE handle)
00866 {
00867   ACE_TRACE ("ACE_Select_Reactor_T::find_handler_i");
00868 
00869   ACE_Event_Handler *event_handler =
00870     this->handler_rep_.find (handle);
00871 
00872   if (event_handler)
00873     event_handler->add_reference ();
00874 
00875   return event_handler;
00876 }
00877 
00878 // Must be called with locks held.
00879 
00880 template <class ACE_SELECT_REACTOR_TOKEN> int
00881 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::handler_i
00882   (ACE_HANDLE handle,
00883    ACE_Reactor_Mask mask,
00884    ACE_Event_Handler **eh)
00885 {
00886   ACE_TRACE ("ACE_Select_Reactor_T::handler_i");
00887   ACE_Event_Handler *event_handler =
00888     this->handler_rep_.find (handle);
00889 
00890   if (event_handler == 0)
00891     return -1;
00892   else
00893     {
00894       if ((ACE_BIT_ENABLED (mask, ACE_Event_Handler::READ_MASK)
00895            || ACE_BIT_ENABLED (mask, ACE_Event_Handler::ACCEPT_MASK))
00896           && this->wait_set_.rd_mask_.is_set (handle) == 0)
00897         return -1;
00898       if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::WRITE_MASK)
00899           && this->wait_set_.wr_mask_.is_set (handle) == 0)
00900         return -1;
00901       if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::EXCEPT_MASK)
00902           && this->wait_set_.ex_mask_.is_set (handle) == 0)
00903         return -1;
00904     }
00905 
00906   if (eh != 0)
00907     {
00908       *eh = event_handler;
00909       event_handler->add_reference ();
00910     }
00911 
00912   return 0;
00913 }
00914 
00915 // Must be called with locks held
00916 
00917 template <class ACE_SELECT_REACTOR_TOKEN> int
00918 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::resume_i (ACE_HANDLE handle)
00919 {
00920   ACE_TRACE ("ACE_Select_Reactor_T::resume_i");
00921   if (this->handler_rep_.find (handle) == 0)
00922     return -1;
00923 
00924   if (this->suspend_set_.rd_mask_.is_set (handle))
00925     {
00926       this->wait_set_.rd_mask_.set_bit (handle);
00927       this->suspend_set_.rd_mask_.clr_bit (handle);
00928     }
00929   if (this->suspend_set_.wr_mask_.is_set (handle))
00930     {
00931       this->wait_set_.wr_mask_.set_bit (handle);
00932       this->suspend_set_.wr_mask_.clr_bit (handle);
00933     }
00934   if (this->suspend_set_.ex_mask_.is_set (handle))
00935     {
00936       this->wait_set_.ex_mask_.set_bit (handle);
00937       this->suspend_set_.ex_mask_.clr_bit (handle);
00938     }
00939   return 0;
00940 }
00941 
00942 // Must be called with locks held
00943 
00944 template <class ACE_SELECT_REACTOR_TOKEN> int
00945 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::suspend_i (ACE_HANDLE handle)
00946 {
00947   ACE_TRACE ("ACE_Select_Reactor_T::suspend_i");
00948   if (this->handler_rep_.find (handle) == 0)
00949     return -1;
00950 
00951   if (this->wait_set_.rd_mask_.is_set (handle))
00952     {
00953       this->suspend_set_.rd_mask_.set_bit (handle);
00954       this->wait_set_.rd_mask_.clr_bit (handle);
00955     }
00956   if (this->wait_set_.wr_mask_.is_set (handle))
00957     {
00958       this->suspend_set_.wr_mask_.set_bit (handle);
00959       this->wait_set_.wr_mask_.clr_bit (handle);
00960     }
00961   if (this->wait_set_.ex_mask_.is_set (handle))
00962     {
00963       this->suspend_set_.ex_mask_.set_bit (handle);
00964       this->wait_set_.ex_mask_.clr_bit (handle);
00965     }
00966 
00967   // Kobi: we need to remove that handle from the
00968   // dispatch set as well. We use that function with all the relevant
00969   // masks - rd/wr/ex - all the mask. it is completely suspended
00970   this->clear_dispatch_mask (handle, ACE_Event_Handler::RWE_MASK);
00971   return 0;
00972 }
00973 
00974 // Must be called with locks held
00975 
00976 template <class ACE_SELECT_REACTOR_TOKEN> int
00977 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::is_suspended_i (ACE_HANDLE handle)
00978 {
00979   ACE_TRACE ("ACE_Select_Reactor_T::is_suspended_i");
00980   if (this->handler_rep_.find (handle) == 0)
00981     return 0;
00982 
00983   return this->suspend_set_.rd_mask_.is_set (handle) ||
00984          this->suspend_set_.wr_mask_.is_set (handle) ||
00985          this->suspend_set_.ex_mask_.is_set (handle)    ;
00986 
00987 }
00988 
00989 // Must be called with locks held
00990 
00991 template <class ACE_SELECT_REACTOR_TOKEN> int
00992 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::register_handler_i
00993   (ACE_HANDLE handle,
00994    ACE_Event_Handler *event_handler,
00995    ACE_Reactor_Mask mask)
00996 {
00997   ACE_TRACE ("ACE_Select_Reactor_T::register_handler_i");
00998 
00999   // Insert the <handle, event_handle> tuple into the Handler
01000   // Repository.
01001   return this->handler_rep_.bind (handle, event_handler, mask);
01002 }
01003 
01004 template <class ACE_SELECT_REACTOR_TOKEN> int
01005 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::remove_handler_i
01006   (ACE_HANDLE handle,
01007    ACE_Reactor_Mask mask)
01008 {
01009   ACE_TRACE ("ACE_Select_Reactor_T::remove_handler_i");
01010 
01011   // Unbind this handle.
01012   return this->handler_rep_.unbind (handle, mask);
01013 }
01014 
01015 template <class ACE_SELECT_REACTOR_TOKEN> int
01016 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::work_pending
01017   (const ACE_Time_Value &max_wait_time)
01018 {
01019   ACE_TRACE ("ACE_Select_Reactor_T::work_pending");
01020 
01021   ACE_Time_Value mwt (max_wait_time);
01022   ACE_MT (ACE_Countdown_Time countdown (&mwt));
01023 
01024   ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN,
01025                             ace_mon,
01026                             this->token_,
01027                             -1));
01028 
01029   if (this->deactivated_)
01030     return 0;
01031 
01032   // Update the countdown to reflect time waiting for the mutex.
01033   ACE_MT (countdown.update ());
01034 
01035   ACE_Time_Value timer_buf (0);
01036   ACE_Time_Value *this_timeout =
01037     this->timer_queue_->calculate_timeout (&mwt, &timer_buf);
01038 
01039   // Check if we have timers to fire.
01040   bool const timers_pending =
01041     (this_timeout != 0 && *this_timeout != mwt ? true : false);
01042 
01043 #ifdef ACE_WIN32
01044   // This arg is ignored on Windows and causes pointer truncation
01045   // warnings on 64-bit compiles.
01046   int const width = 0;
01047 #else
01048   int const width = this->handler_rep_.max_handlep1 ();
01049 #endif  /* ACE_WIN32 */
01050 
01051   ACE_Select_Reactor_Handle_Set fd_set;
01052   fd_set.rd_mask_ = this->wait_set_.rd_mask_;
01053   fd_set.wr_mask_ = this->wait_set_.wr_mask_;
01054   fd_set.ex_mask_ = this->wait_set_.ex_mask_;
01055 
01056   int const nfds = ACE_OS::select (width,
01057                                    fd_set.rd_mask_,
01058                                    fd_set.wr_mask_,
01059                                    fd_set.ex_mask_,
01060                                    this_timeout);
01061 
01062   // If timers are pending, override any timeout from the select()
01063   // call.
01064   return (nfds == 0 && timers_pending ? 1 : nfds);
01065 }
01066 
01067 // Must be called with lock held.
01068 
01069 template <class ACE_SELECT_REACTOR_TOKEN> int
01070 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::wait_for_multiple_events
01071   (ACE_Select_Reactor_Handle_Set &dispatch_set,
01072    ACE_Time_Value *max_wait_time)
01073 {
01074   ACE_TRACE ("ACE_Select_Reactor_T::wait_for_multiple_events");
01075   ACE_Time_Value timer_buf (0);
01076   ACE_Time_Value *this_timeout;
01077 
01078   int number_of_active_handles = this->any_ready (dispatch_set);
01079 
01080   // If there are any bits enabled in the <ready_set_> then we'll
01081   // handle those first, otherwise we'll block in <select>.
01082 
01083   if (number_of_active_handles == 0)
01084     {
01085       do
01086         {
01087           if (this->timer_queue_ == 0)
01088             return 0;
01089 
01090           this_timeout =
01091             this->timer_queue_->calculate_timeout (max_wait_time,
01092                                                    &timer_buf);
01093 #ifdef ACE_WIN32
01094           // This arg is ignored on Windows and causes pointer
01095           // truncation warnings on 64-bit compiles.
01096           int const width = 0;
01097 #else
01098           int const width = this->handler_rep_.max_handlep1 ();
01099 #endif  /* ACE_WIN32 */
01100 
01101           dispatch_set.rd_mask_ = this->wait_set_.rd_mask_;
01102           dispatch_set.wr_mask_ = this->wait_set_.wr_mask_;
01103           dispatch_set.ex_mask_ = this->wait_set_.ex_mask_;
01104           number_of_active_handles = ACE_OS::select (width,
01105                                                      dispatch_set.rd_mask_,
01106                                                      dispatch_set.wr_mask_,
01107                                                      dispatch_set.ex_mask_,
01108                                                      this_timeout);
01109         }
01110       while (number_of_active_handles == -1 && this->handle_error () > 0);
01111 
01112       if (number_of_active_handles > 0)
01113         {
01114 #if !defined (ACE_WIN32)
01115           // Resynchronize the fd_sets so their "max" is set properly.
01116           dispatch_set.rd_mask_.sync (this->handler_rep_.max_handlep1 ());
01117           dispatch_set.wr_mask_.sync (this->handler_rep_.max_handlep1 ());
01118           dispatch_set.ex_mask_.sync (this->handler_rep_.max_handlep1 ());
01119 #endif /* ACE_WIN32 */
01120         }
01121       else if (number_of_active_handles == -1)
01122         {
01123           // Normally, select() will reset the bits in dispatch_set
01124           // so that only those filed descriptors that are ready will
01125           // have bits set.  However, when an error occurs, the bit
01126           // set remains as it was when the select call was first made.
01127           // Thus, we now have a dispatch_set that has every file
01128           // descriptor that was originally waited for, which is not
01129           // correct.  We must clear all the bit sets because we
01130           // have no idea if any of the file descriptors is ready.
01131           //
01132           // NOTE: We dont have a test case to reproduce this
01133           // problem. But pleae dont ignore this and remove it off.
01134           dispatch_set.rd_mask_.reset ();
01135           dispatch_set.wr_mask_.reset ();
01136           dispatch_set.ex_mask_.reset ();
01137         }
01138     }
01139 
01140   // Return the number of events to dispatch.
01141   return number_of_active_handles;
01142 }
01143 
01144 template <class ACE_SELECT_REACTOR_TOKEN> int
01145 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::dispatch_timer_handlers
01146   (int &number_of_handlers_dispatched)
01147 {
01148   number_of_handlers_dispatched += this->timer_queue_->expire ();
01149 
01150   return 0;
01151 }
01152 
01153 template <class ACE_SELECT_REACTOR_TOKEN> int
01154 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::dispatch_notification_handlers
01155   (ACE_Select_Reactor_Handle_Set &dispatch_set,
01156    int &number_of_active_handles,
01157    int &number_of_handlers_dispatched)
01158 {
01159   // Check to see if the ACE_HANDLE associated with the
01160   // Select_Reactor's notify hook is enabled.  If so, it means that
01161   // one or more other threads are trying to update the
01162   // ACE_Select_Reactor_T's internal tables or the notify pipe is
01163   // enabled.  We'll handle all these threads and notifications, and
01164   // then break out to continue the event loop.
01165   int const n =
01166     this->notify_handler_->dispatch_notifications (number_of_active_handles,
01167                                                    dispatch_set.rd_mask_);
01168 
01169   if (n == -1)
01170     return -1;
01171   else
01172     {
01173       number_of_handlers_dispatched += n;
01174       number_of_active_handles -= n;
01175     }
01176 
01177   // Same as dispatch_timer_handlers
01178   // No need to do anything with the state changed. That is because
01179   // unbind already handles the case where someone unregister some
01180   // kind of handle and unbind it. (::unbind calls the function
01181   // state_changed ()  to reflect ant change with that)
01182   //   return this->state_changed_ ? -1 : 0;
01183   return 0;
01184 }
01185 
01186 template <class ACE_SELECT_REACTOR_TOKEN> int
01187 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::dispatch_io_set
01188   (int number_of_active_handles,
01189    int &number_of_handlers_dispatched,
01190    int mask,
01191    ACE_Handle_Set &dispatch_mask,
01192    ACE_Handle_Set &ready_mask,
01193    ACE_EH_PTMF callback)
01194 {
01195   ACE_TRACE ("ACE_Select_Reactor_T::dispatch_io_set");
01196   ACE_HANDLE handle;
01197 
01198   ACE_Handle_Set_Iterator handle_iter (dispatch_mask);
01199 
01200   while ((handle = handle_iter ()) != ACE_INVALID_HANDLE &&
01201          number_of_handlers_dispatched < number_of_active_handles)
01202     {
01203       ++number_of_handlers_dispatched;
01204 
01205       this->notify_handle (handle,
01206                            mask,
01207                            ready_mask,
01208                            this->handler_rep_.find (handle),
01209                            callback);
01210 
01211       // clear the bit from that dispatch mask,
01212       // so when we need to restart the iteration (rebuilding the iterator...)
01213       // we will not dispatch the already dispatched handlers
01214       this->clear_dispatch_mask (handle, mask);
01215 
01216       if (this->state_changed_)
01217         {
01218 
01219           handle_iter.reset_state ();
01220           this->state_changed_ = false;
01221         }
01222     }
01223 
01224   return 0;
01225 }
01226 
01227 template <class ACE_SELECT_REACTOR_TOKEN> int
01228 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::dispatch_io_handlers
01229   (ACE_Select_Reactor_Handle_Set &dispatch_set,
01230    int &number_of_active_handles,
01231    int &number_of_handlers_dispatched)
01232 {
01233   ACE_TRACE ("ACE_Select_Reactor_T::dispatch_io_handlers");
01234 
01235   // Handle output events (this code needs to come first to handle the
01236   // obscure case of piggy-backed data coming along with the final
01237   // handshake message of a nonblocking connection).
01238 
01239   if (this->dispatch_io_set (number_of_active_handles,
01240                              number_of_handlers_dispatched,
01241                              ACE_Event_Handler::WRITE_MASK,
01242                              dispatch_set.wr_mask_,
01243                              this->ready_set_.wr_mask_,
01244                              &ACE_Event_Handler::handle_output) == -1)
01245     {
01246       number_of_active_handles -= number_of_handlers_dispatched;
01247       return -1;
01248     }
01249 
01250   // ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("ACE_Select_Reactor_T::dispatch - EXCEPT\n")));
01251   if (this->dispatch_io_set (number_of_active_handles,
01252                              number_of_handlers_dispatched,
01253                              ACE_Event_Handler::EXCEPT_MASK,
01254                              dispatch_set.ex_mask_,
01255                              this->ready_set_.ex_mask_,
01256                              &ACE_Event_Handler::handle_exception) == -1)
01257     {
01258       number_of_active_handles -= number_of_handlers_dispatched;
01259       return -1;
01260     }
01261 
01262   // ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("ACE_Select_Reactor_T::dispatch - READ\n")));
01263   if (this->dispatch_io_set (number_of_active_handles,
01264                              number_of_handlers_dispatched,
01265                              ACE_Event_Handler::READ_MASK,
01266                              dispatch_set.rd_mask_,
01267                              this->ready_set_.rd_mask_,
01268                              &ACE_Event_Handler::handle_input) == -1)
01269     {
01270       number_of_active_handles -= number_of_handlers_dispatched;
01271       return -1;
01272     }
01273 
01274   number_of_active_handles -= number_of_handlers_dispatched;
01275   return 0;
01276 }
01277 
01278 template <class ACE_SELECT_REACTOR_TOKEN> int
01279 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::dispatch
01280   (int active_handle_count,
01281    ACE_Select_Reactor_Handle_Set &dispatch_set)
01282 {
01283   ACE_TRACE ("ACE_Select_Reactor_T::dispatch");
01284 
01285   int io_handlers_dispatched = 0;
01286   int other_handlers_dispatched = 0;
01287   int signal_occurred = 0;
01288   // The following do/while loop keeps dispatching as long as there
01289   // are still active handles.  Note that the only way we should ever
01290   // iterate more than once through this loop is if signals occur
01291   // while we're dispatching other handlers.
01292 
01293   do
01294     {
01295       // We expect that the loop will decrease the number of active
01296       // handles in each iteration.  If it does not, then something is
01297       // inconsistent in the state of the Reactor and we should avoid
01298       // the loop.  Please read the comments on bug 2540 for more
01299       // details.
01300       int initial_handle_count = active_handle_count;
01301 
01302       // Note that we keep track of changes to our state.  If any of
01303       // the dispatch_*() methods below return -1 it means that the
01304       // <wait_set_> state has changed as the result of an
01305       // <ACE_Event_Handler> being dispatched.  This means that we
01306       // need to bail out and rerun the select() loop since our
01307       // existing notion of handles in <dispatch_set> may no longer be
01308       // correct.
01309       //
01310       // In the beginning, our state starts out unchanged.  After
01311       // every iteration (i.e., due to signals), our state starts out
01312       // unchanged again.
01313 
01314       this->state_changed_ = false;
01315 
01316       // Perform the Template Method for dispatching all the handlers.
01317 
01318       // First check for interrupts.
01319       if (active_handle_count == -1)
01320         {
01321           // Bail out -- we got here since <select> was interrupted.
01322           if (ACE_Sig_Handler::sig_pending () != 0)
01323             {
01324               ACE_Sig_Handler::sig_pending (0);
01325 
01326               // If any HANDLES in the <ready_set_> are activated as a
01327               // result of signals they should be dispatched since
01328               // they may be time critical...
01329               active_handle_count = this->any_ready (dispatch_set);
01330 
01331               // Record the fact that the Reactor has dispatched a
01332               // handle_signal() method.  We need this to return the
01333               // appropriate count below.
01334               signal_occurred = 1;
01335             }
01336           else
01337             return -1;
01338         }
01339 
01340       // Handle timers early since they may have higher latency
01341       // constraints than I/O handlers.  Ideally, the order of
01342       // dispatching should be a strategy...
01343       else if (this->dispatch_timer_handlers (other_handlers_dispatched) == -1)
01344         // State has changed or timer queue has failed, exit loop.
01345         break;
01346 
01347       // Check to see if there are no more I/O handles left to
01348       // dispatch AFTER we've handled the timers...
01349       else if (active_handle_count == 0)
01350         return io_handlers_dispatched
01351           + other_handlers_dispatched
01352           + signal_occurred;
01353 
01354       // Next dispatch the notification handlers (if there are any to
01355       // dispatch).  These are required to handle multi-threads that
01356       // are trying to update the <Reactor>.
01357 
01358       else if (this->dispatch_notification_handlers
01359                (dispatch_set,
01360                 active_handle_count,
01361                 other_handlers_dispatched) == -1)
01362         // State has changed or a serious failure has occured, so exit
01363         // loop.
01364         break;
01365 
01366       // Finally, dispatch the I/O handlers.
01367       else if (this->dispatch_io_handlers
01368                (dispatch_set,
01369                 active_handle_count,
01370                 io_handlers_dispatched) == -1)
01371         // State has changed, so exit loop.
01372         break;
01373 
01374       // if state changed, we need to re-eval active_handle_count,
01375       // so we will not end with an endless loop
01376       if (initial_handle_count == active_handle_count
01377           || this->state_changed_)
01378       {
01379         active_handle_count = this->any_ready (dispatch_set);
01380       }
01381     }
01382   while (active_handle_count > 0);
01383 
01384   return io_handlers_dispatched + other_handlers_dispatched + signal_occurred;
01385 }
01386 
01387 template <class ACE_SELECT_REACTOR_TOKEN> int
01388 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::release_token (void)
01389 {
01390 #if defined (ACE_WIN32)
01391   this->token_.release ();
01392   return (int) EXCEPTION_CONTINUE_SEARCH;
01393 #else
01394   return 0;
01395 #endif /* ACE_WIN32 */
01396 }
01397 
01398 template <class ACE_SELECT_REACTOR_TOKEN> int
01399 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::handle_events
01400   (ACE_Time_Value *max_wait_time)
01401 {
01402   ACE_TRACE ("ACE_Select_Reactor_T::handle_events");
01403 
01404 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
01405 
01406   // Stash the current time -- the destructor of this object will
01407   // automatically compute how much time elapsed since this method was
01408   // called.
01409   ACE_Countdown_Time countdown (max_wait_time);
01410 
01411   ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1);
01412 
01413   if (ACE_OS::thr_equal (ACE_Thread::self (),
01414                          this->owner_) == 0 || this->deactivated_)
01415     return -1;
01416 
01417   // Update the countdown to reflect time waiting for the mutex.
01418   countdown.update ();
01419 #else
01420   if (this->deactivated_)
01421     return -1;
01422 #endif /* ACE_MT_SAFE */
01423 
01424   return this->handle_events_i (max_wait_time);
01425 }
01426 
01427 template <class ACE_SELECT_REACTOR_TOKEN> int
01428 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::handle_events_i
01429   (ACE_Time_Value *max_wait_time)
01430 {
01431   int result = -1;
01432 
01433   ACE_SEH_TRY
01434     {
01435       // We use the data member dispatch_set_ as the current dispatch
01436       // set.
01437 
01438       // We need to start from a clean dispatch_set
01439       this->dispatch_set_.rd_mask_.reset ();
01440       this->dispatch_set_.wr_mask_.reset ();
01441       this->dispatch_set_.ex_mask_.reset ();
01442 
01443       int number_of_active_handles =
01444         this->wait_for_multiple_events (this->dispatch_set_,
01445                                         max_wait_time);
01446 
01447       result =
01448         this->dispatch (number_of_active_handles,
01449                         this->dispatch_set_);
01450     }
01451   ACE_SEH_EXCEPT (this->release_token ())
01452     {
01453       // As it stands now, we catch and then rethrow all Win32
01454       // structured exceptions so that we can make sure to release the
01455       // <token_> lock correctly.
01456     }
01457 
01458   return result;
01459 }
01460 
01461 template <class ACE_SELECT_REACTOR_TOKEN> int
01462 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::check_handles (void)
01463 {
01464   ACE_TRACE ("ACE_Select_Reactor_T::check_handles");
01465 
01466 #if defined (ACE_WIN32) || defined (__MVS__) || defined (ACE_VXWORKS)
01467   ACE_Time_Value time_poll = ACE_Time_Value::zero;
01468   ACE_Handle_Set rd_mask;
01469 #endif /* ACE_WIN32 || MVS || ACE_VXWORKS */
01470 
01471   int result = 0;
01472 
01473   /*
01474    * It's easier to run through the handler repository iterator, but that
01475    * misses handles that are registered on a handler that doesn't implement
01476    * get_handle(). So, build a handle set that's the union of the three
01477    * wait_sets (rd, wrt, ex) and run through that. Bad handles get cleared
01478    * out of all sets.
01479    */
01480   ACE_HANDLE h;
01481   ACE_Handle_Set check_set (this->wait_set_.rd_mask_);
01482   ACE_Handle_Set_Iterator wr_iter (this->wait_set_.wr_mask_);
01483   while ((h = wr_iter ()) != ACE_INVALID_HANDLE)
01484     check_set.set_bit (h);
01485   ACE_Handle_Set_Iterator ex_iter (this->wait_set_.ex_mask_);
01486   while ((h = ex_iter ()) != ACE_INVALID_HANDLE)
01487     check_set.set_bit (h);
01488 
01489   ACE_Handle_Set_Iterator check_iter (check_set);
01490   while ((h = check_iter ()) != ACE_INVALID_HANDLE)
01491     {
01492 
01493 #if defined (ACE_WIN32) || defined (__MVS__) || defined (ACE_VXWORKS)
01494       // Win32 needs to do the check this way because fstat won't work on
01495       // a socket handle.  MVS Open Edition needs to do it this way because,
01496       // even though the docs say to check a handle with either select or
01497       // fstat, the fstat method always says the handle is ok.
01498       // pSOS needs to do it this way because file handles and socket handles
01499       // are maintained by separate pieces of the system.  VxWorks needs the select
01500       // variant since fstat always returns an error on socket FDs.
01501       rd_mask.set_bit (h);
01502 
01503       int select_width;
01504 #  if defined (ACE_WIN32)
01505       // This arg is ignored on Windows and causes pointer truncation
01506       // warnings on 64-bit compiles.
01507       select_width = 0;
01508 #  else
01509       select_width = int (h) + 1;
01510 #  endif /* ACE_WIN32 */
01511 
01512       if (ACE_OS::select (select_width,
01513                           rd_mask, 0, 0,
01514                           &time_poll) < 0)
01515         {
01516           result = 1;
01517           this->remove_handler_i (h, ACE_Event_Handler::ALL_EVENTS_MASK);
01518         }
01519       rd_mask.clr_bit (h);
01520 #else /* !ACE_WIN32 && !MVS && !VXWORKS */
01521       struct stat temp;
01522 
01523       if (ACE_OS::fstat (h, &temp) == -1)
01524         {
01525           result = 1;
01526           this->remove_handler_i (h, ACE_Event_Handler::ALL_EVENTS_MASK);
01527         }
01528 #endif /* ACE_WIN32 || MVS */
01529     }
01530 
01531   return result;
01532 }
01533 
01534 template <class ACE_SELECT_REACTOR_TOKEN> void
01535 ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::dump (void) const
01536 {
01537 #if defined (ACE_HAS_DUMP)
01538   ACE_TRACE ("ACE_Select_Reactor_T::dump");
01539 
01540   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
01541 
01542   this->timer_queue_->dump ();
01543   this->handler_rep_.dump ();
01544   this->signal_handler_->dump ();
01545   ACE_DEBUG ((LM_DEBUG,
01546               ACE_TEXT ("delete_signal_handler_ = %d\n"),
01547               this->delete_signal_handler_));
01548 
01549   ACE_HANDLE h;
01550 
01551   for (ACE_Handle_Set_Iterator handle_iter_wr (this->wait_set_.wr_mask_);
01552        (h = handle_iter_wr ()) != ACE_INVALID_HANDLE;)
01553     ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("write_handle = %d\n"), h));
01554 
01555   for (ACE_Handle_Set_Iterator handle_iter_rd (this->wait_set_.rd_mask_);
01556        (h = handle_iter_rd ()) != ACE_INVALID_HANDLE;)
01557     ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("read_handle = %d\n"), h));
01558 
01559   for (ACE_Handle_Set_Iterator handle_iter_ex (this->wait_set_.ex_mask_);
01560        (h = handle_iter_ex ()) != ACE_INVALID_HANDLE;)
01561     ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("except_handle = %d\n"), h));
01562 
01563   for (ACE_Handle_Set_Iterator handle_iter_wr_ready (this->ready_set_.wr_mask_);
01564        (h = handle_iter_wr_ready ()) != ACE_INVALID_HANDLE;)
01565     ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("write_handle_ready = %d\n"), h));
01566 
01567   for (ACE_Handle_Set_Iterator handle_iter_rd_ready (this->ready_set_.rd_mask_);
01568        (h = handle_iter_rd_ready ()) != ACE_INVALID_HANDLE;)
01569     ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("read_handle_ready = %d\n"), h));
01570 
01571   for (ACE_Handle_Set_Iterator handle_iter_ex_ready (this->ready_set_.ex_mask_);
01572        (h = handle_iter_ex_ready ()) != ACE_INVALID_HANDLE;)
01573     ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("except_handle_ready = %d\n"), h));
01574 
01575   for (ACE_Handle_Set_Iterator handle_iter_su_ready (this->suspend_set_.wr_mask_);
01576        (h = handle_iter_su_ready ()) != ACE_INVALID_HANDLE;)
01577     ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("write_handle_suspend = %d\n"), h));
01578 
01579   for (ACE_Handle_Set_Iterator handle_iter_su_ready (this->suspend_set_.rd_mask_);
01580        (h = handle_iter_su_ready ()) != ACE_INVALID_HANDLE;)
01581     ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("read_handle_suspend = %d\n"), h));
01582 
01583   for (ACE_Handle_Set_Iterator handle_iter_su_ready (this->suspend_set_.ex_mask_);
01584        (h = handle_iter_su_ready ()) != ACE_INVALID_HANDLE;)
01585     ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("except_handle_suspend = %d\n"), h));
01586 
01587   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("restart_ = %d\n"), this->restart_));
01588   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("requeue_position_ = %d\n"), this->requeue_position_));
01589   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("initialized_ = %d\n"), this->initialized_));
01590   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("owner_ = %d\n"), this->owner_));
01591 
01592 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
01593   this->notify_handler_->dump ();
01594   this->token_.dump ();
01595 #endif /* ACE_MT_SAFE */
01596 
01597   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
01598 #endif /* ACE_HAS_DUMP */
01599 }
01600 
01601 ACE_END_VERSIONED_NAMESPACE_DECL
01602 
01603 #endif /* ACE_SELECT_REACTOR_T_CPP */

Generated on Sun Jan 27 12:05:37 2008 for ACE by doxygen 1.3.6