[newlib-cygwin] Cygwin: shm: Convert muto into SRWLOCK and avoid overlocking

Corinna Vinschen corinna@sourceware.org
Mon Aug 22 12:39:17 GMT 2022


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

commit d6c50e630a3c51ebbab477f452bb8138408c5c2a
Author: Corinna Vinschen <corinna@vinschen.de>
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 <corinna@vinschen.de>

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. */


More information about the Cygwin-cvs mailing list