Apache Mesos
owned.hpp
Go to the documentation of this file.
1 // Licensed under the Apache License, Version 2.0 (the "License");
2 // you may not use this file except in compliance with the License.
3 // You may obtain a copy of the License at
4 //
5 // http://www.apache.org/licenses/LICENSE-2.0
6 //
7 // Unless required by applicable law or agreed to in writing, software
8 // distributed under the License is distributed on an "AS IS" BASIS,
9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 // See the License for the specific language governing permissions and
11 // limitations under the License
12 
13 #ifndef __PROCESS_OWNED_HPP__
14 #define __PROCESS_OWNED_HPP__
15 
16 #include <atomic>
17 #include <cstddef>
18 #include <memory>
19 
20 #include <glog/logging.h>
21 
22 namespace process {
23 
24 // Forward declaration.
25 template <typename T>
26 class Shared;
27 
28 
29 // Represents a uniquely owned pointer.
30 //
31 // TODO(bmahler): For now, Owned only provides shared_ptr semantics.
32 // When we make the switch to C++11, we will change to provide
33 // unique_ptr semantics. Consequently, each usage of Owned that
34 // invokes a copy will have to be adjusted to use move semantics.
35 template <typename T>
36 class Owned
37 {
38 public:
39  Owned();
40  explicit Owned(T* t);
41  /*implicit*/ Owned(std::nullptr_t) : Owned(static_cast<T*>(nullptr)) {};
42 
43  bool operator==(const Owned<T>& that) const;
44  bool operator<(const Owned<T>& that) const;
45 
46  T& operator*() const;
47  T* operator->() const;
48  T* get() const;
49 
50  void reset();
51  void reset(T* t);
52  void swap(Owned<T>& that);
53 
54  // Converts from an owned pointer to a shared pointer. This owned
55  // pointer will be reset after this function is invoked.
56  Shared<T> share();
57 
58  // Converts from an owned pointer to a raw pointer. This owned
59  // pointer will be reset after this function is invoked.
60  T* release();
61 
62 private:
63  struct Data
64  {
65  explicit Data(T* t);
66  ~Data();
67 
68  std::atomic<T*> t;
69  };
70 
71  std::shared_ptr<Data> data;
72 };
73 
74 
75 template <typename T>
77 
78 
79 template <typename T>
81 {
82  if (t != nullptr) {
83  data.reset(new Data(t));
84  }
85 }
86 
87 
88 template <typename T>
89 bool Owned<T>::operator==(const Owned<T>& that) const
90 {
91  return data == that.data;
92 }
93 
94 
95 template <typename T>
96 bool Owned<T>::operator<(const Owned<T>& that) const
97 {
98  return data < that.data;
99 }
100 
101 
102 template <typename T>
104 {
105  return *CHECK_NOTNULL(get());
106 }
107 
108 
109 template <typename T>
111 {
112  return CHECK_NOTNULL(get());
113 }
114 
115 
116 template <typename T>
117 T* Owned<T>::get() const
118 {
119  if (data == nullptr) {
120  return nullptr;
121  } else {
122  // Static cast to avoid ambiguity in Visual Studio compiler.
123  CHECK(data->t != static_cast<T*>(nullptr))
124  << "This owned pointer has already been shared";
125 
126  return data->t;
127  }
128 }
129 
130 
131 template <typename T>
133 {
134  data.reset();
135 }
136 
137 
138 template <typename T>
139 void Owned<T>::reset(T* t)
140 {
141  if (t == nullptr) {
142  data.reset();
143  } else {
144  data.reset(new Data(t));
145  }
146 }
147 
148 
149 template <typename T>
151 {
152  data.swap(that.data);
153 }
154 
155 
156 template <typename T>
158 {
159  if (data == nullptr) {
160  // The ownership of this pointer has already been lost.
161  return Shared<T>(nullptr);
162  }
163 
164  // Atomically set the pointer 'data->t' to `nullptr`.
165  T* old = data->t.exchange(nullptr);
166  if (old == nullptr) {
167  // The ownership of this pointer has already been lost.
168  return Shared<T>(nullptr);
169  }
170 
171  data.reset();
172  return Shared<T>(old);
173 }
174 
175 
176 template <typename T>
178 {
179  if (data == nullptr) {
180  // The ownership of this pointer has already been lost.
181  return nullptr;
182  }
183 
184  // Atomically set the pointer 'data->t' to `nullptr`.
185  T* old = data->t.exchange(nullptr);
186  if (old == nullptr) {
187  // The ownership of this pointer has already been lost.
188  return nullptr;
189  }
190 
191  data.reset();
192  return old;
193 }
194 
195 
196 template <typename T>
198  : t(CHECK_NOTNULL(_t)) {}
199 
200 
201 template <typename T>
203 {
204  delete t.load();
205 }
206 
207 } // namespace process {
208 
209 #endif // __PROCESS_OWNED_HPP__
void reset()
Definition: owned.hpp:132
void reset()
Definition: shared.hpp:136
T * get() const
Definition: owned.hpp:117
bool operator==(const Owned< T > &that) const
Definition: owned.hpp:89
T * operator->() const
Definition: owned.hpp:110
Definition: owned.hpp:26
Owned()
Definition: owned.hpp:76
bool operator<(const Owned< T > &that) const
Definition: owned.hpp:96
Shared< T > share()
Definition: owned.hpp:157
Owned(std::nullptr_t)
Definition: owned.hpp:41
Definition: executor.hpp:48
T & operator*() const
Definition: owned.hpp:103
Definition: owned.hpp:36
T * release()
Definition: owned.hpp:177
void swap(Owned< T > &that)
Definition: owned.hpp:150