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

Side by Side Diff: content/browser/loader/throttling_resource_handler.cc

Issue 2271403002: Add CHECKs to investigate ResourceThrottle crash. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Oops Created 4 years, 3 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
« no previous file with comments | « content/browser/loader/throttling_resource_handler.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/loader/throttling_resource_handler.h" 5 #include "content/browser/loader/throttling_resource_handler.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/debug/alias.h"
10 #include "base/strings/string_util.h"
9 #include "content/browser/loader/resource_request_info_impl.h" 11 #include "content/browser/loader/resource_request_info_impl.h"
10 #include "content/public/browser/resource_throttle.h" 12 #include "content/public/browser/resource_throttle.h"
11 #include "content/public/common/resource_response.h" 13 #include "content/public/common/resource_response.h"
12 #include "net/url_request/url_request.h" 14 #include "net/url_request/url_request.h"
13 15
14 namespace content { 16 namespace content {
15 17
16 ThrottlingResourceHandler::ThrottlingResourceHandler( 18 ThrottlingResourceHandler::ThrottlingResourceHandler(
17 std::unique_ptr<ResourceHandler> next_handler, 19 std::unique_ptr<ResourceHandler> next_handler,
18 net::URLRequest* request, 20 net::URLRequest* request,
19 ScopedVector<ResourceThrottle> throttles) 21 ScopedVector<ResourceThrottle> throttles)
20 : LayeredResourceHandler(request, std::move(next_handler)), 22 : LayeredResourceHandler(request, std::move(next_handler)),
21 deferred_stage_(DEFERRED_NONE), 23 deferred_stage_(DEFERRED_NONE),
22 throttles_(std::move(throttles)), 24 throttles_(std::move(throttles)),
23 next_index_(0), 25 next_index_(0),
24 cancelled_by_resource_throttle_(false) { 26 cancelled_by_resource_throttle_(false),
27 currently_calling_throttle_(false) {
25 for (size_t i = 0; i < throttles_.size(); ++i) { 28 for (size_t i = 0; i < throttles_.size(); ++i) {
26 throttles_[i]->set_controller(this); 29 throttles_[i]->set_controller(this);
27 // Throttles must have a name, as otherwise, bugs where a throttle fails 30 // Throttles must have a name, as otherwise, bugs where a throttle fails
28 // to resume a request can be very difficult to debug. 31 // to resume a request can be very difficult to debug.
29 DCHECK(throttles_[i]->GetNameForLogging()); 32 DCHECK(throttles_[i]->GetNameForLogging());
30 } 33 }
31 } 34 }
32 35
33 ThrottlingResourceHandler::~ThrottlingResourceHandler() { 36 ThrottlingResourceHandler::~ThrottlingResourceHandler() {
37 // Check if |this| is being destroyed in a reentrant call from a throttle.
38 if (currently_calling_throttle_) {
39 CHECK_LE(1u, next_index_);
40 CHECK_LE(next_index_, throttles_.size());
41
42 // Stick some information on the stack that may be useful in debugging.
43 char bad_throttle_name[100];
44 base::strlcpy(bad_throttle_name,
45 throttles_[next_index_ - 1]->GetNameForLogging(),
46 arraysize(bad_throttle_name));
47 DeferredStage deferred_stage = deferred_stage_;
48 char url[128];
49 // The request should still be valid at this point...
50 base::strlcpy(url, request()->url().spec().c_str(), arraysize(url));
51 base::debug::Alias(bad_throttle_name);
52 base::debug::Alias(&deferred_stage);
53 base::debug::Alias(url);
54
55 CHECK(false);
56 }
34 } 57 }
35 58
36 bool ThrottlingResourceHandler::OnRequestRedirected( 59 bool ThrottlingResourceHandler::OnRequestRedirected(
37 const net::RedirectInfo& redirect_info, 60 const net::RedirectInfo& redirect_info,
38 ResourceResponse* response, 61 ResourceResponse* response,
39 bool* defer) { 62 bool* defer) {
63 CHECK(!currently_calling_throttle_);
40 DCHECK(!cancelled_by_resource_throttle_); 64 DCHECK(!cancelled_by_resource_throttle_);
41 65
42 *defer = false; 66 *defer = false;
43 while (next_index_ < throttles_.size()) { 67 while (next_index_ < throttles_.size()) {
44 int index = next_index_; 68 int index = next_index_;
69 currently_calling_throttle_ = true;
45 throttles_[index]->WillRedirectRequest(redirect_info, defer); 70 throttles_[index]->WillRedirectRequest(redirect_info, defer);
71 currently_calling_throttle_ = false;
46 next_index_++; 72 next_index_++;
47 if (cancelled_by_resource_throttle_) 73 if (cancelled_by_resource_throttle_)
48 return false; 74 return false;
49 if (*defer) { 75 if (*defer) {
50 OnRequestDefered(index); 76 OnRequestDefered(index);
51 deferred_stage_ = DEFERRED_REDIRECT; 77 deferred_stage_ = DEFERRED_REDIRECT;
52 deferred_redirect_ = redirect_info; 78 deferred_redirect_ = redirect_info;
53 deferred_response_ = response; 79 deferred_response_ = response;
54 return true; // Do not cancel. 80 return true; // Do not cancel.
55 } 81 }
56 } 82 }
57 83
58 next_index_ = 0; // Reset for next time. 84 next_index_ = 0; // Reset for next time.
59 85
60 return next_handler_->OnRequestRedirected(redirect_info, response, defer); 86 return next_handler_->OnRequestRedirected(redirect_info, response, defer);
61 } 87 }
62 88
63 bool ThrottlingResourceHandler::OnWillStart(const GURL& url, bool* defer) { 89 bool ThrottlingResourceHandler::OnWillStart(const GURL& url, bool* defer) {
90 CHECK(!currently_calling_throttle_);
64 DCHECK(!cancelled_by_resource_throttle_); 91 DCHECK(!cancelled_by_resource_throttle_);
65 92
66 *defer = false; 93 *defer = false;
67 while (next_index_ < throttles_.size()) { 94 while (next_index_ < throttles_.size()) {
68 int index = next_index_; 95 int index = next_index_;
96 currently_calling_throttle_ = true;
69 throttles_[index]->WillStartRequest(defer); 97 throttles_[index]->WillStartRequest(defer);
98 currently_calling_throttle_ = false;
70 next_index_++; 99 next_index_++;
71 if (cancelled_by_resource_throttle_) 100 if (cancelled_by_resource_throttle_)
72 return false; 101 return false;
73 if (*defer) { 102 if (*defer) {
74 OnRequestDefered(index); 103 OnRequestDefered(index);
75 deferred_stage_ = DEFERRED_START; 104 deferred_stage_ = DEFERRED_START;
76 deferred_url_ = url; 105 deferred_url_ = url;
77 return true; // Do not cancel. 106 return true; // Do not cancel.
78 } 107 }
79 } 108 }
80 109
81 next_index_ = 0; // Reset for next time. 110 next_index_ = 0; // Reset for next time.
82 111
83 return next_handler_->OnWillStart(url, defer); 112 return next_handler_->OnWillStart(url, defer);
84 } 113 }
85 114
86 bool ThrottlingResourceHandler::OnResponseStarted(ResourceResponse* response, 115 bool ThrottlingResourceHandler::OnResponseStarted(ResourceResponse* response,
87 bool* defer) { 116 bool* defer) {
117 CHECK(!currently_calling_throttle_);
88 DCHECK(!cancelled_by_resource_throttle_); 118 DCHECK(!cancelled_by_resource_throttle_);
89 119
90 while (next_index_ < throttles_.size()) { 120 while (next_index_ < throttles_.size()) {
91 int index = next_index_; 121 int index = next_index_;
122 currently_calling_throttle_ = true;
92 throttles_[index]->WillProcessResponse(defer); 123 throttles_[index]->WillProcessResponse(defer);
124 currently_calling_throttle_ = false;
93 next_index_++; 125 next_index_++;
94 if (cancelled_by_resource_throttle_) 126 if (cancelled_by_resource_throttle_)
95 return false; 127 return false;
96 if (*defer) { 128 if (*defer) {
97 OnRequestDefered(index); 129 OnRequestDefered(index);
98 deferred_stage_ = DEFERRED_RESPONSE; 130 deferred_stage_ = DEFERRED_RESPONSE;
99 deferred_response_ = response; 131 deferred_response_ = response;
100 return true; // Do not cancel. 132 return true; // Do not cancel.
101 } 133 }
102 } 134 }
(...skipping 12 matching lines...) Expand all
115 cancelled_by_resource_throttle_ = true; 147 cancelled_by_resource_throttle_ = true;
116 controller()->CancelAndIgnore(); 148 controller()->CancelAndIgnore();
117 } 149 }
118 150
119 void ThrottlingResourceHandler::CancelWithError(int error_code) { 151 void ThrottlingResourceHandler::CancelWithError(int error_code) {
120 cancelled_by_resource_throttle_ = true; 152 cancelled_by_resource_throttle_ = true;
121 controller()->CancelWithError(error_code); 153 controller()->CancelWithError(error_code);
122 } 154 }
123 155
124 void ThrottlingResourceHandler::Resume() { 156 void ThrottlingResourceHandler::Resume() {
157 CHECK(!currently_calling_throttle_);
125 DCHECK(!cancelled_by_resource_throttle_); 158 DCHECK(!cancelled_by_resource_throttle_);
159 // TODO(mmenke): Remove CHECK once https://crbug.com/640545 is resolved, as
160 // it's redundant with the NOTREACHED() below.
161 CHECK_NE(DEFERRED_NONE, deferred_stage_);
126 162
127 DeferredStage last_deferred_stage = deferred_stage_; 163 DeferredStage last_deferred_stage = deferred_stage_;
128 deferred_stage_ = DEFERRED_NONE; 164 deferred_stage_ = DEFERRED_NONE;
129 // Clear information about the throttle that delayed the request. 165 // Clear information about the throttle that delayed the request.
130 request()->LogUnblocked(); 166 request()->LogUnblocked();
131 switch (last_deferred_stage) { 167 switch (last_deferred_stage) {
132 case DEFERRED_NONE: 168 case DEFERRED_NONE:
133 NOTREACHED(); 169 NOTREACHED();
134 break; 170 break;
135 case DEFERRED_START: 171 case DEFERRED_START:
136 ResumeStart(); 172 ResumeStart();
137 break; 173 break;
138 case DEFERRED_REDIRECT: 174 case DEFERRED_REDIRECT:
139 ResumeRedirect(); 175 ResumeRedirect();
140 break; 176 break;
141 case DEFERRED_RESPONSE: 177 case DEFERRED_RESPONSE:
142 ResumeResponse(); 178 ResumeResponse();
143 break; 179 break;
144 } 180 }
145 } 181 }
146 182
147 void ThrottlingResourceHandler::ResumeStart() { 183 void ThrottlingResourceHandler::ResumeStart() {
184 CHECK(!currently_calling_throttle_);
148 DCHECK(!cancelled_by_resource_throttle_); 185 DCHECK(!cancelled_by_resource_throttle_);
149 186
150 GURL url = deferred_url_; 187 GURL url = deferred_url_;
151 deferred_url_ = GURL(); 188 deferred_url_ = GURL();
152 189
153 bool defer = false; 190 bool defer = false;
154 if (!OnWillStart(url, &defer)) { 191 if (!OnWillStart(url, &defer)) {
155 controller()->Cancel(); 192 controller()->Cancel();
156 } else if (!defer) { 193 } else if (!defer) {
157 controller()->Resume(); 194 controller()->Resume();
158 } 195 }
159 } 196 }
160 197
161 void ThrottlingResourceHandler::ResumeRedirect() { 198 void ThrottlingResourceHandler::ResumeRedirect() {
199 CHECK(!currently_calling_throttle_);
162 DCHECK(!cancelled_by_resource_throttle_); 200 DCHECK(!cancelled_by_resource_throttle_);
163 201
164 net::RedirectInfo redirect_info = deferred_redirect_; 202 net::RedirectInfo redirect_info = deferred_redirect_;
165 deferred_redirect_ = net::RedirectInfo(); 203 deferred_redirect_ = net::RedirectInfo();
166 scoped_refptr<ResourceResponse> response; 204 scoped_refptr<ResourceResponse> response;
167 deferred_response_.swap(response); 205 deferred_response_.swap(response);
168 206
169 bool defer = false; 207 bool defer = false;
170 if (!OnRequestRedirected(redirect_info, response.get(), &defer)) { 208 if (!OnRequestRedirected(redirect_info, response.get(), &defer)) {
171 controller()->Cancel(); 209 controller()->Cancel();
172 } else if (!defer) { 210 } else if (!defer) {
173 controller()->Resume(); 211 controller()->Resume();
174 } 212 }
175 } 213 }
176 214
177 void ThrottlingResourceHandler::ResumeResponse() { 215 void ThrottlingResourceHandler::ResumeResponse() {
216 CHECK(!currently_calling_throttle_);
178 DCHECK(!cancelled_by_resource_throttle_); 217 DCHECK(!cancelled_by_resource_throttle_);
179 218
180 scoped_refptr<ResourceResponse> response; 219 scoped_refptr<ResourceResponse> response;
181 deferred_response_.swap(response); 220 deferred_response_.swap(response);
182 221
183 bool defer = false; 222 bool defer = false;
184 if (!OnResponseStarted(response.get(), &defer)) { 223 if (!OnResponseStarted(response.get(), &defer)) {
185 controller()->Cancel(); 224 controller()->Cancel();
186 } else if (!defer) { 225 } else if (!defer) {
187 controller()->Resume(); 226 controller()->Resume();
188 } 227 }
189 } 228 }
190 229
191 void ThrottlingResourceHandler::OnRequestDefered(int throttle_index) { 230 void ThrottlingResourceHandler::OnRequestDefered(int throttle_index) {
192 request()->LogBlockedBy(throttles_[throttle_index]->GetNameForLogging()); 231 request()->LogBlockedBy(throttles_[throttle_index]->GetNameForLogging());
193 } 232 }
194 233
195 } // namespace content 234 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/loader/throttling_resource_handler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698