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

Side by Side Diff: Source/modules/fetch/BodyStreamBuffer.cpp

Issue 1233573002: [Fetch API] Remove DrainingBuffer. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 5 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "config.h" 5 #include "config.h"
6 #include "modules/fetch/BodyStreamBuffer.h" 6 #include "modules/fetch/BodyStreamBuffer.h"
7 7
8 #include "core/dom/DOMArrayBuffer.h" 8 #include "core/dom/DOMArrayBuffer.h"
9 #include "core/dom/DOMTypedArray.h"
9 #include "core/dom/ExceptionCode.h" 10 #include "core/dom/ExceptionCode.h"
11 #include "modules/fetch/DataConsumerHandleUtil.h"
12 #include "platform/blob/BlobData.h"
10 13
11 namespace blink { 14 namespace blink {
12 15
13 BodyStreamBuffer* BodyStreamBuffer::createEmpty() 16 namespace {
14 { 17
15 return BodyStreamBuffer::create(createFetchDataConsumerHandleFromWebHandle(c reateDoneDataConsumerHandle())); 18 class LoaderHolder final : public GarbageCollectedFinalized<LoaderHolder>, publi c FetchDataLoader::Client {
16 } 19 WTF_MAKE_NONCOPYABLE(LoaderHolder);
17 20 USING_GARBAGE_COLLECTED_MIXIN(LoaderHolder);
18 FetchDataConsumerHandle* BodyStreamBuffer::handle() const
19 {
20 ASSERT(!m_fetchDataLoader);
21 ASSERT(!m_drainingStreamNotificationClient);
22 return m_handle.get();
23 }
24
25 PassOwnPtr<FetchDataConsumerHandle> BodyStreamBuffer::releaseHandle()
26 {
27 ASSERT(!m_fetchDataLoader);
28 ASSERT(!m_drainingStreamNotificationClient);
29 return m_handle.release();
30 }
31
32 class ClientWithFinishNotification final : public GarbageCollectedFinalized<Clie ntWithFinishNotification>, public FetchDataLoader::Client {
33 USING_GARBAGE_COLLECTED_MIXIN(ClientWithFinishNotification);
34 public: 21 public:
35 ClientWithFinishNotification(BodyStreamBuffer* buffer, FetchDataLoader::Clie nt* client) 22 LoaderHolder(BodyStreamBuffer* buffer, FetchDataLoader* loader, FetchDataLoa der::Client* client) : m_buffer(buffer), m_loader(loader), m_client(client) {}
36 : m_buffer(buffer) 23
37 , m_client(client) 24 void start(PassOwnPtr<FetchDataConsumerHandle> handle) { m_loader->start(han dle.get(), this); }
38 { 25
39 } 26 void didFetchDataLoadedBlobHandle(PassRefPtr<BlobDataHandle> blobDataHandle) override
40 27 {
41 DEFINE_INLINE_VIRTUAL_TRACE() 28 m_buffer->endLoading(this, createFetchDataConsumerHandleFromWebHandle(cr eateDoneDataConsumerHandle()));
29 m_client->didFetchDataLoadedBlobHandle(blobDataHandle);
30 }
31
32 void didFetchDataLoadedArrayBuffer(PassRefPtr<DOMArrayBuffer> arrayBuffer) o verride
33 {
34 m_buffer->endLoading(this, createFetchDataConsumerHandleFromWebHandle(cr eateDoneDataConsumerHandle()));
35 m_client->didFetchDataLoadedArrayBuffer(arrayBuffer);
36 }
37
38 void didFetchDataLoadedString(const String& string) override
39 {
40 m_buffer->endLoading(this, createFetchDataConsumerHandleFromWebHandle(cr eateDoneDataConsumerHandle()));
41 m_client->didFetchDataLoadedString(string);
42 }
43
44 void didFetchDataLoadedStream() override
45 {
46 m_buffer->endLoading(this, createFetchDataConsumerHandleFromWebHandle(cr eateDoneDataConsumerHandle()));
47 m_client->didFetchDataLoadedStream();
48 }
49
50 void didFetchDataLoadFailed() override
51 {
52 m_buffer->endLoading(this, createFetchDataConsumerHandleFromWebHandle(cr eateUnexpectedErrorDataConsumerHandle()));
53 m_client->didFetchDataLoadFailed();
54 }
55
56 DEFINE_INLINE_TRACE()
42 { 57 {
43 visitor->trace(m_buffer); 58 visitor->trace(m_buffer);
59 visitor->trace(m_loader);
44 visitor->trace(m_client); 60 visitor->trace(m_client);
45 FetchDataLoader::Client::trace(visitor); 61 FetchDataLoader::Client::trace(visitor);
46 } 62 }
47 63
48 private: 64 private:
49 void didFetchDataLoadedBlobHandle(PassRefPtr<BlobDataHandle> blobDataHandle) override
50 {
51 if (m_client)
52 m_client->didFetchDataLoadedBlobHandle(blobDataHandle);
53 m_buffer->didFetchDataLoadFinished();
54 }
55 void didFetchDataLoadedArrayBuffer(PassRefPtr<DOMArrayBuffer> arrayBuffer) o verride
56 {
57 if (m_client)
58 m_client->didFetchDataLoadedArrayBuffer(arrayBuffer);
59 m_buffer->didFetchDataLoadFinished();
60 }
61 void didFetchDataLoadedString(const String& str) override
62 {
63 if (m_client)
64 m_client->didFetchDataLoadedString(str);
65 m_buffer->didFetchDataLoadFinished();
66 }
67 void didFetchDataLoadedStream() override
68 {
69 if (m_client)
70 m_client->didFetchDataLoadedStream();
71 m_buffer->didFetchDataLoadFinished();
72 }
73 void didFetchDataLoadFailed() override
74 {
75 if (m_client)
76 m_client->didFetchDataLoadFailed();
77 m_buffer->didFetchDataLoadFinished();
78 }
79
80 Member<BodyStreamBuffer> m_buffer; 65 Member<BodyStreamBuffer> m_buffer;
66 Member<FetchDataLoader> m_loader;
81 Member<FetchDataLoader::Client> m_client; 67 Member<FetchDataLoader::Client> m_client;
82 }; 68 };
83 69
84 void BodyStreamBuffer::setDrainingStreamNotificationClient(DrainingStreamNotific ationClient* client) 70 } // namespace
85 { 71
86 ASSERT(!m_fetchDataLoader); 72 BodyStreamBuffer::BodyStreamBuffer(PassOwnPtr<FetchDataConsumerHandle> handle)
87 ASSERT(!m_drainingStreamNotificationClient); 73 : m_handle(handle)
88 m_drainingStreamNotificationClient = client; 74 , m_reader(m_handle ? m_handle->obtainReader(this) : nullptr)
89 } 75 , m_stream(new ReadableByteStream(this, new ReadableByteStream::StrictStrate gy))
90 76 , m_lockLevel(0)
91 void BodyStreamBuffer::startLoading(FetchDataLoader* fetchDataLoader, FetchDataL oader::Client* client) 77 , m_hasBody(m_handle)
92 { 78 , m_streamNeedsMore(false)
93 ASSERT(!m_fetchDataLoader); 79 {
94 m_fetchDataLoader = fetchDataLoader; 80 if (m_hasBody) {
95 m_fetchDataLoader->start(m_handle.get(), new ClientWithFinishNotification(th is, client)); 81 m_stream->didSourceStart();
96 } 82 } else {
97 83 // a null body corresponds to an empty stream.
98 void BodyStreamBuffer::doDrainingStreamNotification() 84 close();
99 { 85 }
100 ASSERT(!m_fetchDataLoader); 86 }
101 DrainingStreamNotificationClient* client = m_drainingStreamNotificationClien t; 87
102 m_drainingStreamNotificationClient.clear(); 88 PassOwnPtr<FetchDataConsumerHandle> BodyStreamBuffer::lock(ExecutionContext* exe cutionContext)
103 if (client) 89 {
104 client->didFetchDataLoadFinishedFromDrainingStream(); 90 ASSERT(!isLocked());
105 } 91 ++m_lockLevel;
106 92 m_reader = nullptr;
107 void BodyStreamBuffer::clearDrainingStreamNotification() 93 OwnPtr<FetchDataConsumerHandle> handle = m_handle.release();
108 { 94 if (ReadableStream::Closed == m_stream->stateInternal() || !m_hasBody)
109 ASSERT(!m_fetchDataLoader); 95 return createFetchDataConsumerHandleFromWebHandle(createDoneDataConsumer Handle());
110 m_drainingStreamNotificationClient.clear(); 96 if (ReadableStream::Errored == m_stream->stateInternal())
111 } 97 return createFetchDataConsumerHandleFromWebHandle(createUnexpectedErrorD ataConsumerHandle());
112 98
113 void BodyStreamBuffer::didFetchDataLoadFinished() 99 TrackExceptionState exceptionState;
114 { 100 m_streamReader = m_stream->getBytesReader(executionContext, exceptionState);
115 ASSERT(m_fetchDataLoader); 101 return handle.release();
116 m_fetchDataLoader.clear(); 102 }
117 doDrainingStreamNotification(); 103
118 } 104 void BodyStreamBuffer::unlock(PassOwnPtr<FetchDataConsumerHandle> handle)
119 105 {
120 DrainingBodyStreamBuffer::~DrainingBodyStreamBuffer() 106 ASSERT(m_lockLevel > 0);
121 { 107 if (m_streamReader) {
122 if (m_buffer) 108 m_streamReader->releaseLock();
123 m_buffer->doDrainingStreamNotification(); 109 m_streamReader = nullptr;
124 } 110 }
125 111 --m_lockLevel;
126 void DrainingBodyStreamBuffer::startLoading(FetchDataLoader* fetchDataLoader, Fe tchDataLoader::Client* client) 112 if (!m_hasBody)
127 { 113 return;
128 if (!m_buffer) 114 ASSERT(handle);
129 return; 115 if (ReadableStream::Closed == m_stream->stateInternal() || ReadableStream::E rrored == m_stream->stateInternal()) {
130 116 m_handle = handle;
131 m_buffer->startLoading(fetchDataLoader, client); 117 return;
132 m_buffer.clear(); 118 }
133 } 119 ASSERT(!m_handle);
134 120 m_handle = handle;
135 BodyStreamBuffer* DrainingBodyStreamBuffer::leakBuffer() 121 m_reader = m_handle->obtainReader(this);
136 { 122 // We need to update the stream state synchronously.
137 if (!m_buffer) 123 didGetReadable();
138 return nullptr; 124 }
139 125
140 m_buffer->clearDrainingStreamNotification(); 126 void BodyStreamBuffer::startLoading(ExecutionContext* executionContext, FetchDat aLoader* loader, FetchDataLoader::Client* client)
141 BodyStreamBuffer* buffer = m_buffer; 127 {
142 m_buffer.clear(); 128 OwnPtr<FetchDataConsumerHandle> handle = lock(executionContext);
143 return buffer; 129 auto holder = new LoaderHolder(this, loader, client);
144 } 130 m_loaders.add(holder);
145 131 holder->start(handle.release());
146 PassRefPtr<BlobDataHandle> DrainingBodyStreamBuffer::drainAsBlobDataHandle(Fetch DataConsumerHandle::Reader::BlobSizePolicy blobSizePolicy) 132 }
147 { 133
148 if (!m_buffer) 134 void BodyStreamBuffer::pullSource()
149 return nullptr; 135 {
150 136 ASSERT(!m_streamNeedsMore);
151 RefPtr<BlobDataHandle> blobDataHandle = m_buffer->m_handle->obtainReader(nul lptr)->drainAsBlobDataHandle(blobSizePolicy); 137 m_streamNeedsMore = true;
152 if (!blobDataHandle) 138 processData();
153 return nullptr; 139 }
154 m_buffer->doDrainingStreamNotification(); 140
155 m_buffer.clear(); 141 ScriptPromise BodyStreamBuffer::cancelSource(ScriptState* scriptState, ScriptVal ue)
156 return blobDataHandle.release(); 142 {
157 } 143 close();
158 144 return ScriptPromise::cast(scriptState, v8::Undefined(scriptState->isolate() ));
159 DrainingBodyStreamBuffer::DrainingBodyStreamBuffer(BodyStreamBuffer* buffer, Bod yStreamBuffer::DrainingStreamNotificationClient* client) 145 }
160 : m_buffer(buffer) 146
161 { 147 void BodyStreamBuffer::didGetReadable()
162 ASSERT(client); 148 {
163 m_buffer->setDrainingStreamNotificationClient(client); 149 if (!m_reader)
150 return;
151
152 if (!m_streamNeedsMore) {
153 // Perform zero-length read to call close()/error() early.
154 size_t readSize;
155 WebDataConsumerHandle::Result result = m_reader->read(nullptr, 0, WebDat aConsumerHandle::FlagNone, &readSize);
156 switch (result) {
157 case WebDataConsumerHandle::Ok:
158 case WebDataConsumerHandle::ShouldWait:
159 return;
160 case WebDataConsumerHandle::Done:
161 close();
162 return;
163 case WebDataConsumerHandle::Busy:
164 case WebDataConsumerHandle::ResourceExhausted:
165 case WebDataConsumerHandle::UnexpectedError:
166 error();
167 return;
168 }
169 return;
170 }
171 processData();
172 }
173
174 void BodyStreamBuffer::endLoading(FetchDataLoader::Client* client, PassOwnPtr<Fe tchDataConsumerHandle> handle)
175 {
176 ASSERT(m_loaders.contains(client));
177 m_loaders.remove(client);
178 unlock(handle);
179 }
180
181 void BodyStreamBuffer::processData()
182 {
183 ASSERT(m_reader);
184 while (m_streamNeedsMore) {
185 const void* buffer;
186 size_t available;
187 WebDataConsumerHandle::Result result = m_reader->beginRead(&buffer, WebD ataConsumerHandle::FlagNone, &available);
188 switch (result) {
189 case WebDataConsumerHandle::Ok:
190 m_streamNeedsMore = m_stream->enqueue(DOMUint8Array::create(static_c ast<const unsigned char*>(buffer), available));
191 m_reader->endRead(available);
192 break;
193
194 case WebDataConsumerHandle::Done:
195 close();
196 return;
197
198 case WebDataConsumerHandle::ShouldWait:
199 return;
200
201 case WebDataConsumerHandle::Busy:
202 case WebDataConsumerHandle::ResourceExhausted:
203 case WebDataConsumerHandle::UnexpectedError:
204 error();
205 return;
206 }
207 }
208 }
209
210 void BodyStreamBuffer::close()
211 {
212 m_reader = nullptr;
213 m_stream->close();
214 }
215
216 void BodyStreamBuffer::error()
217 {
218 m_reader = nullptr;
219 m_stream->error(DOMException::create(NetworkError, "network error"));
164 } 220 }
165 221
166 } // namespace blink 222 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698