21class LockedPtr final {
23 using Mutex =
typename Lock::mutex_type;
25 LockedPtr(Mutex& mutex, Data& data)
29 LockedPtr(Lock&& lock, Data& data)
30 : lock_(std::move(lock)),
34 Data& operator*() & USERVER_IMPL_LIFETIME_BOUND {
return data_; }
35 const Data& operator*()
const& USERVER_IMPL_LIFETIME_BOUND {
return data_; }
38 Data&
operator*() && {
return *GetOnRvalue(); }
40 Data* operator->() & USERVER_IMPL_LIFETIME_BOUND {
return &data_; }
41 const Data* operator->()
const& USERVER_IMPL_LIFETIME_BOUND {
return &data_; }
44 Data*
operator->() && {
return GetOnRvalue(); }
49 const Data& GetUnsafeForStableSubobject()
const& {
return data_; }
54 Lock& GetLock() USERVER_IMPL_LIFETIME_BOUND {
return lock_; }
57 const Data* GetOnRvalue() {
58 static_assert(!
sizeof(Data),
"Don't use temporary LockedPtr, store it to a variable");
78 template <
typename... Arg>
79 Variable(Arg&&... arg)
80 : data_(std::forward<Arg>(arg)...)
83 LockedPtr<std::unique_lock<Mutex>, Data> UniqueLock() {
return {mutex_, data_}; }
85 LockedPtr<std::unique_lock<Mutex>,
const Data> UniqueLock()
const {
return {mutex_, data_}; }
87 std::optional<LockedPtr<std::unique_lock<Mutex>,
const Data>> UniqueLock(std::try_to_lock_t)
const {
88 return DoUniqueLock(*
this, std::try_to_lock);
91 std::optional<LockedPtr<std::unique_lock<Mutex>, Data>> UniqueLock(std::try_to_lock_t) {
92 return DoUniqueLock(*
this, std::try_to_lock);
95 std::optional<LockedPtr<std::unique_lock<Mutex>,
const Data>> UniqueLock(std::chrono::milliseconds try_duration
97 return DoUniqueLock(*
this, try_duration);
100 std::optional<LockedPtr<std::unique_lock<Mutex>, Data>> UniqueLock(std::chrono::milliseconds try_duration) {
101 return DoUniqueLock(*
this, try_duration);
104 LockedPtr<std::shared_lock<Mutex>,
const Data> SharedLock()
const {
return {mutex_, data_}; }
110 LockedPtr<std::lock_guard<Mutex>, Data> Lock() {
return {mutex_, data_}; }
112 LockedPtr<std::lock_guard<Mutex>,
const Data> Lock()
const {
return {mutex_, data_}; }
124 const Data& GetDataUnsafe()
const {
return data_; }
127 mutable Mutex mutex_;
134 template <
typename VariableType,
typename... StdUniqueLockArgs>
135 static auto DoUniqueLock(VariableType& concurrent_variable, StdUniqueLockArgs&&... args) {
136 std::unique_lock<Mutex> lock(concurrent_variable.mutex_, std::forward<StdUniqueLockArgs>(args)...);
137 return lock ? std::optional{LockedPtr{std::move(lock), concurrent_variable.data_}} : std::nullopt;