Chromium Code Reviews| Index: content/browser/renderer_host/p2p/socket_host_udp.cc |
| diff --git a/content/browser/renderer_host/p2p/socket_host_udp.cc b/content/browser/renderer_host/p2p/socket_host_udp.cc |
| index 3bea4dfb2d71d23bb8fd66a3e707aff3b8ea6953..b2ca86afec62f586684a4740fd2ed61dae67eb4a 100644 |
| --- a/content/browser/renderer_host/p2p/socket_host_udp.cc |
| +++ b/content/browser/renderer_host/p2p/socket_host_udp.cc |
| @@ -6,6 +6,8 @@ |
| #include "base/bind.h" |
| #include "base/debug/trace_event.h" |
| +#include "base/metrics/field_trial.h" |
| +#include "base/metrics/histogram.h" |
| #include "base/stl_util.h" |
| #include "content/browser/renderer_host/p2p/socket_host_throttler.h" |
| #include "content/common/p2p_messages.h" |
| @@ -74,6 +76,7 @@ P2PSocketHostUdp::P2PSocketHostUdp(IPC::Sender* message_sender, |
| net::NetLog::Source())), |
| send_pending_(false), |
| last_dscp_(net::DSCP_CS0), |
| + random_socket_id_prefix_(0), |
| throttler_(throttler) { |
| } |
| @@ -84,6 +87,28 @@ P2PSocketHostUdp::~P2PSocketHostUdp() { |
| } |
| } |
| +void P2PSocketHostUdp::SetSendBufferSize() { |
| + int send_buffer_size = 0; |
| + if (base::FieldTrialList::FindFullName("WebRTC-SystemUDPSendSocketSize") == |
|
juberti2
2014/11/04 06:00:18
Seems like we should read FindFullName into a stri
Alexei Svitkine (slow)
2014/11/04 15:17:50
Agreed.
guoweis2
2014/11/07 22:18:19
Done.
|
| + "2K") { |
| + send_buffer_size = 2048; |
| + } else if (base::FieldTrialList::FindFullName( |
| + "WebRTC-SystemUDPSendSocketSize") == "64K") { |
|
Alexei Svitkine (slow)
2014/11/04 15:17:50
I would normally suggest to use variation params h
guoweis2
2014/11/07 22:18:19
Variation is not allowed so following the pattern
|
| + send_buffer_size = 65536; |
| + } else if (base::FieldTrialList::FindFullName( |
| + "WebRTC-SystemUDPSendSocketSize") == "256K") { |
| + send_buffer_size = 262144; |
|
Alexei Svitkine (slow)
2014/11/04 15:17:50
Nit: It would be more readable to have these be 25
guoweis2
2014/11/07 22:18:19
Done.
|
| + } |
| + |
| + if (send_buffer_size > 0) { |
|
juberti2
2014/11/04 06:00:18
Probably want to invalidate the experiment if this
guoweis2
2014/11/07 22:18:19
Alexei, is there a way to invalidate this instance
|
| + // Setting send socket buffer size. |
| + if (socket_->SetSendBufferSize(send_buffer_size) != net::OK) { |
| + LOG(WARNING) << "Failed to set socket send buffer size to " |
| + << send_buffer_size; |
| + } |
| + } |
| +} |
| + |
| bool P2PSocketHostUdp::Init(const net::IPEndPoint& local_address, |
| const P2PHostAndIPEndPoint& remote_address) { |
| DCHECK_EQ(state_, STATE_UNINITIALIZED); |
| @@ -101,6 +126,8 @@ bool P2PSocketHostUdp::Init(const net::IPEndPoint& local_address, |
| << kRecvSocketBufferSize; |
| } |
| + SetSendBufferSize(); |
| + |
| net::IPEndPoint address; |
| result = socket_->GetLocalAddress(&address); |
| if (result < 0) { |
| @@ -194,6 +221,15 @@ void P2PSocketHostUdp::Send(const net::IPEndPoint& to, |
| return; |
| } |
| + // The lower 32 bits of packet id is a sequence number. 2^32 bits is a large |
| + // number space. If we send 1000 packets per second, it'll take 49 days to |
| + // finish 2^32 bits. |
| + if (random_socket_id_prefix_ == 0) { |
| + random_socket_id_prefix_ = (packet_id >> 32) << 32; |
| + } else { |
| + DCHECK_EQ((random_socket_id_prefix_ >> 32), (packet_id >> 32)); |
| + } |
| + |
| if (!ContainsKey(connected_peers_, to)) { |
| P2PSocketHost::StunMessageType type = P2PSocketHost::StunMessageType(); |
| bool stun = GetStunPacketType(&*data.begin(), data.size(), &type); |
| @@ -245,13 +281,18 @@ void P2PSocketHostUdp::DoSend(const PendingPacket& packet) { |
| last_dscp_ = net::DSCP_NO_CHANGE; |
| } |
| } |
| + |
| + uint64 call_record = |
|
juberti2
2014/11/04 06:00:18
For the future, I think it would be better to allo
guoweis2
2014/11/07 22:18:19
Changed to allocate memory.
|
| + PackCallRecord(packet.id, base::TimeTicks::Now().ToInternalValue()); |
| + |
| packet_processing_helpers::ApplyPacketOptions( |
| packet.data->data(), packet.size, packet.packet_options, 0); |
| int result = socket_->SendTo( |
| packet.data.get(), |
| packet.size, |
| packet.to, |
| - base::Bind(&P2PSocketHostUdp::OnSend, base::Unretained(this), packet.id)); |
| + base::Bind( |
| + &P2PSocketHostUdp::OnSend, base::Unretained(this), call_record)); |
| // sendto() may return an error, e.g. if we've received an ICMP Destination |
| // Unreachable message. When this happens try sending the same packet again, |
| @@ -261,27 +302,28 @@ void P2PSocketHostUdp::DoSend(const PendingPacket& packet) { |
| packet.data.get(), |
| packet.size, |
| packet.to, |
| - base::Bind(&P2PSocketHostUdp::OnSend, base::Unretained(this), |
| - packet.id)); |
| + base::Bind( |
| + &P2PSocketHostUdp::OnSend, base::Unretained(this), call_record)); |
| } |
| if (result == net::ERR_IO_PENDING) { |
| send_pending_ = true; |
| } else { |
| - HandleSendResult(packet.id, result); |
| + HandleSendResult(call_record, result); |
| } |
| if (dump_outgoing_rtp_packet_) |
| DumpRtpPacket(packet.data->data(), packet.size, false); |
| } |
| -void P2PSocketHostUdp::OnSend(uint64 packet_id, int result) { |
| +void P2PSocketHostUdp::OnSend(uint64 call_record, int result) { |
| DCHECK(send_pending_); |
| + |
| DCHECK_NE(result, net::ERR_IO_PENDING); |
| send_pending_ = false; |
| - HandleSendResult(packet_id, result); |
| + HandleSendResult(call_record, result); |
| // Send next packets if we have them waiting in the buffer. |
| while (state_ == STATE_OPEN && !send_queue_.empty() && !send_pending_) { |
| @@ -292,7 +334,15 @@ void P2PSocketHostUdp::OnSend(uint64 packet_id, int result) { |
| } |
| } |
| -void P2PSocketHostUdp::HandleSendResult(uint64 packet_id, int result) { |
| +void P2PSocketHostUdp::HandleSendResult(uint64 call_record, int result) { |
| + uint64 packet_id; |
| + uint64 ticks; |
| + UnpackCallRecord(call_record, |
| + random_socket_id_prefix_, |
| + base::TimeTicks::Now().ToInternalValue(), |
| + &packet_id, |
| + &ticks); |
| + |
| TRACE_EVENT_ASYNC_END1("p2p", "Send", packet_id, |
| "result", result); |
| if (result < 0) { |
| @@ -304,6 +354,16 @@ void P2PSocketHostUdp::HandleSendResult(uint64 packet_id, int result) { |
| VLOG(0) << "sendto() has failed twice returning a " |
| " transient error. Dropping the packet."; |
| } |
| + |
| + // UMA to track the histograms from 1ms to 1 sec for how long a packet spends |
| + // in the browser process. |
| + UMA_HISTOGRAM_CUSTOM_TIMES( |
| + "WebRTC.SystemSendPacketDuration_UDP" /* name */, |
| + base::TimeDelta::FromInternalValue(ticks) /* sample */, |
| + base::TimeDelta::FromMilliseconds(1) /* min */, |
| + base::TimeDelta::FromSeconds(1) /* max */, |
| + 100 /* bucket_count */); |
|
Alexei Svitkine (slow)
2014/11/04 15:17:50
I suggest just using UMA_HISTOGRAM_TIMES() here, w
guoweis2
2014/11/07 22:18:19
Done.
|
| + |
| message_sender_->Send(new P2PMsg_OnSendComplete(id_)); |
| } |
| @@ -330,4 +390,33 @@ bool P2PSocketHostUdp::SetOption(P2PSocketOption option, int value) { |
| } |
| } |
| +#define ALL_ONES_LOWER_32_BITS ((1uLL << 32) - 1) |
| + |
| +uint64 P2PSocketHostUdp::PackCallRecord(const uint64 packet_id, |
| + const uint64 ticks_now) { |
| + // Lower 32 bits is the packet id. |
| + uint64 call_record = packet_id & ALL_ONES_LOWER_32_BITS; |
| + uint64 ticks_now_lower = ticks_now & ALL_ONES_LOWER_32_BITS; |
| + return (ticks_now_lower << 32) + call_record; |
| +} |
| + |
| +void P2PSocketHostUdp::UnpackCallRecord(const uint64 packed_call_record, |
| + const uint64 random_socket_id_prefix, |
| + const uint64 ticks_now, |
| + uint64* packet_id, |
| + uint64* ticks_diff) { |
| + // Prefix the random prefix to the packet id. |
| + *packet_id = |
| + (packed_call_record & ALL_ONES_LOWER_32_BITS) | random_socket_id_prefix; |
| + |
| + // Calculate the tick spent. |
| + int64 ticks_duration = |
| + (ticks_now & ALL_ONES_LOWER_32_BITS) - (packed_call_record >> 32); |
| + |
| + if (ticks_duration < 0) { |
| + ticks_duration = ALL_ONES_LOWER_32_BITS + ticks_duration + 1; |
| + } |
| + *ticks_diff = ticks_duration; |
| +} |
| + |
| } // namespace content |