Fenix @develop
 
Loading...
Searching...
No Matches
task.hpp
1#ifndef FENIX_TASKS_TASK_HPP
2#define FENIX_TASKS_TASK_HPP
3
4#include <cassert>
5#include <memory>
6
7#include "promise.hpp"
8#include "request.hpp"
9#include "forward.hpp"
10
11namespace fenix::tasks {
12
13// WARNING: eager tasks can cause gross double free errors, due to some
14// early wonkiness in the C++ spec and in compiler implementations
15template <typename T, bool eager /*= false*/>
16class Task {
17 public:
19 using TaskT = Task<T, eager>;
20 using promise_type = PromiseT;
22 PromiseHolder() = delete;
23 PromiseHolder(PromiseT* p) : promise(p) {
24 promise->register_owning_ptr(&promise);
25 }
27 if (promise) promise->destroy();
28 }
29 PromiseT* operator->() { return promise; }
30 PromiseT* promise;
31 };
32
33 Task() = default;
34 Task(PromiseT* p) : prom(std::make_shared<PromiseHolder>(p)) {};
35
36 // Copy and move support
37 TaskT& operator=(const TaskT& o) {
38 prom = o.prom;
39 return *this;
40 }
41 TaskT& operator=(TaskT&& o) {
42 *this = o;
43 TaskT t{};
44 o = t;
45 return *this;
46 }
47 Task(const TaskT& o) { *this = o; };
48 Task(TaskT&& o) noexcept { *this = std::move(o); };
49
50 operator bool() const { return (bool)prom; };
51
52 bool done() const { return promise().done(); }
53 virtual void resume() { promise().resume(); }
54 virtual void wait() { promise().wait(); }
55
56 auto result() {
57 this->wait();
58 return promise().result();
59 }
60
61 private:
62 mutable std::shared_ptr<PromiseHolder> prom;
63 PromiseT& promise() const {
64 assert(prom);
65 return *(prom->promise);
66 }
67};
68
69template <typename T>
70using LazyTask = Task<T, false>;
71
72} // namespace fenix::tasks
73
74#endif // FENIX_TASKS_TASK_HPP
Definition promise.hpp:31
Definition task.hpp:16
Definition task.hpp:21