From 378d04837cb0033031f26269b1194855870ee1d6 Mon Sep 17 00:00:00 2001
From: Christian Kandeler <christian.kandeler@digia.com>
Date: Fri, 19 Sep 2014 13:48:07 +0200
Subject: [PATCH] Fix crash when accessing the content model.

1) Make sure invalidateContents() is called whenever the help engine's
   DB readers are destroyed.
2) In QHelpContentProvider::stopCollecting(), remove all root items, as
   they are invalid now: Their child items reference DB readers that
   are going to be destroyed.

Task-number: QTBUG-18829
Change-Id: Id9cc4ea99c43c36ad5c5d1f04157a68bac79d44a
Reviewed-by: Karsten Heimrich <karsten.heimrich@digia.com>
---
 src/assistant/help/qhelpcontentwidget.cpp | 20 +++++++++++++-------
 src/assistant/help/qhelpenginecore.cpp    |  1 +
 src/assistant/help/qhelpenginecore.h      |  1 +
 src/assistant/help/qhelpindexwidget.cpp   |  2 +-
 4 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/src/assistant/help/qhelpcontentwidget.cpp b/src/assistant/help/qhelpcontentwidget.cpp
index cf3838c2b..b3c7c9c1b 100644
--- a/src/assistant/help/qhelpcontentwidget.cpp
+++ b/src/assistant/help/qhelpcontentwidget.cpp
@@ -220,22 +220,28 @@ void QHelpContentProvider::collectContents(const QString &customFilterName)
 
 void QHelpContentProvider::stopCollecting()
 {
-    if (!isRunning())
-        return;
-    m_mutex.lock();
-    m_abort = true;
-    m_mutex.unlock();
-    wait();
+    if (isRunning()) {
+        m_mutex.lock();
+        m_abort = true;
+        m_mutex.unlock();
+        wait();
+    }
+    qDeleteAll(m_rootItems);
+    m_rootItems.clear();
 }
 
 QHelpContentItem *QHelpContentProvider::rootItem()
 {
     QMutexLocker locker(&m_mutex);
+    if (m_rootItems.isEmpty())
+        return 0;
     return m_rootItems.dequeue();
 }
 
 int QHelpContentProvider::nextChildCount() const
 {
+    if (m_rootItems.isEmpty())
+        return 0;
     return m_rootItems.head()->childCount();
 }
 
@@ -349,7 +355,7 @@ QHelpContentModel::QHelpContentModel(QHelpEnginePrivate *helpEngine)
 
     connect(d->qhelpContentProvider, SIGNAL(finished()),
         this, SLOT(insertContents()), Qt::QueuedConnection);
-    connect(helpEngine->q, SIGNAL(setupStarted()), this, SLOT(invalidateContents()));
+    connect(helpEngine->q, SIGNAL(readersAboutToBeInvalidated()), this, SLOT(invalidateContents()));
 }
 
 /*!
diff --git a/src/assistant/help/qhelpenginecore.cpp b/src/assistant/help/qhelpenginecore.cpp
index a2aeb73ed..3d5ba60a1 100644
--- a/src/assistant/help/qhelpenginecore.cpp
+++ b/src/assistant/help/qhelpenginecore.cpp
@@ -79,6 +79,7 @@ QHelpEngineCorePrivate::~QHelpEngineCorePrivate()
 
 void QHelpEngineCorePrivate::clearMaps()
 {
+    emit q->readersAboutToBeInvalidated();
     QMap<QString, QHelpDBReader*>::iterator it = readerMap.begin();
     while (it != readerMap.end()) {
         delete it.value();
diff --git a/src/assistant/help/qhelpenginecore.h b/src/assistant/help/qhelpenginecore.h
index 202b1850d..17e5dec25 100644
--- a/src/assistant/help/qhelpenginecore.h
+++ b/src/assistant/help/qhelpenginecore.h
@@ -116,6 +116,7 @@ Q_SIGNALS:
     void setupFinished();
     void currentFilterChanged(const QString &newFilter);
     void warning(const QString &msg);
+    void readersAboutToBeInvalidated();
 
 protected:
     QHelpEngineCore(QHelpEngineCorePrivate *helpEngineCorePrivate,
diff --git a/src/assistant/help/qhelpindexwidget.cpp b/src/assistant/help/qhelpindexwidget.cpp
index 64c2e0538..61f7841ea 100644
--- a/src/assistant/help/qhelpindexwidget.cpp
+++ b/src/assistant/help/qhelpindexwidget.cpp
@@ -232,7 +232,7 @@ QHelpIndexModel::QHelpIndexModel(QHelpEnginePrivate *helpEngine)
     d = new QHelpIndexModelPrivate(helpEngine);
 
     connect(d->indexProvider, SIGNAL(finished()), this, SLOT(insertIndices()));
-    connect(helpEngine->q, SIGNAL(setupStarted()), this, SLOT(invalidateIndex()));
+    connect(helpEngine->q, SIGNAL(readersAboutToBeInvalidated()), this, SLOT(invalidateIndex()));
 }
 
 QHelpIndexModel::~QHelpIndexModel()
-- 
GitLab