mirror of
https://github.com/reactos/reactos.git
synced 2025-02-25 01:39:30 +00:00
Added waiting on console handles. We use a thread to poll for input
availability. svn path=/trunk/; revision=8568
This commit is contained in:
parent
796f34f5ff
commit
ce4344ab2c
1 changed files with 72 additions and 11 deletions
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: wait.c,v 1.27 2004/01/23 21:16:04 ekohl Exp $
|
/* $Id: wait.c,v 1.28 2004/03/07 18:06:29 arty Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS system libraries
|
* PROJECT: ReactOS system libraries
|
||||||
|
@ -19,6 +19,39 @@
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Thread that waits for a console handle. Console handles only fire when
|
||||||
|
* they're readable.
|
||||||
|
*/
|
||||||
|
|
||||||
|
DWORD STDCALL WaitForConsoleHandleThread( PVOID ConHandle ) {
|
||||||
|
DWORD AmtRead = 0;
|
||||||
|
INPUT_RECORD Buffer[1];
|
||||||
|
do {
|
||||||
|
PeekConsoleInputA( ConHandle, Buffer, 1, &AmtRead );
|
||||||
|
if( !AmtRead ) Sleep( 100 );
|
||||||
|
} while( AmtRead == 0 );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return a waitable object given a console handle
|
||||||
|
*/
|
||||||
|
DWORD GetWaiterForConsoleHandle( HANDLE ConHandle, PHANDLE Waitable ) {
|
||||||
|
DWORD ThreadId;
|
||||||
|
HANDLE WaitableHandle = CreateThread( 0,
|
||||||
|
0,
|
||||||
|
WaitForConsoleHandleThread,
|
||||||
|
ConHandle,
|
||||||
|
0,
|
||||||
|
&ThreadId );
|
||||||
|
|
||||||
|
*Waitable = WaitableHandle;
|
||||||
|
|
||||||
|
return WaitableHandle ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
|
@ -43,6 +76,7 @@ WaitForSingleObjectEx(HANDLE hHandle,
|
||||||
PLARGE_INTEGER TimePtr;
|
PLARGE_INTEGER TimePtr;
|
||||||
LARGE_INTEGER Time;
|
LARGE_INTEGER Time;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
BOOL CloseWaitHandle = FALSE;
|
||||||
|
|
||||||
/* Get real handle */
|
/* Get real handle */
|
||||||
switch ((ULONG)hHandle)
|
switch ((ULONG)hHandle)
|
||||||
|
@ -65,9 +99,12 @@ WaitForSingleObjectEx(HANDLE hHandle,
|
||||||
{
|
{
|
||||||
if (VerifyConsoleIoHandle(hHandle))
|
if (VerifyConsoleIoHandle(hHandle))
|
||||||
{
|
{
|
||||||
DPRINT1("Console handles are not supported yet!\n");
|
Status = GetWaiterForConsoleHandle( hHandle, &hHandle );
|
||||||
SetLastError(ERROR_INVALID_HANDLE);
|
if (!NT_SUCCESS(Status))
|
||||||
return WAIT_FAILED;
|
{
|
||||||
|
SetLastErrorByStatus (Status);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,6 +121,10 @@ WaitForSingleObjectEx(HANDLE hHandle,
|
||||||
Status = NtWaitForSingleObject(hHandle,
|
Status = NtWaitForSingleObject(hHandle,
|
||||||
(BOOLEAN) bAlertable,
|
(BOOLEAN) bAlertable,
|
||||||
TimePtr);
|
TimePtr);
|
||||||
|
|
||||||
|
if (CloseWaitHandle)
|
||||||
|
NtClose(hHandle);
|
||||||
|
|
||||||
if (Status == STATUS_TIMEOUT)
|
if (Status == STATUS_TIMEOUT)
|
||||||
{
|
{
|
||||||
return WAIT_TIMEOUT;
|
return WAIT_TIMEOUT;
|
||||||
|
@ -130,12 +171,15 @@ WaitForMultipleObjectsEx(DWORD nCount,
|
||||||
PLARGE_INTEGER TimePtr;
|
PLARGE_INTEGER TimePtr;
|
||||||
LARGE_INTEGER Time;
|
LARGE_INTEGER Time;
|
||||||
PHANDLE HandleBuffer;
|
PHANDLE HandleBuffer;
|
||||||
DWORD i;
|
DWORD i,j;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
PBOOL FreeThisHandle;
|
||||||
|
|
||||||
DPRINT("nCount %lu\n", nCount);
|
DPRINT("nCount %lu\n", nCount);
|
||||||
|
|
||||||
HandleBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, nCount * sizeof(HANDLE));
|
HandleBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, nCount * (sizeof(HANDLE) + sizeof(BOOL)) );
|
||||||
|
FreeThisHandle = (PBOOL)(&HandleBuffer[nCount]);
|
||||||
|
|
||||||
if (HandleBuffer == NULL)
|
if (HandleBuffer == NULL)
|
||||||
{
|
{
|
||||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
@ -144,6 +188,7 @@ WaitForMultipleObjectsEx(DWORD nCount,
|
||||||
|
|
||||||
for (i = 0; i < nCount; i++)
|
for (i = 0; i < nCount; i++)
|
||||||
{
|
{
|
||||||
|
FreeThisHandle[i] = FALSE;
|
||||||
switch ((DWORD)lpHandles[i])
|
switch ((DWORD)lpHandles[i])
|
||||||
{
|
{
|
||||||
case STD_INPUT_HANDLE:
|
case STD_INPUT_HANDLE:
|
||||||
|
@ -168,11 +213,23 @@ WaitForMultipleObjectsEx(DWORD nCount,
|
||||||
{
|
{
|
||||||
if (VerifyConsoleIoHandle(HandleBuffer[i]))
|
if (VerifyConsoleIoHandle(HandleBuffer[i]))
|
||||||
{
|
{
|
||||||
DPRINT1("Console handles are not supported yet!\n");
|
Status = GetWaiterForConsoleHandle( HandleBuffer[i],
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, HandleBuffer);
|
&HandleBuffer[i] );
|
||||||
SetLastError(ERROR_INVALID_HANDLE);
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* We'll leak some handles unless we close the already
|
||||||
|
created handles */
|
||||||
|
for (j = 0; j < i; j++)
|
||||||
|
if (FreeThisHandle[j])
|
||||||
|
NtClose(HandleBuffer[j]);
|
||||||
|
|
||||||
|
SetLastErrorByStatus (Status);
|
||||||
|
RtlFreeHeap(GetProcessHeap(),0,HandleBuffer);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FreeThisHandle[i] = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,6 +249,10 @@ WaitForMultipleObjectsEx(DWORD nCount,
|
||||||
(BOOLEAN)bAlertable,
|
(BOOLEAN)bAlertable,
|
||||||
TimePtr);
|
TimePtr);
|
||||||
|
|
||||||
|
for (i = 0; i < nCount; i++)
|
||||||
|
if (FreeThisHandle[i])
|
||||||
|
NtClose(HandleBuffer[i]);
|
||||||
|
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, HandleBuffer);
|
RtlFreeHeap(RtlGetProcessHeap(), 0, HandleBuffer);
|
||||||
|
|
||||||
if (Status == STATUS_TIMEOUT)
|
if (Status == STATUS_TIMEOUT)
|
||||||
|
|
Loading…
Reference in a new issue