diff options
-rw-r--r-- | ace/Event_Handler.cpp | 35 | ||||
-rw-r--r-- | ace/Event_Handler.h | 10 | ||||
-rw-r--r-- | ace/Handle_Set.h | 2 | ||||
-rw-r--r-- | ace/Local_Tokens.h | 22 | ||||
-rw-r--r-- | ace/Local_Tokens.i | 35 | ||||
-rw-r--r-- | ace/Message_Queue.h | 8 | ||||
-rw-r--r-- | ace/OS.h | 6 | ||||
-rw-r--r-- | ace/Proactor.cpp | 8 | ||||
-rw-r--r-- | ace/Proactor.h | 10 | ||||
-rw-r--r-- | ace/README | 1 | ||||
-rw-r--r-- | ace/Reactor.cpp | 1817 | ||||
-rw-r--r-- | ace/Reactor.h | 826 | ||||
-rw-r--r-- | ace/Reactor.i | 444 | ||||
-rw-r--r-- | ace/Reactor_Impl.h | 348 | ||||
-rw-r--r-- | ace/Select_Reactor.cpp | 1798 | ||||
-rw-r--r-- | ace/Select_Reactor.h | 818 | ||||
-rw-r--r-- | ace/Select_Reactor.i | 214 | ||||
-rw-r--r-- | ace/Service_Config.cpp | 114 | ||||
-rw-r--r-- | ace/Service_Config.h | 86 | ||||
-rw-r--r-- | ace/Strategies.cpp | 34 | ||||
-rw-r--r-- | ace/Strategies.h | 27 | ||||
-rw-r--r-- | ace/Synch_T.h | 19 | ||||
-rw-r--r-- | ace/Synch_T.i | 38 | ||||
-rw-r--r-- | ace/Timer_Queue_T.h | 1 | ||||
-rw-r--r-- | ace/Token.h | 12 | ||||
-rw-r--r-- | ace/Token.i | 28 | ||||
-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.cpp | 120 |
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); @@ -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 ¤t_info = + ACE_WFMO_Reactor_Handler_Repository::Current_Info ¤t_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 { |