#include <ace/ReactorEx.h>
class ACE_ReactorEx {
public:
friend class ACE_ReactorEx_Handler_Repository;
friend class ACE_ReactorEx_Test;
enum { DEFAULT_SIZE = MAXIMUM_WAIT_OBJECTS - 2 };
ACE_ReactorEx (ACE_Sig_Handler * = 0, ACE_Timer_Queue * = 0);
ACE_ReactorEx ( size_t size, int unused = 0, ACE_Sig_Handler * = 0, ACE_Timer_Queue * = 0 );
static ACE_ReactorEx *instance (void);
static ACE_ReactorEx *instance (ACE_ReactorEx *);
static void close_singleton (void);
static int run_event_loop (void);
static int run_event_loop (ACE_Time_Value &tv);
static int end_event_loop (void);
static sig_atomic_t event_loop_done (void);
virtual int open ( size_t size = DEFAULT_SIZE, int restart = 0, ACE_Sig_Handler * = 0, ACE_Timer_Queue * = 0 );
virtual int close (void);
virtual ~ACE_ReactorEx (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 *eh, ACE_HANDLE event_handle = ACE_INVALID_HANDLE );
virtual int register_handler ( ACE_HANDLE event_handle, ACE_HANDLE io_handle, ACE_Event_Handler *eh, ACE_Reactor_Mask mask );
virtual int register_handler ( ACE_HANDLE io_handle, ACE_Event_Handler *eh, ACE_Reactor_Mask mask );
virtual int register_handler ( ACE_Event_Handler *eh, ACE_Reactor_Mask mask );
virtual int register_handler ( const ACE_Handle_Set &handles, ACE_Event_Handler *eh, ACE_Reactor_Mask mask );
virtual int remove_handler ( ACE_Event_Handler *eh, ACE_Reactor_Mask mask = 0 );
virtual int remove_handler ( ACE_HANDLE handle, ACE_Reactor_Mask mask = 0 );
virtual int remove_handler ( const ACE_Handle_Set &handle_set, ACE_Reactor_Mask );
virtual int suspend_handler (ACE_Event_Handler *eh);
virtual int suspend_handler (ACE_HANDLE handle);
virtual int suspend_handler (const ACE_Handle_Set &handles);
virtual int suspend_all (void);
virtual int resume_handler (ACE_Event_Handler *eh);
virtual int resume_handler (ACE_HANDLE handle);
virtual int resume_handler (const ACE_Handle_Set &handles);
virtual int resume_all (void);
virtual int schedule_timer ( ACE_Event_Handler *eh, 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 ( int timer_id, const void **arg = 0, int dont_call_handle_close = 1 );
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 owner (ACE_thread_t *owner);
virtual int owner ( ACE_thread_t new_owner, ACE_thread_t *old_owner = 0 );
virtual void wakeup_all_threads (void);
ACE_ALLOC_HOOK_DECLARE;
void dump (void) const;
inline virtual int handle_events (void);
inline virtual int handle_events (ACE_Time_Value &);
inline int notify ( ACE_Event_Handler * = 0, ACE_Reactor_Mask = ACE_Event_Handler::EXCEPT_MASK );
static ACE_ReactorEx *instance (void);
static ACE_ReactorEx *instance (ACE_ReactorEx *);
static void close_singleton (void);
static int run_event_loop (void);
static int run_event_loop (ACE_Time_Value &tv);
static int end_event_loop (void);
static sig_atomic_t event_loop_done (void);
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 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 ( ACE_Time_Value *max_wait_time, int alertable );
virtual int dispatch (int wait_status);
int safe_dispatch (int wait_status);
virtual int dispatch_handles (size_t index);
virtual int dispatch_handler (int index);
virtual int simple_dispatch_handler ( int index, ACE_HANDLE event_handle );
virtual int complex_dispatch_handler ( int index, ACE_HANDLE event_handle );
virtual int 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_Timer_Queue *timer_queue_;
int delete_timer_queue_;
int delete_handler_rep_;
ACE_Process_Mutex lock_;
ACE_ReactorEx_Handler_Repository handler_rep_;
ACE_ReactorEx_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:
static ACE_ReactorEx *reactorEx_;
static int delete_reactorEx_;
static sig_atomic_t end_event_loop_;
ACE_ReactorEx (const ACE_ReactorEx &);
ACE_ReactorEx &operator = (const ACE_ReactorEx &);
};
ACE_ReactorEx (ACE_Sig_Handler * = 0, ACE_Timer_Queue * = 0);
ACE_ReactorEx
with the default size.
ACE_ReactorEx (
size_t size,
int unused = 0,
ACE_Sig_Handler * = 0,
ACE_Timer_Queue * = 0
);
ACE_ReactorEx
with size size
. Two slots will be
added to the size
parameter which will store handles used for
internal management purposes.
static ACE_ReactorEx *instance (void);
ACE_ReactorEx
.
static ACE_ReactorEx *instance (ACE_ReactorEx *);
ACE_ReactorEx
and return existing
pointer.
static void close_singleton (void);
static int run_event_loop (void);
ACE_ReactorEx::handle_events
method returns -1 or the end_event_loop
method
is invoked.
static int run_event_loop (ACE_Time_Value &tv);
ACE_ReactorEx::handle_events
method returns -1, the end_event_loop
method
is invoked, or the ACE_Time_Value
expires.
static int end_event_loop (void);
ACE_ReactorEx::instance()
to terminate its event loop.
static sig_atomic_t event_loop_done (void);
ACE_ReactorEx::instance
event loop is finished.
virtual int open (
size_t size = DEFAULT_SIZE,
int restart = 0,
ACE_Sig_Handler * = 0,
ACE_Timer_Queue * = 0
);
ACE_ReactorEx
with size size
. Two slots will be
added to the size
parameter which will store handles used for
internal management purposes.
virtual int close (void);
virtual ~ACE_ReactorEx (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.
WaitForMultipleObjectsEx
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
WaitForMultipleObjectsEx
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
WaitForMultipleObjectsEx
for the bAlertable
option.
virtual int register_handler (
ACE_Event_Handler *eh,
ACE_HANDLE event_handle = ACE_INVALID_HANDLE
);
ACE_Event_Handler
eh
. 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, ReactorEx
will call handle_signal on eh
. If
handle
== ACE_INVALID_HANDLE
the ACE_ReactorEx
will call
the get_handle
method of eh
to extract the underlying event
handle.
virtual int register_handler (
ACE_HANDLE event_handle,
ACE_HANDLE io_handle,
ACE_Event_Handler *eh,
ACE_Reactor_Mask mask
);
ACE_Event_Handler
eh
. mask
specifies the
network events that the eh
is interested in. If io_handle
==
ACE_INVALID_HANDLE
the ACE_ReactorEx
will call the
get_handle
method of eh
to extract the underlying I/O
handle. If the event_handle
== ACE_INVALID_HANDLE
, ReactorEx
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 *eh,
ACE_Reactor_Mask mask
);
register_handler
method
where the I/O handle is passed in and the event handle will
always be created by ReactorEx
virtual int register_handler (
ACE_Event_Handler *eh,
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
ReactorEx
virtual int register_handler (
const ACE_Handle_Set &handles,
ACE_Event_Handler *eh,
ACE_Reactor_Mask mask
);
eh
with all the handles
in the Handle_Set
.
virtual int remove_handler (
ACE_Event_Handler *eh,
ACE_Reactor_Mask mask = 0
);
eh
from the ACE_ReactorEx
. Note that the
ACE_ReactorEx
will call the get_handle
method of eh
to
extract the underlying handle. If mask
==
ACE_Event_Handler::DONT_CALL
then the handle_close
method of
the eh
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 = 0
);
handle
from the ACE_ReactorEx
. If mask
==
ACE_Event_Handler::DONT_CALL
then the handle_close
method of
the eh
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 ReactorEx
. If
there are no more bindings for this eh
then it is removed from
the Reactor. For simple event entries, mask is mostly ignored
and the Event_Handler
is always removed from ReactorEx
=
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 handlers then they are removed from ReactorEx.
virtual int suspend_handler (ACE_Event_Handler *eh);
eh
temporarily. Use eh-
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_all (void);
handles
temporarily.
virtual int resume_handler (ACE_Event_Handler *eh);
eh
. Use eh-
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_all (void);
handles
.
Timer management.
virtual int schedule_timer (
ACE_Event_Handler *eh,
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 (
int 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 notify (
ACE_Event_Handler * = 0,
ACE_Reactor_Mask = ACE_Event_Handler::EXCEPT_MASK,
ACE_Time_Value * = 0
);
ACE_ReactorEx
thread if it is currently blocked in
WaitForMultipleObjects
. The ACE_Time_Value
indicates how
long to blocking trying to notify the 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_ReactorEx_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_ReactorEx_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 owner (ACE_thread_t *owner);
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 void wakeup_all_threads (void);
ACE_ALLOC_HOOK_DECLARE;
void dump (void) const;