ACE  Snapshot(2023/04/28-19:12)
Dev_Poll_Reactor.cpp
Go to the documentation of this file.
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"
6 
7 #if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL)
8 
9 # include "ace/OS_NS_unistd.h"
10 # include "ace/OS_NS_fcntl.h"
11 # include "ace/OS_NS_stropts.h"
12 
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 */
22 
23 #if !defined (__ACE_INLINE__)
24 # include "ace/Dev_Poll_Reactor.inl"
25 #endif /* __ACE_INLINE__ */
26 
27 
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"
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"
42 
44 
48 
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 */
56 {
57 }
58 
59 int
61  ACE_Timer_Queue * /* timer_queue */,
62  int disable_notify_pipe)
63 {
64  ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::open");
65 
66  if (disable_notify_pipe == 0)
67  {
68  this->dp_reactor_ = dynamic_cast<ACE_Dev_Poll_Reactor *> (r);
69 
70  if (this->dp_reactor_ == 0)
71  {
72  errno = EINVAL;
73  return -1;
74  }
75 
76  if (this->notification_pipe_.open () == -1)
77  return -1;
78 
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)
82  {
83  return -1;
84  }
85  if (ACE_OS::fcntl (this->notification_pipe_.write_handle (), F_SETFD, 1) == -1)
86  {
87  return -1;
88  }
89 #endif /* F_SETFD */
90 
91 #if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE)
92  if (notification_queue_.open () == -1)
93  {
94  return -1;
95  }
96 
97  if (ACE::set_flags (this->notification_pipe_.write_handle (),
98  ACE_NONBLOCK) == -1)
99  return -1;
100 #endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */
101 
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;
108  }
109 
110  return 0;
111 }
112 
113 int
115 {
116  ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::close");
117 
118 #if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE)
119  notification_queue_.reset ();
120 #endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */
121 
122  return this->notification_pipe_.close ();
123 }
124 
125 int
127  ACE_Reactor_Mask mask,
128  ACE_Time_Value *timeout)
129 {
130  ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::notify");
131 
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;
136 
137  ACE_Notification_Buffer buffer (eh, mask);
138 
139 #if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE)
140  ACE_UNUSED_ARG (timeout);
141  ACE_Dev_Poll_Handler_Guard eh_guard (eh);
142 
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
148 
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 ();
152 
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;
163 
164  return 0;
165 #else
166 
167  ACE_Dev_Poll_Handler_Guard eh_guard (eh);
168 
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;
175 
176  eh_guard.release ();
177 
178  return 0;
179 #endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */
180 }
181 
182 int
184  int & /* number_of_active_handles */,
185  ACE_Handle_Set & /* rd_mask */)
186 {
187  ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::dispatch_notifications");
188 
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.
196 
197  ACE_NOTSUP_RETURN (-1);
198 }
199 
200 int
202  ACE_Notification_Buffer &buffer)
203 {
204  ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::read_notify_pipe");
205 
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;
215 
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);
228 
229  bool more_messages_queued = false;
231  int result = 1;
232  while (result == 1)
233  {
234  result = notification_queue_.pop_next_notification (buffer,
235  more_messages_queued,
236  next);
237 
238  if (result <= 0) // Nothing dequeued or error
239  return result;
240 
241  // If it's just a wake-up, toss it and see if there's anything else.
242  if (buffer.eh_ != 0)
243  break;
244  }
245 
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;
257 
258  ssize_t n = ACE::recv (handle, read_p, to_read);
259 
260  if (n > 0)
261  {
262  // Check to see if we've got a short read.
263  if (static_cast<size_t> (n) != to_read)
264  {
265  size_t remainder = to_read - n;
266 
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;
273  }
274 
275  return 1;
276  }
277 
278  // Return -1 if things have gone seriously wrong.
279  if (n <= 0 && (errno != EWOULDBLOCK && errno != EAGAIN))
280  return -1;
281 
282  return 0;
283 #endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */
284 }
285 
286 
287 int
289 {
290  ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::handle_input");
291  ACELIB_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("SHOULD NOT BE HERE.\n")), -1);
292 }
293 
294 ACE_HANDLE
296 {
297  ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::notify_handle");
298 
299  return this->notification_pipe_.read_handle ();
300 }
301 
302 int
304 {
305  ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::is_dispatchable");
306 
307  ACE_NOTSUP_RETURN (-1);
308 }
309 
310 int
312 {
313  ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::dispatch_notify");
314 
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)
321  {
322  int result = 0;
323 
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);
328 
329  switch (buffer.mask_)
330  {
333  result = buffer.eh_->handle_input (ACE_INVALID_HANDLE);
334  break;
336  result = buffer.eh_->handle_output (ACE_INVALID_HANDLE);
337  break;
339  result = buffer.eh_->handle_exception (ACE_INVALID_HANDLE);
340  break;
341  default:
342  // Should we bail out if we get an invalid mask?
344  ACE_TEXT ("dispatch_notify invalid mask = %d\n"),
345  buffer.mask_));
346  }
347  if (result == -1)
348  buffer.eh_->handle_close (ACE_INVALID_HANDLE, buffer.mask_);
349  }
350 
351  return 1;
352 }
353 
354 void
356 {
357  ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::max_notify_iterations");
358 
359  // Must always be > 0 or < 0 to optimize the loop exit condition.
360  if (iterations == 0)
361  iterations = 1;
362 
363  this->max_notify_iterations_ = iterations;
364 }
365 
366 int
368 {
369  ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::max_notify_iterations");
370 
371  return this->max_notify_iterations_;
372 }
373 
374 int
376  ACE_Event_Handler *eh,
377  ACE_Reactor_Mask mask)
378 {
379  ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::purge_pending_notifications");
380 
381 #if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE)
382 
383  return notification_queue_.purge_pending_notifications (eh, mask);
384 
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) */
390 }
391 
392 void
394 {
395 #if defined (ACE_HAS_DUMP)
396  ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::dump");
397 
400  ACE_TEXT ("dp_reactor_ = %@"),
401  this->dp_reactor_));
402  this->notification_pipe_.dump ();
404 #endif /* ACE_HAS_DUMP */
405 }
406 
407 int
409 {
410  nb.eh_ = 0;
411  nb.mask_ = 0;
412  return this->read_notify_pipe (this->notify_handle (), nb);
413 }
414 
415 
416 // -----------------------------------------------------------------
417 
419  : size_ (0),
420  max_size_ (0),
421  handlers_ (0)
422 {
423  ACE_TRACE ("ACE_Dev_Poll_Reactor::Handler_Repository::Handler_Repository");
424 }
425 
426 bool
428  ACE_HANDLE handle) const
429 {
430  ACE_TRACE ("ACE_Dev_Poll_Reactor::Handler_Repository::invalid_handle");
431 
432  if (handle < 0 || handle >= this->max_size_)
433  {
434  errno = EINVAL;
435  return true;
436  }
437  else
438  return false;
439 }
440 
441 bool
443  ACE_HANDLE handle) const
444 {
445  ACE_TRACE ("ACE_Dev_Poll_Reactor::Handler_Repository::handle_in_range");
446 
447  if (handle >= 0 && handle < this->max_size_)
448  return true;
449  else
450  {
451  errno = EINVAL;
452  return false;
453  }
454 }
455 
456 int
458 {
459  ACE_TRACE ("ACE_Dev_Poll_Reactor::Handler_Repository::open");
460 
461  this->max_size_ = size;
462 
463  // Try to allocate the memory.
464  ACE_NEW_RETURN (this->handlers_, Event_Tuple[size], -1);
465 
466  // Try to increase the number of handles if <size> is greater than
467  // the current limit.
468  return ACE::set_handle_limit (size);
469 }
470 
471 int
473 {
474  ACE_TRACE ("ACE_Dev_Poll_Reactor::Handler_Repository::unbind_all");
475 
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)
480  {
481  Event_Tuple *entry = this->find (handle);
482  if (entry == 0)
483  continue;
484 
485  // Check for ref counting now - handle_close () may delete eh.
486  bool const requires_reference_counting =
489 
490  (void) entry->event_handler->handle_close (handle, entry->mask);
491  this->unbind (handle, requires_reference_counting);
492  }
493 
494  return 0;
495 }
496 
497 int
499 {
500  ACE_TRACE ("ACE_Dev_Poll_Reactor::Handler_Repository::close");
501 
502  if (this->handlers_ != 0)
503  {
504  this->unbind_all ();
505 
506  delete [] this->handlers_;
507  this->handlers_ = 0;
508  }
509 
510  return 0;
511 }
512 
515 {
516  ACE_TRACE ("ACE_Dev_Poll_Reactor::Handler_Repository::find");
517 
518  Event_Tuple *tuple = 0;
519 
520  // Only bother to search for the <handle> if it's in range.
521  if (!this->handle_in_range (handle))
522  {
523  errno = ERANGE;
524  return 0;
525  }
526 
527  tuple = &(this->handlers_[handle]);
528  if (tuple->event_handler == 0)
529  {
530  errno = ENOENT;
531  tuple = 0;
532  }
533 
534  return tuple;
535 }
536 
537 int
539  ACE_HANDLE handle,
540  ACE_Event_Handler *event_handler,
541  ACE_Reactor_Mask mask)
542 {
543  ACE_TRACE ("ACE_Dev_Poll_Reactor::Handler_Repository::bind");
544 
545  if (event_handler == 0)
546  return -1;
547 
548  if (handle == ACE_INVALID_HANDLE)
549  handle = event_handler->get_handle ();
550 
551  if (this->invalid_handle (handle))
552  return -1;
553 
554  this->handlers_[handle].event_handler = event_handler;
555  this->handlers_[handle].mask = mask;
556  event_handler->add_reference ();
557  ++this->size_;
558 
559  return 0;
560 }
561 
562 int
564  bool decr_refcnt)
565 {
566  ACE_TRACE ("ACE_Dev_Poll_Reactor::Handler_Repository::unbind");
567 
568  Event_Tuple *entry = this->find (handle);
569  if (entry == 0)
570  return -1;
571 
572  if (decr_refcnt)
573  entry->event_handler->remove_reference ();
574 
575  entry->event_handler = 0;
577  entry->suspended = false;
578  entry->controlled = false;
579  --this->size_;
580  return 0;
581 }
582 
583 // -----------------------------------------------------------------
584 
586  ACE_Timer_Queue *tq,
587  int disable_notify_pipe,
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)
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)
610 {
611  ACE_TRACE ("ACE_Dev_Poll_Reactor::ACE_Dev_Poll_Reactor");
612 
613  if (this->open (ACE::max_handles (),
614  0,
615  sh,
616  tq,
617  disable_notify_pipe,
618  notify) == -1)
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")));
624 }
625 
627  bool rs,
628  ACE_Sig_Handler *sh,
629  ACE_Timer_Queue *tq,
630  int disable_notify_pipe,
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)
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)
653 {
654  if (this->open (size,
655  rs,
656  sh,
657  tq,
658  disable_notify_pipe,
659  notify) == -1)
661  ACE_TEXT ("%p\n"),
662  ACE_TEXT ("ACE_Dev_Poll_Reactor::open ")
663  ACE_TEXT ("failed inside ACE_Dev_Poll_Reactor::CTOR")));
664 }
665 
667 {
668  ACE_TRACE ("ACE_Dev_Poll_Reactor::~ACE_Dev_Poll_Reactor");
669 
670  (void) this->close ();
671 }
672 
673 int
675  bool restart,
676  ACE_Sig_Handler *sh,
677  ACE_Timer_Queue *tq,
678  int disable_notify_pipe,
680 {
681  ACE_TRACE ("ACE_Dev_Poll_Reactor::open");
682 
683  ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1));
684 
685  // Can't initialize ourselves more than once.
686  if (this->initialized_)
687  return -1;
688 
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 */
693 
694  this->restart_ = restart;
695  this->signal_handler_ = sh;
696  this->timer_queue_ = tq;
697  this->notify_handler_ = notify;
698 
699  int result = 0;
700 
701  // Allows the signal handler to be overridden.
702  if (this->signal_handler_ == 0)
703  {
706  -1);
707 
708  if (this->signal_handler_ == 0)
709  result = -1;
710  else
711  this->delete_signal_handler_ = true;
712  }
713 
714  // Allows the timer queue to be overridden.
715  if (result != -1 && this->timer_queue_ == 0)
716  {
719  -1);
720 
721  if (this->timer_queue_ == 0)
722  result = -1;
723  else
724  this->delete_timer_queue_ = true;
725  }
726 
727  // Allows the Notify_Handler to be overridden.
728  if (result != -1 && this->notify_handler_ == 0)
729  {
732  -1);
733 
734  if (this->notify_handler_ == 0)
735  result = -1;
736  else
737  this->delete_notify_handler_ = true;
738  }
739 
740 #if defined (ACE_HAS_EVENT_POLL)
741 
742  // Initialize epoll:
743  this->poll_fd_ = ::epoll_create (size);
744  if (this->poll_fd_ == -1)
745  result = -1;
746 
747 #else
748 
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);
754 
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;
759 
760 #endif /* ACE_HAS_EVENT_POLL */
761 
762  if (result != -1 && this->handler_rep_.open (size) == -1)
763  result = -1;
764 
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,
768  0,
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_,
775  result = -1;
776 
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 ();
783 
784  return result;
785 }
786 
787 int
788 ACE_Dev_Poll_Reactor::current_info (ACE_HANDLE, size_t & /* size */)
789 {
790  ACE_NOTSUP_RETURN (-1);
791 }
792 
793 
794 int
796 {
797  if (this->delete_signal_handler_)
798  delete this->signal_handler_;
799 
800  this->signal_handler_ = signal_handler;
801  this->delete_signal_handler_ = false;
802 
803  return 0;
804 }
805 
806 int
808 {
809  if (this->delete_timer_queue_)
810  delete this->timer_queue_;
811  else if (this->timer_queue_)
812  this->timer_queue_->close ();
813 
814  this->timer_queue_ = tq;
815  this->delete_timer_queue_ = false;
816 
817  return 0;
818 }
819 
822 {
823  return this->timer_queue_;
824 }
825 
826 int
828 {
829  ACE_TRACE ("ACE_Dev_Poll_Reactor::close");
830 
831  ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1));
832 
833  int result = 0;
834 
835  if (this->poll_fd_ != ACE_INVALID_HANDLE)
836  {
837  result = ACE_OS::close (this->poll_fd_);
838  }
839 
840 #if defined (ACE_HAS_EVENT_POLL)
841 
842  ACE_OS::memset (&this->event_, 0, sizeof (this->event_));
843  this->event_.data.fd = ACE_INVALID_HANDLE;
844 
845 #else
846 
847  delete [] this->dp_fds_;
848  this->dp_fds_ = 0;
849  this->start_pfds_ = 0;
850  this->end_pfds_ = 0;
851 
852 #endif /* ACE_HAS_EVENT_POLL */
853 
854  if (this->delete_signal_handler_)
855  {
856  delete this->signal_handler_;
857  this->signal_handler_ = 0;
858  this->delete_signal_handler_ = false;
859  }
860 
861  (void) this->handler_rep_.close ();
862 
863  if (this->delete_timer_queue_)
864  {
865  delete this->timer_queue_;
866  this->timer_queue_ = 0;
867  this->delete_timer_queue_ = false;
868  }
869  else if (this->timer_queue_)
870  {
871  this->timer_queue_->close ();
872  this->timer_queue_ = 0;
873  }
874 
875  if (this->notify_handler_ != 0)
876  this->notify_handler_->close ();
877 
878  if (this->delete_notify_handler_)
879  {
880  delete this->notify_handler_;
881  this->notify_handler_ = 0;
882  this->delete_notify_handler_ = false;
883  }
884 
885  this->poll_fd_ = ACE_INVALID_HANDLE;
886 
887  this->initialized_ = false;
888 
889  return result;
890 }
891 
892 int
894 {
895  ACE_TRACE ("ACE_Dev_Poll_Reactor::work_pending");
896 
897  // Stash the current time
898  //
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));
903 
904  Token_Guard guard (this->token_);
905  int const result = guard.acquire_quietly (&mwt);
906 
907  // If the guard is NOT the owner just return the retval
908  if (!guard.is_owner ())
909  return result;
910 
911  // Update the countdown to reflect time waiting for the mutex.
912  ACE_MT (countdown.update ());
913 
914  return this->work_pending_i (&mwt);
915 }
916 
917 int
919 {
920  ACE_TRACE ("ACE_Dev_Poll_Reactor::work_pending_i");
921 
922  if (this->deactivated_)
923  return 0;
924 
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.
932 
933  ACE_Time_Value timer_buf (0);
934  ACE_Time_Value *this_timeout =
935  this->timer_queue_->calculate_timeout (max_wait_time, &timer_buf);
936 
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);
942 
943  long const timeout =
944  (this_timeout == 0
945  ? -1 /* Infinity */
946  : static_cast<long> (this_timeout->msec ()));
947 
948 #if defined (ACE_HAS_EVENT_POLL)
949 
950  // Wait for an event.
951  int const nfds = ::epoll_wait (this->poll_fd_,
952  &this->event_,
953  1,
954  static_cast<int> (timeout));
955 
956 #else
957 
958  struct dvpoll dvp;
959 
960  dvp.dp_fds = this->dp_fds_;
961  dvp.dp_nfds = this->handler_rep_.size ();
962  dvp.dp_timeout = timeout; // Milliseconds
963 
964  // Poll for events
965  int const nfds = ACE_OS::ioctl (this->poll_fd_, DP_POLL, &dvp);
966 
967  // Retrieve the results from the pollfd array.
968  this->start_pfds_ = dvp.dp_fds;
969 
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 */
976 
977  // If timers are pending, override any timeout from the poll.
978  return (nfds == 0 && timers_pending != 0 ? 1 : nfds);
979 }
980 
981 
982 int
984 {
985  ACE_TRACE ("ACE_Dev_Poll_Reactor::handle_events");
986 
987  // Stash the current time
988  //
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);
992 
993  Token_Guard guard (this->token_);
994  int const result = guard.acquire_quietly (max_wait_time);
995 
996  // If the guard is NOT the owner just return the retval
997  if (!guard.is_owner ())
998  return result;
999 
1000  if (this->deactivated_)
1001  {
1002  errno = ESHUTDOWN;
1003  return -1;
1004  }
1005 
1006  // Update the countdown to reflect time waiting for the mutex.
1007  ACE_MT (countdown.update ());
1008 
1009  return this->handle_events_i (max_wait_time, guard);
1010 }
1011 
1012 int
1014  Token_Guard &guard)
1015 {
1016  ACE_TRACE ("ACE_Dev_Poll_Reactor::handle_events_i");
1017 
1018  int result = 0;
1019 
1020  // Poll for events
1021  //
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.
1025  do
1026  {
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")));
1030  }
1031  while (result == -1 && this->restart_ != 0 && errno == EINTR);
1032 
1033  if (result == 0 || (result == -1 && errno == ETIME))
1034  return 0;
1035  else if (result == -1)
1036  {
1037  if (errno != EINTR)
1038  return -1;
1039 
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)
1045  {
1047  return 1;
1048  }
1049  return -1;
1050  }
1051 
1052  // Dispatch an event.
1053  return this->dispatch (guard);
1054 }
1055 
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.
1058 int
1060 {
1061  ACE_TRACE ("ACE_Dev_Poll_Reactor::dispatch");
1062 
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;
1068 
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;
1074 
1075  // If no timer dispatched, check for an I/O event.
1076  result = this->dispatch_io_event (guard);
1077 
1078  return result;
1079 }
1080 
1081 int
1083 {
1084  typedef ACE_Member_Function_Command<Token_Guard> Guard_Release;
1085 
1086  Guard_Release release(guard, &Token_Guard::release_token);
1087  return this->timer_queue_->expire_single(release);
1088 }
1089 
1090 #if 0
1091 int
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)
1096 {
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.
1103 
1104  const int n =
1105  this->notify_handler_->dispatch_notifications (number_of_active_handles,
1106  dispatch_set.rd_mask_);
1107 
1108  if (n == -1)
1109  return -1;
1110  else
1111  number_of_handlers_dispatched += n;
1112 
1113  return /* this->state_changed_ ? -1 : */ 0;
1114 }
1115 #endif /* 0 */
1116 
1117 int
1119 {
1120 
1121  // Dispatch a ready event.
1122 
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 */
1135 
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)
1145 
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.
1153 
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.
1159  //
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 */
1167 
1168  {
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 ?
1174  */
1175 
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;
1183  {
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;
1188 
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;
1195 
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))
1204  {
1205  disp_mask = ACE_Event_Handler::WRITE_MASK;
1207  ACE_CLR_BITS (revents, out_event);
1208  }
1209  else if (ACE_BIT_ENABLED (revents, exc_event))
1210  {
1211  disp_mask = ACE_Event_Handler::EXCEPT_MASK;
1213  ACE_CLR_BITS (revents, exc_event);
1214  }
1215  else if (ACE_BIT_ENABLED (revents, in_event))
1216  {
1217  disp_mask = ACE_Event_Handler::READ_MASK;
1218  callback = &ACE_Event_Handler::handle_input;
1219  ACE_CLR_BITS (revents, in_event);
1220  }
1221  else if (ACE_BIT_ENABLED (revents, err_event))
1222  {
1223  this->remove_handler_i (handle,
1225  grd,
1226  info->event_handler);
1227 #ifdef ACE_HAS_DEV_POLL
1228  ++pfds;
1229 #endif /* ACE_HAS_DEV_POLL */
1230  return 1;
1231  }
1232  else
1233  {
1235  ACE_TEXT ("(%t) dispatch_io h %d unknown events 0x%x\n"),
1236  handle, revents));
1237  }
1238 
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_)
1255  {
1256  info->suspended = true;
1257 
1258  reactor_resumes_eh =
1259  eh->resume_handler () ==
1261  }
1262 #endif /* ACE_HAS_DEV_POLL */
1263 
1264  } // End scope for ACE_GUARD holding repo lock
1265 
1266  int status = 0; // gets callback status, below.
1267 
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_)
1273  {
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);
1281  }
1282 
1283  {
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);
1290 
1291  // Release the reactor token before upcall.
1292  guard.release_token ();
1293 
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);
1300 
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)
1307  {
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)
1313  {
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);
1318  }
1319 #endif /* ACE_HAS_EVENT_POLL */
1320  return 1;
1321  }
1322 
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)
1331  {
1332  if (status < 0)
1333  {
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)
1340  {
1341  info = this->handler_rep_.find (handle);
1342  if (info != 0 && info->event_handler == eh)
1343  {
1344  this->resume_handler_i (handle);
1345  }
1346  }
1347 #endif /* ACE_HAS_EVENT_POLL */
1348  }
1349  }
1350  }
1351  // Scope close handles eh ref count decrement, if needed.
1352 
1353  return 1;
1354  }
1355 
1356  return 0;
1357 }
1358 
1359 int
1361 {
1362  ACE_TRACE ("ACE_Dev_Poll_Reactor::alertable_handle_events");
1363 
1364  return this->handle_events (max_wait_time);
1365 }
1366 
1367 int
1369 {
1370  ACE_TRACE ("ACE_Dev_Poll_Reactor::handle_events");
1371 
1372  return this->handle_events (&max_wait_time);
1373 }
1374 
1375 int
1377 {
1378  ACE_TRACE ("ACE_Dev_Poll_Reactor::alertable_handle_events");
1379 
1380  return this->handle_events (max_wait_time);
1381 }
1382 
1383 int
1385 {
1386  return this->deactivated_;
1387 }
1388 
1389 void
1391 {
1392  this->deactivated_ = do_stop;
1393  this->wakeup_all_threads ();
1394 }
1395 
1396 int
1398  ACE_Reactor_Mask mask)
1399 {
1400  ACE_TRACE ("ACE_Dev_Poll_Reactor::register_handler");
1401 
1402  ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, grd, this->repo_lock_, -1));
1403 
1404  return this->register_handler_i (handler->get_handle (),
1405  handler,
1406  mask);
1407 }
1408 
1409 int
1411  ACE_Event_Handler *event_handler,
1412  ACE_Reactor_Mask mask)
1413 {
1414  ACE_TRACE ("ACE_Dev_Poll_Reactor::register_handler");
1415 
1416  ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, grd, this->repo_lock_, -1));
1417 
1418  return this->register_handler_i (handle,
1419  event_handler,
1420  mask);
1421 }
1422 
1423 int
1425  ACE_Event_Handler *event_handler,
1426  ACE_Reactor_Mask mask)
1427 {
1428  ACE_TRACE ("ACE_Dev_Poll_Reactor::register_handler_i");
1429 
1430  if (handle == ACE_INVALID_HANDLE
1431  || mask == ACE_Event_Handler::NULL_MASK)
1432  {
1433  errno = EINVAL;
1434  return -1;
1435  }
1436 
1437  if (this->handler_rep_.find (handle) == 0)
1438  {
1439  // Handler not present in the repository. Bind it.
1440  if (this->handler_rep_.bind (handle, event_handler, mask) != 0)
1441  return -1;
1442 
1443 #if defined (ACE_HAS_EVENT_POLL)
1444 
1445  Event_Tuple *info = this->handler_rep_.find (handle);
1446 
1447  struct epoll_event epev;
1448  ACE_OS::memset (&epev, 0, sizeof (epev));
1449  static const int op = EPOLL_CTL_ADD;
1450 
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;
1458 
1459  if (::epoll_ctl (this->poll_fd_, op, handle, &epev) == -1)
1460  {
1461  ACELIB_ERROR ((LM_ERROR, ACE_TEXT("%p\n"), ACE_TEXT("epoll_ctl")));
1462  (void) this->handler_rep_.unbind (handle);
1463  return -1;
1464  }
1465  info->controlled = true;
1466 
1467 #endif /* ACE_HAS_EVENT_POLL */
1468  }
1469  else
1470  {
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);
1477  }
1478 
1479 #ifdef ACE_HAS_DEV_POLL
1480 
1481  struct pollfd pfd;
1482 
1483  pfd.fd = handle;
1484  pfd.events = this->reactor_mask_to_poll_event (mask);
1485  pfd.revents = 0;
1486 
1487  // Add file descriptor to the "interest set."
1488  if (ACE_OS::write (this->poll_fd_, &pfd, sizeof (pfd)) != sizeof (pfd))
1489  {
1490  (void) this->handler_rep_.unbind (handle);
1491  return -1;
1492  }
1493 #endif /*ACE_HAS_DEV_POLL*/
1494 
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;
1499 
1500  return 0;
1501 }
1502 
1503 int
1505  ACE_HANDLE /* event_handle */,
1506  ACE_HANDLE /* io_handle */,
1507  ACE_Event_Handler * /* event_handler */,
1508  ACE_Reactor_Mask /* mask */)
1509 {
1510  ACE_NOTSUP_RETURN (-1);
1511 }
1512 
1513 int
1515  ACE_Event_Handler *event_handler,
1516  ACE_Reactor_Mask mask)
1517 {
1518  ACE_TRACE ("ACE_Dev_Poll_Reactor::register_handler");
1519 
1520  ACE_Handle_Set_Iterator handle_iter (handle_set);
1521 
1522  ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, grd, this->repo_lock_, -1));
1523 
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.
1528 
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;
1534 
1535  return 0;
1536 }
1537 
1538 int
1540  ACE_Event_Handler *new_sh,
1541  ACE_Sig_Action *new_disp,
1542  ACE_Event_Handler **old_sh,
1543  ACE_Sig_Action *old_disp)
1544 {
1545  ACE_TRACE ("ACE_Dev_Poll_Reactor::register_handler");
1546 
1547  return this->signal_handler_->register_handler (signum,
1548  new_sh,
1549  new_disp,
1550  old_sh,
1551  old_disp);
1552 }
1553 
1554 int
1556  ACE_Event_Handler *new_sh,
1557  ACE_Sig_Action *new_disp)
1558 {
1559  ACE_TRACE ("ACE_Dev_Poll_Reactor::register_handler");
1560 
1561  int result = 0;
1562 
1563 #if (ACE_NSIG > 0)
1564 
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;
1571 
1572 #else /* ACE_NSIG <= 0 */
1573 
1574  ACE_UNUSED_ARG (sigset);
1575  ACE_UNUSED_ARG (new_sh);
1576  ACE_UNUSED_ARG (new_disp);
1577 
1578 #endif /* ACE_NSIG <= 0 */
1579 
1580  return result;
1581 }
1582 
1583 int
1585  ACE_Reactor_Mask mask)
1586 {
1587  ACE_TRACE ("ACE_Dev_Poll_Reactor::remove_handler");
1588 
1589  ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, grd, this->repo_lock_, -1);
1590  return this->remove_handler_i (handler->get_handle (), mask, grd);
1591 }
1592 
1593 int
1595  ACE_Reactor_Mask mask)
1596 {
1597  ACE_TRACE ("ACE_Dev_Poll_Reactor::remove_handler");
1598 
1599  ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, grd, this->repo_lock_, -1);
1600 
1601  return this->remove_handler_i (handle, mask, grd);
1602 }
1603 
1604 // FUZZ: disable check_for_ACE_Guard
1605 int
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
1611 {
1612  ACE_TRACE ("ACE_Dev_Poll_Reactor::remove_handler_i");
1613 
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))
1621  {
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;
1626  }
1627 
1628  // Check for ref counting now - handle_close () may delete eh.
1629  bool const requires_reference_counting =
1630  eh->reference_counting_policy ().value () ==
1632 
1634  {
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 ();
1639  }
1640 
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);
1645 
1646  return 0;
1647 }
1648 
1649 int
1651  ACE_Reactor_Mask mask)
1652 {
1653  ACE_TRACE ("ACE_Dev_Poll_Reactor::remove_handler");
1654 
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 ())
1659  {
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;
1663  }
1664  return 0;
1665 }
1666 
1667 int
1669  ACE_Sig_Action *new_disp,
1670  ACE_Sig_Action *old_disp,
1671  int sigkey)
1672 {
1673  ACE_TRACE ("ACE_Dev_Poll_Reactor::remove_handler");
1674 
1675  return this->signal_handler_->remove_handler (signum,
1676  new_disp,
1677  old_disp,
1678  sigkey);
1679 }
1680 
1681 int
1683 {
1684  ACE_TRACE ("ACE_Dev_Poll_Reactor::remove_handler");
1685 
1686  int result = 0;
1687 
1688 #if (ACE_NSIG > 0)
1689 
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;
1694 
1695 #else /* ACE_NSIG <= 0 */
1696 
1697  ACE_UNUSED_ARG (sigset);
1698 
1699 #endif /* ACE_NSIG <= 0 */
1700 
1701  return result;
1702 }
1703 
1704 int
1706 {
1707  ACE_TRACE ("ACE_Dev_Poll_Reactor::suspend_handler");
1708 
1709  if (event_handler == 0)
1710  {
1711  errno = EINVAL;
1712  return -1;
1713  }
1714 
1715  ACE_HANDLE handle = event_handler->get_handle ();
1716 
1717  ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, grd, this->repo_lock_, -1));
1718 
1719  return this->suspend_handler_i (handle);
1720 }
1721 
1722 int
1724 {
1725  ACE_TRACE ("ACE_Dev_Poll_Reactor::suspend_handler");
1726 
1727  ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, grd, this->repo_lock_, -1));
1728 
1729  return this->suspend_handler_i (handle);
1730 }
1731 
1732 int
1734 {
1735  ACE_TRACE ("ACE_Dev_Poll_Reactor::suspend_handler");
1736 
1737  ACE_Handle_Set_Iterator handle_iter (handles);
1738  ACE_HANDLE h;
1739 
1740  ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, grd, this->repo_lock_, -1));
1741 
1742  while ((h = handle_iter ()) != ACE_INVALID_HANDLE)
1743  if (this->suspend_handler_i (h) == -1)
1744  return -1;
1745 
1746  return 0;
1747 }
1748 
1749 int
1751 {
1752  ACE_TRACE ("ACE_Dev_Poll_Reactor::suspend_handlers");
1753 
1754  ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, grd, this->repo_lock_, -1));
1755 
1756  size_t const len = this->handler_rep_.max_size ();
1757 
1758  for (size_t i = 0; i < len; ++i)
1759  {
1760  Event_Tuple *info = this->handler_rep_.find (i);
1761  if (info != 0 && !info->suspended && this->suspend_handler_i (i) != 0)
1762  return -1;
1763  }
1764  return 0;
1765 }
1766 
1767 int
1769 {
1770  ACE_TRACE ("ACE_Dev_Poll_Reactor::suspend_handler_i");
1771 
1772  Event_Tuple *info = this->handler_rep_.find (handle);
1773  if (info == 0)
1774  return -1;
1775 
1776  if (info->suspended)
1777  return 0; // Already suspended. @@ Should this be an error?
1778 
1779  // Remove the handle from the "interest set."
1780  //
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.
1784 
1785 #if defined (ACE_HAS_EVENT_POLL)
1786 
1787  struct epoll_event epev;
1788  ACE_OS::memset (&epev, 0, sizeof (epev));
1789  static const int op = EPOLL_CTL_DEL;
1790 
1791  epev.events = 0;
1792  epev.data.fd = handle;
1793 
1794  if (::epoll_ctl (this->poll_fd_, op, handle, &epev) == -1)
1795  return -1;
1796  info->controlled = false;
1797 #else
1798 
1799  struct pollfd pfd[1];
1800 
1801  pfd[0].fd = handle;
1802  pfd[0].events = POLLREMOVE;
1803  pfd[0].revents = 0;
1804 
1805  if (ACE_OS::write (this->poll_fd_, pfd, sizeof (pfd)) != sizeof (pfd))
1806  return -1;
1807 
1808 #endif /* ACE_HAS_EVENT_POLL */
1809 
1810  info->suspended = true;
1811 
1812  return 0;
1813 }
1814 
1815 int
1817 {
1818  ACE_TRACE ("ACE_Dev_Poll_Reactor::resume_handler");
1819 
1820  if (event_handler == 0)
1821  {
1822  errno = EINVAL;
1823  return -1;
1824  }
1825 
1826  ACE_HANDLE handle = event_handler->get_handle ();
1827 
1828  ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, grd, this->repo_lock_, -1));
1829 
1830  return this->resume_handler_i (handle);
1831 }
1832 
1833 int
1835 {
1836  ACE_TRACE ("ACE_Dev_Poll_Reactor::resume_handler");
1837 
1838  ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, grd, this->repo_lock_, -1));
1839 
1840  return this->resume_handler_i (handle);
1841 }
1842 
1843 int
1845 {
1846  ACE_TRACE ("ACE_Dev_Poll_Reactor::resume_handler");
1847 
1848  ACE_Handle_Set_Iterator handle_iter (handles);
1849  ACE_HANDLE h;
1850 
1851  ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, grd, this->repo_lock_, -1));
1852 
1853  while ((h = handle_iter ()) != ACE_INVALID_HANDLE)
1854  if (this->resume_handler_i (h) == -1)
1855  return -1;
1856 
1857  return 0;
1858 }
1859 
1860 int
1862 {
1863  ACE_TRACE ("ACE_Dev_Poll_Reactor::resume_handlers");
1864 
1865  ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, grd, this->repo_lock_, -1));
1866 
1867  size_t const len = this->handler_rep_.max_size ();
1868 
1869  for (size_t i = 0; i < len; ++i)
1870  {
1871  Event_Tuple *info = this->handler_rep_.find (i);
1872  if (info != 0 && info->suspended && this->resume_handler_i (i) != 0)
1873  return -1;
1874  }
1875 
1876  return 0;
1877 }
1878 
1879 int
1881 {
1882  ACE_TRACE ("ACE_Dev_Poll_Reactor::resume_handler_i");
1883 
1884  Event_Tuple *info = this->handler_rep_.find (handle);
1885  if (info == 0)
1886  return -1;
1887 
1888  if (!info->suspended)
1889  return 0;
1890 
1891  ACE_Reactor_Mask mask = info->mask;
1892  if (mask == ACE_Event_Handler::NULL_MASK)
1893  {
1894  info->suspended = false;
1895  return 0;
1896  }
1897 
1898  // Place the handle back in to the "interest set."
1899  //
1900  // Events for the given handle will once again be polled.
1901 
1902 #if defined (ACE_HAS_EVENT_POLL)
1903 
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;
1911 
1912  if (::epoll_ctl (this->poll_fd_, op, handle, &epev) == -1)
1913  return -1;
1914  info->controlled = true;
1915 
1916 #else
1917 
1918  struct pollfd pfd[1];
1919 
1920  pfd[0].fd = handle;
1921  pfd[0].events = this->reactor_mask_to_poll_event (mask);
1922  pfd[0].revents = 0;
1923 
1924  if (ACE_OS::write (this->poll_fd_, pfd, sizeof (pfd)) != sizeof (pfd))
1925  return -1;
1926 
1927 #endif /* ACE_HAS_EVENT_POLL */
1928 
1929  info->suspended = false;
1930 
1931  return 0;
1932 }
1933 
1934 int
1936 {
1937  // @@ Is this correct?
1938 
1939  return 1;
1940 }
1941 
1942 bool
1944 {
1945  // Since the Dev_Poll_Reactor does not do any event associations,
1946  // this method always return false.
1947  return false;
1948 }
1949 
1950 long
1952  const void *arg,
1953  const ACE_Time_Value &delay,
1954  const ACE_Time_Value &interval)
1955 {
1956  ACE_TRACE ("ACE_Dev_Poll_Reactor::schedule_timer");
1957 
1958  ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1));
1959 
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);
1966 
1967  errno = ESHUTDOWN;
1968  return -1;
1969 }
1970 
1971 int
1973  const ACE_Time_Value &interval)
1974 {
1975  ACE_TRACE ("ACE_Dev_Poll_Reactor::reset_timer_interval");
1976 
1977  ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1));
1978 
1979  if (0 != this->timer_queue_)
1980  return this->timer_queue_->reset_interval (timer_id, interval);
1981 
1982  errno = ESHUTDOWN;
1983  return -1;
1984 }
1985 
1986 int
1988  int dont_call_handle_close)
1989 {
1990  ACE_TRACE ("ACE_Dev_Poll_Reactor::cancel_timer");
1991 
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;
1998 }
1999 
2000 int
2002  const void **arg,
2003  int dont_call_handle_close)
2004 {
2005  ACE_TRACE ("ACE_Dev_Poll_Reactor::cancel_timer");
2006 
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
2010  ? 0
2011  : this->timer_queue_->cancel (timer_id,
2012  arg,
2013  dont_call_handle_close));
2014 }
2015 
2016 int
2018  ACE_Reactor_Mask mask)
2019 {
2020  ACE_TRACE ("ACE_Dev_Poll_Reactor::schedule_wakeup");
2021 
2022  return this->mask_ops (eh->get_handle (), mask, ACE_Reactor::ADD_MASK);
2023 }
2024 
2025 int
2027  ACE_Reactor_Mask mask)
2028 {
2029  ACE_TRACE ("ACE_Dev_Poll_Reactor::schedule_wakeup");
2030 
2031  return this->mask_ops (handle, mask, ACE_Reactor::ADD_MASK);
2032 }
2033 
2034 int
2036  ACE_Reactor_Mask mask)
2037 {
2038  ACE_TRACE ("ACE_Dev_Poll_Reactor::cancel_wakeup");
2039 
2040  return this->mask_ops (eh->get_handle (), mask, ACE_Reactor::CLR_MASK);
2041 }
2042 
2043 int
2045  ACE_Reactor_Mask mask)
2046 {
2047  ACE_TRACE ("ACE_Dev_Poll_Reactor::cancel_wakeup");
2048 
2049  return this->mask_ops (handle, mask, ACE_Reactor::CLR_MASK);
2050 }
2051 
2052 int
2054  ACE_Reactor_Mask mask,
2055  ACE_Time_Value *timeout)
2056 {
2057  ACE_TRACE ("ACE_Dev_Poll_Reactor::notify");
2058 
2059  ssize_t n = 0;
2060 
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.
2064 
2065  n = this->notify_handler_->notify (eh, mask, timeout);
2066 
2067  return n == -1 ? -1 : 0;
2068 }
2069 
2070 void
2072 {
2073  ACE_TRACE ("ACE_Dev_Poll_Reactor::max_notify_iterations");
2074 
2075  ACE_MT (ACE_GUARD (ACE_Dev_Poll_Reactor_Token, mon, this->token_));
2076 
2077  this->notify_handler_->max_notify_iterations (iterations);
2078 }
2079 
2080 int
2082 {
2083  ACE_TRACE ("ACE_Dev_Poll_Reactor::max_notify_iterations");
2084 
2085  ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1));
2086 
2087  return this->notify_handler_->max_notify_iterations ();
2088 }
2089 
2090 int
2092  ACE_Reactor_Mask mask)
2093 {
2094  if (this->notify_handler_ == 0)
2095  return 0;
2096 
2097  return this->notify_handler_->purge_pending_notifications (eh, mask);
2098 }
2099 
2102 {
2103  ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, grd, this->repo_lock_, 0));
2104 
2105  Event_Tuple *info = this->handler_rep_.find (handle);
2106  if (info)
2107  {
2108  info->event_handler->add_reference ();
2109  return info->event_handler;
2110  }
2111  else
2112  {
2113  return 0;
2114  }
2115 }
2116 
2117 int
2119  ACE_Reactor_Mask mask,
2120  ACE_Event_Handler **event_handler)
2121 {
2122  ACE_TRACE ("ACE_Dev_Poll_Reactor::handler");
2123 
2124  ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, grd, this->repo_lock_, -1));
2125 
2126  Event_Tuple *info = this->handler_rep_.find (handle);
2127 
2128  if (info != 0
2129  && ACE_BIT_CMP_MASK (info->mask,
2130  mask, // Compare all bits in the mask
2131  mask))
2132  {
2133  if (event_handler != 0)
2134  *event_handler = info->event_handler;
2135 
2136  return 0;
2137  }
2138 
2139  return -1;
2140 }
2141 
2142 int
2144  ACE_Event_Handler **eh)
2145 {
2146  ACE_TRACE ("ACE_Dev_Poll_Reactor::handler");
2147 
2148  ACE_Event_Handler *handler = this->signal_handler_->handler (signum);
2149 
2150  if (handler == 0)
2151  return -1;
2152  else if (eh != 0)
2153  *eh = handler;
2154 
2155  return 0;
2156 }
2157 
2158 bool
2160 {
2161  ACE_TRACE ("ACE_Dev_Poll_Reactor::initialized");
2162 
2163  ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, false));
2164 
2165  return this->initialized_;
2166 }
2167 
2168 size_t
2170 {
2171  return this->handler_rep_.size ();
2172 }
2173 
2174 ACE_Lock &
2176 {
2177  ACE_TRACE ("ACE_Dev_Poll_Reactor::lock");
2178 
2179  return this->lock_adapter_;
2180 }
2181 
2182 void
2184 {
2185  ACE_TRACE ("ACE_Dev_Poll_Reactor::wakeup_all_threads");
2186 
2187  // Send a notification, but don't block if there's no one to receive
2188  // it.
2189  this->notify (0,
2192 }
2193 
2194 int
2196  ACE_thread_t * /* old_owner */)
2197 {
2198  ACE_TRACE ("ACE_Dev_Poll_Reactor::owner");
2199 
2200  // There is no need to set the owner of the event loop. Multiple
2201  // threads may invoke the event loop simulataneously.
2202 
2203  return 0;
2204 }
2205 
2206 int
2208 {
2209  ACE_TRACE ("ACE_Dev_Poll_Reactor::owner");
2210 
2211  // There is no need to set the owner of the event loop. Multiple
2212  // threads may invoke the event loop simulataneously.
2213 
2214  return 0;
2215 }
2216 
2217 bool
2219 {
2220  ACE_TRACE ("ACE_Dev_Poll_Reactor::restart");
2221 
2222  ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, false));
2223 
2224  return this->restart_;
2225 }
2226 
2227 bool
2229 {
2230  ACE_TRACE ("ACE_Dev_Poll_Reactor::restart");
2231 
2232  ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, false));
2233 
2234  bool current_value = this->restart_;
2235  this->restart_ = r;
2236  return current_value;
2237 }
2238 
2239 void
2241 {
2242  ACE_TRACE ("ACE_Dev_Poll_Reactor::requeue_position");
2243 }
2244 
2245 int
2247 {
2248  ACE_TRACE ("ACE_Dev_Poll_Reactor::requeue_position");
2249 
2250  ACE_NOTSUP_RETURN (-1);
2251 }
2252 
2253 int
2255  ACE_Reactor_Mask mask,
2256  int ops)
2257 {
2258  ACE_TRACE ("ACE_Dev_Poll_Reactor::mask_ops");
2259 
2260  ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, grd, this->repo_lock_, -1));
2261 
2262  return this->mask_ops_i (event_handler->get_handle (), mask, ops);
2263 }
2264 
2265 int
2267  ACE_Reactor_Mask mask,
2268  int ops)
2269 {
2270  ACE_TRACE ("ACE_Dev_Poll_Reactor::mask_ops");
2271 
2272  ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, grd, this->repo_lock_, -1));
2273 
2274  return this->mask_ops_i (handle, mask, ops);
2275 }
2276 
2277 int
2279  ACE_Reactor_Mask mask,
2280  int ops)
2281 {
2282  ACE_TRACE ("ACE_Dev_Poll_Reactor::mask_ops_i");
2283 
2284  Event_Tuple *info = this->handler_rep_.find (handle);
2285  if (info == 0)
2286  return -1;
2287 
2288  // Block out all signals until method returns.
2289  ACE_Sig_Guard sb;
2290 
2291  ACE_Reactor_Mask const old_mask = info->mask;
2292  ACE_Reactor_Mask new_mask = old_mask;
2293 
2294  // Perform GET, CLR, SET, and ADD operations on the interest/wait
2295  // set and the suspend set (if necessary).
2296  //
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)
2303  //
2304  // Returns the original mask.
2305 
2306  switch (ops)
2307  {
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;
2312 
2313  case ACE_Reactor::CLR_MASK:
2314  ACE_CLR_BITS (new_mask, mask);
2315  break;
2316 
2317  case ACE_Reactor::SET_MASK:
2318  new_mask = mask;
2319  break;
2320 
2321  case ACE_Reactor::ADD_MASK:
2322  ACE_SET_BITS (new_mask, mask);
2323  break;
2324 
2325  default:
2326  return -1;
2327  }
2328 
2329  /// Reset the mask for the given handle.
2330  info->mask = new_mask;
2331 
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))
2338  {
2339 
2340  short const events = this->reactor_mask_to_poll_event (new_mask);
2341 
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];
2346 
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;
2353 
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)
2360 
2361  struct epoll_event epev;
2362  ACE_OS::memset (&epev, 0, sizeof (epev));
2363  int op;
2364 
2365  // ACE_Event_Handler::NULL_MASK ???
2366  if (new_mask == 0)
2367  {
2368  op = EPOLL_CTL_DEL;
2369  epev.events = 0;
2370  }
2371  else
2372  {
2373  op = EPOLL_CTL_MOD;
2374  epev.events = events | EPOLLONESHOT;
2375  }
2376 
2377  epev.data.fd = handle;
2378 
2379  if (::epoll_ctl (this->poll_fd_, op, handle, &epev) == -1)
2380  {
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;
2388  }
2389  info->controlled = (op != EPOLL_CTL_DEL);
2390 #else
2391  pollfd pfd[1];
2392 
2393  pfd[0].fd = handle;
2394  pfd[0].events = events;
2395  pfd[0].revents = 0;
2396 
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 */
2403  }
2404 
2405  return old_mask;
2406 }
2407 
2408 int
2410  ACE_Reactor_Mask /* mask */,
2411  int /* ops */)
2412 {
2413  ACE_TRACE ("ACE_Dev_Poll_Reactor::ready_ops");
2414 
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);
2419 }
2420 
2421 int
2422 ACE_Dev_Poll_Reactor::ready_ops (ACE_HANDLE /* handle */,
2423  ACE_Reactor_Mask /* mask */,
2424  int /* ops */)
2425 {
2426  ACE_TRACE ("ACE_Dev_Poll_Reactor::ready_ops");
2427 
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);
2432 }
2433 
2434 void
2436 {
2437 #if defined (ACE_HAS_DUMP)
2438  ACE_TRACE ("ACE_Dev_Poll_Reactor::dump");
2439 
2441  ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("restart_ = %d\n"), this->restart_));
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 ()));
2448  ACE_TEXT ("deactivated_ = %d"),
2449  this->deactivated_));
2451 #endif /* ACE_HAS_DUMP */
2452 }
2453 
2454 short
2456 {
2457  ACE_TRACE ("ACE_Dev_Poll_Reactor::reactor_mask_to_poll_event");
2458 
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 */
2466 
2467  short events = 0;
2468 
2469  // READ, ACCEPT, and CONNECT flag will place the handle in the
2470  // read set.
2474  {
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*/
2480  }
2481 
2482  // WRITE and CONNECT flag will place the handle in the write set.
2485  {
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*/
2491  }
2492 
2493  // EXCEPT flag will place the handle in the except set.
2495  {
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*/
2501  }
2502 
2503  return events;
2504 }
2505 
2506 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
2507 namespace {
2508  void polite_sleep_hook (void *) { }
2509 }
2510 #endif
2511 
2512 int
2514 {
2515  ACE_TRACE ("ACE_Dev_Poll_Reactor::Token_Guard::acquire_quietly");
2516 
2517  // Acquire the token but don't ping any waiters; just queue up politely.
2518  int result = 0;
2519  if (max_wait)
2520  {
2522  tv += *max_wait;
2523 
2524  ACE_MT (result = this->token_.acquire_read (&polite_sleep_hook,
2525  0,
2526  &tv));
2527  }
2528  else
2529  {
2530  ACE_MT (result = this->token_.acquire_read (&polite_sleep_hook));
2531  }
2532 
2533  // Check for timeouts and errors.
2534  if (result == -1)
2535  {
2536  if (errno == ETIME)
2537  return 0;
2538  else
2539  {
2540  ACELIB_ERROR ((LM_ERROR, ACE_TEXT("%t: %p\n"), ACE_TEXT("token acquire_read")));
2541  return -1;
2542  }
2543  }
2544 
2545  // We got the token and so let us mark ourselves as owner
2546  this->owner_ = true;
2547 
2548  return result;
2549 }
2550 
2551 int
2553 {
2554  ACE_TRACE ("ACE_Dev_Poll_Reactor::Token_Guard::acquire");
2555 
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)
2560  {
2562  tv += *max_wait;
2563 
2564  ACE_MT (result = this->token_.acquire (0, 0, &tv));
2565  }
2566  else
2567  {
2568  ACE_MT (result = this->token_.acquire ());
2569  }
2570 
2571  // Check for timeouts and errors.
2572  if (result == -1)
2573  {
2574  if (errno == ETIME)
2575  return 0;
2576  else
2577  return -1;
2578  }
2579 
2580  // We got the token and so let us mark ourseleves as owner
2581  this->owner_ = true;
2582 
2583  return result;
2584 }
2585 
2587 
2588 #endif /* ACE_HAS_EVENT_POLL || ACE_HAS_DEV_POLL */
virtual int handle_input(ACE_HANDLE handle)
virtual bool initialized(void)
virtual int register_handler(ACE_Event_Handler *event_handler, ACE_Reactor_Mask mask)
ACE_Event_Handler * eh_
Provides an abstract interface for handling various types of I/O, timer, and signal events...
Definition: Event_Handler.h:48
A `/dev/poll&#39; or `/dev/epoll&#39; based Reactor implemenatation.
#define ACE_BEGIN_VERSIONED_NAMESPACE_DECL
#define ACE_GUARD(MUTEX, OBJ, LOCK)
int acquire_quietly(ACE_Time_Value *max_wait=0)
int is_member(int signo) const
Checks whether the signal specified by signo is in the set.
Definition: Signal.inl:76
virtual ~ACE_Dev_Poll_Reactor(void)
Close down and release all resources.
ACE_Handle_Set rd_mask_
Read events (e.g., input pending, accept pending).
virtual int notify(ACE_Event_Handler *eh=0, ACE_Reactor_Mask mask=ACE_Event_Handler::EXCEPT_MASK, ACE_Time_Value *timeout=0)
#define ACE_SYNCH_MUTEX
Definition: Synch_Traits.h:92
virtual int resumable_handler(void)
Reference_Counting_Policy & reference_counting_policy(void)
Current Reference_Counting_Policy.
int fcntl(ACE_HANDLE handle, int cmd, long arg=0)
Definition: OS_NS_fcntl.inl:7
virtual ACE_Timer_Queue * timer_queue(void) const
virtual int notify(ACE_Event_Handler *event_handler=0, ACE_Reactor_Mask mask=ACE_Event_Handler::EXCEPT_MASK, ACE_Time_Value *=0)
int unbind(ACE_HANDLE handle, bool decr_refcnt=true)
ACE_Reactor_Notify * notify_handler_
int resume_handler_i(ACE_HANDLE handle)
virtual int dispatch_notify(ACE_Notification_Buffer &buffer)=0
unsigned long ACE_Reactor_Mask
Definition: Event_Handler.h:33
This data structure is meant to be used within a method or function... It performs automatic acquisit...
Definition: Guard_T.h:65
ACE_Sig_Handler * signal_handler_
Handle signals without requiring global/static variables.
virtual int handle_input(ACE_HANDLE fd=ACE_INVALID_HANDLE)
Called when input events occur (e.g., connection or data).
Event handler used for unblocking the ACE_Dev_Poll_Reactor from its event loop.
virtual int handle_output(ACE_HANDLE fd=ACE_INVALID_HANDLE)
C++ wrapper facade for the sigaction struct.
Definition: Signal.h:97
virtual int close(void)=0
Operations on "timeval" structures, which express time in seconds (secs) and microseconds (usecs)...
Definition: Time_Value.h:53
#define ESHUTDOWN
Definition: os_errno.h:235
virtual ACE_HANDLE notify_handle(void)=0
This is the main dispatcher of signals for ACE. It improves the existing UNIX signal handling mechani...
Definition: Sig_Handler.h:41
#define ACELIB_DEBUG(X)
Definition: Log_Category.h:120
virtual int cancel_wakeup(ACE_Event_Handler *event_handler, ACE_Reactor_Mask masks_to_be_cleared)
Clear masks_to_be_cleared from the event_handler&#39;s entry.
virtual int purge_pending_notifications(ACE_Event_Handler *=0, ACE_Reactor_Mask=ACE_Event_Handler::ALL_EVENTS_MASK)
virtual int max_notify_iterations(void)
virtual void dump(void) const
Dump the state of an object.
Base class for all timer queues of a single type.
virtual int resume_handlers(void)
Resume all handles.
int unbind_all(void)
Remove all the registered tuples.
Keeps track of the amount of elapsed time.
virtual void deactivate(int do_stop)
ssize_t recv(ACE_HANDLE handle, void *buf, size_t len, int flags, const ACE_Time_Value *timeout=0)
Receive into a variable number of pieces.
Definition: ACE.cpp:445
virtual ACE_HANDLE notify_handle(void)
virtual int suspend_handlers(void)
Suspend all handles temporarily.
virtual ACE_Time_Value gettimeofday(void)=0
int acquire(void)
Return 0.
Definition: Null_Mutex.h:46
Iterator for the ACE_Handle_Set abstraction.
Definition: Handle_Set.h:175
virtual int current_info(ACE_HANDLE handle, size_t &)
An abstract class for implementing the Reactor Pattern.
Definition: Reactor_Impl.h:125
int acquire(void)
Explicitly acquire the lock.
Definition: Guard_T.inl:9
Simple wrapper for passing ACE_Event_Handler *s and ACE_Reactor_Masks between threads.
ssize_t send(ACE_HANDLE handle, const void *buf, size_t len, int flags, const ACE_Time_Value *timeout=0)
Receive into a variable number of pieces.
Definition: ACE.cpp:1219
Class used to make event handler reference count manipulation exception-safe.
#define ACE_END_DUMP
Definition: Global_Macros.h:33
int dispatch_io_event(Token_Guard &guard)
virtual int remove_handler(int signum, ACE_Sig_Action *new_disp=0, ACE_Sig_Action *old_disp=0, int sigkey=-1)
Remove an ACE_Event_Handler.
int max_size_
Maximum number of handles.
#define ACELIB_ERROR(X)
Definition: Log_Category.h:99
int ssize_t
Definition: os_types.h:119
Provide a C++ wrapper for the C sigset_t interface.
Definition: Signal.h:43
int release(void)
Explicitly release the lock, but only if it is held!
Definition: Guard_T.inl:21
ACE_Reactor_Mask mask
The event mask for the above event handler.
virtual int work_pending(const ACE_Time_Value &max_wait_time=ACE_Time_Value::zero)
virtual Reference_Count add_reference(void)
Increment reference count on the handler.
#define ACE_BIT_DISABLED(WORD, BIT)
Definition: Global_Macros.h:55
#define ACE_NSIG
Definition: os_signal.h:145
virtual int open(ACE_Reactor_Impl *, ACE_Timer_Queue *timer_queue=0, int disable_notify=0)
virtual int read_notify_pipe(ACE_HANDLE handle, ACE_Notification_Buffer &buffer)
virtual int mask_ops(ACE_Event_Handler *event_handler, ACE_Reactor_Mask mask, int ops)
virtual long schedule(const TYPE &type, const void *act, const ACE_Time_Value &future_time, const ACE_Time_Value &interval=ACE_Time_Value::zero)=0
int dequeue_one(ACE_Notification_Buffer &nb)
int close(ACE_HANDLE handle)
virtual int ready_ops(ACE_Event_Handler *event_handler, ACE_Reactor_Mask mask, int ops)
struct pollfd * dp_fds_
The pollfd array that `/dev/poll&#39; will feed its results to.
Abstract class for unblocking an ACE_Reactor_Impl from its event loop.
Definition: Reactor_Impl.h:45
virtual int dispatch_notifications(int &number_of_active_handles, ACE_Handle_Set &rd_mask)
virtual int requeue_position(void)
Get position of the owner thread.
ACE_SYNCH_MUTEX repo_lock_
int register_handler_i(ACE_HANDLE handle, ACE_Event_Handler *eh, ACE_Reactor_Mask mask)
Register the given event handler with the reactor.
#define ACE_BIT_CMP_MASK(WORD, BIT, MASK)
Definition: Global_Macros.h:56
virtual ACE_Lock & lock(void)
Returns a reference to the Reactor&#39;s internal repository lock.
ACE_Event_Handler * event_handler
The event handler.
virtual int open(size_t size, bool restart=false, ACE_Sig_Handler *=0, ACE_Timer_Queue *=0, int disable_notify_pipe=0, ACE_Reactor_Notify *=0)
Initialization.
int set_flags(ACE_HANDLE handle, int flags)
Set flags associated with handle.
Definition: Flag_Manip.cpp:25
int handle_events_i(ACE_Time_Value *max_wait_time, Token_Guard &guard)
virtual int max_notify_iterations(void)
size_t max_size(void) const
Returns the maximum table size.
ssize_t write(ACE_HANDLE handle, const void *buf, size_t nbyte)
ACE_Timer_Queue * timer_queue_
Defined as a pointer to allow overriding by derived classes...
struct pollfd * start_pfds_
virtual bool uses_event_associations(void)
virtual int owner(ACE_thread_t new_owner, ACE_thread_t *old_owner=0)
Transfers ownership of Reactor_Impl to the new_owner.
#define ACELIB_ERROR_RETURN(X, Y)
Definition: Log_Category.h:77
bool suspended
Flag that states whether or not the event handler is suspended.
void release_token(void)
Release the token ..
int mask_ops_i(ACE_HANDLE handle, ACE_Reactor_Mask mask, int ops)
int close(void)
Close down the repository.
ACE_HANDLE open(const char *filename, int mode, mode_t perms=ACE_DEFAULT_OPEN_PERMS, LPSECURITY_ATTRIBUTES sa=0)
Definition: OS_NS_fcntl.cpp:15
#define ACE_NONBLOCK
Definition: os_fcntl.h:87
Provides a very fast and predictable timer implementation.
Definition: Timer_Heap_T.h:28
DWORD ACE_thread_t
Definition: OS_NS_Thread.h:65
int upcall(ACE_Event_Handler *event_handler, int(ACE_Event_Handler::*callback)(ACE_HANDLE), ACE_HANDLE handle)
Perform the upcall with the given event handler method.
virtual int handle_exception(ACE_HANDLE fd=ACE_INVALID_HANDLE)
Called when an exceptional events occur (e.g., SIGURG).
#define ACE_GUARD_RETURN(MUTEX, OBJ, LOCK, RETURN)
bool initialized_
Has the reactor been initialized.
int set_handle_limit(int new_limit=-1, int increase_limit_only=0)
Definition: ACE.cpp:2845
#define ACE_SET_BITS(WORD, BITS)
Definition: Global_Macros.h:57
virtual int notify(ACE_Event_Handler *eh=0, ACE_Reactor_Mask mask=ACE_Event_Handler::EXCEPT_MASK, ACE_Time_Value *timeout=0)=0
int max_handles(void)
Definition: ACE.cpp:2814
size_t size(void) const
Returns the current table size.
ACE_Reactor_Mask mask_
Mask that indicates which method to call.
virtual int schedule_wakeup(ACE_Event_Handler *event_handler, ACE_Reactor_Mask masks_to_be_added)
virtual int purge_pending_notifications(ACE_Event_Handler *=0, ACE_Reactor_Mask=ACE_Event_Handler::ALL_EVENTS_MASK)
Track handles we are interested for various events.
#define ACE_TEXT(STRING)
Definition: ace_wchar.h:105
#define ACE_END_VERSIONED_NAMESPACE_DECL
bool controlled
Flag to say whether or not this handle is registered with epoll.
virtual int close(void)=0
#define ETIME
Definition: os_errno.h:163
int size_
Current number of handles.
virtual long schedule_timer(ACE_Event_Handler *event_handler, const void *arg, const ACE_Time_Value &delay, const ACE_Time_Value &interval=ACE_Time_Value::zero)
Event_Tuple * find(ACE_HANDLE handle)
virtual int purge_pending_notifications(ACE_Event_Handler *=0, ACE_Reactor_Mask=ACE_Event_Handler::ALL_EVENTS_MASK)=0
int bind(ACE_HANDLE handle, ACE_Event_Handler *handler, ACE_Reactor_Mask mask)
ACE_Dev_Poll_Reactor(ACE_Sig_Handler *=0, ACE_Timer_Queue *=0, int disable_notify_pipe=0, ACE_Reactor_Notify *notify=0, int mask_signals=1, int s_queue=ACE_DEV_POLL_TOKEN::FIFO)
Initialize ACE_Dev_Poll_Reactor with the default size.
Set value of bits to new mask (changes the entire mask).
Definition: Reactor.h:65
Value value(void) const
Current Reference_Counting_Policy.
virtual bool restart(void)
Get the existing restart value.
bool invalid_handle(ACE_HANDLE handle) const
virtual int dispatch_notify(ACE_Notification_Buffer &buffer)
virtual int cancel(const TYPE &type, int dont_call_handle_close=1)=0
virtual int suspend_handler(ACE_Event_Handler *event_handler)
virtual int handle_close(ACE_HANDLE handle, ACE_Reactor_Mask close_mask)
bool handle_in_range(ACE_HANDLE handle) const
int acquire_read(void)
Return 0.
Definition: Null_Mutex.h:70
int dispatch_timer_handler(Token_Guard &guard)
virtual int deactivated(void)
Event_Tuple * handlers_
The underlying array of event handlers.
Struct that collects event registration information for a handle.
#define ACE_BEGIN_DUMP
Definition: Global_Macros.h:32
ACE_ALLOC_HOOK_DEFINE(ACE_Based_Pointer_Repository_Rep)
virtual ACE_HANDLE get_handle(void) const
Get the I/O handle.
virtual int handler(ACE_HANDLE handle, ACE_Reactor_Mask mask, ACE_Event_Handler **event_handler=0)
ACE_Lock_Adapter< ACE_Dev_Poll_Reactor_Token > lock_adapter_
Adapter used to return internal lock to outside world.
virtual void wakeup_all_threads(void)
Wake up all threads waiting in the event loop.
int dispatch(Token_Guard &guard)
unsigned long msec(void) const
Converts from ACE_Time_Value format into milliseconds format.
Definition: Time_Value.inl:136
void * memset(void *s, int c, size_t len)
Fills a buffer with a character value.
virtual int open(ACE_Reactor_Impl *, ACE_Timer_Queue *timer_queue=0, int disable_notify=0)=0
#define EWOULDBLOCK
Definition: os_errno.h:166
Handler_Repository handler_rep_
The repository that contains all registered event handlers.
virtual int close(void)
Close down and release all resources.
static const ACE_Time_Value zero
Constant "0".
Definition: Time_Value.h:57
virtual ACE_Time_Value * calculate_timeout(ACE_Time_Value *max)=0
virtual int remove_handler(ACE_Event_Handler *event_handler, ACE_Reactor_Mask mask)
Removes event_handler.
virtual int set_sig_handler(ACE_Sig_Handler *signal_handler)
Use a user specified signal handler instead.
ACE_Time_Value gettimeofday(void)
Defines a class template that allows us to invoke a member function using the GoF command style callb...
Definition: Functor_T.h:89
virtual int dispatch_notifications(int &number_of_active_handles, ACE_Handle_Set &rd_mask)=0
This is the abstract base class that contains the uniform locking API that is supported by all the AC...
Definition: Lock.h:41
C++ wrapper facade for the socket fd_set abstraction.
Definition: Handle_Set.h:55
virtual Reference_Count remove_reference(void)
Decrement reference count on the handler.
#define ACE_NEW_RETURN(POINTER, CONSTRUCTOR, RET_VAL)
Definition: OS_Memory.h:215
struct pollfd * end_pfds_
The last element in the pollfd array plus one.
virtual int handle_events(ACE_Time_Value *max_wait_time=0)
Hold signals in MASK for duration of a C++ statement block. Note that a "0" for mask causes all signa...
Definition: Signal.h:222
virtual int cancel_timer(ACE_Event_Handler *event_handler, int dont_call_handle_close=1)
virtual ACE_Event_Handler * find_handler(ACE_HANDLE handle)
virtual int reset_timer_interval(long timer_id, const ACE_Time_Value &interval)
int acquire(ACE_Time_Value *max_wait=0)
#define ACE_TRACE(X)
Definition: config-all.h:47
virtual void dump(void) const
Dump the state of an object.
virtual size_t size(void) const
int suspend_handler_i(ACE_HANDLE handle)
Temporarily remove the given handle from the "interest set.".
#define ACE_CLR_BITS(WORD, BITS)
Definition: Global_Macros.h:58
int work_pending_i(ACE_Time_Value *max_wait_time)
Non-locking version of wait_pending().
Error messages (decimal 128).
Definition: Log_Priority.h:59
virtual int expire_single(ACE_Command_Base &pre_dispatch_command)=0
virtual ACE_Event_Handler * handler(int signum)
Return the ACE_Sig_Handler associated with signum.
Definition: Sig_Handler.cpp:88
int remove_handler_i(ACE_HANDLE handle, ACE_Reactor_Mask mask, ACE_Guard< ACE_SYNCH_MUTEX > &repo_guard, ACE_Event_Handler *eh=0)
virtual void max_notify_iterations(int)=0
virtual int is_dispatchable(ACE_Notification_Buffer &buffer)
Verify whether the buffer has dispatchable info or not.
virtual int resume_handler(ACE_Event_Handler *event_handler)
#define ACE_NOTSUP_RETURN(FAILVALUE)
Definition: config-all.h:33
#define ACE_BIT_ENABLED(WORD, BIT)
Definition: Global_Macros.h:54
virtual int alertable_handle_events(ACE_Time_Value *max_wait_time=0)
static int sig_pending(void)
True if there is a pending signal.
Definition: Sig_Handler.cpp:65
virtual int resume_handler(void)
virtual int reset_interval(long timer_id, const ACE_Time_Value &interval)=0
int ioctl(ACE_HANDLE handle, ACE_IOCTL_TYPE_ARG2 cmd, void *=0)
UNIX-style ioctl.
virtual int register_handler(int signum, ACE_Event_Handler *new_sh, ACE_Sig_Action *new_disp=0, ACE_Event_Handler **old_sh=0, ACE_Sig_Action *old_disp=0)
short reactor_mask_to_poll_event(ACE_Reactor_Mask mask)
Convert a reactor mask to its corresponding poll() event mask.
A helper class that helps grabbing, releasing and waiting on tokens for a thread that needs access to...
ACE_Dev_Poll_Reactor_Token token_
Token serializing event waiter threads.