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