OLD | NEW |
---|---|
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 Loading... | |
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 IncrementDiscardCounters(uint32 size); | |
Alexei Svitkine (slow)
2014/10/27 17:45:21
This should have a comment. What is |size|?
guoweis2
2014/10/27 18:07:07
Done.
| |
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 Loading... | |
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 consecutive bytes discarded due to not enough | |
168 // send_bytes_available_. | |
169 uint32 max_discard_bytes_sequence_; | |
170 uint32 cur_discard_bytes_sequence_; | |
171 | |
172 // Track total count of packet drops and attempt of packet sends. | |
173 uint32 packets_discarded_; | |
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 Loading... | |
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_discard_bytes_sequence_(0), | |
212 cur_discard_bytes_sequence_(0), | |
213 packets_discarded_(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_10000("WebRTC.MaxApplicationConsecutiveBytesDiscard", | |
227 max_discard_bytes_sequence_); | |
228 | |
229 if (total_packets_ > 0) { | |
230 UMA_HISTOGRAM_PERCENTAGE("WebRTC.PacketDiscardByApplication", | |
231 ((static_cast<double>(packets_discarded_)) / | |
232 (static_cast<double>(total_packets_)) * 100.0)); | |
Alexei Svitkine (slow)
2014/10/27 17:45:21
The usual way to do this is:
(packets_discarded_
guoweis2
2014/10/27 18:07:07
Done.
| |
233 } | |
209 } | 234 } |
210 | 235 |
211 void IpcPacketSocket::TraceSendThrottlingState() const { | 236 void IpcPacketSocket::TraceSendThrottlingState() const { |
212 TRACE_COUNTER_ID1("p2p", "P2PSendBytesAvailable", local_address_.port(), | 237 TRACE_COUNTER_ID1("p2p", "P2PSendBytesAvailable", local_address_.port(), |
213 send_bytes_available_); | 238 send_bytes_available_); |
214 TRACE_COUNTER_ID1("p2p", "P2PSendPacketsInFlight", local_address_.port(), | 239 TRACE_COUNTER_ID1("p2p", "P2PSendPacketsInFlight", local_address_.port(), |
215 in_flight_packet_sizes_.size()); | 240 in_flight_packet_sizes_.size()); |
216 } | 241 } |
217 | 242 |
243 void IpcPacketSocket::IncrementDiscardCounters(uint32 size) { | |
244 cur_discard_bytes_sequence_ += size; | |
245 packets_discarded_++; | |
246 | |
247 if (cur_discard_bytes_sequence_ > max_discard_bytes_sequence_) { | |
248 max_discard_bytes_sequence_ = cur_discard_bytes_sequence_; | |
249 } | |
250 } | |
251 | |
218 bool IpcPacketSocket::Init(P2PSocketType type, | 252 bool IpcPacketSocket::Init(P2PSocketType type, |
219 P2PSocketClientImpl* client, | 253 P2PSocketClientImpl* client, |
220 const rtc::SocketAddress& local_address, | 254 const rtc::SocketAddress& local_address, |
221 const rtc::SocketAddress& remote_address) { | 255 const rtc::SocketAddress& remote_address) { |
222 DCHECK_EQ(base::MessageLoop::current(), message_loop_); | 256 DCHECK_EQ(base::MessageLoop::current(), message_loop_); |
223 DCHECK_EQ(state_, IS_UNINITIALIZED); | 257 DCHECK_EQ(state_, IS_UNINITIALIZED); |
224 | 258 |
225 type_ = type; | 259 type_ = type; |
226 client_ = client; | 260 client_ = client; |
227 local_address_ = local_address; | 261 local_address_ = local_address; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
309 case IS_OPEN: | 343 case IS_OPEN: |
310 // Continue sending the packet. | 344 // Continue sending the packet. |
311 break; | 345 break; |
312 } | 346 } |
313 | 347 |
314 if (data_size == 0) { | 348 if (data_size == 0) { |
315 NOTREACHED(); | 349 NOTREACHED(); |
316 return 0; | 350 return 0; |
317 } | 351 } |
318 | 352 |
353 total_packets_++; | |
354 | |
319 if (data_size > send_bytes_available_) { | 355 if (data_size > send_bytes_available_) { |
320 TRACE_EVENT_INSTANT1("p2p", "MaxPendingBytesWouldBlock", | 356 TRACE_EVENT_INSTANT1("p2p", "MaxPendingBytesWouldBlock", |
321 TRACE_EVENT_SCOPE_THREAD, | 357 TRACE_EVENT_SCOPE_THREAD, |
322 "id", | 358 "id", |
323 client_->GetSocketID()); | 359 client_->GetSocketID()); |
324 if (!writable_signal_expected_) { | 360 if (!writable_signal_expected_) { |
325 WebRtcLogMessage(base::StringPrintf( | 361 WebRtcLogMessage(base::StringPrintf( |
326 "IpcPacketSocket: sending is blocked. %d packets_in_flight.", | 362 "IpcPacketSocket: sending is blocked. %d packets_in_flight.", |
327 static_cast<int>(in_flight_packet_sizes_.size()))); | 363 static_cast<int>(in_flight_packet_sizes_.size()))); |
328 | 364 |
329 writable_signal_expected_ = true; | 365 writable_signal_expected_ = true; |
330 } | 366 } |
331 | 367 |
332 error_ = EWOULDBLOCK; | 368 error_ = EWOULDBLOCK; |
369 IncrementDiscardCounters(data_size); | |
333 return -1; | 370 return -1; |
371 } else { | |
372 cur_discard_bytes_sequence_ = 0; | |
334 } | 373 } |
335 | 374 |
336 net::IPEndPoint address_chrome; | 375 net::IPEndPoint address_chrome; |
337 if (!jingle_glue::SocketAddressToIPEndPoint(address, &address_chrome)) { | 376 if (!jingle_glue::SocketAddressToIPEndPoint(address, &address_chrome)) { |
338 NOTREACHED(); | 377 NOTREACHED(); |
339 error_ = EINVAL; | 378 error_ = EINVAL; |
340 return -1; | 379 return -1; |
341 } | 380 } |
342 | 381 |
343 send_bytes_available_ -= data_size; | 382 send_bytes_available_ -= data_size; |
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
670 } | 709 } |
671 | 710 |
672 rtc::AsyncResolverInterface* | 711 rtc::AsyncResolverInterface* |
673 IpcPacketSocketFactory::CreateAsyncResolver() { | 712 IpcPacketSocketFactory::CreateAsyncResolver() { |
674 scoped_ptr<AsyncAddressResolverImpl> resolver( | 713 scoped_ptr<AsyncAddressResolverImpl> resolver( |
675 new AsyncAddressResolverImpl(socket_dispatcher_)); | 714 new AsyncAddressResolverImpl(socket_dispatcher_)); |
676 return resolver.release(); | 715 return resolver.release(); |
677 } | 716 } |
678 | 717 |
679 } // namespace content | 718 } // namespace content |
OLD | NEW |