Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1424)

Unified Diff: Source/core/streams/ReadableStreamReader.cpp

Issue 1004623007: Streams Implementation Update: async read (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@stream-reader-read
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/streams/ReadableStreamReader.h ('k') | Source/core/streams/ReadableStreamReader.idl » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/streams/ReadableStreamReader.cpp
diff --git a/Source/core/streams/ReadableStreamReader.cpp b/Source/core/streams/ReadableStreamReader.cpp
index c58706363fc66434814caf926be9319b172c315a..60417d750062895377a49b3517da21d6c7dbc0a5 100644
--- a/Source/core/streams/ReadableStreamReader.cpp
+++ b/Source/core/streams/ReadableStreamReader.cpp
@@ -6,99 +6,33 @@
#include "core/streams/ReadableStreamReader.h"
#include "bindings/core/v8/ExceptionState.h"
-#include "bindings/core/v8/ScriptFunction.h"
#include "bindings/core/v8/ScriptPromiseResolver.h"
+#include "bindings/core/v8/V8IteratorResultValue.h"
#include "core/dom/DOMException.h"
#include "core/streams/ReadableStream.h"
namespace blink {
-namespace {
-
-class PromiseRaceFulfillHandler : public ScriptFunction {
-public:
- static v8::Handle<v8::Function> create(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolver)
- {
- return (new PromiseRaceFulfillHandler(resolver))->bindToV8Function();
- }
-
- DEFINE_INLINE_TRACE()
- {
- visitor->trace(m_resolver);
- ScriptFunction::trace(visitor);
- }
-
-private:
- explicit PromiseRaceFulfillHandler(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolver)
- : ScriptFunction(resolver->scriptState())
- , m_resolver(resolver) { }
- ScriptValue call(ScriptValue value) override
- {
- m_resolver->resolve(value);
- return ScriptValue(scriptState(), v8::Undefined(scriptState()->isolate()));
- }
-
- RefPtrWillBeMember<ScriptPromiseResolver> m_resolver;
-};
-
-class PromiseRaceRejectHandler : public ScriptFunction {
-public:
- static v8::Handle<v8::Function> create(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolver)
- {
- return (new PromiseRaceRejectHandler(resolver))->bindToV8Function();
- }
-
- DEFINE_INLINE_TRACE()
- {
- visitor->trace(m_resolver);
- ScriptFunction::trace(visitor);
- }
-
-private:
- explicit PromiseRaceRejectHandler(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolver)
- : ScriptFunction(resolver->scriptState())
- , m_resolver(resolver) { }
- ScriptValue call(ScriptValue value) override
- {
- m_resolver->reject(value);
- return ScriptValue(scriptState(), v8::Undefined(scriptState()->isolate()));
- }
-
- RefPtrWillBeMember<ScriptPromiseResolver> m_resolver;
-};
-
-ScriptPromise race(ScriptState* scriptState, const Vector<ScriptPromise>& promises)
-{
- RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
- for (ScriptPromise promise : promises) {
- promise.then(PromiseRaceFulfillHandler::create(resolver), PromiseRaceRejectHandler::create(resolver));
- }
- return resolver->promise();
-}
-
-} // namespace
-
ReadableStreamReader::ReadableStreamReader(ReadableStream* stream)
: ActiveDOMObject(stream->executionContext())
, m_stream(stream)
- , m_released(new ReleasedPromise(stream->executionContext(), this, ReleasedPromise::Released))
, m_stateAfterRelease(ReadableStream::Closed)
+ , m_closed(new ClosedPromise(stream->executionContext(), this, ClosedPromise::Closed))
{
suspendIfNeeded();
ASSERT(m_stream->isLockedTo(nullptr));
m_stream->setReader(this);
+
+ if (m_stream->stateInternal() == ReadableStream::Closed || m_stream->stateInternal() == ReadableStream::Errored) {
+ // If the stream is already closed or errored the created reader
+ // should be closed or errored respectively.
+ releaseLock();
+ }
}
ScriptPromise ReadableStreamReader::closed(ScriptState* scriptState)
{
- if (isActive()) {
- Vector<ScriptPromise> promises;
- promises.append(m_stream->closed(scriptState));
- promises.append(m_released->promise(scriptState->world()));
- return race(scriptState, promises);
- }
- ASSERT(m_released);
- return m_closedAfterRelease->promise(scriptState->world());
+ return m_closed->promise(scriptState->world());
}
bool ReadableStreamReader::isActive() const
@@ -106,41 +40,46 @@ bool ReadableStreamReader::isActive() const
return m_stream->isLockedTo(this);
}
-ScriptPromise ReadableStreamReader::ready(ScriptState* scriptState)
-{
- if (isActive()) {
- Vector<ScriptPromise> promises;
- promises.append(m_stream->readyInternal(scriptState));
- promises.append(m_released->promise(scriptState->world()));
- return race(scriptState, promises);
- }
- ASSERT(m_readyAfterRelease);
- return m_readyAfterRelease->promise(scriptState->world());
-}
-
-String ReadableStreamReader::state() const
+ScriptPromise ReadableStreamReader::cancel(ScriptState* scriptState, ScriptValue reason)
{
if (isActive())
- return ReadableStream::stateToString(m_stream->stateInternal());
- return ReadableStream::stateToString(m_stateAfterRelease);
+ return m_stream->cancelInternal(scriptState, reason);
+
+ // A method should return a different promise on each call.
+ RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
+ ScriptPromise promise = resolver->promise();
+ resolver->resolve(closed(scriptState).v8Value());
+ return promise;
}
-ScriptPromise ReadableStreamReader::cancel(ScriptState* scriptState, ScriptValue reason)
+ScriptPromise ReadableStreamReader::read(ScriptState* scriptState)
{
- if (isActive()) {
- releaseLock();
- return m_stream->cancel(scriptState, reason);
+ if (!isActive()) {
+ ASSERT(m_stateAfterRelease == ReadableStream::Closed || m_stateAfterRelease == ReadableStream::Errored);
+ if (m_stateAfterRelease == ReadableStream::Closed) {
+ // {value: undefined, done: true}
+ return ScriptPromise::cast(scriptState, v8IteratorResultDone(scriptState));
+ }
+ // A method should return a different promise on each call.
+ RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
+ ScriptPromise promise = resolver->promise();
+ resolver->resolve(closed(scriptState).v8Value());
+ return promise;
}
- return m_closedAfterRelease->promise(scriptState->world());
+
+ return m_stream->read(scriptState);
}
-ScriptValue ReadableStreamReader::read(ScriptState* scriptState, ExceptionState& es)
+void ReadableStreamReader::releaseLock(ExceptionState& es)
{
- if (!isActive()) {
- es.throwTypeError("The stream is not locked to this reader");
- return ScriptValue();
+ if (!isActive())
+ return;
+ if (m_stream->hasPendingReads()) {
+ es.throwTypeError("The stream has pending read operations.");
+ return;
}
- return m_stream->readInternal(scriptState, es);
+
+ releaseLock();
}
void ReadableStreamReader::releaseLock()
@@ -148,29 +87,22 @@ void ReadableStreamReader::releaseLock()
if (!isActive())
return;
- m_stream->setReader(nullptr);
-
- m_readyAfterRelease = new ReadyPromise(executionContext(), this, ReadyPromise::Ready);
- m_readyAfterRelease->resolve(ToV8UndefinedGenerator());
- m_closedAfterRelease = new ClosedPromise(executionContext(), this, ReadyPromise::Closed);
-
+ ASSERT(!m_stream->hasPendingReads());
if (m_stream->stateInternal() == ReadableStream::Closed) {
m_stateAfterRelease = ReadableStream::Closed;
- m_closedAfterRelease->resolve(ToV8UndefinedGenerator());
+ m_closed->resolve(ToV8UndefinedGenerator());
} else if (m_stream->stateInternal() == ReadableStream::Errored) {
m_stateAfterRelease = ReadableStream::Errored;
- m_closedAfterRelease->reject(m_stream->storedException());
+ m_closed->reject(m_stream->storedException());
} else {
m_stateAfterRelease = ReadableStream::Closed;
- m_closedAfterRelease->resolve(ToV8UndefinedGenerator());
+ m_closed->resolve(ToV8UndefinedGenerator());
}
- m_released->resolve(ToV8UndefinedGenerator());
- ASSERT(!isActive());
-}
-ScriptPromise ReadableStreamReader::released(ScriptState* scriptState)
-{
- return m_released->promise(scriptState->world());
+ // We call setReader(nullptr) after resolving / rejecting |m_closed|
+ // because it affects hasPendingActivity.
+ m_stream->setReader(nullptr);
+ ASSERT(!isActive());
}
bool ReadableStreamReader::hasPendingActivity() const
@@ -189,9 +121,7 @@ void ReadableStreamReader::stop()
DEFINE_TRACE(ReadableStreamReader)
{
visitor->trace(m_stream);
- visitor->trace(m_released);
- visitor->trace(m_closedAfterRelease);
- visitor->trace(m_readyAfterRelease);
+ visitor->trace(m_closed);
ActiveDOMObject::trace(visitor);
}
« no previous file with comments | « Source/core/streams/ReadableStreamReader.h ('k') | Source/core/streams/ReadableStreamReader.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698