Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

Select_Reactor_T.cpp

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

Generated on Mon Jun 16 11:21:09 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002