YACLib
C++ library for concurrent tasks execution
Loading...
Searching...
No Matches
shared_core.hpp
Go to the documentation of this file.
1
#pragma once
2
3
#include <
yaclib/algo/detail/result_core.hpp
>
4
#include <
yaclib/async/future.hpp
>
5
#include <
yaclib/async/promise.hpp
>
6
#include <
yaclib/exe/executor.hpp
>
7
#include <
yaclib/fwd.hpp
>
8
#include <
yaclib/util/ref.hpp
>
9
10
#include <atomic>
11
12
namespace
yaclib
{
13
namespace
detail {
14
15
template
<
typename
V,
typename
E>
16
class
SharedCore
:
public
IRef
{
17
using
ResultCoreType
=
ResultCore<V, E>
;
18
19
public
:
20
SharedCore
()
noexcept
{}
21
22
void
Attach
(
Promise<V, E>
&&
p
) {
23
ResultCoreType
*
core
=
p
.GetCore().
Get
();
24
ResultCoreType
* next = _head.load(std::memory_order_acquire);
25
do
{
26
if
(
reinterpret_cast<
std::uintptr_t
>
(next) == kSet) {
27
std::move(
p
).Set(
_result
);
28
break
;
29
}
30
core
->next = next;
31
}
while
(!_head.compare_exchange_weak(next,
core
, std::memory_order_release, std::memory_order_acquire));
32
p
.GetCore().Release();
33
}
34
35
template
<
typename
...
Args
>
36
void
Set
(
Args
&&...
args
) {
37
new
(&
_result
)
Result<V, E>
{std::forward<Args>(
args
)...};
38
39
auto
head
= _head.exchange(
reinterpret_cast<
ResultCoreType
*
>
(kSet), std::memory_order_acq_rel);
40
YACLIB_ASSERT
(
reinterpret_cast<
std::uintptr_t
>
(
head
) != kSet);
41
42
while
(
head
) {
43
auto
next =
head
->next;
44
Promise<V, E>
{
detail::ResultCorePtr<V, E>
{
NoRefTag
{},
head
}}.Set(
_result
);
45
head
=
static_cast<
ResultCoreType
*
>
(next);
46
}
47
}
48
49
~SharedCore
() {
50
YACLIB_ASSERT
(
reinterpret_cast<
std::uintptr_t
>
(_head.load(std::memory_order_relaxed)) == kSet);
51
_result
.~Result<V,
E
>();
52
}
53
54
private
:
55
static
constexpr
auto
kSet = std::numeric_limits<std::uintptr_t>::max();
56
57
yaclib_std::atomic<ResultCoreType*> _head =
nullptr
;
58
union
{
59
Result<V, E>
_result
;
60
};
61
};
62
63
template
<
typename
V,
typename
E>
64
using
SharedCorePtr
=
IntrusivePtr<SharedCore<V, E>
>;
65
66
}
// namespace detail
67
}
// namespace yaclib
future.hpp
yaclib::IRef
Reference counting interface.
Definition
ref.hpp:8
yaclib::IntrusivePtr
A intrusive pointer to objects with an embedded reference count.
Definition
intrusive_ptr.hpp:17
yaclib::Promise
Definition
promise.hpp:10
yaclib::Result
Encapsulated return value from caller.
Definition
result.hpp:90
yaclib::detail::ResultCore
Definition
result_core.hpp:17
yaclib::detail::ResultCore::Get
Result< V, E > & Get() noexcept
Definition
result_core.hpp:51
yaclib::detail::SharedCore
Definition
shared_core.hpp:16
yaclib::detail::SharedCore::Set
void Set(Args &&... args)
Definition
shared_core.hpp:36
yaclib::detail::SharedCore::~SharedCore
~SharedCore()
Definition
shared_core.hpp:49
yaclib::detail::SharedCore::SharedCore
SharedCore() noexcept
Definition
shared_core.hpp:20
yaclib::detail::SharedCore::_result
Result< V, E > _result
Definition
shared_core.hpp:59
yaclib::detail::SharedCore::Attach
void Attach(Promise< V, E > &&p)
Definition
shared_core.hpp:22
executor.hpp
fwd.hpp
YACLIB_ASSERT
#define YACLIB_ASSERT(cond)
Definition
log.hpp:85
yaclib
Definition
base_core.hpp:18
yaclib::MakeContract
Contract< V, E > MakeContract()
Creates related future and promise.
Definition
contract.hpp:25
promise.hpp
ref.hpp
result_core.hpp
yaclib::NoRefTag
Definition
intrusive_ptr.hpp:9
include
yaclib
algo
detail
shared_core.hpp
Generated by
1.9.8