Chromium Code Reviews| Index: content/renderer/p2p/ipc_socket_factory.cc |
| diff --git a/content/renderer/p2p/ipc_socket_factory.cc b/content/renderer/p2p/ipc_socket_factory.cc |
| index b56ebbab336bb8c7a288eafb97eaaae47c684b1e..0854e5c976c1103bb7b5a31fab2b06e40a3c4ad9 100644 |
| --- a/content/renderer/p2p/ipc_socket_factory.cc |
| +++ b/content/renderer/p2p/ipc_socket_factory.cc |
| @@ -5,7 +5,7 @@ |
| #include "content/renderer/p2p/ipc_socket_factory.h" |
| #include <algorithm> |
| -#include <deque> |
| +#include <list> |
| #include "base/compiler_specific.h" |
| #include "base/debug/trace_event.h" |
| @@ -76,6 +76,19 @@ class IpcPacketSocket : public rtc::AsyncPacketSocket, |
| IpcPacketSocket(); |
| ~IpcPacketSocket() override; |
| + // Struct to track information when a packet is received by this socket for |
| + // send. The information tracked here will be used to match with the |
| + // P2PSendPacketMetrics from the underneath system socket. |
| + struct InFlightPacketRecord { |
| + InFlightPacketRecord(uint64_t packet_id, size_t packet_size) |
| + : packet_id(packet_id), packet_size(packet_size) {} |
| + |
| + uint64_t packet_id; |
| + size_t packet_size; |
| + }; |
| + |
| + typedef std::list<InFlightPacketRecord> InFlightPacketList; |
| + |
| // Always takes ownership of client even if initialization fails. |
| bool Init(P2PSocketType type, P2PSocketClientImpl* client, |
| const rtc::SocketAddress& local_address, |
| @@ -103,7 +116,8 @@ class IpcPacketSocket : public rtc::AsyncPacketSocket, |
| const net::IPEndPoint& remote_address) override; |
| void OnIncomingTcpConnection(const net::IPEndPoint& address, |
| P2PSocketClient* client) override; |
| - void OnSendComplete() override; |
| + void OnSendComplete(const P2PSendPacketMetrics& send_metrics) override; |
| + |
|
Sergey Ulanov
2014/12/23 01:11:02
nit: Don't need this empty line.
guoweis_left_chromium
2014/12/23 18:53:16
Done.
|
| void OnError() override; |
| void OnDataReceived(const net::IPEndPoint& address, |
| const std::vector<char>& data, |
| @@ -124,7 +138,7 @@ class IpcPacketSocket : public rtc::AsyncPacketSocket, |
| // Update trace of send throttling internal state. This should be called |
| // immediately after any changes to |send_bytes_available_| and/or |
| - // |in_flight_packet_sizes_|. |
| + // |in_flight_packet_records_|. |
| void TraceSendThrottlingState() const; |
| void InitAcceptedTcp(P2PSocketClient* client, |
| @@ -163,7 +177,11 @@ class IpcPacketSocket : public rtc::AsyncPacketSocket, |
| // allows short bursts of high-rate sending without dropping packets, but |
| // quickly restricts the client to a sustainable steady-state rate. |
| size_t send_bytes_available_; |
| - std::deque<size_t> in_flight_packet_sizes_; |
| + |
| + // Used to detect when browser doesn't send SendComplete message for some |
| + // packets. In normal case, the first packet should be the one that we're |
| + // going to receive the next completion signal. |
| + InFlightPacketList in_flight_packet_records_; |
| // Set to true once EWOULDBLOCK was returned from Send(). Indicates that the |
| // caller expects SignalWritable notification. |
| @@ -245,7 +263,7 @@ void IpcPacketSocket::TraceSendThrottlingState() const { |
| TRACE_COUNTER_ID1("p2p", "P2PSendBytesAvailable", local_address_.port(), |
| send_bytes_available_); |
| TRACE_COUNTER_ID1("p2p", "P2PSendPacketsInFlight", local_address_.port(), |
| - in_flight_packet_sizes_.size()); |
| + in_flight_packet_records_.size()); |
| } |
| void IpcPacketSocket::IncrementDiscardCounters(size_t bytes_discarded) { |
| @@ -385,7 +403,7 @@ int IpcPacketSocket::SendTo(const void *data, size_t data_size, |
| if (!writable_signal_expected_) { |
| WebRtcLogMessage(base::StringPrintf( |
| "IpcPacketSocket: sending is blocked. %d packets_in_flight.", |
| - static_cast<int>(in_flight_packet_sizes_.size()))); |
| + static_cast<int>(in_flight_packet_records_.size()))); |
| writable_signal_expected_ = true; |
| } |
| @@ -408,12 +426,19 @@ int IpcPacketSocket::SendTo(const void *data, size_t data_size, |
| } |
| send_bytes_available_ -= data_size; |
| - in_flight_packet_sizes_.push_back(data_size); |
| - TraceSendThrottlingState(); |
| const char* data_char = reinterpret_cast<const char*>(data); |
| std::vector<char> data_vector(data_char, data_char + data_size); |
| - client_->SendWithDscp(address_chrome, data_vector, options); |
| + uint64_t packet_id = |
| + client_->SendWithDscp(address_chrome, data_vector, options); |
| + |
| + // Ensure packet_id is not 0. It can't be the case according to |
| + // P2PSocketClientImpl::SendWithDscp(). |
| + DCHECK_NE(packet_id, 0uL); |
| + |
| + in_flight_packet_records_.push_back( |
| + InFlightPacketRecord(packet_id, data_size)); |
| + TraceSendThrottlingState(); |
| // Fake successful send. The caller ignores result anyway. |
| return data_size; |
| @@ -559,21 +584,28 @@ void IpcPacketSocket::OnIncomingTcpConnection( |
| SignalNewConnection(this, socket.release()); |
| } |
| -void IpcPacketSocket::OnSendComplete() { |
| +void IpcPacketSocket::OnSendComplete(const P2PSendPacketMetrics& send_metrics) { |
| DCHECK_EQ(base::MessageLoop::current(), message_loop_); |
| - CHECK(!in_flight_packet_sizes_.empty()); |
| - send_bytes_available_ += in_flight_packet_sizes_.front(); |
| + CHECK(!in_flight_packet_records_.empty()); |
| + |
| + InFlightPacketList::iterator it = in_flight_packet_records_.begin(); |
|
Sergey Ulanov
2014/12/23 01:11:02
nit: this can be:
const InFlightPacketRecord& pack
guoweis_left_chromium
2014/12/23 18:53:16
Done.
|
| + |
| + // Tracking is not turned on for TCP so it's always 0. For UDP, this will |
| + // cause a crash when the packet ids don't match. |
| + CHECK(send_metrics.packet_id == 0 || it->packet_id == send_metrics.packet_id); |
| + |
| + send_bytes_available_ += it->packet_size; |
| DCHECK_LE(send_bytes_available_, kMaximumInFlightBytes); |
| - in_flight_packet_sizes_.pop_front(); |
| + in_flight_packet_records_.erase(it); |
|
Sergey Ulanov
2014/12/23 01:11:02
pop_front()?
guoweis_left_chromium
2014/12/23 18:53:16
Done.
|
| TraceSendThrottlingState(); |
| if (writable_signal_expected_ && send_bytes_available_ > 0) { |
| WebRtcLogMessage(base::StringPrintf( |
| "IpcPacketSocket: sending is unblocked. %d packets in flight.", |
| - static_cast<int>(in_flight_packet_sizes_.size()))); |
| + static_cast<int>(in_flight_packet_records_.size()))); |
| SignalReadyToSend(this); |
| writable_signal_expected_ = false; |