Bug 1834537 - Part 6: Simplify GCRuntime::checkAllocatorState a little r=sfink
[gecko.git] / ipc / glue / DataPipe.h
blobd6439189ad906f207507e55a0e8a9683d87d7a43
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 https://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_ipc_DataPipe_h
8 #define mozilla_ipc_DataPipe_h
10 #include "mozilla/ipc/SharedMemoryBasic.h"
11 #include "mozilla/ipc/NodeController.h"
12 #include "nsIAsyncInputStream.h"
13 #include "nsIAsyncOutputStream.h"
14 #include "nsIIPCSerializableInputStream.h"
15 #include "nsISupports.h"
17 namespace mozilla {
18 namespace ipc {
20 namespace data_pipe_detail {
22 class DataPipeAutoLock;
23 class DataPipeLink;
25 class DataPipeBase {
26 public:
27 DataPipeBase(const DataPipeBase&) = delete;
28 DataPipeBase& operator=(const DataPipeBase&) = delete;
30 protected:
31 explicit DataPipeBase(bool aReceiverSide, nsresult aError);
32 DataPipeBase(bool aReceiverSide, ScopedPort aPort, SharedMemory* aShmem,
33 uint32_t aCapacity, nsresult aPeerStatus, uint32_t aOffset,
34 uint32_t aAvailable);
36 void CloseInternal(DataPipeAutoLock&, nsresult aStatus) MOZ_REQUIRES(*mMutex);
38 void AsyncWaitInternal(already_AddRefed<nsIRunnable> aCallback,
39 already_AddRefed<nsIEventTarget> aTarget,
40 bool aClosureOnly) MOZ_EXCLUDES(*mMutex);
42 // Like `nsWriteSegmentFun` or `nsReadSegmentFun`.
43 using ProcessSegmentFun =
44 FunctionRef<nsresult(Span<char> aSpan, uint32_t aProcessedThisCall,
45 uint32_t* aProcessedCount)>;
46 nsresult ProcessSegmentsInternal(uint32_t aCount,
47 ProcessSegmentFun aProcessSegment,
48 uint32_t* aProcessedCount)
49 MOZ_EXCLUDES(*mMutex);
51 nsresult CheckStatus(DataPipeAutoLock&) MOZ_REQUIRES(*mMutex);
53 nsCString Describe(DataPipeAutoLock&) MOZ_REQUIRES(*mMutex);
55 // Thread safety helper to tell the analysis that `mLink->mMutex` is held when
56 // `mMutex` is held.
57 void AssertSameMutex(const std::shared_ptr<Mutex>& aMutex)
58 MOZ_REQUIRES(*mMutex) MOZ_ASSERT_CAPABILITY(*aMutex) {
59 MOZ_ASSERT(mMutex == aMutex);
62 virtual ~DataPipeBase();
64 const std::shared_ptr<Mutex> mMutex;
65 nsresult mStatus MOZ_GUARDED_BY(*mMutex) = NS_OK;
66 RefPtr<DataPipeLink> mLink MOZ_GUARDED_BY(*mMutex);
69 template <typename T>
70 void DataPipeWrite(IPC::MessageWriter* aWriter, T* aParam);
72 template <typename T>
73 bool DataPipeRead(IPC::MessageReader* aReader, RefPtr<T>* aResult);
75 } // namespace data_pipe_detail
77 class DataPipeSender;
78 class DataPipeReceiver;
80 #define NS_DATAPIPESENDER_IID \
81 { \
82 0x6698ed77, 0x9fff, 0x425d, { \
83 0xb0, 0xa6, 0x1d, 0x30, 0x66, 0xee, 0xb8, 0x16 \
84 } \
87 // Helper class for streaming data to another process.
88 class DataPipeSender final : public nsIAsyncOutputStream,
89 public data_pipe_detail::DataPipeBase {
90 public:
91 NS_DECLARE_STATIC_IID_ACCESSOR(NS_DATAPIPESENDER_IID)
92 NS_DECL_THREADSAFE_ISUPPORTS
93 NS_DECL_NSIOUTPUTSTREAM
94 NS_DECL_NSIASYNCOUTPUTSTREAM
96 private:
97 friend nsresult NewDataPipe(uint32_t, DataPipeSender**, DataPipeReceiver**);
98 friend void data_pipe_detail::DataPipeWrite<DataPipeSender>(
99 IPC::MessageWriter* aWriter, DataPipeSender* aParam);
100 friend bool data_pipe_detail::DataPipeRead<DataPipeSender>(
101 IPC::MessageReader* aReader, RefPtr<DataPipeSender>* aResult);
103 explicit DataPipeSender(nsresult aError)
104 : data_pipe_detail::DataPipeBase(/* aReceiverSide */ false, aError) {}
105 DataPipeSender(ScopedPort aPort, SharedMemory* aShmem, uint32_t aCapacity,
106 nsresult aPeerStatus, uint32_t aOffset, uint32_t aAvailable)
107 : data_pipe_detail::DataPipeBase(/* aReceiverSide */ false,
108 std::move(aPort), aShmem, aCapacity,
109 aPeerStatus, aOffset, aAvailable) {}
111 ~DataPipeSender() = default;
114 NS_DEFINE_STATIC_IID_ACCESSOR(DataPipeSender, NS_DATAPIPESENDER_IID)
116 #define NS_DATAPIPERECEIVER_IID \
118 0x0a185f83, 0x499e, 0x450c, { \
119 0x95, 0x82, 0x27, 0x67, 0xad, 0x6d, 0x64, 0xb5 \
123 // Helper class for streaming data from another process.
124 class DataPipeReceiver final : public nsIAsyncInputStream,
125 public nsIIPCSerializableInputStream,
126 public data_pipe_detail::DataPipeBase {
127 public:
128 NS_DECLARE_STATIC_IID_ACCESSOR(NS_DATAPIPERECEIVER_IID)
129 NS_DECL_THREADSAFE_ISUPPORTS
130 NS_DECL_NSIINPUTSTREAM
131 NS_DECL_NSIASYNCINPUTSTREAM
132 NS_DECL_NSIIPCSERIALIZABLEINPUTSTREAM
134 private:
135 friend nsresult NewDataPipe(uint32_t, DataPipeSender**, DataPipeReceiver**);
136 friend void data_pipe_detail::DataPipeWrite<DataPipeReceiver>(
137 IPC::MessageWriter* aWriter, DataPipeReceiver* aParam);
138 friend bool data_pipe_detail::DataPipeRead<DataPipeReceiver>(
139 IPC::MessageReader* aReader, RefPtr<DataPipeReceiver>* aResult);
141 explicit DataPipeReceiver(nsresult aError)
142 : data_pipe_detail::DataPipeBase(/* aReceiverSide */ true, aError) {}
143 DataPipeReceiver(ScopedPort aPort, SharedMemory* aShmem, uint32_t aCapacity,
144 nsresult aPeerStatus, uint32_t aOffset, uint32_t aAvailable)
145 : data_pipe_detail::DataPipeBase(/* aReceiverSide */ true,
146 std::move(aPort), aShmem, aCapacity,
147 aPeerStatus, aOffset, aAvailable) {}
149 ~DataPipeReceiver() = default;
152 NS_DEFINE_STATIC_IID_ACCESSOR(DataPipeReceiver, NS_DATAPIPERECEIVER_IID)
154 constexpr uint32_t kDefaultDataPipeCapacity = 64 * 1024;
157 * Create a new DataPipe pair. The sender and receiver ends of the pipe may be
158 * used to transfer data between processes. |aCapacity| is the capacity of the
159 * underlying ring buffer. If `0` is passed, `kDefaultDataPipeCapacity` will be
160 * used.
162 nsresult NewDataPipe(uint32_t aCapacity, DataPipeSender** aSender,
163 DataPipeReceiver** aReceiver);
165 } // namespace ipc
166 } // namespace mozilla
168 namespace IPC {
170 template <>
171 struct ParamTraits<mozilla::ipc::DataPipeSender*> {
172 static void Write(MessageWriter* aWriter,
173 mozilla::ipc::DataPipeSender* aParam);
174 static bool Read(MessageReader* aReader,
175 RefPtr<mozilla::ipc::DataPipeSender>* aResult);
178 template <>
179 struct ParamTraits<mozilla::ipc::DataPipeReceiver*> {
180 static void Write(MessageWriter* aWriter,
181 mozilla::ipc::DataPipeReceiver* aParam);
182 static bool Read(MessageReader* aReader,
183 RefPtr<mozilla::ipc::DataPipeReceiver>* aResult);
186 } // namespace IPC
188 #endif // mozilla_ipc_DataPipe_h