From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2155) id DB9F93857C53; Tue, 24 Aug 2021 07:56:57 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DB9F93857C53 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Corinna Vinschen To: cygwin-cvs@sourceware.org Subject: [newlib-cygwin] fix race condition in List_insert X-Act-Checkin: newlib-cygwin X-Git-Author: Aleksand Malikov X-Git-Refname: refs/heads/master X-Git-Oldrev: bc0e8a996110550f65cd356d7da0ba1b5beb243e X-Git-Newrev: 1a821390d11d3bc66e6858f27dceeef67e14078d Message-Id: <20210824075657.DB9F93857C53@sourceware.org> Date: Tue, 24 Aug 2021 07:56:57 +0000 (GMT) X-BeenThere: cygwin-cvs@cygwin.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Cygwin core component git logs List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 24 Aug 2021 07:56:58 -0000 https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=1a821390d11d3bc66e6858f27dceeef67e14078d commit 1a821390d11d3bc66e6858f27dceeef67e14078d Author: Aleksand Malikov Date: Mon Aug 23 17:27:48 2021 +0300 fix race condition in List_insert Revert mx parameter and mutex lock while operating the list. Mutex was removed with 94d24160 informing that: 'Use InterlockedCompareExchangePointer to ensure race safeness without using a mutex.' But it does not. Calling pthread_mutex_init and pthread_mutex_destroy from two or more threads occasionally leads to hang in pthread_mutex_destroy. To not change the behaviour of other cases where List_insert was called, List_insert_nolock is added. Diff: --- winsup/cygwin/thread.cc | 8 ++++---- winsup/cygwin/thread.h | 17 +++++++++++++++-- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc index 4d0ea274f..7c6a919c0 100644 --- a/winsup/cygwin/thread.cc +++ b/winsup/cygwin/thread.cc @@ -1595,7 +1595,7 @@ pthread_rwlock::add_reader () { RWLOCK_READER *rd = new RWLOCK_READER; if (rd) - List_insert (readers, rd); + List_insert_nolock (readers, rd); return rd; } @@ -2165,7 +2165,7 @@ pthread::atfork (void (*prepare)(void), void (*parent)(void), void (*child)(void if (prepcb) { prepcb->cb = prepare; - List_insert (MT_INTERFACE->pthread_prepare, prepcb); + List_insert_nolock (MT_INTERFACE->pthread_prepare, prepcb); } if (parentcb) { @@ -2174,7 +2174,7 @@ pthread::atfork (void (*prepare)(void), void (*parent)(void), void (*child)(void while (*t) t = &(*t)->next; /* t = pointer to last next in the list */ - List_insert (*t, parentcb); + List_insert_nolock (*t, parentcb); } if (childcb) { @@ -2183,7 +2183,7 @@ pthread::atfork (void (*prepare)(void), void (*parent)(void), void (*child)(void while (*t) t = &(*t)->next; /* t = pointer to last next in the list */ - List_insert (*t, childcb); + List_insert_nolock (*t, childcb); } return 0; } diff --git a/winsup/cygwin/thread.h b/winsup/cygwin/thread.h index 6b699ccb6..ddb2d7dbf 100644 --- a/winsup/cygwin/thread.h +++ b/winsup/cygwin/thread.h @@ -111,7 +111,20 @@ typedef enum } verifyable_object_state; template inline void -List_insert (list_node *&head, list_node *node) +List_insert (fast_mutex &mx, list_node *&head, list_node *node) +{ + if (!node) + return; + mx.lock (); + do + node->next = head; + while (InterlockedCompareExchangePointer ((PVOID volatile *) &head, + node, node->next) != node->next); + mx.unlock (); +} + +template inline void +List_insert_nolock (list_node *&head, list_node *node) { if (!node) return; @@ -163,7 +176,7 @@ template class List void insert (list_node *node) { - List_insert (head, node); + List_insert (mx, head, node); } void remove (list_node *node)