Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 "content/browser/service_worker/service_worker_cache.h" | 5 #include "content/browser/service_worker/service_worker_cache.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/files/file_path.h" | 9 #include "base/files/file_path.h" |
| 10 #include "base/guid.h" | 10 #include "base/guid.h" |
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 421 ServiceWorkerCache::~ServiceWorkerCache() { | 421 ServiceWorkerCache::~ServiceWorkerCache() { |
| 422 } | 422 } |
| 423 | 423 |
| 424 base::WeakPtr<ServiceWorkerCache> ServiceWorkerCache::AsWeakPtr() { | 424 base::WeakPtr<ServiceWorkerCache> ServiceWorkerCache::AsWeakPtr() { |
| 425 return weak_ptr_factory_.GetWeakPtr(); | 425 return weak_ptr_factory_.GetWeakPtr(); |
| 426 } | 426 } |
| 427 | 427 |
| 428 void ServiceWorkerCache::Put(scoped_ptr<ServiceWorkerFetchRequest> request, | 428 void ServiceWorkerCache::Put(scoped_ptr<ServiceWorkerFetchRequest> request, |
| 429 scoped_ptr<ServiceWorkerResponse> response, | 429 scoped_ptr<ServiceWorkerResponse> response, |
| 430 const ResponseCallback& callback) { | 430 const ResponseCallback& callback) { |
| 431 IncPendingOps(); | |
| 432 ResponseCallback pending_callback = | |
| 433 base::Bind(&ServiceWorkerCache::PendingResponseCallback, | |
| 434 weak_ptr_factory_.GetWeakPtr(), callback); | |
| 435 scoped_ptr<storage::BlobDataHandle> blob_data_handle; | 431 scoped_ptr<storage::BlobDataHandle> blob_data_handle; |
| 436 | 432 |
| 437 if (!response->blob_uuid.empty()) { | 433 if (!response->blob_uuid.empty()) { |
| 438 if (!blob_storage_context_) { | 434 if (!blob_storage_context_) { |
| 439 pending_callback.Run(ErrorTypeStorage, | 435 callback.Run(ErrorTypeStorage, scoped_ptr<ServiceWorkerResponse>(), |
| 440 scoped_ptr<ServiceWorkerResponse>(), | 436 scoped_ptr<storage::BlobDataHandle>()); |
| 441 scoped_ptr<storage::BlobDataHandle>()); | |
| 442 return; | 437 return; |
| 443 } | 438 } |
| 444 blob_data_handle = | 439 blob_data_handle = |
| 445 blob_storage_context_->GetBlobDataFromUUID(response->blob_uuid); | 440 blob_storage_context_->GetBlobDataFromUUID(response->blob_uuid); |
| 446 if (!blob_data_handle) { | 441 if (!blob_data_handle) { |
| 447 pending_callback.Run(ErrorTypeStorage, | 442 callback.Run(ErrorTypeStorage, scoped_ptr<ServiceWorkerResponse>(), |
| 448 scoped_ptr<ServiceWorkerResponse>(), | 443 scoped_ptr<storage::BlobDataHandle>()); |
| 449 scoped_ptr<storage::BlobDataHandle>()); | |
| 450 return; | 444 return; |
| 451 } | 445 } |
| 452 } | 446 } |
| 453 | 447 |
| 448 ResponseCallback pending_callback = | |
| 449 base::Bind(&ServiceWorkerCache::PendingResponseCallback, | |
| 450 weak_ptr_factory_.GetWeakPtr(), callback); | |
| 451 | |
| 454 scoped_ptr<PutContext> put_context(new PutContext( | 452 scoped_ptr<PutContext> put_context(new PutContext( |
| 455 origin_, request.Pass(), response.Pass(), blob_data_handle.Pass(), | 453 origin_, request.Pass(), response.Pass(), blob_data_handle.Pass(), |
| 456 pending_callback, request_context_, quota_manager_proxy_)); | 454 pending_callback, request_context_, quota_manager_proxy_)); |
| 457 | 455 |
| 458 if (put_context->blob_data_handle) { | 456 if (put_context->blob_data_handle) { |
| 459 // Grab another handle to the blob for the callback response. | 457 // Grab another handle to the blob for the callback response. |
| 460 put_context->out_blob_data_handle = | 458 put_context->out_blob_data_handle = |
| 461 blob_storage_context_->GetBlobDataFromUUID( | 459 blob_storage_context_->GetBlobDataFromUUID( |
| 462 put_context->response->blob_uuid); | 460 put_context->response->blob_uuid); |
| 463 } | 461 } |
| 464 | 462 |
| 465 base::Closure continuation = | 463 pending_operations_.push_back(base::Bind(&ServiceWorkerCache::PutImpl, |
| 466 base::Bind(&ServiceWorkerCache::PutImpl, weak_ptr_factory_.GetWeakPtr(), | 464 weak_ptr_factory_.GetWeakPtr(), |
| 467 base::Passed(put_context.Pass())); | 465 base::Passed(put_context.Pass()))); |
| 468 | 466 |
| 469 if (backend_state_ == BACKEND_UNINITIALIZED) { | 467 if (backend_state_ == BACKEND_UNINITIALIZED) { |
| 470 InitBackend(continuation); | 468 InitBackend(pending_operations_.back()); |
| 471 return; | 469 return; |
| 472 } | 470 } |
| 473 | 471 |
| 474 continuation.Run(); | 472 RunOperationIfIdle(); |
| 475 } | 473 } |
| 476 | 474 |
| 477 void ServiceWorkerCache::Match(scoped_ptr<ServiceWorkerFetchRequest> request, | 475 void ServiceWorkerCache::Match(scoped_ptr<ServiceWorkerFetchRequest> request, |
| 478 const ResponseCallback& callback) { | 476 const ResponseCallback& callback) { |
| 479 IncPendingOps(); | |
| 480 ResponseCallback pending_callback = | 477 ResponseCallback pending_callback = |
| 481 base::Bind(&ServiceWorkerCache::PendingResponseCallback, | 478 base::Bind(&ServiceWorkerCache::PendingResponseCallback, |
| 482 weak_ptr_factory_.GetWeakPtr(), callback); | 479 weak_ptr_factory_.GetWeakPtr(), callback); |
| 480 pending_operations_.push_back( | |
| 481 base::Bind(&ServiceWorkerCache::MatchImpl, weak_ptr_factory_.GetWeakPtr(), | |
| 482 base::Passed(request.Pass()), pending_callback)); | |
| 483 | 483 |
| 484 switch (backend_state_) { | 484 switch (backend_state_) { |
| 485 case BACKEND_UNINITIALIZED: | 485 case BACKEND_UNINITIALIZED: |
| 486 InitBackend(base::Bind(&ServiceWorkerCache::Match, | 486 InitBackend(pending_operations_.back()); |
| 487 weak_ptr_factory_.GetWeakPtr(), | |
| 488 base::Passed(request.Pass()), pending_callback)); | |
| 489 return; | 487 return; |
| 490 case BACKEND_CLOSED: | 488 case BACKEND_CLOSED: |
| 491 pending_callback.Run(ErrorTypeStorage, | 489 pending_callback.Run(ErrorTypeStorage, |
| 492 scoped_ptr<ServiceWorkerResponse>(), | 490 scoped_ptr<ServiceWorkerResponse>(), |
| 493 scoped_ptr<storage::BlobDataHandle>()); | 491 scoped_ptr<storage::BlobDataHandle>()); |
| 494 return; | 492 return; |
| 495 case BACKEND_OPEN: | 493 case BACKEND_OPEN: |
| 496 DCHECK(backend_); | 494 DCHECK(backend_); |
| 497 break; | 495 RunOperationIfIdle(); |
| 496 return; | |
| 498 } | 497 } |
| 499 | 498 NOTREACHED(); |
| 500 scoped_ptr<MatchContext> match_context(new MatchContext( | |
| 501 request.Pass(), pending_callback, blob_storage_context_)); | |
| 502 | |
| 503 disk_cache::Entry** entry_ptr = &match_context->entry; | |
| 504 ServiceWorkerFetchRequest* request_ptr = match_context->request.get(); | |
| 505 | |
| 506 net::CompletionCallback open_entry_callback = base::Bind( | |
| 507 &ServiceWorkerCache::MatchDidOpenEntry, weak_ptr_factory_.GetWeakPtr(), | |
| 508 base::Passed(match_context.Pass())); | |
| 509 | |
| 510 int rv = backend_->OpenEntry( | |
| 511 request_ptr->url.spec(), entry_ptr, open_entry_callback); | |
| 512 if (rv != net::ERR_IO_PENDING) | |
| 513 open_entry_callback.Run(rv); | |
| 514 } | 499 } |
| 515 | 500 |
| 516 void ServiceWorkerCache::Delete(scoped_ptr<ServiceWorkerFetchRequest> request, | 501 void ServiceWorkerCache::Delete(scoped_ptr<ServiceWorkerFetchRequest> request, |
| 517 const ErrorCallback& callback) { | 502 const ErrorCallback& callback) { |
| 518 IncPendingOps(); | |
| 519 ErrorCallback pending_callback = | 503 ErrorCallback pending_callback = |
| 520 base::Bind(&ServiceWorkerCache::PendingErrorCallback, | 504 base::Bind(&ServiceWorkerCache::PendingErrorCallback, |
| 521 weak_ptr_factory_.GetWeakPtr(), callback); | 505 weak_ptr_factory_.GetWeakPtr(), callback); |
| 506 pending_operations_.push_back(base::Bind( | |
| 507 &ServiceWorkerCache::DeleteImpl, weak_ptr_factory_.GetWeakPtr(), | |
| 508 base::Passed(request.Pass()), pending_callback)); | |
| 522 | 509 |
| 523 switch (backend_state_) { | 510 switch (backend_state_) { |
| 524 case BACKEND_UNINITIALIZED: | 511 case BACKEND_UNINITIALIZED: |
| 525 InitBackend(base::Bind(&ServiceWorkerCache::Delete, | 512 InitBackend(pending_operations_.back()); |
| 526 weak_ptr_factory_.GetWeakPtr(), | |
| 527 base::Passed(request.Pass()), pending_callback)); | |
| 528 return; | 513 return; |
| 529 case BACKEND_CLOSED: | 514 case BACKEND_CLOSED: |
| 530 pending_callback.Run(ErrorTypeStorage); | 515 pending_callback.Run(ErrorTypeStorage); |
| 531 return; | 516 return; |
| 532 case BACKEND_OPEN: | 517 case BACKEND_OPEN: |
| 533 DCHECK(backend_); | 518 DCHECK(backend_); |
| 534 break; | 519 RunOperationIfIdle(); |
| 520 return; | |
| 535 } | 521 } |
| 536 | 522 NOTREACHED(); |
| 537 scoped_ptr<disk_cache::Entry*> entry(new disk_cache::Entry*); | |
| 538 | |
| 539 disk_cache::Entry** entry_ptr = entry.get(); | |
| 540 | |
| 541 ServiceWorkerFetchRequest* request_ptr = request.get(); | |
| 542 | |
| 543 net::CompletionCallback open_entry_callback = base::Bind( | |
| 544 &ServiceWorkerCache::DeleteDidOpenEntry, weak_ptr_factory_.GetWeakPtr(), | |
| 545 origin_, base::Passed(request.Pass()), pending_callback, | |
| 546 base::Passed(entry.Pass()), quota_manager_proxy_); | |
| 547 | |
| 548 int rv = backend_->OpenEntry( | |
| 549 request_ptr->url.spec(), entry_ptr, open_entry_callback); | |
| 550 if (rv != net::ERR_IO_PENDING) | |
| 551 open_entry_callback.Run(rv); | |
| 552 } | 523 } |
| 553 | 524 |
| 554 void ServiceWorkerCache::Keys(const RequestsCallback& callback) { | 525 void ServiceWorkerCache::Keys(const RequestsCallback& callback) { |
| 555 IncPendingOps(); | |
| 556 RequestsCallback pending_callback = | 526 RequestsCallback pending_callback = |
| 557 base::Bind(&ServiceWorkerCache::PendingRequestsCallback, | 527 base::Bind(&ServiceWorkerCache::PendingRequestsCallback, |
| 558 weak_ptr_factory_.GetWeakPtr(), callback); | 528 weak_ptr_factory_.GetWeakPtr(), callback); |
| 529 pending_operations_.push_back(base::Bind(&ServiceWorkerCache::KeysImpl, | |
| 530 weak_ptr_factory_.GetWeakPtr(), | |
| 531 pending_callback)); | |
| 559 | 532 |
| 560 switch (backend_state_) { | 533 switch (backend_state_) { |
| 561 case BACKEND_UNINITIALIZED: | 534 case BACKEND_UNINITIALIZED: |
| 562 InitBackend(base::Bind(&ServiceWorkerCache::Keys, | 535 InitBackend(pending_operations_.back()); |
| 563 weak_ptr_factory_.GetWeakPtr(), pending_callback)); | |
| 564 return; | 536 return; |
| 565 case BACKEND_CLOSED: | 537 case BACKEND_CLOSED: |
| 566 pending_callback.Run(ErrorTypeStorage, scoped_ptr<Requests>()); | 538 pending_callback.Run(ErrorTypeStorage, scoped_ptr<Requests>()); |
| 567 return; | 539 return; |
| 568 case BACKEND_OPEN: | 540 case BACKEND_OPEN: |
| 569 DCHECK(backend_); | 541 DCHECK(backend_); |
| 570 break; | 542 RunOperationIfIdle(); |
| 543 return; | |
| 571 } | 544 } |
| 572 | 545 NOTREACHED(); |
| 573 // 1. Iterate through all of the entries, open them, and add them to a vector. | |
| 574 // 2. For each open entry: | |
| 575 // 2.1. Read the headers into a protobuf. | |
| 576 // 2.2. Copy the protobuf into a ServiceWorkerFetchRequest (a "key"). | |
| 577 // 2.3. Push the response into a vector of requests to be returned. | |
| 578 // 3. Return the vector of requests (keys). | |
| 579 | |
| 580 // The entries have to be loaded into a vector first because enumeration loops | |
| 581 // forever if you read data from a cache entry while enumerating. | |
| 582 | |
| 583 scoped_ptr<KeysContext> keys_context(new KeysContext(pending_callback)); | |
| 584 | |
| 585 keys_context->backend_iterator = backend_->CreateIterator(); | |
| 586 disk_cache::Backend::Iterator& iterator = *keys_context->backend_iterator; | |
| 587 disk_cache::Entry** enumerated_entry = &keys_context->enumerated_entry; | |
| 588 | |
| 589 net::CompletionCallback open_entry_callback = base::Bind( | |
| 590 &ServiceWorkerCache::KeysDidOpenNextEntry, weak_ptr_factory_.GetWeakPtr(), | |
| 591 base::Passed(keys_context.Pass())); | |
| 592 | |
| 593 int rv = iterator.OpenNextEntry(enumerated_entry, open_entry_callback); | |
| 594 | |
| 595 if (rv != net::ERR_IO_PENDING) | |
| 596 open_entry_callback.Run(rv); | |
| 597 } | 546 } |
| 598 | 547 |
| 599 void ServiceWorkerCache::Close(const base::Closure& callback) { | 548 void ServiceWorkerCache::Close(const base::Closure& callback) { |
| 600 DCHECK(backend_state_ != BACKEND_CLOSED) | 549 DCHECK(backend_state_ != BACKEND_CLOSED) |
| 601 << "Don't call ServiceWorkerCache::Close() twice."; | 550 << "Don't call ServiceWorkerCache::Close() twice."; |
| 602 | 551 |
| 603 backend_state_ = BACKEND_CLOSED; | 552 backend_state_ = BACKEND_CLOSED; |
| 604 if (pending_ops_ > 0) { | 553 base::Closure pending_callback = |
| 605 DCHECK(ops_complete_callback_.is_null()); | 554 base::Bind(&ServiceWorkerCache::PendingClosure, |
| 606 ops_complete_callback_ = | 555 weak_ptr_factory_.GetWeakPtr(), callback); |
| 607 base::Bind(&ServiceWorkerCache::CloseImpl, | |
| 608 weak_ptr_factory_.GetWeakPtr(), callback); | |
| 609 return; | |
| 610 } | |
| 611 | 556 |
| 612 CloseImpl(callback); | 557 pending_operations_.push_back(base::Bind(&ServiceWorkerCache::CloseImpl, |
| 558 weak_ptr_factory_.GetWeakPtr(), | |
| 559 pending_callback)); | |
| 560 RunOperationIfIdle(); | |
| 613 } | 561 } |
| 614 | 562 |
| 615 int64 ServiceWorkerCache::MemoryBackedSize() const { | 563 int64 ServiceWorkerCache::MemoryBackedSize() const { |
| 616 if (backend_state_ != BACKEND_OPEN || !memory_only_) | 564 if (backend_state_ != BACKEND_OPEN || !memory_only_) |
| 617 return 0; | 565 return 0; |
| 618 | 566 |
| 619 scoped_ptr<disk_cache::Backend::Iterator> backend_iter = | 567 scoped_ptr<disk_cache::Backend::Iterator> backend_iter = |
| 620 backend_->CreateIterator(); | 568 backend_->CreateIterator(); |
| 621 disk_cache::Entry* entry = nullptr; | 569 disk_cache::Entry* entry = nullptr; |
| 622 | 570 |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 645 const base::FilePath& path, | 593 const base::FilePath& path, |
| 646 net::URLRequestContext* request_context, | 594 net::URLRequestContext* request_context, |
| 647 const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy, | 595 const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy, |
| 648 base::WeakPtr<storage::BlobStorageContext> blob_context) | 596 base::WeakPtr<storage::BlobStorageContext> blob_context) |
| 649 : origin_(origin), | 597 : origin_(origin), |
| 650 path_(path), | 598 path_(path), |
| 651 request_context_(request_context), | 599 request_context_(request_context), |
| 652 quota_manager_proxy_(quota_manager_proxy), | 600 quota_manager_proxy_(quota_manager_proxy), |
| 653 blob_storage_context_(blob_context), | 601 blob_storage_context_(blob_context), |
| 654 backend_state_(BACKEND_UNINITIALIZED), | 602 backend_state_(BACKEND_UNINITIALIZED), |
| 603 initializing_(false), | |
| 655 memory_only_(path.empty()), | 604 memory_only_(path.empty()), |
| 656 pending_ops_(0), | |
| 657 weak_ptr_factory_(this) { | 605 weak_ptr_factory_(this) { |
| 658 } | 606 } |
| 659 | 607 |
| 608 void ServiceWorkerCache::MatchImpl( | |
| 609 scoped_ptr<ServiceWorkerFetchRequest> request, | |
| 610 const ResponseCallback& callback) { | |
| 611 DCHECK(backend_state_ != BACKEND_UNINITIALIZED); | |
| 612 if (backend_state_ != BACKEND_OPEN) { | |
| 613 callback.Run(ErrorTypeStorage, scoped_ptr<ServiceWorkerResponse>(), | |
| 614 scoped_ptr<storage::BlobDataHandle>()); | |
| 615 return; | |
| 616 } | |
| 617 | |
| 618 scoped_ptr<MatchContext> match_context( | |
| 619 new MatchContext(request.Pass(), callback, blob_storage_context_)); | |
| 620 | |
| 621 disk_cache::Entry** entry_ptr = &match_context->entry; | |
| 622 ServiceWorkerFetchRequest* request_ptr = match_context->request.get(); | |
| 623 | |
| 624 net::CompletionCallback open_entry_callback = base::Bind( | |
| 625 &ServiceWorkerCache::MatchDidOpenEntry, weak_ptr_factory_.GetWeakPtr(), | |
| 626 base::Passed(match_context.Pass())); | |
| 627 | |
| 628 int rv = backend_->OpenEntry(request_ptr->url.spec(), entry_ptr, | |
| 629 open_entry_callback); | |
| 630 if (rv != net::ERR_IO_PENDING) | |
| 631 open_entry_callback.Run(rv); | |
| 632 } | |
| 633 | |
| 660 void ServiceWorkerCache::MatchDidOpenEntry( | 634 void ServiceWorkerCache::MatchDidOpenEntry( |
| 661 scoped_ptr<MatchContext> match_context, | 635 scoped_ptr<MatchContext> match_context, |
| 662 int rv) { | 636 int rv) { |
| 663 if (rv != net::OK) { | 637 if (rv != net::OK) { |
| 664 match_context->original_callback.Run(ServiceWorkerCache::ErrorTypeNotFound, | 638 match_context->original_callback.Run(ServiceWorkerCache::ErrorTypeNotFound, |
| 665 scoped_ptr<ServiceWorkerResponse>(), | 639 scoped_ptr<ServiceWorkerResponse>(), |
| 666 scoped_ptr<storage::BlobDataHandle>()); | 640 scoped_ptr<storage::BlobDataHandle>()); |
| 667 return; | 641 return; |
| 668 } | 642 } |
| 669 | 643 |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 811 scoped_ptr<storage::BlobDataHandle> blob_data_handle( | 785 scoped_ptr<storage::BlobDataHandle> blob_data_handle( |
| 812 match_context->blob_storage_context->AddFinishedBlob( | 786 match_context->blob_storage_context->AddFinishedBlob( |
| 813 match_context->blob_data.get())); | 787 match_context->blob_data.get())); |
| 814 | 788 |
| 815 match_context->original_callback.Run(ServiceWorkerCache::ErrorTypeOK, | 789 match_context->original_callback.Run(ServiceWorkerCache::ErrorTypeOK, |
| 816 match_context->response.Pass(), | 790 match_context->response.Pass(), |
| 817 blob_data_handle.Pass()); | 791 blob_data_handle.Pass()); |
| 818 } | 792 } |
| 819 | 793 |
| 820 void ServiceWorkerCache::PutImpl(scoped_ptr<PutContext> put_context) { | 794 void ServiceWorkerCache::PutImpl(scoped_ptr<PutContext> put_context) { |
| 795 DCHECK(backend_state_ != BACKEND_UNINITIALIZED); | |
| 821 if (backend_state_ != BACKEND_OPEN) { | 796 if (backend_state_ != BACKEND_OPEN) { |
| 822 put_context->callback.Run(ErrorTypeStorage, | 797 put_context->callback.Run(ErrorTypeStorage, |
| 823 scoped_ptr<ServiceWorkerResponse>(), | 798 scoped_ptr<ServiceWorkerResponse>(), |
| 824 scoped_ptr<storage::BlobDataHandle>()); | 799 scoped_ptr<storage::BlobDataHandle>()); |
| 825 return; | 800 return; |
| 826 } | 801 } |
| 827 | 802 |
| 828 scoped_ptr<ServiceWorkerFetchRequest> request_copy( | 803 scoped_ptr<ServiceWorkerFetchRequest> request_copy( |
| 829 new ServiceWorkerFetchRequest(*put_context->request)); | 804 new ServiceWorkerFetchRequest(*put_context->request)); |
| 830 | 805 |
| 831 Delete(request_copy.Pass(), base::Bind(&ServiceWorkerCache::PutDidDelete, | 806 DeleteImpl(request_copy.Pass(), base::Bind(&ServiceWorkerCache::PutDidDelete, |
| 832 weak_ptr_factory_.GetWeakPtr(), | 807 weak_ptr_factory_.GetWeakPtr(), |
| 833 base::Passed(put_context.Pass()))); | 808 base::Passed(put_context.Pass()))); |
| 834 } | 809 } |
| 835 | 810 |
| 836 void ServiceWorkerCache::PutDidDelete(scoped_ptr<PutContext> put_context, | 811 void ServiceWorkerCache::PutDidDelete(scoped_ptr<PutContext> put_context, |
| 837 ErrorType delete_error) { | 812 ErrorType delete_error) { |
| 838 if (backend_state_ != BACKEND_OPEN) { | 813 if (backend_state_ != BACKEND_OPEN) { |
| 839 put_context->callback.Run(ErrorTypeStorage, | 814 put_context->callback.Run(ErrorTypeStorage, |
| 840 scoped_ptr<ServiceWorkerResponse>(), | 815 scoped_ptr<ServiceWorkerResponse>(), |
| 841 scoped_ptr<storage::BlobDataHandle>()); | 816 scoped_ptr<storage::BlobDataHandle>()); |
| 842 return; | 817 return; |
| 843 } | 818 } |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 996 storage::kStorageTypeTemporary, | 971 storage::kStorageTypeTemporary, |
| 997 put_context->cache_entry->GetDataSize(INDEX_HEADERS) + | 972 put_context->cache_entry->GetDataSize(INDEX_HEADERS) + |
| 998 put_context->cache_entry->GetDataSize(INDEX_RESPONSE_BODY)); | 973 put_context->cache_entry->GetDataSize(INDEX_RESPONSE_BODY)); |
| 999 } | 974 } |
| 1000 | 975 |
| 1001 put_context->callback.Run(ServiceWorkerCache::ErrorTypeOK, | 976 put_context->callback.Run(ServiceWorkerCache::ErrorTypeOK, |
| 1002 put_context->response.Pass(), | 977 put_context->response.Pass(), |
| 1003 put_context->out_blob_data_handle.Pass()); | 978 put_context->out_blob_data_handle.Pass()); |
| 1004 } | 979 } |
| 1005 | 980 |
| 981 void ServiceWorkerCache::DeleteImpl( | |
| 982 scoped_ptr<ServiceWorkerFetchRequest> request, | |
| 983 const ErrorCallback& callback) { | |
| 984 DCHECK(backend_state_ != BACKEND_UNINITIALIZED); | |
| 985 if (backend_state_ != BACKEND_OPEN) { | |
| 986 callback.Run(ErrorTypeStorage); | |
| 987 return; | |
| 988 } | |
| 989 scoped_ptr<disk_cache::Entry*> entry(new disk_cache::Entry*); | |
| 990 | |
| 991 disk_cache::Entry** entry_ptr = entry.get(); | |
| 992 | |
| 993 ServiceWorkerFetchRequest* request_ptr = request.get(); | |
| 994 | |
| 995 net::CompletionCallback open_entry_callback = base::Bind( | |
| 996 &ServiceWorkerCache::DeleteDidOpenEntry, weak_ptr_factory_.GetWeakPtr(), | |
| 997 origin_, base::Passed(request.Pass()), callback, | |
| 998 base::Passed(entry.Pass()), quota_manager_proxy_); | |
| 999 | |
| 1000 int rv = backend_->OpenEntry(request_ptr->url.spec(), entry_ptr, | |
| 1001 open_entry_callback); | |
| 1002 if (rv != net::ERR_IO_PENDING) | |
| 1003 open_entry_callback.Run(rv); | |
| 1004 } | |
| 1005 | |
| 1006 void ServiceWorkerCache::DeleteDidOpenEntry( | 1006 void ServiceWorkerCache::DeleteDidOpenEntry( |
| 1007 const GURL& origin, | 1007 const GURL& origin, |
| 1008 scoped_ptr<ServiceWorkerFetchRequest> request, | 1008 scoped_ptr<ServiceWorkerFetchRequest> request, |
| 1009 const ServiceWorkerCache::ErrorCallback& callback, | 1009 const ServiceWorkerCache::ErrorCallback& callback, |
| 1010 scoped_ptr<disk_cache::Entry*> entry_ptr, | 1010 scoped_ptr<disk_cache::Entry*> entry_ptr, |
| 1011 const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy, | 1011 const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy, |
| 1012 int rv) { | 1012 int rv) { |
| 1013 if (rv != net::OK) { | 1013 if (rv != net::OK) { |
| 1014 callback.Run(ServiceWorkerCache::ErrorTypeNotFound); | 1014 callback.Run(ServiceWorkerCache::ErrorTypeNotFound); |
| 1015 return; | 1015 return; |
| 1016 } | 1016 } |
| 1017 | 1017 |
| 1018 DCHECK(entry_ptr); | 1018 DCHECK(entry_ptr); |
| 1019 disk_cache::ScopedEntryPtr entry(*entry_ptr); | 1019 disk_cache::ScopedEntryPtr entry(*entry_ptr); |
| 1020 | 1020 |
| 1021 if (quota_manager_proxy.get()) { | 1021 if (quota_manager_proxy.get()) { |
| 1022 quota_manager_proxy->NotifyStorageModified( | 1022 quota_manager_proxy->NotifyStorageModified( |
| 1023 storage::QuotaClient::kServiceWorkerCache, origin, | 1023 storage::QuotaClient::kServiceWorkerCache, origin, |
| 1024 storage::kStorageTypeTemporary, | 1024 storage::kStorageTypeTemporary, |
| 1025 -1 * (entry->GetDataSize(INDEX_HEADERS) + | 1025 -1 * (entry->GetDataSize(INDEX_HEADERS) + |
| 1026 entry->GetDataSize(INDEX_RESPONSE_BODY))); | 1026 entry->GetDataSize(INDEX_RESPONSE_BODY))); |
| 1027 } | 1027 } |
| 1028 | 1028 |
| 1029 entry->Doom(); | 1029 entry->Doom(); |
| 1030 callback.Run(ServiceWorkerCache::ErrorTypeOK); | 1030 callback.Run(ServiceWorkerCache::ErrorTypeOK); |
| 1031 } | 1031 } |
| 1032 | 1032 |
| 1033 void ServiceWorkerCache::KeysImpl(const RequestsCallback& callback) { | |
| 1034 DCHECK(backend_state_ != BACKEND_UNINITIALIZED); | |
| 1035 if (backend_state_ != BACKEND_OPEN) { | |
| 1036 callback.Run(ErrorTypeStorage, scoped_ptr<Requests>()); | |
| 1037 return; | |
| 1038 } | |
| 1039 | |
| 1040 // 1. Iterate through all of the entries, open them, and add them to a vector. | |
| 1041 // 2. For each open entry: | |
| 1042 // 2.1. Read the headers into a protobuf. | |
| 1043 // 2.2. Copy the protobuf into a ServiceWorkerFetchRequest (a "key"). | |
| 1044 // 2.3. Push the response into a vector of requests to be returned. | |
| 1045 // 3. Return the vector of requests (keys). | |
| 1046 | |
| 1047 // The entries have to be loaded into a vector first because enumeration loops | |
| 1048 // forever if you read data from a cache entry while enumerating. | |
| 1049 | |
| 1050 scoped_ptr<KeysContext> keys_context(new KeysContext(callback)); | |
| 1051 | |
| 1052 keys_context->backend_iterator = backend_->CreateIterator(); | |
| 1053 disk_cache::Backend::Iterator& iterator = *keys_context->backend_iterator; | |
| 1054 disk_cache::Entry** enumerated_entry = &keys_context->enumerated_entry; | |
| 1055 | |
| 1056 net::CompletionCallback open_entry_callback = base::Bind( | |
| 1057 &ServiceWorkerCache::KeysDidOpenNextEntry, weak_ptr_factory_.GetWeakPtr(), | |
| 1058 base::Passed(keys_context.Pass())); | |
| 1059 | |
| 1060 int rv = iterator.OpenNextEntry(enumerated_entry, open_entry_callback); | |
| 1061 | |
| 1062 if (rv != net::ERR_IO_PENDING) | |
| 1063 open_entry_callback.Run(rv); | |
| 1064 } | |
| 1065 | |
| 1033 void ServiceWorkerCache::KeysDidOpenNextEntry( | 1066 void ServiceWorkerCache::KeysDidOpenNextEntry( |
| 1034 scoped_ptr<KeysContext> keys_context, | 1067 scoped_ptr<KeysContext> keys_context, |
| 1035 int rv) { | 1068 int rv) { |
| 1036 if (rv == net::ERR_FAILED) { | 1069 if (rv == net::ERR_FAILED) { |
| 1037 DCHECK(!keys_context->enumerated_entry); | 1070 DCHECK(!keys_context->enumerated_entry); |
| 1038 // Enumeration is complete, extract the requests from the entries. | 1071 // Enumeration is complete, extract the requests from the entries. |
| 1039 Entries::iterator iter = keys_context->entries.begin(); | 1072 Entries::iterator iter = keys_context->entries.begin(); |
| 1040 KeysProcessNextEntry(keys_context.Pass(), iter); | 1073 KeysProcessNextEntry(keys_context.Pass(), iter); |
| 1041 return; | 1074 return; |
| 1042 } | 1075 } |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1108 } | 1141 } |
| 1109 } else { | 1142 } else { |
| 1110 entry->Doom(); | 1143 entry->Doom(); |
| 1111 } | 1144 } |
| 1112 | 1145 |
| 1113 KeysProcessNextEntry(keys_context.Pass(), iter + 1); | 1146 KeysProcessNextEntry(keys_context.Pass(), iter + 1); |
| 1114 } | 1147 } |
| 1115 | 1148 |
| 1116 void ServiceWorkerCache::CloseImpl(const base::Closure& callback) { | 1149 void ServiceWorkerCache::CloseImpl(const base::Closure& callback) { |
| 1117 DCHECK(backend_state_ == BACKEND_CLOSED); | 1150 DCHECK(backend_state_ == BACKEND_CLOSED); |
| 1151 DCHECK(pending_operations_.size() == 1u); | |
| 1118 backend_.reset(); | 1152 backend_.reset(); |
| 1119 callback.Run(); | 1153 callback.Run(); |
| 1120 } | 1154 } |
| 1121 | 1155 |
| 1122 void ServiceWorkerCache::CreateBackend(const ErrorCallback& callback) { | 1156 void ServiceWorkerCache::CreateBackend(const ErrorCallback& callback) { |
| 1123 DCHECK(!backend_); | 1157 DCHECK(!backend_); |
| 1124 | 1158 |
| 1125 // Use APP_CACHE as opposed to DISK_CACHE to prevent cache eviction. | 1159 // Use APP_CACHE as opposed to DISK_CACHE to prevent cache eviction. |
| 1126 net::CacheType cache_type = memory_only_ ? net::MEMORY_CACHE : net::APP_CACHE; | 1160 net::CacheType cache_type = memory_only_ ? net::MEMORY_CACHE : net::APP_CACHE; |
| 1127 | 1161 |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 1157 int rv) { | 1191 int rv) { |
| 1158 if (rv != net::OK) { | 1192 if (rv != net::OK) { |
| 1159 callback.Run(ServiceWorkerCache::ErrorTypeStorage); | 1193 callback.Run(ServiceWorkerCache::ErrorTypeStorage); |
| 1160 return; | 1194 return; |
| 1161 } | 1195 } |
| 1162 | 1196 |
| 1163 backend_ = backend_ptr->Pass(); | 1197 backend_ = backend_ptr->Pass(); |
| 1164 callback.Run(ServiceWorkerCache::ErrorTypeOK); | 1198 callback.Run(ServiceWorkerCache::ErrorTypeOK); |
| 1165 } | 1199 } |
| 1166 | 1200 |
| 1167 void ServiceWorkerCache::InitBackend(const base::Closure& callback) { | 1201 void ServiceWorkerCache::InitBackend(const base::Closure& callback) { |
|
michaeln
2015/01/23 00:55:25
The contract is a little odd, the 'callback' provi
jkarlin
2015/01/23 18:13:42
Done.
| |
| 1168 DCHECK(backend_state_ == BACKEND_UNINITIALIZED); | 1202 DCHECK(backend_state_ == BACKEND_UNINITIALIZED); |
| 1169 init_callbacks_.push_back(callback); | |
| 1170 | 1203 |
| 1171 // If this isn't the first call to Init then return as the initialization | 1204 if (initializing_) |
| 1172 // has already started. | |
| 1173 if (init_callbacks_.size() > 1u) | |
| 1174 return; | 1205 return; |
| 1175 | 1206 |
| 1207 initializing_ = true; | |
| 1176 CreateBackend(base::Bind(&ServiceWorkerCache::InitDone, | 1208 CreateBackend(base::Bind(&ServiceWorkerCache::InitDone, |
| 1177 weak_ptr_factory_.GetWeakPtr())); | 1209 weak_ptr_factory_.GetWeakPtr(), callback)); |
| 1178 } | 1210 } |
| 1179 | 1211 |
| 1180 void ServiceWorkerCache::InitDone(ErrorType error) { | 1212 void ServiceWorkerCache::InitDone(const base::Closure& callback, |
| 1213 ErrorType error) { | |
| 1214 initializing_ = false; | |
| 1181 backend_state_ = (error == ErrorTypeOK && backend_ && | 1215 backend_state_ = (error == ErrorTypeOK && backend_ && |
| 1182 backend_state_ == BACKEND_UNINITIALIZED) | 1216 backend_state_ == BACKEND_UNINITIALIZED) |
| 1183 ? BACKEND_OPEN | 1217 ? BACKEND_OPEN |
| 1184 : BACKEND_CLOSED; | 1218 : BACKEND_CLOSED; |
| 1185 for (std::vector<base::Closure>::iterator it = init_callbacks_.begin(); | 1219 callback.Run(); |
| 1186 it != init_callbacks_.end(); ++it) { | |
| 1187 it->Run(); | |
| 1188 } | |
| 1189 init_callbacks_.clear(); | |
| 1190 } | 1220 } |
| 1191 | 1221 |
| 1192 void ServiceWorkerCache::DecPendingOps() { | 1222 void ServiceWorkerCache::CompleteOperationAndRunNext() { |
| 1193 DCHECK(pending_ops_ > 0); | 1223 DCHECK(!pending_operations_.empty()); |
| 1194 pending_ops_--; | 1224 |
| 1195 if (pending_ops_ == 0 && !ops_complete_callback_.is_null()) { | 1225 pending_operations_.pop_front(); |
| 1196 ops_complete_callback_.Run(); | 1226 |
| 1197 ops_complete_callback_.Reset(); | 1227 // TODO(jkarlin): Run multiple operations in parallel where allowed (e.g., if |
| 1198 } | 1228 // they're for different keys then they won't interfere). See |
| 1229 // https://crbug.com/451174. | |
| 1230 if (!pending_operations_.empty()) | |
| 1231 pending_operations_.front().Run(); | |
| 1232 } | |
| 1233 | |
| 1234 void ServiceWorkerCache::RunOperationIfIdle() { | |
|
michaeln
2015/01/23 00:55:25
nit: this method is a little dangerous, if called
jkarlin
2015/01/23 18:13:42
Done.
| |
| 1235 if (pending_operations_.size() == 1u) | |
| 1236 pending_operations_.front().Run(); | |
| 1237 } | |
| 1238 | |
| 1239 void ServiceWorkerCache::PendingClosure(const base::Closure& callback) { | |
| 1240 callback.Run(); | |
| 1241 CompleteOperationAndRunNext(); | |
| 1199 } | 1242 } |
| 1200 | 1243 |
| 1201 void ServiceWorkerCache::PendingErrorCallback(const ErrorCallback& callback, | 1244 void ServiceWorkerCache::PendingErrorCallback(const ErrorCallback& callback, |
| 1202 ErrorType error) { | 1245 ErrorType error) { |
| 1203 callback.Run(error); | 1246 callback.Run(error); |
| 1204 DecPendingOps(); | 1247 CompleteOperationAndRunNext(); |
| 1205 } | 1248 } |
| 1206 | 1249 |
| 1207 void ServiceWorkerCache::PendingResponseCallback( | 1250 void ServiceWorkerCache::PendingResponseCallback( |
| 1208 const ResponseCallback& callback, | 1251 const ResponseCallback& callback, |
| 1209 ErrorType error, | 1252 ErrorType error, |
| 1210 scoped_ptr<ServiceWorkerResponse> response, | 1253 scoped_ptr<ServiceWorkerResponse> response, |
| 1211 scoped_ptr<storage::BlobDataHandle> blob_data_handle) { | 1254 scoped_ptr<storage::BlobDataHandle> blob_data_handle) { |
| 1212 callback.Run(error, response.Pass(), blob_data_handle.Pass()); | 1255 callback.Run(error, response.Pass(), blob_data_handle.Pass()); |
| 1213 DecPendingOps(); | 1256 CompleteOperationAndRunNext(); |
| 1214 } | 1257 } |
| 1215 | 1258 |
| 1216 void ServiceWorkerCache::PendingRequestsCallback( | 1259 void ServiceWorkerCache::PendingRequestsCallback( |
| 1217 const RequestsCallback& callback, | 1260 const RequestsCallback& callback, |
| 1218 ErrorType error, | 1261 ErrorType error, |
| 1219 scoped_ptr<Requests> requests) { | 1262 scoped_ptr<Requests> requests) { |
| 1220 callback.Run(error, requests.Pass()); | 1263 callback.Run(error, requests.Pass()); |
| 1221 DecPendingOps(); | 1264 CompleteOperationAndRunNext(); |
| 1222 } | 1265 } |
| 1223 | 1266 |
| 1224 } // namespace content | 1267 } // namespace content |
| OLD | NEW |