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

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

Issue 2519473002: Fixes the cache lock issue. (Closed)
Patch Set: Test only change to fix a memory leak. Created 3 years, 10 months 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
OLDNEW
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>
11 #endif 11 #endif
12 12
13 #include <algorithm> 13 #include <algorithm>
14 #include <limits>
14 #include <string> 15 #include <string>
16 #include <utility>
15 17
16 #include "base/bind.h" 18 #include "base/bind.h"
17 #include "base/callback_helpers.h" 19 #include "base/callback_helpers.h"
18 #include "base/compiler_specific.h" 20 #include "base/compiler_specific.h"
19 #include "base/format_macros.h" 21 #include "base/format_macros.h"
20 #include "base/location.h" 22 #include "base/location.h"
21 #include "base/macros.h" 23 #include "base/macros.h"
22 #include "base/metrics/histogram_macros.h" 24 #include "base/metrics/histogram_macros.h"
23 #include "base/metrics/sparse_histogram.h" 25 #include "base/metrics/sparse_histogram.h"
24 #include "base/single_thread_task_runner.h" 26 #include "base/single_thread_task_runner.h"
25 #include "base/strings/string_number_conversions.h" // For HexEncode. 27 #include "base/strings/string_number_conversions.h" // For HexEncode.
26 #include "base/strings/string_piece.h" 28 #include "base/strings/string_piece.h"
27 #include "base/strings/string_util.h" // For LowerCaseEqualsASCII. 29 #include "base/strings/string_util.h" // For LowerCaseEqualsASCII.
28 #include "base/strings/stringprintf.h" 30 #include "base/strings/stringprintf.h"
29 #include "base/threading/thread_task_runner_handle.h" 31 #include "base/threading/thread_task_runner_handle.h"
30 #include "base/time/clock.h" 32 #include "base/time/clock.h"
31 #include "base/trace_event/trace_event.h" 33 #include "base/trace_event/trace_event.h"
32 #include "base/values.h" 34 #include "base/values.h"
33 #include "net/base/auth.h" 35 #include "net/base/auth.h"
34 #include "net/base/load_flags.h" 36 #include "net/base/load_flags.h"
35 #include "net/base/load_timing_info.h" 37 #include "net/base/load_timing_info.h"
36 #include "net/base/trace_constants.h" 38 #include "net/base/trace_constants.h"
37 #include "net/base/upload_data_stream.h" 39 #include "net/base/upload_data_stream.h"
38 #include "net/cert/cert_status_flags.h" 40 #include "net/cert/cert_status_flags.h"
39 #include "net/cert/x509_certificate.h" 41 #include "net/cert/x509_certificate.h"
40 #include "net/disk_cache/disk_cache.h" 42 #include "net/disk_cache/disk_cache.h"
43 #include "net/http/http_cache_shared_writers.h"
41 #include "net/http/http_network_session.h" 44 #include "net/http/http_network_session.h"
42 #include "net/http/http_request_info.h" 45 #include "net/http/http_request_info.h"
43 #include "net/http/http_util.h" 46 #include "net/http/http_util.h"
44 #include "net/log/net_log_event_type.h" 47 #include "net/log/net_log_event_type.h"
45 #include "net/ssl/ssl_cert_request_info.h" 48 #include "net/ssl/ssl_cert_request_info.h"
46 #include "net/ssl/ssl_config_service.h" 49 #include "net/ssl/ssl_config_service.h"
47 50
48 using base::Time; 51 using base::Time;
49 using base::TimeDelta; 52 using base::TimeDelta;
50 using base::TimeTicks; 53 using base::TimeTicks;
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 truncated_(false), 177 truncated_(false),
175 is_sparse_(false), 178 is_sparse_(false),
176 range_requested_(false), 179 range_requested_(false),
177 handling_206_(false), 180 handling_206_(false),
178 cache_pending_(false), 181 cache_pending_(false),
179 done_reading_(false), 182 done_reading_(false),
180 vary_mismatch_(false), 183 vary_mismatch_(false),
181 couldnt_conditionalize_request_(false), 184 couldnt_conditionalize_request_(false),
182 bypass_lock_for_test_(false), 185 bypass_lock_for_test_(false),
183 fail_conditionalization_for_test_(false), 186 fail_conditionalization_for_test_(false),
187 shared_(false),
188 initiate_shared_writing_(false),
189 shared_read_write_failure_result_(0),
184 io_buf_len_(0), 190 io_buf_len_(0),
185 read_offset_(0), 191 read_offset_(0),
186 effective_load_flags_(0), 192 effective_load_flags_(0),
187 write_len_(0), 193 write_len_(0),
188 cache_entry_status_(CacheEntryStatus::ENTRY_UNDEFINED), 194 cache_entry_status_(CacheEntryStatus::ENTRY_UNDEFINED),
189 validation_cause_(VALIDATION_CAUSE_UNDEFINED), 195 validation_cause_(VALIDATION_CAUSE_UNDEFINED),
190 total_received_bytes_(0), 196 total_received_bytes_(0),
191 total_sent_bytes_(0), 197 total_sent_bytes_(0),
192 websocket_handshake_stream_base_create_helper_(NULL), 198 websocket_handshake_stream_base_create_helper_(NULL),
199 have_full_request_headers_(false),
193 weak_factory_(this) { 200 weak_factory_(this) {
194 TRACE_EVENT0("io", "HttpCacheTransaction::Transaction"); 201 TRACE_EVENT0("io", "HttpCacheTransaction::Transaction");
195 static_assert(HttpCache::Transaction::kNumValidationHeaders == 202 static_assert(HttpCache::Transaction::kNumValidationHeaders ==
196 arraysize(kValidationHeaders), 203 arraysize(kValidationHeaders),
197 "invalid number of validation headers"); 204 "invalid number of validation headers");
198 205
199 io_callback_ = base::Bind(&Transaction::OnIOComplete, 206 io_callback_ = base::Bind(&Transaction::OnIOComplete,
200 weak_factory_.GetWeakPtr()); 207 weak_factory_.GetWeakPtr());
201 } 208 }
202 209
203 HttpCache::Transaction::~Transaction() { 210 HttpCache::Transaction::~Transaction() {
204 TRACE_EVENT0("io", "HttpCacheTransaction::~Transaction"); 211 TRACE_EVENT0("io", "HttpCacheTransaction::~Transaction");
212
205 // We may have to issue another IO, but we should never invoke the callback_ 213 // We may have to issue another IO, but we should never invoke the callback_
206 // after this point. 214 // after this point.
207 callback_.Reset(); 215 callback_.Reset();
208 216
217 if (shared_) {
218 // Remove transaction from shared writers and do any cleanup, if needed, for
219 // entry_->shared_writers and entry_.
220 RemoveTransactionFromSharedWriters();
221 }
222
209 if (cache_) { 223 if (cache_) {
210 if (entry_) { 224 if (entry_) {
211 bool cancel_request = reading_ && response_.headers.get(); 225 bool cancel_request = reading_ && response_.headers.get();
212 if (cancel_request) { 226 if (cancel_request) {
213 if (partial_) { 227 if (partial_) {
214 entry_->disk_entry->CancelSparseIO(); 228 entry_->disk_entry->CancelSparseIO();
215 } else { 229 } else {
216 cancel_request &= (response_.headers->response_code() == 200); 230 cancel_request &= (response_.headers->response_code() == 200);
217 } 231 }
218 } 232 }
219
220 cache_->DoneWithEntry(entry_, this, cancel_request); 233 cache_->DoneWithEntry(entry_, this, cancel_request);
221 } else if (cache_pending_) { 234 } else if (cache_pending_) {
222 cache_->RemovePendingTransaction(this); 235 cache_->RemovePendingTransaction(this);
223 } 236 }
224 } 237 }
225 } 238 }
226 239
240 void HttpCache::Transaction::RemoveTransactionFromSharedWriters() {
241 // Current shared network transaction's consumer.
242 if (next_state_ == STATE_SHARED_NETWORK_READ_COMPLETE ||
243 next_state_ == STATE_SHARED_CACHE_WRITE_DATA_COMPLETE) {
244 entry_->shared_writers->RemoveActiveTransaction(this);
245 } else if (next_state_ == STATE_SHARED_NETWORK_READ_WAIT_COMPLETE) {
246 // Waiting on Read() operation to be completed by another
247 // transaction.
248 entry_->shared_writers->RemoveWaitingForReadTransaction(this);
249 } else if (next_state_ != STATE_NONE &&
250 next_state_ <= STATE_ADD_TO_ENTRY_COMPLETE) {
251 // Pending transaction not yet added to an entry, so entry_ is null, let
252 // cache_ handle the deletion.
253 cache_->RemovePendingTransaction(this);
254 // Set cache_pending_ to false so that more cleanup is not attempted in
255 // the destructor.
256 cache_pending_ = false;
257 } else if (validating_shared()) {
258 entry_->shared_writers->RemoveValidatingTransaction(this);
259 } else {
260 entry_->shared_writers->RemoveIdleTransaction(this);
261 }
262
263 DCHECK(!shared_);
264
265 // Since any cleanup needed in entry_ and shared_writers is already done,
266 // set entry_ to null.
267 entry_ = nullptr;
268 }
269
227 int HttpCache::Transaction::WriteMetadata(IOBuffer* buf, int buf_len, 270 int HttpCache::Transaction::WriteMetadata(IOBuffer* buf, int buf_len,
228 const CompletionCallback& callback) { 271 const CompletionCallback& callback) {
229 DCHECK(buf); 272 DCHECK(buf);
230 DCHECK_GT(buf_len, 0); 273 DCHECK_GT(buf_len, 0);
231 DCHECK(!callback.is_null()); 274 DCHECK(!callback.is_null());
232 if (!cache_.get() || !entry_) 275 if (!cache_.get() || !entry_)
233 return ERR_UNEXPECTED; 276 return ERR_UNEXPECTED;
234 277
235 // We don't need to track this operation for anything. 278 // We don't need to track this operation for anything.
236 // It could be possible to check if there is something already written and 279 // It could be possible to check if there is something already written and
237 // avoid writing again (it should be the same, right?), but let's allow the 280 // avoid writing again (it should be the same, right?), but let's allow the
238 // caller to "update" the contents with something new. 281 // caller to "update" the contents with something new.
239 return entry_->disk_entry->WriteData(kMetadataIndex, 0, buf, buf_len, 282 return entry_->disk_entry->WriteData(kMetadataIndex, 0, buf, buf_len,
240 callback, true); 283 callback, true);
241 } 284 }
242 285
243 bool HttpCache::Transaction::AddTruncatedFlag() { 286 bool HttpCache::Transaction::AddTruncatedFlag() {
244 DCHECK(mode_ & WRITE || mode_ == NONE); 287 DCHECK(mode_ & WRITE || mode_ == NONE);
245 288
246 // Don't set the flag for sparse entries. 289 // Don't set the flag for sparse entries.
247 if (partial_ && !truncated_) 290 if (partial_ && !truncated_)
248 return true; 291 return true;
249 292
250 if (!CanResume(true)) 293 if (!cache_->CanResumeEntry(true, request_->method, &response_, entry_))
251 return false; 294 return false;
252 295
253 // We may have received the whole resource already. 296 // We may have received the whole resource already.
254 if (done_reading_) 297 if (done_reading_)
255 return true; 298 return true;
256 299
257 truncated_ = true; 300 truncated_ = true;
258 next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE; 301 next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE;
259 DoLoop(OK); 302 DoLoop(OK);
260 return true; 303 return true;
261 } 304 }
262 305
263 LoadState HttpCache::Transaction::GetWriterLoadState() const { 306 LoadState HttpCache::Transaction::GetWriterLoadState() const {
264 if (network_trans_.get()) 307 HttpTransaction* network_transaction = GetCurrentNetworkTransaction();
265 return network_trans_->GetLoadState(); 308 if (network_transaction)
309 return network_transaction->GetLoadState();
266 if (entry_ || !request_) 310 if (entry_ || !request_)
267 return LOAD_STATE_IDLE; 311 return LOAD_STATE_IDLE;
268 return LOAD_STATE_WAITING_FOR_CACHE; 312 return LOAD_STATE_WAITING_FOR_CACHE;
269 } 313 }
270 314
271 const NetLogWithSource& HttpCache::Transaction::net_log() const { 315 const NetLogWithSource& HttpCache::Transaction::net_log() const {
272 return net_log_; 316 return net_log_;
273 } 317 }
274 318
275 int HttpCache::Transaction::Start(const HttpRequestInfo* request, 319 int HttpCache::Transaction::Start(const HttpRequestInfo* request,
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 } 409 }
366 410
367 bool HttpCache::Transaction::IsReadyToRestartForAuth() { 411 bool HttpCache::Transaction::IsReadyToRestartForAuth() {
368 if (!network_trans_.get()) 412 if (!network_trans_.get())
369 return false; 413 return false;
370 return network_trans_->IsReadyToRestartForAuth(); 414 return network_trans_->IsReadyToRestartForAuth();
371 } 415 }
372 416
373 int HttpCache::Transaction::Read(IOBuffer* buf, int buf_len, 417 int HttpCache::Transaction::Read(IOBuffer* buf, int buf_len,
374 const CompletionCallback& callback) { 418 const CompletionCallback& callback) {
419 if (next_state_ == STATE_SHARED_READ_WRITE_FAILED) {
420 if (net_log_.IsCapturing())
421 net_log_.EndEventWithNetErrorCode(
422 NetLogEventType::HTTP_CACHE_SHARED_READ_WRITE_FAILED,
423 shared_read_write_failure_result_);
424
425 return shared_read_write_failure_result_;
426 }
427
375 DCHECK_EQ(next_state_, STATE_NONE); 428 DCHECK_EQ(next_state_, STATE_NONE);
376 DCHECK(buf); 429 DCHECK(buf);
377 DCHECK_GT(buf_len, 0); 430 DCHECK_GT(buf_len, 0);
378 DCHECK(!callback.is_null()); 431 DCHECK(!callback.is_null());
379 432
380 DCHECK(callback_.is_null()); 433 DCHECK(callback_.is_null());
381 434
382 if (!cache_.get()) 435 if (!cache_.get())
383 return ERR_UNEXPECTED; 436 return ERR_UNEXPECTED;
384 437
385 // If we have an intermediate auth response at this point, then it means the 438 // If we have an intermediate auth response at this point, then it means the
386 // user wishes to read the network response (the error page). If there is a 439 // user wishes to read the network response (the error page). If there is a
387 // previous response in the cache then we should leave it intact. 440 // previous response in the cache then we should leave it intact.
388 if (auth_response_.headers.get() && mode_ != NONE) { 441 if (auth_response_.headers.get() && mode_ != NONE) {
389 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER); 442 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER);
390 DCHECK(mode_ & WRITE); 443 DCHECK(mode_ & WRITE);
391 DoneWritingToEntry(mode_ == READ_WRITE); 444 DoneWritingToEntry(mode_ == READ_WRITE);
392 mode_ = NONE; 445 mode_ = NONE;
393 } 446 }
394 447
395 reading_ = true; 448 reading_ = true;
396 read_buf_ = buf; 449 read_buf_ = buf;
397 io_buf_len_ = buf_len; 450 io_buf_len_ = buf_len;
398 if (network_trans_) { 451
399 DCHECK(mode_ == WRITE || mode_ == NONE || 452 if (shared_) {
400 (mode_ == READ_WRITE && partial_)); 453 int disk_entry_size =
401 next_state_ = STATE_NETWORK_READ; 454 entry_->disk_entry->GetDataSize(kResponseContentIndex);
402 } else { 455 if (read_offset_ == disk_entry_size) {
403 DCHECK(mode_ == READ || (mode_ == READ_WRITE && partial_)); 456 next_state_ = STATE_SHARED_NETWORK_READ;
404 next_state_ = STATE_CACHE_READ_DATA; 457 } else {
458 DCHECK_LT(read_offset_, disk_entry_size);
459 next_state_ = STATE_CACHE_READ_DATA;
460 }
461 } else { // not shared.
462 if (network_trans_) {
463 DCHECK(mode_ == WRITE || mode_ == NONE ||
464 (mode_ == READ_WRITE && partial_));
465 next_state_ = STATE_NETWORK_READ;
466 } else { // read-only
467 DCHECK(mode_ == READ || (mode_ == READ_WRITE && partial_));
468 next_state_ = STATE_CACHE_READ_DATA;
469 }
405 } 470 }
406 471
407 int rv = DoLoop(OK); 472 int rv = DoLoop(OK);
408 473
409 if (rv == ERR_IO_PENDING) { 474 if (rv == ERR_IO_PENDING) {
410 DCHECK(callback_.is_null()); 475 DCHECK(callback_.is_null());
411 callback_ = callback; 476 callback_ = callback;
412 } 477 }
413 return rv; 478 return rv;
414 } 479 }
415 480
416 void HttpCache::Transaction::StopCaching() { 481 void HttpCache::Transaction::StopCaching() {
417 // We really don't know where we are now. Hopefully there is no operation in 482 // We really don't know where we are now. Hopefully there is no operation in
418 // progress, but nothing really prevents this method to be called after we 483 // progress, but nothing really prevents this method to be called after we
419 // returned ERR_IO_PENDING. We cannot attempt to truncate the entry at this 484 // returned ERR_IO_PENDING. We cannot attempt to truncate the entry at this
420 // point because we need the state machine for that (and even if we are really 485 // point because we need the state machine for that (and even if we are really
421 // free, that would be an asynchronous operation). In other words, keep the 486 // free, that would be an asynchronous operation). In other words, keep the
422 // entry how it is (it will be marked as truncated at destruction), and let 487 // entry how it is (it will be marked as truncated at destruction), and let
423 // the next piece of code that executes know that we are now reading directly 488 // the next piece of code that executes know that we are now reading directly
424 // from the net. 489 // from the net.
425 // TODO(mmenke): This doesn't release the lock on the cache entry, so a 490 // TODO(mmenke): This doesn't release the lock on the cache entry, so a
426 // future request for the resource will be blocked on this one. 491 // future request for the resource will be blocked on this one.
427 // Fix this. 492 // Fix this.
428 if (cache_.get() && entry_ && (mode_ & WRITE) && network_trans_.get() && 493 if (shared_) {
429 !is_sparse_ && !range_requested_) { 494 // This might or might not stop caching based on whether other consumers
495 // exist for this resource or not. If it does, shared_ will be set to false.
496 entry_->shared_writers->StopCaching(this);
497 }
498 if (!shared_ && cache_.get() && entry_ && (mode_ & WRITE) &&
499 network_trans_.get() && !is_sparse_ && !range_requested_) {
430 mode_ = NONE; 500 mode_ = NONE;
431 } 501 }
432 } 502 }
433 503
434 bool HttpCache::Transaction::GetFullRequestHeaders( 504 bool HttpCache::Transaction::GetFullRequestHeaders(
435 HttpRequestHeaders* headers) const { 505 HttpRequestHeaders* headers) const {
436 if (network_trans_) 506 HttpTransaction* network_transaction = GetCurrentNetworkTransaction();
437 return network_trans_->GetFullRequestHeaders(headers); 507 if (network_transaction) {
438 508 return network_transaction->GetFullRequestHeaders(headers);
509 } else if (have_full_request_headers_) {
510 *headers = full_request_headers_;
511 return true;
512 }
439 // TODO(juliatuttle): Read headers from cache. 513 // TODO(juliatuttle): Read headers from cache.
440 return false; 514 return false;
441 } 515 }
442 516
443 int64_t HttpCache::Transaction::GetTotalReceivedBytes() const { 517 int64_t HttpCache::Transaction::GetTotalReceivedBytes() const {
444 int64_t total_received_bytes = total_received_bytes_; 518 int64_t total_received_bytes = total_received_bytes_;
445 if (network_trans_) 519 HttpTransaction* network_transaction = GetCurrentNetworkTransaction();
446 total_received_bytes += network_trans_->GetTotalReceivedBytes(); 520 if (network_transaction)
521 total_received_bytes += network_transaction->GetTotalReceivedBytes();
447 return total_received_bytes; 522 return total_received_bytes;
448 } 523 }
449 524
450 int64_t HttpCache::Transaction::GetTotalSentBytes() const { 525 int64_t HttpCache::Transaction::GetTotalSentBytes() const {
451 int64_t total_sent_bytes = total_sent_bytes_; 526 int64_t total_sent_bytes = total_sent_bytes_;
452 if (network_trans_) 527 HttpTransaction* network_transaction = GetCurrentNetworkTransaction();
453 total_sent_bytes += network_trans_->GetTotalSentBytes(); 528 if (network_transaction)
529 total_sent_bytes += network_transaction->GetTotalSentBytes();
454 return total_sent_bytes; 530 return total_sent_bytes;
455 } 531 }
456 532
457 void HttpCache::Transaction::DoneReading() { 533 void HttpCache::Transaction::DoneReading() {
458 if (cache_.get() && entry_) { 534 if (cache_.get() && entry_) {
459 DCHECK_NE(mode_, UPDATE); 535 DCHECK_NE(mode_, UPDATE);
536 bool perform_entry_cleanup = true;
537 if (shared_) {
538 entry_->shared_writers->DoneReading(this);
539
540 // shared_ should have been set to false.
541 DCHECK(!shared_);
542
543 DoneWritingToEntry(true, false);
544 return;
545 }
546
460 if (mode_ & WRITE) { 547 if (mode_ & WRITE) {
461 DoneWritingToEntry(true); 548 DoneWritingToEntry(true, perform_entry_cleanup);
462 } else if (mode_ & READ) { 549 } else if (mode_ & READ) {
463 // It is necessary to check mode_ & READ because it is possible 550 // It is necessary to check mode_ & READ because it is possible
464 // for mode_ to be NONE and entry_ non-NULL with a write entry 551 // for mode_ to be NONE and entry_ non-NULL with a write entry
465 // if StopCaching was called. 552 // if StopCaching was called.
466 cache_->DoneReadingFromEntry(entry_, this); 553 cache_->DoneReadingFromEntry(entry_, this);
467 entry_ = NULL; 554 entry_ = NULL;
468 } 555 }
469 } 556 }
470 } 557 }
471 558
(...skipping 18 matching lines...) Expand all
490 return cache_->GetLoadStateForPendingTransaction(this); 577 return cache_->GetLoadStateForPendingTransaction(this);
491 578
492 return LOAD_STATE_IDLE; 579 return LOAD_STATE_IDLE;
493 } 580 }
494 581
495 void HttpCache::Transaction::SetQuicServerInfo( 582 void HttpCache::Transaction::SetQuicServerInfo(
496 QuicServerInfo* quic_server_info) {} 583 QuicServerInfo* quic_server_info) {}
497 584
498 bool HttpCache::Transaction::GetLoadTimingInfo( 585 bool HttpCache::Transaction::GetLoadTimingInfo(
499 LoadTimingInfo* load_timing_info) const { 586 LoadTimingInfo* load_timing_info) const {
500 if (network_trans_) 587 HttpTransaction* network_transaction = GetCurrentNetworkTransaction();
501 return network_trans_->GetLoadTimingInfo(load_timing_info); 588 if (network_transaction)
589 return network_transaction->GetLoadTimingInfo(load_timing_info);
502 590
503 if (old_network_trans_load_timing_) { 591 if (old_network_trans_load_timing_) {
504 *load_timing_info = *old_network_trans_load_timing_; 592 *load_timing_info = *old_network_trans_load_timing_;
505 return true; 593 return true;
506 } 594 }
507 595
508 if (first_cache_access_since_.is_null()) 596 if (first_cache_access_since_.is_null())
509 return false; 597 return false;
510 598
511 // If the cache entry was opened, return that time. 599 // If the cache entry was opened, return that time.
512 load_timing_info->send_start = first_cache_access_since_; 600 load_timing_info->send_start = first_cache_access_since_;
513 // This time doesn't make much sense when reading from the cache, so just use 601 // This time doesn't make much sense when reading from the cache, so just use
514 // the same time as send_start. 602 // the same time as send_start.
515 load_timing_info->send_end = first_cache_access_since_; 603 load_timing_info->send_end = first_cache_access_since_;
516 return true; 604 return true;
517 } 605 }
518 606
519 bool HttpCache::Transaction::GetRemoteEndpoint(IPEndPoint* endpoint) const { 607 bool HttpCache::Transaction::GetRemoteEndpoint(IPEndPoint* endpoint) const {
520 if (network_trans_) 608 HttpTransaction* network_transaction = GetCurrentNetworkTransaction();
521 return network_trans_->GetRemoteEndpoint(endpoint); 609 if (network_transaction)
610 return network_transaction->GetRemoteEndpoint(endpoint);
522 611
523 if (!old_remote_endpoint_.address().empty()) { 612 if (!old_remote_endpoint_.address().empty()) {
524 *endpoint = old_remote_endpoint_; 613 *endpoint = old_remote_endpoint_;
525 return true; 614 return true;
526 } 615 }
527 616
528 return false; 617 return false;
529 } 618 }
530 619
531 void HttpCache::Transaction::PopulateNetErrorDetails( 620 void HttpCache::Transaction::PopulateNetErrorDetails(
532 NetErrorDetails* details) const { 621 NetErrorDetails* details) const {
533 if (network_trans_) 622 HttpTransaction* network_transaction = GetCurrentNetworkTransaction();
534 return network_trans_->PopulateNetErrorDetails(details); 623 if (network_transaction)
624 network_transaction->PopulateNetErrorDetails(details);
535 return; 625 return;
536 } 626 }
537 627
538 void HttpCache::Transaction::SetPriority(RequestPriority priority) { 628 void HttpCache::Transaction::SetPriority(RequestPriority priority) {
539 priority_ = priority; 629 priority_ = priority;
540 if (network_trans_) 630 if (network_trans_)
541 network_trans_->SetPriority(priority_); 631 network_trans_->SetPriority(priority_);
632 else if (shared_ && entry_ && entry_->shared_writers)
633 entry_->shared_writers->PriorityChanged();
542 } 634 }
543 635
544 void HttpCache::Transaction::SetWebSocketHandshakeStreamCreateHelper( 636 void HttpCache::Transaction::SetWebSocketHandshakeStreamCreateHelper(
545 WebSocketHandshakeStreamBase::CreateHelper* create_helper) { 637 WebSocketHandshakeStreamBase::CreateHelper* create_helper) {
546 websocket_handshake_stream_base_create_helper_ = create_helper; 638 websocket_handshake_stream_base_create_helper_ = create_helper;
547 if (network_trans_) 639 if (network_trans_)
548 network_trans_->SetWebSocketHandshakeStreamCreateHelper(create_helper); 640 network_trans_->SetWebSocketHandshakeStreamCreateHelper(create_helper);
549 } 641 }
550 642
551 void HttpCache::Transaction::SetBeforeNetworkStartCallback( 643 void HttpCache::Transaction::SetBeforeNetworkStartCallback(
(...skipping 10 matching lines...) Expand all
562 654
563 int HttpCache::Transaction::ResumeNetworkStart() { 655 int HttpCache::Transaction::ResumeNetworkStart() {
564 if (network_trans_) 656 if (network_trans_)
565 return network_trans_->ResumeNetworkStart(); 657 return network_trans_->ResumeNetworkStart();
566 return ERR_UNEXPECTED; 658 return ERR_UNEXPECTED;
567 } 659 }
568 660
569 void HttpCache::Transaction::GetConnectionAttempts( 661 void HttpCache::Transaction::GetConnectionAttempts(
570 ConnectionAttempts* out) const { 662 ConnectionAttempts* out) const {
571 ConnectionAttempts new_connection_attempts; 663 ConnectionAttempts new_connection_attempts;
572 if (network_trans_) 664 HttpTransaction* network_transaction = GetCurrentNetworkTransaction();
573 network_trans_->GetConnectionAttempts(&new_connection_attempts); 665 if (network_transaction)
666 network_transaction->GetConnectionAttempts(&new_connection_attempts);
574 667
575 out->swap(new_connection_attempts); 668 out->swap(new_connection_attempts);
576 out->insert(out->begin(), old_connection_attempts_.begin(), 669 out->insert(out->begin(), old_connection_attempts_.begin(),
577 old_connection_attempts_.end()); 670 old_connection_attempts_.end());
578 } 671 }
579 672
580 //----------------------------------------------------------------------------- 673 //-----------------------------------------------------------------------------
581 674
582 // A few common patterns: (Foo* means Foo -> FooComplete) 675 // A few common patterns: (Foo* means Foo -> FooComplete)
583 // 676 //
584 // 1. Not-cached entry: 677 // 1. Not-cached entry:
585 // Start(): 678 // Start():
586 // GetBackend* -> InitEntry -> OpenEntry* -> CreateEntry* -> AddToEntry* -> 679 // GetBackend* -> InitEntry -> OpenEntry* -> CreateEntry* -> AddToEntry* ->
587 // SendRequest* -> SuccessfulSendRequest -> OverwriteCachedResponse -> 680 // SendRequest* -> SuccessfulSendRequest -> OverwriteCachedResponse ->
588 // CacheWriteResponse* -> TruncateCachedData* -> TruncateCachedMetadata* -> 681 // CacheWriteResponse* -> TruncateCachedData* -> TruncateCachedMetadata* ->
589 // PartialHeadersReceived 682 // PartialHeadersReceived
590 // 683 //
591 // Read(): 684 // Read(): (For transactions that are not eligible for shared writing)
592 // NetworkRead* -> CacheWriteData* 685 // NetworkRead* -> CacheWriteData*
593 // 686 //
687 // Read(): (For transactions that are eligible for shared writing)
688 // SharedNetworkRead* -> SharedCacheWriteData*
689 //
690 // Read(): (For a transaction that is shared and another read is already in
691 // progress)
692 // SharedNetworkRead -> SharedNetworkReadWaitComplete
693 //
594 // 2. Cached entry, no validation: 694 // 2. Cached entry, no validation:
595 // Start(): 695 // Start():
596 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* 696 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse*
597 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> 697 // -> CacheDispatchValidation -> BeginPartialCacheValidation() ->
598 // BeginCacheValidation() -> SetupEntryForRead() 698 // BeginCacheValidation() -> SetupEntryForRead()
599 // 699 //
600 // Read(): 700 // Read(): (When response is already written to the cache.)
601 // CacheReadData* 701 // CacheReadData*
602 // 702 //
703 // Read(): (When response is currently being written to the cache by shared
704 // writing.)
705 // SharedNetworkRead* -> SharedCacheWriteData*
706 //
603 // 3. Cached entry, validation (304): 707 // 3. Cached entry, validation (304):
604 // Start(): 708 // Start():
605 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* 709 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse*
606 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> 710 // -> CacheDispatchValidation -> BeginPartialCacheValidation() ->
607 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest -> 711 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest ->
608 // UpdateCachedResponse -> CacheWriteUpdatedResponse* -> 712 // UpdateCachedResponse -> CacheWriteUpdatedResponse* ->
609 // UpdateCachedResponseComplete -> OverwriteCachedResponse -> 713 // UpdateCachedResponseComplete -> OverwriteCachedResponse ->
610 // PartialHeadersReceived 714 // PartialHeadersReceived
611 // 715 //
612 // Read(): 716 // Read(): () (When response is already written to the cache.)
613 // CacheReadData* 717 // CacheReadData*
614 // 718 //
719 // Read(): (When response is currently being written to the cache by shared
720 // writing.)
721 // SharedNetworkRead* -> SharedCacheWriteData*
722 //
615 // 4. Cached entry, validation and replace (200): 723 // 4. Cached entry, validation and replace (200):
616 // Start(): 724 // Start():
617 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* 725 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse*
618 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> 726 // -> CacheDispatchValidation -> BeginPartialCacheValidation() ->
619 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest -> 727 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest ->
620 // OverwriteCachedResponse -> CacheWriteResponse* -> DoTruncateCachedData* -> 728 // OverwriteCachedResponse -> CacheWriteResponse* -> DoTruncateCachedData* ->
621 // TruncateCachedMetadata* -> PartialHeadersReceived 729 // TruncateCachedMetadata* -> PartialHeadersReceived
622 // 730 //
623 // Read(): 731 // Read():
624 // NetworkRead* -> CacheWriteData* 732 // NetworkRead* -> CacheWriteData*
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 // -> CacheToggleUnusedSincePrefetch* -> CacheDispatchValidation -> 807 // -> CacheToggleUnusedSincePrefetch* -> CacheDispatchValidation ->
700 // BeginPartialCacheValidation() -> BeginCacheValidation() -> 808 // BeginPartialCacheValidation() -> BeginCacheValidation() ->
701 // SetupEntryForRead() 809 // SetupEntryForRead()
702 // 810 //
703 // Read(): 811 // Read():
704 // CacheReadData* 812 // CacheReadData*
705 // 813 //
706 // 14. Cached entry more than 5 minutes old, unused_since_prefetch is true: 814 // 14. Cached entry more than 5 minutes old, unused_since_prefetch is true:
707 // Like examples 2-4, only CacheToggleUnusedSincePrefetch* is inserted between 815 // Like examples 2-4, only CacheToggleUnusedSincePrefetch* is inserted between
708 // CacheReadResponse* and CacheDispatchValidation. 816 // CacheReadResponse* and CacheDispatchValidation.
817 //
jkarlin 2017/02/07 15:20:31 Delete line
shivanisha 2017/02/07 20:56:48 Done
709 int HttpCache::Transaction::DoLoop(int result) { 818 int HttpCache::Transaction::DoLoop(int result) {
710 DCHECK(next_state_ != STATE_NONE); 819 DCHECK(next_state_ != STATE_NONE);
711 820
712 int rv = result; 821 int rv = result;
713 do { 822 do {
714 State state = next_state_; 823 State state = next_state_;
715 next_state_ = STATE_NONE; 824 next_state_ = STATE_NONE;
716 switch (state) { 825 switch (state) {
717 case STATE_GET_BACKEND: 826 case STATE_GET_BACKEND:
718 DCHECK_EQ(OK, rv); 827 DCHECK_EQ(OK, rv);
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
866 case STATE_CACHE_WRITE_DATA_COMPLETE: 975 case STATE_CACHE_WRITE_DATA_COMPLETE:
867 rv = DoCacheWriteDataComplete(rv); 976 rv = DoCacheWriteDataComplete(rv);
868 break; 977 break;
869 case STATE_CACHE_WRITE_TRUNCATED_RESPONSE: 978 case STATE_CACHE_WRITE_TRUNCATED_RESPONSE:
870 DCHECK_EQ(OK, rv); 979 DCHECK_EQ(OK, rv);
871 rv = DoCacheWriteTruncatedResponse(); 980 rv = DoCacheWriteTruncatedResponse();
872 break; 981 break;
873 case STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE: 982 case STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE:
874 rv = DoCacheWriteTruncatedResponseComplete(rv); 983 rv = DoCacheWriteTruncatedResponseComplete(rv);
875 break; 984 break;
985 case STATE_SHARED_NETWORK_READ:
986 DCHECK_EQ(OK, rv);
987 rv = DoSharedNetworkRead();
988 break;
989 case STATE_SHARED_NETWORK_READ_COMPLETE:
990 rv = DoSharedNetworkReadComplete(rv);
991 break;
992 case STATE_SHARED_NETWORK_READ_WAIT_COMPLETE:
993 rv = DoSharedNetworkReadWaitComplete(rv);
994 break;
995 case STATE_SHARED_CACHE_WRITE_DATA:
996 rv = DoSharedCacheWriteData(rv);
997 break;
998 case STATE_SHARED_CACHE_WRITE_DATA_COMPLETE:
999 rv = DoSharedCacheWriteDataComplete(rv);
1000 break;
1001 case STATE_SHARED_READ_WRITE_FAILED:
1002 rv = DoSharedReadWriteFailed();
1003 break;
876 default: 1004 default:
877 NOTREACHED() << "bad state"; 1005 NOTREACHED() << "bad state";
878 rv = ERR_FAILED; 1006 rv = ERR_FAILED;
879 break; 1007 break;
880 } 1008 }
881 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); 1009 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
882 1010
883 if (rv != ERR_IO_PENDING && !callback_.is_null()) { 1011 if (rv != ERR_IO_PENDING && !callback_.is_null()) {
884 read_buf_ = NULL; // Release the buffer before invoking the callback. 1012 read_buf_ = NULL; // Release the buffer before invoking the callback.
885 base::ResetAndReturn(&callback_).Run(rv); 1013 base::ResetAndReturn(&callback_).Run(rv);
(...skipping 617 matching lines...) Expand 10 before | Expand all | Expand 10 after
1503 1631
1504 RecordNoStoreHeaderHistogram(request_->load_flags, new_response); 1632 RecordNoStoreHeaderHistogram(request_->load_flags, new_response);
1505 1633
1506 if (new_response_->headers->response_code() == 416 && 1634 if (new_response_->headers->response_code() == 416 &&
1507 (request_->method == "GET" || request_->method == "POST")) { 1635 (request_->method == "GET" || request_->method == "POST")) {
1508 // If there is an active entry it may be destroyed with this transaction. 1636 // If there is an active entry it may be destroyed with this transaction.
1509 SetResponse(*new_response_); 1637 SetResponse(*new_response_);
1510 return OK; 1638 return OK;
1511 } 1639 }
1512 1640
1641 // If the transaction is shared and it is a 200 or an error response, then
1642 // doom the entry and let this transaction continue without writing to the
1643 // cache if shared writers contain more transactions. If not, continue
1644 // writing to the cache and also transfer the network transaction to shared
1645 // writers.
1646 if (shared_ && new_response->headers->response_code() != 304) {
1647 network_trans_ = entry_->shared_writers->OnValidationNoMatch(
1648 cache_key_, this, std::move(network_trans_), priority_);
1649 if (!shared_) {
1650 DCHECK(network_trans_);
1651 if (cache_entry_status_ == CacheEntryStatus::ENTRY_UNDEFINED) {
1652 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_DOOM_SHARED_WRITING);
1653 }
1654 DoneWritingToEntry(false, false);
1655 return OK;
1656 } else {
1657 DCHECK(!network_trans_);
1658 }
1659 }
1660
1513 // Are we expecting a response to a conditional query? 1661 // Are we expecting a response to a conditional query?
1514 if (mode_ == READ_WRITE || mode_ == UPDATE) { 1662 if (mode_ == READ_WRITE || mode_ == UPDATE) {
1515 if (new_response->headers->response_code() == 304 || handling_206_) { 1663 if (new_response->headers->response_code() == 304 || handling_206_) {
1516 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_VALIDATED); 1664 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_VALIDATED);
1517 next_state_ = STATE_UPDATE_CACHED_RESPONSE; 1665 next_state_ = STATE_UPDATE_CACHED_RESPONSE;
1518 return OK; 1666 return OK;
1519 } 1667 }
1520 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_UPDATED); 1668 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_UPDATED);
1521 mode_ = WRITE; 1669 mode_ = WRITE;
1522 } 1670 }
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1625 SetResponse(*new_response_); 1773 SetResponse(*new_response_);
1626 1774
1627 if (request_->method == "HEAD") { 1775 if (request_->method == "HEAD") {
1628 // This response is replacing the cached one. 1776 // This response is replacing the cached one.
1629 DoneWritingToEntry(false); 1777 DoneWritingToEntry(false);
1630 mode_ = NONE; 1778 mode_ = NONE;
1631 new_response_ = NULL; 1779 new_response_ = NULL;
1632 return OK; 1780 return OK;
1633 } 1781 }
1634 1782
1635 if (handling_206_ && !CanResume(false)) { 1783 if (handling_206_ &&
1784 !cache_->CanResumeEntry(false, request_->method, &response_, entry_)) {
1636 // There is no point in storing this resource because it will never be used. 1785 // There is no point in storing this resource because it will never be used.
1637 // This may change if we support LOAD_ONLY_FROM_CACHE with sparse entries. 1786 // This may change if we support LOAD_ONLY_FROM_CACHE with sparse entries.
1638 DoneWritingToEntry(false); 1787 DoneWritingToEntry(false);
1639 if (partial_) 1788 if (partial_)
1640 partial_->FixResponseHeaders(response_.headers.get(), true); 1789 partial_->FixResponseHeaders(response_.headers.get(), true);
1641 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; 1790 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED;
1642 return OK; 1791 return OK;
1643 } 1792 }
1644 1793
1645 next_state_ = STATE_CACHE_WRITE_RESPONSE; 1794 next_state_ = STATE_CACHE_WRITE_RESPONSE;
1646 return OK; 1795 return OK;
1647 } 1796 }
1648 1797
1649 int HttpCache::Transaction::DoCacheWriteResponse() { 1798 int HttpCache::Transaction::DoCacheWriteResponse() {
1650 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponse"); 1799 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponse");
1651 next_state_ = STATE_CACHE_WRITE_RESPONSE_COMPLETE; 1800 next_state_ = STATE_CACHE_WRITE_RESPONSE_COMPLETE;
1652 return WriteResponseInfoToEntry(truncated_); 1801 return WriteResponseInfoToEntry(truncated_);
1653 } 1802 }
1654 1803
1655 int HttpCache::Transaction::DoCacheWriteResponseComplete(int result) { 1804 int HttpCache::Transaction::DoCacheWriteResponseComplete(int result) {
1656 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponseComplete"); 1805 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponseComplete");
1657 next_state_ = STATE_TRUNCATE_CACHED_DATA; 1806 next_state_ = STATE_TRUNCATE_CACHED_DATA;
1658 return OnWriteResponseInfoToEntryComplete(result); 1807 return OnWriteResponseInfoToEntryComplete(result);
1659 } 1808 }
1660 1809
1810 void HttpCache::Transaction::ResetShared(bool continue_network_reading,
1811 bool continue_cache_reading) {
1812 if (!continue_network_reading) {
1813 SaveSharedNetworkTransactionInfo();
1814 }
1815 if (continue_cache_reading) {
1816 mode_ = READ;
1817 }
1818 shared_ = false;
1819 }
1820
1821 void HttpCache::Transaction::SetShared() {
1822 shared_ = true;
1823 }
1824
1825 bool HttpCache::Transaction::validating_shared() const {
1826 return shared_ && next_state_ != STATE_NONE &&
1827 next_state_ <= STATE_START_STATE_MACHINE_FINAL;
1828 }
1829
1661 int HttpCache::Transaction::DoTruncateCachedData() { 1830 int HttpCache::Transaction::DoTruncateCachedData() {
1662 TRACE_EVENT0("io", "HttpCacheTransaction::DoTruncateCachedData"); 1831 TRACE_EVENT0("io", "HttpCacheTransaction::DoTruncateCachedData");
1663 next_state_ = STATE_TRUNCATE_CACHED_DATA_COMPLETE; 1832 next_state_ = STATE_TRUNCATE_CACHED_DATA_COMPLETE;
1664 if (!entry_) 1833 if (!entry_)
1665 return OK; 1834 return OK;
1666 if (net_log_.IsCapturing()) 1835 if (net_log_.IsCapturing())
1667 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_WRITE_DATA); 1836 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_WRITE_DATA);
1668 // Truncate the stream. 1837 // Truncate the stream.
1669 return WriteToEntry(kResponseContentIndex, 0, NULL, 0, io_callback_); 1838 return WriteToEntry(kResponseContentIndex, 0, NULL, 0, io_callback_);
1670 } 1839 }
(...skipping 28 matching lines...) Expand all
1699 if (net_log_.IsCapturing()) { 1868 if (net_log_.IsCapturing()) {
1700 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_INFO, 1869 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_INFO,
1701 result); 1870 result);
1702 } 1871 }
1703 } 1872 }
1704 1873
1705 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; 1874 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED;
1706 return OK; 1875 return OK;
1707 } 1876 }
1708 1877
1878 void HttpCache::Transaction::ProcessForSharedWriting() {
1879 // Should not be already reading.
1880 if (reading_)
1881 return;
1882
1883 // If not already part of SharedWriters, then check if one should be
1884 // created.
1885 if (!shared_ && !IsEligibleForSharedWriting())
1886 return;
1887
1888 if (shared_) {
1889 // Non 304 case is already handled in DoSuccessfulSendRequest.
1890 if (response_.headers->response_code() != 304) {
1891 return;
1892 }
1893 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_JOIN_SHARED_WRITING);
1894 entry_->shared_writers->OnValidationMatch(this, priority_);
1895 network_trans_.reset();
1896 return;
1897 }
1898
1899 // Do not create a SharedWriters if its a Redirect response.
1900 if (response_.headers->response_code() != 200)
1901 return;
1902
1903 // or if its a no-store response.
jkarlin 2017/02/07 15:20:31 Comment should be a full sentence.
shivanisha 2017/02/07 20:56:48 Merged with the above comment.
1904 if (!entry_)
1905 return;
1906
1907 DCHECK(cache_entry_status_ == CacheEntryStatus::ENTRY_NOT_IN_CACHE ||
1908 cache_entry_status_ == CacheEntryStatus::ENTRY_UPDATED ||
1909 cache_entry_status_ == CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE ||
1910 cache_entry_status_ == CacheEntryStatus::ENTRY_OTHER);
1911 // Measure how many requests out of the total of "not cached" and "updated"
1912 // are initiating Shared Writing.
jkarlin 2017/02/07 15:20:31 shared writing probably shouldn't be capitalized
shivanisha 2017/02/07 20:56:48 Made lower case.
1913 initiate_shared_writing_ = true;
1914 DCHECK(entry_ && network_trans_);
1915
1916 // An instance of SharedWriters will be created when the first writer has
1917 // written the new response headers in the cache. Transfer network
1918 // transaction’s ownership to SharedWriters so it can be used by any of the
1919 // transactions for subsequent reading from the network.
1920 cache_->CreateSharedWriters(this, std::move(network_trans_), priority_);
1921 }
1922
1709 int HttpCache::Transaction::DoPartialHeadersReceived() { 1923 int HttpCache::Transaction::DoPartialHeadersReceived() {
1710 new_response_ = NULL; 1924 new_response_ = NULL;
1711 if (entry_ && !partial_ && entry_->disk_entry->GetDataSize(kMetadataIndex)) 1925 if (entry_ && !partial_ && entry_->disk_entry->GetDataSize(kMetadataIndex))
1712 next_state_ = STATE_CACHE_READ_METADATA; 1926 next_state_ = STATE_CACHE_READ_METADATA;
1713 1927
1928 ProcessForSharedWriting();
1929
1714 if (!partial_) 1930 if (!partial_)
1715 return OK; 1931 return OK;
1716 1932
1717 if (reading_) { 1933 if (reading_) {
1718 if (network_trans_.get()) { 1934 if (network_trans_.get()) {
1719 next_state_ = STATE_NETWORK_READ; 1935 next_state_ = STATE_NETWORK_READ;
1720 } else { 1936 } else {
1721 next_state_ = STATE_CACHE_READ_DATA; 1937 next_state_ = STATE_CACHE_READ_DATA;
1722 } 1938 }
1723 } else if (mode_ != NONE) { 1939 } else if (mode_ != NONE) {
(...skipping 30 matching lines...) Expand all
1754 } 1970 }
1755 1971
1756 int HttpCache::Transaction::DoNetworkRead() { 1972 int HttpCache::Transaction::DoNetworkRead() {
1757 TRACE_EVENT0("io", "HttpCacheTransaction::DoNetworkRead"); 1973 TRACE_EVENT0("io", "HttpCacheTransaction::DoNetworkRead");
1758 next_state_ = STATE_NETWORK_READ_COMPLETE; 1974 next_state_ = STATE_NETWORK_READ_COMPLETE;
1759 return network_trans_->Read(read_buf_.get(), io_buf_len_, io_callback_); 1975 return network_trans_->Read(read_buf_.get(), io_buf_len_, io_callback_);
1760 } 1976 }
1761 1977
1762 int HttpCache::Transaction::DoNetworkReadComplete(int result) { 1978 int HttpCache::Transaction::DoNetworkReadComplete(int result) {
1763 TRACE_EVENT0("io", "HttpCacheTransaction::DoNetworkReadComplete"); 1979 TRACE_EVENT0("io", "HttpCacheTransaction::DoNetworkReadComplete");
1980 if (net_log_.IsCapturing())
1981 net_log_.EndEventWithNetErrorCode(
1982 NetLogEventType::HTTP_CACHE_NETWORK_READ_COMPLETE, result);
1983
1764 DCHECK(mode_ & WRITE || mode_ == NONE); 1984 DCHECK(mode_ & WRITE || mode_ == NONE);
1765 1985
1766 if (!cache_.get()) 1986 if (!cache_.get())
1767 return ERR_UNEXPECTED; 1987 return ERR_UNEXPECTED;
1768 1988
1769 // If there is an error or we aren't saving the data, we are done; just wait 1989 // If there is an error or we aren't saving the data, we are done; just wait
1770 // until the destructor runs to see if we can keep the data. 1990 // until the destructor runs to see if we can keep the data.
1771 if (mode_ == NONE || result < 0) 1991 if (mode_ == NONE || result < 0)
1772 return result; 1992 return result;
1773 1993
1774 next_state_ = STATE_CACHE_WRITE_DATA; 1994 next_state_ = STATE_CACHE_WRITE_DATA;
1775 return result; 1995 return result;
1776 } 1996 }
1777 1997
1998 int HttpCache::Transaction::DoSharedNetworkRead() {
1999 TRACE_EVENT0("io", "HttpCacheTransaction::DoSharedNetworkRead");
2000 if (net_log_.IsCapturing())
2001 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_SHARED_NETWORK_READ);
2002
2003 next_state_ = STATE_SHARED_NETWORK_READ_COMPLETE;
2004 bool shared_read_in_progress = false;
2005 int result = entry_->shared_writers->Read(
2006 read_buf_, io_buf_len_, io_callback_, this, &shared_read_in_progress);
2007 if (shared_read_in_progress) {
2008 next_state_ = STATE_SHARED_NETWORK_READ_WAIT_COMPLETE;
2009 }
2010 return result;
2011 }
2012
2013 int HttpCache::Transaction::DoSharedNetworkReadComplete(int result) {
2014 TRACE_EVENT0("io", "HttpCacheTransaction::DoSharedNetworkReadComplete");
2015 if (net_log_.IsCapturing())
2016 net_log_.EndEventWithNetErrorCode(
2017 NetLogEventType::HTTP_CACHE_SHARED_NETWORK_READ_COMPLETE, result);
2018
2019 if (result <= 0) {
2020 // Set entry as null so that the destructor does not invoke DoneWithEntry
2021 // again as entry_ is already cleaned up by SharedWriters.
2022 entry_ = nullptr;
2023 return result;
2024 }
2025
2026 read_offset_ += result;
2027
2028 next_state_ = STATE_SHARED_CACHE_WRITE_DATA;
2029 return result;
2030 }
2031
2032 int HttpCache::Transaction::DoSharedCacheWriteData(int result) {
2033 TRACE_EVENT0("io", "HttpCacheTransaction::DoSharedCacheWriteData");
2034 if (net_log_.IsCapturing())
2035 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_SHARED_CACHE_WRITE_DATA);
2036
2037 next_state_ = STATE_SHARED_CACHE_WRITE_DATA_COMPLETE;
2038 write_len_ = result;
2039 return entry_->shared_writers->CacheWrite(read_buf_, write_len_, io_callback_,
2040 this);
2041 }
2042
2043 int HttpCache::Transaction::DoSharedCacheWriteDataComplete(int result) {
2044 TRACE_EVENT0("io", "HttpCacheTransaction::DoSharedCacheWriteDataComplete");
2045 if (net_log_.IsCapturing())
2046 net_log_.EndEventWithNetErrorCode(
2047 NetLogEventType::HTTP_CACHE_SHARED_CACHE_WRITE_DATA_COMPLETE, result);
2048
2049 OnCacheWriteDataComplete(true, &result);
2050
2051 if (result == 0) {
2052 DoneWritingToEntry(true, false);
2053 }
2054 return result;
2055 }
2056
2057 void HttpCache::Transaction::OnCacheWriteDataComplete(bool was_shared,
2058 int* result) {
2059 if (*result != write_len_) {
2060 DoneWritingToEntry(false, !was_shared);
2061 // Consumer need not know that it was a failure since this transaction can
2062 // continue reading from the network.
2063 *result = write_len_;
2064 } else if (!done_reading_ && entry_ && (!partial_ || truncated_)) {
2065 done_reading_ = cache_->IsResponseCompleted(entry_, &response_);
2066 }
2067 }
2068
2069 int HttpCache::Transaction::DoSharedNetworkReadWaitComplete(int result) {
2070 TRACE_EVENT0("io", "HttpCacheTransaction::DoSharedNetworkReadWaitComplete");
2071 if (net_log_.IsCapturing())
2072 net_log_.EndEventWithNetErrorCode(
2073 NetLogEventType::HTTP_CACHE_SHARED_NETWORK_READ_WAIT_COMPLETE, result);
2074
2075 // If its a network read failure or cache write failure, we just return the
2076 // result.
2077 // If its a cache write success, read_buf_ would have been filled
2078 // with the read data by SharedWriters.
2079 if (result == 0) { // response is complete.
2080 DoneWritingToEntry(true, false); // changes the mode_ to NONE.
2081 } else if (result > 0) {
2082 read_offset_ += result;
2083 } else {
2084 // Set entry as null so that the destructor does not invoke DoneWithEntry
2085 // again as entry_ is already cleaned up by SharedWriters.
2086 entry_ = nullptr;
2087 }
2088
2089 return result;
2090 }
2091
1778 int HttpCache::Transaction::DoCacheReadData() { 2092 int HttpCache::Transaction::DoCacheReadData() {
1779 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadData"); 2093 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadData");
1780 if (request_->method == "HEAD") 2094 if (request_->method == "HEAD")
1781 return 0; 2095 return 0;
1782 2096
1783 DCHECK(entry_); 2097 DCHECK(entry_);
1784 next_state_ = STATE_CACHE_READ_DATA_COMPLETE; 2098 next_state_ = STATE_CACHE_READ_DATA_COMPLETE;
1785 2099
1786 if (net_log_.IsCapturing()) 2100 if (net_log_.IsCapturing())
1787 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_READ_DATA); 2101 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_READ_DATA);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1829 next_state_ = STATE_CACHE_WRITE_DATA_COMPLETE; 2143 next_state_ = STATE_CACHE_WRITE_DATA_COMPLETE;
1830 write_len_ = num_bytes; 2144 write_len_ = num_bytes;
1831 if (entry_) { 2145 if (entry_) {
1832 if (net_log_.IsCapturing()) 2146 if (net_log_.IsCapturing())
1833 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_WRITE_DATA); 2147 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_WRITE_DATA);
1834 } 2148 }
1835 2149
1836 if (!entry_ || !num_bytes) 2150 if (!entry_ || !num_bytes)
1837 return num_bytes; 2151 return num_bytes;
1838 2152
2153 if (partial_) {
2154 return partial_->CacheWrite(entry_->disk_entry, read_buf_.get(), num_bytes,
2155 io_callback_);
2156 }
2157
1839 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); 2158 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex);
1840 return WriteToEntry(kResponseContentIndex, current_size, read_buf_.get(), 2159 return entry_->disk_entry->WriteData(kResponseContentIndex, current_size,
1841 num_bytes, io_callback_); 2160 read_buf_.get(), num_bytes, io_callback_,
2161 true);
1842 } 2162 }
1843 2163
1844 int HttpCache::Transaction::DoCacheWriteDataComplete(int result) { 2164 int HttpCache::Transaction::DoCacheWriteDataComplete(int result) {
1845 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteDataComplete"); 2165 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteDataComplete");
1846 if (entry_) { 2166 if (entry_) {
1847 if (net_log_.IsCapturing()) { 2167 if (net_log_.IsCapturing()) {
1848 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_DATA, 2168 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_DATA,
1849 result); 2169 result);
1850 } 2170 }
1851 } 2171 }
1852 if (!cache_.get()) 2172 if (!cache_.get())
1853 return ERR_UNEXPECTED; 2173 return ERR_UNEXPECTED;
1854 2174
1855 if (result != write_len_) { 2175 OnCacheWriteDataComplete(false, &result);
1856 DLOG(ERROR) << "failed to write response data to cache";
1857 DoneWritingToEntry(false);
1858
1859 // We want to ignore errors writing to disk and just keep reading from
1860 // the network.
1861 result = write_len_;
1862 } else if (!done_reading_ && entry_ && (!partial_ || truncated_)) {
1863 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex);
1864 int64_t body_size = response_.headers->GetContentLength();
1865 if (body_size >= 0 && body_size <= current_size)
1866 done_reading_ = true;
1867 }
1868 2176
1869 if (partial_) { 2177 if (partial_) {
1870 // This may be the last request. 2178 // This may be the last request.
1871 if (result != 0 || truncated_ || 2179 if (result != 0 || truncated_ ||
1872 !(partial_->IsLastRange() || mode_ == WRITE)) { 2180 !(partial_->IsLastRange() || mode_ == WRITE)) {
1873 return DoPartialNetworkReadCompleted(result); 2181 return DoPartialNetworkReadCompleted(result);
1874 } 2182 }
1875 } 2183 }
1876 2184
2185 // End of file. This may be the result of a connection problem so see if we
2186 // have to keep the entry around to be flagged as truncated later on.
1877 if (result == 0) { 2187 if (result == 0) {
1878 // End of file. This may be the result of a connection problem so see if we
1879 // have to keep the entry around to be flagged as truncated later on.
1880 if (done_reading_ || !entry_ || partial_ || 2188 if (done_reading_ || !entry_ || partial_ ||
1881 response_.headers->GetContentLength() <= 0) { 2189 response_.headers->GetContentLength() <= 0)
1882 DoneWritingToEntry(true); 2190 DoneWritingToEntry(true);
1883 }
1884 } 2191 }
1885 2192
1886 return result; 2193 return result;
1887 } 2194 }
1888 2195
1889 int HttpCache::Transaction::DoCacheWriteTruncatedResponse() { 2196 int HttpCache::Transaction::DoCacheWriteTruncatedResponse() {
1890 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteTruncatedResponse"); 2197 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteTruncatedResponse");
1891 next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE; 2198 next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE;
1892 return WriteResponseInfoToEntry(true); 2199 return WriteResponseInfoToEntry(true);
1893 } 2200 }
1894 2201
1895 int HttpCache::Transaction::DoCacheWriteTruncatedResponseComplete(int result) { 2202 int HttpCache::Transaction::DoCacheWriteTruncatedResponseComplete(int result) {
1896 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteTruncatedResponse"); 2203 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteTruncatedResponse");
1897 2204
1898 return OnWriteResponseInfoToEntryComplete(result); 2205 return OnWriteResponseInfoToEntryComplete(result);
1899 } 2206 }
1900 2207
2208 int HttpCache::Transaction::DoSharedReadWriteFailed() {
2209 if (net_log_.IsCapturing())
2210 net_log_.EndEventWithNetErrorCode(
2211 NetLogEventType::HTTP_CACHE_SHARED_READ_WRITE_FAILED,
2212 shared_read_write_failure_result_);
2213
2214 return shared_read_write_failure_result_;
2215 }
2216
1901 //----------------------------------------------------------------------------- 2217 //-----------------------------------------------------------------------------
1902 2218
1903 void HttpCache::Transaction::SetRequest(const NetLogWithSource& net_log, 2219 void HttpCache::Transaction::SetRequest(const NetLogWithSource& net_log,
1904 const HttpRequestInfo* request) { 2220 const HttpRequestInfo* request) {
1905 net_log_ = net_log; 2221 net_log_ = net_log;
1906 request_ = request; 2222 request_ = request;
1907 effective_load_flags_ = request_->load_flags; 2223 effective_load_flags_ = request_->load_flags;
1908 2224
1909 if (cache_->mode() == DISABLE) 2225 if (cache_->mode() == DISABLE)
1910 effective_load_flags_ |= LOAD_DISABLE_CACHE; 2226 effective_load_flags_ |= LOAD_DISABLE_CACHE;
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
2084 2400
2085 if (partial_ && (is_sparse_ || truncated_) && 2401 if (partial_ && (is_sparse_ || truncated_) &&
2086 (!partial_->IsCurrentRangeCached() || invalid_range_)) { 2402 (!partial_->IsCurrentRangeCached() || invalid_range_)) {
2087 // Force revalidation for sparse or truncated entries. Note that we don't 2403 // Force revalidation for sparse or truncated entries. Note that we don't
2088 // want to ignore the regular validation logic just because a byte range was 2404 // want to ignore the regular validation logic just because a byte range was
2089 // part of the request. 2405 // part of the request.
2090 skip_validation = false; 2406 skip_validation = false;
2091 } 2407 }
2092 2408
2093 if (skip_validation) { 2409 if (skip_validation) {
2094 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_USED); 2410 if (shared_) {
2095 return SetupEntryForRead(); 2411 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_JOIN_SHARED_WRITING);
2412 entry_->shared_writers->OnValidationMatch(this, priority_);
2413 } else {
2414 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_USED);
2415 return SetupEntryForRead();
2416 }
2096 } else { 2417 } else {
2097 // Make the network request conditional, to see if we may reuse our cached 2418 // Make the network request conditional, to see if we may reuse our cached
2098 // response. If we cannot do so, then we just resort to a normal fetch. 2419 // response. If we cannot do so, then we just resort to a normal fetch.
2099 // Our mode remains READ_WRITE for a conditional request. Even if the 2420 // Our mode remains READ_WRITE for a conditional request. Even if the
2100 // conditionalization fails, we don't switch to WRITE mode until we 2421 // conditionalization fails, we don't switch to WRITE mode until we
2101 // know we won't be falling back to using the cache entry in the 2422 // know we won't be falling back to using the cache entry in the
2102 // LOAD_FROM_CACHE_IF_OFFLINE case. 2423 // LOAD_FROM_CACHE_IF_OFFLINE case.
2103 if (!ConditionalizeRequest()) { 2424 if (!ConditionalizeRequest()) {
2104 couldnt_conditionalize_request_ = true; 2425 couldnt_conditionalize_request_ = true;
2105 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE); 2426 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE);
(...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after
2604 IsCertStatusError(response_.ssl_info.cert_status)) { 2925 IsCertStatusError(response_.ssl_info.cert_status)) {
2605 DoneWritingToEntry(false); 2926 DoneWritingToEntry(false);
2606 if (net_log_.IsCapturing()) 2927 if (net_log_.IsCapturing())
2607 net_log_.EndEvent(NetLogEventType::HTTP_CACHE_WRITE_INFO); 2928 net_log_.EndEvent(NetLogEventType::HTTP_CACHE_WRITE_INFO);
2608 return OK; 2929 return OK;
2609 } 2930 }
2610 2931
2611 if (truncated) 2932 if (truncated)
2612 DCHECK_EQ(200, response_.headers->response_code()); 2933 DCHECK_EQ(200, response_.headers->response_code());
2613 2934
2614 // When writing headers, we normally only write the non-transient headers. 2935 return cache_->WriteResponseInfo(entry_, &response_, io_callback_, truncated,
2615 bool skip_transient_headers = true; 2936 &io_buf_len_);
2616 scoped_refptr<PickledIOBuffer> data(new PickledIOBuffer());
2617 response_.Persist(data->pickle(), skip_transient_headers, truncated);
2618 data->Done();
2619
2620 io_buf_len_ = data->pickle()->size();
2621 return entry_->disk_entry->WriteData(kResponseInfoIndex, 0, data.get(),
2622 io_buf_len_, io_callback_, true);
2623 } 2937 }
2624 2938
2625 int HttpCache::Transaction::OnWriteResponseInfoToEntryComplete(int result) { 2939 int HttpCache::Transaction::OnWriteResponseInfoToEntryComplete(int result) {
2626 if (!entry_) 2940 if (!entry_)
2627 return OK; 2941 return OK;
2628 if (net_log_.IsCapturing()) { 2942 if (net_log_.IsCapturing()) {
2629 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_INFO, 2943 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_INFO,
2630 result); 2944 result);
2631 } 2945 }
2632 2946
2633 if (result != io_buf_len_) { 2947 if (result != io_buf_len_) {
2634 DLOG(ERROR) << "failed to write response info to cache"; 2948 DLOG(ERROR) << "failed to write response info to cache";
2635 DoneWritingToEntry(false); 2949 DoneWritingToEntry(false);
2636 } 2950 }
2637 return OK; 2951 return OK;
2638 } 2952 }
2639 2953
2640 void HttpCache::Transaction::DoneWritingToEntry(bool success) { 2954 void HttpCache::Transaction::DoneWritingToEntry(bool success,
2955 bool perform_entry_cleanup) {
2641 if (!entry_) 2956 if (!entry_)
2642 return; 2957 return;
2643 2958
2644 RecordHistograms(); 2959 RecordHistograms();
2645 2960
2646 cache_->DoneWritingToEntry(entry_, success); 2961 if (perform_entry_cleanup) {
2647 entry_ = NULL; 2962 cache_->DoneWritingToEntry(entry_, success);
2963 }
2964 entry_ = nullptr;
2648 mode_ = NONE; // switch to 'pass through' mode 2965 mode_ = NONE; // switch to 'pass through' mode
2649 } 2966 }
2650 2967
2968 void HttpCache::Transaction::ContinueWithoutSharedWriting(
2969 std::unique_ptr<HttpTransaction> network_transaction,
2970 bool needs_entry) {
2971 shared_ = false;
2972 if (!needs_entry)
2973 entry_ = nullptr;
2974 mode_ = NONE;
2975 network_trans_ = std::move(network_transaction);
2976 }
2977
2651 int HttpCache::Transaction::OnCacheReadError(int result, bool restart) { 2978 int HttpCache::Transaction::OnCacheReadError(int result, bool restart) {
2652 DLOG(ERROR) << "ReadData failed: " << result; 2979 DLOG(ERROR) << "ReadData failed: " << result;
2653 const int result_for_histogram = std::max(0, -result); 2980 const int result_for_histogram = std::max(0, -result);
2654 if (restart) { 2981 if (restart) {
2655 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorRestartable", 2982 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorRestartable",
2656 result_for_histogram); 2983 result_for_histogram);
2657 } else { 2984 } else {
2658 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorNonRestartable", 2985 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorNonRestartable",
2659 result_for_histogram); 2986 result_for_histogram);
2660 } 2987 }
2661 2988
2662 // Avoid using this entry in the future. 2989 // Avoid using this entry in the future.
2663 if (cache_.get()) 2990 if (cache_.get())
2664 cache_->DoomActiveEntry(cache_key_); 2991 cache_->DoomActiveEntry(cache_key_);
2665 2992
2666 if (restart) { 2993 if (restart) {
2667 DCHECK(!reading_); 2994 DCHECK(!reading_);
2668 DCHECK(!network_trans_.get()); 2995 DCHECK(!network_trans_.get());
2669 cache_->DoneWithEntry(entry_, this, false); 2996 if (shared_) {
2997 entry_->shared_writers->RemoveValidatingTransaction(this);
2998 } else {
2999 cache_->DoneWithEntry(entry_, this, false);
3000 }
2670 entry_ = NULL; 3001 entry_ = NULL;
2671 is_sparse_ = false; 3002 is_sparse_ = false;
2672 partial_.reset(); 3003 partial_.reset();
2673 next_state_ = STATE_GET_BACKEND; 3004 next_state_ = STATE_GET_BACKEND;
2674 return OK; 3005 return OK;
2675 } 3006 }
2676 3007
2677 return ERR_CACHE_READ_FAILURE; 3008 return ERR_CACHE_READ_FAILURE;
2678 } 3009 }
2679 3010
2680 void HttpCache::Transaction::OnAddToEntryTimeout(base::TimeTicks start_time) { 3011 void HttpCache::Transaction::OnAddToEntryTimeout(base::TimeTicks start_time) {
2681 if (entry_lock_waiting_since_ != start_time) 3012 if (entry_lock_waiting_since_ != start_time)
2682 return; 3013 return;
2683 3014
2684 DCHECK_EQ(next_state_, STATE_ADD_TO_ENTRY_COMPLETE); 3015 DCHECK_EQ(next_state_, STATE_ADD_TO_ENTRY_COMPLETE);
2685 3016
2686 if (!cache_) 3017 if (!cache_)
2687 return; 3018 return;
2688 3019
2689 cache_->RemovePendingTransaction(this); 3020 cache_->RemovePendingTransaction(this);
2690 OnIOComplete(ERR_CACHE_LOCK_TIMEOUT); 3021 OnIOComplete(ERR_CACHE_LOCK_TIMEOUT);
2691 } 3022 }
2692 3023
2693 void HttpCache::Transaction::DoomPartialEntry(bool delete_object) { 3024 void HttpCache::Transaction::DoomPartialEntry(bool delete_object) {
3025 // Partial requests not supported with shared writing as of now.
3026 DCHECK(!shared_);
2694 DVLOG(2) << "DoomPartialEntry"; 3027 DVLOG(2) << "DoomPartialEntry";
2695 int rv = cache_->DoomEntry(cache_key_, NULL); 3028 int rv = cache_->DoomEntry(cache_key_, NULL);
2696 DCHECK_EQ(OK, rv); 3029 DCHECK_EQ(OK, rv);
2697 cache_->DoneWithEntry(entry_, this, false); 3030 cache_->DoneWithEntry(entry_, this, false);
2698 entry_ = NULL; 3031 entry_ = NULL;
2699 is_sparse_ = false; 3032 is_sparse_ = false;
2700 truncated_ = false; 3033 truncated_ = false;
2701 if (delete_object) 3034 if (delete_object)
2702 partial_.reset(NULL); 3035 partial_.reset(NULL);
2703 } 3036 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2744 if (!delete_object) { 3077 if (!delete_object) {
2745 // The simplest way to re-initialize partial_ is to create a new object. 3078 // The simplest way to re-initialize partial_ is to create a new object.
2746 partial_.reset(new PartialData()); 3079 partial_.reset(new PartialData());
2747 if (partial_->Init(request_->extra_headers)) 3080 if (partial_->Init(request_->extra_headers))
2748 partial_->SetHeaders(custom_request_->extra_headers); 3081 partial_->SetHeaders(custom_request_->extra_headers);
2749 else 3082 else
2750 partial_.reset(); 3083 partial_.reset();
2751 } 3084 }
2752 } 3085 }
2753 3086
2754 void HttpCache::Transaction::ResetNetworkTransaction() { 3087 void HttpCache::Transaction::SaveNetworkTransactionInfo(
3088 const HttpTransaction* transaction) {
2755 DCHECK(!old_network_trans_load_timing_); 3089 DCHECK(!old_network_trans_load_timing_);
2756 DCHECK(network_trans_); 3090 DCHECK(transaction);
2757 LoadTimingInfo load_timing; 3091 LoadTimingInfo load_timing;
2758 if (network_trans_->GetLoadTimingInfo(&load_timing)) 3092 if (transaction->GetLoadTimingInfo(&load_timing))
2759 old_network_trans_load_timing_.reset(new LoadTimingInfo(load_timing)); 3093 old_network_trans_load_timing_.reset(new LoadTimingInfo(load_timing));
2760 total_received_bytes_ += network_trans_->GetTotalReceivedBytes(); 3094 total_received_bytes_ += transaction->GetTotalReceivedBytes();
2761 total_sent_bytes_ += network_trans_->GetTotalSentBytes(); 3095 total_sent_bytes_ += transaction->GetTotalSentBytes();
2762 ConnectionAttempts attempts; 3096 ConnectionAttempts attempts;
2763 network_trans_->GetConnectionAttempts(&attempts); 3097 transaction->GetConnectionAttempts(&attempts);
2764 for (const auto& attempt : attempts) 3098 for (const auto& attempt : attempts)
2765 old_connection_attempts_.push_back(attempt); 3099 old_connection_attempts_.push_back(attempt);
2766 old_remote_endpoint_ = IPEndPoint(); 3100 old_remote_endpoint_ = IPEndPoint();
2767 network_trans_->GetRemoteEndpoint(&old_remote_endpoint_); 3101 transaction->GetRemoteEndpoint(&old_remote_endpoint_);
3102 }
3103
3104 void HttpCache::Transaction::SaveSharedNetworkTransactionInfo() {
3105 // If network_trans_ is still present, this transaction has not started using
3106 // the "shared" network transaction.
3107 if (network_trans_) {
3108 SaveNetworkTransactionInfo(network_trans_.get());
3109 return;
3110 }
3111
3112 DCHECK(!old_network_trans_load_timing_);
3113
3114 // If the transaction is being deleted while still in the waiting queue,
3115 // entry_ is not yet set, do nothing.
3116 if (!entry_)
3117 return;
3118 DCHECK(entry_->shared_writers);
3119 HttpTransaction* network_transaction =
3120 entry_->shared_writers->network_transaction();
3121 SaveNetworkTransactionInfo(network_transaction);
3122 have_full_request_headers_ =
3123 network_transaction->GetFullRequestHeaders(&full_request_headers_);
3124 }
3125
3126 void HttpCache::Transaction::ResetNetworkTransaction() {
3127 SaveNetworkTransactionInfo(network_trans_.get());
2768 network_trans_.reset(); 3128 network_trans_.reset();
2769 } 3129 }
2770 3130
2771 // Histogram data from the end of 2010 show the following distribution of 3131 HttpTransaction* HttpCache::Transaction::GetCurrentNetworkTransaction() const {
2772 // response headers: 3132 if (network_trans_)
2773 // 3133 return network_trans_.get();
2774 // Content-Length............... 87% 3134 if (shared_ && entry_ && entry_->shared_writers)
2775 // Date......................... 98% 3135 return entry_->shared_writers->network_transaction();
2776 // Last-Modified................ 49% 3136 return nullptr;
2777 // Etag......................... 19%
2778 // Accept-Ranges: bytes......... 25%
2779 // Accept-Ranges: none.......... 0.4%
2780 // Strong Validator............. 50%
2781 // Strong Validator + ranges.... 24%
2782 // Strong Validator + CL........ 49%
2783 //
2784 bool HttpCache::Transaction::CanResume(bool has_data) {
2785 // Double check that there is something worth keeping.
2786 if (has_data && !entry_->disk_entry->GetDataSize(kResponseContentIndex))
2787 return false;
2788
2789 if (request_->method != "GET")
2790 return false;
2791
2792 // Note that if this is a 206, content-length was already fixed after calling
2793 // PartialData::ResponseHeadersOK().
2794 if (response_.headers->GetContentLength() <= 0 ||
2795 response_.headers->HasHeaderValue("Accept-Ranges", "none") ||
2796 !response_.headers->HasStrongValidators()) {
2797 return false;
2798 }
2799
2800 return true;
2801 } 3137 }
2802 3138
2803 void HttpCache::Transaction::SetResponse(const HttpResponseInfo& response) { 3139 void HttpCache::Transaction::SetResponse(const HttpResponseInfo& response) {
2804 response_ = response; 3140 response_ = response;
2805 SyncCacheEntryStatusToResponse(); 3141 SyncCacheEntryStatusToResponse();
2806 } 3142 }
2807 3143
2808 void HttpCache::Transaction::SetAuthResponse( 3144 void HttpCache::Transaction::SetAuthResponse(
2809 const HttpResponseInfo& auth_response) { 3145 const HttpResponseInfo& auth_response) {
2810 auth_response_ = auth_response; 3146 auth_response_ = auth_response;
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
2916 } 3252 }
2917 } 3253 }
2918 3254
2919 CACHE_STATUS_HISTOGRAMS(""); 3255 CACHE_STATUS_HISTOGRAMS("");
2920 3256
2921 if (cache_entry_status_ == CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE) { 3257 if (cache_entry_status_ == CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE) {
2922 UMA_HISTOGRAM_ENUMERATION("HttpCache.CantConditionalizeCause", 3258 UMA_HISTOGRAM_ENUMERATION("HttpCache.CantConditionalizeCause",
2923 validation_cause_, VALIDATION_CAUSE_MAX); 3259 validation_cause_, VALIDATION_CAUSE_MAX);
2924 } 3260 }
2925 3261
3262 // This may also exclude shared writing counts for these cases.
2926 if (cache_entry_status_ == CacheEntryStatus::ENTRY_OTHER) 3263 if (cache_entry_status_ == CacheEntryStatus::ENTRY_OTHER)
2927 return; 3264 return;
3265
2928 DCHECK(!range_requested_); 3266 DCHECK(!range_requested_);
2929 DCHECK(!first_cache_access_since_.is_null()); 3267 DCHECK(!first_cache_access_since_.is_null());
2930 3268
2931 TimeDelta total_time = base::TimeTicks::Now() - first_cache_access_since_; 3269 TimeDelta total_time = base::TimeTicks::Now() - first_cache_access_since_;
2932 3270
2933 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone", total_time); 3271 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone", total_time);
2934 3272
3273 if (cache_entry_status_ == CacheEntryStatus::ENTRY_JOIN_SHARED_WRITING) {
3274 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.JoinSharedWriting", total_time);
3275 } else if (cache_entry_status_ ==
3276 CacheEntryStatus::ENTRY_DOOM_SHARED_WRITING) {
3277 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.DoomSharedWriting", total_time);
3278 } else if (initiate_shared_writing_) {
3279 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.InitiateSharedWriting",
3280 total_time);
3281 }
3282
2935 bool did_send_request = !send_request_since_.is_null(); 3283 bool did_send_request = !send_request_since_.is_null();
2936 DCHECK( 3284 DCHECK(
2937 (did_send_request && 3285 (did_send_request &&
2938 (cache_entry_status_ == CacheEntryStatus::ENTRY_NOT_IN_CACHE || 3286 (cache_entry_status_ == CacheEntryStatus::ENTRY_NOT_IN_CACHE ||
2939 cache_entry_status_ == CacheEntryStatus::ENTRY_VALIDATED || 3287 cache_entry_status_ == CacheEntryStatus::ENTRY_VALIDATED ||
2940 cache_entry_status_ == CacheEntryStatus::ENTRY_UPDATED || 3288 cache_entry_status_ == CacheEntryStatus::ENTRY_UPDATED ||
2941 cache_entry_status_ == CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE)) || 3289 cache_entry_status_ == CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE ||
3290 cache_entry_status_ == CacheEntryStatus::ENTRY_JOIN_SHARED_WRITING ||
3291 cache_entry_status_ == CacheEntryStatus::ENTRY_DOOM_SHARED_WRITING)) ||
2942 (!did_send_request && 3292 (!did_send_request &&
2943 cache_entry_status_ == CacheEntryStatus::ENTRY_USED)); 3293 (cache_entry_status_ == CacheEntryStatus::ENTRY_USED ||
3294 cache_entry_status_ == CacheEntryStatus::ENTRY_JOIN_SHARED_WRITING)));
2944 3295
2945 if (!did_send_request) { 3296 if (!did_send_request) {
2946 DCHECK(cache_entry_status_ == CacheEntryStatus::ENTRY_USED); 3297 if (cache_entry_status_ == CacheEntryStatus::ENTRY_USED) {
2947 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.Used", total_time); 3298 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.Used", total_time);
3299 }
2948 return; 3300 return;
2949 } 3301 }
2950 3302
2951 TimeDelta before_send_time = send_request_since_ - first_cache_access_since_; 3303 TimeDelta before_send_time = send_request_since_ - first_cache_access_since_;
2952 int64_t before_send_percent = (total_time.ToInternalValue() == 0) 3304 int64_t before_send_percent = (total_time.ToInternalValue() == 0)
2953 ? 0 3305 ? 0
2954 : before_send_time * 100 / total_time; 3306 : before_send_time * 100 / total_time;
2955 DCHECK_GE(before_send_percent, 0); 3307 DCHECK_GE(before_send_percent, 0);
2956 DCHECK_LE(before_send_percent, 100); 3308 DCHECK_LE(before_send_percent, 100);
2957 base::HistogramBase::Sample before_send_sample = 3309 base::HistogramBase::Sample before_send_sample =
2958 static_cast<base::HistogramBase::Sample>(before_send_percent); 3310 static_cast<base::HistogramBase::Sample>(before_send_percent);
2959 3311
2960 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.SentRequest", total_time); 3312 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.SentRequest", total_time);
2961 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend", before_send_time); 3313 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend", before_send_time);
2962 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend", before_send_sample); 3314 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend", before_send_sample);
2963 3315
2964 // TODO(gavinp): Remove or minimize these histograms, particularly the ones 3316 // TODO(gavinp): Remove or minimize these histograms, particularly the ones
2965 // below this comment after we have received initial data. 3317 // below this comment after we have received initial data.
2966 switch (cache_entry_status_) { 3318 switch (cache_entry_status_) {
2967 case CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE: { 3319 case CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE: {
2968 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.CantConditionalize", 3320 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.CantConditionalize",
2969 before_send_time); 3321 before_send_time);
2970 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.CantConditionalize", 3322 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.CantConditionalize",
2971 before_send_sample); 3323 before_send_sample);
3324 if (initiate_shared_writing_) {
3325 UMA_HISTOGRAM_TIMES(
3326 "HttpCache.BeforeSend.CantConditionalize.InitiateSharedWriting",
3327 before_send_time);
3328 UMA_HISTOGRAM_PERCENTAGE(
3329 "HttpCache.PercentBeforeSend.CantConditionalize."
3330 "InitiateSharedWriting",
3331 before_send_sample);
3332 }
3333
2972 break; 3334 break;
2973 } 3335 }
2974 case CacheEntryStatus::ENTRY_NOT_IN_CACHE: { 3336 case CacheEntryStatus::ENTRY_NOT_IN_CACHE: {
2975 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.NotCached", before_send_time); 3337 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.NotCached", before_send_time);
2976 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.NotCached", 3338 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.NotCached",
2977 before_send_sample); 3339 before_send_sample);
3340 if (initiate_shared_writing_) {
3341 UMA_HISTOGRAM_TIMES(
3342 "HttpCache.BeforeSend.NotCached.InitiateSharedWriting",
3343 before_send_time);
3344 UMA_HISTOGRAM_PERCENTAGE(
3345 "HttpCache.PercentBeforeSend.NotCached.InitiateSharedWriting",
3346 before_send_sample);
3347 }
3348
2978 break; 3349 break;
2979 } 3350 }
2980 case CacheEntryStatus::ENTRY_VALIDATED: { 3351 case CacheEntryStatus::ENTRY_VALIDATED: {
2981 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.Validated", before_send_time); 3352 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.Validated", before_send_time);
2982 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.Validated", 3353 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.Validated",
2983 before_send_sample); 3354 before_send_sample);
2984 break; 3355 break;
2985 } 3356 }
2986 case CacheEntryStatus::ENTRY_UPDATED: { 3357 case CacheEntryStatus::ENTRY_UPDATED: {
2987 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.Updated", before_send_time); 3358 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.Updated", before_send_time);
2988 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.Updated", 3359 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.Updated",
2989 before_send_sample); 3360 before_send_sample);
3361 if (initiate_shared_writing_) {
3362 UMA_HISTOGRAM_TIMES(
3363 "HttpCache.BeforeSend.Updated.InitiateSharedWriting",
3364 before_send_time);
3365 UMA_HISTOGRAM_PERCENTAGE(
3366 "HttpCache.PercentBeforeSend.Updated.InitiateSharedWriting",
3367 before_send_sample);
3368 }
3369 break;
3370 }
3371 case CacheEntryStatus::ENTRY_JOIN_SHARED_WRITING: {
3372 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.JoinSharedWriting",
3373 before_send_time);
3374 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.JoinSharedWriting",
3375 before_send_sample);
3376 break;
3377 }
3378 case CacheEntryStatus::ENTRY_DOOM_SHARED_WRITING: {
3379 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.DoomSharedWriting",
3380 before_send_time);
3381 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.DoomSharedWriting",
3382 before_send_sample);
2990 break; 3383 break;
2991 } 3384 }
2992 default: 3385 default:
2993 NOTREACHED(); 3386 NOTREACHED();
2994 } 3387 }
2995 } 3388 }
2996 3389
3390 bool HttpCache::Transaction::IsEligibleForSharedWriting() const {
3391 if (!(mode_ & WRITE))
3392 return false;
3393
3394 DCHECK(request_);
3395 if (request_->method != "GET")
3396 return false;
3397
3398 if (partial_ || range_requested_)
3399 return false;
3400
3401 if (truncated_)
3402 return false;
3403
3404 return true;
3405 }
3406
3407 void HttpCache::Transaction::SetSharedWritingFailState(int result) {
3408 next_state_ = STATE_SHARED_READ_WRITE_FAILED;
3409 shared_read_write_failure_result_ = result;
3410 entry_ = nullptr;
3411 }
3412
2997 void HttpCache::Transaction::OnIOComplete(int result) { 3413 void HttpCache::Transaction::OnIOComplete(int result) {
2998 DoLoop(result); 3414 DoLoop(result);
2999 } 3415 }
3000 3416
3001 } // namespace net 3417 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698