1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef mozilla_ipc_AutoTransportDescriptor_h
8 #define mozilla_ipc_AutoTransportDescriptor_h
9 
10 #include <utility>
11 
12 #include "mozilla/ipc/Transport.h"
13 #include "mozilla/Result.h"
14 
15 namespace mozilla::ipc {
16 
17 class AutoTransportDescriptor final {
18  public:
19   AutoTransportDescriptor() = default;
AutoTransportDescriptor(TransportDescriptor aTransport)20   explicit AutoTransportDescriptor(TransportDescriptor aTransport)
21       : mTransport(aTransport), mValid(true) {}
22   ~AutoTransportDescriptor();
23 
24   AutoTransportDescriptor(AutoTransportDescriptor&& aOther) noexcept;
25   AutoTransportDescriptor& operator=(AutoTransportDescriptor&& aOther) noexcept;
26 
27   static Result<std::pair<AutoTransportDescriptor, AutoTransportDescriptor>,
28                 nsresult>
29   Create(int32_t aProcIdOne);
30 
31   AutoTransportDescriptor Duplicate() const;
32 
33   // NOTE: This will consume this transport descriptor, making it invalid.
34   UniquePtr<Transport> Open(Transport::Mode aMode);
35 
36   explicit operator bool() const { return mValid; }
37 
38  private:
39   friend struct IPC::ParamTraits<AutoTransportDescriptor>;
40 
41   TransportDescriptor mTransport;
42   bool mValid = false;
43 };
44 
45 }  // namespace mozilla::ipc
46 
47 namespace IPC {
48 
49 template <>
50 struct ParamTraits<mozilla::ipc::AutoTransportDescriptor> {
51   using paramType = mozilla::ipc::AutoTransportDescriptor;
52   static void Write(Message* aMsg, paramType&& aParam) {
53     WriteParam(aMsg, aParam.mValid);
54     if (aParam.mValid) {
55       // TransportDescriptor's serialization code takes it by `const T&`,
56       // however, it actually closes the handles when passed, so we need to mark
57       // our state as invalid after sending.
58       WriteParam(aMsg, aParam.mTransport);
59       aParam.mValid = false;
60     }
61   }
62   static bool Read(const Message* aMsg, PickleIterator* aIter,
63                    paramType* aResult) {
64     bool valid = false;
65     if (!ReadParam(aMsg, aIter, &valid)) {
66       return false;
67     }
68     if (!valid) {
69       *aResult = mozilla::ipc::AutoTransportDescriptor{};
70       return true;
71     }
72 
73     mozilla::ipc::TransportDescriptor descr;
74     if (!ReadParam(aMsg, aIter, &descr)) {
75       return false;
76     }
77     *aResult = mozilla::ipc::AutoTransportDescriptor{descr};
78     return true;
79   }
80 };
81 
82 }  // namespace IPC
83 
84 #endif
85