reactos/dll/win32/kernel32/synch/wait.c
Amine Khaldi c424146e2c Create a branch for cmake bringup.
svn path=/branches/cmake-bringup/; revision=48236
2010-07-24 18:52:44 +00:00

255 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 */