ReactivePlusPlus
ReactiveX implementation for C++20
Toggle main menu visibility
Loading...
Searching...
No Matches
refcount_disposable.hpp
1
// ReactivePlusPlus library
2
//
3
// Copyright Aleksey Loginov 2023 - present.
4
// Distributed under the Boost Software License, Version 1.0.
5
// (See accompanying file LICENSE_1_0.txt or copy at
6
// https://www.boost.org/LICENSE_1_0.txt)
7
//
8
// Project home: https://github.com/AlexInLog/ReactivePlusPlus
9
//
10
11
#pragma once
12
13
#include <rpp/disposables/fwd.hpp>
14
15
#include <rpp/disposables/composite_disposable.hpp>
16
#include <rpp/disposables/details/base_disposable.hpp>
17
#include <rpp/disposables/disposable_wrapper.hpp>
18
19
#include <atomic>
20
#include <limits>
21
22
namespace
rpp::details
23
{
24
class
refocunt_disposable_inner
;
25
}
// namespace rpp::details
26
27
namespace
rpp
28
{
29
class
refcount_disposable :
public
rpp::details::enable_wrapper_from_this
<refcount_disposable>
30
,
public
rpp::composite_disposable
31
{
32
33
void
release()
34
{
35
auto
current_value = m_refcount.load(std::memory_order::seq_cst);
36
while
(current_value != s_disposed)
37
{
38
const
size_t
new_value = current_value == 1 ? s_disposed : current_value - 1;
39
if
(!m_refcount.compare_exchange_strong(current_value, new_value, std::memory_order::seq_cst))
40
continue
;
41
42
if
(new_value == s_disposed)
43
dispose
();
44
return
;
45
}
46
}
47
48
void
composite_dispose_impl(interface_disposable::Mode)
noexcept
override
49
{
50
m_refcount.store(s_disposed, std::memory_order::seq_cst);
51
}
52
53
public
:
54
friend
class
details::refocunt_disposable_inner
;
55
refcount_disposable() =
default
;
56
57
composite_disposable_wrapper
add_ref();
58
59
private
:
60
std::atomic<size_t> m_refcount{0};
61
constexpr
static
size_t
s_disposed = std::numeric_limits<size_t>::max();
62
};
63
}
// namespace rpp
64
65
namespace
rpp::details
66
{
67
class
refocunt_disposable_inner final :
public
rpp::composite_disposable
68
,
public
rpp::details::enable_wrapper_from_this
<refocunt_disposable_inner>
69
{
70
public
:
71
refocunt_disposable_inner(disposable_wrapper_impl<refcount_disposable> state)
72
: m_state{std::move(state)}
73
{
74
}
75
76
void
composite_dispose_impl(interface_disposable::Mode mode)
noexcept
override
77
{
78
if
(mode != interface_disposable::Mode::Destroying)
79
m_state.remove(this->wrapper_from_this());
80
81
if
(
const
auto
locked = m_state.lock())
82
locked->release();
83
m_state =
disposable_wrapper_impl<refcount_disposable>::empty
();
84
}
85
86
private
:
87
disposable_wrapper_impl<refcount_disposable> m_state;
88
};
89
90
}
// namespace rpp::details
91
92
namespace
rpp
93
{
94
inline
composite_disposable_wrapper
refcount_disposable::add_ref()
95
{
96
auto
current_value = m_refcount.load(std::memory_order::seq_cst);
97
while
(
true
)
98
{
99
if
(current_value == s_disposed)
100
return
composite_disposable_wrapper::empty
();
101
102
// just need atomicity, not guarding anything
103
if
(m_refcount.compare_exchange_strong(current_value, current_value + 1, std::memory_order::seq_cst))
104
{
105
auto
inner =
composite_disposable_wrapper::make<details::refocunt_disposable_inner>
(wrapper_from_this());
106
add(inner.as_weak());
107
return
inner;
108
}
109
}
110
}
111
}
// namespace rpp
rpp::composite_disposable
Disposable which can keep some other sub-disposables. When this root disposable is disposed,...
Definition
composite_disposable.hpp:175
rpp::details::enable_wrapper_from_this
Definition
disposable_wrapper.hpp:252
rpp::details::refocunt_disposable_inner
Definition
refcount_disposable.hpp:69
rpp::disposable_wrapper_impl< interface_composite_disposable >::make
static disposable_wrapper_impl make(TArgs &&... args)
Definition
disposable_wrapper.hpp:164
rpp::disposable_wrapper_impl::empty
static disposable_wrapper_impl empty()
Creates disposable_wrapper which behaves like disposed disposable.
Definition
disposable_wrapper.hpp:178
rpp::composite_disposable_wrapper
disposable_wrapper_impl< interface_composite_disposable > composite_disposable_wrapper
Wrapper to keep "composite" disposable. Specialization of rpp::disposable_wrapper_impl.
Definition
fwd.hpp:41
rpp::interface_disposable::dispose
void dispose() noexcept
Dispose disposable and free any underlying resources and etc.
Definition
interface_disposable.hpp:36
src
rpp
rpp
disposables
refcount_disposable.hpp
Generated by
1.17.0