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

Side by Side Diff: content/browser/appcache/appcache_update_job.cc

Issue 879393002: Expire appcaches that fail to update for "too long". (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 6 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/appcache/appcache_update_job.h" 5 #include "content/browser/appcache/appcache_update_job.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/compiler_specific.h" 9 #include "base/compiler_specific.h"
10 #include "base/strings/string_util.h" 10 #include "base/strings/string_util.h"
11 #include "base/strings/stringprintf.h" 11 #include "base/strings/stringprintf.h"
12 #include "base/thread_task_runner_handle.h" 12 #include "base/thread_task_runner_handle.h"
13 #include "content/browser/appcache/appcache_group.h" 13 #include "content/browser/appcache/appcache_group.h"
14 #include "content/browser/appcache/appcache_histograms.h" 14 #include "content/browser/appcache/appcache_histograms.h"
15 #include "content/public/browser/browser_thread.h" 15 #include "content/public/browser/browser_thread.h"
16 #include "net/base/io_buffer.h" 16 #include "net/base/io_buffer.h"
17 #include "net/base/load_flags.h" 17 #include "net/base/load_flags.h"
18 #include "net/base/net_errors.h" 18 #include "net/base/net_errors.h"
19 #include "net/base/request_priority.h" 19 #include "net/base/request_priority.h"
20 #include "net/http/http_request_headers.h" 20 #include "net/http/http_request_headers.h"
21 #include "net/http/http_response_headers.h" 21 #include "net/http/http_response_headers.h"
22 #include "net/url_request/url_request_context.h" 22 #include "net/url_request/url_request_context.h"
23 23
24 namespace content { 24 namespace content {
25 25
26 static const int kBufferSize = 32768; 26 namespace {
27 static const size_t kMaxConcurrentUrlFetches = 2;
28 static const int kMax503Retries = 3;
29 27
30 static std::string FormatUrlErrorMessage( 28 const int kBufferSize = 32768;
29 const size_t kMaxConcurrentUrlFetches = 2;
30 const int kMax503Retries = 3;
31
32 std::string FormatUrlErrorMessage(
31 const char* format, const GURL& url, 33 const char* format, const GURL& url,
32 AppCacheUpdateJob::ResultType error, 34 AppCacheUpdateJob::ResultType error,
33 int response_code) { 35 int response_code) {
34 // Show the net response code if we have one. 36 // Show the net response code if we have one.
35 int code = response_code; 37 int code = response_code;
36 if (error != AppCacheUpdateJob::SERVER_ERROR) 38 if (error != AppCacheUpdateJob::SERVER_ERROR)
37 code = static_cast<int>(error); 39 code = static_cast<int>(error);
38 return base::StringPrintf(format, code, url.spec().c_str()); 40 return base::StringPrintf(format, code, url.spec().c_str());
39 } 41 }
40 42
43 bool IsEvictableError(AppCacheUpdateJob::ResultType result,
44 const AppCacheErrorDetails& details) {
45 switch (result) {
46 case AppCacheUpdateJob::DB_ERROR:
47 case AppCacheUpdateJob::DISKCACHE_ERROR:
48 case AppCacheUpdateJob::QUOTA_ERROR:
49 case AppCacheUpdateJob::NETWORK_ERROR:
50 case AppCacheUpdateJob::CANCELLED_ERROR:
51 return false;
52
53 case AppCacheUpdateJob::REDIRECT_ERROR:
54 case AppCacheUpdateJob::SERVER_ERROR:
55 case AppCacheUpdateJob::SECURITY_ERROR:
56 return true;
57
58 case AppCacheUpdateJob::MANIFEST_ERROR:
59 return details.reason == APPCACHE_SIGNATURE_ERROR;
60
61 default:
62 NOTREACHED();
63 return true;
64 }
65 }
66
67 void EmptyCompletionCallback(int result) {}
68
69 } // namespace
70
41 // Helper class for collecting hosts per frontend when sending notifications 71 // Helper class for collecting hosts per frontend when sending notifications
42 // so that only one notification is sent for all hosts using the same frontend. 72 // so that only one notification is sent for all hosts using the same frontend.
43 class HostNotifier { 73 class HostNotifier {
44 public: 74 public:
45 typedef std::vector<int> HostIds; 75 typedef std::vector<int> HostIds;
46 typedef std::map<AppCacheFrontend*, HostIds> NotifyHostMap; 76 typedef std::map<AppCacheFrontend*, HostIds> NotifyHostMap;
47 77
48 // Caller is responsible for ensuring there will be no duplicate hosts. 78 // Caller is responsible for ensuring there will be no duplicate hosts.
49 void AddHost(AppCacheHost* host) { 79 void AddHost(AppCacheHost* host) {
50 std::pair<NotifyHostMap::iterator , bool> ret = hosts_to_notify.insert( 80 std::pair<NotifyHostMap::iterator , bool> ret = hosts_to_notify.insert(
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 request_(job->service_->request_context() 156 request_(job->service_->request_context()
127 ->CreateRequest(url, net::DEFAULT_PRIORITY, this)), 157 ->CreateRequest(url, net::DEFAULT_PRIORITY, this)),
128 result_(UPDATE_OK), 158 result_(UPDATE_OK),
129 redirect_response_code_(-1) {} 159 redirect_response_code_(-1) {}
130 160
131 AppCacheUpdateJob::URLFetcher::~URLFetcher() { 161 AppCacheUpdateJob::URLFetcher::~URLFetcher() {
132 } 162 }
133 163
134 void AppCacheUpdateJob::URLFetcher::Start() { 164 void AppCacheUpdateJob::URLFetcher::Start() {
135 request_->set_first_party_for_cookies(job_->manifest_url_); 165 request_->set_first_party_for_cookies(job_->manifest_url_);
136 if (existing_response_headers_.get()) 166 if (fetch_type_ == MANIFEST_FETCH && job_->doing_full_update_check_)
167 request_->SetLoadFlags(request_->load_flags() | net::LOAD_BYPASS_CACHE);
168 else if (existing_response_headers_.get())
137 AddConditionalHeaders(existing_response_headers_.get()); 169 AddConditionalHeaders(existing_response_headers_.get());
138 request_->Start(); 170 request_->Start();
139 } 171 }
140 172
141 void AppCacheUpdateJob::URLFetcher::OnReceivedRedirect( 173 void AppCacheUpdateJob::URLFetcher::OnReceivedRedirect(
142 net::URLRequest* request, 174 net::URLRequest* request,
143 const net::RedirectInfo& redirect_info, 175 const net::RedirectInfo& redirect_info,
144 bool* defer_redirect) { 176 bool* defer_redirect) {
145 DCHECK(request_ == request); 177 DCHECK(request_ == request);
146 // Redirect is not allowed by the update process. 178 // Redirect is not allowed by the update process.
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 return true; 381 return true;
350 } 382 }
351 383
352 AppCacheUpdateJob::AppCacheUpdateJob(AppCacheServiceImpl* service, 384 AppCacheUpdateJob::AppCacheUpdateJob(AppCacheServiceImpl* service,
353 AppCacheGroup* group) 385 AppCacheGroup* group)
354 : service_(service), 386 : service_(service),
355 manifest_url_(group->manifest_url()), 387 manifest_url_(group->manifest_url()),
356 group_(group), 388 group_(group),
357 update_type_(UNKNOWN_TYPE), 389 update_type_(UNKNOWN_TYPE),
358 internal_state_(FETCH_MANIFEST), 390 internal_state_(FETCH_MANIFEST),
391 doing_full_update_check_(false),
359 master_entries_completed_(0), 392 master_entries_completed_(0),
360 url_fetches_completed_(0), 393 url_fetches_completed_(0),
361 manifest_fetcher_(NULL), 394 manifest_fetcher_(NULL),
362 manifest_has_valid_mime_type_(false), 395 manifest_has_valid_mime_type_(false),
363 stored_state_(UNSTORED), 396 stored_state_(UNSTORED),
364 storage_(service->storage()), 397 storage_(service->storage()),
365 weak_factory_(this) { 398 weak_factory_(this) {
366 service_->AddObserver(this); 399 service_->AddObserver(this);
367 } 400 }
368 401
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 } 456 }
424 } 457 }
425 return; 458 return;
426 } 459 }
427 460
428 // Begin update process for the group. 461 // Begin update process for the group.
429 MadeProgress(); 462 MadeProgress();
430 group_->SetUpdateAppCacheStatus(AppCacheGroup::CHECKING); 463 group_->SetUpdateAppCacheStatus(AppCacheGroup::CHECKING);
431 if (group_->HasCache()) { 464 if (group_->HasCache()) {
432 update_type_ = UPGRADE_ATTEMPT; 465 update_type_ = UPGRADE_ATTEMPT;
466 base::TimeDelta time_since_last_check =
467 base::Time::Now() - group_->last_full_update_check_time();
468 doing_full_update_check_ =
469 time_since_last_check > base::TimeDelta::FromHours(24);
433 NotifyAllAssociatedHosts(APPCACHE_CHECKING_EVENT); 470 NotifyAllAssociatedHosts(APPCACHE_CHECKING_EVENT);
434 } else { 471 } else {
435 update_type_ = CACHE_ATTEMPT; 472 update_type_ = CACHE_ATTEMPT;
473 doing_full_update_check_ = true;
436 DCHECK(host); 474 DCHECK(host);
437 NotifySingleHost(host, APPCACHE_CHECKING_EVENT); 475 NotifySingleHost(host, APPCACHE_CHECKING_EVENT);
438 } 476 }
439 477
440 if (!new_master_resource.is_empty()) { 478 if (!new_master_resource.is_empty()) {
441 AddMasterEntryToFetchList(host, new_master_resource, 479 AddMasterEntryToFetchList(host, new_master_resource,
442 is_new_pending_master_entry); 480 is_new_pending_master_entry);
443 } 481 }
444 482
445 BrowserThread::PostAfterStartupTask( 483 BrowserThread::PostAfterStartupTask(
(...skipping 18 matching lines...) Expand all
464 DCHECK(internal_state_ != CACHE_FAILURE); 502 DCHECK(internal_state_ != CACHE_FAILURE);
465 DCHECK(!error_details.message.empty()); 503 DCHECK(!error_details.message.empty());
466 DCHECK(result != UPDATE_OK); 504 DCHECK(result != UPDATE_OK);
467 internal_state_ = CACHE_FAILURE; 505 internal_state_ = CACHE_FAILURE;
468 LogHistogramStats(result, failed_resource_url); 506 LogHistogramStats(result, failed_resource_url);
469 CancelAllUrlFetches(); 507 CancelAllUrlFetches();
470 CancelAllMasterEntryFetches(error_details); 508 CancelAllMasterEntryFetches(error_details);
471 NotifyAllError(error_details); 509 NotifyAllError(error_details);
472 DiscardInprogressCache(); 510 DiscardInprogressCache();
473 internal_state_ = COMPLETED; 511 internal_state_ = COMPLETED;
512
513 if (update_type_ == CACHE_ATTEMPT ||
514 !IsEvictableError(result, error_details) ||
515 service_->storage() != storage_) {
516 DeleteSoon();
517 return;
518 }
519
520 if (group_->first_evictable_error_time().is_null()) {
521 group_->set_first_evictable_error_time(base::Time::Now());
522 storage_->StoreEvictionTimes(group_);
523 DeleteSoon();
524 return;
525 }
526
527 base::TimeDelta error_duration =
528 base::Time::Now() - group_->first_evictable_error_time();
529 base::TimeDelta kMaxPersistentErrorDuration = base::TimeDelta::FromDays(4);
530 if (error_duration > kMaxPersistentErrorDuration) {
531 // Break the connection with the group prior to calling
532 // DeleteAppCacheGroup, otherwise that method would delete |this|
533 // and we need the stack to unwind prior to deletion.
534 group_->SetUpdateAppCacheStatus(AppCacheGroup::IDLE);
535 group_ = NULL;
536 service_->DeleteAppCacheGroup(manifest_url_,
537 base::Bind(EmptyCompletionCallback));
538 }
539
474 DeleteSoon(); // To unwind the stack prior to deletion. 540 DeleteSoon(); // To unwind the stack prior to deletion.
475 } 541 }
476 542
477 void AppCacheUpdateJob::FetchManifest(bool is_first_fetch) { 543 void AppCacheUpdateJob::FetchManifest(bool is_first_fetch) {
478 DCHECK(!manifest_fetcher_); 544 DCHECK(!manifest_fetcher_);
479 manifest_fetcher_ = new URLFetcher( 545 manifest_fetcher_ = new URLFetcher(
480 manifest_url_, 546 manifest_url_,
481 is_first_fetch ? URLFetcher::MANIFEST_FETCH : 547 is_first_fetch ? URLFetcher::MANIFEST_FETCH :
482 URLFetcher::MANIFEST_REFETCH, 548 URLFetcher::MANIFEST_REFETCH,
483 this); 549 this);
484 550
485 // Add any necessary Http headers before sending fetch request.
486 if (is_first_fetch) { 551 if (is_first_fetch) {
552 // Maybe load the cached headers to make a condiditional request.
487 AppCacheEntry* entry = (update_type_ == UPGRADE_ATTEMPT) ? 553 AppCacheEntry* entry = (update_type_ == UPGRADE_ATTEMPT) ?
488 group_->newest_complete_cache()->GetEntry(manifest_url_) : NULL; 554 group_->newest_complete_cache()->GetEntry(manifest_url_) : NULL;
489 if (entry) { 555 if (entry && !doing_full_update_check_) {
490 // Asynchronously load response info for manifest from newest cache. 556 // Asynchronously load response info for manifest from newest cache.
491 storage_->LoadResponseInfo(manifest_url_, group_->group_id(), 557 storage_->LoadResponseInfo(manifest_url_, group_->group_id(),
492 entry->response_id(), this); 558 entry->response_id(), this);
493 } else { 559 return;
jsbell 2015/05/27 22:38:18 Much nicer code flow here!
michaeln 2015/05/27 23:21:51 yup, i put in some early returns elsewhere too for
494 manifest_fetcher_->Start();
495 } 560 }
496 } else {
497 DCHECK(internal_state_ == REFETCH_MANIFEST);
498 DCHECK(manifest_response_info_.get());
499 manifest_fetcher_->set_existing_response_headers(
500 manifest_response_info_->headers.get());
501 manifest_fetcher_->Start(); 561 manifest_fetcher_->Start();
562 return;
502 } 563 }
564
565 DCHECK(internal_state_ == REFETCH_MANIFEST);
566 DCHECK(manifest_response_info_.get());
567 manifest_fetcher_->set_existing_response_headers(
568 manifest_response_info_->headers.get());
569 manifest_fetcher_->Start();
503 } 570 }
504 571
505 572
506 void AppCacheUpdateJob::HandleManifestFetchCompleted( 573 void AppCacheUpdateJob::HandleManifestFetchCompleted(
507 URLFetcher* fetcher) { 574 URLFetcher* fetcher) {
508 DCHECK_EQ(internal_state_, FETCH_MANIFEST); 575 DCHECK_EQ(internal_state_, FETCH_MANIFEST);
509 DCHECK_EQ(manifest_fetcher_, fetcher); 576 DCHECK_EQ(manifest_fetcher_, fetcher);
510 manifest_fetcher_ = NULL; 577 manifest_fetcher_ = NULL;
511 578
512 net::URLRequest* request = fetcher->request(); 579 net::URLRequest* request = fetcher->request();
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
560 response_code, 627 response_code,
561 false /*is_cross_origin*/)); 628 false /*is_cross_origin*/));
562 if (success) { 629 if (success) {
563 DCHECK(group->is_obsolete()); 630 DCHECK(group->is_obsolete());
564 NotifyAllAssociatedHosts(APPCACHE_OBSOLETE_EVENT); 631 NotifyAllAssociatedHosts(APPCACHE_OBSOLETE_EVENT);
565 internal_state_ = COMPLETED; 632 internal_state_ = COMPLETED;
566 MaybeCompleteUpdate(); 633 MaybeCompleteUpdate();
567 } else { 634 } else {
568 // Treat failure to mark group obsolete as a cache failure. 635 // Treat failure to mark group obsolete as a cache failure.
569 HandleCacheFailure(AppCacheErrorDetails( 636 HandleCacheFailure(AppCacheErrorDetails(
570 "Failed to mark the cache as obsolete", 637 "Failed to mark the cache as obsolete",
571 APPCACHE_UNKNOWN_ERROR, 638 APPCACHE_UNKNOWN_ERROR, GURL(), 0,
572 GURL(), 639 false /*is_cross_origin*/),
573 0,
574 false /*is_cross_origin*/),
575 DB_ERROR, 640 DB_ERROR,
576 GURL()); 641 GURL());
577 } 642 }
578 } 643 }
579 644
580 void AppCacheUpdateJob::ContinueHandleManifestFetchCompleted(bool changed) { 645 void AppCacheUpdateJob::ContinueHandleManifestFetchCompleted(bool changed) {
581 DCHECK(internal_state_ == FETCH_MANIFEST); 646 DCHECK(internal_state_ == FETCH_MANIFEST);
582 647
583 if (!changed) { 648 if (!changed) {
584 DCHECK(update_type_ == UPGRADE_ATTEMPT); 649 DCHECK(update_type_ == UPGRADE_ATTEMPT);
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
924 0, 989 0,
925 false /*is_cross_origin*/), 990 false /*is_cross_origin*/),
926 DISKCACHE_ERROR, 991 DISKCACHE_ERROR,
927 GURL()); 992 GURL());
928 } 993 }
929 } 994 }
930 995
931 void AppCacheUpdateJob::StoreGroupAndCache() { 996 void AppCacheUpdateJob::StoreGroupAndCache() {
932 DCHECK(stored_state_ == UNSTORED); 997 DCHECK(stored_state_ == UNSTORED);
933 stored_state_ = STORING; 998 stored_state_ = STORING;
999
934 scoped_refptr<AppCache> newest_cache; 1000 scoped_refptr<AppCache> newest_cache;
935 if (inprogress_cache_.get()) 1001 if (inprogress_cache_.get())
936 newest_cache.swap(inprogress_cache_); 1002 newest_cache.swap(inprogress_cache_);
937 else 1003 else
938 newest_cache = group_->newest_complete_cache(); 1004 newest_cache = group_->newest_complete_cache();
939 newest_cache->set_update_time(base::Time::Now()); 1005 newest_cache->set_update_time(base::Time::Now());
940 1006
941 // TODO(michaeln): dcheck is fishing for clues to crbug/95101 1007 group_->set_first_evictable_error_time(base::Time());
942 DCHECK_EQ(manifest_url_, group_->manifest_url()); 1008 if (doing_full_update_check_)
1009 group_->set_last_full_update_check_time(base::Time::Now());
1010
943 storage_->StoreGroupAndNewestCache(group_, newest_cache.get(), this); 1011 storage_->StoreGroupAndNewestCache(group_, newest_cache.get(), this);
944 } 1012 }
945 1013
946 void AppCacheUpdateJob::OnGroupAndNewestCacheStored(AppCacheGroup* group, 1014 void AppCacheUpdateJob::OnGroupAndNewestCacheStored(AppCacheGroup* group,
947 AppCache* newest_cache, 1015 AppCache* newest_cache,
948 bool success, 1016 bool success,
949 bool would_exceed_quota) { 1017 bool would_exceed_quota) {
950 DCHECK(stored_state_ == STORING); 1018 DCHECK(stored_state_ == STORING);
951 if (success) { 1019 if (success) {
952 stored_state_ = STORED; 1020 stored_state_ = STORED;
953 MaybeCompleteUpdate(); // will definitely complete 1021 MaybeCompleteUpdate(); // will definitely complete
954 } else { 1022 return;
955 stored_state_ = UNSTORED; 1023 }
1024
1025 stored_state_ = UNSTORED;
956 1026
957 // Restore inprogress_cache_ to get the proper events delivered 1027 // Restore inprogress_cache_ to get the proper events delivered
958 // and the proper cleanup to occur. 1028 // and the proper cleanup to occur.
959 if (newest_cache != group->newest_complete_cache()) 1029 if (newest_cache != group->newest_complete_cache())
960 inprogress_cache_ = newest_cache; 1030 inprogress_cache_ = newest_cache;
961 1031
962 ResultType result = DB_ERROR; 1032 ResultType result = DB_ERROR;
963 AppCacheErrorReason reason = APPCACHE_UNKNOWN_ERROR; 1033 AppCacheErrorReason reason = APPCACHE_UNKNOWN_ERROR;
964 std::string message("Failed to commit new cache to storage"); 1034 std::string message("Failed to commit new cache to storage");
965 if (would_exceed_quota) { 1035 if (would_exceed_quota) {
966 message.append(", would exceed quota"); 1036 message.append(", would exceed quota");
967 result = QUOTA_ERROR; 1037 result = QUOTA_ERROR;
968 reason = APPCACHE_QUOTA_ERROR; 1038 reason = APPCACHE_QUOTA_ERROR;
969 } 1039 }
970 HandleCacheFailure( 1040 HandleCacheFailure(
971 AppCacheErrorDetails(message, reason, GURL(), 0, 1041 AppCacheErrorDetails(message, reason, GURL(), 0,
972 false /*is_cross_origin*/), 1042 false /*is_cross_origin*/),
973 result, 1043 result,
974 GURL()); 1044 GURL());
975 }
976 } 1045 }
977 1046
978 void AppCacheUpdateJob::NotifySingleHost(AppCacheHost* host, 1047 void AppCacheUpdateJob::NotifySingleHost(AppCacheHost* host,
979 AppCacheEventID event_id) { 1048 AppCacheEventID event_id) {
980 std::vector<int> ids(1, host->host_id()); 1049 std::vector<int> ids(1, host->host_id());
981 host->frontend()->OnEventRaised(ids, event_id); 1050 host->frontend()->OnEventRaised(ids, event_id);
982 } 1051 }
983 1052
984 void AppCacheUpdateJob::NotifyAllAssociatedHosts(AppCacheEventID event_id) { 1053 void AppCacheUpdateJob::NotifyAllAssociatedHosts(AppCacheEventID event_id) {
985 HostNotifier host_notifier; 1054 HostNotifier host_notifier;
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after
1447 if (master_entries_completed_ > 0) { 1516 if (master_entries_completed_ > 0) {
1448 switch (stored_state_) { 1517 switch (stored_state_) {
1449 case UNSTORED: 1518 case UNSTORED:
1450 StoreGroupAndCache(); 1519 StoreGroupAndCache();
1451 return; 1520 return;
1452 case STORING: 1521 case STORING:
1453 return; 1522 return;
1454 case STORED: 1523 case STORED:
1455 break; 1524 break;
1456 } 1525 }
1526 } else {
1527 bool times_changed = false;
1528 if (!group_->first_evictable_error_time().is_null()) {
1529 group_->set_first_evictable_error_time(base::Time());
1530 times_changed = true;
1531 }
1532 if (doing_full_update_check_) {
1533 group_->set_last_full_update_check_time(base::Time::Now());
1534 times_changed = true;
1535 }
1536 if (times_changed)
1537 storage_->StoreEvictionTimes(group_);
1457 } 1538 }
1458 // 6.9.4 steps 7.3-7.7. 1539 // 6.9.4 steps 7.3-7.7.
1459 NotifyAllAssociatedHosts(APPCACHE_NO_UPDATE_EVENT); 1540 NotifyAllAssociatedHosts(APPCACHE_NO_UPDATE_EVENT);
1460 DiscardDuplicateResponses(); 1541 DiscardDuplicateResponses();
1461 internal_state_ = COMPLETED; 1542 internal_state_ = COMPLETED;
1462 break; 1543 break;
1463 case DOWNLOADING: 1544 case DOWNLOADING:
1464 internal_state_ = REFETCH_MANIFEST; 1545 internal_state_ = REFETCH_MANIFEST;
1465 FetchManifest(false); 1546 FetchManifest(false);
1466 break; 1547 break;
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
1608 1689
1609 void AppCacheUpdateJob::DeleteSoon() { 1690 void AppCacheUpdateJob::DeleteSoon() {
1610 ClearPendingMasterEntries(); 1691 ClearPendingMasterEntries();
1611 manifest_response_writer_.reset(); 1692 manifest_response_writer_.reset();
1612 storage_->CancelDelegateCallbacks(this); 1693 storage_->CancelDelegateCallbacks(this);
1613 service_->RemoveObserver(this); 1694 service_->RemoveObserver(this);
1614 service_ = NULL; 1695 service_ = NULL;
1615 1696
1616 // Break the connection with the group so the group cannot call delete 1697 // Break the connection with the group so the group cannot call delete
1617 // on this object after we've posted a task to delete ourselves. 1698 // on this object after we've posted a task to delete ourselves.
1618 group_->SetUpdateAppCacheStatus(AppCacheGroup::IDLE); 1699 if (group_) {
1619 group_ = NULL; 1700 group_->SetUpdateAppCacheStatus(AppCacheGroup::IDLE);
1701 group_ = NULL;
1702 }
1620 1703
1621 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); 1704 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
1622 } 1705 }
1623 1706
1624 } // namespace content 1707 } // namespace content
OLDNEW
« content/browser/appcache/appcache_storage.h ('K') | « content/browser/appcache/appcache_update_job.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698