summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ace/Event_Handler.cpp35
-rw-r--r--ace/Event_Handler.h10
-rw-r--r--ace/Handle_Set.h2
-rw-r--r--ace/Local_Tokens.h22
-rw-r--r--ace/Local_Tokens.i35
-rw-r--r--ace/Message_Queue.h8
-rw-r--r--ace/OS.h6
-rw-r--r--ace/Proactor.cpp8
-rw-r--r--ace/Proactor.h10
-rw-r--r--ace/README1
-rw-r--r--ace/Reactor.cpp1817
-rw-r--r--ace/Reactor.h826
-rw-r--r--ace/Reactor.i444
-rw-r--r--ace/Reactor_Impl.h348
-rw-r--r--ace/Select_Reactor.cpp1798
-rw-r--r--ace/Select_Reactor.h818
-rw-r--r--ace/Select_Reactor.i214
-rw-r--r--ace/Service_Config.cpp114
-rw-r--r--ace/Service_Config.h86
-rw-r--r--ace/Strategies.cpp34
-rw-r--r--ace/Strategies.h27
-rw-r--r--ace/Synch_T.h19
-rw-r--r--ace/Synch_T.i38
-rw-r--r--ace/Timer_Queue_T.h1
-rw-r--r--ace/Token.h12
-rw-r--r--ace/Token.i28
-rw-r--r--ace/WFMO_Reactor.cpp (renamed from ace/ReactorEx.cpp)448
-rw-r--r--ace/WFMO_Reactor.h (renamed from ace/ReactorEx.h)367
-rw-r--r--ace/WFMO_Reactor.i (renamed from ace/ReactorEx.i)423
-rw-r--r--ace/XtReactor.cpp120
30 files changed, 4675 insertions, 3444 deletions
diff --git a/ace/Event_Handler.cpp b/ace/Event_Handler.cpp
index d406702c1b1..a090ccb36f1 100644
--- a/ace/Event_Handler.cpp
+++ b/ace/Event_Handler.cpp
@@ -14,9 +14,7 @@
ACE_Event_Handler::ACE_Event_Handler (void)
: priority_ (ACE_Event_Handler::LO_PRIORITY),
- reactor_ (0),
- reactorex_ (0),
- proactor_ (0)
+ reactor_ (0)
{
// ACE_TRACE ("ACE_Event_Handler::ACE_Event_Handler");
}
@@ -144,37 +142,6 @@ ACE_Event_Handler::reactor (void) const
return this->reactor_;
}
-void
-ACE_Event_Handler::reactorEx (ACE_ReactorEx *reactorex)
-{
- ACE_TRACE ("ACE_Event_Handler::reactorex");
- this->reactorex_ = reactorex;
-}
-
-ACE_ReactorEx *
-ACE_Event_Handler::reactorEx (void) const
-{
- ACE_TRACE ("ACE_Event_Handler::ReactorEx");
-
- return this->reactorex_;
-}
-
-void
-ACE_Event_Handler::proactor (ACE_Proactor *proactor)
-{
- ACE_TRACE ("ACE_Event_Handler::proactor");
-
- this->proactor_ = proactor;
-}
-
-ACE_Proactor *
-ACE_Event_Handler::proactor (void) const
-{
- ACE_TRACE ("ACE_Event_Handler::Proactor");
-
- return this->proactor_;
-}
-
ACE_Notification_Buffer::ACE_Notification_Buffer (void)
{
ACE_TRACE ("ACE_Notification_Buffer::ACE_Notification_Buffer");
diff --git a/ace/Event_Handler.h b/ace/Event_Handler.h
index 935587d17e3..c63e781d6cd 100644
--- a/ace/Event_Handler.h
+++ b/ace/Event_Handler.h
@@ -22,8 +22,6 @@
// Forward declaration.
class ACE_Message_Block;
class ACE_Reactor;
-class ACE_ReactorEx;
-class ACE_Proactor;
typedef u_long ACE_Reactor_Mask;
@@ -113,12 +111,6 @@ public:
virtual void reactor (ACE_Reactor *reactor);
virtual ACE_Reactor *reactor (void) const;
- virtual void reactorEx (ACE_ReactorEx *reactorex);
- virtual ACE_ReactorEx *reactorEx (void) const;
-
- virtual void proactor (ACE_Proactor *proactor);
- virtual ACE_Proactor *proactor (void) const;
-
protected:
ACE_Event_Handler (void);
// Force ACE_Event_Handler to be an abstract base class.
@@ -128,8 +120,6 @@ protected:
// = Pointers to the various event demultiplexors.
ACE_Reactor *reactor_;
- ACE_ReactorEx *reactorex_;
- ACE_Proactor *proactor_;
};
struct ACE_Export ACE_Notification_Buffer
diff --git a/ace/Handle_Set.h b/ace/Handle_Set.h
index 22e098852f4..46ace888b92 100644
--- a/ace/Handle_Set.h
+++ b/ace/Handle_Set.h
@@ -29,7 +29,7 @@ public:
enum
{
- MAXSIZE = ACE_DEFAULT_REACTOR_SIZE
+ MAXSIZE = ACE_DEFAULT_SELECT_REACTOR_SIZE
};
// = Initialization methods.
diff --git a/ace/Local_Tokens.h b/ace/Local_Tokens.h
index cd86d10e9b2..11b1528c7bc 100644
--- a/ace/Local_Tokens.h
+++ b/ace/Local_Tokens.h
@@ -720,6 +720,28 @@ public:
ACE_Synch_Options::defaults);
// Calls remove on the token.
+ virtual int acquire_read (int notify = 0,
+ void (*sleep_hook)(void *) = 0,
+ ACE_Synch_Options &options =
+ ACE_Synch_Options::defaults);
+ // Since the locking mechanism doesn't support read locks then this
+ // just calls <acquire>.
+
+ virtual int acquire_write (int notify = 0,
+ void (*sleep_hook)(void *) = 0,
+ ACE_Synch_Options &options =
+ ACE_Synch_Options::defaults);
+ // Since the locking mechanism doesn't support write locks then this
+ // just calls <acquire>.
+
+ virtual int tryacquire_read (void (*sleep_hook)(void *) = 0);
+ // Since the locking mechanism doesn't support read locks then this
+ // just calls <tryacquire>.
+
+ virtual int tryacquire_write (void (*sleep_hook)(void *) = 0);
+ // Since the locking mechanism doesn't support write locks then this
+ // just calls <tryacquire>.
+
// = Utility methods.
virtual const char *client_id (void) const;
diff --git a/ace/Local_Tokens.i b/ace/Local_Tokens.i
index 430c542bd85..a1e70bc9e9a 100644
--- a/ace/Local_Tokens.i
+++ b/ace/Local_Tokens.i
@@ -10,6 +10,41 @@ ACE_Token_Proxy::type (void) const
return 0;
}
+
+ACE_INLINE int
+ACE_Token_Proxy::acquire_read (int notify,
+ void (*sleep_hook)(void *),
+ ACE_Synch_Options &options)
+{
+ return this->acquire (notify,
+ sleep_hook,
+ options);
+}
+
+ACE_INLINE int
+ACE_Token_Proxy::acquire_write (int notify,
+ void (*sleep_hook)(void *),
+ ACE_Synch_Options &options)
+{
+ return this->acquire (notify,
+ sleep_hook,
+ options);
+}
+
+ACE_INLINE int
+ACE_Token_Proxy::tryacquire_read (void (*sleep_hook)(void *))
+{
+ return this->tryacquire (sleep_hook);
+}
+
+ACE_INLINE int
+ACE_Token_Proxy::tryacquire_write (void (*sleep_hook)(void *))
+{
+ return this->tryacquire (sleep_hook);
+}
+
+// ************************************************************
+
ACE_INLINE int
ACE_Token_Proxy_Queue::size (void)
{
diff --git a/ace/Message_Queue.h b/ace/Message_Queue.h
index a96db9fa72a..2a814b2fbb0 100644
--- a/ace/Message_Queue.h
+++ b/ace/Message_Queue.h
@@ -163,10 +163,10 @@ public:
// <enqueue_tail>, and <enqueue_prio> when a new item is inserted
// into the queue. Subclasses can override this method to perform
// specific notification strategies (e.g., signaling events for a
- // <ReactorEx>, notifying a <Reactor>, etc.). In a multi-threaded
- // application with concurrent consumers, there is no guarantee that
- // the queue will be still be non-empty by the time the notification
- // occurs.
+ // <WFMO_Reactor>, notifying a <Reactor>, etc.). In a
+ // multi-threaded application with concurrent consumers, there is no
+ // guarantee that the queue will be still be non-empty by the time
+ // the notification occurs.
// = Get/set the notification strategy for the <Message_Queue>
ACE_Notification_Strategy *notification_strategy (void);
diff --git a/ace/OS.h b/ace/OS.h
index fa6167992f5..fe9f77474a6 100644
--- a/ace/OS.h
+++ b/ace/OS.h
@@ -200,9 +200,9 @@
#endif /* ACE_DEFAULT_DIR_PERMS */
// Default size of the ACE Reactor.
-#if !defined (ACE_DEFAULT_REACTOR_SIZE)
-#define ACE_DEFAULT_REACTOR_SIZE FD_SETSIZE
-#endif /* ACE_DEFAULT_REACTOR_SIZE */
+#if !defined (ACE_DEFAULT_SELECT_REACTOR_SIZE)
+#define ACE_DEFAULT_SELECT_REACTOR_SIZE FD_SETSIZE
+#endif /* ACE_DEFAULT_SELECT_REACTOR_SIZE */
// Default size of the ACE Map_Manager.
#if !defined (ACE_DEFAULT_MAP_SIZE)
diff --git a/ace/Proactor.cpp b/ace/Proactor.cpp
index 32f8a21a38d..6b19bc08f24 100644
--- a/ace/Proactor.cpp
+++ b/ace/Proactor.cpp
@@ -203,13 +203,13 @@ ACE_Proactor_Handle_Timeout_Upcall::proactor (ACE_Proactor &proactor)
ACE_Proactor::ACE_Proactor (size_t number_of_threads,
Timer_Queue *tq,
- int used_with_reactorEx_event_loop)
+ int used_with_reactor_event_loop)
: completion_port_ (0), // This *MUST* be 0, *NOT* ACE_INVALID_HANDLE!!!!
number_of_threads_ (number_of_threads),
timer_queue_ (0),
delete_timer_queue_ (0),
timer_handler_ (0),
- used_with_reactorEx_event_loop_ (used_with_reactorEx_event_loop)
+ used_with_reactor_event_loop_ (used_with_reactor_event_loop)
{
// create the completion port
this->completion_port_ = ::CreateIoCompletionPort (INVALID_HANDLE_VALUE,
@@ -476,7 +476,7 @@ ACE_Proactor::handle_signal (int, siginfo_t *, ucontext_t *)
continue;
// If our handle_events failed, we'll report a failure to the
- // ReactorEx.
+ // Reactor.
return result == -1 ? -1 : 0;
}
@@ -493,7 +493,7 @@ ACE_Proactor::handle_close (ACE_HANDLE handle,
ACE_HANDLE
ACE_Proactor::get_handle (void) const
{
- if (this->used_with_reactorEx_event_loop_)
+ if (this->used_with_reactor_event_loop_)
return this->event_.handle ();
else
return 0;
diff --git a/ace/Proactor.h b/ace/Proactor.h
index 97bd0ecd896..582a487e600 100644
--- a/ace/Proactor.h
+++ b/ace/Proactor.h
@@ -133,7 +133,7 @@ public:
ACE_Proactor (size_t number_of_threads = 0,
Timer_Queue *tq = 0,
- int used_with_reactorEx_event_loop = 0);
+ int used_with_reactor_event_loop = 0);
// A do nothing constructor.
virtual ~ACE_Proactor (void);
@@ -314,12 +314,12 @@ protected:
// This will manage the thread in the Timer_Handler
ACE_Auto_Event event_;
- // This event is used in conjunction with ReactorEx when we try to
- // integrate the event loops of ReactorEx and the Proactor.
+ // This event is used in conjunction with Reactor when we try to
+ // integrate the event loops of Reactor and the Proactor.
- int used_with_reactorEx_event_loop_;
+ int used_with_reactor_event_loop_;
// Flag that indicates whether we are used in conjunction with
- // ReactorEx
+ // Reactor
private:
static ACE_Proactor *proactor_;
diff --git a/ace/README b/ace/README
index 52bf154c23f..c171b5109fd 100644
--- a/ace/README
+++ b/ace/README
@@ -118,6 +118,7 @@ ACE_HAS_REENTRANT_FUNCTIONS Platform supports reentrant functions (i.e., all th
ACE_LACKS_NETDB_REENTRANT_FUNCTIONS Platform does not support reentrant netdb functions (getprotobyname_r, getprotobynumber_r, gethostbyaddr_r, gethostbyname_r, getservbyname_r).
ACE_HAS_REGEX Platform supports the POSIX regular expression library
ACE_HAS_SELECT_H Platform has special header for select().
+ACE_USE_SELECT_REACTOR_FOR_REACTOR_IMPL For Win32: Use Select_Reactor as default implementation of Reactor instead of WFMO_Reactor.
ACE_HAS_SEMUN Compiler/platform defines a union semun for SysV shared memory
ACE_HAS_SET_T_ERRNO Platform has a function to set t_errno (e.g., Tandem).
ACE_HAS_SIGINFO_T Platform supports SVR4 extended signals
diff --git a/ace/Reactor.cpp b/ace/Reactor.cpp
index 361efeadb4d..e5c53b43142 100644
--- a/ace/Reactor.cpp
+++ b/ace/Reactor.cpp
@@ -1,13 +1,14 @@
-// Reactor.cpp
// $Id$
#define ACE_BUILD_DLL
-#include "ace/Synch_T.h"
-#include "ace/SOCK_Acceptor.h"
-#include "ace/SOCK_Connector.h"
-#include "ace/Timer_List.h"
+
#include "ace/Reactor.h"
+
+#include "ace/Reactor_Impl.h"
+#include "ace/Handle_Set.h"
#include "ace/Service_Config.h"
+#include "ace/Select_Reactor.h"
+#include "ace/WFMO_Reactor.h"
#if !defined (__ACE_INLINE__)
#include "ace/Reactor.i"
@@ -15,14 +16,27 @@
ACE_ALLOC_HOOK_DEFINE(ACE_Reactor)
-#if defined (ACE_WIN32)
-#define ACE_REACTOR_HANDLE(H) (this->event_handlers_[(H)].handle_)
-#define ACE_REACTOR_EVENT_HANDLER(THIS,H) ((THIS)->event_handlers_[(H)].event_handler_)
-#else
-#define ACE_REACTOR_HANDLE(H) (H)
-#define ACE_REACTOR_EVENT_HANDLER(THIS,H) ((THIS)->event_handlers_[(H)])
-#endif /* ACE_WIN32 */
-
+ACE_Reactor::ACE_Reactor (ACE_Reactor_Impl *implementation)
+ : implementation_ (implementation),
+ delete_implementation_ (0)
+{
+ if (this->implementation_ == 0)
+ {
+#if defined (ACE_WIN32) && !defined (ACE_USE_SELECT_REACTOR_FOR_REACTOR_IMPL)
+ ACE_NEW (this->implementation_, ACE_WFMO_Reactor);
+#else /* ACE_WIN32 && !ACE_USE_SELECT_REACTOR_AS_REACTOR */
+ ACE_NEW (this->implementation_, ACE_Select_Reactor);
+#endif /* ACE_WIN32 && !ACE_USE_SELECT_REACTOR_AS_REACTOR */
+ this->delete_implementation_ = 1;
+ }
+}
+
+ACE_Reactor::~ACE_Reactor (void)
+{
+ if (this->delete_implementation_)
+ delete this->implementation_;
+}
+
// Process-wide ACE_Reactor.
ACE_Reactor *ACE_Reactor::reactor_ = 0;
@@ -33,875 +47,8 @@ int ACE_Reactor::delete_reactor_ = 0;
// Terminate the eventloop.
sig_atomic_t ACE_Reactor::end_event_loop_ = 0;
-// Performs sanity checking on the ACE_HANDLE.
-
-int
-ACE_Reactor_Handler_Repository::invalid_handle (ACE_HANDLE handle)
-{
- ACE_TRACE ("ACE_Reactor_Handler_Repository::invalid_handle");
-#if defined (ACE_WIN32)
- // It's too expensive to perform more exhaustive validity checks on
- // Win32 due to the way that they implement SOCKET HANDLEs.
- if (handle == ACE_INVALID_HANDLE)
-#else /* !ACE_WIN32 */
- if (handle < 0 || handle >= this->max_size_)
-#endif /* ACE_WIN32 */
- {
- errno = EINVAL;
- return 1;
- }
- else
- return 0;
-}
-
-// Performs sanity checking on the ACE_HANDLE.
-
-int
-ACE_Reactor_Handler_Repository::handle_in_range (ACE_HANDLE handle)
-{
- ACE_TRACE ("ACE_Reactor_Handler_Repository::handle_in_range");
-#if defined (ACE_WIN32)
- // It's too expensive to perform more exhaustive validity checks on
- // Win32 due to the way that they implement SOCKET HANDLEs.
- if (handle != ACE_INVALID_HANDLE)
-#else /* !ACE_WIN32 */
- if (handle >= 0 && handle < this->max_handlep1_)
-#endif /* ACE_WIN32 */
- return 1;
- else
- {
- errno = EINVAL;
- return 0;
- }
-}
-
-size_t
-ACE_Reactor_Handler_Repository::max_handlep1 (void)
-{
- ACE_TRACE ("ACE_Reactor_Handler_Repository::max_handlep1");
-
- return this->max_handlep1_;
-}
-
-int
-ACE_Reactor_Handler_Repository::open (size_t size)
-{
- ACE_TRACE ("ACE_Reactor_Handler_Repository::open");
- this->max_size_ = size;
- this->max_handlep1_ = 0;
-
-#if defined (ACE_WIN32)
- // Try to allocate the memory.
- ACE_NEW_RETURN (this->event_handlers_,
- ACE_NT_EH_Record[size],
- -1);
-
- // Initialize the ACE_Event_Handler * to { ACE_INVALID_HANDLE, 0 }.
- for (size_t h = 0; h < size; h++)
- {
- ACE_REACTOR_HANDLE (h) = ACE_INVALID_HANDLE;
- ACE_REACTOR_EVENT_HANDLER (this, h) = 0;
- }
-#else
- // Try to allocate the memory.
- ACE_NEW_RETURN (this->event_handlers_,
- ACE_Event_Handler *[size],
- -1);
-
- // Initialize the ACE_Event_Handler * to NULL.
- for (size_t h = 0; h < size; h++)
- ACE_REACTOR_EVENT_HANDLER (this, h) = 0;
-#endif /* ACE_WIN32 */
- return 0;
-}
-
-// Initialize a repository of the appropriate <size>.
-
-ACE_Reactor_Handler_Repository::ACE_Reactor_Handler_Repository (ACE_Reactor &reactor)
- : reactor_ (reactor),
- max_size_ (0),
- max_handlep1_ (0),
- event_handlers_ (0)
-{
- ACE_TRACE ("ACE_Reactor_Handler_Repository::ACE_Reactor_Handler_Repository");
-}
-
-int
-ACE_Reactor_Handler_Repository::unbind_all (void)
-{
- // Unbind all of the <handle, ACE_Event_Handler>s.
- for (int handle = 0;
- handle < this->max_handlep1_;
- handle++)
- this->unbind (ACE_REACTOR_HANDLE (handle),
- ACE_Event_Handler::ALL_EVENTS_MASK);
-
- return 0;
-}
-
-int
-ACE_Reactor_Handler_Repository::close (void)
-{
- ACE_TRACE ("ACE_Reactor_Handler_Repository::close");
-
- if (this->event_handlers_ != 0)
- {
- this->unbind_all ();
-
- delete [] this->event_handlers_;
- this->event_handlers_ = 0;
- }
- return 0;
-}
-
-// Return the <ACE_Event_Handler *> associated with the <handle>.
-
-ACE_Event_Handler *
-ACE_Reactor_Handler_Repository::find (ACE_HANDLE handle,
- size_t *index_p)
-{
- ACE_TRACE ("ACE_Reactor_Handler_Repository::find");
-
- ACE_Event_Handler *eh = 0;
- ssize_t i;
-
- // Only bother to search for the <handle> if it's in range.
- if (this->handle_in_range (handle))
- {
-#if defined (ACE_WIN32)
- i = 0;
-
- for (; i < this->max_handlep1_; i++)
- if (ACE_REACTOR_HANDLE (i) == handle)
- {
- eh = ACE_REACTOR_EVENT_HANDLER (this, i);
- break;
- }
-#else
- i = handle;
-
- eh = ACE_REACTOR_EVENT_HANDLER (this, handle);
-#endif /* ACE_WIN32 */
- }
- else
- // g++ can't figure out that i won't be used below if the handle
- // is out of range, so keep it happy by defining i here . . .
- i = 0;
-
- if (eh != 0 && index_p != 0)
- *index_p = i;
- else
- errno = ENOENT;
-
- return eh;
-}
-
-// Bind the <ACE_Event_Handler *> to the <ACE_HANDLE>.
-
-int
-ACE_Reactor_Handler_Repository::bind (ACE_HANDLE handle,
- ACE_Event_Handler *event_handler,
- ACE_Reactor_Mask mask)
-{
- ACE_TRACE ("ACE_Reactor_Handler_Repository::bind");
-
- if (handle == ACE_INVALID_HANDLE)
- handle = event_handler->get_handle ();
-
- if (this->invalid_handle (handle))
- return -1;
-
-#if defined (ACE_WIN32)
- int assigned_slot = -1;
-
- for (ssize_t i = 0; i < this->max_handlep1_; i++)
- {
- // Found it, so let's just reuse this location.
- if (ACE_REACTOR_HANDLE (i) == handle)
- {
- assigned_slot = i;
- break;
- }
- // Here's the first free slot, so let's take it.
- else if (ACE_REACTOR_HANDLE (i) == ACE_INVALID_HANDLE
- && assigned_slot == -1)
- assigned_slot = i;
- }
-
- if (assigned_slot > -1)
- // We found a free spot, let's reuse it.
- {
- ACE_REACTOR_HANDLE (assigned_slot) = handle;
- ACE_REACTOR_EVENT_HANDLER (this, assigned_slot) = event_handler;
- }
- else if (this->max_handlep1_ < this->max_size_)
- {
- // Insert at the end of the active portion.
- ACE_REACTOR_HANDLE (this->max_handlep1_) = handle;
- ACE_REACTOR_EVENT_HANDLER (this, this->max_handlep1_) = event_handler;
- this->max_handlep1_++;
- }
- else
- {
- // No more room at the inn!
- errno = ENOMEM;
- return -1;
- }
-#else
- ACE_REACTOR_EVENT_HANDLER (this, handle) = event_handler;
-
- if (this->max_handlep1_ < handle + 1)
- this->max_handlep1_ = handle + 1;
-#endif /* ACE_WIN32 */
-
- // Add the <mask> for this <handle> in the Reactor's wait_set.
- this->reactor_.bit_ops (handle,
- mask,
- this->reactor_.wait_set_,
- ACE_Reactor::ADD_MASK);
-
- // Note the fact that we've changed the state of the <wait_set_>,
- // which is used by the dispatching loop to determine whether it can
- // keep going or if it needs to reconsult select().
- this->reactor_.state_changed_ = 1;
-
- // Assign *this* <Reactor> to the <Event_Handler>.
- event_handler->reactor (&this->reactor_);
- return 0;
-}
-
-// Remove the binding of <ACE_HANDLE>.
-
-int
-ACE_Reactor_Handler_Repository::unbind (ACE_HANDLE handle,
- ACE_Reactor_Mask mask)
-{
- ACE_TRACE ("ACE_Reactor_Handler_Repository::unbind");
-
- size_t index;
- ACE_Event_Handler *eh = this->find (handle, &index);
-
- if (eh == 0)
- return -1;
-
- // Clear out the <mask> bits in the Reactor's wait_set.
- this->reactor_.bit_ops (handle,
- mask,
- this->reactor_.wait_set_,
- ACE_Reactor::CLR_MASK);
-
- // Note the fact that we've changed the state of the <wait_set_>,
- // which is used by the dispatching loop to determine whether it can
- // keep going or if it needs to reconsult select().
- this->reactor_.state_changed_ = 1;
-
- // Close down the <Event_Handler> unless we've been instructed not
- // to.
- if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::DONT_CALL) == 0)
- eh->handle_close (handle, mask);
-
- // If there are no longer any outstanding events on this <handle>
- // then we can totally shut down the Event_Handler.
- if (this->reactor_.wait_set_.rd_mask_.is_set (handle) == 0
- && this->reactor_.wait_set_.wr_mask_.is_set (handle) == 0
- && this->reactor_.wait_set_.ex_mask_.is_set (handle) == 0)
-#if defined (ACE_WIN32)
- {
- ACE_REACTOR_HANDLE (index) = ACE_INVALID_HANDLE;
- ACE_REACTOR_EVENT_HANDLER (this, index) = 0;
-
- if (this->max_handlep1_ == (int) index + 1)
- {
- // We've deleted the last entry (i.e., i + 1 == the current
- // size of the array), so we need to figure out the last
- // valid place in the array that we should consider in
- // subsequent searches.
-
- for (int i = this->max_handlep1_ - 1;
- i >= 0 && ACE_REACTOR_HANDLE (i) == ACE_INVALID_HANDLE;
- i--)
- continue;
-
- this->max_handlep1_ = i + 1;
- }
- }
-#else
- {
- ACE_REACTOR_EVENT_HANDLER (this, handle) = 0;
-
- if (this->max_handlep1_ == handle + 1)
- {
- // We've deleted the last entry, so we need to figure out
- // the last valid place in the array that is worth looking
- // at.
- ACE_HANDLE rd_max = this->reactor_.wait_set_.rd_mask_.max_set ();
- ACE_HANDLE wr_max = this->reactor_.wait_set_.wr_mask_.max_set ();
- ACE_HANDLE ex_max = this->reactor_.wait_set_.ex_mask_.max_set ();
-
- // Compute the maximum of three values.
- this->max_handlep1_ = rd_max < wr_max ? wr_max : rd_max;
-
- if (this->max_handlep1_ < ex_max)
- this->max_handlep1_ = ex_max;
-
- this->max_handlep1_++;
- }
- }
-#endif /* ACE_WIN32 */
-
- return 0;
-}
-
-ACE_Reactor_Handler_Repository_Iterator::ACE_Reactor_Handler_Repository_Iterator
- (const ACE_Reactor_Handler_Repository *s)
- : rep_ (s),
- current_ (-1)
-{
- this->advance ();
-}
-
-// Pass back the <next_item> that hasn't been seen in the Set.
-// Returns 0 when all items have been seen, else 1.
-
-int
-ACE_Reactor_Handler_Repository_Iterator::next (ACE_Event_Handler *&next_item)
-{
- int result = 1;
-
- if (this->current_ >= this->rep_->max_handlep1_)
- result = 0;
- else
- next_item = ACE_REACTOR_EVENT_HANDLER (this->rep_,
- this->current_);
- return result;
-}
-
-int
-ACE_Reactor_Handler_Repository_Iterator::done (void) const
-{
- return this->current_ >= this->rep_->max_handlep1_;
-}
-
-// Move forward by one element in the set.
-
-int
-ACE_Reactor_Handler_Repository_Iterator::advance (void)
-{
- if (this->current_ < this->rep_->max_handlep1_)
- this->current_++;
-
- while (this->current_ < this->rep_->max_handlep1_)
- if (ACE_REACTOR_EVENT_HANDLER (this->rep_, this->current_) != 0)
- return 1;
- else
- this->current_++;
-
- return this->current_ < this->rep_->max_handlep1_;
-}
-
-// Dump the state of an object.
-
-void
-ACE_Reactor_Handler_Repository_Iterator::dump (void) const
-{
- ACE_TRACE ("ACE_Reactor_Handler_Repository_Iterator::dump");
-
- ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
- ACE_DEBUG ((LM_DEBUG, "rep_ = %u", this->rep_));
- ACE_DEBUG ((LM_DEBUG, "current_ = %d", this->current_));
- ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
-}
-
-void
-ACE_Reactor_Handler_Repository::dump (void) const
-{
- ACE_TRACE ("ACE_Reactor_Handler_Repository::dump");
-
- ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
- ACE_DEBUG ((LM_DEBUG,
- "(%t) max_handlep1_ = %d, max_size_ = %d\n",
- this->max_handlep1_, this->max_size_));
- ACE_DEBUG ((LM_DEBUG, "["));
-
- ACE_Event_Handler *eh = 0;
-
- for (ACE_Reactor_Handler_Repository_Iterator iter (this);
- iter.next (eh) != 0;
- iter.advance ())
- ACE_DEBUG ((LM_DEBUG, " (eh = %x, eh->handle_ = %d)",
- eh, eh->get_handle ()));
-
- ACE_DEBUG ((LM_DEBUG, " ]"));
- ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
-}
-
-ACE_ALLOC_HOOK_DEFINE(ACE_Reactor_Handler_Repository_Iterator)
-
-int
-ACE_Reactor::any_ready (ACE_Reactor_Handle_Set &wait_set)
-{
- ACE_TRACE ("ACE_Reactor::fill_in_ready");
-
-#if !defined (ACE_WIN32)
- // Make this call signal safe.
- ACE_Sig_Guard sb;
-#endif /* ACE_WIN32 */
-
- int number_ready = this->ready_set_.rd_mask_.num_set ()
- + this->ready_set_.wr_mask_.num_set ()
- + this->ready_set_.ex_mask_.num_set ();
-
- if (number_ready > 0)
- {
- wait_set.rd_mask_ = this->wait_set_.rd_mask_;
- wait_set.wr_mask_ = this->wait_set_.wr_mask_;
- wait_set.ex_mask_ = this->wait_set_.ex_mask_;
-
- this->ready_set_.rd_mask_.reset ();
- this->ready_set_.wr_mask_.reset ();
- this->ready_set_.ex_mask_.reset ();
- }
-
- return number_ready;
-}
-
-int
-ACE_Reactor::handler_i (int signum, ACE_Event_Handler **eh)
-{
- ACE_TRACE ("ACE_Reactor::handler_i");
- ACE_Event_Handler *handler = this->signal_handler_->handler (signum);
-
- if (handler == 0)
- return -1;
- else if (*eh != 0)
- *eh = handler;
- return 0;
-}
-
-int
-ACE_Reactor::initialized (void)
-{
- ACE_TRACE ("ACE_Reactor::initialized");
- ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, 0));
- return this->initialized_;
-}
-
-int
-ACE_Reactor::owner (ACE_thread_t tid, ACE_thread_t *o_id)
-{
- ACE_TRACE ("ACE_Reactor::owner");
- ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1));
-
- if (o_id)
- *o_id = this->owner_;
-
- this->owner_ = tid;
-
- return 0;
-}
-
-int
-ACE_Reactor::owner (ACE_thread_t *t_id)
-{
- ACE_TRACE ("ACE_Reactor::owner");
- ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1));
- *t_id = this->owner_;
- return 0;
-}
-
-void
-ACE_Reactor::requeue_position (int rp)
-{
- ACE_TRACE ("ACE_Reactor::requeue_position");
- ACE_MT (ACE_GUARD (ACE_REACTOR_MUTEX, ace_mon, this->token_));
-#if defined (ACE_WIN32)
- ACE_UNUSED_ARG (rp);
- // Must always requeue ourselves "next" on Win32.
- this->requeue_position_ = 0;
-#else
- this->requeue_position_ = rp;
-#endif /* ACE_WIN32 */
-}
-
-int
-ACE_Reactor::requeue_position (void)
-{
- ACE_TRACE ("ACE_Reactor::requeue_position");
- ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1));
- return this->requeue_position_;
-}
-
-void
-ACE_Reactor::max_notify_iterations (int iterations)
-{
- ACE_TRACE ("ACE_Reactor::max_notify_iterations");
- ACE_MT (ACE_GUARD (ACE_REACTOR_MUTEX, ace_mon, this->token_));
-
- // Must always be > 0 or < 0 to optimize the loop exit condition.
- if (iterations == 0)
- iterations = 1;
-
- this->max_notify_iterations_ = iterations;
-}
-
-int
-ACE_Reactor::max_notify_iterations (void)
-{
- ACE_TRACE ("ACE_Reactor::max_notify_iterations");
- ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1));
- return this->max_notify_iterations_;
-}
-
-// Enqueue ourselves into the list of waiting threads.
-void
-ACE_Reactor::renew (void)
-{
- ACE_TRACE ("ACE_Reactor::renew");
-#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
- this->token_.renew (this->requeue_position_);
-#endif /* defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) */
-}
-
-#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
-
-void
-ACE_Reactor_Token::dump (void) const
-{
- ACE_TRACE ("ACE_Reactor_Token::dump");
-
- ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
- ACE_DEBUG ((LM_DEBUG, "\n"));
- ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
-}
-
-ACE_Reactor_Token::ACE_Reactor_Token (ACE_Reactor &r)
- : reactor_ (r)
-#if defined (ACE_REACTOR_HAS_DEADLOCK_DETECTION)
- , ACE_Local_Mutex (0) // Triggers unique name by stringifying "this"...
-#endif /* ACE_REACTOR_HAS_DEADLOCK_DETECTION */
-{
- ACE_TRACE ("ACE_Reactor_Token::ACE_Reactor_Token");
-}
-
-// Used to wakeup the Reactor.
-
-void
-ACE_Reactor_Token::sleep_hook (void)
-{
- ACE_TRACE ("ACE_Reactor_Token::sleep_hook");
- if (this->reactor_.notify () == -1)
- ACE_ERROR ((LM_ERROR, "%p\n", "sleep_hook failed"));
-}
-
-#endif /* ACE_MT_SAFE */
-
-void
-ACE_Reactor_Notify::dump (void) const
-{
- ACE_TRACE ("ACE_Reactor_Notify::dump");
-
- ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
- ACE_DEBUG ((LM_DEBUG, "reactor_ = %x", this->reactor_));
- this->notification_pipe_.dump ();
- ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
-}
-
-int
-ACE_Reactor_Notify::open (ACE_Reactor *r)
-{
- ACE_TRACE ("ACE_Reactor_Notify::open");
-
- this->reactor_ = r;
-
- if (this->notification_pipe_.open () == -1)
- return -1;
-
- // There seems to be a Win32 bug with this... Set this into
- // non-blocking mode.
- if (ACE::set_flags (this->notification_pipe_.read_handle (),
- ACE_NONBLOCK) == -1)
- return -1;
- else
- return this->reactor_->register_handler
- (this->notification_pipe_.read_handle (),
- this,
- ACE_Event_Handler::READ_MASK);
-}
-
-int
-ACE_Reactor_Notify::close (void)
-{
- ACE_TRACE ("ACE_Reactor_Notify::close");
- return this->notification_pipe_.close ();
-}
-
-ssize_t
-ACE_Reactor_Notify::notify (ACE_Event_Handler *eh,
- ACE_Reactor_Mask mask,
- ACE_Time_Value *timeout)
-{
- ACE_TRACE ("ACE_Reactor_Notify::notify");
-
- ACE_Notification_Buffer buffer (eh, mask);
-
- ssize_t n = ACE::send (this->notification_pipe_.write_handle (),
- (char *) &buffer,
- sizeof buffer,
- timeout);
- return n == -1 ? -1 : 0;
-}
-
-// Handles pending threads (if any) that are waiting to unblock the
-// Reactor.
-
-int
-ACE_Reactor_Notify::dispatch_notifications (int &number_of_active_handles,
- const ACE_Handle_Set &rd_mask)
-{
- ACE_TRACE ("ACE_Reactor_Notify::handle_notification");
-
- ACE_HANDLE read_handle =
- this->notification_pipe_.read_handle ();
-
- if (rd_mask.is_set (read_handle))
- {
- number_of_active_handles--;
- return this->handle_input (read_handle);
- }
- else
- return 0;
-}
-
-// Special trick to unblock select() when updates occur in somewhere
-// other than the main ACE_Reactor thread. All we do is write data to
-// a pipe that the ACE_Reactor is listening on. Thanks to Paul
-// Stephenson for suggesting this approach.
-
-int
-ACE_Reactor_Notify::handle_input (ACE_HANDLE handle)
-{
- ACE_TRACE ("ACE_Reactor_Notify::handle_input");
- // Precondition: this->reactor_.token_.current_owner () ==
- // ACE_Thread::self ();
-
- ACE_Notification_Buffer buffer;
- ssize_t n;
- int number_dispatched = 0;
-
- while ((n = ACE::recv (handle, (char *) &buffer, sizeof buffer)) > 0)
- {
- // Check to see if we've got a short read.
- if (n != sizeof buffer)
- {
- ssize_t remainder = sizeof buffer - n;
-
- // If so, try to recover by reading the remainder. If this doesn't
- // work we're in big trouble since the input stream won't be aligned
- // correctly. I'm not sure quite what to do at this point. It's
- // probably best just to return -1.
- if (ACE::recv (handle, ((char *) &buffer) + n, remainder) != remainder)
- return -1;
- }
-
- // If eh == 0 then another thread is unblocking the ACE_Reactor
- // to update the ACE_Reactor's internal structures. Otherwise,
- // we need to dispatch the appropriate handle_* method on the
- // ACE_Event_Handler pointer we've been passed.
- if (buffer.eh_ != 0)
- {
- int result = 0;
-
- switch (buffer.mask_)
- {
- case ACE_Event_Handler::READ_MASK:
- case ACE_Event_Handler::ACCEPT_MASK:
- result = buffer.eh_->handle_input (ACE_INVALID_HANDLE);
- break;
- case ACE_Event_Handler::WRITE_MASK:
- result = buffer.eh_->handle_output (ACE_INVALID_HANDLE);
- break;
- case ACE_Event_Handler::EXCEPT_MASK:
- result = buffer.eh_->handle_exception (ACE_INVALID_HANDLE);
- break;
- default:
- // Should we bail out if we get an invalid mask?
- ACE_ERROR ((LM_ERROR, "invalid mask = %d\n", buffer.mask_));
- }
- if (result == -1)
- buffer.eh_->handle_close (ACE_INVALID_HANDLE,
- ACE_Event_Handler::EXCEPT_MASK);
- }
-
- number_dispatched++;
-
- // Bail out if we've reached the <notify_threshold_>. Note that
- // by default <notify_threshold_> is -1, so we'll loop until all
- // the notifications in the pipe have been dispatched.
- if (number_dispatched == this->reactor_->max_notify_iterations_)
- break;
- }
-
- // Reassign number_dispatched to -1 if things have gone seriously
- // wrong.
- if (n <= 0 && errno != EWOULDBLOCK)
- number_dispatched = -1;
-
- // Enqueue ourselves into the list of waiting threads. When we
- // reacquire the token we'll be off and running again with ownership
- // of the token. The postcondition of this call is that
- // this->reactor_.token_.current_owner () == ACE_Thread::self ();
- this->reactor_->renew ();
- return number_dispatched;
-}
-
-int
-ACE_Reactor::notify (ACE_Event_Handler *eh,
- ACE_Reactor_Mask mask,
- ACE_Time_Value *timeout)
-{
- ACE_TRACE ("ACE_Reactor::notify");
-
- ssize_t n = 0;
-
- // Pass over both the Event_Handler *and* the mask to allow the
- // caller to dictate which Event_Handler method the receiver
- // invokes. Note that this call can timeout.
-
- n = this->notify_handler_.notify (eh, mask, timeout);
- return n == -1 ? -1 : 0;
-}
-
-int
-ACE_Reactor::resume_handler (ACE_HANDLE handle)
-{
- ACE_TRACE ("ACE_Reactor::resume_handler");
- ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1));
- return this->resume_i (handle);
-}
-
-int
-ACE_Reactor::suspend_handler (ACE_HANDLE handle)
-{
- ACE_TRACE ("ACE_Reactor::suspend_handler");
- ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1));
- return this->suspend_i (handle);
-}
-
-int
-ACE_Reactor::suspend_handlers (void)
-{
- ACE_TRACE ("ACE_Reactor::suspend_handlers");
- ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1));
-
- ACE_Event_Handler *eh = 0;
-
- for (ACE_Reactor_Handler_Repository_Iterator iter (&this->handler_rep_);
- iter.next (eh) != 0;
- iter.advance ())
- this->suspend_i (eh->get_handle ());
-
- return 0;
-}
-
-int
-ACE_Reactor::resume_handlers (void)
-{
- ACE_TRACE ("ACE_Reactor::resume_handlers");
- ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1));
-
- ACE_Event_Handler *eh = 0;
-
- for (ACE_Reactor_Handler_Repository_Iterator iter (&this->handler_rep_);
- iter.next (eh) != 0;
- iter.advance ())
- this->resume_i (eh->get_handle ());
-
- return 0;
-}
-
-int
-ACE_Reactor::register_handler (ACE_Event_Handler *handler,
- ACE_Reactor_Mask mask)
-{
- ACE_TRACE ("ACE_Reactor::register_handler");
- ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1));
- return this->register_handler_i (handler->get_handle (), handler, mask);
-}
-
-int
-ACE_Reactor::register_handler (ACE_HANDLE handle,
- ACE_Event_Handler *handler,
- ACE_Reactor_Mask mask)
-{
- ACE_TRACE ("ACE_Reactor::register_handler");
- ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1));
- return this->register_handler_i (handle, handler, mask);
-}
-
-int
-ACE_Reactor::register_handler (const ACE_Handle_Set &handles,
- ACE_Event_Handler *handler,
- ACE_Reactor_Mask mask)
-{
- ACE_TRACE ("ACE_Reactor::register_handler");
- ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1));
- return this->register_handler_i (handles, handler, mask);
-}
-
-int
-ACE_Reactor::handler (ACE_HANDLE handle,
- ACE_Reactor_Mask mask,
- ACE_Event_Handler **handler)
-{
- ACE_TRACE ("ACE_Reactor::handler");
- ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1));
- return this->handler_i (handle, mask, handler);
-}
-
-int
-ACE_Reactor::remove_handler (const ACE_Handle_Set &handles,
- ACE_Reactor_Mask mask)
-{
- ACE_TRACE ("ACE_Reactor::remove_handler");
- ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1));
- return this->remove_handler_i (handles, mask);
-}
-
-int
-ACE_Reactor::remove_handler (ACE_Event_Handler *handler,
- ACE_Reactor_Mask mask)
-{
- ACE_TRACE ("ACE_Reactor::remove_handler");
- ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1));
- return this->remove_handler_i (handler->get_handle (), mask);
-}
-
-int
-ACE_Reactor::remove_handler (ACE_HANDLE handle,
- ACE_Reactor_Mask mask)
-{
- ACE_TRACE ("ACE_Reactor::remove_handler");
- ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1));
- return this->remove_handler_i (handle, mask);
-}
-
-// Performs operations on the "ready" bits.
-
-int
-ACE_Reactor::ready_ops (ACE_HANDLE handle,
- ACE_Reactor_Mask mask,
- int ops)
-{
- ACE_TRACE ("ACE_Reactor::ready_ops");
- ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1));
- return this->bit_ops (handle,
- mask,
- this->ready_set_,
- ops);
-}
-
ACE_Reactor *
-ACE_Reactor::instance (size_t size /* = ACE_Reactor::DEFAULT_SIZE */)
+ACE_Reactor::instance (void)
{
ACE_TRACE ("ACE_Reactor::instance");
@@ -910,10 +57,10 @@ ACE_Reactor::instance (size_t size /* = ACE_Reactor::DEFAULT_SIZE */)
// Perform Double-Checked Locking Optimization.
ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
*ACE_Static_Object_Lock::instance (), 0));
-
+
if (ACE_Reactor::reactor_ == 0)
{
- ACE_NEW_RETURN (ACE_Reactor::reactor_, ACE_Reactor (size), NULL);
+ ACE_NEW_RETURN (ACE_Reactor::reactor_, ACE_Reactor, NULL);
ACE_Reactor::delete_reactor_ = 1;
}
}
@@ -997,7 +144,6 @@ ACE_Reactor::run_event_loop (ACE_Time_Value &tv)
return 0;
}
-/* static */
int
ACE_Reactor::end_event_loop (void)
{
@@ -1010,7 +156,6 @@ ACE_Reactor::end_event_loop (void)
(0, ACE_Event_Handler::NULL_MASK, (ACE_Time_Value *) &ACE_Time_Value::zero);
}
-/* static */
sig_atomic_t
ACE_Reactor::event_loop_done (void)
{
@@ -1018,905 +163,3 @@ ACE_Reactor::event_loop_done (void)
return ACE_Reactor::end_event_loop_;
}
-// Initialize the ACE_Reactor
-
-int
-ACE_Reactor::open (size_t size,
- int restart,
- ACE_Sig_Handler *sh,
- ACE_Timer_Queue *tq)
-{
- ACE_TRACE ("ACE_Reactor::open");
- ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1));
-
- // Can't initialize ourselves more than once.
- if (this->initialized_ > 0)
- return -1;
-
- this->owner_ = ACE_Thread::self ();
- this->restart_ = restart;
- this->signal_handler_ = sh;
- this->timer_queue_ = tq;
-
- int result = 0;
-
- // Allows the signal handler to be overridden.
- if (this->signal_handler_ == 0)
- {
- this->signal_handler_ = new ACE_Sig_Handler;
-
- if (this->signal_handler_ == 0)
- result = -1;
- else
- this->delete_signal_handler_ = 1;
- }
-
- if (result != -1 && this->timer_queue_ == 0)
- {
- this->timer_queue_ = new ACE_Timer_Heap;
-
- if (this->timer_queue_ == 0)
- result = -1;
- else
- this->delete_timer_queue_ = 1;
- }
-
- if (result != -1 && this->handler_rep_.open (size) == -1)
- result = -1;
- else if (this->notify_handler_.open (this) == -1)
- result = -1;
-
- if (result != -1)
- // We're all set to go.
- this->initialized_ = 1;
- else
- // This will close down all the allocated resources properly.
- this->close ();
-
- return result;
-}
-
-ACE_Reactor::ACE_Reactor (ACE_Sig_Handler *sh,
- ACE_Timer_Queue *tq)
- : handler_rep_ (*this),
- timer_queue_ (0),
- delete_timer_queue_ (0),
- delete_signal_handler_ (0),
- requeue_position_ (-1), // Requeue at end of waiters by default.
- max_notify_iterations_ (-1),
- initialized_ (0),
- state_changed_ (0)
-#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
- , token_ (*this)
-#endif /* ACE_MT_SAFE */
-{
- ACE_TRACE ("ACE_Reactor::ACE_Reactor");
-
- if (this->open (ACE_Reactor::DEFAULT_SIZE, 0, sh, tq) == -1)
- ACE_ERROR ((LM_ERROR, "%p\n", "open failed"));
-}
-
-// Initialize ACE_Reactor.
-
-ACE_Reactor::ACE_Reactor (size_t size,
- int rs,
- ACE_Sig_Handler *sh,
- ACE_Timer_Queue *tq)
- : handler_rep_ (*this),
- timer_queue_ (0),
- delete_timer_queue_ (0),
- delete_signal_handler_ (0),
- requeue_position_ (-1), // Requeue at end of waiters by default.
- max_notify_iterations_ (-1),
- initialized_ (0),
- state_changed_ (0)
-#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
- , token_ (*this)
-#endif /* ACE_MT_SAFE */
-{
- ACE_TRACE ("ACE_Reactor::ACE_Reactor");
-
- if (this->open (size, rs, sh, tq) == -1)
- ACE_ERROR ((LM_ERROR, "%p\n", "open failed"));
-}
-
-// Close down the ACE_Reactor instance, detaching any remaining
-// Event_Handers. This had better be called from the main event loop
-// thread...
-
-void
-ACE_Reactor::close (void)
-{
- ACE_TRACE ("ACE_Reactor::close");
- ACE_MT (ACE_GUARD (ACE_REACTOR_MUTEX, ace_mon, this->token_));
-
- if (this->delete_signal_handler_)
- delete this->signal_handler_;
- this->signal_handler_ = 0;
-
- this->handler_rep_.close ();
-
- if (this->delete_timer_queue_)
- delete this->timer_queue_;
- this->timer_queue_ = 0;
-
- this->notify_handler_.close ();
- this->initialized_ = 0;
-}
-
-ACE_Reactor::~ACE_Reactor (void)
-{
- ACE_TRACE ("ACE_Reactor::~ACE_Reactor");
- this->close ();
-}
-
-int
-ACE_Reactor::remove_handler_i (const ACE_Handle_Set &handles,
- ACE_Reactor_Mask mask)
-{
- ACE_TRACE ("ACE_Reactor::remove_handler_i");
- ACE_HANDLE h;
-
- ACE_Handle_Set_Iterator handle_iter (handles);
-
- while ((h = handle_iter ()) != ACE_INVALID_HANDLE)
- if (this->remove_handler_i (h, mask) == -1)
- return -1;
-
- return 0;
-}
-
-int
-ACE_Reactor::register_handler_i (const ACE_Handle_Set &handles,
- ACE_Event_Handler *handler,
- ACE_Reactor_Mask mask)
-{
- ACE_TRACE ("ACE_Reactor::register_handler_i");
- ACE_HANDLE h;
-
- ACE_Handle_Set_Iterator handle_iter (handles);
- while ((h = handle_iter ()) != ACE_INVALID_HANDLE)
- if (this->register_handler_i (h, handler, mask) == -1)
- return -1;
-
- return 0;
-}
-
-int
-ACE_Reactor::register_handler (const ACE_Sig_Set &sigset,
- ACE_Event_Handler *new_sh,
- ACE_Sig_Action *new_disp)
-{
- ACE_TRACE ("ACE_Reactor::register_handler");
-
- int result = 0;
-
-#if (NSIG > 0)
-
- for (int s = 1; s < NSIG; s++)
- if (sigset.is_member (s)
- && this->signal_handler_->register_handler (s, new_sh,
- new_disp) == -1)
- result = -1;
-#endif /* NSIG */
- return result;
-}
-
-int
-ACE_Reactor::remove_handler (const ACE_Sig_Set &sigset)
-{
- ACE_TRACE ("ACE_Reactor::remove_handler");
- int result = 0;
-
-#if (NSIG > 0)
- for (int s = 1; s < NSIG; s++)
- if (sigset.is_member (s)
- && this->signal_handler_->remove_handler (s) == -1)
- result = -1;
-#else
- ACE_UNUSED_ARG (sigset);
-#endif /* NSIG */
-
- return result;
-}
-
-// Note the queue handles its own locking.
-
-long
-ACE_Reactor::schedule_timer (ACE_Event_Handler *handler,
- const void *arg,
- const ACE_Time_Value &delta_time,
- const ACE_Time_Value &interval)
-{
- ACE_TRACE ("ACE_Reactor::schedule_timer");
- ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1));
-
- return this->timer_queue_->schedule
- (handler, arg, timer_queue_->gettimeofday () + delta_time, interval);
-}
-
-// Main event loop driver that blocks for <max_wait_time> before
-// returning (will return earlier if I/O or signal events occur).
-
-int
-ACE_Reactor::handle_events (ACE_Time_Value &max_wait_time)
-{
- ACE_TRACE ("ACE_Reactor::handle_events");
-
- return this->handle_events (&max_wait_time);
-}
-
-int
-ACE_Reactor::handle_error (void)
-{
- ACE_TRACE ("ACE_Reactor::handle_error");
- if (errno == EINTR)
- return this->restart_;
- else if (errno == EBADF)
- return this->check_handles ();
- else
- return -1;
-}
-
-void
-ACE_Reactor::notify_handle (ACE_HANDLE handle,
- ACE_Reactor_Mask mask,
- ACE_Handle_Set &ready_mask,
- ACE_Event_Handler *event_handler,
- ACE_EH_PTMF ptmf)
-{
- ACE_TRACE ("ACE_Reactor::notify_handle");
- // Check for removed handlers.
- if (event_handler == 0)
- return;
-
- int status = (event_handler->*ptmf) (handle);
-
- if (status < 0)
- this->remove_handler_i (handle, mask);
- else if (status > 0)
- ready_mask.set_bit (handle);
-}
-
-// Perform GET, CLR, SET, and ADD operations on the Handle_Sets.
-//
-// GET = 1, Retrieve current value
-// SET = 2, Set value of bits to new mask (changes the entire mask)
-// ADD = 3, Bitwise "or" the value into the mask (only changes
-// enabled bits)
-// CLR = 4 Bitwise "and" the negation of the value out of the mask
-// (only changes enabled bits)
-//
-// Returns the original mask. Must be called with locks held.
-
-int
-ACE_Reactor::bit_ops (ACE_HANDLE handle,
- ACE_Reactor_Mask mask,
- ACE_Reactor_Handle_Set &handle_set,
- int ops)
-{
- ACE_TRACE ("ACE_Reactor::bit_ops");
- if (this->handler_rep_.handle_in_range (handle) == 0)
- return -1;
-
-#if !defined (ACE_WIN32)
- ACE_Sig_Guard sb; // Block out all signals until method returns.
-#endif /* ACE_WIN32 */
-
- ACE_FDS_PTMF ptmf = &ACE_Handle_Set::set_bit;
- u_long omask = ACE_Event_Handler::NULL_MASK;
-
- switch (ops)
- {
- case ACE_Reactor::GET_MASK:
- if (handle_set.rd_mask_.is_set (handle))
- ACE_SET_BITS (omask, ACE_Event_Handler::READ_MASK);
- if (handle_set.wr_mask_.is_set (handle))
- ACE_SET_BITS (omask, ACE_Event_Handler::WRITE_MASK);
- if (handle_set.ex_mask_.is_set (handle))
- ACE_SET_BITS (omask, ACE_Event_Handler::EXCEPT_MASK);
- break;
-
- case ACE_Reactor::CLR_MASK:
- ptmf = &ACE_Handle_Set::clr_bit;
- /* FALLTHRU */
- case ACE_Reactor::SET_MASK:
- /* FALLTHRU */
- case ACE_Reactor::ADD_MASK:
-
- // The following code is rather subtle... Note that if we are
- // doing a ACE_Reactor::SET_MASK then if the bit is not enabled
- // in the mask we need to clear the bit from the ACE_Handle_Set.
- // On the other hand, if we are doing a ACE_Reactor::CLR_MASK or
- // a ACE_Reactor::ADD_MASK we just carry out the operations
- // specified by the mask.
-
- if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::READ_MASK)
- || ACE_BIT_ENABLED (mask, ACE_Event_Handler::ACCEPT_MASK))
- {
- (handle_set.rd_mask_.*ptmf) (handle);
- ACE_SET_BITS (omask, ACE_Event_Handler::READ_MASK);
- }
- else if (ops == ACE_Reactor::SET_MASK)
- handle_set.rd_mask_.clr_bit (handle);
-
- if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::WRITE_MASK))
- {
- (handle_set.wr_mask_.*ptmf) (handle);
- ACE_SET_BITS (omask, ACE_Event_Handler::WRITE_MASK);
- }
- else if (ops == ACE_Reactor::SET_MASK)
- handle_set.wr_mask_.clr_bit (handle);
-
- if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::EXCEPT_MASK))
- {
- (handle_set.ex_mask_.*ptmf) (handle);
- ACE_SET_BITS (omask, ACE_Event_Handler::EXCEPT_MASK);
- }
- else if (ops == ACE_Reactor::SET_MASK)
- handle_set.ex_mask_.clr_bit (handle);
- break;
- default:
- return -1;
- }
- return omask;
-}
-
-// Perform GET, CLR, SET, and ADD operations on the select()
-// Handle_Sets.
-//
-// GET = 1, Retrieve current value
-// SET = 2, Set value of bits to new mask (changes the entire mask)
-// ADD = 3, Bitwise "or" the value into the mask (only changes
-// enabled bits)
-// CLR = 4 Bitwise "and" the negation of the value out of the mask
-// (only changes enabled bits)
-//
-// Returns the original mask.
-
-int
-ACE_Reactor::mask_ops (ACE_HANDLE handle,
- ACE_Reactor_Mask mask,
- int ops)
-{
- ACE_TRACE ("ACE_Reactor::mask_ops");
- ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1));
- return this->bit_ops (handle, mask,
- this->wait_set_,
- ops);
-}
-
-// Must be called with locks held.
-
-int
-ACE_Reactor::handler_i (ACE_HANDLE handle,
- ACE_Reactor_Mask mask,
- ACE_Event_Handler **handler)
-{
- ACE_TRACE ("ACE_Reactor::handler_i");
- ACE_Event_Handler *h = this->handler_rep_.find (handle);
-
- if (h == 0)
- return -1;
- else
- {
- if ((ACE_BIT_ENABLED (mask, ACE_Event_Handler::READ_MASK)
- || ACE_BIT_ENABLED (mask, ACE_Event_Handler::ACCEPT_MASK))
- && this->wait_set_.rd_mask_.is_set (handle) == 0)
- return -1;
- if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::WRITE_MASK)
- && this->wait_set_.wr_mask_.is_set (handle) == 0)
- return -1;
- if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::EXCEPT_MASK)
- && this->wait_set_.ex_mask_.is_set (handle) == 0)
- return -1;
- }
-
- if (handler != 0)
- *handler = h;
- return 0;
-}
-
-// Must be called with locks held
-
-int
-ACE_Reactor::resume_i (ACE_HANDLE handle)
-{
- ACE_TRACE ("ACE_Reactor::resume");
- if (this->handler_rep_.find (handle) == 0)
- return -1;
-
- if (this->suspend_set_.rd_mask_.is_set (handle))
- {
- this->wait_set_.rd_mask_.set_bit (handle);
- this->suspend_set_.rd_mask_.clr_bit(handle);
- }
- if (this->suspend_set_.wr_mask_.is_set (handle))
- {
- this->wait_set_.wr_mask_.set_bit (handle);
- this->suspend_set_.wr_mask_.clr_bit(handle);
- }
- if (this->suspend_set_.ex_mask_.is_set (handle))
- {
- this->wait_set_.ex_mask_.set_bit (handle);
- this->suspend_set_.ex_mask_.clr_bit(handle);
- }
- return 0;
-}
-
-// Must be called with locks held
-
-int
-ACE_Reactor::suspend_i (ACE_HANDLE handle)
-{
- ACE_TRACE ("ACE_Reactor::suspend");
- if (this->handler_rep_.find (handle) == 0)
- return -1;
-
- if (this->wait_set_.rd_mask_.is_set (handle))
- {
- this->suspend_set_.rd_mask_.set_bit (handle);
- this->wait_set_.wr_mask_.clr_bit(handle);
- }
- if (this->wait_set_.wr_mask_.is_set (handle))
- {
- this->suspend_set_.wr_mask_.set_bit (handle);
- this->wait_set_.wr_mask_.clr_bit(handle);
- }
- if (this->wait_set_.ex_mask_.is_set (handle))
- {
- this->suspend_set_.ex_mask_.set_bit (handle);
- this->wait_set_.ex_mask_.clr_bit(handle);
- }
- return 0;
-}
-
-// Must be called with locks held
-
-int
-ACE_Reactor::register_handler_i (ACE_HANDLE handle,
- ACE_Event_Handler *event_handler,
- ACE_Reactor_Mask mask)
-{
- ACE_TRACE ("ACE_Reactor::register_handler_i");
-
- // Insert the <handle, event_handle> tuple into the Handler
- // Repository.
- return this->handler_rep_.bind (handle, event_handler, mask);
-}
-
-int
-ACE_Reactor::remove_handler_i (ACE_HANDLE handle,
- ACE_Reactor_Mask mask)
-{
- ACE_TRACE ("ACE_Reactor::remove_handler_i");
-
- // Unbind this handle.
- return this->handler_rep_.unbind (handle, mask);
-}
-
-// Must be called with lock held.
-
-int
-ACE_Reactor::wait_for_multiple_events (ACE_Reactor_Handle_Set &dispatch_set,
- ACE_Time_Value *max_wait_time)
-{
- ACE_TRACE ("ACE_Reactor::wait_for_multiple_events");
- u_long width = 0;
- ACE_Time_Value timer_buf (0);
- ACE_Time_Value *this_timeout = &timer_buf;
-
- int number_of_active_handles = this->any_ready (dispatch_set);
-
- // If there are any bits enabled in the <ready_set_> then we'll
- // handle those first, otherwise we'll block in select().
-
- if (number_of_active_handles == 0)
- {
- do
- {
- if (this->timer_queue_->calculate_timeout (max_wait_time,
- this_timeout) == 0)
- this_timeout = 0;
-
- width = (u_long) this->handler_rep_.max_handlep1 ();
-
- dispatch_set.rd_mask_ = this->wait_set_.rd_mask_;
- dispatch_set.wr_mask_ = this->wait_set_.wr_mask_;
- dispatch_set.ex_mask_ = this->wait_set_.ex_mask_;
-
- number_of_active_handles = ACE_OS::select (int (width),
- dispatch_set.rd_mask_,
- dispatch_set.wr_mask_,
- dispatch_set.ex_mask_,
- this_timeout);
- }
- while (number_of_active_handles == -1 && this->handle_error () > 0);
-
- // @@ Remove?!
- if (number_of_active_handles > 0)
- {
-#if !defined (ACE_WIN32)
- dispatch_set.rd_mask_.sync (this->handler_rep_.max_handlep1 ());
- dispatch_set.wr_mask_.sync (this->handler_rep_.max_handlep1 ());
- dispatch_set.ex_mask_.sync (this->handler_rep_.max_handlep1 ());
-#endif /* ACE_WIN32 */
- }
-
- }
-
- // Return the number of events to dispatch.
- return number_of_active_handles;
-}
-
-int
-ACE_Reactor::dispatch_timer_handlers (void)
-{
- int number_dispatched = this->timer_queue_->expire ();
- return this->state_changed_ ? -1 : number_dispatched;
-}
-
-int
-ACE_Reactor::dispatch_notification_handlers (int &number_of_active_handles,
- ACE_Reactor_Handle_Set &dispatch_set)
-{
-#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
- // Check to see if the ACE_HANDLE associated with the Reactor's
- // notify hook is enabled. If so, it means that one or more
- // other threads are trying to update the ACE_Reactor's internal
- // tables. We'll handle all these threads and then break out to
- // continue the event loop.
-
- int number_dispatched =
- this->notify_handler_.dispatch_notifications (number_of_active_handles,
- dispatch_set.rd_mask_);
- return this->state_changed_ ? -1 : number_dispatched;
-#else
- ACE_UNUSED_ARG (number_of_active_handles);
- ACE_UNUSED_ARG (dispatch_set);
- return 0;
-#endif /* ACE_MT_SAFE */
-}
-
-int
-ACE_Reactor::dispatch_io_handlers (int &number_of_active_handles,
- ACE_Reactor_Handle_Set &dispatch_set)
-{
- int number_dispatched = 0;
-
- if (number_of_active_handles > 0)
- {
- ACE_HANDLE handle;
-
- // Handle output events (this code needs to come first to handle
- // the obscure case of piggy-backed data coming along with the
- // final handshake message of a nonblocking connection).
-
- ACE_Handle_Set_Iterator handle_iter_wr (dispatch_set.wr_mask_);
-
- while ((handle = handle_iter_wr ()) != ACE_INVALID_HANDLE
- && number_dispatched < number_of_active_handles
- && this->state_changed_ == 0)
- {
- number_dispatched++;
- this->notify_handle (handle,
- ACE_Event_Handler::WRITE_MASK,
- this->ready_set_.wr_mask_,
- this->handler_rep_.find (handle),
- &ACE_Event_Handler::handle_output);
- }
- }
-
- if (number_dispatched > 0)
- {
- number_of_active_handles -= number_dispatched;
- if (this->state_changed_)
- return -1;
- }
-
- number_dispatched = 0;
-
- if (number_of_active_handles > 0)
- {
- ACE_HANDLE handle;
-
- // Handle "exceptional" events.
-
- ACE_Handle_Set_Iterator handle_iter_ex (dispatch_set.ex_mask_);
-
- while ((handle = handle_iter_ex ()) != ACE_INVALID_HANDLE
- && number_dispatched < number_of_active_handles
- && this->state_changed_ == 0)
- {
- this->notify_handle (handle,
- ACE_Event_Handler::EXCEPT_MASK,
- this->ready_set_.ex_mask_,
- this->handler_rep_.find (handle),
- &ACE_Event_Handler::handle_exception);
- number_dispatched++;
- }
- }
-
- if (number_dispatched > 0)
- {
- number_of_active_handles -= number_dispatched;
- if (this->state_changed_)
- return -1;
- }
-
- number_dispatched = 0;
-
- if (number_of_active_handles > 0)
- {
- ACE_HANDLE handle;
-
- // Handle input, passive connection, and shutdown events.
-
- ACE_Handle_Set_Iterator handle_iter_rd (dispatch_set.rd_mask_);
-
- while ((handle = handle_iter_rd ()) != ACE_INVALID_HANDLE
- && number_dispatched < number_of_active_handles
- && this->state_changed_ == 0)
- {
- this->notify_handle (handle,
- ACE_Event_Handler::READ_MASK,
- this->ready_set_.rd_mask_,
- this->handler_rep_.find (handle),
- &ACE_Event_Handler::handle_input);
- number_dispatched++;
- }
- }
-
- if (number_dispatched > 0)
- {
- number_of_active_handles -= number_dispatched;
-
- if (this->state_changed_)
- return -1;
- }
-
- return number_dispatched;
-}
-
-int
-ACE_Reactor::dispatch (int number_of_active_handles,
- ACE_Reactor_Handle_Set &dispatch_set)
-{
- ACE_TRACE ("ACE_Reactor::dispatch");
-
- // The following do/while loop keeps dispatching as long as there
- // are still active handles. Note that the only way we should ever
- // iterate more than once through this loop is if signals occur
- // while we're dispatching other handlers.
-
- do
- {
- // Note that we keep track of changes to our state. If any of
- // the dispatch_*() methods below return -1 it means that the
- // <wait_set_> state has changed as the result of an
- // <ACE_Event_Handler> being dispatched. This means that we
- // need to bail out and rerun the select() loop since our
- // existing notion of handles in <dispatch_set> may no longer be
- // correct.
- //
- // In the beginning, our state starts out unchanged. After
- // every iteration (i.e., due to signals), our state starts out
- // unchanged again.
-
- this->state_changed_ = 0;
-
- // Perform the Template Method for dispatching all the handlers.
-
- // Handle timers first since they may have higher latency
- // constraints.
-
- if (this->dispatch_timer_handlers () == -1)
- // State has changed or timer queue has failed, exit inner
- // loop.
- break;
- else if (number_of_active_handles <= 0)
- // Bail out since we got here since select() was interrupted.
- {
- if (ACE_Sig_Handler::sig_pending () != 0)
- {
- ACE_Sig_Handler::sig_pending (0);
-
- // If any HANDLES in the <ready_set_> are activated as a
- // result of signals they should be dispatched since
- // they may be time critical...
- number_of_active_handles = this->any_ready (dispatch_set);
- }
- else
- return number_of_active_handles;
- }
- else if (this->dispatch_notification_handlers
- (number_of_active_handles, dispatch_set) == -1)
- break; // State has changed, exit inner loop.
- else if (this->dispatch_io_handlers
- (number_of_active_handles, dispatch_set) == -1)
- // State has changed, so exit the inner loop.
- break;
-
- }
- while (number_of_active_handles > 0);
-
- return 1;
-}
-
-int
-ACE_Reactor::release_token (void)
-{
-#if defined (ACE_WIN32)
- this->token_.release ();
- return (int) EXCEPTION_CONTINUE_SEARCH;
-#else
- return 0;
-#endif /* ACE_WIN32 */
-}
-
-int
-ACE_Reactor::handle_events (ACE_Time_Value *max_wait_time)
-{
- ACE_TRACE ("ACE_Reactor::handle_events");
-
- // Stash the current time -- the destructor of this object will
- // automatically compute how much time elpased since this method was
- // called.
- ACE_Countdown_Time countdown (max_wait_time);
-
-#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
- ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1);
-
- if (ACE_OS::thr_equal (ACE_Thread::self (), this->owner_) == 0)
- return -1;
-
- // Update the countdown to reflect time waiting for the mutex.
- countdown.update ();
-#endif /* ACE_MT_SAFE */
-
- return this->handle_events_i (max_wait_time);
-}
-
-int
-ACE_Reactor::handle_events_i (ACE_Time_Value *max_wait_time)
-{
- int result = -1;
-
- ACE_SEH_TRY {
- ACE_Reactor_Handle_Set dispatch_set;
-
- int number_of_active_handles =
- this->wait_for_multiple_events (dispatch_set,
- max_wait_time);
-
- result = this->dispatch (number_of_active_handles, dispatch_set);
- }
- ACE_SEH_EXCEPT (this->release_token ()) {
- // As it stands now, we catch and then rethrow all Win32
- // structured exceptions so that we can make sure to release the
- // <token_> lock correctly.
- }
-
- return result;
-}
-
-int
-ACE_Reactor::check_handles (void)
-{
- ACE_TRACE ("ACE_Reactor::check_handles");
-
-#if defined (ACE_WIN32)
- ACE_Time_Value time_poll = ACE_Time_Value::zero;
- ACE_Handle_Set rd_mask;
-#endif /* ACE_WIN32 */
-
- ACE_Event_Handler *eh = 0;
- int result = 0;
-
- for (ACE_Reactor_Handler_Repository_Iterator iter (&this->handler_rep_);
- iter.next (eh) != 0;
- iter.advance ())
- {
- ACE_HANDLE handle = eh->get_handle ();
-
- // Skip back to the beginning of the loop if the HANDLE is
- // invalid.
- if (handle == ACE_INVALID_HANDLE)
- continue;
-
-#if defined (ACE_WIN32)
- rd_mask.set_bit (handle);
-
- if (ACE_OS::select (int (handle) + 1,
- rd_mask, 0, 0,
- &time_poll) < 0)
- {
- result = 1;
- this->remove_handler_i (handle,
- ACE_Event_Handler::ALL_EVENTS_MASK);
- }
- rd_mask.clr_bit (handle);
-#else /* !ACE_WIN32 */
- struct stat temp;
-
- if (ACE_OS::fstat (handle, &temp) == -1)
- {
- result = 1;
- this->remove_handler_i (handle,
- ACE_Event_Handler::ALL_EVENTS_MASK);
- }
-#endif /* ACE_WIN32 */
- }
-
- return result;
-}
-
-void
-ACE_Reactor::dump (void) const
-{
- ACE_TRACE ("ACE_Reactor::dump");
-
- ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
-
- this->timer_queue_->dump ();
- this->handler_rep_.dump ();
- this->signal_handler_->dump ();
- ACE_DEBUG ((LM_DEBUG,
- "delete_signal_handler_ = %d\n",
- this->delete_signal_handler_));
-
- ACE_HANDLE h;
-
- for (ACE_Handle_Set_Iterator handle_iter_wr (this->wait_set_.wr_mask_);
- (h = handle_iter_wr ()) != ACE_INVALID_HANDLE;
- ++handle_iter_wr)
- ACE_DEBUG ((LM_DEBUG, "write_handle = %d\n", h));
-
- for (ACE_Handle_Set_Iterator handle_iter_rd (this->wait_set_.rd_mask_);
- (h = handle_iter_rd ()) != ACE_INVALID_HANDLE;
- ++handle_iter_rd)
- ACE_DEBUG ((LM_DEBUG, "read_handle = %d\n", h));
-
- for (ACE_Handle_Set_Iterator handle_iter_ex (this->wait_set_.ex_mask_);
- (h = handle_iter_ex ()) != ACE_INVALID_HANDLE;
- ++handle_iter_ex)
- ACE_DEBUG ((LM_DEBUG, "except_handle = %d\n", h));
-
- for (ACE_Handle_Set_Iterator handle_iter_wr_ready (this->ready_set_.wr_mask_);
- (h = handle_iter_wr_ready ()) != ACE_INVALID_HANDLE;
- ++handle_iter_wr_ready)
- ACE_DEBUG ((LM_DEBUG, "write_handle_ready = %d\n", h));
-
- for (ACE_Handle_Set_Iterator handle_iter_rd_ready (this->ready_set_.rd_mask_);
- (h = handle_iter_rd_ready ()) != ACE_INVALID_HANDLE;
- ++handle_iter_rd_ready)
- ACE_DEBUG ((LM_DEBUG, "read_handle_ready = %d\n", h));
-
- for (ACE_Handle_Set_Iterator handle_iter_ex_ready (this->ready_set_.ex_mask_);
- (h = handle_iter_ex_ready ()) != ACE_INVALID_HANDLE;
- ++handle_iter_ex_ready)
- ACE_DEBUG ((LM_DEBUG, "except_handle_ready = %d\n", h));
-
- ACE_DEBUG ((LM_DEBUG, "restart_ = %d\n", this->restart_));
- ACE_DEBUG ((LM_DEBUG, "\nrequeue_position_ = %d\n", this->requeue_position_));
- ACE_DEBUG ((LM_DEBUG, "\ninitialized_ = %d\n", this->initialized_));
- ACE_DEBUG ((LM_DEBUG, "\nowner_ = %d\n", this->owner_));
-
-#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
- this->notify_handler_.dump ();
- this->token_.dump ();
-#endif /* ACE_MT_SAFE */
-
- ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
-}
-
-#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
-ACE_MT (template class ACE_Guard<ACE_REACTOR_MUTEX>);
-template class ACE_Event_Handler_Handle_Timeout_Upcall<ACE_SYNCH_RECURSIVE_MUTEX>;
-#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
-#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
-#pragma instantiate ACE_Guard<ACE_REACTOR_MUTEX>
-#endif /* ACE_MT_SAFE */
-#pragma instantiate ACE_Event_Handler_Handle_Timeout_Upcall<ACE_SYNCH_RECURSIVE_MUTEX>
-#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
-
diff --git a/ace/Reactor.h b/ace/Reactor.h
index a4d976d14dd..93d2996e4c0 100644
--- a/ace/Reactor.h
+++ b/ace/Reactor.h
@@ -1,4 +1,5 @@
/* -*- C++ -*- */
+
// $Id$
// ============================================================================
@@ -10,292 +11,38 @@
// Reactor.h
//
// = AUTHOR
-// Doug Schmidt
+// Irfan Pyarali
//
// ============================================================================
#if !defined (ACE_REACTOR_H)
#define ACE_REACTOR_H
-#include "ace/Handle_Set.h"
-#include "ace/Timer_Queue.h"
-#include "ace/Signal.h"
-#include "ace/Thread.h"
-#include "ace/Token.h"
-#include "ace/Pipe.h"
-#include "ace/SOCK_Stream.h"
-
-// Add useful typedefs to simplify the following code.
-typedef void (ACE_Handle_Set::*ACE_FDS_PTMF) (ACE_HANDLE);
-typedef int (ACE_Event_Handler::*ACE_EH_PTMF) (ACE_HANDLE);
-
-// Forward declaration.
-class ACE_Reactor;
-
-class ACE_Export ACE_Reactor_Handle_Set
- // = TITLE
- // Track handles we are interested for various events.
-{
-public:
- ACE_Handle_Set rd_mask_;
- // Read events (e.g., input pending, accept pending).
-
- ACE_Handle_Set wr_mask_;
- // Write events (e.g., flow control abated, non-blocking connection
- // complete).
-
- ACE_Handle_Set ex_mask_;
- // Exception events (e.g., SIG_URG).
-};
-
-#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
-
-#if defined (ACE_REACTOR_HAS_DEADLOCK_DETECTION)
-#include "ace/Local_Tokens.h"
-typedef ACE_Local_Mutex ACE_REACTOR_MUTEX;
-#else
-typedef ACE_Token ACE_REACTOR_MUTEX;
-#endif /* ACE_REACTOR_HAS_DEADLOCK_DETECTION */
-
-class ACE_Export ACE_Reactor_Token : public ACE_REACTOR_MUTEX
- // = TITLE
- // Used as a synchronization mechanism to coordinate concurrent
- // access to a Reactor object.
-{
-public:
- ACE_Reactor_Token (ACE_Reactor &r);
-
- virtual void sleep_hook (void);
- // Called just before the ACE_Event_Handler goes to sleep.
+class ACE_Handle_Set;
+class ACE_Reactor_Impl;
- void dump (void) const;
- // Dump the state of an object.
-
- ACE_ALLOC_HOOK_DECLARE;
- // Declare the dynamic allocation hooks.
+// Timer Queue is a complicated template class. A simple forward
+// declaration will not work
+#include "ace/Timer_Queue.h"
-private:
- ACE_Reactor &reactor_;
-};
-#else
-// If we're non-MT safe then this is just a no-op...
-typedef ACE_Null_Mutex ACE_Reactor_Token;
-#endif /* ACE_MT_SAFE */
+// Event_Handler.h contains the definition of ACE_Reactor_Mask
+#include "ace/Event_Handler.h"
-// The following two classes have to be moved out here to keep the SGI
-// C++ compiler happy (it doesn't like nested classes).
+// We are using 4 or 5 signal classes, we could forward declare
+// them.... But Timer_Queue_T.h includes Signal.h, so I don't think
+// forward declaration will be useful here
+#include "ace/Signal.h"
-class ACE_Export ACE_Reactor_Notify : public ACE_Event_Handler
+class ACE_Export ACE_Reactor
// = TITLE
- // Unblock the <ACE_Reactor> from its event loop.
//
- // = DESCRIPTION
- // This implementation is necessary for cases where the
- // <ACE_Reactor> is run in a multi-threaded program. In this
- // case, we need to be able to unblock select() or poll() when
- // updates occur other than in the main <ACE_Reactor> thread.
- // To do this, we signal an auto-reset event the <ACE_Reactor>
- // is listening on. If an <ACE_Event_Handler> and
- // <ACE_Reactor_Mask> is passed to <notify>, the appropriate
- // <handle_*> method is dispatched in the context of the
- // <ACE_Reactor> thread.
-{
-public:
- // = Initialization and termination methods.
- int open (ACE_Reactor *);
- int close (void);
-
- int dispatch_notifications (int &number_of_active_handles,
- const ACE_Handle_Set &rd_mask);
- // Handles pending threads (if any) that are waiting to unblock the
- // Reactor.
-
- ssize_t notify (ACE_Event_Handler * = 0,
- ACE_Reactor_Mask = ACE_Event_Handler::EXCEPT_MASK,
- ACE_Time_Value * = 0);
- // Called by a thread when it wants to unblock the Reactor. This
- // wakeups the <ACE_Reactor> if currently blocked in
- // select()/poll(). Pass over both the <Event_Handler> *and* the
- // <mask> to allow the caller to dictate which <Event_Handler>
- // method the <Reactor> will invoke. 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 int handle_input (ACE_HANDLE handle);
- // Called back by the Reactor when a thread wants to unblock us.
-
- void dump (void) const;
- // Dump the state of an object.
-
- ACE_ALLOC_HOOK_DECLARE;
- // Declare the dynamic allocation hooks.
-
-private:
- ACE_Reactor *reactor_;
- // Keep a back pointer to the Reactor.
-
- ACE_Pipe notification_pipe_;
- // Contains the HANDLE the Reactor is listening on, as well as the
- // HANDLE that threads wanting the attention of the Reactor will
- // write to.
-};
-
-class ACE_Export ACE_Reactor_Handler_Repository
- // = TITLE
- // Used to map <ACE_HANDLE>s onto the appropriate
- // <ACE_Event_Handler> *.
- //
- // = DESCRIPTION
- // This class is necessary to shield differences between UNIX
- // and Win32. In UNIX, <ACE_HANDLE> is an int, whereas in Win32
- // it's a void *. This class hides all these details from the
- // bulk of the <ACE_Reactor> code. All of these methods are
- // called with the main <Reactor> token lock held.
+ // The resposiblility of this class is to forward all methods to
+ // its delegation/implementation class
{
public:
- friend class ACE_Reactor_Handler_Repository_Iterator;
- // = Initialization and termination methods.
- ACE_Reactor_Handler_Repository (ACE_Reactor &);
- // Default "do-nothing" constructor.
-
- int open (size_t size);
- // Initialize a repository of the appropriate <size>.
-
- int close (void);
- // Close down the repository.
-
- // = Search structure operations.
-
- ACE_Event_Handler *find (ACE_HANDLE handle, size_t *index_p = 0);
- // Return the <ACE_Event_Handler *> associated with <ACE_HANDLE>.
- // If <index_p> is non-0, then return the index location of the
- // <handle>, if found.
-
- int bind (ACE_HANDLE,
- ACE_Event_Handler *,
- ACE_Reactor_Mask);
- // Bind the <ACE_Event_Handler *> to the <ACE_HANDLE> with the
- // appropriate <ACE_Reactor_Mask> settings.
-
- int unbind (ACE_HANDLE,
- ACE_Reactor_Mask mask);
- // Remove the binding of <ACE_HANDLE> in accordance with the <mask>.
-
- int unbind_all (void);
- // Remove all the <ACE_HANDLE, ACE_Event_Handler> tuples.
-
- // = Sanity checking.
-
- // Check the <handle> to make sure it's a valid ACE_HANDLE that
- // within the range of legal handles (i.e., >= 0 && < max_size_).
- int invalid_handle (ACE_HANDLE handle);
-
- // Check the <handle> to make sure it's a valid ACE_HANDLE that
- // within the range of currently registered handles (i.e., >= 0 && <
- // max_handlep1_).
- int handle_in_range (ACE_HANDLE handle);
-
- // = Accessors.
- size_t max_handlep1 (void);
- // Maximum ACE_HANDLE value, plus 1.
-
- void dump (void) const;
- // Dump the state of an object.
-
- ACE_ALLOC_HOOK_DECLARE;
- // Declare the dynamic allocation hooks.
-
-private:
- ACE_Reactor &reactor_;
- // Reference to our <Reactor>.
-
- ssize_t max_size_;
- // Maximum number of handles.
-
- int max_handlep1_;
- // The highest currently active handle, plus 1 (ranges between 0 and
- // <max_size_>.
-
-#if defined (ACE_WIN32)
- // = This structure maps <HANDLES> to <Event_Handlers>.
- struct ACE_NT_EH_Record
- {
- ACE_HANDLE handle_;
- ACE_Event_Handler *event_handler_;
- };
-
- ACE_NT_EH_Record *event_handlers_;
- // The NT version implements this via a dynamically allocated
- // array of <ACE_NT_EH_Record *>. Since NT implements ACE_HANDLE
- // as a void * we can't directly index into this array. Therefore,
- // we just do a linear search (for now). Next, we'll modify
- // things to use hashing or something faster...
-#else
- ACE_Event_Handler **event_handlers_;
- // The UNIX version implements this via a dynamically allocated
- // array of <ACE_Event_Handler *> that is indexed directly using
- // the ACE_HANDLE value.
-#endif /* ACE_WIN32 */
-};
-
-class ACE_Export ACE_Reactor_Handler_Repository_Iterator
- // = TITLE
- // Iterate through the <ACE_Reactor_Handler_Repository>.
-{
-public:
- // = Initialization method.
- ACE_Reactor_Handler_Repository_Iterator (const ACE_Reactor_Handler_Repository *s);
-
- // = Iteration methods.
-
- int next (ACE_Event_Handler *&next_item);
- // Pass back the <next_item> that hasn't been seen in the Set.
- // Returns 0 when all items have been seen, else 1.
-
- int done (void) const;
- // Returns 1 when all items have been seen, else 0.
-
- int advance (void);
- // Move forward by one element in the set. Returns 0 when all the
- // items in the set have been seen, else 1.
-
- void dump (void) const;
- // Dump the state of an object.
-
- ACE_ALLOC_HOOK_DECLARE;
- // Declare the dynamic allocation hooks.
-
-private:
- const ACE_Reactor_Handler_Repository *rep_;
- // Reference to the Handler_Repository we are iterating over.
-
- ssize_t current_;
- // Pointer to the current iteration level.
-};
-
-class ACE_Export ACE_Reactor
- // = TITLE
- // An object oriented event demultiplexor and event handler
- // dispatcher.
- //
- // = DESCRIPTION
- // The ACE_Reactor is an object-oriented event demultiplexor
- // and event handler dispatcher. The sources of events that the
- // ACE_Reactor waits for and dispatches includes I/O events,
- // signals, and timer events. All public methods acquire the
- // main <Reactor> token lock and call down to private or
- // protected methods, which assume that the lock is held and so
- // therefore don't (re)acquire the lock.
-{
-public:
enum
{
- DEFAULT_SIZE = ACE_DEFAULT_REACTOR_SIZE,
- // Default size of the Reactor's handle table.
-
// = Operations on the "ready" mask and the "dispatch" mask.
GET_MASK = 1,
// Retrieve current value of the the "ready" mask or the "dispatch" mask.
@@ -307,19 +54,7 @@ public:
// Bitwise "and" the negation of the value out of the mask (only changes enabled bits).
};
- // = Initialization and termination methods.
-
- ACE_Reactor (ACE_Sig_Handler * = 0,
- ACE_Timer_Queue * = 0);
- // Initialize <ACE_Reactor> with the default size.
-
- ACE_Reactor (size_t size,
- int restart = 0,
- ACE_Sig_Handler * = 0,
- ACE_Timer_Queue * = 0);
- // Initialize <ACE_Reactor> with size <size>.
-
- static ACE_Reactor *instance (size_t size = ACE_Reactor::DEFAULT_SIZE);
+ static ACE_Reactor *instance (void);
// Get pointer to a process-wide <ACE_Reactor>.
static ACE_Reactor *instance (ACE_Reactor *);
@@ -347,24 +82,29 @@ public:
static sig_atomic_t event_loop_done (void);
// Report if the <ACE_Reactor::instance>'s event loop is finished.
- virtual int open (size_t size = DEFAULT_SIZE,
+ ACE_Reactor (ACE_Reactor_Impl *implementation = 0);
+ // Create the Reactor using <implementation>
+
+ virtual ~ACE_Reactor (void);
+ // Close down and release all resources.
+
+ virtual int open (size_t size,
int restart = 0,
- ACE_Sig_Handler * = 0,
- ACE_Timer_Queue * = 0);
- // Initialize <ACE_Reactor> with size <size>.
+ ACE_Sig_Handler *signal_handler = 0,
+ ACE_Timer_Queue *timer_queue = 0);
+ // Initialization.
- virtual void close (void);
- // Close down the reactor and release all of its resources.
+ virtual int close (void);
+ // Close down and release all resources.
+
+ // = Event loop drivers.
- virtual ~ACE_Reactor (void);
- // Close down the reactor and release all of its resources.
-
- // = Event loop drivers.
virtual int handle_events (ACE_Time_Value *max_wait_time = 0);
- // This event loop driver that blocks for <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.
+ virtual int alertable_handle_events (ACE_Time_Value *max_wait_time = 0);
+ // This event loop driver blocks for up to <max_wait_time> before
+ // returning. It will return earlier if 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
@@ -372,34 +112,59 @@ public:
// <max_wait_time> will equal 1 second. This can be used if an
// application wishes to handle events for some fixed amount of
// time.
- //
+ //
// 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 something goes wrong.
+ // any handlers, or -1 if an error occurs.
+ //
+ // The only difference between <alertable_handle_events> and
+ // <handle_events> is that in the alertable case, the eventloop will
+ // return when the system queues an I/O completion routine or an
+ // Asynchronous Procedure Call.
virtual int handle_events (ACE_Time_Value &max_wait_time);
+ virtual int alertable_handle_events (ACE_Time_Value &max_wait_time);
// This method is just like the one above, except the
// <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, the eventloop will
+ // return when the system queues an I/O completion routine or an
+ // Asynchronous Procedure Call.
+
+ // = Register and remove Handlers.
- // = Register and remove <ACE_Event_Handler>s.
- virtual int register_handler (ACE_Event_Handler *eh,
+ virtual int register_handler (ACE_Event_Handler *event_handler,
ACE_Reactor_Mask mask);
- // Register a <eh> with a particular <mask>. Note that the
- // <Reactor[> will call eh->get_handle() to extract the underlying
- // I/O handle.
+ // Register <event_handler> with <mask>. The I/O handle will always
+ // come from <get_handle> on the <event_handler>.
- virtual int register_handler (ACE_HANDLE handle,
- ACE_Event_Handler *eh,
+ virtual int register_handler (ACE_HANDLE io_handle,
+ ACE_Event_Handler *event_handler,
ACE_Reactor_Mask mask);
- // Register a <eh> with a particular <mask>. Note that since the
- // <handle> is given the Reactor will *not* call eh->get_handle() to
- // extract the underlying I/O handle.
-
+ // Register <event_handler> with <mask>. The I/O handle is provided
+ // through the <io_handle> parameter.
+
+ virtual int register_handler (ACE_Event_Handler *event_handler,
+ ACE_HANDLE event_handle = ACE_INVALID_HANDLE);
+ // Register an <event_handler> that will be notified when
+ // <event_handle> is signaled. Since no event mask is passed
+ // through this interface, it is assumed that the <event_handle>
+ // being passed in is an event handle and not an I/O handle.
+
+ virtual int register_handler (ACE_HANDLE event_handle,
+ ACE_HANDLE io_handle,
+ ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask mask);
+ // Register an <event_handler> that will be notified when
+ // <event_handle> is signaled. <mask> specifies the network events
+ // that the <event_handler> is interested in.
+
virtual int register_handler (const ACE_Handle_Set &handles,
- ACE_Event_Handler *eh,
+ ACE_Event_Handler *event_handler,
ACE_Reactor_Mask mask);
- // Register <eh> with all the <handles> in the <Handle_Set>.
+ // Register <event_handler> with all the <handles> in the <Handle_Set>.
virtual int register_handler (int signum,
ACE_Event_Handler *new_sh,
@@ -416,69 +181,75 @@ public:
// Registers <new_sh> to handle a set of signals <sigset> using the
// <new_disp>.
- virtual int remove_handler (ACE_Event_Handler *eh,
+ virtual int remove_handler (ACE_Event_Handler *event_handler,
ACE_Reactor_Mask mask);
- // Removes the <mask> binding of <eh> from the Reactor. If there
- // are no more bindings for this <eh> then it is removed from the
- // Reactor. Note that the Reactor will call eh->get_handle() to
- // extract the underlying I/O handle.
+ // Removes <event_handler>. Note that the I/O handle will be
+ // obtained using <get_handle> method of <event_handler> . If
+ // <mask> == <ACE_Event_Handler::DONT_CALL> then the <handle_close>
+ // method of the <event_handler> is not invoked.
virtual int remove_handler (ACE_HANDLE handle,
- ACE_Reactor_Mask);
- // Removes the <mask> bind of <Event_Handler> whose handle is
- // <handle> from the Reactor. If there are no more bindings for
- // this <eh> then it is removed from the Reactor.
+ ACE_Reactor_Mask mask);
+ // Removes <handle>. If <mask> == <ACE_Event_Handler::DONT_CALL>
+ // then the <handle_close> method of the associated <event_handler>
+ // is not invoked.
virtual int remove_handler (const ACE_Handle_Set &handle_set,
- ACE_Reactor_Mask);
- // Removes all the <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 the Reactor.
+ ACE_Reactor_Mask mask);
+ // Removes all handles in <handle_set>. If <mask> ==
+ // <ACE_Event_Handler::DONT_CALL> then the <handle_close> method of
+ // the associated <event_handler>s is not invoked.
virtual int remove_handler (int signum,
ACE_Sig_Action *new_disp,
ACE_Sig_Action *old_disp = 0,
int sigkey = -1);
// Remove the ACE_Event_Handler currently associated with <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.
+ // 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);
// Calls <remove_handler> for every signal in <sigset>.
// = Suspend and resume Handlers.
- virtual int suspend_handler (ACE_Event_Handler *eh);
- // Temporarily suspend the <Event_Handler> associated with <eh>.
+ virtual int suspend_handler (ACE_Event_Handler *event_handler);
+ // Suspend <event_handler> temporarily. Use
+ // <event_handler->get_handle()> to get the handle.
virtual int suspend_handler (ACE_HANDLE handle);
- // Temporarily suspend the <Event_Handler> associated with <handle>.
+ // Suspend <handle> temporarily.
- virtual int resume_handler (ACE_Event_Handler *eh);
- // Resume a temporarily suspend <Event_Handler> associated with
- // <eh>.
+ virtual int suspend_handler (const ACE_Handle_Set &handles);
+ // Suspend all <handles> in handle set temporarily.
+
+ virtual int suspend_handlers (void);
+ // Suspend all <handles> temporarily.
+
+ virtual int resume_handler (ACE_Event_Handler *event_handler);
+ // Resume <event_handler>. Use <event_handler->get_handle()> to get
+ // the handle.
virtual int resume_handler (ACE_HANDLE handle);
- // Resume a temporarily suspended <Event_Handler> associated with
- // <handle>.
+ // Resume <handle>.
- virtual int suspend_handlers (void);
- // Suspend all the <Event_Handlers> in the Reactor.
+ virtual int resume_handler (const ACE_Handle_Set &handles);
+ // Resume all <handles> in handle set.
virtual int resume_handlers (void);
- // Resume all the <Event_Handlers> in the Reactor.
+ // Resume all <handles>.
- // = Timer management.
- virtual long schedule_timer (ACE_Event_Handler *,
+ // Timer management.
+
+ virtual long schedule_timer (ACE_Event_Handler *event_handler,
const void *arg,
- const ACE_Time_Value &delta_time,
+ const ACE_Time_Value &delta,
const ACE_Time_Value &interval = ACE_Time_Value::zero);
- // Schedule an <event_handler> that will expire after <delta_time>
- // 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
+ // Schedule an <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
@@ -491,311 +262,144 @@ public:
virtual int cancel_timer (ACE_Event_Handler *event_handler,
int dont_call_handle_close = 1);
- // Cancel all <event_handlers> that match the address of
- // <event_handler>. If <dont_call_handle_close> is 0 then the
- // <handle_close> method of <event_handler> will be invoked.
- // Returns number of handler's cancelled.
+ // Cancel all Event_Handlers that match the address of
+ // <event_handler>. Returns number of handlers cancelled.
virtual int cancel_timer (long timer_id,
const void **arg = 0,
int dont_call_handle_close = 1);
- // Cancel the single <ACE_Event_Handler> that matches the <timer_id>
- // value (which was returned from the <schedule> method). If arg is
+ // Cancel the single Event_Handler that matches the <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
+ // argument passed in when the Event_Handler was registered. This
// makes it possible to free up the memory and avoid memory leaks.
- // If <dont_call_handle_close> is 0 then the <handle_close> method
- // of <event_handler> will be invoked. Returns 1 if cancellation
- // succeeded and 0 if the <timer_id> wasn't found.
+ // Returns 1 if cancellation succeeded and 0 if the <timer_id>
+ // wasn't found.
// = High-level Event_Handler scheduling operations
- virtual int schedule_wakeup (ACE_Event_Handler *eh,
- ACE_Reactor_Mask mask);
- // ADD the dispatch MASK "bit" bound with the <eh> and the <mask>.
-
+ virtual int schedule_wakeup (ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask masks_to_be_added);
+ // Add <masks_to_be_added> to the <event_handler>'s entry.
+ // <event_handler> must already have been registered.
+
virtual int schedule_wakeup (ACE_HANDLE handle,
- ACE_Reactor_Mask mask);
- // ADD the dispatch MASK "bit" bound with the <handle> and the <mask>.
+ ACE_Reactor_Mask masks_to_be_added);
+ // Add <masks_to_be_added> to the <handle>'s entry. <event_handler>
+ // associated with <handle> must already have been registered.
- virtual int cancel_wakeup (ACE_Event_Handler *eh,
- ACE_Reactor_Mask mask);
- // CLR the dispatch MASK "bit" bound with the <eh> and the <mask>.
+ virtual int cancel_wakeup (ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask masks_to_be_cleared);
+ // Clear <masks_to_be_cleared> from the <event_handler>'s entry.
virtual int cancel_wakeup (ACE_HANDLE handle,
- ACE_Reactor_Mask mask);
- // CLR the dispatch MASK "bit" bound with the <handle> and the <mask>.
+ ACE_Reactor_Mask masks_to_be_cleared);
+ // Clear <masks_to_be_cleared> from the <handle>'s entry.
// = Notification methods.
- virtual int notify (ACE_Event_Handler * = 0,
- ACE_Reactor_Mask = ACE_Event_Handler::EXCEPT_MASK,
- ACE_Time_Value * = 0);
- // Called by a thread when it wants to unblock the Reactor. This
- // wakeups the <ACE_Reactor> if currently blocked in
- // select()/poll(). Pass over both the <Event_Handler> *and* the
- // <mask> to allow the caller to dictate which <Event_Handler>
- // method the <Reactor> will invoke. 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).
-
- void requeue_position (int);
- // Set position that the main ACE_Reactor thread is requeued in the
- // list of waiters during a notify() callback.
-
- int requeue_position (void);
- // Get position that the main ACE_Reactor thread is requeued in the
- // list of waiters during a notify() callback.
-
- void max_notify_iterations (int);
- // Set the maximum number of times that the
- // <ACE_Reactor_Notify::handle_input> method will iterate and
- // dispatch the <ACE_Event_Handlers> that are passed in via the
- // notify pipe before breaking out of its <recv> loop. By default,
- // this is set to -1, which means "iterate until the pipe 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.
-
- int max_notify_iterations (void);
- // Get the maximum number of times that the
- // <ACE_Reactor_Notify::handle_input> method will iterate and
- // dispatch the <ACE_Event_Handlers> that are passed in via the
- // notify pipe before breaking out of its <recv> loop.
- // = Low-level wait_set mask manipulation methods.
- virtual int mask_ops (ACE_Event_Handler *eh,
- ACE_Reactor_Mask mask,
- int ops);
- // GET/SET/ADD/CLR the dispatch mask "bit" bound with the <eh> and
- // <mask>.
+ virtual int notify (ACE_Event_Handler *event_handler = 0,
+ ACE_Reactor_Mask mask = ACE_Event_Handler::EXCEPT_MASK,
+ ACE_Time_Value *tv = 0);
+ // Notify <event_handler> of <mask> event. The <ACE_Time_Value>
+ // indicates how long to blocking trying to notify. 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 iterations);
+ // Set the maximum number of times that ACE_Reactor 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);
+ // Get the maximum number of times that the ACE_Reactor 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 mask_ops (ACE_HANDLE handle,
- ACE_Reactor_Mask mask,
- int ops);
- // GET/SET/ADD/CLR the dispatch MASK "bit" bound with the <handle>
- // and <mask>.
-
- // = Low-level ready_set mask manipulation methods.
- virtual int ready_ops (ACE_Event_Handler *eh,
- ACE_Reactor_Mask mask,
- int ops);
- // GET/SET/ADD/CLR the ready "bit" bound with the <eh> and <mask>.
-
- virtual int ready_ops (ACE_HANDLE handle,
- ACE_Reactor_Mask,
- int ops);
- // GET/SET/ADD/CLR the ready "bit" bound with the <handle> and <mask>.
-
- // = Only the owner thread that can perform a <handle_events>.
-
- int owner (ACE_thread_t n_id, ACE_thread_t *o_id = 0);
- // Set the new owner of the thread and return the old owner.
-
- int owner (ACE_thread_t *);
- // Return the current owner of the thread.
-
- // = Miscellaneous Handler operations.
virtual int handler (ACE_HANDLE handle,
ACE_Reactor_Mask mask,
- ACE_Event_Handler **eh = 0);
+ ACE_Event_Handler **event_handler = 0);
// Check to see if <handle> is associated with a valid Event_Handler
- // bound to <mask>. Return the <eh> associated with this <handler>
- // if <eh> != 0.
+ // bound to <mask>. Return the <event_handler> associated with this
+ // <handler> if <event_handler> != 0.
virtual int handler (int signum,
- ACE_Event_Handler ** = 0);
+ ACE_Event_Handler **event_handler = 0);
// Check to see if <signum> is associated with a valid Event_Handler
- // bound to a signal. Return the <eh> associated with this
- // <handler> if <eh> != 0.
+ // bound to a signal. Return the <event_handler> associated with
+ // this <handler> if <event_handler> != 0.
- int initialized (void);
- // Returns true if we've been successfully initialized, else false.
+ virtual int initialized (void);
+ // Returns true if Reactor has been successfully initialized, else
+ // false.
- ACE_Reactor_Token &lock (void);
- // Returns a reference to the <ACE_Reactor_Token> that is used to
- // serialize the internal Reactor's processing logic. This can be
- // useful for situations where you need to avoid deadlock
- // efficiently when <ACE_Event_Handlers> are used in multiple
- // threads.
+ virtual size_t size (void);
+ // Returns the current size of the Reactor's internal descriptor
+ // table.
- void dump (void) const;
- // Dump the state of an object.
+ virtual ACE_Lock &lock (void);
+ // Returns a reference to the Reactor's internal lock.
- ACE_ALLOC_HOOK_DECLARE;
- // Declare the dynamic allocation hooks.
+ virtual void wakeup_all_threads (void);
+ // Wake up all threads in waiting in the event loop
-protected:
- // = Internal methods that do the actual work.
-
- // All of these methods assume that the <Reactor>'s token lock is
- // held by the public methods that call down to them.
+ virtual int owner (ACE_thread_t new_owner,
+ ACE_thread_t *old_owner = 0);
+ // Transfers ownership of Reactor to the <new_owner>.
- virtual int register_handler_i (ACE_HANDLE handle,
- ACE_Event_Handler *eh,
- ACE_Reactor_Mask mask);
- // Do the work of actually binding the <handle> and <eh> with the
- // <mask>.
+ virtual int owner (ACE_thread_t *owner);
+ // Return the ID of the "owner" thread.
- virtual int register_handler_i (const ACE_Handle_Set &handles,
- ACE_Event_Handler *handler,
- ACE_Reactor_Mask mask);
- // Register a set of <handles>.
+ virtual void requeue_position (int position);
+ // Set position of the owner thread.
- virtual int remove_handler_i (ACE_HANDLE handle,
- ACE_Reactor_Mask);
- // Do the work of actually unbinding the <handle> and <eh> with the
- // <mask>.
+ virtual int requeue_position (void);
+ // Get position of the owner thread.
- virtual int remove_handler_i (const ACE_Handle_Set &handles,
- ACE_Reactor_Mask);
- // Remove a set of <handles>.
+ // = Low-level wait_set mask manipulation methods.
- virtual int suspend_i (ACE_HANDLE handle);
- // Suspend the <Event_Handler> associated with <handle>
+ virtual int mask_ops (ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask mask,
+ int ops);
+ // GET/SET/ADD/CLR the dispatch mask "bit" bound with the
+ // <event_handler> and <mask>.
- virtual int resume_i (ACE_HANDLE handle);
- // Resume the <Event_Handler> associated with <handle>
+ virtual int mask_ops (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask,
+ int ops);
+ // GET/SET/ADD/CLR the dispatch MASK "bit" bound with the <handle>
+ // and <mask>.
- virtual int handler_i (ACE_HANDLE handle,
- ACE_Reactor_Mask,
- ACE_Event_Handler ** = 0);
- // Implement the public <handler> method.
+ // = Low-level ready_set mask manipulation methods.
+ virtual int ready_ops (ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask mask,
+ int ops);
+ // GET/SET/ADD/CLR the ready "bit" bound with the <event_handler>
+ // and <mask>.
- virtual int handler_i (int signum, ACE_Event_Handler ** = 0);
- // Implement the public <handler> method.
+ virtual int ready_ops (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask,
+ int ops);
+ // GET/SET/ADD/CLR the ready "bit" bound with the <handle> and <mask>.
- virtual int any_ready (ACE_Reactor_Handle_Set &handle_set);
- // Check if there are any HANDLEs enabled in the <ready_set_>, and
- // if so, update the <handle_set> and return the number ready. If
- // there aren't any HANDLEs enabled return 0.
+ ACE_ALLOC_HOOK_DECLARE;
+ // Declare the dynamic allocation hooks.
- virtual int handle_error (void);
- // Take corrective action when errors occur.
+protected:
- virtual int check_handles (void);
- // Make sure the handles are all valid.
+ ACE_Reactor_Impl *implementation_;
+ // Delegation/implementation class that all methods will be
+ // forwarded to
- virtual int bit_ops (ACE_HANDLE handle,
- ACE_Reactor_Mask mask,
- ACE_Reactor_Handle_Set &wait_Set,
- int ops);
- // Allow manipulation of the <wait_set_> mask and <ready_set_> mask.
-
- virtual int wait_for_multiple_events (ACE_Reactor_Handle_Set &,
- ACE_Time_Value *);
- // Wait for events to occur.
-
- // = Dispatching methods.
-
- virtual int dispatch (int nfound,
- ACE_Reactor_Handle_Set &);
- // Template Method that dispatches <ACE_Event_Handler>s for time
- // events, I/O events, and signal events. Returns the total number
- // of <ACE_Event_Handler>s that were dispatched or -1 if something
- // goes wrong.
-
- virtual int dispatch_timer_handlers (void);
- // Dispatch any expired timer handlers. Returns -1 if the state of
- // the <wait_set_> has changed, else returns number of timer
- // handlers dispatched.
-
- virtual int dispatch_notification_handlers (int &number_of_active_handles,
- ACE_Reactor_Handle_Set &dispatch_set);
- // Dispatch any notification handlers. Returns -1 if the state of
- // the <wait_set_> has changed, else returns number of handlers
- // notified.
-
- virtual int dispatch_io_handlers (int &number_of_active_handles,
- ACE_Reactor_Handle_Set &dispatch_set);
- // Dispatch all the input/output/except handlers that are enabled in
- // the <dispatch_set>. Returns -1 if the state of the <wait_set_>
- // has changed, else returns number of handlers dispatched.
-
- virtual void notify_handle (ACE_HANDLE handle,
- ACE_Reactor_Mask mask,
- ACE_Handle_Set &,
- ACE_Event_Handler *eh,
- ACE_EH_PTMF callback);
- // Notify the appropriate <callback> in the context of the <eh>
- // associated with <handle> that a particular event has occurred.
-
- ACE_Reactor_Handler_Repository handler_rep_;
- // Table that maps <ACE_HANDLEs> to <ACE_Event_Handler *>'s.
-
- ACE_Timer_Queue *timer_queue_;
- // Defined as a pointer to allow overriding by derived classes...
-
- int delete_timer_queue_;
- // Keeps track of whether we should delete the timer queue (if we
- // didn't create it, then we don't delete it).
-
- ACE_Sig_Handler *signal_handler_;
- // Handle signals without requiring global/static variables.
-
- int delete_signal_handler_;
- // Keeps track of whether we should delete the signal handler (if we
- // didn't create it, then we don't delete it).
-
- ACE_Reactor_Handle_Set wait_set_;
- // Tracks handles that are waited for by select().
-
- ACE_Reactor_Handle_Set suspend_set_;
- // Tracks handles that are currently suspended.
-
- ACE_Reactor_Handle_Set ready_set_;
- // Track HANDLES we are interested in for various events that must
- // be dispatched *without* going through select().
-
- int restart_;
- // Restart automatically when interrupted
-
- int requeue_position_;
- // Position that the main ACE_Reactor thread is requeued in the list
- // of waiters during a notify() callback. If this value == -1 we
- // are requeued at the end of the list. Else if it's 0 then we are
- // requeued at the front of the list. Else if it's > 1 then that
- // indicates the number of waiters to skip over.
-
- int max_notify_iterations_;
- // Keeps track of the maximum number of times that the
- // <ACE_Reactor_Notify::handle_input> method will iterate and
- // dispatch the <ACE_Event_Handlers> that are passed in via the
- // notify pipe before breaking out of its <recv> loop. By default,
- // this is set to -1, which means "iterate until the pipe is empty."
-
- int initialized_;
- // True if we've been initialized yet...
-
- ACE_thread_t owner_;
- // The original thread that created this Reactor.
-
- int state_changed_;
- // True if state has changed during dispatching of
- // <ACE_Event_Handlers>, else false. This is used to determine
- // whether we need to make another trip through the <Reactor>'s
- // <wait_for_multiple_events> loop.
-
- ACE_Reactor_Token token_;
- // Synchronization token for the MT_SAFE ACE_Reactor.
-
- ACE_Reactor_Notify notify_handler_;
- // Callback object that unblocks the ACE_Reactor if it's sleeping.
-
- void renew (void);
- // Enqueue ourselves into the list of waiting threads at the
- // appropriate point specified by <requeue_position_>.
-
- friend class ACE_Reactor_Notify;
- friend class ACE_Reactor_Handler_Repository;
-
-private:
- int release_token (void);
- // Release the token lock when a Win32 structured exception occurs.
-
- int handle_events_i (ACE_Time_Value *max_wait_time = 0);
- // Stops the VC++ compiler from bitching about exceptions and destructors
+ int delete_implementation_;
+ // Flag used to indicate whether we are responsible for cleaning up
+ // the implementation instance
static ACE_Reactor *reactor_;
// Pointer to a process-wide <ACE_Reactor>.
diff --git a/ace/Reactor.i b/ace/Reactor.i
index 3e275fdd683..948ec748c43 100644
--- a/ace/Reactor.i
+++ b/ace/Reactor.i
@@ -1,132 +1,432 @@
/* -*- C++ -*- */
// $Id$
-// Reactor.i
+#include "ace/Reactor_Impl.h"
+#include "ace/Handle_Set.h"
-ACE_INLINE int
-ACE_Reactor::resume_handler (ACE_Event_Handler *h)
+ACE_INLINE int
+ACE_Reactor::open (size_t size,
+ int restart,
+ ACE_Sig_Handler *signal_handler,
+ ACE_Timer_Queue *timer_queue)
+{
+ return this->implementation_->open (size,
+ restart,
+ signal_handler,
+ timer_queue);
+}
+
+ACE_INLINE int
+ACE_Reactor::close (void)
+{
+ return this->implementation_->close ();
+}
+
+ACE_INLINE int
+ACE_Reactor::handle_events (ACE_Time_Value *max_wait_time)
+{
+ return this->implementation_->handle_events (max_wait_time);
+}
+
+ACE_INLINE int
+ACE_Reactor::alertable_handle_events (ACE_Time_Value *max_wait_time)
+{
+ return this->implementation_->alertable_handle_events (max_wait_time);
+}
+
+ACE_INLINE int
+ACE_Reactor::handle_events (ACE_Time_Value &max_wait_time)
+{
+ return this->implementation_->handle_events (max_wait_time);
+}
+
+ACE_INLINE int
+ACE_Reactor::alertable_handle_events (ACE_Time_Value &max_wait_time)
+{
+ return this->implementation_->alertable_handle_events (max_wait_time);
+}
+
+
+ACE_INLINE int
+ACE_Reactor::register_handler (ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask mask)
+{
+ int result = this->implementation_->register_handler (event_handler,
+ mask);
+ if (result != -1)
+ // Assign *this* <Reactor> to the <Event_Handler>.
+ event_handler->reactor (this);
+
+ return result;
+}
+
+ACE_INLINE int
+ACE_Reactor::register_handler (ACE_HANDLE io_handle,
+ ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask mask)
+{
+ int result = this->implementation_->register_handler (io_handle,
+ event_handler,
+ mask);
+ if (result != -1)
+ // Assign *this* <Reactor> to the <Event_Handler>.
+ event_handler->reactor (this);
+
+ return result;
+}
+
+ACE_INLINE int
+ACE_Reactor::register_handler (ACE_Event_Handler *event_handler,
+ ACE_HANDLE event_handle)
{
- ACE_TRACE ("ACE_Reactor::resume_handler");
- return this->resume_handler (h->get_handle ());
+ int result = this->implementation_->register_handler (event_handler,
+ event_handle);
+ if (result != -1)
+ // Assign *this* <Reactor> to the <Event_Handler>.
+ event_handler->reactor (this);
+
+ return result;
}
+
+ACE_INLINE int
+ACE_Reactor::register_handler (ACE_HANDLE event_handle,
+ ACE_HANDLE io_handle,
+ ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask mask)
+{
+ int result = this->implementation_->register_handler (event_handle,
+ io_handle,
+ event_handler,
+ mask);
+ if (result != -1)
+ // Assign *this* <Reactor> to the <Event_Handler>.
+ event_handler->reactor (this);
-ACE_INLINE int
-ACE_Reactor::suspend_handler (ACE_Event_Handler *h)
+ return result;
+}
+
+ACE_INLINE int
+ACE_Reactor::register_handler (const ACE_Handle_Set &handles,
+ ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask mask)
{
- ACE_TRACE ("ACE_Reactor::suspend_handler");
- return this->suspend_handler (h->get_handle ());
+ int result = this->implementation_->register_handler (handles,
+ event_handler,
+ mask);
+ if (result != -1)
+ // Assign *this* <Reactor> to the <Event_Handler>.
+ event_handler->reactor (this);
+
+ return result;
}
-ACE_INLINE int
-ACE_Reactor::register_handler (int signum,
- ACE_Event_Handler *new_sh,
- ACE_Sig_Action *new_disp,
+ACE_INLINE int
+ACE_Reactor::register_handler (int signum,
+ ACE_Event_Handler *new_sh,
+ ACE_Sig_Action *new_disp,
ACE_Event_Handler **old_sh,
ACE_Sig_Action *old_disp)
{
- ACE_TRACE ("ACE_Reactor::register_handler");
- return this->signal_handler_->register_handler (signum,
- new_sh, new_disp,
- old_sh, old_disp);
+ return this->implementation_->register_handler (signum,
+ new_sh,
+ new_disp,
+ old_sh,
+ old_disp);
+}
+
+ACE_INLINE int
+ACE_Reactor::register_handler (const ACE_Sig_Set &sigset,
+ ACE_Event_Handler *new_sh,
+ ACE_Sig_Action *new_disp)
+{
+ return this->implementation_->register_handler (sigset,
+ new_sh,
+ new_disp);
+}
+
+ACE_INLINE int
+ACE_Reactor::remove_handler (ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask mask)
+{
+ return this->implementation_->remove_handler (event_handler,
+ mask);
+}
+
+ACE_INLINE int
+ACE_Reactor::remove_handler (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask)
+{
+ return this->implementation_->remove_handler (handle,
+ mask);
}
-ACE_INLINE int
-ACE_Reactor::handler (int signum, ACE_Event_Handler **handler)
+ACE_INLINE int
+ACE_Reactor::remove_handler (const ACE_Handle_Set &handle_set,
+ ACE_Reactor_Mask mask)
{
- ACE_TRACE ("ACE_Reactor::handler");
- return this->handler_i (signum, handler);
+ return this->implementation_->remove_handler (handle_set,
+ mask);
}
-ACE_INLINE int
-ACE_Reactor::remove_handler (int signum,
- ACE_Sig_Action *new_disp,
+ACE_INLINE int
+ACE_Reactor::remove_handler (int signum,
+ ACE_Sig_Action *new_disp,
ACE_Sig_Action *old_disp,
int sigkey)
{
- ACE_TRACE ("ACE_Reactor::remove_handler");
- return this->signal_handler_->remove_handler (signum, new_disp, old_disp, sigkey);
+ return this->implementation_->remove_handler (signum,
+ new_disp,
+ old_disp,
+ sigkey);
+}
+
+ACE_INLINE int
+ACE_Reactor::remove_handler (const ACE_Sig_Set &sigset)
+{
+ return this->implementation_->remove_handler (sigset);
+}
+
+
+ACE_INLINE int
+ACE_Reactor::suspend_handler (ACE_Event_Handler *event_handler)
+{
+ return this->implementation_->suspend_handler (event_handler);
+}
+
+ACE_INLINE int
+ACE_Reactor::suspend_handler (ACE_HANDLE handle)
+{
+ return this->implementation_->suspend_handler (handle);
+}
+
+ACE_INLINE int
+ACE_Reactor::suspend_handler (const ACE_Handle_Set &handles)
+{
+ return this->implementation_->suspend_handler (handles);
+}
+
+ACE_INLINE int
+ACE_Reactor::suspend_handlers (void)
+{
+ return this->implementation_->suspend_handlers ();
+}
+
+ACE_INLINE int
+ACE_Reactor::resume_handler (ACE_Event_Handler *event_handler)
+{
+ return this->implementation_->resume_handler (event_handler);
}
-// = The remaining methods in this file must be called with locks
-// held. Note the queue handles its own locking.
+ACE_INLINE int
+ACE_Reactor::resume_handler (ACE_HANDLE handle)
+{
+ return this->implementation_->resume_handler (handle);
+}
+
+ACE_INLINE int
+ACE_Reactor::resume_handler (const ACE_Handle_Set &handles)
+{
+ return this->implementation_->resume_handler (handles);
+}
+
+ACE_INLINE int
+ACE_Reactor::resume_handlers (void)
+{
+ return this->implementation_->resume_handlers ();
+}
+
+
+ACE_INLINE long
+ACE_Reactor::schedule_timer (ACE_Event_Handler *event_handler,
+ const void *arg,
+ const ACE_Time_Value &delta,
+ const ACE_Time_Value &interval)
+{
+ return this->implementation_->schedule_timer (event_handler,
+ arg,
+ delta,
+ interval);
+}
-ACE_INLINE int
-ACE_Reactor::cancel_timer (ACE_Event_Handler *handler,
+ACE_INLINE int
+ACE_Reactor::cancel_timer (ACE_Event_Handler *event_handler,
int dont_call_handle_close)
{
- ACE_TRACE ("ACE_Reactor::cancel_timer");
- return this->timer_queue_->cancel (handler,
- dont_call_handle_close);
+ return this->implementation_->cancel_timer (event_handler,
+ dont_call_handle_close);
}
-ACE_INLINE int
-ACE_Reactor::cancel_timer (long timer_id,
+ACE_INLINE int
+ACE_Reactor::cancel_timer (long timer_id,
const void **arg,
int dont_call_handle_close)
{
- ACE_TRACE ("ACE_Reactor::cancel_timer");
- return this->timer_queue_->cancel (timer_id,
- arg,
- dont_call_handle_close);
+ return this->implementation_->cancel_timer (timer_id,
+ arg,
+ dont_call_handle_close);
+}
+
+
+ACE_INLINE int
+ACE_Reactor::schedule_wakeup (ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask masks_to_be_added)
+{
+ return this->implementation_->schedule_wakeup (event_handler,
+ masks_to_be_added);
+}
+
+ACE_INLINE int
+ACE_Reactor::schedule_wakeup (ACE_HANDLE handle,
+ ACE_Reactor_Mask masks_to_be_added)
+{
+ return this->implementation_->schedule_wakeup (handle,
+ masks_to_be_added);
}
-// Performs operations on the "ready" bits.
+ACE_INLINE int
+ACE_Reactor::cancel_wakeup (ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask masks_to_be_cleared)
+{
+ return this->implementation_->cancel_wakeup (event_handler,
+ masks_to_be_cleared);
+}
-ACE_INLINE int
-ACE_Reactor::ready_ops (ACE_Event_Handler *handler,
- ACE_Reactor_Mask mask,
- int ops)
+ACE_INLINE int
+ACE_Reactor::cancel_wakeup (ACE_HANDLE handle,
+ ACE_Reactor_Mask masks_to_be_cleared)
{
- ACE_TRACE ("ACE_Reactor::ready_ops");
- return this->ready_ops (handler->get_handle (), mask, ops);
+ return this->implementation_->cancel_wakeup (handle,
+ masks_to_be_cleared);
}
-// Performs operations on the "dispatch" masks.
-ACE_INLINE int
-ACE_Reactor::mask_ops (ACE_Event_Handler *handler,
- ACE_Reactor_Mask mask,
- int ops)
+ACE_INLINE int
+ACE_Reactor::notify (ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask mask,
+ ACE_Time_Value *tv)
+{
+ return this->implementation_->notify (event_handler,
+ mask,
+ tv);
+}
+
+ACE_INLINE void
+ACE_Reactor::max_notify_iterations (int iterations)
{
- ACE_TRACE ("ACE_Reactor::mask_ops");
- return this->mask_ops (handler->get_handle (), mask, ops);
+ this->implementation_->max_notify_iterations (iterations);
}
ACE_INLINE int
-ACE_Reactor::schedule_wakeup (ACE_Event_Handler *eh,
- ACE_Reactor_Mask mask)
+ACE_Reactor::max_notify_iterations (void)
{
- ACE_TRACE ("ACE_Reactor::schedule_wakeup");
- return this->mask_ops (eh->get_handle (), mask, ACE_Reactor::ADD_MASK);
+ return this->implementation_->max_notify_iterations ();
}
ACE_INLINE int
-ACE_Reactor::cancel_wakeup (ACE_Event_Handler *eh,
- ACE_Reactor_Mask mask)
+ACE_Reactor::handler (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask,
+ ACE_Event_Handler **event_handler)
{
- ACE_TRACE ("ACE_Reactor::cancel_wakeup");
- return this->mask_ops (eh->get_handle (), mask, ACE_Reactor::CLR_MASK);
+ return this->implementation_->handler (handle,
+ mask,
+ event_handler);
}
ACE_INLINE int
-ACE_Reactor::schedule_wakeup (ACE_HANDLE handle,
- ACE_Reactor_Mask mask)
+ACE_Reactor::handler (int signum,
+ ACE_Event_Handler **event_handler)
{
- ACE_TRACE ("ACE_Reactor::schedule_wakeup");
- return this->mask_ops (handle, mask, ACE_Reactor::ADD_MASK);
+ return this->implementation_->handler (signum,
+ event_handler);
}
ACE_INLINE int
-ACE_Reactor::cancel_wakeup (ACE_HANDLE handle,
- ACE_Reactor_Mask mask)
+ACE_Reactor::initialized (void)
{
- ACE_TRACE ("ACE_Reactor::cancel_wakeup");
- return this->mask_ops (handle, mask, ACE_Reactor::CLR_MASK);
+ return this->implementation_->initialized ();
}
-ACE_INLINE ACE_Reactor_Token &
+ACE_INLINE ACE_Lock &
ACE_Reactor::lock (void)
{
- ACE_TRACE ("ACE_Reactor::lock");
- return this->token_;
+ return this->implementation_->lock ();
+}
+
+ACE_INLINE void
+ACE_Reactor::wakeup_all_threads (void)
+{
+ this->implementation_->wakeup_all_threads ();
+}
+
+ACE_INLINE int
+ACE_Reactor::owner (ACE_thread_t new_owner,
+ ACE_thread_t *old_owner)
+{
+ return this->implementation_->owner (new_owner,
+ old_owner);
+}
+
+ACE_INLINE int
+ACE_Reactor::owner (ACE_thread_t *owner)
+{
+ return this->implementation_->owner (owner);
+}
+
+ACE_INLINE void
+ACE_Reactor::requeue_position (int position)
+{
+ this->implementation_->requeue_position (position);
+}
+
+ACE_INLINE int
+ACE_Reactor::requeue_position (void)
+{
+ return this->implementation_->requeue_position ();
+}
+
+
+ACE_INLINE int
+ACE_Reactor::mask_ops (ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask mask,
+ int ops)
+{
+ return this->implementation_->mask_ops (event_handler,
+ mask,
+ ops);
+}
+
+ACE_INLINE int
+ACE_Reactor::mask_ops (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask,
+ int ops)
+{
+ return this->implementation_->mask_ops (handle,
+ mask,
+ ops);
+}
+
+ACE_INLINE int
+ACE_Reactor::ready_ops (ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask mask,
+ int ops)
+{
+ return this->implementation_->ready_ops (event_handler,
+ mask,
+ ops);
+}
+
+ACE_INLINE int
+ACE_Reactor::ready_ops (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask,
+ int ops)
+{
+ return this->implementation_->ready_ops (handle,
+ mask,
+ ops);
+}
+
+ACE_INLINE size_t
+ACE_Reactor::size (void)
+{
+ return this->implementation_->size ();
}
diff --git a/ace/Reactor_Impl.h b/ace/Reactor_Impl.h
new file mode 100644
index 00000000000..001d8cd3c0a
--- /dev/null
+++ b/ace/Reactor_Impl.h
@@ -0,0 +1,348 @@
+/* -*- C++ -*- */
+
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// ace
+//
+// = FILENAME
+// Reactor_Impl.h
+//
+// = AUTHOR
+// Irfan Pyarali
+//
+// ============================================================================
+
+#if !defined (ACE_REACTOR_IMPL_H)
+#define ACE_REACTOR_IMPL_H
+
+class ACE_Handle_Set;
+
+// Timer Queue is a complicated template class. A simple forward
+// declaration will not work
+#include "ace/Timer_Queue.h"
+
+// Event_Handler.h contains the definition of ACE_Reactor_Mask
+#include "ace/Event_Handler.h"
+
+// We are using 4 or 5 signal classes, we could forward declare
+// them.... But Timer_Queue_T.h includes Signal.h, so I don't think
+// forward declaration will be useful here
+#include "ace/Signal.h"
+
+class ACE_Export ACE_Reactor_Impl
+ // = TITLE
+ //
+ // An abstract class for implementing the Reactor Pattern.
+{
+public:
+
+ virtual ~ACE_Reactor_Impl (void) {};
+ // Close down and release all resources.
+
+ virtual int open (size_t size,
+ int restart = 0,
+ ACE_Sig_Handler * = 0,
+ ACE_Timer_Queue * = 0) = 0;
+ // Initialization.
+
+ virtual int close (void) = 0;
+ // Close down and release all resources.
+
+ // = Event loop drivers.
+
+ virtual int handle_events (ACE_Time_Value *max_wait_time = 0) = 0;
+ virtual int alertable_handle_events (ACE_Time_Value *max_wait_time = 0) = 0;
+ // This event loop driver blocks for up to <max_wait_time> before
+ // returning. It will return earlier if 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.
+ //
+ // 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, the eventloop will
+ // return when the system queues an I/O completion routine or an
+ // Asynchronous Procedure Call.
+
+ virtual int handle_events (ACE_Time_Value &max_wait_time) = 0;
+ virtual int alertable_handle_events (ACE_Time_Value &max_wait_time) = 0;
+ // This method is just like the one above, except the
+ // <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, the eventloop will
+ // return when the system queues an I/O completion routine or an
+ // Asynchronous Procedure Call.
+
+ // = Register and remove Handlers.
+
+ virtual int register_handler (ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask mask) = 0;
+ // Register <event_handler> with <mask>. The I/O handle will always
+ // come from <get_handle> on the <event_handler>.
+
+ virtual int register_handler (ACE_HANDLE io_handle,
+ ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask mask) = 0;
+ // Register <event_handler> with <mask>. The I/O handle is provided
+ // through the <io_handle> parameter.
+
+ virtual int register_handler (ACE_Event_Handler *event_handler,
+ ACE_HANDLE event_handle = ACE_INVALID_HANDLE) = 0;
+ // Register an <event_handler> that will be notified when
+ // <event_handle> is signaled. Since no event mask is passed
+ // through this interface, it is assumed that the <event_handle>
+ // being passed in is an event handle and not an I/O handle.
+
+ virtual int register_handler (ACE_HANDLE event_handle,
+ ACE_HANDLE io_handle,
+ ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask mask) = 0;
+ // Register an <event_handler> that will be notified when
+ // <event_handle> is signaled. <mask> specifies the network events
+ // that the <event_handler> is interested in.
+
+ virtual int register_handler (const ACE_Handle_Set &handles,
+ ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask mask) = 0;
+ // Register <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) = 0;
+ // Register <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) = 0;
+ // Registers <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) = 0;
+ // Removes <event_handler>. Note that the I/O handle will be
+ // obtained using <get_handle> method of <event_handler> . If
+ // <mask> == <ACE_Event_Handler::DONT_CALL> then the <handle_close>
+ // method of the <event_handler> is not invoked.
+
+ virtual int remove_handler (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask) = 0;
+ // Removes <handle>. If <mask> == <ACE_Event_Handler::DONT_CALL>
+ // then the <handle_close> method of the associated <event_handler>
+ // is not invoked.
+
+ virtual int remove_handler (const ACE_Handle_Set &handle_set,
+ ACE_Reactor_Mask mask) = 0;
+ // Removes all handles in <handle_set>. If <mask> ==
+ // <ACE_Event_Handler::DONT_CALL> then the <handle_close> method of
+ // the associated <event_handler>s is not invoked.
+
+ virtual int remove_handler (int signum,
+ ACE_Sig_Action *new_disp,
+ ACE_Sig_Action *old_disp = 0,
+ int sigkey = -1) = 0;
+ // Remove the ACE_Event_Handler currently associated with <signum>.
+ // 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) = 0;
+ // Calls <remove_handler> for every signal in <sigset>.
+
+ // = Suspend and resume Handlers.
+
+ virtual int suspend_handler (ACE_Event_Handler *event_handler) = 0;
+ // Suspend <event_handler> temporarily. Use
+ // <event_handler->get_handle()> to get the handle.
+
+ virtual int suspend_handler (ACE_HANDLE handle) = 0;
+ // Suspend <handle> temporarily.
+
+ virtual int suspend_handler (const ACE_Handle_Set &handles) = 0;
+ // Suspend all <handles> in handle set temporarily.
+
+ virtual int suspend_handlers (void) = 0;
+ // Suspend all <handles> temporarily.
+
+ virtual int resume_handler (ACE_Event_Handler *event_handler) = 0;
+ // Resume <event_handler>. Use <event_handler->get_handle()> to get
+ // the handle.
+
+ virtual int resume_handler (ACE_HANDLE handle) = 0;
+ // Resume <handle>.
+
+ virtual int resume_handler (const ACE_Handle_Set &handles) = 0;
+ // Resume all <handles> in handle set.
+
+ virtual int resume_handlers (void) = 0;
+ // Resume all <handles>.
+
+ // 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) = 0;
+ // Schedule an <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) = 0;
+ // Cancel all Event_Handlers that match the address of
+ // <event_handler>. Returns number of handlers cancelled.
+
+ virtual int cancel_timer (long timer_id,
+ const void **arg = 0,
+ int dont_call_handle_close = 1) = 0;
+ // Cancel the single Event_Handler that matches the <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.
+
+ // = High-level Event_Handler scheduling operations
+
+ virtual int schedule_wakeup (ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask masks_to_be_added) = 0;
+ // Add <masks_to_be_added> to the <event_handler>'s entry.
+ // <event_handler> must already have been registered.
+
+ virtual int schedule_wakeup (ACE_HANDLE handle,
+ ACE_Reactor_Mask masks_to_be_added) = 0;
+ // Add <masks_to_be_added> to the <handle>'s entry. <event_handler>
+ // associated with <handle> must already have been registered.
+
+ virtual int cancel_wakeup (ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask masks_to_be_cleared) = 0;
+ // Clear <masks_to_be_cleared> from the <event_handler>'s entry.
+
+ virtual int cancel_wakeup (ACE_HANDLE handle,
+ ACE_Reactor_Mask masks_to_be_cleared) = 0;
+ // Clear <masks_to_be_cleared> from the <handle>'s entry.
+
+ // = Notification methods.
+
+ virtual int notify (ACE_Event_Handler *event_handler = 0,
+ ACE_Reactor_Mask mask = ACE_Event_Handler::EXCEPT_MASK,
+ ACE_Time_Value * = 0) = 0;
+ // Notify <event_handler> of <mask> event. The <ACE_Time_Value>
+ // indicates how long to blocking trying to notify. 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) = 0;
+ // Set the maximum number of times that ACE_Reactor_Impl 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) = 0;
+ // Get the maximum number of times that the ACE_Reactor_Impl 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) = 0;
+ // Check to see if <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) = 0;
+ // Check to see if <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) = 0;
+ // Returns true if Reactor has been successfully initialized, else
+ // false.
+
+ virtual size_t size (void) = 0;
+ // Returns the current size of the Reactor's internal descriptor
+ // table.
+
+ virtual ACE_Lock &lock (void) = 0;
+ // Returns a reference to the Reactor's internal lock.
+
+ virtual void wakeup_all_threads (void) = 0;
+ // Wake up all threads in waiting in the event loop
+
+ virtual int owner (ACE_thread_t new_owner, ACE_thread_t *old_owner = 0) = 0;
+ // Transfers ownership of Reactor_Impl to the <new_owner>.
+
+ virtual int owner (ACE_thread_t *owner) = 0;
+ // Return the ID of the "owner" thread.
+
+ virtual void requeue_position (int) = 0;
+ // Set position of the owner thread.
+
+ virtual int requeue_position (void) = 0;
+ // Get position of the owner thread.
+
+ // = Low-level wait_set mask manipulation methods.
+
+ virtual int mask_ops (ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask mask,
+ int ops) = 0;
+ // GET/SET/ADD/CLR the dispatch mask "bit" bound with the
+ // <event_handler> and <mask>.
+
+ virtual int mask_ops (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask,
+ int ops) = 0;
+ // GET/SET/ADD/CLR the dispatch MASK "bit" bound with the <handle>
+ // and <mask>.
+
+ // = Low-level ready_set mask manipulation methods.
+ virtual int ready_ops (ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask mask,
+ int ops) = 0;
+ // GET/SET/ADD/CLR the ready "bit" bound with the <event_handler>
+ // and <mask>.
+
+ virtual int ready_ops (ACE_HANDLE handle,
+ ACE_Reactor_Mask,
+ int ops) = 0;
+ // GET/SET/ADD/CLR the ready "bit" bound with the <handle> and <mask>.
+
+ ACE_ALLOC_HOOK_DECLARE;
+ // Declare the dynamic allocation hooks.
+};
+
+#endif /* ACE_REACTOR_IMPL_H */
diff --git a/ace/Select_Reactor.cpp b/ace/Select_Reactor.cpp
new file mode 100644
index 00000000000..01b9c2df138
--- /dev/null
+++ b/ace/Select_Reactor.cpp
@@ -0,0 +1,1798 @@
+// $Id$
+
+#define ACE_BUILD_DLL
+
+#include "ace/Select_Reactor.h"
+
+#include "ace/Reactor.h"
+#include "ace/Synch_T.h"
+#include "ace/SOCK_Acceptor.h"
+#include "ace/SOCK_Connector.h"
+#include "ace/Timer_Heap.h"
+
+#if !defined (__ACE_INLINE__)
+#include "ace/Select_Reactor.i"
+#endif /* __ACE_INLINE__ */
+
+ACE_ALLOC_HOOK_DEFINE(ACE_Select_Reactor)
+
+#if defined (ACE_WIN32)
+#define ACE_SELECT_REACTOR_HANDLE(H) (this->event_handlers_[(H)].handle_)
+#define ACE_SELECT_REACTOR_EVENT_HANDLER(THIS,H) ((THIS)->event_handlers_[(H)].event_handler_)
+#else
+#define ACE_SELECT_REACTOR_HANDLE(H) (H)
+#define ACE_SELECT_REACTOR_EVENT_HANDLER(THIS,H) ((THIS)->event_handlers_[(H)])
+#endif /* ACE_WIN32 */
+
+// Performs sanity checking on the ACE_HANDLE.
+
+int
+ACE_Select_Reactor_Handler_Repository::invalid_handle (ACE_HANDLE handle)
+{
+ ACE_TRACE ("ACE_Select_Reactor_Handler_Repository::invalid_handle");
+#if defined (ACE_WIN32)
+ // It's too expensive to perform more exhaustive validity checks on
+ // Win32 due to the way that they implement SOCKET HANDLEs.
+ if (handle == ACE_INVALID_HANDLE)
+#else /* !ACE_WIN32 */
+ if (handle < 0 || handle >= this->max_size_)
+#endif /* ACE_WIN32 */
+ {
+ errno = EINVAL;
+ return 1;
+ }
+ else
+ return 0;
+}
+
+// Performs sanity checking on the ACE_HANDLE.
+
+int
+ACE_Select_Reactor_Handler_Repository::handle_in_range (ACE_HANDLE handle)
+{
+ ACE_TRACE ("ACE_Select_Reactor_Handler_Repository::handle_in_range");
+#if defined (ACE_WIN32)
+ // It's too expensive to perform more exhaustive validity checks on
+ // Win32 due to the way that they implement SOCKET HANDLEs.
+ if (handle != ACE_INVALID_HANDLE)
+#else /* !ACE_WIN32 */
+ if (handle >= 0 && handle < this->max_handlep1_)
+#endif /* ACE_WIN32 */
+ return 1;
+ else
+ {
+ errno = EINVAL;
+ return 0;
+ }
+}
+
+size_t
+ACE_Select_Reactor_Handler_Repository::max_handlep1 (void)
+{
+ ACE_TRACE ("ACE_Select_Reactor_Handler_Repository::max_handlep1");
+
+ return this->max_handlep1_;
+}
+
+int
+ACE_Select_Reactor_Handler_Repository::open (size_t size)
+{
+ ACE_TRACE ("ACE_Select_Reactor_Handler_Repository::open");
+ this->max_size_ = size;
+ this->max_handlep1_ = 0;
+
+#if defined (ACE_WIN32)
+ // Try to allocate the memory.
+ ACE_NEW_RETURN (this->event_handlers_,
+ ACE_NT_EH_Record[size],
+ -1);
+
+ // Initialize the ACE_Event_Handler * to { ACE_INVALID_HANDLE, 0 }.
+ for (size_t h = 0; h < size; h++)
+ {
+ ACE_SELECT_REACTOR_HANDLE (h) = ACE_INVALID_HANDLE;
+ ACE_SELECT_REACTOR_EVENT_HANDLER (this, h) = 0;
+ }
+#else
+ // Try to allocate the memory.
+ ACE_NEW_RETURN (this->event_handlers_,
+ ACE_Event_Handler *[size],
+ -1);
+
+ // Initialize the ACE_Event_Handler * to NULL.
+ for (size_t h = 0; h < size; h++)
+ ACE_SELECT_REACTOR_EVENT_HANDLER (this, h) = 0;
+#endif /* ACE_WIN32 */
+ return 0;
+}
+
+// Initialize a repository of the appropriate <size>.
+
+ACE_Select_Reactor_Handler_Repository::ACE_Select_Reactor_Handler_Repository (ACE_Select_Reactor &select_reactor)
+ : select_reactor_ (select_reactor),
+ max_size_ (0),
+ max_handlep1_ (0),
+ event_handlers_ (0)
+{
+ ACE_TRACE ("ACE_Select_Reactor_Handler_Repository::ACE_Select_Reactor_Handler_Repository");
+}
+
+int
+ACE_Select_Reactor_Handler_Repository::unbind_all (void)
+{
+ // Unbind all of the <handle, ACE_Event_Handler>s.
+ for (int handle = 0;
+ handle < this->max_handlep1_;
+ handle++)
+ this->unbind (ACE_SELECT_REACTOR_HANDLE (handle),
+ ACE_Event_Handler::ALL_EVENTS_MASK);
+
+ return 0;
+}
+
+int
+ACE_Select_Reactor_Handler_Repository::close (void)
+{
+ ACE_TRACE ("ACE_Select_Reactor_Handler_Repository::close");
+
+ if (this->event_handlers_ != 0)
+ {
+ this->unbind_all ();
+
+ delete [] this->event_handlers_;
+ this->event_handlers_ = 0;
+ }
+ return 0;
+}
+
+// Return the <ACE_Event_Handler *> associated with the <handle>.
+
+ACE_Event_Handler *
+ACE_Select_Reactor_Handler_Repository::find (ACE_HANDLE handle,
+ size_t *index_p)
+{
+ ACE_TRACE ("ACE_Select_Reactor_Handler_Repository::find");
+
+ ACE_Event_Handler *eh = 0;
+ ssize_t i;
+
+ // Only bother to search for the <handle> if it's in range.
+ if (this->handle_in_range (handle))
+ {
+#if defined (ACE_WIN32)
+ i = 0;
+
+ for (; i < this->max_handlep1_; i++)
+ if (ACE_SELECT_REACTOR_HANDLE (i) == handle)
+ {
+ eh = ACE_SELECT_REACTOR_EVENT_HANDLER (this, i);
+ break;
+ }
+#else
+ i = handle;
+
+ eh = ACE_SELECT_REACTOR_EVENT_HANDLER (this, handle);
+#endif /* ACE_WIN32 */
+ }
+ else
+ // g++ can't figure out that i won't be used below if the handle
+ // is out of range, so keep it happy by defining i here . . .
+ i = 0;
+
+ if (eh != 0 && index_p != 0)
+ *index_p = i;
+ else
+ errno = ENOENT;
+
+ return eh;
+}
+
+// Bind the <ACE_Event_Handler *> to the <ACE_HANDLE>.
+
+int
+ACE_Select_Reactor_Handler_Repository::bind (ACE_HANDLE handle,
+ ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask mask)
+{
+ ACE_TRACE ("ACE_Select_Reactor_Handler_Repository::bind");
+
+ if (handle == ACE_INVALID_HANDLE)
+ handle = event_handler->get_handle ();
+
+ if (this->invalid_handle (handle))
+ return -1;
+
+#if defined (ACE_WIN32)
+ int assigned_slot = -1;
+
+ for (ssize_t i = 0; i < this->max_handlep1_; i++)
+ {
+ // Found it, so let's just reuse this location.
+ if (ACE_SELECT_REACTOR_HANDLE (i) == handle)
+ {
+ assigned_slot = i;
+ break;
+ }
+ // Here's the first free slot, so let's take it.
+ else if (ACE_SELECT_REACTOR_HANDLE (i) == ACE_INVALID_HANDLE
+ && assigned_slot == -1)
+ assigned_slot = i;
+ }
+
+ if (assigned_slot > -1)
+ // We found a free spot, let's reuse it.
+ {
+ ACE_SELECT_REACTOR_HANDLE (assigned_slot) = handle;
+ ACE_SELECT_REACTOR_EVENT_HANDLER (this, assigned_slot) = event_handler;
+ }
+ else if (this->max_handlep1_ < this->max_size_)
+ {
+ // Insert at the end of the active portion.
+ ACE_SELECT_REACTOR_HANDLE (this->max_handlep1_) = handle;
+ ACE_SELECT_REACTOR_EVENT_HANDLER (this, this->max_handlep1_) = event_handler;
+ this->max_handlep1_++;
+ }
+ else
+ {
+ // No more room at the inn!
+ errno = ENOMEM;
+ return -1;
+ }
+#else
+ ACE_SELECT_REACTOR_EVENT_HANDLER (this, handle) = event_handler;
+
+ if (this->max_handlep1_ < handle + 1)
+ this->max_handlep1_ = handle + 1;
+#endif /* ACE_WIN32 */
+
+ // Add the <mask> for this <handle> in the Select_Reactor's wait_set.
+ this->select_reactor_.bit_ops (handle,
+ mask,
+ this->select_reactor_.wait_set_,
+ ACE_Reactor::ADD_MASK);
+
+ // Note the fact that we've changed the state of the <wait_set_>,
+ // which is used by the dispatching loop to determine whether it can
+ // keep going or if it needs to reconsult select().
+ this->select_reactor_.state_changed_ = 1;
+
+ return 0;
+}
+
+// Remove the binding of <ACE_HANDLE>.
+
+int
+ACE_Select_Reactor_Handler_Repository::unbind (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask)
+{
+ ACE_TRACE ("ACE_Select_Reactor_Handler_Repository::unbind");
+
+ size_t index;
+ ACE_Event_Handler *eh = this->find (handle, &index);
+
+ if (eh == 0)
+ return -1;
+
+ // Clear out the <mask> bits in the Select_Reactor's wait_set.
+ this->select_reactor_.bit_ops (handle,
+ mask,
+ this->select_reactor_.wait_set_,
+ ACE_Reactor::CLR_MASK);
+
+ // Note the fact that we've changed the state of the <wait_set_>,
+ // which is used by the dispatching loop to determine whether it can
+ // keep going or if it needs to reconsult select().
+ this->select_reactor_.state_changed_ = 1;
+
+ // Close down the <Event_Handler> unless we've been instructed not
+ // to.
+ if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::DONT_CALL) == 0)
+ eh->handle_close (handle, mask);
+
+ // If there are no longer any outstanding events on this <handle>
+ // then we can totally shut down the Event_Handler.
+ if (this->select_reactor_.wait_set_.rd_mask_.is_set (handle) == 0
+ && this->select_reactor_.wait_set_.wr_mask_.is_set (handle) == 0
+ && this->select_reactor_.wait_set_.ex_mask_.is_set (handle) == 0)
+#if defined (ACE_WIN32)
+ {
+ ACE_SELECT_REACTOR_HANDLE (index) = ACE_INVALID_HANDLE;
+ ACE_SELECT_REACTOR_EVENT_HANDLER (this, index) = 0;
+
+ if (this->max_handlep1_ == (int) index + 1)
+ {
+ // We've deleted the last entry (i.e., i + 1 == the current
+ // size of the array), so we need to figure out the last
+ // valid place in the array that we should consider in
+ // subsequent searches.
+
+ for (int i = this->max_handlep1_ - 1;
+ i >= 0 && ACE_SELECT_REACTOR_HANDLE (i) == ACE_INVALID_HANDLE;
+ i--)
+ continue;
+
+ this->max_handlep1_ = i + 1;
+ }
+ }
+#else
+ {
+ ACE_SELECT_REACTOR_EVENT_HANDLER (this, handle) = 0;
+
+ if (this->max_handlep1_ == handle + 1)
+ {
+ // We've deleted the last entry, so we need to figure out
+ // the last valid place in the array that is worth looking
+ // at.
+ ACE_HANDLE rd_max = this->select_reactor_.wait_set_.rd_mask_.max_set ();
+ ACE_HANDLE wr_max = this->select_reactor_.wait_set_.wr_mask_.max_set ();
+ ACE_HANDLE ex_max = this->select_reactor_.wait_set_.ex_mask_.max_set ();
+
+ // Compute the maximum of three values.
+ this->max_handlep1_ = rd_max < wr_max ? wr_max : rd_max;
+
+ if (this->max_handlep1_ < ex_max)
+ this->max_handlep1_ = ex_max;
+
+ this->max_handlep1_++;
+ }
+ }
+#endif /* ACE_WIN32 */
+
+ return 0;
+}
+
+ACE_Select_Reactor_Handler_Repository_Iterator::ACE_Select_Reactor_Handler_Repository_Iterator
+(const ACE_Select_Reactor_Handler_Repository *s)
+ : rep_ (s),
+ current_ (-1)
+{
+ this->advance ();
+}
+
+// Pass back the <next_item> that hasn't been seen in the Set.
+// Returns 0 when all items have been seen, else 1.
+
+int
+ACE_Select_Reactor_Handler_Repository_Iterator::next (ACE_Event_Handler *&next_item)
+{
+ int result = 1;
+
+ if (this->current_ >= this->rep_->max_handlep1_)
+ result = 0;
+ else
+ next_item = ACE_SELECT_REACTOR_EVENT_HANDLER (this->rep_,
+ this->current_);
+ return result;
+}
+
+int
+ACE_Select_Reactor_Handler_Repository_Iterator::done (void) const
+{
+ return this->current_ >= this->rep_->max_handlep1_;
+}
+
+// Move forward by one element in the set.
+
+int
+ACE_Select_Reactor_Handler_Repository_Iterator::advance (void)
+{
+ if (this->current_ < this->rep_->max_handlep1_)
+ this->current_++;
+
+ while (this->current_ < this->rep_->max_handlep1_)
+ if (ACE_SELECT_REACTOR_EVENT_HANDLER (this->rep_, this->current_) != 0)
+ return 1;
+ else
+ this->current_++;
+
+ return this->current_ < this->rep_->max_handlep1_;
+}
+
+// Dump the state of an object.
+
+void
+ACE_Select_Reactor_Handler_Repository_Iterator::dump (void) const
+{
+ ACE_TRACE ("ACE_Select_Reactor_Handler_Repository_Iterator::dump");
+
+ ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
+ ACE_DEBUG ((LM_DEBUG, "rep_ = %u", this->rep_));
+ ACE_DEBUG ((LM_DEBUG, "current_ = %d", this->current_));
+ ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
+}
+
+void
+ACE_Select_Reactor_Handler_Repository::dump (void) const
+{
+ ACE_TRACE ("ACE_Select_Reactor_Handler_Repository::dump");
+
+ ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
+ ACE_DEBUG ((LM_DEBUG,
+ "(%t) max_handlep1_ = %d, max_size_ = %d\n",
+ this->max_handlep1_, this->max_size_));
+ ACE_DEBUG ((LM_DEBUG, "["));
+
+ ACE_Event_Handler *eh = 0;
+
+ for (ACE_Select_Reactor_Handler_Repository_Iterator iter (this);
+ iter.next (eh) != 0;
+ iter.advance ())
+ ACE_DEBUG ((LM_DEBUG, " (eh = %x, eh->handle_ = %d)",
+ eh, eh->get_handle ()));
+
+ ACE_DEBUG ((LM_DEBUG, " ]"));
+ ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
+}
+
+ACE_ALLOC_HOOK_DEFINE(ACE_Select_Reactor_Handler_Repository_Iterator)
+
+ int
+ACE_Select_Reactor::any_ready (ACE_Select_Reactor_Handle_Set &wait_set)
+{
+ ACE_TRACE ("ACE_Select_Reactor::fill_in_ready");
+
+#if !defined (ACE_WIN32)
+ // Make this call signal safe.
+ ACE_Sig_Guard sb;
+#endif /* ACE_WIN32 */
+
+ int number_ready = this->ready_set_.rd_mask_.num_set ()
+ + this->ready_set_.wr_mask_.num_set ()
+ + this->ready_set_.ex_mask_.num_set ();
+
+ if (number_ready > 0)
+ {
+ wait_set.rd_mask_ = this->wait_set_.rd_mask_;
+ wait_set.wr_mask_ = this->wait_set_.wr_mask_;
+ wait_set.ex_mask_ = this->wait_set_.ex_mask_;
+
+ this->ready_set_.rd_mask_.reset ();
+ this->ready_set_.wr_mask_.reset ();
+ this->ready_set_.ex_mask_.reset ();
+ }
+
+ return number_ready;
+}
+
+int
+ACE_Select_Reactor::handler_i (int signum, ACE_Event_Handler **eh)
+{
+ ACE_TRACE ("ACE_Select_Reactor::handler_i");
+ ACE_Event_Handler *handler = this->signal_handler_->handler (signum);
+
+ if (handler == 0)
+ return -1;
+ else if (*eh != 0)
+ *eh = handler;
+ return 0;
+}
+
+int
+ACE_Select_Reactor::initialized (void)
+{
+ ACE_TRACE ("ACE_Select_Reactor::initialized");
+ ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_MUTEX, ace_mon, this->token_, 0));
+ return this->initialized_;
+}
+
+int
+ACE_Select_Reactor::owner (ACE_thread_t tid, ACE_thread_t *o_id)
+{
+ ACE_TRACE ("ACE_Select_Reactor::owner");
+ ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_MUTEX, ace_mon, this->token_, -1));
+
+ if (o_id)
+ *o_id = this->owner_;
+
+ this->owner_ = tid;
+
+ return 0;
+}
+
+int
+ACE_Select_Reactor::owner (ACE_thread_t *t_id)
+{
+ ACE_TRACE ("ACE_Select_Reactor::owner");
+ ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_MUTEX, ace_mon, this->token_, -1));
+ *t_id = this->owner_;
+ return 0;
+}
+
+void
+ACE_Select_Reactor::requeue_position (int rp)
+{
+ ACE_TRACE ("ACE_Select_Reactor::requeue_position");
+ ACE_MT (ACE_GUARD (ACE_SELECT_REACTOR_MUTEX, ace_mon, this->token_));
+#if defined (ACE_WIN32)
+ ACE_UNUSED_ARG (rp);
+ // Must always requeue ourselves "next" on Win32.
+ this->requeue_position_ = 0;
+#else
+ this->requeue_position_ = rp;
+#endif /* ACE_WIN32 */
+}
+
+int
+ACE_Select_Reactor::requeue_position (void)
+{
+ ACE_TRACE ("ACE_Select_Reactor::requeue_position");
+ ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_MUTEX, ace_mon, this->token_, -1));
+ return this->requeue_position_;
+}
+
+void
+ACE_Select_Reactor::max_notify_iterations (int iterations)
+{
+ ACE_TRACE ("ACE_Select_Reactor::max_notify_iterations");
+ ACE_MT (ACE_GUARD (ACE_SELECT_REACTOR_MUTEX, ace_mon, this->token_));
+
+ // Must always be > 0 or < 0 to optimize the loop exit condition.
+ if (iterations == 0)
+ iterations = 1;
+
+ this->max_notify_iterations_ = iterations;
+}
+
+int
+ACE_Select_Reactor::max_notify_iterations (void)
+{
+ ACE_TRACE ("ACE_Select_Reactor::max_notify_iterations");
+ ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_MUTEX, ace_mon, this->token_, -1));
+ return this->max_notify_iterations_;
+}
+
+// Enqueue ourselves into the list of waiting threads.
+void
+ACE_Select_Reactor::renew (void)
+{
+ ACE_TRACE ("ACE_Select_Reactor::renew");
+#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+ this->token_.renew (this->requeue_position_);
+#endif /* defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) */
+}
+
+#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+
+void
+ACE_Select_Reactor_Token::dump (void) const
+{
+ ACE_TRACE ("ACE_Select_Reactor_Token::dump");
+
+ ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
+ ACE_DEBUG ((LM_DEBUG, "\n"));
+ ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
+}
+
+ACE_Select_Reactor_Token::ACE_Select_Reactor_Token (ACE_Select_Reactor &r)
+ : select_reactor_ (r)
+#if defined (ACE_SELECT_REACTOR_HAS_DEADLOCK_DETECTION)
+ , ACE_Local_Mutex (0) // Triggers unique name by stringifying "this"...
+#endif /* ACE_SELECT_REACTOR_HAS_DEADLOCK_DETECTION */
+{
+ ACE_TRACE ("ACE_Select_Reactor_Token::ACE_Select_Reactor_Token");
+}
+
+// Used to wakeup the Select_Reactor.
+
+void
+ACE_Select_Reactor_Token::sleep_hook (void)
+{
+ ACE_TRACE ("ACE_Select_Reactor_Token::sleep_hook");
+ if (this->select_reactor_.notify () == -1)
+ ACE_ERROR ((LM_ERROR, "%p\n", "sleep_hook failed"));
+}
+
+#endif /* ACE_MT_SAFE */
+
+void
+ACE_Select_Reactor_Notify::dump (void) const
+{
+ ACE_TRACE ("ACE_Select_Reactor_Notify::dump");
+
+ ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
+ ACE_DEBUG ((LM_DEBUG, "select_reactor_ = %x", this->select_reactor_));
+ this->notification_pipe_.dump ();
+ ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
+}
+
+int
+ACE_Select_Reactor_Notify::open (ACE_Select_Reactor *r)
+{
+ ACE_TRACE ("ACE_Select_Reactor_Notify::open");
+
+ this->select_reactor_ = r;
+
+ if (this->notification_pipe_.open () == -1)
+ return -1;
+
+ // There seems to be a Win32 bug with this... Set this into
+ // non-blocking mode.
+ if (ACE::set_flags (this->notification_pipe_.read_handle (),
+ ACE_NONBLOCK) == -1)
+ return -1;
+ else
+ return this->select_reactor_->register_handler
+ (this->notification_pipe_.read_handle (),
+ this,
+ ACE_Event_Handler::READ_MASK);
+}
+
+int
+ACE_Select_Reactor_Notify::close (void)
+{
+ ACE_TRACE ("ACE_Select_Reactor_Notify::close");
+ return this->notification_pipe_.close ();
+}
+
+ssize_t
+ACE_Select_Reactor_Notify::notify (ACE_Event_Handler *eh,
+ ACE_Reactor_Mask mask,
+ ACE_Time_Value *timeout)
+{
+ ACE_TRACE ("ACE_Select_Reactor_Notify::notify");
+
+ ACE_Notification_Buffer buffer (eh, mask);
+
+ ssize_t n = ACE::send (this->notification_pipe_.write_handle (),
+ (char *) &buffer,
+ sizeof buffer,
+ timeout);
+ return n == -1 ? -1 : 0;
+}
+
+// Handles pending threads (if any) that are waiting to unblock the
+// Select_Reactor.
+
+int
+ACE_Select_Reactor_Notify::dispatch_notifications (int &number_of_active_handles,
+ const ACE_Handle_Set &rd_mask)
+{
+ ACE_TRACE ("ACE_Select_Reactor_Notify::handle_notification");
+
+ ACE_HANDLE read_handle =
+ this->notification_pipe_.read_handle ();
+
+ if (rd_mask.is_set (read_handle))
+ {
+ number_of_active_handles--;
+ return this->handle_input (read_handle);
+ }
+ else
+ return 0;
+}
+
+// Special trick to unblock select() when updates occur in somewhere
+// other than the main ACE_Select_Reactor thread. All we do is write data to
+// a pipe that the ACE_Select_Reactor is listening on. Thanks to Paul
+// Stephenson for suggesting this approach.
+
+int
+ACE_Select_Reactor_Notify::handle_input (ACE_HANDLE handle)
+{
+ ACE_TRACE ("ACE_Select_Reactor_Notify::handle_input");
+ // Precondition: this->select_reactor_.token_.current_owner () ==
+ // ACE_Thread::self ();
+
+ ACE_Notification_Buffer buffer;
+ ssize_t n;
+ int number_dispatched = 0;
+
+ while ((n = ACE::recv (handle, (char *) &buffer, sizeof buffer)) > 0)
+ {
+ // Check to see if we've got a short read.
+ if (n != sizeof buffer)
+ {
+ ssize_t remainder = sizeof buffer - n;
+
+ // If so, try to recover by reading the remainder. If this doesn't
+ // work we're in big trouble since the input stream won't be aligned
+ // correctly. I'm not sure quite what to do at this point. It's
+ // probably best just to return -1.
+ if (ACE::recv (handle, ((char *) &buffer) + n, remainder) != remainder)
+ return -1;
+ }
+
+ // If eh == 0 then another thread is unblocking the ACE_Select_Reactor
+ // to update the ACE_Select_Reactor's internal structures. Otherwise,
+ // we need to dispatch the appropriate handle_* method on the
+ // ACE_Event_Handler pointer we've been passed.
+ if (buffer.eh_ != 0)
+ {
+ int result = 0;
+
+ switch (buffer.mask_)
+ {
+ case ACE_Event_Handler::READ_MASK:
+ case ACE_Event_Handler::ACCEPT_MASK:
+ result = buffer.eh_->handle_input (ACE_INVALID_HANDLE);
+ break;
+ case ACE_Event_Handler::WRITE_MASK:
+ result = buffer.eh_->handle_output (ACE_INVALID_HANDLE);
+ break;
+ case ACE_Event_Handler::EXCEPT_MASK:
+ result = buffer.eh_->handle_exception (ACE_INVALID_HANDLE);
+ break;
+ default:
+ // Should we bail out if we get an invalid mask?
+ ACE_ERROR ((LM_ERROR, "invalid mask = %d\n", buffer.mask_));
+ }
+ if (result == -1)
+ buffer.eh_->handle_close (ACE_INVALID_HANDLE,
+ ACE_Event_Handler::EXCEPT_MASK);
+ }
+
+ number_dispatched++;
+
+ // Bail out if we've reached the <notify_threshold_>. Note that
+ // by default <notify_threshold_> is -1, so we'll loop until all
+ // the notifications in the pipe have been dispatched.
+ if (number_dispatched == this->select_reactor_->max_notify_iterations_)
+ break;
+ }
+
+ // Reassign number_dispatched to -1 if things have gone seriously
+ // wrong.
+ if (n <= 0 && errno != EWOULDBLOCK)
+ number_dispatched = -1;
+
+ // Enqueue ourselves into the list of waiting threads. When we
+ // reacquire the token we'll be off and running again with ownership
+ // of the token. The postcondition of this call is that
+ // this->select_reactor_.token_.current_owner () == ACE_Thread::self ();
+ this->select_reactor_->renew ();
+ return number_dispatched;
+}
+
+int
+ACE_Select_Reactor::notify (ACE_Event_Handler *eh,
+ ACE_Reactor_Mask mask,
+ ACE_Time_Value *timeout)
+{
+ ACE_TRACE ("ACE_Select_Reactor::notify");
+
+ ssize_t n = 0;
+
+ // Pass over both the Event_Handler *and* the mask to allow the
+ // caller to dictate which Event_Handler method the receiver
+ // invokes. Note that this call can timeout.
+
+ n = this->notify_handler_.notify (eh, mask, timeout);
+ return n == -1 ? -1 : 0;
+}
+
+int
+ACE_Select_Reactor::resume_handler (ACE_HANDLE handle)
+{
+ ACE_TRACE ("ACE_Select_Reactor::resume_handler");
+ ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_MUTEX, ace_mon, this->token_, -1));
+ return this->resume_i (handle);
+}
+
+int
+ACE_Select_Reactor::suspend_handler (ACE_HANDLE handle)
+{
+ ACE_TRACE ("ACE_Select_Reactor::suspend_handler");
+ ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_MUTEX, ace_mon, this->token_, -1));
+ return this->suspend_i (handle);
+}
+
+int
+ACE_Select_Reactor::suspend_handlers (void)
+{
+ ACE_TRACE ("ACE_Select_Reactor::suspend_handlers");
+ ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_MUTEX, ace_mon, this->token_, -1));
+
+ ACE_Event_Handler *eh = 0;
+
+ for (ACE_Select_Reactor_Handler_Repository_Iterator iter (&this->handler_rep_);
+ iter.next (eh) != 0;
+ iter.advance ())
+ this->suspend_i (eh->get_handle ());
+
+ return 0;
+}
+
+int
+ACE_Select_Reactor::resume_handlers (void)
+{
+ ACE_TRACE ("ACE_Select_Reactor::resume_handlers");
+ ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_MUTEX, ace_mon, this->token_, -1));
+
+ ACE_Event_Handler *eh = 0;
+
+ for (ACE_Select_Reactor_Handler_Repository_Iterator iter (&this->handler_rep_);
+ iter.next (eh) != 0;
+ iter.advance ())
+ this->resume_i (eh->get_handle ());
+
+ return 0;
+}
+
+int
+ACE_Select_Reactor::register_handler (ACE_Event_Handler *handler,
+ ACE_Reactor_Mask mask)
+{
+ ACE_TRACE ("ACE_Select_Reactor::register_handler");
+ ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_MUTEX, ace_mon, this->token_, -1));
+ return this->register_handler_i (handler->get_handle (), handler, mask);
+}
+
+int
+ACE_Select_Reactor::register_handler (ACE_HANDLE handle,
+ ACE_Event_Handler *handler,
+ ACE_Reactor_Mask mask)
+{
+ ACE_TRACE ("ACE_Select_Reactor::register_handler");
+ ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_MUTEX, ace_mon, this->token_, -1));
+ return this->register_handler_i (handle, handler, mask);
+}
+
+int
+ACE_Select_Reactor::register_handler (const ACE_Handle_Set &handles,
+ ACE_Event_Handler *handler,
+ ACE_Reactor_Mask mask)
+{
+ ACE_TRACE ("ACE_Select_Reactor::register_handler");
+ ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_MUTEX, ace_mon, this->token_, -1));
+ return this->register_handler_i (handles, handler, mask);
+}
+
+int
+ACE_Select_Reactor::handler (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask,
+ ACE_Event_Handler **handler)
+{
+ ACE_TRACE ("ACE_Select_Reactor::handler");
+ ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_MUTEX, ace_mon, this->token_, -1));
+ return this->handler_i (handle, mask, handler);
+}
+
+int
+ACE_Select_Reactor::remove_handler (const ACE_Handle_Set &handles,
+ ACE_Reactor_Mask mask)
+{
+ ACE_TRACE ("ACE_Select_Reactor::remove_handler");
+ ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_MUTEX, ace_mon, this->token_, -1));
+ return this->remove_handler_i (handles, mask);
+}
+
+int
+ACE_Select_Reactor::remove_handler (ACE_Event_Handler *handler,
+ ACE_Reactor_Mask mask)
+{
+ ACE_TRACE ("ACE_Select_Reactor::remove_handler");
+ ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_MUTEX, ace_mon, this->token_, -1));
+ return this->remove_handler_i (handler->get_handle (), mask);
+}
+
+int
+ACE_Select_Reactor::remove_handler (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask)
+{
+ ACE_TRACE ("ACE_Select_Reactor::remove_handler");
+ ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_MUTEX, ace_mon, this->token_, -1));
+ return this->remove_handler_i (handle, mask);
+}
+
+// Performs operations on the "ready" bits.
+
+int
+ACE_Select_Reactor::ready_ops (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask,
+ int ops)
+{
+ ACE_TRACE ("ACE_Select_Reactor::ready_ops");
+ ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_MUTEX, ace_mon, this->token_, -1));
+ return this->bit_ops (handle,
+ mask,
+ this->ready_set_,
+ ops);
+}
+
+int
+ACE_Select_Reactor::open (size_t size,
+ int restart,
+ ACE_Sig_Handler *sh,
+ ACE_Timer_Queue *tq)
+{
+ ACE_TRACE ("ACE_Select_Reactor::open");
+ ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_MUTEX, ace_mon, this->token_, -1));
+
+ // Can't initialize ourselves more than once.
+ if (this->initialized_ > 0)
+ return -1;
+
+ this->owner_ = ACE_Thread::self ();
+ this->restart_ = restart;
+ this->signal_handler_ = sh;
+ this->timer_queue_ = tq;
+
+ int result = 0;
+
+ // Allows the signal handler to be overridden.
+ if (this->signal_handler_ == 0)
+ {
+ this->signal_handler_ = new ACE_Sig_Handler;
+
+ if (this->signal_handler_ == 0)
+ result = -1;
+ else
+ this->delete_signal_handler_ = 1;
+ }
+
+ if (result != -1 && this->timer_queue_ == 0)
+ {
+ this->timer_queue_ = new ACE_Timer_Heap;
+
+ if (this->timer_queue_ == 0)
+ result = -1;
+ else
+ this->delete_timer_queue_ = 1;
+ }
+
+ if (result != -1 && this->handler_rep_.open (size) == -1)
+ result = -1;
+ else if (this->notify_handler_.open (this) == -1)
+ result = -1;
+
+ if (result != -1)
+ // We're all set to go.
+ this->initialized_ = 1;
+ else
+ // This will close down all the allocated resources properly.
+ this->close ();
+
+ return result;
+}
+
+ACE_Select_Reactor::ACE_Select_Reactor (ACE_Sig_Handler *sh,
+ ACE_Timer_Queue *tq)
+ : handler_rep_ (*this),
+ timer_queue_ (0),
+ delete_timer_queue_ (0),
+ delete_signal_handler_ (0),
+ requeue_position_ (-1), // Requeue at end of waiters by default.
+ max_notify_iterations_ (-1),
+ initialized_ (0),
+ state_changed_ (0),
+#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+ token_ (*this),
+#endif /* ACE_MT_SAFE */
+ lock_adapter_ (token_)
+{
+ ACE_TRACE ("ACE_Select_Reactor::ACE_Select_Reactor");
+
+ if (this->open (ACE_Select_Reactor::DEFAULT_SIZE, 0, sh, tq) == -1)
+ ACE_ERROR ((LM_ERROR, "%p\n", "open failed"));
+}
+
+// Initialize ACE_Select_Reactor.
+
+ACE_Select_Reactor::ACE_Select_Reactor (size_t size,
+ int rs,
+ ACE_Sig_Handler *sh,
+ ACE_Timer_Queue *tq)
+ : handler_rep_ (*this),
+ timer_queue_ (0),
+ delete_timer_queue_ (0),
+ delete_signal_handler_ (0),
+ requeue_position_ (-1), // Requeue at end of waiters by default.
+ max_notify_iterations_ (-1),
+ initialized_ (0),
+ state_changed_ (0),
+#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+ token_ (*this),
+#endif /* ACE_MT_SAFE */
+ lock_adapter_ (token_)
+{
+ ACE_TRACE ("ACE_Select_Reactor::ACE_Select_Reactor");
+
+ if (this->open (size, rs, sh, tq) == -1)
+ ACE_ERROR ((LM_ERROR, "%p\n", "open failed"));
+}
+
+// Close down the ACE_Select_Reactor instance, detaching any remaining
+// Event_Handers. This had better be called from the main event loop
+// thread...
+
+int
+ACE_Select_Reactor::close (void)
+{
+ ACE_TRACE ("ACE_Select_Reactor::close");
+ ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_MUTEX, ace_mon, this->token_, -1));
+
+ if (this->delete_signal_handler_)
+ delete this->signal_handler_;
+ this->signal_handler_ = 0;
+
+ this->handler_rep_.close ();
+
+ if (this->delete_timer_queue_)
+ delete this->timer_queue_;
+ this->timer_queue_ = 0;
+
+ this->notify_handler_.close ();
+ this->initialized_ = 0;
+
+ return 0;
+}
+
+ACE_Select_Reactor::~ACE_Select_Reactor (void)
+{
+ ACE_TRACE ("ACE_Select_Reactor::~ACE_Select_Reactor");
+ this->close ();
+}
+
+int
+ACE_Select_Reactor::remove_handler_i (const ACE_Handle_Set &handles,
+ ACE_Reactor_Mask mask)
+{
+ ACE_TRACE ("ACE_Select_Reactor::remove_handler_i");
+ ACE_HANDLE h;
+
+ ACE_Handle_Set_Iterator handle_iter (handles);
+
+ while ((h = handle_iter ()) != ACE_INVALID_HANDLE)
+ if (this->remove_handler_i (h, mask) == -1)
+ return -1;
+
+ return 0;
+}
+
+int
+ACE_Select_Reactor::register_handler_i (const ACE_Handle_Set &handles,
+ ACE_Event_Handler *handler,
+ ACE_Reactor_Mask mask)
+{
+ ACE_TRACE ("ACE_Select_Reactor::register_handler_i");
+ ACE_HANDLE h;
+
+ ACE_Handle_Set_Iterator handle_iter (handles);
+ while ((h = handle_iter ()) != ACE_INVALID_HANDLE)
+ if (this->register_handler_i (h, handler, mask) == -1)
+ return -1;
+
+ return 0;
+}
+
+int
+ACE_Select_Reactor::register_handler (const ACE_Sig_Set &sigset,
+ ACE_Event_Handler *new_sh,
+ ACE_Sig_Action *new_disp)
+{
+ ACE_TRACE ("ACE_Select_Reactor::register_handler");
+
+ int result = 0;
+
+#if (NSIG > 0)
+ for (int s = 1; s < NSIG; s++)
+ if (sigset.is_member (s)
+ && this->signal_handler_->register_handler (s, new_sh,
+ new_disp) == -1)
+ result = -1;
+#else
+ ACE_UNUSED_ARG (sigset);
+ ACE_UNUSED_ARG (new_sh);
+ ACE_UNUSED_ARG (new_disp);
+#endif /* NSIG */
+ return result;
+}
+
+int
+ACE_Select_Reactor::remove_handler (const ACE_Sig_Set &sigset)
+{
+ ACE_TRACE ("ACE_Select_Reactor::remove_handler");
+ int result = 0;
+
+#if (NSIG > 0)
+ for (int s = 1; s < NSIG; s++)
+ if (sigset.is_member (s)
+ && this->signal_handler_->remove_handler (s) == -1)
+ result = -1;
+#else
+ ACE_UNUSED_ARG (sigset);
+#endif /* NSIG */
+
+ return result;
+}
+
+// Note the queue handles its own locking.
+
+long
+ACE_Select_Reactor::schedule_timer (ACE_Event_Handler *handler,
+ const void *arg,
+ const ACE_Time_Value &delta_time,
+ const ACE_Time_Value &interval)
+{
+ ACE_TRACE ("ACE_Select_Reactor::schedule_timer");
+ ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_MUTEX, ace_mon, this->token_, -1));
+
+ return this->timer_queue_->schedule
+ (handler, arg, timer_queue_->gettimeofday () + delta_time, interval);
+}
+
+// Main event loop driver that blocks for <max_wait_time> before
+// returning (will return earlier if I/O or signal events occur).
+
+int
+ACE_Select_Reactor::handle_events (ACE_Time_Value &max_wait_time)
+{
+ ACE_TRACE ("ACE_Select_Reactor::handle_events");
+
+ return this->handle_events (&max_wait_time);
+}
+
+int
+ACE_Select_Reactor::handle_error (void)
+{
+ ACE_TRACE ("ACE_Select_Reactor::handle_error");
+ if (errno == EINTR)
+ return this->restart_;
+ else if (errno == EBADF)
+ return this->check_handles ();
+ else
+ return -1;
+}
+
+void
+ACE_Select_Reactor::notify_handle (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask,
+ ACE_Handle_Set &ready_mask,
+ ACE_Event_Handler *event_handler,
+ ACE_EH_PTMF ptmf)
+{
+ ACE_TRACE ("ACE_Select_Reactor::notify_handle");
+ // Check for removed handlers.
+ if (event_handler == 0)
+ return;
+
+ int status = (event_handler->*ptmf) (handle);
+
+ if (status < 0)
+ this->remove_handler_i (handle, mask);
+ else if (status > 0)
+ ready_mask.set_bit (handle);
+}
+
+// Perform GET, CLR, SET, and ADD operations on the Handle_Sets.
+//
+// GET = 1, Retrieve current value
+// SET = 2, Set value of bits to new mask (changes the entire mask)
+// ADD = 3, Bitwise "or" the value into the mask (only changes
+// enabled bits)
+// CLR = 4 Bitwise "and" the negation of the value out of the mask
+// (only changes enabled bits)
+//
+// Returns the original mask. Must be called with locks held.
+
+int
+ACE_Select_Reactor::bit_ops (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask,
+ ACE_Select_Reactor_Handle_Set &handle_set,
+ int ops)
+{
+ ACE_TRACE ("ACE_Select_Reactor::bit_ops");
+ if (this->handler_rep_.handle_in_range (handle) == 0)
+ return -1;
+
+#if !defined (ACE_WIN32)
+ ACE_Sig_Guard sb; // Block out all signals until method returns.
+#endif /* ACE_WIN32 */
+
+ ACE_FDS_PTMF ptmf = &ACE_Handle_Set::set_bit;
+ u_long omask = ACE_Event_Handler::NULL_MASK;
+
+ switch (ops)
+ {
+ case ACE_Reactor::GET_MASK:
+ if (handle_set.rd_mask_.is_set (handle))
+ ACE_SET_BITS (omask, ACE_Event_Handler::READ_MASK);
+ if (handle_set.wr_mask_.is_set (handle))
+ ACE_SET_BITS (omask, ACE_Event_Handler::WRITE_MASK);
+ if (handle_set.ex_mask_.is_set (handle))
+ ACE_SET_BITS (omask, ACE_Event_Handler::EXCEPT_MASK);
+ break;
+
+ case ACE_Reactor::CLR_MASK:
+ ptmf = &ACE_Handle_Set::clr_bit;
+ /* FALLTHRU */
+ case ACE_Reactor::SET_MASK:
+ /* FALLTHRU */
+ case ACE_Reactor::ADD_MASK:
+
+ // The following code is rather subtle... Note that if we are
+ // doing a ACE_Reactor::SET_MASK then if the bit is not enabled
+ // in the mask we need to clear the bit from the ACE_Handle_Set.
+ // On the other hand, if we are doing a ACE_Reactor::CLR_MASK or
+ // a ACE_Reactor::ADD_MASK we just carry out the operations
+ // specified by the mask.
+
+ if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::READ_MASK)
+ || ACE_BIT_ENABLED (mask, ACE_Event_Handler::ACCEPT_MASK))
+ {
+ (handle_set.rd_mask_.*ptmf) (handle);
+ ACE_SET_BITS (omask, ACE_Event_Handler::READ_MASK);
+ }
+ else if (ops == ACE_Reactor::SET_MASK)
+ handle_set.rd_mask_.clr_bit (handle);
+
+ if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::WRITE_MASK))
+ {
+ (handle_set.wr_mask_.*ptmf) (handle);
+ ACE_SET_BITS (omask, ACE_Event_Handler::WRITE_MASK);
+ }
+ else if (ops == ACE_Reactor::SET_MASK)
+ handle_set.wr_mask_.clr_bit (handle);
+
+ if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::EXCEPT_MASK))
+ {
+ (handle_set.ex_mask_.*ptmf) (handle);
+ ACE_SET_BITS (omask, ACE_Event_Handler::EXCEPT_MASK);
+ }
+ else if (ops == ACE_Reactor::SET_MASK)
+ handle_set.ex_mask_.clr_bit (handle);
+ break;
+ default:
+ return -1;
+ }
+ return omask;
+}
+
+// Perform GET, CLR, SET, and ADD operations on the select()
+// Handle_Sets.
+//
+// GET = 1, Retrieve current value
+// SET = 2, Set value of bits to new mask (changes the entire mask)
+// ADD = 3, Bitwise "or" the value into the mask (only changes
+// enabled bits)
+// CLR = 4 Bitwise "and" the negation of the value out of the mask
+// (only changes enabled bits)
+//
+// Returns the original mask.
+
+int
+ACE_Select_Reactor::mask_ops (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask,
+ int ops)
+{
+ ACE_TRACE ("ACE_Select_Reactor::mask_ops");
+ ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_MUTEX, ace_mon, this->token_, -1));
+ return this->bit_ops (handle, mask,
+ this->wait_set_,
+ ops);
+}
+
+// Must be called with locks held.
+
+int
+ACE_Select_Reactor::handler_i (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask,
+ ACE_Event_Handler **handler)
+{
+ ACE_TRACE ("ACE_Select_Reactor::handler_i");
+ ACE_Event_Handler *h = this->handler_rep_.find (handle);
+
+ if (h == 0)
+ return -1;
+ else
+ {
+ if ((ACE_BIT_ENABLED (mask, ACE_Event_Handler::READ_MASK)
+ || ACE_BIT_ENABLED (mask, ACE_Event_Handler::ACCEPT_MASK))
+ && this->wait_set_.rd_mask_.is_set (handle) == 0)
+ return -1;
+ if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::WRITE_MASK)
+ && this->wait_set_.wr_mask_.is_set (handle) == 0)
+ return -1;
+ if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::EXCEPT_MASK)
+ && this->wait_set_.ex_mask_.is_set (handle) == 0)
+ return -1;
+ }
+
+ if (handler != 0)
+ *handler = h;
+ return 0;
+}
+
+// Must be called with locks held
+
+int
+ACE_Reactor::resume_i (ACE_HANDLE handle)
+{
+ ACE_TRACE ("ACE_Reactor::resume");
+ if (this->handler_rep_.find (handle) == 0)
+ return -1;
+
+ if (this->suspend_set_.rd_mask_.is_set (handle))
+ {
+ this->wait_set_.rd_mask_.set_bit (handle);
+ this->suspend_set_.rd_mask_.clr_bit(handle);
+ }
+ if (this->suspend_set_.wr_mask_.is_set (handle))
+ {
+ this->wait_set_.wr_mask_.set_bit (handle);
+ this->suspend_set_.wr_mask_.clr_bit(handle);
+ }
+ if (this->suspend_set_.ex_mask_.is_set (handle))
+ {
+ this->wait_set_.ex_mask_.set_bit (handle);
+ this->suspend_set_.ex_mask_.clr_bit(handle);
+ }
+ return 0;
+}
+
+// Must be called with locks held
+
+int
+ACE_Reactor::suspend_i (ACE_HANDLE handle)
+{
+ ACE_TRACE ("ACE_Reactor::suspend");
+ if (this->handler_rep_.find (handle) == 0)
+ return -1;
+
+ if (this->wait_set_.rd_mask_.is_set (handle))
+ {
+ this->suspend_set_.rd_mask_.set_bit (handle);
+ this->wait_set_.wr_mask_.clr_bit(handle);
+ }
+ if (this->wait_set_.wr_mask_.is_set (handle))
+ {
+ this->suspend_set_.wr_mask_.set_bit (handle);
+ this->wait_set_.wr_mask_.clr_bit(handle);
+ }
+ if (this->wait_set_.ex_mask_.is_set (handle))
+ {
+ this->suspend_set_.ex_mask_.set_bit (handle);
+ this->ex_mask_.clr_bit(handle);
+ }
+ return 0;
+}
+
+// Must be called with locks held
+
+int
+ACE_Select_Reactor::register_handler_i (ACE_HANDLE handle,
+ ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask mask)
+{
+ ACE_TRACE ("ACE_Select_Reactor::register_handler_i");
+
+ // Insert the <handle, event_handle> tuple into the Handler
+ // Repository.
+ return this->handler_rep_.bind (handle, event_handler, mask);
+}
+
+int
+ACE_Select_Reactor::remove_handler_i (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask)
+{
+ ACE_TRACE ("ACE_Select_Reactor::remove_handler_i");
+
+ // Unbind this handle.
+ return this->handler_rep_.unbind (handle, mask);
+}
+
+// Must be called with lock held.
+
+int
+ACE_Select_Reactor::wait_for_multiple_events (ACE_Select_Reactor_Handle_Set &dispatch_set,
+ ACE_Time_Value *max_wait_time)
+{
+ ACE_TRACE ("ACE_Select_Reactor::wait_for_multiple_events");
+ u_long width = 0;
+ ACE_Time_Value timer_buf (0);
+ ACE_Time_Value *this_timeout = &timer_buf;
+
+ int number_of_active_handles = this->any_ready (dispatch_set);
+
+ // If there are any bits enabled in the <ready_set_> then we'll
+ // handle those first, otherwise we'll block in select().
+
+ if (number_of_active_handles == 0)
+ {
+ do
+ {
+ if (this->timer_queue_->calculate_timeout (max_wait_time,
+ this_timeout) == 0)
+ this_timeout = 0;
+
+ width = (u_long) this->handler_rep_.max_handlep1 ();
+
+ dispatch_set.rd_mask_ = this->wait_set_.rd_mask_;
+ dispatch_set.wr_mask_ = this->wait_set_.wr_mask_;
+ dispatch_set.ex_mask_ = this->wait_set_.ex_mask_;
+
+ number_of_active_handles = ACE_OS::select (int (width),
+ dispatch_set.rd_mask_,
+ dispatch_set.wr_mask_,
+ dispatch_set.ex_mask_,
+ this_timeout);
+ }
+ while (number_of_active_handles == -1 && this->handle_error () > 0);
+
+ // @@ Remove?!
+ if (number_of_active_handles > 0)
+ {
+#if !defined (ACE_WIN32)
+ dispatch_set.rd_mask_.sync (this->handler_rep_.max_handlep1 ());
+ dispatch_set.wr_mask_.sync (this->handler_rep_.max_handlep1 ());
+ dispatch_set.ex_mask_.sync (this->handler_rep_.max_handlep1 ());
+#endif /* ACE_WIN32 */
+ }
+
+ }
+
+ // Return the number of events to dispatch.
+ return number_of_active_handles;
+}
+
+int
+ACE_Select_Reactor::dispatch_timer_handlers (void)
+{
+ int number_dispatched = this->timer_queue_->expire ();
+ return this->state_changed_ ? -1 : number_dispatched;
+}
+
+int
+ACE_Select_Reactor::dispatch_notification_handlers (int &number_of_active_handles,
+ ACE_Select_Reactor_Handle_Set &dispatch_set)
+{
+#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+ // Check to see if the ACE_HANDLE associated with the Select_Reactor's
+ // notify hook is enabled. If so, it means that one or more
+ // other threads are trying to update the ACE_Select_Reactor's internal
+ // tables. We'll handle all these threads and then break out to
+ // continue the event loop.
+
+ int number_dispatched =
+ this->notify_handler_.dispatch_notifications (number_of_active_handles,
+ dispatch_set.rd_mask_);
+ return this->state_changed_ ? -1 : number_dispatched;
+#else
+ ACE_UNUSED_ARG (number_of_active_handles);
+ ACE_UNUSED_ARG (dispatch_set);
+ return 0;
+#endif /* ACE_MT_SAFE */
+}
+
+int
+ACE_Select_Reactor::dispatch_io_handlers (int &number_of_active_handles,
+ ACE_Select_Reactor_Handle_Set &dispatch_set)
+{
+ int number_dispatched = 0;
+
+ if (number_of_active_handles > 0)
+ {
+ ACE_HANDLE handle;
+
+ // Handle output events (this code needs to come first to handle
+ // the obscure case of piggy-backed data coming along with the
+ // final handshake message of a nonblocking connection).
+
+ ACE_Handle_Set_Iterator handle_iter_wr (dispatch_set.wr_mask_);
+
+ while ((handle = handle_iter_wr ()) != ACE_INVALID_HANDLE
+ && number_dispatched < number_of_active_handles
+ && this->state_changed_ == 0)
+ {
+ number_dispatched++;
+ this->notify_handle (handle,
+ ACE_Event_Handler::WRITE_MASK,
+ this->ready_set_.wr_mask_,
+ this->handler_rep_.find (handle),
+ &ACE_Event_Handler::handle_output);
+ }
+ }
+
+ if (number_dispatched > 0)
+ {
+ number_of_active_handles -= number_dispatched;
+ if (this->state_changed_)
+ return -1;
+ }
+
+ number_dispatched = 0;
+
+ if (number_of_active_handles > 0)
+ {
+ ACE_HANDLE handle;
+
+ // Handle "exceptional" events.
+
+ ACE_Handle_Set_Iterator handle_iter_ex (dispatch_set.ex_mask_);
+
+ while ((handle = handle_iter_ex ()) != ACE_INVALID_HANDLE
+ && number_dispatched < number_of_active_handles
+ && this->state_changed_ == 0)
+ {
+ this->notify_handle (handle,
+ ACE_Event_Handler::EXCEPT_MASK,
+ this->ready_set_.ex_mask_,
+ this->handler_rep_.find (handle),
+ &ACE_Event_Handler::handle_exception);
+ number_dispatched++;
+ }
+ }
+
+ if (number_dispatched > 0)
+ {
+ number_of_active_handles -= number_dispatched;
+ if (this->state_changed_)
+ return -1;
+ }
+
+ number_dispatched = 0;
+
+ if (number_of_active_handles > 0)
+ {
+ ACE_HANDLE handle;
+
+ // Handle input, passive connection, and shutdown events.
+
+ ACE_Handle_Set_Iterator handle_iter_rd (dispatch_set.rd_mask_);
+
+ while ((handle = handle_iter_rd ()) != ACE_INVALID_HANDLE
+ && number_dispatched < number_of_active_handles
+ && this->state_changed_ == 0)
+ {
+ this->notify_handle (handle,
+ ACE_Event_Handler::READ_MASK,
+ this->ready_set_.rd_mask_,
+ this->handler_rep_.find (handle),
+ &ACE_Event_Handler::handle_input);
+ number_dispatched++;
+ }
+ }
+
+ if (number_dispatched > 0)
+ {
+ number_of_active_handles -= number_dispatched;
+
+ if (this->state_changed_)
+ return -1;
+ }
+
+ return number_dispatched;
+}
+
+int
+ACE_Select_Reactor::dispatch (int number_of_active_handles,
+ ACE_Select_Reactor_Handle_Set &dispatch_set)
+{
+ ACE_TRACE ("ACE_Select_Reactor::dispatch");
+
+ // The following do/while loop keeps dispatching as long as there
+ // are still active handles. Note that the only way we should ever
+ // iterate more than once through this loop is if signals occur
+ // while we're dispatching other handlers.
+
+ do
+ {
+ // Note that we keep track of changes to our state. If any of
+ // the dispatch_*() methods below return -1 it means that the
+ // <wait_set_> state has changed as the result of an
+ // <ACE_Event_Handler> being dispatched. This means that we
+ // need to bail out and rerun the select() loop since our
+ // existing notion of handles in <dispatch_set> may no longer be
+ // correct.
+ //
+ // In the beginning, our state starts out unchanged. After
+ // every iteration (i.e., due to signals), our state starts out
+ // unchanged again.
+
+ this->state_changed_ = 0;
+
+ // Perform the Template Method for dispatching all the handlers.
+
+ // Handle timers first since they may have higher latency
+ // constraints.
+
+ if (this->dispatch_timer_handlers () == -1)
+ // State has changed or timer queue has failed, exit inner
+ // loop.
+ break;
+ else if (number_of_active_handles <= 0)
+ // Bail out since we got here since select() was interrupted.
+ {
+ if (ACE_Sig_Handler::sig_pending () != 0)
+ {
+ ACE_Sig_Handler::sig_pending (0);
+
+ // If any HANDLES in the <ready_set_> are activated as a
+ // result of signals they should be dispatched since
+ // they may be time critical...
+ number_of_active_handles = this->any_ready (dispatch_set);
+ }
+ else
+ return number_of_active_handles;
+ }
+ else if (this->dispatch_notification_handlers
+ (number_of_active_handles, dispatch_set) == -1)
+ break; // State has changed, exit inner loop.
+ else if (this->dispatch_io_handlers
+ (number_of_active_handles, dispatch_set) == -1)
+ // State has changed, so exit the inner loop.
+ break;
+
+ }
+ while (number_of_active_handles > 0);
+
+ return 1;
+}
+
+int
+ACE_Select_Reactor::release_token (void)
+{
+#if defined (ACE_WIN32)
+ this->token_.release ();
+ return (int) EXCEPTION_CONTINUE_SEARCH;
+#else
+ return 0;
+#endif /* ACE_WIN32 */
+}
+
+int
+ACE_Select_Reactor::handle_events (ACE_Time_Value *max_wait_time)
+{
+ ACE_TRACE ("ACE_Select_Reactor::handle_events");
+
+ // Stash the current time -- the destructor of this object will
+ // automatically compute how much time elpased since this method was
+ // called.
+ ACE_Countdown_Time countdown (max_wait_time);
+
+#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+ ACE_GUARD_RETURN (ACE_SELECT_REACTOR_MUTEX, ace_mon, this->token_, -1);
+
+ if (ACE_OS::thr_equal (ACE_Thread::self (), this->owner_) == 0)
+ return -1;
+
+ // Update the countdown to reflect time waiting for the mutex.
+ countdown.update ();
+#endif /* ACE_MT_SAFE */
+
+ return this->handle_events_i (max_wait_time);
+}
+
+int
+ACE_Select_Reactor::handle_events_i (ACE_Time_Value *max_wait_time)
+{
+ int result = -1;
+
+ ACE_SEH_TRY {
+ ACE_Select_Reactor_Handle_Set dispatch_set;
+
+ int number_of_active_handles =
+ this->wait_for_multiple_events (dispatch_set,
+ max_wait_time);
+
+ result = this->dispatch (number_of_active_handles, dispatch_set);
+ }
+ ACE_SEH_EXCEPT (this->release_token ()) {
+ // As it stands now, we catch and then rethrow all Win32
+ // structured exceptions so that we can make sure to release the
+ // <token_> lock correctly.
+ }
+
+ return result;
+}
+
+int
+ACE_Select_Reactor::check_handles (void)
+{
+ ACE_TRACE ("ACE_Select_Reactor::check_handles");
+
+#if defined (ACE_WIN32)
+ ACE_Time_Value time_poll = ACE_Time_Value::zero;
+ ACE_Handle_Set rd_mask;
+#endif /* ACE_WIN32 */
+
+ ACE_Event_Handler *eh = 0;
+ int result = 0;
+
+ for (ACE_Select_Reactor_Handler_Repository_Iterator iter (&this->handler_rep_);
+ iter.next (eh) != 0;
+ iter.advance ())
+ {
+ ACE_HANDLE handle = eh->get_handle ();
+
+ // Skip back to the beginning of the loop if the HANDLE is
+ // invalid.
+ if (handle == ACE_INVALID_HANDLE)
+ continue;
+
+#if defined (ACE_WIN32)
+ rd_mask.set_bit (handle);
+
+ if (ACE_OS::select (int (handle) + 1,
+ rd_mask, 0, 0,
+ &time_poll) < 0)
+ {
+ result = 1;
+ this->remove_handler_i (handle,
+ ACE_Event_Handler::ALL_EVENTS_MASK);
+ }
+ rd_mask.clr_bit (handle);
+#else /* !ACE_WIN32 */
+ struct stat temp;
+
+ if (ACE_OS::fstat (handle, &temp) == -1)
+ {
+ result = 1;
+ this->remove_handler_i (handle,
+ ACE_Event_Handler::ALL_EVENTS_MASK);
+ }
+#endif /* ACE_WIN32 */
+ }
+
+ return result;
+}
+
+void
+ACE_Select_Reactor::dump (void) const
+{
+ ACE_TRACE ("ACE_Select_Reactor::dump");
+
+ ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
+
+ this->timer_queue_->dump ();
+ this->handler_rep_.dump ();
+ this->signal_handler_->dump ();
+ ACE_DEBUG ((LM_DEBUG,
+ "delete_signal_handler_ = %d\n",
+ this->delete_signal_handler_));
+
+ ACE_HANDLE h;
+
+ for (ACE_Handle_Set_Iterator handle_iter_wr (this->wait_set_.wr_mask_);
+ (h = handle_iter_wr ()) != ACE_INVALID_HANDLE;
+ ++handle_iter_wr)
+ ACE_DEBUG ((LM_DEBUG, "write_handle = %d\n", h));
+
+ for (ACE_Handle_Set_Iterator handle_iter_rd (this->wait_set_.rd_mask_);
+ (h = handle_iter_rd ()) != ACE_INVALID_HANDLE;
+ ++handle_iter_rd)
+ ACE_DEBUG ((LM_DEBUG, "read_handle = %d\n", h));
+
+ for (ACE_Handle_Set_Iterator handle_iter_ex (this->wait_set_.ex_mask_);
+ (h = handle_iter_ex ()) != ACE_INVALID_HANDLE;
+ ++handle_iter_ex)
+ ACE_DEBUG ((LM_DEBUG, "except_handle = %d\n", h));
+
+ for (ACE_Handle_Set_Iterator handle_iter_wr_ready (this->ready_set_.wr_mask_);
+ (h = handle_iter_wr_ready ()) != ACE_INVALID_HANDLE;
+ ++handle_iter_wr_ready)
+ ACE_DEBUG ((LM_DEBUG, "write_handle_ready = %d\n", h));
+
+ for (ACE_Handle_Set_Iterator handle_iter_rd_ready (this->ready_set_.rd_mask_);
+ (h = handle_iter_rd_ready ()) != ACE_INVALID_HANDLE;
+ ++handle_iter_rd_ready)
+ ACE_DEBUG ((LM_DEBUG, "read_handle_ready = %d\n", h));
+
+ for (ACE_Handle_Set_Iterator handle_iter_ex_ready (this->ready_set_.ex_mask_);
+ (h = handle_iter_ex_ready ()) != ACE_INVALID_HANDLE;
+ ++handle_iter_ex_ready)
+ ACE_DEBUG ((LM_DEBUG, "except_handle_ready = %d\n", h));
+
+ ACE_DEBUG ((LM_DEBUG, "restart_ = %d\n", this->restart_));
+ ACE_DEBUG ((LM_DEBUG, "\nrequeue_position_ = %d\n", this->requeue_position_));
+ ACE_DEBUG ((LM_DEBUG, "\ninitialized_ = %d\n", this->initialized_));
+ ACE_DEBUG ((LM_DEBUG, "\nowner_ = %d\n", this->owner_));
+
+#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+ this->notify_handler_.dump ();
+ this->token_.dump ();
+#endif /* ACE_MT_SAFE */
+
+ ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
+}
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+ACE_MT (template class ACE_Guard<ACE_SELECT_REACTOR_MUTEX>);
+template class ACE_Event_Handler_Handle_Timeout_Upcall<ACE_SYNCH_RECURSIVE_MUTEX>;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+#pragma instantiate ACE_Guard<ACE_SELECT_REACTOR_MUTEX>
+#endif /* ACE_MT_SAFE */
+#pragma instantiate ACE_Event_Handler_Handle_Timeout_Upcall<ACE_SYNCH_RECURSIVE_MUTEX>
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
+
diff --git a/ace/Select_Reactor.h b/ace/Select_Reactor.h
new file mode 100644
index 00000000000..3df57809e1b
--- /dev/null
+++ b/ace/Select_Reactor.h
@@ -0,0 +1,818 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// ace
+//
+// = FILENAME
+// Select_Reactor.h
+//
+// = AUTHOR
+// Doug Schmidt
+//
+// ============================================================================
+
+#if !defined (ACE_SELECT_REACTOR_H)
+#define ACE_SELECT_REACTOR_H
+
+#include "ace/Signal.h"
+#include "ace/Timer_Queue.h"
+#include "ace/Event_Handler.h"
+#include "ace/Handle_Set.h"
+#include "ace/Token.h"
+#include "ace/Pipe.h"
+#include "ace/Reactor_Impl.h"
+
+// Add useful typedefs to simplify the following code.
+typedef void (ACE_Handle_Set::*ACE_FDS_PTMF) (ACE_HANDLE);
+typedef int (ACE_Event_Handler::*ACE_EH_PTMF) (ACE_HANDLE);
+
+// Forward declaration.
+class ACE_Select_Reactor;
+
+class ACE_Export ACE_Select_Reactor_Handle_Set
+ // = TITLE
+ //
+ // Track handles we are interested for various events.
+{
+public:
+ ACE_Handle_Set rd_mask_;
+ // Read events (e.g., input pending, accept pending).
+
+ ACE_Handle_Set wr_mask_;
+ // Write events (e.g., flow control abated, non-blocking connection
+ // complete).
+
+ ACE_Handle_Set ex_mask_;
+ // Exception events (e.g., SIG_URG).
+};
+
+#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+
+#if defined (ACE_SELECT_REACTOR_HAS_DEADLOCK_DETECTION)
+#include "ace/Local_Tokens.h"
+typedef ACE_Local_Mutex ACE_SELECT_REACTOR_MUTEX;
+#else
+typedef ACE_Token ACE_SELECT_REACTOR_MUTEX;
+#endif /* ACE_SELECT_REACTOR_HAS_DEADLOCK_DETECTION */
+
+class ACE_Export ACE_Select_Reactor_Token : public ACE_SELECT_REACTOR_MUTEX
+ // = TITLE
+ //
+ // Used as a synchronization mechanism to coordinate concurrent
+ // access to a Select_Reactor object.
+{
+public:
+ ACE_Select_Reactor_Token (ACE_Select_Reactor &r);
+
+ virtual void sleep_hook (void);
+ // Called just before the ACE_Event_Handler goes to sleep.
+
+ void dump (void) const;
+ // Dump the state of an object.
+
+ ACE_ALLOC_HOOK_DECLARE;
+ // Declare the dynamic allocation hooks.
+
+private:
+ ACE_Select_Reactor &select_reactor_;
+};
+#else
+// If we're non-MT safe then this is just a no-op...
+typedef ACE_Null_Mutex ACE_Select_Reactor_Token;
+#endif /* ACE_MT_SAFE */
+
+// The following two classes have to be moved out here to keep the SGI
+// C++ compiler happy (it doesn't like nested classes).
+
+class ACE_Export ACE_Select_Reactor_Notify : public ACE_Event_Handler
+ // = TITLE
+ //
+ // Unblock the <ACE_Select_Reactor> from its event loop.
+ //
+ // = DESCRIPTION
+ //
+ // This implementation is necessary for cases where the
+ // <ACE_Select_Reactor> is run in a multi-threaded program. In
+ // this case, we need to be able to unblock select() or poll()
+ // when updates occur other than in the main
+ // <ACE_Select_Reactor> thread. To do this, we signal an
+ // auto-reset event the <ACE_Select_Reactor> is listening on.
+ // If an <ACE_Event_Handler> and <ACE_Select_Reactor_Mask> is
+ // passed to <notify>, the appropriate <handle_*> method is
+ // dispatched in the context of the <ACE_Select_Reactor> thread.
+{
+public:
+ // = Initialization and termination methods.
+ int open (ACE_Select_Reactor *);
+ int close (void);
+
+ int dispatch_notifications (int &number_of_active_handles,
+ const ACE_Handle_Set &rd_mask);
+ // Handles pending threads (if any) that are waiting to unblock the
+ // Select_Reactor.
+
+ ssize_t notify (ACE_Event_Handler * = 0,
+ ACE_Reactor_Mask = ACE_Event_Handler::EXCEPT_MASK,
+ ACE_Time_Value * = 0);
+ // Called by a thread when it wants to unblock the Select_Reactor.
+ // This wakeups the <ACE_Select_Reactor> if currently blocked in
+ // select()/poll(). Pass over both the <Event_Handler> *and* the
+ // <mask> to allow the caller to dictate which <Event_Handler>
+ // method the <Select_Reactor> will invoke. The <ACE_Time_Value>
+ // indicates how long to blocking trying to notify the
+ // <Select_Reactor>. If <timeout> == 0, the caller will block until
+ // action is possible, else will wait until the relative time
+ // specified in *<timeout> elapses).
+
+ virtual int handle_input (ACE_HANDLE handle);
+ // Called back by the Select_Reactor when a thread wants to unblock us.
+
+ void dump (void) const;
+ // Dump the state of an object.
+
+ ACE_ALLOC_HOOK_DECLARE;
+ // Declare the dynamic allocation hooks.
+
+private:
+ ACE_Select_Reactor *select_reactor_;
+ // Keep a back pointer to the Select_Reactor.
+
+ ACE_Pipe notification_pipe_;
+ // Contains the HANDLE the Select_Reactor is listening on, as well
+ // as the HANDLE that threads wanting the attention of the
+ // Select_Reactor will write to.
+};
+
+class ACE_Export ACE_Select_Reactor_Handler_Repository
+ // = TITLE
+ //
+ // Used to map <ACE_HANDLE>s onto the appropriate
+ // <ACE_Event_Handler> *.
+ //
+ // = DESCRIPTION
+ //
+ // This class is necessary to shield differences between UNIX
+ // and Win32. In UNIX, <ACE_HANDLE> is an int, whereas in Win32
+ // it's a void *. This class hides all these details from the
+ // bulk of the <ACE_Select_Reactor> code. All of these methods
+ // are called with the main <Select_Reactor> token lock held.
+{
+public:
+ friend class ACE_Select_Reactor_Handler_Repository_Iterator;
+
+ // = Initialization and termination methods.
+ ACE_Select_Reactor_Handler_Repository (ACE_Select_Reactor &);
+ // Default "do-nothing" constructor.
+
+ int open (size_t size);
+ // Initialize a repository of the appropriate <size>.
+
+ int close (void);
+ // Close down the repository.
+
+ // = Search structure operations.
+
+ ACE_Event_Handler *find (ACE_HANDLE handle, size_t *index_p = 0);
+ // Return the <ACE_Event_Handler *> associated with <ACE_HANDLE>.
+ // If <index_p> is non-0, then return the index location of the
+ // <handle>, if found.
+
+ int bind (ACE_HANDLE,
+ ACE_Event_Handler *,
+ ACE_Reactor_Mask);
+ // Bind the <ACE_Event_Handler *> to the <ACE_HANDLE> with the
+ // appropriate <ACE_Reactor_Mask> settings.
+
+ int unbind (ACE_HANDLE,
+ ACE_Reactor_Mask mask);
+ // Remove the binding of <ACE_HANDLE> in accordance with the <mask>.
+
+ int unbind_all (void);
+ // Remove all the <ACE_HANDLE, ACE_Event_Handler> tuples.
+
+ // = Sanity checking.
+
+ // Check the <handle> to make sure it's a valid ACE_HANDLE that
+ // within the range of legal handles (i.e., >= 0 && < max_size_).
+ int invalid_handle (ACE_HANDLE handle);
+
+ // Check the <handle> to make sure it's a valid ACE_HANDLE that
+ // within the range of currently registered handles (i.e., >= 0 && <
+ // max_handlep1_).
+ int handle_in_range (ACE_HANDLE handle);
+
+ // = Accessors.
+ size_t size (void);
+ // Returns the current table size.
+
+ size_t max_handlep1 (void);
+ // Maximum ACE_HANDLE value, plus 1.
+
+ void dump (void) const;
+ // Dump the state of an object.
+
+ ACE_ALLOC_HOOK_DECLARE;
+ // Declare the dynamic allocation hooks.
+
+private:
+ ACE_Select_Reactor &select_reactor_;
+ // Reference to our <Select_Reactor>.
+
+ ssize_t max_size_;
+ // Maximum number of handles.
+
+ int max_handlep1_;
+ // The highest currently active handle, plus 1 (ranges between 0 and
+ // <max_size_>.
+
+#if defined (ACE_WIN32)
+ // = This structure maps <HANDLES> to <Event_Handlers>.
+ struct ACE_NT_EH_Record
+ {
+ ACE_HANDLE handle_;
+ ACE_Event_Handler *event_handler_;
+ };
+
+ ACE_NT_EH_Record *event_handlers_;
+ // The NT version implements this via a dynamically allocated
+ // array of <ACE_NT_EH_Record *>. Since NT implements ACE_HANDLE
+ // as a void * we can't directly index into this array. Therefore,
+ // we just do a linear search (for now). Next, we'll modify
+ // things to use hashing or something faster...
+#else
+ ACE_Event_Handler **event_handlers_;
+ // The UNIX version implements this via a dynamically allocated
+ // array of <ACE_Event_Handler *> that is indexed directly using
+ // the ACE_HANDLE value.
+#endif /* ACE_WIN32 */
+};
+
+class ACE_Export ACE_Select_Reactor_Handler_Repository_Iterator
+ // = TITLE
+ //
+ // Iterate through the <ACE_Select_Reactor_Handler_Repository>.
+{
+public:
+ // = Initialization method.
+ ACE_Select_Reactor_Handler_Repository_Iterator (const ACE_Select_Reactor_Handler_Repository *s);
+
+ // = Iteration methods.
+
+ int next (ACE_Event_Handler *&next_item);
+ // Pass back the <next_item> that hasn't been seen in the Set.
+ // Returns 0 when all items have been seen, else 1.
+
+ int done (void) const;
+ // Returns 1 when all items have been seen, else 0.
+
+ int advance (void);
+ // Move forward by one element in the set. Returns 0 when all the
+ // items in the set have been seen, else 1.
+
+ void dump (void) const;
+ // Dump the state of an object.
+
+ ACE_ALLOC_HOOK_DECLARE;
+ // Declare the dynamic allocation hooks.
+
+private:
+ const ACE_Select_Reactor_Handler_Repository *rep_;
+ // Reference to the Handler_Repository we are iterating over.
+
+ ssize_t current_;
+ // Pointer to the current iteration level.
+};
+
+class ACE_Export ACE_Select_Reactor : public ACE_Reactor_Impl
+ // = TITLE
+ //
+ // An object oriented event demultiplexor and event handler
+ // dispatcher.
+ //
+ // = DESCRIPTION
+ //
+ // The ACE_Select_Reactor is an object-oriented event
+ // demultiplexor and event handler dispatcher. The sources of
+ // events that the ACE_Select_Reactor waits for and dispatches
+ // includes I/O events, signals, and timer events. All public
+ // methods acquire the main <Select_Reactor> token lock and call
+ // down to private or protected methods, which assume that the
+ // lock is held and so therefore don't (re)acquire the lock.
+{
+public:
+ enum
+ {
+ DEFAULT_SIZE = ACE_DEFAULT_SELECT_REACTOR_SIZE,
+ // Default size of the Select_Reactor's handle table.
+ };
+
+ // = Initialization and termination methods.
+
+ ACE_Select_Reactor (ACE_Sig_Handler * = 0,
+ ACE_Timer_Queue * = 0);
+ // Initialize <ACE_Select_Reactor> with the default size.
+
+ ACE_Select_Reactor (size_t size,
+ int restart = 0,
+ ACE_Sig_Handler * = 0,
+ ACE_Timer_Queue * = 0);
+ // Initialize <ACE_Select_Reactor> with size <size>.
+
+ virtual int open (size_t size = DEFAULT_SIZE,
+ int restart = 0,
+ ACE_Sig_Handler * = 0,
+ ACE_Timer_Queue * = 0);
+ // Initialize <ACE_Select_Reactor> with size <size>.
+
+ virtual int close (void);
+ // Close down the select_reactor and release all of its resources.
+
+ virtual ~ACE_Select_Reactor (void);
+ // Close down the select_reactor and release all of its resources.
+
+ // = Event loop drivers.
+
+ virtual int handle_events (ACE_Time_Value *max_wait_time = 0);
+ virtual int alertable_handle_events (ACE_Time_Value *max_wait_time = 0);
+ // This event loop driver that blocks for <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.
+ //
+ // 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 something goes wrong.
+ //
+ // Current <alertable_handle_events> is identical to
+ // <handle_events>.
+
+ virtual int handle_events (ACE_Time_Value &max_wait_time);
+ virtual int alertable_handle_events (ACE_Time_Value &max_wait_time);
+ // This method is just like the one above, except the
+ // <max_wait_time> value is a reference and can therefore never be
+ // NULL.
+ //
+ // Current <alertable_handle_events> is identical to
+ // <handle_events>.
+
+ // = Register and remove <ACE_Event_Handler>s.
+ virtual int register_handler (ACE_Event_Handler *eh,
+ ACE_Reactor_Mask mask);
+ // Register a <eh> with a particular <mask>. Note that the
+ // <Select_Reactor> will call eh->get_handle() to extract the
+ // underlying I/O handle.
+
+ virtual int register_handler (ACE_HANDLE handle,
+ ACE_Event_Handler *eh,
+ ACE_Reactor_Mask mask);
+ // Register a <eh> with a particular <mask>. Note that since the
+ // <handle> is given the Select_Reactor will *not* call
+ // eh->get_handle() to extract the underlying I/O handle.
+
+ virtual int register_handler (ACE_Event_Handler *event_handler,
+ ACE_HANDLE event_handle = ACE_INVALID_HANDLE);
+ // Not implemented.
+
+ virtual int register_handler (ACE_HANDLE event_handle,
+ ACE_HANDLE io_handle,
+ ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask mask);
+ // Not implemented.
+
+ virtual int register_handler (const ACE_Handle_Set &handles,
+ ACE_Event_Handler *eh,
+ ACE_Reactor_Mask mask);
+ // Register <eh> 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);
+ // Register <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);
+ // Registers <new_sh> to handle a set of signals <sigset> using the
+ // <new_disp>.
+
+ virtual int remove_handler (ACE_Event_Handler *eh,
+ ACE_Reactor_Mask mask);
+ // Removes the <mask> binding of <eh> from the Select_Reactor. If
+ // there are no more bindings for this <eh> then it is removed from
+ // the Select_Reactor. Note that the Select_Reactor will call
+ // eh->get_handle() to extract the underlying I/O handle.
+
+ virtual int remove_handler (ACE_HANDLE handle,
+ ACE_Reactor_Mask);
+ // Removes the <mask> bind of <Event_Handler> whose handle is
+ // <handle> from the Select_Reactor. If there are no more bindings
+ // for this <eh> then it is removed from the Select_Reactor.
+
+ virtual int remove_handler (const ACE_Handle_Set &handle_set,
+ ACE_Reactor_Mask);
+ // Removes all the <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 the Select_Reactor.
+
+ virtual int remove_handler (int signum,
+ ACE_Sig_Action *new_disp,
+ ACE_Sig_Action *old_disp = 0,
+ int sigkey = -1);
+ // Remove the ACE_Event_Handler currently associated with <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);
+ // Calls <remove_handler> for every signal in <sigset>.
+
+ // = Suspend and resume Handlers.
+
+ virtual int suspend_handler (ACE_Event_Handler *eh);
+ // Temporarily suspend the <Event_Handler> associated with <eh>.
+
+ virtual int suspend_handler (ACE_HANDLE handle);
+ // Temporarily suspend the <Event_Handler> associated with <handle>.
+
+ virtual int suspend_handler (const ACE_Handle_Set &handles);
+ // Suspend all <handles> in handle set temporarily.
+
+ virtual int suspend_handlers (void);
+ // Suspend all the <Event_Handlers> in the Select_Reactor.
+
+ virtual int resume_handler (ACE_Event_Handler *eh);
+ // Resume a temporarily suspend <Event_Handler> associated with
+ // <eh>.
+
+ virtual int resume_handler (ACE_HANDLE handle);
+ // Resume a temporarily suspended <Event_Handler> associated with
+ // <handle>.
+
+ virtual int resume_handler (const ACE_Handle_Set &handles);
+ // Resume all <handles> in handle set.
+
+ virtual int resume_handlers (void);
+ // Resume all the <Event_Handlers> in the Select_Reactor.
+
+ // = Timer management.
+ virtual long schedule_timer (ACE_Event_Handler *,
+ const void *arg,
+ const ACE_Time_Value &delta_time,
+ const ACE_Time_Value &interval = ACE_Time_Value::zero);
+ // Schedule an <event_handler> that will expire after <delta_time>
+ // 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);
+ // Cancel all <event_handlers> that match the address of
+ // <event_handler>. If <dont_call_handle_close> is 0 then the
+ // <handle_close> method of <event_handler> will be invoked.
+ // Returns number of handler's cancelled.
+
+ virtual int cancel_timer (long timer_id,
+ const void **arg = 0,
+ int dont_call_handle_close = 1);
+ // Cancel the single <ACE_Event_Handler> that matches the <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.
+ // If <dont_call_handle_close> is 0 then the <handle_close> method
+ // of <event_handler> will be invoked. Returns 1 if cancellation
+ // succeeded and 0 if the <timer_id> wasn't found.
+
+ // = High-level Event_Handler scheduling operations
+
+ virtual int schedule_wakeup (ACE_Event_Handler *eh,
+ ACE_Reactor_Mask mask);
+ // ADD the dispatch MASK "bit" bound with the <eh> and the <mask>.
+
+ virtual int schedule_wakeup (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask);
+ // ADD the dispatch MASK "bit" bound with the <handle> and the <mask>.
+
+ virtual int cancel_wakeup (ACE_Event_Handler *eh,
+ ACE_Reactor_Mask mask);
+ // CLR the dispatch MASK "bit" bound with the <eh> and the <mask>.
+
+ virtual int cancel_wakeup (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask);
+ // CLR the dispatch MASK "bit" bound with the <handle> and the <mask>.
+
+ // = Notification methods.
+ virtual int notify (ACE_Event_Handler * = 0,
+ ACE_Reactor_Mask = ACE_Event_Handler::EXCEPT_MASK,
+ ACE_Time_Value * = 0);
+ // Called by a thread when it wants to unblock the Select_Reactor.
+ // This wakeups the <ACE_Select_Reactor> if currently blocked in
+ // select()/poll(). Pass over both the <Event_Handler> *and* the
+ // <mask> to allow the caller to dictate which <Event_Handler>
+ // method the <Select_Reactor> will invoke. The <ACE_Time_Value>
+ // indicates how long to blocking trying to notify the
+ // <Select_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 requeue_position (int);
+ // Set position that the main ACE_Select_Reactor thread is requeued in the
+ // list of waiters during a notify() callback.
+
+ virtual int requeue_position (void);
+ // Get position that the main ACE_Select_Reactor thread is requeued in the
+ // list of waiters during a notify() callback.
+
+ virtual void max_notify_iterations (int);
+ // Set the maximum number of times that the
+ // <ACE_Select_Reactor_Notify::handle_input> method will iterate and
+ // dispatch the <ACE_Event_Handlers> that are passed in via the
+ // notify pipe before breaking out of its <recv> loop. By default,
+ // this is set to -1, which means "iterate until the pipe 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);
+ // Get the maximum number of times that the
+ // <ACE_Select_Reactor_Notify::handle_input> method will iterate and
+ // dispatch the <ACE_Event_Handlers> that are passed in via the
+ // notify pipe before breaking out of its <recv> loop.
+
+ // = Low-level wait_set mask manipulation methods.
+ virtual int mask_ops (ACE_Event_Handler *eh,
+ ACE_Reactor_Mask mask,
+ int ops);
+ // GET/SET/ADD/CLR the dispatch mask "bit" bound with the <eh> and
+ // <mask>.
+
+ virtual int mask_ops (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask,
+ int ops);
+ // GET/SET/ADD/CLR the dispatch MASK "bit" bound with the <handle>
+ // and <mask>.
+
+ // = Low-level ready_set mask manipulation methods.
+ virtual int ready_ops (ACE_Event_Handler *eh,
+ ACE_Reactor_Mask mask,
+ int ops);
+ // GET/SET/ADD/CLR the ready "bit" bound with the <eh> and <mask>.
+
+ virtual int ready_ops (ACE_HANDLE handle,
+ ACE_Reactor_Mask,
+ int ops);
+ // GET/SET/ADD/CLR the ready "bit" bound with the <handle> and <mask>.
+
+ virtual void wakeup_all_threads (void);
+ // Wake up all threads in waiting in the event loop
+
+ // = Only the owner thread that can perform a <handle_events>.
+
+ virtual int owner (ACE_thread_t n_id, ACE_thread_t *o_id = 0);
+ // Set the new owner of the thread and return the old owner.
+
+ virtual int owner (ACE_thread_t *);
+ // Return the current owner of the thread.
+
+ // = Miscellaneous Handler operations.
+ virtual int handler (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask,
+ ACE_Event_Handler **eh = 0);
+ // Check to see if <handle> is associated with a valid Event_Handler
+ // bound to <mask>. Return the <eh> associated with this <handler>
+ // if <eh> != 0.
+
+ virtual int handler (int signum,
+ ACE_Event_Handler ** = 0);
+ // Check to see if <signum> is associated with a valid Event_Handler
+ // bound to a signal. Return the <eh> associated with this
+ // <handler> if <eh> != 0.
+
+ virtual int initialized (void);
+ // Returns true if we've been successfully initialized, else false.
+
+ virtual size_t size (void);
+ // Returns the current size of the Reactor's internal descriptor
+ // table.
+
+ virtual ACE_Lock &lock (void);
+ // Returns a reference to the <ACE_Select_Reactor_Token> that is
+ // used to serialize the internal Select_Reactor's processing logic.
+ // This can be useful for situations where you need to avoid
+ // deadlock efficiently when <ACE_Event_Handlers> are used in
+ // multiple threads.
+
+ void dump (void) const;
+ // Dump the state of an object.
+
+ ACE_ALLOC_HOOK_DECLARE;
+ // Declare the dynamic allocation hooks.
+
+protected:
+ // = Internal methods that do the actual work.
+
+ // All of these methods assume that the <Select_Reactor>'s token
+ // lock is held by the public methods that call down to them.
+
+ virtual int register_handler_i (ACE_HANDLE handle,
+ ACE_Event_Handler *eh,
+ ACE_Reactor_Mask mask);
+ // Do the work of actually binding the <handle> and <eh> with the
+ // <mask>.
+
+ virtual int register_handler_i (const ACE_Handle_Set &handles,
+ ACE_Event_Handler *handler,
+ ACE_Reactor_Mask mask);
+ // Register a set of <handles>.
+
+ virtual int remove_handler_i (ACE_HANDLE handle,
+ ACE_Reactor_Mask);
+ // Do the work of actually unbinding the <handle> and <eh> with the
+ // <mask>.
+
+ virtual int remove_handler_i (const ACE_Handle_Set &handles,
+ ACE_Reactor_Mask);
+ // Remove a set of <handles>.
+
+ virtual int suspend_i (ACE_HANDLE handle);
+ // Suspend the <Event_Handler> associated with <handle>
+
+ virtual int resume_i (ACE_HANDLE handle);
+ // Resume the <Event_Handler> associated with <handle>
+
+ virtual int handler_i (ACE_HANDLE handle,
+ ACE_Reactor_Mask,
+ ACE_Event_Handler ** = 0);
+ // Implement the public <handler> method.
+
+ virtual int handler_i (int signum, ACE_Event_Handler ** = 0);
+ // Implement the public <handler> method.
+
+ virtual int any_ready (ACE_Select_Reactor_Handle_Set &handle_set);
+ // Check if there are any HANDLEs enabled in the <ready_set_>, and
+ // if so, update the <handle_set> and return the number ready. If
+ // there aren't any HANDLEs enabled return 0.
+
+ virtual int handle_error (void);
+ // Take corrective action when errors occur.
+
+ virtual int check_handles (void);
+ // Make sure the handles are all valid.
+
+ virtual int bit_ops (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask,
+ ACE_Select_Reactor_Handle_Set &wait_Set,
+ int ops);
+ // Allow manipulation of the <wait_set_> mask and <ready_set_> mask.
+
+ virtual int wait_for_multiple_events (ACE_Select_Reactor_Handle_Set &,
+ ACE_Time_Value *);
+ // Wait for events to occur.
+
+ // = Dispatching methods.
+
+ virtual int dispatch (int nfound,
+ ACE_Select_Reactor_Handle_Set &);
+ // Template Method that dispatches <ACE_Event_Handler>s for time
+ // events, I/O events, and signal events. Returns the total number
+ // of <ACE_Event_Handler>s that were dispatched or -1 if something
+ // goes wrong.
+
+ virtual int dispatch_timer_handlers (void);
+ // Dispatch any expired timer handlers. Returns -1 if the state of
+ // the <wait_set_> has changed, else returns number of timer
+ // handlers dispatched.
+
+ virtual int dispatch_notification_handlers (int &number_of_active_handles,
+ ACE_Select_Reactor_Handle_Set &dispatch_set);
+ // Dispatch any notification handlers. Returns -1 if the state of
+ // the <wait_set_> has changed, else returns number of handlers
+ // notified.
+
+ virtual int dispatch_io_handlers (int &number_of_active_handles,
+ ACE_Select_Reactor_Handle_Set &dispatch_set);
+ // Dispatch all the input/output/except handlers that are enabled in
+ // the <dispatch_set>. Returns -1 if the state of the <wait_set_>
+ // has changed, else returns number of handlers dispatched.
+
+ virtual void notify_handle (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask,
+ ACE_Handle_Set &,
+ ACE_Event_Handler *eh,
+ ACE_EH_PTMF callback);
+ // Notify the appropriate <callback> in the context of the <eh>
+ // associated with <handle> that a particular event has occurred.
+
+ ACE_Select_Reactor_Handler_Repository handler_rep_;
+ // Table that maps <ACE_HANDLEs> to <ACE_Event_Handler *>'s.
+
+ ACE_Timer_Queue *timer_queue_;
+ // Defined as a pointer to allow overriding by derived classes...
+
+ int delete_timer_queue_;
+ // Keeps track of whether we should delete the timer queue (if we
+ // didn't create it, then we don't delete it).
+
+ ACE_Sig_Handler *signal_handler_;
+ // Handle signals without requiring global/static variables.
+
+ int delete_signal_handler_;
+ // Keeps track of whether we should delete the signal handler (if we
+ // didn't create it, then we don't delete it).
+
+ ACE_Select_Reactor_Handle_Set wait_set_;
+ // Tracks handles that are waited for by select().
+
+ ACE_Reactor_Handle_Set suspend_set_;
+ // Tracks handles that are currently suspended.
+
+ ACE_Select_Reactor_Handle_Set ready_set_;
+ // Track HANDLES we are interested in for various events that must
+ // be dispatched *without* going through select().
+
+ int restart_;
+ // Restart automatically when interrupted
+
+ int requeue_position_;
+ // Position that the main ACE_Select_Reactor thread is requeued in
+ // the list of waiters during a notify() callback. If this value ==
+ // -1 we are requeued at the end of the list. Else if it's 0 then
+ // we are requeued at the front of the list. Else if it's > 1 then
+ // that indicates the number of waiters to skip over.
+
+ int max_notify_iterations_;
+ // Keeps track of the maximum number of times that the
+ // <ACE_Select_Reactor_Notify::handle_input> method will iterate and
+ // dispatch the <ACE_Event_Handlers> that are passed in via the
+ // notify pipe before breaking out of its <recv> loop. By default,
+ // this is set to -1, which means "iterate until the pipe is empty."
+
+ int initialized_;
+ // True if we've been initialized yet...
+
+ ACE_thread_t owner_;
+ // The original thread that created this Select_Reactor.
+
+ int state_changed_;
+ // True if state has changed during dispatching of
+ // <ACE_Event_Handlers>, else false. This is used to determine
+ // whether we need to make another trip through the <Select_Reactor>'s
+ // <wait_for_multiple_events> loop.
+
+ ACE_Select_Reactor_Token token_;
+ // Synchronization token for the MT_SAFE ACE_Select_Reactor.
+
+ ACE_Lock_Adapter<ACE_Select_Reactor_Token> lock_adapter_;
+ // Adapter used to return internal lock to outside world.
+
+ ACE_Select_Reactor_Notify notify_handler_;
+ // Callback object that unblocks the ACE_Select_Reactor if it's sleeping.
+
+ void renew (void);
+ // Enqueue ourselves into the list of waiting threads at the
+ // appropriate point specified by <requeue_position_>.
+
+ friend class ACE_Select_Reactor_Notify;
+ friend class ACE_Select_Reactor_Handler_Repository;
+
+private:
+ int release_token (void);
+ // Release the token lock when a Win32 structured exception occurs.
+
+ int handle_events_i (ACE_Time_Value *max_wait_time = 0);
+ // Stops the VC++ compiler from bitching about exceptions and destructors
+
+ ACE_Select_Reactor (const ACE_Select_Reactor &);
+ ACE_Select_Reactor &operator = (const ACE_Select_Reactor &);
+ // Deny access since member-wise won't work...
+};
+
+#if defined (__ACE_INLINE__)
+#include "ace/Select_Reactor.i"
+#endif /* __ACE_INLINE__ */
+
+#endif /* ACE_SELECT_REACTOR_H */
diff --git a/ace/Select_Reactor.i b/ace/Select_Reactor.i
new file mode 100644
index 00000000000..c972720b7c6
--- /dev/null
+++ b/ace/Select_Reactor.i
@@ -0,0 +1,214 @@
+/* -*- C++ -*- */
+// $Id$
+
+#include "ace/Reactor.h"
+
+ACE_INLINE int
+ACE_Select_Reactor::resume_handler (ACE_Event_Handler *h)
+{
+ ACE_TRACE ("ACE_Select_Reactor::resume_handler");
+ return this->resume_handler (h->get_handle ());
+}
+
+ACE_INLINE int
+ACE_Select_Reactor::resume_handler (const ACE_Handle_Set &handles)
+{
+ ACE_TRACE ("ACE_Select_Reactor::resume_handler");
+ ACE_Handle_Set_Iterator handle_iter (handles);
+ ACE_HANDLE h;
+
+ ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_MUTEX, ace_mon, this->token_, -1));
+
+ while ((h = handle_iter ()) != ACE_INVALID_HANDLE)
+ if (this->resume_i (h) == -1)
+ return -1;
+
+ return 0;
+}
+
+ACE_INLINE int
+ACE_Select_Reactor::suspend_handler (ACE_Event_Handler *h)
+{
+ ACE_TRACE ("ACE_Select_Reactor::suspend_handler");
+ return this->suspend_handler (h->get_handle ());
+}
+
+ACE_INLINE int
+ACE_Select_Reactor::suspend_handler (const ACE_Handle_Set &handles)
+{
+ ACE_TRACE ("ACE_Select_Reactor::suspend_handler");
+ ACE_Handle_Set_Iterator handle_iter (handles);
+ ACE_HANDLE h;
+
+ ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_MUTEX, ace_mon, this->token_, -1));
+
+ while ((h = handle_iter ()) != ACE_INVALID_HANDLE)
+ if (this->suspend_i (h) == -1)
+ return -1;
+
+ return 0;
+}
+
+ACE_INLINE int
+ACE_Select_Reactor::register_handler (int signum,
+ ACE_Event_Handler *new_sh,
+ ACE_Sig_Action *new_disp,
+ ACE_Event_Handler **old_sh,
+ ACE_Sig_Action *old_disp)
+{
+ ACE_TRACE ("ACE_Select_Reactor::register_handler");
+ return this->signal_handler_->register_handler (signum,
+ new_sh, new_disp,
+ old_sh, old_disp);
+}
+
+ACE_INLINE int
+ACE_Select_Reactor::register_handler (ACE_Event_Handler *event_handler,
+ ACE_HANDLE event_handle)
+{
+ // Don't have an implementation for this yet...
+ ACE_NOTSUP_RETURN (-1);
+}
+
+ACE_INLINE int
+ACE_Select_Reactor::register_handler (ACE_HANDLE event_handle,
+ ACE_HANDLE io_handle,
+ ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask mask)
+{
+ // Don't have an implementation for this yet...
+ ACE_NOTSUP_RETURN (-1);
+}
+
+ACE_INLINE int
+ACE_Select_Reactor::handler (int signum, ACE_Event_Handler **handler)
+{
+ ACE_TRACE ("ACE_Select_Reactor::handler");
+ return this->handler_i (signum, handler);
+}
+
+ACE_INLINE int
+ACE_Select_Reactor::remove_handler (int signum,
+ ACE_Sig_Action *new_disp,
+ ACE_Sig_Action *old_disp,
+ int sigkey)
+{
+ ACE_TRACE ("ACE_Select_Reactor::remove_handler");
+ return this->signal_handler_->remove_handler (signum, new_disp, old_disp, sigkey);
+}
+
+// = The remaining methods in this file must be called with locks
+// held. Note the queue handles its own locking.
+
+ACE_INLINE int
+ACE_Select_Reactor::cancel_timer (ACE_Event_Handler *handler,
+ int dont_call_handle_close)
+{
+ ACE_TRACE ("ACE_Select_Reactor::cancel_timer");
+ return this->timer_queue_->cancel (handler,
+ dont_call_handle_close);
+}
+
+ACE_INLINE int
+ACE_Select_Reactor::cancel_timer (long timer_id,
+ const void **arg,
+ int dont_call_handle_close)
+{
+ ACE_TRACE ("ACE_Select_Reactor::cancel_timer");
+ return this->timer_queue_->cancel (timer_id,
+ arg,
+ dont_call_handle_close);
+}
+
+// Performs operations on the "ready" bits.
+
+ACE_INLINE int
+ACE_Select_Reactor::ready_ops (ACE_Event_Handler *handler,
+ ACE_Reactor_Mask mask,
+ int ops)
+{
+ ACE_TRACE ("ACE_Select_Reactor::ready_ops");
+ return this->ready_ops (handler->get_handle (), mask, ops);
+}
+
+// Performs operations on the "dispatch" masks.
+
+ACE_INLINE int
+ACE_Select_Reactor::mask_ops (ACE_Event_Handler *handler,
+ ACE_Reactor_Mask mask,
+ int ops)
+{
+ ACE_TRACE ("ACE_Select_Reactor::mask_ops");
+ return this->mask_ops (handler->get_handle (), mask, ops);
+}
+
+ACE_INLINE int
+ACE_Select_Reactor::schedule_wakeup (ACE_Event_Handler *eh,
+ ACE_Reactor_Mask mask)
+{
+ ACE_TRACE ("ACE_Select_Reactor::schedule_wakeup");
+ return this->mask_ops (eh->get_handle (), mask, ACE_Reactor::ADD_MASK);
+}
+
+ACE_INLINE int
+ACE_Select_Reactor::cancel_wakeup (ACE_Event_Handler *eh,
+ ACE_Reactor_Mask mask)
+{
+ ACE_TRACE ("ACE_Select_Reactor::cancel_wakeup");
+ return this->mask_ops (eh->get_handle (), mask, ACE_Reactor::CLR_MASK);
+}
+
+ACE_INLINE int
+ACE_Select_Reactor::schedule_wakeup (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask)
+{
+ ACE_TRACE ("ACE_Select_Reactor::schedule_wakeup");
+ return this->mask_ops (handle, mask, ACE_Reactor::ADD_MASK);
+}
+
+ACE_INLINE int
+ACE_Select_Reactor::cancel_wakeup (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask)
+{
+ ACE_TRACE ("ACE_Select_Reactor::cancel_wakeup");
+ return this->mask_ops (handle, mask, ACE_Reactor::CLR_MASK);
+}
+
+ACE_INLINE ACE_Lock &
+ACE_Select_Reactor::lock (void)
+{
+ ACE_TRACE ("ACE_Select_Reactor::lock");
+ return this->lock_adapter_;
+}
+
+ACE_INLINE void
+ACE_Select_Reactor::wakeup_all_threads (void)
+{
+ // Send a notification, but don't block if there's no one to receive
+ // it.
+ this->notify (0, ACE_Event_Handler::NULL_MASK, (ACE_Time_Value *) &ACE_Time_Value::zero);
+}
+
+ACE_INLINE int
+ACE_Select_Reactor::alertable_handle_events (ACE_Time_Value *max_wait_time)
+{
+ return this->handle_events (max_wait_time);
+}
+
+ACE_INLINE int
+ACE_Select_Reactor::alertable_handle_events (ACE_Time_Value &max_wait_time)
+{
+ return this->handle_events (max_wait_time);
+}
+
+ACE_INLINE size_t
+ACE_Select_Reactor::size (void)
+{
+ return this->handler_rep_.size ();
+}
+
+ACE_INLINE size_t
+ACE_Select_Reactor_Handler_Repository::size (void)
+{
+ return this->max_size_;
+}
diff --git a/ace/Service_Config.cpp b/ace/Service_Config.cpp
index fc51931484e..8822ffc49ef 100644
--- a/ace/Service_Config.cpp
+++ b/ace/Service_Config.cpp
@@ -11,10 +11,8 @@
#include "ace/Service_Types.h"
#include "ace/Containers.h"
#include "ace/Auto_Ptr.h"
-
-#include "ace/Reactor.h"
#include "ace/Proactor.h"
-#include "ace/ReactorEx.h"
+#include "ace/Reactor.h"
#include "ace/Thread_Manager.h"
#include "ace/Service_Config.h"
@@ -109,39 +107,11 @@ ACE_Service_Config::reactor (ACE_Reactor *r)
return ACE_Reactor::instance (r);
}
-ACE_Proactor *
-ACE_Service_Config::proactor (size_t threads)
-{
- ACE_TRACE ("ACE_Service_Config::proactor");
- return ACE_Proactor::instance (threads);
-}
-
-ACE_Proactor *
-ACE_Service_Config::proactor (ACE_Proactor *r)
-{
- ACE_TRACE ("ACE_Service_Config::proactor");
- return ACE_Proactor::instance (r);
-}
-
-ACE_ReactorEx *
-ACE_Service_Config::reactorEx (void)
-{
- ACE_TRACE ("ACE_Service_Config::reactorEx");
- return ACE_ReactorEx::instance ();
-}
-
-ACE_ReactorEx *
-ACE_Service_Config::reactorEx (ACE_ReactorEx *r)
-{
- ACE_TRACE ("ACE_Service_Config::reactorEx");
- return ACE_ReactorEx::instance (r);
-}
-
ACE_Service_Repository *
ACE_Service_Config::svc_rep ()
{
ACE_TRACE ("ACE_Service_Config::svc_rep");
- return ACE_Service_Repository::instance();
+ return ACE_Service_Repository::instance ();
}
ACE_Service_Repository *
@@ -216,7 +186,7 @@ ACE_Service_Config::ACE_Service_Config (int ignore_static_svcs,
// Initialize the ACE_Reactor (the ACE_Reactor should be the same
// size as the ACE_Service_Repository).
- ACE_Reactor::instance (size);
+ ACE_Reactor::instance ();
// There's no point in dealing with this on NT since it doesn't really
// support signals very well...
@@ -260,7 +230,7 @@ ACE_Service_Config::parse_args (int argc, char *argv[])
#if !defined (ACE_LACKS_UNIX_SIGNALS)
ACE_Service_Config::signum_ = ACE_OS::atoi (getopt.optarg);
- if (ACE_Reactor::instance()->register_handler
+ if (ACE_Reactor::instance ()->register_handler
(ACE_Service_Config::signum_,
&ACE_Service_Config::signal_handler_) == -1)
ACE_ERROR ((LM_ERROR, "cannot obtain signal handler\n"));
@@ -285,8 +255,8 @@ ACE_Service_Config::initialize (const char svc_name[],
ACE_DEBUG ((LM_DEBUG, "opening static service %s\n", svc_name));
- if (ACE_Service_Repository::instance()->find (svc_name,
- (const ACE_Service_Type **) &srp) == -1)
+ if (ACE_Service_Repository::instance ()->find (svc_name,
+ (const ACE_Service_Type **) &srp) == -1)
ACE_ERROR_RETURN ((LM_ERROR, "%s not found\n", svc_name), -1);
else if (srp->type ()->init (args.argc (), args.argv ()) == -1)
@@ -311,7 +281,7 @@ ACE_Service_Config::initialize (const ACE_Service_Type *sr,
ACE_DEBUG ((LM_DEBUG, "opening dynamic service %s\n", sr->name ()));
- if (ACE_Service_Repository::instance()->insert (sr) == -1)
+ if (ACE_Service_Repository::instance ()->insert (sr) == -1)
ACE_ERROR_RETURN ((LM_ERROR, "insertion failed, %p\n", sr->name ()), -1);
else if (sr->type ()->init (args.argc (), args.argv ()) == -1)
@@ -391,7 +361,7 @@ ACE_Service_Config::load_static_svcs (void)
ACE_NEW_RETURN (sr, ACE_Service_Type (ssd->name_, stp,
0, ssd->active_), -1);
- if (ACE_Service_Repository::instance()->insert (sr) == -1)
+ if (ACE_Service_Repository::instance ()->insert (sr) == -1)
return -1;
}
return 0;
@@ -417,11 +387,11 @@ ACE_Service_Config::open (const char program_name[])
// Initialize the Service Repository (this will still work if user
// forgets to define an object of type ACE_Service_Config).
- ACE_Service_Repository::instance(ACE_Service_Config::MAX_SERVICES);
+ ACE_Service_Repository::instance (ACE_Service_Config::MAX_SERVICES);
// Initialize the ACE_Reactor (the ACE_Reactor should be the same
// size as the ACE_Service_Repository).
- ACE_Reactor::instance(ACE_Service_Config::MAX_SERVICES);
+ ACE_Reactor::instance ();
// Register ourselves to receive reconfiguration requests via
// signals!
@@ -559,7 +529,6 @@ ACE_Service_Config::close_singletons (void)
ACE_TRACE ("ACE_Service_Config::close_singletons");
ACE_Reactor::close_singleton ();
- ACE_ReactorEx::close_singleton ();
ACE_Proactor::close_singleton ();
ACE_Thread_Manager::close_singleton ();
@@ -575,69 +544,6 @@ ACE_Service_Config::~ACE_Service_Config (void)
ACE_Service_Config::close ();
}
-int
-ACE_Service_Config::run_proactor_event_loop (void)
-{
- ACE_TRACE ("ACE_Service_Config::run_proactor_event_loop");
- return ACE_Proactor::run_event_loop ();
-}
-
-// Handle events for -tv- time. handle_events updates -tv- to reflect
-// time elapsed, so do not return until -tv- == 0, or an error occurs.
-int
-ACE_Service_Config::run_proactor_event_loop (ACE_Time_Value &tv)
-{
- ACE_TRACE ("ACE_Service_Config::run_proactor_event_loop");
- return ACE_Proactor::run_event_loop (tv);
-}
-
-int
-ACE_Service_Config::end_proactor_event_loop (void)
-{
- ACE_TRACE ("ACE_Service_Config::end_proactor_event_loop");
- return ACE_Proactor::end_event_loop ();
-}
-
-/* static */
-sig_atomic_t
-ACE_Service_Config::proactor_event_loop_done (void)
-{
- ACE_TRACE ("ACE_Service_Config::proactor_event_loop_done");
- return ACE_Proactor::event_loop_done ();
-}
-
-// ************************************************************
-
-int
-ACE_Service_Config::run_reactorEx_event_loop (void)
-{
- ACE_TRACE ("ACE_Service_Config::run_reactorEx_event_loop");
- return ACE_ReactorEx::run_event_loop ();
-}
-
-
-int
-ACE_Service_Config::run_reactorEx_event_loop (ACE_Time_Value &tv)
-{
- ACE_TRACE ("ACE_Service_Config::run_reactorEx_event_loop");
- return ACE_ReactorEx::run_event_loop (tv);
-}
-
-int
-ACE_Service_Config::end_reactorEx_event_loop (void)
-{
- ACE_TRACE ("ACE_Service_Config::end_reactorEx_event_loop");
- return ACE_ReactorEx::end_event_loop ();
-}
-
-/* static */
-sig_atomic_t
-ACE_Service_Config::reactorEx_event_loop_done (void)
-{
- ACE_TRACE ("ACE_Service_Config::reactorEx_event_loop_done");
- return ACE_ReactorEx::event_loop_done ();
-}
-
// ************************************************************
/* static */
diff --git a/ace/Service_Config.h b/ace/Service_Config.h
index f1adbcccd64..9fbc3b14c7d 100644
--- a/ace/Service_Config.h
+++ b/ace/Service_Config.h
@@ -18,7 +18,6 @@
#define ACE_SERVICE_CONFIG_H
#include "ace/Service_Object.h"
-//#include "ace/Thread_Manager.h"
#include "ace/Signal.h"
#include "ace/Containers.h"
@@ -27,8 +26,6 @@ class ACE_Service_Repository;
class ACE_Service_Type;
class ACE_Allocator;
class ACE_Reactor;
-class ACE_Proactor;
-class ACE_ReactorEx;
class ACE_Thread_Manager;
extern "C"
@@ -75,7 +72,7 @@ class ACE_Export ACE_Service_Config
// configuration of services.
{
public:
- enum {MAX_SERVICES = ACE_DEFAULT_REACTOR_SIZE};
+ enum {MAX_SERVICES = ACE_DEFAULT_SELECT_REACTOR_SIZE};
// = Initialization and termination methods.
@@ -143,56 +140,6 @@ public:
// DO NOT USE THIS METHOD. It may be unsupported in future releases.
// Use ACE_Reactor::event_loop_done() instead.
- // = Proactor event loop management methods.
- static int run_proactor_event_loop (void);
- // Run the event loop until the <ACE_Proactor::handle_events>
- // method returns -1 or the <end_proactor_event_loop> method
- // is invoked.
- // DO NOT USE THIS METHOD. It may be unsupported in future releases.
- // Use ACE_Proactor::run_event_loop() instead.
-
- static int run_proactor_event_loop (ACE_Time_Value &tv);
- // Run the event loop until the <ACE_Proactor::handle_events>
- // method returns -1, the <end_proactor_event_loop> method
- // is invoked, or the <ACE_Time_Value> expires.
- // DO NOT USE THIS METHOD. It may be unsupported in future releases.
- // Use ACE_Proactor::run_event_loop() instead.
-
- static int end_proactor_event_loop (void);
- // Instruct the <ACE_Service_Config> to terminate its event loop.
- // DO NOT USE THIS METHOD. It may be unsupported in future releases.
- // Use ACE_Proactor::end_event_loop() instead.
-
- static sig_atomic_t proactor_event_loop_done (void);
- // Report if the proactor event loop is finished.
- // DO NOT USE THIS METHOD. It may be unsupported in future releases.
- // Use ACE_Proactor::event_loop_done() instead.
-
- // = ReactorEx event loop management methods.
- static int run_reactorEx_event_loop (void);
- // Run the event loop until the <ACE_ReactorEx::handle_events>
- // method returns -1 or the <end_reactorEx_event_loop> method
- // is invoked.
- // DO NOT USE THIS METHOD. It may be unsupported in future releases.
- // Use ACE_ReactorEx::run_event_loop() instead.
-
- static int run_reactorEx_event_loop (ACE_Time_Value &tv);
- // Run the event loop until the <ACE_ReactorEx::handle_events>
- // method returns -1, the <end_reactorEx_event_loop> method
- // is invoked, or the <ACE_Time_Value> expires.
- // DO NOT USE THIS METHOD. It may be unsupported in future releases.
- // Use ACE_ReactorEx::run_event_loop() instead.
-
- static int end_reactorEx_event_loop (void);
- // Instruct the <ACE_Service_Config> to terminate its event loop.
- // DO NOT USE THIS METHOD. It may be unsupported in future releases.
- // Use ACE_ReactorEx::end_event_loop() instead.
-
- static sig_atomic_t reactorEx_event_loop_done (void);
- // Report if the ReactorEx event loop is finished.
- // DO NOT USE THIS METHOD. It may be unsupported in future releases.
- // Use ACE_ReactorEx::event_loop_done() instead.
-
static sig_atomic_t reconfig_occurred (void);
// True if reconfiguration occurred.
@@ -204,9 +151,8 @@ public:
// = The following methods are static in order to enforce Singleton
// semantics for the Reactor, Service_Repository, Thread_Manager,
- // Acceptor/Connector Strategy factory, Proactor, and ReactorEx.
- // Other portions of the system may need to access them at some
- // point or another...
+ // and Acceptor/Connector Strategy factory. Other portions of the
+ // system may need to access them at some point or another...
// = Accessors and mutators for process-wide Singletons.
@@ -224,30 +170,6 @@ public:
// DO NOT USE THIS METHOD. It may be unsupported in future releases.
// Use ACE_Reactor::instance() instead.
- static ACE_Proactor *proactor (size_t threads = 0);
- // Get pointer to a process-wide <ACE_Proactor>. <threads> should
- // be part of another method. It's only here because I'm just a
- // grad student and not in charge. No, I'm not bitter about this.
- // DO NOT USE THIS METHOD. It may be unsupported in future releases.
- // Use ACE_Proactor::instance() instead.
-
- static ACE_Proactor *proactor (ACE_Proactor *);
- // Set pointer to a process-wide <ACE_Proactor> and return existing
- // pointer.
- // DO NOT USE THIS METHOD. It may be unsupported in future releases.
- // Use ACE_Proactor::instance() instead.
-
- static ACE_ReactorEx *reactorEx (void);
- // Get pointer to a process-wide <ACE_ReactorEx>.
- // DO NOT USE THIS METHOD. It may be unsupported in future releases.
- // Use ACE_ReactorEx::instance() instead.
-
- static ACE_ReactorEx *reactorEx (ACE_ReactorEx *);
- // Set pointer to a process-wide <ACE_ReactorEx> and return existing
- // pointer.
- // DO NOT USE THIS METHOD. It may be unsupported in future releases.
- // Use ACE_ReactorEx::instance() instead.
-
static ACE_Service_Repository *svc_rep (void);
// Get pointer to a process-wide <ACE_Service_Repository>.
// DO NOT USE THIS METHOD. It may be unsupported in future releases.
@@ -367,7 +289,5 @@ private:
// (only left here for to not break applications
// which rely on this - no real need any longer)
#include "ace/Reactor.h"
-#include "ace/Proactor.h"
-#include "ace/ReactorEx.h"
#include "ace/Svc_Conf_Tokens.h"
#endif /* ACE_SERVICE_CONFIG_H */
diff --git a/ace/Strategies.cpp b/ace/Strategies.cpp
index 576faa6ee2b..ec068c18c33 100644
--- a/ace/Strategies.cpp
+++ b/ace/Strategies.cpp
@@ -6,7 +6,6 @@
#define ACE_BUILD_DLL
#include "ace/Reactor.h"
-#include "ace/ReactorEx.h"
#include "ace/Strategies.h"
ACE_Notification_Strategy::ACE_Notification_Strategy (ACE_Event_Handler *eh,
@@ -77,38 +76,5 @@ ACE_Reactor_Notification_Strategy::reactor (ACE_Reactor *r)
this->reactor_ = r;
}
-ACE_ReactorEx_Notification_Strategy::ACE_ReactorEx_Notification_Strategy (ACE_ReactorEx *reactorEx,
- ACE_Event_Handler *eh,
- ACE_Reactor_Mask mask)
- : ACE_Notification_Strategy (eh, mask),
- reactorEx_ (reactorEx)
-{
-}
-
-int
-ACE_ReactorEx_Notification_Strategy::notify (void)
-{
- return this->reactorEx_->notify (this->eh_, this->mask_);
-}
-
-int
-ACE_ReactorEx_Notification_Strategy::notify (ACE_Event_Handler *eh,
- ACE_Reactor_Mask mask)
-{
- return this->reactorEx_->notify (eh, mask);
-}
-
-ACE_ReactorEx *
-ACE_ReactorEx_Notification_Strategy::reactorEx (void)
-{
- return this->reactorEx_;
-}
-
-void
-ACE_ReactorEx_Notification_Strategy::reactorEx (ACE_ReactorEx *r)
-{
- this->reactorEx_ = r;
-}
-
#endif /* ACE_STRATEGIES_C */
diff --git a/ace/Strategies.h b/ace/Strategies.h
index 0c16b0bbbe1..07eb421db1d 100644
--- a/ace/Strategies.h
+++ b/ace/Strategies.h
@@ -21,7 +21,6 @@
// Forward decls.
class ACE_Reactor;
-class ACE_ReactorEx;
class ACE_Export ACE_Notification_Strategy
// = TITLE
@@ -80,32 +79,6 @@ protected:
ACE_Reactor *reactor_;
};
-class ACE_Export ACE_ReactorEx_Notification_Strategy : public ACE_Notification_Strategy
- // = TITLE
- // Used to notify an ACE_ReactorEx
- //
- // = DESCRIPTION
- // Integrates the ACE_Message_Queue notification into the
- // ACE_ReactorEx::notify() method.
-{
-public:
- ACE_ReactorEx_Notification_Strategy (ACE_ReactorEx *reactorEx,
- ACE_Event_Handler *eh,
- ACE_Reactor_Mask mask);
-
- virtual int notify (void);
-
- virtual int notify (ACE_Event_Handler *,
- ACE_Reactor_Mask mask);
-
- // Get/Set the reactorEx
- ACE_ReactorEx *reactorEx (void);
- void reactorEx (ACE_ReactorEx *r);
-
-protected:
- ACE_ReactorEx *reactorEx_;
-};
-
// This needs to come here to avoid circular dependencies.
#include "ace/Strategies_T.h"
diff --git a/ace/Synch_T.h b/ace/Synch_T.h
index 69c2c46af42..775288687fa 100644
--- a/ace/Synch_T.h
+++ b/ace/Synch_T.h
@@ -39,6 +39,19 @@ class ACE_Lock_Adapter : public ACE_Lock
public:
typedef ACE_LOCKING_MECHANISM ACE_LOCK;
+ // = Initialization/Finalization methods.
+
+ ACE_Lock_Adapter (ACE_LOCKING_MECHANISM &lock);
+ // Constructor. All locking requests will be forwarded to <lock>.
+
+ ACE_Lock_Adapter (void);
+ // Constructor. Since no lock is provided by the user, one will be
+ // created internally.
+
+ virtual ~ACE_Lock_Adapter (void);
+ // Destructor. If <lock_> was not passed in by the user, it will be
+ // deleted.
+
// = Lock accessors.
virtual int acquire (void);
// Block the thread until the lock is acquired.
@@ -71,8 +84,12 @@ public:
// Explicitly destroy the lock.
private:
- ACE_LOCKING_MECHANISM lock_;
+ ACE_LOCKING_MECHANISM *lock_;
// The concrete locking mechanism that all the methods delegate to.
+
+ int delete_lock_;
+ // This flag keep track of whether we are responsible for deleting
+ // the lock
};
template <class ACE_LOCK, class TYPE>
diff --git a/ace/Synch_T.i b/ace/Synch_T.i
index d79aa6b7128..586f056e6cc 100644
--- a/ace/Synch_T.i
+++ b/ace/Synch_T.i
@@ -5,18 +5,40 @@
#include "ace/Thread.h"
+template <class ACE_LOCKING_MECHANISM> ACE_INLINE
+ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::ACE_Lock_Adapter (ACE_LOCKING_MECHANISM &lock)
+ : lock_ (&lock),
+ delete_lock_ (0)
+{
+}
+
+template <class ACE_LOCKING_MECHANISM> ACE_INLINE
+ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::ACE_Lock_Adapter (void)
+ : lock_ (0),
+ delete_lock_ (1)
+{
+ ACE_NEW (this->lock_, ACE_LOCKING_MECHANISM);
+}
+
+template <class ACE_LOCKING_MECHANISM> ACE_INLINE
+ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::~ACE_Lock_Adapter (void)
+{
+ if (this->delete_lock_)
+ delete this->lock_;
+}
+
// Explicitly destroy the lock.
template <class ACE_LOCKING_MECHANISM> ACE_INLINE int
ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::remove (void)
{
- return this->lock_.remove ();
+ return this->lock_->remove ();
}
// Block the thread until the lock is acquired.
template <class ACE_LOCKING_MECHANISM> ACE_INLINE int
ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::acquire (void)
{
- return this->lock_.acquire ();
+ return this->lock_->acquire ();
}
// Conditionally acquire the lock (i.e., won't block).
@@ -24,7 +46,7 @@ ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::acquire (void)
template <class ACE_LOCKING_MECHANISM> ACE_INLINE int
ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::tryacquire (void)
{
- return this->lock_.tryacquire ();
+ return this->lock_->tryacquire ();
}
// Release the lock.
@@ -32,7 +54,7 @@ ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::tryacquire (void)
template <class ACE_LOCKING_MECHANISM> ACE_INLINE int
ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::release (void)
{
- return this->lock_.release ();
+ return this->lock_->release ();
}
// Block until the thread acquires a read lock. If the locking
@@ -42,7 +64,7 @@ ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::release (void)
template <class ACE_LOCKING_MECHANISM> ACE_INLINE int
ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::acquire_read (void)
{
- return this->lock_.acquire_read ();
+ return this->lock_->acquire_read ();
}
// Block until the thread acquires a write lock. If the locking
@@ -52,7 +74,7 @@ ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::acquire_read (void)
template <class ACE_LOCKING_MECHANISM> ACE_INLINE int
ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::acquire_write (void)
{
- return this->lock_.acquire_write ();
+ return this->lock_->acquire_write ();
}
// Conditionally acquire a read lock. If the locking mechanism
@@ -61,7 +83,7 @@ ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::acquire_write (void)
template <class ACE_LOCKING_MECHANISM> ACE_INLINE int
ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::tryacquire_read (void)
{
- return this->lock_.tryacquire_read ();
+ return this->lock_->tryacquire_read ();
}
// Conditionally acquire a write lock. If the locking mechanism
@@ -70,7 +92,7 @@ ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::tryacquire_read (void)
template <class ACE_LOCKING_MECHANISM> ACE_INLINE int
ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::tryacquire_write (void)
{
- return this->lock_.tryacquire_write ();
+ return this->lock_->tryacquire_write ();
}
#if defined (ACE_HAS_THREADS)
diff --git a/ace/Timer_Queue_T.h b/ace/Timer_Queue_T.h
index 132e44cb020..db74cdfc4d5 100644
--- a/ace/Timer_Queue_T.h
+++ b/ace/Timer_Queue_T.h
@@ -18,7 +18,6 @@
#if !defined (ACE_TIMER_QUEUE_T_H)
#define ACE_TIMER_QUEUE_T_H
-#include "ace/Time_Value.h"
#include "ace/Signal.h"
#include "ace/Free_List.h"
#include "ace/Signal.h"
diff --git a/ace/Token.h b/ace/Token.h
index 26d76735f8c..095582b8ffb 100644
--- a/ace/Token.h
+++ b/ace/Token.h
@@ -97,6 +97,18 @@ public:
// Relinquish the token. If there are any waiters then the next one
// in line gets it.
+ int acquire_read (void);
+ // Just calls <acquire>.
+
+ int acquire_write (void);
+ // Just calls <acquire>.
+
+ int tryacquire_read (void);
+ // Just calls <tryacquire>.
+
+ int tryacquire_write (void);
+ // Just calls <tryacquire>.
+
// = Accessor methods.
int waiters (void);
diff --git a/ace/Token.i b/ace/Token.i
index 8aa52c7c0e0..44e7b506f5f 100644
--- a/ace/Token.i
+++ b/ace/Token.i
@@ -38,3 +38,31 @@ ACE_Token::current_owner (void)
return this->owner_;
}
+ACE_INLINE int
+ACE_Token::acquire_read (void)
+{
+ ACE_TRACE ("ACE_Token::acquire_read");
+ return this->acquire ();
+}
+
+ACE_INLINE int
+ACE_Token::acquire_write (void)
+{
+ ACE_TRACE ("ACE_Token::acquire_write");
+ return this->acquire ();
+}
+
+ACE_INLINE int
+ACE_Token::tryacquire_read (void)
+{
+ ACE_TRACE ("ACE_Token::tryacquire_read");
+ return this->tryacquire ();
+}
+
+ACE_INLINE int
+ACE_Token::tryacquire_write (void)
+{
+ ACE_TRACE ("ACE_Token::tryacquire_write");
+ return this->tryacquire ();
+}
+
diff --git a/ace/ReactorEx.cpp b/ace/WFMO_Reactor.cpp
index 8d03e8c627f..3fd9616c6aa 100644
--- a/ace/ReactorEx.cpp
+++ b/ace/WFMO_Reactor.cpp
@@ -1,40 +1,28 @@
-// ReactorEx.cpp
// $Id$
#define ACE_BUILD_DLL
-#include "ace/ReactorEx.h"
-#include "ace/Timer_List.h"
+
+#include "ace/WFMO_Reactor.h"
+
+#include "ace/Handle_Set.h"
+#include "ace/Timer_Heap.h"
#include "ace/Thread.h"
-#include "ace/Service_Config.h"
#if defined (ACE_WIN32)
#if !defined (__ACE_INLINE__)
-#include "ace/Handle_Set.h"
-#include "ace/ReactorEx.i"
+#include "ace/WFMO_Reactor.i"
#endif /* __ACE_INLINE__ */
#include "ace/Auto_Ptr.h"
-// Process-wide ACE_ReactorEx.
-ACE_ReactorEx *ACE_ReactorEx::reactorEx_ = 0;
-
-// Controls whether the ReactorEx is deleted when we shut down (we can
-// only delete it safely if we created it!)
-int ACE_ReactorEx::delete_reactorEx_ = 0;
-
-// Terminate the eventloop.
-sig_atomic_t ACE_ReactorEx::end_event_loop_ = 0;
-
-/************************************************************/
-
-ACE_ReactorEx_Handler_Repository::ACE_ReactorEx_Handler_Repository (ACE_ReactorEx &reactorEx)
- : reactorEx_ (reactorEx)
+ACE_WFMO_Reactor_Handler_Repository::ACE_WFMO_Reactor_Handler_Repository (ACE_WFMO_Reactor &wfmo_reactor)
+ : wfmo_reactor_ (wfmo_reactor)
{
}
int
-ACE_ReactorEx_Handler_Repository::open (size_t size)
+ACE_WFMO_Reactor_Handler_Repository::open (size_t size)
{
// Dynamic allocation
ACE_NEW_RETURN (this->current_handles_, ACE_HANDLE[size], -1);
@@ -57,7 +45,7 @@ ACE_ReactorEx_Handler_Repository::open (size_t size)
return 0;
}
-ACE_ReactorEx_Handler_Repository::~ACE_ReactorEx_Handler_Repository (void)
+ACE_WFMO_Reactor_Handler_Repository::~ACE_WFMO_Reactor_Handler_Repository (void)
{
// Free up dynamically allocated space
delete[] this->current_handles_;
@@ -67,8 +55,8 @@ ACE_ReactorEx_Handler_Repository::~ACE_ReactorEx_Handler_Repository (void)
}
void
-ACE_ReactorEx_Handler_Repository::remove_network_events_i (long &existing_masks,
- ACE_Reactor_Mask to_be_removed_masks)
+ACE_WFMO_Reactor_Handler_Repository::remove_network_events_i (long &existing_masks,
+ ACE_Reactor_Mask to_be_removed_masks)
{
if (ACE_BIT_STRICTLY_ENABLED (to_be_removed_masks, ACE_Event_Handler::READ_MASK))
ACE_CLR_BITS (existing_masks, FD_READ);
@@ -96,9 +84,9 @@ ACE_ReactorEx_Handler_Repository::remove_network_events_i (long &existing_masks,
}
int
-ACE_ReactorEx_Handler_Repository::unbind_i (ACE_HANDLE handle,
- ACE_Reactor_Mask mask,
- int &changes_required)
+ACE_WFMO_Reactor_Handler_Repository::unbind_i (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask,
+ int &changes_required)
{
int error = 0;
@@ -148,8 +136,8 @@ ACE_ReactorEx_Handler_Repository::unbind_i (ACE_HANDLE handle,
}
int
-ACE_ReactorEx_Handler_Repository::remove_handler_i (size_t index,
- ACE_Reactor_Mask to_be_removed_masks)
+ACE_WFMO_Reactor_Handler_Repository::remove_handler_i (size_t index,
+ ACE_Reactor_Mask to_be_removed_masks)
{
// I/O entries
if (this->current_info_[index].io_entry_)
@@ -186,8 +174,8 @@ ACE_ReactorEx_Handler_Repository::remove_handler_i (size_t index,
}
int
-ACE_ReactorEx_Handler_Repository::remove_suspended_handler_i (size_t index,
- ACE_Reactor_Mask to_be_removed_masks)
+ACE_WFMO_Reactor_Handler_Repository::remove_suspended_handler_i (size_t index,
+ ACE_Reactor_Mask to_be_removed_masks)
{
// I/O entries
if (this->current_suspended_info_[index].io_entry_)
@@ -224,8 +212,8 @@ ACE_ReactorEx_Handler_Repository::remove_suspended_handler_i (size_t index,
}
int
-ACE_ReactorEx_Handler_Repository::suspend_handler_i (ACE_HANDLE handle,
- int &changes_required)
+ACE_WFMO_Reactor_Handler_Repository::suspend_handler_i (ACE_HANDLE handle,
+ int &changes_required)
{
// Remember this value; only if it changes do we need to wakeup
// the other threads
@@ -258,8 +246,8 @@ ACE_ReactorEx_Handler_Repository::suspend_handler_i (ACE_HANDLE handle,
}
int
-ACE_ReactorEx_Handler_Repository::resume_handler_i (ACE_HANDLE handle,
- int &changes_required)
+ACE_WFMO_Reactor_Handler_Repository::resume_handler_i (ACE_HANDLE handle,
+ int &changes_required)
{
// Remember this value; only if it changes do we need to wakeup
// the other threads
@@ -290,10 +278,10 @@ ACE_ReactorEx_Handler_Repository::resume_handler_i (ACE_HANDLE handle,
}
void
-ACE_ReactorEx_Handler_Repository::unbind_all (void)
+ACE_WFMO_Reactor_Handler_Repository::unbind_all (void)
{
{
- ACE_GUARD (ACE_Process_Mutex, ace_mon, this->reactorEx_.lock_);
+ ACE_GUARD (ACE_Process_Mutex, ace_mon, this->wfmo_reactor_.lock_);
// Remove all the handlers
for (size_t i = 0; i < this->max_handlep1_; i++)
@@ -306,16 +294,16 @@ ACE_ReactorEx_Handler_Repository::unbind_all (void)
// Wake up all threads in WaitForMultipleObjects so that they can
// reconsult the handle set
- this->reactorEx_.wakeup_all_threads ();
+ this->wfmo_reactor_.wakeup_all_threads ();
}
int
-ACE_ReactorEx_Handler_Repository::bind_i (int io_entry,
- ACE_Event_Handler *event_handler,
- long network_events,
- ACE_HANDLE io_handle,
- ACE_HANDLE event_handle,
- int delete_event)
+ACE_WFMO_Reactor_Handler_Repository::bind_i (int io_entry,
+ ACE_Event_Handler *event_handler,
+ long network_events,
+ ACE_HANDLE io_handle,
+ ACE_HANDLE event_handle,
+ int delete_event)
{
// Make sure that the <handle> is valid
if (event_handle == ACE_INVALID_HANDLE)
@@ -324,9 +312,9 @@ ACE_ReactorEx_Handler_Repository::bind_i (int io_entry,
return -1;
size_t current_size = this->max_handlep1_ +
- this->handles_to_be_added_ -
- this->handles_to_be_deleted_ +
- this->suspended_handles_;
+ this->handles_to_be_added_ -
+ this->handles_to_be_deleted_ +
+ this->suspended_handles_;
// Make sure that there's room in the table.
if (current_size < this->max_size_)
@@ -342,12 +330,9 @@ ACE_ReactorEx_Handler_Repository::bind_i (int io_entry,
this->handles_to_be_added_++;
- // Assign *this* <ReactorEx> to the <Event_Handler>.
- event_handler->reactorEx (&this->reactorEx_);
-
// Wake up all threads in WaitForMultipleObjects so that they can
// reconsult the handle set
- this->reactorEx_.wakeup_all_threads ();
+ this->wfmo_reactor_.wakeup_all_threads ();
}
else
return -1;
@@ -356,7 +341,7 @@ ACE_ReactorEx_Handler_Repository::bind_i (int io_entry,
}
int
-ACE_ReactorEx_Handler_Repository::handle_deletions (void)
+ACE_WFMO_Reactor_Handler_Repository::handle_deletions (void)
{
// Go through the entire valid array and check for all handles that
// have been schedule for deletion
@@ -375,7 +360,7 @@ ACE_ReactorEx_Handler_Repository::handle_deletions (void)
// will only call it once per deregistering <Event_Handler>.
// This is essential in the case when the <Event_Handler> will
// do something like delete itself and we have multiple
- // threads in ReactorEx.
+ // threads in WFMO_Reactor.
//
// Make sure that the DONT_CALL mask is not set
ACE_Reactor_Mask masks = this->current_info_[i].close_masks_;
@@ -392,7 +377,7 @@ ACE_ReactorEx_Handler_Repository::handle_deletions (void)
this->current_info_[i].event_handler_->handle_close (handle, masks);
}
- // If <ReactorEx> created the event, we need to clean it up
+ // If <WFMO_Reactor> created the event, we need to clean it up
if (this->current_info_[i].delete_event_)
ACE_OS::event_destroy (&this->current_handles_[i]);
@@ -447,7 +432,7 @@ ACE_ReactorEx_Handler_Repository::handle_deletions (void)
}
int
-ACE_ReactorEx_Handler_Repository::handle_additions (void)
+ACE_WFMO_Reactor_Handler_Repository::handle_additions (void)
{
// Go through the <to_be_added_*> arrays
for (int i = 0; i < (int) this->handles_to_be_added_; i++)
@@ -478,7 +463,7 @@ ACE_ReactorEx_Handler_Repository::handle_additions (void)
// will only call it once per deregistering <Event_Handler>.
// This is essential in the case when the <Event_Handler> will
// do something like delete itself and we have multiple
- // threads in ReactorEx.
+ // threads in WFMO_Reactor.
//
// Make sure that the DONT_CALL mask is not set
ACE_Reactor_Mask masks = this->current_suspended_info_[i].close_masks_;
@@ -495,7 +480,7 @@ ACE_ReactorEx_Handler_Repository::handle_additions (void)
this->current_suspended_info_[i].event_handler_->handle_close (handle, masks);
}
- // If <ReactorEx> created the event, we need to clean it up
+ // If <WFMO_Reactor> created the event, we need to clean it up
if (this->current_suspended_info_[i].delete_event_)
ACE_OS::event_destroy (&this->current_suspended_info_[i].event_handle_);
@@ -542,12 +527,15 @@ ACE_ReactorEx_Handler_Repository::handle_additions (void)
/************************************************************/
-ACE_ReactorEx::ACE_ReactorEx (ACE_Sig_Handler *sh,
- ACE_Timer_Queue *tq)
- : timer_queue_ (0),
+ACE_WFMO_Reactor::ACE_WFMO_Reactor (ACE_Sig_Handler *sh,
+ ACE_Timer_Queue *tq)
+ : signal_handler_ (0),
+ delete_signal_handler_ (0),
+ timer_queue_ (0),
delete_timer_queue_ (0),
handler_rep_ (*this),
delete_handler_rep_ (0),
+ lock_adapter_ (lock_),
// this event is initially signaled
ok_to_wait_ (1),
// this event is initially unsignaled
@@ -560,18 +548,21 @@ ACE_ReactorEx::ACE_ReactorEx (ACE_Sig_Handler *sh,
change_state_thread_ (0),
open_for_business_ (0)
{
- if (this->open (ACE_ReactorEx::DEFAULT_SIZE, 0, sh, tq) == -1)
- ACE_ERROR ((LM_ERROR, "%p\n", "ReactorEx"));
+ if (this->open (ACE_WFMO_Reactor::DEFAULT_SIZE, 0, sh, tq) == -1)
+ ACE_ERROR ((LM_ERROR, "%p\n", "WFMO_Reactor"));
}
-ACE_ReactorEx::ACE_ReactorEx (size_t size,
- int unused,
- ACE_Sig_Handler *sh,
- ACE_Timer_Queue *tq)
- : timer_queue_ (0),
+ACE_WFMO_Reactor::ACE_WFMO_Reactor (size_t size,
+ int unused,
+ ACE_Sig_Handler *sh,
+ ACE_Timer_Queue *tq)
+ : signal_handler_ (0),
+ delete_signal_handler_ (0),
+ timer_queue_ (0),
delete_timer_queue_ (0),
handler_rep_ (*this),
delete_handler_rep_ (0),
+ lock_adapter_ (lock_),
// this event is initially signaled
ok_to_wait_ (1),
// this event is initially unsignaled
@@ -587,120 +578,14 @@ ACE_ReactorEx::ACE_ReactorEx (size_t size,
ACE_UNUSED_ARG (unused);
if (this->open (size, 0, sh, tq) == -1)
- ACE_ERROR ((LM_ERROR, "%p\n", "ReactorEx"));
-}
-
-ACE_ReactorEx *
-ACE_ReactorEx::instance (void)
-{
- ACE_TRACE ("ACE_ReactorEx::instance");
-
- if (ACE_ReactorEx::reactorEx_ == 0)
- {
- // Perform Double-Checked Locking Optimization.
- ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
- *ACE_Static_Object_Lock::instance (), 0));
-
- if (ACE_ReactorEx::reactorEx_ == 0)
- {
- ACE_NEW_RETURN (ACE_ReactorEx::reactorEx_, ACE_ReactorEx, 0);
- ACE_ReactorEx::delete_reactorEx_ = 1;
- }
- }
-
- return ACE_ReactorEx::reactorEx_;
-}
-
-ACE_ReactorEx *
-ACE_ReactorEx::instance (ACE_ReactorEx *r)
-{
- ACE_TRACE ("ACE_ReactorEx::instance");
-
- ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
- *ACE_Static_Object_Lock::instance (), 0));
- ACE_ReactorEx *t = ACE_ReactorEx::reactorEx_;
- // We can't safely delete it since we don't know who created it!
- ACE_ReactorEx::delete_reactorEx_ = 0;
-
- ACE_ReactorEx::reactorEx_ = r;
- return t;
-}
-
-void
-ACE_ReactorEx::close_singleton (void)
-{
- ACE_TRACE ("ACE_ReactorEx::close_singleton");
-
- ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon,
- *ACE_Static_Object_Lock::instance ()));
-
- if (ACE_ReactorEx::delete_reactorEx_)
- {
- delete ACE_ReactorEx::reactorEx_;
- ACE_ReactorEx::reactorEx_ = 0;
- ACE_ReactorEx::delete_reactorEx_ = 0;
- }
-}
-
-int
-ACE_ReactorEx::run_event_loop (void)
-{
- ACE_TRACE ("ACE_ReactorEx::run_event_loop");
-
- while (ACE_ReactorEx::end_event_loop_ == 0)
- {
- int result = ACE_ReactorEx::instance ()->handle_events ();
-
- if (ACE_Service_Config::reconfig_occurred ())
- ACE_Service_Config::reconfigure ();
-
- else if (result == -1)
- return -1;
- }
- /* NOTREACHED */
- return 0;
-}
-
-
-int
-ACE_ReactorEx::run_event_loop (ACE_Time_Value &tv)
-{
- ACE_TRACE ("ACE_ReactorEx::run_event_loop");
-
- while (ACE_ReactorEx::end_event_loop_ == 0 && tv != ACE_Time_Value::zero)
- {
- int result = ACE_ReactorEx::instance ()->handle_events (tv);
- if (ACE_Service_Config::reconfig_occurred ())
- ACE_Service_Config::reconfigure ();
- else if (result == -1)
- return result;
- }
-
- /* NOTREACHED */
- return 0;
+ ACE_ERROR ((LM_ERROR, "%p\n", "WFMO_Reactor"));
}
int
-ACE_ReactorEx::end_event_loop (void)
-{
- ACE_TRACE ("ACE_ReactorEx::end_event_loop");
- ACE_ReactorEx::end_event_loop_ = 1;
- return ACE_ReactorEx::instance ()->notify ();
-}
-
-/* static */
-sig_atomic_t
-ACE_ReactorEx::event_loop_done (void)
-{
- ACE_TRACE ("ACE_ReactorEx::end_event_loop");
- return ACE_ReactorEx::end_event_loop_;
-}
-
-int
-ACE_ReactorEx::open (size_t size,
- int unused,
- ACE_Sig_Handler *sh,
- ACE_Timer_Queue *tq)
+ACE_WFMO_Reactor::open (size_t size,
+ int unused,
+ ACE_Sig_Handler *sh,
+ ACE_Timer_Queue *tq)
{
ACE_UNUSED_ARG (unused);
ACE_UNUSED_ARG (sh);
@@ -716,9 +601,9 @@ ACE_ReactorEx::open (size_t size,
this->atomic_wait_array_[0] = this->lock_.lock ().proc_mutex_;
this->atomic_wait_array_[1] = this->ok_to_wait_.handle ();
- // This is to guard against reopens of ReactorEx
+ // This is to guard against reopens of WFMO_Reactor
if (this->delete_handler_rep_)
- this->handler_rep_.~ACE_ReactorEx_Handler_Repository ();
+ this->handler_rep_.~ACE_WFMO_Reactor_Handler_Repository ();
// Open the handle repository
// Two additional handles for internal purposes
@@ -768,6 +653,21 @@ ACE_ReactorEx::open (size_t size,
this->delete_timer_queue_ = 0;
}
+ // Signal Handler
+ if (this->delete_signal_handler_)
+ delete this->signal_handler_;
+
+ if (sh == 0)
+ {
+ ACE_NEW_RETURN (this->signal_handler_, ACE_Sig_Handler, -1);
+ this->delete_signal_handler_ = 1;
+ }
+ else
+ {
+ this->signal_handler_ = sh;
+ this->delete_signal_handler_ = 0;
+ }
+
// We are open for business
this->open_for_business_ = 1;
@@ -775,7 +675,7 @@ ACE_ReactorEx::open (size_t size,
}
int
-ACE_ReactorEx::close (void)
+ACE_WFMO_Reactor::close (void)
{
// This GUARD is necessary since we are updating shared state.
ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, this->lock_, -1);
@@ -792,7 +692,7 @@ ACE_ReactorEx::close (void)
return 0;
}
-ACE_ReactorEx::~ACE_ReactorEx (void)
+ACE_WFMO_Reactor::~ACE_WFMO_Reactor (void)
{
this->close ();
@@ -802,13 +702,20 @@ ACE_ReactorEx::~ACE_ReactorEx (void)
this->timer_queue_ = 0;
this->delete_timer_queue_ = 0;
}
+
+ if (this->delete_signal_handler_)
+ {
+ delete this->signal_handler_;
+ this->signal_handler_ = 0;
+ this->delete_signal_handler_ = 0;
+ }
}
int
-ACE_ReactorEx::register_handler_i (ACE_HANDLE event_handle,
- ACE_HANDLE io_handle,
- ACE_Event_Handler *event_handler,
- ACE_Reactor_Mask mask)
+ACE_WFMO_Reactor::register_handler_i (ACE_HANDLE event_handle,
+ ACE_HANDLE io_handle,
+ ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask mask)
{
// Make sure that the <handle> is valid
if (io_handle == ACE_INVALID_HANDLE)
@@ -868,8 +775,8 @@ ACE_ReactorEx::register_handler_i (ACE_HANDLE event_handle,
}
int
-ACE_ReactorEx::schedule_wakeup_i (ACE_HANDLE io_handle,
- ACE_Reactor_Mask masks_to_be_added)
+ACE_WFMO_Reactor::schedule_wakeup_i (ACE_HANDLE io_handle,
+ ACE_Reactor_Mask masks_to_be_added)
{
// Make sure that the <handle> is valid
if (this->handler_rep_.invalid_handle (io_handle))
@@ -897,11 +804,11 @@ ACE_ReactorEx::schedule_wakeup_i (ACE_HANDLE io_handle,
int
-ACE_ReactorEx_Handler_Repository::add_network_events_i (ACE_Reactor_Mask mask,
- ACE_HANDLE io_handle,
- long &new_masks,
- ACE_HANDLE &event_handle,
- int &delete_event)
+ACE_WFMO_Reactor_Handler_Repository::add_network_events_i (ACE_Reactor_Mask mask,
+ ACE_HANDLE io_handle,
+ long &new_masks,
+ ACE_HANDLE &event_handle,
+ int &delete_event)
{
int found = 0;
size_t i;
@@ -964,10 +871,10 @@ ACE_ReactorEx_Handler_Repository::add_network_events_i (ACE_Reactor_Mask mask,
// Waits for and dispatches all events. Returns -1 on error, 0 if
// max_wait_time expired, or the number of events that were dispatched.
int
-ACE_ReactorEx::event_handling (ACE_Time_Value *max_wait_time,
- int alertable)
+ACE_WFMO_Reactor::event_handling (ACE_Time_Value *max_wait_time,
+ int alertable)
{
- ACE_TRACE ("ACE_ReactorEx::event_handling");
+ ACE_TRACE ("ACE_WFMO_Reactor::event_handling");
// Make sure we are not closed
if (!this->open_for_business_)
@@ -992,7 +899,7 @@ ACE_ReactorEx::event_handling (ACE_Time_Value *max_wait_time,
this->lock_.release ();
// Update the countdown to reflect time waiting to play with the
- // mutex and event.
+ // mut and event.
countdown.update ();
// Wait for event to happen
@@ -1006,8 +913,8 @@ ACE_ReactorEx::event_handling (ACE_Time_Value *max_wait_time,
}
int
-ACE_ReactorEx::ok_to_wait (ACE_Time_Value *max_wait_time,
- int alertable)
+ACE_WFMO_Reactor::ok_to_wait (ACE_Time_Value *max_wait_time,
+ int alertable)
{
// Calculate the max time we should spend here
//
@@ -1041,14 +948,14 @@ ACE_ReactorEx::ok_to_wait (ACE_Time_Value *max_wait_time,
}
int
-ACE_ReactorEx::wait_for_multiple_events (ACE_Time_Value *max_wait_time,
- int alertable)
+ACE_WFMO_Reactor::wait_for_multiple_events (ACE_Time_Value *max_wait_time,
+ int alertable)
{
int timeout = this->calculate_timeout (max_wait_time);
// Wait for any of handles_ to be active, or until timeout expires.
// If <alertable> is enabled allow asynchronous completion of
- // ReadFileEx and WriteFileEx operations.
+ // ReadFile and WriteFile operations.
return ::WaitForMultipleObjectsEx (this->handler_rep_.max_handlep1 (),
this->handler_rep_.handles (),
FALSE,
@@ -1057,7 +964,7 @@ ACE_ReactorEx::wait_for_multiple_events (ACE_Time_Value *max_wait_time,
}
int
-ACE_ReactorEx::calculate_timeout (ACE_Time_Value *max_wait_time)
+ACE_WFMO_Reactor::calculate_timeout (ACE_Time_Value *max_wait_time)
{
ACE_Time_Value *time = 0;
if (this->owner_ == ACE_Thread::self ())
@@ -1073,12 +980,14 @@ ACE_ReactorEx::calculate_timeout (ACE_Time_Value *max_wait_time)
int
-ACE_ReactorEx::dispatch (int wait_status)
+ACE_WFMO_Reactor::dispatch (int wait_status)
{
+ int handlers_dispatched = 0;
+
// If "owner" thread
if (ACE_Thread::self () == this->owner_)
- // Expire all pending timers.
- this->timer_queue_->expire ();
+ // expire all pending timers.
+ handlers_dispatched += this->timer_queue_->expire ();
switch (wait_status)
{
@@ -1087,11 +996,12 @@ ACE_ReactorEx::dispatch (int wait_status)
return -1;
case WAIT_TIMEOUT: // Timeout.
errno = ETIME;
- return 0;
+ return handlers_dispatched;
case WAIT_ABANDONED_0:
- // We'll let dispatch worry about abandoned mutexes.
+ // We'll let dispatch worry about abandoned mutes.
default: // Dispatch.
- return this->dispatch_handles (wait_status - WAIT_OBJECT_0);
+ handlers_dispatched += this->dispatch_handles (wait_status - WAIT_OBJECT_0);
+ return handlers_dispatched;
}
}
@@ -1100,7 +1010,7 @@ ACE_ReactorEx::dispatch (int wait_status)
// through our handle set looking for active handles.
int
-ACE_ReactorEx::dispatch_handles (size_t index)
+ACE_WFMO_Reactor::dispatch_handles (size_t index)
{
for (int number_of_handlers_dispatched = 1;
;
@@ -1140,14 +1050,14 @@ ACE_ReactorEx::dispatch_handles (size_t index)
// handler was removed.
int
-ACE_ReactorEx::dispatch_handler (int index)
+ACE_WFMO_Reactor::dispatch_handler (int index)
{
// Dispatch the handler if it has not been scheduled for deletion.
// Note that this is a very week test if there are multiple threads
// dispatching this index as no locks are held here. Generally, you
// do not want to do something like deleting the this pointer in
// handle_close() if you have registered multiple times and there is
- // more than one thread in ReactorEx->handle_events().
+ // more than one thread in WFMO_Reactor->handle_events().
if (!this->handler_rep_.scheduled_for_deletion (index))
{
ACE_HANDLE event_handle = *(this->handler_rep_.handles () + index);
@@ -1161,8 +1071,8 @@ ACE_ReactorEx::dispatch_handler (int index)
}
int
-ACE_ReactorEx::simple_dispatch_handler (int index,
- ACE_HANDLE event_handle)
+ACE_WFMO_Reactor::simple_dispatch_handler (int index,
+ ACE_HANDLE event_handle)
{
// This dispatch is used for non-I/O entires
@@ -1178,12 +1088,12 @@ ACE_ReactorEx::simple_dispatch_handler (int index,
}
int
-ACE_ReactorEx::complex_dispatch_handler (int index,
- ACE_HANDLE event_handle)
+ACE_WFMO_Reactor::complex_dispatch_handler (int index,
+ ACE_HANDLE event_handle)
{
// This dispatch is used for I/O entires
- ACE_ReactorEx_Handler_Repository::Current_Info &current_info =
+ ACE_WFMO_Reactor_Handler_Repository::Current_Info &current_info =
this->handler_rep_.current_info ()[index];
// Upcall
@@ -1197,10 +1107,10 @@ ACE_ReactorEx::complex_dispatch_handler (int index,
}
int
-ACE_ReactorEx::upcall (ACE_Event_Handler *event_handler,
- ACE_HANDLE io_handle,
- ACE_HANDLE event_handle,
- long interested_events)
+ACE_WFMO_Reactor::upcall (ACE_Event_Handler *event_handler,
+ ACE_HANDLE io_handle,
+ ACE_HANDLE event_handle,
+ long interested_events)
{
// This method figures out what exactly has happened to the socket and then calls appropriate methods
int result = 0;
@@ -1250,7 +1160,7 @@ ACE_ReactorEx::upcall (ACE_Event_Handler *event_handler,
}
-ACE_ReactorEx::update_state (void)
+ACE_WFMO_Reactor::update_state (void)
{
// This GUARD is necessary since we are updating shared state.
ACE_GUARD_RETURN (ACE_Process_Mutex, monitor, this->lock_, -1);
@@ -1308,22 +1218,22 @@ ACE_ReactorEx::update_state (void)
// ************************************************************
-ACE_ReactorEx_Notify::ACE_ReactorEx_Notify (void)
+ACE_WFMO_Reactor_Notify::ACE_WFMO_Reactor_Notify (void)
: max_notify_iterations_ (-1),
timer_queue_ (0)
{
}
int
-ACE_ReactorEx_Notify::open (ACE_ReactorEx &reactorEx,
- ACE_Timer_Queue *timer_queue)
+ACE_WFMO_Reactor_Notify::open (ACE_WFMO_Reactor &wfmo_reactor,
+ ACE_Timer_Queue *timer_queue)
{
timer_queue_ = timer_queue;
- return reactorEx.register_handler (this);
+ return wfmo_reactor.register_handler (this);
}
ACE_HANDLE
-ACE_ReactorEx_Notify::get_handle (void) const
+ACE_WFMO_Reactor_Notify::get_handle (void) const
{
return this->wakeup_one_thread_.handle ();
}
@@ -1331,9 +1241,9 @@ ACE_ReactorEx_Notify::get_handle (void) const
// Handle all pending notifications.
int
-ACE_ReactorEx_Notify::handle_signal (int signum,
- siginfo_t *siginfo,
- ucontext_t *)
+ACE_WFMO_Reactor_Notify::handle_signal (int signum,
+ siginfo_t *siginfo,
+ ucontext_t *)
{
ACE_UNUSED_ARG (signum);
@@ -1341,7 +1251,7 @@ ACE_ReactorEx_Notify::handle_signal (int signum,
if (siginfo->si_handle_ != this->wakeup_one_thread_.handle ())
return -1;
- // This will get called when <ReactorEx->wakeup_one_thread_> event
+ // This will get called when <WFMO_Reactor->wakeup_one_thread_> event
// is signaled.
// ACE_DEBUG ((LM_DEBUG, "(%t) waking up to handle internal notifications\n"));
@@ -1405,14 +1315,14 @@ ACE_ReactorEx_Notify::handle_signal (int signum,
}
}
-// Notify the ReactorEx, potentially enqueueing the
-// <ACE_Event_Handler> for subsequent processing in the ReactorEx
+// Notify the WFMO_Reactor, potentially enqueueing the
+// <ACE_Event_Handler> for subsequent processing in the WFMO_Reactor
// thread of control.
int
-ACE_ReactorEx_Notify::notify (ACE_Event_Handler *eh,
- ACE_Reactor_Mask mask,
- ACE_Time_Value *timeout)
+ACE_WFMO_Reactor_Notify::notify (ACE_Event_Handler *eh,
+ ACE_Reactor_Mask mask,
+ ACE_Time_Value *timeout)
{
if (eh != 0)
{
@@ -1442,9 +1352,9 @@ ACE_ReactorEx_Notify::notify (ACE_Event_Handler *eh,
}
void
-ACE_ReactorEx_Notify::max_notify_iterations (int iterations)
+ACE_WFMO_Reactor_Notify::max_notify_iterations (int iterations)
{
- ACE_TRACE ("ACE_ReactorEx_Notify::max_notify_iterations");
+ ACE_TRACE ("ACE_WFMO_Reactor_Notify::max_notify_iterations");
// Must always be > 0 or < 0 to optimize the loop exit condition.
if (iterations == 0)
iterations = 1;
@@ -1453,16 +1363,16 @@ ACE_ReactorEx_Notify::max_notify_iterations (int iterations)
}
int
-ACE_ReactorEx_Notify::max_notify_iterations (void)
+ACE_WFMO_Reactor_Notify::max_notify_iterations (void)
{
- ACE_TRACE ("ACE_ReactorEx_Notify::max_notify_iterations");
+ ACE_TRACE ("ACE_WFMO_Reactor_Notify::max_notify_iterations");
return this->max_notify_iterations_;
}
void
-ACE_ReactorEx::max_notify_iterations (int iterations)
+ACE_WFMO_Reactor::max_notify_iterations (int iterations)
{
- ACE_TRACE ("ACE_ReactorEx::max_notify_iterations");
+ ACE_TRACE ("ACE_WFMO_Reactor::max_notify_iterations");
ACE_GUARD (ACE_Process_Mutex, monitor, this->lock_);
// Must always be > 0 or < 0 to optimize the loop exit condition.
@@ -1470,15 +1380,15 @@ ACE_ReactorEx::max_notify_iterations (int iterations)
}
int
-ACE_ReactorEx::max_notify_iterations (void)
+ACE_WFMO_Reactor::max_notify_iterations (void)
{
- ACE_TRACE ("ACE_ReactorEx::max_notify_iterations");
+ ACE_TRACE ("ACE_WFMO_Reactor::max_notify_iterations");
ACE_GUARD_RETURN (ACE_Process_Mutex, monitor, this->lock_, -1);
return this->notify_handler_.max_notify_iterations ();
}
-// No-op WinSOCK2 methods to help ReactorEx compile
+// No-op WinSOCK2 methods to help WFMO_Reactor compile
#if !defined (ACE_HAS_WINSOCK2) || (ACE_HAS_WINSOCK2 == 0)
int
WSAEventSelect (SOCKET s,
@@ -1505,53 +1415,5 @@ WSAEnumNetworkEvents (SOCKET s,
}
#endif /* !defined ACE_HAS_WINSOCK2 */
-#else /* ACE_WIN32 */
-
-ACE_ReactorEx *
-ACE_ReactorEx::instance (void)
-{
- return NULL;
-}
-
-ACE_ReactorEx *
-ACE_ReactorEx::instance (ACE_ReactorEx *r)
-{
- ACE_UNUSED_ARG (r);
- return NULL;
-}
-
-void
-ACE_ReactorEx::close_singleton (void)
-{
-}
-
-int
-ACE_ReactorEx::run_event_loop (void)
-{
- // not implemented
- return -1;
-}
-
-int
-ACE_ReactorEx::run_event_loop (ACE_Time_Value &tv)
-{
- // not implemented
- ACE_UNUSED_ARG (tv);
- return -1;
-}
-
-int
-ACE_ReactorEx::end_event_loop (void)
-{
- // not implemented
- return -1;
-}
-
-sig_atomic_t
-ACE_ReactorEx::event_loop_done (void)
-{
- return sig_atomic_t(1);
-}
-
#endif /* ACE_WIN32 */
diff --git a/ace/ReactorEx.h b/ace/WFMO_Reactor.h
index 33c141cabcb..e8d8954ec65 100644
--- a/ace/ReactorEx.h
+++ b/ace/WFMO_Reactor.h
@@ -7,46 +7,46 @@
// ace
//
// = FILENAME
-// ReactorEx.h
+// WFMO_Reactor.h
//
// = AUTHOR
// Irfan Pyarali, Tim Harrison, and Doug Schmidt
//
// ============================================================================
-#if !defined (ACE_REACTOREX_H)
-#define ACE_REACTOREX_H
+#if !defined (ACE_WFMO_REACTOR_H)
+#define ACE_WFMO_REACTOR_H
-#include "ace/Time_Value.h"
+#include "ace/Signal.h"
#include "ace/Timer_Queue.h"
#include "ace/Event_Handler.h"
-#include "ace/Message_Queue.h"
#include "ace/Synch.h"
+#include "ace/Reactor_Impl.h"
+#include "ace/Message_Queue.h"
// Forward decl.
-class ACE_ReactorEx;
+class ACE_WFMO_Reactor;
class ACE_Handle_Set;
-class ACE_Sig_Handler;
class ACE_Export ACE_Wakeup_All_Threads_Handler : public ACE_Event_Handler
// = TITLE
// This is a helper class whose sole purpose is to handle events
- // on <ACE_ReactorEx->wakeup_all_threads_>
+ // on <ACE_WFMO_Reactor->wakeup_all_threads_>
{
public:
virtual int handle_signal (int signum, siginfo_t * = 0, ucontext_t * = 0);
- // Called when the <ACE_ReactorEx->wakeup_all_threads_>
+ // Called when the <ACE_WFMO_Reactor->wakeup_all_threads_>
private:
};
-class ACE_Export ACE_ReactorEx_Handler_Repository
+class ACE_Export ACE_WFMO_Reactor_Handler_Repository
// = TITLE
// Used to map <ACE_HANDLE>s onto the appropriate
// <ACE_Event_Handler> * and other information.
//
{
- friend class ACE_ReactorEx;
+ friend class ACE_WFMO_Reactor;
public:
@@ -74,9 +74,9 @@ public:
// This entry is only valid if the <io_entry_> flag is true.
int delete_event_;
- // This flag indicates that <ReactorEx> created the event on
+ // This flag indicates that <WFMO_Reactor> created the event on
// behalf of the user. Therefore we need to clean this up when the
- // <Event_Handler> removes itself from <ReactorEx>.
+ // <Event_Handler> removes itself from <WFMO_Reactor>.
// This entry is only valid if the <io_entry_> flag is true.
Common_Info (void);
@@ -202,10 +202,10 @@ public:
// Set the structure to these new values
};
- ACE_ReactorEx_Handler_Repository (ACE_ReactorEx &reactorEx);
+ ACE_WFMO_Reactor_Handler_Repository (ACE_WFMO_Reactor &wfmo_reactor);
// Constructor.
- virtual ~ACE_ReactorEx_Handler_Repository (void);
+ virtual ~ACE_WFMO_Reactor_Handler_Repository (void);
// Destructor.
int open (size_t size);
@@ -269,14 +269,14 @@ public:
ACE_HANDLE &event_handle,
int &delete_event);
// This method is used to calculate the network mask after a
- // register request to <ReactorEx>. Note that because the
+ // register request to <WFMO_Reactor>. Note that because the
// <Event_Handler> may already be in the handler repository, we may
// have to find the old event and the old network events
void remove_network_events_i (long &existing_masks,
ACE_Reactor_Mask to_be_removed_masks);
// This method is used to change the network mask left (if any)
- // after a remove request to <ReactorEx>
+ // after a remove request to <WFMO_Reactor>
int suspend_handler_i (ACE_HANDLE handle,
int &changes_required);
@@ -293,19 +293,19 @@ public:
// Add handles to the handle set
int remove_handler_i (size_t index,
- ACE_Reactor_Mask mask = 0);
+ ACE_Reactor_Mask mask);
// Removes the <ACE_Event_Handler> at <index> from the table.
int remove_suspended_handler_i (size_t index,
- ACE_Reactor_Mask mask = 0);
+ ACE_Reactor_Mask mask);
// Removes the <ACE_Event_Handler> at <index> from the table.
void dump (void) const;
// Dump the state of an object.
protected:
- ACE_ReactorEx &reactorEx_;
- // Reference to our <ReactorEx>.
+ ACE_WFMO_Reactor &wfmo_reactor_;
+ // Reference to our <WFMO_Reactor>.
size_t max_size_;
// Maximum number of handles.
@@ -343,26 +343,26 @@ protected:
// Number of records to be added
};
-class ACE_Export ACE_ReactorEx_Notify : public ACE_Event_Handler
+class ACE_Export ACE_WFMO_Reactor_Notify : public ACE_Event_Handler
// = TITLE
- // Unblock the <ACE_ReactorEx> from its event loop, passing it an
+ // Unblock the <ACE_WFMO_Reactor> from its event loop, passing it an
// optional <ACE_Event_Handler> to dispatch.
//
// = DESCRIPTION
// This implementation is necessary for cases where the
- // <ACE_ReactorEx> is run in a multi-threaded program. In this
+ // <ACE_WFMO_Reactor> is run in a multi-threaded program. In this
// case, we need to be able to unblock WaitForMultipleObjects()
- // when updates occur other than in the main <ACE_ReactorEx>
+ // when updates occur other than in the main <ACE_WFMO_Reactor>
// thread. To do this, we signal an auto-reset event the
- // <ACE_ReactorEx> is listening on. If an <ACE_Event_Handler>
+ // <ACE_WFMO_Reactor> is listening on. If an <ACE_Event_Handler>
// and <ACE_Reactor_Mask> is passed to <notify>, the appropriate
// <handle_*> method is dispatched.
{
public:
- ACE_ReactorEx_Notify (void);
+ ACE_WFMO_Reactor_Notify (void);
// Constructor
- int open (ACE_ReactorEx &reactorEx,
+ int open (ACE_WFMO_Reactor &wfmo_reactor,
ACE_Timer_Queue *timer_queue);
// Initialization. <timer_queue> is stored to call gettimeofday.
@@ -371,9 +371,9 @@ public:
ACE_Time_Value *timeout = 0);
// Special trick to unblock WaitForMultipleObjects() when updates
// occur. All we do is enqueue <event_handler> and <mask> onto the
- // <ACE_Message_Queue> and wakeup the ReactorEx by signaling its
+ // <ACE_Message_Queue> and wakeup the WFMO_Reactor by signaling its
// <ACE_Event> handle. The <ACE_Time_Value> indicates how long to
- // blocking trying to notify the <Reactor>. If <timeout> == 0, the
+ // 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).
@@ -382,7 +382,7 @@ public:
void max_notify_iterations (int);
// Set the maximum number of times that the
- // <ACE_ReactorEx_Notify::handle_input> method will iterate and
+ // <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
@@ -393,17 +393,17 @@ public:
int max_notify_iterations (void);
// Get the maximum number of times that the
- // <ACE_ReactorEx_Notify::handle_input> method will iterate and
+ // <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.
private:
ACE_Timer_Queue *timer_queue_;
- // Pointer to the reactor's timer queue.
+ // Pointer to the wfmo_reactor's timer queue.
virtual int handle_signal (int signum, siginfo_t * = 0, ucontext_t * = 0);
- // Called when the notification event waited on by <ACE_ReactorEx>
+ // Called when the notification event waited on by <ACE_WFMO_Reactor>
// is signaled. This dequeues all pending <ACE_Event_Handlers> and
// dispatches them.
@@ -420,7 +420,7 @@ private:
int max_notify_iterations_;
// Keeps track of the maximum number of times that the
- // <ACE_ReactorEx_Notify::handle_input> method will iterate and
+ // <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
@@ -428,25 +428,25 @@ private:
};
#if defined (ACE_WIN32)
-class ACE_Export ACE_ReactorEx
+class ACE_Export ACE_WFMO_Reactor : public ACE_Reactor_Impl
// = TITLE
// An object oriented event demultiplexor and event handler
- // ReactorEx for Win32 WaitForMultipleObjects
+ // WFMO_Reactor for Win32 WaitForMultipleObjects
//
// = DESCRIPTION
- // The ACE_ReactorEx is an object-oriented event demultiplexor
- // and event handler ReactorEx. The sources of events that the
- // ACE_ReactorEx waits for and dispatches includes I/O events,
+ // 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.
{
- friend class ACE_ReactorEx_Handler_Repository;
- friend class ACE_ReactorEx_Test;
+ friend class ACE_WFMO_Reactor_Handler_Repository;
+ friend class ACE_WFMO_Reactor_Test;
public:
enum
{
DEFAULT_SIZE = MAXIMUM_WAIT_OBJECTS - 2
- // Default size of the ReactorEx's handle table. Two slots will be
+ // Default size of the WFMO_Reactor's handle table. Two slots will be
// added to the <size> parameter in the constructor and open
// methods which will store handles used for internal management
// purposes.
@@ -454,58 +454,31 @@ public:
// = Initialization and termination methods.
- ACE_ReactorEx (ACE_Sig_Handler * = 0,
- ACE_Timer_Queue * = 0);
- // Initialize <ACE_ReactorEx> with the default size.
+ ACE_WFMO_Reactor (ACE_Sig_Handler * = 0,
+ ACE_Timer_Queue * = 0);
+ // Initialize <ACE_WFMO_Reactor> with the default size.
- ACE_ReactorEx (size_t size,
- int unused = 0,
- ACE_Sig_Handler * = 0,
- ACE_Timer_Queue * = 0);
- // Initialize <ACE_ReactorEx> with size <size>. Two slots will be
+ ACE_WFMO_Reactor (size_t size,
+ int unused = 0,
+ ACE_Sig_Handler * = 0,
+ ACE_Timer_Queue * = 0);
+ // Initialize <ACE_WFMO_Reactor> 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);
- // Get pointer to a process-wide <ACE_ReactorEx>.
-
- static ACE_ReactorEx *instance (ACE_ReactorEx *);
- // Set pointer to a process-wide <ACE_ReactorEx> and return existing
- // pointer.
-
- static void close_singleton (void);
- // Delete the dynamically allocated Singleton
-
- // = ReactorEx event loop management methods.
- static int run_event_loop (void);
- // Run the event loop until the <ACE_ReactorEx::handle_events>
- // method returns -1 or the <end_event_loop> method
- // is invoked.
-
- static int run_event_loop (ACE_Time_Value &tv);
- // Run the event loop until the <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);
- // Instruct the <ACE_ReactorEx::instance()> to terminate its event loop.
-
- static sig_atomic_t event_loop_done (void);
- // Report if the <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);
- // Initialize <ACE_ReactorEx> with size <size>. Two slots will be
+ // Initialize <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 close (void);
- // Close down the ReactorEx and release all of its resources.
+ // Close down the WFMO_Reactor and release all of its resources.
- virtual ~ACE_ReactorEx (void);
- // Close down the ReactorEx and release all of its resources.
+ virtual ~ACE_WFMO_Reactor (void);
+ // Close down the WFMO_Reactor and release all of its resources.
// = Event loop drivers.
@@ -523,7 +496,7 @@ public:
// application wishes to handle events for some fixed amount of
// time.
//
- // <WaitForMultipleObjectsEx> is used as the demultiplexing call
+ // <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
@@ -531,7 +504,7 @@ public:
//
// 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.
+ // <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);
@@ -541,7 +514,7 @@ public:
//
// 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.
+ // <WaitForMultipleObjects> for the <bAlertable> option.
// = Register and remove Handlers.
@@ -551,8 +524,8 @@ public:
// Register an <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, <ReactorEx> will call handle_signal on <event_handler>. If
- // <handle> == <ACE_INVALID_HANDLE> the <ACE_ReactorEx> will call
+ // 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.
@@ -562,9 +535,9 @@ public:
ACE_Reactor_Mask mask);
// Register an <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_ReactorEx> will call
+ // <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>, ReactorEx
+ // 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>
@@ -574,47 +547,77 @@ public:
ACE_Reactor_Mask mask);
// This is a simple version of the above <register_handler> method
// where the I/O handle is passed in and the event handle will
- // always be created by <ReactorEx>
+ // always be created by <WFMO_Reactor>
virtual int register_handler (ACE_Event_Handler *event_handler,
ACE_Reactor_Mask mask);
// This is a simple version of the above <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>
+ // <WFMO_Reactor>
virtual int register_handler (const ACE_Handle_Set &handles,
ACE_Event_Handler *event_handler,
ACE_Reactor_Mask mask);
// Register <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);
+ // Register <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);
+ // Registers <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 = 0);
- // Removes <event_handler> from the <ACE_ReactorEx>. Note that the
- // <ACE_ReactorEx> will call the <get_handle> method of <event_handler> to
- // extract the underlying handle. If <mask> ==
+ ACE_Reactor_Mask mask);
+ // Removes <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>
+ // 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 = 0);
- // Removes <handle> from the <ACE_ReactorEx>. If <mask> ==
+ ACE_Reactor_Mask mask);
+ // Removes <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 <ReactorEx>. If
+ // <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 Reactor. For simple event entries, mask is mostly ignored
- // and the <Event_Handler> is always removed from <ReactorEx> =
+ // 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);
// Removes all the <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 ReactorEx.
+ // 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);
+ // Remove the ACE_Event_Handler currently associated with <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);
+ // Calls <remove_handler> for every signal in <sigset>.
+
+ // = Suspend and resume Handlers.
virtual int suspend_handler (ACE_Event_Handler *event_handler);
// Suspend <event_handler> temporarily. Use <event_handler->get_handle()> to get the handle.
@@ -625,7 +628,7 @@ public:
virtual int suspend_handler (const ACE_Handle_Set &handles);
// Suspend all <handles> in handle set temporarily.
- virtual int suspend_all (void);
+ virtual int suspend_handlers (void);
// Suspend all <handles> temporarily.
virtual int resume_handler (ACE_Event_Handler *event_handler);
@@ -637,15 +640,15 @@ public:
virtual int resume_handler (const ACE_Handle_Set &handles);
// Resume all <handles> in handle set.
- virtual int resume_all (void);
+ virtual int resume_handlers (void);
// Resume all <handles>.
// Timer management.
- virtual int 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 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);
// Schedule an <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
@@ -665,7 +668,7 @@ public:
// Cancel all Event_Handlers that match the address of
// <event_handler>. Returns number of handler's cancelled.
- virtual int cancel_timer (int timer_id,
+ virtual int cancel_timer (long timer_id,
const void **arg = 0,
int dont_call_handle_close = 1);
// Cancel the single Event_Handler that matches the <timer_id> value
@@ -681,14 +684,14 @@ public:
virtual int schedule_wakeup (ACE_Event_Handler *event_handler,
ACE_Reactor_Mask masks_to_be_added);
// Add <masks_to_be_added> to the <event_handler>'s entry in
- // ReactorEx. <event_handler> must already have been registered
- // with ReactorEx.
+ // 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);
- // Add <masks_to_be_added> to the <handle>'s entry in ReactorEx.
+ // Add <masks_to_be_added> to the <handle>'s entry in WFMO_Reactor.
// The Event_Handler associated with <handle> must already have been
- // registered with ReactorEx.
+ // registered with WFMO_Reactor.
virtual int cancel_wakeup (ACE_Event_Handler *event_handler,
ACE_Reactor_Mask mask);
@@ -704,15 +707,15 @@ public:
virtual int notify (ACE_Event_Handler * = 0,
ACE_Reactor_Mask = ACE_Event_Handler::EXCEPT_MASK,
ACE_Time_Value * = 0);
- // Wakeup one <ACE_ReactorEx> thread if it is currently blocked in
+ // Wakeup one <ACE_WFMO_Reactor> thread if it is currently blocked in
// <WaitForMultipleObjects>. The <ACE_Time_Value> indicates how
- // long to blocking trying to notify the <Reactor>. If <timeout> ==
+ // 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);
// Set the maximum number of times that the
- // <ACE_ReactorEx_Notify::handle_input> method will iterate and
+ // <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
@@ -723,23 +726,75 @@ public:
virtual int max_notify_iterations (void);
// Get the maximum number of times that the
- // <ACE_ReactorEx_Notify::handle_input> method will iterate and
+ // <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 owner (ACE_thread_t *owner);
- // Return the ID of the "owner" thread.
+ virtual int handler (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask,
+ ACE_Event_Handler **event_handler = 0);
+ // Not implemented
- virtual int owner (ACE_thread_t new_owner, ACE_thread_t *old_owner = 0);
- // Transfers ownership of the ReactorEx to the <new_owner>. The
- // transfer will not complete until all threads are ready (just like
- // the handle set).
+ virtual int handler (int signum,
+ ACE_Event_Handler ** = 0);
+ // Check to see if <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);
+ // Returns true if WFMO_Reactor has been successfully initialized, else
+ // false.
+
+ virtual size_t size (void);
+ // Returns the current size of the WFMO_Reactor's internal
+ // descriptor table.
+
+ virtual ACE_Lock &lock (void);
+ // Returns a reference to the WFMO_Reactor's internal lock.
virtual void wakeup_all_threads (void);
// Wake up all threads in WaitForMultipleObjects so that they can
// reconsult the handle set
+ virtual int owner (ACE_thread_t new_owner, ACE_thread_t *old_owner = 0);
+ // Transfers ownership of the WFMO_Reactor to the <new_owner>. The
+ // transfer will not complete until all threads are ready (just like
+ // the handle set).
+
+ virtual int owner (ACE_thread_t *owner);
+ // Return the ID of the "owner" thread.
+
+ virtual void requeue_position (int);
+ // Not implemented
+
+ virtual int requeue_position (void);
+ // Not implemented
+
+ // = Low-level wait_set mask manipulation methods.
+
+ virtual int mask_ops (ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask mask,
+ int ops);
+ // Not implemented
+
+ virtual int mask_ops (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask,
+ int ops);
+ // Not implemented
+
+ // = Low-level ready_set mask manipulation methods.
+
+ virtual int ready_ops (ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask mask,
+ int ops);
+ // Not implemented
+
+ virtual int ready_ops (ACE_HANDLE handle,
+ ACE_Reactor_Mask,
+ int ops);
+ // Not implemented
+
ACE_ALLOC_HOOK_DECLARE;
// Declare the dynamic allocation hooks.
@@ -815,6 +870,13 @@ protected:
virtual int change_owner (void);
// Set owner to new owner
+ ACE_Sig_Handler *signal_handler_;
+ // Handle signals without requiring global/static variables.
+
+ int delete_signal_handler_;
+ // Keeps track of whether we should delete the signal handler (if we
+ // didn't create it, then we don't delete it).
+
ACE_Timer_Queue *timer_queue_;
// Defined as a pointer to allow overriding by derived classes...
@@ -826,17 +888,20 @@ protected:
// Keeps track of whether we should delete the handler repository
ACE_Process_Mutex lock_;
- // Synchronization for the ACE_Reactor.
+ // Synchronization for the ACE_WFMO_Reactor.
// A Process Mutex is used here because of two reasons:
// (a) The implementation of ACE_Thread_Mutex uses CriticalSections
// CriticalSections are not waitable using ::WaitForMultipleObjects
// (b) This is really not a process mutex because it is not
// named. No other process can use this mutex.
- ACE_ReactorEx_Handler_Repository handler_rep_;
+ ACE_Lock_Adapter<ACE_Process_Mutex> lock_adapter_;
+ // Adapter used to return internal lock to outside world.
+
+ ACE_WFMO_Reactor_Handler_Repository handler_rep_;
// Table that maps <ACE_HANDLEs> to <ACE_Event_Handler *>'s.
- ACE_ReactorEx_Notify notify_handler_;
+ ACE_WFMO_Reactor_Notify notify_handler_;
// Used when <notify> is called.
ACE_Manual_Event ok_to_wait_;
@@ -859,7 +924,7 @@ protected:
// Count of currently active threads
ACE_thread_t owner_;
- // The thread which is "owner" of the ReactorEx. The owner concept
+ // The thread which is "owner" of the WFMO_Reactor. The owner concept
// is used because we don't want multiple threads to try to expire
// timers. Therefore the "owner" thread is the only one allowed to
// expire timers. Also, the owner thread is the only thread which
@@ -867,11 +932,11 @@ protected:
// transferred.
ACE_thread_t new_owner_;
- // The owner to be of the ReactorEx
+ // The owner to be of the WFMO_Reactor
ACE_thread_t change_state_thread_;
// This is the thread which is responsible for the changing the
- // state of the <ReactorEx> handle set
+ // state of the <WFMO_Reactor> handle set
ACE_HANDLE atomic_wait_array_ [2];
// This is an array of ACE_HANDLEs which keep track of the <lock_>
@@ -881,17 +946,8 @@ protected:
// This flag is used to keep track of whether we are already closed.
private:
- static ACE_ReactorEx *reactorEx_;
- // Pointer to a process-wide <ACE_Reactor>.
-
- static int delete_reactorEx_;
- // Must delete the <reactor_> if non-0.
-
- static sig_atomic_t end_event_loop_;
- // Terminate the reactor-ex event loop.
-
- ACE_ReactorEx (const ACE_ReactorEx &);
- ACE_ReactorEx &operator = (const ACE_ReactorEx &);
+ ACE_WFMO_Reactor (const ACE_WFMO_Reactor &);
+ ACE_WFMO_Reactor &operator = (const ACE_WFMO_Reactor &);
// Deny access since member-wise won't work...
};
@@ -934,7 +990,7 @@ int WSAEnumNetworkEvents (SOCKET s,
#endif /* !defined ACE_HAS_WINSOCK2 */
#else /* NOT win32 */
-class ACE_Export ACE_ReactorEx
+class ACE_Export ACE_WFMO_Reactor : public ACE_Reactor_Impl
{
public:
virtual int handle_events (void) { return -1; }
@@ -942,34 +998,11 @@ public:
int notify (ACE_Event_Handler * = 0,
ACE_Reactor_Mask = ACE_Event_Handler::EXCEPT_MASK)
{ return 0; }
-
- static ACE_ReactorEx *instance (void);
- // Get pointer to a process-wide <ACE_ReactorEx>.
-
- static ACE_ReactorEx *instance (ACE_ReactorEx *);
- // Set pointer to a process-wide <ACE_ReactorEx> and return existing
- // pointer.
-
- static void close_singleton (void);
- // Delete the dynamically allocated Singleton
-
- static int run_event_loop (void);
- // Placeholder to enable compilation on non-Win32 platforms
-
- static int run_event_loop (ACE_Time_Value &tv);
- // Placeholder to enable compilation on non-Win32 platforms
-
- static int end_event_loop (void);
- // Placeholder to enable compilation on non-Win32 platforms
-
- static sig_atomic_t event_loop_done (void);
- // Placeholder to enable compilation on non-Win32 platforms
};
#endif /* ACE_WIN32 */
#if defined (__ACE_INLINE__)
-#include "ace/Handle_Set.h"
-#include "ace/ReactorEx.i"
+#include "ace/WFMO_Reactor.i"
#endif /* __ACE_INLINE__ */
-#endif /* ACE_REACTOREX_H */
+#endif /* ACE_WFMO_REACTOR_H */
diff --git a/ace/ReactorEx.i b/ace/WFMO_Reactor.i
index eb9c748a97d..552bdcb5b4a 100644
--- a/ace/ReactorEx.i
+++ b/ace/WFMO_Reactor.i
@@ -1,6 +1,8 @@
/* -*- C++ -*- */
// $Id$
+#include "ace/Handle_Set.h"
+
#if defined (ACE_WIN32)
/************************************************************/
@@ -13,7 +15,7 @@ ACE_Wakeup_All_Threads_Handler::handle_signal (int signum,
ACE_UNUSED_ARG (signum);
ACE_UNUSED_ARG (siginfo);
- // This will get called when <ReactorEx->wakeup_all_threads_> event
+ // This will get called when <WFMO_Reactor->wakeup_all_threads_> event
// is signaled. There is nothing to be done here.
// ACE_DEBUG ((LM_DEBUG, "(%t) waking up to get updated handle set info\n"));
return 0;
@@ -22,7 +24,7 @@ ACE_Wakeup_All_Threads_Handler::handle_signal (int signum,
/************************************************************/
ACE_INLINE
-ACE_ReactorEx_Handler_Repository::Common_Info::Common_Info (void)
+ACE_WFMO_Reactor_Handler_Repository::Common_Info::Common_Info (void)
: event_handler_ (0),
io_entry_ (0),
io_handle_ (ACE_INVALID_HANDLE),
@@ -32,7 +34,7 @@ ACE_ReactorEx_Handler_Repository::Common_Info::Common_Info (void)
}
ACE_INLINE void
-ACE_ReactorEx_Handler_Repository::Common_Info::reset (void)
+ACE_WFMO_Reactor_Handler_Repository::Common_Info::reset (void)
{
this->event_handler_ = 0;
this->io_entry_ = 0;
@@ -42,11 +44,11 @@ ACE_ReactorEx_Handler_Repository::Common_Info::reset (void)
}
ACE_INLINE void
-ACE_ReactorEx_Handler_Repository::Common_Info::set (int io_entry,
- ACE_Event_Handler *event_handler,
- ACE_HANDLE io_handle,
- long network_events,
- int delete_event)
+ACE_WFMO_Reactor_Handler_Repository::Common_Info::set (int io_entry,
+ ACE_Event_Handler *event_handler,
+ ACE_HANDLE io_handle,
+ long network_events,
+ int delete_event)
{
this->event_handler_ = event_handler;
this->io_entry_ = io_entry;
@@ -56,7 +58,7 @@ ACE_ReactorEx_Handler_Repository::Common_Info::set (int io_entry,
}
ACE_INLINE void
-ACE_ReactorEx_Handler_Repository::Common_Info::set (Common_Info &common_info)
+ACE_WFMO_Reactor_Handler_Repository::Common_Info::set (Common_Info &common_info)
{
*this = common_info;
}
@@ -64,7 +66,7 @@ ACE_ReactorEx_Handler_Repository::Common_Info::set (Common_Info &common_info)
/************************************************************/
ACE_INLINE
-ACE_ReactorEx_Handler_Repository::Current_Info::Current_Info (void)
+ACE_WFMO_Reactor_Handler_Repository::Current_Info::Current_Info (void)
: delete_entry_ (0),
close_masks_ (0),
suspend_entry_ (0)
@@ -72,14 +74,14 @@ ACE_ReactorEx_Handler_Repository::Current_Info::Current_Info (void)
}
ACE_INLINE void
-ACE_ReactorEx_Handler_Repository::Current_Info::set (int io_entry,
- ACE_Event_Handler *event_handler,
- ACE_HANDLE io_handle,
- long network_events,
- int delete_event,
- int delete_entry,
- ACE_Reactor_Mask close_masks,
- int suspend_entry)
+ACE_WFMO_Reactor_Handler_Repository::Current_Info::set (int io_entry,
+ ACE_Event_Handler *event_handler,
+ ACE_HANDLE io_handle,
+ long network_events,
+ int delete_event,
+ int delete_entry,
+ ACE_Reactor_Mask close_masks,
+ int suspend_entry)
{
this->delete_entry_ = delete_entry;
this->close_masks_ = close_masks;
@@ -92,10 +94,10 @@ ACE_ReactorEx_Handler_Repository::Current_Info::set (int io_entry,
}
ACE_INLINE void
-ACE_ReactorEx_Handler_Repository::Current_Info::set (Common_Info &common_info,
- int delete_entry,
- ACE_Reactor_Mask close_masks,
- int suspend_entry)
+ACE_WFMO_Reactor_Handler_Repository::Current_Info::set (Common_Info &common_info,
+ int delete_entry,
+ ACE_Reactor_Mask close_masks,
+ int suspend_entry)
{
this->delete_entry_ = delete_entry;
this->close_masks_ = close_masks;
@@ -104,7 +106,7 @@ ACE_ReactorEx_Handler_Repository::Current_Info::set (Common_Info &common_info,
}
ACE_INLINE void
-ACE_ReactorEx_Handler_Repository::Current_Info::reset (void)
+ACE_WFMO_Reactor_Handler_Repository::Current_Info::reset (void)
{
this->delete_entry_ = 0;
this->close_masks_ = 0;
@@ -115,18 +117,18 @@ ACE_ReactorEx_Handler_Repository::Current_Info::reset (void)
/************************************************************/
ACE_INLINE
-ACE_ReactorEx_Handler_Repository::To_Be_Added_Info::To_Be_Added_Info (void)
+ACE_WFMO_Reactor_Handler_Repository::To_Be_Added_Info::To_Be_Added_Info (void)
: event_handle_ (ACE_INVALID_HANDLE)
{
}
ACE_INLINE void
-ACE_ReactorEx_Handler_Repository::To_Be_Added_Info::set (ACE_HANDLE event_handle,
- int io_entry,
- ACE_Event_Handler *event_handler,
- ACE_HANDLE io_handle,
- long network_events,
- int delete_event)
+ACE_WFMO_Reactor_Handler_Repository::To_Be_Added_Info::set (ACE_HANDLE event_handle,
+ int io_entry,
+ ACE_Event_Handler *event_handler,
+ ACE_HANDLE io_handle,
+ long network_events,
+ int delete_event)
{
this->event_handle_ = event_handle;
Common_Info::set (io_entry,
@@ -137,15 +139,15 @@ ACE_ReactorEx_Handler_Repository::To_Be_Added_Info::set (ACE_HANDLE event_handle
}
ACE_INLINE void
-ACE_ReactorEx_Handler_Repository::To_Be_Added_Info::set (ACE_HANDLE event_handle,
- Common_Info &common_info)
+ACE_WFMO_Reactor_Handler_Repository::To_Be_Added_Info::set (ACE_HANDLE event_handle,
+ Common_Info &common_info)
{
this->event_handle_ = event_handle;
Common_Info::set (common_info);
}
ACE_INLINE void
-ACE_ReactorEx_Handler_Repository::To_Be_Added_Info::reset (void)
+ACE_WFMO_Reactor_Handler_Repository::To_Be_Added_Info::reset (void)
{
this->event_handle_ = ACE_INVALID_HANDLE;
Common_Info::reset ();
@@ -154,7 +156,7 @@ ACE_ReactorEx_Handler_Repository::To_Be_Added_Info::reset (void)
/************************************************************/
ACE_INLINE
-ACE_ReactorEx_Handler_Repository::Suspended_Info::Suspended_Info (void)
+ACE_WFMO_Reactor_Handler_Repository::Suspended_Info::Suspended_Info (void)
: event_handle_ (ACE_INVALID_HANDLE),
resume_entry_ (0),
delete_entry_ (0),
@@ -163,7 +165,7 @@ ACE_ReactorEx_Handler_Repository::Suspended_Info::Suspended_Info (void)
}
ACE_INLINE void
-ACE_ReactorEx_Handler_Repository::Suspended_Info::reset (void)
+ACE_WFMO_Reactor_Handler_Repository::Suspended_Info::reset (void)
{
this->event_handle_ = ACE_INVALID_HANDLE;
this->resume_entry_ = 0;
@@ -173,15 +175,15 @@ ACE_ReactorEx_Handler_Repository::Suspended_Info::reset (void)
}
ACE_INLINE void
-ACE_ReactorEx_Handler_Repository::Suspended_Info::set (ACE_HANDLE event_handle,
- int io_entry,
- ACE_Event_Handler *event_handler,
- ACE_HANDLE io_handle,
- long network_events,
- int delete_event,
- int resume_entry,
- int delete_entry,
- ACE_Reactor_Mask close_masks)
+ACE_WFMO_Reactor_Handler_Repository::Suspended_Info::set (ACE_HANDLE event_handle,
+ int io_entry,
+ ACE_Event_Handler *event_handler,
+ ACE_HANDLE io_handle,
+ long network_events,
+ int delete_event,
+ int resume_entry,
+ int delete_entry,
+ ACE_Reactor_Mask close_masks)
{
this->event_handle_ = event_handle;
this->resume_entry_ = resume_entry;
@@ -195,11 +197,11 @@ ACE_ReactorEx_Handler_Repository::Suspended_Info::set (ACE_HANDLE event_handle,
}
ACE_INLINE void
-ACE_ReactorEx_Handler_Repository::Suspended_Info::set (ACE_HANDLE event_handle,
- Common_Info &common_info,
- int resume_entry,
- int delete_entry,
- ACE_Reactor_Mask close_masks)
+ACE_WFMO_Reactor_Handler_Repository::Suspended_Info::set (ACE_HANDLE event_handle,
+ Common_Info &common_info,
+ int resume_entry,
+ int delete_entry,
+ ACE_Reactor_Mask close_masks)
{
this->event_handle_ = event_handle;
this->resume_entry_ = resume_entry;
@@ -211,16 +213,16 @@ ACE_ReactorEx_Handler_Repository::Suspended_Info::set (ACE_HANDLE event_handle,
/************************************************************/
ACE_INLINE int
-ACE_ReactorEx_Handler_Repository::close (void)
+ACE_WFMO_Reactor_Handler_Repository::close (void)
{
- // Let all the handlers know that the <ReactorEx> is closing down
+ // Let all the handlers know that the <WFMO_Reactor> is closing down
this->unbind_all ();
return 0;
}
ACE_INLINE ACE_HANDLE *
-ACE_ReactorEx_Handler_Repository::handles (void) const
+ACE_WFMO_Reactor_Handler_Repository::handles (void) const
{
// This code is probably too subtle to be useful in the long run...
// The basic idea is that all threads wait on all user handles plus
@@ -228,43 +230,43 @@ ACE_ReactorEx_Handler_Repository::handles (void) const
// waits on the <notify_> handle. This is to ensure that only the
// <owner_> thread get to expire timers and handle event on the
// notify pipe.
- if (ACE_Thread::self () == this->reactorEx_.owner_i ())
+ if (ACE_Thread::self () == this->wfmo_reactor_.owner_i ())
return this->current_handles_;
else
return this->current_handles_ + 1;
}
-ACE_INLINE ACE_ReactorEx_Handler_Repository::Current_Info *
-ACE_ReactorEx_Handler_Repository::current_info (void) const
+ACE_INLINE ACE_WFMO_Reactor_Handler_Repository::Current_Info *
+ACE_WFMO_Reactor_Handler_Repository::current_info (void) const
{
- if (ACE_Thread::self () == this->reactorEx_.owner_i ())
+ if (ACE_Thread::self () == this->wfmo_reactor_.owner_i ())
return this->current_info_;
else
return this->current_info_ + 1;
}
ACE_INLINE size_t
-ACE_ReactorEx_Handler_Repository::max_handlep1 (void) const
+ACE_WFMO_Reactor_Handler_Repository::max_handlep1 (void) const
{
- if (ACE_Thread::self () == this->reactorEx_.owner_i ())
+ if (ACE_Thread::self () == this->wfmo_reactor_.owner_i ())
return this->max_handlep1_;
else
return this->max_handlep1_ - 1;
}
ACE_INLINE int
-ACE_ReactorEx_Handler_Repository::scheduled_for_deletion (size_t index) const
+ACE_WFMO_Reactor_Handler_Repository::scheduled_for_deletion (size_t index) const
{
- if (ACE_Thread::self () == this->reactorEx_.owner_i ())
+ if (ACE_Thread::self () == this->wfmo_reactor_.owner_i ())
return this->current_info_[index].delete_entry_ == 1;
else
return this->current_info_[index + 1].delete_entry_ == 1;
}
ACE_INLINE int
-ACE_ReactorEx_Handler_Repository::invalid_handle (ACE_HANDLE handle) const
+ACE_WFMO_Reactor_Handler_Repository::invalid_handle (ACE_HANDLE handle) const
{
- ACE_TRACE ("ACE_ReactorEx_Handler_Repository::invalid_handle");
+ ACE_TRACE ("ACE_WFMO_Reactor_Handler_Repository::invalid_handle");
// It's too expensive to perform more exhaustive validity checks on
// Win32 due to the way that they implement SOCKET HANDLEs.
if (handle == ACE_INVALID_HANDLE)
@@ -277,20 +279,20 @@ ACE_ReactorEx_Handler_Repository::invalid_handle (ACE_HANDLE handle) const
}
ACE_INLINE int
-ACE_ReactorEx_Handler_Repository::changes_required (void)
+ACE_WFMO_Reactor_Handler_Repository::changes_required (void)
{
// Check if handles have be scheduled for additions or removal
return this->handles_to_be_added_ > 0 ||
- this->handles_to_be_deleted_ > 0 ||
- this->handles_to_be_suspended_ > 0 ||
- this->handles_to_be_resumed_ > 0;
+ this->handles_to_be_deleted_ > 0 ||
+ this->handles_to_be_suspended_ > 0 ||
+ this->handles_to_be_resumed_ > 0;
}
ACE_INLINE int
-ACE_ReactorEx_Handler_Repository::make_changes (void)
+ACE_WFMO_Reactor_Handler_Repository::make_changes (void)
{
// This method must ONLY be called by the
- // <ReactorEx->change_state_thread_>. We therefore assume that there
+ // <WFMO_Reactor->change_state_thread_>. We therefore assume that there
// will be no contention for this method and hence no guards are
// neccessary.
@@ -304,10 +306,10 @@ ACE_ReactorEx_Handler_Repository::make_changes (void)
}
ACE_INLINE int
-ACE_ReactorEx_Handler_Repository::unbind (ACE_HANDLE handle,
- ACE_Reactor_Mask mask)
+ACE_WFMO_Reactor_Handler_Repository::unbind (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask)
{
- ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, this->reactorEx_.lock_, -1);
+ ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, this->wfmo_reactor_.lock_, -1);
int changes_required = 0;
int result = this->unbind_i (handle, mask, changes_required);
@@ -315,22 +317,22 @@ ACE_ReactorEx_Handler_Repository::unbind (ACE_HANDLE handle,
if (changes_required)
// Wake up all threads in WaitForMultipleObjects so that they can
// reconsult the handle set
- this->reactorEx_.wakeup_all_threads ();
+ this->wfmo_reactor_.wakeup_all_threads ();
return result;
}
/************************************************************/
-ACE_INLINE int
-ACE_ReactorEx::schedule_timer (ACE_Event_Handler *handler,
- const void *arg,
- const ACE_Time_Value &delta_time,
- const ACE_Time_Value &interval)
+ACE_INLINE long
+ACE_WFMO_Reactor::schedule_timer (ACE_Event_Handler *handler,
+ const void *arg,
+ const ACE_Time_Value &delta_time,
+ const ACE_Time_Value &interval)
{
- ACE_TRACE ("ACE_ReactorEx::schedule_timer");
+ ACE_TRACE ("ACE_WFMO_Reactor::schedule_timer");
- int result = this->timer_queue_->schedule
+ long result = this->timer_queue_->schedule
(handler, arg, timer_queue_->gettimeofday () + delta_time, interval);
// Wakeup the owner thread so that it gets the latest timer values
@@ -340,25 +342,25 @@ ACE_ReactorEx::schedule_timer (ACE_Event_Handler *handler,
}
ACE_INLINE int
-ACE_ReactorEx::cancel_timer (ACE_Event_Handler *handler,
- int dont_call_handle_close)
+ACE_WFMO_Reactor::cancel_timer (ACE_Event_Handler *handler,
+ int dont_call_handle_close)
{
- ACE_TRACE ("ACE_ReactorEx::cancel_timer");
+ ACE_TRACE ("ACE_WFMO_Reactor::cancel_timer");
return this->timer_queue_->cancel (handler, dont_call_handle_close);
}
ACE_INLINE int
-ACE_ReactorEx::cancel_timer (int timer_id,
- const void **arg,
- int dont_call_handle_close)
+ACE_WFMO_Reactor::cancel_timer (long timer_id,
+ const void **arg,
+ int dont_call_handle_close)
{
- ACE_TRACE ("ACE_ReactorEx::cancel_timer");
+ ACE_TRACE ("ACE_WFMO_Reactor::cancel_timer");
return this->timer_queue_->cancel (timer_id, arg, dont_call_handle_close);
}
ACE_INLINE int
-ACE_ReactorEx::register_handler (ACE_Event_Handler *event_handler,
- ACE_HANDLE event_handle)
+ACE_WFMO_Reactor::register_handler (ACE_Event_Handler *event_handler,
+ ACE_HANDLE event_handle)
{
// This GUARD is necessary since we are updating shared state.
ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, this->lock_, -1);
@@ -372,8 +374,8 @@ ACE_ReactorEx::register_handler (ACE_Event_Handler *event_handler,
}
ACE_INLINE int
-ACE_ReactorEx::register_handler (ACE_Event_Handler *event_handler,
- ACE_Reactor_Mask mask)
+ACE_WFMO_Reactor::register_handler (ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask mask)
{
// This GUARD is necessary since we are updating shared state.
ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, this->lock_, -1);
@@ -385,9 +387,9 @@ ACE_ReactorEx::register_handler (ACE_Event_Handler *event_handler,
}
ACE_INLINE int
-ACE_ReactorEx::register_handler (ACE_HANDLE io_handle,
- ACE_Event_Handler *event_handler,
- ACE_Reactor_Mask mask)
+ACE_WFMO_Reactor::register_handler (ACE_HANDLE io_handle,
+ ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask mask)
{
// This GUARD is necessary since we are updating shared state.
ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, this->lock_, -1);
@@ -399,10 +401,10 @@ ACE_ReactorEx::register_handler (ACE_HANDLE io_handle,
}
ACE_INLINE int
-ACE_ReactorEx::register_handler (ACE_HANDLE event_handle,
- ACE_HANDLE io_handle,
- ACE_Event_Handler *event_handler,
- ACE_Reactor_Mask mask)
+ACE_WFMO_Reactor::register_handler (ACE_HANDLE event_handle,
+ ACE_HANDLE io_handle,
+ ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask mask)
{
// This GUARD is necessary since we are updating shared state.
ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, this->lock_, -1);
@@ -415,9 +417,9 @@ ACE_ReactorEx::register_handler (ACE_HANDLE event_handle,
}
ACE_INLINE int
-ACE_ReactorEx::register_handler (const ACE_Handle_Set &handles,
- ACE_Event_Handler *handler,
- ACE_Reactor_Mask mask)
+ACE_WFMO_Reactor::register_handler (const ACE_Handle_Set &handles,
+ ACE_Event_Handler *handler,
+ ACE_Reactor_Mask mask)
{
// This GUARD is necessary since we are updating shared state.
ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, this->lock_, -1);
@@ -433,8 +435,8 @@ ACE_ReactorEx::register_handler (const ACE_Handle_Set &handles,
}
ACE_INLINE int
-ACE_ReactorEx::schedule_wakeup (ACE_HANDLE io_handle,
- ACE_Reactor_Mask masks_to_be_added)
+ACE_WFMO_Reactor::schedule_wakeup (ACE_HANDLE io_handle,
+ ACE_Reactor_Mask masks_to_be_added)
{
// This GUARD is necessary since we are updating shared state.
ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, this->lock_, -1);
@@ -443,8 +445,8 @@ ACE_ReactorEx::schedule_wakeup (ACE_HANDLE io_handle,
}
ACE_INLINE int
-ACE_ReactorEx::schedule_wakeup (ACE_Event_Handler *event_handler,
- ACE_Reactor_Mask masks_to_be_added)
+ACE_WFMO_Reactor::schedule_wakeup (ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask masks_to_be_added)
{
// This GUARD is necessary since we are updating shared state.
ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, this->lock_, -1);
@@ -453,22 +455,22 @@ ACE_ReactorEx::schedule_wakeup (ACE_Event_Handler *event_handler,
}
ACE_INLINE int
-ACE_ReactorEx::remove_handler (ACE_Event_Handler *event_handler,
- ACE_Reactor_Mask mask)
+ACE_WFMO_Reactor::remove_handler (ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask mask)
{
return this->handler_rep_.unbind (event_handler->get_handle (), mask);
}
ACE_INLINE int
-ACE_ReactorEx::remove_handler (ACE_HANDLE handle,
- ACE_Reactor_Mask mask)
+ACE_WFMO_Reactor::remove_handler (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask)
{
return this->handler_rep_.unbind (handle, mask);
}
ACE_INLINE int
-ACE_ReactorEx::remove_handler (const ACE_Handle_Set &handles,
- ACE_Reactor_Mask mask)
+ACE_WFMO_Reactor::remove_handler (const ACE_Handle_Set &handles,
+ ACE_Reactor_Mask mask)
{
ACE_Handle_Set_Iterator handle_iter (handles);
ACE_HANDLE h;
@@ -488,21 +490,21 @@ ACE_ReactorEx::remove_handler (const ACE_Handle_Set &handles,
}
ACE_INLINE int
-ACE_ReactorEx::cancel_wakeup (ACE_HANDLE io_handle,
- ACE_Reactor_Mask masks_to_be_removed)
+ACE_WFMO_Reactor::cancel_wakeup (ACE_HANDLE io_handle,
+ ACE_Reactor_Mask masks_to_be_removed)
{
return this->remove_handler (io_handle, masks_to_be_removed);
}
ACE_INLINE int
-ACE_ReactorEx::cancel_wakeup (ACE_Event_Handler *event_handler,
- ACE_Reactor_Mask masks_to_be_removed)
+ACE_WFMO_Reactor::cancel_wakeup (ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask masks_to_be_removed)
{
return this->remove_handler (event_handler, masks_to_be_removed);
}
ACE_INLINE int
-ACE_ReactorEx::suspend_handler (ACE_HANDLE handle)
+ACE_WFMO_Reactor::suspend_handler (ACE_HANDLE handle)
{
ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, this->lock_, -1);
@@ -518,13 +520,13 @@ ACE_ReactorEx::suspend_handler (ACE_HANDLE handle)
}
ACE_INLINE int
-ACE_ReactorEx::suspend_handler (ACE_Event_Handler *event_handler)
+ACE_WFMO_Reactor::suspend_handler (ACE_Event_Handler *event_handler)
{
return this->suspend_handler (event_handler->get_handle ());
}
ACE_INLINE int
-ACE_ReactorEx::suspend_handler (const ACE_Handle_Set &handles)
+ACE_WFMO_Reactor::suspend_handler (const ACE_Handle_Set &handles)
{
ACE_Handle_Set_Iterator handle_iter (handles);
ACE_HANDLE h;
@@ -544,7 +546,7 @@ ACE_ReactorEx::suspend_handler (const ACE_Handle_Set &handles)
}
ACE_INLINE int
-ACE_ReactorEx::suspend_all (void)
+ACE_WFMO_Reactor::suspend_handlers (void)
{
int error = 0;
int result = 0;
@@ -567,7 +569,7 @@ ACE_ReactorEx::suspend_all (void)
}
ACE_INLINE int
-ACE_ReactorEx::resume_handler (ACE_HANDLE handle)
+ACE_WFMO_Reactor::resume_handler (ACE_HANDLE handle)
{
ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, this->lock_, -1);
@@ -583,13 +585,13 @@ ACE_ReactorEx::resume_handler (ACE_HANDLE handle)
}
ACE_INLINE int
-ACE_ReactorEx::resume_handler (ACE_Event_Handler *event_handler)
+ACE_WFMO_Reactor::resume_handler (ACE_Event_Handler *event_handler)
{
return this->resume_handler (event_handler->get_handle ());
}
ACE_INLINE int
-ACE_ReactorEx::resume_handler (const ACE_Handle_Set &handles)
+ACE_WFMO_Reactor::resume_handler (const ACE_Handle_Set &handles)
{
ACE_Handle_Set_Iterator handle_iter (handles);
ACE_HANDLE h;
@@ -609,7 +611,7 @@ ACE_ReactorEx::resume_handler (const ACE_Handle_Set &handles)
}
ACE_INLINE int
-ACE_ReactorEx::resume_all (void)
+ACE_WFMO_Reactor::resume_handlers (void)
{
int error = 0;
int result = 0;
@@ -632,31 +634,31 @@ ACE_ReactorEx::resume_all (void)
}
ACE_INLINE int
-ACE_ReactorEx::handle_events (ACE_Time_Value &how_long)
+ACE_WFMO_Reactor::handle_events (ACE_Time_Value &how_long)
{
return this->event_handling (&how_long, 0);
}
ACE_INLINE int
-ACE_ReactorEx::alertable_handle_events (ACE_Time_Value &how_long)
+ACE_WFMO_Reactor::alertable_handle_events (ACE_Time_Value &how_long)
{
return this->event_handling (&how_long, 1);
}
ACE_INLINE int
-ACE_ReactorEx::handle_events (ACE_Time_Value *how_long)
+ACE_WFMO_Reactor::handle_events (ACE_Time_Value *how_long)
{
return this->event_handling (how_long, 0);
}
ACE_INLINE int
-ACE_ReactorEx::alertable_handle_events (ACE_Time_Value *how_long)
+ACE_WFMO_Reactor::alertable_handle_events (ACE_Time_Value *how_long)
{
return this->event_handling (how_long, 1);
}
ACE_INLINE int
-ACE_ReactorEx::owner (ACE_thread_t *t)
+ACE_WFMO_Reactor::owner (ACE_thread_t *t)
{
ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, this->lock_, -1);
*t = this->owner_i ();
@@ -664,13 +666,13 @@ ACE_ReactorEx::owner (ACE_thread_t *t)
}
ACE_INLINE ACE_thread_t
-ACE_ReactorEx::owner_i (void)
+ACE_WFMO_Reactor::owner_i (void)
{
return this->owner_;
}
ACE_INLINE int
-ACE_ReactorEx::owner (ACE_thread_t new_owner, ACE_thread_t *old_owner)
+ACE_WFMO_Reactor::owner (ACE_thread_t new_owner, ACE_thread_t *old_owner)
{
ACE_GUARD_RETURN (ACE_Process_Mutex, monitor, this->lock_, -1);
this->new_owner_ = new_owner;
@@ -686,13 +688,13 @@ ACE_ReactorEx::owner (ACE_thread_t new_owner, ACE_thread_t *old_owner)
}
ACE_INLINE int
-ACE_ReactorEx::new_owner (void)
+ACE_WFMO_Reactor::new_owner (void)
{
return this->new_owner_ != ACE_thread_t (0);
}
ACE_INLINE int
-ACE_ReactorEx::change_owner (void)
+ACE_WFMO_Reactor::change_owner (void)
{
this->owner_ = this->new_owner_;
this->new_owner_ = ACE_thread_t (0);
@@ -700,7 +702,7 @@ ACE_ReactorEx::change_owner (void)
}
ACE_INLINE int
-ACE_ReactorEx::safe_dispatch (int wait_status)
+ACE_WFMO_Reactor::safe_dispatch (int wait_status)
{
int result = -1;
ACE_SEH_TRY
@@ -716,17 +718,166 @@ ACE_ReactorEx::safe_dispatch (int wait_status)
}
ACE_INLINE void
-ACE_ReactorEx::wakeup_all_threads (void)
+ACE_WFMO_Reactor::wakeup_all_threads (void)
{
this->wakeup_all_threads_.signal ();
}
ACE_INLINE int
-ACE_ReactorEx::notify (ACE_Event_Handler *event_handler,
- ACE_Reactor_Mask mask,
- ACE_Time_Value *timeout)
+ACE_WFMO_Reactor::notify (ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask mask,
+ ACE_Time_Value *timeout)
{
return this->notify_handler_.notify (event_handler, mask, timeout);
}
+ACE_INLINE int
+ACE_WFMO_Reactor::register_handler (int signum,
+ ACE_Event_Handler *new_sh,
+ ACE_Sig_Action *new_disp,
+ ACE_Event_Handler **old_sh,
+ ACE_Sig_Action *old_disp)
+{
+ return this->signal_handler_->register_handler (signum,
+ new_sh, new_disp,
+ old_sh, old_disp);
+}
+
+ACE_INLINE int
+ACE_WFMO_Reactor::register_handler (const ACE_Sig_Set &sigset,
+ ACE_Event_Handler *new_sh,
+ ACE_Sig_Action *new_disp)
+{
+ int result = 0;
+
+#if (NSIG > 0)
+ for (int s = 1; s < NSIG; s++)
+ if (sigset.is_member (s)
+ && this->signal_handler_->register_handler (s, new_sh,
+ new_disp) == -1)
+ result = -1;
+#else
+ ACE_UNUSED_ARG (sigset);
+ ACE_UNUSED_ARG (new_sh);
+ ACE_UNUSED_ARG (new_disp);
+#endif /* NSIG */
+
+ return result;
+}
+
+ACE_INLINE int
+ACE_WFMO_Reactor::remove_handler (int signum,
+ ACE_Sig_Action *new_disp,
+ ACE_Sig_Action *old_disp,
+ int sigkey)
+{
+ return this->signal_handler_->remove_handler (signum, new_disp, old_disp, sigkey);
+}
+
+ACE_INLINE int
+ACE_WFMO_Reactor::remove_handler (const ACE_Sig_Set &sigset)
+{
+ int result = 0;
+
+#if (NSIG > 0)
+ for (int s = 1; s < NSIG; s++)
+ if (sigset.is_member (s)
+ && this->signal_handler_->remove_handler (s) == -1)
+ result = -1;
+#else
+ ACE_UNUSED_ARG (sigset);
+#endif /* NSIG */
+
+ return result;
+}
+
+ACE_INLINE int
+ACE_WFMO_Reactor::handler (int signum, ACE_Event_Handler **eh)
+{
+ ACE_Event_Handler *handler = this->signal_handler_->handler (signum);
+
+ if (handler == 0)
+ return -1;
+ else if (*eh != 0)
+ *eh = handler;
+ return 0;
+}
+
+ACE_INLINE void
+ACE_WFMO_Reactor::requeue_position (int)
+{
+ // Not implemented
+}
+
+ACE_INLINE int
+ACE_WFMO_Reactor::requeue_position (void)
+{
+ // Don't have an implementation for this yet...
+ ACE_NOTSUP_RETURN (-1);
+}
+
+ACE_INLINE int
+ACE_WFMO_Reactor::mask_ops (ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask mask,
+ int ops)
+{
+ // Don't have an implementation for this yet...
+ ACE_NOTSUP_RETURN (-1);
+}
+
+ACE_INLINE int
+ACE_WFMO_Reactor::mask_ops (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask,
+ int ops)
+{
+ // Don't have an implementation for this yet...
+ ACE_NOTSUP_RETURN (-1);
+}
+
+ACE_INLINE int
+ACE_WFMO_Reactor::ready_ops (ACE_Event_Handler *event_handler,
+ ACE_Reactor_Mask mask,
+ int ops)
+{
+ // Don't have an implementation for this yet...
+ ACE_NOTSUP_RETURN (-1);
+}
+
+ACE_INLINE int
+ACE_WFMO_Reactor::ready_ops (ACE_HANDLE handle,
+ ACE_Reactor_Mask,
+ int ops)
+{
+ // Don't have an implementation for this yet...
+ ACE_NOTSUP_RETURN (-1);
+}
+
+ACE_INLINE int
+ACE_WFMO_Reactor::handler (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask,
+ ACE_Event_Handler **event_handler)
+{
+ // Don't have an implementation for this yet...
+ ACE_NOTSUP_RETURN (-1);
+}
+
+ACE_INLINE int
+ACE_WFMO_Reactor::initialized (void)
+{
+ return this->open_for_business_;
+}
+
+ACE_INLINE ACE_Lock &
+ACE_WFMO_Reactor::lock (void)
+{
+ return this->lock_adapter_;
+}
+
+ACE_INLINE size_t
+ACE_WFMO_Reactor::size (void)
+{
+ // Size of repository minus the 2 used for internal purposes
+ return this->handler_rep_.max_size_ - 2;
+}
+
#endif /* ACE_WIN32 */
diff --git a/ace/XtReactor.cpp b/ace/XtReactor.cpp
index cfc82d78c4f..491d9f27b68 100644
--- a/ace/XtReactor.cpp
+++ b/ace/XtReactor.cpp
@@ -1,4 +1,3 @@
-// XtReactor.cpp
// $Id$
#define ACE_BUILD_DLL
@@ -22,22 +21,22 @@ ACE_XtReactor::ACE_XtReactor (XtAppContext context,
size_t size,
int restart,
ACE_Sig_Handler *h)
- : ACE_Reactor (size, restart, h),
+ : ACE_Select_Reactor (size, restart, h),
context_ (context),
id_len_ (0),
ids_ (0),
timeout_ (0)
{
- // When the ACE_Reactor is constructed it creates the notify pipe
- // and registers it with the register_handler_i() method. The
+ // When the ACE_Select_Reactor is constructed it creates the notify
+ // pipe and registers it with the register_handler_i() method. The
// XtReactor overloads this method BUT because the
// register_handler_i occurs when constructing the base class
- // ACE_Reactor, the ACE_Reactor register_handler_i() is called not
- // the XtReactor register_handler_i(). This means that the notify
- // pipe is registered with the ACE_Reactor event handling code not
- // the XtReactor and so notfications don't work. To get around this
- // we simply close and re-opened the notification handler in the
- // constructor of the XtReactor.
+ // ACE_Select_Reactor, the ACE_Select_Reactor register_handler_i()
+ // is called not the XtReactor register_handler_i(). This means
+ // that the notify pipe is registered with the ACE_Select_Reactor
+ // event handling code not the XtReactor and so notfications don't
+ // work. To get around this we simply close and re-opened the
+ // notification handler in the constructor of the XtReactor.
#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
this->notify_handler_.close ();
@@ -54,35 +53,35 @@ ACE_XtReactor::~ACE_XtReactor (void)
// we use the Xt functions to wait for an event, not select ()
int
-ACE_XtReactor::wait_for_multiple_events (ACE_Reactor_Handle_Set &handle_set,
+ACE_XtReactor::wait_for_multiple_events (ACE_Select_Reactor_Handle_Set &handle_set,
ACE_Time_Value *max_wait_time)
{
- ACE_TRACE ("ACE_Reactor::wait_for_multiple_events");
- int nfound;
+ ACE_TRACE ("ACE_XtReactor::wait_for_multiple_events");
+ int nfound;
- do
- {
- max_wait_time = this->timer_queue_->calculate_timeout (max_wait_time);
+ do
+ {
+ max_wait_time = this->timer_queue_->calculate_timeout (max_wait_time);
- size_t width = this->handler_rep_.max_handlep1 ();
- handle_set.rd_mask_ = this->wait_set_.rd_mask_;
- handle_set.wr_mask_ = this->wait_set_.wr_mask_;
- handle_set.ex_mask_ = this->wait_set_.ex_mask_;
- nfound = XtWaitForMultipleEvents (width,
- handle_set,
- max_wait_time);
-
- } while (nfound == -1 && this->handle_error () > 0);
-
- if (nfound > 0)
- {
+ size_t width = this->handler_rep_.max_handlep1 ();
+ handle_set.rd_mask_ = this->wait_set_.rd_mask_;
+ handle_set.wr_mask_ = this->wait_set_.wr_mask_;
+ handle_set.ex_mask_ = this->wait_set_.ex_mask_;
+ nfound = XtWaitForMultipleEvents (width,
+ handle_set,
+ max_wait_time);
+
+ } while (nfound == -1 && this->handle_error () > 0);
+
+ if (nfound > 0)
+ {
#if !defined (ACE_WIN32)
- handle_set.rd_mask_.sync (this->handler_rep_.max_handlep1 ());
- handle_set.wr_mask_.sync (this->handler_rep_.max_handlep1 ());
- handle_set.ex_mask_.sync (this->handler_rep_.max_handlep1 ());
-#endif /* ACE_REACTOR_ALTERANTIVE_IMPL */
- }
- return nfound; // Timed out or input available
+ handle_set.rd_mask_.sync (this->handler_rep_.max_handlep1 ());
+ handle_set.wr_mask_.sync (this->handler_rep_.max_handlep1 ());
+ handle_set.ex_mask_.sync (this->handler_rep_.max_handlep1 ());
+#endif /* ACE_WIN32 */
+ }
+ return nfound; // Timed out or input available
}
void
@@ -96,7 +95,7 @@ ACE_XtReactor::TimerCallbackProc (XtPointer closure, XtIntervalId *id)
ACE_Time_Value zero = ACE_Time_Value::zero; // my copy isn't const
// Deal with any timer events
- ACE_Reactor_Handle_Set handle_set;
+ ACE_Select_Reactor_Handle_Set handle_set;
self->dispatch (0, handle_set);
self->reset_timeout ();
}
@@ -105,9 +104,10 @@ ACE_XtReactor::TimerCallbackProc (XtPointer closure, XtIntervalId *id)
// about to get. Here we use select () to find out which one might be
// available.
-void ACE_XtReactor::InputCallbackProc (XtPointer closure,
- int * source,
- XtInputId *)
+void
+ACE_XtReactor::InputCallbackProc (XtPointer closure,
+ int * source,
+ XtInputId *)
{
ACE_XtReactor *self = (ACE_XtReactor *) closure;
@@ -115,7 +115,7 @@ void ACE_XtReactor::InputCallbackProc (XtPointer closure,
ACE_Time_Value zero = ACE_Time_Value::zero; // my copy isn't const
- ACE_Reactor_Handle_Set wait_set;
+ ACE_Select_Reactor_Handle_Set wait_set;
// Deal with one file event
@@ -132,7 +132,7 @@ void ACE_XtReactor::InputCallbackProc (XtPointer closure,
wait_set.wr_mask_,
wait_set.ex_mask_, &zero);
- ACE_Reactor_Handle_Set dispatch_set;
+ ACE_Select_Reactor_Handle_Set dispatch_set;
// - Use only that one file event (removes events for other files)
if (result > 0)
@@ -150,12 +150,12 @@ void ACE_XtReactor::InputCallbackProc (XtPointer closure,
int
ACE_XtReactor::XtWaitForMultipleEvents (int width,
- ACE_Reactor_Handle_Set &wait_set,
+ ACE_Select_Reactor_Handle_Set &wait_set,
ACE_Time_Value *)
{
// Check to make sure our handle's are all usable.
- ACE_Reactor_Handle_Set temp_set = wait_set;
+ ACE_Select_Reactor_Handle_Set temp_set = wait_set;
if (ACE_OS::select (width,
temp_set.rd_mask_,
@@ -170,7 +170,7 @@ ACE_XtReactor::XtWaitForMultipleEvents (int width,
// Wait for something to happen.
::XtAppProcessEvent (context_, XtIMAll);
- // Now actually read the result needed by the Reactor using select.
+ // Now actually read the result needed by the Select_Reactor using select.
return ACE_OS::select (width,
wait_set.rd_mask_,
wait_set.wr_mask_,
@@ -178,7 +178,8 @@ ACE_XtReactor::XtWaitForMultipleEvents (int width,
(ACE_Time_Value *) &ACE_Time_Value::zero);
}
-XtAppContext ACE_XtReactor::context (void)
+XtAppContext
+ACE_XtReactor::context (void)
{
return this->context_;
}
@@ -192,7 +193,7 @@ ACE_XtReactor::register_handler_i (ACE_HANDLE handle,
ACE_DEBUG ((LM_DEBUG, "+++%d\n", handle));
- int result = ACE_Reactor::register_handler_i (handle, handler, mask);
+ int result = ACE_Select_Reactor::register_handler_i (handle, handler, mask);
if (result == -1)
return -1;
@@ -233,10 +234,10 @@ ACE_XtReactor::register_handler_i (ACE_HANDLE handle,
::XtRemoveInput (ids_[handle].id_);
ids_[handle].id_ = ::XtAppAddInput (context_,
- handle,
- (XtPointer) condition,
- InputCallbackProc,
- (XtPointer) this);
+ handle,
+ (XtPointer) condition,
+ InputCallbackProc,
+ (XtPointer) this);
ids_[handle].good_id_ = 1;
}
return 0;
@@ -247,7 +248,7 @@ ACE_XtReactor::register_handler_i (const ACE_Handle_Set &handles,
ACE_Event_Handler *handler,
ACE_Reactor_Mask mask)
{
- return ACE_Reactor::register_handler_i (handles, handler, mask);
+ return ACE_Select_Reactor::register_handler_i (handles, handler, mask);
}
int
@@ -257,7 +258,7 @@ ACE_XtReactor::remove_handler_i (ACE_HANDLE handle,
ACE_TRACE ("ACE_XtReactor::remove_handler_i");
ACE_DEBUG ((LM_DEBUG, "---%d\n", handle));
- int result = ACE_Reactor::remove_handler_i (handle, mask);
+ int result = ACE_Select_Reactor::remove_handler_i (handle, mask);
if (handle <= id_len_)
{
@@ -279,7 +280,8 @@ ACE_XtReactor::remove_handler_i (ACE_HANDLE handle,
// The following functions ensure that there is an Xt timeout for the
// first timeout in the Reactor's Timer_Queue.
-void ACE_XtReactor::reset_timeout (void)
+void
+ACE_XtReactor::reset_timeout (void)
{
if (timeout_)
::XtRemoveTimeOut (timeout_);
@@ -306,10 +308,10 @@ ACE_XtReactor::schedule_timer (ACE_Event_Handler *handler,
const ACE_Time_Value &interval)
{
ACE_TRACE ("ACE_XtReactor::schedule_timer");
- ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1));
+ ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_MUTEX, ace_mon, this->token_, -1));
long result =
- ACE_Reactor::schedule_timer (handler, arg, delta_time, interval);
+ ACE_Select_Reactor::schedule_timer (handler, arg, delta_time, interval);
if (result == -1)
return -1;
@@ -326,8 +328,8 @@ ACE_XtReactor::cancel_timer (ACE_Event_Handler *handler,
{
ACE_TRACE ("ACE_XtReactor::cancel_timer");
- if (ACE_Reactor::cancel_timer (handler,
- dont_call_handle_close) == -1)
+ if (ACE_Select_Reactor::cancel_timer (handler,
+ dont_call_handle_close) == -1)
return -1;
else
{
@@ -343,9 +345,9 @@ ACE_XtReactor::cancel_timer (long timer_id,
{
ACE_TRACE ("ACE_XtReactor::cancel_timer");
- if (ACE_Reactor::cancel_timer (timer_id,
- arg,
- dont_call_handle_close) == -1)
+ if (ACE_Select_Reactor::cancel_timer (timer_id,
+ arg,
+ dont_call_handle_close) == -1)
return -1;
else
{