Index: content/browser/loader/detachable_resource_handler.cc |
diff --git a/content/browser/loader/detachable_resource_handler.cc b/content/browser/loader/detachable_resource_handler.cc |
index 2e1af5e7c6c396821e762203c1d9628012f1093b..001734901e4cc44c7ac93b9726e3d0553339ac88 100644 |
--- a/content/browser/loader/detachable_resource_handler.cc |
+++ b/content/browser/loader/detachable_resource_handler.cc |
@@ -7,7 +7,10 @@ |
#include <utility> |
#include "base/logging.h" |
+#include "base/memory/ptr_util.h" |
#include "base/time/time.h" |
+#include "content/browser/loader/null_resource_controller.h" |
+#include "content/browser/loader/resource_controller.h" |
#include "content/browser/loader/resource_request_info_impl.h" |
#include "net/base/io_buffer.h" |
#include "net/base/net_errors.h" |
@@ -21,6 +24,32 @@ const int kReadBufSize = 32 * 1024; |
namespace content { |
+// ResourceController that, when invoked, runs the corresponding method on |
+// ResourceHandler. |
+class DetachableResourceHandler::Controller : public ResourceController { |
+ public: |
+ explicit Controller(DetachableResourceHandler* detachable_handler) |
+ : detachable_handler_(detachable_handler){}; |
+ |
+ ~Controller() override {} |
+ |
+ // ResourceController implementation: |
+ void Resume() override { detachable_handler_->Resume(); } |
Charlie Harrison
2017/01/27 22:48:04
Can e use the MarkAsUsed pattern here?
mmenke
2017/01/27 23:02:15
Done.
|
+ |
+ void Cancel() override { detachable_handler_->Cancel(); } |
+ |
+ void CancelAndIgnore() override { detachable_handler_->CancelAndIgnore(); } |
+ |
+ void CancelWithError(int error_code) override { |
+ detachable_handler_->CancelWithError(error_code); |
+ } |
+ |
+ private: |
+ DetachableResourceHandler* detachable_handler_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(Controller); |
+}; |
+ |
DetachableResourceHandler::DetachableResourceHandler( |
net::URLRequest* request, |
base::TimeDelta cancel_delay, |
@@ -28,7 +57,6 @@ DetachableResourceHandler::DetachableResourceHandler( |
: ResourceHandler(request), |
next_handler_(std::move(next_handler)), |
cancel_delay_(cancel_delay), |
- is_deferred_(false), |
is_finished_(false) { |
GetRequestInfo()->set_detachable_handler(this); |
} |
@@ -38,6 +66,12 @@ DetachableResourceHandler::~DetachableResourceHandler() { |
GetRequestInfo()->set_detachable_handler(NULL); |
} |
+void DetachableResourceHandler::SetDelegate(Delegate* delegate) { |
+ ResourceHandler::SetDelegate(delegate); |
+ if (next_handler_) |
+ next_handler_->SetDelegate(delegate); |
+} |
+ |
void DetachableResourceHandler::Detach() { |
if (is_detached()) |
return; |
@@ -46,9 +80,10 @@ void DetachableResourceHandler::Detach() { |
// Simulate a cancel on the next handler before destroying it. |
net::URLRequestStatus status(net::URLRequestStatus::CANCELED, |
net::ERR_ABORTED); |
- bool defer_ignored = false; |
- next_handler_->OnResponseCompleted(status, &defer_ignored); |
- DCHECK(!defer_ignored); |
+ bool was_resumed; |
+ next_handler_->OnResponseCompleted( |
+ status, base::MakeUnique<NullResourceController>(&was_resumed)); |
+ DCHECK(was_resumed); |
// If |next_handler_| were to defer its shutdown in OnResponseCompleted, |
// this would destroy it anyway. Fortunately, AsyncResourceHandler never |
// does this anyway, so DCHECK it. MimeTypeResourceHandler and RVH shutdown |
@@ -66,13 +101,13 @@ void DetachableResourceHandler::Detach() { |
// Time the request out if it takes too long. |
detached_timer_.reset(new base::OneShotTimer()); |
- detached_timer_->Start( |
- FROM_HERE, cancel_delay_, this, &DetachableResourceHandler::Cancel); |
+ detached_timer_->Start(FROM_HERE, cancel_delay_, this, |
+ &DetachableResourceHandler::OnTimedOut); |
// Resume if necessary. The request may have been deferred, say, waiting on a |
// full buffer in AsyncResourceHandler. Now that it has been detached, resume |
// and drain it. |
- if (is_deferred_) { |
+ if (has_controller()) { |
// The nested ResourceHandler may have logged that it's blocking the |
// request. Log it as no longer doing so, to avoid a DCHECK on resume. |
request()->LogUnblocked(); |
@@ -80,52 +115,49 @@ void DetachableResourceHandler::Detach() { |
} |
} |
-void DetachableResourceHandler::SetController(ResourceController* controller) { |
- ResourceHandler::SetController(controller); |
- |
- // Intercept the ResourceController for downstream handlers to keep track of |
- // whether the request is deferred. |
- if (next_handler_) |
- next_handler_->SetController(this); |
-} |
- |
-bool DetachableResourceHandler::OnRequestRedirected( |
+void DetachableResourceHandler::OnRequestRedirected( |
const net::RedirectInfo& redirect_info, |
ResourceResponse* response, |
- bool* defer) { |
- DCHECK(!is_deferred_); |
+ std::unique_ptr<ResourceController> controller) { |
+ DCHECK(!has_controller()); |
- if (!next_handler_) |
- return true; |
+ if (!next_handler_) { |
+ controller->Resume(); |
+ return; |
+ } |
- bool ret = next_handler_->OnRequestRedirected( |
- redirect_info, response, &is_deferred_); |
- *defer = is_deferred_; |
- return ret; |
+ HoldController(std::move(controller)); |
+ next_handler_->OnRequestRedirected(redirect_info, response, |
+ base::MakeUnique<Controller>(this)); |
} |
-bool DetachableResourceHandler::OnResponseStarted(ResourceResponse* response, |
- bool* defer) { |
- DCHECK(!is_deferred_); |
+void DetachableResourceHandler::OnResponseStarted( |
+ ResourceResponse* response, |
+ std::unique_ptr<ResourceController> controller) { |
+ DCHECK(!has_controller()); |
- if (!next_handler_) |
- return true; |
+ if (!next_handler_) { |
+ controller->Resume(); |
+ return; |
+ } |
- bool ret = |
- next_handler_->OnResponseStarted(response, &is_deferred_); |
- *defer = is_deferred_; |
- return ret; |
+ HoldController(std::move(controller)); |
+ next_handler_->OnResponseStarted(response, |
+ base::MakeUnique<Controller>(this)); |
} |
-bool DetachableResourceHandler::OnWillStart(const GURL& url, bool* defer) { |
- DCHECK(!is_deferred_); |
+void DetachableResourceHandler::OnWillStart( |
+ const GURL& url, |
+ std::unique_ptr<ResourceController> controller) { |
+ DCHECK(!has_controller()); |
- if (!next_handler_) |
- return true; |
+ if (!next_handler_) { |
+ controller->Resume(); |
+ return; |
+ } |
- bool ret = next_handler_->OnWillStart(url, &is_deferred_); |
- *defer = is_deferred_; |
- return ret; |
+ HoldController(std::move(controller)); |
+ next_handler_->OnWillStart(url, base::MakeUnique<Controller>(this)); |
} |
bool DetachableResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf, |
@@ -143,31 +175,35 @@ bool DetachableResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf, |
return next_handler_->OnWillRead(buf, buf_size, min_size); |
} |
-bool DetachableResourceHandler::OnReadCompleted(int bytes_read, bool* defer) { |
- DCHECK(!is_deferred_); |
+void DetachableResourceHandler::OnReadCompleted( |
+ int bytes_read, |
+ std::unique_ptr<ResourceController> controller) { |
+ DCHECK(!has_controller()); |
- if (!next_handler_) |
- return true; |
+ if (!next_handler_) { |
+ controller->Resume(); |
+ return; |
+ } |
- bool ret = |
- next_handler_->OnReadCompleted(bytes_read, &is_deferred_); |
- *defer = is_deferred_; |
- return ret; |
+ HoldController(std::move(controller)); |
+ next_handler_->OnReadCompleted(bytes_read, |
+ base::MakeUnique<Controller>(this)); |
} |
void DetachableResourceHandler::OnResponseCompleted( |
const net::URLRequestStatus& status, |
- bool* defer) { |
+ std::unique_ptr<ResourceController> controller) { |
// No DCHECK(!is_deferred_) as the request may have been cancelled while |
// deferred. |
- if (!next_handler_) |
+ if (!next_handler_) { |
+ controller->Resume(); |
return; |
+ } |
is_finished_ = true; |
- next_handler_->OnResponseCompleted(status, &is_deferred_); |
- *defer = is_deferred_; |
+ next_handler_->OnResponseCompleted(status, std::move(controller)); |
} |
void DetachableResourceHandler::OnDataDownloaded(int bytes_downloaded) { |
@@ -177,22 +213,13 @@ void DetachableResourceHandler::OnDataDownloaded(int bytes_downloaded) { |
next_handler_->OnDataDownloaded(bytes_downloaded); |
} |
-void DetachableResourceHandler::Resume() { |
- DCHECK(is_deferred_); |
- is_deferred_ = false; |
- controller()->Resume(); |
-} |
- |
-void DetachableResourceHandler::Cancel() { |
- controller()->Cancel(); |
-} |
- |
-void DetachableResourceHandler::CancelAndIgnore() { |
- controller()->CancelAndIgnore(); |
-} |
+void DetachableResourceHandler::OnTimedOut() { |
+ // Requests are only timed out after being detached, and shouldn't be deferred |
+ // once detached. |
+ DCHECK(!next_handler_); |
+ DCHECK(!has_controller()); |
-void DetachableResourceHandler::CancelWithError(int error_code) { |
- controller()->CancelWithError(error_code); |
+ OutOfBandCancel(net::ERR_ABORTED, true /* tell_renderer */); |
} |
} // namespace content |