From fd132e60e4d2dbf85dac1685762efdb17c6b61cc Mon Sep 17 00:00:00 2001 From: Jean-Yves Avenard Date: Mon, 12 Aug 2013 09:03:38 +1000 Subject: [PATCH] Revert "Revert "Fix MythDownloadManger after 997f7aa10. It was possible for queue and cancel requests to be handled out of order resulting in newly queued downloads being cancelled almost immediately. We avoid this by removing any cancelled downloads from the download queue to a new cancellation queue, then we clean up the cancelled downloads later without affecting new additions."" This reverts commit eb3a3382a21c71fd0d1c9ff57aa64480ad03b36a. --- .../libs/libmythbase/mythdownloadmanager.cpp | 58 ++++++++++--------- mythtv/libs/libmythbase/mythdownloadmanager.h | 3 +- 2 files changed, 32 insertions(+), 29 deletions(-) diff --git a/mythtv/libs/libmythbase/mythdownloadmanager.cpp b/mythtv/libs/libmythbase/mythdownloadmanager.cpp index 46b129e2926..ce19d10e04c 100644 --- a/mythtv/libs/libmythbase/mythdownloadmanager.cpp +++ b/mythtv/libs/libmythbase/mythdownloadmanager.cpp @@ -862,12 +862,6 @@ bool MythDownloadManager::downloadNow(MythDownloadInfo *dlInfo, bool deleteInfo) * \param url for download to cancel */ void MythDownloadManager::cancelDownload(const QString &url) -{ - QMetaObject::invokeMethod(this, "downloadCanceled", - Qt::QueuedConnection, Q_ARG(const QString&, url)); -} - -void MythDownloadManager::downloadCanceled(const QString &url) { QMutexLocker locker(m_infoLock); MythDownloadInfo *dlInfo; @@ -879,41 +873,49 @@ void MythDownloadManager::downloadCanceled(const QString &url) dlInfo = lit.value(); if (dlInfo->m_url == url) { - // this shouldn't happen - if (dlInfo->m_reply) - { - LOG(VB_FILE, LOG_DEBUG, - LOC + QString("Aborting download - user request")); - dlInfo->m_reply->abort(); - } + m_cancellationQueue.append(dlInfo); lit.remove(); - if (dlInfo->IsDone()) - continue; - dlInfo->m_lock.lock(); - dlInfo->m_errorCode = QNetworkReply::OperationCanceledError; - dlInfo->m_done = true; - dlInfo->m_lock.unlock(); } } if (m_downloadInfos.contains(url)) { dlInfo = m_downloadInfos[url]; + if (dlInfo->m_reply) + m_downloadReplies.remove(dlInfo->m_reply); + + m_cancellationQueue.append(dlInfo); + m_downloadInfos.remove(url); + } + + QMetaObject::invokeMethod(this, "downloadCanceled", + Qt::QueuedConnection); +} + +void MythDownloadManager::downloadCanceled() +{ + QMutexLocker locker(m_infoLock); + MythDownloadInfo *dlInfo; + + QMutableListIterator lit(m_cancellationQueue); + while (lit.hasNext()) + { + lit.next(); + dlInfo = lit.value(); + // this shouldn't happen if (dlInfo->m_reply) { LOG(VB_FILE, LOG_DEBUG, LOC + QString("Aborting download - user request")); - m_downloadReplies.remove(dlInfo->m_reply); dlInfo->m_reply->abort(); } - m_downloadInfos.remove(url); - if (!dlInfo->IsDone()) - { - dlInfo->m_lock.lock(); - dlInfo->m_errorCode = QNetworkReply::OperationCanceledError; - dlInfo->m_done = true; - dlInfo->m_lock.unlock(); - } + lit.remove(); + if (dlInfo->IsDone()) + continue; + dlInfo->m_lock.lock(); + dlInfo->m_errorCode = QNetworkReply::OperationCanceledError; + dlInfo->m_done = true; + dlInfo->m_lock.unlock(); } } diff --git a/mythtv/libs/libmythbase/mythdownloadmanager.h b/mythtv/libs/libmythbase/mythdownloadmanager.h index 5ed95732508..c49278da276 100644 --- a/mythtv/libs/libmythbase/mythdownloadmanager.h +++ b/mythtv/libs/libmythbase/mythdownloadmanager.h @@ -97,7 +97,7 @@ class MBASE_PUBLIC MythDownloadManager : public QObject, public MThread void downloadError(QNetworkReply::NetworkError errorCode); void downloadProgress(qint64 bytesReceived, qint64 bytesTotal); - void downloadCanceled(const QString &url); + void downloadCanceled(); private: // Notification from RemoteFile downloads @@ -140,6 +140,7 @@ class MBASE_PUBLIC MythDownloadManager : public QObject, public MThread QMap m_downloadInfos; QMap m_downloadReplies; QList m_downloadQueue; + QList m_cancellationQueue; QThread *m_queueThread;