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

Unified Diff: net/http/http_transaction_test_util.cc

Issue 2519473002: Fixes the cache lock issue. (Closed)
Patch Set: Initial patch Created 4 years 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 side-by-side diff with in-line comments
Download patch
Index: net/http/http_transaction_test_util.cc
diff --git a/net/http/http_transaction_test_util.cc b/net/http/http_transaction_test_util.cc
index 556033a0580d4a5a9b77875fb3ee2a3e3d441fa3..8b31842b00fb2972d7adc91ab104589c9fa619b7 100644
--- a/net/http/http_transaction_test_util.cc
+++ b/net/http/http_transaction_test_util.cc
@@ -148,6 +148,13 @@ MockHttpRequest::MockHttpRequest(const MockTransaction& t) {
load_flags = t.load_flags;
}
+Context::Context() : result(ERR_IO_PENDING) {}
+Context::~Context() {
+ if (trans.get()) {
+ trans->Orphan(std::move(trans));
+ }
+}
+
//-----------------------------------------------------------------------------
// static
@@ -163,6 +170,7 @@ TestTransactionConsumer::TestTransactionConsumer(
}
TestTransactionConsumer::~TestTransactionConsumer() {
+ trans_->Orphan(std::move(trans_));
}
void TestTransactionConsumer::Start(const HttpRequestInfo* request,
@@ -250,6 +258,10 @@ int MockNetworkTransaction::Start(const HttpRequestInfo* request,
return StartInternal(request, callback, net_log);
}
+void MockNetworkTransaction::Orphan(std::unique_ptr<HttpTransaction> trans) {
+ trans.reset();
+}
+
int MockNetworkTransaction::RestartIgnoringLastError(
const CompletionCallback& callback) {
return ERR_FAILED;
@@ -487,7 +499,7 @@ int MockNetworkTransaction::ResumeNetworkStart() {
void MockNetworkTransaction::GetConnectionAttempts(
ConnectionAttempts* out) const {
- NOTIMPLEMENTED();
+ return;
}
void MockNetworkTransaction::CallbackLater(const CompletionCallback& callback,
@@ -581,4 +593,242 @@ int ReadTransaction(HttpTransaction* trans, std::string* result) {
return OK;
}
+// The 1st transaction reads from the network and the subsequent transactions
+// are able to read from the cache even before the complete response is written
+// to the cache.
+int ReadSharedWritersCacheRead(std::vector<Context*>& context_list,
+ std::vector<std::string>& results) {
+ int rv;
+
+ size_t i = 0;
+ HttpTransaction* trans = nullptr;
+ do {
+ Context* c = context_list.at(i);
+ trans = c->trans.get();
+ scoped_refptr<IOBuffer> buf(new IOBuffer(256));
+ rv = trans->Read(buf.get(), 256, c->callback.callback());
+ if (rv == ERR_IO_PENDING)
+ rv = c->callback.WaitForResult();
+
+ if (rv > 0)
+ results.at(i).append(buf->data(), rv);
+ else if (rv < 0)
+ return rv;
+
+ i = (i == context_list.size() - 1) ? 0 : i + 1;
+ } while (rv > 0);
+
+ return OK;
+}
+
+// The 1st transaction reads from the network and read is invoked on other
+// transactions even before the 1st one's io callback is invoked. The other
+// transactions should have data written in their read buffers as part
+// of the 1st transaction's callback.
+int ReadSharedWritersJoinedRead(std::vector<Context*>& context_list,
+ std::vector<std::string>& results) {
+ int rv = 0;
+ do {
+ // Invoke Read for all transactions.
+ std::vector<scoped_refptr<IOBuffer>> buffers(context_list.size());
+ for (size_t i = 0; i < context_list.size(); i++) {
+ HttpTransaction* trans = context_list[i]->trans.get();
+ buffers[i] = new IOBuffer(30);
+ rv = trans->Read(buffers[i].get(), 30,
+ context_list[i]->callback.callback());
+ // Invoking stop caching here should not have any impact since there are
+ // multiple transactions waiting for this resource.
+ if (i == 0)
+ trans->StopCaching();
+ }
+ if (rv == ERR_IO_PENDING) {
+ Context* ct = *(context_list.begin());
+ rv = ct->callback.WaitForResult();
+ }
+
+ if (rv > 0) {
+ for (size_t i = 0; i < results.size(); i++) {
+ results[i].append(buffers[i]->data(), rv);
+ }
+ } else if (rv < 0)
+ return rv;
+
+ } while (rv > 0);
+
+ return OK;
+}
+
+int ReadSharedWritersJoinedReadDoneReading(std::vector<Context*>& context_list,
+ std::vector<std::string>& results) {
+ int rv = 0;
+ int cnt = 0;
+ do {
+ // Invoke Read for all transactions.
+ std::vector<scoped_refptr<IOBuffer>> buffers(context_list.size());
+ for (size_t i = 0; i < context_list.size(); i++) {
+ HttpTransaction* trans = context_list[i]->trans.get();
+ buffers[i] = new IOBuffer(30);
+ rv = trans->Read(buffers[i].get(), 30,
+ context_list[i]->callback.callback());
+ }
+ if (rv == ERR_IO_PENDING) {
+ Context* ct = *(context_list.begin());
+ rv = ct->callback.WaitForResult();
+ }
+
+ if (rv > 0) {
+ for (size_t i = 0; i < results.size(); i++) {
+ results[i].append(buffers[i]->data(), rv);
+ }
+ } else if (rv < 0)
+ return rv;
+
+ cnt++;
+ if (cnt == 2) {
+ context_list[0]->trans.get()->DoneReading();
+ }
+ } while (cnt < 2);
+
+ return OK;
+}
+
+// The 1st transaction reads from the network and read is invoked on other
+// transactions even before the 1st one's io callback is invoked. Also, the
+// first transaction is deleted before the io callback is invoked. The other
+// transactions should have data written in their read buffers as part
+// of the 1st transaction's callback.
+int ReadSharedWritersJoinedReadDoomCurrentWriter(
+ std::vector<Context*>& context_list,
+ std::vector<std::string>& results) {
+ int rv = 0;
+ bool first_iter = true;
+ do {
+ // Invoke Read for all transactions.
+ std::vector<scoped_refptr<IOBuffer>> buffers(context_list.size());
+ for (size_t i = 0; i < context_list.size(); i++) {
+ HttpTransaction* trans = context_list[i]->trans.get();
+ buffers[i] = new IOBuffer(30);
+ rv = trans->Read(buffers[i].get(), 30,
+ context_list[i]->callback.callback());
+ }
+
+ // Delete the 1st transaction.
+ if (first_iter) {
+ Context* c = context_list[0];
+ context_list.erase(context_list.begin());
+ delete c;
+ buffers.erase(buffers.begin());
+ }
+
+ if (rv == ERR_IO_PENDING) {
+ Context* ct = *(context_list.begin());
+ rv = ct->callback.WaitForResult();
+ }
+
+ if (rv > 0) {
+ for (size_t i = 0; i < context_list.size(); i++) {
+ results[i].append(buffers[i]->data(), rv);
+ }
+ } else if (rv < 0)
+ return rv;
+
+ first_iter = false;
+ } while (rv > 0);
+
+ return OK;
+}
+
+int ReadSharedWritersJoinedReadDeleteWaitingWriter(
+ std::vector<Context*>& context_list,
+ std::vector<std::string>& results) {
+ int rv = 0;
+ bool first_iter = true;
+ do {
+ // Invoke Read for all transactions.
+ std::vector<scoped_refptr<IOBuffer>> buffers(context_list.size());
+ for (size_t i = 0; i < context_list.size(); i++) {
+ HttpTransaction* trans = context_list[i]->trans.get();
+ buffers[i] = new IOBuffer(30);
+ rv = trans->Read(buffers[i].get(), 30,
+ context_list[i]->callback.callback());
+ }
+
+ // Remove a waiting writer transaction.
+ if (first_iter) {
+ auto it = context_list.begin();
+ it++;
+ if (it != context_list.end()) {
+ Context* c = *it;
+ context_list.erase(it);
+ delete c;
+ auto it1 = buffers.begin();
+ it1++;
+ buffers.erase(it1);
+ }
+ }
+
+ if (rv == ERR_IO_PENDING) {
+ Context* ct = *(context_list.begin());
+ rv = ct->callback.WaitForResult();
+ }
+
+ if (rv > 0) {
+ for (size_t i = 0; i < context_list.size(); i++) {
+ results[i].append(buffers[i]->data(), rv);
+ }
+ } else if (rv < 0)
+ return rv;
+
+ first_iter = false;
+ } while (rv > 0);
+
+ return OK;
+}
+
+int ReadSharedWritersJoinedReadDeleteIdleWriter(
+ std::vector<Context*>& context_list,
+ std::vector<std::string>& results) {
+ int rv = 0;
+ bool first_iter = true;
+ do {
+ // Invoke Read for all transactions.
+ std::vector<scoped_refptr<IOBuffer>> buffers(context_list.size());
+ for (size_t i = 0; i < context_list.size(); i++) {
+ HttpTransaction* trans = context_list[i]->trans.get();
+ buffers[i] = new IOBuffer(30);
+ // Do not invoke Read on the first transaction.
+ if (first_iter && i == 0)
+ continue;
+ rv = trans->Read(buffers[i].get(), 30,
+ context_list[i]->callback.callback());
+ }
+
+ // Remove the idle writer transaction.
+ if (first_iter) {
+ auto it = context_list.begin();
+ Context* c = *it;
+ context_list.erase(it);
+ delete c;
+ auto it1 = buffers.begin();
+ buffers.erase(it1);
+ }
+
+ if (rv == ERR_IO_PENDING) {
+ Context* ct = *(context_list.begin());
+ rv = ct->callback.WaitForResult();
+ }
+
+ if (rv > 0) {
+ for (size_t i = 0; i < context_list.size(); i++) {
+ results[i].append(buffers[i]->data(), rv);
+ }
+ } else if (rv < 0)
+ return rv;
+
+ first_iter = false;
+ } while (rv > 0);
+
+ return OK;
+}
+
} // namespace net

Powered by Google App Engine
This is Rietveld 408576698