| Index: chrome/browser/renderer_host/offline_resource_handler.cc
|
| diff --git a/chrome/browser/renderer_host/offline_resource_handler.cc b/chrome/browser/renderer_host/offline_resource_handler.cc
|
| index 536e27cc800110f3a89d906560d34cb4b2e9f054..f3f10fa5f6200eb04996dfc732bca00d71adf92b 100644
|
| --- a/chrome/browser/renderer_host/offline_resource_handler.cc
|
| +++ b/chrome/browser/renderer_host/offline_resource_handler.cc
|
| @@ -45,7 +45,7 @@ OfflineResourceHandler::OfflineResourceHandler(
|
|
|
| OfflineResourceHandler::~OfflineResourceHandler() {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| - DCHECK(!appcache_completion_callback_.get());
|
| + DCHECK(appcache_completion_callback_.IsCancelled());
|
| }
|
|
|
| bool OfflineResourceHandler::OnUploadProgress(int request_id,
|
| @@ -77,26 +77,24 @@ bool OfflineResourceHandler::OnResponseCompleted(
|
| }
|
|
|
| void OfflineResourceHandler::OnRequestClosed() {
|
| - if (appcache_completion_callback_) {
|
| - appcache_completion_callback_->Cancel();
|
| - appcache_completion_callback_.release();
|
| - Release(); // Balanced with OnWillStart
|
| - }
|
| + if (!appcache_completion_callback_.IsCancelled())
|
| + appcache_completion_callback_.Cancel();
|
| +
|
| next_handler_->OnRequestClosed();
|
| }
|
|
|
| void OfflineResourceHandler::OnCanHandleOfflineComplete(int rv) {
|
| - CHECK(appcache_completion_callback_);
|
| - appcache_completion_callback_ = NULL;
|
| + // Cancel() to break the circular reference cycle.
|
| + appcache_completion_callback_.Cancel();
|
| +
|
| if (deferred_request_id_ == -1) {
|
| - LOG(WARNING) << "OnCanHandleOfflineComplete called after completion: "
|
| - << " this=" << this;
|
| - NOTREACHED();
|
| + DLOG(FATAL) << "OnCanHandleOfflineComplete called after completion: "
|
| + << " this=" << this;
|
| return;
|
| }
|
| +
|
| if (rv == net::OK) {
|
| Resume();
|
| - Release(); // Balanced with OnWillStart
|
| } else {
|
| BrowserThread::PostTask(
|
| BrowserThread::UI, FROM_HERE,
|
| @@ -107,24 +105,29 @@ void OfflineResourceHandler::OnCanHandleOfflineComplete(int rv) {
|
| bool OfflineResourceHandler::OnWillStart(int request_id,
|
| const GURL& url,
|
| bool* defer) {
|
| - if (ShouldShowOfflinePage(url)) {
|
| - deferred_request_id_ = request_id;
|
| - deferred_url_ = url;
|
| - DVLOG(1) << "OnWillStart: this=" << this << ", request id=" << request_id
|
| - << ", url=" << url;
|
| - AddRef(); // Balanced with OnCanHandleOfflineComplete
|
| - DCHECK(!appcache_completion_callback_);
|
| - appcache_completion_callback_ =
|
| - new net::CancelableOldCompletionCallback<OfflineResourceHandler>(
|
| - this, &OfflineResourceHandler::OnCanHandleOfflineComplete);
|
| - appcache_service_->CanHandleMainResourceOffline(
|
| - url, request_->first_party_for_cookies(),
|
| - appcache_completion_callback_);
|
| -
|
| - *defer = true;
|
| - return true;
|
| - }
|
| - return next_handler_->OnWillStart(request_id, url, defer);
|
| + if (!ShouldShowOfflinePage(url))
|
| + return next_handler_->OnWillStart(request_id, url, defer);
|
| +
|
| + deferred_request_id_ = request_id;
|
| + deferred_url_ = url;
|
| + DVLOG(1) << "OnWillStart: this=" << this << ", request id=" << request_id
|
| + << ", url=" << url;
|
| +
|
| + DCHECK(appcache_completion_callback_.IsCancelled());
|
| +
|
| + // |appcache_completion_callback_| holds a reference to |this|, so there is a
|
| + // circular reference; however, either
|
| + // OfflineResourceHandler::OnCanHandleOfflineComplete cancels the callback
|
| + // (thus dropping the reference), or CanHandleMainResourceOffline calls the
|
| + // callback which Resets it.
|
| + appcache_completion_callback_.Reset(
|
| + base::Bind(&OfflineResourceHandler::OnCanHandleOfflineComplete, this));
|
| + appcache_service_->CanHandleMainResourceOffline(
|
| + url, request_->first_party_for_cookies(),
|
| + appcache_completion_callback_.callback());
|
| +
|
| + *defer = true;
|
| + return true;
|
| }
|
|
|
| // We'll let the original event handler provide a buffer, and reuse it for
|
| @@ -161,7 +164,6 @@ void OfflineResourceHandler::OnBlockingPageComplete(bool proceed) {
|
| ClearRequestInfo();
|
| rdh_->CancelRequest(process_host_id_, request_id, false);
|
| }
|
| - Release(); // Balanced with OnWillStart
|
| }
|
|
|
| void OfflineResourceHandler::ClearRequestInfo() {
|
|
|