From 1083ed94683c3356f9ee19210cfe9b0dd53e4815 Mon Sep 17 00:00:00 2001 From: VaL Doroshchuk Date: Mon, 18 Dec 2017 09:41:16 +0100 Subject: PulseAudio: Fix deadlock for QSoundEffect in setMuted, setVolume The deadlock would happen when one of the protected functions were reentered, as the lock used was not recursive. Since reading and writing to the volume and muted properties don't happen that often, the rw-mutex was replaced by a normal non-recursive mutex, which is now unlocked before the property changed signal is emitted. Task-number: QTBUG-65220 Change-Id: I1a224e9ff03f14593a854a7c1049c8a0445e29e6 Reviewed-by: Christian Stromme --- src/multimedia/audio/qsoundeffect_pulse_p.cpp | 13 ++++++++----- src/multimedia/audio/qsoundeffect_pulse_p.h | 5 +++-- 2 files changed, 11 insertions(+), 7 deletions(-) (limited to 'src/multimedia/audio') diff --git a/src/multimedia/audio/qsoundeffect_pulse_p.cpp b/src/multimedia/audio/qsoundeffect_pulse_p.cpp index bf647ea1f..a86f22872 100644 --- a/src/multimedia/audio/qsoundeffect_pulse_p.cpp +++ b/src/multimedia/audio/qsoundeffect_pulse_p.cpp @@ -535,31 +535,34 @@ void QSoundEffectPrivate::setLoopCount(int loopCount) qreal QSoundEffectPrivate::volume() const { - QReadLocker locker(&m_volumeLock); + QMutexLocker locker(&m_volumeLock); return m_volume; } void QSoundEffectPrivate::setVolume(qreal volume) { - QWriteLocker locker(&m_volumeLock); + QMutexLocker locker(&m_volumeLock); if (qFuzzyCompare(m_volume, volume)) return; m_volume = qBound(qreal(0), volume, qreal(1)); + locker.unlock(); emit volumeChanged(); } bool QSoundEffectPrivate::isMuted() const { - QReadLocker locker(&m_volumeLock); + QMutexLocker locker(&m_volumeLock); return m_muted; } void QSoundEffectPrivate::setMuted(bool muted) { - QWriteLocker locker(&m_volumeLock); + m_volumeLock.lock(); m_muted = muted; + m_volumeLock.unlock(); + emit mutedChanged(); } @@ -884,7 +887,7 @@ int QSoundEffectPrivate::writeToStream(const void *data, int size) if (size < 1) return 0; - m_volumeLock.lockForRead(); + m_volumeLock.lock(); qreal volume = m_muted ? 0 : m_volume; m_volumeLock.unlock(); pa_free_cb_t writeDoneCb = stream_write_done_callback; diff --git a/src/multimedia/audio/qsoundeffect_pulse_p.h b/src/multimedia/audio/qsoundeffect_pulse_p.h index 7be88c55a..268a99326 100644 --- a/src/multimedia/audio/qsoundeffect_pulse_p.h +++ b/src/multimedia/audio/qsoundeffect_pulse_p.h @@ -56,7 +56,7 @@ #include #include -#include +#include #include #include #include "qsamplecache_p.h" @@ -175,7 +175,8 @@ private: bool m_resourcesAvailable; - mutable QReadWriteLock m_volumeLock; + // Protects volume while PuseAudio is accessing it + mutable QMutex m_volumeLock; QMediaPlayerResourceSetInterface *m_resources; }; -- cgit v1.2.1