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
