From 7c65124882899919bbd302842095758cb5804bde Mon Sep 17 00:00:00 2001 From: "ygorshenin@chromium.org" Date: Wed, 27 Feb 2013 12:19:50 +0000 Subject: Implemented queued UDP SendTo/RecvFrom requests. BUG=154338 TEST=browser_tests:*UDPSocketPrivate* Review URL: https://chromiumcodereview.appspot.com/12316095 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@184934 0039d316-1c4b-4281-b951-d872f2087c98 --- .../pepper_udp_socket_private_message_filter.cc | 124 +++++++++++++++------ .../pepper_udp_socket_private_message_filter.h | 40 +++++-- 2 files changed, 117 insertions(+), 47 deletions(-) (limited to 'content/browser/renderer_host/pepper') 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 a6261dd..41b0620 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,28 @@ bool CanUseSocketAPIs(const SocketPermissionRequest& request, } // namespace +PepperUDPSocketPrivateMessageFilter::IORequest::IORequest( + const scoped_refptr& buffer, + int32_t buffer_size, + const linked_ptr& 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), closed_(false), + recvfrom_state_(IO_STATE_IDLE), + sendto_state_(IO_STATE_IDLE), plugin_process_type_(host->plugin_process_type()), render_process_id_(0), render_view_id_(0) { @@ -161,20 +176,18 @@ int32_t PepperUDPSocketPrivateMessageFilter::OnMsgRecvFrom( DCHECK(socket_.get()); DCHECK(!closed_); - 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 recvfrom_buffer(new net::IOBuffer(num_bytes)); + linked_ptr end_point(new net::IPEndPoint()); + recvfrom_requests_.push(IORequest(recvfrom_buffer, + num_bytes, + end_point, + context->MakeReplyMessageContext())); + RecvFromInternal(); return PP_OK_COMPLETIONPENDING; } @@ -207,6 +220,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(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(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) { @@ -251,11 +296,6 @@ void PepperUDPSocketPrivateMessageFilter::DoSendTo( DCHECK(socket_.get()); DCHECK(!closed_); - if (sendto_buffer_.get()) { - SendSendToError(context, PP_ERROR_INPROGRESS); - return; - } - if (data.empty() || data.size() > static_cast(std::numeric_limits::max())) { SendSendToError(context, PP_ERROR_BADARGUMENT); @@ -269,8 +309,10 @@ void PepperUDPSocketPrivateMessageFilter::DoSendTo( num_bytes = static_cast( ppapi::proxy::UDPSocketPrivateResource::kMaxWriteSize); } - sendto_buffer_ = new net::IOBufferWithSize(num_bytes); - memcpy(sendto_buffer_->data(), data.data(), num_bytes); + + scoped_refptr sendto_buffer( + new net::IOBufferWithSize(num_bytes)) ; + memcpy(sendto_buffer->data(), data.data(), num_bytes); net::IPAddressNumber address; int port; @@ -278,13 +320,13 @@ void PepperUDPSocketPrivateMessageFilter::DoSendTo( SendSendToError(context, PP_ERROR_FAILED); return; } + linked_ptr 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(num_bytes), + end_point, + context)); + SendToInternal(); } void PepperUDPSocketPrivateMessageFilter::Close() { @@ -295,38 +337,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 eb62a1f..7ae6488 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 #include #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& buffer, + int32_t buffer_size, + const linked_ptr& end_point, + const ppapi::host::ReplyMessageContext& context); + ~IORequest(); + + scoped_refptr buffer; + int32_t buffer_size; + linked_ptr end_point; + ppapi::host::ReplyMessageContext context; + }; + // ppapi::host::ResourceMessageFilter overrides. virtual scoped_refptr OverrideTaskRunnerForMessage( const IPC::Message& message) OVERRIDE; @@ -69,6 +88,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 +98,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, @@ -105,10 +125,10 @@ class CONTENT_EXPORT PepperUDPSocketPrivateMessageFilter scoped_ptr socket_; bool closed_; - scoped_refptr recvfrom_buffer_; - scoped_refptr sendto_buffer_; - - net::IPEndPoint recvfrom_address_; + std::queue recvfrom_requests_; + std::queue sendto_requests_; + IOState recvfrom_state_; + IOState sendto_state_; ProcessType plugin_process_type_; int render_process_id_; -- cgit v1.1