Merge pull request #2309 from mitza-oci/warnings
[ACE_TAO.git] / ACE / ace / Dev_Poll_Reactor.h
blob6b0d99b5e94b17106e8778d0a11553f902e608f5
1 // -*- C++ -*-
3 // =========================================================================
4 /**
5 * @file Dev_Poll_Reactor.h
7 * @c /dev/poll (or Linux @c sys_epoll) based Reactor implementation.
9 * @author Ossama Othman <ossama@dre.vanderbilt.edu>
11 // =========================================================================
14 #ifndef ACE_DEV_POLL_REACTOR_H
15 #define ACE_DEV_POLL_REACTOR_H
17 #include /**/ "ace/pre.h"
19 #include /**/ "ace/ACE_export.h"
21 #if !defined (ACE_LACKS_PRAGMA_ONCE)
22 # pragma once
23 #endif /* ACE_LACKS_PRAGMA_ONCE */
25 #if defined (ACE_HAS_EVENT_POLL) && defined (ACE_HAS_DEV_POLL)
26 # error ACE_HAS_EVENT_POLL and ACE_HAS_DEV_POLL are mutually exclusive.
27 #endif /* ACE_HAS_EVENT_POLL && defined ACE_HAS_DEV_POLL */
29 #if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL)
31 #include "ace/Pipe.h"
32 #include "ace/Lock_Adapter_T.h"
33 #include "ace/Reactor_Impl.h"
34 #include "ace/Reactor_Token_T.h"
35 #include "ace/Token.h"
37 #if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE)
38 # include "ace/Notification_Queue.h"
39 #endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */
41 #if defined (ACE_HAS_DEV_POLL)
42 struct pollfd;
43 #elif defined (ACE_HAS_EVENT_POLL)
44 # include "ace/Array_Map.h"
45 # include /**/ <sys/epoll.h>
46 #endif
48 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
50 // Forward declarations
51 class ACE_Sig_Handler;
52 class ACE_Dev_Poll_Reactor;
54 // ---------------------------------------------------------------------
56 /**
57 * @class ACE_Dev_Poll_Reactor_Notify
59 * @brief Event handler used for unblocking the ACE_Dev_Poll_Reactor
60 * from its event loop.
62 * This event handler is used internally by the ACE_Dev_Poll_Reactor
63 * as a means to allow a thread other then the one running the event
64 * loop to unblock the event loop.
66 class ACE_Dev_Poll_Reactor_Notify : public ACE_Reactor_Notify
68 public:
69 /// Constructor
70 ACE_Dev_Poll_Reactor_Notify ();
72 /**
73 * @name Initialization and Termination Methods
75 * Methods called when initializing and terminating this event
76 * handler.
78 virtual int open (ACE_Reactor_Impl *,
79 ACE_Timer_Queue *timer_queue = 0,
80 int disable_notify = 0);
81 virtual int close ();
83 /**
84 * Called by a thread when it wants to unblock the Reactor_Impl.
85 * This wakes up the Reactor_Impl if currently blocked. Pass over
86 * both the Event_Handler and the mask to allow the caller to
87 * dictate which Event_Handler method the Reactor_Impl will
88 * invoke. The ACE_Time_Value indicates how long to block
89 * trying to notify the Reactor_Impl. If timeout == 0, the
90 * caller will block until action is possible, else will wait until
91 * the relative time specified in *timeout elapses).
93 virtual int notify (ACE_Event_Handler *eh = 0,
94 ACE_Reactor_Mask mask = ACE_Event_Handler::EXCEPT_MASK,
95 ACE_Time_Value *timeout = 0);
97 /// Unimplemented method required by pure virtual method in abstract
98 /// base class.
99 /**
100 * This method's interface is not very compatible with this
101 * Reactor's design. It's not clear why this method is pure virtual
102 * either.
104 virtual int dispatch_notifications (int &number_of_active_handles,
105 ACE_Handle_Set &rd_mask);
107 /// Returns the ACE_HANDLE of the notify pipe on which the reactor
108 /// is listening for notifications so that other threads can unblock
109 /// the Reactor_Impl.
110 virtual ACE_HANDLE notify_handle ();
112 /// Verify whether the buffer has dispatchable info or not.
113 virtual int is_dispatchable (ACE_Notification_Buffer &buffer);
115 /// Handle one notify call represented in @a buffer. This could be
116 /// because of a thread trying to unblock the Reactor_Impl.
117 virtual int dispatch_notify (ACE_Notification_Buffer &buffer);
119 /// Read one notify call on the handle into @a buffer.
120 /// This could be because of a thread trying to unblock the Reactor_Impl.
121 virtual int read_notify_pipe (ACE_HANDLE handle,
122 ACE_Notification_Buffer &buffer);
124 /// Called back by the ACE_Dev_Poll_Reactor when a thread wants to
125 /// unblock us.
126 virtual int handle_input (ACE_HANDLE handle);
129 * Set the maximum number of times that the handle_input method
130 * will iterate and dispatch the ACE_Event_Handlers that are
131 * passed in via the notify queue before breaking out of the event
132 * loop. By default, this is set to -1, which means "iterate until
133 * the queue is empty." Setting this to a value like "1 or 2" will
134 * increase "fairness" (and thus prevent starvation) at the expense
135 * of slightly higher dispatching overhead.
137 virtual void max_notify_iterations (int);
140 * Get the maximum number of times that the handle_input method
141 * will iterate and dispatch the ACE_Event_Handlers that are
142 * passed in via the notify queue before breaking out of its event
143 * loop.
145 virtual int max_notify_iterations ();
148 * Purge any notifications pending in this reactor for the specified
149 * ACE_Event_Handler object. Returns the number of notifications
150 * purged. Returns -1 on error.
152 virtual int purge_pending_notifications (
153 ACE_Event_Handler * = 0,
154 ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK);
156 /// Dump the state of an object.
157 virtual void dump () const;
159 /// Method called by ACE_Dev_Poll_Reactor to obtain one notification.
160 /// THIS METHOD MUST BE CALLED WITH THE REACTOR TOKEN HELD!
162 /// @return -1 on error, else 0 and @arg nb has the notify to
163 /// dispatch. Note that the contained event handler may be
164 /// 0 if there were only wake-ups (no handlers to dispatch).
165 int dequeue_one (ACE_Notification_Buffer &nb);
167 ACE_ALLOC_HOOK_DECLARE;
169 protected:
171 * Keep a back pointer to the ACE_Dev_Poll_Reactor. If this value
172 * if NULL then the ACE_Dev_Poll_Reactor has been initialized with
173 * disable_notify_pipe.
175 ACE_Dev_Poll_Reactor *dp_reactor_;
178 * Contains the ACE_HANDLE the ACE_Dev_Poll_Reactor is listening
179 * on, as well as the ACE_HANDLE that threads wanting the attention
180 * of the ACE_Dev_Poll_Reactor will write to.
182 ACE_Pipe notification_pipe_;
185 * Keeps track of the maximum number of times that the
186 * ACE_Dev_Poll_Reactor_Notify::handle_input method will iterate and
187 * dispatch the ACE_Event_Handlers that are passed in via the
188 * notify pipe before breaking out of its recv loop. By default,
189 * this is set to -1, which means "iterate until the pipe is empty."
191 int max_notify_iterations_;
193 #if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE)
195 * @brief A user-space queue to store the notifications.
197 * The notification pipe has OS-specific size restrictions. That
198 * is, no more than a certain number of bytes may be stored in the
199 * pipe without blocking. This limit may be too small for certain
200 * applications. In this case, ACE can be configured to store all
201 * the events in user-space. The pipe is still needed to wake up
202 * the reactor thread, but only one event is sent through the pipe
203 * at a time.
205 ACE_Notification_Queue notification_queue_;
206 #endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */
209 // ---------------------------------------------------------------------
212 * @class ACE_Dev_Poll_Reactor
214 * @brief A `/dev/poll' or `/dev/epoll' based Reactor implemenatation.
216 * @attention The Linux epoll implementation works quite well and is
217 * fully supported; however, the /dev/poll implementation is @em experimental.
219 * The ACE_Dev_Poll_Reactor uses the `/dev/poll' or '/dev/epoll'
220 * character devices to demultiplex events on a given set of file
221 * descriptors. Unlike @c select(), `/dev/poll' and `/dev/epoll' have
222 * no hard-coded limit on the number of file descriptors that may be
223 * handled at any given time. As such, the ACE_Dev_Poll_Reactor can
224 * generally handle a much larger number of file descriptors than
225 * @c select() -based reactors. Furthermore, since `/dev/poll' and
226 * `/dev/epoll' both return a set of file descriptors that are active,
227 * there is no need to "walk" the set of file descriptors to determine
228 * which ones are active, such as what is done with the @c select() and
229 * @c poll() system calls. All returned file descriptors are active.
230 * This makes event dispatching very efficient.
232 * @note In general, this reactor may only be used to demultiplex
233 * events on sockets. Demultiplexing events on pipes, for
234 * example may not work. This is due to a limitation in the
235 * underlying `/dev/poll' device driver.
237 * @note It is only possible to achieve millisecond timeout
238 * resolutions with the @c ACE_Dev_Poll_Reactor. However, the
239 * timeout resolution for timers is independent of the reactors
240 * timeout resolution. As such, it may be possible to achieve
241 * sub-millisecond timeout resolutions for timers but that is
242 * entirely platform dependent.
245 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
246 typedef ACE_Token ACE_DEV_POLL_TOKEN;
247 #else
248 typedef ACE_Noop_Token ACE_DEV_POLL_TOKEN;
249 #endif /* ACE_MT_SAFE && ACE_MT_SAFE != 0 */
250 typedef ACE_Reactor_Token_T<ACE_DEV_POLL_TOKEN> ACE_Dev_Poll_Reactor_Token;
252 class ACE_Export ACE_Dev_Poll_Reactor : public ACE_Reactor_Impl
255 * @struct Event_Tuple
257 * @brief Struct that collects event registration information for a handle.
259 * @internal Internal use only
261 * This struct merely provides a means to associate an event mask
262 * with an event handler. Such an association is needed since it is
263 * not possible to retrieve the event mask from the "interest set"
264 * stored in the `/dev/poll' or `/dev/epoll' driver. Without this
265 * external association, it would not be possible keep track of the
266 * event mask for a given event handler when suspending it or resuming
267 * it.
269 * @note An ACE_Handle_Set is not used since the number of handles may
270 * exceed its capacity (ACE_DEFAULT_SELECT_REACTOR_SIZE).
272 struct Event_Tuple
274 /// Constructor to set up defaults.
275 Event_Tuple (ACE_Event_Handler *eh = 0,
276 ACE_Reactor_Mask m = ACE_Event_Handler::NULL_MASK,
277 bool is_suspended = false,
278 bool is_controlled = false);
280 /// The event handler.
281 ACE_Event_Handler *event_handler;
283 /// The event mask for the above event handler.
284 ACE_Reactor_Mask mask;
286 /// Flag that states whether or not the event handler is suspended.
287 bool suspended;
289 /// Flag to say whether or not this handle is registered with epoll.
290 bool controlled;
292 ACE_ALLOC_HOOK_DECLARE;
296 // ---------------------------------------------------------------------
299 * @class Handler_Repository
301 * @internal
303 * @brief Used to map ACE_HANDLEs onto the appropriate Event_Tuple.
305 * This class is simply a container that maps a handle to its
306 * corresponding event tuple. It is not meant for use outside of
307 * the Dev_Poll_Reactor.
309 * @note Calls to any method in this class, and any modification to a
310 * Event_Tuple returned from this class's methods, must be made
311 * while holding the repository lock.
313 class Handler_Repository
315 public:
316 /// Constructor.
317 Handler_Repository ();
319 /// Initialize a repository that can map handles up to the value @a size.
320 /// Since the event tuples are accessed directly using the handle as
321 /// an index, @a size sets the maximum handle value, minus 1.
322 int open (size_t size);
324 /// Close down the repository.
325 int close ();
328 * @name Repository Manipulation Operations
330 * Methods used to search and modify the handler repository.
332 //@{
333 /// Return a pointer to the Event_Tuple associated with @a handle.
334 /// If there is none associated, returns 0 and sets errno.
335 Event_Tuple *find (ACE_HANDLE handle);
338 /// Bind the ACE_Event_Handler to the @c ACE_HANDLE with the
339 /// appropriate ACE_Reactor_Mask settings.
340 int bind (ACE_HANDLE handle,
341 ACE_Event_Handler *handler,
342 ACE_Reactor_Mask mask);
344 /// Remove the binding for @a handle; optionally decrement the associated
345 /// handler's reference count.
346 int unbind (ACE_HANDLE handle, bool decr_refcnt = true);
348 /// Remove all the registered tuples.
349 int unbind_all ();
351 //@}
354 * @name Sanity Checking
356 * Methods used to prevent "out-of-range" errors when indexing the
357 * underlying handler array.
359 //@{
360 // Check the @a handle to make sure it's a valid @c ACE_HANDLE that
361 // within the range of legal handles (i.e., greater than or equal to
362 // zero and less than @c max_size_).
363 bool invalid_handle (ACE_HANDLE handle) const;
365 // Check the handle to make sure it's a valid @c ACE_HANDLE that is
366 // within the range of currently registered handles (i.e., greater
367 // than or equal to zero and less than @c max_handlep1_).
368 bool handle_in_range (ACE_HANDLE handle) const;
370 //@}
372 /// Returns the current table size.
373 size_t size () const;
375 /// Returns the maximum table size.
376 size_t max_size () const;
378 /// Dump the state of an object.
379 void dump () const;
381 /// Declare the dynamic allocation hooks.
382 ACE_ALLOC_HOOK_DECLARE;
384 private:
385 /// Current number of handles.
386 int size_;
388 /// Maximum number of handles.
389 int max_size_;
391 /// The underlying array of event handlers.
393 * The array of event handlers is directly indexed directly using
394 * an @c ACE_HANDLE value. This is Unix-specific.
396 Event_Tuple *handlers_;
399 public:
400 /// Initialize @c ACE_Dev_Poll_Reactor with the default size.
402 * The default size for the @c ACE_Dev_Poll_Reactor is the maximum
403 * number of open file descriptors for the process.
405 ACE_Dev_Poll_Reactor (ACE_Sig_Handler * = 0,
406 ACE_Timer_Queue * = 0,
407 int disable_notify_pipe = 0,
408 ACE_Reactor_Notify *notify = 0,
409 int mask_signals = 1,
410 int s_queue = ACE_DEV_POLL_TOKEN::FIFO);
412 /// Initialize ACE_Dev_Poll_Reactor with size @a size.
414 * @note On Unix platforms, the @a size parameter should be as large
415 * as the maximum number of file descriptors allowed for a
416 * given process. This is necessary since a file descriptor
417 * is used to directly index the array of event handlers
418 * maintained by the Reactor's handler repository. Direct
419 * indexing is used for efficiency reasons. If the size
420 * parameter is less than the process maximum, the process
421 * maximum will be decreased in order to prevent potential
422 * access violations.
424 ACE_Dev_Poll_Reactor (size_t size,
425 bool restart = false,
426 ACE_Sig_Handler * = 0,
427 ACE_Timer_Queue * = 0,
428 int disable_notify_pipe = 0,
429 ACE_Reactor_Notify *notify = 0,
430 int mask_signals = 1,
431 int s_queue = ACE_DEV_POLL_TOKEN::FIFO);
433 /// Close down and release all resources.
434 virtual ~ACE_Dev_Poll_Reactor ();
436 /// Initialization.
437 virtual int open (size_t size,
438 bool restart = false,
439 ACE_Sig_Handler * = 0,
440 ACE_Timer_Queue * = 0,
441 int disable_notify_pipe = 0,
442 ACE_Reactor_Notify * = 0);
445 * @param handle allows the reactor to check if the caller is
446 * valid.
448 * @return 0 if the size of the current message has been put in
449 * size. -1 if not.
451 virtual int current_info (ACE_HANDLE handle, size_t & /* size */);
453 /// Use a user specified signal handler instead.
454 virtual int set_sig_handler (ACE_Sig_Handler *signal_handler);
456 /// Set a user-specified timer queue.
457 virtual int timer_queue (ACE_Timer_Queue *tq);
459 /// Get the timer queue
460 /// @return The current @c ACE_Timer_Queue.
461 virtual ACE_Timer_Queue *timer_queue () const;
463 /// Close down and release all resources.
464 virtual int close ();
466 // = Event loop drivers.
468 * Returns non-zero if there are I/O events "ready" for dispatching,
469 * but does not actually dispatch the event handlers. By default,
470 * don't block while checking this, i.e., "poll".
472 * @note It is only possible to achieve millisecond timeout
473 * resolutions with the @c ACE_Dev_Poll_Reactor.
475 virtual int work_pending (
476 const ACE_Time_Value &max_wait_time = ACE_Time_Value::zero);
479 * This event loop driver blocks for up to @a max_wait_time before
480 * returning. It will return earlier if events occur. Note that
481 * @a max_wait_time can be 0, in which case this method blocks
482 * indefinitely until events occur.
483 * @par
484 * @a max_wait_time is decremented to reflect how much time this
485 * call took. For instance, if a time value of 3 seconds is passed
486 * to @c handle_events() and an event occurs after 2 seconds,
487 * @a max_wait_time will equal 1 second. This can be used if an
488 * application wishes to handle events for some fixed amount of
489 * time.
490 * @par
491 * The only difference between @c alertable_handle_events() and
492 * handle_events() is that in the alertable case, the event loop
493 * will return when the system queues an I/O completion routine or
494 * an Asynchronous Procedure Call.
496 * @return The total number of @c ACE_Event_Handlers that were
497 * dispatched, 0 if the @a max_wait_time elapsed without
498 * dispatching any handlers, or -1 if an error occurs.
500 * @note It is only possible to achieve millisecond timeout
501 * resolutions with the @c ACE_Dev_Poll_Reactor.
503 virtual int handle_events (ACE_Time_Value *max_wait_time = 0);
504 virtual int alertable_handle_events (ACE_Time_Value *max_wait_time = 0);
507 * This method is just like the one above, except the
508 * @a max_wait_time value is a reference and can therefore never be
509 * @c NULL.
511 * @note It is only possible to achieve millisecond timeout
512 * resolutions with the @c ACE_Dev_Poll_Reactor.
514 virtual int handle_events (ACE_Time_Value &max_wait_time);
515 virtual int alertable_handle_events (ACE_Time_Value &max_wait_time);
517 // = Event handling control.
520 * @return The status of Reactor. If this function returns 0, the
521 * reactor is actively handling events. If it returns
522 * non-zero, @c handle_events() and
523 * @c handle_alertable_events() return -1 immediately.
525 virtual int deactivated ();
528 * Control whether the Reactor will handle any more incoming events
529 * or not. If @a do_stop == 1, the Reactor will be disabled. By
530 * default, a reactor is in active state and can be
531 * deactivated/reactived as desired.
533 virtual void deactivate (int do_stop);
535 // = Register and remove Handlers.
537 /// Register @a event_handler with @a mask. The I/O handle will
538 /// always come from get_handle on the event_handler.
539 virtual int register_handler (ACE_Event_Handler *event_handler,
540 ACE_Reactor_Mask mask);
542 /// Register @a event_handler with @a mask. The I/O handle is
543 /// provided through the @a io_handle parameter.
544 virtual int register_handler (ACE_HANDLE io_handle,
545 ACE_Event_Handler *event_handler,
546 ACE_Reactor_Mask mask);
549 * Register an @a event_handler that will be notified when
550 * @a event_handle is signaled. @a mask specifies the network
551 * events that the @a event_handler is interested in.
553 virtual int register_handler (ACE_HANDLE event_handle,
554 ACE_HANDLE io_handle,
555 ACE_Event_Handler *event_handler,
556 ACE_Reactor_Mask mask);
558 /// Register @a event_handler with all the @a handles in the @c
559 /// Handle_Set.
560 virtual int register_handler (const ACE_Handle_Set &handles,
561 ACE_Event_Handler *event_handler,
562 ACE_Reactor_Mask mask);
565 * Register @a new_sh to handle the signal @a signum using the
566 * @a new_disp. Returns the @a old_sh that was previously
567 * registered (if any), along with the @a old_disp of the signal
568 * handler.
570 virtual int register_handler (int signum,
571 ACE_Event_Handler *new_sh,
572 ACE_Sig_Action *new_disp = 0,
573 ACE_Event_Handler **old_sh = 0,
574 ACE_Sig_Action *old_disp = 0);
576 /// Registers @a new_sh to handle a set of signals @a sigset using the
577 /// @a new_disp.
578 virtual int register_handler (const ACE_Sig_Set &sigset,
579 ACE_Event_Handler *new_sh,
580 ACE_Sig_Action *new_disp = 0);
582 /// Removes @a event_handler.
584 * @note The I/O handle will be obtained using @c get_handle()
585 * method of @a event_handler . If @a mask ==
586 * @c ACE_Event_Handler::DONT_CALL then the @c handle_close()
587 * method of the @a event_handler is not invoked.
589 virtual int remove_handler (ACE_Event_Handler *event_handler,
590 ACE_Reactor_Mask mask);
593 * Removes @a handle. If @a mask == ACE_Event_Handler::DONT_CALL
594 * then the <handle_close> method of the associated <event_handler>
595 * is not invoked.
597 virtual int remove_handler (ACE_HANDLE handle,
598 ACE_Reactor_Mask mask);
601 * Removes all handles in @a handle_set. If @a mask ==
602 * ACE_Event_Handler::DONT_CALL then the <handle_close> method of
603 * the associated <event_handler>s is not invoked.
605 virtual int remove_handler (const ACE_Handle_Set &handle_set,
606 ACE_Reactor_Mask mask);
609 * Remove the ACE_Event_Handler currently associated with @a signum.
610 * Install the new disposition (if given) and return the previous
611 * disposition (if desired by the caller). Returns 0 on success and
612 * -1 if @a signum is invalid.
614 virtual int remove_handler (int signum,
615 ACE_Sig_Action *new_disp,
616 ACE_Sig_Action *old_disp = 0,
617 int sigkey = -1);
619 /// Calls <remove_handler> for every signal in @a sigset.
620 virtual int remove_handler (const ACE_Sig_Set &sigset);
622 // = Suspend and resume Handlers.
624 /// Suspend event_handler temporarily. Use
625 /// ACE_Event_Handler::get_handle() to get the handle.
626 virtual int suspend_handler (ACE_Event_Handler *event_handler);
628 /// Suspend handle temporarily.
629 virtual int suspend_handler (ACE_HANDLE handle);
631 /// Suspend all handles in handle set temporarily.
632 virtual int suspend_handler (const ACE_Handle_Set &handles);
634 /// Suspend all handles temporarily.
635 virtual int suspend_handlers ();
637 /// Resume event_handler. Use ACE_Event_Handler::get_handle() to
638 /// get the handle.
639 virtual int resume_handler (ACE_Event_Handler *event_handler);
641 /// Resume handle.
642 virtual int resume_handler (ACE_HANDLE handle);
644 /// Resume all handles in handle set.
645 virtual int resume_handler (const ACE_Handle_Set &handles);
647 /// Resume all handles.
648 virtual int resume_handlers ();
650 /// Does the reactor allow the application to resume the handle on
651 /// its own, i.e., can it pass on the control of handle resumption to
652 /// the application.
653 virtual int resumable_handler ();
655 /// Return true if we any event associations were made by the reactor
656 /// for the handles that it waits on, false otherwise.
657 virtual bool uses_event_associations ();
659 // = Timer management.
662 * Schedule an ACE_Event_Handler that will expire after an amount
663 * of time. The return value of this method, a timer_id value,
664 * uniquely identifies the event_handler in the ACE_Reactor's
665 * internal list of timers.
666 * This timer_id value can be used to cancel the timer
667 * with the cancel_timer() call.
669 * @see cancel_timer()
670 * @see reset_timer_interval()
672 * @param event_handler event handler to schedule on reactor
673 * @param arg argument passed to the handle_timeout() method of
674 * event_handler.
675 * @param delay time interval after which the timer will expire.
676 * @param interval time interval for which the timer will be
677 * automatically rescheduled.
678 * @return -1 on failure, a timer_id value on success
680 virtual long schedule_timer (ACE_Event_Handler *event_handler,
681 const void *arg,
682 const ACE_Time_Value &delay,
683 const ACE_Time_Value &interval = ACE_Time_Value::zero);
686 * Resets the interval of the timer represented by @a timer_id to
687 * @a interval, which is specified in relative time to the current
688 * <gettimeofday>. If @a interval is equal to
689 * ACE_Time_Value::zero, the timer will become a non-rescheduling
690 * timer. Returns 0 if successful, -1 if not.
692 virtual int reset_timer_interval (long timer_id,
693 const ACE_Time_Value &interval);
695 /// Cancel all Event_Handlers that match the address of
696 /// @a event_handler. Returns number of handlers cancelled.
697 virtual int cancel_timer (ACE_Event_Handler *event_handler,
698 int dont_call_handle_close = 1);
701 * Cancel the single event handler that matches the @a timer_id value
702 * (which was returned from the schedule method). If @a arg is
703 * non-NULL then it will be set to point to the ``magic cookie''
704 * argument passed in when the event handler was registered. This
705 * makes it possible to free up the memory and avoid memory leaks.
706 * Returns 1 if cancellation succeeded and 0 if the @a timer_id
707 * wasn't found.
709 virtual int cancel_timer (long timer_id,
710 const void **arg = 0,
711 int dont_call_handle_close = 1);
713 // = High-level event handler scheduling operations
715 /// Add @a masks_to_be_added to the @a event_handler's entry.
716 /// @a event_handler must already have been registered.
717 virtual int schedule_wakeup (ACE_Event_Handler *event_handler,
718 ACE_Reactor_Mask masks_to_be_added);
720 /// Add @a masks_to_be_added to the @a handle's entry. <event_handler>
721 /// associated with @a handle must already have been registered.
722 virtual int schedule_wakeup (ACE_HANDLE handle,
723 ACE_Reactor_Mask masks_to_be_added);
725 /// Clear @a masks_to_be_cleared from the @a event_handler's entry.
726 virtual int cancel_wakeup (ACE_Event_Handler *event_handler,
727 ACE_Reactor_Mask masks_to_be_cleared);
729 /// Clear @a masks_to_be_cleared from the @a handle's entry.
730 virtual int cancel_wakeup (ACE_HANDLE handle,
731 ACE_Reactor_Mask masks_to_be_cleared);
733 // = Notification methods.
736 * Notify @a event_handler of @a mask event. The ACE_Time_Value
737 * indicates how long to blocking trying to notify. If @a timeout ==
738 * 0, the caller will block until action is possible, else will wait
739 * until the relative time specified in @a timeout elapses).
741 virtual int notify (ACE_Event_Handler *event_handler = 0,
742 ACE_Reactor_Mask mask = ACE_Event_Handler::EXCEPT_MASK,
743 ACE_Time_Value * = 0);
746 * Set the maximum number of times that ACE_Reactor_Impl will
747 * iterate and dispatch the ACE_Event_Handlers that are passed in
748 * via the notify queue before breaking out of its
749 * ACE_Message_Queue::dequeue() loop. By default, this is set to
750 * -1, which means "iterate until the queue is empty." Setting this
751 * to a value like "1 or 2" will increase "fairness" (and thus
752 * prevent starvation) at the expense of slightly higher dispatching
753 * overhead.
755 virtual void max_notify_iterations (int);
758 * Get the maximum number of times that the ACE_Reactor_Impl will
759 * iterate and dispatch the ACE_Event_Handlers that are passed in
760 * via the notify queue before breaking out of its
761 * ACE_Message_Queue::dequeue() loop.
763 virtual int max_notify_iterations ();
766 * Purge any notifications pending in this reactor for the specified
767 * ACE_Event_Handler object. Returns the number of notifications
768 * purged. Returns -1 on error.
770 virtual int purge_pending_notifications (ACE_Event_Handler * = 0,
771 ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK);
774 * Return the Event_Handler associated with @a handle. Return 0 if
775 * @a handle is not registered.
777 virtual ACE_Event_Handler *find_handler (ACE_HANDLE handle);
780 * Check to see if @a handle is associated with a valid Event_Handler
781 * bound to @a mask. Return the @a event_handler associated with this
782 * @c handler if @a event_handler != 0.
784 virtual int handler (ACE_HANDLE handle,
785 ACE_Reactor_Mask mask,
786 ACE_Event_Handler **event_handler = 0);
789 * Check to see if @a signum is associated with a valid Event_Handler
790 * bound to a signal. Return the @a event_handler associated with
791 * this @c handler if @a event_handler != 0.
793 virtual int handler (int signum,
794 ACE_Event_Handler ** = 0);
796 /// Returns true if Reactor has been successfully initialized, else
797 /// false.
798 virtual bool initialized ();
800 /// Returns the current size of the Reactor's internal descriptor
801 /// table.
802 virtual size_t size () const;
804 /// Returns a reference to the Reactor's internal repository lock.
805 virtual ACE_Lock &lock ();
807 /// Wake up all threads waiting in the event loop.
808 virtual void wakeup_all_threads ();
810 /// Transfers ownership of Reactor_Impl to the @a new_owner.
812 * @note There is no need to set the owner of the event loop for the
813 * ACE_Dev_Poll_Reactor. Multiple threads may invoke the
814 * event loop simulataneously. As such, this method is a
815 * no-op.
817 virtual int owner (ACE_thread_t new_owner, ACE_thread_t *old_owner = 0);
819 /// Return the ID of the "owner" thread.
821 * @note There is no need to set the owner of the event loop for the
822 * ACE_Dev_Poll_Reactor. Multiple threads may invoke the
823 * event loop simultaneously. As such, this method is a
824 * no-op.
826 virtual int owner (ACE_thread_t *owner);
828 /// Get the existing restart value.
829 virtual bool restart ();
831 /// Set a new value for restart and return the original value.
833 * @param r If zero, then the event loop will not be automatically
834 * restarted if the underlying poll is interrupted via the
835 * INTR (interrupt) signal.
837 * @return Returns the previous "restart" value.
839 virtual bool restart (bool r);
841 /// Set position of the owner thread.
843 * @note This is currently a no-op.
845 virtual void requeue_position (int);
847 /// Get position of the owner thread.
849 * @note This is currently a no-op.
851 virtual int requeue_position ();
854 * @name Low-level wait_set mask manipulation methods
856 * Low-level methods to manipulate the event/reactor mask associated
857 * with a handle and event handler when polling for events.
858 * @par
859 * The "interest set," i.e. the wait set, can be directly
860 * manipulated with these methods.
862 //@{
863 /// GET/SET/ADD/CLR the dispatch mask "bit" bound with the
864 /// event_handler and mask.
866 * @return Old mask on success, -1 on error.
868 virtual int mask_ops (ACE_Event_Handler *event_handler,
869 ACE_Reactor_Mask mask,
870 int ops);
872 /// GET/SET/ADD/CLR the dispatch MASK "bit" bound with the handle
873 /// and mask.
875 * @return Old mask on success, -1 on error.
877 virtual int mask_ops (ACE_HANDLE handle,
878 ACE_Reactor_Mask mask,
879 int ops);
881 //@}
884 * @name Low-level ready_set mask manipulation methods
886 * These methods are unimplemented.
888 //@{
889 /// GET/SET/ADD/CLR the ready "bit" bound with the event_handler
890 /// and mask.
891 virtual int ready_ops (ACE_Event_Handler *event_handler,
892 ACE_Reactor_Mask mask,
893 int ops);
895 /// GET/SET/ADD/CLR the ready "bit" bound with the handle and mask.
896 virtual int ready_ops (ACE_HANDLE handle,
897 ACE_Reactor_Mask,
898 int ops);
900 //@}
902 /// Dump the state of an object.
903 virtual void dump () const;
905 /// Declare the dynamic allocation hooks.
906 ACE_ALLOC_HOOK_DECLARE;
908 protected:
909 class Token_Guard;
911 /// Non-locking version of wait_pending().
913 * Returns non-zero if there are I/O events "ready" for dispatching,
914 * but does not actually dispatch the event handlers. By default,
915 * don't block while checking this, i.e., "poll".
917 * @note It is only possible to achieve millisecond timeout
918 * resolutions with the ACE_Dev_Poll_Reactor.
920 int work_pending_i (ACE_Time_Value *max_wait_time);
922 /// Poll for events and return the number of event handlers that
923 /// were dispatched.
925 * This is a helper method called by all handle_events() methods.
927 int handle_events_i (ACE_Time_Value *max_wait_time, Token_Guard &guard);
929 /// Perform the upcall with the given event handler method.
930 int upcall (ACE_Event_Handler *event_handler,
931 int (ACE_Event_Handler::*callback)(ACE_HANDLE),
932 ACE_HANDLE handle);
935 * Dispatch ACE_Event_Handlers for time events, I/O events, and
936 * signal events. Returns the total number of ACE_Event_Handlers
937 * that were dispatched or -1 if something goes wrong.
939 int dispatch (Token_Guard &guard);
941 /// Dispatch a single timer, if ready.
942 /// Returns: 0 if no timers ready (token still held),
943 /// 1 if a timer was expired (token released),
944 /// -1 on error (token still held).
945 int dispatch_timer_handler (Token_Guard &guard);
947 /// Dispatch an IO event to the corresponding event handler. Returns
948 /// Returns: 0 if no events ready (token still held),
949 /// 1 if an event was expired (token released),
950 /// -1 on error (token still held).
951 int dispatch_io_event (Token_Guard &guard);
953 /// Register the given event handler with the reactor.
954 int register_handler_i (ACE_HANDLE handle,
955 ACE_Event_Handler *eh,
956 ACE_Reactor_Mask mask);
958 /// Remove the event handler associated with the given handle and
959 /// event mask from the "interest set." If @a eh is supplied, only do the
960 /// remove if @eh matches the event handler that's registered for @a handle.
961 /// The caller is expected to be holding the repo token on entry and have
962 /// @repo_guard referencing that token. It will be temporarily released
963 /// during a handle_close() callback if needed; if it is released for the
964 //// callback it will be reacquired before return.
965 // FUZZ: disable check_for_ACE_Guard
966 int remove_handler_i (ACE_HANDLE handle,
967 ACE_Reactor_Mask mask,
968 ACE_Guard<ACE_SYNCH_MUTEX> &repo_guard,
969 ACE_Event_Handler *eh = 0);
970 // FUZZ: enable check_for_ACE_Guard
972 /// Temporarily remove the given handle from the "interest set."
973 int suspend_handler_i (ACE_HANDLE handle);
975 /// Place the given handle that was temporarily removed from the
976 /// "interest set," i.e that was suspended, back in to the interest
977 /// set. The given handle will once again be polled for events.
978 int resume_handler_i (ACE_HANDLE handle);
980 /// GET/SET/ADD/CLR the dispatch MASK "bit" bound with the handle
981 /// and mask. This internal helper method acquires no lock.
983 * @return Old mask on success, -1 on error.
985 int mask_ops_i (ACE_HANDLE handle,
986 ACE_Reactor_Mask mask,
987 int ops);
989 /// Convert a reactor mask to its corresponding poll() event mask.
990 short reactor_mask_to_poll_event (ACE_Reactor_Mask mask);
992 protected:
993 /// Has the reactor been initialized.
994 bool initialized_;
996 /// The file descriptor associated with the open `/dev/poll' or
997 /// `/dev/epoll' device.
999 * All interactions with the `/dev/poll' or `/dev/epoll' device are
1000 * done through this file descriptor.
1002 ACE_HANDLE poll_fd_;
1004 #if defined (ACE_HAS_EVENT_POLL)
1005 /// Event structure to be filled by epoll_wait. epoll_wait() only gets
1006 /// one event at a time and we rely on it's internals for fairness.
1007 /// If this struct's fd is ACE_INVALID_HANDLE, the rest is indeterminate.
1008 /// If the fd is good, the event is one that's been retrieved by
1009 /// epoll_wait() but not yet processed.
1010 struct epoll_event event_;
1012 #else
1013 /// The pollfd array that `/dev/poll' will feed its results to.
1014 struct pollfd *dp_fds_;
1017 /// Pointer to the next pollfd array element that contains the next
1018 /// event to be dispatched.
1019 struct pollfd *start_pfds_;
1021 /// The last element in the pollfd array plus one.
1023 * The loop that dispatches IO events stops when this->start_pfds ==
1024 * this->end_pfds_.
1026 struct pollfd *end_pfds_;
1027 #endif /* ACE_HAS_EVENT_POLL */
1029 /// Token serializing event waiter threads.
1030 ACE_Dev_Poll_Reactor_Token token_;
1032 /// Adapter used to return internal lock to outside world.
1033 ACE_Lock_Adapter<ACE_Dev_Poll_Reactor_Token> lock_adapter_;
1035 /// This flag is used to keep track of whether we are actively handling
1036 /// events or not.
1037 sig_atomic_t deactivated_;
1039 /// Token used to protect manipulation of the handler repository.
1040 /// No need to hold the waiter token to change the repo.
1041 // ACE_DEV_POLL_TOKEN repo_token_;
1042 ACE_SYNCH_MUTEX repo_lock_;
1044 /// The repository that contains all registered event handlers.
1045 Handler_Repository handler_rep_;
1047 /// Defined as a pointer to allow overriding by derived classes...
1048 ACE_Timer_Queue *timer_queue_;
1050 /// Keeps track of whether we should delete the timer queue (if we
1051 /// didn't create it, then we don't delete it).
1052 bool delete_timer_queue_;
1054 /// Handle signals without requiring global/static variables.
1055 ACE_Sig_Handler *signal_handler_;
1057 /// Keeps track of whether we should delete the signal handler (if we
1058 /// didn't create it, then we don't delete it).
1059 bool delete_signal_handler_;
1061 /// Callback object that unblocks the <ACE_Select_Reactor> if it's
1062 /// sleeping.
1063 ACE_Reactor_Notify *notify_handler_;
1065 /// Keeps track of whether we need to delete the notify handler (if
1066 /// we didn't create it, then we don't delete it).
1067 bool delete_notify_handler_;
1069 /// Flag that determines if signals are masked during event
1070 /// dispatching.
1072 * If 0 then the Reactor will not mask the signals during the event
1073 * dispatching. This is useful for applications that do not
1074 * register any signal handlers and want to reduce the overhead
1075 * introduce by the kernel level locks required to change the mask.
1077 int mask_signals_;
1079 /// Restart the handle_events event loop method automatically when
1080 /// polling function in use (ioctl() in this case) is interrupted
1081 /// via an EINTR signal.
1082 bool restart_;
1084 protected:
1086 * @class Token_Guard
1088 * @brief A helper class that helps grabbing, releasing and waiting
1089 * on tokens for a thread that needs access to the reactor's token.
1091 class ACE_Export Token_Guard
1093 public:
1094 /// Constructor that will grab the token for us
1095 Token_Guard (ACE_Dev_Poll_Reactor_Token &token);
1097 /// Destructor. This will release the token if it hasn't been
1098 /// released till this point
1099 ~Token_Guard ();
1101 /// Release the token ..
1102 void release_token ();
1104 /// Returns whether the thread that created this object owns the
1105 /// token or not.
1106 bool is_owner ();
1108 /// A helper method that acquires the token 1) at a low priority, and
1109 /// 2) wait quietly for the token, not waking another thread. This
1110 /// is appropriate for cases where a thread wants to wait for and
1111 /// dispatch an event, not causing an existing waiter to relinquish the
1112 /// token.
1113 int acquire_quietly (ACE_Time_Value *max_wait = 0);
1115 /// A helper method that acquires the token at a high priority, and
1116 /// does wake the current token holder.
1117 int acquire (ACE_Time_Value *max_wait = 0);
1119 private:
1120 Token_Guard ();
1122 private:
1123 /// The Reactor token.
1124 ACE_Dev_Poll_Reactor_Token &token_;
1126 /// Flag that indicate whether the thread that created this object
1127 /// owns the token or not. A value of false indicates that this class
1128 /// hasn't got the token (and hence the thread) and a value of true
1129 /// vice-versa.
1130 bool owner_;
1136 * @class ACE_Dev_Poll_Handler_Guard
1138 * @brief Class used to make event handler reference count
1139 * manipulation exception-safe.
1141 * This class makes the reference count manipulation that occurs
1142 * during an upcall exception-safe. Prior to dispatching the event
1143 * handler, the reference count is increased. Once the upcall for the
1144 * given event handler is complete, its reference count will be decreased.
1146 class ACE_Dev_Poll_Handler_Guard
1148 public:
1149 /// Constructor
1151 * The constructor checks to see if @a eh is a reference-counted handler and
1152 * remember that for later. If @a eh is reference counted, its reference
1153 * count is incremented unless @a do_incr is false.
1154 * @a do_incr should be false if the reference count was incremented
1155 * independently of this guard, for example, on a notify handler since
1156 * the reference count is incremented when the notify is queued.
1158 ACE_Dev_Poll_Handler_Guard (ACE_Event_Handler *eh, bool do_incr = true);
1160 /// Destructor
1162 * The destructor decrements the reference count on the event
1163 * handler corresponding to the given handle.
1165 ~ACE_Dev_Poll_Handler_Guard ();
1167 /// Release the event handler from this guard; when the destructor is
1168 /// called, the handler's reference count will not be decremented.
1169 void release ();
1171 private:
1172 /// The event handler being managed.
1173 ACE_Event_Handler *eh_;
1175 /// true if eh_ is a reference-counted handler.
1176 bool refcounted_;
1179 ACE_END_VERSIONED_NAMESPACE_DECL
1181 #if defined (__ACE_INLINE__)
1182 # include "ace/Dev_Poll_Reactor.inl"
1183 #endif /* __ACE_INLINE__ */
1185 #endif /* ACE_HAS_EVENT_POLL || ACE_HAS_DEV_POLL */
1187 #include /**/ "ace/post.h"
1189 #endif /* ACE_DEV_POLL_REACTOR_H */