3 // =========================================================================
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)
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)
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)
43 #elif defined (ACE_HAS_EVENT_POLL)
44 # include "ace/Array_Map.h"
45 # include /**/ <sys/epoll.h>
48 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
50 // Forward declarations
51 class ACE_Sig_Handler
;
52 class ACE_Dev_Poll_Reactor
;
54 // ---------------------------------------------------------------------
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
70 ACE_Dev_Poll_Reactor_Notify (void);
73 * @name Initialization and Termination Methods
75 * Methods called when initializing and terminating this event
78 virtual int open (ACE_Reactor_Impl
*,
79 ACE_Timer_Queue
*timer_queue
= 0,
80 int disable_notify
= 0);
81 virtual int close (void);
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
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
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 (void);
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
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
145 virtual int max_notify_iterations (void);
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 (void) 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
;
172 * Keep a back pointer to the ACE_Dev_Poll_Reactor. If this value
173 * if NULL then the ACE_Dev_Poll_Reactor has been initialized with
174 * disable_notify_pipe.
176 ACE_Dev_Poll_Reactor
*dp_reactor_
;
179 * Contains the ACE_HANDLE the ACE_Dev_Poll_Reactor is listening
180 * on, as well as the ACE_HANDLE that threads wanting the attention
181 * of the ACE_Dev_Poll_Reactor will write to.
183 ACE_Pipe notification_pipe_
;
186 * Keeps track of the maximum number of times that the
187 * ACE_Dev_Poll_Reactor_Notify::handle_input method will iterate and
188 * dispatch the ACE_Event_Handlers that are passed in via the
189 * notify pipe before breaking out of its recv loop. By default,
190 * this is set to -1, which means "iterate until the pipe is empty."
192 int max_notify_iterations_
;
194 #if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE)
196 * @brief A user-space queue to store the notifications.
198 * The notification pipe has OS-specific size restrictions. That
199 * is, no more than a certain number of bytes may be stored in the
200 * pipe without blocking. This limit may be too small for certain
201 * applications. In this case, ACE can be configured to store all
202 * the events in user-space. The pipe is still needed to wake up
203 * the reactor thread, but only one event is sent through the pipe
206 ACE_Notification_Queue notification_queue_
;
207 #endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */
210 // ---------------------------------------------------------------------
213 * @class ACE_Dev_Poll_Reactor
215 * @brief A `/dev/poll' or `/dev/epoll' based Reactor implemenatation.
217 * @attention The Linux epoll implementation works quite well and is
218 * fully supported; however, the /dev/poll implementation is @em experimental.
220 * The ACE_Dev_Poll_Reactor uses the `/dev/poll' or '/dev/epoll'
221 * character devices to demultiplex events on a given set of file
222 * descriptors. Unlike @c select(), `/dev/poll' and `/dev/epoll' have
223 * no hard-coded limit on the number of file descriptors that may be
224 * handled at any given time. As such, the ACE_Dev_Poll_Reactor can
225 * generally handle a much larger number of file descriptors than
226 * @c select() -based reactors. Furthermore, since `/dev/poll' and
227 * `/dev/epoll' both return a set of file descriptors that are active,
228 * there is no need to "walk" the set of file descriptors to determine
229 * which ones are active, such as what is done with the @c select() and
230 * @c poll() system calls. All returned file descriptors are active.
231 * This makes event dispatching very efficient.
233 * @note In general, this reactor may only be used to demultiplex
234 * events on sockets. Demultiplexing events on pipes, for
235 * example may not work. This is due to a limitation in the
236 * underlying `/dev/poll' device driver.
238 * @note It is only possible to achieve millisecond timeout
239 * resolutions with the @c ACE_Dev_Poll_Reactor. However, the
240 * timeout resolution for timers is independent of the reactors
241 * timeout resolution. As such, it may be possible to achieve
242 * sub-millisecond timeout resolutions for timers but that is
243 * entirely platform dependent.
246 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
247 typedef ACE_Token ACE_DEV_POLL_TOKEN
;
249 typedef ACE_Noop_Token ACE_DEV_POLL_TOKEN
;
250 #endif /* ACE_MT_SAFE && ACE_MT_SAFE != 0 */
251 typedef ACE_Reactor_Token_T
<ACE_DEV_POLL_TOKEN
> ACE_Dev_Poll_Reactor_Token
;
253 class ACE_Export ACE_Dev_Poll_Reactor
: public ACE_Reactor_Impl
257 * @struct Event_Tuple
259 * @brief Struct that collects event registration information for a handle.
261 * @internal Internal use only
263 * This struct merely provides a means to associate an event mask
264 * with an event handler. Such an association is needed since it is
265 * not possible to retrieve the event mask from the "interest set"
266 * stored in the `/dev/poll' or `/dev/epoll' driver. Without this
267 * external association, it would not be possible keep track of the
268 * event mask for a given event handler when suspending it or resuming
271 * @note An ACE_Handle_Set is not used since the number of handles may
272 * exceed its capacity (ACE_DEFAULT_SELECT_REACTOR_SIZE).
276 /// Constructor to set up defaults.
277 Event_Tuple (ACE_Event_Handler
*eh
= 0,
278 ACE_Reactor_Mask m
= ACE_Event_Handler::NULL_MASK
,
279 bool is_suspended
= false,
280 bool is_controlled
= false);
282 /// The event handler.
283 ACE_Event_Handler
*event_handler
;
285 /// The event mask for the above event handler.
286 ACE_Reactor_Mask mask
;
288 /// Flag that states whether or not the event handler is suspended.
291 /// Flag to say whether or not this handle is registered with epoll.
294 ACE_ALLOC_HOOK_DECLARE
;
298 // ---------------------------------------------------------------------
301 * @class Handler_Repository
305 * @brief Used to map ACE_HANDLEs onto the appropriate Event_Tuple.
307 * This class is simply a container that maps a handle to its
308 * corresponding event tuple. It is not meant for use outside of
309 * the Dev_Poll_Reactor.
311 * @note Calls to any method in this class, and any modification to a
312 * Event_Tuple returned from this class's methods, must be made
313 * while holding the repository lock.
315 class Handler_Repository
319 Handler_Repository (void);
321 /// Initialize a repository that can map handles up to the value @a size.
322 /// Since the event tuples are accessed directly using the handle as
323 /// an index, @a size sets the maximum handle value, minus 1.
324 int open (size_t size
);
326 /// Close down the repository.
330 * @name Repository Manipulation Operations
332 * Methods used to search and modify the handler repository.
336 /// Return a pointer to the Event_Tuple associated with @a handle.
337 /// If there is none associated, returns 0 and sets errno.
338 Event_Tuple
*find (ACE_HANDLE handle
);
341 /// Bind the ACE_Event_Handler to the @c ACE_HANDLE with the
342 /// appropriate ACE_Reactor_Mask settings.
343 int bind (ACE_HANDLE handle
,
344 ACE_Event_Handler
*handler
,
345 ACE_Reactor_Mask mask
);
347 /// Remove the binding for @a handle; optionally decrement the associated
348 /// handler's reference count.
349 int unbind (ACE_HANDLE handle
, bool decr_refcnt
= true);
351 /// Remove all the registered tuples.
352 int unbind_all (void);
357 * @name Sanity Checking
359 * Methods used to prevent "out-of-range" errors when indexing the
360 * underlying handler array.
364 // Check the @a handle to make sure it's a valid @c ACE_HANDLE that
365 // within the range of legal handles (i.e., greater than or equal to
366 // zero and less than @c max_size_).
367 bool invalid_handle (ACE_HANDLE handle
) const;
369 // Check the handle to make sure it's a valid @c ACE_HANDLE that is
370 // within the range of currently registered handles (i.e., greater
371 // than or equal to zero and less than @c max_handlep1_).
372 bool handle_in_range (ACE_HANDLE handle
) const;
376 /// Returns the current table size.
377 size_t size (void) const;
379 /// Returns the maximum table size.
380 size_t max_size (void) const;
382 /// Dump the state of an object.
383 void dump (void) const;
385 /// Declare the dynamic allocation hooks.
386 ACE_ALLOC_HOOK_DECLARE
;
389 /// Current number of handles.
392 /// Maximum number of handles.
395 /// The underlying array of event handlers.
397 * The array of event handlers is directly indexed directly using
398 * an @c ACE_HANDLE value. This is Unix-specific.
400 Event_Tuple
*handlers_
;
405 /// Initialize @c ACE_Dev_Poll_Reactor with the default size.
407 * The default size for the @c ACE_Dev_Poll_Reactor is the maximum
408 * number of open file descriptors for the process.
410 ACE_Dev_Poll_Reactor (ACE_Sig_Handler
* = 0,
411 ACE_Timer_Queue
* = 0,
412 int disable_notify_pipe
= 0,
413 ACE_Reactor_Notify
*notify
= 0,
414 int mask_signals
= 1,
415 int s_queue
= ACE_DEV_POLL_TOKEN::FIFO
);
417 /// Initialize ACE_Dev_Poll_Reactor with size @a size.
419 * @note On Unix platforms, the @a size parameter should be as large
420 * as the maximum number of file descriptors allowed for a
421 * given process. This is necessary since a file descriptor
422 * is used to directly index the array of event handlers
423 * maintained by the Reactor's handler repository. Direct
424 * indexing is used for efficiency reasons. If the size
425 * parameter is less than the process maximum, the process
426 * maximum will be decreased in order to prevent potential
429 ACE_Dev_Poll_Reactor (size_t size
,
430 bool restart
= false,
431 ACE_Sig_Handler
* = 0,
432 ACE_Timer_Queue
* = 0,
433 int disable_notify_pipe
= 0,
434 ACE_Reactor_Notify
*notify
= 0,
435 int mask_signals
= 1,
436 int s_queue
= ACE_DEV_POLL_TOKEN::FIFO
);
438 /// Close down and release all resources.
439 virtual ~ACE_Dev_Poll_Reactor (void);
442 virtual int open (size_t size
,
443 bool restart
= false,
444 ACE_Sig_Handler
* = 0,
445 ACE_Timer_Queue
* = 0,
446 int disable_notify_pipe
= 0,
447 ACE_Reactor_Notify
* = 0);
450 * @param handle allows the reactor to check if the caller is
453 * @return 0 if the size of the current message has been put in
456 virtual int current_info (ACE_HANDLE handle
, size_t & /* size */);
458 /// Use a user specified signal handler instead.
459 virtual int set_sig_handler (ACE_Sig_Handler
*signal_handler
);
461 /// Set a user-specified timer queue.
462 virtual int timer_queue (ACE_Timer_Queue
*tq
);
464 /// Get the timer queue
465 /// @return The current @c ACE_Timer_Queue.
466 virtual ACE_Timer_Queue
*timer_queue (void) const;
468 /// Close down and release all resources.
469 virtual int close (void);
471 // = Event loop drivers.
473 * Returns non-zero if there are I/O events "ready" for dispatching,
474 * but does not actually dispatch the event handlers. By default,
475 * don't block while checking this, i.e., "poll".
477 * @note It is only possible to achieve millisecond timeout
478 * resolutions with the @c ACE_Dev_Poll_Reactor.
480 virtual int work_pending (
481 const ACE_Time_Value
&max_wait_time
= ACE_Time_Value::zero
);
484 * This event loop driver blocks for up to @a max_wait_time before
485 * returning. It will return earlier if events occur. Note that
486 * @a max_wait_time can be 0, in which case this method blocks
487 * indefinitely until events occur.
489 * @a max_wait_time is decremented to reflect how much time this
490 * call took. For instance, if a time value of 3 seconds is passed
491 * to @c handle_events() and an event occurs after 2 seconds,
492 * @a max_wait_time will equal 1 second. This can be used if an
493 * application wishes to handle events for some fixed amount of
496 * The only difference between @c alertable_handle_events() and
497 * handle_events() is that in the alertable case, the event loop
498 * will return when the system queues an I/O completion routine or
499 * an Asynchronous Procedure Call.
501 * @return The total number of @c ACE_Event_Handlers that were
502 * dispatched, 0 if the @a max_wait_time elapsed without
503 * dispatching any handlers, or -1 if an error occurs.
505 * @note It is only possible to achieve millisecond timeout
506 * resolutions with the @c ACE_Dev_Poll_Reactor.
508 virtual int handle_events (ACE_Time_Value
*max_wait_time
= 0);
509 virtual int alertable_handle_events (ACE_Time_Value
*max_wait_time
= 0);
512 * This method is just like the one above, except the
513 * @a max_wait_time value is a reference and can therefore never be
516 * @note It is only possible to achieve millisecond timeout
517 * resolutions with the @c ACE_Dev_Poll_Reactor.
519 virtual int handle_events (ACE_Time_Value
&max_wait_time
);
520 virtual int alertable_handle_events (ACE_Time_Value
&max_wait_time
);
522 // = Event handling control.
525 * @return The status of Reactor. If this function returns 0, the
526 * reactor is actively handling events. If it returns
527 * non-zero, @c handle_events() and
528 * @c handle_alertable_events() return -1 immediately.
530 virtual int deactivated (void);
533 * Control whether the Reactor will handle any more incoming events
534 * or not. If @a do_stop == 1, the Reactor will be disabled. By
535 * default, a reactor is in active state and can be
536 * deactivated/reactived as desired.
538 virtual void deactivate (int do_stop
);
540 // = Register and remove Handlers.
542 /// Register @a event_handler with @a mask. The I/O handle will
543 /// always come from get_handle on the event_handler.
544 virtual int register_handler (ACE_Event_Handler
*event_handler
,
545 ACE_Reactor_Mask mask
);
547 /// Register @a event_handler with @a mask. The I/O handle is
548 /// provided through the @a io_handle parameter.
549 virtual int register_handler (ACE_HANDLE io_handle
,
550 ACE_Event_Handler
*event_handler
,
551 ACE_Reactor_Mask mask
);
554 * Register an @a event_handler that will be notified when
555 * @a event_handle is signaled. @a mask specifies the network
556 * events that the @a event_handler is interested in.
558 virtual int register_handler (ACE_HANDLE event_handle
,
559 ACE_HANDLE io_handle
,
560 ACE_Event_Handler
*event_handler
,
561 ACE_Reactor_Mask mask
);
563 /// Register @a event_handler with all the @a handles in the @c
565 virtual int register_handler (const ACE_Handle_Set
&handles
,
566 ACE_Event_Handler
*event_handler
,
567 ACE_Reactor_Mask mask
);
570 * Register @a new_sh to handle the signal @a signum using the
571 * @a new_disp. Returns the @a old_sh that was previously
572 * registered (if any), along with the @a old_disp of the signal
575 virtual int register_handler (int signum
,
576 ACE_Event_Handler
*new_sh
,
577 ACE_Sig_Action
*new_disp
= 0,
578 ACE_Event_Handler
**old_sh
= 0,
579 ACE_Sig_Action
*old_disp
= 0);
581 /// Registers @a new_sh to handle a set of signals @a sigset using the
583 virtual int register_handler (const ACE_Sig_Set
&sigset
,
584 ACE_Event_Handler
*new_sh
,
585 ACE_Sig_Action
*new_disp
= 0);
587 /// Removes @a event_handler.
589 * @note The I/O handle will be obtained using @c get_handle()
590 * method of @a event_handler . If @a mask ==
591 * @c ACE_Event_Handler::DONT_CALL then the @c handle_close()
592 * method of the @a event_handler is not invoked.
594 virtual int remove_handler (ACE_Event_Handler
*event_handler
,
595 ACE_Reactor_Mask mask
);
598 * Removes @a handle. If @a mask == ACE_Event_Handler::DONT_CALL
599 * then the <handle_close> method of the associated <event_handler>
602 virtual int remove_handler (ACE_HANDLE handle
,
603 ACE_Reactor_Mask mask
);
606 * Removes all handles in @a handle_set. If @a mask ==
607 * ACE_Event_Handler::DONT_CALL then the <handle_close> method of
608 * the associated <event_handler>s is not invoked.
610 virtual int remove_handler (const ACE_Handle_Set
&handle_set
,
611 ACE_Reactor_Mask mask
);
614 * Remove the ACE_Event_Handler currently associated with @a signum.
615 * Install the new disposition (if given) and return the previous
616 * disposition (if desired by the caller). Returns 0 on success and
617 * -1 if @a signum is invalid.
619 virtual int remove_handler (int signum
,
620 ACE_Sig_Action
*new_disp
,
621 ACE_Sig_Action
*old_disp
= 0,
624 /// Calls <remove_handler> for every signal in @a sigset.
625 virtual int remove_handler (const ACE_Sig_Set
&sigset
);
627 // = Suspend and resume Handlers.
629 /// Suspend event_handler temporarily. Use
630 /// ACE_Event_Handler::get_handle() to get the handle.
631 virtual int suspend_handler (ACE_Event_Handler
*event_handler
);
633 /// Suspend handle temporarily.
634 virtual int suspend_handler (ACE_HANDLE handle
);
636 /// Suspend all handles in handle set temporarily.
637 virtual int suspend_handler (const ACE_Handle_Set
&handles
);
639 /// Suspend all handles temporarily.
640 virtual int suspend_handlers (void);
642 /// Resume event_handler. Use ACE_Event_Handler::get_handle() to
644 virtual int resume_handler (ACE_Event_Handler
*event_handler
);
647 virtual int resume_handler (ACE_HANDLE handle
);
649 /// Resume all handles in handle set.
650 virtual int resume_handler (const ACE_Handle_Set
&handles
);
652 /// Resume all handles.
653 virtual int resume_handlers (void);
655 /// Does the reactor allow the application to resume the handle on
656 /// its own, i.e., can it pass on the control of handle resumption to
658 virtual int resumable_handler (void);
660 /// Return true if we any event associations were made by the reactor
661 /// for the handles that it waits on, false otherwise.
662 virtual bool uses_event_associations (void);
664 // = Timer management.
667 * Schedule an ACE_Event_Handler that will expire after an amount
668 * of time. The return value of this method, a timer_id value,
669 * uniquely identifies the event_handler in the ACE_Reactor's
670 * internal list of timers.
671 * This timer_id value can be used to cancel the timer
672 * with the cancel_timer() call.
674 * @see cancel_timer()
675 * @see reset_timer_interval()
677 * @param event_handler event handler to schedule on reactor
678 * @param arg argument passed to the handle_timeout() method of
680 * @param delay time interval after which the timer will expire.
681 * @param interval time interval for which the timer will be
682 * automatically rescheduled.
683 * @return -1 on failure, a timer_id value on success
685 virtual long schedule_timer (ACE_Event_Handler
*event_handler
,
687 const ACE_Time_Value
&delay
,
688 const ACE_Time_Value
&interval
= ACE_Time_Value::zero
);
691 * Resets the interval of the timer represented by @a timer_id to
692 * @a interval, which is specified in relative time to the current
693 * <gettimeofday>. If @a interval is equal to
694 * ACE_Time_Value::zero, the timer will become a non-rescheduling
695 * timer. Returns 0 if successful, -1 if not.
697 virtual int reset_timer_interval (long timer_id
,
698 const ACE_Time_Value
&interval
);
700 /// Cancel all Event_Handlers that match the address of
701 /// @a event_handler. Returns number of handlers cancelled.
702 virtual int cancel_timer (ACE_Event_Handler
*event_handler
,
703 int dont_call_handle_close
= 1);
706 * Cancel the single event handler that matches the @a timer_id value
707 * (which was returned from the schedule method). If @a arg is
708 * non-NULL then it will be set to point to the ``magic cookie''
709 * argument passed in when the event handler was registered. This
710 * makes it possible to free up the memory and avoid memory leaks.
711 * Returns 1 if cancellation succeeded and 0 if the @a timer_id
714 virtual int cancel_timer (long timer_id
,
715 const void **arg
= 0,
716 int dont_call_handle_close
= 1);
718 // = High-level event handler scheduling operations
720 /// Add @a masks_to_be_added to the @a event_handler's entry.
721 /// @a event_handler must already have been registered.
722 virtual int schedule_wakeup (ACE_Event_Handler
*event_handler
,
723 ACE_Reactor_Mask masks_to_be_added
);
725 /// Add @a masks_to_be_added to the @a handle's entry. <event_handler>
726 /// associated with @a handle must already have been registered.
727 virtual int schedule_wakeup (ACE_HANDLE handle
,
728 ACE_Reactor_Mask masks_to_be_added
);
730 /// Clear @a masks_to_be_cleared from the @a event_handler's entry.
731 virtual int cancel_wakeup (ACE_Event_Handler
*event_handler
,
732 ACE_Reactor_Mask masks_to_be_cleared
);
734 /// Clear @a masks_to_be_cleared from the @a handle's entry.
735 virtual int cancel_wakeup (ACE_HANDLE handle
,
736 ACE_Reactor_Mask masks_to_be_cleared
);
738 // = Notification methods.
741 * Notify @a event_handler of @a mask event. The ACE_Time_Value
742 * indicates how long to blocking trying to notify. If @a timeout ==
743 * 0, the caller will block until action is possible, else will wait
744 * until the relative time specified in @a timeout elapses).
746 virtual int notify (ACE_Event_Handler
*event_handler
= 0,
747 ACE_Reactor_Mask mask
= ACE_Event_Handler::EXCEPT_MASK
,
748 ACE_Time_Value
* = 0);
751 * Set the maximum number of times that ACE_Reactor_Impl will
752 * iterate and dispatch the ACE_Event_Handlers that are passed in
753 * via the notify queue before breaking out of its
754 * ACE_Message_Queue::dequeue() loop. By default, this is set to
755 * -1, which means "iterate until the queue is empty." Setting this
756 * to a value like "1 or 2" will increase "fairness" (and thus
757 * prevent starvation) at the expense of slightly higher dispatching
760 virtual void max_notify_iterations (int);
763 * Get the maximum number of times that the ACE_Reactor_Impl will
764 * iterate and dispatch the ACE_Event_Handlers that are passed in
765 * via the notify queue before breaking out of its
766 * ACE_Message_Queue::dequeue() loop.
768 virtual int max_notify_iterations (void);
771 * Purge any notifications pending in this reactor for the specified
772 * ACE_Event_Handler object. Returns the number of notifications
773 * purged. Returns -1 on error.
775 virtual int purge_pending_notifications (ACE_Event_Handler
* = 0,
776 ACE_Reactor_Mask
= ACE_Event_Handler::ALL_EVENTS_MASK
);
779 * Return the Event_Handler associated with @a handle. Return 0 if
780 * @a handle is not registered.
782 virtual ACE_Event_Handler
*find_handler (ACE_HANDLE handle
);
785 * Check to see if @a handle is associated with a valid Event_Handler
786 * bound to @a mask. Return the @a event_handler associated with this
787 * @c handler if @a event_handler != 0.
789 virtual int handler (ACE_HANDLE handle
,
790 ACE_Reactor_Mask mask
,
791 ACE_Event_Handler
**event_handler
= 0);
794 * Check to see if @a signum is associated with a valid Event_Handler
795 * bound to a signal. Return the @a event_handler associated with
796 * this @c handler if @a event_handler != 0.
798 virtual int handler (int signum
,
799 ACE_Event_Handler
** = 0);
801 /// Returns true if Reactor has been successfully initialized, else
803 virtual bool initialized (void);
805 /// Returns the current size of the Reactor's internal descriptor
807 virtual size_t size (void) const;
809 /// Returns a reference to the Reactor's internal repository lock.
810 virtual ACE_Lock
&lock (void);
812 /// Wake up all threads waiting in the event loop.
813 virtual void wakeup_all_threads (void);
815 /// Transfers ownership of Reactor_Impl to the @a new_owner.
817 * @note There is no need to set the owner of the event loop for the
818 * ACE_Dev_Poll_Reactor. Multiple threads may invoke the
819 * event loop simulataneously. As such, this method is a
822 virtual int owner (ACE_thread_t new_owner
, ACE_thread_t
*old_owner
= 0);
824 /// Return the ID of the "owner" thread.
826 * @note There is no need to set the owner of the event loop for the
827 * ACE_Dev_Poll_Reactor. Multiple threads may invoke the
828 * event loop simultaneously. As such, this method is a
831 virtual int owner (ACE_thread_t
*owner
);
833 /// Get the existing restart value.
834 virtual bool restart (void);
836 /// Set a new value for restart and return the original value.
838 * @param r If zero, then the event loop will not be automatically
839 * restarted if the underlying poll is interrupted via the
840 * INTR (interrupt) signal.
842 * @return Returns the previous "restart" value.
844 virtual bool restart (bool r
);
846 /// Set position of the owner thread.
848 * @note This is currently a no-op.
850 virtual void requeue_position (int);
852 /// Get position of the owner thread.
854 * @note This is currently a no-op.
856 virtual int requeue_position (void);
859 * @name Low-level wait_set mask manipulation methods
861 * Low-level methods to manipulate the event/reactor mask associated
862 * with a handle and event handler when polling for events.
864 * The "interest set," i.e. the wait set, can be directly
865 * manipulated with these methods.
869 /// GET/SET/ADD/CLR the dispatch mask "bit" bound with the
870 /// event_handler and mask.
872 * @return Old mask on success, -1 on error.
874 virtual int mask_ops (ACE_Event_Handler
*event_handler
,
875 ACE_Reactor_Mask mask
,
878 /// GET/SET/ADD/CLR the dispatch MASK "bit" bound with the handle
881 * @return Old mask on success, -1 on error.
883 virtual int mask_ops (ACE_HANDLE handle
,
884 ACE_Reactor_Mask mask
,
890 * @name Low-level ready_set mask manipulation methods
892 * These methods are unimplemented.
896 /// GET/SET/ADD/CLR the ready "bit" bound with the event_handler
898 virtual int ready_ops (ACE_Event_Handler
*event_handler
,
899 ACE_Reactor_Mask mask
,
902 /// GET/SET/ADD/CLR the ready "bit" bound with the handle and mask.
903 virtual int ready_ops (ACE_HANDLE handle
,
909 /// Dump the state of an object.
910 virtual void dump (void) const;
912 /// Declare the dynamic allocation hooks.
913 ACE_ALLOC_HOOK_DECLARE
;
919 /// Non-locking version of wait_pending().
921 * Returns non-zero if there are I/O events "ready" for dispatching,
922 * but does not actually dispatch the event handlers. By default,
923 * don't block while checking this, i.e., "poll".
925 * @note It is only possible to achieve millisecond timeout
926 * resolutions with the ACE_Dev_Poll_Reactor.
928 int work_pending_i (ACE_Time_Value
*max_wait_time
);
930 /// Poll for events and return the number of event handlers that
933 * This is a helper method called by all handle_events() methods.
935 int handle_events_i (ACE_Time_Value
*max_wait_time
, Token_Guard
&guard
);
937 /// Perform the upcall with the given event handler method.
938 int upcall (ACE_Event_Handler
*event_handler
,
939 int (ACE_Event_Handler::*callback
)(ACE_HANDLE
),
943 * Dispatch ACE_Event_Handlers for time events, I/O events, and
944 * signal events. Returns the total number of ACE_Event_Handlers
945 * that were dispatched or -1 if something goes wrong.
947 int dispatch (Token_Guard
&guard
);
949 /// Dispatch a single timer, if ready.
950 /// Returns: 0 if no timers ready (token still held),
951 /// 1 if a timer was expired (token released),
952 /// -1 on error (token still held).
953 int dispatch_timer_handler (Token_Guard
&guard
);
955 /// Dispatch an IO event to the corresponding event handler. Returns
956 /// Returns: 0 if no events ready (token still held),
957 /// 1 if an event was expired (token released),
958 /// -1 on error (token still held).
959 int dispatch_io_event (Token_Guard
&guard
);
961 /// Register the given event handler with the reactor.
962 int register_handler_i (ACE_HANDLE handle
,
963 ACE_Event_Handler
*eh
,
964 ACE_Reactor_Mask mask
);
966 /// Remove the event handler associated with the given handle and
967 /// event mask from the "interest set." If @a eh is supplied, only do the
968 /// remove if @eh matches the event handler that's registered for @a handle.
969 /// The caller is expected to be holding the repo token on entry and have
970 /// @repo_guard referencing that token. It will be temporarily released
971 /// during a handle_close() callback if needed; if it is released for the
972 //// callback it will be reacquired before return.
973 // FUZZ: disable check_for_ACE_Guard
974 int remove_handler_i (ACE_HANDLE handle
,
975 ACE_Reactor_Mask mask
,
976 ACE_Guard
<ACE_SYNCH_MUTEX
> &repo_guard
,
977 ACE_Event_Handler
*eh
= 0);
978 // FUZZ: enable check_for_ACE_Guard
980 /// Temporarily remove the given handle from the "interest set."
981 int suspend_handler_i (ACE_HANDLE handle
);
983 /// Place the given handle that was temporarily removed from the
984 /// "interest set," i.e that was suspended, back in to the interest
985 /// set. The given handle will once again be polled for events.
986 int resume_handler_i (ACE_HANDLE handle
);
988 /// GET/SET/ADD/CLR the dispatch MASK "bit" bound with the handle
989 /// and mask. This internal helper method acquires no lock.
991 * @return Old mask on success, -1 on error.
993 int mask_ops_i (ACE_HANDLE handle
,
994 ACE_Reactor_Mask mask
,
997 /// Convert a reactor mask to its corresponding poll() event mask.
998 short reactor_mask_to_poll_event (ACE_Reactor_Mask mask
);
1001 /// Has the reactor been initialized.
1004 /// The file descriptor associated with the open `/dev/poll' or
1005 /// `/dev/epoll' device.
1007 * All interactions with the `/dev/poll' or `/dev/epoll' device are
1008 * done through this file descriptor.
1010 ACE_HANDLE poll_fd_
;
1012 #if defined (ACE_HAS_EVENT_POLL)
1013 /// Event structure to be filled by epoll_wait. epoll_wait() only gets
1014 /// one event at a time and we rely on it's internals for fairness.
1015 /// If this struct's fd is ACE_INVALID_HANDLE, the rest is indeterminate.
1016 /// If the fd is good, the event is one that's been retrieved by
1017 /// epoll_wait() but not yet processed.
1018 struct epoll_event event_
;
1021 /// The pollfd array that `/dev/poll' will feed its results to.
1022 struct pollfd
*dp_fds_
;
1025 /// Pointer to the next pollfd array element that contains the next
1026 /// event to be dispatched.
1027 struct pollfd
*start_pfds_
;
1029 /// The last element in the pollfd array plus one.
1031 * The loop that dispatches IO events stops when this->start_pfds ==
1034 struct pollfd
*end_pfds_
;
1035 #endif /* ACE_HAS_EVENT_POLL */
1037 /// Token serializing event waiter threads.
1038 ACE_Dev_Poll_Reactor_Token token_
;
1040 /// Adapter used to return internal lock to outside world.
1041 ACE_Lock_Adapter
<ACE_Dev_Poll_Reactor_Token
> lock_adapter_
;
1043 /// This flag is used to keep track of whether we are actively handling
1045 sig_atomic_t deactivated_
;
1047 /// Token used to protect manipulation of the handler repository.
1048 /// No need to hold the waiter token to change the repo.
1049 // ACE_DEV_POLL_TOKEN repo_token_;
1050 ACE_SYNCH_MUTEX repo_lock_
;
1052 /// The repository that contains all registered event handlers.
1053 Handler_Repository handler_rep_
;
1055 /// Defined as a pointer to allow overriding by derived classes...
1056 ACE_Timer_Queue
*timer_queue_
;
1058 /// Keeps track of whether we should delete the timer queue (if we
1059 /// didn't create it, then we don't delete it).
1060 bool delete_timer_queue_
;
1062 /// Handle signals without requiring global/static variables.
1063 ACE_Sig_Handler
*signal_handler_
;
1065 /// Keeps track of whether we should delete the signal handler (if we
1066 /// didn't create it, then we don't delete it).
1067 bool delete_signal_handler_
;
1069 /// Callback object that unblocks the <ACE_Select_Reactor> if it's
1071 ACE_Reactor_Notify
*notify_handler_
;
1073 /// Keeps track of whether we need to delete the notify handler (if
1074 /// we didn't create it, then we don't delete it).
1075 bool delete_notify_handler_
;
1077 /// Flag that determines if signals are masked during event
1080 * If 0 then the Reactor will not mask the signals during the event
1081 * dispatching. This is useful for applications that do not
1082 * register any signal handlers and want to reduce the overhead
1083 * introduce by the kernel level locks required to change the mask.
1087 /// Restart the handle_events event loop method automatically when
1088 /// polling function in use (ioctl() in this case) is interrupted
1089 /// via an EINTR signal.
1095 * @class Token_Guard
1097 * @brief A helper class that helps grabbing, releasing and waiting
1098 * on tokens for a thread that needs access to the reactor's token.
1100 class ACE_Export Token_Guard
1103 /// Constructor that will grab the token for us
1104 Token_Guard (ACE_Dev_Poll_Reactor_Token
&token
);
1106 /// Destructor. This will release the token if it hasn't been
1107 /// released till this point
1108 ~Token_Guard (void);
1110 /// Release the token ..
1111 void release_token (void);
1113 /// Returns whether the thread that created this object owns the
1115 bool is_owner (void);
1117 /// A helper method that acquires the token 1) at a low priority, and
1118 /// 2) wait quietly for the token, not waking another thread. This
1119 /// is appropriate for cases where a thread wants to wait for and
1120 /// dispatch an event, not causing an existing waiter to relinquish the
1122 int acquire_quietly (ACE_Time_Value
*max_wait
= 0);
1124 /// A helper method that acquires the token at a high priority, and
1125 /// does wake the current token holder.
1126 int acquire (ACE_Time_Value
*max_wait
= 0);
1132 /// The Reactor token.
1133 ACE_Dev_Poll_Reactor_Token
&token_
;
1135 /// Flag that indicate whether the thread that created this object
1136 /// owns the token or not. A value of false indicates that this class
1137 /// hasn't got the token (and hence the thread) and a value of true
1145 * @class ACE_Dev_Poll_Handler_Guard
1147 * @brief Class used to make event handler reference count
1148 * manipulation exception-safe.
1150 * This class makes the reference count manipulation that occurs
1151 * during an upcall exception-safe. Prior to dispatching the event
1152 * handler, the reference count is increased. Once the upcall for the
1153 * given event handler is complete, its reference count will be decreased.
1155 class ACE_Dev_Poll_Handler_Guard
1160 * The constructor checks to see if @a eh is a reference-counted handler and
1161 * remember that for later. If @a eh is reference counted, its reference
1162 * count is incremented unless @a do_incr is false.
1163 * @a do_incr should be false if the reference count was incremented
1164 * independently of this guard, for example, on a notify handler since
1165 * the reference count is incremented when the notify is queued.
1167 ACE_Dev_Poll_Handler_Guard (ACE_Event_Handler
*eh
, bool do_incr
= true);
1171 * The destructor decrements the reference count on the event
1172 * handler corresponding to the given handle.
1174 ~ACE_Dev_Poll_Handler_Guard (void);
1176 /// Release the event handler from this guard; when the destructor is
1177 /// called, the handler's reference count will not be decremented.
1178 void release (void);
1181 /// The event handler being managed.
1182 ACE_Event_Handler
*eh_
;
1184 /// true if eh_ is a reference-counted handler.
1188 ACE_END_VERSIONED_NAMESPACE_DECL
1190 #if defined (__ACE_INLINE__)
1191 # include "ace/Dev_Poll_Reactor.inl"
1192 #endif /* __ACE_INLINE__ */
1194 #endif /* ACE_HAS_EVENT_POLL || ACE_HAS_DEV_POLL */
1196 #include /**/ "ace/post.h"
1198 #endif /* ACE_DEV_POLL_REACTOR_H */