https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=d6c50e630a3c51ebbab477f452bb8138408c5c2a

commit d6c50e630a3c51ebbab477f452bb8138408c5c2a
Author: Corinna Vinschen <[email protected]>
Date:   Mon Aug 22 14:28:11 2022 +0200

    Cygwin: shm: Convert muto into SRWLOCK and avoid overlocking
    
    shmat may call shmget.  shmget locks by itself as necessary,
    so there's no reason to keep the lock active and recurse into
    the lock.  Use SRWLOCK and only lock  as required.
    
    Signed-off-by: Corinna Vinschen <[email protected]>

Diff:
---
 winsup/cygwin/shm.cc | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/winsup/cygwin/shm.cc b/winsup/cygwin/shm.cc
index 88d3c0a48..b60ce4cde 100644
--- a/winsup/cygwin/shm.cc
+++ b/winsup/cygwin/shm.cc
@@ -113,9 +113,9 @@ struct shm_attached_list {
 
 static SLIST_HEAD (, shm_attached_list) sph_list;
 
-static NO_COPY muto shm_guard;
-#define SLIST_LOCK()   (shm_guard.init ("shm_guard")->acquire ())
-#define SLIST_UNLOCK() (shm_guard.release ())
+static NO_COPY SRWLOCK shm_lock = SRWLOCK_INIT;
+#define SLIST_LOCK()    (AcquireSRWLockExclusive (&shm_lock))
+#define SLIST_UNLOCK()  (ReleaseSRWLockExclusive (&shm_lock))
 
 int
 fixup_shms_after_fork ()
@@ -174,22 +174,22 @@ shmat (int shmid, const void *shmaddr, int shmflg)
         shmid if one exists.  Since shmctl inserts a new entry for this
         shmid into ssh_list automatically, we just have to go through
         that list again.  If that still fails, well, bad luck. */
+      SLIST_UNLOCK ();
       if (shmid && shmget ((key_t) shmid, 0, IPC_KEY_IS_SHMID) != -1)
        {
+         SLIST_LOCK ();
          SLIST_FOREACH (ssh_entry, &ssh_list, ssh_next)
            {
              if (ssh_entry->shmid == shmid)
-               break;
+               goto inc_ref_count;
            }
-       }
-      if (!ssh_entry)
-       {
-         /* Invalid shmid */
-         set_errno (EINVAL);
          SLIST_UNLOCK ();
-         return (void *) -1;
        }
+      /* Invalid shmid */
+      set_errno (EINVAL);
+      return (void *) -1;
     }
+inc_ref_count:
   /* Early increment ref counter.  This allows further actions to run with
      unlocked lists, because shmdt or shmctl(IPC_RMID) won't delete this
      ssh_entry. */

Reply via email to