summaryrefslogtreecommitdiff
path: root/ace
diff options
context:
space:
mode:
authorirfan <irfan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1998-03-17 22:50:07 +0000
committerirfan <irfan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1998-03-17 22:50:07 +0000
commit82814eaf4eace275ff1a016f172589b8d25b162f (patch)
tree838219ce10242c92129ac198b5daccdb2a2268a8 /ace
parent23ec78401e35f9c73d914ae9902e9692ac971d76 (diff)
downloadATCD-82814eaf4eace275ff1a016f172589b8d25b162f.tar.gz
*** empty log message ***
Diffstat (limited to 'ace')
-rw-r--r--ace/Msg_WFMO_Reactor.cpp77
-rw-r--r--ace/Msg_WFMO_Reactor.h107
-rw-r--r--ace/Msg_WFMO_Reactor.i30
-rw-r--r--ace/WFMO_Reactor.cpp107
-rw-r--r--ace/WFMO_Reactor.h19
-rw-r--r--ace/WFMO_Reactor.i24
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)
{