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>
17 # include /**/ <sys/devpoll.h>
18 # endif /* ACE_LINUX */
19 # endif /* ACE_HAS_DEV_POLL */
21 #if !defined (__ACE_INLINE__)
22 # include "ace/Dev_Poll_Reactor.inl"
23 #endif /* __ACE_INLINE__ */
25 #include "ace/Handle_Set.h"
26 #include "ace/Reactor.h"
27 #include "ace/Timer_Heap.h"
28 #include "ace/Timer_Queue.h"
30 #include "ace/Reverse_Lock_T.h"
31 #include "ace/Recursive_Thread_Mutex.h"
32 #include "ace/Null_Mutex.h"
33 #include "ace/os_include/os_poll.h"
34 #include "ace/OS_NS_sys_mman.h"
35 #include "ace/Guard_T.h"
36 #include "ace/OS_NS_string.h"
37 #include "ace/OS_NS_sys_time.h"
38 #include "ace/Functor_T.h"
40 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
42 ACE_ALLOC_HOOK_DEFINE(ACE_Dev_Poll_Reactor
)
43 ACE_ALLOC_HOOK_DEFINE(ACE_Dev_Poll_Reactor::Event_Tuple
)
44 ACE_ALLOC_HOOK_DEFINE(ACE_Dev_Poll_Reactor_Notify
)
46 ACE_Dev_Poll_Reactor_Notify::ACE_Dev_Poll_Reactor_Notify ()
48 , notification_pipe_ ()
49 , max_notify_iterations_ (-1)
50 #if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE)
51 , notification_queue_ ()
52 #endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */
57 ACE_Dev_Poll_Reactor_Notify::open (ACE_Reactor_Impl
*r
,
58 ACE_Timer_Queue
* /* timer_queue */,
59 int disable_notify_pipe
)
61 ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::open");
63 if (disable_notify_pipe
== 0)
65 this->dp_reactor_
= dynamic_cast<ACE_Dev_Poll_Reactor
*> (r
);
67 if (this->dp_reactor_
== 0)
73 if (this->notification_pipe_
.open () == -1)
76 #if defined (F_SETFD) && !defined (ACE_LACKS_FCNTL)
78 if (ACE_OS::fcntl (this->notification_pipe_
.read_handle (), F_SETFD
, 1) == -1)
82 if (ACE_OS::fcntl (this->notification_pipe_
.write_handle (), F_SETFD
, 1) == -1)
88 #if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE)
89 if (notification_queue_
.open () == -1)
94 if (ACE::set_flags (this->notification_pipe_
.write_handle (),
97 #endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */
99 // Set the read handle into non-blocking mode since we need to
100 // perform a "speculative" read when determining if there are
101 // notifications to dispatch.
102 if (ACE::set_flags (this->notification_pipe_
.read_handle (),
111 ACE_Dev_Poll_Reactor_Notify::close ()
113 ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::close");
115 #if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE)
116 notification_queue_
.reset ();
117 #endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */
119 return this->notification_pipe_
.close ();
123 ACE_Dev_Poll_Reactor_Notify::notify (ACE_Event_Handler
*eh
,
124 ACE_Reactor_Mask mask
,
125 ACE_Time_Value
*timeout
)
127 ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::notify");
129 // Just consider this method a "no-op" if there's no
130 // ACE_Dev_Poll_Reactor configured.
131 if (this->dp_reactor_
== 0)
134 ACE_Notification_Buffer
buffer (eh
, mask
);
136 #if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE)
137 ACE_UNUSED_ARG (timeout
);
138 ACE_Dev_Poll_Handler_Guard
eh_guard (eh
);
140 // When using the queue, always try to write to the notify pipe. If it
141 // fills up, ignore it safely because the already-written bytes will
142 // eventually cause the notify handler to be dispatched.
143 if (-1 == this->notification_queue_
.push_new_notification (buffer
))
144 return -1; // Also decrement eh's reference count
146 // The notification has been queued, so it will be delivered at some
147 // point (and may have been already); release the refcnt guard.
150 // Now pop the pipe to force the callback for dispatching when ready. If
151 // the send fails due to a full pipe, don't fail - assume the already-sent
152 // pipe bytes will cause the entire notification queue to be processed.
153 // Note that we don't need a timeout since the pipe is already in
154 // nonblocking mode and all we want is one attempt.
155 ssize_t n
= ACE::send (this->notification_pipe_
.write_handle (),
157 1); // Only need one byte to pop the pipe
158 if (n
== -1 && (errno
!= EAGAIN
))
164 ACE_Dev_Poll_Handler_Guard
eh_guard (eh
);
166 ssize_t n
= ACE::send (this->notification_pipe_
.write_handle (),
176 #endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */
180 ACE_Dev_Poll_Reactor_Notify::dispatch_notifications (
181 int & /* number_of_active_handles */,
182 ACE_Handle_Set
& /* rd_mask */)
184 ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::dispatch_notifications");
186 // This method is unimplemented in the ACE_Dev_Poll_Reactor.
187 // Instead, the notification handler is invoked as part of the IO
188 // event set. Doing so alters the some documented semantics that
189 // state that the notifications are handled before IO events.
190 // Enforcing such semantics does not appear to be beneficial, and
191 // also serves to slow down event dispatching particularly with this
192 // ACE_Dev_Poll_Reactor.
194 ACE_NOTSUP_RETURN (-1);
198 ACE_Dev_Poll_Reactor_Notify::read_notify_pipe (ACE_HANDLE handle
,
199 ACE_Notification_Buffer
&buffer
)
201 ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::read_notify_pipe");
203 // This is a (non-blocking) "speculative" read, i.e., we attempt to
204 // read even if no event was polled on the read handle. A
205 // speculative read is necessary since notifications must be
206 // dispatched before IO events. We can avoid the speculative read
207 // by "walking" the array of pollfd structures returned from
208 // `/dev/poll' or `/dev/epoll' but that is potentially much more
209 // expensive than simply checking for an EWOULDBLOCK.
213 #if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE)
214 // The idea in the queued case is to be sure we never end up with a notify
215 // queued but no byte in the pipe. If that happens, the notify won't be
216 // dispatched. So always try to empty the pipe, read the queue, then put
217 // a byte in if needed. The notify() method is enqueueing then writing the
218 // pipe, so be sure to do it in the reverse order here to avoid a race
219 // between removing the last notification from the queue and the notify
220 // side writing its byte.
224 (void)ACE::recv (handle
, read_p
, to_read
);
226 bool more_messages_queued
= false;
227 ACE_Notification_Buffer next
;
231 result
= notification_queue_
.pop_next_notification (buffer
,
232 more_messages_queued
,
235 if (result
<= 0) // Nothing dequeued or error
238 // If it's just a wake-up, toss it and see if there's anything else.
243 // If there are more messages, ensure there's a byte in the pipe
244 // in case the notification limit stops dequeuing notifies before
245 // emptying the queue.
246 if (more_messages_queued
)
247 (void) ACE::send (this->notification_pipe_
.write_handle (),
249 1); /* one byte is enough */
252 to_read
= sizeof buffer
;
253 read_p
= (char *)&buffer
;
255 ssize_t n
= ACE::recv (handle
, read_p
, to_read
);
259 // Check to see if we've got a short read.
260 if (static_cast<size_t> (n
) != to_read
)
262 size_t remainder
= to_read
- n
;
264 // If so, try to recover by reading the remainder. If this
265 // doesn't work we're in big trouble since the input stream
266 // won't be aligned correctly. I'm not sure quite what to
267 // do at this point. It's probably best just to return -1.
268 if (ACE::recv (handle
, &read_p
[n
], remainder
) <= 0)
275 // Return -1 if things have gone seriously wrong.
276 if (n
<= 0 && (errno
!= EWOULDBLOCK
&& errno
!= EAGAIN
))
280 #endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */
285 ACE_Dev_Poll_Reactor_Notify::handle_input (ACE_HANDLE
/*handle*/)
287 ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::handle_input");
288 ACELIB_ERROR_RETURN ((LM_ERROR
, ACE_TEXT ("SHOULD NOT BE HERE.\n")), -1);
292 ACE_Dev_Poll_Reactor_Notify::notify_handle ()
294 ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::notify_handle");
296 return this->notification_pipe_
.read_handle ();
300 ACE_Dev_Poll_Reactor_Notify::is_dispatchable (ACE_Notification_Buffer
&)
302 ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::is_dispatchable");
304 ACE_NOTSUP_RETURN (-1);
308 ACE_Dev_Poll_Reactor_Notify::dispatch_notify (ACE_Notification_Buffer
&buffer
)
310 ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::dispatch_notify");
312 // If eh == 0 then another thread is unblocking the
313 // ACE_Dev_Poll_Reactor to update the ACE_Dev_Poll_Reactor's
314 // internal structures. Otherwise, we need to dispatch the
315 // appropriate handle_* method on the ACE_Event_Handler
316 // pointer we've been passed.
321 // Guard the handler's refcount. Recall that when the notify
322 // was queued, the refcount was incremented, so it need not be
323 // now. The guard insures that it is decremented properly.
324 ACE_Dev_Poll_Handler_Guard
eh_guard (buffer
.eh_
, false);
326 switch (buffer
.mask_
)
328 case ACE_Event_Handler::READ_MASK
:
329 case ACE_Event_Handler::ACCEPT_MASK
:
330 result
= buffer
.eh_
->handle_input (ACE_INVALID_HANDLE
);
332 case ACE_Event_Handler::WRITE_MASK
:
333 result
= buffer
.eh_
->handle_output (ACE_INVALID_HANDLE
);
335 case ACE_Event_Handler::EXCEPT_MASK
:
336 result
= buffer
.eh_
->handle_exception (ACE_INVALID_HANDLE
);
339 // Should we bail out if we get an invalid mask?
340 ACELIB_ERROR ((LM_ERROR
,
341 ACE_TEXT ("dispatch_notify invalid mask = %d\n"),
345 buffer
.eh_
->handle_close (ACE_INVALID_HANDLE
, buffer
.mask_
);
352 ACE_Dev_Poll_Reactor_Notify::max_notify_iterations (int iterations
)
354 ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::max_notify_iterations");
356 // Must always be > 0 or < 0 to optimize the loop exit condition.
360 this->max_notify_iterations_
= iterations
;
364 ACE_Dev_Poll_Reactor_Notify::max_notify_iterations ()
366 ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::max_notify_iterations");
368 return this->max_notify_iterations_
;
372 ACE_Dev_Poll_Reactor_Notify::purge_pending_notifications (
373 ACE_Event_Handler
*eh
,
374 ACE_Reactor_Mask mask
)
376 ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::purge_pending_notifications");
378 #if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE)
380 return notification_queue_
.purge_pending_notifications (eh
, mask
);
382 #else /* defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE) */
384 ACE_UNUSED_ARG (mask
);
385 ACE_NOTSUP_RETURN (-1);
386 #endif /* defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE) */
390 ACE_Dev_Poll_Reactor_Notify::dump () const
392 #if defined (ACE_HAS_DUMP)
393 ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::dump");
395 ACELIB_DEBUG ((LM_DEBUG
, ACE_BEGIN_DUMP
, this));
396 ACELIB_DEBUG ((LM_DEBUG
,
397 ACE_TEXT ("dp_reactor_ = %@"),
399 this->notification_pipe_
.dump ();
400 ACELIB_DEBUG ((LM_DEBUG
, ACE_END_DUMP
));
401 #endif /* ACE_HAS_DUMP */
405 ACE_Dev_Poll_Reactor_Notify::dequeue_one (ACE_Notification_Buffer
&nb
)
409 return this->read_notify_pipe (this->notify_handle (), nb
);
413 // -----------------------------------------------------------------
415 ACE_Dev_Poll_Reactor::Handler_Repository::Handler_Repository ()
420 ACE_TRACE ("ACE_Dev_Poll_Reactor::Handler_Repository::Handler_Repository");
424 ACE_Dev_Poll_Reactor::Handler_Repository::invalid_handle (
425 ACE_HANDLE handle
) const
427 ACE_TRACE ("ACE_Dev_Poll_Reactor::Handler_Repository::invalid_handle");
429 if (handle
< 0 || handle
>= this->max_size_
)
439 ACE_Dev_Poll_Reactor::Handler_Repository::handle_in_range (
440 ACE_HANDLE handle
) const
442 ACE_TRACE ("ACE_Dev_Poll_Reactor::Handler_Repository::handle_in_range");
444 if (handle
>= 0 && handle
< this->max_size_
)
454 ACE_Dev_Poll_Reactor::Handler_Repository::open (size_t size
)
456 ACE_TRACE ("ACE_Dev_Poll_Reactor::Handler_Repository::open");
458 this->max_size_
= size
;
460 // Try to allocate the memory.
461 ACE_NEW_RETURN (this->handlers_
, Event_Tuple
[size
], -1);
463 // Try to increase the number of handles if <size> is greater than
464 // the current limit.
465 return ACE::set_handle_limit (size
);
469 ACE_Dev_Poll_Reactor::Handler_Repository::unbind_all ()
471 ACE_TRACE ("ACE_Dev_Poll_Reactor::Handler_Repository::unbind_all");
473 // Unbind all of the event handlers; similar to remove_handler() on all.
475 handle
< this->max_size_
;
478 Event_Tuple
*entry
= this->find (handle
);
482 // Check for ref counting now - handle_close () may delete eh.
483 bool const requires_reference_counting
=
484 entry
->event_handler
->reference_counting_policy ().value () ==
485 ACE_Event_Handler::Reference_Counting_Policy::ENABLED
;
487 (void) entry
->event_handler
->handle_close (handle
, entry
->mask
);
488 this->unbind (handle
, requires_reference_counting
);
495 ACE_Dev_Poll_Reactor::Handler_Repository::close ()
497 ACE_TRACE ("ACE_Dev_Poll_Reactor::Handler_Repository::close");
499 if (this->handlers_
!= 0)
503 delete [] this->handlers_
;
510 ACE_Dev_Poll_Reactor::Event_Tuple
*
511 ACE_Dev_Poll_Reactor::Handler_Repository::find (ACE_HANDLE handle
)
513 ACE_TRACE ("ACE_Dev_Poll_Reactor::Handler_Repository::find");
515 Event_Tuple
*tuple
= 0;
517 // Only bother to search for the <handle> if it's in range.
518 if (!this->handle_in_range (handle
))
523 tuple
= &(this->handlers_
[handle
]);
524 if (tuple
->event_handler
== 0)
534 ACE_Dev_Poll_Reactor::Handler_Repository::bind (
536 ACE_Event_Handler
*event_handler
,
537 ACE_Reactor_Mask mask
)
539 ACE_TRACE ("ACE_Dev_Poll_Reactor::Handler_Repository::bind");
541 if (event_handler
== 0)
544 if (handle
== ACE_INVALID_HANDLE
)
545 handle
= event_handler
->get_handle ();
547 if (this->invalid_handle (handle
))
550 this->handlers_
[handle
].event_handler
= event_handler
;
551 this->handlers_
[handle
].mask
= mask
;
552 event_handler
->add_reference ();
559 ACE_Dev_Poll_Reactor::Handler_Repository::unbind (ACE_HANDLE handle
,
562 ACE_TRACE ("ACE_Dev_Poll_Reactor::Handler_Repository::unbind");
564 Event_Tuple
*entry
= this->find (handle
);
569 entry
->event_handler
->remove_reference ();
571 entry
->event_handler
= 0;
572 entry
->mask
= ACE_Event_Handler::NULL_MASK
;
573 entry
->suspended
= false;
574 entry
->controlled
= false;
579 // -----------------------------------------------------------------
581 ACE_Dev_Poll_Reactor::ACE_Dev_Poll_Reactor (ACE_Sig_Handler
*sh
,
583 int disable_notify_pipe
,
584 ACE_Reactor_Notify
*notify
,
587 : initialized_ (false)
588 , poll_fd_ (ACE_INVALID_HANDLE
)
590 #if defined (ACE_HAS_DEV_POLL)
594 #endif /* ACE_HAS_DEV_POLL */
595 , token_ (*this, s_queue
)
596 , lock_adapter_ (token_
)
599 , delete_timer_queue_ (false)
600 , signal_handler_ (0)
601 , delete_signal_handler_ (false)
602 , notify_handler_ (0)
603 , delete_notify_handler_ (false)
604 , mask_signals_ (mask_signals
)
607 ACE_TRACE ("ACE_Dev_Poll_Reactor::ACE_Dev_Poll_Reactor");
609 if (this->open (ACE::max_handles (),
615 ACELIB_ERROR ((LM_ERROR
,
617 ACE_TEXT ("ACE_Dev_Poll_Reactor::open ")
618 ACE_TEXT ("failed inside ")
619 ACE_TEXT ("ACE_Dev_Poll_Reactor::CTOR")));
622 ACE_Dev_Poll_Reactor::ACE_Dev_Poll_Reactor (size_t size
,
626 int disable_notify_pipe
,
627 ACE_Reactor_Notify
*notify
,
630 : initialized_ (false)
631 , poll_fd_ (ACE_INVALID_HANDLE
)
633 #if defined (ACE_HAS_DEV_POLL)
637 #endif /* ACE_HAS_DEV_POLL */
638 , token_ (*this, s_queue
)
639 , lock_adapter_ (token_
)
642 , delete_timer_queue_ (false)
643 , signal_handler_ (0)
644 , delete_signal_handler_ (false)
645 , notify_handler_ (0)
646 , delete_notify_handler_ (false)
647 , mask_signals_ (mask_signals
)
650 if (this->open (size
,
656 ACELIB_ERROR ((LM_ERROR
,
658 ACE_TEXT ("ACE_Dev_Poll_Reactor::open ")
659 ACE_TEXT ("failed inside ACE_Dev_Poll_Reactor::CTOR")));
662 ACE_Dev_Poll_Reactor::~ACE_Dev_Poll_Reactor ()
664 ACE_TRACE ("ACE_Dev_Poll_Reactor::~ACE_Dev_Poll_Reactor");
666 (void) this->close ();
670 ACE_Dev_Poll_Reactor::open (size_t size
,
674 int disable_notify_pipe
,
675 ACE_Reactor_Notify
*notify
)
677 ACE_TRACE ("ACE_Dev_Poll_Reactor::open");
679 ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token
, mon
, this->token_
, -1));
681 // Can't initialize ourselves more than once.
682 if (this->initialized_
)
685 #ifdef ACE_HAS_EVENT_POLL
686 ACE_OS::memset (&this->event_
, 0, sizeof (this->event_
));
687 this->event_
.data
.fd
= ACE_INVALID_HANDLE
;
688 #endif /* ACE_HAS_EVENT_POLL */
690 this->restart_
= restart
;
691 this->signal_handler_
= sh
;
692 this->timer_queue_
= tq
;
693 this->notify_handler_
= notify
;
697 // Allows the signal handler to be overridden.
698 if (this->signal_handler_
== 0)
700 ACE_NEW_RETURN (this->signal_handler_
,
704 if (this->signal_handler_
== 0)
707 this->delete_signal_handler_
= true;
710 // Allows the timer queue to be overridden.
711 if (result
!= -1 && this->timer_queue_
== 0)
713 ACE_NEW_RETURN (this->timer_queue_
,
717 if (this->timer_queue_
== 0)
720 this->delete_timer_queue_
= true;
723 // Allows the Notify_Handler to be overridden.
724 if (result
!= -1 && this->notify_handler_
== 0)
726 ACE_NEW_RETURN (this->notify_handler_
,
727 ACE_Dev_Poll_Reactor_Notify
,
730 if (this->notify_handler_
== 0)
733 this->delete_notify_handler_
= true;
736 #if defined (ACE_HAS_EVENT_POLL)
739 this->poll_fd_
= ::epoll_create (size
);
740 if (this->poll_fd_
== -1)
745 // Allocate the array before opening the device to avoid a potential
746 // resource leak if allocation fails.
747 ACE_NEW_RETURN (this->dp_fds_
,
751 // Open the `/dev/poll' character device.
752 this->poll_fd_
= ACE_OS::open ("/dev/poll", O_RDWR
);
753 if (this->poll_fd_
== ACE_INVALID_HANDLE
)
756 #endif /* ACE_HAS_EVENT_POLL */
758 if (result
!= -1 && this->handler_rep_
.open (size
) == -1)
761 // Registration of the notification handler must be done after the
762 // /dev/poll device has been fully initialized.
763 else if (this->notify_handler_
->open (this,
765 disable_notify_pipe
) == -1
766 || (disable_notify_pipe
== 0
767 && this->register_handler_i (
768 this->notify_handler_
->notify_handle (),
769 this->notify_handler_
,
770 ACE_Event_Handler::READ_MASK
) == -1))
774 // We're all set to go.
775 this->initialized_
= true;
777 // This will close down all the allocated resources properly.
778 (void) this->close ();
784 ACE_Dev_Poll_Reactor::current_info (ACE_HANDLE
, size_t & /* size */)
786 ACE_NOTSUP_RETURN (-1);
791 ACE_Dev_Poll_Reactor::set_sig_handler (ACE_Sig_Handler
*signal_handler
)
793 if (this->delete_signal_handler_
)
794 delete this->signal_handler_
;
796 this->signal_handler_
= signal_handler
;
797 this->delete_signal_handler_
= false;
803 ACE_Dev_Poll_Reactor::timer_queue (ACE_Timer_Queue
*tq
)
805 if (this->delete_timer_queue_
)
806 delete this->timer_queue_
;
807 else if (this->timer_queue_
)
808 this->timer_queue_
->close ();
810 this->timer_queue_
= tq
;
811 this->delete_timer_queue_
= false;
817 ACE_Dev_Poll_Reactor::timer_queue () const
819 return this->timer_queue_
;
823 ACE_Dev_Poll_Reactor::close ()
825 ACE_TRACE ("ACE_Dev_Poll_Reactor::close");
827 ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token
, mon
, this->token_
, -1));
831 if (this->poll_fd_
!= ACE_INVALID_HANDLE
)
833 result
= ACE_OS::close (this->poll_fd_
);
836 #if defined (ACE_HAS_EVENT_POLL)
838 ACE_OS::memset (&this->event_
, 0, sizeof (this->event_
));
839 this->event_
.data
.fd
= ACE_INVALID_HANDLE
;
843 delete [] this->dp_fds_
;
845 this->start_pfds_
= 0;
848 #endif /* ACE_HAS_EVENT_POLL */
850 if (this->delete_signal_handler_
)
852 delete this->signal_handler_
;
853 this->signal_handler_
= 0;
854 this->delete_signal_handler_
= false;
857 (void) this->handler_rep_
.close ();
859 if (this->delete_timer_queue_
)
861 delete this->timer_queue_
;
862 this->timer_queue_
= 0;
863 this->delete_timer_queue_
= false;
865 else if (this->timer_queue_
)
867 this->timer_queue_
->close ();
868 this->timer_queue_
= 0;
871 if (this->notify_handler_
!= 0)
872 this->notify_handler_
->close ();
874 if (this->delete_notify_handler_
)
876 delete this->notify_handler_
;
877 this->notify_handler_
= 0;
878 this->delete_notify_handler_
= false;
881 this->poll_fd_
= ACE_INVALID_HANDLE
;
883 this->initialized_
= false;
889 ACE_Dev_Poll_Reactor::work_pending (const ACE_Time_Value
& max_wait_time
)
891 ACE_TRACE ("ACE_Dev_Poll_Reactor::work_pending");
893 // Stash the current time
895 // The destructor of this object will automatically compute how much
896 // time elapsed since this method was called.
897 ACE_Time_Value
mwt (max_wait_time
);
898 ACE_MT (ACE_Countdown_Time
countdown (&mwt
));
900 Token_Guard
guard (this->token_
);
901 int const result
= guard
.acquire_quietly (&mwt
);
903 // If the guard is NOT the owner just return the retval
904 if (!guard
.is_owner ())
907 // Update the countdown to reflect time waiting for the mutex.
908 ACE_MT (countdown
.update ());
910 return this->work_pending_i (&mwt
);
914 ACE_Dev_Poll_Reactor::work_pending_i (ACE_Time_Value
* max_wait_time
)
916 ACE_TRACE ("ACE_Dev_Poll_Reactor::work_pending_i");
918 if (this->deactivated_
)
921 #if defined (ACE_HAS_EVENT_POLL)
922 if (this->event_
.data
.fd
!= ACE_INVALID_HANDLE
)
924 if (this->start_pfds_
!= this->end_pfds_
)
925 #endif /* ACE_HAS_EVENT_POLL */
926 return 1; // We still have work_pending (). Do not poll for
927 // additional events.
929 ACE_Time_Value
timer_buf (0);
930 ACE_Time_Value
*this_timeout
=
931 this->timer_queue_
->calculate_timeout (max_wait_time
, &timer_buf
);
933 // Check if we have timers to fire.
934 int const timers_pending
=
935 ((this_timeout
!= 0 && max_wait_time
== 0)
936 || (this_timeout
!= 0 && max_wait_time
!= 0
937 && *this_timeout
!= *max_wait_time
) ? 1 : 0);
942 : static_cast<long> (this_timeout
->msec ()));
944 #if defined (ACE_HAS_EVENT_POLL)
946 // Wait for an event.
947 int const nfds
= ::epoll_wait (this->poll_fd_
,
950 static_cast<int> (timeout
));
956 dvp
.dp_fds
= this->dp_fds_
;
957 dvp
.dp_nfds
= this->handler_rep_
.size ();
958 dvp
.dp_timeout
= timeout
; // Milliseconds
961 int const nfds
= ACE_OS::ioctl (this->poll_fd_
, DP_POLL
, &dvp
);
963 // Retrieve the results from the pollfd array.
964 this->start_pfds_
= dvp
.dp_fds
;
966 // If nfds == 0 then end_pfds_ == start_pfds_ meaning that there is
967 // no work pending. If nfds > 0 then there is work pending.
968 // Otherwise an error occurred.
970 this->end_pfds_
= this->start_pfds_
+ nfds
;
971 #endif /* ACE_HAS_EVENT_POLL */
973 // If timers are pending, override any timeout from the poll.
974 return (nfds
== 0 && timers_pending
!= 0 ? 1 : nfds
);
979 ACE_Dev_Poll_Reactor::handle_events (ACE_Time_Value
*max_wait_time
)
981 ACE_TRACE ("ACE_Dev_Poll_Reactor::handle_events");
983 // Stash the current time
985 // The destructor of this object will automatically compute how much
986 // time elapsed since this method was called.
987 ACE_Countdown_Time
countdown (max_wait_time
);
989 Token_Guard
guard (this->token_
);
990 int const result
= guard
.acquire_quietly (max_wait_time
);
992 // If the guard is NOT the owner just return the retval
993 if (!guard
.is_owner ())
996 if (this->deactivated_
)
1002 // Update the countdown to reflect time waiting for the mutex.
1003 ACE_MT (countdown
.update ());
1005 return this->handle_events_i (max_wait_time
, guard
);
1009 ACE_Dev_Poll_Reactor::handle_events_i (ACE_Time_Value
*max_wait_time
,
1012 ACE_TRACE ("ACE_Dev_Poll_Reactor::handle_events_i");
1018 // If the underlying event wait call was interrupted via the interrupt
1019 // signal (i.e. returned -1 with errno == EINTR) then the loop will
1020 // be restarted if so desired.
1023 result
= this->work_pending_i (max_wait_time
);
1024 if (result
== -1 && (this->restart_
== 0 || errno
!= EINTR
))
1025 ACELIB_ERROR ((LM_ERROR
, ACE_TEXT("%t: %p\n"), ACE_TEXT("work_pending_i")));
1027 while (result
== -1 && this->restart_
!= 0 && errno
== EINTR
);
1029 if (result
== 0 || (result
== -1 && errno
== ETIME
))
1031 else if (result
== -1)
1036 // Bail out -- we got here since the poll was interrupted.
1037 // If it was due to a signal registered through our ACE_Sig_Handler,
1038 // then it was dispatched, so we count it in the number of events
1039 // handled rather than cause an error return.
1040 if (ACE_Sig_Handler::sig_pending () != 0)
1042 ACE_Sig_Handler::sig_pending (0);
1048 // Dispatch an event.
1049 return this->dispatch (guard
);
1052 // Dispatch an event. On entry, the token is held by the caller. If an
1053 // event is found to dispatch, the token is released before dispatching it.
1055 ACE_Dev_Poll_Reactor::dispatch (Token_Guard
&guard
)
1057 ACE_TRACE ("ACE_Dev_Poll_Reactor::dispatch");
1059 // Perform the Template Method for dispatching the first located event.
1060 // We dispatch only one to effectively dispatch events concurrently.
1061 // As soon as an event is located, the token is released, allowing the
1062 // next waiter to begin getting an event while we dispatch one here.
1065 // Handle timers early since they may have higher latency
1066 // constraints than I/O handlers. Ideally, the order of
1067 // dispatching should be a strategy...
1068 if ((result
= this->dispatch_timer_handler (guard
)) != 0)
1071 // If no timer dispatched, check for an I/O event.
1072 result
= this->dispatch_io_event (guard
);
1078 ACE_Dev_Poll_Reactor::dispatch_timer_handler (Token_Guard
&guard
)
1080 using Guard_Release
= ACE_Member_Function_Command
<Token_Guard
>;
1082 Guard_Release
release(guard
, &Token_Guard::release_token
);
1083 return this->timer_queue_
->expire_single(release
);
1088 ACE_Dev_Poll_Reactor::dispatch_notification_handlers (
1089 ACE_Select_Reactor_Handle_Set
&dispatch_set
,
1090 int &number_of_active_handles
,
1091 int &number_of_handlers_dispatched
)
1093 // Check to see if the ACE_HANDLE associated with the
1094 // Dev_Poll_Reactor's notify hook is enabled. If so, it means that
1095 // one or more other threads are trying to update the
1096 // ACE_Dev_Poll_Reactor's internal tables or the notify pipe is
1097 // enabled. We'll handle all these threads and notifications, and
1098 // then break out to continue the event loop.
1101 this->notify_handler_
->dispatch_notifications (number_of_active_handles
,
1102 dispatch_set
.rd_mask_
);
1107 number_of_handlers_dispatched
+= n
;
1109 return /* this->state_changed_ ? -1 : */ 0;
1114 ACE_Dev_Poll_Reactor::dispatch_io_event (Token_Guard
&guard
)
1116 // Dispatch a ready event.
1118 // Define bits to check for while dispatching.
1119 #if defined (ACE_HAS_EVENT_POLL)
1120 const __uint32_t out_event
= EPOLLOUT
;
1121 const __uint32_t exc_event
= EPOLLPRI
;
1122 const __uint32_t in_event
= EPOLLIN
;
1123 const __uint32_t err_event
= EPOLLHUP
| EPOLLERR
;
1125 const short out_event
= POLLOUT
;
1126 const short exc_event
= POLLPRI
;
1127 const short in_event
= POLLIN
;
1128 const short err_event
= 0; // No known bits for this
1129 #endif /* ACE_HAS_EVENT_POLL */
1131 #if defined (ACE_HAS_EVENT_POLL)
1132 // epoll_wait() pulls one event which is stored in event_. If the handle
1133 // is invalid, there's no event there. Else process it. In any event, we
1134 // have the event, so clear event_ for the next thread.
1135 const ACE_HANDLE handle
= this->event_
.data
.fd
;
1136 __uint32_t revents
= this->event_
.events
;
1137 this->event_
.data
.fd
= ACE_INVALID_HANDLE
;
1138 this->event_
.events
= 0;
1139 if (handle
!= ACE_INVALID_HANDLE
)
1142 // Since the underlying event demultiplexing mechansim (`/dev/poll'
1143 // or '/dev/epoll') is stateful, and since only one result buffer is
1144 // used, all pending events (i.e. those retrieved from a previous
1145 // poll) must be dispatched before any additional event can be
1146 // polled. As such, the Dev_Poll_Reactor keeps track of the
1147 // progress of events that have been dispatched.
1149 // Select the first available handle with event (s) pending. Check for
1150 // event type in defined order of dispatch: output, exception, input.
1151 // When an event is located, clear its bit in the dispatch set. If there
1152 // are no more events for the handle, also increment the pfds pointer
1153 // to move to the next handle ready.
1155 // Notice that pfds only contains file descriptors that have
1157 struct pollfd
*& pfds
= this->start_pfds_
;
1158 const ACE_HANDLE handle
= pfds
->fd
;
1159 short &revents
= pfds
->revents
;
1160 if (pfds
< this->end_pfds_
)
1161 #endif /* ACE_HAS_EVENT_POLL */
1164 /* When using sys_epoll, we can attach arbitrary user
1165 data to the descriptor, so it can be delivered when
1166 activity is detected. Perhaps we should store event
1167 handler together with descriptor, instead of looking
1168 it up in a repository ? Could it boost performance ?
1171 // Going to access handler repo, so lock it. If the lock is
1172 // unobtainable, something is very wrong so bail out.
1173 Event_Tuple
*info
= 0;
1174 ACE_Reactor_Mask disp_mask
= 0;
1175 ACE_Event_Handler
*eh
= 0;
1176 int (ACE_Event_Handler::*callback
)(ACE_HANDLE
) = 0;
1177 #ifndef ACE_HAS_DEV_POLL
1178 bool reactor_resumes_eh
= false;
1179 #endif /* !ACE_HAS_DEV_POLL */
1181 ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1);
1182 info
= this->handler_rep_
.find (handle
);
1183 if (info
== 0) // No registered handler any longer
1186 // It is possible another thread has changed (and possibly re-armed)
1187 // this handle mask before current thread obtained the repo lock.
1188 // If that did happen and this handler is still suspended, don't
1189 // dispatch on top of another callback. See Bugzilla 4129.
1190 if (info
->suspended
)
1193 // Figure out what to do first in order to make it easier to manage
1194 // the bit twiddling and possible pfds increment before releasing
1195 // the token for dispatch.
1196 // Note that if there's an error (such as the handle was closed
1197 // without being removed from the event set) the EPOLLHUP and/or
1198 // EPOLLERR bits will be set in revents.
1199 eh
= info
->event_handler
;
1200 if (ACE_BIT_ENABLED (revents
, out_event
))
1202 disp_mask
= ACE_Event_Handler::WRITE_MASK
;
1203 callback
= &ACE_Event_Handler::handle_output
;
1204 ACE_CLR_BITS (revents
, out_event
);
1206 else if (ACE_BIT_ENABLED (revents
, exc_event
))
1208 disp_mask
= ACE_Event_Handler::EXCEPT_MASK
;
1209 callback
= &ACE_Event_Handler::handle_exception
;
1210 ACE_CLR_BITS (revents
, exc_event
);
1212 else if (ACE_BIT_ENABLED (revents
, in_event
))
1214 disp_mask
= ACE_Event_Handler::READ_MASK
;
1215 callback
= &ACE_Event_Handler::handle_input
;
1216 ACE_CLR_BITS (revents
, in_event
);
1218 else if (ACE_BIT_ENABLED (revents
, err_event
))
1220 this->remove_handler_i (handle
,
1221 ACE_Event_Handler::ALL_EVENTS_MASK
,
1223 info
->event_handler
);
1224 #ifdef ACE_HAS_DEV_POLL
1226 #endif /* ACE_HAS_DEV_POLL */
1231 ACELIB_ERROR ((LM_ERROR
,
1232 ACE_TEXT ("(%t) dispatch_io h %d unknown events 0x%x\n"),
1236 #ifdef ACE_HAS_DEV_POLL
1237 // Increment the pointer to the next element before we
1238 // release the token. Otherwise event handlers end up being
1239 // dispatched multiple times for the same poll.
1243 // With epoll, events are registered with oneshot, so the handle is
1244 // effectively suspended; future calls to epoll_wait() will select
1245 // the next event, so they're not managed here.
1246 // The hitch to this is that the notify handler is always registered
1247 // WITHOUT oneshot and is never suspended/resumed. This avoids endless
1248 // notify loops caused by the notify handler requiring a resumption
1249 // which requires the token, which requires a notify, etc. described
1250 // in Bugzilla 3714. So, never suspend the notify handler.
1251 if (eh
!= this->notify_handler_
)
1253 info
->suspended
= true;
1255 reactor_resumes_eh
=
1256 eh
->resume_handler () ==
1257 ACE_Event_Handler::ACE_REACTOR_RESUMES_HANDLER
;
1259 #endif /* ACE_HAS_DEV_POLL */
1261 } // End scope for ACE_GUARD holding repo lock
1263 int status
= 0; // gets callback status, below.
1265 // Dispatch notifies directly. The notify dispatcher locates a
1266 // notification then releases the token prior to dispatching it.
1267 // NOTE: If notify_handler_->dispatch_one() returns a fail condition
1268 // it has not releases the guard. Else, it has.
1269 if (eh
== this->notify_handler_
)
1271 ACE_Notification_Buffer b
;
1273 dynamic_cast<ACE_Dev_Poll_Reactor_Notify
*>(notify_handler_
)->dequeue_one (b
);
1276 guard
.release_token ();
1277 return notify_handler_
->dispatch_notify (b
);
1281 // Modify the reference count in an exception-safe way.
1282 // Note that eh could be the notify handler. It's not strictly
1283 // necessary to manage its refcount, but since we don't enable
1284 // the counting policy, it won't do much. Management of the
1285 // notified handlers themselves is done in the notify handler.
1286 ACE_Dev_Poll_Handler_Guard
eh_guard (eh
);
1288 // Release the reactor token before upcall.
1289 guard
.release_token ();
1291 // Dispatch the detected event; will do the repeated upcalls
1292 // if callback returns > 0, unless it's the notify handler (which
1293 // returns the number of notfies dispatched, not an indication of
1294 // re-callback requested). If anything other than the notify, come
1295 // back with either 0 or < 0.
1296 status
= this->upcall (eh
, callback
, handle
);
1298 // If the callback returned 0, epoll-based needs to resume the
1299 // suspended handler but dev/poll doesn't.
1300 // In both epoll and dev/poll cases, if the callback returns <0,
1301 // the token needs to be acquired and the handler checked and
1302 // removed if it hasn't already been.
1305 #ifdef ACE_HAS_EVENT_POLL
1306 // epoll-based effectively suspends handlers around the upcall.
1307 // If the handler must be resumed, check to be sure it's the
1308 // same handle/handler combination still.
1309 if (reactor_resumes_eh
)
1311 ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1);
1312 info
= this->handler_rep_
.find (handle
);
1313 if (info
!= 0 && info
->event_handler
== eh
)
1314 this->resume_handler_i (handle
);
1316 #endif /* ACE_HAS_EVENT_POLL */
1320 // All state in the handler repository may have changed during the
1321 // upcall. Thus, reacquire the repo lock and evaluate what's needed.
1322 // If the upcalled handler is still the handler of record for handle,
1323 // continue with checking whether or not to remove or resume the
1325 ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, 1);
1326 info
= this->handler_rep_
.find (handle
);
1327 if (info
!= 0 && info
->event_handler
== eh
)
1331 this->remove_handler_i (handle
, disp_mask
, grd
);
1332 #ifdef ACE_HAS_EVENT_POLL
1333 // epoll-based effectively suspends handlers around the upcall.
1334 // If the handler must be resumed, check to be sure it's the
1335 // same handle/handler combination still.
1336 if (reactor_resumes_eh
)
1338 info
= this->handler_rep_
.find (handle
);
1339 if (info
!= 0 && info
->event_handler
== eh
)
1341 this->resume_handler_i (handle
);
1344 #endif /* ACE_HAS_EVENT_POLL */
1348 // Scope close handles eh ref count decrement, if needed.
1357 ACE_Dev_Poll_Reactor::alertable_handle_events (ACE_Time_Value
*max_wait_time
)
1359 ACE_TRACE ("ACE_Dev_Poll_Reactor::alertable_handle_events");
1361 return this->handle_events (max_wait_time
);
1365 ACE_Dev_Poll_Reactor::handle_events (ACE_Time_Value
&max_wait_time
)
1367 ACE_TRACE ("ACE_Dev_Poll_Reactor::handle_events");
1369 return this->handle_events (&max_wait_time
);
1373 ACE_Dev_Poll_Reactor::alertable_handle_events (ACE_Time_Value
&max_wait_time
)
1375 ACE_TRACE ("ACE_Dev_Poll_Reactor::alertable_handle_events");
1377 return this->handle_events (max_wait_time
);
1381 ACE_Dev_Poll_Reactor::deactivated ()
1383 return this->deactivated_
;
1387 ACE_Dev_Poll_Reactor::deactivate (int do_stop
)
1389 this->deactivated_
= do_stop
;
1390 this->wakeup_all_threads ();
1394 ACE_Dev_Poll_Reactor::register_handler (ACE_Event_Handler
*handler
,
1395 ACE_Reactor_Mask mask
)
1397 ACE_TRACE ("ACE_Dev_Poll_Reactor::register_handler");
1399 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1));
1401 return this->register_handler_i (handler
->get_handle (),
1407 ACE_Dev_Poll_Reactor::register_handler (ACE_HANDLE handle
,
1408 ACE_Event_Handler
*event_handler
,
1409 ACE_Reactor_Mask mask
)
1411 ACE_TRACE ("ACE_Dev_Poll_Reactor::register_handler");
1413 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1));
1415 return this->register_handler_i (handle
,
1421 ACE_Dev_Poll_Reactor::register_handler_i (ACE_HANDLE handle
,
1422 ACE_Event_Handler
*event_handler
,
1423 ACE_Reactor_Mask mask
)
1425 ACE_TRACE ("ACE_Dev_Poll_Reactor::register_handler_i");
1427 if (handle
== ACE_INVALID_HANDLE
1428 || mask
== ACE_Event_Handler::NULL_MASK
)
1434 if (this->handler_rep_
.find (handle
) == 0)
1436 // Handler not present in the repository. Bind it.
1437 if (this->handler_rep_
.bind (handle
, event_handler
, mask
) != 0)
1440 #if defined (ACE_HAS_EVENT_POLL)
1442 Event_Tuple
*info
= this->handler_rep_
.find (handle
);
1444 struct epoll_event epev
;
1445 ACE_OS::memset (&epev
, 0, sizeof (epev
));
1446 static const int op
= EPOLL_CTL_ADD
;
1448 epev
.data
.fd
= handle
;
1449 epev
.events
= this->reactor_mask_to_poll_event (mask
);
1450 // All but the notify handler get registered with oneshot to facilitate
1451 // auto suspend before the upcall. See dispatch_io_event for more
1453 if (event_handler
!= this->notify_handler_
)
1454 epev
.events
|= EPOLLONESHOT
;
1456 if (::epoll_ctl (this->poll_fd_
, op
, handle
, &epev
) == -1)
1458 ACELIB_ERROR ((LM_ERROR
, ACE_TEXT("%p\n"), ACE_TEXT("epoll_ctl")));
1459 (void) this->handler_rep_
.unbind (handle
);
1462 info
->controlled
= true;
1464 #endif /* ACE_HAS_EVENT_POLL */
1468 // Handler is already present in the repository, so register it
1469 // again, possibly for different event. Add new mask to the
1471 if (this->mask_ops_i (handle
, mask
, ACE_Reactor::ADD_MASK
) == -1)
1472 ACELIB_ERROR_RETURN ((LM_ERROR
, ACE_TEXT("%p\n"), ACE_TEXT("mask_ops_i")),
1476 #ifdef ACE_HAS_DEV_POLL
1481 pfd
.events
= this->reactor_mask_to_poll_event (mask
);
1484 // Add file descriptor to the "interest set."
1485 if (ACE_OS::write (this->poll_fd_
, &pfd
, sizeof (pfd
)) != sizeof (pfd
))
1487 (void) this->handler_rep_
.unbind (handle
);
1490 #endif /*ACE_HAS_DEV_POLL*/
1492 // Note the fact that we've changed the state of the wait_set_,
1493 // which is used by the dispatching loop to determine whether it can
1494 // keep going or if it needs to reconsult select ().
1495 // this->state_changed_ = 1;
1501 ACE_Dev_Poll_Reactor::register_handler (
1502 ACE_HANDLE
/* event_handle */,
1503 ACE_HANDLE
/* io_handle */,
1504 ACE_Event_Handler
* /* event_handler */,
1505 ACE_Reactor_Mask
/* mask */)
1507 ACE_NOTSUP_RETURN (-1);
1511 ACE_Dev_Poll_Reactor::register_handler (const ACE_Handle_Set
&handle_set
,
1512 ACE_Event_Handler
*event_handler
,
1513 ACE_Reactor_Mask mask
)
1515 ACE_TRACE ("ACE_Dev_Poll_Reactor::register_handler");
1517 ACE_Handle_Set_Iterator
handle_iter (handle_set
);
1519 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1));
1521 // @@ It might be more efficient to construct a pollfd array and
1522 // pass it to the write () call in register_handler_i () only once,
1523 // instead of calling write () (a system call) once for each file
1526 for (ACE_HANDLE h
= handle_iter ();
1527 h
!= ACE_INVALID_HANDLE
;
1529 if (this->register_handler_i (h
, event_handler
, mask
) == -1)
1536 ACE_Dev_Poll_Reactor::register_handler (int signum
,
1537 ACE_Event_Handler
*new_sh
,
1538 ACE_Sig_Action
*new_disp
,
1539 ACE_Event_Handler
**old_sh
,
1540 ACE_Sig_Action
*old_disp
)
1542 ACE_TRACE ("ACE_Dev_Poll_Reactor::register_handler");
1544 return this->signal_handler_
->register_handler (signum
,
1552 ACE_Dev_Poll_Reactor::register_handler (const ACE_Sig_Set
&sigset
,
1553 ACE_Event_Handler
*new_sh
,
1554 ACE_Sig_Action
*new_disp
)
1556 ACE_TRACE ("ACE_Dev_Poll_Reactor::register_handler");
1562 for (int s
= 1; s
< ACE_NSIG
; ++s
)
1563 if ((sigset
.is_member (s
) == 1)
1564 && this->signal_handler_
->register_handler (s
,
1569 #else /* ACE_NSIG <= 0 */
1571 ACE_UNUSED_ARG (sigset
);
1572 ACE_UNUSED_ARG (new_sh
);
1573 ACE_UNUSED_ARG (new_disp
);
1575 #endif /* ACE_NSIG <= 0 */
1581 ACE_Dev_Poll_Reactor::remove_handler (ACE_Event_Handler
*handler
,
1582 ACE_Reactor_Mask mask
)
1584 ACE_TRACE ("ACE_Dev_Poll_Reactor::remove_handler");
1586 ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1);
1587 return this->remove_handler_i (handler
->get_handle (), mask
, grd
);
1591 ACE_Dev_Poll_Reactor::remove_handler (ACE_HANDLE handle
,
1592 ACE_Reactor_Mask mask
)
1594 ACE_TRACE ("ACE_Dev_Poll_Reactor::remove_handler");
1596 ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1);
1598 return this->remove_handler_i (handle
, mask
, grd
);
1601 // FUZZ: disable check_for_ACE_Guard
1603 ACE_Dev_Poll_Reactor::remove_handler_i (ACE_HANDLE handle
,
1604 ACE_Reactor_Mask mask
,
1605 ACE_Guard
<ACE_SYNCH_MUTEX
> &repo_guard
,
1606 ACE_Event_Handler
*eh
)
1607 // FUZZ: enable check_for_ACE_Guard
1609 ACE_TRACE ("ACE_Dev_Poll_Reactor::remove_handler_i");
1611 // If registered event handler not the same as eh, don't mess with
1612 // the mask, but do the proper callback and refcount when needed.
1613 bool handle_reg_changed
= true;
1614 Event_Tuple
*info
= this->handler_rep_
.find (handle
);
1615 if (info
== 0 && eh
== 0) // Nothing to work with
1617 if (info
!= 0 && (eh
== 0 || info
->event_handler
== eh
))
1619 if (this->mask_ops_i (handle
, mask
, ACE_Reactor::CLR_MASK
) == -1)
1621 handle_reg_changed
= false;
1622 eh
= info
->event_handler
;
1625 // Check for ref counting now - handle_close () may delete eh.
1626 bool const requires_reference_counting
=
1627 eh
->reference_counting_policy ().value () ==
1628 ACE_Event_Handler::Reference_Counting_Policy::ENABLED
;
1630 if (ACE_BIT_DISABLED (mask
, ACE_Event_Handler::DONT_CALL
))
1632 // It would be great if ACE_Reverse_Lock worked with the Guard.
1633 repo_guard
.release ();
1634 eh
->handle_close (handle
, mask
);
1635 repo_guard
.acquire ();
1638 // If there are no longer any outstanding events on the given handle
1639 // then remove it from the handler repository.
1640 if (!handle_reg_changed
&& info
->mask
== ACE_Event_Handler::NULL_MASK
)
1641 this->handler_rep_
.unbind (handle
, requires_reference_counting
);
1647 ACE_Dev_Poll_Reactor::remove_handler (const ACE_Handle_Set
&handle_set
,
1648 ACE_Reactor_Mask mask
)
1650 ACE_TRACE ("ACE_Dev_Poll_Reactor::remove_handler");
1652 ACE_Handle_Set_Iterator
handle_iter (handle_set
);
1653 for (ACE_HANDLE h
= handle_iter ();
1654 h
!= ACE_INVALID_HANDLE
;
1657 ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1);
1658 if (this->remove_handler_i (h
, mask
, grd
) == -1)
1665 ACE_Dev_Poll_Reactor::remove_handler (int signum
,
1666 ACE_Sig_Action
*new_disp
,
1667 ACE_Sig_Action
*old_disp
,
1670 ACE_TRACE ("ACE_Dev_Poll_Reactor::remove_handler");
1672 return this->signal_handler_
->remove_handler (signum
,
1679 ACE_Dev_Poll_Reactor::remove_handler (const ACE_Sig_Set
&sigset
)
1681 ACE_TRACE ("ACE_Dev_Poll_Reactor::remove_handler");
1687 for (int s
= 1; s
< ACE_NSIG
; ++s
)
1688 if ((sigset
.is_member (s
) == 1)
1689 && this->signal_handler_
->remove_handler (s
) == -1)
1692 #else /* ACE_NSIG <= 0 */
1694 ACE_UNUSED_ARG (sigset
);
1696 #endif /* ACE_NSIG <= 0 */
1702 ACE_Dev_Poll_Reactor::suspend_handler (ACE_Event_Handler
*event_handler
)
1704 ACE_TRACE ("ACE_Dev_Poll_Reactor::suspend_handler");
1706 if (event_handler
== 0)
1712 ACE_HANDLE handle
= event_handler
->get_handle ();
1714 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1));
1716 return this->suspend_handler_i (handle
);
1720 ACE_Dev_Poll_Reactor::suspend_handler (ACE_HANDLE handle
)
1722 ACE_TRACE ("ACE_Dev_Poll_Reactor::suspend_handler");
1724 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1));
1726 return this->suspend_handler_i (handle
);
1730 ACE_Dev_Poll_Reactor::suspend_handler (const ACE_Handle_Set
&handles
)
1732 ACE_TRACE ("ACE_Dev_Poll_Reactor::suspend_handler");
1734 ACE_Handle_Set_Iterator
handle_iter (handles
);
1737 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1));
1739 while ((h
= handle_iter ()) != ACE_INVALID_HANDLE
)
1740 if (this->suspend_handler_i (h
) == -1)
1747 ACE_Dev_Poll_Reactor::suspend_handlers ()
1749 ACE_TRACE ("ACE_Dev_Poll_Reactor::suspend_handlers");
1751 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1));
1753 size_t const len
= this->handler_rep_
.max_size ();
1755 for (size_t i
= 0; i
< len
; ++i
)
1757 Event_Tuple
*info
= this->handler_rep_
.find (i
);
1758 if (info
!= 0 && !info
->suspended
&& this->suspend_handler_i (i
) != 0)
1765 ACE_Dev_Poll_Reactor::suspend_handler_i (ACE_HANDLE handle
)
1767 ACE_TRACE ("ACE_Dev_Poll_Reactor::suspend_handler_i");
1769 Event_Tuple
*info
= this->handler_rep_
.find (handle
);
1773 if (info
->suspended
)
1774 return 0; // Already suspended. @@ Should this be an error?
1776 // Remove the handle from the "interest set."
1778 // Note that the associated event handler is still in the handler
1779 // repository, but no events will be polled on the given handle thus
1780 // no event will be dispatched to the event handler.
1782 #if defined (ACE_HAS_EVENT_POLL)
1784 struct epoll_event epev
;
1785 ACE_OS::memset (&epev
, 0, sizeof (epev
));
1786 static const int op
= EPOLL_CTL_DEL
;
1789 epev
.data
.fd
= handle
;
1791 if (::epoll_ctl (this->poll_fd_
, op
, handle
, &epev
) == -1)
1793 info
->controlled
= false;
1796 struct pollfd pfd
[1];
1799 pfd
[0].events
= POLLREMOVE
;
1802 if (ACE_OS::write (this->poll_fd_
, pfd
, sizeof (pfd
)) != sizeof (pfd
))
1805 #endif /* ACE_HAS_EVENT_POLL */
1807 info
->suspended
= true;
1813 ACE_Dev_Poll_Reactor::resume_handler (ACE_Event_Handler
*event_handler
)
1815 ACE_TRACE ("ACE_Dev_Poll_Reactor::resume_handler");
1817 if (event_handler
== 0)
1823 ACE_HANDLE handle
= event_handler
->get_handle ();
1825 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1));
1827 return this->resume_handler_i (handle
);
1831 ACE_Dev_Poll_Reactor::resume_handler (ACE_HANDLE handle
)
1833 ACE_TRACE ("ACE_Dev_Poll_Reactor::resume_handler");
1835 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1));
1837 return this->resume_handler_i (handle
);
1841 ACE_Dev_Poll_Reactor::resume_handler (const ACE_Handle_Set
&handles
)
1843 ACE_TRACE ("ACE_Dev_Poll_Reactor::resume_handler");
1845 ACE_Handle_Set_Iterator
handle_iter (handles
);
1848 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1));
1850 while ((h
= handle_iter ()) != ACE_INVALID_HANDLE
)
1851 if (this->resume_handler_i (h
) == -1)
1858 ACE_Dev_Poll_Reactor::resume_handlers ()
1860 ACE_TRACE ("ACE_Dev_Poll_Reactor::resume_handlers");
1862 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1));
1864 size_t const len
= this->handler_rep_
.max_size ();
1866 for (size_t i
= 0; i
< len
; ++i
)
1868 Event_Tuple
*info
= this->handler_rep_
.find (i
);
1869 if (info
!= 0 && info
->suspended
&& this->resume_handler_i (i
) != 0)
1877 ACE_Dev_Poll_Reactor::resume_handler_i (ACE_HANDLE handle
)
1879 ACE_TRACE ("ACE_Dev_Poll_Reactor::resume_handler_i");
1881 Event_Tuple
*info
= this->handler_rep_
.find (handle
);
1885 if (!info
->suspended
)
1888 ACE_Reactor_Mask mask
= info
->mask
;
1889 if (mask
== ACE_Event_Handler::NULL_MASK
)
1891 info
->suspended
= false;
1895 // Place the handle back in to the "interest set."
1897 // Events for the given handle will once again be polled.
1899 #if defined (ACE_HAS_EVENT_POLL)
1901 struct epoll_event epev
;
1902 ACE_OS::memset (&epev
, 0, sizeof (epev
));
1903 int op
= EPOLL_CTL_ADD
;
1904 if (info
->controlled
)
1906 epev
.events
= this->reactor_mask_to_poll_event (mask
) | EPOLLONESHOT
;
1907 epev
.data
.fd
= handle
;
1909 if (::epoll_ctl (this->poll_fd_
, op
, handle
, &epev
) == -1)
1911 info
->controlled
= true;
1915 struct pollfd pfd
[1];
1918 pfd
[0].events
= this->reactor_mask_to_poll_event (mask
);
1921 if (ACE_OS::write (this->poll_fd_
, pfd
, sizeof (pfd
)) != sizeof (pfd
))
1924 #endif /* ACE_HAS_EVENT_POLL */
1926 info
->suspended
= false;
1932 ACE_Dev_Poll_Reactor::resumable_handler ()
1934 // @@ Is this correct?
1940 ACE_Dev_Poll_Reactor::uses_event_associations ()
1942 // Since the Dev_Poll_Reactor does not do any event associations,
1943 // this method always return false.
1948 ACE_Dev_Poll_Reactor::schedule_timer (ACE_Event_Handler
*event_handler
,
1950 const ACE_Time_Value
&delay
,
1951 const ACE_Time_Value
&interval
)
1953 ACE_TRACE ("ACE_Dev_Poll_Reactor::schedule_timer");
1955 ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token
, mon
, this->token_
, -1));
1957 if (0 != this->timer_queue_
)
1958 return this->timer_queue_
->schedule
1961 this->timer_queue_
->gettimeofday () + delay
,
1969 ACE_Dev_Poll_Reactor::reset_timer_interval (long timer_id
,
1970 const ACE_Time_Value
&interval
)
1972 ACE_TRACE ("ACE_Dev_Poll_Reactor::reset_timer_interval");
1974 ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token
, mon
, this->token_
, -1));
1976 if (0 != this->timer_queue_
)
1977 return this->timer_queue_
->reset_interval (timer_id
, interval
);
1984 ACE_Dev_Poll_Reactor::cancel_timer (ACE_Event_Handler
*handler
,
1985 int dont_call_handle_close
)
1987 ACE_TRACE ("ACE_Dev_Poll_Reactor::cancel_timer");
1989 // Don't bother waking the poll - the worse that will happen is it will
1990 // wake up for a timer that doesn't exist then go back to waiting.
1991 if ((this->timer_queue_
!= 0) && (handler
!= 0))
1992 return this->timer_queue_
->cancel (handler
, dont_call_handle_close
);
1998 ACE_Dev_Poll_Reactor::cancel_timer (long timer_id
,
2000 int dont_call_handle_close
)
2002 ACE_TRACE ("ACE_Dev_Poll_Reactor::cancel_timer");
2004 // Don't bother waking the poll - the worse that will happen is it will
2005 // wake up for a timer that doesn't exist then go back to waiting.
2006 return (this->timer_queue_
== 0
2008 : this->timer_queue_
->cancel (timer_id
,
2010 dont_call_handle_close
));
2014 ACE_Dev_Poll_Reactor::schedule_wakeup (ACE_Event_Handler
*eh
,
2015 ACE_Reactor_Mask mask
)
2017 ACE_TRACE ("ACE_Dev_Poll_Reactor::schedule_wakeup");
2019 return this->mask_ops (eh
->get_handle (), mask
, ACE_Reactor::ADD_MASK
);
2023 ACE_Dev_Poll_Reactor::schedule_wakeup (ACE_HANDLE handle
,
2024 ACE_Reactor_Mask mask
)
2026 ACE_TRACE ("ACE_Dev_Poll_Reactor::schedule_wakeup");
2028 return this->mask_ops (handle
, mask
, ACE_Reactor::ADD_MASK
);
2032 ACE_Dev_Poll_Reactor::cancel_wakeup (ACE_Event_Handler
*eh
,
2033 ACE_Reactor_Mask mask
)
2035 ACE_TRACE ("ACE_Dev_Poll_Reactor::cancel_wakeup");
2037 return this->mask_ops (eh
->get_handle (), mask
, ACE_Reactor::CLR_MASK
);
2041 ACE_Dev_Poll_Reactor::cancel_wakeup (ACE_HANDLE handle
,
2042 ACE_Reactor_Mask mask
)
2044 ACE_TRACE ("ACE_Dev_Poll_Reactor::cancel_wakeup");
2046 return this->mask_ops (handle
, mask
, ACE_Reactor::CLR_MASK
);
2050 ACE_Dev_Poll_Reactor::notify (ACE_Event_Handler
*eh
,
2051 ACE_Reactor_Mask mask
,
2052 ACE_Time_Value
*timeout
)
2054 ACE_TRACE ("ACE_Dev_Poll_Reactor::notify");
2058 // Pass over both the Event_Handler *and* the mask to allow the
2059 // caller to dictate which Event_Handler method the receiver
2060 // invokes. Note that this call can timeout.
2062 n
= this->notify_handler_
->notify (eh
, mask
, timeout
);
2064 return n
== -1 ? -1 : 0;
2068 ACE_Dev_Poll_Reactor::max_notify_iterations (int iterations
)
2070 ACE_TRACE ("ACE_Dev_Poll_Reactor::max_notify_iterations");
2072 ACE_MT (ACE_GUARD (ACE_Dev_Poll_Reactor_Token
, mon
, this->token_
));
2074 this->notify_handler_
->max_notify_iterations (iterations
);
2078 ACE_Dev_Poll_Reactor::max_notify_iterations ()
2080 ACE_TRACE ("ACE_Dev_Poll_Reactor::max_notify_iterations");
2082 ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token
, mon
, this->token_
, -1));
2084 return this->notify_handler_
->max_notify_iterations ();
2088 ACE_Dev_Poll_Reactor::purge_pending_notifications (ACE_Event_Handler
* eh
,
2089 ACE_Reactor_Mask mask
)
2091 if (this->notify_handler_
== 0)
2094 return this->notify_handler_
->purge_pending_notifications (eh
, mask
);
2098 ACE_Dev_Poll_Reactor::find_handler (ACE_HANDLE handle
)
2100 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, 0));
2102 Event_Tuple
*info
= this->handler_rep_
.find (handle
);
2105 info
->event_handler
->add_reference ();
2106 return info
->event_handler
;
2115 ACE_Dev_Poll_Reactor::handler (ACE_HANDLE handle
,
2116 ACE_Reactor_Mask mask
,
2117 ACE_Event_Handler
**event_handler
)
2119 ACE_TRACE ("ACE_Dev_Poll_Reactor::handler");
2121 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1));
2123 Event_Tuple
*info
= this->handler_rep_
.find (handle
);
2126 && ACE_BIT_CMP_MASK (info
->mask
,
2127 mask
, // Compare all bits in the mask
2130 if (event_handler
!= 0)
2131 *event_handler
= info
->event_handler
;
2140 ACE_Dev_Poll_Reactor::handler (int signum
,
2141 ACE_Event_Handler
**eh
)
2143 ACE_TRACE ("ACE_Dev_Poll_Reactor::handler");
2145 ACE_Event_Handler
*handler
= this->signal_handler_
->handler (signum
);
2156 ACE_Dev_Poll_Reactor::initialized ()
2158 ACE_TRACE ("ACE_Dev_Poll_Reactor::initialized");
2160 ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token
, mon
, this->token_
, false));
2162 return this->initialized_
;
2166 ACE_Dev_Poll_Reactor::size () const
2168 return this->handler_rep_
.size ();
2172 ACE_Dev_Poll_Reactor::lock ()
2174 ACE_TRACE ("ACE_Dev_Poll_Reactor::lock");
2176 return this->lock_adapter_
;
2180 ACE_Dev_Poll_Reactor::wakeup_all_threads ()
2182 ACE_TRACE ("ACE_Dev_Poll_Reactor::wakeup_all_threads");
2184 // Send a notification, but don't block if there's no one to receive
2187 ACE_Event_Handler::NULL_MASK
,
2188 (ACE_Time_Value
*) &ACE_Time_Value::zero
);
2192 ACE_Dev_Poll_Reactor::owner (ACE_thread_t
/* new_owner */,
2193 ACE_thread_t
* /* old_owner */)
2195 ACE_TRACE ("ACE_Dev_Poll_Reactor::owner");
2197 // There is no need to set the owner of the event loop. Multiple
2198 // threads may invoke the event loop simulataneously.
2204 ACE_Dev_Poll_Reactor::owner (ACE_thread_t
* /* owner */)
2206 ACE_TRACE ("ACE_Dev_Poll_Reactor::owner");
2208 // There is no need to set the owner of the event loop. Multiple
2209 // threads may invoke the event loop simulataneously.
2215 ACE_Dev_Poll_Reactor::restart ()
2217 ACE_TRACE ("ACE_Dev_Poll_Reactor::restart");
2219 ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token
, mon
, this->token_
, false));
2221 return this->restart_
;
2225 ACE_Dev_Poll_Reactor::restart (bool r
)
2227 ACE_TRACE ("ACE_Dev_Poll_Reactor::restart");
2229 ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token
, mon
, this->token_
, false));
2231 bool current_value
= this->restart_
;
2233 return current_value
;
2237 ACE_Dev_Poll_Reactor::requeue_position (int)
2239 ACE_TRACE ("ACE_Dev_Poll_Reactor::requeue_position");
2243 ACE_Dev_Poll_Reactor::requeue_position ()
2245 ACE_TRACE ("ACE_Dev_Poll_Reactor::requeue_position");
2247 ACE_NOTSUP_RETURN (-1);
2251 ACE_Dev_Poll_Reactor::mask_ops (ACE_Event_Handler
*event_handler
,
2252 ACE_Reactor_Mask mask
,
2255 ACE_TRACE ("ACE_Dev_Poll_Reactor::mask_ops");
2257 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1));
2259 return this->mask_ops_i (event_handler
->get_handle (), mask
, ops
);
2263 ACE_Dev_Poll_Reactor::mask_ops (ACE_HANDLE handle
,
2264 ACE_Reactor_Mask mask
,
2267 ACE_TRACE ("ACE_Dev_Poll_Reactor::mask_ops");
2269 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, grd
, this->repo_lock_
, -1));
2271 return this->mask_ops_i (handle
, mask
, ops
);
2275 ACE_Dev_Poll_Reactor::mask_ops_i (ACE_HANDLE handle
,
2276 ACE_Reactor_Mask mask
,
2279 ACE_TRACE ("ACE_Dev_Poll_Reactor::mask_ops_i");
2281 Event_Tuple
*info
= this->handler_rep_
.find (handle
);
2285 // Block out all signals until method returns.
2288 ACE_Reactor_Mask
const old_mask
= info
->mask
;
2289 ACE_Reactor_Mask new_mask
= old_mask
;
2291 // Perform GET, CLR, SET, and ADD operations on the interest/wait
2292 // set and the suspend set (if necessary).
2294 // GET = 1, Retrieve current value
2295 // SET = 2, Set value of bits to new mask (changes the entire mask)
2296 // ADD = 3, Bitwise "or" the value into the mask (only changes
2298 // CLR = 4 Bitwise "and" the negation of the value out of the mask
2299 // (only changes enabled bits)
2301 // Returns the original mask.
2305 case ACE_Reactor::GET_MASK
:
2306 // The work for this operation is done in all cases at the
2307 // beginning of the function.
2310 case ACE_Reactor::CLR_MASK
:
2311 ACE_CLR_BITS (new_mask
, mask
);
2314 case ACE_Reactor::SET_MASK
:
2318 case ACE_Reactor::ADD_MASK
:
2319 ACE_SET_BITS (new_mask
, mask
);
2326 /// Reset the mask for the given handle.
2327 info
->mask
= new_mask
;
2329 // Only attempt to alter events for the handle from the
2330 // "interest set" if it hasn't been suspended. If it has been
2331 // suspended, the revised mask will take affect when the
2332 // handle is resumed. The exception is if all the mask bits are
2333 // cleared, we can un-control the fd now.
2334 if (!info
->suspended
|| (info
->controlled
&& new_mask
== 0))
2336 short const events
= this->reactor_mask_to_poll_event (new_mask
);
2338 #if defined (ACE_HAS_EVENT_POLL)
2340 struct epoll_event epev
;
2341 ACE_OS::memset (&epev
, 0, sizeof (epev
));
2344 // ACE_Event_Handler::NULL_MASK ???
2353 epev
.events
= events
| EPOLLONESHOT
;
2356 epev
.data
.fd
= handle
;
2358 if (::epoll_ctl (this->poll_fd_
, op
, handle
, &epev
) == -1)
2360 // If a handle is closed, epoll removes it from the poll set
2361 // automatically - we may not know about it yet. If that's the
2362 // case, a mod operation will fail with ENOENT. Retry it as
2363 // an add. If it's any other failure, just fail outright.
2364 if (op
!= EPOLL_CTL_MOD
|| errno
!= ENOENT
||
2365 ::epoll_ctl (this->poll_fd_
, EPOLL_CTL_ADD
, handle
, &epev
) == -1)
2368 info
->controlled
= (op
!= EPOLL_CTL_DEL
);
2373 pfd
[0].events
= events
;
2376 // Change the events associated with the given file descriptor.
2377 if (ACE_OS::write (this->poll_fd_
,
2379 sizeof (pfd
)) != sizeof (pfd
))
2381 #endif /*ACE_HAS_EVENT_POLL */
2388 ACE_Dev_Poll_Reactor::ready_ops (ACE_Event_Handler
* /* event_handler */,
2389 ACE_Reactor_Mask
/* mask */,
2392 ACE_TRACE ("ACE_Dev_Poll_Reactor::ready_ops");
2394 // Since the Dev_Poll_Reactor uses the poll result buffer, the
2395 // ready_set cannot be directly manipulated outside of the event
2397 ACE_NOTSUP_RETURN (-1);
2401 ACE_Dev_Poll_Reactor::ready_ops (ACE_HANDLE
/* handle */,
2402 ACE_Reactor_Mask
/* mask */,
2405 ACE_TRACE ("ACE_Dev_Poll_Reactor::ready_ops");
2407 // Since the Dev_Poll_Reactor uses the poll result buffer, the
2408 // ready_set cannot be directly manipulated outside of the event
2410 ACE_NOTSUP_RETURN (-1);
2414 ACE_Dev_Poll_Reactor::dump () const
2416 #if defined (ACE_HAS_DUMP)
2417 ACE_TRACE ("ACE_Dev_Poll_Reactor::dump");
2419 ACELIB_DEBUG ((LM_DEBUG
, ACE_BEGIN_DUMP
, this));
2420 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("restart_ = %d\n"), this->restart_
));
2421 ACELIB_DEBUG ((LM_DEBUG
,
2422 ACE_TEXT ("initialized_ = %d"),
2423 this->initialized_
));
2424 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("poll_fd_ = %d"), this->poll_fd_
));
2425 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("size_ = %u"), this->handler_rep_
.size ()));
2426 ACELIB_DEBUG ((LM_DEBUG
,
2427 ACE_TEXT ("deactivated_ = %d"),
2428 this->deactivated_
));
2429 ACELIB_DEBUG ((LM_DEBUG
, ACE_END_DUMP
));
2430 #endif /* ACE_HAS_DUMP */
2434 ACE_Dev_Poll_Reactor::reactor_mask_to_poll_event (ACE_Reactor_Mask mask
)
2436 ACE_TRACE ("ACE_Dev_Poll_Reactor::reactor_mask_to_poll_event");
2438 if (mask
== ACE_Event_Handler::NULL_MASK
)
2439 // No event. Remove from interest set.
2440 #if defined (ACE_HAS_EVENT_POLL)
2441 return EPOLL_CTL_DEL
;
2444 #endif /* ACE_HAS_EVENT_POLL */
2448 // READ, ACCEPT, and CONNECT flag will place the handle in the
2450 if (ACE_BIT_ENABLED (mask
, ACE_Event_Handler::READ_MASK
)
2451 || ACE_BIT_ENABLED (mask
, ACE_Event_Handler::ACCEPT_MASK
)
2452 || ACE_BIT_ENABLED (mask
, ACE_Event_Handler::CONNECT_MASK
))
2454 #if defined (ACE_HAS_EVENT_POLL)
2455 ACE_SET_BITS (events
, EPOLLIN
);
2457 ACE_SET_BITS (events
, POLLIN
);
2458 #endif /*ACE_HAS_EVENT_POLL*/
2461 // WRITE and CONNECT flag will place the handle in the write set.
2462 if (ACE_BIT_ENABLED (mask
, ACE_Event_Handler::WRITE_MASK
)
2463 || ACE_BIT_ENABLED (mask
, ACE_Event_Handler::CONNECT_MASK
))
2465 #if defined (ACE_HAS_EVENT_POLL)
2466 ACE_SET_BITS (events
, EPOLLOUT
);
2468 ACE_SET_BITS (events
, POLLOUT
);
2469 #endif /*ACE_HAS_EVENT_POLL*/
2472 // EXCEPT flag will place the handle in the except set.
2473 if (ACE_BIT_ENABLED (mask
, ACE_Event_Handler::EXCEPT_MASK
))
2475 #if defined (ACE_HAS_EVENT_POLL)
2476 ACE_SET_BITS (events
, EPOLLPRI
);
2478 ACE_SET_BITS (events
, POLLPRI
);
2479 #endif /*ACE_HAS_EVENT_POLL*/
2485 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
2487 void polite_sleep_hook (void *) { }
2492 ACE_Dev_Poll_Reactor::Token_Guard::acquire_quietly (ACE_Time_Value
*max_wait
)
2494 ACE_TRACE ("ACE_Dev_Poll_Reactor::Token_Guard::acquire_quietly");
2496 // Acquire the token but don't ping any waiters; just queue up politely.
2500 ACE_Time_Value tv
= ACE_OS::gettimeofday ();
2503 ACE_MT (result
= this->token_
.acquire_read (&polite_sleep_hook
,
2509 ACE_MT (result
= this->token_
.acquire_read (&polite_sleep_hook
));
2512 // Check for timeouts and errors.
2519 ACELIB_ERROR ((LM_ERROR
, ACE_TEXT("%t: %p\n"), ACE_TEXT("token acquire_read")));
2524 // We got the token and so let us mark ourselves as owner
2525 this->owner_
= true;
2531 ACE_Dev_Poll_Reactor::Token_Guard::acquire (ACE_Time_Value
*max_wait
)
2533 ACE_TRACE ("ACE_Dev_Poll_Reactor::Token_Guard::acquire");
2535 // Try to grab the token. If someone if already there, don't wake
2536 // them up, just queue up in the thread pool.
2540 ACE_Time_Value tv
= ACE_OS::gettimeofday ();
2543 ACE_MT (result
= this->token_
.acquire (0, 0, &tv
));
2547 ACE_MT (result
= this->token_
.acquire ());
2550 // Check for timeouts and errors.
2559 // We got the token and so let us mark ourseleves as owner
2560 this->owner_
= true;
2565 ACE_END_VERSIONED_NAMESPACE_DECL
2567 #endif /* ACE_HAS_EVENT_POLL || ACE_HAS_DEV_POLL */