Select_Reactor_T.cpp

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

Generated on Tue Feb 2 17:18:42 2010 for ACE by  doxygen 1.4.7