#include <ace/WFMO_Reactor.h>
class ACE_WFMO_Reactor : public ACE_Reactor_Impl {
public:friend class ACE_WFMO_Reactor_Handler_Repository;friend class ACE_WFMO_Reactor_Test;enum{ DEFAULT_SIZE = MAXIMUM_WAIT_OBJECTS - 2 };ACE_WFMO_Reactor (ACE_Sig_Handler * = 0, ACE_Timer_Queue * = 0);ACE_WFMO_Reactor ( size_t size, int unused = 0, ACE_Sig_Handler * = 0, ACE_Timer_Queue * = 0 );virtual int open ( size_t size = ACE_WFMO_Reactor::DEFAULT_SIZE, int restart = 0, ACE_Sig_Handler * = 0, ACE_Timer_Queue * = 0, int disable_notify_pipe = 0, ACE_Reactor_Notify * = 0 );virtual int current_info (ACE_HANDLE, size_t & );virtual int set_sig_handler (ACE_Sig_Handler *signal_handler);virtual int set_timer_queue (ACE_Timer_Queue *timer_queue);virtual int close (void);virtual ~ACE_WFMO_Reactor (void);virtual int work_pending ( const ACE_Time_Value &max_wait_time = ACE_Time_Value::zero );virtual int handle_events (ACE_Time_Value *max_wait_time = 0);virtual int alertable_handle_events ( ACE_Time_Value *max_wait_time = 0 );virtual int handle_events (ACE_Time_Value &max_wait_time);virtual int alertable_handle_events ( ACE_Time_Value &max_wait_time );virtual int deactivated (void);virtual void deactivate (int do_stop);virtual int register_handler ( ACE_Event_Handler *event_handler, ACE_HANDLE event_handle = ACE_INVALID_HANDLE );virtual int register_handler ( ACE_HANDLE event_handle, ACE_HANDLE io_handle, ACE_Event_Handler *event_handler, ACE_Reactor_Mask mask );virtual int register_handler ( ACE_HANDLE io_handle, ACE_Event_Handler *event_handler, ACE_Reactor_Mask mask );virtual int register_handler ( ACE_Event_Handler *event_handler, ACE_Reactor_Mask mask );virtual int register_handler ( const ACE_Handle_Set &handles, ACE_Event_Handler *event_handler, ACE_Reactor_Mask mask );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 );virtual int register_handler ( const ACE_Sig_Set &sigset, ACE_Event_Handler *new_sh, ACE_Sig_Action *new_disp = 0 );virtual int remove_handler ( ACE_Event_Handler *event_handler, ACE_Reactor_Mask mask );virtual int remove_handler ( ACE_HANDLE handle, ACE_Reactor_Mask mask );virtual int remove_handler ( const ACE_Handle_Set &handle_set, ACE_Reactor_Mask );virtual int remove_handler ( int signum, ACE_Sig_Action *new_disp, ACE_Sig_Action *old_disp = 0, int sigkey = -1 );virtual int remove_handler (const ACE_Sig_Set &sigset);virtual int suspend_handler (ACE_Event_Handler *event_handler);virtual int suspend_handler (ACE_HANDLE handle);virtual int suspend_handler (const ACE_Handle_Set &handles);virtual int suspend_handlers (void);virtual int resume_handler (ACE_Event_Handler *event_handler);virtual int resume_handler (ACE_HANDLE handle);virtual int resume_handler (const ACE_Handle_Set &handles);virtual int resume_handlers (void);virtual int uses_event_associations (void);virtual long schedule_timer ( ACE_Event_Handler *event_handler, const void *arg, const ACE_Time_Value &delta, const ACE_Time_Value &interval = ACE_Time_Value::zero );virtual int reset_timer_interval ( long timer_id, const ACE_Time_Value &interval );virtual int cancel_timer ( ACE_Event_Handler *event_handler, int dont_call_handle_close = 1 );virtual int cancel_timer ( long timer_id, const void **arg = 0, int dont_call_handle_close = 1 );virtual int schedule_wakeup ( ACE_Event_Handler *event_handler, ACE_Reactor_Mask masks_to_be_added );virtual int schedule_wakeup ( ACE_HANDLE handle, ACE_Reactor_Mask masks_to_be_added );virtual int cancel_wakeup ( ACE_Event_Handler *event_handler, ACE_Reactor_Mask masks_to_be_deleted );virtual int cancel_wakeup ( ACE_HANDLE handle, ACE_Reactor_Mask masks_to_be_deleted );virtual int notify ( ACE_Event_Handler * = 0, ACE_Reactor_Mask = ACE_Event_Handler::EXCEPT_MASK, ACE_Time_Value * = 0 );virtual void max_notify_iterations (int);virtual int max_notify_iterations (void);virtual int handler ( ACE_HANDLE handle, ACE_Reactor_Mask mask, ACE_Event_Handler **event_handler = 0 );virtual int handler (int signum, ACE_Event_Handler ** = 0);virtual int initialized (void);virtual size_t size (void);virtual ACE_Lock &lock (void);virtual void wakeup_all_threads (void);virtual int owner ( ACE_thread_t new_owner, ACE_thread_t *old_owner = 0 );virtual int owner (ACE_thread_t *owner);virtual int restart (void);virtual int restart (int r);virtual void requeue_position (int);virtual int requeue_position (void);virtual int mask_ops ( ACE_Event_Handler *event_handler, ACE_Reactor_Mask masks, int operation );virtual int mask_ops ( ACE_HANDLE handle, ACE_Reactor_Mask masks, int ops );virtual int ready_ops ( ACE_Event_Handler *event_handler, ACE_Reactor_Mask mask, int ops );virtual int ready_ops ( ACE_HANDLE handle, ACE_Reactor_Mask, int ops );ACE_ALLOC_HOOK_DECLARE;virtual void dump (void) const;protected:virtual int register_handler_i ( ACE_HANDLE event_handle, ACE_HANDLE io_handle, ACE_Event_Handler *event_handler, ACE_Reactor_Mask mask );virtual int event_handling ( ACE_Time_Value *max_wait_time = 0, int alertable = 0 );virtual int mask_ops_i ( ACE_HANDLE io_handle, ACE_Reactor_Mask masks, int operation );virtual ACE_thread_t owner_i (void);virtual int ok_to_wait ( ACE_Time_Value *max_wait_time, int alertable );virtual int wait_for_multiple_events (int timeout, int alertable);virtual DWORD poll_remaining_handles (size_t slot);virtual int expire_timers (void);virtual int dispatch (int wait_status);virtual int safe_dispatch (int wait_status);virtual int dispatch_handles (size_t slot);virtual int dispatch_handler (size_t slot, size_t max_handlep1);virtual int simple_dispatch_handler ( int slot, ACE_HANDLE event_handle );virtual int complex_dispatch_handler ( int slot, ACE_HANDLE event_handle );virtual int dispatch_window_messages (void);virtual ACE_Reactor_Mask upcall ( ACE_Event_Handler *event_handler, ACE_HANDLE io_handle, ACE_HANDLE event_handle, long interested_events );virtual int calculate_timeout (ACE_Time_Value *time);virtual int update_state (void);virtual int new_owner (void);virtual int change_owner (void);ACE_Sig_Handler *signal_handler_;int delete_signal_handler_;ACE_Timer_Queue *timer_queue_;int delete_timer_queue_;int delete_handler_rep_;ACE_Reactor_Notify *notify_handler_;int delete_notify_handler_;ACE_Process_Mutex lock_;ACE_Lock_Adapter<ACE_Process_Mutex> lock_adapter_;ACE_WFMO_Reactor_Handler_Repository handler_rep_;ACE_Manual_Event ok_to_wait_;ACE_Manual_Event wakeup_all_threads_;ACE_Wakeup_All_Threads_Handler wakeup_all_threads_handler_;ACE_Auto_Event waiting_to_change_state_;size_t active_threads_;ACE_thread_t owner_;ACE_thread_t new_owner_;ACE_thread_t change_state_thread_;ACE_HANDLE atomic_wait_array_ [2];int open_for_business_;sig_atomic_t deactivated_;private:ACE_WFMO_Reactor (const ACE_WFMO_Reactor &);ACE_WFMO_Reactor &operator = (const ACE_WFMO_Reactor &);};
Note that changes to the state of WFMO_Reactor are not
instantaneous. Most changes (registration, removal,
suspension, and resumption of handles, and changes in
ownership) are made when the WFMO_Reactor reaches a stable
state. Users should be careful, specially when removing
handlers. This is because the WFMO_Reactor will call
handle_close on the handler when it is finally removed and
not when remove_handler is called. If the handler is not
going to be around when the WFMO_Reactor calls
ACE_Event_Handler::handle_close, use the DONT_CALL flag
with remove_handler. Or else, dynamically allocate the
handler, and then call "delete this" inside
ACE_Event_Handler::handle_close.
ACE_WFMO_Reactor (ACE_Sig_Handler * = 0, ACE_Timer_Queue * = 0);
ACE_WFMO_Reactor with the default size.
ACE_WFMO_Reactor (
size_t size,
int unused = 0,
ACE_Sig_Handler * = 0,
ACE_Timer_Queue * = 0
);
ACE_WFMO_Reactor with size size. size should
not exceed ACE_WFMO_Reactor::DEFAULT_SIZE. Two slots will be
added to the size parameter which will store handles used for
internal management purposes.
virtual int open (
size_t size = ACE_WFMO_Reactor::DEFAULT_SIZE,
int restart = 0,
ACE_Sig_Handler * = 0,
ACE_Timer_Queue * = 0,
int disable_notify_pipe = 0,
ACE_Reactor_Notify * = 0
);
ACE_WFMO_Reactor with size size. size should
not exceed ACE_WFMO_Reactor::DEFAULT_SIZE. Two slots will be
added to the size parameter which will store handles used for
internal management purposes.
virtual int current_info (ACE_HANDLE, size_t & );
virtual int set_sig_handler (ACE_Sig_Handler *signal_handler);
virtual int set_timer_queue (ACE_Timer_Queue *timer_queue);
virtual int close (void);
virtual ~ACE_WFMO_Reactor (void);
virtual int work_pending (
const ACE_Time_Value &max_wait_time = ACE_Time_Value::zero
);
virtual int handle_events (ACE_Time_Value *max_wait_time = 0);
virtual int alertable_handle_events (
ACE_Time_Value *max_wait_time = 0
);
max_wait_time before
returning. It will return earlier if timer events, I/O events,
or signal events occur. Note that max_wait_time can be 0, in
which case this method blocks indefinitely until events occur.
max_wait_time is decremented to reflect how much time this call
took. For instance, if a time value of 3 seconds is passed to
handle_events and an event occurs after 2 seconds,
max_wait_time will equal 1 second. This can be used if an
application wishes to handle events for some fixed amount of
time.
WaitForMultipleObjects is used as the demultiplexing call
Returns the total number of I/O and timer ACE_Event_Handlers
that were dispatched, 0 if the max_wait_time elapsed without
dispatching any handlers, or -1 if an error occurs.
The only difference between alertable_handle_events and
handle_events is that in the alertable case, TRUE is passed to
WaitForMultipleObjects for the bAlertable option.
virtual int handle_events (ACE_Time_Value &max_wait_time);
virtual int alertable_handle_events (ACE_Time_Value &max_wait_time);
max_wait_time value is a reference and can therefore never be
NULL.
The only difference between alertable_handle_events and
handle_events is that in the alertable case, TRUE is passed to
WaitForMultipleObjects for the bAlertable option.
virtual int deactivated (void);
handling_events and
handle_alertable_events return -1 immediately.
virtual void deactivate (int do_stop);
do_stop == 1, the Reactor will be disabled. By default, a reactor
is in active state and can be deactivated/reactived as wish.
virtual int register_handler (
ACE_Event_Handler *event_handler,
ACE_HANDLE event_handle = ACE_INVALID_HANDLE
);
ACE_Event_Handler event_handler. Since no Event
Mask is passed through this interface, it is assumed that the
handle being passed in is an event handle and when the event
becomes signaled, WFMO_Reactor will call handle_signal on
event_handler. If handle == ACE_INVALID_HANDLE the
ACE_WFMO_Reactor will call the get_handle method of
event_handler to extract the underlying event handle.
virtual int register_handler (
ACE_HANDLE event_handle,
ACE_HANDLE io_handle,
ACE_Event_Handler *event_handler,
ACE_Reactor_Mask mask
);
ACE_Event_Handler event_handle. mask specifies
the network events that the event_handler is interested in. If
io_handle == ACE_INVALID_HANDLE the ACE_WFMO_Reactor will
call the get_handle method of event_handler to extract the
underlying I/O handle. If the event_handle ==
ACE_INVALID_HANDLE, WFMO_Reactor will create an event for
associating it with the I/O handle. When the event_handle is
signalled, the appropriate handle_* callback will be invoked on
the Event_Handler
virtual int register_handler (
ACE_HANDLE io_handle,
ACE_Event_Handler *event_handler,
ACE_Reactor_Mask mask
);
register_handler method
where the I/O handle is passed in and the event handle will
always be created by WFMO_Reactor
virtual int register_handler (
ACE_Event_Handler *event_handler,
ACE_Reactor_Mask mask
);
register_handler method
where the I/O handle will always come from get_handle on the
Event_Handler and the event handle will always be created by
WFMO_Reactor
virtual int register_handler (
const ACE_Handle_Set &handles,
ACE_Event_Handler *event_handler,
ACE_Reactor_Mask mask
);
event_handler with all the handles in the
Handle_Set.
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
);
new_sh to handle the signal signum using the
new_disp. Returns the old_sh that was previously registered
(if any), along with the old_disp of the signal handler.
virtual int register_handler (
const ACE_Sig_Set &sigset,
ACE_Event_Handler *new_sh,
ACE_Sig_Action *new_disp = 0
);
new_sh to handle a set of signals sigset using the
new_disp.
virtual int remove_handler (
ACE_Event_Handler *event_handler,
ACE_Reactor_Mask mask
);
event_handler from the ACE_WFMO_Reactor. Note that
the ACE_WFMO_Reactor will call the get_handle method of
event_handler to extract the underlying handle. If mask ==
ACE_Event_Handler::DONT_CALL then the handle_close method of
the event_handler is not invoked. Note that the handle can
either be the event_handle or the io_handle
virtual int remove_handler (ACE_HANDLE handle, ACE_Reactor_Mask mask);
handle from the ACE_WFMO_Reactor. If mask ==
ACE_Event_Handler::DONT_CALL then the handle_close method of
the event_handler is not invoked. Note that the handle can
either be the event_handle or the io_handle
For the case of I/O entries, this removes the mask binding of
Event_Handler whose handle is handle from WFMO_Reactor. If
there are no more bindings for this event_handler then it is
removed from the WFMO_Reactor. For simple event entries, mask is
mostly ignored and the Event_Handler is always removed from
WFMO_Reactor
virtual int remove_handler (
const ACE_Handle_Set &handle_set,
ACE_Reactor_Mask
);
mask bindings for handles in the handle_set
bind of Event_Handler. If there are no more bindings for any
of these handles then they are removed from WFMO_Reactor.
virtual int remove_handler (
int signum,
ACE_Sig_Action *new_disp,
ACE_Sig_Action *old_disp = 0,
int sigkey = -1
);
signum.
sigkey is ignored in this implementation since there is only
one instance of a signal handler. Install the new disposition
(if given) and return the previous disposition (if desired by the
caller). Returns 0 on success and -1 if signum is invalid.
virtual int remove_handler (const ACE_Sig_Set &sigset);
remove_handler for every signal in sigset.
virtual int suspend_handler (ACE_Event_Handler *event_handler);
event_handler temporarily. Use
ACE_Event_Handler::get_handle to get the handle.
virtual int suspend_handler (ACE_HANDLE handle);
handle temporarily.
virtual int suspend_handler (const ACE_Handle_Set &handles);
handles in handle set temporarily.
virtual int suspend_handlers (void);
handles temporarily.
virtual int resume_handler (ACE_Event_Handler *event_handler);
event_handler. Use ACE_Event_Handler::get_handle to
get the handle.
virtual int resume_handler (ACE_HANDLE handle);
handle.
virtual int resume_handler (const ACE_Handle_Set &handles);
handles in handle set.
virtual int resume_handlers (void);
handles.
virtual int uses_event_associations (void);
Timer management.
virtual long schedule_timer (
ACE_Event_Handler *event_handler,
const void *arg,
const ACE_Time_Value &delta,
const ACE_Time_Value &interval = ACE_Time_Value::zero
);
event_handler that will expire after delay amount
of time, which is specified using relative time to the current
gettimeofday. If it expires then arg is passed in as the
value to the event_handler's handle_timeout callback method.
If interval is != to ACE_Time_Value::zero then it is used to
reschedule the event_handler automatically, which is also
specified using relative time. This method returns a timer_id
that uniquely identifies the event_handler in an internal list.
This timer_id can be used to cancel an event_handler before
it expires. The cancellation ensures that timer_ids are unique
up to values of greater than 2 billion timers. As long as timers
don't stay around longer than this there should be no problems
with accidentally deleting the wrong timer. Returns -1 on
failure (which is guaranteed never to be a valid timer_id.
virtual int reset_timer_interval (
long timer_id,
const ACE_Time_Value &interval
);
timer_id to
interval, which is specified in relative time to the current
gettimeofday. If interval is equal to
ACE_Time_Value::zero, the timer will become a non-rescheduling
timer. Returns 0 if successful, -1 if not.
virtual int cancel_timer (
ACE_Event_Handler *event_handler,
int dont_call_handle_close = 1
);
event_handler. Returns number of handler's cancelled.
virtual int cancel_timer (
long timer_id,
const void **arg = 0,
int dont_call_handle_close = 1
);
timer_id value
(which was returned from the schedule method). If arg is
non-NULL then it will be set to point to the ``magic cookie''
argument passed in when the Event_Handler was registered. This
makes it possible to free up the memory and avoid memory leaks.
Returns 1 if cancellation succeeded and 0 if the timer_id
wasn't found.
virtual int schedule_wakeup (
ACE_Event_Handler *event_handler,
ACE_Reactor_Mask masks_to_be_added
);
masks_to_be_added to the event_handler's entry in
WFMO_Reactor. event_handler must already have been registered
with WFMO_Reactor.
virtual int schedule_wakeup (
ACE_HANDLE handle,
ACE_Reactor_Mask masks_to_be_added
);
masks_to_be_added to the handle's entry in WFMO_Reactor.
The Event_Handler associated with handle must already have been
registered with WFMO_Reactor.
virtual int cancel_wakeup (
ACE_Event_Handler *event_handler,
ACE_Reactor_Mask masks_to_be_deleted
);
masks_to_be_deleted to the handle's entry in
WFMO_Reactor. The Event_Handler associated with handle must
already have been registered with WFMO_Reactor.
virtual int cancel_wakeup (
ACE_HANDLE handle,
ACE_Reactor_Mask masks_to_be_deleted
);
masks_to_be_deleted to the handle's entry in
WFMO_Reactor. The Event_Handler associated with handle must
already have been registered with WFMO_Reactor.
virtual int notify (
ACE_Event_Handler * = 0,
ACE_Reactor_Mask = ACE_Event_Handler::EXCEPT_MASK,
ACE_Time_Value * = 0
);
ACE_WFMO_Reactor thread if it is currently blocked
in WaitForMultipleObjects. The ACE_Time_Value indicates how
long to blocking trying to notify the WFMO_Reactor. If
timeout == 0, the caller will block until action is possible,
else will wait until the relative time specified in timeout
elapses).
virtual void max_notify_iterations (int);
ACE_WFMO_Reactor_Notify::handle_input method will iterate and
dispatch the ACE_Event_Handlers that are passed in via the
notify queue before breaking out of its
ACE_Message_Queue::dequeue loop. By default, this is set to
-1, which means "iterate until the queue is empty." Setting this
to a value like "1 or 2" will increase "fairness" (and thus
prevent starvation) at the expense of slightly higher dispatching
overhead.
virtual int max_notify_iterations (void);
ACE_WFMO_Reactor_Notify::handle_input method will iterate and
dispatch the ACE_Event_Handlers that are passed in via the
notify queue before breaking out of its
ACE_Message_Queue::dequeue loop.
virtual int handler (
ACE_HANDLE handle,
ACE_Reactor_Mask mask,
ACE_Event_Handler **event_handler = 0
);
handle is associated with a valid Event_Handler
bound to mask. Return the event_handler associated with this
handler if event_handler != 0.
virtual int handler (int signum, ACE_Event_Handler ** = 0);
signum is associated with a valid Event_Handler
bound to a signal. Return the event_handler associated with
this handler if event_handler != 0.
virtual int initialized (void);
virtual size_t size (void);
virtual ACE_Lock &lock (void);
virtual void wakeup_all_threads (void);
virtual int owner (
ACE_thread_t new_owner,
ACE_thread_t *old_owner = 0
);
new_owner. The
transfer will not complete until all threads are ready (just like
the handle set).
virtual int owner (ACE_thread_t *owner);
virtual int restart (void);
virtual int restart (int r);
virtual void requeue_position (int);
virtual int requeue_position (void);
virtual int mask_ops (
ACE_Event_Handler *event_handler,
ACE_Reactor_Mask masks,
int operation
);
masks of the event_handler's entry in WFMO_Reactor
depending upon operation. event_handler must already have
been registered with WFMO_Reactor.
virtual int mask_ops (
ACE_HANDLE handle,
ACE_Reactor_Mask masks,
int ops
);
masks of the handle's entry in WFMO_Reactor depending
upon operation. handle must already have been registered
with WFMO_Reactor.
virtual int ready_ops (
ACE_Event_Handler *event_handler,
ACE_Reactor_Mask mask,
int ops
);
virtual int ready_ops (ACE_HANDLE handle, ACE_Reactor_Mask, int ops);
ACE_ALLOC_HOOK_DECLARE;
virtual void dump (void) const;