Chromium Code Reviews| Index: content/browser/renderer_host/pepper_tcp_server_socket.cc |
| diff --git a/content/browser/renderer_host/pepper_tcp_server_socket.cc b/content/browser/renderer_host/pepper_tcp_server_socket.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..c89861c7d96366cf8c2a6490235b589471d41526 |
| --- /dev/null |
| +++ b/content/browser/renderer_host/pepper_tcp_server_socket.cc |
| @@ -0,0 +1,150 @@ |
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "content/browser/renderer_host/pepper_tcp_server_socket.h" |
| + |
| +#include <cstddef> |
| + |
| +#include "base/logging.h" |
| +#include "content/browser/renderer_host/pepper_message_filter.h" |
| +#include "content/public/browser/browser_thread.h" |
| +#include "content/public/browser/browser_thread.h" |
|
yzshen1
2012/02/09 02:31:50
duplicate.
ygorshenin1
2012/02/09 15:00:10
Done.
|
| +#include "net/base/ip_endpoint.h" |
| +#include "net/base/net_errors.h" |
| +#include "net/socket/tcp_client_socket.h" |
| +#include "net/socket/tcp_server_socket.h" |
| +#include "ppapi/proxy/ppapi_messages.h" |
| +#include "ppapi/shared_impl/private/net_address_private_impl.h" |
| + |
| +using content::BrowserThread; |
| +using ppapi::NetAddressPrivateImpl; |
| + |
| +PepperTCPServerSocket::PepperTCPServerSocket( |
| + PepperMessageFilter* manager, |
| + int32 routing_id, |
| + uint32 plugin_dispatcher_id, |
| + uint32 socket_id) |
| + : manager_(manager), |
| + routing_id_(routing_id), |
| + plugin_dispatcher_id_(plugin_dispatcher_id), |
| + socket_id_(socket_id), |
| + state_(BEFORE_LISTENING) { |
| + DCHECK(manager); |
| +} |
| + |
| +PepperTCPServerSocket::~PepperTCPServerSocket() { |
| +} |
| + |
| +void PepperTCPServerSocket::SetAcceptCallback( |
| + const AcceptCallback& accept_callback) { |
| + accept_callback_ = accept_callback; |
| +} |
| + |
| +void PepperTCPServerSocket::Listen(const PP_NetAddress_Private& addr, |
| + int32 backlog) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| + |
| + net::IPEndPoint ip_end_point; |
| + if (state_ != BEFORE_LISTENING || |
| + !NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &ip_end_point)) { |
| + SendListenACKError(); |
| + return; |
| + } |
| + |
| + state_ = LISTEN_IN_PROGRESS; |
| + |
| + socket_.reset(new net::TCPServerSocket(NULL, net::NetLog::Source())); |
| + int result = socket_->Listen(ip_end_point, backlog); |
| + if (result != net::ERR_IO_PENDING) |
| + OnListenCompleted(result); |
| +} |
| + |
| +void PepperTCPServerSocket::Accept() { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| + |
| + if (state_ != LISTENING) { |
| + SendAcceptACKError(); |
| + return; |
| + } |
| + |
| + state_ = ACCEPT_IN_PROGRESS; |
| + |
| + int result = socket_->Accept( |
|
yzshen1
2012/02/09 02:31:50
I think Accept() will DCHECK if the previous Accep
ygorshenin1
2012/02/09 15:00:10
I added a state_ check before DCHECK, but didn't u
yzshen1
2012/02/09 17:36:39
I mean:
http://code.google.com/codesearch#OAMlx_jo
ygorshenin1
2012/02/10 13:27:40
OK, but in this case check that state_ == LISTENIN
yzshen1
2012/02/10 22:40:14
Ah, you are right. Thanks for pointing it out.
On
|
| + &socket_buffer_, |
| + base::Bind(&PepperTCPServerSocket::OnAcceptCompleted, |
| + base::Unretained(this))); |
| + if (result != net::ERR_IO_PENDING) |
| + OnAcceptCompleted(result); |
| +} |
| + |
| +void PepperTCPServerSocket::SendListenACKError() { |
| + manager_->Send(new PpapiMsg_PPBTCPServerSocket_ListenACK( |
| + routing_id_, plugin_dispatcher_id_, socket_id_, false)); |
| +} |
| + |
| +void PepperTCPServerSocket::SendAcceptACKError() { |
| + manager_->Send(new PpapiMsg_PPBTCPServerSocket_AcceptACK( |
| + routing_id_, |
| + plugin_dispatcher_id_, |
| + socket_id_, |
| + 0, |
| + NetAddressPrivateImpl::kInvalidNetAddress, |
| + NetAddressPrivateImpl::kInvalidNetAddress)); |
| +} |
| + |
| +void PepperTCPServerSocket::OnListenCompleted(int result) { |
| + DCHECK(state_ == LISTEN_IN_PROGRESS && socket_.get()); |
| + |
| + if (result != net::OK) { |
| + SendListenACKError(); |
| + state_ = BEFORE_LISTENING; |
| + } else { |
| + manager_->Send(new PpapiMsg_PPBTCPServerSocket_ListenACK( |
| + routing_id_, plugin_dispatcher_id_, socket_id_, true)); |
| + state_ = LISTENING; |
| + } |
| +} |
| + |
| +void PepperTCPServerSocket::OnAcceptCompleted(int result) { |
| + DCHECK(state_ == ACCEPT_IN_PROGRESS && socket_buffer_.get()); |
| + |
| + if (result != net::OK) |
|
brettw
2012/02/09 00:13:48
Style nit: this needs {} since the other arm has t
ygorshenin1
2012/02/09 15:00:10
Done.
|
| + SendAcceptACKError(); |
| + else { |
| + net::StreamSocket* socket = socket_buffer_.release(); |
| + |
| + net::IPEndPoint ip_end_point; |
| + net::AddressList address_list; |
| + PP_NetAddress_Private local_addr = |
| + NetAddressPrivateImpl::kInvalidNetAddress; |
| + PP_NetAddress_Private remote_addr = |
| + NetAddressPrivateImpl::kInvalidNetAddress; |
| + |
| + if (socket->GetLocalAddress(&ip_end_point) != net::OK || |
| + !NetAddressPrivateImpl::IPEndPointToNetAddress(ip_end_point, |
| + &local_addr) || |
| + socket->GetPeerAddress(&address_list) != net::OK || |
| + !NetAddressPrivateImpl::AddressListToNetAddress(address_list, |
| + &remote_addr)) { |
| + SendAcceptACKError(); |
| + } |
| + |
| + if (!accept_callback_.is_null()) { |
| + BrowserThread::PostTask(BrowserThread::IO, |
|
yzshen1
2012/02/09 02:31:50
The logic related to accept_callback_ is a little
ygorshenin1
2012/02/09 15:00:10
Done.
|
| + FROM_HERE, |
| + base::Bind(&AcceptCallback::Run, |
| + base::Unretained(&accept_callback_), |
| + routing_id_, |
| + plugin_dispatcher_id_, |
| + socket_id_, |
| + socket, |
| + local_addr, |
| + remote_addr)); |
| + } else { |
| + delete socket; |
|
brettw
2012/02/09 00:13:48
The ownership model of this is pretty complex. I t
ygorshenin1
2012/02/09 15:00:10
OK, now socket ownership is passed to PepperMessag
|
| + } |
| + } |
| + |
| + state_ = LISTENING; |
| +} |