mirror of
https://github.com/reactos/reactos.git
synced 2025-01-11 16:51:06 +00:00
c424146e2c
svn path=/branches/cmake-bringup/; revision=48236
254 lines
6.6 KiB
C
254 lines
6.6 KiB
C
/*
|
|
* PROJECT: ReactOS Win32 Base API
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
|
* FILE: dll/win32/kernel32/synch/wait.c
|
|
* PURPOSE: Wrappers for the NT Wait Implementation
|
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
|
*/
|
|
|
|
/* INCLUDES *****************************************************************/
|
|
|
|
#include <k32.h>
|
|
|
|
#define NDEBUG
|
|
#include <debug.h>
|
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
DWORD
|
|
WINAPI
|
|
WaitForSingleObject(IN HANDLE hHandle,
|
|
IN DWORD dwMilliseconds)
|
|
{
|
|
/* Call the extended API */
|
|
return WaitForSingleObjectEx(hHandle, dwMilliseconds, FALSE);
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
DWORD
|
|
WINAPI
|
|
WaitForSingleObjectEx(IN HANDLE hHandle,
|
|
IN DWORD dwMilliseconds,
|
|
IN BOOL bAlertable)
|
|
{
|
|
PLARGE_INTEGER TimePtr;
|
|
LARGE_INTEGER Time;
|
|
NTSTATUS Status;
|
|
|
|
/* Get real handle */
|
|
hHandle = TranslateStdHandle(hHandle);
|
|
|
|
/* Check for console handle */
|
|
if ((IsConsoleHandle(hHandle)) && (VerifyConsoleIoHandle(hHandle)))
|
|
{
|
|
/* Get the real wait handle */
|
|
hHandle = GetConsoleInputWaitHandle();
|
|
}
|
|
|
|
/* Check if this is an infinite wait */
|
|
if (dwMilliseconds == INFINITE)
|
|
{
|
|
/* Under NT, this means no timer argument */
|
|
TimePtr = NULL;
|
|
}
|
|
else
|
|
{
|
|
/* Otherwise, convert the time to NT Format */
|
|
Time.QuadPart = UInt32x32To64(-10000, dwMilliseconds);
|
|
TimePtr = &Time;
|
|
}
|
|
|
|
/* Start wait loop */
|
|
do
|
|
{
|
|
/* Do the wait */
|
|
Status = NtWaitForSingleObject(hHandle, (BOOLEAN)bAlertable, TimePtr);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
/* The wait failed */
|
|
SetLastErrorByStatus (Status);
|
|
return WAIT_FAILED;
|
|
}
|
|
} while ((Status == STATUS_ALERTED) && (bAlertable));
|
|
|
|
/* Return wait status */
|
|
return Status;
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
DWORD
|
|
WINAPI
|
|
WaitForMultipleObjects(IN DWORD nCount,
|
|
IN CONST HANDLE *lpHandles,
|
|
IN BOOL bWaitAll,
|
|
IN DWORD dwMilliseconds)
|
|
{
|
|
/* Call the extended API */
|
|
return WaitForMultipleObjectsEx(nCount,
|
|
lpHandles,
|
|
bWaitAll,
|
|
dwMilliseconds,
|
|
FALSE);
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
DWORD
|
|
WINAPI
|
|
WaitForMultipleObjectsEx(IN DWORD nCount,
|
|
IN CONST HANDLE *lpHandles,
|
|
IN BOOL bWaitAll,
|
|
IN DWORD dwMilliseconds,
|
|
IN BOOL bAlertable)
|
|
{
|
|
PLARGE_INTEGER TimePtr;
|
|
LARGE_INTEGER Time;
|
|
PHANDLE HandleBuffer;
|
|
HANDLE Handle[8];
|
|
DWORD i;
|
|
NTSTATUS Status;
|
|
|
|
/* Check if we have more handles then we locally optimize */
|
|
if (nCount > 8)
|
|
{
|
|
/* Allocate a buffer for them */
|
|
HandleBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
|
|
0,
|
|
nCount * sizeof(HANDLE));
|
|
if (!HandleBuffer)
|
|
{
|
|
/* No buffer, fail the wait */
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
return WAIT_FAILED;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Otherwise, use our local buffer */
|
|
HandleBuffer = Handle;
|
|
}
|
|
|
|
/* Copy the handles into our buffer and loop them all */
|
|
RtlCopyMemory(HandleBuffer, (LPVOID)lpHandles, nCount * sizeof(HANDLE));
|
|
for (i = 0; i < nCount; i++)
|
|
{
|
|
/* Check what kind of handle this is */
|
|
HandleBuffer[i] = TranslateStdHandle(HandleBuffer[i]);
|
|
|
|
/* Check for console handle */
|
|
if ((IsConsoleHandle(HandleBuffer[i])) &&
|
|
(VerifyConsoleIoHandle(HandleBuffer[i])))
|
|
{
|
|
/* Get the real wait handle */
|
|
HandleBuffer[i] = GetConsoleInputWaitHandle();
|
|
}
|
|
}
|
|
|
|
/* Check if this is an infinite wait */
|
|
if (dwMilliseconds == INFINITE)
|
|
{
|
|
/* Under NT, this means no timer argument */
|
|
TimePtr = NULL;
|
|
}
|
|
else
|
|
{
|
|
/* Otherwise, convert the time to NT Format */
|
|
Time.QuadPart = UInt32x32To64(-10000, dwMilliseconds);
|
|
TimePtr = &Time;
|
|
}
|
|
|
|
/* Start wait loop */
|
|
do
|
|
{
|
|
/* Do the wait */
|
|
Status = NtWaitForMultipleObjects(nCount,
|
|
HandleBuffer,
|
|
bWaitAll ? WaitAll : WaitAny,
|
|
(BOOLEAN)bAlertable,
|
|
TimePtr);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
/* Wait failed */
|
|
SetLastErrorByStatus (Status);
|
|
return WAIT_FAILED;
|
|
}
|
|
} while ((Status == STATUS_ALERTED) && (bAlertable));
|
|
|
|
/* Check if we didn't use our local buffer */
|
|
if (HandleBuffer != Handle)
|
|
{
|
|
/* Free the allocated one */
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, HandleBuffer);
|
|
}
|
|
|
|
/* Return wait status */
|
|
return Status;
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
DWORD
|
|
WINAPI
|
|
SignalObjectAndWait(IN HANDLE hObjectToSignal,
|
|
IN HANDLE hObjectToWaitOn,
|
|
IN DWORD dwMilliseconds,
|
|
IN BOOL bAlertable)
|
|
{
|
|
PLARGE_INTEGER TimePtr;
|
|
LARGE_INTEGER Time;
|
|
NTSTATUS Status;
|
|
|
|
/* Get real handle */
|
|
hObjectToWaitOn = TranslateStdHandle(hObjectToWaitOn);
|
|
|
|
/* Check for console handle */
|
|
if ((IsConsoleHandle(hObjectToWaitOn)) &&
|
|
(VerifyConsoleIoHandle(hObjectToWaitOn)))
|
|
{
|
|
/* Get the real wait handle */
|
|
hObjectToWaitOn = GetConsoleInputWaitHandle();
|
|
}
|
|
|
|
/* Check if this is an infinite wait */
|
|
if (dwMilliseconds == INFINITE)
|
|
{
|
|
/* Under NT, this means no timer argument */
|
|
TimePtr = NULL;
|
|
}
|
|
else
|
|
{
|
|
/* Otherwise, convert the time to NT Format */
|
|
Time.QuadPart = UInt32x32To64(-10000, dwMilliseconds);
|
|
TimePtr = &Time;
|
|
}
|
|
|
|
/* Start wait loop */
|
|
do
|
|
{
|
|
/* Do the wait */
|
|
Status = NtSignalAndWaitForSingleObject(hObjectToSignal,
|
|
hObjectToWaitOn,
|
|
(BOOLEAN)bAlertable,
|
|
TimePtr);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
/* The wait failed */
|
|
SetLastErrorByStatus (Status);
|
|
return WAIT_FAILED;
|
|
}
|
|
} while ((Status == STATUS_ALERTED) && (bAlertable));
|
|
|
|
/* Return wait status */
|
|
return Status;
|
|
}
|
|
|
|
/* EOF */
|