summaryrefslogtreecommitdiffstats
path: root/async/src
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2015-01-19 19:22:16 +0100
committerChristian Mollekopf <chrigi_1@fastmail.fm>2015-01-19 19:22:16 +0100
commit65e5a6ac8848750e94e35ec65ac37d0d4a8638cd (patch)
treecf353e8364e40ce5d803f032a22788ccf5d76a75 /async/src
parentf4929574125def1ef006f8fd65c529971d164959 (diff)
downloadsink-65e5a6ac8848750e94e35ec65ac37d0d4a8638cd.tar.gz
sink-65e5a6ac8848750e94e35ec65ac37d0d4a8638cd.zip
Async: Error continuation.
Diffstat (limited to 'async/src')
-rw-r--r--async/src/async.h26
-rw-r--r--async/src/future.h18
2 files changed, 38 insertions, 6 deletions
diff --git a/async/src/async.h b/async/src/async.h
index 8fee0bc..e4b06a9 100644
--- a/async/src/async.h
+++ b/async/src/async.h
@@ -47,6 +47,7 @@ template<typename Out, typename In>
47using EachTask = typename detail::identity<std::function<void(In, Async::Future<Out>&)>>::type; 47using EachTask = typename detail::identity<std::function<void(In, Async::Future<Out>&)>>::type;
48template<typename Out, typename In> 48template<typename Out, typename In>
49using ReduceTask = typename detail::identity<std::function<void(In, Async::Future<Out>&)>>::type; 49using ReduceTask = typename detail::identity<std::function<void(In, Async::Future<Out>&)>>::type;
50using ErrorHandler = std::function<void(int, const QString &)>;
50 51
51namespace Private 52namespace Private
52{ 53{
@@ -93,6 +94,7 @@ protected:
93 void exec(); 94 void exec();
94 95
95 std::function<void(const In& ..., Async::Future<Out> &)> mFunc; 96 std::function<void(const In& ..., Async::Future<Out> &)> mFunc;
97 std::function<void(int, const QString &)> mErrorFunc;
96 Async::Future<PrevOut> *mPrevFuture; 98 Async::Future<PrevOut> *mPrevFuture;
97 Async::FutureWatcher<PrevOut> *mPrevFutureWatcher; 99 Async::FutureWatcher<PrevOut> *mPrevFutureWatcher;
98}; 100};
@@ -101,7 +103,7 @@ template<typename Out, typename ... In>
101class ThenExecutor: public Executor<typename PreviousOut<In ...>::type, Out, In ...> 103class ThenExecutor: public Executor<typename PreviousOut<In ...>::type, Out, In ...>
102{ 104{
103public: 105public:
104 ThenExecutor(ThenTask<Out, In ...> then, ExecutorBase *parent = nullptr); 106 ThenExecutor(ThenTask<Out, In ...> then, ErrorHandler errorHandler = ErrorHandler(), ExecutorBase *parent = nullptr);
105 void previousFutureReady(); 107 void previousFutureReady();
106 108
107private: 109private:
@@ -221,9 +223,9 @@ class Job : public JobBase
221 223
222public: 224public:
223 template<typename OutOther, typename ... InOther> 225 template<typename OutOther, typename ... InOther>
224 Job<OutOther, InOther ...> then(ThenTask<OutOther, InOther ...> func) 226 Job<OutOther, InOther ...> then(ThenTask<OutOther, InOther ...> func, ErrorHandler errorFunc = ErrorHandler())
225 { 227 {
226 return Job<OutOther, InOther ...>(new Private::ThenExecutor<OutOther, InOther ...>(func, mExecutor)); 228 return Job<OutOther, InOther ...>(new Private::ThenExecutor<OutOther, InOther ...>(func, errorFunc, mExecutor));
227 } 229 }
228 230
229 template<typename OutOther, typename InOther> 231 template<typename OutOther, typename InOther>
@@ -309,10 +311,11 @@ void Executor<PrevOut, Out, In ...>::exec()
309} 311}
310 312
311template<typename Out, typename ... In> 313template<typename Out, typename ... In>
312ThenExecutor<Out, In ...>::ThenExecutor(ThenTask<Out, In ...> then, ExecutorBase* parent) 314ThenExecutor<Out, In ...>::ThenExecutor(ThenTask<Out, In ...> then, ErrorHandler error, ExecutorBase* parent)
313 : Executor<typename PreviousOut<In ...>::type, Out, In ...>(parent) 315 : Executor<typename PreviousOut<In ...>::type, Out, In ...>(parent)
314{ 316{
315 this->mFunc = then; 317 this->mFunc = then;
318 this->mErrorFunc = error;
316} 319}
317 320
318template<typename Out, typename ... In> 321template<typename Out, typename ... In>
@@ -321,8 +324,19 @@ void ThenExecutor<Out, In ...>::previousFutureReady()
321 if (this->mPrevFuture) { 324 if (this->mPrevFuture) {
322 assert(this->mPrevFuture->isFinished()); 325 assert(this->mPrevFuture->isFinished());
323 } 326 }
324 this->mFunc(this->mPrevFuture ? this->mPrevFuture->value() : In() ..., 327 if (this->mPrevFuture && this->mPrevFuture->errorCode()) {
325 *static_cast<Async::Future<Out>*>(this->mResult)); 328 if (this->mErrorFunc) {
329 this->mErrorFunc(this->mPrevFuture->errorCode(), this->mPrevFuture->errorMessage());
330 } else {
331 static_cast<Async::Future<Out>*>(this->mResult)->setError(this->mPrevFuture->errorCode(), this->mPrevFuture->errorMessage());
332 //propagate error if no error handler is available
333 this->mFunc(this->mPrevFuture ? this->mPrevFuture->value() : In() ...,
334 *static_cast<Async::Future<Out>*>(this->mResult));
335 }
336 } else {
337 this->mFunc(this->mPrevFuture ? this->mPrevFuture->value() : In() ...,
338 *static_cast<Async::Future<Out>*>(this->mResult));
339 }
326} 340}
327 341
328template<typename PrevOut, typename Out, typename In> 342template<typename PrevOut, typename Out, typename In>
diff --git a/async/src/future.h b/async/src/future.h
index 54580ad..098f6e8 100644
--- a/async/src/future.h
+++ b/async/src/future.h
@@ -36,6 +36,7 @@ public:
36 36
37 virtual void setFinished() = 0; 37 virtual void setFinished() = 0;
38 virtual bool isFinished() const = 0; 38 virtual bool isFinished() const = 0;
39 virtual void setError(int code = 1, const QString &message = QString()) = 0;
39 40
40protected: 41protected:
41 FutureBase(); 42 FutureBase();
@@ -69,6 +70,23 @@ public:
69 return d->finished; 70 return d->finished;
70 } 71 }
71 72
73 void setError(int errorCode, const QString &message)
74 {
75 d->errorCode = errorCode;
76 d->errorMessage = message;
77 setFinished();
78 }
79
80 int errorCode() const
81 {
82 return d->errorCode;
83 }
84
85 QString errorMessage() const
86 {
87 return d->errorMessage;
88 }
89
72 void waitForFinished() 90 void waitForFinished()
73 { 91 {
74 if (isFinished()) { 92 if (isFinished()) {