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

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

Issue 13584008: Send notification about outgoing p2p packets from browser to renderer. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « content/common/p2p_messages.h ('k') | content/renderer/p2p/socket_client.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "base/compiler_specific.h" 7 #include "base/compiler_specific.h"
8 #include "base/message_loop.h" 8 #include "base/message_loop.h"
9 #include "base/message_loop_proxy.h" 9 #include "base/message_loop_proxy.h"
10 #include "content/renderer/p2p/socket_client.h" 10 #include "content/renderer/p2p/socket_client.h"
11 #include "content/renderer/p2p/socket_dispatcher.h" 11 #include "content/renderer/p2p/socket_dispatcher.h"
12 #include "jingle/glue/utils.h" 12 #include "jingle/glue/utils.h"
13 #include "third_party/libjingle/source/talk/base/asyncpacketsocket.h" 13 #include "third_party/libjingle/source/talk/base/asyncpacketsocket.h"
14 14
15 namespace content { 15 namespace content {
16 16
17 namespace { 17 namespace {
18 18
19 // TODO(sergeyu): Try adjusting these parameters to achieve optimal performance.
20 const int kMaxPendingPackets = 8;
21 const int kWritableSignalThreshold = 0;
22
19 // IpcPacketSocket implements talk_base::AsyncPacketSocket interface 23 // IpcPacketSocket implements talk_base::AsyncPacketSocket interface
20 // using P2PSocketClient that works over IPC-channel. It must be used 24 // using P2PSocketClient that works over IPC-channel. It must be used
21 // on the thread it was created. 25 // on the thread it was created.
22 class IpcPacketSocket : public talk_base::AsyncPacketSocket, 26 class IpcPacketSocket : public talk_base::AsyncPacketSocket,
23 public P2PSocketClient::Delegate { 27 public P2PSocketClient::Delegate {
24 public: 28 public:
25 IpcPacketSocket(); 29 IpcPacketSocket();
26 virtual ~IpcPacketSocket(); 30 virtual ~IpcPacketSocket();
27 31
28 // Always takes ownership of client even if initialization fails. 32 // Always takes ownership of client even if initialization fails.
(...skipping 11 matching lines...) Expand all
40 virtual State GetState() const OVERRIDE; 44 virtual State GetState() const OVERRIDE;
41 virtual int GetOption(talk_base::Socket::Option opt, int* value) OVERRIDE; 45 virtual int GetOption(talk_base::Socket::Option opt, int* value) OVERRIDE;
42 virtual int SetOption(talk_base::Socket::Option opt, int value) OVERRIDE; 46 virtual int SetOption(talk_base::Socket::Option opt, int value) OVERRIDE;
43 virtual int GetError() const OVERRIDE; 47 virtual int GetError() const OVERRIDE;
44 virtual void SetError(int error) OVERRIDE; 48 virtual void SetError(int error) OVERRIDE;
45 49
46 // P2PSocketClient::Delegate implementation. 50 // P2PSocketClient::Delegate implementation.
47 virtual void OnOpen(const net::IPEndPoint& address) OVERRIDE; 51 virtual void OnOpen(const net::IPEndPoint& address) OVERRIDE;
48 virtual void OnIncomingTcpConnection(const net::IPEndPoint& address, 52 virtual void OnIncomingTcpConnection(const net::IPEndPoint& address,
49 P2PSocketClient* client) OVERRIDE; 53 P2PSocketClient* client) OVERRIDE;
54 virtual void OnSendComplete() OVERRIDE;
50 virtual void OnError() OVERRIDE; 55 virtual void OnError() OVERRIDE;
51 virtual void OnDataReceived(const net::IPEndPoint& address, 56 virtual void OnDataReceived(const net::IPEndPoint& address,
52 const std::vector<char>& data) OVERRIDE; 57 const std::vector<char>& data) OVERRIDE;
53 58
54 private: 59 private:
55 enum InternalState { 60 enum InternalState {
56 IS_UNINITIALIZED, 61 IS_UNINITIALIZED,
57 IS_OPENING, 62 IS_OPENING,
58 IS_OPEN, 63 IS_OPEN,
59 IS_CLOSED, 64 IS_CLOSED,
(...skipping 16 matching lines...) Expand all
76 // renderer side doesn't know the address until it receives OnOpen() 81 // renderer side doesn't know the address until it receives OnOpen()
77 // event from the browser. 82 // event from the browser.
78 talk_base::SocketAddress local_address_; 83 talk_base::SocketAddress local_address_;
79 84
80 // Remote address for client TCP connections. 85 // Remote address for client TCP connections.
81 talk_base::SocketAddress remote_address_; 86 talk_base::SocketAddress remote_address_;
82 87
83 // Current state of the object. 88 // Current state of the object.
84 InternalState state_; 89 InternalState state_;
85 90
91 // Number which have been sent to the browser, but for which we haven't
92 // received response.
93 int send_packets_pending_;
94
95 // Set to true once EWOULDBLOCK was returned from Send(). Indicates that the
96 // caller expects SignalWritable notification.
97 bool writable_signal_expected_;
98
86 // Current error code. Valid when state_ == IS_ERROR. 99 // Current error code. Valid when state_ == IS_ERROR.
87 int error_; 100 int error_;
88 101
89 DISALLOW_COPY_AND_ASSIGN(IpcPacketSocket); 102 DISALLOW_COPY_AND_ASSIGN(IpcPacketSocket);
90 }; 103 };
91 104
92 IpcPacketSocket::IpcPacketSocket() 105 IpcPacketSocket::IpcPacketSocket()
93 : type_(P2P_SOCKET_UDP), 106 : type_(P2P_SOCKET_UDP),
94 message_loop_(MessageLoop::current()), 107 message_loop_(MessageLoop::current()),
95 state_(IS_UNINITIALIZED), 108 state_(IS_UNINITIALIZED),
109 send_packets_pending_(0),
110 writable_signal_expected_(false),
96 error_(0) { 111 error_(0) {
97 } 112 }
98 113
99 IpcPacketSocket::~IpcPacketSocket() { 114 IpcPacketSocket::~IpcPacketSocket() {
100 if (state_ == IS_OPENING || state_ == IS_OPEN || 115 if (state_ == IS_OPENING || state_ == IS_OPEN ||
101 state_ == IS_ERROR) { 116 state_ == IS_ERROR) {
102 Close(); 117 Close();
103 } 118 }
104 } 119 }
105 120
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 return EWOULDBLOCK; 188 return EWOULDBLOCK;
174 case IS_CLOSED: 189 case IS_CLOSED:
175 return ENOTCONN; 190 return ENOTCONN;
176 case IS_ERROR: 191 case IS_ERROR:
177 return error_; 192 return error_;
178 case IS_OPEN: 193 case IS_OPEN:
179 // Continue sending the packet. 194 // Continue sending the packet.
180 break; 195 break;
181 } 196 }
182 197
198 if (send_packets_pending_ > kMaxPendingPackets) {
199 writable_signal_expected_ = true;
200 return EWOULDBLOCK;
Ronghua Wu (Left Chromium) 2013/04/04 23:53:02 Justin, you mentioned in my cl that you want somet
Ronghua Wu (Left Chromium) 2013/04/05 17:56:04 Should we set error_ to EWOULDBLOCK? IOW, should t
Sergey Ulanov 2013/04/05 21:04:03 That's a good point. I think we should return -1 h
201 }
202
183 const char* data_char = reinterpret_cast<const char*>(data); 203 const char* data_char = reinterpret_cast<const char*>(data);
184 std::vector<char> data_vector(data_char, data_char + data_size); 204 std::vector<char> data_vector(data_char, data_char + data_size);
185 205
186 net::IPEndPoint address_chrome; 206 net::IPEndPoint address_chrome;
187 if (!jingle_glue::SocketAddressToIPEndPoint(address, &address_chrome)) { 207 if (!jingle_glue::SocketAddressToIPEndPoint(address, &address_chrome)) {
188 // Just drop the packet if we failed to convert the address. 208 // Just drop the packet if we failed to convert the address.
189 return 0; 209 return 0;
190 } 210 }
191 211
212 ++send_packets_pending_;
192 client_->Send(address_chrome, data_vector); 213 client_->Send(address_chrome, data_vector);
193 214
194 // Fake successful send. The caller ignores result anyway. 215 // Fake successful send. The caller ignores result anyway.
195 return data_size; 216 return data_size;
196 } 217 }
197 218
198 int IpcPacketSocket::Close() { 219 int IpcPacketSocket::Close() {
199 DCHECK_EQ(MessageLoop::current(), message_loop_); 220 DCHECK_EQ(MessageLoop::current(), message_loop_);
200 221
201 client_->Close(); 222 client_->Close();
(...skipping 29 matching lines...) Expand all
231 return STATE_CLOSED; 252 return STATE_CLOSED;
232 } 253 }
233 254
234 int IpcPacketSocket::GetOption(talk_base::Socket::Option opt, int* value) { 255 int IpcPacketSocket::GetOption(talk_base::Socket::Option opt, int* value) {
235 // We don't support socket options for IPC sockets. 256 // We don't support socket options for IPC sockets.
236 return -1; 257 return -1;
237 } 258 }
238 259
239 int IpcPacketSocket::SetOption(talk_base::Socket::Option opt, int value) { 260 int IpcPacketSocket::SetOption(talk_base::Socket::Option opt, int value) {
240 // We don't support socket options for IPC sockets. 261 // We don't support socket options for IPC sockets.
241 //
242 // TODO(sergeyu): Make sure we set proper socket options on the
243 // browser side.
244 return -1; 262 return -1;
245 } 263 }
246 264
247 int IpcPacketSocket::GetError() const { 265 int IpcPacketSocket::GetError() const {
248 DCHECK_EQ(MessageLoop::current(), message_loop_); 266 DCHECK_EQ(MessageLoop::current(), message_loop_);
249 return error_; 267 return error_;
250 } 268 }
251 269
252 void IpcPacketSocket::SetError(int error) { 270 void IpcPacketSocket::SetError(int error) {
253 DCHECK_EQ(MessageLoop::current(), message_loop_); 271 DCHECK_EQ(MessageLoop::current(), message_loop_);
(...skipping 26 matching lines...) Expand all
280 298
281 talk_base::SocketAddress remote_address; 299 talk_base::SocketAddress remote_address;
282 if (!jingle_glue::IPEndPointToSocketAddress(address, &remote_address)) { 300 if (!jingle_glue::IPEndPointToSocketAddress(address, &remote_address)) {
283 // Always expect correct IPv4 address to be allocated. 301 // Always expect correct IPv4 address to be allocated.
284 NOTREACHED(); 302 NOTREACHED();
285 } 303 }
286 socket->InitAcceptedTcp(client, local_address_, remote_address); 304 socket->InitAcceptedTcp(client, local_address_, remote_address);
287 SignalNewConnection(this, socket.release()); 305 SignalNewConnection(this, socket.release());
288 } 306 }
289 307
308 void IpcPacketSocket::OnSendComplete() {
309 DCHECK_EQ(MessageLoop::current(), message_loop_);
310
311 --send_packets_pending_;
312 DCHECK_GE(send_packets_pending_, 0);
313
314 if (writable_signal_expected_ &&
315 send_packets_pending_ <= kWritableSignalThreshold) {
316 // TODO(sergeyu): Uncomment this line once SignalWritable is added in
317 // talk_base::AsyncPacketSocket.
318 //
319 // SignalWritable(this);
320 writable_signal_expected_ = false;
321 }
322 }
323
290 void IpcPacketSocket::OnError() { 324 void IpcPacketSocket::OnError() {
291 DCHECK_EQ(MessageLoop::current(), message_loop_); 325 DCHECK_EQ(MessageLoop::current(), message_loop_);
292 state_ = IS_ERROR; 326 state_ = IS_ERROR;
293 error_ = ECONNABORTED; 327 error_ = ECONNABORTED;
294 } 328 }
295 329
296 void IpcPacketSocket::OnDataReceived(const net::IPEndPoint& address, 330 void IpcPacketSocket::OnDataReceived(const net::IPEndPoint& address,
297 const std::vector<char>& data) { 331 const std::vector<char>& data) {
298 DCHECK_EQ(MessageLoop::current(), message_loop_); 332 DCHECK_EQ(MessageLoop::current(), message_loop_);
299 333
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 talk_base::SocketAddress crome_address; 395 talk_base::SocketAddress crome_address;
362 P2PSocketClient* socket_client = new P2PSocketClient(socket_dispatcher_); 396 P2PSocketClient* socket_client = new P2PSocketClient(socket_dispatcher_);
363 scoped_ptr<IpcPacketSocket> socket(new IpcPacketSocket()); 397 scoped_ptr<IpcPacketSocket> socket(new IpcPacketSocket());
364 if (!socket->Init(P2P_SOCKET_TCP_CLIENT, socket_client, local_address, 398 if (!socket->Init(P2P_SOCKET_TCP_CLIENT, socket_client, local_address,
365 remote_address)) 399 remote_address))
366 return NULL; 400 return NULL;
367 return socket.release(); 401 return socket.release();
368 } 402 }
369 403
370 } // namespace content 404 } // namespace content
OLDNEW
« no previous file with comments | « content/common/p2p_messages.h ('k') | content/renderer/p2p/socket_client.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698