forked from infinit/elle
-
Notifications
You must be signed in to change notification settings - Fork 0
/
BackgroundFuture.hxx
108 lines (96 loc) · 2.37 KB
/
BackgroundFuture.hxx
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
#include <elle/utils.hh>
#include <elle/log.hh>
#include <elle/reactor/scheduler.hh>
namespace elle
{
namespace reactor
{
template <typename T>
template <typename>
BackgroundFuture<T>::BackgroundFuture()
: _operation()
, _value()
{
this->_value.emplace();
}
template <typename T>
BackgroundFuture<T>::BackgroundFuture(T value)
: _operation()
, _value(std::move(value))
{}
template <typename T>
BackgroundFuture<T>::BackgroundFuture(Action action)
: _operation(std::move(action))
, _value()
{
this->_operation->start();
}
template <typename T>
BackgroundFuture<T>::BackgroundFuture(BackgroundFuture<T> const& src)
: _operation()
, _value(src.value())
{}
template <typename T>
BackgroundFuture<T>::~BackgroundFuture()
{}
template <typename T>
BackgroundFuture<T>&
BackgroundFuture<T>::operator =(Action action)
{
this->_operation.reset();
this->_value.reset();
this->_operation.emplace(std::move(action));
this->_operation->start();
return *this;
}
template <typename T>
BackgroundFuture<T>&
BackgroundFuture<T>::operator =(T value)
{
this->_operation.reset();
this->_value.reset();
this->_value.emplace(std::move(value));
return *this;
}
template <typename T>
T const&
BackgroundFuture<T>::value() const
{
return elle::unconst(this)->value();
}
template <typename T>
T&
BackgroundFuture<T>::value()
{
this->_resolve();
return this->_value.get();
}
template <typename T>
void
BackgroundFuture<T>::_resolve()
{
ELLE_LOG_COMPONENT("elle.reactor.BackgroundFuture");
if (this->_operation)
{
ELLE_TRACE_SCOPE("%s: join", *this);
if (this->_operation->running())
reactor::wait(this->_operation.get());
if (!this->_operation) // an other thread called _resolve and reset it
ELLE_ASSERT(this->_value);
else
{
this->_value.emplace(std::move(this->_operation->result().get()));
this->_operation.reset();
}
}
ELLE_ASSERT(!this->_operation);
ELLE_ASSERT(this->_value);
}
template <typename T>
bool
BackgroundFuture<T>::running() const
{
return !this->_value;
}
}
}