This is the mail archive of the
cygwin-cvs@cygwin.com
mailing list for the Cygwin project.
[newlib-cygwin] Drop has_fast_cwd flag
- From: Corinna Vinschen <corinna at sourceware dot org>
- To: cygwin-cvs at sourceware dot org
- Date: 24 Jun 2016 11:19:10 -0000
- Subject: [newlib-cygwin] Drop has_fast_cwd flag
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=ffcef702e78f81c64376dbe7547f242f67b433d4
commit ffcef702e78f81c64376dbe7547f242f67b433d4
Author: Corinna Vinschen <corinna@vinschen.de>
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)