Also use Objects as part of an operation but as a result don't generate Any operation...
[ACE_TAO.git] / ACE / ace / Dev_Poll_Reactor.cpp
blob55cb4d4d5a37ff5f7cb6fc7329034a934c8d7aee
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>
18 # else
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"
32 #include "ace/ACE.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)
50 : dp_reactor_ (0)
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 */
59 int
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)
72 errno = EINVAL;
73 return -1;
76 if (this->notification_pipe_.open () == -1)
77 return -1;
79 #if defined (F_SETFD) && !defined (ACE_LACKS_FCNTL)
80 // close-on-exec
81 if (ACE_OS::fcntl (this->notification_pipe_.read_handle (), F_SETFD, 1) == -1)
83 return -1;
85 if (ACE_OS::fcntl (this->notification_pipe_.write_handle (), F_SETFD, 1) == -1)
87 return -1;
89 #endif /* F_SETFD */
91 #if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE)
92 if (notification_queue_.open () == -1)
94 return -1;
97 if (ACE::set_flags (this->notification_pipe_.write_handle (),
98 ACE_NONBLOCK) == -1)
99 return -1;
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 (),
106 ACE_NONBLOCK) == -1)
107 return -1;
110 return 0;
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)
135 return 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.
151 eh_guard.release ();
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 (),
159 (char *) &buffer,
160 1); // Only need one byte to pop the pipe
161 if (n == -1 && (errno != EAGAIN))
162 return -1;
164 return 0;
165 #else
167 ACE_Dev_Poll_Handler_Guard eh_guard (eh);
169 ssize_t n = ACE::send (this->notification_pipe_.write_handle (),
170 (char *) &buffer,
171 sizeof buffer,
172 timeout);
173 if (n == -1)
174 return -1;
176 eh_guard.release ();
178 return 0;
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.
213 size_t to_read;
214 char *read_p;
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.
224 char b[1024];
225 read_p = b;
226 to_read = sizeof(b);
227 (void)ACE::recv (handle, read_p, to_read);
229 bool more_messages_queued = false;
230 ACE_Notification_Buffer next;
231 int result = 1;
232 while (result == 1)
234 result = notification_queue_.pop_next_notification (buffer,
235 more_messages_queued,
236 next);
238 if (result <= 0) // Nothing dequeued or error
239 return result;
241 // If it's just a wake-up, toss it and see if there's anything else.
242 if (buffer.eh_ != 0)
243 break;
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 (),
251 (char *)&next,
252 1); /* one byte is enough */
253 return 1;
254 #else
255 to_read = sizeof buffer;
256 read_p = (char *)&buffer;
258 ssize_t n = ACE::recv (handle, read_p, to_read);
260 if (n > 0)
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)
272 return -1;
275 return 1;
278 // Return -1 if things have gone seriously wrong.
279 if (n <= 0 && (errno != EWOULDBLOCK && errno != EAGAIN))
280 return -1;
282 return 0;
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);
294 ACE_HANDLE
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.
320 if (buffer.eh_ != 0)
322 int result = 0;
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);
334 break;
335 case ACE_Event_Handler::WRITE_MASK:
336 result = buffer.eh_->handle_output (ACE_INVALID_HANDLE);
337 break;
338 case ACE_Event_Handler::EXCEPT_MASK:
339 result = buffer.eh_->handle_exception (ACE_INVALID_HANDLE);
340 break;
341 default:
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"),
345 buffer.mask_));
347 if (result == -1)
348 buffer.eh_->handle_close (ACE_INVALID_HANDLE, buffer.mask_);
351 return 1;
354 void
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.
360 if (iterations == 0)
361 iterations = 1;
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) */
386 ACE_UNUSED_ARG (eh);
387 ACE_UNUSED_ARG (mask);
388 ACE_NOTSUP_RETURN (-1);
389 #endif /* defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE) */
392 void
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_ = %@"),
401 this->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)
410 nb.eh_ = 0;
411 nb.mask_ = 0;
412 return this->read_notify_pipe (this->notify_handle (), nb);
416 // -----------------------------------------------------------------
418 ACE_Dev_Poll_Reactor::Handler_Repository::Handler_Repository (void)
419 : size_ (0),
420 max_size_ (0),
421 handlers_ (0)
423 ACE_TRACE ("ACE_Dev_Poll_Reactor::Handler_Repository::Handler_Repository");
426 bool
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_)
434 errno = EINVAL;
435 return true;
437 else
438 return false;
441 bool
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_)
448 return true;
449 else
451 errno = EINVAL;
452 return false;
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.
477 for (int handle = 0;
478 handle < this->max_size_;
479 ++handle)
481 Event_Tuple *entry = this->find (handle);
482 if (entry == 0)
483 continue;
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);
494 return 0;
498 ACE_Dev_Poll_Reactor::Handler_Repository::close (void)
500 ACE_TRACE ("ACE_Dev_Poll_Reactor::Handler_Repository::close");
502 if (this->handlers_ != 0)
504 this->unbind_all ();
506 delete [] this->handlers_;
507 this->handlers_ = 0;
510 return 0;
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))
523 errno = ERANGE;
524 return 0;
527 tuple = &(this->handlers_[handle]);
528 if (tuple->event_handler == 0)
530 errno = ENOENT;
531 tuple = 0;
534 return tuple;
538 ACE_Dev_Poll_Reactor::Handler_Repository::bind (
539 ACE_HANDLE handle,
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)
546 return -1;
548 if (handle == ACE_INVALID_HANDLE)
549 handle = event_handler->get_handle ();
551 if (this->invalid_handle (handle))
552 return -1;
554 this->handlers_[handle].event_handler = event_handler;
555 this->handlers_[handle].mask = mask;
556 event_handler->add_reference ();
557 ++this->size_;
559 return 0;
563 ACE_Dev_Poll_Reactor::Handler_Repository::unbind (ACE_HANDLE handle,
564 bool decr_refcnt)
566 ACE_TRACE ("ACE_Dev_Poll_Reactor::Handler_Repository::unbind");
568 Event_Tuple *entry = this->find (handle);
569 if (entry == 0)
570 return -1;
572 if (decr_refcnt)
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;
579 --this->size_;
580 return 0;
583 // -----------------------------------------------------------------
585 ACE_Dev_Poll_Reactor::ACE_Dev_Poll_Reactor (ACE_Sig_Handler *sh,
586 ACE_Timer_Queue *tq,
587 int disable_notify_pipe,
588 ACE_Reactor_Notify *notify,
589 int mask_signals,
590 int s_queue)
591 : initialized_ (false)
592 , poll_fd_ (ACE_INVALID_HANDLE)
593 // , ready_set_ ()
594 #if defined (ACE_HAS_DEV_POLL)
595 , dp_fds_ (0)
596 , start_pfds_ (0)
597 , end_pfds_ (0)
598 #endif /* ACE_HAS_DEV_POLL */
599 , token_ (*this, s_queue)
600 , lock_adapter_ (token_)
601 , deactivated_ (0)
602 , timer_queue_ (0)
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)
609 , restart_ (0)
611 ACE_TRACE ("ACE_Dev_Poll_Reactor::ACE_Dev_Poll_Reactor");
613 if (this->open (ACE::max_handles (),
617 disable_notify_pipe,
618 notify) == -1)
619 ACELIB_ERROR ((LM_ERROR,
620 ACE_TEXT ("%p\n"),
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,
627 bool rs,
628 ACE_Sig_Handler *sh,
629 ACE_Timer_Queue *tq,
630 int disable_notify_pipe,
631 ACE_Reactor_Notify *notify,
632 int mask_signals,
633 int s_queue)
634 : initialized_ (false)
635 , poll_fd_ (ACE_INVALID_HANDLE)
636 // , ready_set_ ()
637 #if defined (ACE_HAS_DEV_POLL)
638 , dp_fds_ (0)
639 , start_pfds_ (0)
640 , end_pfds_ (0)
641 #endif /* ACE_HAS_DEV_POLL */
642 , token_ (*this, s_queue)
643 , lock_adapter_ (token_)
644 , deactivated_ (0)
645 , timer_queue_ (0)
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)
652 , restart_ (0)
654 if (this->open (size,
658 disable_notify_pipe,
659 notify) == -1)
660 ACELIB_ERROR ((LM_ERROR,
661 ACE_TEXT ("%p\n"),
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,
675 bool restart,
676 ACE_Sig_Handler *sh,
677 ACE_Timer_Queue *tq,
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_)
687 return -1;
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;
699 int result = 0;
701 // Allows the signal handler to be overridden.
702 if (this->signal_handler_ == 0)
704 ACE_NEW_RETURN (this->signal_handler_,
705 ACE_Sig_Handler,
706 -1);
708 if (this->signal_handler_ == 0)
709 result = -1;
710 else
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_,
718 ACE_Timer_Heap,
719 -1);
721 if (this->timer_queue_ == 0)
722 result = -1;
723 else
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,
732 -1);
734 if (this->notify_handler_ == 0)
735 result = -1;
736 else
737 this->delete_notify_handler_ = true;
740 #if defined (ACE_HAS_EVENT_POLL)
742 // Initialize epoll:
743 this->poll_fd_ = ::epoll_create (size);
744 if (this->poll_fd_ == -1)
745 result = -1;
747 #else
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_,
752 pollfd[size],
753 -1);
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)
758 result = -1;
760 #endif /* ACE_HAS_EVENT_POLL */
762 if (result != -1 && this->handler_rep_.open (size) == -1)
763 result = -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))
775 result = -1;
777 if (result != -1)
778 // We're all set to go.
779 this->initialized_ = true;
780 else
781 // This will close down all the allocated resources properly.
782 (void) this->close ();
784 return result;
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;
803 return 0;
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;
817 return 0;
820 ACE_Timer_Queue *
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));
833 int result = 0;
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;
845 #else
847 delete [] this->dp_fds_;
848 this->dp_fds_ = 0;
849 this->start_pfds_ = 0;
850 this->end_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;
889 return result;
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 ())
909 return result;
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_)
923 return 0;
925 #if defined (ACE_HAS_EVENT_POLL)
926 if (this->event_.data.fd != ACE_INVALID_HANDLE)
927 #else
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);
943 long const timeout =
944 (this_timeout == 0
945 ? -1 /* Infinity */
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_,
952 &this->event_,
954 static_cast<int> (timeout));
956 #else
958 struct dvpoll dvp;
960 dvp.dp_fds = this->dp_fds_;
961 dvp.dp_nfds = this->handler_rep_.size ();
962 dvp.dp_timeout = timeout; // Milliseconds
964 // Poll for events
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.
973 if (nfds > -1)
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 ())
998 return result;
1000 if (this->deactivated_)
1002 errno = ESHUTDOWN;
1003 return -1;
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,
1014 Token_Guard &guard)
1016 ACE_TRACE ("ACE_Dev_Poll_Reactor::handle_events_i");
1018 int result = 0;
1020 // Poll for events
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))
1034 return 0;
1035 else if (result == -1)
1037 if (errno != EINTR)
1038 return -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);
1047 return 1;
1049 return -1;
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.
1067 int result = 0;
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)
1073 return result;
1075 // If no timer dispatched, check for an I/O event.
1076 result = this->dispatch_io_event (guard);
1078 return result;
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);
1090 #if 0
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.
1104 const int n =
1105 this->notify_handler_->dispatch_notifications (number_of_active_handles,
1106 dispatch_set.rd_mask_);
1108 if (n == -1)
1109 return -1;
1110 else
1111 number_of_handlers_dispatched += n;
1113 return /* this->state_changed_ ? -1 : */ 0;
1115 #endif /* 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;
1129 #else
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)
1146 #else
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
1161 // received events.
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
1187 return 0;
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)
1194 return 0;
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,
1225 grd,
1226 info->event_handler);
1227 #ifdef ACE_HAS_DEV_POLL
1228 ++pfds;
1229 #endif /* ACE_HAS_DEV_POLL */
1230 return 1;
1232 else
1234 ACELIB_ERROR ((LM_ERROR,
1235 ACE_TEXT ("(%t) dispatch_io h %d unknown events 0x%x\n"),
1236 handle, revents));
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.
1243 if (revents == 0)
1244 ++pfds;
1245 #else
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;
1275 status =
1276 dynamic_cast<ACE_Dev_Poll_Reactor_Notify *>(notify_handler_)->dequeue_one (b);
1277 if (status == -1)
1278 return status;
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.
1306 if (status == 0)
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 */
1320 return 1;
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
1327 // handler.
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)
1332 if (status < 0)
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.
1353 return 1;
1356 return 0;
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_;
1389 void
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 (),
1405 handler,
1406 mask);
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,
1419 event_handler,
1420 mask);
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)
1433 errno = EINVAL;
1434 return -1;
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)
1441 return -1;
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
1455 // information.
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);
1463 return -1;
1465 info->controlled = true;
1467 #endif /* ACE_HAS_EVENT_POLL */
1469 else
1471 // Handler is already present in the repository, so register it
1472 // again, possibly for different event. Add new mask to the
1473 // current one.
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")),
1476 -1);
1479 #ifdef ACE_HAS_DEV_POLL
1481 struct pollfd pfd;
1483 pfd.fd = handle;
1484 pfd.events = this->reactor_mask_to_poll_event (mask);
1485 pfd.revents = 0;
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);
1491 return -1;
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;
1500 return 0;
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
1527 // descriptor.
1529 for (ACE_HANDLE h = handle_iter ();
1530 h != ACE_INVALID_HANDLE;
1531 h = handle_iter ())
1532 if (this->register_handler_i (h, event_handler, mask) == -1)
1533 return -1;
1535 return 0;
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,
1548 new_sh,
1549 new_disp,
1550 old_sh,
1551 old_disp);
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");
1561 int result = 0;
1563 #if (ACE_NSIG > 0)
1565 for (int s = 1; s < ACE_NSIG; ++s)
1566 if ((sigset.is_member (s) == 1)
1567 && this->signal_handler_->register_handler (s,
1568 new_sh,
1569 new_disp) == -1)
1570 result = -1;
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 */
1580 return result;
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
1619 return -1;
1620 if (info != 0 && (eh == 0 || info->event_handler == eh))
1622 if (this->mask_ops_i (handle, mask, ACE_Reactor::CLR_MASK) == -1)
1623 return -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);
1646 return 0;
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;
1658 h = handle_iter ())
1660 ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, grd, this->repo_lock_, -1);
1661 if (this->remove_handler_i (h, mask, grd) == -1)
1662 return -1;
1664 return 0;
1668 ACE_Dev_Poll_Reactor::remove_handler (int signum,
1669 ACE_Sig_Action *new_disp,
1670 ACE_Sig_Action *old_disp,
1671 int sigkey)
1673 ACE_TRACE ("ACE_Dev_Poll_Reactor::remove_handler");
1675 return this->signal_handler_->remove_handler (signum,
1676 new_disp,
1677 old_disp,
1678 sigkey);
1682 ACE_Dev_Poll_Reactor::remove_handler (const ACE_Sig_Set &sigset)
1684 ACE_TRACE ("ACE_Dev_Poll_Reactor::remove_handler");
1686 int result = 0;
1688 #if (ACE_NSIG > 0)
1690 for (int s = 1; s < ACE_NSIG; ++s)
1691 if ((sigset.is_member (s) == 1)
1692 && this->signal_handler_->remove_handler (s) == -1)
1693 result = -1;
1695 #else /* ACE_NSIG <= 0 */
1697 ACE_UNUSED_ARG (sigset);
1699 #endif /* ACE_NSIG <= 0 */
1701 return result;
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)
1711 errno = EINVAL;
1712 return -1;
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);
1738 ACE_HANDLE h;
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)
1744 return -1;
1746 return 0;
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)
1762 return -1;
1764 return 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);
1773 if (info == 0)
1774 return -1;
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;
1791 epev.events = 0;
1792 epev.data.fd = handle;
1794 if (::epoll_ctl (this->poll_fd_, op, handle, &epev) == -1)
1795 return -1;
1796 info->controlled = false;
1797 #else
1799 struct pollfd pfd[1];
1801 pfd[0].fd = handle;
1802 pfd[0].events = POLLREMOVE;
1803 pfd[0].revents = 0;
1805 if (ACE_OS::write (this->poll_fd_, pfd, sizeof (pfd)) != sizeof (pfd))
1806 return -1;
1808 #endif /* ACE_HAS_EVENT_POLL */
1810 info->suspended = true;
1812 return 0;
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)
1822 errno = EINVAL;
1823 return -1;
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);
1849 ACE_HANDLE h;
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)
1855 return -1;
1857 return 0;
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)
1873 return -1;
1876 return 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);
1885 if (info == 0)
1886 return -1;
1888 if (!info->suspended)
1889 return 0;
1891 ACE_Reactor_Mask mask = info->mask;
1892 if (mask == ACE_Event_Handler::NULL_MASK)
1894 info->suspended = false;
1895 return 0;
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)
1908 op = EPOLL_CTL_MOD;
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)
1913 return -1;
1914 info->controlled = true;
1916 #else
1918 struct pollfd pfd[1];
1920 pfd[0].fd = handle;
1921 pfd[0].events = this->reactor_mask_to_poll_event (mask);
1922 pfd[0].revents = 0;
1924 if (ACE_OS::write (this->poll_fd_, pfd, sizeof (pfd)) != sizeof (pfd))
1925 return -1;
1927 #endif /* ACE_HAS_EVENT_POLL */
1929 info->suspended = false;
1931 return 0;
1935 ACE_Dev_Poll_Reactor::resumable_handler (void)
1937 // @@ Is this correct?
1939 return 1;
1942 bool
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.
1947 return false;
1950 long
1951 ACE_Dev_Poll_Reactor::schedule_timer (ACE_Event_Handler *event_handler,
1952 const void *arg,
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
1962 (event_handler,
1963 arg,
1964 this->timer_queue_->gettimeofday () + delay,
1965 interval);
1967 errno = ESHUTDOWN;
1968 return -1;
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);
1982 errno = ESHUTDOWN;
1983 return -1;
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);
1996 else
1997 return 0;
2001 ACE_Dev_Poll_Reactor::cancel_timer (long timer_id,
2002 const void **arg,
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,
2012 arg,
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");
2059 ssize_t n = 0;
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;
2070 void
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)
2095 return 0;
2097 return this->notify_handler_->purge_pending_notifications (eh, mask);
2100 ACE_Event_Handler *
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);
2106 if (info)
2108 info->event_handler->add_reference ();
2109 return info->event_handler;
2111 else
2113 return 0;
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);
2128 if (info != 0
2129 && ACE_BIT_CMP_MASK (info->mask,
2130 mask, // Compare all bits in the mask
2131 mask))
2133 if (event_handler != 0)
2134 *event_handler = info->event_handler;
2136 return 0;
2139 return -1;
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);
2150 if (handler == 0)
2151 return -1;
2152 else if (eh != 0)
2153 *eh = handler;
2155 return 0;
2158 bool
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_;
2168 size_t
2169 ACE_Dev_Poll_Reactor::size (void) const
2171 return this->handler_rep_.size ();
2174 ACE_Lock &
2175 ACE_Dev_Poll_Reactor::lock (void)
2177 ACE_TRACE ("ACE_Dev_Poll_Reactor::lock");
2179 return this->lock_adapter_;
2182 void
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
2188 // it.
2189 this->notify (0,
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.
2203 return 0;
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.
2214 return 0;
2217 bool
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_;
2227 bool
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_;
2235 this->restart_ = r;
2236 return current_value;
2239 void
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,
2256 int ops)
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,
2268 int ops)
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,
2280 int ops)
2282 ACE_TRACE ("ACE_Dev_Poll_Reactor::mask_ops_i");
2284 Event_Tuple *info = this->handler_rep_.find (handle);
2285 if (info == 0)
2286 return -1;
2288 // Block out all signals until method returns.
2289 ACE_Sig_Guard sb;
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
2300 // enabled bits)
2301 // CLR = 4 Bitwise "and" the negation of the value out of the mask
2302 // (only changes enabled bits)
2304 // Returns the original mask.
2306 switch (ops)
2308 case ACE_Reactor::GET_MASK:
2309 // The work for this operation is done in all cases at the
2310 // beginning of the function.
2311 return old_mask;
2313 case ACE_Reactor::CLR_MASK:
2314 ACE_CLR_BITS (new_mask, mask);
2315 break;
2317 case ACE_Reactor::SET_MASK:
2318 new_mask = mask;
2319 break;
2321 case ACE_Reactor::ADD_MASK:
2322 ACE_SET_BITS (new_mask, mask);
2323 break;
2325 default:
2326 return -1;
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);
2342 #if defined (sun)
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];
2347 pfd[0].fd = handle;
2348 pfd[0].events = POLLREMOVE;
2349 pfd[0].revents = 0;
2350 pfd[1].fd = (events == POLLREMOVE ? ACE_INVALID_HANDLE : handle);
2351 pfd[1].events = events;
2352 pfd[1].revents = 0;
2354 // Change the events associated with the given file descriptor.
2355 if (ACE_OS::write (this->poll_fd_,
2356 pfd,
2357 sizeof (pfd)) != sizeof (pfd))
2358 return -1;
2359 #elif defined (ACE_HAS_EVENT_POLL)
2361 struct epoll_event epev;
2362 ACE_OS::memset (&epev, 0, sizeof (epev));
2363 int op;
2365 // ACE_Event_Handler::NULL_MASK ???
2366 if (new_mask == 0)
2368 op = EPOLL_CTL_DEL;
2369 epev.events = 0;
2371 else
2373 op = EPOLL_CTL_MOD;
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)
2387 return -1;
2389 info->controlled = (op != EPOLL_CTL_DEL);
2390 #else
2391 pollfd pfd[1];
2393 pfd[0].fd = handle;
2394 pfd[0].events = events;
2395 pfd[0].revents = 0;
2397 // Change the events associated with the given file descriptor.
2398 if (ACE_OS::write (this->poll_fd_,
2399 pfd,
2400 sizeof (pfd)) != sizeof (pfd))
2401 return -1;
2402 #endif /*ACE_HAS_EVENT_POLL */
2405 return old_mask;
2409 ACE_Dev_Poll_Reactor::ready_ops (ACE_Event_Handler * /* event_handler */,
2410 ACE_Reactor_Mask /* mask */,
2411 int /* ops */)
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
2417 // loop.
2418 ACE_NOTSUP_RETURN (-1);
2422 ACE_Dev_Poll_Reactor::ready_ops (ACE_HANDLE /* handle */,
2423 ACE_Reactor_Mask /* mask */,
2424 int /* ops */)
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
2430 // loop.
2431 ACE_NOTSUP_RETURN (-1);
2434 void
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 */
2454 short
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;
2463 #else
2464 return POLLREMOVE;
2465 #endif /* ACE_HAS_EVENT_POLL */
2467 short events = 0;
2469 // READ, ACCEPT, and CONNECT flag will place the handle in the
2470 // read set.
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);
2477 #else
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);
2488 #else
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);
2498 #else
2499 ACE_SET_BITS (events, POLLPRI);
2500 #endif /*ACE_HAS_EVENT_POLL*/
2503 return events;
2506 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
2507 namespace {
2508 void polite_sleep_hook (void *) { }
2510 #endif
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.
2518 int result = 0;
2519 if (max_wait)
2521 ACE_Time_Value tv = ACE_OS::gettimeofday ();
2522 tv += *max_wait;
2524 ACE_MT (result = this->token_.acquire_read (&polite_sleep_hook,
2526 &tv));
2528 else
2530 ACE_MT (result = this->token_.acquire_read (&polite_sleep_hook));
2533 // Check for timeouts and errors.
2534 if (result == -1)
2536 if (errno == ETIME)
2537 return 0;
2538 else
2540 ACELIB_ERROR ((LM_ERROR, ACE_TEXT("%t: %p\n"), ACE_TEXT("token acquire_read")));
2541 return -1;
2545 // We got the token and so let us mark ourselves as owner
2546 this->owner_ = true;
2548 return result;
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.
2558 int result = 0;
2559 if (max_wait)
2561 ACE_Time_Value tv = ACE_OS::gettimeofday ();
2562 tv += *max_wait;
2564 ACE_MT (result = this->token_.acquire (0, 0, &tv));
2566 else
2568 ACE_MT (result = this->token_.acquire ());
2571 // Check for timeouts and errors.
2572 if (result == -1)
2574 if (errno == ETIME)
2575 return 0;
2576 else
2577 return -1;
2580 // We got the token and so let us mark ourseleves as owner
2581 this->owner_ = true;
2583 return result;
2586 ACE_END_VERSIONED_NAMESPACE_DECL
2588 #endif /* ACE_HAS_EVENT_POLL || ACE_HAS_DEV_POLL */