Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Unified Diff: content/renderer/p2p/ipc_socket_factory.cc

Issue 759923003: Detect situation when there is no missing send completion signal in P2PSocket implementation. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/common/p2p_socket_type.h ('k') | content/renderer/p2p/socket_client.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..6aeebe3218e0447fc122d7af9acf629b91e5d9e0 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,7 @@ 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;
void OnError() override;
void OnDataReceived(const net::IPEndPoint& address,
const std::vector<char>& data,
@@ -124,7 +137,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 +176,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 +262,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 +402,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 +425,18 @@ 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_->Send(address_chrome, data_vector, options);
+
+ // Ensure packet_id is not 0. It can't be the case according to
+ // P2PSocketClientImpl::Send().
+ 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 +582,29 @@ 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());
+
+ const InFlightPacketRecord& record = in_flight_packet_records_.front();
+
+ // 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 ||
+ record.packet_id == send_metrics.packet_id);
+
+ send_bytes_available_ += record.packet_size;
DCHECK_LE(send_bytes_available_, kMaximumInFlightBytes);
- in_flight_packet_sizes_.pop_front();
+ in_flight_packet_records_.pop_front();
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;
« no previous file with comments | « content/common/p2p_socket_type.h ('k') | content/renderer/p2p/socket_client.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698