Chromium Code Reviews| 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 // Keep track of the max discarded byte sequence in the IpcPacketSocket | |
|
jamesr
2014/10/28 00:24:15
what does 'max' mean here? maximum length? maximum
guoweis2
2014/10/28 04:44:10
Rephrased this.
| |
| 119 // session. | |
| 120 void IncrementDiscardCounters(uint32 bytes_discarded); | |
| 121 | |
| 122 // Reset cur_discard_bytes_sequence_ to 0. | |
|
jamesr
2014/10/28 00:24:15
not a useful comment. if this just sets one variab
guoweis2
2014/10/28 04:44:09
Removed this function.
| |
| 123 void RestartCurrentDiscardCounter(); | |
| 124 | |
| 117 // Update trace of send throttling internal state. This should be called | 125 // Update trace of send throttling internal state. This should be called |
| 118 // immediately after any changes to |send_bytes_available_| and/or | 126 // immediately after any changes to |send_bytes_available_| and/or |
| 119 // |in_flight_packet_sizes_|. | 127 // |in_flight_packet_sizes_|. |
| 120 void TraceSendThrottlingState() const; | 128 void TraceSendThrottlingState() const; |
| 121 | 129 |
| 122 void InitAcceptedTcp(P2PSocketClient* client, | 130 void InitAcceptedTcp(P2PSocketClient* client, |
| 123 const rtc::SocketAddress& local_address, | 131 const rtc::SocketAddress& local_address, |
| 124 const rtc::SocketAddress& remote_address); | 132 const rtc::SocketAddress& remote_address); |
| 125 | 133 |
| 126 int DoSetOption(P2PSocketOption option, int value); | 134 int DoSetOption(P2PSocketOption option, int value); |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 154 std::deque<size_t> in_flight_packet_sizes_; | 162 std::deque<size_t> in_flight_packet_sizes_; |
| 155 | 163 |
| 156 // Set to true once EWOULDBLOCK was returned from Send(). Indicates that the | 164 // Set to true once EWOULDBLOCK was returned from Send(). Indicates that the |
| 157 // caller expects SignalWritable notification. | 165 // caller expects SignalWritable notification. |
| 158 bool writable_signal_expected_; | 166 bool writable_signal_expected_; |
| 159 | 167 |
| 160 // Current error code. Valid when state_ == IS_ERROR. | 168 // Current error code. Valid when state_ == IS_ERROR. |
| 161 int error_; | 169 int error_; |
| 162 int options_[P2P_SOCKET_OPT_MAX]; | 170 int options_[P2P_SOCKET_OPT_MAX]; |
| 163 | 171 |
| 172 // Track the maximum & current consecutive bytes discarded due to not enough | |
|
jamesr
2014/10/28 00:24:15
use words in comments, not symbols.
guoweis2
2014/10/28 04:44:09
Done.
| |
| 173 // send_bytes_available_. | |
| 174 uint32 max_discard_bytes_sequence_; | |
|
jamesr
2014/10/28 00:24:15
we use uint32_t, etc, not the _t-less versions
if
guoweis2
2014/10/28 04:44:10
Done.
| |
| 175 uint32 cur_discard_bytes_sequence_; | |
|
jamesr
2014/10/28 00:24:15
don't use abbreviations. if 'cur' means current, s
guoweis2
2014/10/28 04:44:09
Done.
| |
| 176 | |
| 177 // Track total count of packet drops and attempt of packet sends. | |
|
jamesr
2014/10/28 00:24:15
this isn't very grammatical, could you try to reph
guoweis2
2014/10/28 04:44:09
Done.
| |
| 178 uint32 packets_discarded_; | |
| 179 uint32 total_packets_; | |
| 180 | |
| 164 DISALLOW_COPY_AND_ASSIGN(IpcPacketSocket); | 181 DISALLOW_COPY_AND_ASSIGN(IpcPacketSocket); |
| 165 }; | 182 }; |
| 166 | 183 |
| 167 // Simple wrapper around P2PAsyncAddressResolver. The main purpose of this | 184 // Simple wrapper around P2PAsyncAddressResolver. The main purpose of this |
| 168 // class is to send SignalDone, after OnDone callback from | 185 // class is to send SignalDone, after OnDone callback from |
| 169 // P2PAsyncAddressResolver. Libjingle sig slots are not thread safe. In case | 186 // 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 | 187 // 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. | 188 // we destruct from the same thread on which is created. |
| 172 class AsyncAddressResolverImpl : public base::NonThreadSafe, | 189 class AsyncAddressResolverImpl : public base::NonThreadSafe, |
| 173 public rtc::AsyncResolverInterface { | 190 public rtc::AsyncResolverInterface { |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 188 int port_; // Port number in |addr| from Start() method. | 205 int port_; // Port number in |addr| from Start() method. |
| 189 std::vector<rtc::IPAddress> addresses_; // Resolved addresses. | 206 std::vector<rtc::IPAddress> addresses_; // Resolved addresses. |
| 190 }; | 207 }; |
| 191 | 208 |
| 192 IpcPacketSocket::IpcPacketSocket() | 209 IpcPacketSocket::IpcPacketSocket() |
| 193 : type_(P2P_SOCKET_UDP), | 210 : type_(P2P_SOCKET_UDP), |
| 194 message_loop_(base::MessageLoop::current()), | 211 message_loop_(base::MessageLoop::current()), |
| 195 state_(IS_UNINITIALIZED), | 212 state_(IS_UNINITIALIZED), |
| 196 send_bytes_available_(kMaximumInFlightBytes), | 213 send_bytes_available_(kMaximumInFlightBytes), |
| 197 writable_signal_expected_(false), | 214 writable_signal_expected_(false), |
| 198 error_(0) { | 215 error_(0), |
| 216 max_discard_bytes_sequence_(0), | |
| 217 cur_discard_bytes_sequence_(0), | |
| 218 packets_discarded_(0), | |
| 219 total_packets_(0) { | |
| 199 COMPILE_ASSERT(kMaximumInFlightBytes > 0, would_send_at_zero_rate); | 220 COMPILE_ASSERT(kMaximumInFlightBytes > 0, would_send_at_zero_rate); |
| 200 std::fill_n(options_, static_cast<int> (P2P_SOCKET_OPT_MAX), | 221 std::fill_n(options_, static_cast<int> (P2P_SOCKET_OPT_MAX), |
| 201 kDefaultNonSetOptionValue); | 222 kDefaultNonSetOptionValue); |
| 202 } | 223 } |
| 203 | 224 |
| 204 IpcPacketSocket::~IpcPacketSocket() { | 225 IpcPacketSocket::~IpcPacketSocket() { |
| 205 if (state_ == IS_OPENING || state_ == IS_OPEN || | 226 if (state_ == IS_OPENING || state_ == IS_OPEN || |
| 206 state_ == IS_ERROR) { | 227 state_ == IS_ERROR) { |
| 207 Close(); | 228 Close(); |
| 208 } | 229 } |
| 230 | |
| 231 UMA_HISTOGRAM_COUNTS_10000("WebRTC.ApplicationMaxConsecutiveBytesDiscard", | |
| 232 max_discard_bytes_sequence_); | |
| 233 | |
| 234 if (total_packets_ > 0) { | |
| 235 UMA_HISTOGRAM_PERCENTAGE("WebRTC.ApplicationPercenetPacketsDiscarded", | |
|
jamesr
2014/10/28 00:24:15
'Percenet' - you probably mean Percent right?
guoweis2
2014/10/28 04:44:10
Thanks for catching this. My test should have caug
| |
| 236 (packets_discarded_ * 100) / total_packets_); | |
| 237 } | |
| 209 } | 238 } |
| 210 | 239 |
| 211 void IpcPacketSocket::TraceSendThrottlingState() const { | 240 void IpcPacketSocket::TraceSendThrottlingState() const { |
| 212 TRACE_COUNTER_ID1("p2p", "P2PSendBytesAvailable", local_address_.port(), | 241 TRACE_COUNTER_ID1("p2p", "P2PSendBytesAvailable", local_address_.port(), |
| 213 send_bytes_available_); | 242 send_bytes_available_); |
| 214 TRACE_COUNTER_ID1("p2p", "P2PSendPacketsInFlight", local_address_.port(), | 243 TRACE_COUNTER_ID1("p2p", "P2PSendPacketsInFlight", local_address_.port(), |
| 215 in_flight_packet_sizes_.size()); | 244 in_flight_packet_sizes_.size()); |
| 216 } | 245 } |
| 217 | 246 |
| 247 void IpcPacketSocket::IncrementDiscardCounters(uint32 bytes_discarded) { | |
| 248 cur_discard_bytes_sequence_ += bytes_discarded; | |
| 249 packets_discarded_++; | |
| 250 | |
| 251 if (cur_discard_bytes_sequence_ > max_discard_bytes_sequence_) { | |
| 252 max_discard_bytes_sequence_ = cur_discard_bytes_sequence_; | |
| 253 } | |
| 254 } | |
| 255 | |
| 256 void IpcPacketSocket::RestartCurrentDiscardCounter() { | |
| 257 cur_discard_bytes_sequence_ = 0; | |
| 258 } | |
| 259 | |
| 218 bool IpcPacketSocket::Init(P2PSocketType type, | 260 bool IpcPacketSocket::Init(P2PSocketType type, |
| 219 P2PSocketClientImpl* client, | 261 P2PSocketClientImpl* client, |
| 220 const rtc::SocketAddress& local_address, | 262 const rtc::SocketAddress& local_address, |
| 221 const rtc::SocketAddress& remote_address) { | 263 const rtc::SocketAddress& remote_address) { |
| 222 DCHECK_EQ(base::MessageLoop::current(), message_loop_); | 264 DCHECK_EQ(base::MessageLoop::current(), message_loop_); |
| 223 DCHECK_EQ(state_, IS_UNINITIALIZED); | 265 DCHECK_EQ(state_, IS_UNINITIALIZED); |
| 224 | 266 |
| 225 type_ = type; | 267 type_ = type; |
| 226 client_ = client; | 268 client_ = client; |
| 227 local_address_ = local_address; | 269 local_address_ = local_address; |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 309 case IS_OPEN: | 351 case IS_OPEN: |
| 310 // Continue sending the packet. | 352 // Continue sending the packet. |
| 311 break; | 353 break; |
| 312 } | 354 } |
| 313 | 355 |
| 314 if (data_size == 0) { | 356 if (data_size == 0) { |
| 315 NOTREACHED(); | 357 NOTREACHED(); |
| 316 return 0; | 358 return 0; |
| 317 } | 359 } |
| 318 | 360 |
| 361 total_packets_++; | |
| 362 | |
| 319 if (data_size > send_bytes_available_) { | 363 if (data_size > send_bytes_available_) { |
| 320 TRACE_EVENT_INSTANT1("p2p", "MaxPendingBytesWouldBlock", | 364 TRACE_EVENT_INSTANT1("p2p", "MaxPendingBytesWouldBlock", |
| 321 TRACE_EVENT_SCOPE_THREAD, | 365 TRACE_EVENT_SCOPE_THREAD, |
| 322 "id", | 366 "id", |
| 323 client_->GetSocketID()); | 367 client_->GetSocketID()); |
| 324 if (!writable_signal_expected_) { | 368 if (!writable_signal_expected_) { |
| 325 WebRtcLogMessage(base::StringPrintf( | 369 WebRtcLogMessage(base::StringPrintf( |
| 326 "IpcPacketSocket: sending is blocked. %d packets_in_flight.", | 370 "IpcPacketSocket: sending is blocked. %d packets_in_flight.", |
| 327 static_cast<int>(in_flight_packet_sizes_.size()))); | 371 static_cast<int>(in_flight_packet_sizes_.size()))); |
| 328 | 372 |
| 329 writable_signal_expected_ = true; | 373 writable_signal_expected_ = true; |
| 330 } | 374 } |
| 331 | 375 |
| 332 error_ = EWOULDBLOCK; | 376 error_ = EWOULDBLOCK; |
| 377 IncrementDiscardCounters(data_size); | |
| 333 return -1; | 378 return -1; |
| 379 } else { | |
| 380 RestartCurrentDiscardCounter(); | |
| 334 } | 381 } |
| 335 | 382 |
| 336 net::IPEndPoint address_chrome; | 383 net::IPEndPoint address_chrome; |
| 337 if (!jingle_glue::SocketAddressToIPEndPoint(address, &address_chrome)) { | 384 if (!jingle_glue::SocketAddressToIPEndPoint(address, &address_chrome)) { |
| 338 NOTREACHED(); | 385 NOTREACHED(); |
| 339 error_ = EINVAL; | 386 error_ = EINVAL; |
| 340 return -1; | 387 return -1; |
| 341 } | 388 } |
| 342 | 389 |
| 343 send_bytes_available_ -= data_size; | 390 send_bytes_available_ -= data_size; |
| (...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 670 } | 717 } |
| 671 | 718 |
| 672 rtc::AsyncResolverInterface* | 719 rtc::AsyncResolverInterface* |
| 673 IpcPacketSocketFactory::CreateAsyncResolver() { | 720 IpcPacketSocketFactory::CreateAsyncResolver() { |
| 674 scoped_ptr<AsyncAddressResolverImpl> resolver( | 721 scoped_ptr<AsyncAddressResolverImpl> resolver( |
| 675 new AsyncAddressResolverImpl(socket_dispatcher_)); | 722 new AsyncAddressResolverImpl(socket_dispatcher_)); |
| 676 return resolver.release(); | 723 return resolver.release(); |
| 677 } | 724 } |
| 678 | 725 |
| 679 } // namespace content | 726 } // namespace content |
| OLD | NEW |