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

Side by Side Diff: content/renderer/p2p/ipc_socket_factory.cc

Issue 677473002: Implement UMA and internal data structure for tracking EWOULDBLOCK. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 1 month 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 unified diff | Download patch
OLDNEW
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 <deque>
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/histogram.h"
14 #include "base/strings/stringprintf.h" 15 #include "base/strings/stringprintf.h"
15 #include "base/threading/non_thread_safe.h" 16 #include "base/threading/non_thread_safe.h"
16 #include "content/renderer/media/webrtc_logging.h" 17 #include "content/renderer/media/webrtc_logging.h"
17 #include "content/renderer/p2p/host_address_request.h" 18 #include "content/renderer/p2p/host_address_request.h"
18 #include "content/renderer/p2p/socket_client_delegate.h" 19 #include "content/renderer/p2p/socket_client_delegate.h"
19 #include "content/renderer/p2p/socket_client_impl.h" 20 #include "content/renderer/p2p/socket_client_impl.h"
20 #include "content/renderer/p2p/socket_dispatcher.h" 21 #include "content/renderer/p2p/socket_dispatcher.h"
21 #include "jingle/glue/utils.h" 22 #include "jingle/glue/utils.h"
22 #include "third_party/webrtc/base/asyncpacketsocket.h" 23 #include "third_party/webrtc/base/asyncpacketsocket.h"
23 24
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 108
108 private: 109 private:
109 enum InternalState { 110 enum InternalState {
110 IS_UNINITIALIZED, 111 IS_UNINITIALIZED,
111 IS_OPENING, 112 IS_OPENING,
112 IS_OPEN, 113 IS_OPEN,
113 IS_CLOSED, 114 IS_CLOSED,
114 IS_ERROR, 115 IS_ERROR,
115 }; 116 };
116 117
118 // Keep track of the max discarded byte sequence in the IpcPacketSocket
119 // session. If |bytesDiscarded| is 0, it'll restart the
120 // cur_discard_bytes_sequence_ counting.
121 void IncrementDiscardCounters(uint32 bytesDiscarded);
Alexei Svitkine (slow) 2014/10/27 18:10:05 Nit: bytes_discarded. Update .cc file and comment
guoweis2 2014/10/27 22:53:18 Done.
122
117 // Update trace of send throttling internal state. This should be called 123 // Update trace of send throttling internal state. This should be called
118 // immediately after any changes to |send_bytes_available_| and/or 124 // immediately after any changes to |send_bytes_available_| and/or
119 // |in_flight_packet_sizes_|. 125 // |in_flight_packet_sizes_|.
120 void TraceSendThrottlingState() const; 126 void TraceSendThrottlingState() const;
121 127
122 void InitAcceptedTcp(P2PSocketClient* client, 128 void InitAcceptedTcp(P2PSocketClient* client,
123 const rtc::SocketAddress& local_address, 129 const rtc::SocketAddress& local_address,
124 const rtc::SocketAddress& remote_address); 130 const rtc::SocketAddress& remote_address);
125 131
126 int DoSetOption(P2PSocketOption option, int value); 132 int DoSetOption(P2PSocketOption option, int value);
(...skipping 27 matching lines...) Expand all
154 std::deque<size_t> in_flight_packet_sizes_; 160 std::deque<size_t> in_flight_packet_sizes_;
155 161
156 // Set to true once EWOULDBLOCK was returned from Send(). Indicates that the 162 // Set to true once EWOULDBLOCK was returned from Send(). Indicates that the
157 // caller expects SignalWritable notification. 163 // caller expects SignalWritable notification.
158 bool writable_signal_expected_; 164 bool writable_signal_expected_;
159 165
160 // Current error code. Valid when state_ == IS_ERROR. 166 // Current error code. Valid when state_ == IS_ERROR.
161 int error_; 167 int error_;
162 int options_[P2P_SOCKET_OPT_MAX]; 168 int options_[P2P_SOCKET_OPT_MAX];
163 169
170 // Track the maximum & current consecutive bytes discarded due to not enough
171 // send_bytes_available_.
172 uint32 max_discard_bytes_sequence_;
173 uint32 cur_discard_bytes_sequence_;
174
175 // Track total count of packet drops and attempt of packet sends.
176 uint32 packets_discarded_;
177 uint32 total_packets_;
178
164 DISALLOW_COPY_AND_ASSIGN(IpcPacketSocket); 179 DISALLOW_COPY_AND_ASSIGN(IpcPacketSocket);
165 }; 180 };
166 181
167 // Simple wrapper around P2PAsyncAddressResolver. The main purpose of this 182 // Simple wrapper around P2PAsyncAddressResolver. The main purpose of this
168 // class is to send SignalDone, after OnDone callback from 183 // class is to send SignalDone, after OnDone callback from
169 // P2PAsyncAddressResolver. Libjingle sig slots are not thread safe. In case 184 // P2PAsyncAddressResolver. Libjingle sig slots are not thread safe. In case
170 // of MT sig slots clients must call disconnect. This class is to make sure 185 // of MT sig slots clients must call disconnect. This class is to make sure
171 // we destruct from the same thread on which is created. 186 // we destruct from the same thread on which is created.
172 class AsyncAddressResolverImpl : public base::NonThreadSafe, 187 class AsyncAddressResolverImpl : public base::NonThreadSafe,
173 public rtc::AsyncResolverInterface { 188 public rtc::AsyncResolverInterface {
(...skipping 14 matching lines...) Expand all
188 int port_; // Port number in |addr| from Start() method. 203 int port_; // Port number in |addr| from Start() method.
189 std::vector<rtc::IPAddress> addresses_; // Resolved addresses. 204 std::vector<rtc::IPAddress> addresses_; // Resolved addresses.
190 }; 205 };
191 206
192 IpcPacketSocket::IpcPacketSocket() 207 IpcPacketSocket::IpcPacketSocket()
193 : type_(P2P_SOCKET_UDP), 208 : type_(P2P_SOCKET_UDP),
194 message_loop_(base::MessageLoop::current()), 209 message_loop_(base::MessageLoop::current()),
195 state_(IS_UNINITIALIZED), 210 state_(IS_UNINITIALIZED),
196 send_bytes_available_(kMaximumInFlightBytes), 211 send_bytes_available_(kMaximumInFlightBytes),
197 writable_signal_expected_(false), 212 writable_signal_expected_(false),
198 error_(0) { 213 error_(0),
214 max_discard_bytes_sequence_(0),
215 cur_discard_bytes_sequence_(0),
216 packets_discarded_(0),
217 total_packets_(0) {
199 COMPILE_ASSERT(kMaximumInFlightBytes > 0, would_send_at_zero_rate); 218 COMPILE_ASSERT(kMaximumInFlightBytes > 0, would_send_at_zero_rate);
200 std::fill_n(options_, static_cast<int> (P2P_SOCKET_OPT_MAX), 219 std::fill_n(options_, static_cast<int> (P2P_SOCKET_OPT_MAX),
201 kDefaultNonSetOptionValue); 220 kDefaultNonSetOptionValue);
202 } 221 }
203 222
204 IpcPacketSocket::~IpcPacketSocket() { 223 IpcPacketSocket::~IpcPacketSocket() {
205 if (state_ == IS_OPENING || state_ == IS_OPEN || 224 if (state_ == IS_OPENING || state_ == IS_OPEN ||
206 state_ == IS_ERROR) { 225 state_ == IS_ERROR) {
207 Close(); 226 Close();
208 } 227 }
228
229 UMA_HISTOGRAM_COUNTS_10000("WebRTC.MaxApplicationConsecutiveBytesDiscard",
230 max_discard_bytes_sequence_);
231
232 if (total_packets_ > 0) {
233 UMA_HISTOGRAM_PERCENTAGE("WebRTC.PacketDiscardByApplication",
234 (packets_discarded_ * 100) / total_packets_);
235 }
209 } 236 }
210 237
211 void IpcPacketSocket::TraceSendThrottlingState() const { 238 void IpcPacketSocket::TraceSendThrottlingState() const {
212 TRACE_COUNTER_ID1("p2p", "P2PSendBytesAvailable", local_address_.port(), 239 TRACE_COUNTER_ID1("p2p", "P2PSendBytesAvailable", local_address_.port(),
213 send_bytes_available_); 240 send_bytes_available_);
214 TRACE_COUNTER_ID1("p2p", "P2PSendPacketsInFlight", local_address_.port(), 241 TRACE_COUNTER_ID1("p2p", "P2PSendPacketsInFlight", local_address_.port(),
215 in_flight_packet_sizes_.size()); 242 in_flight_packet_sizes_.size());
216 } 243 }
217 244
245 void IpcPacketSocket::IncrementDiscardCounters(uint32 bytesDiscarded) {
246 if (bytesDiscarded == 0) {
247 cur_discard_bytes_sequence_ = 0;
248 } else {
249 cur_discard_bytes_sequence_ += bytesDiscarded;
250 packets_discarded_++;
251
252 if (cur_discard_bytes_sequence_ > max_discard_bytes_sequence_) {
253 max_discard_bytes_sequence_ = cur_discard_bytes_sequence_;
254 }
255 }
256 }
257
218 bool IpcPacketSocket::Init(P2PSocketType type, 258 bool IpcPacketSocket::Init(P2PSocketType type,
219 P2PSocketClientImpl* client, 259 P2PSocketClientImpl* client,
220 const rtc::SocketAddress& local_address, 260 const rtc::SocketAddress& local_address,
221 const rtc::SocketAddress& remote_address) { 261 const rtc::SocketAddress& remote_address) {
222 DCHECK_EQ(base::MessageLoop::current(), message_loop_); 262 DCHECK_EQ(base::MessageLoop::current(), message_loop_);
223 DCHECK_EQ(state_, IS_UNINITIALIZED); 263 DCHECK_EQ(state_, IS_UNINITIALIZED);
224 264
225 type_ = type; 265 type_ = type;
226 client_ = client; 266 client_ = client;
227 local_address_ = local_address; 267 local_address_ = local_address;
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 case IS_OPEN: 349 case IS_OPEN:
310 // Continue sending the packet. 350 // Continue sending the packet.
311 break; 351 break;
312 } 352 }
313 353
314 if (data_size == 0) { 354 if (data_size == 0) {
315 NOTREACHED(); 355 NOTREACHED();
316 return 0; 356 return 0;
317 } 357 }
318 358
359 total_packets_++;
360
319 if (data_size > send_bytes_available_) { 361 if (data_size > send_bytes_available_) {
320 TRACE_EVENT_INSTANT1("p2p", "MaxPendingBytesWouldBlock", 362 TRACE_EVENT_INSTANT1("p2p", "MaxPendingBytesWouldBlock",
321 TRACE_EVENT_SCOPE_THREAD, 363 TRACE_EVENT_SCOPE_THREAD,
322 "id", 364 "id",
323 client_->GetSocketID()); 365 client_->GetSocketID());
324 if (!writable_signal_expected_) { 366 if (!writable_signal_expected_) {
325 WebRtcLogMessage(base::StringPrintf( 367 WebRtcLogMessage(base::StringPrintf(
326 "IpcPacketSocket: sending is blocked. %d packets_in_flight.", 368 "IpcPacketSocket: sending is blocked. %d packets_in_flight.",
327 static_cast<int>(in_flight_packet_sizes_.size()))); 369 static_cast<int>(in_flight_packet_sizes_.size())));
328 370
329 writable_signal_expected_ = true; 371 writable_signal_expected_ = true;
330 } 372 }
331 373
332 error_ = EWOULDBLOCK; 374 error_ = EWOULDBLOCK;
375 IncrementDiscardCounters(data_size);
333 return -1; 376 return -1;
377 } else {
378 // Passing 0 to IncrementDiscardCounters will restart the sequence counting.
379 IncrementDiscardCounters(0);
334 } 380 }
335 381
336 net::IPEndPoint address_chrome; 382 net::IPEndPoint address_chrome;
337 if (!jingle_glue::SocketAddressToIPEndPoint(address, &address_chrome)) { 383 if (!jingle_glue::SocketAddressToIPEndPoint(address, &address_chrome)) {
338 NOTREACHED(); 384 NOTREACHED();
339 error_ = EINVAL; 385 error_ = EINVAL;
340 return -1; 386 return -1;
341 } 387 }
342 388
343 send_bytes_available_ -= data_size; 389 send_bytes_available_ -= data_size;
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
670 } 716 }
671 717
672 rtc::AsyncResolverInterface* 718 rtc::AsyncResolverInterface*
673 IpcPacketSocketFactory::CreateAsyncResolver() { 719 IpcPacketSocketFactory::CreateAsyncResolver() {
674 scoped_ptr<AsyncAddressResolverImpl> resolver( 720 scoped_ptr<AsyncAddressResolverImpl> resolver(
675 new AsyncAddressResolverImpl(socket_dispatcher_)); 721 new AsyncAddressResolverImpl(socket_dispatcher_));
676 return resolver.release(); 722 return resolver.release();
677 } 723 }
678 724
679 } // namespace content 725 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/p2p/socket_host_udp.cc ('k') | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698