1 #ifndef ACE_SELECT_REACTOR_T_CPP
2 #define ACE_SELECT_REACTOR_T_CPP
4 #include "ace/Select_Reactor_T.h"
6 #if !defined (ACE_LACKS_PRAGMA_ONCE)
8 #endif /* ACE_LACKS_PRAGMA_ONCE */
11 #include "ace/Guard_T.h"
12 #include "ace/Log_Category.h"
13 #include "ace/Signal.h"
14 #include "ace/Sig_Handler.h"
15 #include "ace/Thread.h"
16 #include "ace/Timer_Heap.h"
17 #include "ace/OS_NS_errno.h"
18 #include "ace/OS_NS_sys_select.h"
19 #include "ace/OS_NS_sys_stat.h"
22 #include "ace/Recursive_Thread_Mutex.h"
24 #if !defined (__ACE_INLINE__)
25 #include "ace/Select_Reactor_T.inl"
26 #endif /* __ACE_INLINE__ */
28 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
30 ACE_ALLOC_HOOK_DEFINE_Tc(ACE_Select_Reactor_T
)
32 template <class ACE_SELECT_REACTOR_TOKEN
> int
33 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::any_ready
34 (ACE_Select_Reactor_Handle_Set
&wait_set
)
36 ACE_TRACE ("ACE_Select_Reactor_T::any_ready");
38 if (this->mask_signals_
)
40 #if !defined (ACE_WIN32)
41 // Make this call signal safe.
43 #endif /* ACE_WIN32 */
45 return this->any_ready_i (wait_set
);
47 return this->any_ready_i (wait_set
);
50 template <class ACE_SELECT_REACTOR_TOKEN
> int
51 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::any_ready_i
52 (ACE_Select_Reactor_Handle_Set
&wait_set
)
54 ACE_TRACE ("ACE_Select_Reactor_T::any_ready_i");
56 int const number_ready
= this->ready_set_
.rd_mask_
.num_set ()
57 + this->ready_set_
.wr_mask_
.num_set ()
58 + this->ready_set_
.ex_mask_
.num_set ();
60 // number_ready > 0 meaning there are handles in the ready_set
61 // &wait_set != &(this->ready_set_) means that we need to copy
62 // the handles from the ready_set to the wait set because the
63 // wait_set_ doesn't contain all the handles in the ready_set_
64 if (number_ready
> 0 && &wait_set
!= &(this->ready_set_
))
66 wait_set
.rd_mask_
= this->ready_set_
.rd_mask_
;
67 wait_set
.wr_mask_
= this->ready_set_
.wr_mask_
;
68 wait_set
.ex_mask_
= this->ready_set_
.ex_mask_
;
70 this->ready_set_
.rd_mask_
.reset ();
71 this->ready_set_
.wr_mask_
.reset ();
72 this->ready_set_
.ex_mask_
.reset ();
78 template <class ACE_SELECT_REACTOR_TOKEN
> int
79 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::handler_i (int signum
,
80 ACE_Event_Handler
**eh
)
82 ACE_TRACE ("ACE_Select_Reactor_T::handler_i");
83 ACE_Event_Handler
*handler
= this->signal_handler_
->handler (signum
);
92 template <class ACE_SELECT_REACTOR_TOKEN
> bool
93 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::initialized ()
95 ACE_TRACE ("ACE_Select_Reactor_T::initialized");
96 ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN
, ace_mon
, this->token_
, false));
97 return this->initialized_
;
101 template <class ACE_SELECT_REACTOR_TOKEN
> int
102 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::owner (ACE_thread_t tid
,
105 ACE_TRACE ("ACE_Select_Reactor_T::owner");
106 ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN
, ace_mon
, this->token_
, -1));
110 *o_id
= this->owner_
;
118 template <class ACE_SELECT_REACTOR_TOKEN
> int
119 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::owner (ACE_thread_t
*t_id
)
121 ACE_TRACE ("ACE_Select_Reactor_T::owner");
122 ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN
, ace_mon
, this->token_
, -1));
123 *t_id
= this->owner_
;
127 template <class ACE_SELECT_REACTOR_TOKEN
> bool
128 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::restart ()
130 ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN
, ace_mon
, this->token_
, false));
131 return this->restart_
;
134 template <class ACE_SELECT_REACTOR_TOKEN
> bool
135 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::restart (bool r
)
137 ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN
, ace_mon
, this->token_
, false));
138 bool const current_value
= this->restart_
;
140 return current_value
;
143 template <class ACE_SELECT_REACTOR_TOKEN
> void
144 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::requeue_position (int rp
)
146 ACE_TRACE ("ACE_Select_Reactor_T::requeue_position");
147 ACE_MT (ACE_GUARD (ACE_SELECT_REACTOR_TOKEN
, ace_mon
, this->token_
));
148 #if defined (ACE_WIN32)
150 // Must always requeue ourselves "next" on Win32.
151 this->requeue_position_
= 0;
153 this->requeue_position_
= rp
;
154 #endif /* ACE_WIN32 */
157 template <class ACE_SELECT_REACTOR_TOKEN
> int
158 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::requeue_position ()
160 ACE_TRACE ("ACE_Select_Reactor_T::requeue_position");
161 ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN
, ace_mon
, this->token_
, -1));
162 return this->requeue_position_
;
165 template <class ACE_SELECT_REACTOR_TOKEN
> void
166 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::max_notify_iterations (int iterations
)
168 ACE_TRACE ("ACE_Select_Reactor_T::max_notify_iterations");
169 ACE_MT (ACE_GUARD (ACE_SELECT_REACTOR_TOKEN
, ace_mon
, this->token_
));
171 this->notify_handler_
->max_notify_iterations (iterations
);
174 template <class ACE_SELECT_REACTOR_TOKEN
> int
175 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::max_notify_iterations ()
177 ACE_TRACE ("ACE_Select_Reactor_T::max_notify_iterations");
178 ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN
, ace_mon
, this->token_
, -1));
179 return this->notify_handler_
->max_notify_iterations ();
182 // Enqueue ourselves into the list of waiting threads.
183 template <class ACE_SELECT_REACTOR_TOKEN
> void
184 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::renew ()
186 ACE_TRACE ("ACE_Select_Reactor_T::renew");
187 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
188 if (!this->supress_notify_renew ())
189 this->token_
.renew (this->requeue_position_
);
190 #endif /* defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) */
193 template <class ACE_SELECT_REACTOR_TOKEN
> int
194 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::notify (ACE_Event_Handler
*eh
,
195 ACE_Reactor_Mask mask
,
196 ACE_Time_Value
*timeout
)
198 ACE_TRACE ("ACE_Select_Reactor_T::notify");
200 // Pass over both the Event_Handler *and* the mask to allow the
201 // caller to dictate which Event_Handler method the receiver
202 // invokes. Note that this call can timeout.
204 if (this->notify_handler_
)
206 n
= this->notify_handler_
->notify (eh
, mask
, timeout
);
208 return n
== -1 ? -1 : 0;
211 template <class ACE_SELECT_REACTOR_TOKEN
> int
212 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::resume_handler (ACE_HANDLE handle
)
214 ACE_TRACE ("ACE_Select_Reactor_T::resume_handler");
215 ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN
, ace_mon
, this->token_
, -1));
216 return this->resume_i (handle
);
219 template <class ACE_SELECT_REACTOR_TOKEN
> int
220 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::suspend_handler (ACE_HANDLE handle
)
222 ACE_TRACE ("ACE_Select_Reactor_T::suspend_handler");
223 ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN
, ace_mon
, this->token_
, -1));
224 return this->suspend_i (handle
);
227 template <class ACE_SELECT_REACTOR_TOKEN
> int
228 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::suspend_handlers ()
230 ACE_TRACE ("ACE_Select_Reactor_T::suspend_handlers");
231 ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN
, ace_mon
, this->token_
, -1));
233 ACE_Event_Handler
*eh
= 0;
235 for (ACE_Select_Reactor_Handler_Repository_Iterator
iter (&this->handler_rep_
);
239 this->suspend_i (eh
->get_handle ());
245 template <class ACE_SELECT_REACTOR_TOKEN
> int
246 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::resume_handlers ()
248 ACE_TRACE ("ACE_Select_Reactor_T::resume_handlers");
249 ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN
, ace_mon
, this->token_
, -1));
251 ACE_Event_Handler
*eh
= 0;
253 for (ACE_Select_Reactor_Handler_Repository_Iterator
iter (&this->handler_rep_
);
257 this->resume_i (eh
->get_handle ());
263 template <class ACE_SELECT_REACTOR_TOKEN
> int
264 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::register_handler
265 (ACE_Event_Handler
*handler
,
266 ACE_Reactor_Mask mask
)
268 ACE_TRACE ("ACE_Select_Reactor_T::register_handler");
269 ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN
, ace_mon
, this->token_
, -1));
270 return this->register_handler_i (handler
->get_handle (), handler
, mask
);
273 template <class ACE_SELECT_REACTOR_TOKEN
> int
274 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::register_handler
276 ACE_Event_Handler
*handler
,
277 ACE_Reactor_Mask mask
)
279 ACE_TRACE ("ACE_Select_Reactor_T::register_handler");
280 ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN
, ace_mon
, this->token_
, -1));
281 return this->register_handler_i (handle
, handler
, mask
);
284 template <class ACE_SELECT_REACTOR_TOKEN
> int
285 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::register_handler
286 (const ACE_Handle_Set
&handles
,
287 ACE_Event_Handler
*handler
,
288 ACE_Reactor_Mask mask
)
290 ACE_TRACE ("ACE_Select_Reactor_T::register_handler");
291 ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN
, ace_mon
, this->token_
, -1));
292 return this->register_handler_i (handles
, handler
, mask
);
295 template <class ACE_SELECT_REACTOR_TOKEN
> ACE_Event_Handler
*
296 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::find_handler
299 ACE_TRACE ("ACE_Select_Reactor_T::find_handler");
300 ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN
, ace_mon
, this->token_
, 0));
301 return this->find_handler_i (handle
);
304 template <class ACE_SELECT_REACTOR_TOKEN
> int
305 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::handler
307 ACE_Reactor_Mask mask
,
308 ACE_Event_Handler
**handler
)
310 ACE_TRACE ("ACE_Select_Reactor_T::handler");
311 ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN
, ace_mon
, this->token_
, -1));
312 return this->handler_i (handle
, mask
, handler
);
315 template <class ACE_SELECT_REACTOR_TOKEN
> int
316 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::remove_handler
317 (const ACE_Handle_Set
&handles
,
318 ACE_Reactor_Mask mask
)
320 ACE_TRACE ("ACE_Select_Reactor_T::remove_handler");
321 ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN
, ace_mon
, this->token_
, -1));
322 return this->remove_handler_i (handles
, mask
);
325 template <class ACE_SELECT_REACTOR_TOKEN
> int
326 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::remove_handler
327 (ACE_Event_Handler
*handler
,
328 ACE_Reactor_Mask mask
)
330 ACE_TRACE ("ACE_Select_Reactor_T::remove_handler");
331 ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN
, ace_mon
, this->token_
, -1));
332 return this->remove_handler_i (handler
->get_handle (), mask
);
335 template <class ACE_SELECT_REACTOR_TOKEN
> int
336 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::remove_handler
338 ACE_Reactor_Mask mask
)
340 ACE_TRACE ("ACE_Select_Reactor_T::remove_handler");
341 ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN
, ace_mon
, this->token_
, -1));
342 return this->remove_handler_i (handle
, mask
);
345 // Performs operations on the "ready" bits.
347 template <class ACE_SELECT_REACTOR_TOKEN
> int
348 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::ready_ops
350 ACE_Reactor_Mask mask
,
353 ACE_TRACE ("ACE_Select_Reactor_T::ready_ops");
354 ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN
, ace_mon
, this->token_
, -1));
355 return this->bit_ops (handle
,
361 template <class ACE_SELECT_REACTOR_TOKEN
> int
362 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::open
367 int disable_notify_pipe
,
368 ACE_Reactor_Notify
*notify
)
370 ACE_TRACE ("ACE_Select_Reactor_T::open");
371 ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN
, ace_mon
, this->token_
, -1));
373 // Can't initialize ourselves more than once.
374 if (this->initialized_
)
377 this->owner_
= ACE_Thread::self ();
378 this->restart_
= restart
;
379 this->signal_handler_
= sh
;
380 this->timer_queue_
= tq
;
381 this->notify_handler_
= notify
;
385 // Allows the signal handler to be overridden.
386 if (this->signal_handler_
== 0)
388 ACE_NEW_RETURN (this->signal_handler_
,
392 this->delete_signal_handler_
= true;
395 // Allows the timer queue to be overridden.
396 if (result
!= -1 && this->timer_queue_
== 0)
398 ACE_NEW_RETURN (this->timer_queue_
,
402 this->delete_timer_queue_
= true;
405 // Allows the Notify_Handler to be overridden.
406 if (result
!= -1 && this->notify_handler_
== 0)
408 ACE_NEW_RETURN (this->notify_handler_
,
409 ACE_Select_Reactor_Notify
,
412 this->delete_notify_handler_
= true;
415 if (result
!= -1 && this->handler_rep_
.open (size
) == -1)
417 else if (this->notify_handler_
->open (this,
419 disable_notify_pipe
) == -1)
421 ACELIB_ERROR ((LM_ERROR
,
423 ACE_TEXT ("ACE_Select_Reactor_T::open, ")
424 ACE_TEXT ("notification pipe open failed")));
429 // We're all set to go.
430 this->initialized_
= true;
432 // This will close down all the allocated resources properly.
438 template <class ACE_SELECT_REACTOR_TOKEN
> int
439 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::set_sig_handler
440 (ACE_Sig_Handler
*signal_handler
)
442 delete this->signal_handler_
;
443 this->signal_handler_
= signal_handler
;
444 this->delete_signal_handler_
= false;
448 template <class ACE_SELECT_REACTOR_TOKEN
> ACE_Timer_Queue
*
449 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::timer_queue () const
451 return this->timer_queue_
;
454 template <class ACE_SELECT_REACTOR_TOKEN
> int
455 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::timer_queue
456 (ACE_Timer_Queue
*tq
)
458 if (this->delete_timer_queue_
)
460 delete this->timer_queue_
;
462 else if (this->timer_queue_
)
464 this->timer_queue_
->close ();
466 this->timer_queue_
= tq
;
467 this->delete_timer_queue_
= false;
471 template <class ACE_SELECT_REACTOR_TOKEN
>
472 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::ACE_Select_Reactor_T
473 (ACE_Sig_Handler
*sh
,
475 int disable_notify_pipe
,
476 ACE_Reactor_Notify
*notify
,
479 : ACE_Select_Reactor_Impl (mask_signals
)
481 , lock_adapter_ (token_
)
484 ACE_TRACE ("ACE_Select_Reactor_T::ACE_Select_Reactor_T");
486 this->token_
.reactor (*this);
487 // First try to open the Reactor with the hard-coded default.
488 if (this->open (ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::DEFAULT_SIZE
,
495 // The hard-coded default Reactor size failed, so attempt to
496 // determine the size at run-time by checking the process file
497 // descriptor limit on platforms that support this feature.
499 // reset the errno so that subsequent checks are valid
502 // There is no need to deallocate resources from previous open()
503 // call since the open() method deallocates any resources prior
504 // to exiting if an error was encountered.
506 // Set the default reactor size to be the current limit on the
507 // number of file descriptors available to the process. This
508 // size is not necessarily the maximum limit.
509 if (this->open (ACE::max_handles (),
515 ACELIB_ERROR ((LM_ERROR
,
517 ACE_TEXT ("ACE_Select_Reactor_T::open ")
518 ACE_TEXT ("failed inside ")
519 ACE_TEXT ("ACE_Select_Reactor_T::CTOR")));
523 // Initialize ACE_Select_Reactor_T.
525 template <class ACE_SELECT_REACTOR_TOKEN
>
526 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::ACE_Select_Reactor_T
531 int disable_notify_pipe
,
532 ACE_Reactor_Notify
*notify
,
535 : ACE_Select_Reactor_Impl (mask_signals
)
537 , lock_adapter_ (token_
)
540 ACE_TRACE ("ACE_Select_Reactor_T::ACE_Select_Reactor_T");
542 this->token_
.reactor (*this);
543 if (this->open (size
,
549 ACELIB_ERROR ((LM_ERROR
,
551 ACE_TEXT ("ACE_Select_Reactor_T::open ")
552 ACE_TEXT ("failed inside ACE_Select_Reactor_T::CTOR")));
555 // Close down the ACE_Select_Reactor_T instance, detaching any
556 // remaining Event_Handers. This had better be called from the main
557 // event loop thread...
559 template <class ACE_SELECT_REACTOR_TOKEN
> int
560 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::close ()
562 ACE_TRACE ("ACE_Select_Reactor_T::close");
563 ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN
, ace_mon
, this->token_
, -1));
565 if (this->delete_signal_handler_
)
567 delete this->signal_handler_
;
568 this->signal_handler_
= 0;
569 this->delete_signal_handler_
= false;
572 this->handler_rep_
.close ();
574 if (this->delete_timer_queue_
)
576 delete this->timer_queue_
;
577 this->timer_queue_
= 0;
578 this->delete_timer_queue_
= false;
580 else if (this->timer_queue_
)
582 this->timer_queue_
->close ();
583 this->timer_queue_
= 0;
586 if (this->notify_handler_
!= 0)
587 this->notify_handler_
->close ();
589 if (this->delete_notify_handler_
)
591 delete this->notify_handler_
;
592 this->notify_handler_
= 0;
593 this->delete_notify_handler_
= false;
596 this->initialized_
= false;
601 template <class ACE_SELECT_REACTOR_TOKEN
> int
602 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::current_info
603 (ACE_HANDLE
, size_t &)
608 template <class ACE_SELECT_REACTOR_TOKEN
>
609 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::~ACE_Select_Reactor_T ()
611 ACE_TRACE ("ACE_Select_Reactor_T::~ACE_Select_Reactor_T");
615 template <class ACE_SELECT_REACTOR_TOKEN
> int
616 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::remove_handler_i
617 (const ACE_Handle_Set
&handles
,
618 ACE_Reactor_Mask mask
)
620 ACE_TRACE ("ACE_Select_Reactor_T::remove_handler_i");
623 ACE_Handle_Set_Iterator
handle_iter (handles
);
625 while ((h
= handle_iter ()) != ACE_INVALID_HANDLE
)
626 if (this->remove_handler_i (h
, mask
) == -1)
632 template <class ACE_SELECT_REACTOR_TOKEN
> int
633 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::register_handler_i
634 (const ACE_Handle_Set
&handles
,
635 ACE_Event_Handler
*handler
,
636 ACE_Reactor_Mask mask
)
638 ACE_TRACE ("ACE_Select_Reactor_T::register_handler_i");
641 ACE_Handle_Set_Iterator
handle_iter (handles
);
642 while ((h
= handle_iter ()) != ACE_INVALID_HANDLE
)
643 if (this->register_handler_i (h
, handler
, mask
) == -1)
649 template <class ACE_SELECT_REACTOR_TOKEN
> int
650 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::register_handler
651 (const ACE_Sig_Set
&sigset
,
652 ACE_Event_Handler
*new_sh
,
653 ACE_Sig_Action
*new_disp
)
655 ACE_TRACE ("ACE_Select_Reactor_T::register_handler");
660 for (int s
= 1; s
< ACE_NSIG
; ++s
)
661 if ((sigset
.is_member (s
) == 1)
662 && this->signal_handler_
->register_handler (s
,
666 #else /* ACE_NSIG <= 0 */
667 ACE_UNUSED_ARG (sigset
);
668 ACE_UNUSED_ARG (new_sh
);
669 ACE_UNUSED_ARG (new_disp
);
670 #endif /* ACE_NSIG <= 0 */
674 template <class ACE_SELECT_REACTOR_TOKEN
> int
675 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::remove_handler
676 (const ACE_Sig_Set
&sigset
)
678 ACE_TRACE ("ACE_Select_Reactor_T::remove_handler");
682 for (int s
= 1; s
< ACE_NSIG
; ++s
)
683 if ((sigset
.is_member (s
) == 1)
684 && this->signal_handler_
->remove_handler (s
) == -1)
686 #else /* ACE_NSIG <= 0 */
687 ACE_UNUSED_ARG (sigset
);
688 #endif /* ACE_NSIG <= 0 */
693 template <class ACE_SELECT_REACTOR_TOKEN
> int
694 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::cancel_timer (ACE_Event_Handler
*handler
,
695 int dont_call_handle_close
)
697 ACE_TRACE ("ACE_Select_Reactor_T::cancel_timer");
698 ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN
, ace_mon
, this->token_
, -1));
700 if ((this->timer_queue_
!= 0) && (handler
!= 0))
701 return this->timer_queue_
->cancel (handler
, dont_call_handle_close
);
706 template <class ACE_SELECT_REACTOR_TOKEN
> int
707 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::cancel_timer (long timer_id
,
709 int dont_call_handle_close
)
711 ACE_TRACE ("ACE_Select_Reactor_T::cancel_timer");
712 ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN
, ace_mon
, this->token_
, -1));
714 if (this->timer_queue_
!= 0)
715 return this->timer_queue_
->cancel (timer_id
,
717 dont_call_handle_close
);
722 template <class ACE_SELECT_REACTOR_TOKEN
> long
723 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::schedule_timer
724 (ACE_Event_Handler
*handler
,
726 const ACE_Time_Value
&delay_time
,
727 const ACE_Time_Value
&interval
)
729 ACE_TRACE ("ACE_Select_Reactor_T::schedule_timer");
730 ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN
, ace_mon
, this->token_
, -1));
732 if (0 != this->timer_queue_
)
733 return this->timer_queue_
->schedule
736 timer_queue_
->gettimeofday () + delay_time
,
743 template <class ACE_SELECT_REACTOR_TOKEN
> int
744 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::reset_timer_interval
746 const ACE_Time_Value
&interval
)
748 ACE_TRACE ("ACE_Select_Reactor_T::reset_timer_interval");
749 ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN
, ace_mon
, this->token_
, -1));
751 if (0 != this->timer_queue_
)
753 return this->timer_queue_
->reset_interval (timer_id
, interval
);
760 // Main event loop driver that blocks for <max_wait_time> before
761 // returning (will return earlier if I/O or signal events occur).
763 template <class ACE_SELECT_REACTOR_TOKEN
> int
764 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::handle_events
765 (ACE_Time_Value
&max_wait_time
)
767 ACE_TRACE ("ACE_Select_Reactor_T::handle_events");
769 return this->handle_events (&max_wait_time
);
772 template <class ACE_SELECT_REACTOR_TOKEN
> int
773 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::handle_error ()
775 ACE_TRACE ("ACE_Select_Reactor_T::handle_error");
776 #if defined (ACE_LINUX) && defined (ERESTARTNOHAND)
777 int const error
= errno
; // Avoid multiple TSS accesses.
778 if (error
== EINTR
|| error
== ERESTARTNOHAND
)
779 return this->restart_
;
782 return this->restart_
;
783 #endif /* ACE_LINUX && ERESTARTNOHAND */
784 #if defined (__MVS__) || defined (ACE_WIN32) || defined (ACE_VXWORKS)
785 // On MVS Open Edition and Win32, there can be a number of failure
786 // codes on a bad socket, so check_handles on anything other than
787 // EINTR. VxWorks doesn't even bother to always set errno on error
788 // in select (specifically, it doesn't return EBADF for bad FDs).
790 return this->check_handles ();
792 else if (errno
== EBADF
)
793 return this->check_handles ();
796 #endif /* __MVS__ || ACE_WIN32 */
799 template <class ACE_SELECT_REACTOR_TOKEN
> void
800 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::notify_handle
802 ACE_Reactor_Mask mask
,
803 ACE_Handle_Set
&ready_mask
,
804 ACE_Event_Handler
*event_handler
,
807 ACE_TRACE ("ACE_Select_Reactor_T::notify_handle");
808 // Check for removed handlers.
809 if (event_handler
== 0)
812 bool const reference_counting_required
=
813 event_handler
->reference_counting_policy ().value () ==
814 ACE_Event_Handler::Reference_Counting_Policy::ENABLED
;
816 // Call add_reference() if needed.
817 if (reference_counting_required
)
819 event_handler
->add_reference ();
822 int const status
= (event_handler
->*ptmf
) (handle
);
825 this->remove_handler_i (handle
, mask
);
827 ready_mask
.set_bit (handle
);
829 // Call remove_reference() if needed.
830 if (reference_counting_required
)
831 event_handler
->remove_reference ();
834 // Perform GET, CLR, SET, and ADD operations on the select()
837 // GET = 1, Retrieve current value
838 // SET = 2, Set value of bits to new mask (changes the entire mask)
839 // ADD = 3, Bitwise "or" the value into the mask (only changes
841 // CLR = 4 Bitwise "and" the negation of the value out of the mask
842 // (only changes enabled bits)
844 // Returns the original mask.
846 template <class ACE_SELECT_REACTOR_TOKEN
> int
847 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::mask_ops
849 ACE_Reactor_Mask mask
,
852 ACE_TRACE ("ACE_Select_Reactor_T::mask_ops");
853 ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN
, ace_mon
, this->token_
, -1));
855 // If the handle is not suspended, then set the ops on the
856 // <wait_set_>, otherwise set the <suspend_set_>.
858 if (this->is_suspended_i (handle
))
859 return this->bit_ops (handle
, mask
, this->suspend_set_
, ops
);
861 return this->bit_ops (handle
, mask
, this->wait_set_
, ops
);
864 template <class ACE_SELECT_REACTOR_TOKEN
> ACE_Event_Handler
*
865 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::find_handler_i
868 ACE_TRACE ("ACE_Select_Reactor_T::find_handler_i");
870 ACE_Event_Handler
*event_handler
= this->handler_rep_
.find (handle
);
874 event_handler
->add_reference ();
877 return event_handler
;
880 // Must be called with locks held.
882 template <class ACE_SELECT_REACTOR_TOKEN
> int
883 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::handler_i
885 ACE_Reactor_Mask mask
,
886 ACE_Event_Handler
**eh
)
888 ACE_TRACE ("ACE_Select_Reactor_T::handler_i");
889 ACE_Event_Handler
*event_handler
= this->handler_rep_
.find (handle
);
891 if (event_handler
== 0)
895 if ((ACE_BIT_ENABLED (mask
, ACE_Event_Handler::READ_MASK
)
896 || ACE_BIT_ENABLED (mask
, ACE_Event_Handler::ACCEPT_MASK
))
897 && this->wait_set_
.rd_mask_
.is_set (handle
) == 0)
899 if (ACE_BIT_ENABLED (mask
, ACE_Event_Handler::WRITE_MASK
)
900 && this->wait_set_
.wr_mask_
.is_set (handle
) == 0)
902 if (ACE_BIT_ENABLED (mask
, ACE_Event_Handler::EXCEPT_MASK
)
903 && this->wait_set_
.ex_mask_
.is_set (handle
) == 0)
910 event_handler
->add_reference ();
916 // Must be called with locks held
918 template <class ACE_SELECT_REACTOR_TOKEN
> int
919 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::resume_i (ACE_HANDLE handle
)
921 ACE_TRACE ("ACE_Select_Reactor_T::resume_i");
922 if (this->handler_rep_
.find (handle
) == 0)
925 if (this->suspend_set_
.rd_mask_
.is_set (handle
))
927 this->wait_set_
.rd_mask_
.set_bit (handle
);
928 this->suspend_set_
.rd_mask_
.clr_bit (handle
);
930 if (this->suspend_set_
.wr_mask_
.is_set (handle
))
932 this->wait_set_
.wr_mask_
.set_bit (handle
);
933 this->suspend_set_
.wr_mask_
.clr_bit (handle
);
935 if (this->suspend_set_
.ex_mask_
.is_set (handle
))
937 this->wait_set_
.ex_mask_
.set_bit (handle
);
938 this->suspend_set_
.ex_mask_
.clr_bit (handle
);
943 // Must be called with locks held
945 template <class ACE_SELECT_REACTOR_TOKEN
> int
946 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::suspend_i (ACE_HANDLE handle
)
948 ACE_TRACE ("ACE_Select_Reactor_T::suspend_i");
949 if (this->handler_rep_
.find (handle
) == 0)
952 if (this->wait_set_
.rd_mask_
.is_set (handle
))
954 this->suspend_set_
.rd_mask_
.set_bit (handle
);
955 this->wait_set_
.rd_mask_
.clr_bit (handle
);
957 if (this->wait_set_
.wr_mask_
.is_set (handle
))
959 this->suspend_set_
.wr_mask_
.set_bit (handle
);
960 this->wait_set_
.wr_mask_
.clr_bit (handle
);
962 if (this->wait_set_
.ex_mask_
.is_set (handle
))
964 this->suspend_set_
.ex_mask_
.set_bit (handle
);
965 this->wait_set_
.ex_mask_
.clr_bit (handle
);
968 // Kobi: we need to remove that handle from the
969 // dispatch set as well. We use that function with all the relevant
970 // masks - rd/wr/ex - all the mask. it is completely suspended
971 this->clear_dispatch_mask (handle
, ACE_Event_Handler::RWE_MASK
);
975 // Must be called with locks held
977 template <class ACE_SELECT_REACTOR_TOKEN
> int
978 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::is_suspended_i (ACE_HANDLE handle
)
980 ACE_TRACE ("ACE_Select_Reactor_T::is_suspended_i");
981 if (this->handler_rep_
.find (handle
) == 0)
984 return this->suspend_set_
.rd_mask_
.is_set (handle
) ||
985 this->suspend_set_
.wr_mask_
.is_set (handle
) ||
986 this->suspend_set_
.ex_mask_
.is_set (handle
);
989 // Must be called with locks held
991 template <class ACE_SELECT_REACTOR_TOKEN
> int
992 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::register_handler_i
994 ACE_Event_Handler
*event_handler
,
995 ACE_Reactor_Mask mask
)
997 ACE_TRACE ("ACE_Select_Reactor_T::register_handler_i");
999 // Insert the <handle, event_handle> tuple into the Handler
1001 return this->handler_rep_
.bind (handle
, event_handler
, mask
);
1004 template <class ACE_SELECT_REACTOR_TOKEN
> int
1005 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::remove_handler_i
1007 ACE_Reactor_Mask mask
)
1009 ACE_TRACE ("ACE_Select_Reactor_T::remove_handler_i");
1011 // Unbind this handle.
1012 return this->handler_rep_
.unbind (handle
, mask
);
1015 template <class ACE_SELECT_REACTOR_TOKEN
> int
1016 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::work_pending
1017 (const ACE_Time_Value
&max_wait_time
)
1019 ACE_TRACE ("ACE_Select_Reactor_T::work_pending");
1021 ACE_Time_Value
mwt (max_wait_time
);
1022 ACE_MT (ACE_Countdown_Time
countdown (&mwt
));
1024 ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN
,
1029 if (this->deactivated_
)
1032 // Update the countdown to reflect time waiting for the mutex.
1033 ACE_MT (countdown
.update ());
1035 ACE_Time_Value
timer_buf (0);
1036 ACE_Time_Value
*this_timeout
=
1037 this->timer_queue_
->calculate_timeout (&mwt
, &timer_buf
);
1039 // Check if we have timers to fire.
1040 bool const timers_pending
=
1041 (this_timeout
!= 0 && *this_timeout
!= mwt
? true : false);
1044 // This arg is ignored on Windows and causes pointer truncation
1045 // warnings on 64-bit compiles.
1046 int const width
= 0;
1048 int const width
= this->handler_rep_
.max_handlep1 ();
1049 #endif /* ACE_WIN32 */
1051 ACE_Select_Reactor_Handle_Set fd_set
;
1052 fd_set
.rd_mask_
= this->wait_set_
.rd_mask_
;
1053 fd_set
.wr_mask_
= this->wait_set_
.wr_mask_
;
1054 fd_set
.ex_mask_
= this->wait_set_
.ex_mask_
;
1056 int const nfds
= ACE_OS::select (width
,
1062 // If timers are pending, override any timeout from the select()
1064 return (nfds
== 0 && timers_pending
? 1 : nfds
);
1067 // Must be called with lock held.
1069 template <class ACE_SELECT_REACTOR_TOKEN
> int
1070 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::wait_for_multiple_events
1071 (ACE_Select_Reactor_Handle_Set
&dispatch_set
,
1072 ACE_Time_Value
*max_wait_time
)
1074 ACE_TRACE ("ACE_Select_Reactor_T::wait_for_multiple_events");
1075 ACE_Time_Value
timer_buf (0);
1076 ACE_Time_Value
*this_timeout
= 0;
1078 int number_of_active_handles
= this->any_ready (dispatch_set
);
1080 // If there are any bits enabled in the <ready_set_> then we'll
1081 // handle those first, otherwise we'll block in <select>.
1083 if (number_of_active_handles
== 0)
1087 if (this->timer_queue_
== 0)
1091 this->timer_queue_
->calculate_timeout (max_wait_time
,
1094 // This arg is ignored on Windows and causes pointer
1095 // truncation warnings on 64-bit compiles.
1096 int const width
= 0;
1098 int const width
= this->handler_rep_
.max_handlep1 ();
1099 #endif /* ACE_WIN32 */
1101 dispatch_set
.rd_mask_
= this->wait_set_
.rd_mask_
;
1102 dispatch_set
.wr_mask_
= this->wait_set_
.wr_mask_
;
1103 dispatch_set
.ex_mask_
= this->wait_set_
.ex_mask_
;
1104 number_of_active_handles
= ACE_OS::select (width
,
1105 dispatch_set
.rd_mask_
,
1106 dispatch_set
.wr_mask_
,
1107 dispatch_set
.ex_mask_
,
1110 while (number_of_active_handles
== -1 && this->handle_error () > 0);
1112 if (number_of_active_handles
> 0)
1114 #if !defined (ACE_WIN32)
1115 // Resynchronize the fd_sets so their "max" is set properly.
1116 dispatch_set
.rd_mask_
.sync (this->handler_rep_
.max_handlep1 ());
1117 dispatch_set
.wr_mask_
.sync (this->handler_rep_
.max_handlep1 ());
1118 dispatch_set
.ex_mask_
.sync (this->handler_rep_
.max_handlep1 ());
1119 #endif /* ACE_WIN32 */
1121 else if (number_of_active_handles
== -1)
1123 // Normally, select() will reset the bits in dispatch_set
1124 // so that only those filed descriptors that are ready will
1125 // have bits set. However, when an error occurs, the bit
1126 // set remains as it was when the select call was first made.
1127 // Thus, we now have a dispatch_set that has every file
1128 // descriptor that was originally waited for, which is not
1129 // correct. We must clear all the bit sets because we
1130 // have no idea if any of the file descriptors is ready.
1132 // NOTE: We dont have a test case to reproduce this
1133 // problem. But pleae dont ignore this and remove it off.
1134 dispatch_set
.rd_mask_
.reset ();
1135 dispatch_set
.wr_mask_
.reset ();
1136 dispatch_set
.ex_mask_
.reset ();
1140 // Return the number of events to dispatch.
1141 return number_of_active_handles
;
1144 template <class ACE_SELECT_REACTOR_TOKEN
> int
1145 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::dispatch_timer_handlers
1146 (int &number_of_handlers_dispatched
)
1148 number_of_handlers_dispatched
+= this->timer_queue_
->expire ();
1153 template <class ACE_SELECT_REACTOR_TOKEN
> int
1154 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::dispatch_notification_handlers
1155 (ACE_Select_Reactor_Handle_Set
&dispatch_set
,
1156 int &number_of_active_handles
,
1157 int &number_of_handlers_dispatched
)
1159 // Check to see if the ACE_HANDLE associated with the
1160 // Select_Reactor's notify hook is enabled. If so, it means that
1161 // one or more other threads are trying to update the
1162 // ACE_Select_Reactor_T's internal tables or the notify pipe is
1163 // enabled. We'll handle all these threads and notifications, and
1164 // then break out to continue the event loop.
1166 this->notify_handler_
->dispatch_notifications (number_of_active_handles
,
1167 dispatch_set
.rd_mask_
);
1173 number_of_handlers_dispatched
+= n
;
1174 number_of_active_handles
-= n
;
1177 // Same as dispatch_timer_handlers
1178 // No need to do anything with the state changed. That is because
1179 // unbind already handles the case where someone unregister some
1180 // kind of handle and unbind it. (::unbind calls the function
1181 // state_changed () to reflect ant change with that)
1182 // return this->state_changed_ ? -1 : 0;
1186 template <class ACE_SELECT_REACTOR_TOKEN
> int
1187 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::dispatch_io_set
1188 (int number_of_active_handles
,
1189 int &number_of_handlers_dispatched
,
1191 ACE_Handle_Set
&dispatch_mask
,
1192 ACE_Handle_Set
&ready_mask
,
1193 ACE_EH_PTMF callback
)
1195 ACE_TRACE ("ACE_Select_Reactor_T::dispatch_io_set");
1198 ACE_Handle_Set_Iterator
handle_iter (dispatch_mask
);
1200 while ((handle
= handle_iter ()) != ACE_INVALID_HANDLE
&&
1201 number_of_handlers_dispatched
< number_of_active_handles
)
1203 ++number_of_handlers_dispatched
;
1205 this->notify_handle (handle
,
1208 this->handler_rep_
.find (handle
),
1211 // clear the bit from that dispatch mask,
1212 // so when we need to restart the iteration (rebuilding the iterator...)
1213 // we will not dispatch the already dispatched handlers
1214 this->clear_dispatch_mask (handle
, mask
);
1216 if (this->state_changed_
)
1218 handle_iter
.reset_state ();
1219 this->state_changed_
= false;
1226 template <class ACE_SELECT_REACTOR_TOKEN
> int
1227 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::dispatch_io_handlers
1228 (ACE_Select_Reactor_Handle_Set
&dispatch_set
,
1229 int &number_of_active_handles
,
1230 int &number_of_handlers_dispatched
)
1232 ACE_TRACE ("ACE_Select_Reactor_T::dispatch_io_handlers");
1234 // Handle output events (this code needs to come first to handle the
1235 // obscure case of piggy-backed data coming along with the final
1236 // handshake message of a nonblocking connection).
1238 if (this->dispatch_io_set (number_of_active_handles
,
1239 number_of_handlers_dispatched
,
1240 ACE_Event_Handler::WRITE_MASK
,
1241 dispatch_set
.wr_mask_
,
1242 this->ready_set_
.wr_mask_
,
1243 &ACE_Event_Handler::handle_output
) == -1)
1245 number_of_active_handles
-= number_of_handlers_dispatched
;
1249 // ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_Select_Reactor_T::dispatch - EXCEPT\n")));
1250 if (this->dispatch_io_set (number_of_active_handles
,
1251 number_of_handlers_dispatched
,
1252 ACE_Event_Handler::EXCEPT_MASK
,
1253 dispatch_set
.ex_mask_
,
1254 this->ready_set_
.ex_mask_
,
1255 &ACE_Event_Handler::handle_exception
) == -1)
1257 number_of_active_handles
-= number_of_handlers_dispatched
;
1261 // ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_Select_Reactor_T::dispatch - READ\n")));
1262 if (this->dispatch_io_set (number_of_active_handles
,
1263 number_of_handlers_dispatched
,
1264 ACE_Event_Handler::READ_MASK
,
1265 dispatch_set
.rd_mask_
,
1266 this->ready_set_
.rd_mask_
,
1267 &ACE_Event_Handler::handle_input
) == -1)
1269 number_of_active_handles
-= number_of_handlers_dispatched
;
1273 number_of_active_handles
-= number_of_handlers_dispatched
;
1277 template <class ACE_SELECT_REACTOR_TOKEN
> int
1278 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::dispatch
1279 (int active_handle_count
,
1280 ACE_Select_Reactor_Handle_Set
&dispatch_set
)
1282 ACE_TRACE ("ACE_Select_Reactor_T::dispatch");
1284 int io_handlers_dispatched
= 0;
1285 int other_handlers_dispatched
= 0;
1286 int signal_occurred
= 0;
1287 // The following do/while loop keeps dispatching as long as there
1288 // are still active handles. Note that the only way we should ever
1289 // iterate more than once through this loop is if signals occur
1290 // while we're dispatching other handlers.
1294 // We expect that the loop will decrease the number of active
1295 // handles in each iteration. If it does not, then something is
1296 // inconsistent in the state of the Reactor and we should avoid
1297 // the loop. Please read the comments on bug 2540 for more
1299 int initial_handle_count
= active_handle_count
;
1301 // Note that we keep track of changes to our state. If any of
1302 // the dispatch_*() methods below return -1 it means that the
1303 // <wait_set_> state has changed as the result of an
1304 // <ACE_Event_Handler> being dispatched. This means that we
1305 // need to bail out and rerun the select() loop since our
1306 // existing notion of handles in <dispatch_set> may no longer be
1309 // In the beginning, our state starts out unchanged. After
1310 // every iteration (i.e., due to signals), our state starts out
1313 this->state_changed_
= false;
1315 // Perform the Template Method for dispatching all the handlers.
1317 // First check for interrupts.
1318 if (active_handle_count
== -1)
1320 // Bail out -- we got here since <select> was interrupted.
1321 if (ACE_Sig_Handler::sig_pending () != 0)
1323 ACE_Sig_Handler::sig_pending (0);
1325 // If any HANDLES in the <ready_set_> are activated as a
1326 // result of signals they should be dispatched since
1327 // they may be time critical...
1328 active_handle_count
= this->any_ready (dispatch_set
);
1330 // Record the fact that the Reactor has dispatched a
1331 // handle_signal() method. We need this to return the
1332 // appropriate count below.
1333 signal_occurred
= 1;
1339 // Handle timers early since they may have higher latency
1340 // constraints than I/O handlers. Ideally, the order of
1341 // dispatching should be a strategy...
1342 else if (this->dispatch_timer_handlers (other_handlers_dispatched
) == -1)
1343 // State has changed or timer queue has failed, exit loop.
1346 // Check to see if there are no more I/O handles left to
1347 // dispatch AFTER we've handled the timers...
1348 else if (active_handle_count
== 0)
1349 return io_handlers_dispatched
1350 + other_handlers_dispatched
1353 // Next dispatch the notification handlers (if there are any to
1354 // dispatch). These are required to handle multi-threads that
1355 // are trying to update the <Reactor>.
1357 else if (this->dispatch_notification_handlers
1359 active_handle_count
,
1360 other_handlers_dispatched
) == -1)
1361 // State has changed or a serious failure has occurred, so exit
1365 // Finally, dispatch the I/O handlers.
1366 else if (this->dispatch_io_handlers
1368 active_handle_count
,
1369 io_handlers_dispatched
) == -1)
1370 // State has changed, so exit loop.
1373 // if state changed, we need to re-eval active_handle_count,
1374 // so we will not end with an endless loop
1375 if (initial_handle_count
== active_handle_count
1376 || this->state_changed_
)
1378 active_handle_count
= this->any_ready (dispatch_set
);
1381 while (active_handle_count
> 0);
1383 return io_handlers_dispatched
+ other_handlers_dispatched
+ signal_occurred
;
1386 template <class ACE_SELECT_REACTOR_TOKEN
> int
1387 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::release_token ()
1389 #if defined (ACE_WIN32)
1390 this->token_
.release ();
1391 return (int) EXCEPTION_CONTINUE_SEARCH
;
1394 #endif /* ACE_WIN32 */
1397 template <class ACE_SELECT_REACTOR_TOKEN
> int
1398 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::handle_events
1399 (ACE_Time_Value
*max_wait_time
)
1401 ACE_TRACE ("ACE_Select_Reactor_T::handle_events");
1403 // Stash the current time -- the destructor of this object will
1404 // automatically compute how much time elapsed since this method was
1406 ACE_Countdown_Time
countdown (max_wait_time
);
1408 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
1410 ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN
, ace_mon
, this->token_
, -1);
1412 if (ACE_OS::thr_equal (ACE_Thread::self (), this->owner_
) == 0)
1417 if (this->deactivated_
)
1423 // Update the countdown to reflect time waiting for the mutex.
1424 countdown
.update ();
1426 if (this->deactivated_
)
1431 #endif /* ACE_MT_SAFE */
1433 return this->handle_events_i (max_wait_time
);
1436 template <class ACE_SELECT_REACTOR_TOKEN
> int
1437 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::handle_events_i
1438 (ACE_Time_Value
*max_wait_time
)
1444 // We use the data member dispatch_set_ as the current dispatch
1447 // We need to start from a clean dispatch_set
1448 this->dispatch_set_
.rd_mask_
.reset ();
1449 this->dispatch_set_
.wr_mask_
.reset ();
1450 this->dispatch_set_
.ex_mask_
.reset ();
1452 int number_of_active_handles
=
1453 this->wait_for_multiple_events (this->dispatch_set_
,
1457 this->dispatch (number_of_active_handles
,
1458 this->dispatch_set_
);
1460 ACE_SEH_EXCEPT (this->release_token ())
1462 // As it stands now, we catch and then rethrow all Win32
1463 // structured exceptions so that we can make sure to release the
1464 // <token_> lock correctly.
1470 template <class ACE_SELECT_REACTOR_TOKEN
> int
1471 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::check_handles ()
1473 ACE_TRACE ("ACE_Select_Reactor_T::check_handles");
1475 #if defined (ACE_WIN32) || defined (__MVS__) || defined (ACE_VXWORKS)
1476 ACE_Time_Value time_poll
= ACE_Time_Value::zero
;
1477 ACE_Handle_Set rd_mask
;
1478 #endif /* ACE_WIN32 || MVS || ACE_VXWORKS */
1483 * It's easier to run through the handler repository iterator, but that
1484 * misses handles that are registered on a handler that doesn't implement
1485 * get_handle(). So, build a handle set that's the union of the three
1486 * wait_sets (rd, wrt, ex) and run through that. Bad handles get cleared
1490 ACE_Handle_Set
check_set (this->wait_set_
.rd_mask_
);
1491 ACE_Handle_Set_Iterator
wr_iter (this->wait_set_
.wr_mask_
);
1492 while ((h
= wr_iter ()) != ACE_INVALID_HANDLE
)
1493 check_set
.set_bit (h
);
1494 ACE_Handle_Set_Iterator
ex_iter (this->wait_set_
.ex_mask_
);
1495 while ((h
= ex_iter ()) != ACE_INVALID_HANDLE
)
1496 check_set
.set_bit (h
);
1498 ACE_Handle_Set_Iterator
check_iter (check_set
);
1499 while ((h
= check_iter ()) != ACE_INVALID_HANDLE
)
1501 #if defined (ACE_WIN32) || defined (__MVS__) || defined (ACE_VXWORKS)
1502 // Win32 needs to do the check this way because fstat won't work on
1503 // a socket handle. MVS Open Edition needs to do it this way because,
1504 // even though the docs say to check a handle with either select or
1505 // fstat, the fstat method always says the handle is ok.
1506 // pSOS needs to do it this way because file handles and socket handles
1507 // are maintained by separate pieces of the system. VxWorks needs the select
1508 // variant since fstat always returns an error on socket FDs.
1509 rd_mask
.set_bit (h
);
1511 # if defined (ACE_WIN32)
1512 // This arg is ignored on Windows and causes pointer truncation
1513 // warnings on 64-bit compiles.
1514 int select_width
= 0;
1516 int select_width
= int (h
) + 1;
1517 # endif /* ACE_WIN32 */
1519 if (ACE_OS::select (select_width
,
1524 this->remove_handler_i (h
, ACE_Event_Handler::ALL_EVENTS_MASK
);
1525 this->wait_set_
.rd_mask_
.clr_bit (h
);
1526 this->wait_set_
.wr_mask_
.clr_bit (h
);
1527 this->wait_set_
.ex_mask_
.clr_bit (h
);
1529 rd_mask
.clr_bit (h
);
1530 #else /* !ACE_WIN32 && !MVS && !VXWORKS */
1533 if (ACE_OS::fstat (h
, &temp
) == -1)
1536 this->remove_handler_i (h
, ACE_Event_Handler::ALL_EVENTS_MASK
);
1538 #endif /* ACE_WIN32 || MVS */
1544 template <class ACE_SELECT_REACTOR_TOKEN
> void
1545 ACE_Select_Reactor_T
<ACE_SELECT_REACTOR_TOKEN
>::dump () const
1547 #if defined (ACE_HAS_DUMP)
1548 ACE_TRACE ("ACE_Select_Reactor_T::dump");
1550 ACELIB_DEBUG ((LM_DEBUG
, ACE_BEGIN_DUMP
, this));
1552 this->timer_queue_
->dump ();
1553 this->handler_rep_
.dump ();
1554 this->signal_handler_
->dump ();
1555 ACELIB_DEBUG ((LM_DEBUG
,
1556 ACE_TEXT ("delete_signal_handler_ = %d\n"),
1557 this->delete_signal_handler_
));
1561 for (ACE_Handle_Set_Iterator
handle_iter_wr (this->wait_set_
.wr_mask_
);
1562 (h
= handle_iter_wr ()) != ACE_INVALID_HANDLE
;)
1563 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("write_handle = %d\n"), h
));
1565 for (ACE_Handle_Set_Iterator
handle_iter_rd (this->wait_set_
.rd_mask_
);
1566 (h
= handle_iter_rd ()) != ACE_INVALID_HANDLE
;)
1567 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("read_handle = %d\n"), h
));
1569 for (ACE_Handle_Set_Iterator
handle_iter_ex (this->wait_set_
.ex_mask_
);
1570 (h
= handle_iter_ex ()) != ACE_INVALID_HANDLE
;)
1571 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("except_handle = %d\n"), h
));
1573 for (ACE_Handle_Set_Iterator
handle_iter_wr_ready (this->ready_set_
.wr_mask_
);
1574 (h
= handle_iter_wr_ready ()) != ACE_INVALID_HANDLE
;)
1575 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("write_handle_ready = %d\n"), h
));
1577 for (ACE_Handle_Set_Iterator
handle_iter_rd_ready (this->ready_set_
.rd_mask_
);
1578 (h
= handle_iter_rd_ready ()) != ACE_INVALID_HANDLE
;)
1579 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("read_handle_ready = %d\n"), h
));
1581 for (ACE_Handle_Set_Iterator
handle_iter_ex_ready (this->ready_set_
.ex_mask_
);
1582 (h
= handle_iter_ex_ready ()) != ACE_INVALID_HANDLE
;)
1583 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("except_handle_ready = %d\n"), h
));
1585 for (ACE_Handle_Set_Iterator
handle_iter_su_ready (this->suspend_set_
.wr_mask_
);
1586 (h
= handle_iter_su_ready ()) != ACE_INVALID_HANDLE
;)
1587 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("write_handle_suspend = %d\n"), h
));
1589 for (ACE_Handle_Set_Iterator
handle_iter_su_ready (this->suspend_set_
.rd_mask_
);
1590 (h
= handle_iter_su_ready ()) != ACE_INVALID_HANDLE
;)
1591 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("read_handle_suspend = %d\n"), h
));
1593 for (ACE_Handle_Set_Iterator
handle_iter_su_ready (this->suspend_set_
.ex_mask_
);
1594 (h
= handle_iter_su_ready ()) != ACE_INVALID_HANDLE
;)
1595 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("except_handle_suspend = %d\n"), h
));
1597 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("restart_ = %d\n"), this->restart_
));
1598 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("requeue_position_ = %d\n"), this->requeue_position_
));
1599 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("initialized_ = %d\n"), this->initialized_
));
1600 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("owner_ = %d\n"), this->owner_
));
1602 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
1603 this->notify_handler_
->dump ();
1604 this->token_
.dump ();
1605 #endif /* ACE_MT_SAFE */
1607 ACELIB_DEBUG ((LM_DEBUG
, ACE_END_DUMP
));
1608 #endif /* ACE_HAS_DUMP */
1611 ACE_END_VERSIONED_NAMESPACE_DECL
1613 #endif /* ACE_SELECT_REACTOR_T_CPP */