Index: Source/core/streams/ReadableStreamImpl.h |
diff --git a/Source/core/streams/ReadableStreamImpl.h b/Source/core/streams/ReadableStreamImpl.h |
index 08362e152561aa068cb4fdaae0d1ed965c7ffa05..6a9e1f58637a6085d106e126c3fd570b4d5458e6 100644 |
--- a/Source/core/streams/ReadableStreamImpl.h |
+++ b/Source/core/streams/ReadableStreamImpl.h |
@@ -6,10 +6,13 @@ |
#define ReadableStreamImpl_h |
#include "bindings/core/v8/ExceptionState.h" |
+#include "bindings/core/v8/ScriptPromise.h" |
+#include "bindings/core/v8/ScriptPromiseResolver.h" |
#include "bindings/core/v8/ScriptState.h" |
#include "bindings/core/v8/ScriptValue.h" |
#include "bindings/core/v8/V8ArrayBuffer.h" |
#include "bindings/core/v8/V8Binding.h" |
+#include "bindings/core/v8/V8IteratorResultValue.h" |
#include "core/dom/DOMArrayBuffer.h" |
#include "core/streams/ReadableStream.h" |
#include "wtf/Deque.h" |
@@ -82,7 +85,7 @@ public: |
~ReadableStreamImpl() override { } |
// ReadableStream methods |
- ScriptValue readInternal(ScriptState*, ExceptionState&) override; |
+ ScriptPromise read(ScriptState*) override; |
bool enqueue(typename ChunkTypeTraits::PassType); |
@@ -95,10 +98,19 @@ public: |
DEFINE_INLINE_VIRTUAL_TRACE() |
{ |
visitor->trace(m_strategy); |
+#if ENABLE(OILPAN) |
+ visitor->trace(m_pendingReads); |
+#endif |
ReadableStream::trace(visitor); |
} |
private: |
+#if ENABLE(OILPAN) |
+ using PendingReads = HeapDeque<Member<ScriptPromiseResolver>>; |
+#else |
+ using PendingReads = Deque<RefPtr<ScriptPromiseResolver>>; |
+#endif |
+ |
// ReadableStream methods |
bool isQueueEmpty() const override { return m_queue.isEmpty(); } |
void clearQueue() override |
@@ -106,13 +118,33 @@ private: |
m_queue.clear(); |
m_totalQueueSize = 0; |
} |
+ |
+ void resolveAllPendingReadsAsDone() override |
+ { |
+ for (auto& resolver : m_pendingReads) { |
+ ScriptState::Scope scope(resolver->scriptState()); |
+ resolver->resolve(v8IteratorResultDone(resolver->scriptState())); |
+ } |
+ m_pendingReads.clear(); |
+ } |
+ |
+ void rejectAllPendingReads(PassRefPtrWillBeRawPtr<DOMException> r) override |
+ { |
+ RefPtrWillBeRawPtr<DOMException> reason = r; |
+ for (auto& resolver : m_pendingReads) |
+ resolver->reject(reason); |
+ m_pendingReads.clear(); |
+ } |
+ |
bool shouldApplyBackpressure() override |
{ |
return m_strategy->shouldApplyBackpressure(m_totalQueueSize, this); |
} |
+ bool hasPendingReads() const override { return !m_pendingReads.isEmpty(); } |
Member<Strategy> m_strategy; |
Deque<std::pair<typename ChunkTypeTraits::HoldType, size_t>> m_queue; |
+ PendingReads m_pendingReads; |
size_t m_totalQueueSize; |
}; |
@@ -122,26 +154,37 @@ bool ReadableStreamImpl<ChunkTypeTraits>::enqueue(typename ChunkTypeTraits::Pass |
size_t size = m_strategy->size(chunk, this); |
if (!enqueuePreliminaryCheck()) |
return false; |
- m_queue.append(std::make_pair(chunk, size)); |
- m_totalQueueSize += size; |
+ |
+ if (m_pendingReads.isEmpty()) { |
+ m_queue.append(std::make_pair(chunk, size)); |
+ m_totalQueueSize += size; |
+ return enqueuePostAction(); |
+ } |
+ |
+ RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = m_pendingReads.takeFirst(); |
+ ScriptState* scriptState = resolver->scriptState(); |
+ ScriptState::Scope scope(scriptState); |
+ resolver->resolve(v8IteratorResult(scriptState, chunk)); |
return enqueuePostAction(); |
} |
template <typename ChunkTypeTraits> |
-ScriptValue ReadableStreamImpl<ChunkTypeTraits>::readInternal(ScriptState* scriptState, ExceptionState& exceptionState) |
+ScriptPromise ReadableStreamImpl<ChunkTypeTraits>::read(ScriptState* scriptState) |
{ |
- readInternalPreliminaryCheck(exceptionState); |
- if (exceptionState.hadException()) |
- return ScriptValue(); |
ASSERT(stateInternal() == Readable); |
- ASSERT(!m_queue.isEmpty()); |
+ if (m_queue.isEmpty()) { |
+ m_pendingReads.append(ScriptPromiseResolver::create(scriptState)); |
+ return m_pendingReads.last()->promise(); |
+ } |
+ |
auto pair = m_queue.takeFirst(); |
typename ChunkTypeTraits::HoldType chunk = pair.first; |
size_t size = pair.second; |
ASSERT(m_totalQueueSize >= size); |
m_totalQueueSize -= size; |
readInternalPostAction(); |
- return ChunkTypeTraits::toScriptValue(scriptState, chunk); |
+ |
+ return ScriptPromise::cast(scriptState, v8IteratorResult(scriptState, chunk)); |
} |
template <typename ChunkTypeTraits> |
@@ -149,7 +192,7 @@ void ReadableStreamImpl<ChunkTypeTraits>::readInternal(Deque<std::pair<typename |
{ |
// We omit the preliminary check. Check it by yourself. |
ASSERT(stateInternal() == Readable); |
- ASSERT(!m_queue.isEmpty()); |
+ ASSERT(m_pendingReads.isEmpty()); |
ASSERT(queue.isEmpty()); |
queue.swap(m_queue); |