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 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 | 125 |
113 if (!backend_) | 126 if (!backend_) |
114 return; | 127 return; |
115 | 128 |
116 state_ = CREATE_OR_OPEN; | 129 state_ = CREATE_OR_OPEN; |
117 DoLoop(OK); | 130 DoLoop(OK); |
118 } | 131 } |
119 | 132 |
120 DiskCacheBasedQuicServerInfo::~DiskCacheBasedQuicServerInfo() { | 133 DiskCacheBasedQuicServerInfo::~DiskCacheBasedQuicServerInfo() { |
121 DCHECK(user_callback_.is_null()); | 134 DCHECK(user_callback_.is_null()); |
122 if (entry_) | 135 if (entry_) { |
123 entry_->Close(); | 136 entry_->Close(); |
| 137 RecordDiskCacheEntryState(DISK_CACHE_ENTRY_CLOSED); |
| 138 } |
124 } | 139 } |
125 | 140 |
126 std::string DiskCacheBasedQuicServerInfo::key() const { | 141 std::string DiskCacheBasedQuicServerInfo::key() const { |
127 return "quicserverinfo:" + server_id_.ToString(); | 142 return "quicserverinfo:" + server_id_.ToString(); |
128 } | 143 } |
129 | 144 |
130 void DiskCacheBasedQuicServerInfo::OnIOComplete(CacheOperationDataShim* unused, | 145 void DiskCacheBasedQuicServerInfo::OnIOComplete(CacheOperationDataShim* unused, |
131 int rv) { | 146 int rv) { |
132 DCHECK_NE(NONE, state_); | 147 DCHECK_NE(NONE, state_); |
133 rv = DoLoop(rv); | 148 rv = DoLoop(rv); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 state_ = WAIT_FOR_DATA_READY_DONE; | 209 state_ = WAIT_FOR_DATA_READY_DONE; |
195 } | 210 } |
196 return OK; | 211 return OK; |
197 } | 212 } |
198 | 213 |
199 int DiskCacheBasedQuicServerInfo::DoOpenComplete(int rv) { | 214 int DiskCacheBasedQuicServerInfo::DoOpenComplete(int rv) { |
200 if (rv == OK) { | 215 if (rv == OK) { |
201 entry_ = data_shim_->entry; | 216 entry_ = data_shim_->entry; |
202 state_ = READ; | 217 state_ = READ; |
203 found_entry_ = true; | 218 found_entry_ = true; |
| 219 RecordDiskCacheEntryState(DISK_CACHE_ENTRY_OPENED); |
204 } else { | 220 } else { |
205 state_ = WAIT_FOR_DATA_READY_DONE; | 221 state_ = WAIT_FOR_DATA_READY_DONE; |
206 } | 222 } |
207 | 223 |
208 return OK; | 224 return OK; |
209 } | 225 } |
210 | 226 |
211 int DiskCacheBasedQuicServerInfo::DoReadComplete(int rv) { | 227 int DiskCacheBasedQuicServerInfo::DoReadComplete(int rv) { |
212 if (rv > 0) | 228 if (rv > 0) |
213 data_.assign(read_buffer_->data(), rv); | 229 data_.assign(read_buffer_->data(), rv); |
214 | 230 |
215 state_ = WAIT_FOR_DATA_READY_DONE; | 231 state_ = WAIT_FOR_DATA_READY_DONE; |
216 return OK; | 232 return OK; |
217 } | 233 } |
218 | 234 |
219 int DiskCacheBasedQuicServerInfo::DoWriteComplete(int rv) { | 235 int DiskCacheBasedQuicServerInfo::DoWriteComplete(int rv) { |
220 state_ = SET_DONE; | 236 state_ = SET_DONE; |
221 return OK; | 237 return OK; |
222 } | 238 } |
223 | 239 |
224 int DiskCacheBasedQuicServerInfo::DoCreateOrOpenComplete(int rv) { | 240 int DiskCacheBasedQuicServerInfo::DoCreateOrOpenComplete(int rv) { |
225 if (rv != OK) { | 241 if (rv != OK) { |
226 state_ = SET_DONE; | 242 state_ = SET_DONE; |
227 } else { | 243 } else { |
228 if (!entry_) { | 244 if (!entry_) { |
229 entry_ = data_shim_->entry; | 245 entry_ = data_shim_->entry; |
230 found_entry_ = true; | 246 found_entry_ = true; |
| 247 RecordDiskCacheEntryState(DISK_CACHE_ENTRY_OPENED); |
231 } | 248 } |
232 DCHECK(entry_); | 249 DCHECK(entry_); |
233 state_ = WRITE; | 250 state_ = WRITE; |
234 } | 251 } |
235 return OK; | 252 return OK; |
236 } | 253 } |
237 | 254 |
238 int DiskCacheBasedQuicServerInfo::DoGetBackend() { | 255 int DiskCacheBasedQuicServerInfo::DoGetBackend() { |
239 state_ = GET_BACKEND_COMPLETE; | 256 state_ = GET_BACKEND_COMPLETE; |
240 return http_cache_->GetBackend(&data_shim_->backend, io_callback_); | 257 return http_cache_->GetBackend(&data_shim_->backend, io_callback_); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
282 | 299 |
283 return backend_->CreateEntry(key(), &data_shim_->entry, io_callback_); | 300 return backend_->CreateEntry(key(), &data_shim_->entry, io_callback_); |
284 } | 301 } |
285 | 302 |
286 int DiskCacheBasedQuicServerInfo::DoWaitForDataReadyDone() { | 303 int DiskCacheBasedQuicServerInfo::DoWaitForDataReadyDone() { |
287 DCHECK(!ready_); | 304 DCHECK(!ready_); |
288 state_ = NONE; | 305 state_ = NONE; |
289 ready_ = true; | 306 ready_ = true; |
290 // We close the entry because, if we shutdown before ::Persist is called, | 307 // We close the entry because, if we shutdown before ::Persist is called, |
291 // then we might leak a cache reference, which causes a DCHECK on shutdown. | 308 // then we might leak a cache reference, which causes a DCHECK on shutdown. |
292 if (entry_) | 309 if (entry_) { |
293 entry_->Close(); | 310 entry_->Close(); |
| 311 RecordDiskCacheEntryState(DISK_CACHE_ENTRY_CLOSED); |
| 312 } |
294 entry_ = NULL; | 313 entry_ = NULL; |
295 Parse(data_); | 314 Parse(data_); |
296 return OK; | 315 return OK; |
297 } | 316 } |
298 | 317 |
299 int DiskCacheBasedQuicServerInfo::DoSetDone() { | 318 int DiskCacheBasedQuicServerInfo::DoSetDone() { |
300 if (entry_) | 319 if (entry_) { |
301 entry_->Close(); | 320 entry_->Close(); |
| 321 RecordDiskCacheEntryState(DISK_CACHE_ENTRY_CLOSED); |
| 322 } |
302 entry_ = NULL; | 323 entry_ = NULL; |
303 new_data_.clear(); | 324 new_data_.clear(); |
304 state_ = NONE; | 325 state_ = NONE; |
305 return OK; | 326 return OK; |
306 } | 327 } |
307 | 328 |
308 } // namespace net | 329 } // namespace net |
OLD | NEW |