diff options
author | irfan <irfan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1998-03-17 22:50:07 +0000 |
---|---|---|
committer | irfan <irfan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1998-03-17 22:50:07 +0000 |
commit | 82814eaf4eace275ff1a016f172589b8d25b162f (patch) | |
tree | 838219ce10242c92129ac198b5daccdb2a2268a8 /ace | |
parent | 23ec78401e35f9c73d914ae9902e9692ac971d76 (diff) | |
download | ATCD-82814eaf4eace275ff1a016f172589b8d25b162f.tar.gz |
*** empty log message ***
Diffstat (limited to 'ace')
-rw-r--r-- | ace/Msg_WFMO_Reactor.cpp | 77 | ||||
-rw-r--r-- | ace/Msg_WFMO_Reactor.h | 107 | ||||
-rw-r--r-- | ace/Msg_WFMO_Reactor.i | 30 | ||||
-rw-r--r-- | ace/WFMO_Reactor.cpp | 107 | ||||
-rw-r--r-- | ace/WFMO_Reactor.h | 19 | ||||
-rw-r--r-- | ace/WFMO_Reactor.i | 24 |
6 files changed, 312 insertions, 52 deletions
diff --git a/ace/Msg_WFMO_Reactor.cpp b/ace/Msg_WFMO_Reactor.cpp new file mode 100644 index 00000000000..1b0fb0aa84c --- /dev/null +++ b/ace/Msg_WFMO_Reactor.cpp @@ -0,0 +1,77 @@ +// $Id$ + +#define ACE_BUILD_DLL + +#if defined (ACE_WIN32) + +#include "ace/Msg_WFMO_Reactor.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Msg_WFMO_Reactor.i" +#endif /* __ACE_INLINE__ */ + +ACE_Msg_WFMO_Reactor::ACE_Msg_WFMO_Reactor (ACE_Sig_Handler *sh, + ACE_Timer_Queue *tq) + : ACE_WFMO_Reactor (sh, tq) +{ +} + +ACE_Msg_WFMO_Reactor::ACE_Msg_WFMO_Reactor (size_t size, + int unused, + ACE_Sig_Handler *sh, + ACE_Timer_Queue *tq) + : ACE_WFMO_Reactor (size, unused, sh, tq) +{ +} + +ACE_Msg_WFMO_Reactor::~ACE_Msg_WFMO_Reactor (void) +{ +} + +int +ACE_Msg_WFMO_Reactor::wait_for_multiple_events (int timeout, + int alertable) +{ + // Wait for any of handles_ to be active, or until timeout expires. + // If <alertable> is enabled allow asynchronous completion of + // ReadFile and WriteFile operations. QS_ALLINPUT allows + // <MsgWaitForMultipleObjectsEx> to wait for any message is in the + // queue. + return ::MsgWaitForMultipleObjectsEx (this->handler_rep_.max_handlep1 (), + this->handler_rep_.handles (), + timeout, + QS_ALLINPUT, + alertable); +} + +int +ACE_Msg_WFMO_Reactor::dispatch_window_messages (void) +{ + int number_of_messages = 0; + MSG msg; + + // Process all pending message from this thread's message queue + while (::PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) + { + ::TranslateMessage (&msg); + if (msg.message == WM_QUIT) + return -1; + + ::DispatchMessage (&msg); + number_of_messages++; + } + + return number_of_messages; +} + +DWORD +ACE_Msg_WFMO_Reactor::poll_remaining_handles (size_t index) +{ + return ::MsgWaitForMultipleObjects (this->handler_rep_.max_handlep1 () - index, + this->handler_rep_.handles () + index, + FALSE, + 0, + QS_ALLINPUT); +} + +#endif /* ACE_WIN32 */ diff --git a/ace/Msg_WFMO_Reactor.h b/ace/Msg_WFMO_Reactor.h new file mode 100644 index 00000000000..a2c26f2e9f3 --- /dev/null +++ b/ace/Msg_WFMO_Reactor.h @@ -0,0 +1,107 @@ +/* -*- C++ -*- */ +// $Id$ +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Msg_WFMO_Reactor.h +// +// = AUTHOR +// Beskrovny Evgeny, Comverse Network Systems +// Irfan Pyarali +// +// ============================================================================ + +#if !defined (ACE_MSG_WFMO_REACTOR_H) +#define ACE_MSG_WFMO_REACTOR_H + +#include "ace/WFMO_Reactor.h" + +#if defined (ACE_WIN32) + +class ACE_Export ACE_Msg_WFMO_Reactor : public ACE_WFMO_Reactor +{ + // + // = TITLE + // + // An object oriented event demultiplexor and event handler + // Msg_WFMO_Reactor for Win32 MsgWaitForMultipleObjects. + // + // = DESCRIPTION + // + // The ACE_Msg_WFMO_Reactor is an object-oriented event + // demultiplexor and event handler Reactor. It differs from + // WFMO_Reactor by its ability to react on Windows messages. It + // is needed when the task should serve also as a COM/DCOM + // server. + // +public: + // = Initialization and termination methods. + ACE_Msg_WFMO_Reactor (ACE_Sig_Handler * = 0, + ACE_Timer_Queue * = 0); + // Initialize <ACE_Msg_WFMO_Reactor> with the default size. + + ACE_Msg_WFMO_Reactor (size_t size, + int unused = 0, + ACE_Sig_Handler * = 0, + ACE_Timer_Queue * = 0); + // Initialize <ACE_Msg_WFMO_Reactor> with size <size>. Two slots will be + // added to the <size> parameter which will store handles used for + // internal management purposes. + + virtual ~ACE_Msg_WFMO_Reactor (void); + // Close down the ACE_Msg_WFMO_Reactor and release all of its resources. + + 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 blocks for up to <max_wait_time> before + // returning. It will return earlier if timer events, I/O events, + // window 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. + // + // <MsgWaitForMultipleObjects> is used as the demultiplexing call + // + // Returns the total number of <ACE_Event_Handler>s that were + // dispatched, 0 if the <max_wait_time> elapsed without dispatching + // any handlers, or -1 if an error occurs. + // + // The only difference between <alertable_handle_events> and + // <handle_events> is that in the alertable case, MWMO_ALERTABLE is + // passed to <MsgWaitForMultipleObjects> 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); + // This method is just like the one above, except the + // <max_wait_time> value is a reference and can therefore never be + // NULL. + +protected: + virtual int wait_for_multiple_events (int timeout, + int alertable); + // Wait for timer and I/O events to occur. + + virtual DWORD poll_remaining_handles (size_t index); + // Check for activity on remaining handles. + + virtual int dispatch_window_messages (void); + // Dispatches window messages. +}; + +#endif /* ACE_WIN32 */ + +#if defined (__ACE_INLINE__) +#include "ace/Msg_WFMO_Reactor.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_MSG_WFMO_REACTOR_H */ diff --git a/ace/Msg_WFMO_Reactor.i b/ace/Msg_WFMO_Reactor.i new file mode 100644 index 00000000000..e9f5bd2c70c --- /dev/null +++ b/ace/Msg_WFMO_Reactor.i @@ -0,0 +1,30 @@ +/* -*- C++ -*- */ +// $Id$ + +#if defined (ACE_WIN32) + +ACE_INLINE int +ACE_Msg_WFMO_Reactor::handle_events (ACE_Time_Value &how_long) +{ + return this->event_handling (&how_long, 0); +} + +ACE_INLINE int +ACE_Msg_WFMO_Reactor::alertable_handle_events (ACE_Time_Value &how_long) +{ + return this->event_handling (&how_long, MWMO_ALERTABLE); +} + +ACE_INLINE int +ACE_Msg_WFMO_Reactor::handle_events (ACE_Time_Value *how_long) +{ + return this->event_handling (how_long, 0); +} + +ACE_INLINE int +ACE_Msg_WFMO_Reactor::alertable_handle_events (ACE_Time_Value *how_long) +{ + return this->event_handling (how_long, MWMO_ALERTABLE); +} + +#endif /* ACE_WIN32 */ diff --git a/ace/WFMO_Reactor.cpp b/ace/WFMO_Reactor.cpp index b2b626ab49a..135091e3aa8 100644 --- a/ace/WFMO_Reactor.cpp +++ b/ace/WFMO_Reactor.cpp @@ -1180,8 +1180,11 @@ ACE_WFMO_Reactor::event_handling (ACE_Time_Value *max_wait_time, // mut and event. countdown.update (); + // Calculate timeout + int timeout = this->calculate_timeout (max_wait_time); + // Wait for event to happen - int wait_status = this->wait_for_multiple_events (max_wait_time, + int wait_status = this->wait_for_multiple_events (timeout, alertable); // Upcall @@ -1226,11 +1229,9 @@ ACE_WFMO_Reactor::ok_to_wait (ACE_Time_Value *max_wait_time, } int -ACE_WFMO_Reactor::wait_for_multiple_events (ACE_Time_Value *max_wait_time, - int alertable) +ACE_WFMO_Reactor::wait_for_multiple_events (int timeout, + 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 // ReadFile and WriteFile operations. @@ -1241,6 +1242,15 @@ ACE_WFMO_Reactor::wait_for_multiple_events (ACE_Time_Value *max_wait_time, alertable); } +DWORD +ACE_WFMO_Reactor::poll_remaining_handles (size_t index) +{ + return ::WaitForMultipleObjects (this->handler_rep_.max_handlep1 () - index, + this->handler_rep_.handles () + index, + FALSE, + 0); +} + int ACE_WFMO_Reactor::calculate_timeout (ACE_Time_Value *max_wait_time) { @@ -1258,14 +1268,25 @@ ACE_WFMO_Reactor::calculate_timeout (ACE_Time_Value *max_wait_time) int -ACE_WFMO_Reactor::dispatch (int wait_status) +ACE_WFMO_Reactor::expire_timers (void) { - int handlers_dispatched = 0; - // If "owner" thread if (ACE_Thread::self () == this->owner_) // expire all pending timers. - handlers_dispatched += this->timer_queue_->expire (); + return this->timer_queue_->expire (); + + else + // Nothing to expire + return 0; +} + +int +ACE_WFMO_Reactor::dispatch (int wait_status) +{ + int handlers_dispatched = 0; + + // Expire timers + handlers_dispatched += this->expire_timers (); switch (wait_status) { @@ -1284,9 +1305,8 @@ ACE_WFMO_Reactor::dispatch (int wait_status) } // Dispatches any active handles from <handles_[index]> to -// <handles_[max_handlep1_]> using <WaitForMultipleObjects> to poll -// through our handle set looking for active handles. - +// <handles_[max_handlep1_]>, polling through our handle set looking +// for active handles. int ACE_WFMO_Reactor::dispatch_handles (size_t index) { @@ -1294,16 +1314,17 @@ ACE_WFMO_Reactor::dispatch_handles (size_t index) ; number_of_handlers_dispatched++) { - this->dispatch_handler (index++); + size_t max_handlep1 = this->handler_rep_.max_handlep1 (); + + if (this->dispatch_handler (index++, max_handlep1) == -1) + return -1; // We're done. - if (index >= this->handler_rep_.max_handlep1 ()) + if (index >= max_handlep1) return number_of_handlers_dispatched; - - DWORD wait_status = - ::WaitForMultipleObjects (this->handler_rep_.max_handlep1 () - index, - this->handler_rep_.handles () + index, - FALSE, 0); // We're polling. + + // Check the remaining handles + DWORD wait_status = this->poll_remaining_handles (index); switch (wait_status) { case WAIT_FAILED: // Failure. @@ -1315,7 +1336,7 @@ ACE_WFMO_Reactor::dispatch_handles (size_t index) default: // Dispatch. // Check if a handle successfully became signaled. if (wait_status >= WAIT_OBJECT_0 && - wait_status < WAIT_OBJECT_0 + this->handler_rep_.max_handlep1 () - index) + wait_status <= (WAIT_OBJECT_0 + max_handlep1 - index)) index += wait_status - WAIT_OBJECT_0; else // Otherwise, a handle was abandoned. @@ -1324,28 +1345,35 @@ ACE_WFMO_Reactor::dispatch_handles (size_t index) } } -// Dispatches a single handler. Returns 0 on success, -1 if the -// handler was removed. - int -ACE_WFMO_Reactor::dispatch_handler (int index) +ACE_WFMO_Reactor::dispatch_handler (size_t index, + size_t max_handlep1) { - // 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 WFMO_Reactor->handle_events(). - if (!this->handler_rep_.scheduled_for_deletion (index)) - { - ACE_HANDLE event_handle = *(this->handler_rep_.handles () + index); + // Check if there are window messages that need to be dispatched + if (index == max_handlep1) + return this->dispatch_window_messages (); - if (this->handler_rep_.current_info ()[index].io_entry_) - return this->complex_dispatch_handler (index, event_handle); - else - return this->simple_dispatch_handler (index, event_handle); - } - return 0; + else + { + // 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 WFMO_Reactor->handle_events(). + if (!this->handler_rep_.scheduled_for_deletion (index)) + { + ACE_HANDLE event_handle = *(this->handler_rep_.handles () + index); + + if (this->handler_rep_.current_info ()[index].io_entry_) + return this->complex_dispatch_handler (index, event_handle); + else + return this->simple_dispatch_handler (index, event_handle); + } + else + // The handle was scheduled for deletion, so we will skip it. + return 0; + } } int @@ -1362,6 +1390,7 @@ ACE_WFMO_Reactor::simple_dispatch_handler (int index, // Upcall if (eh->handle_signal (0, &sig) == -1) this->handler_rep_.unbind (event_handle, ACE_Event_Handler::NULL_MASK); + return 0; } diff --git a/ace/WFMO_Reactor.h b/ace/WFMO_Reactor.h index 461792d559b..01290b4ca88 100644 --- a/ace/WFMO_Reactor.h +++ b/ace/WFMO_Reactor.h @@ -886,14 +886,21 @@ protected: int alertable); // Check to see if it is ok to enter ::WaitForMultipleObjects(). - virtual int wait_for_multiple_events (ACE_Time_Value *max_wait_time, - int alertable); + virtual int wait_for_multiple_events (int timeout, + int alertable); // Wait for timer and I/O events to occur. + virtual DWORD poll_remaining_handles (size_t index); + // Check for activity on remaining handles. + + virtual int expire_timers (void); + // Expire timers. Only the owner thread does useful stuff in this + // function. + virtual int dispatch (int wait_status); // Dispatches the timers and I/O handlers. - int safe_dispatch (int wait_status); + virtual int safe_dispatch (int wait_status); // Protect against structured exceptions caused by user code when // dispatching handles @@ -902,7 +909,8 @@ protected: // handles_[active_handles_] using <WaitForMultipleObjects> to poll // through our handle set looking for active handles. - virtual int dispatch_handler (int index); + virtual int dispatch_handler (size_t index, + size_t max_handlep1); // Dispatches a single handler. Returns 0 on success, -1 if the // handler was removed. @@ -916,6 +924,9 @@ protected: // Dispatches a single handler. Returns 0 on success, -1 if the // handler was removed. + virtual int dispatch_window_messages (void); + // Dispatches window messages. Noop for WFMO_Reactor. + virtual ACE_Reactor_Mask upcall (ACE_Event_Handler *event_handler, ACE_HANDLE io_handle, ACE_HANDLE event_handle, diff --git a/ace/WFMO_Reactor.i b/ace/WFMO_Reactor.i index 4c409077926..3caa922ad44 100644 --- a/ace/WFMO_Reactor.i +++ b/ace/WFMO_Reactor.i @@ -657,12 +657,6 @@ ACE_WFMO_Reactor::resume_handlers (void) } ACE_INLINE int -ACE_WFMO_Reactor::handle_events (ACE_Time_Value &how_long) -{ - return this->event_handling (&how_long, 0); -} - -ACE_INLINE int ACE_WFMO_Reactor::uses_event_associations (void) { // Since the WFMO_Reactor does use event associations, this function @@ -671,21 +665,27 @@ ACE_WFMO_Reactor::uses_event_associations (void) } ACE_INLINE int +ACE_WFMO_Reactor::handle_events (ACE_Time_Value &how_long) +{ + return this->event_handling (&how_long, FALSE); +} + +ACE_INLINE int ACE_WFMO_Reactor::alertable_handle_events (ACE_Time_Value &how_long) { - return this->event_handling (&how_long, 1); + return this->event_handling (&how_long, TRUE); } ACE_INLINE int ACE_WFMO_Reactor::handle_events (ACE_Time_Value *how_long) { - return this->event_handling (how_long, 0); + return this->event_handling (how_long, FALSE); } ACE_INLINE int ACE_WFMO_Reactor::alertable_handle_events (ACE_Time_Value *how_long) { - return this->event_handling (how_long, 1); + return this->event_handling (how_long, TRUE); } ACE_INLINE int @@ -748,6 +748,12 @@ ACE_WFMO_Reactor::safe_dispatch (int wait_status) return result; } +ACE_INLINE int +ACE_WFMO_Reactor::dispatch_window_messages (void) +{ + return 0; +} + ACE_INLINE void ACE_WFMO_Reactor::wakeup_all_threads (void) { |