diff options
author | willchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-25 20:42:55 +0000 |
---|---|---|
committer | willchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-25 20:42:55 +0000 |
commit | 725355a29e53a5bc0f37237b9be5023a35e0c09e (patch) | |
tree | 89338fa14de0636689c57716f8ffe1485540d3ea /net | |
parent | 78c3a37c716807e8f50444da64d6506632e13669 (diff) | |
download | chromium_src-725355a29e53a5bc0f37237b9be5023a35e0c09e.zip chromium_src-725355a29e53a5bc0f37237b9be5023a35e0c09e.tar.gz chromium_src-725355a29e53a5bc0f37237b9be5023a35e0c09e.tar.bz2 |
Reverting 12479 which reverted 12470.
This change is the same as 12470, except with HttpRequestInfo::priority initialized in the initializer list, which should fix the purify errors.
Review URL: http://codereview.chromium.org/53066
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@12490 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/base/client_socket_handle.cc | 3 | ||||
-rw-r--r-- | net/base/client_socket_handle.h | 7 | ||||
-rw-r--r-- | net/base/client_socket_pool.cc | 19 | ||||
-rw-r--r-- | net/base/client_socket_pool.h | 54 | ||||
-rw-r--r-- | net/base/client_socket_pool_unittest.cc | 169 | ||||
-rw-r--r-- | net/http/http_network_transaction.cc | 22 | ||||
-rw-r--r-- | net/http/http_request_info.h | 6 | ||||
-rw-r--r-- | net/url_request/url_request.cc | 3 | ||||
-rw-r--r-- | net/url_request/url_request.h | 23 | ||||
-rw-r--r-- | net/url_request/url_request_http_job.cc | 1 |
10 files changed, 199 insertions, 108 deletions
diff --git a/net/base/client_socket_handle.cc b/net/base/client_socket_handle.cc index ff81c0a..f5ab056 100644 --- a/net/base/client_socket_handle.cc +++ b/net/base/client_socket_handle.cc @@ -18,10 +18,11 @@ ClientSocketHandle::~ClientSocketHandle() { } int ClientSocketHandle::Init(const std::string& group_name, + int priority, CompletionCallback* callback) { Reset(); group_name_ = group_name; - return pool_->RequestSocket(this, callback); + return pool_->RequestSocket(this, priority, callback); } void ClientSocketHandle::Reset() { diff --git a/net/base/client_socket_handle.h b/net/base/client_socket_handle.h index c107a16..e0d9e73 100644 --- a/net/base/client_socket_handle.h +++ b/net/base/client_socket_handle.h @@ -32,7 +32,8 @@ class ClientSocketHandle { // Initializes a ClientSocketHandle object, which involves talking to the // ClientSocketPool to locate a socket to possibly reuse. This method - // returns either OK or ERR_IO_PENDING. + // returns either OK or ERR_IO_PENDING. On ERR_IO_PENDING, |priority| is + // used to determine the placement in ClientSocketPool's wait list. // // If this method succeeds, then the socket member will be set to an existing // socket if an existing socket was available to reuse. Otherwise, the @@ -43,7 +44,9 @@ class ClientSocketHandle { // // Init may be called multiple times. // - int Init(const std::string& group_name, CompletionCallback* callback); + int Init(const std::string& group_name, + int priority, + CompletionCallback* callback); // An initialized handle can be reset, which causes it to return to the // un-initialized state. This releases the underlying socket, which in the diff --git a/net/base/client_socket_pool.cc b/net/base/client_socket_pool.cc index 2092017..651fbe2 100644 --- a/net/base/client_socket_pool.cc +++ b/net/base/client_socket_pool.cc @@ -41,7 +41,21 @@ ClientSocketPool::~ClientSocketPool() { DCHECK(group_map_.empty()); } +// InsertRequestIntoQueue inserts the request into the queue based on +// priority. Highest priorities are closest to the front. Older requests are +// prioritized over requests of equal priority. +// +// static +void ClientSocketPool::InsertRequestIntoQueue(const Request& r, + RequestQueue* pending_requests) { + RequestQueue::iterator it = pending_requests->begin(); + while (it != pending_requests->end() && r.priority <= it->priority) + ++it; + pending_requests->insert(it, r); +} + int ClientSocketPool::RequestSocket(ClientSocketHandle* handle, + int priority, CompletionCallback* callback) { Group& group = group_map_[handle->group_name_]; @@ -51,7 +65,8 @@ int ClientSocketPool::RequestSocket(ClientSocketHandle* handle, r.handle = handle; DCHECK(callback); r.callback = callback; - group.pending_requests.push_back(r); + r.priority = priority; + InsertRequestIntoQueue(r, &group.pending_requests); return ERR_IO_PENDING; } @@ -183,7 +198,7 @@ void ClientSocketPool::DoReleaseSocket(const std::string& group_name, if (!group.pending_requests.empty()) { Request r = group.pending_requests.front(); group.pending_requests.pop_front(); - int rv = RequestSocket(r.handle, NULL); + int rv = RequestSocket(r.handle, r.priority, NULL); DCHECK(rv == OK); r.callback->Run(rv); return; diff --git a/net/base/client_socket_pool.h b/net/base/client_socket_pool.h index a313a80..dd08c24 100644 --- a/net/base/client_socket_pool.h +++ b/net/base/client_socket_pool.h @@ -35,7 +35,8 @@ class ClientSocketPool : public base::RefCounted<ClientSocketPool> { // handle will be initialized without a socket such that the consumer needs // to supply a socket, or 3) the handle will be added to a wait list until a // socket is available to reuse or the opportunity to create a new socket - // arises. The completion callback is notified in the 3rd case. + // arises. The completion callback is notified in the 3rd case. |priority| + // will determine the placement into the wait list. // // If this function returns OK, then |handle| is initialized upon return. // The |handle|'s is_initialized method will return true in this case. If a @@ -47,7 +48,9 @@ class ClientSocketPool : public base::RefCounted<ClientSocketPool> { // If ERR_IO_PENDING is returned, then the completion callback will be called // when |handle| has been initialized. // - int RequestSocket(ClientSocketHandle* handle, CompletionCallback* callback); + int RequestSocket(ClientSocketHandle* handle, + int priority, + CompletionCallback* callback); // Called to cancel a RequestSocket call that returned ERR_IO_PENDING. The // same handle parameter must be passed to this method as was passed to the @@ -75,30 +78,12 @@ class ClientSocketPool : public base::RefCounted<ClientSocketPool> { typedef scoped_ptr<ClientSocket> ClientSocketPtr; - ~ClientSocketPool(); - - // Closes all idle sockets if |force| is true. Else, only closes idle - // sockets that timed out or can't be reused. - void CleanupIdleSockets(bool force); - - // Called when the number of idle sockets changes. - void IncrementIdleCount(); - void DecrementIdleCount(); - - // Called via PostTask by ReleaseSocket. - void DoReleaseSocket(const std::string& group_name, ClientSocketPtr* ptr); - - // Called when timer_ fires. This method scans the idle sockets removing - // sockets that timed out or can't be reused. - void OnCleanupTimerFired() { - CleanupIdleSockets(false); - } - // A Request is allocated per call to RequestSocket that results in // ERR_IO_PENDING. struct Request { ClientSocketHandle* handle; CompletionCallback* callback; + int priority; }; // Entry for a persistent socket which became idle at time |start_time|. @@ -116,16 +101,41 @@ class ClientSocketPool : public base::RefCounted<ClientSocketPool> { bool ShouldCleanup(base::TimeTicks now) const; }; + typedef std::deque<Request> RequestQueue; + // A Group is allocated per group_name when there are idle sockets or pending // requests. Otherwise, the Group object is removed from the map. struct Group { Group() : active_socket_count(0) {} std::deque<IdleSocket> idle_sockets; - std::deque<Request> pending_requests; + RequestQueue pending_requests; int active_socket_count; }; typedef std::map<std::string, Group> GroupMap; + + ~ClientSocketPool(); + + static void InsertRequestIntoQueue(const Request& r, + RequestQueue* pending_requests); + + // Closes all idle sockets if |force| is true. Else, only closes idle + // sockets that timed out or can't be reused. + void CleanupIdleSockets(bool force); + + // Called when the number of idle sockets changes. + void IncrementIdleCount(); + void DecrementIdleCount(); + + // Called via PostTask by ReleaseSocket. + void DoReleaseSocket(const std::string& group_name, ClientSocketPtr* ptr); + + // Called when timer_ fires. This method scans the idle sockets removing + // sockets that timed out or can't be reused. + void OnCleanupTimerFired() { + CleanupIdleSockets(false); + } + GroupMap group_map_; // Timer used to periodically prune idle sockets that timed out or can't be diff --git a/net/base/client_socket_pool_unittest.cc b/net/base/client_socket_pool_unittest.cc index 3fb5fd4..8849781 100644 --- a/net/base/client_socket_pool_unittest.cc +++ b/net/base/client_socket_pool_unittest.cc @@ -11,10 +11,16 @@ namespace { -typedef testing::Test ClientSocketPoolTest; - const int kMaxSocketsPerGroup = 6; +// Note that the first and the last are the same, the first should be handled +// before the last, since it was inserted first. +const int kPriorities[10] = { 1, 7, 9, 5, 6, 2, 8, 3, 4, 1 }; + +// This is the number of extra requests beyond the first few that use up all +// available sockets in the socket group. +const int kNumPendingRequests = arraysize(kPriorities); + class MockClientSocket : public net::ClientSocket { public: MockClientSocket() : connected_(false) { @@ -59,12 +65,16 @@ int MockClientSocket::allocation_count = 0; class TestSocketRequest : public CallbackRunner< Tuple1<int> > { public: - explicit TestSocketRequest(net::ClientSocketPool* pool) : handle(pool) {} + TestSocketRequest( + net::ClientSocketPool* pool, + std::vector<TestSocketRequest*>* request_order) + : handle(pool), request_order_(request_order) {} net::ClientSocketHandle handle; void EnsureSocket() { DCHECK(handle.is_initialized()); + request_order_->push_back(this); if (!handle.socket()) { handle.set_socket(new MockClientSocket()); handle.socket()->Connect(NULL); @@ -78,20 +88,32 @@ class TestSocketRequest : public CallbackRunner< Tuple1<int> > { } static int completion_count; + + private: + std::vector<TestSocketRequest*>* request_order_; }; int TestSocketRequest::completion_count = 0; -} // namespace +class ClientSocketPoolTest : public testing::Test { + protected: + ClientSocketPoolTest() + : pool_(new net::ClientSocketPool(kMaxSocketsPerGroup)) {} -TEST(ClientSocketPoolTest, Basic) { - scoped_refptr<net::ClientSocketPool> pool = - new net::ClientSocketPool(kMaxSocketsPerGroup); + virtual void SetUp() { + MockClientSocket::allocation_count = 0; + TestSocketRequest::completion_count = 0; + } + + scoped_refptr<net::ClientSocketPool> pool_; + std::vector<TestSocketRequest*> request_order_; +}; - TestSocketRequest r(pool); +TEST_F(ClientSocketPoolTest, Basic) { + TestSocketRequest r(pool_.get(), &request_order_); int rv; - rv = r.handle.Init("a", &r); + rv = r.handle.Init("a", 0, &r); EXPECT_EQ(net::OK, rv); EXPECT_TRUE(r.handle.is_initialized()); @@ -101,14 +123,11 @@ TEST(ClientSocketPoolTest, Basic) { MessageLoop::current()->RunAllPending(); } -TEST(ClientSocketPoolTest, WithIdleConnection) { - scoped_refptr<net::ClientSocketPool> pool = - new net::ClientSocketPool(kMaxSocketsPerGroup); - - TestSocketRequest r(pool); +TEST_F(ClientSocketPoolTest, WithIdleConnection) { + TestSocketRequest r(pool_.get(), &request_order_); int rv; - rv = r.handle.Init("a", &r); + rv = r.handle.Init("a", 0, &r); EXPECT_EQ(net::OK, rv); EXPECT_TRUE(r.handle.is_initialized()); @@ -123,27 +142,24 @@ TEST(ClientSocketPoolTest, WithIdleConnection) { MessageLoop::current()->RunAllPending(); } -TEST(ClientSocketPoolTest, PendingRequests) { - scoped_refptr<net::ClientSocketPool> pool = - new net::ClientSocketPool(kMaxSocketsPerGroup); - +TEST_F(ClientSocketPoolTest, PendingRequests) { int rv; - scoped_ptr<TestSocketRequest> reqs[kMaxSocketsPerGroup + 10]; - for (size_t i = 0; i < arraysize(reqs); ++i) - reqs[i].reset(new TestSocketRequest(pool)); + scoped_ptr<TestSocketRequest> reqs[kMaxSocketsPerGroup + kNumPendingRequests]; - // Reset - MockClientSocket::allocation_count = 0; - TestSocketRequest::completion_count = 0; + for (size_t i = 0; i < arraysize(reqs); ++i) + reqs[i].reset(new TestSocketRequest(pool_.get(), &request_order_)); // Create connections or queue up requests. - for (size_t i = 0; i < arraysize(reqs); ++i) { - rv = reqs[i]->handle.Init("a", reqs[i].get()); - if (rv != net::ERR_IO_PENDING) { - EXPECT_EQ(net::OK, rv); - reqs[i]->EnsureSocket(); - } + for (int i = 0; i < kMaxSocketsPerGroup; ++i) { + rv = reqs[i]->handle.Init("a", 5, reqs[i].get()); + EXPECT_EQ(net::OK, rv); + reqs[i]->EnsureSocket(); + } + for (int i = 0; i < kNumPendingRequests; ++i) { + rv = reqs[kMaxSocketsPerGroup + i]->handle.Init( + "a", kPriorities[i], reqs[kMaxSocketsPerGroup + i].get()); + EXPECT_EQ(net::ERR_IO_PENDING, rv); } // Release any connections until we have no connections. @@ -160,26 +176,36 @@ TEST(ClientSocketPoolTest, PendingRequests) { } while (released_one); EXPECT_EQ(kMaxSocketsPerGroup, MockClientSocket::allocation_count); - EXPECT_EQ(10, TestSocketRequest::completion_count); -} + EXPECT_EQ(kNumPendingRequests, TestSocketRequest::completion_count); -TEST(ClientSocketPoolTest, PendingRequests_NoKeepAlive) { - scoped_refptr<net::ClientSocketPool> pool = - new net::ClientSocketPool(kMaxSocketsPerGroup); + for (int i = 0; i < kMaxSocketsPerGroup; ++i) { + EXPECT_EQ(request_order_[i], reqs[i].get()) << + "Request " << i << " was not in order."; + } + for (int i = 0; i < kNumPendingRequests - 1; ++i) { + int index_in_queue = (kNumPendingRequests - 1) - kPriorities[i]; + EXPECT_EQ(request_order_[kMaxSocketsPerGroup + index_in_queue], + reqs[kMaxSocketsPerGroup + i].get()) << + "Request " << kMaxSocketsPerGroup + i << " was not in order."; + } + + EXPECT_EQ(request_order_[arraysize(reqs) - 1], + reqs[arraysize(reqs) - 1].get()) << + "The last request with priority 1 should not have been inserted " + "earlier into the queue."; +} + +TEST_F(ClientSocketPoolTest, PendingRequests_NoKeepAlive) { int rv; - scoped_ptr<TestSocketRequest> reqs[kMaxSocketsPerGroup + 10]; + scoped_ptr<TestSocketRequest> reqs[kMaxSocketsPerGroup + kNumPendingRequests]; for (size_t i = 0; i < arraysize(reqs); ++i) - reqs[i].reset(new TestSocketRequest(pool)); - - // Reset - MockClientSocket::allocation_count = 0; - TestSocketRequest::completion_count = 0; + reqs[i].reset(new TestSocketRequest(pool_.get(), &request_order_)); // Create connections or queue up requests. for (size_t i = 0; i < arraysize(reqs); ++i) { - rv = reqs[i]->handle.Init("a", reqs[i].get()); + rv = reqs[i]->handle.Init("a", 0, reqs[i].get()); if (rv != net::ERR_IO_PENDING) { EXPECT_EQ(net::OK, rv); reqs[i]->EnsureSocket(); @@ -200,31 +226,29 @@ TEST(ClientSocketPoolTest, PendingRequests_NoKeepAlive) { } } while (released_one); - EXPECT_EQ(kMaxSocketsPerGroup + 10, MockClientSocket::allocation_count); - EXPECT_EQ(10, TestSocketRequest::completion_count); + EXPECT_EQ(kMaxSocketsPerGroup + kNumPendingRequests, + MockClientSocket::allocation_count); + EXPECT_EQ(kNumPendingRequests, TestSocketRequest::completion_count); } -TEST(ClientSocketPoolTest, CancelRequest) { - scoped_refptr<net::ClientSocketPool> pool = - new net::ClientSocketPool(kMaxSocketsPerGroup); - +TEST_F(ClientSocketPoolTest, CancelRequest) { int rv; - scoped_ptr<TestSocketRequest> reqs[kMaxSocketsPerGroup + 10]; - for (size_t i = 0; i < arraysize(reqs); ++i) - reqs[i].reset(new TestSocketRequest(pool)); + scoped_ptr<TestSocketRequest> reqs[kMaxSocketsPerGroup + kNumPendingRequests]; - // Reset - MockClientSocket::allocation_count = 0; - TestSocketRequest::completion_count = 0; + for (size_t i = 0; i < arraysize(reqs); ++i) + reqs[i].reset(new TestSocketRequest(pool_.get(), &request_order_)); // Create connections or queue up requests. - for (size_t i = 0; i < arraysize(reqs); ++i) { - rv = reqs[i]->handle.Init("a", reqs[i].get()); - if (rv != net::ERR_IO_PENDING) { - EXPECT_EQ(net::OK, rv); - reqs[i]->EnsureSocket(); - } + for (int i = 0; i < kMaxSocketsPerGroup; ++i) { + rv = reqs[i]->handle.Init("a", 5, reqs[i].get()); + EXPECT_EQ(net::OK, rv); + reqs[i]->EnsureSocket(); + } + for (int i = 0; i < kNumPendingRequests; ++i) { + rv = reqs[kMaxSocketsPerGroup + i]->handle.Init( + "a", kPriorities[i], reqs[kMaxSocketsPerGroup + i].get()); + EXPECT_EQ(net::ERR_IO_PENDING, rv); } // Cancel a request. @@ -246,5 +270,26 @@ TEST(ClientSocketPoolTest, CancelRequest) { } while (released_one); EXPECT_EQ(kMaxSocketsPerGroup, MockClientSocket::allocation_count); - EXPECT_EQ(9, TestSocketRequest::completion_count); + EXPECT_EQ(kNumPendingRequests - 1, TestSocketRequest::completion_count); + for (int i = 0; i < kMaxSocketsPerGroup; ++i) { + EXPECT_EQ(request_order_[i], reqs[i].get()) << + "Request " << i << " was not in order."; + } + + for (int i = 0; i < kNumPendingRequests - 1; ++i) { + if (i == 2) continue; + int index_in_queue = (kNumPendingRequests - 1) - kPriorities[i]; + if (kPriorities[i] < kPriorities[index_to_cancel - kMaxSocketsPerGroup]) + index_in_queue--; + EXPECT_EQ(request_order_[kMaxSocketsPerGroup + index_in_queue], + reqs[kMaxSocketsPerGroup + i].get()) << + "Request " << kMaxSocketsPerGroup + i << " was not in order."; + } + + EXPECT_EQ(request_order_[arraysize(reqs) - 2], + reqs[arraysize(reqs) - 1].get()) << + "The last request with priority 1 should not have been inserted " + "earlier into the queue."; } + +} // namespace diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc index ae1d9fd..c7ea56f 100644 --- a/net/http/http_network_transaction.cc +++ b/net/http/http_network_transaction.cc @@ -377,7 +377,7 @@ int HttpNetworkTransaction::DoLoop(int result) { next_state_ = STATE_NONE; switch (state) { case STATE_RESOLVE_PROXY: - DCHECK(rv == OK); + DCHECK_EQ(OK, rv); TRACE_EVENT_BEGIN("http.resolve_proxy", request_, request_->url.spec()); rv = DoResolveProxy(); break; @@ -386,7 +386,7 @@ int HttpNetworkTransaction::DoLoop(int result) { TRACE_EVENT_END("http.resolve_proxy", request_, request_->url.spec()); break; case STATE_INIT_CONNECTION: - DCHECK(rv == OK); + DCHECK_EQ(OK, rv); TRACE_EVENT_BEGIN("http.init_conn", request_, request_->url.spec()); rv = DoInitConnection(); break; @@ -395,7 +395,7 @@ int HttpNetworkTransaction::DoLoop(int result) { TRACE_EVENT_END("http.init_conn", request_, request_->url.spec()); break; case STATE_RESOLVE_HOST: - DCHECK(rv == OK); + DCHECK_EQ(OK, rv); TRACE_EVENT_BEGIN("http.resolve_host", request_, request_->url.spec()); rv = DoResolveHost(); break; @@ -404,7 +404,7 @@ int HttpNetworkTransaction::DoLoop(int result) { TRACE_EVENT_END("http.resolve_host", request_, request_->url.spec()); break; case STATE_CONNECT: - DCHECK(rv == OK); + DCHECK_EQ(OK, rv); TRACE_EVENT_BEGIN("http.connect", request_, request_->url.spec()); rv = DoConnect(); break; @@ -413,7 +413,7 @@ int HttpNetworkTransaction::DoLoop(int result) { TRACE_EVENT_END("http.connect", request_, request_->url.spec()); break; case STATE_SSL_CONNECT_OVER_TUNNEL: - DCHECK(rv == OK); + DCHECK_EQ(OK, rv); TRACE_EVENT_BEGIN("http.ssl_tunnel", request_, request_->url.spec()); rv = DoSSLConnectOverTunnel(); break; @@ -422,7 +422,7 @@ int HttpNetworkTransaction::DoLoop(int result) { TRACE_EVENT_END("http.ssl_tunnel", request_, request_->url.spec()); break; case STATE_WRITE_HEADERS: - DCHECK(rv == OK); + DCHECK_EQ(OK, rv); TRACE_EVENT_BEGIN("http.write_headers", request_, request_->url.spec()); rv = DoWriteHeaders(); break; @@ -431,7 +431,7 @@ int HttpNetworkTransaction::DoLoop(int result) { TRACE_EVENT_END("http.write_headers", request_, request_->url.spec()); break; case STATE_WRITE_BODY: - DCHECK(rv == OK); + DCHECK_EQ(OK, rv); TRACE_EVENT_BEGIN("http.write_body", request_, request_->url.spec()); rv = DoWriteBody(); break; @@ -440,7 +440,7 @@ int HttpNetworkTransaction::DoLoop(int result) { TRACE_EVENT_END("http.write_body", request_, request_->url.spec()); break; case STATE_READ_HEADERS: - DCHECK(rv == OK); + DCHECK_EQ(OK, rv); TRACE_EVENT_BEGIN("http.read_headers", request_, request_->url.spec()); rv = DoReadHeaders(); break; @@ -449,7 +449,7 @@ int HttpNetworkTransaction::DoLoop(int result) { TRACE_EVENT_END("http.read_headers", request_, request_->url.spec()); break; case STATE_READ_BODY: - DCHECK(rv == OK); + DCHECK_EQ(OK, rv); TRACE_EVENT_BEGIN("http.read_body", request_, request_->url.spec()); rv = DoReadBody(); break; @@ -458,7 +458,7 @@ int HttpNetworkTransaction::DoLoop(int result) { TRACE_EVENT_END("http.read_body", request_, request_->url.spec()); break; case STATE_DRAIN_BODY_FOR_AUTH_RESTART: - DCHECK(rv == OK); + DCHECK_EQ(OK, rv); TRACE_EVENT_BEGIN("http.drain_body_for_auth_restart", request_, request_->url.spec()); rv = DoDrainBodyForAuthRestart(); @@ -527,7 +527,7 @@ int HttpNetworkTransaction::DoInitConnection() { connection_group.append(request_->url.GetOrigin().spec()); DCHECK(!connection_group.empty()); - return connection_.Init(connection_group, &io_callback_); + return connection_.Init(connection_group, request_->priority, &io_callback_); } int HttpNetworkTransaction::DoInitConnectionComplete(int result) { diff --git a/net/http/http_request_info.h b/net/http/http_request_info.h index de817fa..1382171 100644 --- a/net/http/http_request_info.h +++ b/net/http/http_request_info.h @@ -5,6 +5,7 @@ #ifndef NET_HTTP_HTTP_REQUEST_INFO_H__ #define NET_HTTP_HTTP_REQUEST_INFO_H__ +#include <string> #include "base/ref_counted.h" #include "googleurl/src/gurl.h" #include "net/base/upload_data.h" @@ -13,7 +14,7 @@ namespace net { class HttpRequestInfo { public: - HttpRequestInfo() : load_flags(0) { + HttpRequestInfo() : load_flags(0), priority(0) { } // The requested URL. @@ -37,6 +38,9 @@ class HttpRequestInfo { // Any load flags (see load_flags.h). int load_flags; + + // The priority level for this request. + int priority; }; } // namespace net diff --git a/net/url_request/url_request.cc b/net/url_request/url_request.cc index 3de8439..335f974 100644 --- a/net/url_request/url_request.cc +++ b/net/url_request/url_request.cc @@ -47,7 +47,8 @@ URLRequest::URLRequest(const GURL& url, Delegate* delegate) user_data_(NULL), enable_profiling_(false), redirect_limit_(kMaxRedirects), - final_upload_progress_(0) { + final_upload_progress_(0), + priority_(0) { URLREQUEST_COUNT_CTOR(); SIMPLE_STATS_COUNTER("URLRequestCount"); origin_pid_ = base::GetCurrentProcId(); diff --git a/net/url_request/url_request.h b/net/url_request/url_request.h index a16080f..d45e510 100644 --- a/net/url_request/url_request.h +++ b/net/url_request/url_request.h @@ -8,6 +8,7 @@ #include <string> #include <vector> +#include "base/logging.h" #include "base/ref_counted.h" #include "googleurl/src/gurl.h" #include "net/base/load_states.h" @@ -15,16 +16,14 @@ #include "net/url_request/url_request_status.h" namespace base { - class Time; -} +class Time; +} // namespace base namespace net { - class IOBuffer; class UploadData; class X509Certificate; - -} +} // namespace net class URLRequestContext; class URLRequestJob; @@ -431,12 +430,20 @@ class URLRequest { // Returns the expected content size if available int64 GetExpectedContentSize() const; + // Returns the priority level for this request. A larger value indicates + // higher priority. Negative values are not used. + int priority() const { return priority_; } + void set_priority(int priority) { + DCHECK_GE(priority, 0); + priority_ = priority; + } + protected: // Allow the URLRequestJob class to control the is_pending() flag. void set_is_pending(bool value) { is_pending_ = value; } // Allow the URLRequestJob class to set our status too - void set_status(const URLRequestStatus &value) { status_ = value; } + void set_status(const URLRequestStatus& value) { status_ = value; } // Allow the URLRequestJob to redirect this request. Returns net::OK if // successful, otherwise an error code is returned. @@ -505,6 +512,10 @@ class URLRequest { // first transaction in a request involving redirects. uint64 final_upload_progress_; + // The priority level for this request. Objects like ClientSocketPool use + // this to determine which URLRequest to allocate sockets to first. + int priority_; + DISALLOW_COPY_AND_ASSIGN(URLRequest); }; diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc index cf380de..4180bef 100644 --- a/net/url_request/url_request_http_job.cc +++ b/net/url_request/url_request_http_job.cc @@ -111,6 +111,7 @@ void URLRequestHttpJob::Start() { request_info_.referrer = referrer; request_info_.method = request_->method(); request_info_.load_flags = request_->load_flags(); + request_info_.priority = request_->priority(); if (request_->context()) { request_info_.user_agent = |