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:
|
||||
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; };
|
||||
void reset_posix (wchar_t *w_cwd);
|
||||
char *get (char *buf, int need_posix = 1, int with_chroot = 0,
|
||||
unsigned ulen = NT_MAX_PATH);
|
||||
PWCHAR get (PWCHAR buf, unsigned buflen = NT_MAX_PATH)
|
||||
{
|
||||
cwd_lock.acquire ();
|
||||
acquire_read ();
|
||||
buf[0] = L'\0';
|
||||
wcsncat (buf, win32.Buffer, buflen - 1);
|
||||
cwd_lock.release ();
|
||||
release_read ();
|
||||
return buf;
|
||||
}
|
||||
HANDLE get_handle () { return dir; }
|
||||
DWORD get_drive (char * dst)
|
||||
{
|
||||
cwd_lock.acquire ();
|
||||
acquire_read ();
|
||||
DWORD ret = sys_wcstombs (dst, NT_MAX_PATH, win32.Buffer, drive_length);
|
||||
cwd_lock.release ();
|
||||
release_read ();
|
||||
return ret;
|
||||
}
|
||||
int get_error () const { return error; }
|
||||
|
|
|
@ -1583,7 +1583,7 @@ internal_setlocale ()
|
|||
_sys_mbstowcs (cygheap->locale.mbtowc, w_path, 32768, path);
|
||||
}
|
||||
w_cwd = tp.w_get ();
|
||||
cwdstuff::cwd_lock.acquire ();
|
||||
cwdstuff::acquire_write ();
|
||||
_sys_mbstowcs (cygheap->locale.mbtowc, w_cwd, 32768,
|
||||
cygheap->cwd.get_posix ());
|
||||
/* Set charset for internal conversion functions. */
|
||||
|
@ -1592,7 +1592,7 @@ internal_setlocale ()
|
|||
cygheap->locale.mbtowc = __utf8_mbtowc;
|
||||
/* Restore CWD and PATH in new charset. */
|
||||
cygheap->cwd.reset_posix (w_cwd);
|
||||
cwdstuff::cwd_lock.release ();
|
||||
cwdstuff::release_write ();
|
||||
if (w_path)
|
||||
{
|
||||
char *c_path = tp.c_get ();
|
||||
|
|
|
@ -103,7 +103,7 @@ struct symlink_info
|
|||
bool set_error (int);
|
||||
};
|
||||
|
||||
muto NO_COPY cwdstuff::cwd_lock;
|
||||
SRWLOCK NO_COPY cwdstuff::cwd_lock;
|
||||
|
||||
static const GUID GUID_shortcut
|
||||
= { 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
|
||||
cwdstuff::init ()
|
||||
{
|
||||
cwd_lock.init ("cwd_lock");
|
||||
|
||||
/* 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
|
||||
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
|
||||
calls fail. */
|
||||
|
||||
cwd_lock.acquire ();
|
||||
|
||||
if (nat_cwd)
|
||||
{
|
||||
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
|
||||
stored in the FAST_CWD structure. It would be simpler to fetch the
|
||||
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. */
|
||||
if (nat_cwd)
|
||||
{
|
||||
cwd_lock.release ();
|
||||
release_write ();
|
||||
__seterrno_from_nt_status (status);
|
||||
return -1;
|
||||
}
|
||||
|
@ -4905,7 +4903,7 @@ cwdstuff::set (path_conv *nat_cwd, const char *posix_cwd)
|
|||
peb.ProcessParameters->CurrentDirectoryHandle,
|
||||
GetCurrentProcess (), &h, 0, TRUE, 0))
|
||||
{
|
||||
cwd_lock.release ();
|
||||
release_write ();
|
||||
if (peb.ProcessParameters->CurrentDirectoryHandle)
|
||||
debug_printf ("...and DuplicateHandle failed with %E.");
|
||||
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);
|
||||
stpcpy (posix, posix_cwd);
|
||||
|
||||
cwd_lock.release ();
|
||||
release_write ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -5079,7 +5077,7 @@ cwdstuff::get (char *buf, int need_posix, int with_chroot, unsigned ulen)
|
|||
goto out;
|
||||
}
|
||||
|
||||
cwd_lock.acquire ();
|
||||
acquire_read ();
|
||||
|
||||
char *tocopy;
|
||||
if (!need_posix)
|
||||
|
@ -5106,7 +5104,7 @@ cwdstuff::get (char *buf, int need_posix, int with_chroot, unsigned ulen)
|
|||
strcpy (buf, "/");
|
||||
}
|
||||
|
||||
cwd_lock.release ();
|
||||
release_read ();
|
||||
|
||||
out:
|
||||
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)
|
||||
{
|
||||
cwdstuff::cwd_lock.acquire ();
|
||||
cwdstuff::acquire_read ();
|
||||
p = stpcpy (path_ret, cygheap->cwd.get_posix ());
|
||||
cwdstuff::cwd_lock.release ();
|
||||
cwdstuff::release_read ();
|
||||
}
|
||||
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. */
|
||||
if (dirfd == AT_FDCWD)
|
||||
{
|
||||
cwdstuff::cwd_lock.acquire ();
|
||||
cwdstuff::acquire_read ();
|
||||
strcpy (path, cygheap->cwd.get_posix ());
|
||||
cwdstuff::cwd_lock.release ();
|
||||
cwdstuff::release_read ();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4626,9 +4626,9 @@ fstatat (int dirfd, const char *__restrict pathname, struct stat *__restrict st,
|
|||
/* pathname is an empty string. Operate on dirfd. */
|
||||
if (dirfd == AT_FDCWD)
|
||||
{
|
||||
cwdstuff::cwd_lock.acquire ();
|
||||
cwdstuff::acquire_read ();
|
||||
strcpy (path, cygheap->cwd.get_posix ());
|
||||
cwdstuff::cwd_lock.release ();
|
||||
cwdstuff::release_read ();
|
||||
}
|
||||
else
|
||||
return fstat (dirfd, st);
|
||||
|
|
Loading…
Reference in New Issue