Skip to content

Commit e7b1484

Browse files
committed
Fix race condition and potential segfault in MythDownloadManager.
Put a lock around the creation of the MythDownloadManager to make sure we don't get two created by a potential race condition. Put a lock around access to the QNetworkDiskCache when called via MythDownloadManager::GetLastModified(). Fixes #9231 using ideas from Jonatan from comhem.se, but most of the patch (and potential issues) are mine.
1 parent 3049eb7 commit e7b1484

File tree

1 file changed

+25
-12
lines changed

1 file changed

+25
-12
lines changed

mythtv/libs/libmythbase/mythdownloadmanager.cpp

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ using namespace std;
2727
#define LOC QString("DownloadManager: ")
2828

2929
MythDownloadManager *downloadManager = NULL;
30+
QMutex dmCreateLock;
3031

3132
/*!
3233
* \class MythDownloadInfo
@@ -134,21 +135,30 @@ void ShutdownMythDownloadManager(void)
134135
*/
135136
MythDownloadManager *GetMythDownloadManager(void)
136137
{
137-
if (!downloadManager)
138-
{
139-
downloadManager = new MythDownloadManager();
140-
downloadManager->start();
141-
while (!downloadManager->getQueueThread())
142-
usleep(10000);
138+
if (downloadManager)
139+
return downloadManager;
140+
141+
QMutexLocker locker(&dmCreateLock);
143142

144-
downloadManager->moveToThread(downloadManager->getQueueThread());
145-
downloadManager->setRunThread();
143+
// Check once more in case the download manager was created
144+
// while we were securing the lock.
145+
if (downloadManager)
146+
return downloadManager;
146147

147-
while (!downloadManager->isRunning())
148-
usleep(10000);
148+
MythDownloadManager *tmpDLM = new MythDownloadManager();
149+
tmpDLM->start();
150+
while (!tmpDLM->getQueueThread())
151+
usleep(10000);
149152

150-
atexit(ShutdownMythDownloadManager);
151-
}
153+
tmpDLM->moveToThread(tmpDLM->getQueueThread());
154+
tmpDLM->setRunThread();
155+
156+
while (!tmpDLM->isRunning())
157+
usleep(10000);
158+
159+
downloadManager = tmpDLM;
160+
161+
atexit(ShutdownMythDownloadManager);
152162

153163
return downloadManager;
154164
}
@@ -1039,7 +1049,10 @@ QDateTime MythDownloadManager::GetLastModified(const QString &url)
10391049
QDateTime result;
10401050

10411051
QDateTime now = QDateTime::currentDateTime();
1052+
1053+
m_infoLock->lock();
10421054
QNetworkCacheMetaData urlData = m_manager->cache()->metaData(QUrl(url));
1055+
m_infoLock->unlock();
10431056

10441057
if (urlData.isValid())
10451058
{

0 commit comments

Comments
 (0)