From b466a1feac2b9570bcf33e44800af5fd4bbdb022 Mon Sep 17 00:00:00 2001 From: Jean-Yves Avenard Date: Sat, 11 Aug 2012 00:29:07 +1000 Subject: [PATCH] Fix MythDownloadManager::cancelDownload() cancelDownload would delete the MythDownloadInfo object, while the object was still in use by the downloading thread, resulting in a crash. Add some locking and do not delete object, instead mark it as cancelled. --- .../libs/libmythbase/mythdownloadmanager.cpp | 35 ++++++++++++++----- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/mythtv/libs/libmythbase/mythdownloadmanager.cpp b/mythtv/libs/libmythbase/mythdownloadmanager.cpp index 53914783679..db9c0377ece 100644 --- a/mythtv/libs/libmythbase/mythdownloadmanager.cpp +++ b/mythtv/libs/libmythbase/mythdownloadmanager.cpp @@ -68,6 +68,18 @@ class MythDownloadInfo m_outFile.detach(); } + bool IsDone(void) + { + QMutexLocker lock(&m_lock); + return m_done; + } + + void SetDone(bool done) + { + QMutexLocker lock(&m_lock); + m_done = done; + } + QString m_url; QUrl m_redirectedTo; QNetworkRequest *m_request; @@ -90,6 +102,7 @@ class MythDownloadInfo const QHash *m_headers; QNetworkReply::NetworkError m_errorCode; + QMutex m_lock; }; @@ -797,7 +810,7 @@ bool MythDownloadManager::downloadNow(MythDownloadInfo *dlInfo, bool deleteInfo) // their last progress update QDateTime startedAt = MythDate::current(); m_infoLock->lock(); - while ((!dlInfo->m_done) && + while ((!dlInfo->IsDone()) && (dlInfo->m_errorCode == QNetworkReply::NoError) && (((!dlInfo->m_url.startsWith("myth://")) && (dlInfo->m_lastStat.secsTo(MythDate::current()) < 10)) || @@ -810,11 +823,11 @@ bool MythDownloadManager::downloadNow(MythDownloadInfo *dlInfo, bool deleteInfo) m_queueWaitLock.unlock(); m_infoLock->lock(); } - + bool done = dlInfo->IsDone(); bool success = - dlInfo->m_done && (dlInfo->m_errorCode == QNetworkReply::NoError); + done && (dlInfo->m_errorCode == QNetworkReply::NoError); - if (!dlInfo->m_done) + if (!done) { dlInfo->m_data = NULL; // Prevent downloadFinished() from updating dlInfo->m_syncMode = false; // Let downloadFinished() cleanup for us @@ -860,8 +873,10 @@ void MythDownloadManager::cancelDownload(const QString &url) dlInfo->m_reply->abort(); } lit.remove(); - delete dlInfo; - dlInfo = NULL; + dlInfo->m_lock.lock(); + dlInfo->m_errorCode = QNetworkReply::OperationCanceledError; + dlInfo->m_done = true; + dlInfo->m_lock.unlock(); } } @@ -876,8 +891,10 @@ void MythDownloadManager::cancelDownload(const QString &url) dlInfo->m_reply->abort(); } m_downloadInfos.remove(url); - delete dlInfo; - dlInfo = NULL; + dlInfo->m_lock.lock(); + dlInfo->m_errorCode = QNetworkReply::OperationCanceledError; + dlInfo->m_done = true; + dlInfo->m_lock.unlock(); } } @@ -1131,7 +1148,7 @@ void MythDownloadManager::downloadFinished(MythDownloadInfo *dlInfo) if (reply) m_downloadReplies.remove(reply); - dlInfo->m_done = true; + dlInfo->SetDone(true); if (!dlInfo->m_syncMode) {