Raymond Chen's blog "the Old New Thing" has some interesting reading on
MsgWaitforMultipleObjectsEx, as a seach there will reveal, including the
"wait all" behavior and some associated APC topics like this: 

http://blogs.msdn.com/oldnewthing/archive/2006/05/03/589110.aspx 


Phil Wilson 


-----Original Message-----
From: Discussion of advanced .NET topics.
[mailto:[EMAIL PROTECTED] On Behalf Of Marc Brooks
Sent: Monday, July 31, 2006 12:46 PM
To: [email protected]
Subject: Re: [ADVANCED-DOTNET] MsgWaitForMultipleObjectsEx

> Of course there's a horrible flaw in both CoWaitForMultipleHandles and
> MsgWaitforMultipleObjectsEx: if you do a 'wait all' and there's a 
> message pump involved, it'll only return when all the handles are 
> signaled *and* you've got at least one message waiting for you in the 
> call.

Ahhh, the memories... here's a blast from the past (in unmanaged C++, of
course)

// This function mimics the up-and-coming CoWaitForMultipleHandles
function but returns the DWORD result of // WAIT_OBJECT_0 for handle
zero, etc..., or WAIT_ABANDONED_0 for abandoned handles, or // WAIT_TIME
if timeout expires DWORD NiceWaitForMultipleHandles(
  BOOL fAll,         // Wait options, FALSE waits for any, TRUE waits
for all messages...
  DWORD dwTimeout,   // Timeout period, in milliseconds.
  ULONG cHandles,    // Number of elements in the pHandles array.
  LPHANDLE pHandles) // Array of Win32 handles.
{
   DWORD dwResult = WAIT_FAILED;
   DWORD dwTimeLeft = dwTimeout;
   static const DWORD dwOneSlice = 100; // do it in 100 millisecond
chunks...

   while (1)
   {
      if ( ! fAll)
      {
         dwResult = MsgWaitForMultipleObjects(cHandles,      // number
of handles in the handle array
                                              pHandles,      //
pointer to the object-handle array
                                              fAll,          // any or
all flag
                                              dwTimeout,     //
time-out interval in milliseconds
                                              QS_ALLINPUT);  // type of
input events to wait for (any input)

         if (dwResult == WAIT_OBJECT_0 + cHandles)
         {
            // We have input messages, dispatch them!
            MSG msg;

            while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD))
            {
               TranslateMessage(&msg);
               DispatchMessage(&msg);
            }

            // When we service messages, let's not count that against
the timeout specified so loop back...
            continue;
         }
      }
      else {
         // MsgWaitForMultipleObjects is broken if ALL is chosen.
Deal with it the hard way...

         // if we are not doing an instant check
         if (0 != dwTimeLeft)
         {
            dwTimeout = dwOneSlice;

            if (INFINITE != dwTimeLeft)
            {
               if (dwTimeLeft < dwTimeout)
                  dwTimeout = dwTimeLeft;

               dwTimeLeft -= dwTimeout;
            }
         }
         else
            dwTimeout = dwTimeLeft;

         dwResult = WaitForMultipleObjects(cHandles,      // number of
handles in the handle array
                                           pHandles,      // pointer
to the object-handle array
                                           fAll,          // any or all
flag
                                           dwTimeout);    // time-out
interval in milliseconds
      }

      if ((WAIT_OBJECT_0 <= dwResult) && (dwResult < (WAIT_OBJECT_0 +
cHandles)))
      {
         // Success on one/all handles
         break;
      }
      else if ((WAIT_ABANDONED_0 <= dwResult) && (dwResult <
(WAIT_ABANDONED_0 + cHandles)))
      {
         // One or more handles abandoned
         break;
      }
      else if (dwResult == WAIT_TIMEOUT)
      {
         // If we were waiting for ANY, or used up the whole timeout,
         // we know it is a "hard" timeout...
         if ( ! fAll || (0 == dwTimeLeft))
            break;

         MSG msg;

         // Service the queue without yeilding...
         while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD))
         {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
         }

         // Note, we could adjust the dwTimeLeft to account for the time
spent dispatching
         // messages, but in most cases we don't really care...
      }
      else break; // something I don't expect
  }

   return dwResult;
}

--
"You hide yourself with sanctimony, I hide myself with narcissism."
--T-Bone Burnett

Marc C. Brooks
http://musingmarc.blogspot.com

===================================
This list is hosted by DevelopMentor(r)  http://www.develop.com

View archives and manage your subscription(s) at
http://discuss.develop.com

===================================
This list is hosted by DevelopMentorĀ®  http://www.develop.com

View archives and manage your subscription(s) at http://discuss.develop.com

Reply via email to