diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/modelresult.cpp | 18 | ||||
-rw-r--r-- | common/resultprovider.h | 10 |
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 | }; |