Changes to attempt to silence bcc64x
[ACE_TAO.git] / ACE / ace / Reactor.cpp
blobd969f84f27714f33bfb54c4dd6a343670ef3f703
1 #include "ace/Reactor.h"
3 #if !defined (ACE_LACKS_ACE_SVCCONF)
4 # include "ace/Service_Config.h"
5 #endif /* !ACE_LACKS_ACE_SVCCONF */
7 // Only include the headers needed to compile.
8 #if !defined (ACE_WIN32) \
9 || !defined (ACE_HAS_WINSOCK2) || (ACE_HAS_WINSOCK2 == 0) \
10 || defined (ACE_USE_SELECT_REACTOR_FOR_REACTOR_IMPL) \
11 || defined (ACE_USE_TP_REACTOR_FOR_REACTOR_IMPL) \
12 || defined (ACE_USE_DEV_POLL_REACTOR_FOR_REACTOR_IMPL)
13 # if defined (ACE_USE_TP_REACTOR_FOR_REACTOR_IMPL)
14 # include "ace/TP_Reactor.h"
15 # else
16 # if defined (ACE_USE_DEV_POLL_REACTOR_FOR_REACTOR_IMPL)
17 # include "ace/Dev_Poll_Reactor.h"
18 # else
19 # include "ace/Select_Reactor.h"
20 # endif /* ACE_USE_DEV_POLL_REACTOR_FOR_REACTOR_IMPL */
21 # endif /* ACE_USE_TP_REACTOR_FOR_REACTOR_IMPL */
22 #else /* We are on Win32 and we have winsock and ACE_USE_SELECT_REACTOR_FOR_REACTOR_IMPL is not defined */
23 # if defined (ACE_USE_MSG_WFMO_REACTOR_FOR_REACTOR_IMPL)
24 # include "ace/Msg_WFMO_Reactor.h"
25 # else
26 # include "ace/WFMO_Reactor.h"
27 # endif /* ACE_USE_MSG_WFMO_REACTOR_FOR_REACTOR_IMPL */
28 #endif /* !defined (ACE_WIN32) || !defined (ACE_HAS_WINSOCK2) || (ACE_HAS_WINSOCK2 == 0) || defined (ACE_USE_SELECT_REACTOR_FOR_REACTOR_IMPL) */
30 #include "ace/Static_Object_Lock.h"
31 #include "ace/Framework_Component.h"
32 #include "ace/Guard_T.h"
33 #include "ace/Recursive_Thread_Mutex.h"
35 #if !defined (__ACE_INLINE__)
36 #include "ace/Reactor.inl"
37 #endif /* __ACE_INLINE__ */
39 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
41 ACE_ALLOC_HOOK_DEFINE(ACE_Reactor)
43 ACE_Reactor::ACE_Reactor (ACE_Reactor_Impl *impl,
44 bool delete_implementation)
45 : implementation_ (0),
46 delete_implementation_ (delete_implementation)
48 this->implementation (impl);
50 if (this->implementation () == 0)
52 #if !defined (ACE_WIN32) \
53 || !defined (ACE_HAS_WINSOCK2) || (ACE_HAS_WINSOCK2 == 0) \
54 || defined (ACE_USE_SELECT_REACTOR_FOR_REACTOR_IMPL) \
55 || defined (ACE_USE_TP_REACTOR_FOR_REACTOR_IMPL) \
56 || defined (ACE_USE_DEV_POLL_REACTOR_FOR_REACTOR_IMPL)
57 # if defined (ACE_USE_TP_REACTOR_FOR_REACTOR_IMPL)
58 ACE_NEW (impl,
59 ACE_TP_Reactor);
60 # else
61 # if defined (ACE_USE_DEV_POLL_REACTOR_FOR_REACTOR_IMPL)
62 ACE_NEW (impl,
63 ACE_Dev_Poll_Reactor);
64 # else
65 ACE_NEW (impl,
66 ACE_Select_Reactor);
67 # endif /* ACE_USE_DEV_POLL_REACTOR_FOR_REACTOR_IMPL */
68 # endif /* ACE_USE_TP_REACTOR_FOR_REACTOR_IMPL */
69 #else /* We are on Win32 and we have winsock and ACE_USE_SELECT_REACTOR_FOR_REACTOR_IMPL is not defined */
70 #if defined (ACE_USE_MSG_WFMO_REACTOR_FOR_REACTOR_IMPL)
71 ACE_NEW (impl,
72 ACE_Msg_WFMO_Reactor);
73 #else
74 ACE_NEW (impl,
75 ACE_WFMO_Reactor);
76 #endif /* ACE_USE_MSG_WFMO_REACTOR_FOR_REACTOR_IMPL */
77 #endif /* !defined (ACE_WIN32) || !defined (ACE_HAS_WINSOCK2) || (ACE_HAS_WINSOCK2 == 0) || defined (ACE_USE_SELECT_REACTOR_FOR_REACTOR_IMPL) */
78 this->implementation (impl);
79 this->delete_implementation_ = true;
83 ACE_Reactor::~ACE_Reactor ()
85 this->implementation ()->close ();
86 if (this->delete_implementation_)
87 delete this->implementation ();
90 // Process-wide ACE_Reactor.
91 ACE_Reactor *ACE_Reactor::reactor_ = 0;
93 // Controls whether the Reactor is deleted when we shut down (we can
94 // only delete it safely if we created it!)
95 bool ACE_Reactor::delete_reactor_ = false;
97 ACE_Reactor *
98 ACE_Reactor::instance ()
100 ACE_TRACE ("ACE_Reactor::instance");
102 if (ACE_Reactor::reactor_ == 0)
104 // Perform Double-Checked Locking Optimization.
105 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
106 *ACE_Static_Object_Lock::instance (), 0));
108 if (ACE_Reactor::reactor_ == 0)
110 ACE_NEW_RETURN (ACE_Reactor::reactor_,
111 ACE_Reactor,
113 ACE_Reactor::delete_reactor_ = true;
114 ACE_REGISTER_FRAMEWORK_COMPONENT(ACE_Reactor, ACE_Reactor::reactor_)
117 return ACE_Reactor::reactor_;
120 ACE_Reactor *
121 ACE_Reactor::instance (ACE_Reactor *r, bool delete_reactor)
123 ACE_TRACE ("ACE_Reactor::instance");
125 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
126 *ACE_Static_Object_Lock::instance (), 0));
127 ACE_Reactor *t = ACE_Reactor::reactor_;
128 ACE_Reactor::delete_reactor_ = delete_reactor;
130 ACE_Reactor::reactor_ = r;
132 // We can't register the Reactor singleton as a framework component twice.
133 // Therefore we test to see if we had an existing reactor instance, which
134 // if so means it must have already been registered.
135 if (t == 0)
136 ACE_REGISTER_FRAMEWORK_COMPONENT(ACE_Reactor, ACE_Reactor::reactor_);
138 return t;
141 void
142 ACE_Reactor::close_singleton ()
144 ACE_TRACE ("ACE_Reactor::close_singleton");
146 ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon,
147 *ACE_Static_Object_Lock::instance ()));
149 if (ACE_Reactor::delete_reactor_)
151 delete ACE_Reactor::reactor_;
152 ACE_Reactor::reactor_ = 0;
153 ACE_Reactor::delete_reactor_ = false;
157 const ACE_TCHAR *
158 ACE_Reactor::dll_name ()
160 return ACE_TEXT ("ACE");
163 const ACE_TCHAR *
164 ACE_Reactor::name ()
166 return ACE_TEXT ("ACE_Reactor");
170 ACE_Reactor::check_reconfiguration (ACE_Reactor *)
172 #if !defined (ACE_LACKS_ACE_SVCCONF)
173 if (ACE_Service_Config::reconfig_occurred ())
175 ACE_Service_Config::reconfigure ();
176 return 1;
178 #endif /* !ACE_LACKS_ACE_SVCCONF */
179 return 0;
183 ACE_Reactor::run_reactor_event_loop (REACTOR_EVENT_HOOK eh)
185 ACE_TRACE ("ACE_Reactor::run_reactor_event_loop");
187 if (this->reactor_event_loop_done ())
188 return 0;
190 while (1)
192 int const result = this->implementation_->handle_events ();
194 if (eh != 0 && (*eh)(this))
195 continue;
196 else if (result == -1 && this->implementation_->deactivated ())
197 return 0;
198 else if (result == -1)
199 return -1;
202 ACE_NOTREACHED (return 0;)
206 ACE_Reactor::run_alertable_reactor_event_loop (REACTOR_EVENT_HOOK eh)
208 ACE_TRACE ("ACE_Reactor::run_alertable_reactor_event_loop");
210 if (this->reactor_event_loop_done ())
211 return 0;
213 while (1)
215 int const result = this->implementation_->alertable_handle_events ();
217 if (eh != 0 && (*eh)(this))
218 continue;
219 else if (result == -1 && this->implementation_->deactivated ())
220 return 0;
221 else if (result == -1)
222 return -1;
225 ACE_NOTREACHED (return 0;)
229 ACE_Reactor::run_reactor_event_loop (ACE_Time_Value &tv,
230 REACTOR_EVENT_HOOK eh)
232 ACE_TRACE ("ACE_Reactor::run_reactor_event_loop");
234 if (this->reactor_event_loop_done ())
235 return 0;
237 while (1)
239 int result = this->implementation_->handle_events (tv);
241 if (eh != 0 && (*eh) (this))
242 continue;
243 else if (result == -1)
245 if (this->implementation_->deactivated ())
246 result = 0;
247 return result;
249 else if (result == 0)
251 // The <handle_events> method timed out without dispatching
252 // anything. Because of rounding and conversion errors and
253 // such, it could be that the wait loop (WFMO, select, etc.)
254 // timed out, but the timer queue said it wasn't quite ready
255 // to expire a timer. In this case, the ACE_Time_Value we
256 // passed into handle_events won't have quite been reduced
257 // to 0, and we need to go around again. If we are all the
258 // way to 0, just return, as the entire time the caller
259 // wanted to wait has been used up.
260 if (tv.usec () > 0)
261 continue;
262 return 0;
264 // Else there were some events dispatched; go around again
267 ACE_NOTREACHED (return 0;)
271 ACE_Reactor::run_alertable_reactor_event_loop (ACE_Time_Value &tv,
272 REACTOR_EVENT_HOOK eh)
274 ACE_TRACE ("ACE_Reactor::run_alertable_reactor_event_loop");
276 if (this->reactor_event_loop_done ())
277 return 0;
279 for (;;)
281 int result = this->implementation_->alertable_handle_events (tv);
283 if (eh != 0 && (*eh)(this))
284 continue;
285 else if (result == -1 && this->implementation_->deactivated ())
286 return 0;
287 else if (result <= 0)
288 return result;
293 ACE_Reactor::register_handler (ACE_Event_Handler *event_handler,
294 ACE_Reactor_Mask mask)
296 // Remember the old reactor.
297 ACE_Reactor *old_reactor = event_handler->reactor ();
299 // Assign *this* <Reactor> to the <Event_Handler>.
300 event_handler->reactor (this);
302 int result = this->implementation ()->register_handler (event_handler, mask);
303 if (result == -1)
304 // Reset the old reactor in case of failures.
305 event_handler->reactor (old_reactor);
307 return result;
311 ACE_Reactor::register_handler (ACE_HANDLE io_handle,
312 ACE_Event_Handler *event_handler,
313 ACE_Reactor_Mask mask)
315 // Remember the old reactor.
316 ACE_Reactor *old_reactor = event_handler->reactor ();
318 // Assign *this* <Reactor> to the <Event_Handler>.
319 event_handler->reactor (this);
321 int result = this->implementation ()->register_handler (io_handle,
322 event_handler,
323 mask);
324 if (result == -1)
325 // Reset the old reactor in case of failures.
326 event_handler->reactor (old_reactor);
328 return result;
331 #if defined (ACE_WIN32)
334 ACE_Reactor::register_handler (ACE_Event_Handler *event_handler,
335 ACE_HANDLE event_handle)
337 // Remember the old reactor.
338 ACE_Reactor *old_reactor = event_handler->reactor ();
340 // Assign *this* <Reactor> to the <Event_Handler>.
341 event_handler->reactor (this);
343 int result = this->implementation ()->register_handler (event_handler,
344 event_handle);
345 if (result == -1)
346 // Reset the old reactor in case of failures.
347 event_handler->reactor (old_reactor);
349 return result;
352 #endif /* ACE_WIN32 */
355 ACE_Reactor::register_handler (ACE_HANDLE event_handle,
356 ACE_HANDLE io_handle,
357 ACE_Event_Handler *event_handler,
358 ACE_Reactor_Mask mask)
360 // Remember the old reactor.
361 ACE_Reactor *old_reactor = event_handler->reactor ();
363 // Assign *this* <Reactor> to the <Event_Handler>.
364 event_handler->reactor (this);
366 int result = this->implementation ()->register_handler (event_handle,
367 io_handle,
368 event_handler,
369 mask);
370 if (result == -1)
371 // Reset the old reactor in case of failures.
372 event_handler->reactor (old_reactor);
374 return result;
378 ACE_Reactor::register_handler (const ACE_Handle_Set &handles,
379 ACE_Event_Handler *event_handler,
380 ACE_Reactor_Mask mask)
382 // Remember the old reactor.
383 ACE_Reactor *old_reactor = event_handler->reactor ();
385 // Assign *this* <Reactor> to the <Event_Handler>.
386 event_handler->reactor (this);
388 int result = this->implementation ()->register_handler (handles,
389 event_handler,
390 mask);
391 if (result == -1)
392 // Reset the old reactor in case of failures.
393 event_handler->reactor (old_reactor);
395 return result;
398 long
399 ACE_Reactor::schedule_timer (ACE_Event_Handler *event_handler,
400 const void *arg,
401 const ACE_Time_Value &delta,
402 const ACE_Time_Value &interval)
404 // Remember the old reactor.
405 ACE_Reactor *old_reactor = event_handler->reactor ();
407 // Assign *this* <Reactor> to the <Event_Handler>.
408 event_handler->reactor (this);
410 long result = this->implementation ()->schedule_timer (event_handler,
411 arg,
412 delta,
413 interval);
414 if (result == -1)
415 // Reset the old reactor in case of failures.
416 event_handler->reactor (old_reactor);
418 return result;
422 ACE_Reactor::schedule_wakeup (ACE_Event_Handler *event_handler,
423 ACE_Reactor_Mask masks_to_be_added)
425 // Remember the old reactor.
426 ACE_Reactor *old_reactor = event_handler->reactor ();
428 // Assign *this* <Reactor> to the <Event_Handler>.
429 event_handler->reactor (this);
431 int result = this->implementation ()->schedule_wakeup (event_handler,
432 masks_to_be_added);
433 if (result == -1)
434 // Reset the old reactor in case of failures.
435 event_handler->reactor (old_reactor);
437 return result;
441 ACE_Reactor::notify (ACE_Event_Handler *event_handler,
442 ACE_Reactor_Mask mask,
443 ACE_Time_Value *tv)
445 // First, try to remember this reactor in the event handler, in case
446 // the event handler goes away before the notification is delivered.
447 if (event_handler != 0 && event_handler->reactor () == 0)
449 event_handler->reactor (this);
451 return this->implementation ()->notify (event_handler, mask, tv);
455 ACE_Reactor::reset_timer_interval
456 (long timer_id,
457 const ACE_Time_Value &interval)
459 ACE_TRACE ("ACE_Reactor::reset_timer_interval");
461 return this->implementation ()->reset_timer_interval (timer_id, interval);
465 ACE_Reactor::cancel_timer (ACE_Event_Handler *event_handler,
466 int dont_call_handle_close)
468 return this->implementation ()->cancel_timer (event_handler,
469 dont_call_handle_close);
473 ACE_Reactor::cancel_timer (long timer_id,
474 const void **arg,
475 int dont_call_handle_close)
477 return this->implementation ()->cancel_timer (timer_id,
478 arg,
479 dont_call_handle_close);
482 ACE_END_VERSIONED_NAMESPACE_DECL