| Index: net/http/http_cache_transaction.cc
|
| diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc
|
| index 648199063a7e0f032f885a0467296a01ece8b035..4c24e0559f4d79ce214821f87ec5fcae2a8cd52a 100644
|
| --- a/net/http/http_cache_transaction.cc
|
| +++ b/net/http/http_cache_transaction.cc
|
| @@ -203,6 +203,7 @@ HttpCache::Transaction::Transaction(
|
| done_reading_(false),
|
| vary_mismatch_(false),
|
| couldnt_conditionalize_request_(false),
|
| + bypass_lock_for_test_(false),
|
| io_buf_len_(0),
|
| read_offset_(0),
|
| effective_load_flags_(0),
|
| @@ -1200,7 +1201,20 @@ int HttpCache::Transaction::DoAddToEntry() {
|
| net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY);
|
| DCHECK(entry_lock_waiting_since_.is_null());
|
| entry_lock_waiting_since_ = TimeTicks::Now();
|
| - return cache_->AddTransactionToEntry(new_entry_, this);
|
| + int rv = cache_->AddTransactionToEntry(new_entry_, this);
|
| + if (rv == ERR_IO_PENDING) {
|
| + if (bypass_lock_for_test_) {
|
| + OnAddToEntryTimeout(entry_lock_waiting_since_);
|
| + } else {
|
| + const int kTimeoutSeconds = 20;
|
| + base::MessageLoop::current()->PostDelayedTask(
|
| + FROM_HERE,
|
| + base::Bind(&HttpCache::Transaction::OnAddToEntryTimeout,
|
| + weak_factory_.GetWeakPtr(), entry_lock_waiting_since_),
|
| + TimeDelta::FromSeconds(kTimeoutSeconds));
|
| + }
|
| + }
|
| + return rv;
|
| }
|
|
|
| int HttpCache::Transaction::DoAddToEntryComplete(int result) {
|
| @@ -1225,6 +1239,17 @@ int HttpCache::Transaction::DoAddToEntryComplete(int result) {
|
| return OK;
|
| }
|
|
|
| + if (result == ERR_CACHE_LOCK_TIMEOUT) {
|
| + // The cache is busy, bypass it for this transaction.
|
| + mode_ = NONE;
|
| + next_state_ = STATE_SEND_REQUEST;
|
| + if (partial_) {
|
| + partial_->RestoreHeaders(&custom_request_->extra_headers);
|
| + partial_.reset();
|
| + }
|
| + return OK;
|
| + }
|
| +
|
| if (result != OK) {
|
| NOTREACHED();
|
| return result;
|
| @@ -2350,6 +2375,19 @@ int HttpCache::Transaction::OnCacheReadError(int result, bool restart) {
|
| return ERR_CACHE_READ_FAILURE;
|
| }
|
|
|
| +void HttpCache::Transaction::OnAddToEntryTimeout(base::TimeTicks start_time) {
|
| + if (entry_lock_waiting_since_ != start_time)
|
| + return;
|
| +
|
| + DCHECK_EQ(next_state_, STATE_ADD_TO_ENTRY_COMPLETE);
|
| +
|
| + if (!cache_)
|
| + return;
|
| +
|
| + cache_->RemovePendingTransaction(this);
|
| + OnIOComplete(ERR_CACHE_LOCK_TIMEOUT);
|
| +}
|
| +
|
| void HttpCache::Transaction::DoomPartialEntry(bool delete_object) {
|
| DVLOG(2) << "DoomPartialEntry";
|
| int rv = cache_->DoomEntry(cache_key_, NULL);
|
|
|