From 37c515bcb5dff500d5795a9cbe3ca08a5187b710 Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 15 Oct 2018 20:57:21 +0200 Subject: [PATCH] patch from sss to fix deadlocks on forum fill thread. To be tested --- .../gui/gxsforums/GxsForumThreadWidget.cpp | 1 - .../src/gui/gxsforums/GxsForumsFillThread.cpp | 75 ++++++++++++++++++- 2 files changed, 71 insertions(+), 5 deletions(-) diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp index 2b72f3f39..e050c7ce2 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp @@ -1438,7 +1438,6 @@ void GxsForumThreadWidget::insertThreads() GxsForumsFillThread *thread = mFillThread; mFillThread = NULL; thread->stop(); - delete(thread); mStateHelper->setLoading(mTokenTypeInsertThreads, false); } diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumsFillThread.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumsFillThread.cpp index a0228f671..dca70d165 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumsFillThread.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumsFillThread.cpp @@ -74,7 +74,6 @@ void GxsForumsFillThread::stop() disconnect(); mStopped = true; QApplication::processEvents(); - wait(); } void GxsForumsFillThread::calculateExpand(const RsGxsForumMsg &msg, QTreeWidgetItem *item) @@ -125,7 +124,10 @@ void GxsForumsFillThread::run() } if (requestStatus == RsTokenService::FAILED) + { + deleteLater(); return; + } } // also get the forum meta data. @@ -154,7 +156,10 @@ void GxsForumsFillThread::run() } if (requestStatus == RsTokenService::FAILED) + { + deleteLater(); return; + } } if (wasStopped()) @@ -166,6 +171,7 @@ void GxsForumsFillThread::run() /* cancel request */ service->cancelRequest(msg_token); service->cancelRequest(grp_token); + deleteLater(); return; } @@ -174,7 +180,10 @@ void GxsForumsFillThread::run() std::vector forum_groups; if (!rsGxsForums->getGroupData(grp_token, forum_groups) || forum_groups.size() != 1) + { + deleteLater(); return; + } RsGxsForumGroup forum_group = *forum_groups.begin(); @@ -197,7 +206,10 @@ void GxsForumsFillThread::run() std::vector msgs_array; if (!rsGxsForums->getMsgData(msg_token, msgs_array)) + { + deleteLater(); return; + } // now put everything into a map in order to make search log(n) @@ -240,6 +252,12 @@ void GxsForumsFillThread::run() std::list msg_stack ; for ( std::map::iterator msgIt = msgs.begin(); msgIt != msgs.end();++msgIt) + { + if(wasStopped()) + { + deleteLater(); + return; + } if(!msgIt->second.mMeta.mOrigMsgId.isNull() && msgIt->second.mMeta.mOrigMsgId != msgIt->second.mMeta.mMsgId) { #ifdef DEBUG_FORUMS @@ -271,14 +289,26 @@ void GxsForumsFillThread::run() mPostVersions[msgIt->second.mMeta.mOrigMsgId].push_back(QPair(msgIt->second.mMeta.mPublishTs,msgIt->second.mMeta.mMsgId)) ; } + } // The following code assembles all new versions of a given post into the same array, indexed by the oldest version of the post. for(QMap > >::iterator it(mPostVersions.begin());it!=mPostVersions.end();++it) { + if(wasStopped()) + { + deleteLater(); + return; + } QVector >& v(*it) ; for(int32_t i=0;i::iterator msgIt = msgs.begin(); msgIt != msgs.end();++msgIt) { + if (wasStopped()) + { + deleteLater(); + return; + } if(mFlatView || msgIt->second.mMeta.mParentId.isNull()) { /* add all threads */ if (wasStopped()) + { + deleteLater(); return; + } const RsGxsForumMsg& msg = msgIt->second; @@ -422,7 +478,13 @@ void GxsForumsFillThread::run() while (!threadStack.empty()) { - std::pair threadPair = threadStack.front(); + if (wasStopped()) + { + deleteLater(); + return; + } + + std::pair threadPair = threadStack.front(); threadStack.pop_front(); std::map >::iterator it = kids_array.find(threadPair.first) ; @@ -433,11 +495,14 @@ void GxsForumsFillThread::run() if(it == kids_array.end()) continue ; - if (wasStopped()) - return; for(std::list::const_iterator it2(it->second.begin());it2!=it->second.end();++it2) { + if(wasStopped()) + { + deleteLater(); + return; + } // We iterate through the top level thread items, and look for which message has the current item as parent. // When found, the item is put in the thread list itself, as a potential new parent. @@ -485,6 +550,8 @@ void GxsForumsFillThread::run() std::cerr << "GxsForumsFillThread::run() stopped: " << (wasStopped() ? "yes" : "no") << std::endl; #endif + if(wasStopped()) + deleteLater(); }