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

Side by Side Diff: net/http/disk_cache_based_quic_server_info.cc

Issue 693943003: Update from https://crrev.com/302630 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 6 years, 1 month 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 | « net/filter/filter_unittest.cc ('k') | net/http/http_cache_transaction.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "base/metrics/histogram.h"
11 #include "net/base/completion_callback.h" 11 #include "net/base/completion_callback.h"
12 #include "net/base/io_buffer.h" 12 #include "net/base/io_buffer.h"
13 #include "net/base/net_errors.h" 13 #include "net/base/net_errors.h"
14 #include "net/http/http_cache.h" 14 #include "net/http/http_cache.h"
15 #include "net/http/http_network_session.h" 15 #include "net/http/http_network_session.h"
16 #include "net/quic/quic_server_id.h" 16 #include "net/quic/quic_server_id.h"
17 17
18 namespace net { 18 namespace net {
19 19
20 // Histogram for tracking down the state of disk_cache::Entry. 20 // Histogram that tracks number of times data read/parse/write API calls of
21 enum DiskCacheEntryState { 21 // QuicServerInfo to and from disk cache is called.
22 DISK_CACHE_ENTRY_OPENED = 0, 22 enum QuicServerInfoAPICall {
23 DISK_CACHE_ENTRY_CLOSED = 1, 23 QUIC_SERVER_INFO_START = 0,
24 DISK_CACHE_ENTRY_NUM_STATES = 2, 24 QUIC_SERVER_INFO_WAIT_FOR_DATA_READY = 1,
25 QUIC_SERVER_INFO_PARSE = 2,
26 QUIC_SERVER_INFO_WAIT_FOR_DATA_READY_CANCEL = 3,
27 QUIC_SERVER_INFO_READY_TO_PERSIST = 4,
28 QUIC_SERVER_INFO_PERSIST = 5,
29 QUIC_SERVER_INFO_NUM_OF_API_CALLS = 6,
25 }; 30 };
26 31
27 void RecordDiskCacheEntryState(DiskCacheEntryState entry_state) { 32 // Histogram that tracks failure reasons to read/load/write of QuicServerInfo to
28 UMA_HISTOGRAM_ENUMERATION("Net.QuicDiskCache.EntryState", entry_state, 33 // and from disk cache.
29 DISK_CACHE_ENTRY_NUM_STATES); 34 enum FailureReason {
35 WAIT_FOR_DATA_READY_INVALID_ARGUMENT_FAILURE = 0,
36 GET_BACKEND_FAILURE = 1,
37 OPEN_FAILURE = 2,
38 CREATE_OR_OPEN_FAILURE = 3,
39 PARSE_NO_DATA_FAILURE = 4,
40 PARSE_FAILURE = 5,
41 READ_FAILURE = 6,
42 READY_TO_PERSIST_FAILURE = 7,
43 PERSIST_NO_BACKEND_FAILURE = 8,
44 WRITE_FAILURE = 9,
45 NUM_OF_FAILURES = 10,
46 };
47
48 void RecordQuicServerInfoStatus(QuicServerInfoAPICall call) {
49 UMA_HISTOGRAM_ENUMERATION("Net.QuicDiskCache.APICall", call,
50 QUIC_SERVER_INFO_NUM_OF_API_CALLS);
51 }
52
53 void RecordQuicServerInfoFailure(FailureReason failure) {
54 UMA_HISTOGRAM_ENUMERATION("Net.QuicDiskCache.FailureReason", failure,
55 NUM_OF_FAILURES);
30 } 56 }
31 57
32 // Some APIs inside disk_cache take a handle that the caller must keep alive 58 // Some APIs inside disk_cache take a handle that the caller must keep alive
33 // until the API has finished its asynchronous execution. 59 // until the API has finished its asynchronous execution.
34 // 60 //
35 // Unfortunately, DiskCacheBasedQuicServerInfo may be deleted before the 61 // Unfortunately, DiskCacheBasedQuicServerInfo may be deleted before the
36 // operation completes causing a use-after-free. 62 // operation completes causing a use-after-free.
37 // 63 //
38 // This data shim struct is meant to provide a location for the disk_cache 64 // This data shim struct is meant to provide a location for the disk_cache
39 // APIs to write into even if the originating DiskCacheBasedQuicServerInfo 65 // APIs to write into even if the originating DiskCacheBasedQuicServerInfo
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 weak_factory_(this) { 97 weak_factory_(this) {
72 io_callback_ = 98 io_callback_ =
73 base::Bind(&DiskCacheBasedQuicServerInfo::OnIOComplete, 99 base::Bind(&DiskCacheBasedQuicServerInfo::OnIOComplete,
74 weak_factory_.GetWeakPtr(), 100 weak_factory_.GetWeakPtr(),
75 base::Owned(data_shim_)); // Ownership assigned. 101 base::Owned(data_shim_)); // Ownership assigned.
76 } 102 }
77 103
78 void DiskCacheBasedQuicServerInfo::Start() { 104 void DiskCacheBasedQuicServerInfo::Start() {
79 DCHECK(CalledOnValidThread()); 105 DCHECK(CalledOnValidThread());
80 DCHECK_EQ(GET_BACKEND, state_); 106 DCHECK_EQ(GET_BACKEND, state_);
107 RecordQuicServerInfoStatus(QUIC_SERVER_INFO_START);
81 load_start_time_ = base::TimeTicks::Now(); 108 load_start_time_ = base::TimeTicks::Now();
82 DoLoop(OK); 109 DoLoop(OK);
83 } 110 }
84 111
85 int DiskCacheBasedQuicServerInfo::WaitForDataReady( 112 int DiskCacheBasedQuicServerInfo::WaitForDataReady(
86 const CompletionCallback& callback) { 113 const CompletionCallback& callback) {
87 DCHECK(CalledOnValidThread()); 114 DCHECK(CalledOnValidThread());
88 DCHECK_NE(GET_BACKEND, state_); 115 DCHECK_NE(GET_BACKEND, state_);
89 116
117 RecordQuicServerInfoStatus(QUIC_SERVER_INFO_WAIT_FOR_DATA_READY);
90 if (ready_) 118 if (ready_)
91 return OK; 119 return OK;
92 120
93 if (!callback.is_null()) { 121 if (!callback.is_null()) {
94 // Prevent a new callback for WaitForDataReady overwriting an existing 122 // Prevent a new callback for WaitForDataReady overwriting an existing
95 // pending callback (|user_callback_|). 123 // pending callback (|user_callback_|).
96 if (!user_callback_.is_null()) 124 if (!user_callback_.is_null()) {
125 RecordQuicServerInfoFailure(WAIT_FOR_DATA_READY_INVALID_ARGUMENT_FAILURE);
97 return ERR_INVALID_ARGUMENT; 126 return ERR_INVALID_ARGUMENT;
127 }
98 user_callback_ = callback; 128 user_callback_ = callback;
99 } 129 }
100 130
101 return ERR_IO_PENDING; 131 return ERR_IO_PENDING;
102 } 132 }
103 133
104 void DiskCacheBasedQuicServerInfo::CancelWaitForDataReadyCallback() { 134 void DiskCacheBasedQuicServerInfo::CancelWaitForDataReadyCallback() {
105 DCHECK(CalledOnValidThread()); 135 DCHECK(CalledOnValidThread());
106 136
137 RecordQuicServerInfoStatus(QUIC_SERVER_INFO_WAIT_FOR_DATA_READY_CANCEL);
107 if (!user_callback_.is_null()) 138 if (!user_callback_.is_null())
108 user_callback_.Reset(); 139 user_callback_.Reset();
109 } 140 }
110 141
111 bool DiskCacheBasedQuicServerInfo::IsDataReady() { 142 bool DiskCacheBasedQuicServerInfo::IsDataReady() {
112 return ready_; 143 return ready_;
113 } 144 }
114 145
115 bool DiskCacheBasedQuicServerInfo::IsReadyToPersist() { 146 bool DiskCacheBasedQuicServerInfo::IsReadyToPersist() {
116 // TODO(rtenneti): Handle updates while a write is pending. Change 147 // TODO(rtenneti): Handle updates while a write is pending. Change
117 // Persist() to save the data to be written into a temporary buffer 148 // Persist() to save the data to be written into a temporary buffer
118 // and then persist that data when we are ready to persist. 149 // and then persist that data when we are ready to persist.
119 // 150 //
120 // The data can be persisted if it has been loaded from the disk cache 151 // The data can be persisted if it has been loaded from the disk cache
121 // and there are no pending writes. 152 // and there are no pending writes.
122 return ready_ && new_data_.empty(); 153 RecordQuicServerInfoStatus(QUIC_SERVER_INFO_READY_TO_PERSIST);
154 if (ready_ && new_data_.empty())
155 return true;
156 RecordQuicServerInfoFailure(READY_TO_PERSIST_FAILURE);
157 return false;
123 } 158 }
124 159
125 void DiskCacheBasedQuicServerInfo::Persist() { 160 void DiskCacheBasedQuicServerInfo::Persist() {
126 DCHECK(CalledOnValidThread()); 161 DCHECK(CalledOnValidThread());
127 DCHECK_NE(GET_BACKEND, state_); 162 DCHECK_NE(GET_BACKEND, state_);
128 163
129 DCHECK(new_data_.empty()); 164 DCHECK(new_data_.empty());
130 CHECK(ready_); 165 CHECK(ready_);
131 DCHECK(user_callback_.is_null()); 166 DCHECK(user_callback_.is_null());
132 new_data_ = Serialize(); 167 new_data_ = Serialize();
133 168
134 if (!backend_) 169 RecordQuicServerInfoStatus(QUIC_SERVER_INFO_PERSIST);
170 if (!backend_) {
171 RecordQuicServerInfoFailure(PERSIST_NO_BACKEND_FAILURE);
135 return; 172 return;
173 }
136 174
137 state_ = CREATE_OR_OPEN; 175 state_ = CREATE_OR_OPEN;
138 DoLoop(OK); 176 DoLoop(OK);
139 } 177 }
140 178
141 DiskCacheBasedQuicServerInfo::~DiskCacheBasedQuicServerInfo() { 179 DiskCacheBasedQuicServerInfo::~DiskCacheBasedQuicServerInfo() {
142 DCHECK(user_callback_.is_null()); 180 DCHECK(user_callback_.is_null());
143 if (entry_) { 181 if (entry_)
144 entry_->Close(); 182 entry_->Close();
145 RecordDiskCacheEntryState(DISK_CACHE_ENTRY_CLOSED);
146 }
147 } 183 }
148 184
149 std::string DiskCacheBasedQuicServerInfo::key() const { 185 std::string DiskCacheBasedQuicServerInfo::key() const {
150 return "quicserverinfo:" + server_id_.ToString(); 186 return "quicserverinfo:" + server_id_.ToString();
151 } 187 }
152 188
153 void DiskCacheBasedQuicServerInfo::OnIOComplete(CacheOperationDataShim* unused, 189 void DiskCacheBasedQuicServerInfo::OnIOComplete(CacheOperationDataShim* unused,
154 int rv) { 190 int rv) {
155 DCHECK_NE(NONE, state_); 191 DCHECK_NE(NONE, state_);
156 rv = DoLoop(rv); 192 rv = DoLoop(rv);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 } while (rv != ERR_IO_PENDING && state_ != NONE); 243 } while (rv != ERR_IO_PENDING && state_ != NONE);
208 244
209 return rv; 245 return rv;
210 } 246 }
211 247
212 int DiskCacheBasedQuicServerInfo::DoGetBackendComplete(int rv) { 248 int DiskCacheBasedQuicServerInfo::DoGetBackendComplete(int rv) {
213 if (rv == OK) { 249 if (rv == OK) {
214 backend_ = data_shim_->backend; 250 backend_ = data_shim_->backend;
215 state_ = OPEN; 251 state_ = OPEN;
216 } else { 252 } else {
253 RecordQuicServerInfoFailure(GET_BACKEND_FAILURE);
217 state_ = WAIT_FOR_DATA_READY_DONE; 254 state_ = WAIT_FOR_DATA_READY_DONE;
218 } 255 }
219 return OK; 256 return OK;
220 } 257 }
221 258
222 int DiskCacheBasedQuicServerInfo::DoOpenComplete(int rv) { 259 int DiskCacheBasedQuicServerInfo::DoOpenComplete(int rv) {
223 if (rv == OK) { 260 if (rv == OK) {
224 entry_ = data_shim_->entry; 261 entry_ = data_shim_->entry;
225 state_ = READ; 262 state_ = READ;
226 found_entry_ = true; 263 found_entry_ = true;
227 RecordDiskCacheEntryState(DISK_CACHE_ENTRY_OPENED);
228 } else { 264 } else {
265 RecordQuicServerInfoFailure(OPEN_FAILURE);
229 state_ = WAIT_FOR_DATA_READY_DONE; 266 state_ = WAIT_FOR_DATA_READY_DONE;
230 } 267 }
231 268
232 return OK; 269 return OK;
233 } 270 }
234 271
235 int DiskCacheBasedQuicServerInfo::DoReadComplete(int rv) { 272 int DiskCacheBasedQuicServerInfo::DoReadComplete(int rv) {
236 if (rv > 0) 273 if (rv > 0)
237 data_.assign(read_buffer_->data(), rv); 274 data_.assign(read_buffer_->data(), rv);
275 else if (rv < 0)
276 RecordQuicServerInfoFailure(READ_FAILURE);
238 277
239 state_ = WAIT_FOR_DATA_READY_DONE; 278 state_ = WAIT_FOR_DATA_READY_DONE;
240 return OK; 279 return OK;
241 } 280 }
242 281
243 int DiskCacheBasedQuicServerInfo::DoWriteComplete(int rv) { 282 int DiskCacheBasedQuicServerInfo::DoWriteComplete(int rv) {
283 if (rv < 0)
284 RecordQuicServerInfoFailure(WRITE_FAILURE);
244 state_ = SET_DONE; 285 state_ = SET_DONE;
245 return OK; 286 return OK;
246 } 287 }
247 288
248 int DiskCacheBasedQuicServerInfo::DoCreateOrOpenComplete(int rv) { 289 int DiskCacheBasedQuicServerInfo::DoCreateOrOpenComplete(int rv) {
249 if (rv != OK) { 290 if (rv != OK) {
291 RecordQuicServerInfoFailure(CREATE_OR_OPEN_FAILURE);
250 state_ = SET_DONE; 292 state_ = SET_DONE;
251 } else { 293 } else {
252 if (!entry_) { 294 if (!entry_) {
253 entry_ = data_shim_->entry; 295 entry_ = data_shim_->entry;
254 found_entry_ = true; 296 found_entry_ = true;
255 RecordDiskCacheEntryState(DISK_CACHE_ENTRY_OPENED);
256 } 297 }
257 DCHECK(entry_); 298 DCHECK(entry_);
258 state_ = WRITE; 299 state_ = WRITE;
259 } 300 }
260 return OK; 301 return OK;
261 } 302 }
262 303
263 int DiskCacheBasedQuicServerInfo::DoGetBackend() { 304 int DiskCacheBasedQuicServerInfo::DoGetBackend() {
264 state_ = GET_BACKEND_COMPLETE; 305 state_ = GET_BACKEND_COMPLETE;
265 return http_cache_->GetBackend(&data_shim_->backend, io_callback_); 306 return http_cache_->GetBackend(&data_shim_->backend, io_callback_);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 348
308 return backend_->CreateEntry(key(), &data_shim_->entry, io_callback_); 349 return backend_->CreateEntry(key(), &data_shim_->entry, io_callback_);
309 } 350 }
310 351
311 int DiskCacheBasedQuicServerInfo::DoWaitForDataReadyDone() { 352 int DiskCacheBasedQuicServerInfo::DoWaitForDataReadyDone() {
312 DCHECK(!ready_); 353 DCHECK(!ready_);
313 state_ = NONE; 354 state_ = NONE;
314 ready_ = true; 355 ready_ = true;
315 // We close the entry because, if we shutdown before ::Persist is called, 356 // We close the entry because, if we shutdown before ::Persist is called,
316 // then we might leak a cache reference, which causes a DCHECK on shutdown. 357 // then we might leak a cache reference, which causes a DCHECK on shutdown.
317 if (entry_) { 358 if (entry_)
318 entry_->Close(); 359 entry_->Close();
319 RecordDiskCacheEntryState(DISK_CACHE_ENTRY_CLOSED); 360 entry_ = NULL;
361
362 RecordQuicServerInfoStatus(QUIC_SERVER_INFO_PARSE);
363 if (!Parse(data_)) {
364 if (data_.empty())
365 RecordQuicServerInfoFailure(PARSE_NO_DATA_FAILURE);
366 else
367 RecordQuicServerInfoFailure(PARSE_FAILURE);
320 } 368 }
321 entry_ = NULL; 369
322 Parse(data_);
323 UMA_HISTOGRAM_TIMES("Net.QuicServerInfo.DiskCacheLoadTime", 370 UMA_HISTOGRAM_TIMES("Net.QuicServerInfo.DiskCacheLoadTime",
324 base::TimeTicks::Now() - load_start_time_); 371 base::TimeTicks::Now() - load_start_time_);
325 return OK; 372 return OK;
326 } 373 }
327 374
328 int DiskCacheBasedQuicServerInfo::DoSetDone() { 375 int DiskCacheBasedQuicServerInfo::DoSetDone() {
329 if (entry_) { 376 if (entry_)
330 entry_->Close(); 377 entry_->Close();
331 RecordDiskCacheEntryState(DISK_CACHE_ENTRY_CLOSED);
332 }
333 entry_ = NULL; 378 entry_ = NULL;
334 new_data_.clear(); 379 new_data_.clear();
335 state_ = NONE; 380 state_ = NONE;
336 return OK; 381 return OK;
337 } 382 }
338 383
339 } // namespace net 384 } // namespace net
OLDNEW
« no previous file with comments | « net/filter/filter_unittest.cc ('k') | net/http/http_cache_transaction.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698