An object oriented event demultiplexor and event handler WFMO_Reactor for Win32 WaitForMultipleObjects
#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 = DEFAULT_SIZE, int restart = 0, ACE_Sig_Handler * = 0, ACE_Timer_Queue * = 0 );
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 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 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 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 mask );
virtual int cancel_wakeup ( ACE_HANDLE handle, ACE_Reactor_Mask mask );
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 void requeue_position (int);
virtual int requeue_position (void);
virtual int mask_ops ( ACE_Event_Handler *event_handler, ACE_Reactor_Mask mask, int ops );
virtual int mask_ops ( ACE_HANDLE handle, ACE_Reactor_Mask mask, 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 schedule_wakeup_i ( ACE_HANDLE handle, ACE_Reactor_Mask masks_to_be_added );
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 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 index);
virtual int expire_timers (void);
virtual int dispatch (int wait_status);
virtual int safe_dispatch (int wait_status);
virtual int dispatch_handles (size_t index);
virtual int dispatch_handler (size_t index, size_t max_handlep1);
virtual int simple_dispatch_handler ( int index, ACE_HANDLE event_handle );
virtual int complex_dispatch_handler ( int index, 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_Process_Mutex lock_;
ACE_Lock_Adapter<ACE_Process_Mutex> lock_adapter_;
ACE_WFMO_Reactor_Handler_Repository handler_rep_;
ACE_WFMO_Reactor_Notify notify_handler_;
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_;
private:
ACE_WFMO_Reactor (const ACE_WFMO_Reactor &);
ACE_WFMO_Reactor &operator = (const ACE_WFMO_Reactor &);
};
The ACE_WFMO_Reactor is an object-oriented event demultiplexor and event handler Reactor. The sources of events that the ACE_WFMO_Reactor waits for and dispatches includes I/O events, general Win32 synchronization events (such as mutexes, semaphores, threads, etc.) and timer events.
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 handler-handle_close(), use the DONT_CALL flag with remove_handler(). Or else, dynamically allocate the handler, and then call "delete this" inside 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
. Two slots will
be added to the size
parameter which will store handles used
for internal management purposes.
virtual int open (
size_t size = DEFAULT_SIZE,
int restart = 0,
ACE_Sig_Handler * = 0,
ACE_Timer_Queue * = 0
);
ACE_WFMO_Reactor
with size size
. Two slots will
be added to the size
parameter which will store handles used
for internal management purposes.
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 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 ACE_Event_Handler
s 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 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
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 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. 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. 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 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 mask
);
remove_handler
method.
virtual int cancel_wakeup (ACE_HANDLE handle, ACE_Reactor_Mask mask);
remove_handler
method.
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
);
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 void requeue_position (int);
virtual int requeue_position (void);
virtual int mask_ops (
ACE_Event_Handler *event_handler,
ACE_Reactor_Mask mask,
int ops
);
virtual int mask_ops (
ACE_HANDLE handle,
ACE_Reactor_Mask mask,
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;