Reactor.cpp

Go to the documentation of this file.
00001 // $Id: Reactor.cpp 80826 2008-03-04 14:51:23Z wotte $
00002 
00003 #include "ace/Reactor.h"
00004 
00005 #if !defined (ACE_LACKS_ACE_SVCCONF)
00006 #  include "ace/Service_Config.h"
00007 #endif /* !ACE_LACKS_ACE_SVCCONF */
00008 
00009 /*
00010  * Hook to specialize the includes directly with the concrete
00011  * Reactor type, e.g., select, thread pool reactor
00012  * known at compile time. This hook results in all the
00013  * #defines being commented
00014  * out and the concrete header file directly included.
00015  */
00016 //@@ REACTOR_SPL_COMMENT_INCLUDE_START_HOOK
00017 // Only include the headers needed to compile.
00018 #if !defined (ACE_WIN32) \
00019       || !defined (ACE_HAS_WINSOCK2) || (ACE_HAS_WINSOCK2 == 0) \
00020       || defined (ACE_USE_SELECT_REACTOR_FOR_REACTOR_IMPL) \
00021       || defined (ACE_USE_TP_REACTOR_FOR_REACTOR_IMPL) \
00022       || defined (ACE_USE_DEV_POLL_REACTOR_FOR_REACTOR_IMPL)
00023 #  if defined (ACE_USE_TP_REACTOR_FOR_REACTOR_IMPL)
00024 #    include "ace/TP_Reactor.h"
00025 #  else
00026 #    if defined (ACE_USE_DEV_POLL_REACTOR_FOR_REACTOR_IMPL)
00027 #      include "ace/Dev_Poll_Reactor.h"
00028 #    else
00029 #      include "ace/Select_Reactor.h"
00030 #    endif /* ACE_USE_DEV_POLL_REACTOR_FOR_REACTOR_IMPL */
00031 #  endif /* ACE_USE_TP_REACTOR_FOR_REACTOR_IMPL */
00032 #else /* We are on Win32 and we have winsock and ACE_USE_SELECT_REACTOR_FOR_REACTOR_IMPL is not defined */
00033 #  if defined (ACE_USE_MSG_WFMO_REACTOR_FOR_REACTOR_IMPL)
00034 #    include "ace/Msg_WFMO_Reactor.h"
00035 #  else
00036 #    include "ace/WFMO_Reactor.h"
00037 #  endif /* ACE_USE_MSG_WFMO_REACTOR_FOR_REACTOR_IMPL */
00038 #endif /* !defined (ACE_WIN32) || !defined (ACE_HAS_WINSOCK2) || (ACE_HAS_WINSOCK2 == 0) || defined (ACE_USE_SELECT_REACTOR_FOR_REACTOR_IMPL) */
00039 
00040 /*
00041  * End comment hook.
00042  */
00043 //@@ REACTOR_SPL_COMMENT_INCLUDE_END_HOOK
00044 
00045 #include "ace/Static_Object_Lock.h"
00046 #include "ace/Framework_Component.h"
00047 #include "ace/Guard_T.h"
00048 #include "ace/Recursive_Thread_Mutex.h"
00049 
00050 #if !defined (__ACE_INLINE__)
00051   #include "ace/Reactor.inl"
00052 #endif /* __ACE_INLINE__ */
00053 
00054 ACE_RCSID (ace,
00055            Reactor,
00056            "$Id: Reactor.cpp 80826 2008-03-04 14:51:23Z wotte $")
00057 
00058 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00059 
00060 ACE_ALLOC_HOOK_DEFINE(ACE_Reactor)
00061 
00062 ACE_Reactor::ACE_Reactor (ACE_Reactor_Impl *impl,
00063                           bool delete_implementation)
00064   : implementation_ (0),
00065     delete_implementation_ (delete_implementation)
00066 {
00067   this->implementation (impl);
00068 
00069   if (this->implementation () == 0)
00070     {
00071 /*
00072  * Hook to specialize the reactor implementation with the concrete
00073  * Reactor implementation known at compile time. This hook will
00074  * cause the conditionally defined code to be commented out and
00075  * the concrete Reactor directly created.
00076  */
00077 //@@ REACTOR_SPL_CONSTRUCTOR_COMMENT_HOOK_START
00078 #if !defined (ACE_WIN32) \
00079       || !defined (ACE_HAS_WINSOCK2) || (ACE_HAS_WINSOCK2 == 0) \
00080       || defined (ACE_USE_SELECT_REACTOR_FOR_REACTOR_IMPL) \
00081       || defined (ACE_USE_TP_REACTOR_FOR_REACTOR_IMPL) \
00082       || defined (ACE_USE_DEV_POLL_REACTOR_FOR_REACTOR_IMPL)
00083 #  if defined (ACE_USE_TP_REACTOR_FOR_REACTOR_IMPL)
00084       ACE_NEW (impl,
00085                ACE_TP_Reactor);
00086 #  else
00087 #    if defined (ACE_USE_DEV_POLL_REACTOR_FOR_REACTOR_IMPL)
00088       ACE_NEW (impl,
00089                ACE_Dev_Poll_Reactor);
00090 #    else
00091       ACE_NEW (impl,
00092                ACE_Select_Reactor);
00093 #    endif /* ACE_USE_DEV_POLL_REACTOR_FOR_REACTOR_IMPL */
00094 #  endif /* ACE_USE_TP_REACTOR_FOR_REACTOR_IMPL */
00095 #else /* We are on Win32 and we have winsock and ACE_USE_SELECT_REACTOR_FOR_REACTOR_IMPL is not defined */
00096   #if defined (ACE_USE_MSG_WFMO_REACTOR_FOR_REACTOR_IMPL)
00097       ACE_NEW (impl,
00098                ACE_Msg_WFMO_Reactor);
00099   #else
00100       ACE_NEW (impl,
00101                ACE_WFMO_Reactor);
00102   #endif /* ACE_USE_MSG_WFMO_REACTOR_FOR_REACTOR_IMPL */
00103 #endif /* !defined (ACE_WIN32) || !defined (ACE_HAS_WINSOCK2) || (ACE_HAS_WINSOCK2 == 0) || defined (ACE_USE_SELECT_REACTOR_FOR_REACTOR_IMPL) */
00104 
00105 /*
00106  * End hook.
00107  */
00108 //@@ REACTOR_SPL_CONSTRUCTOR_COMMENT_HOOK_END
00109 
00110       this->implementation (impl);
00111       this->delete_implementation_ = true;
00112     }
00113 }
00114 
00115 ACE_Reactor::~ACE_Reactor (void)
00116 {
00117   this->implementation ()->close ();
00118   if (this->delete_implementation_)
00119     delete this->implementation ();
00120 }
00121 
00122 // Process-wide ACE_Reactor.
00123 ACE_Reactor *ACE_Reactor::reactor_ = 0;
00124 
00125 // Controls whether the Reactor is deleted when we shut down (we can
00126 // only delete it safely if we created it!)
00127 bool ACE_Reactor::delete_reactor_ = false;
00128 
00129 ACE_Reactor *
00130 ACE_Reactor::instance (void)
00131 {
00132   ACE_TRACE ("ACE_Reactor::instance");
00133 
00134   if (ACE_Reactor::reactor_ == 0)
00135     {
00136       // Perform Double-Checked Locking Optimization.
00137       ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
00138                                 *ACE_Static_Object_Lock::instance (), 0));
00139 
00140       if (ACE_Reactor::reactor_ == 0)
00141         {
00142           ACE_NEW_RETURN (ACE_Reactor::reactor_,
00143                           ACE_Reactor,
00144                           0);
00145           ACE_Reactor::delete_reactor_ = true;
00146           ACE_REGISTER_FRAMEWORK_COMPONENT(ACE_Reactor, ACE_Reactor::reactor_)
00147         }
00148     }
00149   return ACE_Reactor::reactor_;
00150 }
00151 
00152 ACE_Reactor *
00153 ACE_Reactor::instance (ACE_Reactor *r, bool delete_reactor)
00154 {
00155   ACE_TRACE ("ACE_Reactor::instance");
00156 
00157   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
00158                             *ACE_Static_Object_Lock::instance (), 0));
00159   ACE_Reactor *t = ACE_Reactor::reactor_;
00160   ACE_Reactor::delete_reactor_ = delete_reactor;
00161 
00162   ACE_Reactor::reactor_ = r;
00163 
00164   // We can't register the Reactor singleton as a framework component twice.
00165   // Therefore we test to see if we had an existing reactor instance, which
00166   // if so means it must have already been registered.
00167   if (t == 0)
00168     ACE_REGISTER_FRAMEWORK_COMPONENT(ACE_Reactor, ACE_Reactor::reactor_);
00169 
00170   return t;
00171 }
00172 
00173 void
00174 ACE_Reactor::close_singleton (void)
00175 {
00176   ACE_TRACE ("ACE_Reactor::close_singleton");
00177 
00178   ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon,
00179                      *ACE_Static_Object_Lock::instance ()));
00180 
00181   if (ACE_Reactor::delete_reactor_)
00182     {
00183       delete ACE_Reactor::reactor_;
00184       ACE_Reactor::reactor_ = 0;
00185       ACE_Reactor::delete_reactor_ = false;
00186     }
00187 }
00188 
00189 const ACE_TCHAR *
00190 ACE_Reactor::dll_name (void)
00191 {
00192   return ACE_TEXT ("ACE");
00193 }
00194 
00195 const ACE_TCHAR *
00196 ACE_Reactor::name (void)
00197 {
00198   return ACE_TEXT ("ACE_Reactor");
00199 }
00200 
00201 int
00202 ACE_Reactor::check_reconfiguration (ACE_Reactor *)
00203 {
00204 #if !defined (ACE_HAS_WINCE)  &&  !defined (ACE_LACKS_ACE_SVCCONF)
00205   if (ACE_Service_Config::reconfig_occurred ())
00206     {
00207       ACE_Service_Config::reconfigure ();
00208       return 1;
00209     }
00210 #endif /* ! ACE_HAS_WINCE || ! ACE_LACKS_ACE_SVCCONF */
00211   return 0;
00212 }
00213 
00214 int
00215 ACE_Reactor::run_reactor_event_loop (REACTOR_EVENT_HOOK eh)
00216 {
00217   ACE_TRACE ("ACE_Reactor::run_reactor_event_loop");
00218 
00219   if (this->reactor_event_loop_done ())
00220     return 0;
00221 
00222   while (1)
00223     {
00224       int const result = this->implementation_->handle_events ();
00225 
00226       if (eh != 0 && (*eh)(this))
00227         continue;
00228       else if (result == -1 && this->implementation_->deactivated ())
00229         return 0;
00230       else if (result == -1)
00231         return -1;
00232     }
00233 
00234   ACE_NOTREACHED (return 0;)
00235 }
00236 
00237 int
00238 ACE_Reactor::run_alertable_reactor_event_loop (REACTOR_EVENT_HOOK eh)
00239 {
00240   ACE_TRACE ("ACE_Reactor::run_alertable_reactor_event_loop");
00241 
00242   if (this->reactor_event_loop_done ())
00243     return 0;
00244 
00245   while (1)
00246     {
00247       int const result = this->implementation_->alertable_handle_events ();
00248 
00249       if (eh != 0 && (*eh)(this))
00250         continue;
00251       else if (result == -1 && this->implementation_->deactivated ())
00252         return 0;
00253       else if (result == -1)
00254         return -1;
00255     }
00256 
00257   ACE_NOTREACHED (return 0;)
00258 }
00259 
00260 int
00261 ACE_Reactor::run_reactor_event_loop (ACE_Time_Value &tv,
00262                                      REACTOR_EVENT_HOOK eh)
00263 {
00264   ACE_TRACE ("ACE_Reactor::run_reactor_event_loop");
00265 
00266   if (this->reactor_event_loop_done ())
00267     return 0;
00268 
00269   while (1)
00270     {
00271       int result = this->implementation_->handle_events (tv);
00272 
00273       if (eh != 0 && (*eh) (this))
00274         continue;
00275       else if (result == -1)
00276         {
00277           if (this->implementation_->deactivated ())
00278             result = 0;
00279           return result;
00280         }
00281       else if (result == 0)
00282         {
00283           // The <handle_events> method timed out without dispatching
00284           // anything.  Because of rounding and conversion errors and
00285           // such, it could be that the wait loop (WFMO, select, etc.)
00286           // timed out, but the timer queue said it wasn't quite ready
00287           // to expire a timer. In this case, the ACE_Time_Value we
00288           // passed into handle_events won't have quite been reduced
00289           // to 0, and we need to go around again. If we are all the
00290           // way to 0, just return, as the entire time the caller
00291           // wanted to wait has been used up.
00292           if (tv.usec () > 0)
00293             continue;
00294           return 0;
00295         }
00296       // Else there were some events dispatched; go around again
00297     }
00298 
00299   ACE_NOTREACHED (return 0;)
00300 }
00301 
00302 int
00303 ACE_Reactor::run_alertable_reactor_event_loop (ACE_Time_Value &tv,
00304                                                REACTOR_EVENT_HOOK eh)
00305 {
00306   ACE_TRACE ("ACE_Reactor::run_alertable_reactor_event_loop");
00307 
00308   if (this->reactor_event_loop_done ())
00309     return 0;
00310 
00311   for (;;)
00312     {
00313       int result = this->implementation_->alertable_handle_events (tv);
00314 
00315       if (eh != 0 && (*eh)(this))
00316         continue;
00317       else if (result == -1 && this->implementation_->deactivated ())
00318         return 0;
00319       else if (result <= 0)
00320         return result;
00321     }
00322 }
00323 
00324 int
00325 ACE_Reactor::register_handler (ACE_Event_Handler *event_handler,
00326                                ACE_Reactor_Mask mask)
00327 {
00328   // Remember the old reactor.
00329   ACE_Reactor *old_reactor = event_handler->reactor ();
00330 
00331   // Assign *this* <Reactor> to the <Event_Handler>.
00332   event_handler->reactor (this);
00333 
00334   int result = this->implementation ()->register_handler (event_handler, mask);
00335   if (result == -1)
00336     // Reset the old reactor in case of failures.
00337     event_handler->reactor (old_reactor);
00338 
00339   return result;
00340 }
00341 
00342 int
00343 ACE_Reactor::register_handler (ACE_HANDLE io_handle,
00344                                ACE_Event_Handler *event_handler,
00345                                ACE_Reactor_Mask mask)
00346 {
00347   // Remember the old reactor.
00348   ACE_Reactor *old_reactor = event_handler->reactor ();
00349 
00350   // Assign *this* <Reactor> to the <Event_Handler>.
00351   event_handler->reactor (this);
00352 
00353   int result = this->implementation ()->register_handler (io_handle,
00354                                                           event_handler,
00355                                                           mask);
00356   if (result == -1)
00357     // Reset the old reactor in case of failures.
00358     event_handler->reactor (old_reactor);
00359 
00360   return result;
00361 }
00362 
00363 #if defined (ACE_WIN32)
00364 
00365 int
00366 ACE_Reactor::register_handler (ACE_Event_Handler *event_handler,
00367                                ACE_HANDLE event_handle)
00368 {
00369   // Remember the old reactor.
00370   ACE_Reactor *old_reactor = event_handler->reactor ();
00371 
00372   // Assign *this* <Reactor> to the <Event_Handler>.
00373   event_handler->reactor (this);
00374 
00375   int result = this->implementation ()->register_handler (event_handler,
00376                                                           event_handle);
00377   if (result == -1)
00378     // Reset the old reactor in case of failures.
00379     event_handler->reactor (old_reactor);
00380 
00381   return result;
00382 }
00383 
00384 #endif /* ACE_WIN32 */
00385 
00386 int
00387 ACE_Reactor::register_handler (ACE_HANDLE event_handle,
00388                                ACE_HANDLE io_handle,
00389                                ACE_Event_Handler *event_handler,
00390                                ACE_Reactor_Mask mask)
00391 {
00392   // Remember the old reactor.
00393   ACE_Reactor *old_reactor = event_handler->reactor ();
00394 
00395   // Assign *this* <Reactor> to the <Event_Handler>.
00396   event_handler->reactor (this);
00397 
00398   int result = this->implementation ()->register_handler (event_handle,
00399                                                           io_handle,
00400                                                           event_handler,
00401                                                           mask);
00402   if (result == -1)
00403     // Reset the old reactor in case of failures.
00404     event_handler->reactor (old_reactor);
00405 
00406   return result;
00407 }
00408 
00409 int
00410 ACE_Reactor::register_handler (const ACE_Handle_Set &handles,
00411                                ACE_Event_Handler *event_handler,
00412                                ACE_Reactor_Mask mask)
00413 {
00414   // Remember the old reactor.
00415   ACE_Reactor *old_reactor = event_handler->reactor ();
00416 
00417   // Assign *this* <Reactor> to the <Event_Handler>.
00418   event_handler->reactor (this);
00419 
00420   int result = this->implementation ()->register_handler (handles,
00421                                                           event_handler,
00422                                                           mask);
00423   if (result == -1)
00424     // Reset the old reactor in case of failures.
00425     event_handler->reactor (old_reactor);
00426 
00427   return result;
00428 }
00429 
00430 long
00431 ACE_Reactor::schedule_timer (ACE_Event_Handler *event_handler,
00432                              const void *arg,
00433                              const ACE_Time_Value &delta,
00434                              const ACE_Time_Value &interval)
00435 {
00436   // Remember the old reactor.
00437   ACE_Reactor *old_reactor = event_handler->reactor ();
00438 
00439   // Assign *this* <Reactor> to the <Event_Handler>.
00440   event_handler->reactor (this);
00441 
00442   long result = this->implementation ()->schedule_timer (event_handler,
00443                                                          arg,
00444                                                          delta,
00445                                                          interval);
00446   if (result == -1)
00447     // Reset the old reactor in case of failures.
00448     event_handler->reactor (old_reactor);
00449 
00450   return result;
00451 }
00452 
00453 int
00454 ACE_Reactor::schedule_wakeup (ACE_Event_Handler *event_handler,
00455                               ACE_Reactor_Mask masks_to_be_added)
00456 {
00457   // Remember the old reactor.
00458   ACE_Reactor *old_reactor = event_handler->reactor ();
00459 
00460   // Assign *this* <Reactor> to the <Event_Handler>.
00461   event_handler->reactor (this);
00462 
00463   int result = this->implementation ()->schedule_wakeup (event_handler,
00464                                                          masks_to_be_added);
00465   if (result == -1)
00466     // Reset the old reactor in case of failures.
00467     event_handler->reactor (old_reactor);
00468 
00469   return result;
00470 }
00471 
00472 int
00473 ACE_Reactor::notify (ACE_Event_Handler *event_handler,
00474                      ACE_Reactor_Mask mask,
00475                      ACE_Time_Value *tv)
00476 {
00477   // First, try to remember this reactor in the event handler, in case
00478   // the event handler goes away before the notification is delivered.
00479   if (event_handler != 0 && event_handler->reactor () == 0)
00480     event_handler->reactor (this);
00481   return this->implementation ()->notify (event_handler, mask, tv);
00482 }
00483 
00484 int
00485 ACE_Reactor::reset_timer_interval
00486   (long timer_id,
00487    const ACE_Time_Value &interval)
00488 {
00489   ACE_TRACE ("ACE_Reactor::reset_timer_interval");
00490 
00491   return this->implementation ()->reset_timer_interval (timer_id, interval);
00492 }
00493 
00494 int
00495 ACE_Reactor::cancel_timer (ACE_Event_Handler *event_handler,
00496                            int dont_call_handle_close)
00497 {
00498   return this->implementation ()->cancel_timer (event_handler,
00499                                                 dont_call_handle_close);
00500 }
00501 
00502 int
00503 ACE_Reactor::cancel_timer (long timer_id,
00504                            const void **arg,
00505                            int dont_call_handle_close)
00506 {
00507   return this->implementation ()->cancel_timer (timer_id,
00508                                                 arg,
00509                                                 dont_call_handle_close);
00510 }
00511 
00512 ACE_END_VERSIONED_NAMESPACE_DECL

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