Figure 1   Suspending Threads with WaitForMultipleObjects

Index
Handle Value
Set
0
0x1111 (mutex)
0
1
0x2222 (semaphore)

2
0x0000 (OR)

3
0x2222 (semaphore)
1
4
0x3333 (event)

5
0x4444 (process)

6
0x0000 (OR)

7
0x1111 (mutex)
2
8
0x4444 (process)


Figure 2   WaitForMultipleExpressions Return Values

Return Value
Description
WAIT_OBJECT_0 to (WAIT_OBJECT_0 +# of expressions - 1)
Indicates which expression came true
WAIT_TIMEOUT
No expression came true within the specified time
WAIT_FAILED
An error occurred. Call GetLastError for more information. An error of ERROR_TOO_MANY_SECRETS means you specified more than 64 expressions. An error of ERROR_SECRET_TOO_LONG means that at least one expression had more than 63 objects specified. Other error codes may be returned. (I just couldn't resist using these two error codes for my own purposes.)


Figure 4   Win32 APIs that Place Threads in an Alterable State


DWORD SleepEx(DWORD dwTimeout, BOOL fAlertable);
DWORD WaitForSingleObjectEx(HANDLE hObject, DWORD dwTimeout, BOOL fAlertable);
DWORD WaitForMultipleObjectsEx(DWORD cObjects, LPHANDLE lphObjects, BOOL 
     fWaitAll, DWORD dwTimeout, BOOL fAlertable);
BOOL SignalObjectAndWait(HANDLE hObjectToSignal, HANDLE hObjectToWaitOn, DWORD 
     dwMilliseconds, BOOL fAlertable);
DWORD MsgWaitForMultipleObjectsEx(DWORD nCount, LPHANDLE pHandles, DWORD   
     dwMilliseconds, DWORD dwWakeMask, DWORD dwFlags);

Figure 5   Handling Timeouts


 // Wait for an expressions to come TRUE or for a timeout
 dwWaitRet = WaitForMultipleObjects(dwExpNum, 
    ahThreads, FALSE, dwTimeOut);
 
 if (WAIT_TIMEOUT == dwWaitRet) {
    // If we timed-out, we need to check to see if any 
    // expressions were satisfied by checking the state 
    // of the hsemOnlyOne semaphore.
    dwWaitRet = WaitForSingleObject(hsemOnlyOne, 0);
 
    if (WAIT_TIMEOUT == dwWaitRet) {
       // If the semaphore was not signalled, some thread 
       // expressions was satisfied and we need to 
       // determine which expression was satisfied.
       dwWaitRet = WaitForMultipleObjects(dwExpNum, 
          ahThreads, FALSE, INFINITE);
       } else {
          // No expression was satisfied and the call to 
          // WaitForSingleObject gave us the semaphore so we
          // know that no expression will ever be satisfied
          // now -- waiting for an expression has timed-out.
          dwWaitRet = WAIT_TIMEOUT;
    }
 }