summaryrefslogtreecommitdiffstats
path: root/content/browser/renderer_host/pepper
diff options
context:
space:
mode:
authorygorshenin@chromium.org <ygorshenin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-27 12:19:50 +0000
committerygorshenin@chromium.org <ygorshenin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-27 12:19:50 +0000
commit7c65124882899919bbd302842095758cb5804bde (patch)
treebb926631d2d92903780729a1cfe9e409b4288a60 /content/browser/renderer_host/pepper
parentcdbea94e52b0a9fb0590d1e219f764ca44836d37 (diff)
downloadchromium_src-7c65124882899919bbd302842095758cb5804bde.zip
chromium_src-7c65124882899919bbd302842095758cb5804bde.tar.gz
chromium_src-7c65124882899919bbd302842095758cb5804bde.tar.bz2
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
Diffstat (limited to 'content/browser/renderer_host/pepper')
-rw-r--r--content/browser/renderer_host/pepper/pepper_udp_socket_private_message_filter.cc124
-rw-r--r--content/browser/renderer_host/pepper/pepper_udp_socket_private_message_filter.h40
2 files changed, 117 insertions, 47 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 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<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),
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<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;
}
@@ -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<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) {
@@ -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<size_t>(std::numeric_limits<int>::max())) {
SendSendToError(context, PP_ERROR_BADARGUMENT);
@@ -269,8 +309,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;
@@ -278,13 +320,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() {
@@ -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 <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;
@@ -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<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_;
ProcessType plugin_process_type_;
int render_process_id_;