summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVaL Doroshchuk <valentyn.doroshchuk@qt.io>2019-05-30 14:34:43 +0200
committerVaL Doroshchuk <valentyn.doroshchuk@qt.io>2019-07-05 14:38:09 +0200
commit767a7e1c9e418545605f2828b7b0847ee650dea8 (patch)
treee22a001b0bfb76aeef35b370a68433020d2136bf
parentbc03bfdbcf63a81f7261637378e2447e76dc7e97 (diff)
Fix crash when app is destroyed before QSample::load is finished
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 <christian.stromme@qt.io>
-rw-r--r--src/multimedia/audio/qsamplecache_p.cpp12
1 files changed, 8 insertions, 4 deletions
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