OLD | NEW |
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 "net/http/http_cache_transaction.h" | 5 #include "net/http/http_cache_transaction.h" |
6 | 6 |
7 #include "build/build_config.h" | 7 #include "build/build_config.h" |
8 | 8 |
9 #if defined(OS_POSIX) | 9 #if defined(OS_POSIX) |
10 #include <unistd.h> | 10 #include <unistd.h> |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 reading_(false), | 196 reading_(false), |
197 invalid_range_(false), | 197 invalid_range_(false), |
198 truncated_(false), | 198 truncated_(false), |
199 is_sparse_(false), | 199 is_sparse_(false), |
200 range_requested_(false), | 200 range_requested_(false), |
201 handling_206_(false), | 201 handling_206_(false), |
202 cache_pending_(false), | 202 cache_pending_(false), |
203 done_reading_(false), | 203 done_reading_(false), |
204 vary_mismatch_(false), | 204 vary_mismatch_(false), |
205 couldnt_conditionalize_request_(false), | 205 couldnt_conditionalize_request_(false), |
| 206 bypass_lock_for_test_(false), |
206 io_buf_len_(0), | 207 io_buf_len_(0), |
207 read_offset_(0), | 208 read_offset_(0), |
208 effective_load_flags_(0), | 209 effective_load_flags_(0), |
209 write_len_(0), | 210 write_len_(0), |
210 weak_factory_(this), | 211 weak_factory_(this), |
211 io_callback_(base::Bind(&Transaction::OnIOComplete, | 212 io_callback_(base::Bind(&Transaction::OnIOComplete, |
212 weak_factory_.GetWeakPtr())), | 213 weak_factory_.GetWeakPtr())), |
213 transaction_pattern_(PATTERN_UNDEFINED), | 214 transaction_pattern_(PATTERN_UNDEFINED), |
214 total_received_bytes_(0), | 215 total_received_bytes_(0), |
215 websocket_handshake_stream_base_create_helper_(NULL) { | 216 websocket_handshake_stream_base_create_helper_(NULL) { |
(...skipping 977 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1193 return OK; | 1194 return OK; |
1194 } | 1195 } |
1195 | 1196 |
1196 int HttpCache::Transaction::DoAddToEntry() { | 1197 int HttpCache::Transaction::DoAddToEntry() { |
1197 DCHECK(new_entry_); | 1198 DCHECK(new_entry_); |
1198 cache_pending_ = true; | 1199 cache_pending_ = true; |
1199 next_state_ = STATE_ADD_TO_ENTRY_COMPLETE; | 1200 next_state_ = STATE_ADD_TO_ENTRY_COMPLETE; |
1200 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY); | 1201 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY); |
1201 DCHECK(entry_lock_waiting_since_.is_null()); | 1202 DCHECK(entry_lock_waiting_since_.is_null()); |
1202 entry_lock_waiting_since_ = TimeTicks::Now(); | 1203 entry_lock_waiting_since_ = TimeTicks::Now(); |
1203 return cache_->AddTransactionToEntry(new_entry_, this); | 1204 int rv = cache_->AddTransactionToEntry(new_entry_, this); |
| 1205 if (rv == ERR_IO_PENDING) { |
| 1206 if (bypass_lock_for_test_) { |
| 1207 OnAddToEntryTimeout(entry_lock_waiting_since_); |
| 1208 } else { |
| 1209 const int kTimeoutSeconds = 20; |
| 1210 base::MessageLoop::current()->PostDelayedTask( |
| 1211 FROM_HERE, |
| 1212 base::Bind(&HttpCache::Transaction::OnAddToEntryTimeout, |
| 1213 weak_factory_.GetWeakPtr(), entry_lock_waiting_since_), |
| 1214 TimeDelta::FromSeconds(kTimeoutSeconds)); |
| 1215 } |
| 1216 } |
| 1217 return rv; |
1204 } | 1218 } |
1205 | 1219 |
1206 int HttpCache::Transaction::DoAddToEntryComplete(int result) { | 1220 int HttpCache::Transaction::DoAddToEntryComplete(int result) { |
1207 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY, | 1221 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY, |
1208 result); | 1222 result); |
1209 const TimeDelta entry_lock_wait = | 1223 const TimeDelta entry_lock_wait = |
1210 TimeTicks::Now() - entry_lock_waiting_since_; | 1224 TimeTicks::Now() - entry_lock_waiting_since_; |
1211 UMA_HISTOGRAM_TIMES("HttpCache.EntryLockWait", entry_lock_wait); | 1225 UMA_HISTOGRAM_TIMES("HttpCache.EntryLockWait", entry_lock_wait); |
1212 | 1226 |
1213 entry_lock_waiting_since_ = TimeTicks(); | 1227 entry_lock_waiting_since_ = TimeTicks(); |
1214 DCHECK(new_entry_); | 1228 DCHECK(new_entry_); |
1215 cache_pending_ = false; | 1229 cache_pending_ = false; |
1216 | 1230 |
1217 if (result == OK) | 1231 if (result == OK) |
1218 entry_ = new_entry_; | 1232 entry_ = new_entry_; |
1219 | 1233 |
1220 // If there is a failure, the cache should have taken care of new_entry_. | 1234 // If there is a failure, the cache should have taken care of new_entry_. |
1221 new_entry_ = NULL; | 1235 new_entry_ = NULL; |
1222 | 1236 |
1223 if (result == ERR_CACHE_RACE) { | 1237 if (result == ERR_CACHE_RACE) { |
1224 next_state_ = STATE_INIT_ENTRY; | 1238 next_state_ = STATE_INIT_ENTRY; |
1225 return OK; | 1239 return OK; |
1226 } | 1240 } |
1227 | 1241 |
| 1242 if (result == ERR_CACHE_LOCK_TIMEOUT) { |
| 1243 // The cache is busy, bypass it for this transaction. |
| 1244 mode_ = NONE; |
| 1245 next_state_ = STATE_SEND_REQUEST; |
| 1246 if (partial_) { |
| 1247 partial_->RestoreHeaders(&custom_request_->extra_headers); |
| 1248 partial_.reset(); |
| 1249 } |
| 1250 return OK; |
| 1251 } |
| 1252 |
1228 if (result != OK) { | 1253 if (result != OK) { |
1229 NOTREACHED(); | 1254 NOTREACHED(); |
1230 return result; | 1255 return result; |
1231 } | 1256 } |
1232 | 1257 |
1233 if (mode_ == WRITE) { | 1258 if (mode_ == WRITE) { |
1234 if (partial_.get()) | 1259 if (partial_.get()) |
1235 partial_->RestoreHeaders(&custom_request_->extra_headers); | 1260 partial_->RestoreHeaders(&custom_request_->extra_headers); |
1236 next_state_ = STATE_SEND_REQUEST; | 1261 next_state_ = STATE_SEND_REQUEST; |
1237 } else { | 1262 } else { |
(...skipping 1105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2343 entry_ = NULL; | 2368 entry_ = NULL; |
2344 is_sparse_ = false; | 2369 is_sparse_ = false; |
2345 partial_.reset(); | 2370 partial_.reset(); |
2346 next_state_ = STATE_GET_BACKEND; | 2371 next_state_ = STATE_GET_BACKEND; |
2347 return OK; | 2372 return OK; |
2348 } | 2373 } |
2349 | 2374 |
2350 return ERR_CACHE_READ_FAILURE; | 2375 return ERR_CACHE_READ_FAILURE; |
2351 } | 2376 } |
2352 | 2377 |
| 2378 void HttpCache::Transaction::OnAddToEntryTimeout(base::TimeTicks start_time) { |
| 2379 if (entry_lock_waiting_since_ != start_time) |
| 2380 return; |
| 2381 |
| 2382 DCHECK_EQ(next_state_, STATE_ADD_TO_ENTRY_COMPLETE); |
| 2383 |
| 2384 if (!cache_) |
| 2385 return; |
| 2386 |
| 2387 cache_->RemovePendingTransaction(this); |
| 2388 OnIOComplete(ERR_CACHE_LOCK_TIMEOUT); |
| 2389 } |
| 2390 |
2353 void HttpCache::Transaction::DoomPartialEntry(bool delete_object) { | 2391 void HttpCache::Transaction::DoomPartialEntry(bool delete_object) { |
2354 DVLOG(2) << "DoomPartialEntry"; | 2392 DVLOG(2) << "DoomPartialEntry"; |
2355 int rv = cache_->DoomEntry(cache_key_, NULL); | 2393 int rv = cache_->DoomEntry(cache_key_, NULL); |
2356 DCHECK_EQ(OK, rv); | 2394 DCHECK_EQ(OK, rv); |
2357 cache_->DoneWithEntry(entry_, this, false); | 2395 cache_->DoneWithEntry(entry_, this, false); |
2358 entry_ = NULL; | 2396 entry_ = NULL; |
2359 is_sparse_ = false; | 2397 is_sparse_ = false; |
2360 if (delete_object) | 2398 if (delete_object) |
2361 partial_.reset(NULL); | 2399 partial_.reset(NULL); |
2362 } | 2400 } |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2520 default: | 2558 default: |
2521 NOTREACHED(); | 2559 NOTREACHED(); |
2522 } | 2560 } |
2523 } | 2561 } |
2524 | 2562 |
2525 void HttpCache::Transaction::OnIOComplete(int result) { | 2563 void HttpCache::Transaction::OnIOComplete(int result) { |
2526 DoLoop(result); | 2564 DoLoop(result); |
2527 } | 2565 } |
2528 | 2566 |
2529 } // namespace net | 2567 } // namespace net |
OLD | NEW |