1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "net/socket/stream_socket.h" 6 7 #include "base/metrics/field_trial.h" 8 #include "base/metrics/histogram.h" 9 #include "base/strings/string_number_conversions.h" 10 #include "base/values.h" 11 12 namespace net { 13 14 StreamSocket::UseHistory::UseHistory() 15 : was_ever_connected_(false), 16 was_used_to_convey_data_(false), 17 omnibox_speculation_(false), 18 subresource_speculation_(false) { 19 } 20 21 StreamSocket::UseHistory::~UseHistory() { 22 EmitPreconnectionHistograms(); 23 } 24 25 void StreamSocket::UseHistory::Reset() { 26 EmitPreconnectionHistograms(); 27 was_ever_connected_ = false; 28 was_used_to_convey_data_ = false; 29 // omnibox_speculation_ and subresource_speculation_ values 30 // are intentionally preserved. 31 } 32 33 void StreamSocket::UseHistory::set_was_ever_connected() { 34 DCHECK(!was_used_to_convey_data_); 35 was_ever_connected_ = true; 36 } 37 38 void StreamSocket::UseHistory::set_was_used_to_convey_data() { 39 DCHECK(was_ever_connected_); 40 was_used_to_convey_data_ = true; 41 } 42 43 44 void StreamSocket::UseHistory::set_subresource_speculation() { 45 DCHECK(was_ever_connected_); 46 // TODO(jar): We should transition to marking a socket (or stream) at 47 // construction time as being created for speculative reasons. This current 48 // approach of trying to track use of a socket to convey data can make 49 // mistakes when other sockets (such as ones sitting in the pool for a long 50 // time) are issued. Unused sockets can be left over when a when a set of 51 // connections to a host are made, and one is "unlucky" and takes so long to 52 // complete a connection, that another socket is used, and recycled before a 53 // second connection comes available. Similarly, re-try connections can leave 54 // an original (slow to connect socket) in the pool, and that can be issued 55 // to a speculative requester. In any cases such old sockets will fail when an 56 // attempt is made to used them!... and then it will look like a speculative 57 // socket was discarded without any user!?!?! 58 if (was_used_to_convey_data_) 59 return; 60 subresource_speculation_ = true; 61 } 62 63 void StreamSocket::UseHistory::set_omnibox_speculation() { 64 DCHECK(was_ever_connected_); 65 if (was_used_to_convey_data_) 66 return; 67 omnibox_speculation_ = true; 68 } 69 70 bool StreamSocket::UseHistory::was_used_to_convey_data() const { 71 DCHECK(!was_used_to_convey_data_ || was_ever_connected_); 72 return was_used_to_convey_data_; 73 } 74 75 void StreamSocket::UseHistory::EmitPreconnectionHistograms() const { 76 DCHECK(!subresource_speculation_ || !omnibox_speculation_); 77 // 0 ==> non-speculative, never connected. 78 // 1 ==> non-speculative never used (but connected). 79 // 2 ==> non-speculative and used. 80 // 3 ==> omnibox_speculative never connected. 81 // 4 ==> omnibox_speculative never used (but connected). 82 // 5 ==> omnibox_speculative and used. 83 // 6 ==> subresource_speculative never connected. 84 // 7 ==> subresource_speculative never used (but connected). 85 // 8 ==> subresource_speculative and used. 86 int result; 87 if (was_used_to_convey_data_) 88 result = 2; 89 else if (was_ever_connected_) 90 result = 1; 91 else 92 result = 0; // Never used, and not really connected. 93 94 if (omnibox_speculation_) 95 result += 3; 96 else if (subresource_speculation_) 97 result += 6; 98 UMA_HISTOGRAM_ENUMERATION("Net.PreconnectUtilization2", result, 9); 99 } 100 101 } // namespace net 102