OLD | NEW |
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 "core/html/parser/TextResourceDecoder.h" | 8 #include "core/html/parser/TextResourceDecoder.h" |
8 #include "modules/fetch/BytesConsumer.h" | 9 #include "modules/fetch/BytesConsumer.h" |
| 10 #include "mojo/public/cpp/system/simple_watcher.h" |
| 11 #include "platform/instrumentation/tracing/TraceEvent.h" |
9 #include "wtf/PtrUtil.h" | 12 #include "wtf/PtrUtil.h" |
10 #include "wtf/text/StringBuilder.h" | 13 #include "wtf/text/StringBuilder.h" |
11 #include "wtf/text/WTFString.h" | 14 #include "wtf/text/WTFString.h" |
12 #include "wtf/typed_arrays/ArrayBufferBuilder.h" | 15 #include "wtf/typed_arrays/ArrayBufferBuilder.h" |
13 #include <memory> | |
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, |
20 public BytesConsumer::Client { | 22 public BytesConsumer::Client { |
21 USING_GARBAGE_COLLECTED_MIXIN(FetchDataLoaderAsBlobHandle); | 23 USING_GARBAGE_COLLECTED_MIXIN(FetchDataLoaderAsBlobHandle); |
22 | 24 |
23 public: | 25 public: |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 visitor->trace(m_outStream); | 300 visitor->trace(m_outStream); |
299 FetchDataLoader::trace(visitor); | 301 FetchDataLoader::trace(visitor); |
300 BytesConsumer::Client::trace(visitor); | 302 BytesConsumer::Client::trace(visitor); |
301 } | 303 } |
302 | 304 |
303 Member<BytesConsumer> m_consumer; | 305 Member<BytesConsumer> m_consumer; |
304 Member<FetchDataLoader::Client> m_client; | 306 Member<FetchDataLoader::Client> m_client; |
305 Member<Stream> m_outStream; | 307 Member<Stream> m_outStream; |
306 }; | 308 }; |
307 | 309 |
| 310 class FetchDataLoaderAsDataPipe final : public FetchDataLoader, |
| 311 public BytesConsumer::Client { |
| 312 USING_GARBAGE_COLLECTED_MIXIN(FetchDataLoaderAsDataPipe); |
| 313 |
| 314 public: |
| 315 explicit FetchDataLoaderAsDataPipe(mojo::ScopedDataPipeProducerHandle handle) |
| 316 : m_handle(std::move(handle)), |
| 317 m_handleWatcher(FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL) { |
| 318 TRACE_EVENT0("ServiceWorker", |
| 319 "FetchDataLoaderAsDataPipe::FetchDataLoaderAsDataPipe"); |
| 320 } |
| 321 ~FetchDataLoaderAsDataPipe() override {} |
| 322 void start(BytesConsumer* consumer, |
| 323 FetchDataLoader::Client* client) override { |
| 324 TRACE_EVENT0("ServiceWorker", "FetchDataLoaderAsDataPipe::start"); |
| 325 DCHECK(!m_client); |
| 326 DCHECK(!m_consumer); |
| 327 m_handleWatcher.Watch(m_handle.get(), MOJO_HANDLE_SIGNAL_WRITABLE, |
| 328 base::Bind(&FetchDataLoaderAsDataPipe::OnWritable, |
| 329 base::Unretained(this))); |
| 330 m_handleWatcher.ArmOrNotify(); |
| 331 m_client = client; |
| 332 m_consumer = consumer; |
| 333 m_consumer->setClient(this); |
| 334 onStateChange(); |
| 335 } |
| 336 |
| 337 void OnWritable(MojoResult result) { |
| 338 // LOG(ERROR) << "OnWritable"; |
| 339 onStateChange(); |
| 340 } |
| 341 void onStateChange() override { |
| 342 TRACE_EVENT0("ServiceWorker", "FetchDataLoaderAsDataPipe::onStateChange"); |
| 343 // LOG(ERROR) << "onStateChange"; |
| 344 bool should_wait = false; |
| 345 while (!should_wait) { |
| 346 const char* buffer; |
| 347 size_t available; |
| 348 auto result = m_consumer->beginRead(&buffer, &available); |
| 349 if (result == BytesConsumer::Result::ShouldWait) |
| 350 return; |
| 351 if (result == BytesConsumer::Result::Ok) { |
| 352 // LOG(ERROR) << "available " << available; |
| 353 if (available > 0) { |
| 354 uint32_t num_bytes = available; |
| 355 MojoResult mojo_result = WriteDataRaw( |
| 356 m_handle.get(), buffer, &num_bytes, MOJO_WRITE_DATA_FLAG_NONE); |
| 357 // LOG(ERROR) << "mojo_result " << mojo_result; |
| 358 // LOG(ERROR) << "num_bytes " << num_bytes; |
| 359 // LOG(ERROR) << " data: [" << std::string(buffer, num_bytes) << "]"; |
| 360 if (mojo_result == MOJO_RESULT_OK) { |
| 361 // LOG(ERROR) << " MOJO_RESULT_OK"; |
| 362 TRACE_EVENT1("ServiceWorker", |
| 363 "FetchDataLoaderAsDataPipe::onStateChange endRead", |
| 364 "bytes", num_bytes); |
| 365 result = m_consumer->endRead(num_bytes); |
| 366 } else { |
| 367 result = m_consumer->endRead(0); |
| 368 if (mojo_result == MOJO_RESULT_SHOULD_WAIT) { |
| 369 // LOG(ERROR) << " MOJO_RESULT_SHOULD_WAIT"; |
| 370 should_wait = true; |
| 371 m_handleWatcher.ArmOrNotify(); |
| 372 } else { |
| 373 // LOG(ERROR) << " mojo_result != MOJO_RESULT_OK"; |
| 374 m_consumer->cancel(); |
| 375 m_handle.reset(); |
| 376 m_handleWatcher.Cancel(); |
| 377 m_client->didFetchDataLoadFailed(); |
| 378 return; |
| 379 } |
| 380 } |
| 381 } else { |
| 382 result = m_consumer->endRead(available); |
| 383 } |
| 384 } |
| 385 switch (result) { |
| 386 case BytesConsumer::Result::Ok: |
| 387 break; |
| 388 case BytesConsumer::Result::ShouldWait: |
| 389 NOTREACHED(); |
| 390 return; |
| 391 case BytesConsumer::Result::Done: |
| 392 // LOG(ERROR) << "BytesConsumer::Result::Done"; |
| 393 m_handle.reset(); |
| 394 m_handleWatcher.Cancel(); |
| 395 m_client->didFetchDataLoadedStream(); |
| 396 return; |
| 397 case BytesConsumer::Result::Error: |
| 398 LOG(ERROR) << "BytesConsumer::Result::Error"; |
| 399 m_client->didFetchDataLoadFailed(); |
| 400 return; |
| 401 } |
| 402 } |
| 403 } |
| 404 |
| 405 void cancel() override { m_consumer->cancel(); } |
| 406 |
| 407 DEFINE_INLINE_TRACE() { |
| 408 visitor->trace(m_consumer); |
| 409 visitor->trace(m_client); |
| 410 FetchDataLoader::trace(visitor); |
| 411 BytesConsumer::Client::trace(visitor); |
| 412 } |
| 413 |
| 414 Member<BytesConsumer> m_consumer; |
| 415 Member<FetchDataLoader::Client> m_client; |
| 416 |
| 417 mojo::ScopedDataPipeProducerHandle m_handle; |
| 418 mojo::SimpleWatcher m_handleWatcher; |
| 419 }; |
| 420 |
308 } // namespace | 421 } // namespace |
309 | 422 |
310 FetchDataLoader* FetchDataLoader::createLoaderAsBlobHandle( | 423 FetchDataLoader* FetchDataLoader::createLoaderAsBlobHandle( |
311 const String& mimeType) { | 424 const String& mimeType) { |
312 return new FetchDataLoaderAsBlobHandle(mimeType); | 425 return new FetchDataLoaderAsBlobHandle(mimeType); |
313 } | 426 } |
314 | 427 |
315 FetchDataLoader* FetchDataLoader::createLoaderAsArrayBuffer() { | 428 FetchDataLoader* FetchDataLoader::createLoaderAsArrayBuffer() { |
316 return new FetchDataLoaderAsArrayBuffer(); | 429 return new FetchDataLoaderAsArrayBuffer(); |
317 } | 430 } |
318 | 431 |
319 FetchDataLoader* FetchDataLoader::createLoaderAsString() { | 432 FetchDataLoader* FetchDataLoader::createLoaderAsString() { |
320 return new FetchDataLoaderAsString(); | 433 return new FetchDataLoaderAsString(); |
321 } | 434 } |
322 | 435 |
323 FetchDataLoader* FetchDataLoader::createLoaderAsStream(Stream* outStream) { | 436 FetchDataLoader* FetchDataLoader::createLoaderAsStream(Stream* outStream) { |
324 return new FetchDataLoaderAsStream(outStream); | 437 return new FetchDataLoaderAsStream(outStream); |
325 } | 438 } |
326 | 439 |
| 440 FetchDataLoader* FetchDataLoader::createLoaderAsDataPipe( |
| 441 mojo::ScopedDataPipeProducerHandle handle) { |
| 442 return new FetchDataLoaderAsDataPipe(std::move(handle)); |
| 443 } |
| 444 |
327 } // namespace blink | 445 } // namespace blink |
OLD | NEW |