]> sourceware.org Git - newlib-cygwin.git/commitdiff
Cygwin: cwd: use SRWLOCK instead of muto
authorCorinna Vinschen <corinna@vinschen.de>
Tue, 23 Aug 2022 09:58:38 +0000 (11:58 +0200)
committerCorinna Vinschen <corinna@vinschen.de>
Tue, 23 Aug 2022 10:09:44 +0000 (12:09 +0200)
To reduce thread contention, use reader/writer locks as required.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
winsup/cygwin/local_includes/cygheap.h
winsup/cygwin/nlsfuncs.cc
winsup/cygwin/path.cc
winsup/cygwin/syscalls.cc

index 7f36c58374a3d2c157c27efe23e33913f4243bd3..6a844babdb48e986e76d60461d60a03b047887a8 100644 (file)
@@ -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; }
index 5edc0c0e69a8b5c4e2c656c8e9c8cb96b2696041..ddd85bea16475b29a07e08fb905db5c86720b8c8 100644 (file)
@@ -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 ();
index 227b99d0f7205c99a0a9f75b469387ecbb66fd18..4babd10b8a1d5445bcfd64a07ffcc49c73d71f12 100644 (file)
@@ -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",
index 94cb57648d933f6610665faaf40662ac8152a5ae..1338853dfdc048657a87212fd15cf15f4f5b7cc9 100644 (file)
@@ -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);
This page took 0.043923 seconds and 5 git commands to generate.