Bug 1856663 - Add more chunks for Android mochitest-plain. r=jmaher,taskgraph-reviewe...
[gecko.git] / dom / streams / WritableStream.h
blob8b380020fef582906f618a6a2a27c8de6d342ccd
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
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/. */
7 #ifndef mozilla_dom_WritableStream_h
8 #define mozilla_dom_WritableStream_h
10 #include "js/TypeDecls.h"
11 #include "js/Value.h"
12 #include "mozilla/Attributes.h"
13 #include "mozilla/ErrorResult.h"
14 #include "mozilla/dom/BindingDeclarations.h"
15 #include "mozilla/dom/QueuingStrategyBinding.h"
16 #include "mozilla/dom/WritableStreamDefaultController.h"
17 #include "mozilla/dom/WritableStreamDefaultWriter.h"
19 #include "nsCycleCollectionParticipant.h"
20 #include "nsWrapperCache.h"
22 namespace mozilla::dom {
24 class Promise;
25 class WritableStreamDefaultController;
26 class WritableStreamDefaultWriter;
27 class UnderlyingSinkAlgorithmsBase;
28 class UniqueMessagePortId;
29 class MessagePort;
31 class WritableStream : public nsISupports, public nsWrapperCache {
32 public:
33 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
34 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(WritableStream)
36 friend class ReadableStream;
38 protected:
39 virtual ~WritableStream();
41 virtual void LastRelease() {}
43 // If one extends WritableStream with another cycle collectable class,
44 // calling HoldJSObjects and DropJSObjects should happen using 'this' of
45 // that extending class. And in that case Explicit should be passed to the
46 // constructor of WriteableStream so that it doesn't make those calls.
47 // See also https://bugzilla.mozilla.org/show_bug.cgi?id=1801214.
48 enum class HoldDropJSObjectsCaller { Implicit, Explicit };
50 explicit WritableStream(const GlobalObject& aGlobal,
51 HoldDropJSObjectsCaller aHoldDropCaller);
52 explicit WritableStream(nsIGlobalObject* aGlobal,
53 HoldDropJSObjectsCaller aHoldDropCaller);
55 public:
56 // Slot Getter/Setters:
57 bool Backpressure() const { return mBackpressure; }
58 void SetBackpressure(bool aBackpressure) { mBackpressure = aBackpressure; }
60 Promise* GetCloseRequest() { return mCloseRequest; }
61 void SetCloseRequest(Promise* aRequest) { mCloseRequest = aRequest; }
63 MOZ_KNOWN_LIVE WritableStreamDefaultController* Controller() {
64 return mController;
66 void SetController(WritableStreamDefaultController& aController) {
67 MOZ_ASSERT(!mController);
68 mController = &aController;
71 Promise* GetInFlightWriteRequest() const { return mInFlightWriteRequest; }
73 Promise* GetPendingAbortRequestPromise() const {
74 return mPendingAbortRequestPromise;
77 void SetPendingAbortRequest(Promise* aPromise, JS::Handle<JS::Value> aReason,
78 bool aWasAlreadyErroring) {
79 mPendingAbortRequestPromise = aPromise;
80 mPendingAbortRequestReason = aReason;
81 mPendingAbortRequestWasAlreadyErroring = aWasAlreadyErroring;
84 WritableStreamDefaultWriter* GetWriter() const { return mWriter; }
85 void SetWriter(WritableStreamDefaultWriter* aWriter) { mWriter = aWriter; }
87 enum class WriterState { Writable, Closed, Erroring, Errored };
89 WriterState State() const { return mState; }
90 void SetState(const WriterState& aState) { mState = aState; }
92 JS::Value StoredError() const { return mStoredError; }
93 void SetStoredError(JS::Handle<JS::Value> aStoredError) {
94 mStoredError = aStoredError;
97 void AppendWriteRequest(RefPtr<Promise>& aRequest) {
98 mWriteRequests.AppendElement(aRequest);
101 // CreateWritableStream
102 MOZ_CAN_RUN_SCRIPT static already_AddRefed<WritableStream> CreateAbstract(
103 JSContext* aCx, nsIGlobalObject* aGlobal,
104 UnderlyingSinkAlgorithmsBase* aAlgorithms, double aHighWaterMark,
105 QueuingStrategySize* aSizeAlgorithm, ErrorResult& aRv);
107 // WritableStreamCloseQueuedOrInFlight
108 bool CloseQueuedOrInFlight() const {
109 return mCloseRequest || mInFlightCloseRequest;
112 // WritableStreamDealWithRejection
113 MOZ_CAN_RUN_SCRIPT void DealWithRejection(JSContext* aCx,
114 JS::Handle<JS::Value> aError,
115 ErrorResult& aRv);
117 // WritableStreamFinishErroring
118 MOZ_CAN_RUN_SCRIPT void FinishErroring(JSContext* aCx, ErrorResult& aRv);
120 // WritableStreamFinishInFlightClose
121 void FinishInFlightClose();
123 // WritableStreamFinishInFlightCloseWithError
124 MOZ_CAN_RUN_SCRIPT void FinishInFlightCloseWithError(
125 JSContext* aCx, JS::Handle<JS::Value> aError, ErrorResult& aRv);
127 // WritableStreamFinishInFlightWrite
128 void FinishInFlightWrite();
130 // WritableStreamFinishInFlightWriteWithError
131 MOZ_CAN_RUN_SCRIPT void FinishInFlightWriteWithError(
132 JSContext* aCX, JS::Handle<JS::Value> aError, ErrorResult& aR);
134 // WritableStreamHasOperationMarkedInFlight
135 bool HasOperationMarkedInFlight() const {
136 return mInFlightWriteRequest || mInFlightCloseRequest;
139 // WritableStreamMarkCloseRequestInFlight
140 void MarkCloseRequestInFlight();
142 // WritableStreamMarkFirstWriteRequestInFlight
143 void MarkFirstWriteRequestInFlight();
145 // WritableStreamRejectCloseAndClosedPromiseIfNeeded
146 void RejectCloseAndClosedPromiseIfNeeded();
148 // WritableStreamStartErroring
149 MOZ_CAN_RUN_SCRIPT void StartErroring(JSContext* aCx,
150 JS::Handle<JS::Value> aReason,
151 ErrorResult& aRv);
153 // WritableStreamUpdateBackpressure
154 void UpdateBackpressure(bool aBackpressure);
156 // [Transferable]
157 // https://html.spec.whatwg.org/multipage/structured-data.html#transfer-steps
158 MOZ_CAN_RUN_SCRIPT bool Transfer(JSContext* aCx,
159 UniqueMessagePortId& aPortId);
160 // https://html.spec.whatwg.org/multipage/structured-data.html#transfer-receiving-steps
161 MOZ_CAN_RUN_SCRIPT static already_AddRefed<WritableStream>
162 ReceiveTransferImpl(JSContext* aCx, nsIGlobalObject* aGlobal,
163 MessagePort& aPort);
164 MOZ_CAN_RUN_SCRIPT static bool ReceiveTransfer(
165 JSContext* aCx, nsIGlobalObject* aGlobal, MessagePort& aPort,
166 JS::MutableHandle<JSObject*> aReturnObject);
168 // Public functions to implement other specs
169 // https://streams.spec.whatwg.org/#other-specs-ws
171 // https://streams.spec.whatwg.org/#writablestream-set-up
172 protected:
173 // Sets up the WritableStream. Intended for subclasses.
174 void SetUpNative(JSContext* aCx, UnderlyingSinkAlgorithmsWrapper& aAlgorithms,
175 Maybe<double> aHighWaterMark,
176 QueuingStrategySize* aSizeAlgorithm, ErrorResult& aRv);
178 public:
179 // Creates and sets up a WritableStream. Use SetUpNative for this purpose in
180 // subclasses.
181 static already_AddRefed<WritableStream> CreateNative(
182 JSContext* aCx, nsIGlobalObject& aGlobal,
183 UnderlyingSinkAlgorithmsWrapper& aAlgorithms,
184 Maybe<double> aHighWaterMark, QueuingStrategySize* aSizeAlgorithm,
185 ErrorResult& aRv);
187 // The following definitions must only be used on WritableStream instances
188 // initialized via the above set up algorithm:
190 // https://streams.spec.whatwg.org/#writablestream-error
191 MOZ_CAN_RUN_SCRIPT void ErrorNative(JSContext* aCx,
192 JS::Handle<JS::Value> aError,
193 ErrorResult& aRv);
195 // IDL layer functions
197 nsIGlobalObject* GetParentObject() const { return mGlobal; }
199 JSObject* WrapObject(JSContext* aCx,
200 JS::Handle<JSObject*> aGivenProto) override;
202 // IDL methods
204 // TODO: Use MOZ_CAN_RUN_SCRIPT when IDL constructors can use it (bug 1749042)
205 MOZ_CAN_RUN_SCRIPT_BOUNDARY static already_AddRefed<WritableStream>
206 Constructor(const GlobalObject& aGlobal,
207 const Optional<JS::Handle<JSObject*>>& aUnderlyingSink,
208 const QueuingStrategy& aStrategy, ErrorResult& aRv);
210 bool Locked() const { return !!mWriter; }
212 MOZ_CAN_RUN_SCRIPT already_AddRefed<Promise> Abort(
213 JSContext* cx, JS::Handle<JS::Value> aReason, ErrorResult& aRv);
215 MOZ_CAN_RUN_SCRIPT already_AddRefed<Promise> Close(JSContext* aCx,
216 ErrorResult& aRv);
218 already_AddRefed<WritableStreamDefaultWriter> GetWriter(ErrorResult& aRv);
220 protected:
221 nsCOMPtr<nsIGlobalObject> mGlobal;
223 // Internal Slots:
224 private:
225 bool mBackpressure = false;
226 RefPtr<Promise> mCloseRequest;
227 RefPtr<WritableStreamDefaultController> mController;
228 RefPtr<Promise> mInFlightWriteRequest;
229 RefPtr<Promise> mInFlightCloseRequest;
231 // We inline all members of [[pendingAbortRequest]] in this class.
232 // The absence (i.e. undefined) of the [[pendingAbortRequest]]
233 // is indicated by mPendingAbortRequestPromise = nullptr.
234 RefPtr<Promise> mPendingAbortRequestPromise;
235 JS::Heap<JS::Value> mPendingAbortRequestReason;
236 bool mPendingAbortRequestWasAlreadyErroring = false;
238 WriterState mState = WriterState::Writable;
239 JS::Heap<JS::Value> mStoredError;
240 RefPtr<WritableStreamDefaultWriter> mWriter;
241 nsTArray<RefPtr<Promise>> mWriteRequests;
243 HoldDropJSObjectsCaller mHoldDropCaller;
246 namespace streams_abstract {
248 inline bool IsWritableStreamLocked(WritableStream* aStream) {
249 return aStream->Locked();
252 MOZ_CAN_RUN_SCRIPT already_AddRefed<Promise> WritableStreamAbort(
253 JSContext* aCx, WritableStream* aStream, JS::Handle<JS::Value> aReason,
254 ErrorResult& aRv);
256 MOZ_CAN_RUN_SCRIPT already_AddRefed<Promise> WritableStreamClose(
257 JSContext* aCx, WritableStream* aStream, ErrorResult& aRv);
259 already_AddRefed<Promise> WritableStreamAddWriteRequest(
260 WritableStream* aStream);
262 already_AddRefed<WritableStreamDefaultWriter>
263 AcquireWritableStreamDefaultWriter(WritableStream* aStream, ErrorResult& aRv);
265 } // namespace streams_abstract
267 } // namespace mozilla::dom
269 #endif // mozilla_dom_WritableStream_h