[wing/wip/createpipe] namedpipeclient: fix race when waiting for the named pipe



commit 84842d91e5964d45df6777013308b509154998d4
Author: Ignacio Casal Quinteiro <ignacio casal nice-software com>
Date:   Mon Sep 19 13:24:50 2016 +0200

    namedpipeclient: fix race when waiting for the named pipe
    
    In the time that we get that the pipe is ready when calling
    WaitnamedPipe and the time that we call CreateFile another
    named pipe pipe could have been connected and it will fail
    with ERROR_PIPE_BUSY, in this case we should retry to wait again.
    
    See: https://msdn.microsoft.com/es-es/library/windows/desktop/aa365592(v=vs.85).aspx

 wing/wingnamedpipeclient.c |   36 ++++++++++++++++--------------------
 1 files changed, 16 insertions(+), 20 deletions(-)
---
diff --git a/wing/wingnamedpipeclient.c b/wing/wingnamedpipeclient.c
index 1f17574..93f9afb 100644
--- a/wing/wingnamedpipeclient.c
+++ b/wing/wingnamedpipeclient.c
@@ -182,8 +182,11 @@ wing_named_pipe_client_connect (WingNamedPipeClient  *client,
 
   pipe_namew = g_utf8_to_utf16 (pipe_name, -1, NULL, NULL, NULL);
 
-  if (WaitNamedPipeW (pipe_namew, priv->timeout))
+  while (TRUE)
     {
+      if (g_cancellable_set_error_if_cancelled (cancellable, error))
+        break;
+
       handle = CreateFileW (pipe_namew,
                             GENERIC_READ | GENERIC_WRITE,
                             FILE_SHARE_READ | FILE_SHARE_WRITE,
@@ -198,35 +201,28 @@ wing_named_pipe_client_connect (WingNamedPipeClient  *client,
           gchar *err;
 
           errsv = GetLastError ();
+
+          if (errsv == ERROR_PIPE_BUSY)
+            if (!WaitNamedPipeW (pipe_namew, priv->timeout))
+              errsv = GetLastError ();
+            else
+              continue;
+
           err = g_win32_error_message (errsv);
-          g_set_error_literal (error, G_IO_ERROR,
-                               g_io_error_from_win32_error (errsv),
-                               err);
+          g_set_error (error, G_IO_ERROR,
+                       g_io_error_from_win32_error (errsv),
+                       "Could not create file for named pipe '%s': %s",
+                       pipe_name, err);
           g_free (err);
-          goto end;
+          break;
         }
 
-      if (g_cancellable_set_error_if_cancelled (cancellable, error))
-          goto end;
-
       connection = g_object_new (WING_TYPE_NAMED_PIPE_CONNECTION,
                                  "pipe-name", pipe_name,
                                  "handle", handle,
                                  "close-handle", TRUE,
                                  NULL);
     }
-  else
-    {
-      int errsv;
-      gchar *err;
-
-      errsv = GetLastError ();
-      err = g_win32_error_message (errsv);
-      g_set_error_literal (error, G_IO_ERROR,
-                           g_io_error_from_win32_error (errsv),
-                           err);
-      g_free (err);
-    }
 
 end:
   g_free (pipe_namew);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]