Wait Functions (Windows CE 5.0)

Send Feedback

Windows CE supports single-object and multiple-object wait functions that block or unblock a thread based on the signaled or nonsignaled state of the object.

The single object function is WaitForSingleObject.

The multiple object functions are WaitForMultipleObjects and MsgWaitForMultipleObjects.

The WaitForSingleObject function enables a thread wait on a single object. The object can be a synchronization object, such as an event or mutex, or the object can be a handle to a process and thread.

Handles are signaled when their processes or threads terminate. Thus, a process can monitor another process or thread and perform some action based on the status of the process or thread.

The WaitForMultipleObjects and MsgWaitForMultipleObjects functions enable the calling thread to specify an array containing one or more synchronization object handles. These functions return when one of the following events occurs:

  • The state of a specified object is set to signaled.

  • The time-out interval elapses.

    You can set the time-out interval to INFINITE to specify that the wait will not time out.

Windows CE does not support waiting for all objects to be signaled.

The following code example shows how to use CreateEvent to create two event objects. It then uses the two created objects as parameters in the function call to WaitForMultipleObjects. WaitForMultipleObjects does not return until one of the objects is set to signaled.

int EventsExample (void)
{
  HANDLE hEvents[2];
  DWORD dwEvent;
  int i;

  for (i = 0; i < 2; i++)
  {
    hEvents[i] = CreateEvent (NULL,   // No security attributes
                              FALSE,  // Auto-reset event object
                              FALSE,  // Initial state is nonsignaled
                              NULL);  // Unnamed object

    if (hEvents[i] == NULL)
    {
      // Your error handling code goes here.
      MessageBox (NULL, TEXT("CreateEvent error!"),
                  TEXT("Error"), MB_OK);

      // You can use GetLastError to obtain more information.

      return 0;
    }
  }

  // Put code that uses the events here; that is, startup 
  // of threads, which will set the events when completed.
  // . . .

  dwEvent = WaitForMultipleObjects (
                      2,            // Number of objects in an array
                      hEvents,      // Array of objects
                      FALSE,        // Wait for any (required 
                                    // under Windows CE)
                      INFINITE);    // Indefinite wait

  switch (dwEvent)
  {
    case WAIT_OBJECT_0 + 0:         // First event was signaled
    case WAIT_OBJECT_0 + 1:         // Second event was signaled
      break;

    default:
      // Your error handling code goes here.
      MessageBox (NULL, TEXT("Wait error!"),
                  TEXT("Error"), MB_OK);

      // You can use GetLastError to obtain more information.

      return 0;
  }

  return 1;
} // End of EventsExample code

MsgWaitForMultipleObjects is similar to WaitForMultipleObjects, except that it enables you to specify input event objects in the object handle array. You select the type of input event to wait for in the dwWakeMask parameter.

MsgWaitForMultipleObjects does not return if there is unread input of the specified type in the queue. It returns only when new input arrives.

For example, a thread can use MsgWaitForMultipleObjects with its dwWakeMask parameter set to QS_KEY. This blocks its execution until the state of a specified object is set to signaled or until keyboard input is available in the thread's input queue. The thread can use the GetMessage or PeekMessage function to retrieve the input.

The following code example shows how to use MsgWaitForMultipleObjects in a message loop. The loop continues until a WM_QUIT message appears in the queue. The dwWakeMask parameter is set to QS_ALLINPUT so that all messages are checked.

int MessageLoop (
      HANDLE* lphObjects,   // Handles that need to be waited on
      int     iObjCount )   // Number of handles to wait on
{
  while (TRUE)
  {
    // Block-local variables
    DWORD dwResult;
    MSG msgCurrent;

    while (PeekMessage (&msgCurrent, NULL, 0, 0, PM_REMOVE))
    {
      if (WM_QUIT == msgCurrent.message)
        return 1;

      DispatchMessage (&msgCurrent);
    }

    dwResult = MsgWaitForMultipleObjects (iObjCount, lphObjects,
                              FALSE, INFINITE, QS_ALLINPUT);

    if (dwResult == DWORD(WAIT_OBJECT_0 + iObjCount))
    {
      // Some input was received -- go around loop again
      continue;
    }
    else 
    {
      // Check for errors and handle them here. If not an error,
      // write code which processes the result here.  Be sure to
      // create code that provides some way to get out of the loop!

      // The index for the signaled is 
      // (dwResult - WAIT_OBJECT_0).
    }
  }
} // End of MessageLoop example code

Note   Be careful when using wait functions and code that directly or indirectly creates windows.

If a thread creates windows, it must process messages. Message broadcasts are sent to all windows in the system. If a thread uses a wait function with no time-out interval, the system deadlocks.

One example of code that indirectly creates a window is the Component Object Model (COM) CoInitialize function.

If you have a thread that creates windows, use MsgWaitForMultipleObjects rather than the other wait functions.

See Also

Synchronization

Send Feedback on this topic to the authors

Feedback FAQs

© 2006 Microsoft Corporation. All rights reserved.