diff options
author | Ebrahem Qassem <ekassem@codeaurora.org> | 2011-11-20 14:57:09 +0200 |
---|---|---|
committer | Steve Kondik <shade@chemlab.org> | 2012-09-11 13:20:30 -0700 |
commit | 5fbe95affc8eeed93c678b1d271f64dcc4dd919b (patch) | |
tree | 053d8358e76befa6fd95e7cef8319045e534167f /net/socket/client_socket_pool_base.cc | |
parent | a75b259c30d54752a0d42804631bcf309b381f90 (diff) | |
download | external_chromium-5fbe95affc8eeed93c678b1d271f64dcc4dd919b.zip external_chromium-5fbe95affc8eeed93c678b1d271f64dcc4dd919b.tar.gz external_chromium-5fbe95affc8eeed93c678b1d271f64dcc4dd919b.tar.bz2 |
net: networking optimizations
features:
- early connection
- memory cache
- caching of redirection
- request queue priority
- closing unused sockets
- SHUTR
- fin aggregation
- object prefetch
- dns host name prioritization
Change-Id: Ief90b8206ba48115eaeb12d554424d65f36427ac
Diffstat (limited to 'net/socket/client_socket_pool_base.cc')
-rw-r--r-- | net/socket/client_socket_pool_base.cc | 119 |
1 files changed, 106 insertions, 13 deletions
diff --git a/net/socket/client_socket_pool_base.cc b/net/socket/client_socket_pool_base.cc index 46cfc45..f0d9c2c 100644 --- a/net/socket/client_socket_pool_base.cc +++ b/net/socket/client_socket_pool_base.cc @@ -1,4 +1,5 @@ // Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2011,2012, Code Aurora Forum. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -15,6 +16,15 @@ #include "net/base/net_log.h" #include "net/base/net_errors.h" #include "net/socket/client_socket_handle.h" +#include "net/http/http_network_session.h" +#include "net/http/preconnect.h" +#include "net/http/tcp-connections-bridge.h" +#include "googleurl/src/gurl.h" +#include <cutils/properties.h> +#include <cutils/log.h> + +// Define Log Tag for this source file. +#define LOG_TAG "Socket_Pool" using base::TimeDelta; @@ -34,12 +44,23 @@ bool g_cleanup_timer_enabled = true; // Note: It's important to close idle sockets that have received data as soon // as possible because the received data may cause BSOD on Windows XP under // some conditions. See http://crbug.com/4606. -const int kCleanupInterval = 10; // DO NOT INCREASE THIS TIMEOUT. +int kCleanupInterval = 2; // DO NOT INCREASE THIS TIMEOUT. // Indicate whether or not we should establish a new transport layer connection // after a certain timeout has passed without receiving an ACK. bool g_connect_backup_jobs_enabled = true; +// Indicate whether or not we should close the unused sockets in the next run +// of the reaper cleanup thread. +bool g_close_unused_sockets = false; + +// Called to inform that we should close the unused sockets that resides in +// the idle pool. +extern "C" void SetCloseUnUsedSocketsFlag() +{ + g_close_unused_sockets = true; +} + } // namespace namespace net { @@ -166,7 +187,8 @@ ClientSocketPoolBaseHelper::ClientSocketPoolBaseHelper( int max_sockets_per_group, base::TimeDelta unused_idle_socket_timeout, base::TimeDelta used_idle_socket_timeout, - ConnectJobFactory* connect_job_factory) + ConnectJobFactory* connect_job_factory, + HttpNetworkSession *network_session) : idle_socket_count_(0), connecting_socket_count_(0), handed_out_socket_count_(0), @@ -183,6 +205,31 @@ ClientSocketPoolBaseHelper::ClientSocketPoolBaseHelper( DCHECK_LE(max_sockets_per_group, max_sockets); NetworkChangeNotifier::AddIPAddressObserver(this); + + network_session_ = network_session; + + tcp_fin_aggregation = net::TCPFinAggregationFactory::GetTCPFinFactoryInstance(this)->GetTCPFinAggregation(); + if (NULL == tcp_fin_aggregation) { + SLOGD("Failed to create TCP Fin Aggregation interface."); + } else { + int new_cleanup_interval = tcp_fin_aggregation->GetCleanupInterval(kCleanupInterval); + kCleanupInterval = new_cleanup_interval; + } + + close_unused_sockets_enabled = false; + char netCloseUnusedSocketsSystemProperty[PROPERTY_VALUE_MAX]; + if(property_get("net.close.unused.sockets", + netCloseUnusedSocketsSystemProperty, "1")) { + close_unused_sockets_enabled = (bool)atoi(netCloseUnusedSocketsSystemProperty); + } + SLOGD("netstack: CloseUnusedSockets is %s", close_unused_sockets_enabled?"ON":"OFF"); + + char net_statistics_enabled_sys_property[PROPERTY_VALUE_MAX]; + if(property_get("net.statistics", + net_statistics_enabled_sys_property, "0")) { + net_statistics_enabled = (bool)atoi(net_statistics_enabled_sys_property); + SLOGD("netstack: system net.statistics value: %d", net_statistics_enabled); + } } ClientSocketPoolBaseHelper::~ClientSocketPoolBaseHelper() { @@ -229,8 +276,9 @@ int ClientSocketPoolBaseHelper::RequestSocket( CHECK(request->handle()); // Cleanup any timed-out idle sockets if no timer is used. - if (!use_cleanup_timer_) + if ((!use_cleanup_timer_) && ((NULL == tcp_fin_aggregation) || (((NULL != tcp_fin_aggregation) && !tcp_fin_aggregation->IsEnabled())))) { CleanupIdleSockets(false); + } request->net_log().BeginEvent(NetLog::TYPE_SOCKET_POOL, NULL); Group* group = GetOrCreateGroup(group_name); @@ -242,6 +290,9 @@ int ClientSocketPoolBaseHelper::RequestSocket( delete request; } else { InsertRequestIntoQueue(request, group->mutable_pending_requests()); + if (net_statistics_enabled) { + SLOGD("insertRequestToQueue Host = %s Size = %d", group_name.c_str(), group->mutable_pending_requests()->size()); + } } return rv; } @@ -254,8 +305,9 @@ void ClientSocketPoolBaseHelper::RequestSockets( DCHECK(!request.handle()); // Cleanup any timed out idle sockets if no timer is used. - if (!use_cleanup_timer_) + if ((!use_cleanup_timer_) && ((NULL == tcp_fin_aggregation) || (((NULL != tcp_fin_aggregation) && !tcp_fin_aggregation->IsEnabled())))) { CleanupIdleSockets(false); + } if (num_sockets > max_sockets_per_group_) { num_sockets = max_sockets_per_group_; @@ -273,7 +325,7 @@ void ClientSocketPoolBaseHelper::RequestSockets( int rv = OK; for (int num_iterations_left = num_sockets; - group->NumActiveSocketSlots() < num_sockets && + group->NumActiveSocketSlots() <= num_sockets && num_iterations_left > 0 ; num_iterations_left--) { rv = RequestSocketInternal(group_name, &request); if (rv < 0 && rv != ERR_IO_PENDING) { @@ -382,6 +434,20 @@ int ClientSocketPoolBaseHelper::RequestSocketInternal( } } + if (!preconnecting) { + std::string url; + const int ssl_sockets_groupname_prefix_length_ = 4; + if (0 == group_name.compare(0, ssl_sockets_groupname_prefix_length_ , "ssl/")) { + url.append("https://"); + }else { + url.append("http://"); + } + url.append(group_name); + GURL gurl = GURL(url); + + ObserveConnections(network_session_, gurl); + } + return rv; } @@ -420,7 +486,7 @@ bool ClientSocketPoolBaseHelper::AssignIdleSocketToGroup( if (idle_socket_it != idle_sockets->end()) { DecrementIdleCount(); base::TimeDelta idle_time = - base::TimeTicks::Now() - idle_socket_it->start_time; + base::Time::Now() - idle_socket_it->start_time; IdleSocket idle_socket = *idle_socket_it; idle_sockets->erase(idle_socket_it); HandOutSocket( @@ -471,6 +537,9 @@ void ClientSocketPoolBaseHelper::CancelRequest( scoped_ptr<const Request> req(RemoveRequestFromQueue(it, group)); req->net_log().AddEvent(NetLog::TYPE_CANCELLED, NULL); req->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL, NULL); + if (net_statistics_enabled) { + SLOGD("removeRequestFromQueue Host = %s Size = %d", group_name.c_str(), group->mutable_pending_requests()->size()); + } // We let the job run, unless we're at the socket limit. if (group->jobs().size() && ReachedMaxSocketsLimit()) { @@ -595,8 +664,8 @@ DictionaryValue* ClientSocketPoolBaseHelper::GetInfoAsValue( return dict; } -bool ClientSocketPoolBaseHelper::IdleSocket::ShouldCleanup( - base::TimeTicks now, +bool IdleSocket::ShouldCleanup( + base::Time now, base::TimeDelta timeout) const { bool timed_out = (now - start_time) >= timeout; if (timed_out) @@ -607,12 +676,13 @@ bool ClientSocketPoolBaseHelper::IdleSocket::ShouldCleanup( } void ClientSocketPoolBaseHelper::CleanupIdleSockets(bool force) { - if (idle_socket_count_ == 0) + if (idle_socket_count_ == 0) { return; + } // Current time value. Retrieving it once at the function start rather than // inside the inner loop, since it shouldn't change by any meaningful amount. - base::TimeTicks now = base::TimeTicks::Now(); + base::Time now = base::Time::Now(); GroupMap::iterator i = group_map_.begin(); while (i != group_map_.end()) { @@ -623,7 +693,8 @@ void ClientSocketPoolBaseHelper::CleanupIdleSockets(bool force) { base::TimeDelta timeout = j->socket->WasEverUsed() ? used_idle_socket_timeout_ : unused_idle_socket_timeout_; - if (force || j->ShouldCleanup(now, timeout)) { + if (force || j->ShouldCleanup(now, timeout) || + ((true == close_unused_sockets_enabled) && (true == g_close_unused_sockets) && !j->socket->WasEverUsed())) { delete j->socket; j = group->mutable_idle_sockets()->erase(j); DecrementIdleCount(); @@ -685,8 +756,21 @@ void ClientSocketPoolBaseHelper::IncrementIdleCount() { } void ClientSocketPoolBaseHelper::DecrementIdleCount() { - if (--idle_socket_count_ == 0) + if (--idle_socket_count_ == 0) { timer_.Stop(); + } +} + +void ClientSocketPoolBaseHelper::OnCleanupTimerFired() +{ + if((NULL != tcp_fin_aggregation) && + (tcp_fin_aggregation->IsEnabled())) { + tcp_fin_aggregation->ReaperCleanup(g_close_unused_sockets); + } + else { + CleanupIdleSockets(false); + } + g_close_unused_sockets = false; } // static @@ -814,6 +898,9 @@ void ClientSocketPoolBaseHelper::OnConnectJobComplete( base::TimeDelta(), group, r->net_log()); r->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL, NULL); InvokeUserCallbackLater(r->handle(), r->callback(), result); + if (net_statistics_enabled) { + SLOGD("removeRequestFromQueue Host = %s Size = %d", group_name.c_str(), group->mutable_pending_requests()->size()); + } } else { AddIdleSocket(socket.release(), group); OnAvailableSocketSlot(group_name, group); @@ -837,6 +924,9 @@ void ClientSocketPoolBaseHelper::OnConnectJobComplete( r->net_log().EndEventWithNetErrorCode(NetLog::TYPE_SOCKET_POOL, result); InvokeUserCallbackLater(r->handle(), r->callback(), result); + if (net_statistics_enabled) { + SLOGD("removeRequestFromQueue Host = %s Size = %d", group_name.c_str(), group->mutable_pending_requests()->size()); + } } else { RemoveConnectJob(job, group); } @@ -897,6 +987,9 @@ void ClientSocketPoolBaseHelper::ProcessPendingRequest( request->net_log().EndEventWithNetErrorCode(NetLog::TYPE_SOCKET_POOL, rv); InvokeUserCallbackLater(request->handle(), request->callback(), rv); + if (net_statistics_enabled) { + SLOGD("removeRequestFromQueue Host = %s Size = %d", group_name.c_str(), group->mutable_pending_requests()->size()); + } } } @@ -933,7 +1026,7 @@ void ClientSocketPoolBaseHelper::AddIdleSocket( DCHECK(socket); IdleSocket idle_socket; idle_socket.socket = socket; - idle_socket.start_time = base::TimeTicks::Now(); + idle_socket.start_time = base::Time::Now(); group->mutable_idle_sockets()->push_back(idle_socket); IncrementIdleCount(); |