Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/renderer/p2p/ipc_socket_factory.h" | 5 #include "content/renderer/p2p/ipc_socket_factory.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <deque> | 8 #include <list> |
| 9 | 9 |
| 10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
| 11 #include "base/debug/trace_event.h" | 11 #include "base/debug/trace_event.h" |
| 12 #include "base/message_loop/message_loop.h" | 12 #include "base/message_loop/message_loop.h" |
| 13 #include "base/message_loop/message_loop_proxy.h" | 13 #include "base/message_loop/message_loop_proxy.h" |
| 14 #include "base/metrics/field_trial.h" | 14 #include "base/metrics/field_trial.h" |
| 15 #include "base/metrics/histogram.h" | 15 #include "base/metrics/histogram.h" |
| 16 #include "base/strings/string_number_conversions.h" | 16 #include "base/strings/string_number_conversions.h" |
| 17 #include "base/strings/stringprintf.h" | 17 #include "base/strings/stringprintf.h" |
| 18 #include "base/threading/non_thread_safe.h" | 18 #include "base/threading/non_thread_safe.h" |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 69 | 69 |
| 70 // IpcPacketSocket implements rtc::AsyncPacketSocket interface | 70 // IpcPacketSocket implements rtc::AsyncPacketSocket interface |
| 71 // using P2PSocketClient that works over IPC-channel. It must be used | 71 // using P2PSocketClient that works over IPC-channel. It must be used |
| 72 // on the thread it was created. | 72 // on the thread it was created. |
| 73 class IpcPacketSocket : public rtc::AsyncPacketSocket, | 73 class IpcPacketSocket : public rtc::AsyncPacketSocket, |
| 74 public P2PSocketClientDelegate { | 74 public P2PSocketClientDelegate { |
| 75 public: | 75 public: |
| 76 IpcPacketSocket(); | 76 IpcPacketSocket(); |
| 77 ~IpcPacketSocket() override; | 77 ~IpcPacketSocket() override; |
| 78 | 78 |
| 79 // Struct to track information when a packet is received by this socket for | |
| 80 // send. The information tracked here will be used to match with the | |
| 81 // P2PSendPacketMetrics from the underneath system socket. | |
| 82 struct InFlightPacketRecord { | |
| 83 InFlightPacketRecord(uint64 packet_id, | |
| 84 size_t packet_size, | |
| 85 uint64 timeticks_received_by_socket) | |
| 86 : packet_id(packet_id), | |
| 87 packet_size(packet_size), | |
| 88 timeticks_received_by_socket(timeticks_received_by_socket) {} | |
| 89 | |
| 90 uint64 packet_id; | |
| 91 size_t packet_size; | |
| 92 // The first time this packet shows up to this socket. | |
| 93 uint64 timeticks_received_by_socket; | |
|
Sergey Ulanov
2014/12/17 20:05:30
use base::TimeTicks type for this. Is this used an
guoweis_left_chromium
2014/12/22 21:41:47
Removed. This should been another change which tra
| |
| 94 }; | |
| 95 | |
| 96 typedef std::list<InFlightPacketRecord> InFlightPacketList; | |
| 97 | |
| 79 // Always takes ownership of client even if initialization fails. | 98 // Always takes ownership of client even if initialization fails. |
| 80 bool Init(P2PSocketType type, P2PSocketClientImpl* client, | 99 bool Init(P2PSocketType type, P2PSocketClientImpl* client, |
| 81 const rtc::SocketAddress& local_address, | 100 const rtc::SocketAddress& local_address, |
| 82 const rtc::SocketAddress& remote_address); | 101 const rtc::SocketAddress& remote_address); |
| 83 | 102 |
| 84 // rtc::AsyncPacketSocket interface. | 103 // rtc::AsyncPacketSocket interface. |
| 85 rtc::SocketAddress GetLocalAddress() const override; | 104 rtc::SocketAddress GetLocalAddress() const override; |
| 86 rtc::SocketAddress GetRemoteAddress() const override; | 105 rtc::SocketAddress GetRemoteAddress() const override; |
| 87 int Send(const void* pv, | 106 int Send(const void* pv, |
| 88 size_t cb, | 107 size_t cb, |
| 89 const rtc::PacketOptions& options) override; | 108 const rtc::PacketOptions& options) override; |
| 90 int SendTo(const void* pv, | 109 int SendTo(const void* pv, |
| 91 size_t cb, | 110 size_t cb, |
| 92 const rtc::SocketAddress& addr, | 111 const rtc::SocketAddress& addr, |
| 93 const rtc::PacketOptions& options) override; | 112 const rtc::PacketOptions& options) override; |
| 94 int Close() override; | 113 int Close() override; |
| 95 State GetState() const override; | 114 State GetState() const override; |
| 96 int GetOption(rtc::Socket::Option option, int* value) override; | 115 int GetOption(rtc::Socket::Option option, int* value) override; |
| 97 int SetOption(rtc::Socket::Option option, int value) override; | 116 int SetOption(rtc::Socket::Option option, int value) override; |
| 98 int GetError() const override; | 117 int GetError() const override; |
| 99 void SetError(int error) override; | 118 void SetError(int error) override; |
| 100 | 119 |
| 101 // P2PSocketClientDelegate implementation. | 120 // P2PSocketClientDelegate implementation. |
| 102 void OnOpen(const net::IPEndPoint& local_address, | 121 void OnOpen(const net::IPEndPoint& local_address, |
| 103 const net::IPEndPoint& remote_address) override; | 122 const net::IPEndPoint& remote_address) override; |
| 104 void OnIncomingTcpConnection(const net::IPEndPoint& address, | 123 void OnIncomingTcpConnection(const net::IPEndPoint& address, |
| 105 P2PSocketClient* client) override; | 124 P2PSocketClient* client) override; |
| 106 void OnSendComplete() override; | 125 void OnSendComplete(const P2PSendPacketMetrics& send_metrics) override; |
| 126 | |
| 107 void OnError() override; | 127 void OnError() override; |
| 108 void OnDataReceived(const net::IPEndPoint& address, | 128 void OnDataReceived(const net::IPEndPoint& address, |
| 109 const std::vector<char>& data, | 129 const std::vector<char>& data, |
| 110 const base::TimeTicks& timestamp) override; | 130 const base::TimeTicks& timestamp) override; |
| 111 | 131 |
| 112 private: | 132 private: |
| 113 enum InternalState { | 133 enum InternalState { |
| 114 IS_UNINITIALIZED, | 134 IS_UNINITIALIZED, |
| 115 IS_OPENING, | 135 IS_OPENING, |
| 116 IS_OPEN, | 136 IS_OPEN, |
| 117 IS_CLOSED, | 137 IS_CLOSED, |
| 118 IS_ERROR, | 138 IS_ERROR, |
| 119 }; | 139 }; |
| 120 | 140 |
| 121 // Increment the counter for consecutive bytes discarded as socket is running | 141 // Increment the counter for consecutive bytes discarded as socket is running |
| 122 // out of buffer. | 142 // out of buffer. |
| 123 void IncrementDiscardCounters(size_t bytes_discarded); | 143 void IncrementDiscardCounters(size_t bytes_discarded); |
| 124 | 144 |
| 125 // Update trace of send throttling internal state. This should be called | 145 // Update trace of send throttling internal state. This should be called |
| 126 // immediately after any changes to |send_bytes_available_| and/or | 146 // immediately after any changes to |send_bytes_available_| and/or |
| 127 // |in_flight_packet_sizes_|. | 147 // |in_flight_packet_records_|. |
| 128 void TraceSendThrottlingState() const; | 148 void TraceSendThrottlingState() const; |
| 129 | 149 |
| 130 void InitAcceptedTcp(P2PSocketClient* client, | 150 void InitAcceptedTcp(P2PSocketClient* client, |
| 131 const rtc::SocketAddress& local_address, | 151 const rtc::SocketAddress& local_address, |
| 132 const rtc::SocketAddress& remote_address); | 152 const rtc::SocketAddress& remote_address); |
| 133 | 153 |
| 134 int DoSetOption(P2PSocketOption option, int value); | 154 int DoSetOption(P2PSocketOption option, int value); |
| 135 | 155 |
| 136 // Allow a finch experiment to control the initial value of | 156 // Allow a finch experiment to control the initial value of |
| 137 // send_bytes_available_; | 157 // send_bytes_available_; |
| 138 void AdjustUdpSendBufferSize(); | 158 void AdjustUdpSendBufferSize(); |
| 139 | 159 |
| 160 // Helper function to find the matching InFlightPacketRecord by packet_id. | |
| 161 // In normal case, it should always be the first one so the perf impact should | |
| 162 // be negligible. Return value is the iterator pointing to the matching | |
| 163 // InFlightPacketRecord. Can be InFlightPacketRecord::end() if no matching one | |
| 164 // is found. | |
| 165 InFlightPacketList::iterator FindInFlightRecord(uint64 packet_id); | |
| 166 | |
| 140 P2PSocketType type_; | 167 P2PSocketType type_; |
| 141 | 168 |
| 142 // Message loop on which this socket was created and being used. | 169 // Message loop on which this socket was created and being used. |
| 143 base::MessageLoop* message_loop_; | 170 base::MessageLoop* message_loop_; |
| 144 | 171 |
| 145 // Corresponding P2P socket client. | 172 // Corresponding P2P socket client. |
| 146 scoped_refptr<P2PSocketClient> client_; | 173 scoped_refptr<P2PSocketClient> client_; |
| 147 | 174 |
| 148 // Local address is allocated by the browser process, and the | 175 // Local address is allocated by the browser process, and the |
| 149 // renderer side doesn't know the address until it receives OnOpen() | 176 // renderer side doesn't know the address until it receives OnOpen() |
| 150 // event from the browser. | 177 // event from the browser. |
| 151 rtc::SocketAddress local_address_; | 178 rtc::SocketAddress local_address_; |
| 152 | 179 |
| 153 // Remote address for client TCP connections. | 180 // Remote address for client TCP connections. |
| 154 rtc::SocketAddress remote_address_; | 181 rtc::SocketAddress remote_address_; |
| 155 | 182 |
| 156 // Current state of the object. | 183 // Current state of the object. |
| 157 InternalState state_; | 184 InternalState state_; |
| 158 | 185 |
| 159 // Track the number of bytes allowed to be sent non-blocking. This is used to | 186 // Track the number of bytes allowed to be sent non-blocking. This is used to |
| 160 // throttle the sending of packets to the browser process. For each packet | 187 // throttle the sending of packets to the browser process. For each packet |
| 161 // sent, the value is decreased. As callbacks to OnSendComplete() (as IPCs | 188 // sent, the value is decreased. As callbacks to OnSendComplete() (as IPCs |
| 162 // from the browser process) are made, the value is increased back. This | 189 // from the browser process) are made, the value is increased back. This |
| 163 // allows short bursts of high-rate sending without dropping packets, but | 190 // allows short bursts of high-rate sending without dropping packets, but |
| 164 // quickly restricts the client to a sustainable steady-state rate. | 191 // quickly restricts the client to a sustainable steady-state rate. |
| 165 size_t send_bytes_available_; | 192 size_t send_bytes_available_; |
| 166 std::deque<size_t> in_flight_packet_sizes_; | 193 |
| 194 // This is a sorted linked list of all InFlightPacketRecord by its packet_id. | |
|
Sergey Ulanov
2014/12/17 20:05:30
You are not actually sorting them by packet_id. Th
guoweis_left_chromium
2014/12/22 21:41:47
Removed that comment.
| |
| 195 // In normal case, the first packet should always be the one that we're going | |
| 196 // to receive the next completion signal. This list gives us a way to look for | |
| 197 // packets that we never receive its completion signal from OS. | |
|
Sergey Ulanov
2014/12/17 20:05:30
If I understand correctly the purpose of this CL i
guoweis_left_chromium
2014/12/22 21:41:47
Done.
| |
| 198 InFlightPacketList in_flight_packet_records_; | |
| 167 | 199 |
| 168 // Set to true once EWOULDBLOCK was returned from Send(). Indicates that the | 200 // Set to true once EWOULDBLOCK was returned from Send(). Indicates that the |
| 169 // caller expects SignalWritable notification. | 201 // caller expects SignalWritable notification. |
| 170 bool writable_signal_expected_; | 202 bool writable_signal_expected_; |
| 171 | 203 |
| 172 // Current error code. Valid when state_ == IS_ERROR. | 204 // Current error code. Valid when state_ == IS_ERROR. |
| 173 int error_; | 205 int error_; |
| 174 int options_[P2P_SOCKET_OPT_MAX]; | 206 int options_[P2P_SOCKET_OPT_MAX]; |
| 175 | 207 |
| 176 // Track the maximum and current consecutive bytes discarded due to not enough | 208 // Track the maximum and current consecutive bytes discarded due to not enough |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 238 if (total_packets_ > 0) { | 270 if (total_packets_ > 0) { |
| 239 UMA_HISTOGRAM_PERCENTAGE("WebRTC.ApplicationPercentPacketsDiscarded", | 271 UMA_HISTOGRAM_PERCENTAGE("WebRTC.ApplicationPercentPacketsDiscarded", |
| 240 (packets_discarded_ * 100) / total_packets_); | 272 (packets_discarded_ * 100) / total_packets_); |
| 241 } | 273 } |
| 242 } | 274 } |
| 243 | 275 |
| 244 void IpcPacketSocket::TraceSendThrottlingState() const { | 276 void IpcPacketSocket::TraceSendThrottlingState() const { |
| 245 TRACE_COUNTER_ID1("p2p", "P2PSendBytesAvailable", local_address_.port(), | 277 TRACE_COUNTER_ID1("p2p", "P2PSendBytesAvailable", local_address_.port(), |
| 246 send_bytes_available_); | 278 send_bytes_available_); |
| 247 TRACE_COUNTER_ID1("p2p", "P2PSendPacketsInFlight", local_address_.port(), | 279 TRACE_COUNTER_ID1("p2p", "P2PSendPacketsInFlight", local_address_.port(), |
| 248 in_flight_packet_sizes_.size()); | 280 in_flight_packet_records_.size()); |
| 249 } | 281 } |
| 250 | 282 |
| 251 void IpcPacketSocket::IncrementDiscardCounters(size_t bytes_discarded) { | 283 void IpcPacketSocket::IncrementDiscardCounters(size_t bytes_discarded) { |
| 252 current_discard_bytes_sequence_ += bytes_discarded; | 284 current_discard_bytes_sequence_ += bytes_discarded; |
| 253 packets_discarded_++; | 285 packets_discarded_++; |
| 254 | 286 |
| 255 if (current_discard_bytes_sequence_ > max_discard_bytes_sequence_) { | 287 if (current_discard_bytes_sequence_ > max_discard_bytes_sequence_) { |
| 256 max_discard_bytes_sequence_ = current_discard_bytes_sequence_; | 288 max_discard_bytes_sequence_ = current_discard_bytes_sequence_; |
| 257 } | 289 } |
| 258 } | 290 } |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 363 return EWOULDBLOCK; | 395 return EWOULDBLOCK; |
| 364 case IS_CLOSED: | 396 case IS_CLOSED: |
| 365 return ENOTCONN; | 397 return ENOTCONN; |
| 366 case IS_ERROR: | 398 case IS_ERROR: |
| 367 return error_; | 399 return error_; |
| 368 case IS_OPEN: | 400 case IS_OPEN: |
| 369 // Continue sending the packet. | 401 // Continue sending the packet. |
| 370 break; | 402 break; |
| 371 } | 403 } |
| 372 | 404 |
| 405 uint64 tick_received_in_socket = base::TimeTicks::Now().ToInternalValue(); | |
| 406 | |
| 373 if (data_size == 0) { | 407 if (data_size == 0) { |
| 374 NOTREACHED(); | 408 NOTREACHED(); |
| 375 return 0; | 409 return 0; |
| 376 } | 410 } |
| 377 | 411 |
| 378 total_packets_++; | 412 total_packets_++; |
| 379 | 413 |
| 380 if (data_size > send_bytes_available_) { | 414 if (data_size > send_bytes_available_) { |
| 381 TRACE_EVENT_INSTANT1("p2p", "MaxPendingBytesWouldBlock", | 415 TRACE_EVENT_INSTANT1("p2p", "MaxPendingBytesWouldBlock", |
| 382 TRACE_EVENT_SCOPE_THREAD, | 416 TRACE_EVENT_SCOPE_THREAD, |
| 383 "id", | 417 "id", |
| 384 client_->GetSocketID()); | 418 client_->GetSocketID()); |
| 385 if (!writable_signal_expected_) { | 419 if (!writable_signal_expected_) { |
| 386 WebRtcLogMessage(base::StringPrintf( | 420 WebRtcLogMessage(base::StringPrintf( |
| 387 "IpcPacketSocket: sending is blocked. %d packets_in_flight.", | 421 "IpcPacketSocket: sending is blocked. %d packets_in_flight.", |
| 388 static_cast<int>(in_flight_packet_sizes_.size()))); | 422 static_cast<int>(in_flight_packet_records_.size()))); |
| 389 | 423 |
| 390 writable_signal_expected_ = true; | 424 writable_signal_expected_ = true; |
| 391 } | 425 } |
| 392 | 426 |
| 393 error_ = EWOULDBLOCK; | 427 error_ = EWOULDBLOCK; |
| 394 IncrementDiscardCounters(data_size); | 428 IncrementDiscardCounters(data_size); |
| 395 return -1; | 429 return -1; |
| 396 } else { | 430 } else { |
| 397 current_discard_bytes_sequence_ = 0; | 431 current_discard_bytes_sequence_ = 0; |
| 398 } | 432 } |
| 399 | 433 |
| 400 net::IPEndPoint address_chrome; | 434 net::IPEndPoint address_chrome; |
| 401 if (!jingle_glue::SocketAddressToIPEndPoint(address, &address_chrome)) { | 435 if (!jingle_glue::SocketAddressToIPEndPoint(address, &address_chrome)) { |
| 402 DVLOG(1) << "Failed to convert remote address to IPEndPoint: address = " | 436 DVLOG(1) << "Failed to convert remote address to IPEndPoint: address = " |
| 403 << address.ToSensitiveString() << ", remote_address_ = " | 437 << address.ToSensitiveString() << ", remote_address_ = " |
| 404 << remote_address_.ToSensitiveString(); | 438 << remote_address_.ToSensitiveString(); |
| 405 NOTREACHED(); | 439 NOTREACHED(); |
| 406 error_ = EINVAL; | 440 error_ = EINVAL; |
| 407 return -1; | 441 return -1; |
| 408 } | 442 } |
| 409 | 443 |
| 410 send_bytes_available_ -= data_size; | 444 send_bytes_available_ -= data_size; |
| 411 in_flight_packet_sizes_.push_back(data_size); | |
| 412 TraceSendThrottlingState(); | |
| 413 | 445 |
| 414 const char* data_char = reinterpret_cast<const char*>(data); | 446 const char* data_char = reinterpret_cast<const char*>(data); |
| 415 std::vector<char> data_vector(data_char, data_char + data_size); | 447 std::vector<char> data_vector(data_char, data_char + data_size); |
| 416 client_->SendWithDscp(address_chrome, data_vector, options); | 448 uint64 packet_id = |
| 449 client_->SendWithDscp(address_chrome, data_vector, options); | |
| 450 | |
| 451 // Ensure packet_id is not 0. It can't be the case according to | |
| 452 // P2PSocketClientImpl::SendWithDscp(). | |
| 453 DCHECK_NE(packet_id, 0uL); | |
| 454 | |
| 455 // Since OnSendComplete happens on the same thread, there is no chance that | |
|
Sergey Ulanov
2014/12/17 20:05:30
nit: I don't think you really need this comment. I
guoweis_left_chromium
2014/12/22 21:41:47
Done.
| |
| 456 // for the same packet, OnSendComplete is called before SendWithDscp is | |
| 457 // finished with |packet_id| back. | |
| 458 in_flight_packet_records_.push_back( | |
| 459 InFlightPacketRecord(packet_id, data_size, tick_received_in_socket)); | |
| 460 TraceSendThrottlingState(); | |
| 417 | 461 |
| 418 // Fake successful send. The caller ignores result anyway. | 462 // Fake successful send. The caller ignores result anyway. |
| 419 return data_size; | 463 return data_size; |
| 420 } | 464 } |
| 421 | 465 |
| 422 int IpcPacketSocket::Close() { | 466 int IpcPacketSocket::Close() { |
| 423 DCHECK_EQ(base::MessageLoop::current(), message_loop_); | 467 DCHECK_EQ(base::MessageLoop::current(), message_loop_); |
| 424 | 468 |
| 425 client_->Close(); | 469 client_->Close(); |
| 426 state_ = IS_CLOSED; | 470 state_ = IS_CLOSED; |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 552 | 596 |
| 553 rtc::SocketAddress remote_address; | 597 rtc::SocketAddress remote_address; |
| 554 if (!jingle_glue::IPEndPointToSocketAddress(address, &remote_address)) { | 598 if (!jingle_glue::IPEndPointToSocketAddress(address, &remote_address)) { |
| 555 // Always expect correct IPv4 address to be allocated. | 599 // Always expect correct IPv4 address to be allocated. |
| 556 NOTREACHED(); | 600 NOTREACHED(); |
| 557 } | 601 } |
| 558 socket->InitAcceptedTcp(client, local_address_, remote_address); | 602 socket->InitAcceptedTcp(client, local_address_, remote_address); |
| 559 SignalNewConnection(this, socket.release()); | 603 SignalNewConnection(this, socket.release()); |
| 560 } | 604 } |
| 561 | 605 |
| 562 void IpcPacketSocket::OnSendComplete() { | 606 // For most of the case, the completion signal should be returned for the packet |
| 607 // at the beginning of |in_flight_packet_records_| so the perf impact should be | |
| 608 // negligible. | |
| 609 IpcPacketSocket::InFlightPacketList::iterator | |
| 610 IpcPacketSocket::FindInFlightRecord(uint64 packet_id) { | |
| 611 CHECK(!in_flight_packet_records_.empty()); | |
| 612 InFlightPacketList::iterator it = in_flight_packet_records_.begin(); | |
| 613 for (; it != in_flight_packet_records_.end(); ++it) { | |
| 614 if (it->packet_id == packet_id) { | |
| 615 break; | |
| 616 } | |
| 617 } | |
| 618 | |
| 619 // We should always be able to find matching packet_id in the | |
| 620 // in_flight_packet_records_. | |
| 621 DCHECK(it != in_flight_packet_records_.end()); | |
| 622 return it; | |
| 623 } | |
| 624 | |
| 625 void IpcPacketSocket::OnSendComplete(const P2PSendPacketMetrics& send_metrics) { | |
| 563 DCHECK_EQ(base::MessageLoop::current(), message_loop_); | 626 DCHECK_EQ(base::MessageLoop::current(), message_loop_); |
| 564 | 627 |
| 565 CHECK(!in_flight_packet_sizes_.empty()); | 628 CHECK(!in_flight_packet_records_.empty()); |
| 566 send_bytes_available_ += in_flight_packet_sizes_.front(); | 629 |
| 630 InFlightPacketList::iterator it; | |
| 631 if (send_metrics.packet_id == 0) { | |
|
Sergey Ulanov
2014/12/17 20:05:30
When does this happen? Why do you need this?
guoweis_left_chromium
2014/12/22 21:41:47
TCP. We're not tracking tcp's packet id so this is
| |
| 632 // If send_metrics doesn't carry valid packet_id, it means that we should | |
| 633 // not try to detect mismatch packets. | |
| 634 it = in_flight_packet_records_.begin(); | |
| 635 } else { | |
| 636 it = FindInFlightRecord(send_metrics.packet_id); | |
|
Sergey Ulanov
2014/12/17 20:05:30
I don't think you need this because we never expec
guoweis_left_chromium
2014/12/22 21:41:47
Done.
| |
| 637 | |
| 638 // If we can't find the record, something has gone very wrong at this point. | |
| 639 if (it == in_flight_packet_records_.end()) { | |
| 640 VLOG(1) << "Failed to find in-flight record with packet_id = " | |
| 641 << send_metrics.packet_id; | |
| 642 NOTREACHED(); | |
| 643 return; | |
| 644 } | |
| 645 } | |
| 646 | |
| 647 send_bytes_available_ += it->packet_size; | |
| 648 | |
| 649 // Here is to detect a completion signal is not returned. We can't rely on the | |
| 650 // destructor since if a user closes the tab, the destructor is not | |
| 651 // invoked. Or if a user inputs another url, the destructor will be called | |
| 652 // before all completion signals return. | |
| 653 if (send_metrics.packet_id != 0 && | |
| 654 in_flight_packet_records_.front().packet_id != send_metrics.packet_id) { | |
| 655 // Report an instance that a packet didn't have its completion | |
| 656 // signal returned. | |
| 657 UMA_HISTOGRAM_BOOLEAN("WebRTC.ApplicationSocketMismatchPacketsDetected_UDP", | |
|
Sergey Ulanov
2014/12/17 20:05:30
I don't think you need UMA metric for this. Just C
guoweis_left_chromium
2014/12/22 21:41:47
Done.
| |
| 658 true); | |
| 659 } | |
| 567 | 660 |
| 568 DCHECK_LE(send_bytes_available_, kMaximumInFlightBytes); | 661 DCHECK_LE(send_bytes_available_, kMaximumInFlightBytes); |
| 569 | 662 |
| 570 in_flight_packet_sizes_.pop_front(); | 663 in_flight_packet_records_.erase(it); |
| 571 TraceSendThrottlingState(); | 664 TraceSendThrottlingState(); |
| 572 | 665 |
| 573 if (writable_signal_expected_ && send_bytes_available_ > 0) { | 666 if (writable_signal_expected_ && send_bytes_available_ > 0) { |
| 574 WebRtcLogMessage(base::StringPrintf( | 667 WebRtcLogMessage(base::StringPrintf( |
| 575 "IpcPacketSocket: sending is unblocked. %d packets in flight.", | 668 "IpcPacketSocket: sending is unblocked. %d packets in flight.", |
| 576 static_cast<int>(in_flight_packet_sizes_.size()))); | 669 static_cast<int>(in_flight_packet_records_.size()))); |
| 577 | 670 |
| 578 SignalReadyToSend(this); | 671 SignalReadyToSend(this); |
| 579 writable_signal_expected_ = false; | 672 writable_signal_expected_ = false; |
| 580 } | 673 } |
| 581 } | 674 } |
| 582 | 675 |
| 583 void IpcPacketSocket::OnError() { | 676 void IpcPacketSocket::OnError() { |
| 584 DCHECK_EQ(base::MessageLoop::current(), message_loop_); | 677 DCHECK_EQ(base::MessageLoop::current(), message_loop_); |
| 585 bool was_closed = (state_ == IS_ERROR || state_ == IS_CLOSED); | 678 bool was_closed = (state_ == IS_ERROR || state_ == IS_CLOSED); |
| 586 state_ = IS_ERROR; | 679 state_ = IS_ERROR; |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 740 } | 833 } |
| 741 | 834 |
| 742 rtc::AsyncResolverInterface* | 835 rtc::AsyncResolverInterface* |
| 743 IpcPacketSocketFactory::CreateAsyncResolver() { | 836 IpcPacketSocketFactory::CreateAsyncResolver() { |
| 744 scoped_ptr<AsyncAddressResolverImpl> resolver( | 837 scoped_ptr<AsyncAddressResolverImpl> resolver( |
| 745 new AsyncAddressResolverImpl(socket_dispatcher_)); | 838 new AsyncAddressResolverImpl(socket_dispatcher_)); |
| 746 return resolver.release(); | 839 return resolver.release(); |
| 747 } | 840 } |
| 748 | 841 |
| 749 } // namespace content | 842 } // namespace content |
| OLD | NEW |