proxygen
SynchronizedPtr.h
Go to the documentation of this file.
1 /*
2  * Copyright 2017-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <folly/Synchronized.h>
20 
21 /* `SynchronizedPtr` is a variation on the `Synchronized` idea that's useful for
22  * some cases where you want to protect a pointed-to object (or an object within
23  * some pointer-like wrapper). If you would otherwise need to use
24  * `Synchronized<smart_ptr<Synchronized<T>>>` consider using
25  * `SynchronizedPtr<smart_ptr<T>>`as it is a bit easier to use and it works when
26  * you want the `T` object at runtime to actually a subclass of `T`.
27  *
28  * You can access the contained `T` with `.rlock()`, and `.wlock()`, and the
29  * pointer or pointer-like wrapper with `.wlockPointer()`. The corresponding
30  * `with...` methods take a callback, invoke it with a `T const&`, `T&` or
31  * `smart_ptr<T>&` respectively, and return the callback's result.
32  */
33 namespace folly {
34 template <typename LockHolder, typename Element>
36  explicit SynchronizedPtrLockedElement(LockHolder&& holder)
37  : holder_(std::move(holder)) {}
38 
39  Element& operator*() const {
40  return **holder_;
41  }
42 
43  Element* operator->() const {
44  return &**holder_;
45  }
46 
47  explicit operator bool() const {
48  return static_cast<bool>(*holder_);
49  }
50 
51  private:
52  LockHolder holder_;
53 };
54 
55 template <typename PointerType, typename MutexType = SharedMutex>
59 
60  public:
61  using pointer_type = PointerType;
62  using element_type = typename std::pointer_traits<pointer_type>::element_type;
68  typename inner_type::LockedPtr,
70  using write_locked_pointer = typename inner_type::LockedPtr;
71 
72  template <typename... Args>
73  explicit SynchronizedPtr(Args... args)
74  : inner_(std::forward<Args>(args)...) {}
75 
76  SynchronizedPtr() = default;
77  SynchronizedPtr(SynchronizedPtr const&) = default;
78  SynchronizedPtr(SynchronizedPtr&&) = default;
79  SynchronizedPtr& operator=(SynchronizedPtr const&) = default;
80  SynchronizedPtr& operator=(SynchronizedPtr&&) = default;
81 
82  // Methods to provide appropriately locked and const-qualified access to the
83  // element.
84 
86  return read_locked_element(inner_.rlock());
87  }
88 
89  template <class Function>
90  auto withRLock(Function&& function) const {
91  return function(*rlock());
92  }
93 
95  return write_locked_element(inner_.wlock());
96  }
97 
98  template <class Function>
99  auto withWLock(Function&& function) {
100  return function(*wlock());
101  }
102 
103  // Methods to provide write-locked access to the pointer. We deliberately make
104  // it difficult to get a read-locked pointer because that provides read-locked
105  // non-const access to the element, and the purpose of this class is to
106  // discourage that.
108  return inner_.wlock();
109  }
110 
111  template <class Function>
112  auto withWLockPointer(Function&& function) {
113  return function(*wlockPointer());
114  }
115 };
116 } // namespace folly
SynchronizedPtr(Args...args)
typename Base::ConstLockedPtr ConstLockedPtr
Definition: Synchronized.h:454
auto wlock(Synchronized< D, M > &synchronized, Args &&...args)
PskType type
auto withRLock(Function &&function) const
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
STL namespace.
internal::ArgsMatcher< InnerMatcher > Args(const InnerMatcher &matcher)
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
typename inner_type::LockedPtr write_locked_pointer
write_locked_pointer wlockPointer()
auto rlock(const Synchronized< Data, Mutex > &synchronized, Args &&...args)
typename std::add_const< element_type >::type const_element_type
auto withWLock(Function &&function)
read_locked_element rlock() const
SynchronizedPtrLockedElement(LockHolder &&holder)
write_locked_element wlock()
typename std::pointer_traits< pointer_type >::element_type element_type
auto withWLockPointer(Function &&function)