MCPcopy Create free account
hub / github.com/3rdparty/libprocess / AwaitProcess

Class AwaitProcess

include/process/collect.hpp:202–267  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

200
201template <typename T>
202class AwaitProcess : public Process<AwaitProcess<T>>
203{
204public:
205 AwaitProcess(
206 const std::vector<Future<T>>& _futures,
207 Promise<std::vector<Future<T>>>* _promise)
208 : ProcessBase(ID::generate("__await__")),
209 futures(_futures),
210 promise(_promise),
211 ready(0) {}
212
213 ~AwaitProcess() override
214 {
215 delete promise;
216 }
217
218 void initialize() override
219 {
220 // Stop this nonsense if nobody cares.
221 promise->future().onDiscard(defer(this, &AwaitProcess::discarded));
222
223 foreach (const Future<T>& future, futures) {
224 future.onAny(defer(this, &AwaitProcess::waited, lambda::_1));
225 future.onAbandoned(defer(this, &AwaitProcess::abandoned));
226 }
227 }
228
229private:
230 void abandoned()
231 {
232 // There is no use waiting because this future will never complete
233 // so terminate this process which will cause `promise` to get
234 // deleted and our future to also be abandoned.
235 terminate(this);
236 }
237
238 void discarded()
239 {
240 foreach (Future<T> future, futures) {
241 future.discard();
242 }
243
244 // NOTE: we discard the promise after we set discard on each of
245 // the futures so that there is a happens-before relationship that
246 // can be assumed by callers.
247 promise->discard();
248
249 terminate(this);
250 }
251
252 void waited(const Future<T>& future)
253 {
254 CHECK(!future.isPending());
255
256 ready += 1;
257 if (ready == futures.size()) {
258 // It is safe to move futures at this point.
259 promise->set(std::move(futures));

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected