[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [win-pv-devel] [PATCH 3/6] Add named pipe server
> -----Original Message----- > From: win-pv-devel [mailto:win-pv-devel-bounces@xxxxxxxxxxxxxxxxxxxx] On > Behalf Of owen.smith@xxxxxxxxxx > Sent: 24 July 2017 14:35 > To: win-pv-devel@xxxxxxxxxxxxxxxxxxxx > Cc: Owen Smith <owen.smith@xxxxxxxxxx> > Subject: [win-pv-devel] [PATCH 3/6] Add named pipe server > > From: Owen Smith <owen.smith@xxxxxxxxxx> > > Create a threaded NamedPipe server for the device. > This will be used to pass data from the console to child processes, and > read data from the child processes to pass to the console device. > > Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx> Reviewed-by: Paul Durrant <paul.durrant@xxxxxxxxxx> > --- > src/monitor/monitor.c | 320 > ++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 320 insertions(+) > > diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c > index df94934..e3979b8 100644 > --- a/src/monitor/monitor.c > +++ b/src/monitor/monitor.c > @@ -50,6 +50,13 @@ > #define MONITOR_NAME __MODULE__ > #define MONITOR_DISPLAYNAME MONITOR_NAME > > +typedef struct _MONITOR_PIPE { > + HANDLE Pipe; > + HANDLE Event; > + HANDLE Thread; > + LIST_ENTRY ListEntry; > +} MONITOR_PIPE, *PMONITOR_PIPE; > + > typedef struct _MONITOR_CONTEXT { > SERVICE_STATUS Status; > SERVICE_STATUS_HANDLE Service; > @@ -67,10 +74,17 @@ typedef struct _MONITOR_CONTEXT { > HANDLE MonitorThread; > HANDLE DeviceEvent; > HANDLE DeviceThread; > + HANDLE ServerEvent; > + HANDLE ServerThread; > + CRITICAL_SECTION CriticalSection; > + LIST_ENTRY ListHead; > + DWORD ListCount; > } MONITOR_CONTEXT, *PMONITOR_CONTEXT; > > MONITOR_CONTEXT MonitorContext; > > +#define PIPE_NAME TEXT("\\\\.\\pipe\\xencons") > + > #define MAXIMUM_BUFFER_SIZE 1024 > > #define SERVICES_KEY "SYSTEM\\CurrentControlSet\\Services" > @@ -347,6 +361,219 @@ fail1: > return FALSE; > } > > +static FORCEINLINE VOID > +InitializeListHead( > + IN PLIST_ENTRY ListEntry > + ) > +{ > + ListEntry->Flink = ListEntry; > + ListEntry->Blink = ListEntry; > +} > + > +static FORCEINLINE VOID > +InsertTailList( > + IN PLIST_ENTRY ListHead, > + IN PLIST_ENTRY ListEntry > + ) > +{ > + ListEntry->Blink = ListHead->Blink; > + ListEntry->Flink = ListHead; > + ListHead->Blink->Flink = ListEntry; > + ListHead->Blink = ListEntry; > +} > + > +static FORCEINLINE VOID > +RemoveEntryList( > + IN PLIST_ENTRY ListEntry > + ) > +{ > + PLIST_ENTRY Flink; > + PLIST_ENTRY Blink; > + > + Flink = ListEntry->Flink; > + Blink = ListEntry->Blink; > + Flink->Blink = Blink; > + Blink->Flink = Flink; > + > + ListEntry->Flink = ListEntry; > + ListEntry->Blink = ListEntry; > +} > + > +DWORD WINAPI > +PipeThread( > + IN LPVOID Argument > + ) > +{ > + PMONITOR_CONTEXT Context = &MonitorContext; > + PMONITOR_PIPE Pipe = (PMONITOR_PIPE)Argument; > + UCHAR Buffer[MAXIMUM_BUFFER_SIZE]; > + OVERLAPPED Overlapped; > + HANDLE Handle[2]; > + DWORD Length; > + DWORD Object; > + HRESULT Error; > + > + Log("====>"); > + > + memset(&Overlapped, 0, sizeof(OVERLAPPED)); > + Overlapped.hEvent = CreateEvent(NULL, > + TRUE, > + FALSE, > + NULL); > + if (Overlapped.hEvent == NULL) > + goto fail1; > + > + Handle[0] = Pipe->Event; > + Handle[1] = Overlapped.hEvent; > + > + EnterCriticalSection(&Context->CriticalSection); > + InsertTailList(&Context->ListHead, &Pipe->ListEntry); > + ++Context->ListCount; > + LeaveCriticalSection(&Context->CriticalSection); > + > + for (;;) { > + (VOID) ReadFile(Pipe->Pipe, > + Buffer, > + sizeof(Buffer), > + NULL, > + &Overlapped); > + > + Object = WaitForMultipleObjects(ARRAYSIZE(Handle), > + Handle, > + FALSE, > + INFINITE); > + if (Object == WAIT_OBJECT_0) > + break; > + > + if (!GetOverlappedResult(Pipe->Pipe, > + &Overlapped, > + &Length, > + FALSE)) > + break; > + > + ResetEvent(Overlapped.hEvent); > + > + // Length bytes of Buffer have been read > + } > + > + EnterCriticalSection(&Context->CriticalSection); > + RemoveEntryList(&Pipe->ListEntry); > + --Context->ListCount; > + LeaveCriticalSection(&Context->CriticalSection); > + > + CloseHandle(Overlapped.hEvent); > + > + Log("<===="); > + > + return 0; > + > +fail1: > + Error = GetLastError(); > + > + { > + PTCHAR Message; > + Message = GetErrorMessage(Error); > + Log("fail1 (%s)", Message); > + LocalFree(Message); > + } > + > + return 1; > +} > + > +DWORD WINAPI > +ServerThread( > + IN LPVOID Argument > + ) > +{ > + PMONITOR_CONTEXT Context = &MonitorContext; > + OVERLAPPED Overlapped; > + HANDLE Handle[2]; > + DWORD Object; > + HRESULT Error; > + > + UNREFERENCED_PARAMETER(Argument); > + > + Log("====>"); > + > + memset(&Overlapped, 0, sizeof(OVERLAPPED)); > + Overlapped.hEvent = CreateEvent(NULL, > + TRUE, > + FALSE, > + NULL); > + if (Overlapped.hEvent == NULL) > + goto fail1; > + > + Handle[0] = Context->ServerEvent; > + Handle[1] = Overlapped.hEvent; > + > + for (;;) { > + HANDLE Pipe; > + PMONITOR_PIPE Instance; > + > + Pipe = CreateNamedPipe(PIPE_NAME, > + PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, > + PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, > + PIPE_UNLIMITED_INSTANCES, > + MAXIMUM_BUFFER_SIZE, > + MAXIMUM_BUFFER_SIZE, > + 0, > + NULL); > + if (Pipe == INVALID_HANDLE_VALUE) > + break; > + > + (VOID) ConnectNamedPipe(Pipe, > + &Overlapped); > + > + Object = WaitForMultipleObjects(ARRAYSIZE(Handle), > + Handle, > + FALSE, > + INFINITE); > + if (Object == WAIT_OBJECT_0) > + break; > + > + ResetEvent(Overlapped.hEvent); > + > + Instance = (PMONITOR_PIPE)malloc(sizeof(MONITOR_PIPE)); > + if (Instance == NULL) { > + CloseHandle(Pipe); > + break; > + } > + > + InitializeListHead(&Instance->ListEntry); > + Instance->Pipe = Pipe; > + Instance->Event = Context->ServerEvent; > + Instance->Thread = CreateThread(NULL, > + 0, > + PipeThread, > + Instance, > + 0, > + NULL); > + if (Instance->Thread == INVALID_HANDLE_VALUE) { > + free(Instance); > + CloseHandle(Pipe); > + break; > + } > + } > + > + CloseHandle(Overlapped.hEvent); > + > + Log("<===="); > + > + return 0; > + > +fail1: > + Error = GetLastError(); > + > + { > + PTCHAR Message; > + Message = GetErrorMessage(Error); > + Log("fail1 (%s)", Message); > + LocalFree(Message); > + } > + > + return 1; > +} > + > DWORD WINAPI > MonitorThread( > IN LPVOID Argument > @@ -624,6 +851,8 @@ MonitorAdd( > goto fail3; > > Context->DevicePath = Path; > + InitializeListHead(&Context->ListHead); > + InitializeCriticalSection(&Context->CriticalSection); > > Context->MonitorEvent = CreateEvent(NULL, > TRUE, > @@ -661,10 +890,38 @@ MonitorAdd( > if (Context->DeviceThread == INVALID_HANDLE_VALUE) > goto fail7; > > + Context->ServerEvent = CreateEvent(NULL, > + TRUE, > + FALSE, > + NULL); > + if (Context->ServerEvent == NULL) > + goto fail8; > + > + Context->ServerThread = CreateThread(NULL, > + 0, > + ServerThread, > + NULL, > + 0, > + NULL); > + if (Context->ServerThread == INVALID_HANDLE_VALUE) > + goto fail9; > + > Log("<===="); > > return; > > +fail9: > + Log("fail9"); > + > + CloseHandle(Context->ServerEvent); > + Context->ServerEvent = NULL; > + > +fail8: > + Log("fail8"); > + > + SetEvent(Context->DeviceEvent); > + WaitForSingleObject(Context->DeviceThread, INFINITE); > + > fail7: > Log("fail7\n"); > > @@ -686,6 +943,9 @@ fail5: > fail4: > Log("fail4"); > > + DeleteCriticalSection(&Context->CriticalSection); > + memset(&Context->ListHead, 0, sizeof(LIST_ENTRY)); > + > free(Context->DevicePath); > Context->DevicePath = NULL; > > @@ -715,6 +975,56 @@ fail1: > } > > static VOID > +MonitorWaitForPipeThreads( > + VOID > + ) > +{ > + PMONITOR_CONTEXT Context = &MonitorContext; > + HANDLE *Handles; > + DWORD Index; > + PLIST_ENTRY ListEntry; > + > + EnterCriticalSection(&Context->CriticalSection); > + > + if (Context->ListCount == 0) > + goto fail1; > + > + Handles = (HANDLE*)malloc(sizeof(HANDLE) * Context->ListCount); > + if (Handles == NULL) > + goto fail2; > + > + Index = 0; > + for (ListEntry = Context->ListHead.Flink; > + ListEntry != &Context->ListHead && Index < Context->ListCount; > + ListEntry = ListEntry->Flink) { > + PMONITOR_PIPE Pipe = CONTAINING_RECORD(ListEntry, > MONITOR_PIPE, ListEntry); > + Handles[Index++] = Pipe->Thread; > + } > + > + Context->ListCount = 0; > + > + LeaveCriticalSection(&Context->CriticalSection); > + > +#pragma warning(suppress:6385) // Reading invalid data from 'Handles'... > + WaitForMultipleObjects(Index, > + Handles, > + TRUE, > + INFINITE); > + free(Handles); > + return; > + > +fail2: > + Log("fail2"); > + > +fail1: > + Log("fail1"); > + > + LeaveCriticalSection(&Context->CriticalSection); > + > + return; > +} > + > +static VOID > MonitorRemove( > VOID > ) > @@ -726,6 +1036,13 @@ MonitorRemove( > > Log("====>"); > > + SetEvent(Context->ServerEvent); > + MonitorWaitForPipeThreads(); > + WaitForSingleObject(Context->ServerThread, INFINITE); > + > + CloseHandle(Context->ServerEvent); > + Context->ServerEvent = NULL; > + > SetEvent(Context->DeviceEvent); > WaitForSingleObject(Context->DeviceThread, INFINITE); > > @@ -738,6 +1055,9 @@ MonitorRemove( > CloseHandle(Context->MonitorEvent); > Context->MonitorEvent = NULL; > > + DeleteCriticalSection(&Context->CriticalSection); > + memset(&Context->ListHead, 0, sizeof(LIST_ENTRY)); > + > free(Context->DevicePath); > Context->DevicePath = NULL; > > -- > 2.8.3 > > > _______________________________________________ > win-pv-devel mailing list > win-pv-devel@xxxxxxxxxxxxxxxxxxxx > https://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel _______________________________________________ win-pv-devel mailing list win-pv-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |