To reduce thread contention, use reader/writer locks as required.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
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; }
_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. */
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 ();
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}};
}
}
-/* 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. */
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 ();
}
}
+ 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
/* Called from chdir? Just fail. */
if (nat_cwd)
{
- cwd_lock.release ();
+ release_write ();
__seterrno_from_nt_status (status);
return -1;
}
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;
posix = (char *) crealloc_abort (posix, strlen (posix_cwd) + 1);
stpcpy (posix, posix_cwd);
- cwd_lock.release ();
+ release_write ();
return 0;
}
goto out;
}
- cwd_lock.acquire ();
+ acquire_read ();
char *tocopy;
if (!need_posix)
strcpy (buf, "/");
}
- cwd_lock.release ();
+ release_read ();
out:
syscall_printf ("(%s) = cwdstuff::get (%p, %u, %d, %d), errno %d",
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
{
/* 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
{
/* 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);