Chromium Code Reviews| 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" // For OS_POSIX | 7 #include "build/build_config.h" // For OS_POSIX |
| 8 | 8 |
| 9 #if defined(OS_POSIX) | 9 #if defined(OS_POSIX) |
| 10 #include <unistd.h> | 10 #include <unistd.h> |
| (...skipping 1149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1160 | 1160 |
| 1161 int HttpCache::Transaction::DoAddToEntry() { | 1161 int HttpCache::Transaction::DoAddToEntry() { |
| 1162 DCHECK(new_entry_); | 1162 DCHECK(new_entry_); |
| 1163 cache_pending_ = true; | 1163 cache_pending_ = true; |
| 1164 next_state_ = STATE_ADD_TO_ENTRY_COMPLETE; | 1164 next_state_ = STATE_ADD_TO_ENTRY_COMPLETE; |
| 1165 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY); | 1165 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY); |
| 1166 DCHECK(entry_lock_waiting_since_.is_null()); | 1166 DCHECK(entry_lock_waiting_since_.is_null()); |
| 1167 entry_lock_waiting_since_ = TimeTicks::Now(); | 1167 entry_lock_waiting_since_ = TimeTicks::Now(); |
| 1168 int rv = cache_->AddTransactionToEntry(new_entry_, this); | 1168 int rv = cache_->AddTransactionToEntry(new_entry_, this); |
| 1169 if (rv == ERR_IO_PENDING) { | 1169 if (rv == ERR_IO_PENDING) { |
| 1170 if (bypass_lock_for_test_) { | 1170 if (bypass_lock_for_test_) { |
|
mmenke
2015/11/25 20:55:39
I think we can get rid of this, and use the real t
davidben
2015/11/25 21:27:38
Done.
| |
| 1171 OnAddToEntryTimeout(entry_lock_waiting_since_); | 1171 OnAddToEntryTimeout(entry_lock_waiting_since_); |
| 1172 } else { | 1172 } else { |
| 1173 int timeout_milliseconds = 20 * 1000; | 1173 // Quickly timeout and bypass the cache if the blocked by the |
| 1174 if (partial_ && new_entry_->writer && | 1174 // reader/writer lock. Metrics indicate that only 0.42% of requests are |
| 1175 new_entry_->writer->range_requested_) { | 1175 // blocked on the cache lock for longer than 250ms. |
| 1176 // Quickly timeout and bypass the cache if we're a range request and | 1176 // |
| 1177 // we're blocked by the reader/writer lock. Doing so eliminates a long | 1177 // Bypassing the cache is not ideal, as we are now ignoring the cache |
| 1178 // running issue, http://crbug.com/31014, where two of the same media | 1178 // entirely for requests which hit a resource in |
| 1179 // resources could not be played back simultaneously due to one locking | 1179 // parallel. https://crbug.com/472740 tracks a better design for the |
| 1180 // the cache entry until the entire video was downloaded. | 1180 // system. |
| 1181 // | 1181 // |
| 1182 // Bypassing the cache is not ideal, as we are now ignoring the cache | 1182 // In the meantime, having a cache lock causes numerous priority inversion |
| 1183 // entirely for all range requests to a resource beyond the first. This | 1183 // problems and deadlocks, so it is better to ensure the system can make |
| 1184 // is however a much more succinct solution than the alternatives, which | 1184 // forward progress. (See https://crbug.com/31014, |
| 1185 // would require somewhat significant changes to the http caching logic. | 1185 // https://crbug.com/458620, https://crbug.com/535793, and |
| 1186 // | 1186 // https://crbug.com/6697.) |
| 1187 // Allow some timeout slack for the entry addition to complete in case | 1187 // |
| 1188 // the writer lock is imminently released; we want to avoid skipping | 1188 // Allow some timeout slack for the entry addition to complete in case the |
| 1189 // the cache if at all possible. See http://crbug.com/408765 | 1189 // writer lock is imminently released; we want to avoid skipping the cache |
| 1190 timeout_milliseconds = 25; | 1190 // if at all possible. See http://crbug.com/408765 |
| 1191 } | |
| 1192 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 1191 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 1193 FROM_HERE, | 1192 FROM_HERE, |
| 1194 base::Bind(&HttpCache::Transaction::OnAddToEntryTimeout, | 1193 base::Bind(&HttpCache::Transaction::OnAddToEntryTimeout, |
| 1195 weak_factory_.GetWeakPtr(), entry_lock_waiting_since_), | 1194 weak_factory_.GetWeakPtr(), entry_lock_waiting_since_), |
| 1196 TimeDelta::FromMilliseconds(timeout_milliseconds)); | 1195 TimeDelta::FromMilliseconds(25)); |
|
mmenke
2015/11/25 20:55:39
The CL description and comment above say 250, this
davidben
2015/11/25 21:27:38
Fixed to 25 since that's what range requests do. U
| |
| 1197 } | 1196 } |
| 1198 } | 1197 } |
| 1199 return rv; | 1198 return rv; |
| 1200 } | 1199 } |
| 1201 | 1200 |
| 1202 int HttpCache::Transaction::DoAddToEntryComplete(int result) { | 1201 int HttpCache::Transaction::DoAddToEntryComplete(int result) { |
| 1203 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY, | 1202 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY, |
| 1204 result); | 1203 result); |
| 1205 const TimeDelta entry_lock_wait = | 1204 const TimeDelta entry_lock_wait = |
| 1206 TimeTicks::Now() - entry_lock_waiting_since_; | 1205 TimeTicks::Now() - entry_lock_waiting_since_; |
| (...skipping 1730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2937 default: | 2936 default: |
| 2938 NOTREACHED(); | 2937 NOTREACHED(); |
| 2939 } | 2938 } |
| 2940 } | 2939 } |
| 2941 | 2940 |
| 2942 void HttpCache::Transaction::OnIOComplete(int result) { | 2941 void HttpCache::Transaction::OnIOComplete(int result) { |
| 2943 DoLoop(result); | 2942 DoLoop(result); |
| 2944 } | 2943 } |
| 2945 | 2944 |
| 2946 } // namespace net | 2945 } // namespace net |
| OLD | NEW |