18class LockedPtr final {
20 using Mutex =
typename Lock::mutex_type;
22 LockedPtr(Mutex& mutex, Data& data)
26 LockedPtr(Lock&& lock, Data& data)
27 : lock_(std::move(lock)),
31 Data& operator*() & USERVER_IMPL_LIFETIME_BOUND {
return data_; }
32 const Data& operator*()
const& USERVER_IMPL_LIFETIME_BOUND {
return data_; }
35 Data&
operator*() && {
return *GetOnRvalue(); }
37 Data* operator->() & USERVER_IMPL_LIFETIME_BOUND {
return &data_; }
38 const Data* operator->()
const& USERVER_IMPL_LIFETIME_BOUND {
return &data_; }
41 Data*
operator->() && {
return GetOnRvalue(); }
46 const Data& GetUnsafeForStableSubobject()
const& {
return data_; }
51 Lock& GetLock() USERVER_IMPL_LIFETIME_BOUND {
return lock_; }
54 const Data* GetOnRvalue() {
55 static_assert(!
sizeof(Data),
"Don't use temporary LockedPtr, store it to a variable");
75 template <
typename... Arg>
76 Variable(Arg&&... arg)
77 : data_(std::forward<Arg>(arg)...)
80 LockedPtr<std::unique_lock<Mutex>, Data> UniqueLock() {
return {mutex_, data_}; }
82 LockedPtr<std::unique_lock<Mutex>,
const Data> UniqueLock()
const {
return {mutex_, data_}; }
84 std::optional<LockedPtr<std::unique_lock<Mutex>,
const Data>> UniqueLock(std::try_to_lock_t)
const {
85 return DoUniqueLock(*
this, std::try_to_lock);
88 std::optional<LockedPtr<std::unique_lock<Mutex>, Data>> UniqueLock(std::try_to_lock_t) {
89 return DoUniqueLock(*
this, std::try_to_lock);
92 std::optional<LockedPtr<std::unique_lock<Mutex>,
const Data>> UniqueLock(std::chrono::milliseconds try_duration
94 return DoUniqueLock(*
this, try_duration);
97 std::optional<LockedPtr<std::unique_lock<Mutex>, Data>> UniqueLock(std::chrono::milliseconds try_duration) {
98 return DoUniqueLock(*
this, try_duration);
101 LockedPtr<std::shared_lock<Mutex>,
const Data> SharedLock()
const {
return {mutex_, data_}; }
107 LockedPtr<std::lock_guard<Mutex>, Data> Lock() {
return {mutex_, data_}; }
109 LockedPtr<std::lock_guard<Mutex>,
const Data> Lock()
const {
return {mutex_, data_}; }
121 const Data& GetDataUnsafe()
const {
return data_; }
124 mutable Mutex mutex_;
131 template <
typename VariableType,
typename... StdUniqueLockArgs>
132 static auto DoUniqueLock(VariableType& concurrent_variable, StdUniqueLockArgs&&... args) {
133 std::unique_lock<Mutex> lock(concurrent_variable.mutex_, std::forward<StdUniqueLockArgs>(args)...);
134 return lock ? std::optional{LockedPtr{std::move(lock), concurrent_variable.data_}} : std::nullopt;