summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-14 17:30:57 +0000
committerrvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-14 17:30:57 +0000
commitead3edc9cc82e9c4d688c08fb36f3011bbbfaaf5 (patch)
tree252b12f8ae5975b8dc4f30ace7443171277177c1
parentdf9a183ac89847e38cfb953622fe8a86d4bb8f5d (diff)
downloadchromium_src-ead3edc9cc82e9c4d688c08fb36f3011bbbfaaf5.zip
chromium_src-ead3edc9cc82e9c4d688c08fb36f3011bbbfaaf5.tar.gz
chromium_src-ead3edc9cc82e9c4d688c08fb36f3011bbbfaaf5.tar.bz2
Http Cache: chain GetLoadState from transactions waiting for
access to an entry to the transaction that has exclusive access to that entry. This means that requests that are blocked on the single writer lock of the http cache will report the load state of the request that has the lock, and WAITING_FOR_CACHE is reserved for requests that are actually waiting for the entry to be created by the cache. BUG=43582 TEST=net_unittests Review URL: http://codereview.chromium.org/2976004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@52334 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--net/http/http_cache.cc13
-rw-r--r--net/http/http_cache.h4
-rw-r--r--net/http/http_cache_transaction.cc21
-rw-r--r--net/http/http_cache_transaction.h6
-rw-r--r--net/http/http_cache_unittest.cc14
-rw-r--r--net/http/http_transaction_unittest.h3
6 files changed, 55 insertions, 6 deletions
diff --git a/net/http/http_cache.cc b/net/http/http_cache.cc
index 3758a51..61e5a91 100644
--- a/net/http/http_cache.cc
+++ b/net/http/http_cache.cc
@@ -775,6 +775,19 @@ void HttpCache::ConvertWriterToReader(ActiveEntry* entry) {
ProcessPendingQueue(entry);
}
+LoadState HttpCache::GetLoadStateForPendingTransaction(
+ const Transaction* trans) {
+ ActiveEntriesMap::const_iterator i = active_entries_.find(trans->key());
+ if (i == active_entries_.end()) {
+ // If this is really a pending transaction, and it is not part of
+ // active_entries_, we should be creating the backend or the entry.
+ return LOAD_STATE_WAITING_FOR_CACHE;
+ }
+
+ Transaction* writer = i->second->writer;
+ return writer->GetWriterLoadState();
+}
+
void HttpCache::RemovePendingTransaction(Transaction* trans) {
ActiveEntriesMap::const_iterator i = active_entries_.find(trans->key());
bool found = false;
diff --git a/net/http/http_cache.h b/net/http/http_cache.h
index 7961343..daa6d28 100644
--- a/net/http/http_cache.h
+++ b/net/http/http_cache.h
@@ -28,6 +28,7 @@
#include "base/weak_ptr.h"
#include "net/base/cache_type.h"
#include "net/base/completion_callback.h"
+#include "net/base/load_states.h"
#include "net/http/http_transaction_factory.h"
class GURL;
@@ -310,6 +311,9 @@ class HttpCache : public HttpTransactionFactory,
// transactions can start reading from this entry.
void ConvertWriterToReader(ActiveEntry* entry);
+ // Returns the LoadState of the provided pending transaction.
+ LoadState GetLoadStateForPendingTransaction(const Transaction* trans);
+
// Removes the transaction |trans|, from the pending list of an entry
// (PendingOp, active or doomed entry).
void RemovePendingTransaction(Transaction* trans);
diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc
index 96a3622..f524c60 100644
--- a/net/http/http_cache_transaction.cc
+++ b/net/http/http_cache_transaction.cc
@@ -314,11 +314,14 @@ const HttpResponseInfo* HttpCache::Transaction::GetResponseInfo() const {
}
LoadState HttpCache::Transaction::GetLoadState() const {
- if (network_trans_.get())
- return network_trans_->GetLoadState();
- if (entry_ || !request_)
- return LOAD_STATE_IDLE;
- return LOAD_STATE_WAITING_FOR_CACHE;
+ LoadState state = GetWriterLoadState();
+ if (state != LOAD_STATE_WAITING_FOR_CACHE)
+ return state;
+
+ if (cache_)
+ return cache_->GetLoadStateForPendingTransaction(this);
+
+ return LOAD_STATE_IDLE;
}
uint64 HttpCache::Transaction::GetUploadProgress() const {
@@ -366,6 +369,14 @@ bool HttpCache::Transaction::AddTruncatedFlag() {
return true;
}
+LoadState HttpCache::Transaction::GetWriterLoadState() const {
+ if (network_trans_.get())
+ return network_trans_->GetLoadState();
+ if (entry_ || !request_)
+ return LOAD_STATE_IDLE;
+ return LOAD_STATE_WAITING_FOR_CACHE;
+}
+
//-----------------------------------------------------------------------------
void HttpCache::Transaction::DoCallback(int rv) {
diff --git a/net/http/http_cache_transaction.h b/net/http/http_cache_transaction.h
index a458379..f19f76a 100644
--- a/net/http/http_cache_transaction.h
+++ b/net/http/http_cache_transaction.h
@@ -97,6 +97,12 @@ class HttpCache::Transaction : public HttpTransaction {
// success.
bool AddTruncatedFlag();
+ // Returns the LoadState of the writer transaction of a given ActiveEntry. In
+ // other words, returns the LoadState of this transaction without asking the
+ // http cache, because this transaction should be the one currently writing
+ // to the cache entry.
+ LoadState GetWriterLoadState() const;
+
CompletionCallback* io_callback() { return &io_callback_; }
private:
diff --git a/net/http/http_cache_unittest.cc b/net/http/http_cache_unittest.cc
index dc114da..e341674 100644
--- a/net/http/http_cache_unittest.cc
+++ b/net/http/http_cache_unittest.cc
@@ -1401,10 +1401,17 @@ TEST(HttpCache, SimpleGET_ManyReaders) {
c->result = cache.http_cache()->CreateTransaction(&c->trans);
EXPECT_EQ(net::OK, c->result);
+ EXPECT_EQ(net::LOAD_STATE_IDLE, c->trans->GetLoadState());
c->result = c->trans->Start(&request, &c->callback, net::BoundNetLog());
}
+ // All requests are waiting for the active entry.
+ for (int i = 0; i < kNumTransactions; ++i) {
+ Context* c = context_list[i];
+ EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE, c->trans->GetLoadState());
+ }
+
// Allow all requests to move from the Create queue to the active entry.
MessageLoop::current()->RunAllPending();
@@ -1415,6 +1422,13 @@ TEST(HttpCache, SimpleGET_ManyReaders) {
EXPECT_EQ(0, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
+ // All requests depend on the writer, and the writer is between Start and
+ // Read, i.e. idle.
+ for (int i = 0; i < kNumTransactions; ++i) {
+ Context* c = context_list[i];
+ EXPECT_EQ(net::LOAD_STATE_IDLE, c->trans->GetLoadState());
+ }
+
for (int i = 0; i < kNumTransactions; ++i) {
Context* c = context_list[i];
if (c->result == net::ERR_IO_PENDING)
diff --git a/net/http/http_transaction_unittest.h b/net/http/http_transaction_unittest.h
index baed540..e550903 100644
--- a/net/http/http_transaction_unittest.h
+++ b/net/http/http_transaction_unittest.h
@@ -291,7 +291,8 @@ class MockNetworkTransaction : public net::HttpTransaction {
}
virtual net::LoadState GetLoadState() const {
- NOTREACHED() << "define some mock state transitions";
+ if (data_cursor_)
+ return net::LOAD_STATE_READING_RESPONSE;
return net::LOAD_STATE_IDLE;
}