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

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, 4 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
« no previous file with comments | « Source/modules/fetch/BodyStreamBuffer.h ('k') | Source/modules/fetch/BodyStreamBufferTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 class BodyStreamBuffer::LoaderHolder final : public GarbageCollectedFinalized<Lo aderHolder>, public FetchDataLoader::Client {
14 { 17 WTF_MAKE_NONCOPYABLE(LoaderHolder);
15 return BodyStreamBuffer::create(createFetchDataConsumerHandleFromWebHandle(c reateDoneDataConsumerHandle())); 18 USING_GARBAGE_COLLECTED_MIXIN(LoaderHolder);
16 }
17
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: 19 public:
35 ClientWithFinishNotification(BodyStreamBuffer* buffer, FetchDataLoader::Clie nt* client) 20 LoaderHolder(BodyStreamBuffer* buffer, FetchDataLoader* loader, FetchDataLoa der::Client* client) : m_buffer(buffer), m_loader(loader), m_client(client) {}
36 : m_buffer(buffer) 21
37 , m_client(client) 22 void start(PassOwnPtr<FetchDataConsumerHandle> handle) { m_loader->start(han dle.get(), this); }
38 { 23
39 } 24 void didFetchDataLoadedBlobHandle(PassRefPtr<BlobDataHandle> blobDataHandle) override
40 25 {
41 DEFINE_INLINE_VIRTUAL_TRACE() 26 m_buffer->endLoading(this, EndLoadingDone);
27 m_client->didFetchDataLoadedBlobHandle(blobDataHandle);
28 }
29
30 void didFetchDataLoadedArrayBuffer(PassRefPtr<DOMArrayBuffer> arrayBuffer) o verride
31 {
32 m_buffer->endLoading(this, EndLoadingDone);
33 m_client->didFetchDataLoadedArrayBuffer(arrayBuffer);
34 }
35
36 void didFetchDataLoadedString(const String& string) override
37 {
38 m_buffer->endLoading(this, EndLoadingDone);
39 m_client->didFetchDataLoadedString(string);
40 }
41
42 void didFetchDataLoadedStream() override
43 {
44 m_buffer->endLoading(this, EndLoadingDone);
45 m_client->didFetchDataLoadedStream();
46 }
47
48 void didFetchDataLoadFailed() override
49 {
50 m_buffer->endLoading(this, EndLoadingErrored);
51 m_client->didFetchDataLoadFailed();
52 }
53
54 DEFINE_INLINE_TRACE()
42 { 55 {
43 visitor->trace(m_buffer); 56 visitor->trace(m_buffer);
57 visitor->trace(m_loader);
44 visitor->trace(m_client); 58 visitor->trace(m_client);
45 FetchDataLoader::Client::trace(visitor); 59 FetchDataLoader::Client::trace(visitor);
46 } 60 }
47 61
48 private: 62 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; 63 Member<BodyStreamBuffer> m_buffer;
64 Member<FetchDataLoader> m_loader;
81 Member<FetchDataLoader::Client> m_client; 65 Member<FetchDataLoader::Client> m_client;
82 }; 66 };
83 67
84 void BodyStreamBuffer::setDrainingStreamNotificationClient(DrainingStreamNotific ationClient* client) 68 BodyStreamBuffer::BodyStreamBuffer(PassOwnPtr<FetchDataConsumerHandle> handle)
85 { 69 : m_handle(handle)
86 ASSERT(!m_fetchDataLoader); 70 , m_reader(m_handle ? m_handle->obtainReader(this) : nullptr)
87 ASSERT(!m_drainingStreamNotificationClient); 71 , m_stream(new ReadableByteStream(this, new ReadableByteStream::StrictStrate gy))
88 m_drainingStreamNotificationClient = client; 72 , m_lockLevel(0)
89 } 73 , m_hasBody(m_handle)
90 74 , m_streamNeedsMore(false)
91 void BodyStreamBuffer::startLoading(FetchDataLoader* fetchDataLoader, FetchDataL oader::Client* client) 75 {
92 { 76 if (m_hasBody) {
93 ASSERT(!m_fetchDataLoader); 77 m_stream->didSourceStart();
94 m_fetchDataLoader = fetchDataLoader; 78 } else {
95 m_fetchDataLoader->start(m_handle.get(), new ClientWithFinishNotification(th is, client)); 79 // a null body corresponds to an empty stream.
96 } 80 close();
97 81 }
98 void BodyStreamBuffer::doDrainingStreamNotification() 82 }
99 { 83
100 ASSERT(!m_fetchDataLoader); 84 PassRefPtr<BlobDataHandle> BodyStreamBuffer::drainAsBlobDataHandle(FetchDataCons umerHandle::Reader::BlobSizePolicy policy)
101 DrainingStreamNotificationClient* client = m_drainingStreamNotificationClien t; 85 {
102 m_drainingStreamNotificationClient.clear(); 86 ASSERT(!isLocked());
103 if (client) 87 if (ReadableStream::Closed == m_stream->stateInternal() || ReadableStream::E rrored == m_stream->stateInternal())
104 client->didFetchDataLoadFinishedFromDrainingStream(); 88 return nullptr;
105 } 89
106 90 RefPtr<BlobDataHandle> blobDataHandle = m_reader->drainAsBlobDataHandle(poli cy);
107 void BodyStreamBuffer::clearDrainingStreamNotification() 91 if (blobDataHandle) {
108 { 92 close();
109 ASSERT(!m_fetchDataLoader); 93 return blobDataHandle.release();
110 m_drainingStreamNotificationClient.clear(); 94 }
111 } 95 return nullptr;
112 96 }
113 void BodyStreamBuffer::didFetchDataLoadFinished() 97
114 { 98 PassOwnPtr<FetchDataConsumerHandle> BodyStreamBuffer::lock(ExecutionContext* exe cutionContext)
115 ASSERT(m_fetchDataLoader); 99 {
116 m_fetchDataLoader.clear(); 100 ASSERT(!isLocked());
117 doDrainingStreamNotification(); 101 ++m_lockLevel;
118 } 102 m_reader = nullptr;
119 103 OwnPtr<FetchDataConsumerHandle> handle = m_handle.release();
120 DrainingBodyStreamBuffer::~DrainingBodyStreamBuffer() 104 if (ReadableStream::Closed == m_stream->stateInternal() || !m_hasBody)
121 { 105 return createFetchDataConsumerHandleFromWebHandle(createDoneDataConsumer Handle());
122 if (m_buffer) 106 if (ReadableStream::Errored == m_stream->stateInternal())
123 m_buffer->doDrainingStreamNotification(); 107 return createFetchDataConsumerHandleFromWebHandle(createUnexpectedErrorD ataConsumerHandle());
124 } 108
125 109 TrackExceptionState exceptionState;
126 void DrainingBodyStreamBuffer::startLoading(FetchDataLoader* fetchDataLoader, Fe tchDataLoader::Client* client) 110 m_streamReader = m_stream->getBytesReader(executionContext, exceptionState);
127 { 111 return handle.release();
128 if (!m_buffer) 112 }
113
114 void BodyStreamBuffer::startLoading(ExecutionContext* executionContext, FetchDat aLoader* loader, FetchDataLoader::Client* client)
115 {
116 OwnPtr<FetchDataConsumerHandle> handle = lock(executionContext);
117 auto holder = new LoaderHolder(this, loader, client);
118 m_loaders.add(holder);
119 holder->start(handle.release());
120 }
121
122 void BodyStreamBuffer::pullSource()
123 {
124 ASSERT(!m_streamNeedsMore);
125 m_streamNeedsMore = true;
126 processData();
127 }
128
129 ScriptPromise BodyStreamBuffer::cancelSource(ScriptState* scriptState, ScriptVal ue)
130 {
131 close();
132 return ScriptPromise::cast(scriptState, v8::Undefined(scriptState->isolate() ));
133 }
134
135 void BodyStreamBuffer::didGetReadable()
136 {
137 if (!m_reader)
129 return; 138 return;
130 139
131 m_buffer->startLoading(fetchDataLoader, client); 140 if (!m_streamNeedsMore) {
132 m_buffer.clear(); 141 // Perform zero-length read to call close()/error() early.
133 } 142 size_t readSize;
134 143 WebDataConsumerHandle::Result result = m_reader->read(nullptr, 0, WebDat aConsumerHandle::FlagNone, &readSize);
135 BodyStreamBuffer* DrainingBodyStreamBuffer::leakBuffer() 144 switch (result) {
136 { 145 case WebDataConsumerHandle::Ok:
137 if (!m_buffer) 146 case WebDataConsumerHandle::ShouldWait:
138 return nullptr; 147 return;
139 148 case WebDataConsumerHandle::Done:
140 m_buffer->clearDrainingStreamNotification(); 149 close();
141 BodyStreamBuffer* buffer = m_buffer; 150 return;
142 m_buffer.clear(); 151 case WebDataConsumerHandle::Busy:
143 return buffer; 152 case WebDataConsumerHandle::ResourceExhausted:
144 } 153 case WebDataConsumerHandle::UnexpectedError:
145 154 error();
146 PassRefPtr<BlobDataHandle> DrainingBodyStreamBuffer::drainAsBlobDataHandle(Fetch DataConsumerHandle::Reader::BlobSizePolicy blobSizePolicy) 155 return;
147 { 156 }
148 if (!m_buffer) 157 return;
149 return nullptr; 158 }
150 159 processData();
151 RefPtr<BlobDataHandle> blobDataHandle = m_buffer->m_handle->obtainReader(nul lptr)->drainAsBlobDataHandle(blobSizePolicy); 160 }
152 if (!blobDataHandle) 161
153 return nullptr; 162 void BodyStreamBuffer::close()
154 m_buffer->doDrainingStreamNotification(); 163 {
155 m_buffer.clear(); 164 m_reader = nullptr;
156 return blobDataHandle.release(); 165 m_stream->close();
157 } 166 }
158 167
159 DrainingBodyStreamBuffer::DrainingBodyStreamBuffer(BodyStreamBuffer* buffer, Bod yStreamBuffer::DrainingStreamNotificationClient* client) 168 void BodyStreamBuffer::error()
160 : m_buffer(buffer) 169 {
161 { 170 m_reader = nullptr;
162 ASSERT(client); 171 m_stream->error(DOMException::create(NetworkError, "network error"));
163 m_buffer->setDrainingStreamNotificationClient(client); 172 }
173
174 void BodyStreamBuffer::processData()
175 {
176 ASSERT(m_reader);
177 while (m_streamNeedsMore) {
178 const void* buffer;
179 size_t available;
180 WebDataConsumerHandle::Result result = m_reader->beginRead(&buffer, WebD ataConsumerHandle::FlagNone, &available);
181 switch (result) {
182 case WebDataConsumerHandle::Ok:
183 m_streamNeedsMore = m_stream->enqueue(DOMUint8Array::create(static_c ast<const unsigned char*>(buffer), available));
184 m_reader->endRead(available);
185 break;
186
187 case WebDataConsumerHandle::Done:
188 close();
189 return;
190
191 case WebDataConsumerHandle::ShouldWait:
192 return;
193
194 case WebDataConsumerHandle::Busy:
195 case WebDataConsumerHandle::ResourceExhausted:
196 case WebDataConsumerHandle::UnexpectedError:
197 error();
198 return;
199 }
200 }
201 }
202
203 void BodyStreamBuffer::unlock()
204 {
205 ASSERT(m_lockLevel > 0);
206 if (m_streamReader) {
207 m_streamReader->releaseLock();
208 m_streamReader = nullptr;
209 }
210 --m_lockLevel;
211 }
212
213 void BodyStreamBuffer::endLoading(FetchDataLoader::Client* client, EndLoadingMod e mode)
214 {
215 ASSERT(m_loaders.contains(client));
216 m_loaders.remove(client);
217 unlock();
218 if (mode == EndLoadingDone) {
219 close();
220 } else {
221 ASSERT(mode == EndLoadingErrored);
222 error();
223 }
164 } 224 }
165 225
166 } // namespace blink 226 } // namespace blink
OLDNEW
« no previous file with comments | « Source/modules/fetch/BodyStreamBuffer.h ('k') | Source/modules/fetch/BodyStreamBufferTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698