1 // $Id: Reactor.cpp 80826 2008-03-04 14:51:23Z wotte $
3 #include "ace/Reactor.h"
5 #if !defined (ACE_LACKS_ACE_SVCCONF)
6 # include "ace/Service_Config.h"
7 #endif /* !ACE_LACKS_ACE_SVCCONF */
10 * Hook to specialize the includes directly with the concrete
11 * Reactor type, e.g., select, thread pool reactor
12 * known at compile time. This hook results in all the
13 * #defines being commented
14 * out and the concrete header file directly included.
16 //@@ REACTOR_SPL_COMMENT_INCLUDE_START_HOOK
17 // Only include the headers needed to compile.
18 #if !defined (ACE_WIN32) \
19 || !defined (ACE_HAS_WINSOCK2) || (ACE_HAS_WINSOCK2 == 0) \
20 || defined (ACE_USE_SELECT_REACTOR_FOR_REACTOR_IMPL) \
21 || defined (ACE_USE_TP_REACTOR_FOR_REACTOR_IMPL) \
22 || defined (ACE_USE_DEV_POLL_REACTOR_FOR_REACTOR_IMPL)
23 # if defined (ACE_USE_TP_REACTOR_FOR_REACTOR_IMPL)
24 # include "ace/TP_Reactor.h"
26 # if defined (ACE_USE_DEV_POLL_REACTOR_FOR_REACTOR_IMPL)
27 # include "ace/Dev_Poll_Reactor.h"
29 # include "ace/Select_Reactor.h"
30 # endif /* ACE_USE_DEV_POLL_REACTOR_FOR_REACTOR_IMPL */
31 # endif /* ACE_USE_TP_REACTOR_FOR_REACTOR_IMPL */
32 #else /* We are on Win32 and we have winsock and ACE_USE_SELECT_REACTOR_FOR_REACTOR_IMPL is not defined */
33 # if defined (ACE_USE_MSG_WFMO_REACTOR_FOR_REACTOR_IMPL)
34 # include "ace/Msg_WFMO_Reactor.h"
36 # include "ace/WFMO_Reactor.h"
37 # endif /* ACE_USE_MSG_WFMO_REACTOR_FOR_REACTOR_IMPL */
38 #endif /* !defined (ACE_WIN32) || !defined (ACE_HAS_WINSOCK2) || (ACE_HAS_WINSOCK2 == 0) || defined (ACE_USE_SELECT_REACTOR_FOR_REACTOR_IMPL) */
43 //@@ REACTOR_SPL_COMMENT_INCLUDE_END_HOOK
45 #include "ace/Static_Object_Lock.h"
46 #include "ace/Framework_Component.h"
47 #include "ace/Guard_T.h"
48 #include "ace/Recursive_Thread_Mutex.h"
50 #if !defined (__ACE_INLINE__)
51 #include "ace/Reactor.inl"
52 #endif /* __ACE_INLINE__ */
56 "$Id: Reactor.cpp 80826 2008-03-04 14:51:23Z wotte $")
58 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
60 ACE_ALLOC_HOOK_DEFINE(ACE_Reactor
)
62 ACE_Reactor::ACE_Reactor (ACE_Reactor_Impl
*impl
,
63 bool delete_implementation
)
64 : implementation_ (0),
65 delete_implementation_ (delete_implementation
)
67 this->implementation (impl
);
69 if (this->implementation () == 0)
72 * Hook to specialize the reactor implementation with the concrete
73 * Reactor implementation known at compile time. This hook will
74 * cause the conditionally defined code to be commented out and
75 * the concrete Reactor directly created.
77 //@@ REACTOR_SPL_CONSTRUCTOR_COMMENT_HOOK_START
78 #if !defined (ACE_WIN32) \
79 || !defined (ACE_HAS_WINSOCK2) || (ACE_HAS_WINSOCK2 == 0) \
80 || defined (ACE_USE_SELECT_REACTOR_FOR_REACTOR_IMPL) \
81 || defined (ACE_USE_TP_REACTOR_FOR_REACTOR_IMPL) \
82 || defined (ACE_USE_DEV_POLL_REACTOR_FOR_REACTOR_IMPL)
83 # if defined (ACE_USE_TP_REACTOR_FOR_REACTOR_IMPL)
87 # if defined (ACE_USE_DEV_POLL_REACTOR_FOR_REACTOR_IMPL)
89 ACE_Dev_Poll_Reactor
);
93 # endif /* ACE_USE_DEV_POLL_REACTOR_FOR_REACTOR_IMPL */
94 # endif /* ACE_USE_TP_REACTOR_FOR_REACTOR_IMPL */
95 #else /* We are on Win32 and we have winsock and ACE_USE_SELECT_REACTOR_FOR_REACTOR_IMPL is not defined */
96 #if defined (ACE_USE_MSG_WFMO_REACTOR_FOR_REACTOR_IMPL)
98 ACE_Msg_WFMO_Reactor
);
102 #endif /* ACE_USE_MSG_WFMO_REACTOR_FOR_REACTOR_IMPL */
103 #endif /* !defined (ACE_WIN32) || !defined (ACE_HAS_WINSOCK2) || (ACE_HAS_WINSOCK2 == 0) || defined (ACE_USE_SELECT_REACTOR_FOR_REACTOR_IMPL) */
108 //@@ REACTOR_SPL_CONSTRUCTOR_COMMENT_HOOK_END
110 this->implementation (impl
);
111 this->delete_implementation_
= true;
115 ACE_Reactor::~ACE_Reactor (void)
117 this->implementation ()->close ();
118 if (this->delete_implementation_
)
119 delete this->implementation ();
122 // Process-wide ACE_Reactor.
123 ACE_Reactor
*ACE_Reactor::reactor_
= 0;
125 // Controls whether the Reactor is deleted when we shut down (we can
126 // only delete it safely if we created it!)
127 bool ACE_Reactor::delete_reactor_
= false;
130 ACE_Reactor::instance (void)
132 ACE_TRACE ("ACE_Reactor::instance");
134 if (ACE_Reactor::reactor_
== 0)
136 // Perform Double-Checked Locking Optimization.
137 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex
, ace_mon
,
138 *ACE_Static_Object_Lock::instance (), 0));
140 if (ACE_Reactor::reactor_
== 0)
142 ACE_NEW_RETURN (ACE_Reactor::reactor_
,
145 ACE_Reactor::delete_reactor_
= true;
146 ACE_REGISTER_FRAMEWORK_COMPONENT(ACE_Reactor
, ACE_Reactor::reactor_
)
149 return ACE_Reactor::reactor_
;
153 ACE_Reactor::instance (ACE_Reactor
*r
, bool delete_reactor
)
155 ACE_TRACE ("ACE_Reactor::instance");
157 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex
, ace_mon
,
158 *ACE_Static_Object_Lock::instance (), 0));
159 ACE_Reactor
*t
= ACE_Reactor::reactor_
;
160 ACE_Reactor::delete_reactor_
= delete_reactor
;
162 ACE_Reactor::reactor_
= r
;
164 // We can't register the Reactor singleton as a framework component twice.
165 // Therefore we test to see if we had an existing reactor instance, which
166 // if so means it must have already been registered.
168 ACE_REGISTER_FRAMEWORK_COMPONENT(ACE_Reactor
, ACE_Reactor::reactor_
);
174 ACE_Reactor::close_singleton (void)
176 ACE_TRACE ("ACE_Reactor::close_singleton");
178 ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex
, ace_mon
,
179 *ACE_Static_Object_Lock::instance ()));
181 if (ACE_Reactor::delete_reactor_
)
183 delete ACE_Reactor::reactor_
;
184 ACE_Reactor::reactor_
= 0;
185 ACE_Reactor::delete_reactor_
= false;
190 ACE_Reactor::dll_name (void)
192 return ACE_TEXT ("ACE");
196 ACE_Reactor::name (void)
198 return ACE_TEXT ("ACE_Reactor");
202 ACE_Reactor::check_reconfiguration (ACE_Reactor
*)
204 #if !defined (ACE_HAS_WINCE) && !defined (ACE_LACKS_ACE_SVCCONF)
205 if (ACE_Service_Config::reconfig_occurred ())
207 ACE_Service_Config::reconfigure ();
210 #endif /* ! ACE_HAS_WINCE || ! ACE_LACKS_ACE_SVCCONF */
215 ACE_Reactor::run_reactor_event_loop (REACTOR_EVENT_HOOK eh
)
217 ACE_TRACE ("ACE_Reactor::run_reactor_event_loop");
219 if (this->reactor_event_loop_done ())
224 int const result
= this->implementation_
->handle_events ();
226 if (eh
!= 0 && (*eh
)(this))
228 else if (result
== -1 && this->implementation_
->deactivated ())
230 else if (result
== -1)
234 ACE_NOTREACHED (return 0;)
238 ACE_Reactor::run_alertable_reactor_event_loop (REACTOR_EVENT_HOOK eh
)
240 ACE_TRACE ("ACE_Reactor::run_alertable_reactor_event_loop");
242 if (this->reactor_event_loop_done ())
247 int const result
= this->implementation_
->alertable_handle_events ();
249 if (eh
!= 0 && (*eh
)(this))
251 else if (result
== -1 && this->implementation_
->deactivated ())
253 else if (result
== -1)
257 ACE_NOTREACHED (return 0;)
261 ACE_Reactor::run_reactor_event_loop (ACE_Time_Value
&tv
,
262 REACTOR_EVENT_HOOK eh
)
264 ACE_TRACE ("ACE_Reactor::run_reactor_event_loop");
266 if (this->reactor_event_loop_done ())
271 int result
= this->implementation_
->handle_events (tv
);
273 if (eh
!= 0 && (*eh
) (this))
275 else if (result
== -1)
277 if (this->implementation_
->deactivated ())
281 else if (result
== 0)
283 // The <handle_events> method timed out without dispatching
284 // anything. Because of rounding and conversion errors and
285 // such, it could be that the wait loop (WFMO, select, etc.)
286 // timed out, but the timer queue said it wasn't quite ready
287 // to expire a timer. In this case, the ACE_Time_Value we
288 // passed into handle_events won't have quite been reduced
289 // to 0, and we need to go around again. If we are all the
290 // way to 0, just return, as the entire time the caller
291 // wanted to wait has been used up.
296 // Else there were some events dispatched; go around again
299 ACE_NOTREACHED (return 0;)
303 ACE_Reactor::run_alertable_reactor_event_loop (ACE_Time_Value
&tv
,
304 REACTOR_EVENT_HOOK eh
)
306 ACE_TRACE ("ACE_Reactor::run_alertable_reactor_event_loop");
308 if (this->reactor_event_loop_done ())
313 int result
= this->implementation_
->alertable_handle_events (tv
);
315 if (eh
!= 0 && (*eh
)(this))
317 else if (result
== -1 && this->implementation_
->deactivated ())
319 else if (result
<= 0)
325 ACE_Reactor::register_handler (ACE_Event_Handler
*event_handler
,
326 ACE_Reactor_Mask mask
)
328 // Remember the old reactor.
329 ACE_Reactor
*old_reactor
= event_handler
->reactor ();
331 // Assign *this* <Reactor> to the <Event_Handler>.
332 event_handler
->reactor (this);
334 int result
= this->implementation ()->register_handler (event_handler
, mask
);
336 // Reset the old reactor in case of failures.
337 event_handler
->reactor (old_reactor
);
343 ACE_Reactor::register_handler (ACE_HANDLE io_handle
,
344 ACE_Event_Handler
*event_handler
,
345 ACE_Reactor_Mask mask
)
347 // Remember the old reactor.
348 ACE_Reactor
*old_reactor
= event_handler
->reactor ();
350 // Assign *this* <Reactor> to the <Event_Handler>.
351 event_handler
->reactor (this);
353 int result
= this->implementation ()->register_handler (io_handle
,
357 // Reset the old reactor in case of failures.
358 event_handler
->reactor (old_reactor
);
363 #if defined (ACE_WIN32)
366 ACE_Reactor::register_handler (ACE_Event_Handler
*event_handler
,
367 ACE_HANDLE event_handle
)
369 // Remember the old reactor.
370 ACE_Reactor
*old_reactor
= event_handler
->reactor ();
372 // Assign *this* <Reactor> to the <Event_Handler>.
373 event_handler
->reactor (this);
375 int result
= this->implementation ()->register_handler (event_handler
,
378 // Reset the old reactor in case of failures.
379 event_handler
->reactor (old_reactor
);
384 #endif /* ACE_WIN32 */
387 ACE_Reactor::register_handler (ACE_HANDLE event_handle
,
388 ACE_HANDLE io_handle
,
389 ACE_Event_Handler
*event_handler
,
390 ACE_Reactor_Mask mask
)
392 // Remember the old reactor.
393 ACE_Reactor
*old_reactor
= event_handler
->reactor ();
395 // Assign *this* <Reactor> to the <Event_Handler>.
396 event_handler
->reactor (this);
398 int result
= this->implementation ()->register_handler (event_handle
,
403 // Reset the old reactor in case of failures.
404 event_handler
->reactor (old_reactor
);
410 ACE_Reactor::register_handler (const ACE_Handle_Set
&handles
,
411 ACE_Event_Handler
*event_handler
,
412 ACE_Reactor_Mask mask
)
414 // Remember the old reactor.
415 ACE_Reactor
*old_reactor
= event_handler
->reactor ();
417 // Assign *this* <Reactor> to the <Event_Handler>.
418 event_handler
->reactor (this);
420 int result
= this->implementation ()->register_handler (handles
,
424 // Reset the old reactor in case of failures.
425 event_handler
->reactor (old_reactor
);
431 ACE_Reactor::schedule_timer (ACE_Event_Handler
*event_handler
,
433 const ACE_Time_Value
&delta
,
434 const ACE_Time_Value
&interval
)
436 // Remember the old reactor.
437 ACE_Reactor
*old_reactor
= event_handler
->reactor ();
439 // Assign *this* <Reactor> to the <Event_Handler>.
440 event_handler
->reactor (this);
442 long result
= this->implementation ()->schedule_timer (event_handler
,
447 // Reset the old reactor in case of failures.
448 event_handler
->reactor (old_reactor
);
454 ACE_Reactor::schedule_wakeup (ACE_Event_Handler
*event_handler
,
455 ACE_Reactor_Mask masks_to_be_added
)
457 // Remember the old reactor.
458 ACE_Reactor
*old_reactor
= event_handler
->reactor ();
460 // Assign *this* <Reactor> to the <Event_Handler>.
461 event_handler
->reactor (this);
463 int result
= this->implementation ()->schedule_wakeup (event_handler
,
466 // Reset the old reactor in case of failures.
467 event_handler
->reactor (old_reactor
);
473 ACE_Reactor::notify (ACE_Event_Handler
*event_handler
,
474 ACE_Reactor_Mask mask
,
477 // First, try to remember this reactor in the event handler, in case
478 // the event handler goes away before the notification is delivered.
479 if (event_handler
!= 0 && event_handler
->reactor () == 0)
480 event_handler
->reactor (this);
481 return this->implementation ()->notify (event_handler
, mask
, tv
);
485 ACE_Reactor::reset_timer_interval
487 const ACE_Time_Value
&interval
)
489 ACE_TRACE ("ACE_Reactor::reset_timer_interval");
491 return this->implementation ()->reset_timer_interval (timer_id
, interval
);
495 ACE_Reactor::cancel_timer (ACE_Event_Handler
*event_handler
,
496 int dont_call_handle_close
)
498 return this->implementation ()->cancel_timer (event_handler
,
499 dont_call_handle_close
);
503 ACE_Reactor::cancel_timer (long timer_id
,
505 int dont_call_handle_close
)
507 return this->implementation ()->cancel_timer (timer_id
,
509 dont_call_handle_close
);
512 ACE_END_VERSIONED_NAMESPACE_DECL