From 767a7e1c9e418545605f2828b7b0847ee650dea8 Mon Sep 17 00:00:00 2001 From: VaL Doroshchuk Date: Thu, 30 May 2019 14:34:43 +0200 Subject: Fix crash when app is destroyed before QSample::load is finished MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QSample objects live and handled in loading thread (which uses QNetworkAccessManager). When the app is finished and going to be destroyed, all static objects are destroying as well. In case if static QNetworkConfigurationManagerPrivate (which is used by QNetworkAccessManager) is destroyed before static QSampleCache, and loading of the resource is not finished yet (still executing QNetworkAccessManager::get()), this produces a crash. Since the loading thread is started only when loading of new QSample is requested, (and all events are also handled by this thread) proposing a fix to wait before loading thread is finished when a sample is requested to be released. This postpones deleting of the QSample either when new sample is requested to load or when QSampleCache is destroyed. This makes sure that no loading thread exists when all QSoundEffects objects and afterwards QNetworkConfigurationManagerPrivate are already deleted. Change-Id: I55669ea4c2796a48cae4f0465f7f74d89e393675 Fixes: QTBUG-76090 Reviewed-by: Christian Strømme --- src/multimedia/audio/qsamplecache_p.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src/multimedia') diff --git a/src/multimedia/audio/qsamplecache_p.cpp b/src/multimedia/audio/qsamplecache_p.cpp index c956d764b..73fc3cd2f 100644 --- a/src/multimedia/audio/qsamplecache_p.cpp +++ b/src/multimedia/audio/qsamplecache_p.cpp @@ -295,9 +295,12 @@ void QSample::loadIfNecessary() } } -// Called in both threads +// Called in application thread bool QSampleCache::notifyUnreferencedSample(QSample* sample) { + if (m_loadingThread.isRunning()) + m_loadingThread.wait(); + QMutexLocker locker(&m_mutex); if (m_capacity > 0) return false; @@ -306,16 +309,17 @@ bool QSampleCache::notifyUnreferencedSample(QSample* sample) return true; } -// Called in application threadd +// Called in application thread void QSample::release() { QMutexLocker locker(&m_mutex); #ifdef QT_SAMPLECACHE_DEBUG qDebug() << "Sample:: release" << this << QThread::currentThread() << m_ref; #endif - m_ref--; - if (m_ref == 0) + if (--m_ref == 0) { + locker.unlock(); m_parent->notifyUnreferencedSample(this); + } } // Called in dtor and when stream is loaded -- cgit v1.2.3