Skip to content

Commit

Permalink
Ensure cancelling a download is done in the same thread it started
Browse files Browse the repository at this point in the history
This prevent Qt to crash with "Cannot send events to objects owned by a different thread."

Fixes #11663
  • Loading branch information
jyavenard committed Jul 24, 2013
1 parent ea99443 commit 997f7aa
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 8 deletions.
30 changes: 22 additions & 8 deletions mythtv/libs/libmythbase/mythdownloadmanager.cpp
Expand Up @@ -276,12 +276,15 @@ void MythDownloadManager::run(void)
}
m_infoLock->lock();
downloading = !m_downloadInfos.isEmpty();
itemsInQueue = !m_downloadQueue.isEmpty();
m_infoLock->unlock();

if (downloading)
QCoreApplication::processEvents();

m_infoLock->lock();
itemsInQueue = !m_downloadQueue.isEmpty();
m_infoLock->unlock();

if (!itemsInQueue || waitAnyway)
{
waitAnyway = false;
Expand Down Expand Up @@ -835,7 +838,7 @@ bool MythDownloadManager::downloadNow(MythDownloadInfo *dlInfo, bool deleteInfo)
if ((dlInfo->m_reply) &&
(dlInfo->m_errorCode == QNetworkReply::NoError))
{
LOG(VB_FILE, LOG_DEBUG,
LOG(VB_FILE, LOG_DEBUG,
LOC + QString("Aborting download - lack of data transfer"));
dlInfo->m_reply->abort();
}
Expand All @@ -855,6 +858,12 @@ 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;
Expand All @@ -869,11 +878,13 @@ void MythDownloadManager::cancelDownload(const QString &url)
// this shouldn't happen
if (dlInfo->m_reply)
{
LOG(VB_FILE, LOG_DEBUG,
LOG(VB_FILE, LOG_DEBUG,
LOC + QString("Aborting download - user request"));
dlInfo->m_reply->abort();
}
lit.remove();
if (dlInfo->IsDone())
continue;
dlInfo->m_lock.lock();
dlInfo->m_errorCode = QNetworkReply::OperationCanceledError;
dlInfo->m_done = true;
Expand All @@ -886,16 +897,19 @@ void MythDownloadManager::cancelDownload(const QString &url)
dlInfo = m_downloadInfos[url];
if (dlInfo->m_reply)
{
LOG(VB_FILE, LOG_DEBUG,
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);
dlInfo->m_lock.lock();
dlInfo->m_errorCode = QNetworkReply::OperationCanceledError;
dlInfo->m_done = true;
dlInfo->m_lock.unlock();
if (!dlInfo->IsDone())
{
dlInfo->m_lock.lock();
dlInfo->m_errorCode = QNetworkReply::OperationCanceledError;
dlInfo->m_done = true;
dlInfo->m_lock.unlock();
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions mythtv/libs/libmythbase/mythdownloadmanager.h
Expand Up @@ -97,6 +97,8 @@ class MBASE_PUBLIC MythDownloadManager : public QObject, public MThread
void downloadError(QNetworkReply::NetworkError errorCode);
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);

void downloadCanceled(const QString &url);

private:
// Notification from RemoteFile downloads
void downloadFinished(MythDownloadInfo *dlInfo);
Expand Down

0 comments on commit 997f7aa

Please sign in to comment.