[newlib-cygwin] Cygwin: AF_UNIX: fix creation of npfs handle

Corinna Vinschen corinna@sourceware.org
Wed Mar 7 15:24:00 GMT 2018


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=2f2a75b7bbf521057f3e8e502f1a6641a2baf376

commit 2f2a75b7bbf521057f3e8e502f1a6641a2baf376
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Wed Mar 7 15:48:21 2018 +0100

    Cygwin: AF_UNIX: fix creation of npfs handle
    
    The handle to the device is never needed.  As the name impies,
    FSCTL_PIPE_WAIT works on the file system, not on the device level.
    
    Drop opening the device and make sure to open only one handle to NPFS.
    
    Signed-off-by: Corinna Vinschen <corinna@vinschen.de>

Diff:
---
 winsup/cygwin/fhandler.h              |  8 +-------
 winsup/cygwin/fhandler_socket_unix.cc | 37 ++++++++++++++++++++---------------
 winsup/cygwin/globals.cc              |  3 +--
 3 files changed, 23 insertions(+), 25 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 392ba6c..4166126 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -852,12 +852,6 @@ class sun_name_t
 
 class fhandler_socket_unix : public fhandler_socket
 {
-   enum npfs_hdl_t
-   {
-     NPFS_DEVICE,
-     NPFS_DIR
-   };
-
  protected:
   SRWLOCK conn_lock;
   SRWLOCK bind_lock;
@@ -886,7 +880,7 @@ class fhandler_socket_unix : public fhandler_socket
   void set_pipe_non_blocking (bool nonblocking);
   int send_my_name ();
   int recv_peer_name ();
-  static NTSTATUS npfs_handle (HANDLE &nph, npfs_hdl_t type);
+  static NTSTATUS npfs_handle (HANDLE &nph);
   HANDLE create_pipe ();
   HANDLE create_pipe_instance ();
   NTSTATUS open_pipe (HANDLE &ph, PUNICODE_STRING pipe_name);
diff --git a/winsup/cygwin/fhandler_socket_unix.cc b/winsup/cygwin/fhandler_socket_unix.cc
index ea8aece..f320453 100644
--- a/winsup/cygwin/fhandler_socket_unix.cc
+++ b/winsup/cygwin/fhandler_socket_unix.cc
@@ -620,28 +620,33 @@ fhandler_socket_unix::recv_peer_name ()
 }
 
 NTSTATUS
-fhandler_socket_unix::npfs_handle (HANDLE &nph, npfs_hdl_t type)
+fhandler_socket_unix::npfs_handle (HANDLE &nph)
 {
-  static NO_COPY HANDLE npfs_devh;
+  static NO_COPY SRWLOCK npfs_lock;
   static NO_COPY HANDLE npfs_dirh;
 
-  HANDLE &npfs_ref = (type == NPFS_DEVICE) ? npfs_devh : npfs_dirh;
-  PUNICODE_STRING path = (type == NPFS_DEVICE) ? &ro_u_npfs : &ro_u_npfs_dir;
-  NTSTATUS status;
+  NTSTATUS status = STATUS_SUCCESS;
   OBJECT_ATTRIBUTES attr;
   IO_STATUS_BLOCK io;
 
-  if (!npfs_ref)
+  /* Lockless after first call. */
+  if (npfs_dirh)
+    {
+      nph = npfs_dirh;
+      return STATUS_SUCCESS;
+    }
+  AcquireSRWLockExclusive (&npfs_lock);
+  if (!npfs_dirh)
     {
-      InitializeObjectAttributes (&attr, path, 0, NULL, NULL);
-      status = NtOpenFile (&npfs_ref, FILE_READ_ATTRIBUTES | SYNCHRONIZE,
+      InitializeObjectAttributes (&attr, &ro_u_npfs, 0, NULL, NULL);
+      status = NtOpenFile (&npfs_dirh, FILE_READ_ATTRIBUTES | SYNCHRONIZE,
 			   &attr, &io, FILE_SHARE_READ | FILE_SHARE_WRITE,
 			   FILE_SYNCHRONOUS_IO_NONALERT);
-      if (!NT_SUCCESS (status))
-	return status;
     }
-  nph = npfs_ref;
-  return STATUS_SUCCESS;
+  ReleaseSRWLockExclusive (&npfs_lock);
+  if (NT_SUCCESS (status))
+    nph = npfs_dirh;
+  return status;
 }
 
 HANDLE
@@ -658,7 +663,7 @@ fhandler_socket_unix::create_pipe ()
   ULONG max_instances;
   LARGE_INTEGER timeout;
 
-  status = npfs_handle (npfsh, NPFS_DIR);
+  status = npfs_handle (npfsh);
   if (!NT_SUCCESS (status))
     {
       __seterrno_from_nt_status (status);
@@ -700,7 +705,7 @@ fhandler_socket_unix::create_pipe_instance ()
   ULONG max_instances;
   LARGE_INTEGER timeout;
 
-  status = npfs_handle (npfsh, NPFS_DIR);
+  status = npfs_handle (npfsh);
   if (!NT_SUCCESS (status))
     {
       __seterrno_from_nt_status (status);
@@ -738,7 +743,7 @@ fhandler_socket_unix::open_pipe (HANDLE &ph, PUNICODE_STRING pipe_name)
   IO_STATUS_BLOCK io;
   ULONG sharing;
 
-  status = npfs_handle (npfsh, NPFS_DIR);
+  status = npfs_handle (npfsh);
   if (!NT_SUCCESS (status))
     return status;
   access = GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE;
@@ -996,7 +1001,7 @@ fhandler_socket_unix::wait_pipe_thread (PUNICODE_STRING pipe_name)
   LONGLONG stamp;
   HANDLE ph = NULL;
 
-  status = npfs_handle (npfsh, NPFS_DEVICE);
+  status = npfs_handle (npfsh);
   if (!NT_SUCCESS (status))
     {
       error = geterrno_from_nt_status (status);
diff --git a/winsup/cygwin/globals.cc b/winsup/cygwin/globals.cc
index 9dac030..7c84eb6 100644
--- a/winsup/cygwin/globals.cc
+++ b/winsup/cygwin/globals.cc
@@ -149,8 +149,7 @@ const int __collate_load_error = 0;
   extern UNICODE_STRING _RDATA ro_u_natdir = _ROU (L"Directory");
   extern UNICODE_STRING _RDATA ro_u_natsyml = _ROU (L"SymbolicLink");
   extern UNICODE_STRING _RDATA ro_u_natdev = _ROU (L"Device");
-  extern UNICODE_STRING _RDATA ro_u_npfs = _ROU (L"\\Device\\NamedPipe");
-  extern UNICODE_STRING _RDATA ro_u_npfs_dir = _ROU (L"\\Device\\NamedPipe\\");
+  extern UNICODE_STRING _RDATA ro_u_npfs = _ROU (L"\\Device\\NamedPipe\\");
   #undef _ROU
 
   /* This is an exported copy of environ which can be used by DLLs



More information about the Cygwin-cvs mailing list