Signals one object and waits on another object as a single operation.
DWORD SignalObjectAndWait( HANDLE hObjectToSignal, HANDLE hObjectToWaitOn, DWORD dwMilliseconds, BOOL bAlertable );
A handle to the object to be signaled. This object can be a semaphore, a mutex, or an event.
If the handle is a semaphore, the SEMAPHORE_MODIFY_STATE access right is required. If the handle is an event, the EVENT_MODIFY_STATE access right is required. If the handle is a mutex and the caller does not own the mutex, the function fails with ERROR_NOT_OWNER.
A handle to the object to wait on. The SYNCHRONIZE access right is required; for more information, see Synchronization Object Security and Access Rights. For a list of the object types whose handles you can specify, see the Remarks section.
The time-out interval, in milliseconds. The function returns if the interval elapses, even if the object's state is nonsignaled and no completion or asynchronous procedure call (APC) objects are queued. If dwMilliseconds is zero, the function tests the object's state, checks for queued completion routines or APCs, and returns immediately. If dwMilliseconds is INFINITE, the function's time-out interval never elapses.
If this parameter is TRUE, the function returns when the system queues an I/O completion routine or APC function, and the thread calls the function. If FALSE, the function does not return, and the thread does not call the completion routine or APC function.
A completion routine is queued when the function call that queued the APC has completed. This function returns and the completion routine is called only if bAlertable is TRUE, and the calling thread is the thread that queued the APC.
If the function succeeds, the return value indicates the event that caused the function to return. It can be one of the following values.
The specified object is a mutex object that was not released by the thread that owned the mutex object before the owning thread terminated. Ownership of the mutex object is granted to the calling thread, and the mutex is set to nonsignaled.
If the mutex was protecting persistent state information, you should check it for consistency.
||The wait was ended by one or more user-mode asynchronous procedure calls (APC) queued to the thread.|
||The state of the specified object is signaled.|
||The time-out interval elapsed, and the object's state is nonsignaled.|
||The function has failed. To get extended error information, call GetLastError.|
The SignalObjectAndWait function can wait for the following objects:
- Change notification
- Console input
- Memory resource notification
- Waitable timer
A thread can use the SignalObjectAndWait function to ensure that a worker thread is in a wait state before signaling an object. For example, a thread and a worker thread may use handles to event objects to synchronize their work. The thread executes code such as the following:
dwRet = WaitForSingleObject(hEventWorkerDone, INFINITE); if( WAIT_OBJECT_0 == dwRet) SetEvent(hEventMoreWorkToDo);
The worker thread executes code such as the following:
dwRet = SignalObjectAndWait(hEventWorkerDone, hEventMoreWorkToDo, INFINITE, FALSE);
Note that the "signal" and "wait" are not guaranteed to be performed as an atomic operation. Threads executing on other processors can observe the signaled state of the first object before the thread calling SignalObjectAndWait begins its wait on the second object.
Use extreme caution when using SignalObjectAndWait and PulseEvent with Windows 7, since using these APIs among multiple threads can cause an application to deadlock. Threads that are signaled by SignalObjectAndWait call PulseEvent to signal the waiting object of the SignalObjectAndWait call. In some circumstances, the caller of SignalObjectAndWait can't receive signal state of the waiting object in time, causing a deadlock.
Use caution when using the wait functions and code that directly or indirectly creates windows. If a thread creates any windows, it must process messages. Message broadcasts are sent to all windows in the system. A thread that uses a wait function with no time-out interval may cause the system to become deadlocked. Two examples of code that indirectly creates windows are DDE and COM CoInitialize. Therefore, if you have a thread that creates windows, be sure to call SignalObjectAndWait from a different thread. If this is not possible, you can use MsgWaitForMultipleObjects or MsgWaitForMultipleObjectsEx, but the functionality is not equivalent.
To compile an application that uses this function, define _WIN32_WINNT as 0x0400 or later. For more information, see Using the Windows Headers.
|Minimum supported client||Windows XP [desktop apps | UWP apps]|
|Minimum supported server||Windows Server 2003 [desktop apps | UWP apps]|
|Header||synchapi.h (include Windows.h)|