OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/disk_cache_based_quic_server_info.h" | 5 #include "net/http/disk_cache_based_quic_server_info.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/callback.h" | 8 #include "base/callback.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/metrics/histogram.h" |
10 #include "net/base/completion_callback.h" | 11 #include "net/base/completion_callback.h" |
11 #include "net/base/io_buffer.h" | 12 #include "net/base/io_buffer.h" |
12 #include "net/base/net_errors.h" | 13 #include "net/base/net_errors.h" |
13 #include "net/http/http_cache.h" | 14 #include "net/http/http_cache.h" |
14 #include "net/http/http_network_session.h" | 15 #include "net/http/http_network_session.h" |
15 #include "net/quic/quic_server_id.h" | 16 #include "net/quic/quic_server_id.h" |
16 | 17 |
17 namespace net { | 18 namespace net { |
18 | 19 |
| 20 // Histogram for tracking down the state of disk_cache::Entry. |
| 21 enum DiskCacheEntryState { |
| 22 DISK_CACHE_ENTRY_OPENED = 0, |
| 23 DISK_CACHE_ENTRY_CLOSED = 1, |
| 24 DISK_CACHE_ENTRY_NUM_STATES = 2, |
| 25 }; |
| 26 |
| 27 void RecordDiskCacheEntryState(DiskCacheEntryState entry_state) { |
| 28 UMA_HISTOGRAM_ENUMERATION("Net.QuicDiskCache.EntryState", entry_state, |
| 29 DISK_CACHE_ENTRY_NUM_STATES); |
| 30 } |
| 31 |
19 // Some APIs inside disk_cache take a handle that the caller must keep alive | 32 // Some APIs inside disk_cache take a handle that the caller must keep alive |
20 // until the API has finished its asynchronous execution. | 33 // until the API has finished its asynchronous execution. |
21 // | 34 // |
22 // Unfortunately, DiskCacheBasedQuicServerInfo may be deleted before the | 35 // Unfortunately, DiskCacheBasedQuicServerInfo may be deleted before the |
23 // operation completes causing a use-after-free. | 36 // operation completes causing a use-after-free. |
24 // | 37 // |
25 // This data shim struct is meant to provide a location for the disk_cache | 38 // This data shim struct is meant to provide a location for the disk_cache |
26 // APIs to write into even if the originating DiskCacheBasedQuicServerInfo | 39 // APIs to write into even if the originating DiskCacheBasedQuicServerInfo |
27 // object has been deleted. The lifetime for instances of this struct | 40 // object has been deleted. The lifetime for instances of this struct |
28 // should be bound to the CompletionCallback that is passed to the disk_cache | 41 // should be bound to the CompletionCallback that is passed to the disk_cache |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 | 121 |
109 if (!backend_) | 122 if (!backend_) |
110 return; | 123 return; |
111 | 124 |
112 state_ = CREATE_OR_OPEN; | 125 state_ = CREATE_OR_OPEN; |
113 DoLoop(OK); | 126 DoLoop(OK); |
114 } | 127 } |
115 | 128 |
116 DiskCacheBasedQuicServerInfo::~DiskCacheBasedQuicServerInfo() { | 129 DiskCacheBasedQuicServerInfo::~DiskCacheBasedQuicServerInfo() { |
117 DCHECK(user_callback_.is_null()); | 130 DCHECK(user_callback_.is_null()); |
118 if (entry_) | 131 if (entry_) { |
119 entry_->Close(); | 132 entry_->Close(); |
| 133 RecordDiskCacheEntryState(DISK_CACHE_ENTRY_CLOSED); |
| 134 } |
120 } | 135 } |
121 | 136 |
122 std::string DiskCacheBasedQuicServerInfo::key() const { | 137 std::string DiskCacheBasedQuicServerInfo::key() const { |
123 return "quicserverinfo:" + server_id_.ToString(); | 138 return "quicserverinfo:" + server_id_.ToString(); |
124 } | 139 } |
125 | 140 |
126 void DiskCacheBasedQuicServerInfo::OnIOComplete(CacheOperationDataShim* unused, | 141 void DiskCacheBasedQuicServerInfo::OnIOComplete(CacheOperationDataShim* unused, |
127 int rv) { | 142 int rv) { |
128 DCHECK_NE(NONE, state_); | 143 DCHECK_NE(NONE, state_); |
129 rv = DoLoop(rv); | 144 rv = DoLoop(rv); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 state_ = WAIT_FOR_DATA_READY_DONE; | 205 state_ = WAIT_FOR_DATA_READY_DONE; |
191 } | 206 } |
192 return OK; | 207 return OK; |
193 } | 208 } |
194 | 209 |
195 int DiskCacheBasedQuicServerInfo::DoOpenComplete(int rv) { | 210 int DiskCacheBasedQuicServerInfo::DoOpenComplete(int rv) { |
196 if (rv == OK) { | 211 if (rv == OK) { |
197 entry_ = data_shim_->entry; | 212 entry_ = data_shim_->entry; |
198 state_ = READ; | 213 state_ = READ; |
199 found_entry_ = true; | 214 found_entry_ = true; |
| 215 RecordDiskCacheEntryState(DISK_CACHE_ENTRY_OPENED); |
200 } else { | 216 } else { |
201 state_ = WAIT_FOR_DATA_READY_DONE; | 217 state_ = WAIT_FOR_DATA_READY_DONE; |
202 } | 218 } |
203 | 219 |
204 return OK; | 220 return OK; |
205 } | 221 } |
206 | 222 |
207 int DiskCacheBasedQuicServerInfo::DoReadComplete(int rv) { | 223 int DiskCacheBasedQuicServerInfo::DoReadComplete(int rv) { |
208 if (rv > 0) | 224 if (rv > 0) |
209 data_.assign(read_buffer_->data(), rv); | 225 data_.assign(read_buffer_->data(), rv); |
210 | 226 |
211 state_ = WAIT_FOR_DATA_READY_DONE; | 227 state_ = WAIT_FOR_DATA_READY_DONE; |
212 return OK; | 228 return OK; |
213 } | 229 } |
214 | 230 |
215 int DiskCacheBasedQuicServerInfo::DoWriteComplete(int rv) { | 231 int DiskCacheBasedQuicServerInfo::DoWriteComplete(int rv) { |
216 // Keep the entry open for future writes. | 232 // Keep the entry open for future writes. |
217 new_data_.clear(); | 233 new_data_.clear(); |
218 state_ = NONE; | 234 state_ = NONE; |
219 return OK; | 235 return OK; |
220 } | 236 } |
221 | 237 |
222 int DiskCacheBasedQuicServerInfo::DoCreateOrOpenComplete(int rv) { | 238 int DiskCacheBasedQuicServerInfo::DoCreateOrOpenComplete(int rv) { |
223 if (rv != OK) { | 239 if (rv != OK) { |
224 state_ = SET_DONE; | 240 state_ = SET_DONE; |
225 } else { | 241 } else { |
226 if (!entry_) | 242 if (!entry_) { |
227 entry_ = data_shim_->entry; | 243 entry_ = data_shim_->entry; |
| 244 RecordDiskCacheEntryState(DISK_CACHE_ENTRY_OPENED); |
| 245 } |
| 246 DCHECK(entry_); |
228 state_ = WRITE; | 247 state_ = WRITE; |
229 } | 248 } |
230 return OK; | 249 return OK; |
231 } | 250 } |
232 | 251 |
233 int DiskCacheBasedQuicServerInfo::DoGetBackend() { | 252 int DiskCacheBasedQuicServerInfo::DoGetBackend() { |
234 state_ = GET_BACKEND_COMPLETE; | 253 state_ = GET_BACKEND_COMPLETE; |
235 return http_cache_->GetBackend(&data_shim_->backend, io_callback_); | 254 return http_cache_->GetBackend(&data_shim_->backend, io_callback_); |
236 } | 255 } |
237 | 256 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 | 296 |
278 return backend_->CreateEntry(key(), &data_shim_->entry, io_callback_); | 297 return backend_->CreateEntry(key(), &data_shim_->entry, io_callback_); |
279 } | 298 } |
280 | 299 |
281 int DiskCacheBasedQuicServerInfo::DoWaitForDataReadyDone() { | 300 int DiskCacheBasedQuicServerInfo::DoWaitForDataReadyDone() { |
282 DCHECK(!ready_); | 301 DCHECK(!ready_); |
283 state_ = NONE; | 302 state_ = NONE; |
284 ready_ = true; | 303 ready_ = true; |
285 // We close the entry because, if we shutdown before ::Persist is called, | 304 // We close the entry because, if we shutdown before ::Persist is called, |
286 // then we might leak a cache reference, which causes a DCHECK on shutdown. | 305 // then we might leak a cache reference, which causes a DCHECK on shutdown. |
287 if (entry_) | 306 if (entry_) { |
288 entry_->Close(); | 307 entry_->Close(); |
| 308 RecordDiskCacheEntryState(DISK_CACHE_ENTRY_CLOSED); |
| 309 } |
289 entry_ = NULL; | 310 entry_ = NULL; |
290 Parse(data_); | 311 Parse(data_); |
291 return OK; | 312 return OK; |
292 } | 313 } |
293 | 314 |
294 int DiskCacheBasedQuicServerInfo::DoSetDone() { | 315 int DiskCacheBasedQuicServerInfo::DoSetDone() { |
295 if (entry_) | 316 if (entry_) { |
296 entry_->Close(); | 317 entry_->Close(); |
| 318 RecordDiskCacheEntryState(DISK_CACHE_ENTRY_CLOSED); |
| 319 } |
297 entry_ = NULL; | 320 entry_ = NULL; |
298 new_data_.clear(); | 321 new_data_.clear(); |
299 state_ = NONE; | 322 state_ = NONE; |
300 return OK; | 323 return OK; |
301 } | 324 } |
302 | 325 |
303 } // namespace net | 326 } // namespace net |
OLD | NEW |