userver
C++ Async Framework
Toggle main menu visibility
Loading...
Searching...
No Matches
local_variable.hpp
Go to the documentation of this file.
1
#
pragma
once
2
3
/// @file userver/engine/task/local_variable.hpp
4
/// @brief @copybrief engine::TaskLocalVariable
5
6
#
include
<
type_traits
>
7
8
#
include
<
userver
/
engine
/
impl
/
task_local_storage
.
hpp
>
9
10
USERVER_NAMESPACE_BEGIN
11
12
namespace
engine {
13
14
/// @ingroup userver_concurrency
15
///
16
/// @brief TaskLocalVariable is a per-coroutine variable of arbitrary type.
17
///
18
/// It is an alternative to `thread_local`, but per-task instead of per-thread.
19
///
20
/// The order of destruction of task-local variables is inverse to the order of
21
/// initialization.
22
template
<
typename
T>
23
class
TaskLocalVariable final {
24
static_assert
(!std::is_reference_v<T>);
25
static_assert
(!std::is_const_v<T>);
26
27
public
:
28
/// @brief Get the instance of the variable for the current coroutine.
29
/// Initializes (default constructs) the variable if it was not previously
30
/// initialized.
31
/// @note Must be called from a coroutine, otherwise it is UB.
32
T&
operator
*();
33
34
/// @overload
35
T*
operator
->();
36
37
/// @brief Get the variable instance for the current task, or emplace a new
38
/// one with the given arguments.
39
/// @note Must be called from a coroutine, otherwise it is UB.
40
template
<
typename
... Args>
41
T&
GetOrEmplace
(Args&&... args) {
42
return
impl
::task_local::GetCurrentStorage()
43
.GetOrEmplace<T, kVariableKind>(impl_.GetKey(), std::forward<Args>(args)...);
44
}
45
46
/// @brief Get the variable instance for the current task.
47
/// @returns the variable or `nullptr` if the variable was not initialized,
48
/// was already destroyed, or is being destroyed right now. That is,
49
/// a non-null result is guaranteed to point to a variable whose
50
/// destruction has not started (the variable is unset before its
51
/// destructor is invoked, as in POSIX `pthread_getspecific`).
52
T*
GetOptional
()
noexcept
{
53
return
impl
::task_local::GetCurrentStorage().GetOptional<T, kVariableKind>(impl_.GetKey());
54
}
55
56
private
:
57
static
constexpr
auto
kVariableKind =
impl
::task_local::VariableKind::kNormal;
58
59
impl
::task_local::Variable impl_;
60
};
61
62
template
<
typename
T>
63
T& TaskLocalVariable<T>::
operator
*() {
64
return
impl
::task_local::GetCurrentStorage().GetOrEmplace<T, kVariableKind>(impl_.GetKey());
65
}
66
67
template
<
typename
T>
68
T* TaskLocalVariable<T>::
operator
->() {
69
return
&(**
this
);
70
}
71
72
}
// namespace engine
73
74
USERVER_NAMESPACE_END
userver
engine
task
local_variable.hpp
Generated on
for userver by
Doxygen
1.17.0