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

commit ffcef702e78f81c64376dbe7547f242f67b433d4
Author: Corinna Vinschen <[email protected]>
Date:   Tue Dec 15 15:17:18 2015 +0100

    Drop has_fast_cwd flag

Diff:
---
 winsup/cygwin/path.cc   | 181 +++++++++++++++++++++---------------------------
 winsup/cygwin/wincap.cc |   7 --
 winsup/cygwin/wincap.h  |   2 -
 3 files changed, 78 insertions(+), 112 deletions(-)

diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index 77117fc..eb4fc08 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -3894,12 +3894,11 @@ fcwd_access_t::Free (PVOID heap)
 {
   /* Decrement the reference count.  If it's down to 0, free
      structure from heap. */
-  if (this && InterlockedDecrement (&ReferenceCount ()) == 0)
+  if (InterlockedDecrement (&ReferenceCount ()) == 0)
     {
-      /* In contrast to pre-Vista, the handle on init is always a
-        fresh one and not the handle inherited from the parent
-        process.  So we always have to close it here.  However, the
-        handle could be NULL, if we cd'ed into a virtual dir. */
+      /* The handle on init is always a fresh one, not the handle inherited
+        from the parent process.  We always have to close it here.
+        Note: The handle could be NULL, if we cd'ed into a virtual dir. */
       HANDLE h = DirectoryHandle ();
       if (h)
        NtClose (h);
@@ -4247,113 +4246,89 @@ cwdstuff::override_win32_cwd (bool init, ULONG 
old_dismount_count)
   UNICODE_STRING &upp_cwd_str = peb.ProcessParameters->CurrentDirectoryName;
   HANDLE &upp_cwd_hdl = peb.ProcessParameters->CurrentDirectoryHandle;
 
-  if (wincap.has_fast_cwd ())
+  if (fast_cwd_ptr == (fcwd_access_t **) -1)
+    fast_cwd_ptr = find_fast_cwd ();
+  if (fast_cwd_ptr)
     {
-      if (fast_cwd_ptr == (fcwd_access_t **) -1)
-       fast_cwd_ptr = find_fast_cwd ();
-      if (fast_cwd_ptr)
+      /* Default method starting with Vista.  If we got a valid value for
+        fast_cwd_ptr, we can simply replace the RtlSetCurrentDirectory_U
+        function entirely, just as on pre-Vista. */
+      PVOID heap = peb.ProcessHeap;
+      /* First allocate a new fcwd_access_t structure on the heap.
+        The new fcwd_access_t structure is 4 byte bigger than the old one,
+        but we simply don't care, so we allocate always room for the
+        new one. */
+      fcwd_access_t *f_cwd = (fcwd_access_t *)
+                       RtlAllocateHeap (heap, 0, sizeof (fcwd_access_t));
+      if (!f_cwd)
        {
-         /* Default method starting with Vista.  If we got a valid value for
-            fast_cwd_ptr, we can simply replace the RtlSetCurrentDirectory_U
-            function entirely, just as on pre-Vista. */
-         PVOID heap = peb.ProcessHeap;
-         /* First allocate a new fcwd_access_t structure on the heap.
-            The new fcwd_access_t structure is 4 byte bigger than the old one,
-            but we simply don't care, so we allocate always room for the
-            new one. */
-         fcwd_access_t *f_cwd = (fcwd_access_t *)
-                           RtlAllocateHeap (heap, 0, sizeof (fcwd_access_t));
-         if (!f_cwd)
-           {
-             debug_printf ("RtlAllocateHeap failed");
-             return;
-           }
-         /* Fill in the values. */
-         f_cwd->FillIn (dir, error ? &ro_u_pipedir : &win32,
-                        old_dismount_count);
-         /* Use PEB lock when switching fast_cwd_ptr to the new FAST_CWD
-            structure and writing the CWD to the user process parameter
-            block.  This is equivalent to calling RtlAcquirePebLock/
-            RtlReleasePebLock, but without having to go through the FS
-            selector again. */
-         RtlEnterCriticalSection (peb.FastPebLock);
-         fcwd_access_t *old_cwd = *fast_cwd_ptr;
-         *fast_cwd_ptr = f_cwd;
-         f_cwd->CopyPath (upp_cwd_str);
-         upp_cwd_hdl = dir;
-         RtlLeaveCriticalSection (peb.FastPebLock);
-         old_cwd->Free (heap);
-       }
-      else
-       {
-         /* This is more a hack, and it's only used on Vista and later if we
-            failed to find the fast_cwd_ptr value.  What we do here is to call
-            RtlSetCurrentDirectory_U and let it set up a new FAST_CWD
-            structure.  Afterwards, compute the address of that structure
-            utilizing the fact that the buffer address in the user process
-            parameter block is actually pointing to the buffer in that
-            FAST_CWD structure.  Then replace the directory handle in that
-            structure with our own handle and close the original one.
-
-            Note that the call to RtlSetCurrentDirectory_U also closes our
-            old dir handle, so there won't be any handle left open.
-
-            This method is prone to two race conditions:
-
-            - Due to the way RtlSetCurrentDirectory_U opens the directory
-              handle, the directory is locked against deletion or renaming
-              between the RtlSetCurrentDirectory_U and the subsequent NtClose
-              call.
-
-            - When another thread calls SetCurrentDirectory at exactly the
-              same time, a crash might occur, or worse, unrelated data could
-              be overwritten or NtClose could be called on an unrelated handle.
-
-            Therefore, use this *only* as a fallback. */
-         if (!init)
-           {
-             NTSTATUS status =
-               RtlSetCurrentDirectory_U (error ? &ro_u_pipedir : &win32);
-             if (!NT_SUCCESS (status))
-               {
-                 debug_printf ("RtlSetCurrentDirectory_U(%S) failed, %y",
-                               error ? &ro_u_pipedir : &win32, status);
-                 return;
-               }
-           }
-         else if (upp_cwd_hdl == NULL)
-           return;
-         RtlEnterCriticalSection (peb.FastPebLock);
-         fcwd_access_t::SetDirHandleFromBufferPointer(upp_cwd_str.Buffer, dir);
-         h = upp_cwd_hdl;
-         upp_cwd_hdl = dir;
-         RtlLeaveCriticalSection (peb.FastPebLock);
-         /* In contrast to pre-Vista, the handle on init is always a fresh one
-            and not the handle inherited from the parent process.  So we always
-            have to close it here. */
-         NtClose (h);
+         debug_printf ("RtlAllocateHeap failed");
+         return;
        }
+      /* Fill in the values. */
+      f_cwd->FillIn (dir, error ? &ro_u_pipedir : &win32,
+                    old_dismount_count);
+      /* Use PEB lock when switching fast_cwd_ptr to the new FAST_CWD
+        structure and writing the CWD to the user process parameter
+        block.  This is equivalent to calling RtlAcquirePebLock/
+        RtlReleasePebLock, but without having to go through the FS
+        selector again. */
+      RtlEnterCriticalSection (peb.FastPebLock);
+      fcwd_access_t *old_cwd = *fast_cwd_ptr;
+      *fast_cwd_ptr = f_cwd;
+      f_cwd->CopyPath (upp_cwd_str);
+      upp_cwd_hdl = dir;
+      RtlLeaveCriticalSection (peb.FastPebLock);
+      if (old_cwd)
+       old_cwd->Free (heap);
     }
   else
     {
-      /* This method is used for all pre-Vista OSes.  We simply set the values
-        for the CWD in the user process parameter block entirely by ourselves
-        under PEB lock condition.  This is how RtlSetCurrentDirectory_U worked
-        in these older OSes, so we're safe.
-
-        Note that we can't just RtlEnterCriticalSection (peb.FastPebLock)
-        on pre-Vista.  RtlAcquirePebLock was way more complicated back then. */
-      RtlAcquirePebLock ();
+      /* This is more a hack, and it's only used on Vista and later if we
+        failed to find the fast_cwd_ptr value.  What we do here is to call
+        RtlSetCurrentDirectory_U and let it set up a new FAST_CWD
+        structure.  Afterwards, compute the address of that structure
+        utilizing the fact that the buffer address in the user process
+        parameter block is actually pointing to the buffer in that
+        FAST_CWD structure.  Then replace the directory handle in that
+        structure with our own handle and close the original one.
+
+        Note that the call to RtlSetCurrentDirectory_U also closes our
+        old dir handle, so there won't be any handle left open.
+
+        This method is prone to two race conditions:
+
+        - Due to the way RtlSetCurrentDirectory_U opens the directory
+          handle, the directory is locked against deletion or renaming
+          between the RtlSetCurrentDirectory_U and the subsequent NtClose
+          call.
+
+        - When another thread calls SetCurrentDirectory at exactly the
+          same time, a crash might occur, or worse, unrelated data could
+          be overwritten or NtClose could be called on an unrelated handle.
+
+        Therefore, use this *only* as a fallback. */
       if (!init)
-       copy_cwd_str (&upp_cwd_str, error ? &ro_u_pipedir : &win32);
+       {
+         NTSTATUS status =
+           RtlSetCurrentDirectory_U (error ? &ro_u_pipedir : &win32);
+         if (!NT_SUCCESS (status))
+           {
+             debug_printf ("RtlSetCurrentDirectory_U(%S) failed, %y",
+                           error ? &ro_u_pipedir : &win32, status);
+             return;
+           }
+       }
+      else if (upp_cwd_hdl == NULL)
+       return;
+      RtlEnterCriticalSection (peb.FastPebLock);
+      fcwd_access_t::SetDirHandleFromBufferPointer(upp_cwd_str.Buffer, dir);
       h = upp_cwd_hdl;
       upp_cwd_hdl = dir;
-      RtlReleasePebLock ();
-      /* Only on init, the handle is potentially a native handle.  However,
-        if it's identical to dir, it's the inherited handle from a Cygwin
-        parent process and must not be closed. */
-      if (h && h != dir)
-       NtClose (h);
+      RtlLeaveCriticalSection (peb.FastPebLock);
+      /* The handle on init is always a fresh one, not the handle inherited
+        from the parent process.  We always have to close it here. */
+      NtClose (h);
     }
 }
 
diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc
index dcb2c92..caa478b 100644
--- a/winsup/cygwin/wincap.cc
+++ b/winsup/cygwin/wincap.cc
@@ -25,7 +25,6 @@ wincaps wincap_xpsp2 __attribute__((section 
(".cygwin_dll_common"), shared)) = {
   has_gaa_largeaddress_bug:false,
   has_transactions:false,
   has_broken_alloc_console:false,
-  has_fast_cwd:false,
   has_restricted_raw_disk_access:false,
   use_dont_resolve_hack:true,
   has_console_logon_sid:false,
@@ -51,7 +50,6 @@ wincaps wincap_2003 __attribute__((section 
(".cygwin_dll_common"), shared)) = {
   has_gaa_largeaddress_bug:false,
   has_transactions:false,
   has_broken_alloc_console:false,
-  has_fast_cwd:false,
   has_restricted_raw_disk_access:false,
   use_dont_resolve_hack:true,
   has_console_logon_sid:false,
@@ -77,7 +75,6 @@ wincaps wincap_vista __attribute__((section 
(".cygwin_dll_common"), shared)) = {
   has_gaa_largeaddress_bug:true,
   has_transactions:true,
   has_broken_alloc_console:false,
-  has_fast_cwd:true,
   has_restricted_raw_disk_access:true,
   use_dont_resolve_hack:false,
   has_console_logon_sid:false,
@@ -103,7 +100,6 @@ wincaps wincap_7 __attribute__((section 
(".cygwin_dll_common"), shared)) = {
   has_gaa_largeaddress_bug:true,
   has_transactions:true,
   has_broken_alloc_console:true,
-  has_fast_cwd:true,
   has_restricted_raw_disk_access:true,
   use_dont_resolve_hack:false,
   has_console_logon_sid:true,
@@ -129,7 +125,6 @@ wincaps wincap_8 __attribute__((section 
(".cygwin_dll_common"), shared)) = {
   has_gaa_largeaddress_bug:false,
   has_transactions:true,
   has_broken_alloc_console:true,
-  has_fast_cwd:true,
   has_restricted_raw_disk_access:true,
   use_dont_resolve_hack:false,
   has_console_logon_sid:true,
@@ -155,7 +150,6 @@ wincaps wincap_10 __attribute__((section 
(".cygwin_dll_common"), shared)) = {
   has_gaa_largeaddress_bug:false,
   has_transactions:true,
   has_broken_alloc_console:true,
-  has_fast_cwd:true,
   has_restricted_raw_disk_access:true,
   use_dont_resolve_hack:false,
   has_console_logon_sid:true,
@@ -181,7 +175,6 @@ wincaps wincap_10_1511 __attribute__((section 
(".cygwin_dll_common"), shared)) =
   has_gaa_largeaddress_bug:false,
   has_transactions:true,
   has_broken_alloc_console:true,
-  has_fast_cwd:true,
   has_restricted_raw_disk_access:true,
   use_dont_resolve_hack:false,
   has_console_logon_sid:true,
diff --git a/winsup/cygwin/wincap.h b/winsup/cygwin/wincap.h
index 6bed041..bc4abb7 100644
--- a/winsup/cygwin/wincap.h
+++ b/winsup/cygwin/wincap.h
@@ -18,7 +18,6 @@ struct wincaps
   unsigned has_gaa_largeaddress_bug                    : 1;
   unsigned has_transactions                            : 1;
   unsigned has_broken_alloc_console                    : 1;
-  unsigned has_fast_cwd                                        : 1;
   unsigned has_restricted_raw_disk_access              : 1;
   unsigned use_dont_resolve_hack                       : 1;
   unsigned has_console_logon_sid                       : 1;
@@ -69,7 +68,6 @@ public:
   bool IMPLEMENT (has_gaa_largeaddress_bug)
   bool IMPLEMENT (has_transactions)
   bool IMPLEMENT (has_broken_alloc_console)
-  bool IMPLEMENT (has_fast_cwd)
   bool IMPLEMENT (has_restricted_raw_disk_access)
   bool IMPLEMENT (use_dont_resolve_hack)
   bool IMPLEMENT (has_console_logon_sid)

Reply via email to