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

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, 2 months 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 void IncrementEWBCounters();
119
117 // Update trace of send throttling internal state. This should be called 120 // Update trace of send throttling internal state. This should be called
118 // immediately after any changes to |send_bytes_available_| and/or 121 // immediately after any changes to |send_bytes_available_| and/or
119 // |in_flight_packet_sizes_|. 122 // |in_flight_packet_sizes_|.
120 void TraceSendThrottlingState() const; 123 void TraceSendThrottlingState() const;
121 124
122 void InitAcceptedTcp(P2PSocketClient* client, 125 void InitAcceptedTcp(P2PSocketClient* client,
123 const rtc::SocketAddress& local_address, 126 const rtc::SocketAddress& local_address,
124 const rtc::SocketAddress& remote_address); 127 const rtc::SocketAddress& remote_address);
125 128
126 int DoSetOption(P2PSocketOption option, int value); 129 int DoSetOption(P2PSocketOption option, int value);
(...skipping 27 matching lines...) Expand all
154 std::deque<size_t> in_flight_packet_sizes_; 157 std::deque<size_t> in_flight_packet_sizes_;
155 158
156 // Set to true once EWOULDBLOCK was returned from Send(). Indicates that the 159 // Set to true once EWOULDBLOCK was returned from Send(). Indicates that the
157 // caller expects SignalWritable notification. 160 // caller expects SignalWritable notification.
158 bool writable_signal_expected_; 161 bool writable_signal_expected_;
159 162
160 // Current error code. Valid when state_ == IS_ERROR. 163 // Current error code. Valid when state_ == IS_ERROR.
161 int error_; 164 int error_;
162 int options_[P2P_SOCKET_OPT_MAX]; 165 int options_[P2P_SOCKET_OPT_MAX];
163 166
167 // Track the maximum & current length of consecutive EWOULDBLOCK that we
168 // return to the upper layer once the socket is in IS_OPEN state.
169 uint32 max_ewb_sequence_;
juberti2 2014/10/23 19:38:46 I would call this max_discard_sequence_ and cur_di
guoweis2 2014/10/24 06:08:55 Done. Also changed to bytes.
170 uint32 cur_ewb_sequence_;
171
172 // Track total count of packet drops and attempt of packet sends.
173 uint32 packets_dropped_;
juberti2 2014/10/23 19:38:46 Call this packets_discarded_
guoweis2 2014/10/24 06:08:54 Done. Also changed to bytes.
174 uint32 total_packets_;
175
164 DISALLOW_COPY_AND_ASSIGN(IpcPacketSocket); 176 DISALLOW_COPY_AND_ASSIGN(IpcPacketSocket);
165 }; 177 };
166 178
167 // Simple wrapper around P2PAsyncAddressResolver. The main purpose of this 179 // Simple wrapper around P2PAsyncAddressResolver. The main purpose of this
168 // class is to send SignalDone, after OnDone callback from 180 // class is to send SignalDone, after OnDone callback from
169 // P2PAsyncAddressResolver. Libjingle sig slots are not thread safe. In case 181 // 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 182 // 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. 183 // we destruct from the same thread on which is created.
172 class AsyncAddressResolverImpl : public base::NonThreadSafe, 184 class AsyncAddressResolverImpl : public base::NonThreadSafe,
173 public rtc::AsyncResolverInterface { 185 public rtc::AsyncResolverInterface {
(...skipping 14 matching lines...) Expand all
188 int port_; // Port number in |addr| from Start() method. 200 int port_; // Port number in |addr| from Start() method.
189 std::vector<rtc::IPAddress> addresses_; // Resolved addresses. 201 std::vector<rtc::IPAddress> addresses_; // Resolved addresses.
190 }; 202 };
191 203
192 IpcPacketSocket::IpcPacketSocket() 204 IpcPacketSocket::IpcPacketSocket()
193 : type_(P2P_SOCKET_UDP), 205 : type_(P2P_SOCKET_UDP),
194 message_loop_(base::MessageLoop::current()), 206 message_loop_(base::MessageLoop::current()),
195 state_(IS_UNINITIALIZED), 207 state_(IS_UNINITIALIZED),
196 send_bytes_available_(kMaximumInFlightBytes), 208 send_bytes_available_(kMaximumInFlightBytes),
197 writable_signal_expected_(false), 209 writable_signal_expected_(false),
198 error_(0) { 210 error_(0),
211 max_ewb_sequence_(0),
212 cur_ewb_sequence_(0),
213 packets_dropped_(0),
214 total_packets_(0) {
199 COMPILE_ASSERT(kMaximumInFlightBytes > 0, would_send_at_zero_rate); 215 COMPILE_ASSERT(kMaximumInFlightBytes > 0, would_send_at_zero_rate);
200 std::fill_n(options_, static_cast<int> (P2P_SOCKET_OPT_MAX), 216 std::fill_n(options_, static_cast<int> (P2P_SOCKET_OPT_MAX),
201 kDefaultNonSetOptionValue); 217 kDefaultNonSetOptionValue);
202 } 218 }
203 219
204 IpcPacketSocket::~IpcPacketSocket() { 220 IpcPacketSocket::~IpcPacketSocket() {
205 if (state_ == IS_OPENING || state_ == IS_OPEN || 221 if (state_ == IS_OPENING || state_ == IS_OPEN ||
206 state_ == IS_ERROR) { 222 state_ == IS_ERROR) {
207 Close(); 223 Close();
208 } 224 }
225
226 UMA_HISTOGRAM_COUNTS_100("WebRTC.MaxApplicationConsecutiveEWB",
227 max_ewb_sequence_);
228
229 UMA_HISTOGRAM_PERCENTAGE("WebRTC.PacketsDroppedByApplicationEWB",
230 ((static_cast<double>(packets_dropped_)) /
231 (static_cast<double>(total_packets_)) * 100.0));
209 } 232 }
210 233
211 void IpcPacketSocket::TraceSendThrottlingState() const { 234 void IpcPacketSocket::TraceSendThrottlingState() const {
212 TRACE_COUNTER_ID1("p2p", "P2PSendBytesAvailable", local_address_.port(), 235 TRACE_COUNTER_ID1("p2p", "P2PSendBytesAvailable", local_address_.port(),
213 send_bytes_available_); 236 send_bytes_available_);
214 TRACE_COUNTER_ID1("p2p", "P2PSendPacketsInFlight", local_address_.port(), 237 TRACE_COUNTER_ID1("p2p", "P2PSendPacketsInFlight", local_address_.port(),
215 in_flight_packet_sizes_.size()); 238 in_flight_packet_sizes_.size());
216 } 239 }
217 240
241 void IpcPacketSocket::IncrementEWBCounters() {
242 cur_ewb_sequence_++;
243 packets_dropped_++;
244
245 if (cur_ewb_sequence_ > max_ewb_sequence_) {
246 max_ewb_sequence_ = cur_ewb_sequence_;
247 }
248 }
249
218 bool IpcPacketSocket::Init(P2PSocketType type, 250 bool IpcPacketSocket::Init(P2PSocketType type,
219 P2PSocketClientImpl* client, 251 P2PSocketClientImpl* client,
220 const rtc::SocketAddress& local_address, 252 const rtc::SocketAddress& local_address,
221 const rtc::SocketAddress& remote_address) { 253 const rtc::SocketAddress& remote_address) {
222 DCHECK_EQ(base::MessageLoop::current(), message_loop_); 254 DCHECK_EQ(base::MessageLoop::current(), message_loop_);
223 DCHECK_EQ(state_, IS_UNINITIALIZED); 255 DCHECK_EQ(state_, IS_UNINITIALIZED);
224 256
225 type_ = type; 257 type_ = type;
226 client_ = client; 258 client_ = client;
227 local_address_ = local_address; 259 local_address_ = local_address;
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 case IS_OPEN: 341 case IS_OPEN:
310 // Continue sending the packet. 342 // Continue sending the packet.
311 break; 343 break;
312 } 344 }
313 345
314 if (data_size == 0) { 346 if (data_size == 0) {
315 NOTREACHED(); 347 NOTREACHED();
316 return 0; 348 return 0;
317 } 349 }
318 350
351 total_packets_++;
352
319 if (data_size > send_bytes_available_) { 353 if (data_size > send_bytes_available_) {
320 TRACE_EVENT_INSTANT1("p2p", "MaxPendingBytesWouldBlock", 354 TRACE_EVENT_INSTANT1("p2p", "MaxPendingBytesWouldBlock",
321 TRACE_EVENT_SCOPE_THREAD, 355 TRACE_EVENT_SCOPE_THREAD,
322 "id", 356 "id",
323 client_->GetSocketID()); 357 client_->GetSocketID());
324 if (!writable_signal_expected_) { 358 if (!writable_signal_expected_) {
325 WebRtcLogMessage(base::StringPrintf( 359 WebRtcLogMessage(base::StringPrintf(
326 "IpcPacketSocket: sending is blocked. %d packets_in_flight.", 360 "IpcPacketSocket: sending is blocked. %d packets_in_flight.",
327 static_cast<int>(in_flight_packet_sizes_.size()))); 361 static_cast<int>(in_flight_packet_sizes_.size())));
328 362
329 writable_signal_expected_ = true; 363 writable_signal_expected_ = true;
330 } 364 }
331 365
332 error_ = EWOULDBLOCK; 366 error_ = EWOULDBLOCK;
367 IncrementEWBCounters();
333 return -1; 368 return -1;
369 } else {
370 cur_ewb_sequence_ = 0;
334 } 371 }
335 372
336 net::IPEndPoint address_chrome; 373 net::IPEndPoint address_chrome;
337 if (!jingle_glue::SocketAddressToIPEndPoint(address, &address_chrome)) { 374 if (!jingle_glue::SocketAddressToIPEndPoint(address, &address_chrome)) {
338 NOTREACHED(); 375 NOTREACHED();
339 error_ = EINVAL; 376 error_ = EINVAL;
340 return -1; 377 return -1;
341 } 378 }
342 379
343 send_bytes_available_ -= data_size; 380 send_bytes_available_ -= data_size;
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
670 } 707 }
671 708
672 rtc::AsyncResolverInterface* 709 rtc::AsyncResolverInterface*
673 IpcPacketSocketFactory::CreateAsyncResolver() { 710 IpcPacketSocketFactory::CreateAsyncResolver() {
674 scoped_ptr<AsyncAddressResolverImpl> resolver( 711 scoped_ptr<AsyncAddressResolverImpl> resolver(
675 new AsyncAddressResolverImpl(socket_dispatcher_)); 712 new AsyncAddressResolverImpl(socket_dispatcher_));
676 return resolver.release(); 713 return resolver.release();
677 } 714 }
678 715
679 } // namespace content 716 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698