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

Side by Side Diff: third_party/WebKit/Source/modules/fetch/FetchDataLoader.cpp

Issue 2703343002: ServiceWorker: Use mojo's data pipe for respondWith(stream) (Closed)
Patch Set: Addressed comments from kinuko and haraken Created 3 years, 8 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
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "modules/fetch/FetchDataLoader.h" 5 #include "modules/fetch/FetchDataLoader.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include "core/html/parser/TextResourceDecoder.h" 8 #include "core/html/parser/TextResourceDecoder.h"
9 #include "modules/fetch/BytesConsumer.h" 9 #include "modules/fetch/BytesConsumer.h"
10 #include "mojo/public/cpp/system/simple_watcher.h"
11 #include "platform/wtf/Functional.h"
10 #include "platform/wtf/PtrUtil.h" 12 #include "platform/wtf/PtrUtil.h"
11 #include "platform/wtf/text/StringBuilder.h" 13 #include "platform/wtf/text/StringBuilder.h"
12 #include "platform/wtf/text/WTFString.h" 14 #include "platform/wtf/text/WTFString.h"
13 #include "platform/wtf/typed_arrays/ArrayBufferBuilder.h" 15 #include "platform/wtf/typed_arrays/ArrayBufferBuilder.h"
14 16
15 namespace blink { 17 namespace blink {
16 18
17 namespace { 19 namespace {
18 20
19 class FetchDataLoaderAsBlobHandle final : public FetchDataLoader, 21 class FetchDataLoaderAsBlobHandle final : public FetchDataLoader,
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 } 226 }
225 227
226 private: 228 private:
227 Member<BytesConsumer> consumer_; 229 Member<BytesConsumer> consumer_;
228 Member<FetchDataLoader::Client> client_; 230 Member<FetchDataLoader::Client> client_;
229 231
230 std::unique_ptr<TextResourceDecoder> decoder_; 232 std::unique_ptr<TextResourceDecoder> decoder_;
231 StringBuilder builder_; 233 StringBuilder builder_;
232 }; 234 };
233 235
234 class FetchDataLoaderAsStream final : public FetchDataLoader, 236 class FetchDataLoaderAsDataPipe final : public FetchDataLoader,
235 public BytesConsumer::Client { 237 public BytesConsumer::Client {
236 USING_GARBAGE_COLLECTED_MIXIN(FetchDataLoaderAsStream); 238 USING_GARBAGE_COLLECTED_MIXIN(FetchDataLoaderAsDataPipe);
237 239
238 public: 240 public:
239 explicit FetchDataLoaderAsStream(Stream* out_stream) 241 explicit FetchDataLoaderAsDataPipe(
240 : out_stream_(out_stream) {} 242 mojo::ScopedDataPipeProducerHandle out_data_pipe)
243 : out_data_pipe_(std::move(out_data_pipe)),
244 data_pipe_watcher_(FROM_HERE,
245 mojo::SimpleWatcher::ArmingPolicy::MANUAL) {}
246 ~FetchDataLoaderAsDataPipe() override {}
241 247
242 void Start(BytesConsumer* consumer, 248 void Start(BytesConsumer* consumer,
243 FetchDataLoader::Client* client) override { 249 FetchDataLoader::Client* client) override {
244 DCHECK(!client_); 250 DCHECK(!client_);
245 DCHECK(!consumer_); 251 DCHECK(!consumer_);
252 data_pipe_watcher_.Watch(
253 out_data_pipe_.get(), MOJO_HANDLE_SIGNAL_WRITABLE,
254 ConvertToBaseCallback(WTF::Bind(&FetchDataLoaderAsDataPipe::OnWritable,
255 WrapWeakPersistent(this))));
256 data_pipe_watcher_.ArmOrNotify();
246 client_ = client; 257 client_ = client;
247 consumer_ = consumer; 258 consumer_ = consumer;
248 consumer_->SetClient(this); 259 consumer_->SetClient(this);
249 OnStateChange();
250 } 260 }
251 261
262 void OnWritable(MojoResult) { OnStateChange(); }
263
264 // Implements BytesConsumer::Client.
252 void OnStateChange() override { 265 void OnStateChange() override {
253 bool need_to_flush = false; 266 bool should_wait = false;
254 while (true) { 267 while (!should_wait) {
255 const char* buffer; 268 const char* buffer;
256 size_t available; 269 size_t available;
257 auto result = consumer_->BeginRead(&buffer, &available); 270 auto result = consumer_->BeginRead(&buffer, &available);
258 if (result == BytesConsumer::Result::kShouldWait) { 271 if (result == BytesConsumer::Result::kShouldWait)
259 if (need_to_flush)
260 out_stream_->Flush();
261 return; 272 return;
262 }
263 if (result == BytesConsumer::Result::kOk) { 273 if (result == BytesConsumer::Result::kOk) {
264 out_stream_->AddData(buffer, available); 274 DCHECK_GT(available, 0UL);
265 need_to_flush = true; 275 uint32_t num_bytes = available;
266 result = consumer_->EndRead(available); 276 MojoResult mojo_result =
277 mojo::WriteDataRaw(out_data_pipe_.get(), buffer, &num_bytes,
278 MOJO_WRITE_DATA_FLAG_NONE);
279 if (mojo_result == MOJO_RESULT_OK) {
280 result = consumer_->EndRead(num_bytes);
281 } else if (mojo_result == MOJO_RESULT_SHOULD_WAIT) {
282 result = consumer_->EndRead(0);
283 should_wait = true;
284 data_pipe_watcher_.ArmOrNotify();
285 } else {
286 result = consumer_->EndRead(0);
287 StopInternal();
288 client_->DidFetchDataLoadFailed();
289 return;
290 }
267 } 291 }
268 switch (result) { 292 switch (result) {
269 case BytesConsumer::Result::kOk: 293 case BytesConsumer::Result::kOk:
270 break; 294 break;
271 case BytesConsumer::Result::kShouldWait: 295 case BytesConsumer::Result::kShouldWait:
272 NOTREACHED(); 296 NOTREACHED();
273 return; 297 return;
274 case BytesConsumer::Result::kDone: 298 case BytesConsumer::Result::kDone:
275 if (need_to_flush) 299 StopInternal();
276 out_stream_->Flush(); 300 client_->DidFetchDataLoadedDataPipe();
277 out_stream_->Finalize();
278 client_->DidFetchDataLoadedStream();
279 return; 301 return;
280 case BytesConsumer::Result::kError: 302 case BytesConsumer::Result::kError:
281 // If the stream is aborted soon after the stream is registered 303 StopInternal();
282 // to the StreamRegistry, ServiceWorkerURLRequestJob may not
283 // notice the error and continue waiting forever.
284 // TODO(yhirano): Add new message to report the error to the
285 // browser process.
286 out_stream_->Abort();
287 client_->DidFetchDataLoadFailed(); 304 client_->DidFetchDataLoadFailed();
288 return; 305 return;
289 } 306 }
290 } 307 }
291 } 308 }
292 309
293 void Cancel() override { consumer_->Cancel(); } 310 void Cancel() override { StopInternal(); }
294 311
295 DEFINE_INLINE_TRACE() { 312 DEFINE_INLINE_TRACE() {
296 visitor->Trace(consumer_); 313 visitor->Trace(consumer_);
297 visitor->Trace(client_); 314 visitor->Trace(client_);
298 visitor->Trace(out_stream_);
299 FetchDataLoader::Trace(visitor); 315 FetchDataLoader::Trace(visitor);
300 BytesConsumer::Client::Trace(visitor); 316 BytesConsumer::Client::Trace(visitor);
301 } 317 }
302 318
319 private:
320 void StopInternal() {
321 consumer_->Cancel();
322 data_pipe_watcher_.Cancel();
323 out_data_pipe_.reset();
324 }
325
303 Member<BytesConsumer> consumer_; 326 Member<BytesConsumer> consumer_;
304 Member<FetchDataLoader::Client> client_; 327 Member<FetchDataLoader::Client> client_;
305 Member<Stream> out_stream_; 328
329 mojo::ScopedDataPipeProducerHandle out_data_pipe_;
330 mojo::SimpleWatcher data_pipe_watcher_;
306 }; 331 };
307 332
308 } // namespace 333 } // namespace
309 334
310 FetchDataLoader* FetchDataLoader::CreateLoaderAsBlobHandle( 335 FetchDataLoader* FetchDataLoader::CreateLoaderAsBlobHandle(
311 const String& mime_type) { 336 const String& mime_type) {
312 return new FetchDataLoaderAsBlobHandle(mime_type); 337 return new FetchDataLoaderAsBlobHandle(mime_type);
313 } 338 }
314 339
315 FetchDataLoader* FetchDataLoader::CreateLoaderAsArrayBuffer() { 340 FetchDataLoader* FetchDataLoader::CreateLoaderAsArrayBuffer() {
316 return new FetchDataLoaderAsArrayBuffer(); 341 return new FetchDataLoaderAsArrayBuffer();
317 } 342 }
318 343
319 FetchDataLoader* FetchDataLoader::CreateLoaderAsString() { 344 FetchDataLoader* FetchDataLoader::CreateLoaderAsString() {
320 return new FetchDataLoaderAsString(); 345 return new FetchDataLoaderAsString();
321 } 346 }
322 347
323 FetchDataLoader* FetchDataLoader::CreateLoaderAsStream(Stream* out_stream) { 348 FetchDataLoader* FetchDataLoader::CreateLoaderAsDataPipe(
324 return new FetchDataLoaderAsStream(out_stream); 349 mojo::ScopedDataPipeProducerHandle out_data_pipe) {
350 return new FetchDataLoaderAsDataPipe(std::move(out_data_pipe));
325 } 351 }
326 352
327 } // namespace blink 353 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/modules/fetch/FetchDataLoader.h ('k') | third_party/WebKit/Source/modules/serviceworkers/DEPS » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698