summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorjar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-25 20:29:45 +0000
committerjar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-25 20:29:45 +0000
commit9b5614aec311bc0d04416b1fa279e496cca84714 (patch)
treeef89c857a897d45a8540aa0a84252a4a9329b83a /net
parent4055f9a6cd7de30e99288aa1f51b42276a93e705 (diff)
downloadchromium_src-9b5614aec311bc0d04416b1fa279e496cca84714.zip
chromium_src-9b5614aec311bc0d04416b1fa279e496cca84714.tar.gz
chromium_src-9b5614aec311bc0d04416b1fa279e496cca84714.tar.bz2
Gather preconnection use vs waste statistics
I now gather statistics only in the transport socket classes TcpClientSocket*. All other socket classes forward significant data (that they are used in a speculation) to their transport class, where this data is stored, and then dumped when the TCP socket is closed. This CL also repaired a slight miscount in bytes read and written on Windows, as error codes were mistakenly accumulated as byte counts. This CL repaired a significant undercounting in linux/mac via StatsCounter (the logging counter appears correct). Libjingle support is minimal (NOTREACHED), but I don't know that there are subresources that will be speculatively preconnected from that class (and it is less obvious how the class uses underlying sockets, if at all). BUG=42694 r=willchan Review URL: http://codereview.chromium.org/3163033 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@57377 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r--net/http/http_proxy_client_socket.cc16
-rw-r--r--net/http/http_proxy_client_socket.h2
-rw-r--r--net/socket/client_socket.cc59
-rw-r--r--net/socket/client_socket.h78
-rw-r--r--net/socket/client_socket_handle.cc1
-rw-r--r--net/socket/client_socket_handle.h14
-rw-r--r--net/socket/client_socket_pool_base_unittest.cc3
-rw-r--r--net/socket/socket_test_util.h2
-rw-r--r--net/socket/socks5_client_socket.cc16
-rw-r--r--net/socket/socks5_client_socket.h2
-rw-r--r--net/socket/socks_client_socket.cc16
-rw-r--r--net/socket/socks_client_socket.h2
-rw-r--r--net/socket/ssl_client_socket_mac.cc16
-rw-r--r--net/socket/ssl_client_socket_mac.h2
-rw-r--r--net/socket/ssl_client_socket_nss.cc16
-rw-r--r--net/socket/ssl_client_socket_nss.h2
-rw-r--r--net/socket/ssl_client_socket_win.cc16
-rw-r--r--net/socket/ssl_client_socket_win.h2
-rw-r--r--net/socket/tcp_client_socket_libevent.cc25
-rw-r--r--net/socket/tcp_client_socket_libevent.h6
-rw-r--r--net/socket/tcp_client_socket_pool_unittest.cc9
-rw-r--r--net/socket/tcp_client_socket_win.cc34
-rw-r--r--net/socket/tcp_client_socket_win.h8
23 files changed, 265 insertions, 82 deletions
diff --git a/net/http/http_proxy_client_socket.cc b/net/http/http_proxy_client_socket.cc
index 76882fa..16f6e28 100644
--- a/net/http/http_proxy_client_socket.cc
+++ b/net/http/http_proxy_client_socket.cc
@@ -174,6 +174,22 @@ bool HttpProxyClientSocket::IsConnectedAndIdle() const {
transport_->socket()->IsConnectedAndIdle();
}
+void HttpProxyClientSocket::SetSubresourceSpeculation() {
+ if (transport_.get() && transport_->socket()) {
+ transport_->socket()->SetSubresourceSpeculation();
+ } else {
+ NOTREACHED();
+ }
+}
+
+void HttpProxyClientSocket::SetOmniboxSpeculation() {
+ if (transport_.get() && transport_->socket()) {
+ transport_->socket()->SetOmniboxSpeculation();
+ } else {
+ NOTREACHED();
+ }
+}
+
int HttpProxyClientSocket::Read(IOBuffer* buf, int buf_len,
CompletionCallback* callback) {
DCHECK(!user_callback_);
diff --git a/net/http/http_proxy_client_socket.h b/net/http/http_proxy_client_socket.h
index 93afafa..488fbdc 100644
--- a/net/http/http_proxy_client_socket.h
+++ b/net/http/http_proxy_client_socket.h
@@ -65,6 +65,8 @@ class HttpProxyClientSocket : public ClientSocket {
virtual bool IsConnected() const;
virtual bool IsConnectedAndIdle() const;
virtual const BoundNetLog& NetLog() const { return net_log_; }
+ virtual void SetSubresourceSpeculation();
+ virtual void SetOmniboxSpeculation();
// Socket methods:
virtual int Read(IOBuffer* buf, int buf_len, CompletionCallback* callback);
diff --git a/net/socket/client_socket.cc b/net/socket/client_socket.cc
index 7722c64..aba0366 100644
--- a/net/socket/client_socket.cc
+++ b/net/socket/client_socket.cc
@@ -9,17 +9,18 @@
namespace net {
-ClientSocket::ClientSocket()
+ClientSocket::UseHistory::UseHistory()
: was_ever_connected_(false),
+ was_used_to_convey_data_(false),
omnibox_speculation_(false),
- subresource_speculation_(false),
- was_used_to_transmit_data_(false) {}
+ subresource_speculation_(false) {
+}
-ClientSocket::~ClientSocket() {
+ClientSocket::UseHistory::~UseHistory() {
EmitPreconnectionHistograms();
}
-void ClientSocket::EmitPreconnectionHistograms() const {
+void ClientSocket::UseHistory::EmitPreconnectionHistograms() const {
DCHECK(!subresource_speculation_ || !omnibox_speculation_);
// 0 ==> non-speculative, never connected.
// 1 ==> non-speculative never used (but connected).
@@ -31,7 +32,7 @@ void ClientSocket::EmitPreconnectionHistograms() const {
// 7 ==> subresource_speculative never used (but connected).
// 8 ==> subresource_speculative and used.
int result;
- if (was_used_to_transmit_data_)
+ if (was_used_to_convey_data_)
result = 2;
else if (was_ever_connected_)
result = 1;
@@ -42,37 +43,55 @@ void ClientSocket::EmitPreconnectionHistograms() const {
result += 3;
else if (subresource_speculation_)
result += 6;
+ UMA_HISTOGRAM_ENUMERATION("Net.PreconnectUtilization2", result, 9);
static const bool connect_backup_jobs_fieldtrial =
FieldTrialList::Find("ConnnectBackupJobs") &&
!FieldTrialList::Find("ConnnectBackupJobs")->group_name().empty();
if (connect_backup_jobs_fieldtrial) {
UMA_HISTOGRAM_ENUMERATION(
- FieldTrial::MakeName("Net.PreconnectUtilization", "ConnnectBackupJobs"),
+ FieldTrial::MakeName("Net.PreconnectUtilization2",
+ "ConnnectBackupJobs"),
result, 9);
}
}
-void ClientSocket::SetSubresourceSpeculation() {
- if (was_used_to_transmit_data_)
+void ClientSocket::UseHistory::set_was_ever_connected() {
+ DCHECK(!was_used_to_convey_data_);
+ was_ever_connected_ = true;
+}
+
+void ClientSocket::UseHistory::set_was_used_to_convey_data() {
+ DCHECK(was_ever_connected_);
+ was_used_to_convey_data_ = true;
+}
+
+
+void ClientSocket::UseHistory::set_subresource_speculation() {
+ DCHECK(was_ever_connected_);
+ // TODO(jar): We should transition to marking a socket (or stream) at
+ // construction time as being created for speculative reasons. This current
+ // approach of trying to track use of a socket to convey data can make
+ // mistakes when other sockets (such as ones sitting in the pool for a long
+ // time) are issued. Unused sockets can be left over when a when a set of
+ // connections to a host are made, and one is "unlucky" and takes so long to
+ // complete a connection, that another socket is used, and recycled before a
+ // second connection comes available. Similarly, re-try connections can leave
+ // an original (slow to connect socket) in the pool, and that can be issued
+ // to a speculative requester. In any cases such old sockets will fail when an
+ // attempt is made to used them!... and then it will look like a speculative
+ // socket was discarded without any user!?!?!
+ if (was_used_to_convey_data_)
return;
subresource_speculation_ = true;
}
-void ClientSocket::SetOmniboxSpeculation() {
- if (was_used_to_transmit_data_)
+void ClientSocket::UseHistory::set_omnibox_speculation() {
+ DCHECK(was_ever_connected_);
+ if (was_used_to_convey_data_)
return;
omnibox_speculation_ = true;
}
-void ClientSocket::UpdateConnectivityState(bool is_reused) {
- // Record if this connection has every actually connected successfully.
- // Note that IsConnected() won't be defined at destruction time, so we need
- // to record this data now, while the derived class is present.
- was_ever_connected_ |= IsConnected();
- // A socket is_reused only after it has transmitted some data.
- was_used_to_transmit_data_ |= is_reused;
-}
-
} // namespace net
diff --git a/net/socket/client_socket.h b/net/socket/client_socket.h
index 44ee085..6a4fb31 100644
--- a/net/socket/client_socket.h
+++ b/net/socket/client_socket.h
@@ -15,25 +15,7 @@ class BoundNetLog;
class ClientSocket : public Socket {
public:
- ClientSocket();
-
- // Destructor emits statistics for this socket's lifetime.
- virtual ~ClientSocket();
-
- // Set the annotation to indicate this socket was created for speculative
- // reasons. Note that if the socket was used before calling this method, then
- // the call will be ignored (no annotation will be added).
- void SetSubresourceSpeculation();
- void SetOmniboxSpeculation();
-
- // Establish values of was_ever_connected_ and was_used_to_transmit_data_.
- // The argument indicates if the socket's state, as reported by a
- // ClientSocketHandle::is_reused(), should show that the socket has already
- // been used to transmit data.
- // This is typically called when a transaction finishes, and
- // ClientSocketHandle is being destroyed. Calling at that point it allows us
- // to aggregates the impact of that connect job into this instance.
- void UpdateConnectivityState(bool is_reused);
+ virtual ~ClientSocket() {}
// Called to establish a connection. Returns OK if the connection could be
// established synchronously. Otherwise, ERR_IO_PENDING is returned and the
@@ -75,23 +57,47 @@ class ClientSocket : public Socket {
// Gets the NetLog for this socket.
virtual const BoundNetLog& NetLog() const = 0;
- private:
- // Publish histogram to help evaluate preconnection utilization.
- void EmitPreconnectionHistograms() const;
-
- // Indicate if any ClientSocketHandle that used this socket was connected as
- // would be indicated by the IsConnected() method. This variable set by a
- // ClientSocketHandle before releasing this ClientSocket.
- bool was_ever_connected_;
-
- // Indicate if this socket was first created for speculative use, and identify
- // the motivation.
- bool omnibox_speculation_;
- bool subresource_speculation_;
-
- // Indicate if this socket was ever used. This state is set by a
- // ClientSocketHandle before releasing this ClientSocket.
- bool was_used_to_transmit_data_;
+ // Set the annotation to indicate this socket was created for speculative
+ // reasons. This call is generally fowarded to a basic TCPClientSocket*,
+ // where a UseHistory can be updated.
+ virtual void SetSubresourceSpeculation() = 0;
+ virtual void SetOmniboxSpeculation() = 0;
+
+ protected:
+ // The following class is only used to gather statistics about the history of
+ // a socket. It is only instantiated and used in basic sockets, such as
+ // TCPClientSocket* instances. Other classes that are derived from
+ // ClientSocket should forward any potential settings to their underlying
+ // transport sockets.
+ class UseHistory {
+ public:
+ UseHistory();
+ ~UseHistory();
+
+ void set_was_ever_connected();
+ void set_was_used_to_convey_data();
+
+ // The next two setters only have any impact if the socket has not yet been
+ // used to transmit data. If called later, we assume that the socket was
+ // reused from the pool, and was NOT constructed to service a speculative
+ // request.
+ void set_subresource_speculation();
+ void set_omnibox_speculation();
+
+ private:
+ // Summarize the statistics for this socket.
+ void EmitPreconnectionHistograms() const;
+ // Indicate if this was ever connected.
+ bool was_ever_connected_;
+ // Indicate if this socket was ever used to transmit or receive data.
+ bool was_used_to_convey_data_;
+
+ // Indicate if this socket was first created for speculative use, and
+ // identify the motivation.
+ bool omnibox_speculation_;
+ bool subresource_speculation_;
+ DISALLOW_COPY_AND_ASSIGN(UseHistory);
+ };
};
} // namespace net
diff --git a/net/socket/client_socket_handle.cc b/net/socket/client_socket_handle.cc
index ee7c233..d9ccbd5 100644
--- a/net/socket/client_socket_handle.cc
+++ b/net/socket/client_socket_handle.cc
@@ -22,7 +22,6 @@ ClientSocketHandle::ClientSocketHandle()
ClientSocketHandle::~ClientSocketHandle() {
Reset();
- UpdateConnectivityStateForSocket();
}
void ClientSocketHandle::Reset() {
diff --git a/net/socket/client_socket_handle.h b/net/socket/client_socket_handle.h
index c9d636b..e3e6cfb 100644
--- a/net/socket/client_socket_handle.h
+++ b/net/socket/client_socket_handle.h
@@ -132,10 +132,7 @@ class ClientSocketHandle {
const std::string& group_name() const { return group_name_; }
int id() const { return pool_id_; }
ClientSocket* socket() { return socket_.get(); }
- ClientSocket* release_socket() {
- UpdateConnectivityStateForSocket();
- return socket_.release();
- }
+ ClientSocket* release_socket() { return socket_.release(); }
bool is_reused() const { return is_reused_; }
base::TimeDelta idle_time() const { return idle_time_; }
SocketReuseType reuse_type() const {
@@ -164,15 +161,6 @@ class ClientSocketHandle {
// Resets the supplemental error state.
void ResetErrorState();
- // Update the base class to record things like whether we've ever transmitted
- // data, and whether the connection was able to be established. We use this
- // data to construct histograms indicating whether a speculative connection
- // was ever used, etc., when the ClientSocket is eventually discarded.
- void UpdateConnectivityStateForSocket() const {
- if (socket_.get())
- socket_->UpdateConnectivityState(is_reused());
- }
-
bool is_initialized_;
scoped_refptr<ClientSocketPool> pool_;
scoped_ptr<ClientSocket> socket_;
diff --git a/net/socket/client_socket_pool_base_unittest.cc b/net/socket/client_socket_pool_base_unittest.cc
index 89db61d..2a78fb1 100644
--- a/net/socket/client_socket_pool_base_unittest.cc
+++ b/net/socket/client_socket_pool_base_unittest.cc
@@ -76,6 +76,9 @@ class MockClientSocket : public ClientSocket {
return net_log_;
}
+ virtual void SetSubresourceSpeculation() {}
+ virtual void SetOmniboxSpeculation() {}
+
private:
bool connected_;
BoundNetLog net_log_;
diff --git a/net/socket/socket_test_util.h b/net/socket/socket_test_util.h
index 31bbea2..b712215 100644
--- a/net/socket/socket_test_util.h
+++ b/net/socket/socket_test_util.h
@@ -516,6 +516,8 @@ class MockClientSocket : public net::SSLClientSocket {
virtual bool IsConnectedAndIdle() const;
virtual int GetPeerAddress(AddressList* address) const;
virtual const BoundNetLog& NetLog() const { return net_log_;}
+ virtual void SetSubresourceSpeculation() {}
+ virtual void SetOmniboxSpeculation() {}
// SSLClientSocket methods:
virtual void GetSSLInfo(net::SSLInfo* ssl_info);
diff --git a/net/socket/socks5_client_socket.cc b/net/socket/socks5_client_socket.cc
index 9c9ecbe..0af7b9b 100644
--- a/net/socket/socks5_client_socket.cc
+++ b/net/socket/socks5_client_socket.cc
@@ -106,6 +106,22 @@ bool SOCKS5ClientSocket::IsConnectedAndIdle() const {
return completed_handshake_ && transport_->socket()->IsConnectedAndIdle();
}
+void SOCKS5ClientSocket::SetSubresourceSpeculation() {
+ if (transport_.get() && transport_->socket()) {
+ transport_->socket()->SetSubresourceSpeculation();
+ } else {
+ NOTREACHED();
+ }
+}
+
+void SOCKS5ClientSocket::SetOmniboxSpeculation() {
+ if (transport_.get() && transport_->socket()) {
+ transport_->socket()->SetOmniboxSpeculation();
+ } else {
+ NOTREACHED();
+ }
+}
+
// Read is called by the transport layer above to read. This can only be done
// if the SOCKS handshake is complete.
int SOCKS5ClientSocket::Read(IOBuffer* buf, int buf_len,
diff --git a/net/socket/socks5_client_socket.h b/net/socket/socks5_client_socket.h
index c2a1793..ac0dd74 100644
--- a/net/socket/socks5_client_socket.h
+++ b/net/socket/socks5_client_socket.h
@@ -56,6 +56,8 @@ class SOCKS5ClientSocket : public ClientSocket {
virtual bool IsConnected() const;
virtual bool IsConnectedAndIdle() const;
virtual const BoundNetLog& NetLog() const { return net_log_; }
+ virtual void SetSubresourceSpeculation();
+ virtual void SetOmniboxSpeculation();
// Socket methods:
virtual int Read(IOBuffer* buf, int buf_len, CompletionCallback* callback);
diff --git a/net/socket/socks_client_socket.cc b/net/socket/socks_client_socket.cc
index 2000754..c38021f 100644
--- a/net/socket/socks_client_socket.cc
+++ b/net/socket/socks_client_socket.cc
@@ -141,6 +141,22 @@ bool SOCKSClientSocket::IsConnectedAndIdle() const {
return completed_handshake_ && transport_->socket()->IsConnectedAndIdle();
}
+void SOCKSClientSocket::SetSubresourceSpeculation() {
+ if (transport_.get() && transport_->socket()) {
+ transport_->socket()->SetSubresourceSpeculation();
+ } else {
+ NOTREACHED();
+ }
+}
+
+void SOCKSClientSocket::SetOmniboxSpeculation() {
+ if (transport_.get() && transport_->socket()) {
+ transport_->socket()->SetOmniboxSpeculation();
+ } else {
+ NOTREACHED();
+ }
+}
+
// Read is called by the transport layer above to read. This can only be done
// if the SOCKS handshake is complete.
int SOCKSClientSocket::Read(IOBuffer* buf, int buf_len,
diff --git a/net/socket/socks_client_socket.h b/net/socket/socks_client_socket.h
index 515f337..af28574 100644
--- a/net/socket/socks_client_socket.h
+++ b/net/socket/socks_client_socket.h
@@ -53,6 +53,8 @@ class SOCKSClientSocket : public ClientSocket {
virtual bool IsConnected() const;
virtual bool IsConnectedAndIdle() const;
virtual const BoundNetLog& NetLog() const { return net_log_; }
+ virtual void SetSubresourceSpeculation();
+ virtual void SetOmniboxSpeculation();
// Socket methods:
virtual int Read(IOBuffer* buf, int buf_len, CompletionCallback* callback);
diff --git a/net/socket/ssl_client_socket_mac.cc b/net/socket/ssl_client_socket_mac.cc
index 4ee9c23..63e8171 100644
--- a/net/socket/ssl_client_socket_mac.cc
+++ b/net/socket/ssl_client_socket_mac.cc
@@ -591,6 +591,22 @@ int SSLClientSocketMac::GetPeerAddress(AddressList* address) const {
return transport_->socket()->GetPeerAddress(address);
}
+void SSLClientSocketMac::SetSubresourceSpeculation() {
+ if (transport_.get() && transport_->socket()) {
+ transport_->socket()->SetSubresourceSpeculation();
+ } else {
+ NOTREACHED();
+ }
+}
+
+void SSLClientSocketMac::SetOmniboxSpeculation() {
+ if (transport_.get() && transport_->socket()) {
+ transport_->socket()->SetOmniboxSpeculation();
+ } else {
+ NOTREACHED();
+ }
+}
+
int SSLClientSocketMac::Read(IOBuffer* buf, int buf_len,
CompletionCallback* callback) {
DCHECK(completed_handshake_);
diff --git a/net/socket/ssl_client_socket_mac.h b/net/socket/ssl_client_socket_mac.h
index 5166b33..26a270c 100644
--- a/net/socket/ssl_client_socket_mac.h
+++ b/net/socket/ssl_client_socket_mac.h
@@ -47,6 +47,8 @@ class SSLClientSocketMac : public SSLClientSocket {
virtual bool IsConnectedAndIdle() const;
virtual int GetPeerAddress(AddressList* address) const;
virtual const BoundNetLog& NetLog() const { return net_log_; }
+ virtual void SetSubresourceSpeculation();
+ virtual void SetOmniboxSpeculation();
// Socket methods:
virtual int Read(IOBuffer* buf, int buf_len, CompletionCallback* callback);
diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc
index 7b23b26..44b5e1f 100644
--- a/net/socket/ssl_client_socket_nss.cc
+++ b/net/socket/ssl_client_socket_nss.cc
@@ -658,6 +658,22 @@ int SSLClientSocketNSS::GetPeerAddress(AddressList* address) const {
return transport_->socket()->GetPeerAddress(address);
}
+void SSLClientSocketNSS::SetSubresourceSpeculation() {
+ if (transport_.get() && transport_->socket()) {
+ transport_->socket()->SetSubresourceSpeculation();
+ } else {
+ NOTREACHED();
+ }
+}
+
+void SSLClientSocketNSS::SetOmniboxSpeculation() {
+ if (transport_.get() && transport_->socket()) {
+ transport_->socket()->SetOmniboxSpeculation();
+ } else {
+ NOTREACHED();
+ }
+}
+
int SSLClientSocketNSS::Read(IOBuffer* buf, int buf_len,
CompletionCallback* callback) {
EnterFunction(buf_len);
diff --git a/net/socket/ssl_client_socket_nss.h b/net/socket/ssl_client_socket_nss.h
index 8e1e68d..315e142 100644
--- a/net/socket/ssl_client_socket_nss.h
+++ b/net/socket/ssl_client_socket_nss.h
@@ -54,6 +54,8 @@ class SSLClientSocketNSS : public SSLClientSocket {
virtual bool IsConnectedAndIdle() const;
virtual int GetPeerAddress(AddressList* address) const;
virtual const BoundNetLog& NetLog() const { return net_log_; }
+ virtual void SetSubresourceSpeculation();
+ virtual void SetOmniboxSpeculation();
// Socket methods:
virtual int Read(IOBuffer* buf, int buf_len, CompletionCallback* callback);
diff --git a/net/socket/ssl_client_socket_win.cc b/net/socket/ssl_client_socket_win.cc
index 38bdfce..cb6e91e 100644
--- a/net/socket/ssl_client_socket_win.cc
+++ b/net/socket/ssl_client_socket_win.cc
@@ -629,6 +629,22 @@ int SSLClientSocketWin::GetPeerAddress(AddressList* address) const {
return transport_->socket()->GetPeerAddress(address);
}
+void SSLClientSocketWin::SetSubresourceSpeculation() {
+ if (transport_.get() && transport_->socket()) {
+ transport_->socket()->SetSubresourceSpeculation();
+ } else {
+ NOTREACHED();
+ }
+}
+
+void SSLClientSocketWin::SetOmniboxSpeculation() {
+ if (transport_.get() && transport_->socket()) {
+ transport_->socket()->SetOmniboxSpeculation();
+ } else {
+ NOTREACHED();
+ }
+}
+
int SSLClientSocketWin::Read(IOBuffer* buf, int buf_len,
CompletionCallback* callback) {
DCHECK(completed_handshake());
diff --git a/net/socket/ssl_client_socket_win.h b/net/socket/ssl_client_socket_win.h
index a44dca7..44a5374 100644
--- a/net/socket/ssl_client_socket_win.h
+++ b/net/socket/ssl_client_socket_win.h
@@ -51,6 +51,8 @@ class SSLClientSocketWin : public SSLClientSocket {
virtual bool IsConnectedAndIdle() const;
virtual int GetPeerAddress(AddressList* address) const;
virtual const BoundNetLog& NetLog() const { return net_log_; }
+ virtual void SetSubresourceSpeculation();
+ virtual void SetOmniboxSpeculation();
// Socket methods:
virtual int Read(IOBuffer* buf, int buf_len, CompletionCallback* callback);
diff --git a/net/socket/tcp_client_socket_libevent.cc b/net/socket/tcp_client_socket_libevent.cc
index 55c4190..a63528b 100644
--- a/net/socket/tcp_client_socket_libevent.cc
+++ b/net/socket/tcp_client_socket_libevent.cc
@@ -233,8 +233,10 @@ int TCPClientSocketLibevent::DoConnectComplete(int result) {
write_socket_watcher_.StopWatchingFileDescriptor();
- if (result == OK)
+ if (result == OK) {
+ use_history_.set_was_ever_connected();
return OK; // Done!
+ }
// Close whatever partially connected socket we currently have.
DoDisconnect();
@@ -320,7 +322,8 @@ int TCPClientSocketLibevent::Read(IOBuffer* buf,
if (nread >= 0) {
static StatsCounter read_bytes("tcp.read_bytes");
read_bytes.Add(nread);
-
+ if (nread > 0)
+ use_history_.set_was_used_to_convey_data();
net_log_.AddEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED,
new NetLogIntegerParameter("num_bytes", nread));
return nread;
@@ -358,6 +361,8 @@ int TCPClientSocketLibevent::Write(IOBuffer* buf,
if (nwrite >= 0) {
static StatsCounter write_bytes("tcp.write_bytes");
write_bytes.Add(nwrite);
+ if (nwrite > 0)
+ use_history_.set_was_used_to_convey_data();
net_log_.AddEvent(NetLog::TYPE_SOCKET_BYTES_SENT,
new NetLogIntegerParameter("num_bytes", nwrite));
return nwrite;
@@ -474,6 +479,10 @@ void TCPClientSocketLibevent::DidCompleteRead() {
int result;
if (bytes_transferred >= 0) {
result = bytes_transferred;
+ static StatsCounter read_bytes("tcp.read_bytes");
+ read_bytes.Add(bytes_transferred);
+ if (bytes_transferred > 0)
+ use_history_.set_was_used_to_convey_data();
net_log_.AddEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED,
new NetLogIntegerParameter("num_bytes", result));
} else {
@@ -497,6 +506,10 @@ void TCPClientSocketLibevent::DidCompleteWrite() {
int result;
if (bytes_transferred >= 0) {
result = bytes_transferred;
+ static StatsCounter write_bytes("tcp.write_bytes");
+ write_bytes.Add(bytes_transferred);
+ if (bytes_transferred > 0)
+ use_history_.set_was_used_to_convey_data();
net_log_.AddEvent(NetLog::TYPE_SOCKET_BYTES_SENT,
new NetLogIntegerParameter("num_bytes", result));
} else {
@@ -520,4 +533,12 @@ int TCPClientSocketLibevent::GetPeerAddress(AddressList* address) const {
return OK;
}
+void TCPClientSocketLibevent::SetSubresourceSpeculation() {
+ use_history_.set_subresource_speculation();
+}
+
+void TCPClientSocketLibevent::SetOmniboxSpeculation() {
+ use_history_.set_subresource_speculation();
+}
+
} // namespace net
diff --git a/net/socket/tcp_client_socket_libevent.h b/net/socket/tcp_client_socket_libevent.h
index ec4b5aa..8d68bff 100644
--- a/net/socket/tcp_client_socket_libevent.h
+++ b/net/socket/tcp_client_socket_libevent.h
@@ -40,6 +40,8 @@ class TCPClientSocketLibevent : public ClientSocket, NonThreadSafe {
virtual bool IsConnectedAndIdle() const;
virtual int GetPeerAddress(AddressList* address) const;
virtual const BoundNetLog& NetLog() const { return net_log_; }
+ virtual void SetSubresourceSpeculation();
+ virtual void SetOmniboxSpeculation();
// Socket methods:
// Multiple outstanding requests are not supported.
@@ -162,6 +164,10 @@ class TCPClientSocketLibevent : public ClientSocket, NonThreadSafe {
BoundNetLog net_log_;
+ // Record of connectivity and transmissions, for use in speculative connection
+ // histograms.
+ UseHistory use_history_;
+
DISALLOW_COPY_AND_ASSIGN(TCPClientSocketLibevent);
};
diff --git a/net/socket/tcp_client_socket_pool_unittest.cc b/net/socket/tcp_client_socket_pool_unittest.cc
index 7c2df9a..5bcf7e1 100644
--- a/net/socket/tcp_client_socket_pool_unittest.cc
+++ b/net/socket/tcp_client_socket_pool_unittest.cc
@@ -50,6 +50,9 @@ class MockClientSocket : public ClientSocket {
return net_log_;
}
+ virtual void SetSubresourceSpeculation() {}
+ virtual void SetOmniboxSpeculation() {}
+
// Socket methods:
virtual int Read(IOBuffer* buf, int buf_len,
CompletionCallback* callback) {
@@ -91,6 +94,9 @@ class MockFailingClientSocket : public ClientSocket {
return net_log_;
}
+ virtual void SetSubresourceSpeculation() {}
+ virtual void SetOmniboxSpeculation() {}
+
// Socket methods:
virtual int Read(IOBuffer* buf, int buf_len,
CompletionCallback* callback) {
@@ -145,6 +151,9 @@ class MockPendingClientSocket : public ClientSocket {
return net_log_;
}
+ virtual void SetSubresourceSpeculation() {}
+ virtual void SetOmniboxSpeculation() {}
+
// Socket methods:
virtual int Read(IOBuffer* buf, int buf_len,
CompletionCallback* callback) {
diff --git a/net/socket/tcp_client_socket_win.cc b/net/socket/tcp_client_socket_win.cc
index d2f7e04..ed2cccb 100644
--- a/net/socket/tcp_client_socket_win.cc
+++ b/net/socket/tcp_client_socket_win.cc
@@ -414,8 +414,10 @@ int TCPClientSocketWin::DoConnectComplete(int result) {
params = new NetLogIntegerParameter("os_error", os_error);
net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, params);
- if (result == OK)
+ if (result == OK) {
+ use_history_.set_was_ever_connected();
return OK; // Done!
+ }
// Close whatever partially connected socket we currently have.
DoDisconnect();
@@ -514,6 +516,14 @@ int TCPClientSocketWin::GetPeerAddress(AddressList* address) const {
return OK;
}
+void TCPClientSocketWin::SetSubresourceSpeculation() {
+ use_history_.set_subresource_speculation();
+}
+
+void TCPClientSocketWin::SetOmniboxSpeculation() {
+ use_history_.set_subresource_speculation();
+}
+
int TCPClientSocketWin::Read(IOBuffer* buf,
int buf_len,
CompletionCallback* callback) {
@@ -544,6 +554,8 @@ int TCPClientSocketWin::Read(IOBuffer* buf,
base::MemoryDebug::MarkAsInitialized(core_->read_buffer_.buf, num);
static StatsCounter read_bytes("tcp.read_bytes");
read_bytes.Add(num);
+ if (num > 0)
+ use_history_.set_was_used_to_convey_data();
net_log_.AddEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED,
new NetLogIntegerParameter("num_bytes", num));
return static_cast<int>(num);
@@ -570,8 +582,8 @@ int TCPClientSocketWin::Write(IOBuffer* buf,
DCHECK_GT(buf_len, 0);
DCHECK(!core_->write_iobuffer_);
- static StatsCounter reads("tcp.writes");
- reads.Increment();
+ static StatsCounter writes("tcp.writes");
+ writes.Increment();
core_->write_buffer_.len = buf_len;
core_->write_buffer_.buf = buf->data();
@@ -594,6 +606,8 @@ int TCPClientSocketWin::Write(IOBuffer* buf,
}
static StatsCounter write_bytes("tcp.write_bytes");
write_bytes.Add(rv);
+ if (rv > 0)
+ use_history_.set_was_used_to_convey_data();
net_log_.AddEvent(NetLog::TYPE_SOCKET_BYTES_SENT,
new NetLogIntegerParameter("num_bytes", rv));
return rv;
@@ -698,9 +712,6 @@ void TCPClientSocketWin::DoReadCallback(int rv) {
DCHECK_NE(rv, ERR_IO_PENDING);
DCHECK(read_callback_);
- static StatsCounter read_bytes("tcp.read_bytes");
- read_bytes.Add(rv);
-
// since Run may result in Read being called, clear read_callback_ up front.
CompletionCallback* c = read_callback_;
read_callback_ = NULL;
@@ -711,9 +722,6 @@ void TCPClientSocketWin::DoWriteCallback(int rv) {
DCHECK_NE(rv, ERR_IO_PENDING);
DCHECK(write_callback_);
- static StatsCounter write_bytes("tcp.write_bytes");
- write_bytes.Add(rv);
-
// since Run may result in Write being called, clear write_callback_ up front.
CompletionCallback* c = write_callback_;
write_callback_ = NULL;
@@ -757,6 +765,10 @@ void TCPClientSocketWin::DidCompleteRead() {
waiting_read_ = false;
core_->read_iobuffer_ = NULL;
if (ok) {
+ static StatsCounter read_bytes("tcp.read_bytes");
+ read_bytes.Add(num_bytes);
+ if (num_bytes > 0)
+ use_history_.set_was_used_to_convey_data();
net_log_.AddEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED,
new NetLogIntegerParameter("num_bytes", num_bytes));
}
@@ -784,6 +796,10 @@ void TCPClientSocketWin::DidCompleteWrite() {
<< " bytes reported.";
rv = ERR_WINSOCK_UNEXPECTED_WRITTEN_BYTES;
} else {
+ static StatsCounter write_bytes("tcp.write_bytes");
+ write_bytes.Add(num_bytes);
+ if (num_bytes > 0)
+ use_history_.set_was_used_to_convey_data();
net_log_.AddEvent(NetLog::TYPE_SOCKET_BYTES_SENT,
new NetLogIntegerParameter("num_bytes", rv));
}
diff --git a/net/socket/tcp_client_socket_win.h b/net/socket/tcp_client_socket_win.h
index 8940978..bd31960 100644
--- a/net/socket/tcp_client_socket_win.h
+++ b/net/socket/tcp_client_socket_win.h
@@ -28,7 +28,7 @@ class TCPClientSocketWin : public ClientSocket, NonThreadSafe {
net::NetLog* net_log,
const net::NetLog::Source& source);
- ~TCPClientSocketWin();
+ virtual ~TCPClientSocketWin();
// ClientSocket methods:
virtual int Connect(CompletionCallback* callback);
@@ -37,6 +37,8 @@ class TCPClientSocketWin : public ClientSocket, NonThreadSafe {
virtual bool IsConnectedAndIdle() const;
virtual int GetPeerAddress(AddressList* address) const;
virtual const BoundNetLog& NetLog() const { return net_log_; }
+ virtual void SetSubresourceSpeculation();
+ virtual void SetOmniboxSpeculation();
// Socket methods:
// Multiple outstanding requests are not supported.
@@ -114,6 +116,10 @@ class TCPClientSocketWin : public ClientSocket, NonThreadSafe {
BoundNetLog net_log_;
+ // Record of connectivity and transmissions, for use in speculative connection
+ // histograms.
+ UseHistory use_history_;
+
DISALLOW_COPY_AND_ASSIGN(TCPClientSocketWin);
};