diff options
author | ygorshenin@chromium.org <ygorshenin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-15 09:39:56 +0000 |
---|---|---|
committer | ygorshenin@chromium.org <ygorshenin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-15 09:39:56 +0000 |
commit | 2d011e88f4d4106c1a3a2b4fae4ce2e46bb7d8b3 (patch) | |
tree | a1721b6061e1f4cc64350d6d6b61613ec7fe1118 /ppapi/proxy | |
parent | c1c32c85357f14756247b04b8b5ae41b05bf2e16 (diff) | |
download | chromium_src-2d011e88f4d4106c1a3a2b4fae4ce2e46bb7d8b3.zip chromium_src-2d011e88f4d4106c1a3a2b4fae4ce2e46bb7d8b3.tar.gz chromium_src-2d011e88f4d4106c1a3a2b4fae4ce2e46bb7d8b3.tar.bz2 |
Added out-of-process support for server sockets.
BUG=108277
TEST=OutOfProcessPPAPITest.TCPServerSocketPrivate
Review URL: http://codereview.chromium.org/9669038
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@126873 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/proxy')
-rw-r--r-- | ppapi/proxy/interface_list.cc | 1 | ||||
-rw-r--r-- | ppapi/proxy/ppapi_messages.h | 17 | ||||
-rw-r--r-- | ppapi/proxy/ppb_tcp_server_socket_private_proxy.cc | 202 | ||||
-rw-r--r-- | ppapi/proxy/ppb_tcp_server_socket_private_proxy.h | 59 | ||||
-rw-r--r-- | ppapi/proxy/ppb_tcp_socket_private_proxy.cc | 34 | ||||
-rw-r--r-- | ppapi/proxy/ppb_tcp_socket_private_proxy.h | 7 | ||||
-rw-r--r-- | ppapi/proxy/resource_creation_proxy.cc | 4 |
7 files changed, 314 insertions, 10 deletions
diff --git a/ppapi/proxy/interface_list.cc b/ppapi/proxy/interface_list.cc index e746ffd..462148b 100644 --- a/ppapi/proxy/interface_list.cc +++ b/ppapi/proxy/interface_list.cc @@ -92,6 +92,7 @@ #include "ppapi/proxy/ppb_instance_proxy.h" #include "ppapi/proxy/ppb_message_loop_proxy.h" #include "ppapi/proxy/ppb_pdf_proxy.h" +#include "ppapi/proxy/ppb_tcp_server_socket_private_proxy.h" #include "ppapi/proxy/ppb_tcp_socket_private_proxy.h" #include "ppapi/proxy/ppb_testing_proxy.h" #include "ppapi/proxy/ppb_text_input_proxy.h" diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h index 7a5c2f4..dbcbbd1 100644 --- a/ppapi/proxy/ppapi_messages.h +++ b/ppapi/proxy/ppapi_messages.h @@ -351,6 +351,8 @@ IPC_MESSAGE_ROUTED4(PpapiMsg_PPBUDPSocket_SendToACK, // PPB_TCPServerSocket_Private. +// |socket_resource| should not be used as Resource in browser. The +// only purpose of this argument is to be echoed back. // |status| == PP_ERROR_NOSPACE means that the socket table is full // and new socket can't be initialized. // |status| == PP_ERROR_FAILED means that socket is correctly @@ -359,12 +361,12 @@ IPC_MESSAGE_ROUTED4(PpapiMsg_PPBUDPSocket_SendToACK, // needed) and Listen call succeeds. IPC_MESSAGE_ROUTED4(PpapiMsg_PPBTCPServerSocket_ListenACK, uint32 /* plugin_dispatcher_id */, - uint32 /* real_socket_id */, - uint32 /* temp_socket_id */, + PP_Resource /* socket_resource */, + uint32 /* socket_id */, int32_t /* status */) IPC_MESSAGE_ROUTED5(PpapiMsg_PPBTCPServerSocket_AcceptACK, uint32 /* plugin_dispatcher_id */, - uint32 /* real_server_socket_id */, + uint32 /* server_socket_id */, uint32 /* accepted_socket_id */, PP_NetAddress_Private /* local_addr */, PP_NetAddress_Private /* remote_addr */) @@ -1289,13 +1291,14 @@ IPC_MESSAGE_CONTROL1(PpapiHostMsg_PPBUDPSocket_Close, IPC_MESSAGE_CONTROL5(PpapiHostMsg_PPBTCPServerSocket_Listen, int32 /* routing_id */, uint32 /* plugin_dispatcher_id */, - uint32 /* temp_socket_id */, + PP_Resource /* socket_resource */, PP_NetAddress_Private /* addr */, int32_t /* backlog */) -IPC_MESSAGE_CONTROL1(PpapiHostMsg_PPBTCPServerSocket_Accept, - uint32 /* real_socket_id */) +IPC_MESSAGE_CONTROL2(PpapiHostMsg_PPBTCPServerSocket_Accept, + int32 /* tcp_client_socket_routing_id */, + uint32 /* server_socket_id */) IPC_MESSAGE_CONTROL1(PpapiHostMsg_PPBTCPServerSocket_Destroy, - uint32 /* real_socket_id */) + uint32 /* socket_id */) // PPB_Font. IPC_SYNC_MESSAGE_CONTROL0_1(PpapiHostMsg_PPBFont_GetFontFamilies, diff --git a/ppapi/proxy/ppb_tcp_server_socket_private_proxy.cc b/ppapi/proxy/ppb_tcp_server_socket_private_proxy.cc new file mode 100644 index 0000000..ed5d5ad --- /dev/null +++ b/ppapi/proxy/ppb_tcp_server_socket_private_proxy.cc @@ -0,0 +1,202 @@ +// 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 "ppapi/proxy/ppb_tcp_server_socket_private_proxy.h" + +#include <cstddef> + +#include "base/logging.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/proxy/plugin_dispatcher.h" +#include "ppapi/proxy/plugin_globals.h" +#include "ppapi/proxy/plugin_proxy_delegate.h" +#include "ppapi/proxy/plugin_resource_tracker.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/ppb_tcp_socket_private_proxy.h" +#include "ppapi/shared_impl/private/ppb_tcp_server_socket_shared.h" +#include "ppapi/shared_impl/resource.h" +#include "ppapi/thunk/enter.h" +#include "ppapi/thunk/thunk.h" + +namespace ppapi { +namespace proxy { + +typedef thunk::EnterResource<thunk::PPB_TCPServerSocket_Private_API> + EnterTCPServerSocket; + +namespace { + +class TCPServerSocket : public PPB_TCPServerSocket_Shared { + public: + TCPServerSocket(const HostResource& resource, uint32 plugin_dispatcher_id); + virtual ~TCPServerSocket(); + + virtual void OnAcceptCompleted( + bool succeeded, + uint32 tcp_socket_id, + const PP_NetAddress_Private& local_addr, + const PP_NetAddress_Private& remote_addr) OVERRIDE; + + virtual void SendListen(const PP_NetAddress_Private& addr, + int32_t backlog) OVERRIDE; + virtual void SendAccept() OVERRIDE; + virtual void SendStopListening() OVERRIDE; + + private: + void SendToBrowser(IPC::Message* msg); + + uint32 plugin_dispatcher_id_; + + DISALLOW_COPY_AND_ASSIGN(TCPServerSocket); +}; + +TCPServerSocket::TCPServerSocket(const HostResource& resource, + uint32 plugin_dispatcher_id) + : PPB_TCPServerSocket_Shared(resource), + plugin_dispatcher_id_(plugin_dispatcher_id) { +} + +TCPServerSocket::~TCPServerSocket() { + StopListening(); +} + +void TCPServerSocket::OnAcceptCompleted( + bool succeeded, + uint32 accepted_socket_id, + const PP_NetAddress_Private& local_addr, + const PP_NetAddress_Private& remote_addr) { + if (!TrackedCallback::IsPending(accept_callback_) || !tcp_socket_buffer_) { + NOTREACHED(); + return; + } + + if (succeeded) { + *tcp_socket_buffer_ = + PPB_TCPSocket_Private_Proxy::CreateProxyResourceForConnectedSocket( + pp_instance(), + accepted_socket_id, + local_addr, + remote_addr); + } + tcp_socket_buffer_ = NULL; + + TrackedCallback::ClearAndRun(&accept_callback_, + succeeded ? PP_OK : PP_ERROR_FAILED); +} + +void TCPServerSocket::SendListen(const PP_NetAddress_Private& addr, + int32_t backlog) { + SendToBrowser(new PpapiHostMsg_PPBTCPServerSocket_Listen( + API_ID_PPB_TCPSERVERSOCKET_PRIVATE, + plugin_dispatcher_id_, + pp_resource(), + addr, + backlog)); +} + +void TCPServerSocket::SendAccept() { + SendToBrowser(new PpapiHostMsg_PPBTCPServerSocket_Accept( + API_ID_PPB_TCPSOCKET_PRIVATE, socket_id_)); +} + +void TCPServerSocket::SendStopListening() { + if (socket_id_ != 0) { + SendToBrowser(new PpapiHostMsg_PPBTCPServerSocket_Destroy(socket_id_)); + + PluginDispatcher* dispatcher = + PluginDispatcher::GetForInstance(host_resource().instance()); + if (dispatcher) { + InterfaceProxy* proxy = + dispatcher->GetInterfaceProxy(API_ID_PPB_TCPSERVERSOCKET_PRIVATE); + PPB_TCPServerSocket_Private_Proxy* server_socket_proxy = + static_cast<PPB_TCPServerSocket_Private_Proxy*>(proxy); + server_socket_proxy->ObjectDestroyed(socket_id_); + } + } +} + +void TCPServerSocket::SendToBrowser(IPC::Message* msg) { + PluginGlobals::Get()->plugin_proxy_delegate()->SendToBrowser(msg); +} + +} // namespace + +//------------------------------------------------------------------------------ + +PPB_TCPServerSocket_Private_Proxy::PPB_TCPServerSocket_Private_Proxy( + Dispatcher* dispatcher) + : InterfaceProxy(dispatcher) { +} + +PPB_TCPServerSocket_Private_Proxy::~PPB_TCPServerSocket_Private_Proxy() { +} + +PP_Resource PPB_TCPServerSocket_Private_Proxy::CreateProxyResource( + PP_Instance instance) { + PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); + if (!dispatcher) + return 0; + + TCPServerSocket* server_socket = + new TCPServerSocket(HostResource::MakeInstanceOnly(instance), + dispatcher->plugin_dispatcher_id()); + return server_socket->GetReference(); +} + +void PPB_TCPServerSocket_Private_Proxy::ObjectDestroyed(uint32 socket_id) { + id_to_server_socket_.erase(socket_id); +} + +bool PPB_TCPServerSocket_Private_Proxy::OnMessageReceived( + const IPC::Message& msg) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(PPB_TCPServerSocket_Private_Proxy, msg) + IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPServerSocket_ListenACK, OnMsgListenACK) + IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPServerSocket_AcceptACK, OnMsgAcceptACK) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + +void PPB_TCPServerSocket_Private_Proxy::OnMsgListenACK( + uint32 plugin_dispatcher_id, + PP_Resource socket_resource, + uint32 socket_id, + int32_t status) { + EnterTCPServerSocket enter(socket_resource, true); + if (enter.succeeded()) { + PPB_TCPServerSocket_Shared* server_socket = + static_cast<PPB_TCPServerSocket_Shared*>(enter.object()); + if (status == PP_OK) + id_to_server_socket_[socket_id] = server_socket; + server_socket->OnListenCompleted(socket_id, status); + } else if (socket_id != 0 && status == PP_OK) { + IPC::Message* msg = + new PpapiHostMsg_PPBTCPServerSocket_Destroy(socket_id); + PluginGlobals::Get()->plugin_proxy_delegate()->SendToBrowser(msg); + } +} + +void PPB_TCPServerSocket_Private_Proxy::OnMsgAcceptACK( + uint32 plugin_dispatcher_id, + uint32 server_socket_id, + uint32 accepted_socket_id, + const PP_NetAddress_Private& local_addr, + const PP_NetAddress_Private& remote_addr) { + IDToServerSocketMap::iterator it = + id_to_server_socket_.find(server_socket_id); + if (it != id_to_server_socket_.end()) { + bool succeeded = (accepted_socket_id != 0); + it->second->OnAcceptCompleted(succeeded, + accepted_socket_id, + local_addr, + remote_addr); + } else if (accepted_socket_id != 0) { + PluginGlobals::Get()->plugin_proxy_delegate()->SendToBrowser( + new PpapiHostMsg_PPBTCPSocket_Disconnect(accepted_socket_id)); + } +} + +} // namespace proxy +} // namespace ppapi diff --git a/ppapi/proxy/ppb_tcp_server_socket_private_proxy.h b/ppapi/proxy/ppb_tcp_server_socket_private_proxy.h new file mode 100644 index 0000000..e2e644f --- /dev/null +++ b/ppapi/proxy/ppb_tcp_server_socket_private_proxy.h @@ -0,0 +1,59 @@ +// 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. + +#ifndef PPAPI_PROXY_PPB_TCP_SERVER_SOCKET_PRIVATE_PROXY_H_ +#define PPAPI_PROXY_PPB_TCP_SERVER_SOCKET_PRIVATE_PROXY_H_ + +#include <map> +#include <string> + +#include "base/basictypes.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/private/ppb_net_address_private.h" +#include "ppapi/proxy/interface_proxy.h" + +namespace ppapi { + +class PPB_TCPServerSocket_Shared; + +namespace proxy { + +class PPB_TCPServerSocket_Private_Proxy : public InterfaceProxy { + public: + explicit PPB_TCPServerSocket_Private_Proxy(Dispatcher* dispatcher); + virtual ~PPB_TCPServerSocket_Private_Proxy(); + + static PP_Resource CreateProxyResource(PP_Instance instance); + + void ObjectDestroyed(uint32 socket_id); + + // InterfaceProxy implementation. + virtual bool OnMessageReceived(const IPC::Message& msg); + + static const ApiID kApiID = API_ID_PPB_TCPSERVERSOCKET_PRIVATE; + + private: + typedef std::map<uint32, PPB_TCPServerSocket_Shared*> + IDToServerSocketMap; + + void OnMsgListenACK(uint32 plugin_dispatcher_id, + PP_Resource socket_resource, + uint32 socket_id, + int32_t status); + void OnMsgAcceptACK(uint32 plugin_dispatcher_id, + uint32 server_socket_id, + uint32 accepted_socket_id, + const PP_NetAddress_Private& local_addr, + const PP_NetAddress_Private& remote_addr); + + IDToServerSocketMap id_to_server_socket_; + + DISALLOW_COPY_AND_ASSIGN(PPB_TCPServerSocket_Private_Proxy); +}; + +} // namespace proxy +} // namespace ppapi + +#endif // PPAPI_PROXY_PPB_TCP_SERVER_SOCKET_PRIVATE_PROXY_H_ diff --git a/ppapi/proxy/ppb_tcp_socket_private_proxy.cc b/ppapi/proxy/ppb_tcp_socket_private_proxy.cc index 7e92664..26cdfcf 100644 --- a/ppapi/proxy/ppb_tcp_socket_private_proxy.cc +++ b/ppapi/proxy/ppb_tcp_socket_private_proxy.cc @@ -26,7 +26,13 @@ IDToSocketMap* g_id_to_socket = NULL; class TCPSocket : public TCPSocketPrivateImpl { public: + // C-tor for new sockets. TCPSocket(const HostResource& resource, uint32 socket_id); + // C-tor for already connected sockets. + TCPSocket(const HostResource& resource, + uint32 socket_id, + const PP_NetAddress_Private& local_addr, + const PP_NetAddress_Private& remote_addr); virtual ~TCPSocket(); virtual void SendConnect(const std::string& host, uint16_t port) OVERRIDE; @@ -52,6 +58,22 @@ TCPSocket::TCPSocket(const HostResource& resource, uint32 socket_id) (*g_id_to_socket)[socket_id] = this; } +TCPSocket::TCPSocket(const HostResource& resource, + uint32 socket_id, + const PP_NetAddress_Private& local_addr, + const PP_NetAddress_Private& remote_addr) + : TCPSocketPrivateImpl(resource, socket_id) { + if (!g_id_to_socket) + g_id_to_socket = new IDToSocketMap(); + DCHECK(g_id_to_socket->find(socket_id) == g_id_to_socket->end()); + + connection_state_ = CONNECTED; + local_addr_ = local_addr; + remote_addr_ = remote_addr; + + (*g_id_to_socket)[socket_id] = this; +} + TCPSocket::~TCPSocket() { Disconnect(); } @@ -121,6 +143,18 @@ PP_Resource PPB_TCPSocket_Private_Proxy::CreateProxyResource( socket_id))->GetReference(); } +// static +PP_Resource PPB_TCPSocket_Private_Proxy::CreateProxyResourceForConnectedSocket( + PP_Instance instance, + uint32 socket_id, + const PP_NetAddress_Private& local_addr, + const PP_NetAddress_Private& remote_addr) { + return (new TCPSocket(HostResource::MakeInstanceOnly(instance), + socket_id, + local_addr, + remote_addr))->GetReference(); +} + bool PPB_TCPSocket_Private_Proxy::OnMessageReceived(const IPC::Message& msg) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(PPB_TCPSocket_Private_Proxy, msg) diff --git a/ppapi/proxy/ppb_tcp_socket_private_proxy.h b/ppapi/proxy/ppb_tcp_socket_private_proxy.h index 3e50b9f..a7b2e79 100644 --- a/ppapi/proxy/ppb_tcp_socket_private_proxy.h +++ b/ppapi/proxy/ppb_tcp_socket_private_proxy.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// 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. @@ -23,6 +23,11 @@ class PPB_TCPSocket_Private_Proxy : public InterfaceProxy { virtual ~PPB_TCPSocket_Private_Proxy(); static PP_Resource CreateProxyResource(PP_Instance instance); + static PP_Resource CreateProxyResourceForConnectedSocket( + PP_Instance instance, + uint32 socket_id, + const PP_NetAddress_Private& local_addr, + const PP_NetAddress_Private& remote_addr); // InterfaceProxy implementation. virtual bool OnMessageReceived(const IPC::Message& msg); diff --git a/ppapi/proxy/resource_creation_proxy.cc b/ppapi/proxy/resource_creation_proxy.cc index 1f3b323..93112a8 100644 --- a/ppapi/proxy/resource_creation_proxy.cc +++ b/ppapi/proxy/resource_creation_proxy.cc @@ -25,6 +25,7 @@ #include "ppapi/proxy/ppb_graphics_3d_proxy.h" #include "ppapi/proxy/ppb_host_resolver_private_proxy.h" #include "ppapi/proxy/ppb_image_data_proxy.h" +#include "ppapi/proxy/ppb_tcp_server_socket_private_proxy.h" #include "ppapi/proxy/ppb_tcp_socket_private_proxy.h" #include "ppapi/proxy/ppb_udp_socket_private_proxy.h" #include "ppapi/proxy/ppb_url_loader_proxy.h" @@ -286,8 +287,7 @@ PP_Resource ResourceCreationProxy::CreateScrollbar(PP_Instance instance, #if !defined(OS_NACL) PP_Resource ResourceCreationProxy::CreateTCPServerSocketPrivate( PP_Instance instance) { - // TODO (ygorshenin): implement this - return 0; + return PPB_TCPServerSocket_Private_Proxy::CreateProxyResource(instance); } PP_Resource ResourceCreationProxy::CreateTCPSocketPrivate( |