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 <memory>
18 
19 #include <glog/logging.h>
20 
21 namespace process {
22 
23 // Forward declaration.
24 template <typename T>
25 class Shared;
26 
27 
28 // Represents a uniquely owned pointer.
29 //
30 // TODO(bmahler): For now, Owned only provides shared_ptr semantics.
31 // When we make the switch to C++11, we will change to provide
32 // unique_ptr semantics. Consequently, each usage of Owned that
33 // invokes a copy will have to be adjusted to use move semantics.
34 template <typename T>
35 class Owned
36 {
37 public:
38  Owned();
39  explicit Owned(T* t);
40 
41  bool operator==(const Owned<T>& that) const;
42  bool operator<(const Owned<T>& that) const;
43 
44  T& operator*() const;
45  T* operator->() const;
46  T* get() const;
47 
48  void reset();
49  void reset(T* t);
50  void swap(Owned<T>& that);
51 
52  // Converts from an owned pointer to a shared pointer. This owned
53  // pointer will be reset after this function is invoked.
54  Shared<T> share();
55 
56  // Converts from an owned pointer to a raw pointer. This owned
57  // pointer will be reset after this function is invoked.
58  T* release();
59 
60 private:
61  struct Data
62  {
63  explicit Data(T* t);
64  ~Data();
65 
66  std::atomic<T*> t;
67  };
68 
69  std::shared_ptr<Data> data;
70 };
71 
72 
73 template <typename T>
75 
76 
77 template <typename T>
79 {
80  if (t != nullptr) {
81  data.reset(new Data(t));
82  }
83 }
84 
85 
86 template <typename T>
87 bool Owned<T>::operator==(const Owned<T>& that) const
88 {
89  return data == that.data;
90 }
91 
92 
93 template <typename T>
94 bool Owned<T>::operator<(const Owned<T>& that) const
95 {
96  return data < that.data;
97 }
98 
99 
100 template <typename T>
102 {
103  return *CHECK_NOTNULL(get());
104 }
105 
106 
107 template <typename T>
109 {
110  return CHECK_NOTNULL(get());
111 }
112 
113 
114 template <typename T>
115 T* Owned<T>::get() const
116 {
117  if (data == nullptr) {
118  return nullptr;
119  } else {
120  // Static cast to avoid ambiguity in Visual Studio compiler.
121  CHECK(data->t != static_cast<T*>(nullptr))
122  << "This owned pointer has already been shared";
123 
124  return data->t;
125  }
126 }
127 
128 
129 template <typename T>
131 {
132  data.reset();
133 }
134 
135 
136 template <typename T>
137 void Owned<T>::reset(T* t)
138 {
139  if (t == nullptr) {
140  data.reset();
141  } else {
142  data.reset(new Data(t));
143  }
144 }
145 
146 
147 template <typename T>
149 {
150  data.swap(that.data);
151 }
152 
153 
154 template <typename T>
156 {
157  if (data == nullptr) {
158  // The ownership of this pointer has already been lost.
159  return Shared<T>(nullptr);
160  }
161 
162  // Atomically set the pointer 'data->t' to `nullptr`.
163  T* old = data->t.exchange(nullptr);
164  if (old == nullptr) {
165  // The ownership of this pointer has already been lost.
166  return Shared<T>(nullptr);
167  }
168 
169  data.reset();
170  return Shared<T>(old);
171 }
172 
173 
174 template <typename T>
176 {
177  if (data == nullptr) {
178  // The ownership of this pointer has already been lost.
179  return nullptr;
180  }
181 
182  // Atomically set the pointer 'data->t' to `nullptr`.
183  T* old = data->t.exchange(nullptr);
184  if (old == nullptr) {
185  // The ownership of this pointer has already been lost.
186  return nullptr;
187  }
188 
189  data.reset();
190  return old;
191 }
192 
193 
194 template <typename T>
196  : t(CHECK_NOTNULL(_t)) {}
197 
198 
199 template <typename T>
200 Owned<T>::Data::~Data()
201 {
202  delete t.load();
203 }
204 
205 } // namespace process {
206 
207 #endif // __PROCESS_OWNED_HPP__
void reset()
Definition: owned.hpp:130
void reset()
Definition: shared.hpp:134
T * get() const
Definition: owned.hpp:115
bool operator==(const Owned< T > &that) const
Definition: owned.hpp:87
T * operator->() const
Definition: owned.hpp:108
Definition: owned.hpp:25
Owned()
Definition: owned.hpp:74
bool operator<(const Owned< T > &that) const
Definition: owned.hpp:94
Shared< T > share()
Definition: owned.hpp:155
Result< Process > process(pid_t pid)
Definition: freebsd.hpp:30
T & operator*() const
Definition: owned.hpp:101
Definition: owned.hpp:35
T * release()
Definition: owned.hpp:175
void swap(Owned< T > &that)
Definition: owned.hpp:148