| Index: chrome/browser/net/network_stats.cc
|
| diff --git a/chrome/browser/net/network_stats.cc b/chrome/browser/net/network_stats.cc
|
| index 223bade9bcf3d28b986803cf6dc941318d197681..c218227e454c246ee0ca75f943a770880d9a95e7 100644
|
| --- a/chrome/browser/net/network_stats.cc
|
| +++ b/chrome/browser/net/network_stats.cc
|
| @@ -128,6 +128,8 @@ NetworkStats::NetworkStats(net::ClientSocketFactory* socket_factory)
|
| probe_packet_bytes_(0),
|
| bytes_for_packet_size_test_(0),
|
| current_test_index_(0),
|
| + read_state_(READ_STATE_IDLE),
|
| + write_state_(WRITE_STATE_IDLE),
|
| weak_factory_(this) {
|
| ResetData();
|
| }
|
| @@ -171,6 +173,7 @@ bool NetworkStats::Start(net::HostResolver* host_resolver,
|
|
|
| void NetworkStats::StartOneTest() {
|
| if (test_sequence_[current_test_index_] == TOKEN_REQUEST) {
|
| + DCHECK_EQ(WRITE_STATE_IDLE, write_state_);
|
| write_buffer_ = NULL;
|
| SendHelloRequest();
|
| } else {
|
| @@ -179,6 +182,7 @@ void NetworkStats::StartOneTest() {
|
| }
|
|
|
| void NetworkStats::ResetData() {
|
| + DCHECK_EQ(WRITE_STATE_IDLE, write_state_);
|
| write_buffer_ = NULL;
|
| packets_received_mask_.reset();
|
| first_arrival_time_ = base::TimeTicks();
|
| @@ -312,6 +316,9 @@ int NetworkStats::ReadData() {
|
| if (!socket_.get())
|
| return 0;
|
|
|
| + if (read_state_ == READ_STATE_READ_PENDING)
|
| + return net::ERR_IO_PENDING;
|
| +
|
| int rv = 0;
|
| do {
|
| DCHECK(!read_buffer_.get());
|
| @@ -322,10 +329,16 @@ int NetworkStats::ReadData() {
|
| kMaxMessageSize,
|
| base::Bind(&NetworkStats::OnReadComplete, weak_factory_.GetWeakPtr()));
|
| } while (rv > 0 && !ReadComplete(rv));
|
| + if (rv == net::ERR_IO_PENDING)
|
| + read_state_ = READ_STATE_READ_PENDING;
|
| return rv;
|
| }
|
|
|
| void NetworkStats::OnReadComplete(int result) {
|
| + DCHECK_NE(net::ERR_IO_PENDING, result);
|
| + DCHECK_EQ(READ_STATE_READ_PENDING, read_state_);
|
| +
|
| + read_state_ = READ_STATE_IDLE;
|
| if (!ReadComplete(result)) {
|
| // Called ReadData() via PostDelayedTask() to avoid recursion. Added a delay
|
| // of 1ms so that the time-out will fire before we have time to really hog
|
| @@ -438,8 +451,10 @@ bool NetworkStats::UpdateReception(const ProbePacket& probe_packet) {
|
| }
|
|
|
| int NetworkStats::SendData(const std::string& output) {
|
| - if (write_buffer_.get() || !socket_.get())
|
| + if (write_buffer_.get() || !socket_.get() ||
|
| + write_state_ == WRITE_STATE_WRITE_PENDING) {
|
| return net::ERR_UNEXPECTED;
|
| + }
|
| scoped_refptr<net::StringIOBuffer> buffer(new net::StringIOBuffer(output));
|
| write_buffer_ = new net::DrainableIOBuffer(buffer.get(), buffer->size());
|
|
|
| @@ -447,16 +462,20 @@ int NetworkStats::SendData(const std::string& output) {
|
| write_buffer_.get(),
|
| write_buffer_->BytesRemaining(),
|
| base::Bind(&NetworkStats::OnWriteComplete, weak_factory_.GetWeakPtr()));
|
| - if (bytes_written < 0)
|
| + if (bytes_written < 0) {
|
| + if (bytes_written == net::ERR_IO_PENDING)
|
| + write_state_ = WRITE_STATE_WRITE_PENDING;
|
| return bytes_written;
|
| + }
|
| UpdateSendBuffer(bytes_written);
|
| return net::OK;
|
| }
|
|
|
| void NetworkStats::OnWriteComplete(int result) {
|
| - DCHECK(socket_.get());
|
| DCHECK_NE(net::ERR_IO_PENDING, result);
|
| - if (result < 0) {
|
| + DCHECK_EQ(WRITE_STATE_WRITE_PENDING, write_state_);
|
| + write_state_ = WRITE_STATE_IDLE;
|
| + if (result < 0 || !socket_.get() || write_buffer_ == NULL) {
|
| TestPhaseComplete(WRITE_FAILED, result);
|
| return;
|
| }
|
| @@ -466,6 +485,7 @@ void NetworkStats::OnWriteComplete(int result) {
|
| void NetworkStats::UpdateSendBuffer(int bytes_sent) {
|
| write_buffer_->DidConsume(bytes_sent);
|
| DCHECK_EQ(write_buffer_->BytesRemaining(), 0);
|
| + DCHECK_EQ(WRITE_STATE_IDLE, write_state_);
|
| write_buffer_ = NULL;
|
| }
|
|
|
| @@ -513,8 +533,10 @@ void NetworkStats::OnReadDataTimeout(uint32 test_index) {
|
| void NetworkStats::TestPhaseComplete(Status status, int result) {
|
| // If there is no valid token, do nothing and delete self.
|
| // This includes all connection error, name resolve error, etc.
|
| - if (token_.timestamp_micros() != 0 &&
|
| - (status == SUCCESS || status == READ_TIMED_OUT)) {
|
| + if (write_state_ == WRITE_STATE_WRITE_PENDING) {
|
| + UMA_HISTOGRAM_BOOLEAN("NetConnectivity5.TestFailed.WritePending", true);
|
| + } else if (token_.timestamp_micros() != 0 &&
|
| + (status == SUCCESS || status == READ_TIMED_OUT)) {
|
| TestType current_test = test_sequence_[current_test_index_];
|
| DCHECK_LT(current_test, TEST_TYPE_MAX);
|
| if (current_test != TOKEN_REQUEST) {
|
| @@ -601,7 +623,7 @@ void NetworkStats::RecordHistograms(TestType test_type) {
|
| void NetworkStats::RecordInterArrivalHistograms(TestType test_type) {
|
| DCHECK_NE(test_type, PACKET_SIZE_TEST);
|
| std::string histogram_name =
|
| - base::StringPrintf("NetConnectivity4.%s.Sent%d.PacketDelay.%d.%dB",
|
| + base::StringPrintf("NetConnectivity5.%s.Sent%d.PacketDelay.%d.%dB",
|
| kTestName[test_type],
|
| maximum_sequential_packets_,
|
| histogram_port_,
|
| @@ -614,7 +636,7 @@ void NetworkStats::RecordPacketsReceivedHistograms(TestType test_type) {
|
| DCHECK_NE(test_type, PACKET_SIZE_TEST);
|
| const char* test_name = kTestName[test_type];
|
| std::string histogram_prefix = base::StringPrintf(
|
| - "NetConnectivity4.%s.Sent%d.", test_name, maximum_sequential_packets_);
|
| + "NetConnectivity5.%s.Sent%d.", test_name, maximum_sequential_packets_);
|
| std::string histogram_suffix =
|
| base::StringPrintf(".%d.%dB", histogram_port_, probe_packet_bytes_);
|
| std::string name = histogram_prefix + "GotAPacket" + histogram_suffix;
|
| @@ -661,7 +683,7 @@ void NetworkStats::RecordNATTestReceivedHistograms(Status status) {
|
| : "Connectivity.Failure";
|
| // Record whether the HelloRequest got reply successfully.
|
| std::string histogram_name =
|
| - base::StringPrintf("NetConnectivity4.%s.Sent%d.%s.%d.%dB",
|
| + base::StringPrintf("NetConnectivity5.%s.Sent%d.%s.%d.%dB",
|
| test_name,
|
| maximum_NAT_packets_,
|
| middle_name.c_str(),
|
| @@ -681,7 +703,7 @@ void NetworkStats::RecordNATTestReceivedHistograms(Status status) {
|
|
|
| middle_name = packets_received_mask_.test(1) ? "Bind.Success"
|
| : "Bind.Failure";
|
| - histogram_name = base::StringPrintf("NetConnectivity4.%s.Sent%d.%s.%d.%dB",
|
| + histogram_name = base::StringPrintf("NetConnectivity5.%s.Sent%d.%s.%d.%dB",
|
| test_name,
|
| maximum_NAT_packets_,
|
| middle_name.c_str(),
|
| @@ -701,7 +723,7 @@ void NetworkStats::RecordPacketSizeTestReceivedHistograms(Status status) {
|
| : "Connectivity.Failure";
|
| // Record whether the HelloRequest got reply successfully.
|
| std::string histogram_name =
|
| - base::StringPrintf("NetConnectivity4.%s.%s.%d",
|
| + base::StringPrintf("NetConnectivity5.%s.%s.%d",
|
| test_name,
|
| middle_name.c_str(),
|
| histogram_port_);
|
| @@ -715,10 +737,10 @@ void NetworkStats::RecordPacketSizeTestReceivedHistograms(Status status) {
|
| void NetworkStats::RecordPacketLossSeriesHistograms(TestType test_type) {
|
| DCHECK_NE(test_type, PACKET_SIZE_TEST);
|
| const char* test_name = kTestName[test_type];
|
| - // Build "NetConnectivity4.<TestName>.First6.SeriesRecv.<port>.<probe_size>"
|
| + // Build "NetConnectivity5.<TestName>.First6.SeriesRecv.<port>.<probe_size>"
|
| // histogram name. Total 3(tests) x 12 histograms.
|
| std::string series_acked_histogram_name =
|
| - base::StringPrintf("NetConnectivity4.%s.First6.SeriesRecv.%d.%dB",
|
| + base::StringPrintf("NetConnectivity5.%s.First6.SeriesRecv.%d.%dB",
|
| test_name,
|
| histogram_port_,
|
| probe_packet_bytes_);
|
| @@ -746,7 +768,7 @@ void NetworkStats::RecordRTTHistograms(TestType test_type, uint32 index) {
|
| return; // Probe packet never received.
|
|
|
| std::string rtt_histogram_name = base::StringPrintf(
|
| - "NetConnectivity4.%s.Sent%d.Success.RTT.Packet%02d.%d.%dB",
|
| + "NetConnectivity5.%s.Sent%d.Success.RTT.Packet%02d.%d.%dB",
|
| kTestName[test_type],
|
| maximum_sequential_packets_,
|
| index + 1,
|
| @@ -762,7 +784,7 @@ void NetworkStats::RecordSendToLastRecvDelayHistograms(TestType test_type) {
|
| uint32 packets_sent = test_type == NAT_BIND_TEST
|
| ? maximum_NAT_packets_ : maximum_sequential_packets_;
|
| std::string histogram_name = base::StringPrintf(
|
| - "NetConnectivity4.%s.Sent%d.SendToLastRecvDelay.%d.%dB",
|
| + "NetConnectivity5.%s.Sent%d.SendToLastRecvDelay.%d.%dB",
|
| kTestName[test_type],
|
| packets_sent,
|
| histogram_port_,
|
|
|