Cygwin: cwd: use SRWLOCK instead of muto
To reduce thread contention, use reader/writer locks as required. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
parent
ee54cabad9
commit
0819679a7a
|
@ -303,25 +303,30 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UNICODE_STRING win32;
|
UNICODE_STRING win32;
|
||||||
static muto cwd_lock;
|
static SRWLOCK NO_COPY cwd_lock;
|
||||||
|
|
||||||
|
static void acquire_read () { AcquireSRWLockShared (&cwd_lock); }
|
||||||
|
static void release_read () { ReleaseSRWLockShared (&cwd_lock); }
|
||||||
|
static void acquire_write () { AcquireSRWLockExclusive (&cwd_lock); }
|
||||||
|
static void release_write () { ReleaseSRWLockExclusive (&cwd_lock); }
|
||||||
const char *get_posix () const { return posix; };
|
const char *get_posix () const { return posix; };
|
||||||
void reset_posix (wchar_t *w_cwd);
|
void reset_posix (wchar_t *w_cwd);
|
||||||
char *get (char *buf, int need_posix = 1, int with_chroot = 0,
|
char *get (char *buf, int need_posix = 1, int with_chroot = 0,
|
||||||
unsigned ulen = NT_MAX_PATH);
|
unsigned ulen = NT_MAX_PATH);
|
||||||
PWCHAR get (PWCHAR buf, unsigned buflen = NT_MAX_PATH)
|
PWCHAR get (PWCHAR buf, unsigned buflen = NT_MAX_PATH)
|
||||||
{
|
{
|
||||||
cwd_lock.acquire ();
|
acquire_read ();
|
||||||
buf[0] = L'\0';
|
buf[0] = L'\0';
|
||||||
wcsncat (buf, win32.Buffer, buflen - 1);
|
wcsncat (buf, win32.Buffer, buflen - 1);
|
||||||
cwd_lock.release ();
|
release_read ();
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
HANDLE get_handle () { return dir; }
|
HANDLE get_handle () { return dir; }
|
||||||
DWORD get_drive (char * dst)
|
DWORD get_drive (char * dst)
|
||||||
{
|
{
|
||||||
cwd_lock.acquire ();
|
acquire_read ();
|
||||||
DWORD ret = sys_wcstombs (dst, NT_MAX_PATH, win32.Buffer, drive_length);
|
DWORD ret = sys_wcstombs (dst, NT_MAX_PATH, win32.Buffer, drive_length);
|
||||||
cwd_lock.release ();
|
release_read ();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
int get_error () const { return error; }
|
int get_error () const { return error; }
|
||||||
|
|
|
@ -1583,7 +1583,7 @@ internal_setlocale ()
|
||||||
_sys_mbstowcs (cygheap->locale.mbtowc, w_path, 32768, path);
|
_sys_mbstowcs (cygheap->locale.mbtowc, w_path, 32768, path);
|
||||||
}
|
}
|
||||||
w_cwd = tp.w_get ();
|
w_cwd = tp.w_get ();
|
||||||
cwdstuff::cwd_lock.acquire ();
|
cwdstuff::acquire_write ();
|
||||||
_sys_mbstowcs (cygheap->locale.mbtowc, w_cwd, 32768,
|
_sys_mbstowcs (cygheap->locale.mbtowc, w_cwd, 32768,
|
||||||
cygheap->cwd.get_posix ());
|
cygheap->cwd.get_posix ());
|
||||||
/* Set charset for internal conversion functions. */
|
/* Set charset for internal conversion functions. */
|
||||||
|
@ -1592,7 +1592,7 @@ internal_setlocale ()
|
||||||
cygheap->locale.mbtowc = __utf8_mbtowc;
|
cygheap->locale.mbtowc = __utf8_mbtowc;
|
||||||
/* Restore CWD and PATH in new charset. */
|
/* Restore CWD and PATH in new charset. */
|
||||||
cygheap->cwd.reset_posix (w_cwd);
|
cygheap->cwd.reset_posix (w_cwd);
|
||||||
cwdstuff::cwd_lock.release ();
|
cwdstuff::release_write ();
|
||||||
if (w_path)
|
if (w_path)
|
||||||
{
|
{
|
||||||
char *c_path = tp.c_get ();
|
char *c_path = tp.c_get ();
|
||||||
|
|
|
@ -103,7 +103,7 @@ struct symlink_info
|
||||||
bool set_error (int);
|
bool set_error (int);
|
||||||
};
|
};
|
||||||
|
|
||||||
muto NO_COPY cwdstuff::cwd_lock;
|
SRWLOCK NO_COPY cwdstuff::cwd_lock;
|
||||||
|
|
||||||
static const GUID GUID_shortcut
|
static const GUID GUID_shortcut
|
||||||
= { 0x00021401L, 0, 0, {0xc0, 0, 0, 0, 0, 0, 0, 0x46}};
|
= { 0x00021401L, 0, 0, {0xc0, 0, 0, 0, 0, 0, 0, 0x46}};
|
||||||
|
@ -4737,12 +4737,10 @@ cwdstuff::override_win32_cwd (bool init, ULONG old_dismount_count)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize cygcwd 'muto' for serializing access to cwd info. */
|
/* Initialize cwdstuff */
|
||||||
void
|
void
|
||||||
cwdstuff::init ()
|
cwdstuff::init ()
|
||||||
{
|
{
|
||||||
cwd_lock.init ("cwd_lock");
|
|
||||||
|
|
||||||
/* Cygwin processes inherit the cwd from their parent. If the win32 path
|
/* Cygwin processes inherit the cwd from their parent. If the win32 path
|
||||||
buffer is not NULL, the cwd struct is already set up, and we only
|
buffer is not NULL, the cwd struct is already set up, and we only
|
||||||
have to override the Win32 CWD with ours. */
|
have to override the Win32 CWD with ours. */
|
||||||
|
@ -4800,8 +4798,6 @@ cwdstuff::set (path_conv *nat_cwd, const char *posix_cwd)
|
||||||
Win32 CWD to a "weird" directory in which all relative filesystem-related
|
Win32 CWD to a "weird" directory in which all relative filesystem-related
|
||||||
calls fail. */
|
calls fail. */
|
||||||
|
|
||||||
cwd_lock.acquire ();
|
|
||||||
|
|
||||||
if (nat_cwd)
|
if (nat_cwd)
|
||||||
{
|
{
|
||||||
upath = *nat_cwd->get_nt_native_path ();
|
upath = *nat_cwd->get_nt_native_path ();
|
||||||
|
@ -4825,6 +4821,8 @@ cwdstuff::set (path_conv *nat_cwd, const char *posix_cwd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
acquire_write ();
|
||||||
|
|
||||||
/* Memorize old DismountCount before opening the dir. This value is
|
/* Memorize old DismountCount before opening the dir. This value is
|
||||||
stored in the FAST_CWD structure. It would be simpler to fetch the
|
stored in the FAST_CWD structure. It would be simpler to fetch the
|
||||||
old DismountCount in override_win32_cwd, but Windows also fetches
|
old DismountCount in override_win32_cwd, but Windows also fetches
|
||||||
|
@ -4888,7 +4886,7 @@ cwdstuff::set (path_conv *nat_cwd, const char *posix_cwd)
|
||||||
/* Called from chdir? Just fail. */
|
/* Called from chdir? Just fail. */
|
||||||
if (nat_cwd)
|
if (nat_cwd)
|
||||||
{
|
{
|
||||||
cwd_lock.release ();
|
release_write ();
|
||||||
__seterrno_from_nt_status (status);
|
__seterrno_from_nt_status (status);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -4905,7 +4903,7 @@ cwdstuff::set (path_conv *nat_cwd, const char *posix_cwd)
|
||||||
peb.ProcessParameters->CurrentDirectoryHandle,
|
peb.ProcessParameters->CurrentDirectoryHandle,
|
||||||
GetCurrentProcess (), &h, 0, TRUE, 0))
|
GetCurrentProcess (), &h, 0, TRUE, 0))
|
||||||
{
|
{
|
||||||
cwd_lock.release ();
|
release_write ();
|
||||||
if (peb.ProcessParameters->CurrentDirectoryHandle)
|
if (peb.ProcessParameters->CurrentDirectoryHandle)
|
||||||
debug_printf ("...and DuplicateHandle failed with %E.");
|
debug_printf ("...and DuplicateHandle failed with %E.");
|
||||||
dir = NULL;
|
dir = NULL;
|
||||||
|
@ -5027,7 +5025,7 @@ cwdstuff::set (path_conv *nat_cwd, const char *posix_cwd)
|
||||||
posix = (char *) crealloc_abort (posix, strlen (posix_cwd) + 1);
|
posix = (char *) crealloc_abort (posix, strlen (posix_cwd) + 1);
|
||||||
stpcpy (posix, posix_cwd);
|
stpcpy (posix, posix_cwd);
|
||||||
|
|
||||||
cwd_lock.release ();
|
release_write ();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5079,7 +5077,7 @@ cwdstuff::get (char *buf, int need_posix, int with_chroot, unsigned ulen)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
cwd_lock.acquire ();
|
acquire_read ();
|
||||||
|
|
||||||
char *tocopy;
|
char *tocopy;
|
||||||
if (!need_posix)
|
if (!need_posix)
|
||||||
|
@ -5106,7 +5104,7 @@ cwdstuff::get (char *buf, int need_posix, int with_chroot, unsigned ulen)
|
||||||
strcpy (buf, "/");
|
strcpy (buf, "/");
|
||||||
}
|
}
|
||||||
|
|
||||||
cwd_lock.release ();
|
release_read ();
|
||||||
|
|
||||||
out:
|
out:
|
||||||
syscall_printf ("(%s) = cwdstuff::get (%p, %u, %d, %d), errno %d",
|
syscall_printf ("(%s) = cwdstuff::get (%p, %u, %d, %d), errno %d",
|
||||||
|
|
|
@ -4437,9 +4437,9 @@ gen_full_path_at (char *path_ret, int dirfd, const char *pathname,
|
||||||
|
|
||||||
if (dirfd == AT_FDCWD)
|
if (dirfd == AT_FDCWD)
|
||||||
{
|
{
|
||||||
cwdstuff::cwd_lock.acquire ();
|
cwdstuff::acquire_read ();
|
||||||
p = stpcpy (path_ret, cygheap->cwd.get_posix ());
|
p = stpcpy (path_ret, cygheap->cwd.get_posix ());
|
||||||
cwdstuff::cwd_lock.release ();
|
cwdstuff::release_read ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -4581,9 +4581,9 @@ fchownat (int dirfd, const char *pathname, uid_t uid, gid_t gid, int flags)
|
||||||
/* pathname is an empty string. Operate on dirfd. */
|
/* pathname is an empty string. Operate on dirfd. */
|
||||||
if (dirfd == AT_FDCWD)
|
if (dirfd == AT_FDCWD)
|
||||||
{
|
{
|
||||||
cwdstuff::cwd_lock.acquire ();
|
cwdstuff::acquire_read ();
|
||||||
strcpy (path, cygheap->cwd.get_posix ());
|
strcpy (path, cygheap->cwd.get_posix ());
|
||||||
cwdstuff::cwd_lock.release ();
|
cwdstuff::release_read ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -4626,9 +4626,9 @@ fstatat (int dirfd, const char *__restrict pathname, struct stat *__restrict st,
|
||||||
/* pathname is an empty string. Operate on dirfd. */
|
/* pathname is an empty string. Operate on dirfd. */
|
||||||
if (dirfd == AT_FDCWD)
|
if (dirfd == AT_FDCWD)
|
||||||
{
|
{
|
||||||
cwdstuff::cwd_lock.acquire ();
|
cwdstuff::acquire_read ();
|
||||||
strcpy (path, cygheap->cwd.get_posix ());
|
strcpy (path, cygheap->cwd.get_posix ());
|
||||||
cwdstuff::cwd_lock.release ();
|
cwdstuff::release_read ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return fstat (dirfd, st);
|
return fstat (dirfd, st);
|
||||||
|
|
Loading…
Reference in New Issue