1 #include "ace/OS_NS_errno.h"
2 #include "ace/Dev_Poll_Reactor.h"
3 #include "ace/Signal.h"
4 #include "ace/Sig_Handler.h"
5 #include "ace/Flag_Manip.h"
7 #if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL)
9 # include "ace/OS_NS_unistd.h"
10 # include "ace/OS_NS_fcntl.h"
11 # include "ace/OS_NS_stropts.h"
13 # if defined (ACE_HAS_DEV_POLL)
14 # if defined (ACE_LINUX)
15 # include /**/ <linux/devpoll.h>
16 # elif defined (HPUX_VERS) && HPUX_VERS < 1123
17 # include /**/ <devpoll.h>
19 # include /**/ <sys/devpoll.h>
20 # endif /* ACE_LINUX */
21 # endif /* ACE_HAS_DEV_POLL */
23 #if !defined (__ACE_INLINE__)
24 # include "ace/Dev_Poll_Reactor.inl"
25 #endif /* __ACE_INLINE__ */
28 #include "ace/Handle_Set.h"
29 #include "ace/Reactor.h"
30 #include "ace/Timer_Heap.h"
31 #include "ace/Timer_Queue.h"
33 #include "ace/Reverse_Lock_T.h"
34 #include "ace/Recursive_Thread_Mutex.h"
35 #include "ace/Null_Mutex.h"
36 #include "ace/os_include/os_poll.h"
37 #include "ace/OS_NS_sys_mman.h"
38 #include "ace/Guard_T.h"
39 #include "ace/OS_NS_string.h"
40 #include "ace/OS_NS_sys_time.h"
41 #include "ace/Functor_T.h"
43 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
45 ACE_ALLOC_HOOK_DEFINE(ACE_Dev_Poll_Reactor
)
46 ACE_ALLOC_HOOK_DEFINE(ACE_Dev_Poll_Reactor::Event_Tuple
)
47 ACE_ALLOC_HOOK_DEFINE(ACE_Dev_Poll_Reactor_Notify
)
49 ACE_Dev_Poll_Reactor_Notify::ACE_Dev_Poll_Reactor_Notify (void)
51 , notification_pipe_ ()
52 , max_notify_iterations_ (-1)
53 #if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE)
54 , notification_queue_ ()
55 #endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */
60 ACE_Dev_Poll_Reactor_Notify::open (ACE_Reactor_Impl
*r
,
61 ACE_Timer_Queue
* /* timer_queue */,
62 int disable_notify_pipe
)
64 ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::open");
66 if (disable_notify_pipe
== 0)
68 this->dp_reactor_
= dynamic_cast<ACE_Dev_Poll_Reactor
*> (r
);
70 if (this->dp_reactor_
== 0)
76 if (this->notification_pipe_
.open () == -1)
79 #if defined (F_SETFD) && !defined (ACE_LACKS_FCNTL)
81 if (ACE_OS::fcntl (this->notification_pipe_
.read_handle (), F_SETFD
, 1) == -1)
85 if (ACE_OS::fcntl (this->notification_pipe_
.write_handle (), F_SETFD
, 1) == -1)
91 #if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE)
92 if (notification_queue_
.open () == -1)
97 if (ACE::set_flags (this->notification_pipe_
.write_handle (),
100 #endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */
102 // Set the read handle into non-blocking mode since we need to
103 // perform a "speculative" read when determining if there are
104 // notifications to dispatch.
105 if (ACE::set_flags (this->notification_pipe_
.read_handle (),
114 ACE_Dev_Poll_Reactor_Notify::close (void)
116 ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::close");
118 #if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE)
119 notification_queue_
.reset ();
120 #endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */
122 return this->notification_pipe_
.close ();
126 ACE_Dev_Poll_Reactor_Notify::notify (ACE_Event_Handler
*eh
,
127 ACE_Reactor_Mask mask
,
128 ACE_Time_Value
*timeout
)
130 ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::notify");
132 // Just consider this method a "no-op" if there's no
133 // ACE_Dev_Poll_Reactor configured.
134 if (this->dp_reactor_
== 0)
137 ACE_Notification_Buffer
buffer (eh
, mask
);
139 #if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE)
140 ACE_UNUSED_ARG (timeout
);
141 ACE_Dev_Poll_Handler_Guard
eh_guard (eh
);
143 // When using the queue, always try to write to the notify pipe. If it
144 // fills up, ignore it safely because the already-written bytes will
145 // eventually cause the notify handler to be dispatched.
146 if (-1 == this->notification_queue_
.push_new_notification (buffer
))
147 return -1; // Also decrement eh's reference count
149 // The notification has been queued, so it will be delivered at some
150 // point (and may have been already); release the refcnt guard.
153 // Now pop the pipe to force the callback for dispatching when ready. If
154 // the send fails due to a full pipe, don't fail - assume the already-sent
155 // pipe bytes will cause the entire notification queue to be processed.
156 // Note that we don't need a timeout since the pipe is already in
157 // nonblocking mode and all we want is one attempt.
158 ssize_t n
= ACE::send (this->notification_pipe_
.write_handle (),
160 1); // Only need one byte to pop the pipe
161 if (n
== -1 && (errno
!= EAGAIN
))
167 ACE_Dev_Poll_Handler_Guard
eh_guard (eh
);
169 ssize_t n
= ACE::send (this->notification_pipe_
.write_handle (),
179 #endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */
183 ACE_Dev_Poll_Reactor_Notify::dispatch_notifications (
184 int & /* number_of_active_handles */,
185 ACE_Handle_Set
& /* rd_mask */)
187 ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::dispatch_notifications");
189 // This method is unimplemented in the ACE_Dev_Poll_Reactor.
190 // Instead, the notification handler is invoked as part of the IO
191 // event set. Doing so alters the some documented semantics that
192 // state that the notifications are handled before IO events.
193 // Enforcing such semantics does not appear to be beneficial, and
194 // also serves to slow down event dispatching particularly with this
195 // ACE_Dev_Poll_Reactor.
197 ACE_NOTSUP_RETURN (-1);
201 ACE_Dev_Poll_Reactor_Notify::read_notify_pipe (ACE_HANDLE handle
,
202 ACE_Notification_Buffer
&buffer
)
204 ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::read_notify_pipe");
206 // This is a (non-blocking) "speculative" read, i.e., we attempt to
207 // read even if no event was polled on the read handle. A
208 // speculative read is necessary since notifications must be
209 // dispatched before IO events. We can avoid the speculative read
210 // by "walking" the array of pollfd structures returned from
211 // `/dev/poll' or `/dev/epoll' but that is potentially much more
212 // expensive than simply checking for an EWOULDBLOCK.
216 #if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE)
217 // The idea in the queued case is to be sure we never end up with a notify
218 // queued but no byte in the pipe. If that happens, the notify won't be
219 // dispatched. So always try to empty the pipe, read the queue, then put
220 // a byte in if needed. The notify() method is enqueueing then writing the
221 // pipe, so be sure to do it in the reverse order here to avoid a race
222 // between removing the last notification from the queue and the notify
223 // side writing its byte.
227 (void)ACE::recv (handle
, read_p
, to_read
);
229 bool more_messages_queued
= false;
230 ACE_Notification_Buffer next
;
234 result
= notification_queue_
.pop_next_notification (buffer
,
235 more_messages_queued
,
238 if (result
<= 0) // Nothing dequeued or error
241 // If it's just a wake-up, toss it and see if there's anything else.
246 // If there are more messages, ensure there's a byte in the pipe
247 // in case the notification limit stops dequeuing notifies before
248 // emptying the queue.
249 if (more_messages_queued
)
250 (void) ACE::send (this->notification_pipe_
.write_handle (),
252 1); /* one byte is enough */
255 to_read
= sizeof buffer
;
256 read_p
= (char *)&buffer
;
258 ssize_t n
= ACE::recv (handle
, read_p
, to_read
);
262 // Check to see if we've got a short read.
263 if (static_cast<size_t> (n
) != to_read
)
265 size_t remainder
= to_read
- n
;
267 // If so, try to recover by reading the remainder. If this
268 // doesn't work we're in big trouble since the input stream
269 // won't be aligned correctly. I'm not sure quite what to
270 // do at this point. It's probably best just to return -1.
271 if (ACE::recv (handle
, &read_p
[n
], remainder
) <= 0)
278 // Return -1 if things have gone seriously wrong.
279 if (n
<= 0 && (errno
!= EWOULDBLOCK
&& errno
!= EAGAIN
))
283 #endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */
288 ACE_Dev_Poll_Reactor_Notify::handle_input (ACE_HANDLE
/*handle*/)
290 ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::handle_input");
291 ACELIB_ERROR_RETURN ((LM_ERROR
, ACE_TEXT ("SHOULD NOT BE HERE.\n")), -1);
295 ACE_Dev_Poll_Reactor_Notify::notify_handle (void)
297 ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::notify_handle");
299 return this->notification_pipe_
.read_handle ();
303 ACE_Dev_Poll_Reactor_Notify::is_dispatchable (ACE_Notification_Buffer
&)
305 ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::is_dispatchable");
307 ACE_NOTSUP_RETURN (-1);
311 ACE_Dev_Poll_Reactor_Notify::dispatch_notify (ACE_Notification_Buffer
&buffer
)
313 ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::dispatch_notify");
315 // If eh == 0 then another thread is unblocking the
316 // ACE_Dev_Poll_Reactor to update the ACE_Dev_Poll_Reactor's
317 // internal structures. Otherwise, we need to dispatch the
318 // appropriate handle_* method on the ACE_Event_Handler
319 // pointer we've been passed.
324 // Guard the handler's refcount. Recall that when the notify
325 // was queued, the refcount was incremented, so it need not be
326 // now. The guard insures that it is decremented properly.
327 ACE_Dev_Poll_Handler_Guard
eh_guard (buffer
.eh_
, false);
329 switch (buffer
.mask_
)
331 case ACE_Event_Handler::READ_MASK
:
332 case ACE_Event_Handler::ACCEPT_MASK
:
333 result
= buffer
.eh_
->handle_input (ACE_INVALID_HANDLE
);
335 case ACE_Event_Handler::WRITE_MASK
:
336 result
= buffer
.eh_
->handle_output (ACE_INVALID_HANDLE
);
338 case ACE_Event_Handler::EXCEPT_MASK
:
339 result
= buffer
.eh_
->handle_exception (ACE_INVALID_HANDLE
);
342 // Should we bail out if we get an invalid mask?
343 ACELIB_ERROR ((LM_ERROR
,
344 ACE_TEXT ("dispatch_notify invalid mask = %d\n"),
348 buffer
.eh_
->handle_close (ACE_INVALID_HANDLE
, buffer
.mask_
);
355 ACE_Dev_Poll_Reactor_Notify::max_notify_iterations (int iterations
)
357 ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::max_notify_iterations");
359 // Must always be > 0 or < 0 to optimize the loop exit condition.
363 this->max_notify_iterations_
= iterations
;
367 ACE_Dev_Poll_Reactor_Notify::max_notify_iterations (void)
369 ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::max_notify_iterations");
371 return this->max_notify_iterations_
;
375 ACE_Dev_Poll_Reactor_Notify::purge_pending_notifications (
376 ACE_Event_Handler
*eh
,
377 ACE_Reactor_Mask mask
)
379 ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::purge_pending_notifications");
381 #if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE)
383 return notification_queue_
.purge_pending_notifications (eh
, mask
);
385 #else /* defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE) */
387 ACE_UNUSED_ARG (mask
);
388 ACE_NOTSUP_RETURN (-1);
389 #endif /* defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE) */
393 ACE_Dev_Poll_Reactor_Notify::dump (void) const
395 #if defined (ACE_HAS_DUMP)
396 ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::dump");
398 ACELIB_DEBUG ((LM_DEBUG
, ACE_BEGIN_DUMP
, this));
399 ACELIB_DEBUG ((LM_DEBUG
,
400 ACE_TEXT ("dp_reactor_ = %@"),
402 this->notification_pipe_
.dump ();
403 ACELIB_DEBUG ((LM_DEBUG
, ACE_END_DUMP
));
404 #endif /* ACE_HAS_DUMP */
408 ACE_Dev_Poll_Reactor_Notify::dequeue_one (ACE_Notification_Buffer
&nb
)
412 return this->read_notify_pipe (this->notify_handle (), nb
);
416 // -----------------------------------------------------------------
418 ACE_Dev_Poll_Reactor::Handler_Repository::Handler_Repository (void)
423 ACE_TRACE ("ACE_Dev_Poll_Reactor::Handler_Repository::Handler_Repository");
427 ACE_Dev_Poll_Reactor::Handler_Repository::invalid_handle (
428 ACE_HANDLE handle
) const
430 ACE_TRACE ("ACE_Dev_Poll_Reactor::Handler_Repository::invalid_handle");
432 if (handle
< 0 || handle
>= this->max_size_
)
442 ACE_Dev_Poll_Reactor::Handler_Repository::handle_in_range (
443 ACE_HANDLE handle
) const
445 ACE_TRACE ("ACE_Dev_Poll_Reactor::Handler_Repository::handle_in_range");
447 if (handle
>= 0 && handle
< this->max_size_
)
457 ACE_Dev_Poll_Reactor::Handler_Repository::open (size_t size
)
459 ACE_TRACE ("ACE_Dev_Poll_Reactor::Handler_Repository::open");
461 this->max_size_
= size
;
463 // Try to allocate the memory.
464 ACE_NEW_RETURN (this->handlers_
, Event_Tuple
[size
], -1);
466 // Try to increase the number of handles if <size> is greater than
467 // the current limit.
468 return ACE::set_handle_limit (size
);
472 ACE_Dev_Poll_Reactor::Handler_Repository::unbind_all (void)
474 ACE_TRACE ("ACE_Dev_Poll_Reactor::Handler_Repository::unbind_all");
476 // Unbind all of the event handlers; similar to remove_handler() on all.
478 handle
< this->max_size_
;
481 Event_Tuple
*entry
= this->find (handle
);
485 // Check for ref counting now - handle_close () may delete eh.
486 bool const requires_reference_counting
=
487 entry
->event_handler
->reference_counting_policy ().value () ==
488 ACE_Event_Handler::Reference_Counting_Policy::ENABLED
;
490 (void) entry
->event_handler
->handle_close (handle
, entry
->mask
);
491 this->unbind (handle
, requires_reference_counting
);
498 ACE_Dev_Poll_Reactor::Handler_Repository::close (void)
500 ACE_TRACE ("ACE_Dev_Poll_Reactor::Handler_Repository::close");
502 if (this->handlers_
!= 0)
506 delete [] this->handlers_
;
513 ACE_Dev_Poll_Reactor::Event_Tuple
*
514 ACE_Dev_Poll_Reactor::Handler_Repository::find (ACE_HANDLE handle
)
516 ACE_TRACE ("ACE_Dev_Poll_Reactor::Handler_Repository::find");
518 Event_Tuple
*tuple
= 0;
520 // Only bother to search for the <handle> if it's in range.
521 if (!this->handle_in_range (handle
))
527 tuple
= &(this->handlers_
[handle
]);
528 if (tuple
->event_handler
== 0)
538 ACE_Dev_Poll_Reactor::Handler_Repository::bind (
540 ACE_Event_Handler
*event_handler
,
541 ACE_Reactor_Mask mask
)
543 ACE_TRACE ("ACE_Dev_Poll_Reactor::Handler_Repository::bind");
545 if (event_handler
== 0)
548 if (handle
== ACE_INVALID_HANDLE
)
549 handle
= event_handler
->get_handle ();
551 if (this->invalid_handle (handle
))
554 this->handlers_
[handle
].event_handler
= event_handler
;
555 this->handlers_
[handle
].mask
= mask
;
556 event_handler
->add_reference ();
563 ACE_Dev_Poll_Reactor::Handler_Repository::unbind (ACE_HANDLE handle
,
566 ACE_TRACE ("ACE_Dev_Poll_Reactor::Handler_Repository::unbind");
568 Event_Tuple
*entry
= this->find (handle
);
573 entry
->event_handler
->remove_reference ();
575 entry
->event_handler
= 0;
576 entry
->mask
= ACE_Event_Handler::NULL_MASK
;
577 entry
->suspended
= false;
578 entry
->controlled
= false;
583 // -----------------------------------------------------------------
585 ACE_Dev_Poll_Reactor::ACE_Dev_Poll_Reactor (ACE_Sig_Handler
*sh
,
587 int disable_notify_pipe
,
588 ACE_Reactor_Notify
*notify
,
591 : initialized_ (false)
592 , poll_fd_ (ACE_INVALID_HANDLE
)
594 #if defined (ACE_HAS_DEV_POLL)
598 #endif /* ACE_HAS_DEV_POLL */
599 , token_ (*this, s_queue
)
600 , lock_adapter_ (token_
)
603 , delete_timer_queue_ (false)
604 , signal_handler_ (0)
605 , delete_signal_handler_ (false)
606 , notify_handler_ (0)
607 , delete_notify_handler_ (false)
608 , mask_signals_ (mask_signals
)
611 ACE_TRACE ("ACE_Dev_Poll_Reactor::ACE_Dev_Poll_Reactor");
613 if (this->open (ACE::max_handles (),
619 ACELIB_ERROR ((LM_ERROR
,
621 ACE_TEXT ("ACE_Dev_Poll_Reactor::open ")
622 ACE_TEXT ("failed inside ")
623 ACE_TEXT ("ACE_Dev_Poll_Reactor::CTOR")));
626 ACE_Dev_Poll_Reactor::ACE_Dev_Poll_Reactor (size_t size
,
630 int disable_notify_pipe
,
631 ACE_Reactor_Notify
*notify
,
634 : initialized_ (false)
635 , poll_fd_ (ACE_INVALID_HANDLE
)
637 #if defined (ACE_HAS_DEV_POLL)
641 #endif /* ACE_HAS_DEV_POLL */
642 , token_ (*this, s_queue
)
643 , lock_adapter_ (token_
)
646 , delete_timer_queue_ (false)
647 , signal_handler_ (0)
648 , delete_signal_handler_ (false)
649 , notify_handler_ (0)
650 , delete_notify_handler_ (false)
651 , mask_signals_ (mask_signals
)
654 if (this->open (size
,
660 ACELIB_ERROR ((LM_ERROR
,
662 ACE_TEXT ("ACE_Dev_Poll_Reactor::open ")
663 ACE_TEXT ("failed inside ACE_Dev_Poll_Reactor::CTOR")));
666 ACE_Dev_Poll_Reactor::~ACE_Dev_Poll_Reactor (void)
668 ACE_TRACE ("ACE_Dev_Poll_Reactor::~ACE_Dev_Poll_Reactor");
670 (void) this->close ();
674 ACE_Dev_Poll_Reactor::open (size_t size
,
678 int disable_notify_pipe
,
679 ACE_Reactor_Notify
*notify
)
681 ACE_TRACE ("ACE_Dev_Poll_Reactor::open");
683 ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token
, mon
, this->token_
, -1));
685 // Can't initialize ourselves more than once.
686 if (this->initialized_
)
689 #ifdef ACE_HAS_EVENT_POLL
690 ACE_OS::memset (&this->event_
, 0, sizeof (this->event_
));
691 this->event_
.data
.fd
= ACE_INVALID_HANDLE
;
692 #endif /* ACE_HAS_EVENT_POLL */
694 this->restart_
= restart
;
695 this->signal_handler_
= sh
;
696 this->timer_queue_
= tq
;
697 this->notify_handler_
= notify
;
701 // Allows the signal handler to be overridden.
702 if (this->signal_handler_
== 0)
704 ACE_NEW_RETURN (this->signal_handler_
,
708 if (this->signal_handler_
== 0)
711 this->delete_signal_handler_
= true;
714 // Allows the timer queue to be overridden.
715 if (result
!= -1 && this->timer_queue_
== 0)
717 ACE_NEW_RETURN (this->timer_queue_
,
721 if (this->timer_queue_
== 0)
724 this->delete_timer_queue_
= true;
727 // Allows the Notify_Handler to be overridden.
728 if (result
!= -1 && this->notify_handler_
== 0)
730 ACE_NEW_RETURN (this->notify_handler_
,
731 ACE_Dev_Poll_Reactor_Notify
,
734 if (this->notify_handler_
== 0)
737 this->delete_notify_handler_
= true;
740 #if defined (ACE_HAS_EVENT_POLL)
743 this->poll_fd_
= ::epoll_create (size
);
744 if (this->poll_fd_
== -1)
749 // Allocate the array before opening the device to avoid a potential
750 // resource leak if allocation fails.
751 ACE_NEW_RETURN (this->dp_fds_
,
755 // Open the `/dev/poll' character device.
756 this->poll_fd_
= ACE_OS::open ("/dev/poll", O_RDWR
);
757 if (this->poll_fd_
== ACE_INVALID_HANDLE
)
760 #endif /* ACE_HAS_EVENT_POLL */
762 if (result
!= -1 && this->handler_rep_
.open (size
) == -1)
765 // Registration of the notification handler must be done after the
766 // /dev/poll device has been fully initialized.
767 else if (this->notify_handler_
->open (this,
769 disable_notify_pipe
) == -1
770 || (disable_notify_pipe
== 0
771 && this->register_handler_i (
772 this->notify_handler_
->notify_handle (),
773 this->notify_handler_
,
774 ACE_Event_Handler::READ_MASK
) == -1))
778 // We're all set to go.
779 this->initialized_
= true;
781 // This will close down all the allocated resources properly.
782 (void) this->close ();
788 ACE_Dev_Poll_Reactor::current_info (ACE_HANDLE
, size_t & /* size */)
790 ACE_NOTSUP_RETURN (-1);
795 ACE_Dev_Poll_Reactor::set_sig_handler (ACE_Sig_Handler
*signal_handler
)
797 if (this->delete_signal_handler_
)
798 delete this->signal_handler_
;
800 this->signal_handler_
= signal_handler
;
801 this->delete_signal_handler_
= false;
807 ACE_Dev_Poll_Reactor::timer_queue (ACE_Timer_Queue
*tq
)
809 if (this->delete_timer_queue_
)
810 delete this->timer_queue_
;
811 else if (this->timer_queue_
)
812 this->timer_queue_
->close ();
814 this->timer_queue_
= tq
;
815 this->delete_timer_queue_
= false;
821 ACE_Dev_Poll_Reactor::timer_queue (void) const
823 return this->timer_queue_
;
827 ACE_Dev_Poll_Reactor::close (void)
829 ACE_TRACE ("ACE_Dev_Poll_Reactor::close");
831 ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token
, mon
, this->token_
, -1));
835 if (this->poll_fd_
!= ACE_INVALID_HANDLE
)
837 result
= ACE_OS::close (this->poll_fd_
);
840 #if defined (ACE_HAS_EVENT_POLL)
842 ACE_OS::memset (&this->event_
, 0, sizeof (this->event_
));
843 this->event_
.data
.fd
= ACE_INVALID_HANDLE
;
847 delete [] this->dp_fds_
;
849 this->start_pfds_
= 0;
852 #endif /* ACE_HAS_EVENT_POLL */
854 if (this->delete_signal_handler_
)
856 delete this->signal_handler_
;
857 this->signal_handler_
= 0;
858 this->delete_signal_handler_
= false;
861 (void) this->handler_rep_
.close ();
863 if (this->delete_timer_queue_
)
865 delete this->timer_queue_
;
866 this->timer_queue_
= 0;
867 this->delete_timer_queue_
= false;
869 else if (this->timer_queue_
)
871 this->timer_queue_
->close ();
872 this->timer_queue_
= 0;
875 if (this->notify_handler_
!= 0)
876 this->notify_handler_
->close ();
878 if (this->delete_notify_handler_
)
880 delete this->notify_handler_
;
881 this->notify_handler_
= 0;
882 this->delete_notify_handler_
= false;
885 this->poll_fd_
= ACE_INVALID_HANDLE
;
887 this->initialized_
= false;
893 ACE_Dev_Poll_Reactor::work_pending (const ACE_Time_Value
& max_wait_time
)
895 ACE_TRACE ("ACE_Dev_Poll_Reactor::work_pending");
897 // Stash the current time
899 // The destructor of this object will automatically compute how much
900 // time elapsed since this method was called.
901 ACE_Time_Value
mwt (max_wait_time
);
902 ACE_MT (ACE_Countdown_Time
countdown (&mwt
));
904 Token_Guard
guard (this->token_
);
905 int const result
= guard
.acquire_quietly (&mwt
);
907 // If the guard is NOT the owner just return the retval
908 if (!guard
.is_owner ())
911 // Update the countdown to reflect time waiting for the mutex.
912 ACE_MT (countdown
.update ());
914 return this->work_pending_i (&mwt
);
918 ACE_Dev_Poll_Reactor::work_pending_i (ACE_Time_Value
* max_wait_time
)
920 ACE_TRACE ("ACE_Dev_Poll_Reactor::work_pending_i");
922 if (this->deactivated_
)
925 #if defined (ACE_HAS_EVENT_POLL)
926 if (this->event_
.data
.fd
!= ACE_INVALID_HANDLE
)
928 if (this->start_pfds_
!= this->end_pfds_
)
929 #endif /* ACE_HAS_EVENT_POLL */
930 return 1; // We still have work_pending (). Do not poll for
931 // additional events.
933 ACE_Time_Value
timer_buf (0);
934 ACE_Time_Value
*this_timeout
=
935 this->timer_queue_
->calculate_timeout (max_wait_time
, &timer_buf
);
937 // Check if we have timers to fire.
938 int const timers_pending
=
939 ((this_timeout
!= 0 && max_wait_time
== 0)
940 || (this_timeout
!= 0 && max_wait_time
!= 0
941 && *this_timeout
!= *max_wait_time
) ? 1 : 0);
946 : static_cast<long> (this_timeout
->msec ()));
948 #if defined (ACE_HAS_EVENT_POLL)
950 // Wait for an event.
951 int const nfds
= ::epoll_wait (this->poll_fd_
,
954 static_cast<int> (timeout
));
960 dvp
.dp_fds
= this->dp_fds_
;
961 dvp
.dp_nfds
= this->handler_rep_
.size ();
962 dvp
.dp_timeout
= timeout
; // Milliseconds
965 int const nfds
= ACE_OS::ioctl (this->poll_fd_
, DP_POLL
, &dvp
);
967 // Retrieve the results from the pollfd array.
968 this->start_pfds_
= dvp
.dp_fds
;
970 // If nfds == 0 then end_pfds_ == start_pfds_ meaning that there is
971 // no work pending. If nfds > 0 then there is work pending.
972 // Otherwise an error occurred.
974 this->end_pfds_
= this->start_pfds_
+ nfds
;
975 #endif /* ACE_HAS_EVENT_POLL */
977 // If timers are pending, override any timeout from the poll.
978 return (nfds
== 0 && timers_pending
!= 0 ? 1 : nfds
);
983 ACE_Dev_Poll_Reactor::handle_events (ACE_Time_Value
*max_wait_time
)
985 ACE_TRACE ("ACE_Dev_Poll_Reactor::handle_events");
987 // Stash the current time
989 // The destructor of this object will automatically compute how much
990 // time elapsed since this method was called.
991 ACE_Countdown_Time
countdown (max_wait_time
);
993 Token_Guard
guard (this->token_
);
994 int const result
= guard
.acquire_quietly (max_wait_time
);
996 // If the guard is NOT the owner just return the retval
997 if (!guard
.is_owner ())
1000 if (this->deactivated_
)
1006 // Update the countdown to reflect time waiting for the mutex.
1007 ACE_MT (countdown
.update ());
1009 return this->handle_events_i (max_wait_time
, guard
);
1013 ACE_Dev_Poll_Reactor::handle_events_i (ACE_Time_Value
*max_wait_time
,
1016 ACE_TRACE ("ACE_Dev_Poll_Reactor::handle_events_i");
1022 // If the underlying event wait call was interrupted via the interrupt
1023 // signal (i.e. returned -1 with errno == EINTR) then the loop will
1024 // be restarted if so desired.
1027 result
= this->work_pending_i (max_wait_time
);
1028 if (result
== -1 && (this->restart_
== 0 || errno
!= EINTR
))
1029 ACELIB_ERROR ((LM_ERROR
, ACE_TEXT("%t: %p\n"), ACE_TEXT("work_pending_i")));
1031 while (result
== -1 && this->restart_
!= 0 && errno
== EINTR
);
1033 if (result
== 0 || (result
== -1 && errno
== ETIME
))
1035 else if (result
== -1)
1040 // Bail out -- we got here since the poll was interrupted.
1041 // If it was due to a signal registered through our ACE_Sig_Handler,
1042 // then it was dispatched, so we count it in the number of events
1043 // handled rather than cause an error return.
1044 if (ACE_Sig_Handler::sig_pending () != 0)
1046 ACE_Sig_Handler::sig_pending (0);
1052 // Dispatch an event.
1053 return this->dispatch (guard
);
1056 // Dispatch an event. On entry, the token is held by the caller. If an
1057 // event is found to dispatch, the token is released before dispatching it.
1059 ACE_Dev_Poll_Reactor::dispatch (Token_Guard
&guard
)
1061 ACE_TRACE ("ACE_Dev_Poll_Reactor::dispatch");
1063 // Perform the Template Method for dispatching the first located event.
1064 // We dispatch only one to effectively dispatch events concurrently.
1065 // As soon as an event is located, the token is released, allowing the
1066 // next waiter to begin getting an event while we dispatch one here.
1069 // Handle timers early since they may have higher latency
1070 // constraints than I/O handlers. Ideally, the order of
1071 // dispatching should be a strategy...
1072 if ((result
= this->dispatch_timer_handler (guard
)) != 0)
1075 // If no timer dispatched, check for an I/O event.
1076 result
= this->dispatch_io_event (guard
);
1082 ACE_Dev_Poll_Reactor::dispatch_timer_handler (Token_Guard
&guard
)
1084 typedef ACE_Member_Function_Command
<Token_Guard
> Guard_Release
;
1086 Guard_Release
release(guard
, &Token_Guard::release_token
);
1087 return this->timer_queue_
->expire_single(release
);
1092 ACE_Dev_Poll_Reactor::dispatch_notification_handlers (
1093 ACE_Select_Reactor_Handle_Set
&dispatch_set
,
1094 int &number_of_active_handles
,
1095 int &number_of_handlers_dispatched
)
1097 // Check to see if the ACE_HANDLE associated with the
1098 // Dev_Poll_Reactor's notify hook is enabled. If so, it means that
1099 // one or more other threads are trying to update the
1100 // ACE_Dev_Poll_Reactor's internal tables or the notify pipe is
1101 // enabled. We'll handle all these threads and notifications, and
1102 // then break out to continue the event loop.
1105 this->notify_handler_
->dispatch_notifications (number_of_active_handles
,
1106 dispatch_set
.rd_mask_
);
1111 number_of_handlers_dispatched
+= n
;
1113 return /* this->state_changed_ ? -1 : */ 0;
1118 ACE_Dev_Poll_Reactor::dispatch_io_event (Token_Guard
&guard
)
1121 // Dispatch a ready event.
1123 // Define bits to check for while dispatching.
1124 #if defined (ACE_HAS_EVENT_POLL)
1125 const __uint32_t out_event
= EPOLLOUT
;
1126 const __uint32_t exc_event
= EPOLLPRI
;
1127 const __uint32_t in_event
= EPOLLIN
;
1128 const __uint32_t err_event
= EPOLLHUP
| EPOLLERR
;
1130 const short out_event
= POLLOUT
;
1131 const short exc_event
= POLLPRI
;
1132 const short in_event
= POLLIN
;
1133 const short err_event
= 0; // No known bits for this
1134 #endif /* ACE_HAS_EVENT_POLL */
1136 #if defined (ACE_HAS_EVENT_POLL)
1137 // epoll_wait() pulls one event which is stored in event_. If the handle
1138 // is invalid, there's no event there. Else process it. In any event, we
1139 // have the event, so clear event_ for the next thread.
1140 const ACE_HANDLE handle
= this->event_
.data
.fd
;
1141 __uint32_t revents
= this->event_
.events
;
1142 this->event_
.data
.fd
= ACE_INVALID_HANDLE
;
1143 this->event_
.events
= 0;
1144 if (handle
!= ACE_INVALID_HANDLE
)
1147 // Since the underlying event demultiplexing mechansim (`/dev/poll'
1148 // or '/dev/epoll') is stateful, and since only one result buffer is
1149 // used, all pending events (i.e. those retrieved from a previous
1150 // poll) must be dispatched before any additional event can be
1151 // polled. As such, the Dev_Poll_Reactor keeps track of the
1152 // progress of events that have been dispatched.
1154 // Select the first available handle with event (s) pending. Check for
1155 // event type in defined order of dispatch: output, exception, input.
1156 // When an event is located, clear its bit in the dispatch set. If there
1157 // are no more events for the handle, also increment the pfds pointer
1158 // to move to the next handle ready.
1160 // Notice that pfds only contains file descriptors that have
1162 struct pollfd
*& pfds
= this->start_pfds_
;
1163 const ACE_HANDLE handle
= pfds
->fd
;
1164 short &revents
= pfds
->revents
;
1165 if (pfds
< this->end_pfds_
)
1166 #endif /* ACE_HAS_EVENT_POLL */
1169 /* When using sys_epoll, we can attach arbitrary user
1170 data to the descriptor, so it can be delivered when
1171 activity is detected. Perhaps we should store event
1172 handler together with descriptor, instead of looking
1173 it up in a repository ? Could it boost performance ?
1176 // Going to access handler repo, so lock it. If the lock is
1177 // unobtainable, something is very wrong so bail out.
1178 Event_Tuple
*info
= 0;
1179 ACE_Reactor_Mask disp_mask
= 0;
1180 ACE_Event_Handler
*eh
= 0;
1181 int (ACE_Event_Handler::*callback
)(ACE_HANDLE
) = 0;
1182 bool reactor_resumes_eh
= false;
1184 ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1);
1185 info
= this->handler_rep_
.find (handle
);
1186 if (info
== 0) // No registered handler any longer
1189 // It is possible another thread has changed (and possibly re-armed)
1190 // this handle mask before current thread obtained the repo lock.
1191 // If that did happen and this handler is still suspended, don't
1192 // dispatch on top of another callback. See Bugzilla 4129.
1193 if (info
->suspended
)
1196 // Figure out what to do first in order to make it easier to manage
1197 // the bit twiddling and possible pfds increment before releasing
1198 // the token for dispatch.
1199 // Note that if there's an error (such as the handle was closed
1200 // without being removed from the event set) the EPOLLHUP and/or
1201 // EPOLLERR bits will be set in revents.
1202 eh
= info
->event_handler
;
1203 if (ACE_BIT_ENABLED (revents
, out_event
))
1205 disp_mask
= ACE_Event_Handler::WRITE_MASK
;
1206 callback
= &ACE_Event_Handler::handle_output
;
1207 ACE_CLR_BITS (revents
, out_event
);
1209 else if (ACE_BIT_ENABLED (revents
, exc_event
))
1211 disp_mask
= ACE_Event_Handler::EXCEPT_MASK
;
1212 callback
= &ACE_Event_Handler::handle_exception
;
1213 ACE_CLR_BITS (revents
, exc_event
);
1215 else if (ACE_BIT_ENABLED (revents
, in_event
))
1217 disp_mask
= ACE_Event_Handler::READ_MASK
;
1218 callback
= &ACE_Event_Handler::handle_input
;
1219 ACE_CLR_BITS (revents
, in_event
);
1221 else if (ACE_BIT_ENABLED (revents
, err_event
))
1223 this->remove_handler_i (handle
,
1224 ACE_Event_Handler::ALL_EVENTS_MASK
,
1226 info
->event_handler
);
1227 #ifdef ACE_HAS_DEV_POLL
1229 #endif /* ACE_HAS_DEV_POLL */
1234 ACELIB_ERROR ((LM_ERROR
,
1235 ACE_TEXT ("(%t) dispatch_io h %d unknown events 0x%x\n"),
1239 #ifdef ACE_HAS_DEV_POLL
1240 // Increment the pointer to the next element before we
1241 // release the token. Otherwise event handlers end up being
1242 // dispatched multiple times for the same poll.
1246 // With epoll, events are registered with oneshot, so the handle is
1247 // effectively suspended; future calls to epoll_wait() will select
1248 // the next event, so they're not managed here.
1249 // The hitch to this is that the notify handler is always registered
1250 // WITHOUT oneshot and is never suspended/resumed. This avoids endless
1251 // notify loops caused by the notify handler requiring a resumption
1252 // which requires the token, which requires a notify, etc. described
1253 // in Bugzilla 3714. So, never suspend the notify handler.
1254 if (eh
!= this->notify_handler_
)
1256 info
->suspended
= true;
1258 reactor_resumes_eh
=
1259 eh
->resume_handler () ==
1260 ACE_Event_Handler::ACE_REACTOR_RESUMES_HANDLER
;
1262 #endif /* ACE_HAS_DEV_POLL */
1264 } // End scope for ACE_GUARD holding repo lock
1266 int status
= 0; // gets callback status, below.
1268 // Dispatch notifies directly. The notify dispatcher locates a
1269 // notification then releases the token prior to dispatching it.
1270 // NOTE: If notify_handler_->dispatch_one() returns a fail condition
1271 // it has not releases the guard. Else, it has.
1272 if (eh
== this->notify_handler_
)
1274 ACE_Notification_Buffer b
;
1276 dynamic_cast<ACE_Dev_Poll_Reactor_Notify
*>(notify_handler_
)->dequeue_one (b
);
1279 guard
.release_token ();
1280 return notify_handler_
->dispatch_notify (b
);
1284 // Modify the reference count in an exception-safe way.
1285 // Note that eh could be the notify handler. It's not strictly
1286 // necessary to manage its refcount, but since we don't enable
1287 // the counting policy, it won't do much. Management of the
1288 // notified handlers themselves is done in the notify handler.
1289 ACE_Dev_Poll_Handler_Guard
eh_guard (eh
);
1291 // Release the reactor token before upcall.
1292 guard
.release_token ();
1294 // Dispatch the detected event; will do the repeated upcalls
1295 // if callback returns > 0, unless it's the notify handler (which
1296 // returns the number of notfies dispatched, not an indication of
1297 // re-callback requested). If anything other than the notify, come
1298 // back with either 0 or < 0.
1299 status
= this->upcall (eh
, callback
, handle
);
1301 // If the callback returned 0, epoll-based needs to resume the
1302 // suspended handler but dev/poll doesn't.
1303 // In both epoll and dev/poll cases, if the callback returns <0,
1304 // the token needs to be acquired and the handler checked and
1305 // removed if it hasn't already been.
1308 #ifdef ACE_HAS_EVENT_POLL
1309 // epoll-based effectively suspends handlers around the upcall.
1310 // If the handler must be resumed, check to be sure it's the
1311 // same handle/handler combination still.
1312 if (reactor_resumes_eh
)
1314 ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1);
1315 info
= this->handler_rep_
.find (handle
);
1316 if (info
!= 0 && info
->event_handler
== eh
)
1317 this->resume_handler_i (handle
);
1319 #endif /* ACE_HAS_EVENT_POLL */
1323 // All state in the handler repository may have changed during the
1324 // upcall. Thus, reacquire the repo lock and evaluate what's needed.
1325 // If the upcalled handler is still the handler of record for handle,
1326 // continue with checking whether or not to remove or resume the
1328 ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, 1);
1329 info
= this->handler_rep_
.find (handle
);
1330 if (info
!= 0 && info
->event_handler
== eh
)
1334 this->remove_handler_i (handle
, disp_mask
, grd
);
1335 #ifdef ACE_HAS_EVENT_POLL
1336 // epoll-based effectively suspends handlers around the upcall.
1337 // If the handler must be resumed, check to be sure it's the
1338 // same handle/handler combination still.
1339 if (reactor_resumes_eh
)
1341 info
= this->handler_rep_
.find (handle
);
1342 if (info
!= 0 && info
->event_handler
== eh
)
1344 this->resume_handler_i (handle
);
1347 #endif /* ACE_HAS_EVENT_POLL */
1351 // Scope close handles eh ref count decrement, if needed.
1360 ACE_Dev_Poll_Reactor::alertable_handle_events (ACE_Time_Value
*max_wait_time
)
1362 ACE_TRACE ("ACE_Dev_Poll_Reactor::alertable_handle_events");
1364 return this->handle_events (max_wait_time
);
1368 ACE_Dev_Poll_Reactor::handle_events (ACE_Time_Value
&max_wait_time
)
1370 ACE_TRACE ("ACE_Dev_Poll_Reactor::handle_events");
1372 return this->handle_events (&max_wait_time
);
1376 ACE_Dev_Poll_Reactor::alertable_handle_events (ACE_Time_Value
&max_wait_time
)
1378 ACE_TRACE ("ACE_Dev_Poll_Reactor::alertable_handle_events");
1380 return this->handle_events (max_wait_time
);
1384 ACE_Dev_Poll_Reactor::deactivated (void)
1386 return this->deactivated_
;
1390 ACE_Dev_Poll_Reactor::deactivate (int do_stop
)
1392 this->deactivated_
= do_stop
;
1393 this->wakeup_all_threads ();
1397 ACE_Dev_Poll_Reactor::register_handler (ACE_Event_Handler
*handler
,
1398 ACE_Reactor_Mask mask
)
1400 ACE_TRACE ("ACE_Dev_Poll_Reactor::register_handler");
1402 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1));
1404 return this->register_handler_i (handler
->get_handle (),
1410 ACE_Dev_Poll_Reactor::register_handler (ACE_HANDLE handle
,
1411 ACE_Event_Handler
*event_handler
,
1412 ACE_Reactor_Mask mask
)
1414 ACE_TRACE ("ACE_Dev_Poll_Reactor::register_handler");
1416 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1));
1418 return this->register_handler_i (handle
,
1424 ACE_Dev_Poll_Reactor::register_handler_i (ACE_HANDLE handle
,
1425 ACE_Event_Handler
*event_handler
,
1426 ACE_Reactor_Mask mask
)
1428 ACE_TRACE ("ACE_Dev_Poll_Reactor::register_handler_i");
1430 if (handle
== ACE_INVALID_HANDLE
1431 || mask
== ACE_Event_Handler::NULL_MASK
)
1437 if (this->handler_rep_
.find (handle
) == 0)
1439 // Handler not present in the repository. Bind it.
1440 if (this->handler_rep_
.bind (handle
, event_handler
, mask
) != 0)
1443 #if defined (ACE_HAS_EVENT_POLL)
1445 Event_Tuple
*info
= this->handler_rep_
.find (handle
);
1447 struct epoll_event epev
;
1448 ACE_OS::memset (&epev
, 0, sizeof (epev
));
1449 static const int op
= EPOLL_CTL_ADD
;
1451 epev
.data
.fd
= handle
;
1452 epev
.events
= this->reactor_mask_to_poll_event (mask
);
1453 // All but the notify handler get registered with oneshot to facilitate
1454 // auto suspend before the upcall. See dispatch_io_event for more
1456 if (event_handler
!= this->notify_handler_
)
1457 epev
.events
|= EPOLLONESHOT
;
1459 if (::epoll_ctl (this->poll_fd_
, op
, handle
, &epev
) == -1)
1461 ACELIB_ERROR ((LM_ERROR
, ACE_TEXT("%p\n"), ACE_TEXT("epoll_ctl")));
1462 (void) this->handler_rep_
.unbind (handle
);
1465 info
->controlled
= true;
1467 #endif /* ACE_HAS_EVENT_POLL */
1471 // Handler is already present in the repository, so register it
1472 // again, possibly for different event. Add new mask to the
1474 if (this->mask_ops_i (handle
, mask
, ACE_Reactor::ADD_MASK
) == -1)
1475 ACELIB_ERROR_RETURN ((LM_ERROR
, ACE_TEXT("%p\n"), ACE_TEXT("mask_ops_i")),
1479 #ifdef ACE_HAS_DEV_POLL
1484 pfd
.events
= this->reactor_mask_to_poll_event (mask
);
1487 // Add file descriptor to the "interest set."
1488 if (ACE_OS::write (this->poll_fd_
, &pfd
, sizeof (pfd
)) != sizeof (pfd
))
1490 (void) this->handler_rep_
.unbind (handle
);
1493 #endif /*ACE_HAS_DEV_POLL*/
1495 // Note the fact that we've changed the state of the wait_set_,
1496 // which is used by the dispatching loop to determine whether it can
1497 // keep going or if it needs to reconsult select ().
1498 // this->state_changed_ = 1;
1504 ACE_Dev_Poll_Reactor::register_handler (
1505 ACE_HANDLE
/* event_handle */,
1506 ACE_HANDLE
/* io_handle */,
1507 ACE_Event_Handler
* /* event_handler */,
1508 ACE_Reactor_Mask
/* mask */)
1510 ACE_NOTSUP_RETURN (-1);
1514 ACE_Dev_Poll_Reactor::register_handler (const ACE_Handle_Set
&handle_set
,
1515 ACE_Event_Handler
*event_handler
,
1516 ACE_Reactor_Mask mask
)
1518 ACE_TRACE ("ACE_Dev_Poll_Reactor::register_handler");
1520 ACE_Handle_Set_Iterator
handle_iter (handle_set
);
1522 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1));
1524 // @@ It might be more efficient to construct a pollfd array and
1525 // pass it to the write () call in register_handler_i () only once,
1526 // instead of calling write () (a system call) once for each file
1529 for (ACE_HANDLE h
= handle_iter ();
1530 h
!= ACE_INVALID_HANDLE
;
1532 if (this->register_handler_i (h
, event_handler
, mask
) == -1)
1539 ACE_Dev_Poll_Reactor::register_handler (int signum
,
1540 ACE_Event_Handler
*new_sh
,
1541 ACE_Sig_Action
*new_disp
,
1542 ACE_Event_Handler
**old_sh
,
1543 ACE_Sig_Action
*old_disp
)
1545 ACE_TRACE ("ACE_Dev_Poll_Reactor::register_handler");
1547 return this->signal_handler_
->register_handler (signum
,
1555 ACE_Dev_Poll_Reactor::register_handler (const ACE_Sig_Set
&sigset
,
1556 ACE_Event_Handler
*new_sh
,
1557 ACE_Sig_Action
*new_disp
)
1559 ACE_TRACE ("ACE_Dev_Poll_Reactor::register_handler");
1565 for (int s
= 1; s
< ACE_NSIG
; ++s
)
1566 if ((sigset
.is_member (s
) == 1)
1567 && this->signal_handler_
->register_handler (s
,
1572 #else /* ACE_NSIG <= 0 */
1574 ACE_UNUSED_ARG (sigset
);
1575 ACE_UNUSED_ARG (new_sh
);
1576 ACE_UNUSED_ARG (new_disp
);
1578 #endif /* ACE_NSIG <= 0 */
1584 ACE_Dev_Poll_Reactor::remove_handler (ACE_Event_Handler
*handler
,
1585 ACE_Reactor_Mask mask
)
1587 ACE_TRACE ("ACE_Dev_Poll_Reactor::remove_handler");
1589 ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1);
1590 return this->remove_handler_i (handler
->get_handle (), mask
, grd
);
1594 ACE_Dev_Poll_Reactor::remove_handler (ACE_HANDLE handle
,
1595 ACE_Reactor_Mask mask
)
1597 ACE_TRACE ("ACE_Dev_Poll_Reactor::remove_handler");
1599 ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1);
1601 return this->remove_handler_i (handle
, mask
, grd
);
1604 // FUZZ: disable check_for_ACE_Guard
1606 ACE_Dev_Poll_Reactor::remove_handler_i (ACE_HANDLE handle
,
1607 ACE_Reactor_Mask mask
,
1608 ACE_Guard
<ACE_SYNCH_MUTEX
> &repo_guard
,
1609 ACE_Event_Handler
*eh
)
1610 // FUZZ: enable check_for_ACE_Guard
1612 ACE_TRACE ("ACE_Dev_Poll_Reactor::remove_handler_i");
1614 // If registered event handler not the same as eh, don't mess with
1615 // the mask, but do the proper callback and refcount when needed.
1616 bool handle_reg_changed
= true;
1617 Event_Tuple
*info
= this->handler_rep_
.find (handle
);
1618 if (info
== 0 && eh
== 0) // Nothing to work with
1620 if (info
!= 0 && (eh
== 0 || info
->event_handler
== eh
))
1622 if (this->mask_ops_i (handle
, mask
, ACE_Reactor::CLR_MASK
) == -1)
1624 handle_reg_changed
= false;
1625 eh
= info
->event_handler
;
1628 // Check for ref counting now - handle_close () may delete eh.
1629 bool const requires_reference_counting
=
1630 eh
->reference_counting_policy ().value () ==
1631 ACE_Event_Handler::Reference_Counting_Policy::ENABLED
;
1633 if (ACE_BIT_DISABLED (mask
, ACE_Event_Handler::DONT_CALL
))
1635 // It would be great if ACE_Reverse_Lock worked with the Guard.
1636 repo_guard
.release ();
1637 eh
->handle_close (handle
, mask
);
1638 repo_guard
.acquire ();
1641 // If there are no longer any outstanding events on the given handle
1642 // then remove it from the handler repository.
1643 if (!handle_reg_changed
&& info
->mask
== ACE_Event_Handler::NULL_MASK
)
1644 this->handler_rep_
.unbind (handle
, requires_reference_counting
);
1650 ACE_Dev_Poll_Reactor::remove_handler (const ACE_Handle_Set
&handle_set
,
1651 ACE_Reactor_Mask mask
)
1653 ACE_TRACE ("ACE_Dev_Poll_Reactor::remove_handler");
1655 ACE_Handle_Set_Iterator
handle_iter (handle_set
);
1656 for (ACE_HANDLE h
= handle_iter ();
1657 h
!= ACE_INVALID_HANDLE
;
1660 ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1);
1661 if (this->remove_handler_i (h
, mask
, grd
) == -1)
1668 ACE_Dev_Poll_Reactor::remove_handler (int signum
,
1669 ACE_Sig_Action
*new_disp
,
1670 ACE_Sig_Action
*old_disp
,
1673 ACE_TRACE ("ACE_Dev_Poll_Reactor::remove_handler");
1675 return this->signal_handler_
->remove_handler (signum
,
1682 ACE_Dev_Poll_Reactor::remove_handler (const ACE_Sig_Set
&sigset
)
1684 ACE_TRACE ("ACE_Dev_Poll_Reactor::remove_handler");
1690 for (int s
= 1; s
< ACE_NSIG
; ++s
)
1691 if ((sigset
.is_member (s
) == 1)
1692 && this->signal_handler_
->remove_handler (s
) == -1)
1695 #else /* ACE_NSIG <= 0 */
1697 ACE_UNUSED_ARG (sigset
);
1699 #endif /* ACE_NSIG <= 0 */
1705 ACE_Dev_Poll_Reactor::suspend_handler (ACE_Event_Handler
*event_handler
)
1707 ACE_TRACE ("ACE_Dev_Poll_Reactor::suspend_handler");
1709 if (event_handler
== 0)
1715 ACE_HANDLE handle
= event_handler
->get_handle ();
1717 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1));
1719 return this->suspend_handler_i (handle
);
1723 ACE_Dev_Poll_Reactor::suspend_handler (ACE_HANDLE handle
)
1725 ACE_TRACE ("ACE_Dev_Poll_Reactor::suspend_handler");
1727 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1));
1729 return this->suspend_handler_i (handle
);
1733 ACE_Dev_Poll_Reactor::suspend_handler (const ACE_Handle_Set
&handles
)
1735 ACE_TRACE ("ACE_Dev_Poll_Reactor::suspend_handler");
1737 ACE_Handle_Set_Iterator
handle_iter (handles
);
1740 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1));
1742 while ((h
= handle_iter ()) != ACE_INVALID_HANDLE
)
1743 if (this->suspend_handler_i (h
) == -1)
1750 ACE_Dev_Poll_Reactor::suspend_handlers (void)
1752 ACE_TRACE ("ACE_Dev_Poll_Reactor::suspend_handlers");
1754 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1));
1756 size_t const len
= this->handler_rep_
.max_size ();
1758 for (size_t i
= 0; i
< len
; ++i
)
1760 Event_Tuple
*info
= this->handler_rep_
.find (i
);
1761 if (info
!= 0 && !info
->suspended
&& this->suspend_handler_i (i
) != 0)
1768 ACE_Dev_Poll_Reactor::suspend_handler_i (ACE_HANDLE handle
)
1770 ACE_TRACE ("ACE_Dev_Poll_Reactor::suspend_handler_i");
1772 Event_Tuple
*info
= this->handler_rep_
.find (handle
);
1776 if (info
->suspended
)
1777 return 0; // Already suspended. @@ Should this be an error?
1779 // Remove the handle from the "interest set."
1781 // Note that the associated event handler is still in the handler
1782 // repository, but no events will be polled on the given handle thus
1783 // no event will be dispatched to the event handler.
1785 #if defined (ACE_HAS_EVENT_POLL)
1787 struct epoll_event epev
;
1788 ACE_OS::memset (&epev
, 0, sizeof (epev
));
1789 static const int op
= EPOLL_CTL_DEL
;
1792 epev
.data
.fd
= handle
;
1794 if (::epoll_ctl (this->poll_fd_
, op
, handle
, &epev
) == -1)
1796 info
->controlled
= false;
1799 struct pollfd pfd
[1];
1802 pfd
[0].events
= POLLREMOVE
;
1805 if (ACE_OS::write (this->poll_fd_
, pfd
, sizeof (pfd
)) != sizeof (pfd
))
1808 #endif /* ACE_HAS_EVENT_POLL */
1810 info
->suspended
= true;
1816 ACE_Dev_Poll_Reactor::resume_handler (ACE_Event_Handler
*event_handler
)
1818 ACE_TRACE ("ACE_Dev_Poll_Reactor::resume_handler");
1820 if (event_handler
== 0)
1826 ACE_HANDLE handle
= event_handler
->get_handle ();
1828 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1));
1830 return this->resume_handler_i (handle
);
1834 ACE_Dev_Poll_Reactor::resume_handler (ACE_HANDLE handle
)
1836 ACE_TRACE ("ACE_Dev_Poll_Reactor::resume_handler");
1838 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1));
1840 return this->resume_handler_i (handle
);
1844 ACE_Dev_Poll_Reactor::resume_handler (const ACE_Handle_Set
&handles
)
1846 ACE_TRACE ("ACE_Dev_Poll_Reactor::resume_handler");
1848 ACE_Handle_Set_Iterator
handle_iter (handles
);
1851 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1));
1853 while ((h
= handle_iter ()) != ACE_INVALID_HANDLE
)
1854 if (this->resume_handler_i (h
) == -1)
1861 ACE_Dev_Poll_Reactor::resume_handlers (void)
1863 ACE_TRACE ("ACE_Dev_Poll_Reactor::resume_handlers");
1865 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1));
1867 size_t const len
= this->handler_rep_
.max_size ();
1869 for (size_t i
= 0; i
< len
; ++i
)
1871 Event_Tuple
*info
= this->handler_rep_
.find (i
);
1872 if (info
!= 0 && info
->suspended
&& this->resume_handler_i (i
) != 0)
1880 ACE_Dev_Poll_Reactor::resume_handler_i (ACE_HANDLE handle
)
1882 ACE_TRACE ("ACE_Dev_Poll_Reactor::resume_handler_i");
1884 Event_Tuple
*info
= this->handler_rep_
.find (handle
);
1888 if (!info
->suspended
)
1891 ACE_Reactor_Mask mask
= info
->mask
;
1892 if (mask
== ACE_Event_Handler::NULL_MASK
)
1894 info
->suspended
= false;
1898 // Place the handle back in to the "interest set."
1900 // Events for the given handle will once again be polled.
1902 #if defined (ACE_HAS_EVENT_POLL)
1904 struct epoll_event epev
;
1905 ACE_OS::memset (&epev
, 0, sizeof (epev
));
1906 int op
= EPOLL_CTL_ADD
;
1907 if (info
->controlled
)
1909 epev
.events
= this->reactor_mask_to_poll_event (mask
) | EPOLLONESHOT
;
1910 epev
.data
.fd
= handle
;
1912 if (::epoll_ctl (this->poll_fd_
, op
, handle
, &epev
) == -1)
1914 info
->controlled
= true;
1918 struct pollfd pfd
[1];
1921 pfd
[0].events
= this->reactor_mask_to_poll_event (mask
);
1924 if (ACE_OS::write (this->poll_fd_
, pfd
, sizeof (pfd
)) != sizeof (pfd
))
1927 #endif /* ACE_HAS_EVENT_POLL */
1929 info
->suspended
= false;
1935 ACE_Dev_Poll_Reactor::resumable_handler (void)
1937 // @@ Is this correct?
1943 ACE_Dev_Poll_Reactor::uses_event_associations (void)
1945 // Since the Dev_Poll_Reactor does not do any event associations,
1946 // this method always return false.
1951 ACE_Dev_Poll_Reactor::schedule_timer (ACE_Event_Handler
*event_handler
,
1953 const ACE_Time_Value
&delay
,
1954 const ACE_Time_Value
&interval
)
1956 ACE_TRACE ("ACE_Dev_Poll_Reactor::schedule_timer");
1958 ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token
, mon
, this->token_
, -1));
1960 if (0 != this->timer_queue_
)
1961 return this->timer_queue_
->schedule
1964 this->timer_queue_
->gettimeofday () + delay
,
1972 ACE_Dev_Poll_Reactor::reset_timer_interval (long timer_id
,
1973 const ACE_Time_Value
&interval
)
1975 ACE_TRACE ("ACE_Dev_Poll_Reactor::reset_timer_interval");
1977 ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token
, mon
, this->token_
, -1));
1979 if (0 != this->timer_queue_
)
1980 return this->timer_queue_
->reset_interval (timer_id
, interval
);
1987 ACE_Dev_Poll_Reactor::cancel_timer (ACE_Event_Handler
*handler
,
1988 int dont_call_handle_close
)
1990 ACE_TRACE ("ACE_Dev_Poll_Reactor::cancel_timer");
1992 // Don't bother waking the poll - the worse that will happen is it will
1993 // wake up for a timer that doesn't exist then go back to waiting.
1994 if ((this->timer_queue_
!= 0) && (handler
!= 0))
1995 return this->timer_queue_
->cancel (handler
, dont_call_handle_close
);
2001 ACE_Dev_Poll_Reactor::cancel_timer (long timer_id
,
2003 int dont_call_handle_close
)
2005 ACE_TRACE ("ACE_Dev_Poll_Reactor::cancel_timer");
2007 // Don't bother waking the poll - the worse that will happen is it will
2008 // wake up for a timer that doesn't exist then go back to waiting.
2009 return (this->timer_queue_
== 0
2011 : this->timer_queue_
->cancel (timer_id
,
2013 dont_call_handle_close
));
2017 ACE_Dev_Poll_Reactor::schedule_wakeup (ACE_Event_Handler
*eh
,
2018 ACE_Reactor_Mask mask
)
2020 ACE_TRACE ("ACE_Dev_Poll_Reactor::schedule_wakeup");
2022 return this->mask_ops (eh
->get_handle (), mask
, ACE_Reactor::ADD_MASK
);
2026 ACE_Dev_Poll_Reactor::schedule_wakeup (ACE_HANDLE handle
,
2027 ACE_Reactor_Mask mask
)
2029 ACE_TRACE ("ACE_Dev_Poll_Reactor::schedule_wakeup");
2031 return this->mask_ops (handle
, mask
, ACE_Reactor::ADD_MASK
);
2035 ACE_Dev_Poll_Reactor::cancel_wakeup (ACE_Event_Handler
*eh
,
2036 ACE_Reactor_Mask mask
)
2038 ACE_TRACE ("ACE_Dev_Poll_Reactor::cancel_wakeup");
2040 return this->mask_ops (eh
->get_handle (), mask
, ACE_Reactor::CLR_MASK
);
2044 ACE_Dev_Poll_Reactor::cancel_wakeup (ACE_HANDLE handle
,
2045 ACE_Reactor_Mask mask
)
2047 ACE_TRACE ("ACE_Dev_Poll_Reactor::cancel_wakeup");
2049 return this->mask_ops (handle
, mask
, ACE_Reactor::CLR_MASK
);
2053 ACE_Dev_Poll_Reactor::notify (ACE_Event_Handler
*eh
,
2054 ACE_Reactor_Mask mask
,
2055 ACE_Time_Value
*timeout
)
2057 ACE_TRACE ("ACE_Dev_Poll_Reactor::notify");
2061 // Pass over both the Event_Handler *and* the mask to allow the
2062 // caller to dictate which Event_Handler method the receiver
2063 // invokes. Note that this call can timeout.
2065 n
= this->notify_handler_
->notify (eh
, mask
, timeout
);
2067 return n
== -1 ? -1 : 0;
2071 ACE_Dev_Poll_Reactor::max_notify_iterations (int iterations
)
2073 ACE_TRACE ("ACE_Dev_Poll_Reactor::max_notify_iterations");
2075 ACE_MT (ACE_GUARD (ACE_Dev_Poll_Reactor_Token
, mon
, this->token_
));
2077 this->notify_handler_
->max_notify_iterations (iterations
);
2081 ACE_Dev_Poll_Reactor::max_notify_iterations (void)
2083 ACE_TRACE ("ACE_Dev_Poll_Reactor::max_notify_iterations");
2085 ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token
, mon
, this->token_
, -1));
2087 return this->notify_handler_
->max_notify_iterations ();
2091 ACE_Dev_Poll_Reactor::purge_pending_notifications (ACE_Event_Handler
* eh
,
2092 ACE_Reactor_Mask mask
)
2094 if (this->notify_handler_
== 0)
2097 return this->notify_handler_
->purge_pending_notifications (eh
, mask
);
2101 ACE_Dev_Poll_Reactor::find_handler (ACE_HANDLE handle
)
2103 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, 0));
2105 Event_Tuple
*info
= this->handler_rep_
.find (handle
);
2108 info
->event_handler
->add_reference ();
2109 return info
->event_handler
;
2118 ACE_Dev_Poll_Reactor::handler (ACE_HANDLE handle
,
2119 ACE_Reactor_Mask mask
,
2120 ACE_Event_Handler
**event_handler
)
2122 ACE_TRACE ("ACE_Dev_Poll_Reactor::handler");
2124 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1));
2126 Event_Tuple
*info
= this->handler_rep_
.find (handle
);
2129 && ACE_BIT_CMP_MASK (info
->mask
,
2130 mask
, // Compare all bits in the mask
2133 if (event_handler
!= 0)
2134 *event_handler
= info
->event_handler
;
2143 ACE_Dev_Poll_Reactor::handler (int signum
,
2144 ACE_Event_Handler
**eh
)
2146 ACE_TRACE ("ACE_Dev_Poll_Reactor::handler");
2148 ACE_Event_Handler
*handler
= this->signal_handler_
->handler (signum
);
2159 ACE_Dev_Poll_Reactor::initialized (void)
2161 ACE_TRACE ("ACE_Dev_Poll_Reactor::initialized");
2163 ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token
, mon
, this->token_
, false));
2165 return this->initialized_
;
2169 ACE_Dev_Poll_Reactor::size (void) const
2171 return this->handler_rep_
.size ();
2175 ACE_Dev_Poll_Reactor::lock (void)
2177 ACE_TRACE ("ACE_Dev_Poll_Reactor::lock");
2179 return this->lock_adapter_
;
2183 ACE_Dev_Poll_Reactor::wakeup_all_threads (void)
2185 ACE_TRACE ("ACE_Dev_Poll_Reactor::wakeup_all_threads");
2187 // Send a notification, but don't block if there's no one to receive
2190 ACE_Event_Handler::NULL_MASK
,
2191 (ACE_Time_Value
*) &ACE_Time_Value::zero
);
2195 ACE_Dev_Poll_Reactor::owner (ACE_thread_t
/* new_owner */,
2196 ACE_thread_t
* /* old_owner */)
2198 ACE_TRACE ("ACE_Dev_Poll_Reactor::owner");
2200 // There is no need to set the owner of the event loop. Multiple
2201 // threads may invoke the event loop simulataneously.
2207 ACE_Dev_Poll_Reactor::owner (ACE_thread_t
* /* owner */)
2209 ACE_TRACE ("ACE_Dev_Poll_Reactor::owner");
2211 // There is no need to set the owner of the event loop. Multiple
2212 // threads may invoke the event loop simulataneously.
2218 ACE_Dev_Poll_Reactor::restart (void)
2220 ACE_TRACE ("ACE_Dev_Poll_Reactor::restart");
2222 ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token
, mon
, this->token_
, false));
2224 return this->restart_
;
2228 ACE_Dev_Poll_Reactor::restart (bool r
)
2230 ACE_TRACE ("ACE_Dev_Poll_Reactor::restart");
2232 ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token
, mon
, this->token_
, false));
2234 bool current_value
= this->restart_
;
2236 return current_value
;
2240 ACE_Dev_Poll_Reactor::requeue_position (int)
2242 ACE_TRACE ("ACE_Dev_Poll_Reactor::requeue_position");
2246 ACE_Dev_Poll_Reactor::requeue_position (void)
2248 ACE_TRACE ("ACE_Dev_Poll_Reactor::requeue_position");
2250 ACE_NOTSUP_RETURN (-1);
2254 ACE_Dev_Poll_Reactor::mask_ops (ACE_Event_Handler
*event_handler
,
2255 ACE_Reactor_Mask mask
,
2258 ACE_TRACE ("ACE_Dev_Poll_Reactor::mask_ops");
2260 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1));
2262 return this->mask_ops_i (event_handler
->get_handle (), mask
, ops
);
2266 ACE_Dev_Poll_Reactor::mask_ops (ACE_HANDLE handle
,
2267 ACE_Reactor_Mask mask
,
2270 ACE_TRACE ("ACE_Dev_Poll_Reactor::mask_ops");
2272 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1));
2274 return this->mask_ops_i (handle
, mask
, ops
);
2278 ACE_Dev_Poll_Reactor::mask_ops_i (ACE_HANDLE handle
,
2279 ACE_Reactor_Mask mask
,
2282 ACE_TRACE ("ACE_Dev_Poll_Reactor::mask_ops_i");
2284 Event_Tuple
*info
= this->handler_rep_
.find (handle
);
2288 // Block out all signals until method returns.
2291 ACE_Reactor_Mask
const old_mask
= info
->mask
;
2292 ACE_Reactor_Mask new_mask
= old_mask
;
2294 // Perform GET, CLR, SET, and ADD operations on the interest/wait
2295 // set and the suspend set (if necessary).
2297 // GET = 1, Retrieve current value
2298 // SET = 2, Set value of bits to new mask (changes the entire mask)
2299 // ADD = 3, Bitwise "or" the value into the mask (only changes
2301 // CLR = 4 Bitwise "and" the negation of the value out of the mask
2302 // (only changes enabled bits)
2304 // Returns the original mask.
2308 case ACE_Reactor::GET_MASK
:
2309 // The work for this operation is done in all cases at the
2310 // beginning of the function.
2313 case ACE_Reactor::CLR_MASK
:
2314 ACE_CLR_BITS (new_mask
, mask
);
2317 case ACE_Reactor::SET_MASK
:
2321 case ACE_Reactor::ADD_MASK
:
2322 ACE_SET_BITS (new_mask
, mask
);
2329 /// Reset the mask for the given handle.
2330 info
->mask
= new_mask
;
2332 // Only attempt to alter events for the handle from the
2333 // "interest set" if it hasn't been suspended. If it has been
2334 // suspended, the revised mask will take affect when the
2335 // handle is resumed. The exception is if all the mask bits are
2336 // cleared, we can un-control the fd now.
2337 if (!info
->suspended
|| (info
->controlled
&& new_mask
== 0))
2340 short const events
= this->reactor_mask_to_poll_event (new_mask
);
2343 // Apparently events cannot be updated on-the-fly on Solaris so
2344 // remove the existing events, and then add the new ones.
2345 struct pollfd pfd
[2];
2348 pfd
[0].events
= POLLREMOVE
;
2350 pfd
[1].fd
= (events
== POLLREMOVE
? ACE_INVALID_HANDLE
: handle
);
2351 pfd
[1].events
= events
;
2354 // Change the events associated with the given file descriptor.
2355 if (ACE_OS::write (this->poll_fd_
,
2357 sizeof (pfd
)) != sizeof (pfd
))
2359 #elif defined (ACE_HAS_EVENT_POLL)
2361 struct epoll_event epev
;
2362 ACE_OS::memset (&epev
, 0, sizeof (epev
));
2365 // ACE_Event_Handler::NULL_MASK ???
2374 epev
.events
= events
| EPOLLONESHOT
;
2377 epev
.data
.fd
= handle
;
2379 if (::epoll_ctl (this->poll_fd_
, op
, handle
, &epev
) == -1)
2381 // If a handle is closed, epoll removes it from the poll set
2382 // automatically - we may not know about it yet. If that's the
2383 // case, a mod operation will fail with ENOENT. Retry it as
2384 // an add. If it's any other failure, just fail outright.
2385 if (op
!= EPOLL_CTL_MOD
|| errno
!= ENOENT
||
2386 ::epoll_ctl (this->poll_fd_
, EPOLL_CTL_ADD
, handle
, &epev
) == -1)
2389 info
->controlled
= (op
!= EPOLL_CTL_DEL
);
2394 pfd
[0].events
= events
;
2397 // Change the events associated with the given file descriptor.
2398 if (ACE_OS::write (this->poll_fd_
,
2400 sizeof (pfd
)) != sizeof (pfd
))
2402 #endif /*ACE_HAS_EVENT_POLL */
2409 ACE_Dev_Poll_Reactor::ready_ops (ACE_Event_Handler
* /* event_handler */,
2410 ACE_Reactor_Mask
/* mask */,
2413 ACE_TRACE ("ACE_Dev_Poll_Reactor::ready_ops");
2415 // Since the Dev_Poll_Reactor uses the poll result buffer, the
2416 // ready_set cannot be directly manipulated outside of the event
2418 ACE_NOTSUP_RETURN (-1);
2422 ACE_Dev_Poll_Reactor::ready_ops (ACE_HANDLE
/* handle */,
2423 ACE_Reactor_Mask
/* mask */,
2426 ACE_TRACE ("ACE_Dev_Poll_Reactor::ready_ops");
2428 // Since the Dev_Poll_Reactor uses the poll result buffer, the
2429 // ready_set cannot be directly manipulated outside of the event
2431 ACE_NOTSUP_RETURN (-1);
2435 ACE_Dev_Poll_Reactor::dump (void) const
2437 #if defined (ACE_HAS_DUMP)
2438 ACE_TRACE ("ACE_Dev_Poll_Reactor::dump");
2440 ACELIB_DEBUG ((LM_DEBUG
, ACE_BEGIN_DUMP
, this));
2441 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("restart_ = %d\n"), this->restart_
));
2442 ACELIB_DEBUG ((LM_DEBUG
,
2443 ACE_TEXT ("initialized_ = %d"),
2444 this->initialized_
));
2445 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("poll_fd_ = %d"), this->poll_fd_
));
2446 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("size_ = %u"), this->handler_rep_
.size ()));
2447 ACELIB_DEBUG ((LM_DEBUG
,
2448 ACE_TEXT ("deactivated_ = %d"),
2449 this->deactivated_
));
2450 ACELIB_DEBUG ((LM_DEBUG
, ACE_END_DUMP
));
2451 #endif /* ACE_HAS_DUMP */
2455 ACE_Dev_Poll_Reactor::reactor_mask_to_poll_event (ACE_Reactor_Mask mask
)
2457 ACE_TRACE ("ACE_Dev_Poll_Reactor::reactor_mask_to_poll_event");
2459 if (mask
== ACE_Event_Handler::NULL_MASK
)
2460 // No event. Remove from interest set.
2461 #if defined (ACE_HAS_EVENT_POLL)
2462 return EPOLL_CTL_DEL
;
2465 #endif /* ACE_HAS_EVENT_POLL */
2469 // READ, ACCEPT, and CONNECT flag will place the handle in the
2471 if (ACE_BIT_ENABLED (mask
, ACE_Event_Handler::READ_MASK
)
2472 || ACE_BIT_ENABLED (mask
, ACE_Event_Handler::ACCEPT_MASK
)
2473 || ACE_BIT_ENABLED (mask
, ACE_Event_Handler::CONNECT_MASK
))
2475 #if defined (ACE_HAS_EVENT_POLL)
2476 ACE_SET_BITS (events
, EPOLLIN
);
2478 ACE_SET_BITS (events
, POLLIN
);
2479 #endif /*ACE_HAS_EVENT_POLL*/
2482 // WRITE and CONNECT flag will place the handle in the write set.
2483 if (ACE_BIT_ENABLED (mask
, ACE_Event_Handler::WRITE_MASK
)
2484 || ACE_BIT_ENABLED (mask
, ACE_Event_Handler::CONNECT_MASK
))
2486 #if defined (ACE_HAS_EVENT_POLL)
2487 ACE_SET_BITS (events
, EPOLLOUT
);
2489 ACE_SET_BITS (events
, POLLOUT
);
2490 #endif /*ACE_HAS_EVENT_POLL*/
2493 // EXCEPT flag will place the handle in the except set.
2494 if (ACE_BIT_ENABLED (mask
, ACE_Event_Handler::EXCEPT_MASK
))
2496 #if defined (ACE_HAS_EVENT_POLL)
2497 ACE_SET_BITS (events
, EPOLLPRI
);
2499 ACE_SET_BITS (events
, POLLPRI
);
2500 #endif /*ACE_HAS_EVENT_POLL*/
2506 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
2508 void polite_sleep_hook (void *) { }
2513 ACE_Dev_Poll_Reactor::Token_Guard::acquire_quietly (ACE_Time_Value
*max_wait
)
2515 ACE_TRACE ("ACE_Dev_Poll_Reactor::Token_Guard::acquire_quietly");
2517 // Acquire the token but don't ping any waiters; just queue up politely.
2521 ACE_Time_Value tv
= ACE_OS::gettimeofday ();
2524 ACE_MT (result
= this->token_
.acquire_read (&polite_sleep_hook
,
2530 ACE_MT (result
= this->token_
.acquire_read (&polite_sleep_hook
));
2533 // Check for timeouts and errors.
2540 ACELIB_ERROR ((LM_ERROR
, ACE_TEXT("%t: %p\n"), ACE_TEXT("token acquire_read")));
2545 // We got the token and so let us mark ourselves as owner
2546 this->owner_
= true;
2552 ACE_Dev_Poll_Reactor::Token_Guard::acquire (ACE_Time_Value
*max_wait
)
2554 ACE_TRACE ("ACE_Dev_Poll_Reactor::Token_Guard::acquire");
2556 // Try to grab the token. If someone if already there, don't wake
2557 // them up, just queue up in the thread pool.
2561 ACE_Time_Value tv
= ACE_OS::gettimeofday ();
2564 ACE_MT (result
= this->token_
.acquire (0, 0, &tv
));
2568 ACE_MT (result
= this->token_
.acquire ());
2571 // Check for timeouts and errors.
2580 // We got the token and so let us mark ourseleves as owner
2581 this->owner_
= true;
2586 ACE_END_VERSIONED_NAMESPACE_DECL
2588 #endif /* ACE_HAS_EVENT_POLL || ACE_HAS_DEV_POLL */