From: Owen Smith Date: Tue, 25 Jul 2017 12:26:27 +0000 (+0100) Subject: Add asynchronous device polling thread X-Git-Tag: 9.0.0-rc1~44 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=edf75e2262e3737fe18e03fcef25c6eed7ed827b;p=pvdrivers%2Fwin%2Fxencons.git Add asynchronous device polling thread Adds a thread that will asynchrously read the device handle. This will be used to read console data from the device, for passing to the named pipe. Signed-off-by: Owen Smith s/memset/ZeroMemory Signed-off-by: Paul Durrant --- diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c index a2a3cc1..b974fe4 100644 --- a/src/monitor/monitor.c +++ b/src/monitor/monitor.c @@ -65,6 +65,8 @@ typedef struct _MONITOR_CONTEXT { HANDLE Device; HANDLE MonitorEvent; HANDLE MonitorThread; + HANDLE DeviceEvent; + HANDLE DeviceThread; } MONITOR_CONTEXT, *PMONITOR_CONTEXT; MONITOR_CONTEXT MonitorContext; @@ -456,6 +458,96 @@ fail1: return 1; } +DWORD WINAPI +DeviceThread( + IN LPVOID Argument + ) +{ + PMONITOR_CONTEXT Context = &MonitorContext; + OVERLAPPED Overlapped; + HANDLE Device; + UCHAR Buffer[MAXIMUM_BUFFER_SIZE]; + DWORD Length; + DWORD Wait; + HANDLE Handles[2]; + DWORD Error; + + UNREFERENCED_PARAMETER(Argument); + + Log("====>"); + + ZeroMemory(&Overlapped, sizeof(OVERLAPPED)); + Overlapped.hEvent = CreateEvent(NULL, + TRUE, + FALSE, + NULL); + if (Overlapped.hEvent == NULL) + goto fail1; + + Handles[0] = Context->DeviceEvent; + Handles[1] = Overlapped.hEvent; + + Device = CreateFile(Context->DevicePath, + GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, + NULL); + if (Device == INVALID_HANDLE_VALUE) + goto fail2; + + for (;;) { + (VOID) ReadFile(Device, + Buffer, + sizeof(Buffer), + NULL, + &Overlapped); + + Wait = WaitForMultipleObjects(ARRAYSIZE(Handles), + Handles, + FALSE, + INFINITE); + if (Wait == WAIT_OBJECT_0) + break; + + if (!GetOverlappedResult(Device, + &Overlapped, + &Length, + FALSE)) + break; + + ResetEvent(Overlapped.hEvent); + + // Length bytes of Buffer have been read + } + + CloseHandle(Device); + + CloseHandle(Overlapped.hEvent); + + Log("<===="); + + return 0; + +fail2: + Log("fail2\n"); + + CloseHandle(Overlapped.hEvent); + +fail1: + Error = GetLastError(); + + { + PTCHAR Message; + Message = GetErrorMessage(Error); + Log("fail1 (%s)", Message); + LocalFree(Message); + } + + return 1; +} + static VOID PutString( IN HANDLE Handle, @@ -551,10 +643,40 @@ MonitorAdd( if (Context->MonitorThread == INVALID_HANDLE_VALUE) goto fail5; + Context->DeviceEvent = CreateEvent(NULL, + TRUE, + FALSE, + NULL); + + if (Context->DeviceEvent == NULL) + goto fail6; + + Context->DeviceThread = CreateThread(NULL, + 0, + DeviceThread, + NULL, + 0, + NULL); + + if (Context->DeviceThread == INVALID_HANDLE_VALUE) + goto fail7; + Log("<===="); return; +fail7: + Log("fail7\n"); + + CloseHandle(Context->DeviceEvent); + Context->DeviceEvent = NULL; + +fail6: + Log("fail6\n"); + + SetEvent(Context->MonitorThread); + WaitForSingleObject(Context->MonitorThread, INFINITE); + fail5: Log("fail5"); @@ -604,6 +726,12 @@ MonitorRemove( Log("====>"); + SetEvent(Context->DeviceEvent); + WaitForSingleObject(Context->DeviceThread, INFINITE); + + CloseHandle(Context->DeviceEvent); + Context->DeviceEvent = NULL; + SetEvent(Context->MonitorEvent); WaitForSingleObject(Context->MonitorThread, INFINITE);