OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/loader/detachable_resource_handler.h" | 5 #include "content/browser/loader/detachable_resource_handler.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
(...skipping 18 matching lines...) Expand all Loading... |
29 class DetachableResourceHandler::Controller : public ResourceController { | 29 class DetachableResourceHandler::Controller : public ResourceController { |
30 public: | 30 public: |
31 explicit Controller(DetachableResourceHandler* detachable_handler) | 31 explicit Controller(DetachableResourceHandler* detachable_handler) |
32 : detachable_handler_(detachable_handler){}; | 32 : detachable_handler_(detachable_handler){}; |
33 | 33 |
34 ~Controller() override {} | 34 ~Controller() override {} |
35 | 35 |
36 // ResourceController implementation: | 36 // ResourceController implementation: |
37 void Resume() override { | 37 void Resume() override { |
38 MarkAsUsed(); | 38 MarkAsUsed(); |
39 detachable_handler_->Resume(); | 39 detachable_handler_->ResumeInternal(); |
40 } | 40 } |
41 | 41 |
42 void Cancel() override { | 42 void Cancel() override { |
43 MarkAsUsed(); | 43 MarkAsUsed(); |
44 detachable_handler_->Cancel(); | 44 detachable_handler_->Cancel(); |
45 } | 45 } |
46 | 46 |
47 void CancelAndIgnore() override { | 47 void CancelAndIgnore() override { |
48 MarkAsUsed(); | 48 MarkAsUsed(); |
49 detachable_handler_->CancelAndIgnore(); | 49 detachable_handler_->CancelAndIgnore(); |
(...skipping 21 matching lines...) Expand all Loading... |
71 DISALLOW_COPY_AND_ASSIGN(Controller); | 71 DISALLOW_COPY_AND_ASSIGN(Controller); |
72 }; | 72 }; |
73 | 73 |
74 DetachableResourceHandler::DetachableResourceHandler( | 74 DetachableResourceHandler::DetachableResourceHandler( |
75 net::URLRequest* request, | 75 net::URLRequest* request, |
76 base::TimeDelta cancel_delay, | 76 base::TimeDelta cancel_delay, |
77 std::unique_ptr<ResourceHandler> next_handler) | 77 std::unique_ptr<ResourceHandler> next_handler) |
78 : ResourceHandler(request), | 78 : ResourceHandler(request), |
79 next_handler_(std::move(next_handler)), | 79 next_handler_(std::move(next_handler)), |
80 cancel_delay_(cancel_delay), | 80 cancel_delay_(cancel_delay), |
| 81 parent_read_buffer_(nullptr), |
| 82 parent_read_buffer_size_(nullptr), |
81 is_finished_(false) { | 83 is_finished_(false) { |
82 GetRequestInfo()->set_detachable_handler(this); | 84 GetRequestInfo()->set_detachable_handler(this); |
83 } | 85 } |
84 | 86 |
85 DetachableResourceHandler::~DetachableResourceHandler() { | 87 DetachableResourceHandler::~DetachableResourceHandler() { |
86 // Cleanup back-pointer stored on the request info. | 88 // Cleanup back-pointer stored on the request info. |
87 GetRequestInfo()->set_detachable_handler(NULL); | 89 GetRequestInfo()->set_detachable_handler(NULL); |
88 } | 90 } |
89 | 91 |
90 void DetachableResourceHandler::SetDelegate(Delegate* delegate) { | 92 void DetachableResourceHandler::SetDelegate(Delegate* delegate) { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 detached_timer_->Start(FROM_HERE, cancel_delay_, this, | 129 detached_timer_->Start(FROM_HERE, cancel_delay_, this, |
128 &DetachableResourceHandler::OnTimedOut); | 130 &DetachableResourceHandler::OnTimedOut); |
129 | 131 |
130 // Resume if necessary. The request may have been deferred, say, waiting on a | 132 // Resume if necessary. The request may have been deferred, say, waiting on a |
131 // full buffer in AsyncResourceHandler. Now that it has been detached, resume | 133 // full buffer in AsyncResourceHandler. Now that it has been detached, resume |
132 // and drain it. | 134 // and drain it. |
133 if (has_controller()) { | 135 if (has_controller()) { |
134 // The nested ResourceHandler may have logged that it's blocking the | 136 // The nested ResourceHandler may have logged that it's blocking the |
135 // request. Log it as no longer doing so, to avoid a DCHECK on resume. | 137 // request. Log it as no longer doing so, to avoid a DCHECK on resume. |
136 request()->LogUnblocked(); | 138 request()->LogUnblocked(); |
| 139 |
| 140 // If in the middle of an OnWillRead call, need to allocate the read buffer |
| 141 // before resuming. |
| 142 if (parent_read_buffer_) { |
| 143 DCHECK(parent_read_buffer_size_); |
| 144 |
| 145 scoped_refptr<net::IOBuffer>* parent_read_buffer = parent_read_buffer_; |
| 146 int* parent_read_buffer_size = parent_read_buffer_size_; |
| 147 parent_read_buffer_ = nullptr; |
| 148 parent_read_buffer_size_ = nullptr; |
| 149 |
| 150 // Will allocate the buffer and resume the request. |
| 151 OnWillRead(parent_read_buffer, parent_read_buffer_size, |
| 152 ReleaseController()); |
| 153 return; |
| 154 } |
| 155 |
137 Resume(); | 156 Resume(); |
138 } | 157 } |
139 } | 158 } |
140 | 159 |
141 void DetachableResourceHandler::OnRequestRedirected( | 160 void DetachableResourceHandler::OnRequestRedirected( |
142 const net::RedirectInfo& redirect_info, | 161 const net::RedirectInfo& redirect_info, |
143 ResourceResponse* response, | 162 ResourceResponse* response, |
144 std::unique_ptr<ResourceController> controller) { | 163 std::unique_ptr<ResourceController> controller) { |
145 DCHECK(!has_controller()); | 164 DCHECK(!has_controller()); |
146 | 165 |
(...skipping 29 matching lines...) Expand all Loading... |
176 | 195 |
177 if (!next_handler_) { | 196 if (!next_handler_) { |
178 controller->Resume(); | 197 controller->Resume(); |
179 return; | 198 return; |
180 } | 199 } |
181 | 200 |
182 HoldController(std::move(controller)); | 201 HoldController(std::move(controller)); |
183 next_handler_->OnWillStart(url, base::MakeUnique<Controller>(this)); | 202 next_handler_->OnWillStart(url, base::MakeUnique<Controller>(this)); |
184 } | 203 } |
185 | 204 |
186 bool DetachableResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf, | 205 void DetachableResourceHandler::OnWillRead( |
187 int* buf_size) { | 206 scoped_refptr<net::IOBuffer>* buf, |
| 207 int* buf_size, |
| 208 std::unique_ptr<ResourceController> controller) { |
188 if (!next_handler_) { | 209 if (!next_handler_) { |
189 if (!read_buffer_.get()) | 210 if (!read_buffer_.get()) |
190 read_buffer_ = new net::IOBuffer(kReadBufSize); | 211 read_buffer_ = new net::IOBuffer(kReadBufSize); |
191 *buf = read_buffer_; | 212 *buf = read_buffer_; |
192 *buf_size = kReadBufSize; | 213 *buf_size = kReadBufSize; |
193 return true; | 214 controller->Resume(); |
| 215 return; |
194 } | 216 } |
195 | 217 |
196 return next_handler_->OnWillRead(buf, buf_size); | 218 parent_read_buffer_ = buf; |
| 219 parent_read_buffer_size_ = buf_size; |
| 220 |
| 221 HoldController(std::move(controller)); |
| 222 next_handler_->OnWillRead(buf, buf_size, base::MakeUnique<Controller>(this)); |
197 } | 223 } |
198 | 224 |
199 void DetachableResourceHandler::OnReadCompleted( | 225 void DetachableResourceHandler::OnReadCompleted( |
200 int bytes_read, | 226 int bytes_read, |
201 std::unique_ptr<ResourceController> controller) { | 227 std::unique_ptr<ResourceController> controller) { |
202 DCHECK(!has_controller()); | 228 DCHECK(!has_controller()); |
203 | 229 |
204 if (!next_handler_) { | 230 if (!next_handler_) { |
205 controller->Resume(); | 231 controller->Resume(); |
206 return; | 232 return; |
(...skipping 22 matching lines...) Expand all Loading... |
229 base::MakeUnique<Controller>(this)); | 255 base::MakeUnique<Controller>(this)); |
230 } | 256 } |
231 | 257 |
232 void DetachableResourceHandler::OnDataDownloaded(int bytes_downloaded) { | 258 void DetachableResourceHandler::OnDataDownloaded(int bytes_downloaded) { |
233 if (!next_handler_) | 259 if (!next_handler_) |
234 return; | 260 return; |
235 | 261 |
236 next_handler_->OnDataDownloaded(bytes_downloaded); | 262 next_handler_->OnDataDownloaded(bytes_downloaded); |
237 } | 263 } |
238 | 264 |
| 265 void DetachableResourceHandler::ResumeInternal() { |
| 266 parent_read_buffer_ = nullptr; |
| 267 parent_read_buffer_size_ = nullptr; |
| 268 Resume(); |
| 269 } |
| 270 |
239 void DetachableResourceHandler::OnTimedOut() { | 271 void DetachableResourceHandler::OnTimedOut() { |
240 // Requests are only timed out after being detached, and shouldn't be deferred | 272 // Requests are only timed out after being detached, and shouldn't be deferred |
241 // once detached. | 273 // once detached. |
242 DCHECK(!next_handler_); | 274 DCHECK(!next_handler_); |
243 DCHECK(!has_controller()); | 275 DCHECK(!has_controller()); |
244 | 276 |
245 OutOfBandCancel(net::ERR_ABORTED, true /* tell_renderer */); | 277 OutOfBandCancel(net::ERR_ABORTED, true /* tell_renderer */); |
246 } | 278 } |
247 | 279 |
248 } // namespace content | 280 } // namespace content |
OLD | NEW |