summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/modelresult.cpp18
-rw-r--r--common/resultprovider.h10
2 files changed, 18 insertions, 10 deletions
diff --git a/common/modelresult.cpp b/common/modelresult.cpp
index f935419..904766d 100644
--- a/common/modelresult.cpp
+++ b/common/modelresult.cpp
@@ -296,15 +296,15 @@ void ModelResult<T, Ptr>::setEmitter(const typename Sink::ResultEmitter<Ptr>::Pt
296 emitter->onInitialResultSetComplete([this, guard](const Ptr &parent, bool fetchedAll) { 296 emitter->onInitialResultSetComplete([this, guard](const Ptr &parent, bool fetchedAll) {
297 SinkTraceCtx(mLogCtx) << "Initial result set complete. Fetched all: " << fetchedAll; 297 SinkTraceCtx(mLogCtx) << "Initial result set complete. Fetched all: " << fetchedAll;
298 Q_ASSERT(guard); 298 Q_ASSERT(guard);
299 threadBoundary.callInMainThread([=]() { 299 Q_ASSERT(QThread::currentThread() == this->thread());
300 const qint64 parentId = parent ? qHash(*parent) : 0; 300
301 const auto parentIndex = createIndexFromId(parentId); 301 const qint64 parentId = parent ? qHash(*parent) : 0;
302 mEntityChildrenFetchComplete.insert(parentId); 302 const auto parentIndex = createIndexFromId(parentId);
303 if (fetchedAll) { 303 mEntityChildrenFetchComplete.insert(parentId);
304 mEntityAllChildrenFetched.insert(parentId); 304 if (fetchedAll) {
305 } 305 mEntityAllChildrenFetched.insert(parentId);
306 emit dataChanged(parentIndex, parentIndex, QVector<int>() << ChildrenFetchedRole); 306 }
307 }); 307 emit dataChanged(parentIndex, parentIndex, QVector<int>() << ChildrenFetchedRole);
308 }); 308 });
309 mEmitter = emitter; 309 mEmitter = emitter;
310} 310}
diff --git a/common/resultprovider.h b/common/resultprovider.h
index a2ed0b5..d6feaf9 100644
--- a/common/resultprovider.h
+++ b/common/resultprovider.h
@@ -268,8 +268,9 @@ public:
268 268
269 void initialResultSetComplete(const DomainType &parent, bool replayedAll) 269 void initialResultSetComplete(const DomainType &parent, bool replayedAll)
270 { 270 {
271 QMutexLocker locker{&mMutex}; 271 //This callback is only ever called from the main thread, so we don't do any locking
272 if (initialResultSetCompleteHandler && guardOk()) { 272 if (initialResultSetCompleteHandler && guardOk()) {
273 //This can directly lead to our destruction and thus waitForMethodExecutionEnd
273 initialResultSetCompleteHandler(parent, replayedAll); 274 initialResultSetCompleteHandler(parent, replayedAll);
274 } 275 }
275 } 276 }
@@ -313,6 +314,13 @@ private:
313 std::function<void(void)> clearHandler; 314 std::function<void(void)> clearHandler;
314 315
315 std::function<void(const DomainType &parent)> mFetcher; 316 std::function<void(const DomainType &parent)> mFetcher;
317 /*
318 * This mutex is here to protect the emitter from getting destroyed while the producer-thread (ResultProvider) is calling into it,
319 * and vice-verca, to protect the producer thread from calling into a destroyed emitter.
320 *
321 * This is necessary because Emitter and ResultProvider have lifetimes managed by two different threads.
322 * The emitter lives in the application thread, and the resultprovider in the query thread.
323 */
316 QMutex mMutex; 324 QMutex mMutex;
317 bool mDone = false; 325 bool mDone = false;
318}; 326};