53d00fffc2
https://github.com/pulseaudio/pulseaudio/blob/master/src/pulsecore/mutex-posix.c#L55
https://github.com/pulseaudio/pulseaudio/blob/master/src/pulse/thread-mainloop.c#L118
413a8f8917
pulseaudio uses a prio-inheriting mutex since the above revision
that is paised with a condition variable; the behavior of this
was broken in musl until the above patches, which would result
in pulseaudio deadlocking with gstreamer pulsesink (most often
with webkit) and possibly other things.
Fixes https://github.com/void-linux/void-packages/issues/15631
48 lines
1.8 KiB
Diff
48 lines
1.8 KiB
Diff
From 27b2fc9d6db956359727a66c262f1e69995660aa Mon Sep 17 00:00:00 2001
|
|
From: Rich Felker <dalias@aerifal.cx>
|
|
Date: Fri, 30 Oct 2020 11:21:06 -0400
|
|
Subject: fix missing-wake regression in pthread_cond_wait
|
|
|
|
the reasoning in commit 2d0bbe6c788938d1332609c014eeebc1dff966ac was
|
|
not entirely correct. while it's true that setting the waiters flag
|
|
ensures that the next unlock will perform a wake, it's possible that
|
|
the wake is consumed by a mutex waiter that has no relationship with
|
|
the condvar wait queue being processed, which then takes the mutex.
|
|
when that thread subsequently unlocks, it sees no waiters, and leaves
|
|
the rest of the condvar queue stuck.
|
|
|
|
bring back the waiter count adjustment, but skip it for PI mutexes,
|
|
for which a successful lock-after-waiting always sets the waiters bit.
|
|
if future changes are made to bring this same waiters-bit contract to
|
|
all lock types, this can be reverted.
|
|
---
|
|
src/thread/pthread_cond_timedwait.c | 5 +++++
|
|
1 file changed, 5 insertions(+)
|
|
|
|
(limited to 'src/thread/pthread_cond_timedwait.c')
|
|
|
|
diff --git a/src/thread/pthread_cond_timedwait.c b/src/thread/pthread_cond_timedwait.c
|
|
index f5f37af1..a0cd4904 100644
|
|
--- a/src/thread/pthread_cond_timedwait.c
|
|
+++ b/src/thread/pthread_cond_timedwait.c
|
|
@@ -146,12 +146,17 @@ relock:
|
|
|
|
if (oldstate == WAITING) goto done;
|
|
|
|
+ if (!node.next && !(m->_m_type & 8))
|
|
+ a_inc(&m->_m_waiters);
|
|
+
|
|
/* Unlock the barrier that's holding back the next waiter, and
|
|
* either wake it or requeue it to the mutex. */
|
|
if (node.prev) {
|
|
int val = m->_m_lock;
|
|
if (val>0) a_cas(&m->_m_lock, val, val|0x80000000);
|
|
unlock_requeue(&node.prev->barrier, &m->_m_lock, m->_m_type & (8|128));
|
|
+ } else if (!!(m->_m_type & 8)) {
|
|
+ a_dec(&m->_m_waiters);
|
|
}
|
|
|
|
/* Since a signal was consumed, cancellation is not permitted. */
|
|
--
|
|
cgit v1.2.1
|
|
|