[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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.