summaryrefslogtreecommitdiffstats
path: root/async/src/future.h
diff options
context:
space:
mode:
authorDan Vrátil <dvratil@redhat.com>2015-04-01 21:02:34 +0200
committerDan Vrátil <dvratil@redhat.com>2015-04-01 21:19:48 +0200
commitb01fadba903056218f2a00c5e62e1dc8df062124 (patch)
treeadca72675973ab5d8253ab14ff94949824d6523e /async/src/future.h
parent94729eef71570e0b792a9afb95eeab7fd1eec56b (diff)
downloadsink-b01fadba903056218f2a00c5e62e1dc8df062124.tar.gz
sink-b01fadba903056218f2a00c5e62e1dc8df062124.zip
Async: support (re-)executing single Job multiple times
Storing Future and current Job progress directly in Executors means that we cannot re-execute finished job, or even execute the same Job multiple times in parallel. To do so, we need to make Executors stateless and track the state elsewhere. This change does that by moving the execution state from Executor to Execution class. Executors now only describe the tasks to execute, while Execution holds the current state of execution. New Execution is created every time Job::exec() is called. Execution holds reference to it's result (Future) and Executor which created the Execution. This ensures that Executor is not deleted when Job (which owns Executors) goes out of scope while the execution is still running. At the same time Future holds reference to relevant Execution, so that the Execution is deleted when all copies of Future referring result from the respective Execution are deleted.
Diffstat (limited to 'async/src/future.h')
-rw-r--r--async/src/future.h71
1 files changed, 63 insertions, 8 deletions
diff --git a/async/src/future.h b/async/src/future.h
index b580b5a..cadd96d 100644
--- a/async/src/future.h
+++ b/async/src/future.h
@@ -29,8 +29,18 @@ class QEventLoop;
29 29
30namespace Async { 30namespace Async {
31 31
32namespace Private {
33class Execution;
34class ExecutorBase;
35
36typedef QSharedPointer<Execution> ExecutionPtr;
37
38}
39
32class FutureBase 40class FutureBase
33{ 41{
42 friend class Async::Private::Execution;
43
34public: 44public:
35 virtual ~FutureBase(); 45 virtual ~FutureBase();
36 46
@@ -39,6 +49,20 @@ public:
39 virtual void setError(int code = 1, const QString &message = QString()) = 0; 49 virtual void setError(int code = 1, const QString &message = QString()) = 0;
40 50
41protected: 51protected:
52 virtual void releaseExecution() = 0;
53
54 class PrivateBase : public QSharedData
55 {
56 public:
57 PrivateBase(const Async::Private::ExecutionPtr &execution);
58 virtual ~PrivateBase();
59
60 void releaseExecution();
61
62 private:
63 QWeakPointer<Async::Private::Execution> mExecution;
64 };
65
42 FutureBase(); 66 FutureBase();
43 FutureBase(const FutureBase &other); 67 FutureBase(const FutureBase &other);
44}; 68};
@@ -104,9 +128,9 @@ public:
104 } 128 }
105 129
106protected: 130protected:
107 FutureGeneric() 131 FutureGeneric(const Async::Private::ExecutionPtr &execution)
108 : FutureBase() 132 : FutureBase()
109 , d(new Private) 133 , d(new Private(execution))
110 {} 134 {}
111 135
112 FutureGeneric(const FutureGeneric<T> &other) 136 FutureGeneric(const FutureGeneric<T> &other)
@@ -114,10 +138,15 @@ protected:
114 , d(other.d) 138 , d(other.d)
115 {} 139 {}
116 140
117 class Private : public QSharedData 141 class Private : public FutureBase::PrivateBase
118 { 142 {
119 public: 143 public:
120 Private() : QSharedData(), finished(false), errorCode(0) {} 144 Private(const Async::Private::ExecutionPtr &execution)
145 : FutureBase::PrivateBase(execution)
146 , finished(false)
147 , errorCode(0)
148 {}
149
121 typename std::conditional<std::is_void<T>::value, int /* dummy */, T>::type 150 typename std::conditional<std::is_void<T>::value, int /* dummy */, T>::type
122 value; 151 value;
123 152
@@ -129,6 +158,11 @@ protected:
129 158
130 QExplicitlySharedDataPointer<Private> d; 159 QExplicitlySharedDataPointer<Private> d;
131 160
161 void releaseExecution()
162 {
163 d->releaseExecution();
164 }
165
132 void addWatcher(FutureWatcher<T> *watcher) 166 void addWatcher(FutureWatcher<T> *watcher)
133 { 167 {
134 d->watchers.append(QPointer<FutureWatcher<T>>(watcher)); 168 d->watchers.append(QPointer<FutureWatcher<T>>(watcher));
@@ -138,9 +172,14 @@ protected:
138template<typename T> 172template<typename T>
139class Future : public FutureGeneric<T> 173class Future : public FutureGeneric<T>
140{ 174{
175 friend class Async::Private::ExecutorBase;
176
177 template<typename T_>
178 friend class Async::FutureWatcher;
179
141public: 180public:
142 Future() 181 Future()
143 : FutureGeneric<T>() 182 : FutureGeneric<T>(Async::Private::ExecutionPtr())
144 {} 183 {}
145 184
146 Future(const Future<T> &other) 185 Future(const Future<T> &other)
@@ -156,19 +195,35 @@ public:
156 { 195 {
157 return this->d->value; 196 return this->d->value;
158 } 197 }
198
199protected:
200 Future(const Async::Private::ExecutionPtr &execution)
201 : FutureGeneric<T>(execution)
202 {}
203
159}; 204};
160 205
161template<> 206template<>
162class Future<void> : public FutureGeneric<void> 207class Future<void> : public FutureGeneric<void>
163{ 208{
209 friend class Async::Private::ExecutorBase;
210
211 template<typename T_>
212 friend class Async::FutureWatcher;
213
164public: 214public:
165 Future() 215 Future()
166 : FutureGeneric<void>() 216 : FutureGeneric<void>(Async::Private::ExecutionPtr())
167 {} 217 {}
168 218
169 Future(const Future<void> &other) 219 Future(const Future<void> &other)
170 : FutureGeneric<void>(other) 220 : FutureGeneric<void>(other)
171 {} 221 {}
222
223protected:
224 Future(const Async::Private::ExecutionPtr &execution)
225 : FutureGeneric<void>(execution)
226 {}
172}; 227};
173 228
174 229
@@ -177,7 +232,7 @@ class FutureWatcherBase : public QObject
177 Q_OBJECT 232 Q_OBJECT
178 233
179protected: 234protected:
180 FutureWatcherBase(QObject *parent = 0); 235 FutureWatcherBase(QObject *parent = nullptr);
181 virtual ~FutureWatcherBase(); 236 virtual ~FutureWatcherBase();
182 237
183Q_SIGNALS: 238Q_SIGNALS:
@@ -190,7 +245,7 @@ class FutureWatcher : public FutureWatcherBase
190 friend class Async::FutureGeneric<T>; 245 friend class Async::FutureGeneric<T>;
191 246
192public: 247public:
193 FutureWatcher(QObject *parent = 0) 248 FutureWatcher(QObject *parent = nullptr)
194 : FutureWatcherBase(parent) 249 : FutureWatcherBase(parent)
195 {} 250 {}
196 251