Bug 1858509 add thread-safety annotations around MediaSourceDemuxer::mMonitor r=alwu
[gecko.git] / ipc / glue / DataPipe.h
blobf339b1c72d223baf36e53b0e4fd46f2c36403b22
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,
33 SharedMemoryBasic::Handle aShmemHandle, SharedMemory* aShmem,
34 uint32_t aCapacity, nsresult aPeerStatus, uint32_t aOffset,
35 uint32_t aAvailable);
37 void CloseInternal(DataPipeAutoLock&, nsresult aStatus) MOZ_REQUIRES(*mMutex);
39 void AsyncWaitInternal(already_AddRefed<nsIRunnable> aCallback,
40 already_AddRefed<nsIEventTarget> aTarget,
41 bool aClosureOnly) MOZ_EXCLUDES(*mMutex);
43 // Like `nsWriteSegmentFun` or `nsReadSegmentFun`.
44 using ProcessSegmentFun =
45 FunctionRef<nsresult(Span<char> aSpan, uint32_t aProcessedThisCall,
46 uint32_t* aProcessedCount)>;
47 nsresult ProcessSegmentsInternal(uint32_t aCount,
48 ProcessSegmentFun aProcessSegment,
49 uint32_t* aProcessedCount)
50 MOZ_EXCLUDES(*mMutex);
52 nsresult CheckStatus(DataPipeAutoLock&) MOZ_REQUIRES(*mMutex);
54 nsCString Describe(DataPipeAutoLock&) MOZ_REQUIRES(*mMutex);
56 // Thread safety helper to tell the analysis that `mLink->mMutex` is held when
57 // `mMutex` is held.
58 void AssertSameMutex(const std::shared_ptr<Mutex>& aMutex)
59 MOZ_REQUIRES(*mMutex) MOZ_ASSERT_CAPABILITY(*aMutex) {
60 MOZ_ASSERT(mMutex == aMutex);
63 virtual ~DataPipeBase();
65 const std::shared_ptr<Mutex> mMutex;
66 nsresult mStatus MOZ_GUARDED_BY(*mMutex) = NS_OK;
67 RefPtr<DataPipeLink> mLink MOZ_GUARDED_BY(*mMutex);
70 template <typename T>
71 void DataPipeWrite(IPC::MessageWriter* aWriter, T* aParam);
73 template <typename T>
74 bool DataPipeRead(IPC::MessageReader* aReader, RefPtr<T>* aResult);
76 } // namespace data_pipe_detail
78 class DataPipeSender;
79 class DataPipeReceiver;
81 #define NS_DATAPIPESENDER_IID \
82 { \
83 0x6698ed77, 0x9fff, 0x425d, { \
84 0xb0, 0xa6, 0x1d, 0x30, 0x66, 0xee, 0xb8, 0x16 \
85 } \
88 // Helper class for streaming data to another process.
89 class DataPipeSender final : public nsIAsyncOutputStream,
90 public data_pipe_detail::DataPipeBase {
91 public:
92 NS_DECLARE_STATIC_IID_ACCESSOR(NS_DATAPIPESENDER_IID)
93 NS_DECL_THREADSAFE_ISUPPORTS
94 NS_DECL_NSIOUTPUTSTREAM
95 NS_DECL_NSIASYNCOUTPUTSTREAM
97 private:
98 friend nsresult NewDataPipe(uint32_t, DataPipeSender**, DataPipeReceiver**);
99 friend void data_pipe_detail::DataPipeWrite<DataPipeSender>(
100 IPC::MessageWriter* aWriter, DataPipeSender* aParam);
101 friend bool data_pipe_detail::DataPipeRead<DataPipeSender>(
102 IPC::MessageReader* aReader, RefPtr<DataPipeSender>* aResult);
104 explicit DataPipeSender(nsresult aError)
105 : data_pipe_detail::DataPipeBase(/* aReceiverSide */ false, aError) {}
106 DataPipeSender(ScopedPort aPort, SharedMemoryBasic::Handle aShmemHandle,
107 SharedMemory* aShmem, uint32_t aCapacity, nsresult aPeerStatus,
108 uint32_t aOffset, uint32_t aAvailable)
109 : data_pipe_detail::DataPipeBase(
110 /* aReceiverSide */ false, std::move(aPort),
111 std::move(aShmemHandle), aShmem, aCapacity, aPeerStatus, aOffset,
112 aAvailable) {}
114 ~DataPipeSender() = default;
117 NS_DEFINE_STATIC_IID_ACCESSOR(DataPipeSender, NS_DATAPIPESENDER_IID)
119 #define NS_DATAPIPERECEIVER_IID \
121 0x0a185f83, 0x499e, 0x450c, { \
122 0x95, 0x82, 0x27, 0x67, 0xad, 0x6d, 0x64, 0xb5 \
126 // Helper class for streaming data from another process.
127 class DataPipeReceiver final : public nsIAsyncInputStream,
128 public nsIIPCSerializableInputStream,
129 public data_pipe_detail::DataPipeBase {
130 public:
131 NS_DECLARE_STATIC_IID_ACCESSOR(NS_DATAPIPERECEIVER_IID)
132 NS_DECL_THREADSAFE_ISUPPORTS
133 NS_DECL_NSIINPUTSTREAM
134 NS_DECL_NSIASYNCINPUTSTREAM
135 NS_DECL_NSIIPCSERIALIZABLEINPUTSTREAM
137 private:
138 friend nsresult NewDataPipe(uint32_t, DataPipeSender**, DataPipeReceiver**);
139 friend void data_pipe_detail::DataPipeWrite<DataPipeReceiver>(
140 IPC::MessageWriter* aWriter, DataPipeReceiver* aParam);
141 friend bool data_pipe_detail::DataPipeRead<DataPipeReceiver>(
142 IPC::MessageReader* aReader, RefPtr<DataPipeReceiver>* aResult);
144 explicit DataPipeReceiver(nsresult aError)
145 : data_pipe_detail::DataPipeBase(/* aReceiverSide */ true, aError) {}
146 DataPipeReceiver(ScopedPort aPort, SharedMemoryBasic::Handle aShmemHandle,
147 SharedMemory* aShmem, uint32_t aCapacity,
148 nsresult aPeerStatus, uint32_t aOffset, uint32_t aAvailable)
149 : data_pipe_detail::DataPipeBase(
150 /* aReceiverSide */ true, std::move(aPort), std::move(aShmemHandle),
151 aShmem, aCapacity, aPeerStatus, aOffset, aAvailable) {}
153 ~DataPipeReceiver() = default;
156 NS_DEFINE_STATIC_IID_ACCESSOR(DataPipeReceiver, NS_DATAPIPERECEIVER_IID)
158 constexpr uint32_t kDefaultDataPipeCapacity = 64 * 1024;
161 * Create a new DataPipe pair. The sender and receiver ends of the pipe may be
162 * used to transfer data between processes. |aCapacity| is the capacity of the
163 * underlying ring buffer. If `0` is passed, `kDefaultDataPipeCapacity` will be
164 * used.
166 nsresult NewDataPipe(uint32_t aCapacity, DataPipeSender** aSender,
167 DataPipeReceiver** aReceiver);
169 } // namespace ipc
170 } // namespace mozilla
172 namespace IPC {
174 template <>
175 struct ParamTraits<mozilla::ipc::DataPipeSender*> {
176 static void Write(MessageWriter* aWriter,
177 mozilla::ipc::DataPipeSender* aParam);
178 static bool Read(MessageReader* aReader,
179 RefPtr<mozilla::ipc::DataPipeSender>* aResult);
182 template <>
183 struct ParamTraits<mozilla::ipc::DataPipeReceiver*> {
184 static void Write(MessageWriter* aWriter,
185 mozilla::ipc::DataPipeReceiver* aParam);
186 static bool Read(MessageReader* aReader,
187 RefPtr<mozilla::ipc::DataPipeReceiver>* aResult);
190 } // namespace IPC
192 #endif // mozilla_ipc_DataPipe_h