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

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