-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathabstract_task.hpp
111 lines (80 loc) · 2.42 KB
/
abstract_task.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#ifndef __ABSTRACT_TASK_H__
#define __ABSTRACT_TASK_H__
#include <boost/context/execution_context.hpp>
#include <utility>
#include <memory>
#include <future>
#include "scheduler.hpp"
#include "future.hpp"
namespace cosche
{
class AbstractTask;
typedef boost::context::execution_context<AbstractTask*> Context;
class AbstractTask
{
friend Scheduler;
public:
AbstractTask(Scheduler& scheduler);
AbstractTask(Scheduler&& scheduler) = delete;
virtual void run() = 0;
virtual void recycle() = 0;
virtual std::size_t id() const = 0;
void attach(AbstractTask& task);
void detach(AbstractTask& task);
void release();
void onCycle();
Scheduler& scheduler() const;
template <class E>
void throwing(const E& e)
{
try
{
throw e;
}
catch (...)
{
_scheduler._throwing = std::current_exception();
}
}
template <class Fn, class... Args>
void onCycle(Fn&& fn, Args&&... args)
{
*_onCycle = std::packaged_task<void()>(std::bind(fn, args...));
}
template <class T>
T wait(std::future<T>&& future)
{
if (_scheduler.running())
{
_scheduler.haltWaitingFuture(
std::make_shared<Future<T>>(std::move(future)),
this);
*_context = std::get<0>((*_context)(this));
}
return static_cast<Future<T>&>(*_future).get();
}
template <class Rep, class Period, class T>
std::future<T>& waitFor(const std::chrono::duration<Rep,Period>& timeoutDuration,
std::future<T>&& future)
{
if (_scheduler.running())
{
_scheduler.haltWaitingFuture(
std::make_shared<ScopedFuture<T>>(std::move(future),
timeoutDuration),
this);
*_context = std::get<0>((*_context)(this));
}
return static_cast<std::future<T>&>(
static_cast<ScopedFuture<T>&>(*_future)
);
}
static Context start(Context context, AbstractTask* task);
private:
Scheduler& _scheduler;
std::shared_ptr<Context> _context;
std::shared_ptr<AbstractFuture> _future;
std::shared_ptr<std::packaged_task<void()>> _onCycle;
};
} // end cosche namespace
#endif // __ABSTRACT_TASK_H__