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/. */
7 #ifndef mozilla_dom_BodyStream_h
8 #define mozilla_dom_BodyStream_h
11 #include "js/Stream.h"
12 #include "nsIAsyncInputStream.h"
13 #include "nsCycleCollectionParticipant.h"
14 #include "nsIObserver.h"
15 #include "nsISupportsImpl.h"
17 #include "nsWeakReference.h"
18 #include "mozilla/Mutex.h"
20 class nsIGlobalObject
;
32 class BodyStreamHolder
: public nsISupports
{
33 friend class BodyStream
;
36 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
37 NS_DECL_CYCLE_COLLECTION_CLASS(BodyStreamHolder
)
41 virtual void NullifyStream() = 0;
43 virtual void MarkAsRead() = 0;
45 virtual void SetReadableStreamBody(JSObject
* aBody
) = 0;
47 virtual JSObject
* GetReadableStreamBody() = 0;
50 virtual ~BodyStreamHolder() = default;
53 void StoreBodyStream(BodyStream
* aBodyStream
);
54 void ForgetBodyStream();
56 // Raw pointer because BodyStream keeps BodyStreamHolder alive and it
57 // nullifies this stream before being released.
58 BodyStream
* mBodyStream
;
61 bool mStreamCreated
= false;
65 class BodyStream final
: public nsIInputStreamCallback
,
67 public nsSupportsWeakReference
,
68 private JS::ReadableStreamUnderlyingSource
{
69 friend class BodyStreamHolder
;
72 NS_DECL_THREADSAFE_ISUPPORTS
73 NS_DECL_NSIINPUTSTREAMCALLBACK
76 // This method creates a JS ReadableStream object and it assigns it to the
77 // aStreamHolder calling SetReadableStreamBody().
78 static void Create(JSContext
* aCx
, BodyStreamHolder
* aStreamHolder
,
79 nsIGlobalObject
* aGlobal
, nsIInputStream
* aInputStream
,
84 static nsresult
RetrieveInputStream(
85 JS::ReadableStreamUnderlyingSource
* aUnderlyingReadableStreamSource
,
86 nsIInputStream
** aInputStream
);
89 BodyStream(nsIGlobalObject
* aGlobal
, BodyStreamHolder
* aStreamHolder
,
90 nsIInputStream
* aInputStream
);
94 void AssertIsOnOwningThread();
96 void AssertIsOnOwningThread() {}
99 void requestData(JSContext
* aCx
, JS::HandleObject aStream
,
100 size_t aDesiredSize
) override
;
102 void writeIntoReadRequestBuffer(JSContext
* aCx
, JS::HandleObject aStream
,
103 void* aBuffer
, size_t aLength
,
104 size_t* aBytesWritten
) override
;
106 JS::Value
cancel(JSContext
* aCx
, JS::HandleObject aStream
,
107 JS::HandleValue aReason
) override
;
109 void onClosed(JSContext
* aCx
, JS::HandleObject aStream
) override
;
111 void onErrored(JSContext
* aCx
, JS::HandleObject aStream
,
112 JS::HandleValue aReason
) override
;
114 void finalize() override
;
116 void ErrorPropagation(JSContext
* aCx
, const MutexAutoLock
& aProofOfLock
,
117 JS::HandleObject aStream
, nsresult aRv
);
119 void CloseAndReleaseObjects(JSContext
* aCx
, const MutexAutoLock
& aProofOfLock
,
120 JS::HandleObject aSteam
);
122 class WorkerShutdown
;
124 void ReleaseObjects(const MutexAutoLock
& aProofOfLock
);
126 void ReleaseObjects();
131 // This is the beginning state before any reading operation.
134 // RequestDataCallback has not been called yet. We haven't started to read
135 // data from the stream yet.
138 // We are reading data in a separate I/O thread.
141 // We are ready to write something in the JS Buffer.
144 // After a writing, we want to check if the stream is closed. After the
145 // check, we go back to eWaiting. If a reading request happens in the
146 // meantime, we move to eReading state.
149 // Operation completed.
153 // We need a mutex because JS engine can release BodyStream on a non-owning
154 // thread. We must be sure that the releasing of resources doesn't trigger
158 // Protected by mutex.
161 nsCOMPtr
<nsIGlobalObject
> mGlobal
;
162 RefPtr
<BodyStreamHolder
> mStreamHolder
;
163 nsCOMPtr
<nsIEventTarget
> mOwningEventTarget
;
165 // This is the original inputStream received during the CTOR. It will be
166 // converted into an nsIAsyncInputStream and stored into mInputStream at the
168 nsCOMPtr
<nsIInputStream
> mOriginalInputStream
;
169 nsCOMPtr
<nsIAsyncInputStream
> mInputStream
;
171 RefPtr
<WeakWorkerRef
> mWorkerRef
;
175 } // namespace mozilla
177 #endif // mozilla_dom_BodyStream_h