Select_Reactor_T.cpp

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

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