summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/test/ppapi/ppapi_browsertest.cc4
-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
-rw-r--r--ppapi/proxy/udp_socket_private_resource.cc56
-rw-r--r--ppapi/proxy/udp_socket_private_resource.h22
-rw-r--r--ppapi/tests/test_udp_socket_private.cc143
-rw-r--r--ppapi/tests/test_udp_socket_private.h7
7 files changed, 321 insertions, 75 deletions
diff --git a/chrome/test/ppapi/ppapi_browsertest.cc b/chrome/test/ppapi/ppapi_browsertest.cc
index f575df5..21228ef 100644
--- a/chrome/test/ppapi/ppapi_browsertest.cc
+++ b/chrome/test/ppapi/ppapi_browsertest.cc
@@ -294,12 +294,16 @@ TEST_PPAPI_OUT_OF_PROCESS_VIA_HTTP(UDPSocketPrivate_ConnectFailure)
TEST_PPAPI_OUT_OF_PROCESS_VIA_HTTP(UDPSocketPrivate_Broadcast)
#endif // !defined(OS_MACOSX)
TEST_PPAPI_OUT_OF_PROCESS_VIA_HTTP(UDPSocketPrivate_SetSocketFeatureErrors)
+TEST_PPAPI_OUT_OF_PROCESS_VIA_HTTP(UDPSocketPrivate_SequentialRequests)
+TEST_PPAPI_OUT_OF_PROCESS_VIA_HTTP(UDPSocketPrivate_QueuedRequests)
TEST_PPAPI_NACL(UDPSocketPrivate_Connect)
TEST_PPAPI_NACL(UDPSocketPrivate_ConnectFailure)
#if !defined(OS_MACOSX)
TEST_PPAPI_NACL(UDPSocketPrivate_Broadcast)
#endif // !defined(OS_MACOSX)
TEST_PPAPI_NACL(UDPSocketPrivate_SetSocketFeatureErrors)
+TEST_PPAPI_NACL(UDPSocketPrivate_SequentialRequests)
+TEST_PPAPI_NACL(UDPSocketPrivate_QueuedRequests)
TEST_PPAPI_NACL_DISALLOWED_SOCKETS(HostResolverPrivateDisallowed)
TEST_PPAPI_NACL_DISALLOWED_SOCKETS(TCPServerSocketPrivateDisallowed)
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_;
diff --git a/ppapi/proxy/udp_socket_private_resource.cc b/ppapi/proxy/udp_socket_private_resource.cc
index 608fc00..ea08b7e 100644
--- a/ppapi/proxy/udp_socket_private_resource.cc
+++ b/ppapi/proxy/udp_socket_private_resource.cc
@@ -24,9 +24,7 @@ UDPSocketPrivateResource::UDPSocketPrivateResource(Connection connection,
PP_Instance instance)
: PluginResource(connection, instance),
bound_(false),
- closed_(false),
- read_buffer_(NULL),
- bytes_to_read_(-1) {
+ closed_(false) {
recvfrom_addr_.size = 0;
memset(recvfrom_addr_.data, 0,
arraysize(recvfrom_addr_.data) * sizeof(*recvfrom_addr_.data));
@@ -98,15 +96,13 @@ int32_t UDPSocketPrivateResource::RecvFrom(
return PP_ERROR_BADARGUMENT;
if (!bound_)
return PP_ERROR_FAILED;
- if (TrackedCallback::IsPending(recvfrom_callback_))
- return PP_ERROR_INPROGRESS;
- read_buffer_ = buffer;
- bytes_to_read_ = std::min(num_bytes, kMaxReadSize);
- recvfrom_callback_ = callback;
+ recvfrom_requests_.push(RecvFromRequest(callback,
+ buffer,
+ std::min(num_bytes, kMaxReadSize)));
// Send the request, the browser will call us back via RecvFromReply.
- SendRecvFrom(bytes_to_read_);
+ SendRecvFrom(num_bytes);
return PP_OK_COMPLETIONPENDING;
}
@@ -133,13 +129,11 @@ int32_t UDPSocketPrivateResource::SendTo(
return PP_ERROR_BADARGUMENT;
if (!bound_)
return PP_ERROR_FAILED;
- if (TrackedCallback::IsPending(sendto_callback_))
- return PP_ERROR_INPROGRESS;
if (num_bytes > kMaxWriteSize)
num_bytes = kMaxWriteSize;
- sendto_callback_ = callback;
+ sendto_callbacks_.push(callback);
// Send the request, the browser will call us back via SendToReply.
SendSendTo(std::string(buffer, num_bytes), *addr);
@@ -156,8 +150,15 @@ void UDPSocketPrivateResource::Close() {
SendClose();
PostAbortIfNecessary(&bind_callback_);
- PostAbortIfNecessary(&recvfrom_callback_);
- PostAbortIfNecessary(&sendto_callback_);
+ while (!recvfrom_requests_.empty()) {
+ RecvFromRequest& request = recvfrom_requests_.front();
+ PostAbortIfNecessary(&request.callback);
+ recvfrom_requests_.pop();
+ }
+ while (!sendto_callbacks_.empty()) {
+ PostAbortIfNecessary(&sendto_callbacks_.front());
+ sendto_callbacks_.pop();
+ }
}
void UDPSocketPrivateResource::SendBoolSocketFeature(int32_t name, bool value) {
@@ -215,37 +216,44 @@ void UDPSocketPrivateResource::OnPluginMsgRecvFromReply(
const ResourceMessageReplyParams& params,
const std::string& data,
const PP_NetAddress_Private& addr) {
- if (!TrackedCallback::IsPending(recvfrom_callback_) || !read_buffer_) {
+ if (recvfrom_requests_.empty())
+ return;
+ RecvFromRequest request = recvfrom_requests_.front();
+ recvfrom_requests_.pop();
+ if (!TrackedCallback::IsPending(request.callback) || !request.buffer) {
NOTREACHED();
return;
}
bool succeeded = (params.result() == PP_OK);
if (succeeded) {
- CHECK_LE(static_cast<int32_t>(data.size()), bytes_to_read_);
+ CHECK_LE(static_cast<int32_t>(data.size()), request.num_bytes);
if (!data.empty())
- memcpy(read_buffer_, data.c_str(), data.size());
+ memcpy(request.buffer, data.c_str(), data.size());
}
- read_buffer_ = NULL;
- bytes_to_read_ = -1;
+
recvfrom_addr_ = addr;
if (succeeded)
- recvfrom_callback_->Run(static_cast<int32_t>(data.size()));
+ request.callback->Run(static_cast<int32_t>(data.size()));
else
- recvfrom_callback_->Run(params.result());
+ request.callback->Run(params.result());
}
void UDPSocketPrivateResource::OnPluginMsgSendToReply(
const ResourceMessageReplyParams& params,
int32_t bytes_written) {
- if (!TrackedCallback::IsPending(sendto_callback_)) {
+ if (sendto_callbacks_.empty())
+ return;
+ scoped_refptr<TrackedCallback> callback = sendto_callbacks_.front();
+ sendto_callbacks_.pop();
+ if (!TrackedCallback::IsPending(callback)) {
NOTREACHED();
return;
}
if (params.result() == PP_OK)
- sendto_callback_->Run(bytes_written);
+ callback->Run(bytes_written);
else
- sendto_callback_->Run(params.result());
+ callback->Run(params.result());
}
} // namespace proxy
diff --git a/ppapi/proxy/udp_socket_private_resource.h b/ppapi/proxy/udp_socket_private_resource.h
index 6403f6b..e72f44e 100644
--- a/ppapi/proxy/udp_socket_private_resource.h
+++ b/ppapi/proxy/udp_socket_private_resource.h
@@ -5,6 +5,8 @@
#ifndef PPAPI_PROXY_UDP_SOCKET_PRIVATE_RESOURCE_H_
#define PPAPI_PROXY_UDP_SOCKET_PRIVATE_RESOURCE_H_
+#include <queue>
+
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "ppapi/proxy/plugin_resource.h"
@@ -51,6 +53,20 @@ class PPAPI_PROXY_EXPORT UDPSocketPrivateResource
virtual void Close() OVERRIDE;
private:
+ struct RecvFromRequest {
+ RecvFromRequest(scoped_refptr<TrackedCallback> callback,
+ char* buffer,
+ int32_t num_bytes)
+ : callback(callback),
+ buffer(buffer),
+ num_bytes(num_bytes) {
+ }
+
+ scoped_refptr<TrackedCallback> callback;
+ char* buffer;
+ int32_t num_bytes;
+ };
+
void PostAbortIfNecessary(scoped_refptr<TrackedCallback>* callback);
void SendBoolSocketFeature(int32_t name, bool value);
@@ -73,11 +89,9 @@ class PPAPI_PROXY_EXPORT UDPSocketPrivateResource
bool closed_;
scoped_refptr<TrackedCallback> bind_callback_;
- scoped_refptr<TrackedCallback> recvfrom_callback_;
- scoped_refptr<TrackedCallback> sendto_callback_;
- char* read_buffer_;
- int32_t bytes_to_read_;
+ std::queue<RecvFromRequest> recvfrom_requests_;
+ std::queue<scoped_refptr<TrackedCallback> > sendto_callbacks_;
PP_NetAddress_Private recvfrom_addr_;
PP_NetAddress_Private bound_addr_;
diff --git a/ppapi/tests/test_udp_socket_private.cc b/ppapi/tests/test_udp_socket_private.cc
index 4680ff2..b91f1a9 100644
--- a/ppapi/tests/test_udp_socket_private.cc
+++ b/ppapi/tests/test_udp_socket_private.cc
@@ -20,6 +20,17 @@ namespace {
const uint16_t kPortScanFrom = 1024;
const uint16_t kPortScanTo = 4096;
+const size_t kEnglishAlphabetSize = 'z' - 'a' + 1;
+
+// 4K datagrams for sendto/recvfrom benchmarks.
+const size_t kBenchmarkMessageSize = 1u << 12;
+
+// Maximum number of datagrams for sendto/recvfrom benchmarks.
+const size_t kBenchmarkMaxNumMessages = 1u << 12;
+
+// Assuming that system buffer size for UDP sockets is at least 32K.
+const size_t kUDPBufferSize = 32768;
+
} // namespace
TestUDPSocketPrivate::TestUDPSocketPrivate(
@@ -58,6 +69,8 @@ void TestUDPSocketPrivate::RunTests(const std::string& filter) {
RUN_TEST_FORCEASYNC_AND_NOT(ConnectFailure, filter);
RUN_TEST_FORCEASYNC_AND_NOT(Broadcast, filter);
RUN_TEST_FORCEASYNC_AND_NOT(SetSocketFeatureErrors, filter);
+ RUN_TEST_FORCEASYNC_AND_NOT(QueuedRequests, filter);
+ RUN_TEST_FORCEASYNC_AND_NOT(SequentialRequests, filter);
}
std::string TestUDPSocketPrivate::GetLocalAddress(
@@ -182,6 +195,118 @@ std::string TestUDPSocketPrivate::PassMessage(pp::UDPSocketPrivate* target,
PASS();
}
+std::string TestUDPSocketPrivate::BenchmarkQueuedRequests(size_t num_messages,
+ size_t message_size) {
+ pp::UDPSocketPrivate server_socket(instance_), client_socket(instance_);
+ PP_NetAddress_Private server_address, client_address;
+
+ ASSERT_SUBTEST_SUCCESS(LookupPortAndBindUDPSocket(&server_socket,
+ &server_address));
+ ASSERT_SUBTEST_SUCCESS(LookupPortAndBindUDPSocket(&client_socket,
+ &client_address));
+
+ std::vector<std::string> messages(num_messages);
+ for (size_t i = 0; i < num_messages; ++i)
+ messages[i].resize(message_size, 'a' + i % kEnglishAlphabetSize);
+
+ std::vector<TestCompletionCallback*> sendto_callbacks(num_messages);
+ std::vector<int32_t> sendto_rv(num_messages);
+
+ std::vector<std::vector<char> > buffers(num_messages);
+ std::vector<TestCompletionCallback*> recvfrom_callbacks(num_messages);
+ std::vector<int32_t> recvfrom_rv(num_messages);
+
+ for (size_t i = 0; i < num_messages; ++i) {
+ sendto_callbacks[i] = new TestCompletionCallback(instance_->pp_instance(),
+ force_async_);
+ recvfrom_callbacks[i] = new TestCompletionCallback(instance_->pp_instance(),
+ force_async_);
+ }
+
+ for (size_t i = 0; i < num_messages; ++i) {
+ buffers[i].resize(messages[i].size());
+ recvfrom_rv[i] = server_socket.RecvFrom(&buffers[i][0],
+ messages[i].size(),
+ *recvfrom_callbacks[i]);
+ if (force_async_ && recvfrom_rv[i] != PP_OK_COMPLETIONPENDING) {
+ return ReportError("PPB_UDPSocket_Private::RecvFrom force_async",
+ recvfrom_rv[i]);
+ }
+ }
+
+ size_t num_sent = 0, num_read = 0;
+ while (num_sent < num_messages || num_read < num_messages) {
+ if ((num_sent < num_read ||
+ (num_sent - num_read) * message_size < kUDPBufferSize) &&
+ (num_sent < num_messages)) {
+ sendto_rv[num_sent] = client_socket.SendTo(messages[num_sent].c_str(),
+ messages[num_sent].size(),
+ &server_address,
+ *sendto_callbacks[num_sent]);
+ if (force_async_ && sendto_rv[num_sent] != PP_OK_COMPLETIONPENDING) {
+ return ReportError("PPB_UDPSocket_Private::SendTo force_async",
+ sendto_rv[num_sent]);
+ }
+ ++num_sent;
+ } else if (num_read < num_messages) {
+ if (recvfrom_rv[num_read] == PP_OK_COMPLETIONPENDING)
+ recvfrom_rv[num_read] = recvfrom_callbacks[num_read]->WaitForResult();
+ if (recvfrom_rv[num_read] < 0 ||
+ messages[num_read].size() !=
+ static_cast<size_t>(recvfrom_rv[num_read])) {
+ return ReportError("PPB_UDPSocket_Private::RecvFrom",
+ recvfrom_rv[num_read]);
+ }
+ ++num_read;
+ }
+ }
+
+ for (size_t i = 0; i < num_messages; ++i) {
+ if (sendto_rv[i] == PP_OK_COMPLETIONPENDING)
+ sendto_rv[i] = sendto_callbacks[i]->WaitForResult();
+ if (sendto_rv[i] < 0 ||
+ messages[i].size() != static_cast<size_t>(sendto_rv[i])) {
+ return ReportError("PPB_UDPSocket_Private::SendTo", sendto_rv[i]);
+ }
+ ASSERT_EQ(messages[i], std::string(buffers[i].begin(), buffers[i].end()));
+ }
+
+ for (size_t i = 0; i < num_messages; ++i) {
+ delete sendto_callbacks[i];
+ delete recvfrom_callbacks[i];
+ }
+
+ server_socket.Close();
+ client_socket.Close();
+ PASS();
+}
+
+std::string TestUDPSocketPrivate::BenchmarkSequentialRequests(
+ size_t num_messages,
+ size_t message_size) {
+ pp::UDPSocketPrivate server_socket(instance_), client_socket(instance_);
+ PP_NetAddress_Private server_address, client_address;
+
+ ASSERT_SUBTEST_SUCCESS(LookupPortAndBindUDPSocket(&server_socket,
+ &server_address));
+ ASSERT_SUBTEST_SUCCESS(LookupPortAndBindUDPSocket(&client_socket,
+ &client_address));
+ std::vector<std::string> messages(num_messages);
+ for (size_t i = 0; i < num_messages; ++i)
+ messages[i].resize(message_size, 'a' + i % kEnglishAlphabetSize);
+
+ for (size_t i = 0; i < num_messages; ++i) {
+ ASSERT_SUBTEST_SUCCESS(PassMessage(&server_socket,
+ &client_socket,
+ &server_address,
+ messages[i]));
+ }
+
+ server_socket.Close();
+ client_socket.Close();
+ PASS();
+}
+
std::string TestUDPSocketPrivate::TestConnect() {
pp::UDPSocketPrivate server_socket(instance_), client_socket(instance_);
PP_NetAddress_Private server_address, client_address;
@@ -274,3 +399,21 @@ std::string TestUDPSocketPrivate::TestSetSocketFeatureErrors() {
ASSERT_EQ(PP_ERROR_BADARGUMENT, rv);
PASS();
}
+
+std::string TestUDPSocketPrivate::TestSequentialRequests() {
+ for (size_t num_messages = 1u << 8;
+ num_messages <= kBenchmarkMaxNumMessages; num_messages <<= 1) {
+ ASSERT_SUBTEST_SUCCESS(BenchmarkSequentialRequests(num_messages,
+ kBenchmarkMessageSize));
+ }
+ PASS();
+}
+
+std::string TestUDPSocketPrivate::TestQueuedRequests() {
+ for (size_t num_messages = 1u << 8;
+ num_messages <= kBenchmarkMaxNumMessages; num_messages <<= 1) {
+ ASSERT_SUBTEST_SUCCESS(BenchmarkQueuedRequests(num_messages,
+ kBenchmarkMessageSize));
+ }
+ PASS();
+}
diff --git a/ppapi/tests/test_udp_socket_private.h b/ppapi/tests/test_udp_socket_private.h
index e4a23c9..82db100 100644
--- a/ppapi/tests/test_udp_socket_private.h
+++ b/ppapi/tests/test_udp_socket_private.h
@@ -37,10 +37,17 @@ class TestUDPSocketPrivate : public TestCase {
PP_NetAddress_Private* address,
const std::string& message);
+ std::string BenchmarkQueuedRequests(size_t num_messages,
+ size_t message_size);
+ std::string BenchmarkSequentialRequests(size_t num_messages,
+ size_t message_size);
+
std::string TestConnect();
std::string TestConnectFailure();
std::string TestBroadcast();
std::string TestSetSocketFeatureErrors();
+ std::string TestQueuedRequests();
+ std::string TestSequentialRequests();
std::string host_;
uint16_t port_;