diff options
author | ygorshenin@chromium.org <ygorshenin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-29 18:19:30 +0000 |
---|---|---|
committer | ygorshenin@chromium.org <ygorshenin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-29 18:19:30 +0000 |
commit | 51cea8ecdfac3d655f19b27ab4ad59a49401043d (patch) | |
tree | 7867ed86cedddbc0c7539e5ee252816150da375b /content/browser/renderer_host/pepper | |
parent | ce638d154c6e8618b8df761115a5a9e2c9d8a106 (diff) | |
download | chromium_src-51cea8ecdfac3d655f19b27ab4ad59a49401043d.zip chromium_src-51cea8ecdfac3d655f19b27ab4ad59a49401043d.tar.gz chromium_src-51cea8ecdfac3d655f19b27ab4ad59a49401043d.tar.bz2 |
Implemented queued UDP SendTo/RecvFrom requests. Exposed SO_SNDBUF and SO_RVFBUF socket options.
BUG=154338
TEST=browser_tests:*UDPSocketPrivate*
TBR=jschuh
Review URL: https://chromiumcodereview.appspot.com/12316095
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@191401 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser/renderer_host/pepper')
-rw-r--r-- | content/browser/renderer_host/pepper/pepper_udp_socket_private_message_filter.cc | 179 | ||||
-rw-r--r-- | content/browser/renderer_host/pepper/pepper_udp_socket_private_message_filter.h | 50 |
2 files changed, 179 insertions, 50 deletions
diff --git a/content/browser/renderer_host/pepper/pepper_udp_socket_private_message_filter.cc b/content/browser/renderer_host/pepper/pepper_udp_socket_private_message_filter.cc index 08384e78..1282ec2 100644 --- a/content/browser/renderer_host/pepper/pepper_udp_socket_private_message_filter.cc +++ b/content/browser/renderer_host/pepper/pepper_udp_socket_private_message_filter.cc @@ -15,7 +15,6 @@ #include "content/public/common/process_type.h" #include "content/public/common/socket_permission_request.h" #include "ipc/ipc_message_macros.h" -#include "net/base/io_buffer.h" #include "net/base/net_errors.h" #include "net/udp/udp_server_socket.h" #include "ppapi/c/pp_errors.h" @@ -48,12 +47,32 @@ bool CanUseSocketAPIs(const SocketPermissionRequest& request, } // namespace +PepperUDPSocketPrivateMessageFilter::IORequest::IORequest( + const scoped_refptr<net::IOBuffer>& buffer, + int32_t buffer_size, + const linked_ptr<net::IPEndPoint>& end_point, + const ppapi::host::ReplyMessageContext& context) + : buffer(buffer), + buffer_size(buffer_size), + end_point(end_point), + context(context) { +} + +PepperUDPSocketPrivateMessageFilter::IORequest::~IORequest() { +} + PepperUDPSocketPrivateMessageFilter::PepperUDPSocketPrivateMessageFilter( BrowserPpapiHostImpl* host, PP_Instance instance) : allow_address_reuse_(false), allow_broadcast_(false), + custom_send_buffer_size_(false), + send_buffer_size_(0), + custom_recv_buffer_size_(false), + recv_buffer_size_(0), closed_(false), + recvfrom_state_(IO_STATE_IDLE), + sendto_state_(IO_STATE_IDLE), external_plugin_(host->external_plugin()), render_process_id_(0), render_view_id_(0) { @@ -76,6 +95,7 @@ PepperUDPSocketPrivateMessageFilter::OverrideTaskRunnerForMessage( const IPC::Message& message) { switch (message.type()) { case PpapiHostMsg_UDPSocketPrivate_SetBoolSocketFeature::ID: + case PpapiHostMsg_UDPSocketPrivate_SetInt32SocketFeature::ID: case PpapiHostMsg_UDPSocketPrivate_RecvFrom::ID: case PpapiHostMsg_UDPSocketPrivate_Close::ID: return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO); @@ -94,6 +114,9 @@ int32_t PepperUDPSocketPrivateMessageFilter::OnResourceMessageReceived( PpapiHostMsg_UDPSocketPrivate_SetBoolSocketFeature, OnMsgSetBoolSocketFeature) PPAPI_DISPATCH_HOST_RESOURCE_CALL( + PpapiHostMsg_UDPSocketPrivate_SetInt32SocketFeature, + OnMsgSetInt32SocketFeature) + PPAPI_DISPATCH_HOST_RESOURCE_CALL( PpapiHostMsg_UDPSocketPrivate_Bind, OnMsgBind) PPAPI_DISPATCH_HOST_RESOURCE_CALL( @@ -114,16 +137,17 @@ int32_t PepperUDPSocketPrivateMessageFilter::OnMsgSetBoolSocketFeature( int32_t name, bool value) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - DCHECK(!socket_.get()); if (closed_) return PP_ERROR_FAILED; switch(static_cast<PP_UDPSocketFeature_Private>(name)) { case PP_UDPSOCKETFEATURE_ADDRESS_REUSE: + DCHECK(!socket_.get()); allow_address_reuse_ = value; break; case PP_UDPSOCKETFEATURE_BROADCAST: + DCHECK(!socket_.get()); allow_broadcast_ = value; break; default: @@ -133,6 +157,35 @@ int32_t PepperUDPSocketPrivateMessageFilter::OnMsgSetBoolSocketFeature( return PP_OK; } +int32_t PepperUDPSocketPrivateMessageFilter::OnMsgSetInt32SocketFeature( + const ppapi::host::HostMessageContext* context, + int32_t name, + int32_t value) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + + if (closed_) + return PP_ERROR_FAILED; + + switch(static_cast<PP_UDPSocketFeature_Private>(name)) { + case PP_UDPSOCKETFEATURE_SEND_BUFFER_SIZE: + custom_send_buffer_size_ = true; + send_buffer_size_ = value; + if (socket_.get()) + socket_->SetSendBufferSize(send_buffer_size_); + break; + case PP_UDPSOCKETFEATURE_RECV_BUFFER_SIZE: + custom_recv_buffer_size_ = true; + recv_buffer_size_ = value; + if (socket_.get()) + socket_->SetReceiveBufferSize(recv_buffer_size_); + break; + default: + NOTREACHED(); + break; + } + return PP_OK; +} + int32_t PepperUDPSocketPrivateMessageFilter::OnMsgBind( const ppapi::host::HostMessageContext* context, const PP_NetAddress_Private& addr) { @@ -165,20 +218,18 @@ int32_t PepperUDPSocketPrivateMessageFilter::OnMsgRecvFrom( if (closed_) return PP_ERROR_FAILED; - if (recvfrom_buffer_.get()) - return PP_ERROR_INPROGRESS; if (num_bytes > ppapi::proxy::UDPSocketPrivateResource::kMaxReadSize) { // |num_bytes| value is checked on the plugin side. NOTREACHED(); num_bytes = ppapi::proxy::UDPSocketPrivateResource::kMaxReadSize; } - recvfrom_buffer_ = new net::IOBuffer(num_bytes); - int result = socket_->RecvFrom( - recvfrom_buffer_, num_bytes, &recvfrom_address_, - base::Bind(&PepperUDPSocketPrivateMessageFilter::OnRecvFromCompleted, - this, context->MakeReplyMessageContext())); - if (result != net::ERR_IO_PENDING) - OnRecvFromCompleted(context->MakeReplyMessageContext(), result); + scoped_refptr<net::IOBuffer> recvfrom_buffer(new net::IOBuffer(num_bytes)); + linked_ptr<net::IPEndPoint> end_point(new net::IPEndPoint()); + recvfrom_requests_.push(IORequest(recvfrom_buffer, + num_bytes, + end_point, + context->MakeReplyMessageContext())); + RecvFromInternal(); return PP_OK_COMPLETIONPENDING; } @@ -211,6 +262,38 @@ int32_t PepperUDPSocketPrivateMessageFilter::OnMsgClose( return PP_OK; } +void PepperUDPSocketPrivateMessageFilter::RecvFromInternal() { + if (recvfrom_requests_.empty() || recvfrom_state_ == IO_STATE_IN_PROCESS) + return; + DCHECK(recvfrom_state_ == IO_STATE_IDLE); + recvfrom_state_ = IO_STATE_IN_PROCESS; + const IORequest& request = recvfrom_requests_.front(); + int result = socket_->RecvFrom( + request.buffer.get(), + static_cast<int>(request.buffer_size), + request.end_point.get(), + base::Bind(&PepperUDPSocketPrivateMessageFilter::OnRecvFromCompleted, + this, request)); + if (result != net::ERR_IO_PENDING) + OnRecvFromCompleted(request, result); +} + +void PepperUDPSocketPrivateMessageFilter::SendToInternal() { + if (sendto_requests_.empty() || sendto_state_ == IO_STATE_IN_PROCESS) + return; + DCHECK(sendto_state_ == IO_STATE_IDLE); + sendto_state_ = IO_STATE_IN_PROCESS; + const IORequest& request = sendto_requests_.front(); + int result = socket_->SendTo( + request.buffer.get(), + static_cast<int>(request.buffer_size), + *request.end_point.get(), + base::Bind(&PepperUDPSocketPrivateMessageFilter::OnSendToCompleted, + this, request)); + if (result != net::ERR_IO_PENDING) + OnSendToCompleted(request, result); +} + void PepperUDPSocketPrivateMessageFilter::DoBind( const ppapi::host::ReplyMessageContext& context, const PP_NetAddress_Private& addr) { @@ -246,9 +329,20 @@ void PepperUDPSocketPrivateMessageFilter::DoBind( bound_address.port(), &net_address)) { SendBindError(context, PP_ERROR_FAILED); - } else { - SendBindReply(context, PP_OK, net_address); + return; } + if (custom_send_buffer_size_ && + !socket_->SetSendBufferSize(send_buffer_size_)) { + SendBindError(context, PP_ERROR_FAILED); + return; + } + if (custom_recv_buffer_size_ && + !socket_->SetReceiveBufferSize(recv_buffer_size_)) { + SendBindError(context, PP_ERROR_FAILED); + return; + } + + SendBindReply(context, PP_OK, net_address); } void PepperUDPSocketPrivateMessageFilter::DoSendTo( @@ -263,11 +357,6 @@ void PepperUDPSocketPrivateMessageFilter::DoSendTo( return; } - if (sendto_buffer_.get()) { - SendSendToError(context, PP_ERROR_INPROGRESS); - return; - } - if (data.empty() || data.size() > static_cast<size_t>(std::numeric_limits<int>::max())) { SendSendToError(context, PP_ERROR_BADARGUMENT); @@ -281,8 +370,10 @@ void PepperUDPSocketPrivateMessageFilter::DoSendTo( num_bytes = static_cast<size_t>( ppapi::proxy::UDPSocketPrivateResource::kMaxWriteSize); } - sendto_buffer_ = new net::IOBufferWithSize(num_bytes); - memcpy(sendto_buffer_->data(), data.data(), num_bytes); + + scoped_refptr<net::IOBuffer> sendto_buffer( + new net::IOBufferWithSize(num_bytes)) ; + memcpy(sendto_buffer->data(), data.data(), num_bytes); net::IPAddressNumber address; int port; @@ -290,13 +381,13 @@ void PepperUDPSocketPrivateMessageFilter::DoSendTo( SendSendToError(context, PP_ERROR_FAILED); return; } + linked_ptr<net::IPEndPoint> end_point(new net::IPEndPoint(address, port)); - int result = socket_->SendTo( - sendto_buffer_, sendto_buffer_->size(), net::IPEndPoint(address, port), - base::Bind(&PepperUDPSocketPrivateMessageFilter::OnSendToCompleted, this, - context)); - if (result != net::ERR_IO_PENDING) - OnSendToCompleted(context, result); + sendto_requests_.push(IORequest(sendto_buffer, + static_cast<int32_t>(num_bytes), + end_point, + context)); + SendToInternal(); } void PepperUDPSocketPrivateMessageFilter::Close() { @@ -307,38 +398,46 @@ void PepperUDPSocketPrivateMessageFilter::Close() { } void PepperUDPSocketPrivateMessageFilter::OnRecvFromCompleted( - const ppapi::host::ReplyMessageContext& context, + const IORequest& request, int32_t result) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - DCHECK(recvfrom_buffer_.get()); + DCHECK(request.buffer.get()); + DCHECK(request.end_point.get()); // Convert IPEndPoint we get back from RecvFrom to a PP_NetAddress_Private, // to send back. PP_NetAddress_Private addr = NetAddressPrivateImpl::kInvalidNetAddress; if (result < 0 || !NetAddressPrivateImpl::IPEndPointToNetAddress( - recvfrom_address_.address(), - recvfrom_address_.port(), + request.end_point->address(), + request.end_point->port(), &addr)) { - SendRecvFromError(context, PP_ERROR_FAILED); + SendRecvFromError(request.context, PP_ERROR_FAILED); } else { - SendRecvFromReply(context, PP_OK, - std::string(recvfrom_buffer_->data(), result), addr); + SendRecvFromReply(request.context, PP_OK, + std::string(request.buffer->data(), result), addr); } - - recvfrom_buffer_ = NULL; + // Take out |request| from |recvfrom_requests_| queue. + recvfrom_requests_.pop(); + recvfrom_state_ = IO_STATE_IDLE; + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + base::Bind(&PepperUDPSocketPrivateMessageFilter::RecvFromInternal, this)); } void PepperUDPSocketPrivateMessageFilter::OnSendToCompleted( - const ppapi::host::ReplyMessageContext& context, + const IORequest& request, int32_t result) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - DCHECK(sendto_buffer_.get()); + DCHECK(request.buffer.get()); if (result < 0) - SendSendToError(context, PP_ERROR_FAILED); + SendSendToError(request.context, PP_ERROR_FAILED); else - SendSendToReply(context, PP_OK, result); - sendto_buffer_ = NULL; + SendSendToReply(request.context, PP_OK, result); + // Take out |request| from |sendto_requests_| queue. + sendto_requests_.pop(); + sendto_state_ = IO_STATE_IDLE; + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + base::Bind(&PepperUDPSocketPrivateMessageFilter::SendToInternal, this)); } void PepperUDPSocketPrivateMessageFilter::SendBindReply( diff --git a/content/browser/renderer_host/pepper/pepper_udp_socket_private_message_filter.h b/content/browser/renderer_host/pepper/pepper_udp_socket_private_message_filter.h index 90f433f..34400b7 100644 --- a/content/browser/renderer_host/pepper/pepper_udp_socket_private_message_filter.h +++ b/content/browser/renderer_host/pepper/pepper_udp_socket_private_message_filter.h @@ -5,16 +5,19 @@ #ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_UDP_SOCKET_PRIVATE_MESSAGE_FILTER_H_ #define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_UDP_SOCKET_PRIVATE_MESSAGE_FILTER_H_ +#include <queue> #include <string> #include "base/basictypes.h" #include "base/callback.h" #include "base/compiler_specific.h" +#include "base/memory/linked_ptr.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "content/common/content_export.h" #include "content/public/common/process_type.h" #include "net/base/completion_callback.h" +#include "net/base/io_buffer.h" #include "net/base/ip_endpoint.h" #include "ppapi/c/pp_instance.h" #include "ppapi/c/pp_stdint.h" @@ -23,8 +26,6 @@ struct PP_NetAddress_Private; namespace net { -class IOBuffer; -class IOBufferWithSize; class UDPServerSocket; } @@ -49,6 +50,24 @@ class CONTENT_EXPORT PepperUDPSocketPrivateMessageFilter virtual ~PepperUDPSocketPrivateMessageFilter(); private: + enum IOState { + IO_STATE_IDLE = 0, + IO_STATE_IN_PROCESS + }; + + struct IORequest { + IORequest(const scoped_refptr<net::IOBuffer>& buffer, + int32_t buffer_size, + const linked_ptr<net::IPEndPoint>& end_point, + const ppapi::host::ReplyMessageContext& context); + ~IORequest(); + + scoped_refptr<net::IOBuffer> buffer; + int32_t buffer_size; + linked_ptr<net::IPEndPoint> end_point; + ppapi::host::ReplyMessageContext context; + }; + // ppapi::host::ResourceMessageFilter overrides. virtual scoped_refptr<base::TaskRunner> OverrideTaskRunnerForMessage( const IPC::Message& message) OVERRIDE; @@ -60,6 +79,10 @@ class CONTENT_EXPORT PepperUDPSocketPrivateMessageFilter const ppapi::host::HostMessageContext* context, int32_t name, bool value); + int32_t OnMsgSetInt32SocketFeature( + const ppapi::host::HostMessageContext* context, + int32_t name, + int32_t value); int32_t OnMsgBind(const ppapi::host::HostMessageContext* context, const PP_NetAddress_Private& addr); int32_t OnMsgRecvFrom(const ppapi::host::HostMessageContext* context, @@ -69,6 +92,9 @@ class CONTENT_EXPORT PepperUDPSocketPrivateMessageFilter const PP_NetAddress_Private& addr); int32_t OnMsgClose(const ppapi::host::HostMessageContext* context); + void RecvFromInternal(); + void SendToInternal(); + void DoBind(const ppapi::host::ReplyMessageContext& context, const PP_NetAddress_Private& addr); void DoSendTo(const ppapi::host::ReplyMessageContext& context, @@ -76,10 +102,8 @@ class CONTENT_EXPORT PepperUDPSocketPrivateMessageFilter const PP_NetAddress_Private& addr); void Close(); - void OnRecvFromCompleted(const ppapi::host::ReplyMessageContext& context, - int32_t result); - void OnSendToCompleted(const ppapi::host::ReplyMessageContext& context, - int32_t result); + void OnRecvFromCompleted(const IORequest& request, int32_t result); + void OnSendToCompleted(const IORequest& request, int32_t result); void SendBindReply(const ppapi::host::ReplyMessageContext& context, int32_t result, @@ -102,13 +126,19 @@ class CONTENT_EXPORT PepperUDPSocketPrivateMessageFilter bool allow_address_reuse_; bool allow_broadcast_; + bool custom_send_buffer_size_; + int32_t send_buffer_size_; + + bool custom_recv_buffer_size_; + int32_t recv_buffer_size_; + scoped_ptr<net::UDPServerSocket> socket_; bool closed_; - scoped_refptr<net::IOBuffer> recvfrom_buffer_; - scoped_refptr<net::IOBufferWithSize> sendto_buffer_; - - net::IPEndPoint recvfrom_address_; + std::queue<IORequest> recvfrom_requests_; + std::queue<IORequest> sendto_requests_; + IOState recvfrom_state_; + IOState sendto_state_; bool external_plugin_; int render_process_id_; |