summaryrefslogtreecommitdiffstats
path: root/common/resultprovider.h
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2017-01-31 19:01:10 +0100
committerChristian Mollekopf <chrigi_1@fastmail.fm>2017-01-31 19:38:57 +0100
commita910706986aa8e83e070d23525c02649d80c05c3 (patch)
treed31cf91bdfbaf47ed750a744000327f0f8d45f2a /common/resultprovider.h
parent546d86aae7cd0b9766f3a0ea73f3777334d55814 (diff)
downloadsink-a910706986aa8e83e070d23525c02649d80c05c3.tar.gz
sink-a910706986aa8e83e070d23525c02649d80c05c3.zip
Don't call into the model after the model has been destroyed.
Diffstat (limited to 'common/resultprovider.h')
-rw-r--r--common/resultprovider.h60
1 files changed, 51 insertions, 9 deletions
diff --git a/common/resultprovider.h b/common/resultprovider.h
index cda4dac..86138db 100644
--- a/common/resultprovider.h
+++ b/common/resultprovider.h
@@ -22,6 +22,8 @@
22 22
23#include <functional> 23#include <functional>
24#include <memory> 24#include <memory>
25#include <QMutexLocker>
26#include <QPointer>
25 27
26namespace Sink { 28namespace Sink {
27 29
@@ -82,21 +84,21 @@ public:
82 void add(const T &value) 84 void add(const T &value)
83 { 85 {
84 if (auto strongRef = mResultEmitter.toStrongRef()) { 86 if (auto strongRef = mResultEmitter.toStrongRef()) {
85 strongRef->addHandler(value); 87 strongRef->add(value);
86 } 88 }
87 } 89 }
88 90
89 void modify(const T &value) 91 void modify(const T &value)
90 { 92 {
91 if (auto strongRef = mResultEmitter.toStrongRef()) { 93 if (auto strongRef = mResultEmitter.toStrongRef()) {
92 strongRef->modifyHandler(value); 94 strongRef->modify(value);
93 } 95 }
94 } 96 }
95 97
96 void remove(const T &value) 98 void remove(const T &value)
97 { 99 {
98 if (auto strongRef = mResultEmitter.toStrongRef()) { 100 if (auto strongRef = mResultEmitter.toStrongRef()) {
99 strongRef->removeHandler(value); 101 strongRef->remove(value);
100 } 102 }
101 } 103 }
102 104
@@ -194,6 +196,15 @@ public:
194 196
195 virtual ~ResultEmitter() 197 virtual ~ResultEmitter()
196 { 198 {
199 //Try locking in case we're in the middle of an execution in another thread
200 QMutexLocker locker{&mMutex};
201 }
202
203 virtual void waitForMethodExecutionEnd()
204 {
205 //If we're in the middle of a method execution, this will block until the method is done.
206 QMutexLocker locker{&mMutex};
207 mDone = true;
197 } 208 }
198 209
199 void onAdded(const std::function<void(const DomainType &)> &handler) 210 void onAdded(const std::function<void(const DomainType &)> &handler)
@@ -226,38 +237,55 @@ public:
226 clearHandler = handler; 237 clearHandler = handler;
227 } 238 }
228 239
240 bool guardOk()
241 {
242 return !mDone;
243 }
244
229 void add(const DomainType &value) 245 void add(const DomainType &value)
230 { 246 {
231 addHandler(value); 247 QMutexLocker locker{&mMutex};
248 if (guardOk()) {
249 addHandler(value);
250 }
232 } 251 }
233 252
234 void modify(const DomainType &value) 253 void modify(const DomainType &value)
235 { 254 {
236 modifyHandler(value); 255 QMutexLocker locker{&mMutex};
256 if (guardOk()) {
257 modifyHandler(value);
258 }
237 } 259 }
238 260
239 void remove(const DomainType &value) 261 void remove(const DomainType &value)
240 { 262 {
241 removeHandler(value); 263 QMutexLocker locker{&mMutex};
264 if (guardOk()) {
265 removeHandler(value);
266 }
242 } 267 }
243 268
244 void initialResultSetComplete(const DomainType &parent, bool replayedAll) 269 void initialResultSetComplete(const DomainType &parent, bool replayedAll)
245 { 270 {
246 if (initialResultSetCompleteHandler) { 271 QMutexLocker locker{&mMutex};
272 if (initialResultSetCompleteHandler && guardOk()) {
247 initialResultSetCompleteHandler(parent, replayedAll); 273 initialResultSetCompleteHandler(parent, replayedAll);
248 } 274 }
249 } 275 }
250 276
251 void complete() 277 void complete()
252 { 278 {
253 if (completeHandler) { 279 QMutexLocker locker{&mMutex};
280 if (completeHandler && guardOk()) {
254 completeHandler(); 281 completeHandler();
255 } 282 }
256 } 283 }
257 284
258 void clear() 285 void clear()
259 { 286 {
260 if (clearHandler) { 287 QMutexLocker locker{&mMutex};
288 if (clearHandler && guardOk()) {
261 clearHandler(); 289 clearHandler();
262 } 290 }
263 } 291 }
@@ -285,6 +313,8 @@ private:
285 std::function<void(void)> clearHandler; 313 std::function<void(void)> clearHandler;
286 314
287 std::function<void(const DomainType &parent)> mFetcher; 315 std::function<void(const DomainType &parent)> mFetcher;
316 QMutex mMutex;
317 bool mDone = false;
288}; 318};
289 319
290template <class DomainType> 320template <class DomainType>
@@ -293,6 +323,18 @@ class AggregatingResultEmitter : public ResultEmitter<DomainType>
293public: 323public:
294 typedef QSharedPointer<AggregatingResultEmitter<DomainType>> Ptr; 324 typedef QSharedPointer<AggregatingResultEmitter<DomainType>> Ptr;
295 325
326 ~AggregatingResultEmitter()
327 {
328 }
329
330 virtual void waitForMethodExecutionEnd() Q_DECL_OVERRIDE
331 {
332 for (const auto &emitter : mEmitter) {
333 emitter->waitForMethodExecutionEnd();
334 }
335 ResultEmitter<DomainType>::waitForMethodExecutionEnd();
336 }
337
296 void addEmitter(const typename ResultEmitter<DomainType>::Ptr &emitter) 338 void addEmitter(const typename ResultEmitter<DomainType>::Ptr &emitter)
297 { 339 {
298 Q_ASSERT(emitter); 340 Q_ASSERT(emitter);