Apache Mesos
pid.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_PID_HPP__
14 #define __PROCESS_PID_HPP__
15 
16 #include <stdint.h>
17 
18 #include <iosfwd>
19 #include <string>
20 
21 #include <boost/functional/hash.hpp>
22 
23 #include <process/address.hpp>
24 
25 #include <stout/ip.hpp>
26 
27 namespace process {
28 
29 // Forward declaration to break cyclic dependencies.
30 class ProcessBase;
31 
39 struct UPID
40 {
41  UPID() = default;
42 
43  UPID(const UPID& that) = default;
44 
45  UPID(UPID&& that) = default;
46 
47  UPID(const char* id_, const net::IP& ip_, uint16_t port_)
48  : id(id_), address(ip_, port_) { resolve(); }
49 
50  UPID(const char* id_, const network::inet::Address& address_)
51  : id(id_), address(address_) { resolve(); }
52 
53  UPID(const std::string& id_, const net::IP& ip_, uint16_t port_)
54  : id(id_), address(ip_, port_) { resolve(); }
55 
56  UPID(const std::string& id_, const network::inet::Address& address_)
57  : id(id_), address(address_) { resolve(); }
58 
59  /*implicit*/ UPID(const char* s);
60 
61  /*implicit*/ UPID(const std::string& s);
62 
63  /*implicit*/ UPID(const ProcessBase& process);
64 
65  UPID& operator=(const UPID& that) = default;
66 
67  UPID& operator=(UPID&& that) = default;
68 
69  operator std::string() const;
70 
71  operator bool() const
72  {
73  return id != "" && !address.ip.isAny() && address.port != 0;
74  }
75 
76  bool operator!() const // NOLINT(whitespace/operators)
77  {
78  return id == "" && address.ip.isAny() && address.port == 0;
79  }
80 
81  bool operator<(const UPID& that) const
82  {
83  if (address == that.address) {
84  return id < that.id;
85  } else {
86  return address < that.address;
87  }
88  }
89 
90  bool operator==(const UPID& that) const
91  {
92  return (id == that.id && address == that.address);
93  }
94 
95  bool operator!=(const UPID& that) const
96  {
97  return !(*this == that);
98  }
99 
100  // Attempts to resolve and cache a weak pointer to the ProcessBase
101  // to which this UPID refers.
102  void resolve();
103 
104  // TODO(benh): store all of the members of UPID behind a
105  // copy-on-write implementation because UPID is often copied but
106  // rarely written which means we could optimize performance by not
107  // making so many copies.
108 
109  // A copy-on-write string for performance.
110  //
111  // TODO(benh): Factor this out into a generic copy-on-write string.
112  struct ID
113  {
114  static const std::string EMPTY;
115 
116  ID() = default;
117 
118  ID(const std::string& s)
119  : id(std::make_shared<std::string>(s)) {}
120 
121  ID(std::string&& s)
122  : id(std::make_shared<std::string>(std::move(s))) {}
123 
124  ID& operator=(std::string&& that)
125  {
126  id = std::make_shared<std::string>(std::move(that));
127  return *this;
128  }
129 
130  bool operator==(const std::string& that) const
131  {
132  if (!id) {
133  return EMPTY == that;
134  }
135  return *id == that;
136  }
137 
138  bool operator==(const char* that) const
139  {
140  if (!id) {
141  return EMPTY == that;
142  }
143  return *id == that;
144  }
145 
146  bool operator!=(const std::string& that) const
147  {
148  return !(*this == that);
149  }
150 
151  bool operator<(const std::string& that) const
152  {
153  if (!id) {
154  return EMPTY < that;
155  }
156  return *id < that;
157  }
158 
159  operator const std::string&() const
160  {
161  if (!id) {
162  return EMPTY;
163  }
164  return *id;
165  }
166 
167  private:
168  std::shared_ptr<std::string> id;
169  } id;
170 
171  // TODO(asridharan): Ideally, the following `address` field should be of
172  // type `network::Address` so that the default address of the PID
173  // could be a unix domain socket or an IPv4/v6 address. This change
174  // however is disruptive at this point and should be done after we have
175  // introduced support for unix domain and IPv6 sockets into
176  // `libprocess`.
178 
179  // TODO(asridharan): Currently we are introducing only an `Optional`
180  // IPv6 address in the following `addresses` structure. This will
181  // help us initiate some basic IPv6 support for the
182  // `DockerContainerizer`. However, going forward, once we start
183  // supporting unix domain sockets and IPv4/IPv6 socket in
184  // `libprocess` we will add the following fields to this structure.
185  //
186  // Option<network::unix::Address> unix;
187  // Option<network::inet4::Address> v4;
188  //
189  // With the introduction of the above fields `libprocess` PID will
190  // be able to support unix, IPv4 and IPv6 sockets simultaneously.
191  struct
192  {
194  } addresses = {None()};
195 
196  // The hostname that was used to create this UPID, if any. This is useful
197  // both for display purposes and when making outgoing connections on a TLS
198  // socket, where the name recorded here can be used for hostname validation
199  // checks against the X509 certificate presented by the server.
200  //
201  // NOTE: In the context of TLS hostname validation, this can also be set
202  // manually to override the result of DNS resolution before trying to
203  // `connect()` to this UPID, similar to `curl --resolve`.
205 
206 protected:
207  friend class ProcessBase;
208  friend class ProcessManager;
209 
210  // A weak pointer to the actual process used to optimize enqueuing
211  // events without having to go through a shared lock in the
212  // `ProcessManager`. This is `None` if someone creates a UPID and
213  // doesn't call `resolve()` or if `resolve()` doesn't find a valid
214  // process (i.e., the process hasn't started or has terminated).
216 };
217 
218 
219 inline std::ostream& operator<<(std::ostream& stream, const UPID::ID& id)
220 {
221  const std::string& s = id;
222  return stream << s;
223 }
224 
225 
226 inline bool operator==(const std::string& s, const UPID::ID& id)
227 {
228  return id == s;
229 }
230 
231 
232 inline bool operator!=(const std::string& s, const UPID::ID& id)
233 {
234  return !(s == id);
235 }
236 
237 
238 inline std::string operator+(const UPID::ID& id, const std::string& s)
239 {
240  return (const std::string&) id + s;
241 }
242 
243 
244 inline std::string operator+(const UPID::ID& id, std::string&& s)
245 {
246  return (const std::string&) id + std::move(s);
247 }
248 
249 
250 inline std::string operator+(const std::string& s, const UPID::ID& id)
251 {
252  return s + (const std::string&) id;
253 }
254 
255 
256 inline std::string operator+(std::string&& s, const UPID::ID& id)
257 {
258  return std::move(s) + (const std::string&) id;
259 }
260 
261 
288 template <typename T = ProcessBase>
289 struct PID : UPID
290 {
291  // Need to declare PID<U> as a friend in order to write `reference`.
292  template <typename U>
293  friend struct PID;
294 
295  PID() : UPID() {}
296 
297  /*implicit*/ PID(const T* t) : UPID(static_cast<const ProcessBase&>(*t)) {}
298  /*implicit*/ PID(const T& t) : UPID(static_cast<const ProcessBase&>(t)) {}
299 
300  template <typename Base>
301  operator PID<Base>() const
302  {
303  // Only allow upcasts!
304  T* t = nullptr;
305  Base* base = t;
306  (void)base; // Eliminate unused base warning.
307  PID<Base> pid;
308  pid.id = id;
309  pid.address = address;
310  pid.addresses = addresses;
311  pid.reference = reference;
312  return pid;
313  }
314 };
315 
316 
317 // Outputing UPIDs and generating UPIDs using streams.
318 std::ostream& operator<<(std::ostream&, const UPID&);
319 std::istream& operator>>(std::istream&, UPID&);
320 
321 } // namespace process {
322 
323 namespace std {
324 
325 template <>
326 struct hash<process::UPID>
327 {
328  typedef size_t result_type;
329 
331 
332  result_type operator()(const argument_type& upid) const
333  {
334  size_t seed = 0;
335  boost::hash_combine(seed, (const std::string&) upid.id);
336  boost::hash_combine(seed, std::hash<net::IP>()(upid.address.ip));
337  boost::hash_combine(seed, upid.address.port);
338  return seed;
339  }
340 };
341 
342 } // namespace std {
343 
344 #endif // __PROCESS_PID_HPP__
static Address ANY_ANY()
Definition: address.hpp:164
ID & operator=(std::string &&that)
Definition: pid.hpp:124
std::ostream & operator<<(std::ostream &stream, const Future< T > &future)
Definition: future.hpp:1826
UPID & operator=(const UPID &that)=default
PID(const T &t)
Definition: pid.hpp:298
ID(std::string &&s)
Definition: pid.hpp:121
bool operator!=(const UPID &that) const
Definition: pid.hpp:95
network::inet::Address address
Definition: pid.hpp:177
Definition: pid.hpp:112
static const std::string EMPTY
Definition: pid.hpp:114
ID(const std::string &s)
Definition: pid.hpp:118
Definition: ip.hpp:682
bool isAny() const
Definition: ip.hpp:157
Definition: uuid.hpp:33
Definition: type_utils.hpp:598
Definition: process.hpp:72
bool operator<(const std::string &that) const
Definition: pid.hpp:151
event_base * base
UPID(const char *id_, const net::IP &ip_, uint16_t port_)
Definition: pid.hpp:47
struct process::UPID::@5 addresses
UPID(const char *id_, const network::inet::Address &address_)
Definition: pid.hpp:50
Definition: ip.hpp:73
bool operator<(const UPID &that) const
Definition: pid.hpp:81
bool operator!=(const std::string &that) const
Definition: pid.hpp:146
An "untyped" PID, used to encapsulate the process ID for lower-layer abstractions (eg...
Definition: pid.hpp:39
result_type operator()(const argument_type &upid) const
Definition: pid.hpp:332
Option< network::inet6::Address > v6
Definition: pid.hpp:193
bool operator==(const UPID &that) const
Definition: pid.hpp:90
uint16_t port
Definition: address.hpp:141
Option< std::weak_ptr< ProcessBase * > > reference
Definition: pid.hpp:215
Definition: address.hpp:52
std::string operator+(const UPID::ID &id, const std::string &s)
Definition: pid.hpp:238
friend class ProcessManager
Definition: pid.hpp:208
A "process identifier" used to uniquely identify a process when dispatching messages.
Definition: pid.hpp:289
Definition: none.hpp:27
Definition: executor.hpp:48
bool operator!() const
Definition: pid.hpp:76
UPID(const std::string &id_, const network::inet::Address &address_)
Definition: pid.hpp:56
PID(const T *t)
Definition: pid.hpp:297
bool operator==(const std::string &that) const
Definition: pid.hpp:130
bool operator==(const char *that) const
Definition: pid.hpp:138
Option< std::string > host
Definition: pid.hpp:204
UPID()=default
UPID(const std::string &id_, const net::IP &ip_, uint16_t port_)
Definition: pid.hpp:53
struct process::UPID::ID id
std::istream & operator>>(std::istream &, UPID &)
net::IP ip
Definition: address.hpp:140
process::UPID argument_type
Definition: pid.hpp:330
PID()
Definition: pid.hpp:295
size_t result_type
Definition: pid.hpp:328