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

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

Issue 837673002: Introduce ExclusiveStreamReader. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 11 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
Index: Source/core/streams/ReadableStream.cpp
diff --git a/Source/core/streams/ReadableStream.cpp b/Source/core/streams/ReadableStream.cpp
index 0f1a80cf61547873af993ab1d7c6070e855e8280..061b9b942ef26373be56271cfeb5178e34af2761 100644
--- a/Source/core/streams/ReadableStream.cpp
+++ b/Source/core/streams/ReadableStream.cpp
@@ -12,6 +12,7 @@
#include "core/dom/DOMException.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/ExecutionContext.h"
+#include "core/streams/ExclusiveStreamReader.h"
#include "core/streams/UnderlyingSource.h"
namespace blink {
@@ -33,6 +34,32 @@ private:
}
};
+class ResolveWithReady : public ScriptFunction {
+public:
+ static v8::Handle<v8::Function> create(ScriptState* scriptState, ReadableStream* stream)
+ {
+ return (new ResolveWithReady(scriptState, stream))->bindToV8Function();
+ }
+
+ void trace(Visitor* visitor)
+ {
+ visitor->trace(m_stream);
+ ScriptFunction::trace(visitor);
+ }
+
+private:
+ ResolveWithReady(ScriptState* scriptState, ReadableStream* stream)
+ : ScriptFunction(scriptState)
+ , m_stream(stream) { }
+
+ ScriptValue call(ScriptValue value) override
+ {
+ return ScriptValue(scriptState(), m_stream->ready(scriptState()).v8Value());
+ }
+
+ Member<ReadableStream> m_stream;
+};
+
} // namespace
ReadableStream::ReadableStream(ExecutionContext* executionContext, UnderlyingSource* source)
@@ -54,18 +81,10 @@ ReadableStream::~ReadableStream()
String ReadableStream::stateString() const
{
- switch (m_state) {
- case Readable:
- return "readable";
- case Waiting:
+ if (m_reader)
return "waiting";
- case Closed:
- return "closed";
- case Errored:
- return "errored";
- }
- ASSERT(false);
- return String();
+
+ return stateToString(m_state);
}
bool ReadableStream::enqueuePreliminaryCheck()
@@ -108,13 +127,15 @@ void ReadableStream::close()
if (m_state == Waiting) {
m_ready->resolve(ToV8UndefinedGenerator());
m_closed->resolve(ToV8UndefinedGenerator());
+ if (m_reader)
+ m_reader->releaseLock();
m_state = Closed;
} else if (m_state == Readable) {
m_isDraining = true;
}
}
-void ReadableStream::readPreliminaryCheck(ExceptionState& exceptionState)
+void ReadableStream::readInternalPreliminaryCheck(ExceptionState& exceptionState)
{
if (m_state == Waiting) {
exceptionState.throwTypeError("read is called while state is waiting");
@@ -130,12 +151,14 @@ void ReadableStream::readPreliminaryCheck(ExceptionState& exceptionState)
}
}
-void ReadableStream::readPostAction()
+void ReadableStream::readInternalPostAction()
{
ASSERT(m_state == Readable);
if (isQueueEmpty()) {
if (m_isDraining) {
m_closed->resolve(ToV8UndefinedGenerator());
+ if (m_reader)
+ m_reader->releaseLock();
m_state = Closed;
tyoshino (SeeGerritForStatus) 2015/02/02 08:38:24 this doesn't cause any real issue, but let's updat
yhirano 2015/02/02 10:21:20 Done.
} else {
m_ready->reset();
@@ -145,13 +168,36 @@ void ReadableStream::readPostAction()
callPullIfNeeded();
}
+ScriptValue ReadableStream::read(ScriptState* scriptState, ExceptionState& exceptionState)
+{
+ if (m_reader) {
+ exceptionState.throwTypeError("this stream is locked to an ExclusiveStreamReader");
+ return ScriptValue();
+ }
+ return readInternal(scriptState, exceptionState);
+}
+
ScriptPromise ReadableStream::ready(ScriptState* scriptState)
{
+ if (m_reader) {
+ return m_reader->released(scriptState).then(ResolveWithReady::create(scriptState, this));
+ }
+
+ if (m_state == Waiting) {
+ return readyInternal(scriptState).then(ResolveWithReady::create(scriptState, this));
+ }
+ return readyInternal(scriptState);
+}
+
+ScriptPromise ReadableStream::readyInternal(ScriptState* scriptState)
+{
return m_ready->promise(scriptState->world());
}
ScriptPromise ReadableStream::cancel(ScriptState* scriptState, ScriptValue reason)
{
+ if (m_reader)
+ return ScriptPromise::reject(scriptState, V8ThrowException::createTypeError(scriptState->isolate(), "this stream is locked to an ExclusiveStreamReader"));
if (m_state == Closed)
return ScriptPromise::cast(scriptState, v8::Undefined(scriptState->isolate()));
if (m_state == Errored)
@@ -179,6 +225,8 @@ void ReadableStream::error(PassRefPtrWillBeRawPtr<DOMException> exception)
m_ready->reject(m_exception);
m_closed->reject(m_exception);
m_state = Errored;
+ if (m_reader)
+ m_reader->releaseLock();
break;
case Readable:
clearQueue();
@@ -187,6 +235,8 @@ void ReadableStream::error(PassRefPtrWillBeRawPtr<DOMException> exception)
m_ready->reject(m_exception);
m_closed->reject(m_exception);
m_state = Errored;
+ if (m_reader)
+ m_reader->releaseLock();
break;
default:
break;
@@ -199,6 +249,21 @@ void ReadableStream::didSourceStart()
callPullIfNeeded();
}
+ExclusiveStreamReader* ReadableStream::getReader(ExceptionState& exceptionState)
+{
+ if (m_reader) {
+ exceptionState.throwTypeError("already locked to an ExclusiveStreamReader");
+ return nullptr;
+ }
tyoshino (SeeGerritForStatus) 2015/02/02 08:38:24 Throw for closed and errored stream as specified i
yhirano 2015/02/02 10:21:20 Done.
+ return new ExclusiveStreamReader(this);
+}
+
+void ReadableStream::setReader(ExclusiveStreamReader* reader)
+{
+ ASSERT((reader && !m_reader) || (!reader && m_reader));
+ m_reader = reader;
+}
+
void ReadableStream::callPullIfNeeded()
{
if (m_isPulling || m_isDraining || !m_isStarted || m_state == Closed || m_state == Errored)
@@ -223,7 +288,24 @@ void ReadableStream::trace(Visitor* visitor)
visitor->trace(m_ready);
visitor->trace(m_closed);
visitor->trace(m_exception);
+ visitor->trace(m_reader);
ActiveDOMObject::trace(visitor);
}
+String ReadableStream::stateToString(State state)
+{
+ switch (state) {
+ case Readable:
+ return "readable";
+ case Waiting:
+ return "waiting";
+ case Closed:
+ return "closed";
+ case Errored:
+ return "errored";
+ }
+ ASSERT(false);
+ return String();
+}
+
} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698