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.cc179
-rw-r--r--content/browser/renderer_host/pepper/pepper_udp_socket_private_message_filter.h50
-rw-r--r--ppapi/api/private/ppb_udp_socket_private.idl74
-rw-r--r--ppapi/c/pp_macros.h4
-rw-r--r--ppapi/c/private/ppb_udp_socket_private.h88
-rw-r--r--ppapi/cpp/private/udp_socket_private.cc45
-rw-r--r--ppapi/cpp/private/udp_socket_private.h4
-rw-r--r--ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c71
-rw-r--r--ppapi/proxy/ppapi_messages.h3
-rw-r--r--ppapi/proxy/udp_socket_private_resource.cc119
-rw-r--r--ppapi/proxy/udp_socket_private_resource.h52
-rw-r--r--ppapi/tests/test_udp_socket_private.cc174
-rw-r--r--ppapi/tests/test_udp_socket_private.h10
-rw-r--r--ppapi/thunk/interfaces_ppb_private_no_permissions.h2
-rw-r--r--ppapi/thunk/ppb_udp_socket_private_api.h10
-rw-r--r--ppapi/thunk/ppb_udp_socket_private_thunk.cc67
17 files changed, 770 insertions, 186 deletions
diff --git a/chrome/test/ppapi/ppapi_browsertest.cc b/chrome/test/ppapi/ppapi_browsertest.cc
index 3f074876..93b99ef 100644
--- a/chrome/test/ppapi/ppapi_browsertest.cc
+++ b/chrome/test/ppapi/ppapi_browsertest.cc
@@ -315,12 +315,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 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_;
diff --git a/ppapi/api/private/ppb_udp_socket_private.idl b/ppapi/api/private/ppb_udp_socket_private.idl
index fc4fe1c..48a1186 100644
--- a/ppapi/api/private/ppb_udp_socket_private.idl
+++ b/ppapi/api/private/ppb_udp_socket_private.idl
@@ -10,23 +10,37 @@
label Chrome {
M17 = 0.2,
M19 = 0.3,
- M23 = 0.4
+ M23 = 0.4,
+ M28 = 0.5
};
[assert_size(4)]
enum PP_UDPSocketFeature_Private {
// Allow the socket to share the local address to which socket will
// be bound with other processes. Value's type should be
- // PP_VARTYPE_BOOL.
+ // PP_VARTYPE_BOOL. Takes effect if set before Bind().
PP_UDPSOCKETFEATURE_ADDRESS_REUSE = 0,
- // Allow sending and receiving packets sent to and from broadcast
- // addresses. Value's type should be PP_VARTYPE_BOOL.
+ // Allow sending and receiving packets to and from broadcast
+ // addresses. Value's type should be PP_VARTYPE_BOOL. Takes effect
+ // if set before Bind().
PP_UDPSOCKETFEATURE_BROADCAST = 1,
+ // Specifies the total per-socket buffer space reserved for
+ // sends. Value's type should be PP_VARTYPE_INT32. Supported in v0.5
+ // and above.
+ [version=0.5]
+ PP_UDPSOCKETFEATURE_SEND_BUFFER_SIZE = 2,
+
+ // Specifies the total per-socket buffer space reserved for
+ // receives. Value's type should be PP_VARTYPE_INT32. Supported in
+ // v0.5 and above.
+ [version=0.5]
+ PP_UDPSOCKETFEATURE_RECV_BUFFER_SIZE = 3,
+
// Special value for counting the number of available
// features. Should not be passed to SetSocketFeature().
- PP_UDPSOCKETFEATURE_COUNT = 2
+ PP_UDPSOCKETFEATURE_COUNT = 4
};
interface PPB_UDPSocket_Private {
@@ -41,13 +55,13 @@ interface PPB_UDPSocket_Private {
PP_Bool IsUDPSocket([in] PP_Resource resource_id);
/**
- * Sets a socket feature to |udp_socket|. Should be called before
- * Bind(). Possible values for |name|, |value| and |value|'s type
- * are described in PP_UDPSocketFeature_Private description. If no
- * error occurs, returns PP_OK. Otherwise, returns
- * PP_ERROR_BADRESOURCE (if bad |udp_socket| provided),
- * PP_ERROR_BADARGUMENT (if bad name/value/value's type provided)
- * or PP_ERROR_FAILED in the case of internal errors.
+ * Sets a socket feature to |udp_socket|. Possible values for
+ * |name|, |value| and |value|'s type are described in
+ * PP_UDPSocketFeature_Private description. If no error occurs,
+ * returns PP_OK. Otherwise, returns PP_ERROR_BADRESOURCE (if bad
+ * |udp_socket| provided), PP_ERROR_BADARGUMENT (if bad
+ * name/value/value's type provided) or PP_ERROR_FAILED in the case
+ * of internal errors.
*/
[version=0.4]
int32_t SetSocketFeature([in] PP_Resource udp_socket,
@@ -60,32 +74,48 @@ interface PPB_UDPSocket_Private {
[in] PP_CompletionCallback callback);
/* Returns the address that the socket has bound to. A successful
- * call to Bind must be called first. Returns PP_FALSE if Bind
- * fails, or if Close has been called.
+ * call to Bind() must be called first. Returns PP_FALSE if Bind
+ * fails, or if Close() has been called.
*/
[version=0.3]
PP_Bool GetBoundAddress([in] PP_Resource udp_socket,
[out] PP_NetAddress_Private addr);
- /* Performs a non-blocking recvfrom call on socket.
- * Bind must be called first. |callback| is invoked when recvfrom
- * reads data. You must call GetRecvFromAddress to recover the
- * address the data was retrieved from.
+ /* Performs a non-blocking recvfrom call on socket. Bind() must be
+ * called first. |callback| is invoked when recvfrom reads data, and
+ * only after invocation of |callback| it is allowed to call
+ * RecvFrom() again. You must call GetRecvFromAddress() to recover
+ * the address the data was retrieved from.
+ */
+ [version=0.2, deprecate=0.5]
+ int32_t RecvFrom([in] PP_Resource udp_socket,
+ [out] str_t buffer,
+ [in] int32_t num_bytes,
+ [in] PP_CompletionCallback callback);
+
+ /* Performs a non-blocking recvfrom call on socket. Bind() must be
+ * called first. |callback| is invoked when recvfrom reads data. It
+ * is possible to call RecvFrom() again on the same socket before
+ * completion of the previous call.
*/
+ [version=0.5]
int32_t RecvFrom([in] PP_Resource udp_socket,
[out] str_t buffer,
[in] int32_t num_bytes,
+ [out] PP_NetAddress_Private addr,
[in] PP_CompletionCallback callback);
- /* Upon successful completion of RecvFrom, the address that the data
- * was received from is stored in |addr|.
+ /* Upon successful completion of RecvFrom(), the address that the
+ * data was received from is stored in |addr|.
*/
+ [version=0.2, deprecate=0.5]
PP_Bool GetRecvFromAddress([in] PP_Resource udp_socket,
[out] PP_NetAddress_Private addr);
/* Performs a non-blocking sendto call on the socket created and
- * bound(has already called Bind). The callback |callback| is
- * invoked when sendto completes.
+ * bound(has already called Bind()). The callback |callback| is
+ * invoked when sendto completes. |buffer| and |addr| don't need to
+ * persist until |callback| is called.
*/
int32_t SendTo([in] PP_Resource udp_socket,
[in] str_t buffer,
diff --git a/ppapi/c/pp_macros.h b/ppapi/c/pp_macros.h
index 83f85d6..7dbb832 100644
--- a/ppapi/c/pp_macros.h
+++ b/ppapi/c/pp_macros.h
@@ -3,13 +3,13 @@
* found in the LICENSE file.
*/
-/* From pp_macros.idl modified Fri Feb 15 16:46:46 2013. */
+/* From pp_macros.idl modified Wed Mar 13 14:22:53 2013. */
#ifndef PPAPI_C_PP_MACROS_H_
#define PPAPI_C_PP_MACROS_H_
-#define PPAPI_RELEASE 27
+#define PPAPI_RELEASE 28
/**
* @file
diff --git a/ppapi/c/private/ppb_udp_socket_private.h b/ppapi/c/private/ppb_udp_socket_private.h
index 27770b1..c1438a1 100644
--- a/ppapi/c/private/ppb_udp_socket_private.h
+++ b/ppapi/c/private/ppb_udp_socket_private.h
@@ -3,7 +3,7 @@
* found in the LICENSE file.
*/
-/* From private/ppb_udp_socket_private.idl modified Thu Aug 23 12:32:12 2012. */
+/* From private/ppb_udp_socket_private.idl modified Thu Mar 28 15:59:15 2013. */
#ifndef PPAPI_C_PRIVATE_PPB_UDP_SOCKET_PRIVATE_H_
#define PPAPI_C_PRIVATE_PPB_UDP_SOCKET_PRIVATE_H_
@@ -20,7 +20,8 @@
#define PPB_UDPSOCKET_PRIVATE_INTERFACE_0_2 "PPB_UDPSocket_Private;0.2"
#define PPB_UDPSOCKET_PRIVATE_INTERFACE_0_3 "PPB_UDPSocket_Private;0.3"
#define PPB_UDPSOCKET_PRIVATE_INTERFACE_0_4 "PPB_UDPSocket_Private;0.4"
-#define PPB_UDPSOCKET_PRIVATE_INTERFACE PPB_UDPSOCKET_PRIVATE_INTERFACE_0_4
+#define PPB_UDPSOCKET_PRIVATE_INTERFACE_0_5 "PPB_UDPSocket_Private;0.5"
+#define PPB_UDPSOCKET_PRIVATE_INTERFACE PPB_UDPSOCKET_PRIVATE_INTERFACE_0_5
/**
* @file
@@ -35,14 +36,23 @@
typedef enum {
/* Allow the socket to share the local address to which socket will
* be bound with other processes. Value's type should be
- * PP_VARTYPE_BOOL. */
+ * PP_VARTYPE_BOOL. Takes effect if set before Bind(). */
PP_UDPSOCKETFEATURE_ADDRESS_REUSE = 0,
- /* Allow sending and receiving packets sent to and from broadcast
- * addresses. Value's type should be PP_VARTYPE_BOOL. */
+ /* Allow sending and receiving packets to and from broadcast
+ * addresses. Value's type should be PP_VARTYPE_BOOL. Takes effect
+ * if set before Bind(). */
PP_UDPSOCKETFEATURE_BROADCAST = 1,
+ /* Specifies the total per-socket buffer space reserved for
+ * sends. Value's type should be PP_VARTYPE_INT32. Supported in v0.5
+ * and above. */
+ PP_UDPSOCKETFEATURE_SEND_BUFFER_SIZE = 2,
+ /* Specifies the total per-socket buffer space reserved for
+ * receives. Value's type should be PP_VARTYPE_INT32. Supported in
+ * v0.5 and above. */
+ PP_UDPSOCKETFEATURE_RECV_BUFFER_SIZE = 3,
/* Special value for counting the number of available
* features. Should not be passed to SetSocketFeature(). */
- PP_UDPSOCKETFEATURE_COUNT = 2
+ PP_UDPSOCKETFEATURE_COUNT = 4
} PP_UDPSocketFeature_Private;
PP_COMPILE_ASSERT_SIZE_IN_BYTES(PP_UDPSocketFeature_Private, 4);
/**
@@ -53,7 +63,7 @@ PP_COMPILE_ASSERT_SIZE_IN_BYTES(PP_UDPSocketFeature_Private, 4);
* @addtogroup Interfaces
* @{
*/
-struct PPB_UDPSocket_Private_0_4 {
+struct PPB_UDPSocket_Private_0_5 {
/**
* Creates a UDP socket resource.
*/
@@ -63,13 +73,13 @@ struct PPB_UDPSocket_Private_0_4 {
*/
PP_Bool (*IsUDPSocket)(PP_Resource resource_id);
/**
- * Sets a socket feature to |udp_socket|. Should be called before
- * Bind(). Possible values for |name|, |value| and |value|'s type
- * are described in PP_UDPSocketFeature_Private description. If no
- * error occurs, returns PP_OK. Otherwise, returns
- * PP_ERROR_BADRESOURCE (if bad |udp_socket| provided),
- * PP_ERROR_BADARGUMENT (if bad name/value/value's type provided)
- * or PP_ERROR_FAILED in the case of internal errors.
+ * Sets a socket feature to |udp_socket|. Possible values for
+ * |name|, |value| and |value|'s type are described in
+ * PP_UDPSocketFeature_Private description. If no error occurs,
+ * returns PP_OK. Otherwise, returns PP_ERROR_BADRESOURCE (if bad
+ * |udp_socket| provided), PP_ERROR_BADARGUMENT (if bad
+ * name/value/value's type provided) or PP_ERROR_FAILED in the case
+ * of internal errors.
*/
int32_t (*SetSocketFeature)(PP_Resource udp_socket,
PP_UDPSocketFeature_Private name,
@@ -79,28 +89,25 @@ struct PPB_UDPSocket_Private_0_4 {
const struct PP_NetAddress_Private* addr,
struct PP_CompletionCallback callback);
/* Returns the address that the socket has bound to. A successful
- * call to Bind must be called first. Returns PP_FALSE if Bind
- * fails, or if Close has been called.
+ * call to Bind() must be called first. Returns PP_FALSE if Bind
+ * fails, or if Close() has been called.
*/
PP_Bool (*GetBoundAddress)(PP_Resource udp_socket,
struct PP_NetAddress_Private* addr);
- /* Performs a non-blocking recvfrom call on socket.
- * Bind must be called first. |callback| is invoked when recvfrom
- * reads data. You must call GetRecvFromAddress to recover the
- * address the data was retrieved from.
+ /* Performs a non-blocking recvfrom call on socket. Bind() must be
+ * called first. |callback| is invoked when recvfrom reads data. It
+ * is possible to call RecvFrom() again on the same socket before
+ * completion of the previous call.
*/
int32_t (*RecvFrom)(PP_Resource udp_socket,
char* buffer,
int32_t num_bytes,
+ struct PP_NetAddress_Private* addr,
struct PP_CompletionCallback callback);
- /* Upon successful completion of RecvFrom, the address that the data
- * was received from is stored in |addr|.
- */
- PP_Bool (*GetRecvFromAddress)(PP_Resource udp_socket,
- struct PP_NetAddress_Private* addr);
/* Performs a non-blocking sendto call on the socket created and
- * bound(has already called Bind). The callback |callback| is
- * invoked when sendto completes.
+ * bound(has already called Bind()). The callback |callback| is
+ * invoked when sendto completes. |buffer| and |addr| don't need to
+ * persist until |callback| is called.
*/
int32_t (*SendTo)(PP_Resource udp_socket,
const char* buffer,
@@ -111,7 +118,7 @@ struct PPB_UDPSocket_Private_0_4 {
void (*Close)(PP_Resource udp_socket);
};
-typedef struct PPB_UDPSocket_Private_0_4 PPB_UDPSocket_Private;
+typedef struct PPB_UDPSocket_Private_0_5 PPB_UDPSocket_Private;
struct PPB_UDPSocket_Private_0_2 {
PP_Resource (*Create)(PP_Instance instance_id);
@@ -154,6 +161,31 @@ struct PPB_UDPSocket_Private_0_3 {
struct PP_CompletionCallback callback);
void (*Close)(PP_Resource udp_socket);
};
+
+struct PPB_UDPSocket_Private_0_4 {
+ PP_Resource (*Create)(PP_Instance instance_id);
+ PP_Bool (*IsUDPSocket)(PP_Resource resource_id);
+ int32_t (*SetSocketFeature)(PP_Resource udp_socket,
+ PP_UDPSocketFeature_Private name,
+ struct PP_Var value);
+ int32_t (*Bind)(PP_Resource udp_socket,
+ const struct PP_NetAddress_Private* addr,
+ struct PP_CompletionCallback callback);
+ PP_Bool (*GetBoundAddress)(PP_Resource udp_socket,
+ struct PP_NetAddress_Private* addr);
+ int32_t (*RecvFrom)(PP_Resource udp_socket,
+ char* buffer,
+ int32_t num_bytes,
+ struct PP_CompletionCallback callback);
+ PP_Bool (*GetRecvFromAddress)(PP_Resource udp_socket,
+ struct PP_NetAddress_Private* addr);
+ int32_t (*SendTo)(PP_Resource udp_socket,
+ const char* buffer,
+ int32_t num_bytes,
+ const struct PP_NetAddress_Private* addr,
+ struct PP_CompletionCallback callback);
+ void (*Close)(PP_Resource udp_socket);
+};
/**
* @}
*/
diff --git a/ppapi/cpp/private/udp_socket_private.cc b/ppapi/cpp/private/udp_socket_private.cc
index c100924..705ffa6 100644
--- a/ppapi/cpp/private/udp_socket_private.cc
+++ b/ppapi/cpp/private/udp_socket_private.cc
@@ -16,6 +16,10 @@ namespace pp {
namespace {
+template <> const char* interface_name<PPB_UDPSocket_Private_0_5>() {
+ return PPB_UDPSOCKET_PRIVATE_INTERFACE_0_5;
+}
+
template <> const char* interface_name<PPB_UDPSocket_Private_0_4>() {
return PPB_UDPSOCKET_PRIVATE_INTERFACE_0_4;
}
@@ -27,7 +31,10 @@ template <> const char* interface_name<PPB_UDPSocket_Private_0_3>() {
} // namespace
UDPSocketPrivate::UDPSocketPrivate(const InstanceHandle& instance) {
- if (has_interface<PPB_UDPSocket_Private_0_4>()) {
+ if (has_interface<PPB_UDPSocket_Private_0_5>()) {
+ PassRefFromConstructor(get_interface<PPB_UDPSocket_Private_0_5>()->Create(
+ instance.pp_instance()));
+ } else if (has_interface<PPB_UDPSocket_Private_0_4>()) {
PassRefFromConstructor(get_interface<PPB_UDPSocket_Private_0_4>()->Create(
instance.pp_instance()));
} else if (has_interface<PPB_UDPSocket_Private_0_3>()) {
@@ -38,12 +45,17 @@ UDPSocketPrivate::UDPSocketPrivate(const InstanceHandle& instance) {
// static
bool UDPSocketPrivate::IsAvailable() {
- return has_interface<PPB_UDPSocket_Private_0_4>() ||
+ return has_interface<PPB_UDPSocket_Private_0_5>() ||
+ has_interface<PPB_UDPSocket_Private_0_4>() ||
has_interface<PPB_UDPSocket_Private_0_3>();
}
int32_t UDPSocketPrivate::SetSocketFeature(PP_UDPSocketFeature_Private name,
const Var& value) {
+ if (has_interface<PPB_UDPSocket_Private_0_5>()) {
+ return get_interface<PPB_UDPSocket_Private_0_5>()->SetSocketFeature(
+ pp_resource(), name, value.pp_var());
+ }
if (has_interface<PPB_UDPSocket_Private_0_4>()) {
return get_interface<PPB_UDPSocket_Private_0_4>()->SetSocketFeature(
pp_resource(), name, value.pp_var());
@@ -53,6 +65,10 @@ int32_t UDPSocketPrivate::SetSocketFeature(PP_UDPSocketFeature_Private name,
int32_t UDPSocketPrivate::Bind(const PP_NetAddress_Private* addr,
const CompletionCallback& callback) {
+ if (has_interface<PPB_UDPSocket_Private_0_5>()) {
+ return get_interface<PPB_UDPSocket_Private_0_5>()->Bind(
+ pp_resource(), addr, callback.pp_completion_callback());
+ }
if (has_interface<PPB_UDPSocket_Private_0_4>()) {
return get_interface<PPB_UDPSocket_Private_0_4>()->Bind(
pp_resource(), addr, callback.pp_completion_callback());
@@ -65,6 +81,12 @@ int32_t UDPSocketPrivate::Bind(const PP_NetAddress_Private* addr,
}
bool UDPSocketPrivate::GetBoundAddress(PP_NetAddress_Private* addr) {
+ if (has_interface<PPB_UDPSocket_Private_0_5>()) {
+ PP_Bool result =
+ get_interface<PPB_UDPSocket_Private_0_5>()->GetBoundAddress(
+ pp_resource(), addr);
+ return PP_ToBool(result);
+ }
if (has_interface<PPB_UDPSocket_Private_0_4>()) {
PP_Bool result =
get_interface<PPB_UDPSocket_Private_0_4>()->GetBoundAddress(
@@ -94,6 +116,18 @@ int32_t UDPSocketPrivate::RecvFrom(char* buffer,
return callback.MayForce(PP_ERROR_NOINTERFACE);
}
+int32_t UDPSocketPrivate::RecvFrom(char* buffer,
+ int32_t num_bytes,
+ PP_NetAddress_Private* addr,
+ const CompletionCallback& callback) {
+ if (has_interface<PPB_UDPSocket_Private_0_5>()) {
+ return get_interface<PPB_UDPSocket_Private_0_5>()->RecvFrom(
+ pp_resource(), buffer, num_bytes, addr,
+ callback.pp_completion_callback());
+ }
+ return callback.MayForce(PP_ERROR_NOINTERFACE);
+}
+
bool UDPSocketPrivate::GetRecvFromAddress(PP_NetAddress_Private* addr) {
if (has_interface<PPB_UDPSocket_Private_0_4>()) {
PP_Bool result =
@@ -114,6 +148,11 @@ int32_t UDPSocketPrivate::SendTo(const char* buffer,
int32_t num_bytes,
const PP_NetAddress_Private* addr,
const CompletionCallback& callback) {
+ if (has_interface<PPB_UDPSocket_Private_0_5>()) {
+ return get_interface<PPB_UDPSocket_Private_0_5>()->SendTo(
+ pp_resource(), buffer, num_bytes, addr,
+ callback.pp_completion_callback());
+ }
if (has_interface<PPB_UDPSocket_Private_0_4>()) {
return get_interface<PPB_UDPSocket_Private_0_4>()->SendTo(
pp_resource(), buffer, num_bytes, addr,
@@ -128,6 +167,8 @@ int32_t UDPSocketPrivate::SendTo(const char* buffer,
}
void UDPSocketPrivate::Close() {
+ if (has_interface<PPB_UDPSocket_Private_0_5>())
+ return get_interface<PPB_UDPSocket_Private_0_5>()->Close(pp_resource());
if (has_interface<PPB_UDPSocket_Private_0_4>())
return get_interface<PPB_UDPSocket_Private_0_4>()->Close(pp_resource());
if (has_interface<PPB_UDPSocket_Private_0_3>())
diff --git a/ppapi/cpp/private/udp_socket_private.h b/ppapi/cpp/private/udp_socket_private.h
index 34e06a9..ffcbf1c 100644
--- a/ppapi/cpp/private/udp_socket_private.h
+++ b/ppapi/cpp/private/udp_socket_private.h
@@ -29,6 +29,10 @@ class UDPSocketPrivate : public Resource {
int32_t RecvFrom(char* buffer,
int32_t num_bytes,
const CompletionCallback& callback);
+ int32_t RecvFrom(char* buffer,
+ int32_t num_bytes,
+ PP_NetAddress_Private* addr,
+ const CompletionCallback& callback);
bool GetRecvFromAddress(PP_NetAddress_Private* addr);
int32_t SendTo(const char* buffer,
int32_t num_bytes,
diff --git a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c
index 758cb52..3d21eb4 100644
--- a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c
+++ b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c
@@ -264,6 +264,7 @@ static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_TCPSocket_Private_0_5;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_UDPSocket_Private_0_2;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_UDPSocket_Private_0_3;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_UDPSocket_Private_0_4;
+static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_UDPSocket_Private_0_5;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_UMA_Private_0_1;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_X509Certificate_Private_0_1;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPP_ContentDecryptor_Private_0_6;
@@ -3617,6 +3618,58 @@ void Pnacl_M23_PPB_UDPSocket_Private_Close(PP_Resource udp_socket) {
/* End wrapper methods for PPB_UDPSocket_Private_0_4 */
+/* Begin wrapper methods for PPB_UDPSocket_Private_0_5 */
+
+static __attribute__((pnaclcall))
+PP_Resource Pnacl_M28_PPB_UDPSocket_Private_Create(PP_Instance instance_id) {
+ const struct PPB_UDPSocket_Private_0_5 *iface = Pnacl_WrapperInfo_PPB_UDPSocket_Private_0_5.real_iface;
+ return iface->Create(instance_id);
+}
+
+static __attribute__((pnaclcall))
+PP_Bool Pnacl_M28_PPB_UDPSocket_Private_IsUDPSocket(PP_Resource resource_id) {
+ const struct PPB_UDPSocket_Private_0_5 *iface = Pnacl_WrapperInfo_PPB_UDPSocket_Private_0_5.real_iface;
+ return iface->IsUDPSocket(resource_id);
+}
+
+static __attribute__((pnaclcall))
+int32_t Pnacl_M28_PPB_UDPSocket_Private_SetSocketFeature(PP_Resource udp_socket, PP_UDPSocketFeature_Private name, struct PP_Var value) {
+ const struct PPB_UDPSocket_Private_0_5 *iface = Pnacl_WrapperInfo_PPB_UDPSocket_Private_0_5.real_iface;
+ return iface->SetSocketFeature(udp_socket, name, value);
+}
+
+static __attribute__((pnaclcall))
+int32_t Pnacl_M28_PPB_UDPSocket_Private_Bind(PP_Resource udp_socket, const struct PP_NetAddress_Private* addr, struct PP_CompletionCallback callback) {
+ const struct PPB_UDPSocket_Private_0_5 *iface = Pnacl_WrapperInfo_PPB_UDPSocket_Private_0_5.real_iface;
+ return iface->Bind(udp_socket, addr, callback);
+}
+
+static __attribute__((pnaclcall))
+PP_Bool Pnacl_M28_PPB_UDPSocket_Private_GetBoundAddress(PP_Resource udp_socket, struct PP_NetAddress_Private* addr) {
+ const struct PPB_UDPSocket_Private_0_5 *iface = Pnacl_WrapperInfo_PPB_UDPSocket_Private_0_5.real_iface;
+ return iface->GetBoundAddress(udp_socket, addr);
+}
+
+static __attribute__((pnaclcall))
+int32_t Pnacl_M28_PPB_UDPSocket_Private_RecvFrom(PP_Resource udp_socket, char* buffer, int32_t num_bytes, struct PP_NetAddress_Private* addr, struct PP_CompletionCallback callback) {
+ const struct PPB_UDPSocket_Private_0_5 *iface = Pnacl_WrapperInfo_PPB_UDPSocket_Private_0_5.real_iface;
+ return iface->RecvFrom(udp_socket, buffer, num_bytes, addr, callback);
+}
+
+static __attribute__((pnaclcall))
+int32_t Pnacl_M28_PPB_UDPSocket_Private_SendTo(PP_Resource udp_socket, const char* buffer, int32_t num_bytes, const struct PP_NetAddress_Private* addr, struct PP_CompletionCallback callback) {
+ const struct PPB_UDPSocket_Private_0_5 *iface = Pnacl_WrapperInfo_PPB_UDPSocket_Private_0_5.real_iface;
+ return iface->SendTo(udp_socket, buffer, num_bytes, addr, callback);
+}
+
+static __attribute__((pnaclcall))
+void Pnacl_M28_PPB_UDPSocket_Private_Close(PP_Resource udp_socket) {
+ const struct PPB_UDPSocket_Private_0_5 *iface = Pnacl_WrapperInfo_PPB_UDPSocket_Private_0_5.real_iface;
+ iface->Close(udp_socket);
+}
+
+/* End wrapper methods for PPB_UDPSocket_Private_0_5 */
+
/* Begin wrapper methods for PPB_UMA_Private_0_1 */
static __attribute__((pnaclcall))
@@ -4621,6 +4674,17 @@ struct PPB_UDPSocket_Private_0_4 Pnacl_Wrappers_PPB_UDPSocket_Private_0_4 = {
.Close = (void (*)(PP_Resource udp_socket))&Pnacl_M23_PPB_UDPSocket_Private_Close
};
+struct PPB_UDPSocket_Private_0_5 Pnacl_Wrappers_PPB_UDPSocket_Private_0_5 = {
+ .Create = (PP_Resource (*)(PP_Instance instance_id))&Pnacl_M28_PPB_UDPSocket_Private_Create,
+ .IsUDPSocket = (PP_Bool (*)(PP_Resource resource_id))&Pnacl_M28_PPB_UDPSocket_Private_IsUDPSocket,
+ .SetSocketFeature = (int32_t (*)(PP_Resource udp_socket, PP_UDPSocketFeature_Private name, struct PP_Var value))&Pnacl_M28_PPB_UDPSocket_Private_SetSocketFeature,
+ .Bind = (int32_t (*)(PP_Resource udp_socket, const struct PP_NetAddress_Private* addr, struct PP_CompletionCallback callback))&Pnacl_M28_PPB_UDPSocket_Private_Bind,
+ .GetBoundAddress = (PP_Bool (*)(PP_Resource udp_socket, struct PP_NetAddress_Private* addr))&Pnacl_M28_PPB_UDPSocket_Private_GetBoundAddress,
+ .RecvFrom = (int32_t (*)(PP_Resource udp_socket, char* buffer, int32_t num_bytes, struct PP_NetAddress_Private* addr, struct PP_CompletionCallback callback))&Pnacl_M28_PPB_UDPSocket_Private_RecvFrom,
+ .SendTo = (int32_t (*)(PP_Resource udp_socket, const char* buffer, int32_t num_bytes, const struct PP_NetAddress_Private* addr, struct PP_CompletionCallback callback))&Pnacl_M28_PPB_UDPSocket_Private_SendTo,
+ .Close = (void (*)(PP_Resource udp_socket))&Pnacl_M28_PPB_UDPSocket_Private_Close
+};
+
struct PPB_UMA_Private_0_1 Pnacl_Wrappers_PPB_UMA_Private_0_1 = {
.HistogramCustomTimes = (void (*)(struct PP_Var name, int64_t sample, int64_t min, int64_t max, uint32_t bucket_count))&Pnacl_M18_PPB_UMA_Private_HistogramCustomTimes,
.HistogramCustomCounts = (void (*)(struct PP_Var name, int32_t sample, int32_t min, int32_t max, uint32_t bucket_count))&Pnacl_M18_PPB_UMA_Private_HistogramCustomCounts,
@@ -5467,6 +5531,12 @@ static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_UDPSocket_Private_0_4 = {
.real_iface = NULL
};
+static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_UDPSocket_Private_0_5 = {
+ .iface_macro = PPB_UDPSOCKET_PRIVATE_INTERFACE_0_5,
+ .wrapped_iface = (void *) &Pnacl_Wrappers_PPB_UDPSocket_Private_0_5,
+ .real_iface = NULL
+};
+
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_UMA_Private_0_1 = {
.iface_macro = PPB_UMA_PRIVATE_INTERFACE_0_1,
.wrapped_iface = (void *) &Pnacl_Wrappers_PPB_UMA_Private_0_1,
@@ -5637,6 +5707,7 @@ static struct __PnaclWrapperInfo *s_ppb_wrappers[] = {
&Pnacl_WrapperInfo_PPB_UDPSocket_Private_0_2,
&Pnacl_WrapperInfo_PPB_UDPSocket_Private_0_3,
&Pnacl_WrapperInfo_PPB_UDPSocket_Private_0_4,
+ &Pnacl_WrapperInfo_PPB_UDPSocket_Private_0_5,
&Pnacl_WrapperInfo_PPB_UMA_Private_0_1,
&Pnacl_WrapperInfo_PPB_X509Certificate_Private_0_1,
&Pnacl_WrapperInfo_PPB_Ext_Alarms_Dev_0_1,
diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h
index eb921d9..8183b3d 100644
--- a/ppapi/proxy/ppapi_messages.h
+++ b/ppapi/proxy/ppapi_messages.h
@@ -1224,6 +1224,9 @@ IPC_MESSAGE_CONTROL0(PpapiHostMsg_UDPSocketPrivate_Create)
IPC_MESSAGE_CONTROL2(PpapiHostMsg_UDPSocketPrivate_SetBoolSocketFeature,
int32_t /* name */,
bool /* value */)
+IPC_MESSAGE_CONTROL2(PpapiHostMsg_UDPSocketPrivate_SetInt32SocketFeature,
+ int32_t /* name */,
+ int32_t /* value */)
IPC_MESSAGE_CONTROL1(PpapiHostMsg_UDPSocketPrivate_Bind,
PP_NetAddress_Private /* net_addr */)
IPC_MESSAGE_CONTROL1(PpapiHostMsg_UDPSocketPrivate_RecvFrom,
diff --git a/ppapi/proxy/udp_socket_private_resource.cc b/ppapi/proxy/udp_socket_private_resource.cc
index 608fc00..9db535c 100644
--- a/ppapi/proxy/udp_socket_private_resource.cc
+++ b/ppapi/proxy/udp_socket_private_resource.cc
@@ -25,8 +25,7 @@ UDPSocketPrivateResource::UDPSocketPrivateResource(Connection connection,
: PluginResource(connection, instance),
bound_(false),
closed_(false),
- read_buffer_(NULL),
- bytes_to_read_(-1) {
+ pending_recvfrom_0_4_(false) {
recvfrom_addr_.size = 0;
memset(recvfrom_addr_.data, 0,
arraysize(recvfrom_addr_.data) * sizeof(*recvfrom_addr_.data));
@@ -48,17 +47,25 @@ UDPSocketPrivateResource::AsPPB_UDPSocket_Private_API() {
int32_t UDPSocketPrivateResource::SetSocketFeature(
PP_UDPSocketFeature_Private name,
PP_Var value) {
- if (bound_ || closed_)
+ if (closed_)
return PP_ERROR_FAILED;
switch (name) {
case PP_UDPSOCKETFEATURE_ADDRESS_REUSE:
case PP_UDPSOCKETFEATURE_BROADCAST:
+ if (bound_)
+ return PP_ERROR_FAILED;
if (value.type != PP_VARTYPE_BOOL)
return PP_ERROR_BADARGUMENT;
SendBoolSocketFeature(static_cast<int32_t>(name),
PP_ToBool(value.value.as_bool));
break;
+ case PP_UDPSOCKETFEATURE_SEND_BUFFER_SIZE:
+ case PP_UDPSOCKETFEATURE_RECV_BUFFER_SIZE:
+ if (value.type != PP_VARTYPE_INT32)
+ return PP_ERROR_BADARGUMENT;
+ SendInt32SocketFeature(static_cast<int32_t>(name), value.value.as_int);
+ break;
default:
return PP_ERROR_BADARGUMENT;
}
@@ -90,24 +97,19 @@ PP_Bool UDPSocketPrivateResource::GetBoundAddress(PP_NetAddress_Private* addr) {
return PP_TRUE;
}
-int32_t UDPSocketPrivateResource::RecvFrom(
+int32_t UDPSocketPrivateResource::RecvFrom_0_4(
char* buffer,
int32_t num_bytes,
scoped_refptr<TrackedCallback> callback) {
- if (!buffer || num_bytes <= 0)
- 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;
+ return RecvFrom(buffer, num_bytes, &recvfrom_addr_, callback, true);
+}
- // Send the request, the browser will call us back via RecvFromReply.
- SendRecvFrom(bytes_to_read_);
- return PP_OK_COMPLETIONPENDING;
+int32_t UDPSocketPrivateResource::RecvFrom_0_5(
+ char* buffer,
+ int32_t num_bytes,
+ PP_NetAddress_Private* addr,
+ scoped_refptr<TrackedCallback> callback) {
+ return RecvFrom(buffer, num_bytes, addr, callback, false);
}
PP_Bool UDPSocketPrivateResource::GetRecvFromAddress(
@@ -118,6 +120,31 @@ PP_Bool UDPSocketPrivateResource::GetRecvFromAddress(
return PP_TRUE;
}
+int32_t UDPSocketPrivateResource::RecvFrom(
+ char* buffer,
+ int32_t num_bytes,
+ PP_NetAddress_Private* addr,
+ scoped_refptr<TrackedCallback> callback,
+ bool recvfrom_0_4) {
+ if (!buffer || num_bytes <= 0)
+ return PP_ERROR_BADARGUMENT;
+ if (!bound_)
+ return PP_ERROR_FAILED;
+ if (recvfrom_0_4 && pending_recvfrom_0_4_)
+ return PP_ERROR_INPROGRESS;
+ if (recvfrom_0_4)
+ pending_recvfrom_0_4_ = true;
+ num_bytes = std::min(num_bytes, kMaxReadSize);
+ recvfrom_requests_.push(RecvFromRequest(callback,
+ buffer,
+ addr,
+ num_bytes,
+ recvfrom_0_4));
+ // Send the request, the browser will call us back via RecvFromReply.
+ SendRecvFrom(num_bytes);
+ return PP_OK_COMPLETIONPENDING;
+}
+
void UDPSocketPrivateResource::PostAbortIfNecessary(
scoped_refptr<TrackedCallback>* callback) {
if (TrackedCallback::IsPending(*callback))
@@ -133,13 +160,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 +181,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) {
@@ -165,6 +197,12 @@ void UDPSocketPrivateResource::SendBoolSocketFeature(int32_t name, bool value) {
Post(BROWSER, msg);
}
+void UDPSocketPrivateResource::SendInt32SocketFeature(int32_t name,
+ int32_t value) {
+ PpapiHostMsg_UDPSocketPrivate_SetInt32SocketFeature msg(name, value);
+ Post(BROWSER, msg);
+}
+
void UDPSocketPrivateResource::SendBind(const PP_NetAddress_Private& addr) {
PpapiHostMsg_UDPSocketPrivate_Bind msg(addr);
Call<PpapiPluginMsg_UDPSocketPrivate_BindReply>(
@@ -215,37 +253,44 @@ void UDPSocketPrivateResource::OnPluginMsgRecvFromReply(
const ResourceMessageReplyParams& params,
const std::string& data,
const PP_NetAddress_Private& addr) {
- if (!TrackedCallback::IsPending(recvfrom_callback_) || !read_buffer_) {
- NOTREACHED();
+ if (recvfrom_requests_.empty())
return;
+ RecvFromRequest request = recvfrom_requests_.front();
+ recvfrom_requests_.pop();
+ if (request.recvfrom_0_4_) {
+ DCHECK(pending_recvfrom_0_4_);
+ pending_recvfrom_0_4_ = false;
}
+ if (!TrackedCallback::IsPending(request.callback))
+ return;
bool succeeded = (params.result() == PP_OK);
- if (succeeded) {
- CHECK_LE(static_cast<int32_t>(data.size()), bytes_to_read_);
- if (!data.empty())
- memcpy(read_buffer_, data.c_str(), data.size());
+ if (succeeded && !data.empty() && request.buffer) {
+ CHECK_LE(static_cast<int32_t>(data.size()), request.num_bytes);
+ memcpy(request.buffer, data.c_str(), data.size());
}
- read_buffer_ = NULL;
- bytes_to_read_ = -1;
- recvfrom_addr_ = addr;
-
+ if (request.addr)
+ *request.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..d84505e 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"
@@ -40,9 +42,15 @@ class PPAPI_PROXY_EXPORT UDPSocketPrivateResource
virtual int32_t Bind(const PP_NetAddress_Private* addr,
scoped_refptr<TrackedCallback> callback) OVERRIDE;
virtual PP_Bool GetBoundAddress(PP_NetAddress_Private* addr) OVERRIDE;
- virtual int32_t RecvFrom(char* buffer,
- int32_t num_bytes,
- scoped_refptr<TrackedCallback> callback) OVERRIDE;
+ virtual int32_t RecvFrom_0_4(
+ char* buffer,
+ int32_t num_bytes,
+ scoped_refptr<TrackedCallback> callback) OVERRIDE;
+ virtual int32_t RecvFrom_0_5(
+ char* buffer,
+ int32_t num_bytes,
+ PP_NetAddress_Private* addr,
+ scoped_refptr<TrackedCallback> callback) OVERRIDE;
virtual PP_Bool GetRecvFromAddress(PP_NetAddress_Private* addr) OVERRIDE;
virtual int32_t SendTo(const char* buffer,
int32_t num_bytes,
@@ -51,9 +59,36 @@ class PPAPI_PROXY_EXPORT UDPSocketPrivateResource
virtual void Close() OVERRIDE;
private:
+ struct RecvFromRequest {
+ RecvFromRequest(scoped_refptr<TrackedCallback> callback,
+ char* buffer,
+ PP_NetAddress_Private* addr,
+ int32_t num_bytes,
+ bool recvfrom_0_4)
+ : callback(callback),
+ buffer(buffer),
+ addr(addr),
+ num_bytes(num_bytes),
+ recvfrom_0_4_(recvfrom_0_4) {
+ }
+
+ scoped_refptr<TrackedCallback> callback;
+ char* buffer;
+ PP_NetAddress_Private* addr;
+ int32_t num_bytes;
+ bool recvfrom_0_4_;
+ };
+
+ int32_t RecvFrom(char* buffer,
+ int32_t num_bytes,
+ PP_NetAddress_Private* addr,
+ scoped_refptr<TrackedCallback> callback,
+ bool recvfrom_0_4);
+
void PostAbortIfNecessary(scoped_refptr<TrackedCallback>* callback);
void SendBoolSocketFeature(int32_t name, bool value);
+ void SendInt32SocketFeature(int32_t name, int32_t value);
void SendBind(const PP_NetAddress_Private& addr);
void SendRecvFrom(int32_t num_bytes);
void SendSendTo(const std::string& buffer,
@@ -73,11 +108,14 @@ 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_;
+ // Queue of RecvFrom requests, used since v0.5.
+ std::queue<RecvFromRequest> recvfrom_requests_;
+
+ // True if RecvFrom() v0.4 is in process.
+ bool pending_recvfrom_0_4_;
+
+ 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 995b53a..b9405ab 100644
--- a/ppapi/tests/test_udp_socket_private.cc
+++ b/ppapi/tests/test_udp_socket_private.cc
@@ -20,6 +20,8 @@ namespace {
const uint16_t kPortScanFrom = 1024;
const uint16_t kPortScanTo = 4096;
+const size_t kEnglishAlphabetSize = 'z' - 'a' + 1;
+
} // namespace
TestUDPSocketPrivate::TestUDPSocketPrivate(
@@ -58,6 +60,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(
@@ -143,13 +147,22 @@ std::string TestUDPSocketPrivate::BindUDPSocketFailure(
PASS();
}
-std::string TestUDPSocketPrivate::ReadSocket(pp::UDPSocketPrivate* socket,
- PP_NetAddress_Private* address,
- size_t size,
- std::string* message) {
+std::string TestUDPSocketPrivate::ReadSocket(
+ pp::UDPSocketPrivate* socket,
+ PP_NetAddress_Private* address,
+ size_t size,
+ std::string* message,
+ PP_NetAddress_Private* recvfrom_address,
+ bool is_queued_recvfrom) {
std::vector<char> buffer(size);
TestCompletionCallback callback(instance_->pp_instance(), force_async_);
- int32_t rv = socket->RecvFrom(&buffer[0], size, callback.GetCallback());
+ int32_t rv = PP_ERROR_FAILED;
+ if (is_queued_recvfrom) {
+ rv = socket->RecvFrom(&buffer[0], size, recvfrom_address,
+ callback.GetCallback());
+ } else {
+ rv = socket->RecvFrom(&buffer[0], size, callback.GetCallback());
+ }
if (force_async_ && rv != PP_OK_COMPLETIONPENDING)
return ReportError("PPB_UDPSocket_Private::RecvFrom force_async", rv);
if (rv == PP_OK_COMPLETIONPENDING)
@@ -157,13 +170,18 @@ std::string TestUDPSocketPrivate::ReadSocket(pp::UDPSocketPrivate* socket,
if (rv < 0 || size != static_cast<size_t>(rv))
return ReportError("PPB_UDPSocket_Private::RecvFrom", rv);
message->assign(buffer.begin(), buffer.end());
+ if (!is_queued_recvfrom && recvfrom_address)
+ ASSERT_TRUE(socket->GetRecvFromAddress(recvfrom_address));
PASS();
}
-std::string TestUDPSocketPrivate::PassMessage(pp::UDPSocketPrivate* target,
- pp::UDPSocketPrivate* source,
- PP_NetAddress_Private* address,
- const std::string& message) {
+std::string TestUDPSocketPrivate::PassMessage(
+ pp::UDPSocketPrivate* target,
+ pp::UDPSocketPrivate* source,
+ PP_NetAddress_Private* address,
+ const std::string& message,
+ PP_NetAddress_Private* recvfrom_address,
+ bool is_queued_recvfrom) {
TestCompletionCallback callback(instance_->pp_instance(), force_async_);
int32_t rv = source->SendTo(message.c_str(), message.size(), address,
callback.GetCallback());
@@ -171,13 +189,13 @@ std::string TestUDPSocketPrivate::PassMessage(pp::UDPSocketPrivate* target,
return ReportError("PPB_UDPSocket_Private::SendTo force_async", rv);
std::string str;
- ASSERT_SUBTEST_SUCCESS(ReadSocket(target, address, message.size(), &str));
-
+ ASSERT_SUBTEST_SUCCESS(ReadSocket(target, address, message.size(),
+ &str, recvfrom_address,
+ is_queued_recvfrom));
if (rv == PP_OK_COMPLETIONPENDING)
rv = callback.WaitForResult();
if (rv < 0 || message.size() != static_cast<size_t>(rv))
return ReportError("PPB_UDPSocket_Private::SendTo", rv);
-
ASSERT_EQ(message, str);
PASS();
}
@@ -191,14 +209,14 @@ std::string TestUDPSocketPrivate::TestConnect() {
ASSERT_SUBTEST_SUCCESS(LookupPortAndBindUDPSocket(&client_socket,
&client_address));
const std::string message = "Simple message that will be sent via UDP";
+ PP_NetAddress_Private recv_from_address;
ASSERT_SUBTEST_SUCCESS(PassMessage(&server_socket, &client_socket,
&server_address,
- message));
- PP_NetAddress_Private recv_from_address;
- ASSERT_TRUE(server_socket.GetRecvFromAddress(&recv_from_address));
+ message,
+ &recv_from_address,
+ true));
ASSERT_TRUE(pp::NetAddressPrivate::AreEqual(recv_from_address,
client_address));
-
server_socket.Close();
client_socket.Close();
@@ -243,18 +261,20 @@ std::string TestUDPSocketPrivate::TestBroadcast() {
ASSERT_SUBTEST_SUCCESS(PassMessage(&server1, &server2,
&broadcast_address,
- first_message));
+ first_message, NULL, true));
// |first_message| also arrived to |server2|.
ASSERT_SUBTEST_SUCCESS(ReadSocket(&server2, &broadcast_address,
- first_message.size(), &message));
+ first_message.size(), &message, NULL,
+ true));
ASSERT_EQ(first_message, message);
ASSERT_SUBTEST_SUCCESS(PassMessage(&server2, &server1,
&broadcast_address,
- second_message));
+ second_message, NULL, true));
// |second_message| also arrived to |server1|.
ASSERT_SUBTEST_SUCCESS(ReadSocket(&server1, &broadcast_address,
- second_message.size(), &message));
+ second_message.size(), &message, NULL,
+ true));
ASSERT_EQ(second_message, message);
server1.Close();
@@ -274,3 +294,117 @@ std::string TestUDPSocketPrivate::TestSetSocketFeatureErrors() {
ASSERT_EQ(PP_ERROR_BADARGUMENT, rv);
PASS();
}
+
+std::string TestUDPSocketPrivate::TestQueuedRequests() {
+ const size_t kMessageSize = 256;
+ const size_t kNumMessages = 256;
+ const int32_t kSocketBufferSize =
+ static_cast<int32_t>(4 * kMessageSize * kNumMessages);
+
+ pp::UDPSocketPrivate server_socket(instance_), client_socket(instance_);
+ PP_NetAddress_Private server_address, client_address;
+
+ server_socket.SetSocketFeature(PP_UDPSOCKETFEATURE_RECV_BUFFER_SIZE,
+ pp::Var(kSocketBufferSize));
+ client_socket.SetSocketFeature(PP_UDPSOCKETFEATURE_SEND_BUFFER_SIZE,
+ pp::Var(kSocketBufferSize));
+ ASSERT_SUBTEST_SUCCESS(LookupPortAndBindUDPSocket(&server_socket,
+ &server_address));
+ ASSERT_SUBTEST_SUCCESS(LookupPortAndBindUDPSocket(&client_socket,
+ &client_address));
+
+ std::vector<std::string> messages(kNumMessages);
+ for (size_t i = 0; i < kNumMessages; ++i)
+ messages[i].resize(kMessageSize, 'a' + i % kEnglishAlphabetSize);
+
+ std::vector<TestCompletionCallback*> sendto_callbacks(kNumMessages);
+ std::vector<int32_t> sendto_rv(kNumMessages);
+
+ std::vector<std::vector<char> > buffers(kNumMessages);
+ std::vector<TestCompletionCallback*> recvfrom_callbacks(kNumMessages);
+ std::vector<int32_t> recvfrom_rv(kNumMessages);
+
+ for (size_t i = 0; i < kNumMessages; ++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 < kNumMessages; ++i) {
+ buffers[i].resize(messages[i].size());
+ recvfrom_rv[i] = server_socket.RecvFrom(
+ &buffers[i][0],
+ static_cast<int32_t>(messages[i].size()),
+ NULL,
+ recvfrom_callbacks[i]->GetCallback());
+ if (force_async_ && recvfrom_rv[i] != PP_OK_COMPLETIONPENDING) {
+ return ReportError("PPB_UDPSocket_Private::RecvFrom force_async",
+ recvfrom_rv[i]);
+ }
+ }
+
+ for (size_t i = 0; i < kNumMessages; ++i) {
+ sendto_rv[i] = client_socket.SendTo(messages[i].c_str(),
+ messages[i].size(),
+ &server_address,
+ sendto_callbacks[i]->GetCallback());
+ if (force_async_ && sendto_rv[i] != PP_OK_COMPLETIONPENDING) {
+ return ReportError("PPB_UDPSocket_Private::SendTo force_async",
+ sendto_rv[i]);
+ }
+ }
+
+ for (size_t i = 0; i < kNumMessages; ++i) {
+ if (recvfrom_rv[i] == PP_OK_COMPLETIONPENDING)
+ recvfrom_rv[i] = recvfrom_callbacks[i]->WaitForResult();
+ if (recvfrom_rv[i] < 0 ||
+ messages[i].size() != static_cast<size_t>(recvfrom_rv[i])) {
+ return ReportError("PPB_UDPSocket_Private::RecvFrom", recvfrom_rv[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 < kNumMessages; ++i) {
+ delete sendto_callbacks[i];
+ delete recvfrom_callbacks[i];
+ }
+
+ server_socket.Close();
+ client_socket.Close();
+ PASS();
+}
+
+std::string TestUDPSocketPrivate::TestSequentialRequests() {
+ const size_t kMessageSize = 256;
+ const size_t kNumMessages = 256;
+
+ 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(kNumMessages);
+ for (size_t i = 0; i < kNumMessages; ++i)
+ messages[i].resize(kMessageSize, 'a' + i % kEnglishAlphabetSize);
+
+ for (size_t i = 0; i < kNumMessages; ++i) {
+ ASSERT_SUBTEST_SUCCESS(PassMessage(&server_socket,
+ &client_socket,
+ &server_address,
+ messages[i], NULL, false));
+ }
+
+ server_socket.Close();
+ client_socket.Close();
+ PASS();
+}
diff --git a/ppapi/tests/test_udp_socket_private.h b/ppapi/tests/test_udp_socket_private.h
index e4a23c9..5537533 100644
--- a/ppapi/tests/test_udp_socket_private.h
+++ b/ppapi/tests/test_udp_socket_private.h
@@ -31,16 +31,22 @@ class TestUDPSocketPrivate : public TestCase {
std::string ReadSocket(pp::UDPSocketPrivate* socket,
PP_NetAddress_Private* address,
size_t size,
- std::string* message);
+ std::string* message,
+ PP_NetAddress_Private* recvfrom_address,
+ bool is_queued_recvfrom);
std::string PassMessage(pp::UDPSocketPrivate* target,
pp::UDPSocketPrivate* source,
PP_NetAddress_Private* address,
- const std::string& message);
+ const std::string& message,
+ PP_NetAddress_Private* recvfrom_address,
+ bool is_queued_recvfrom);
std::string TestConnect();
std::string TestConnectFailure();
std::string TestBroadcast();
std::string TestSetSocketFeatureErrors();
+ std::string TestQueuedRequests();
+ std::string TestSequentialRequests();
std::string host_;
uint16_t port_;
diff --git a/ppapi/thunk/interfaces_ppb_private_no_permissions.h b/ppapi/thunk/interfaces_ppb_private_no_permissions.h
index 059f603..662840e 100644
--- a/ppapi/thunk/interfaces_ppb_private_no_permissions.h
+++ b/ppapi/thunk/interfaces_ppb_private_no_permissions.h
@@ -31,6 +31,8 @@ PROXIED_IFACE(NoAPIName, PPB_UDPSOCKET_PRIVATE_INTERFACE_0_3,
PPB_UDPSocket_Private_0_3)
PROXIED_IFACE(NoAPIName, PPB_UDPSOCKET_PRIVATE_INTERFACE_0_4,
PPB_UDPSocket_Private_0_4)
+PROXIED_IFACE(NoAPIName, PPB_UDPSOCKET_PRIVATE_INTERFACE_0_5,
+ PPB_UDPSocket_Private_0_5)
PROXIED_IFACE(NoAPIName, PPB_NETADDRESS_PRIVATE_INTERFACE_0_1,
PPB_NetAddress_Private_0_1)
diff --git a/ppapi/thunk/ppb_udp_socket_private_api.h b/ppapi/thunk/ppb_udp_socket_private_api.h
index 9c403a0..bc012dd 100644
--- a/ppapi/thunk/ppb_udp_socket_private_api.h
+++ b/ppapi/thunk/ppb_udp_socket_private_api.h
@@ -24,9 +24,13 @@ class PPAPI_THUNK_EXPORT PPB_UDPSocket_Private_API {
virtual int32_t Bind(const PP_NetAddress_Private* addr,
scoped_refptr<TrackedCallback> callback) = 0;
virtual PP_Bool GetBoundAddress(PP_NetAddress_Private* addr) = 0;
- virtual int32_t RecvFrom(char* buffer,
- int32_t num_bytes,
- scoped_refptr<TrackedCallback> callback) = 0;
+ virtual int32_t RecvFrom_0_4(char* buffer,
+ int32_t num_bytes,
+ scoped_refptr<TrackedCallback> callback) = 0;
+ virtual int32_t RecvFrom_0_5(char* buffer,
+ int32_t num_bytes,
+ PP_NetAddress_Private* addr,
+ scoped_refptr<TrackedCallback> callback) = 0;
virtual PP_Bool GetRecvFromAddress(PP_NetAddress_Private* addr) = 0;
virtual int32_t SendTo(const char* buffer,
int32_t num_bytes,
diff --git a/ppapi/thunk/ppb_udp_socket_private_thunk.cc b/ppapi/thunk/ppb_udp_socket_private_thunk.cc
index a493666..0b98e01 100644
--- a/ppapi/thunk/ppb_udp_socket_private_thunk.cc
+++ b/ppapi/thunk/ppb_udp_socket_private_thunk.cc
@@ -30,15 +30,25 @@ PP_Bool IsUDPSocket(PP_Resource resource) {
return PP_FromBool(enter.succeeded());
}
-int32_t SetSocketFeature(PP_Resource udp_socket,
- PP_UDPSocketFeature_Private name,
- PP_Var value) {
+int32_t SetSocketFeature_0_5(PP_Resource udp_socket,
+ PP_UDPSocketFeature_Private name,
+ PP_Var value) {
EnterUDP enter(udp_socket, true);
if (enter.failed())
return PP_ERROR_BADRESOURCE;
return enter.object()->SetSocketFeature(name, value);
}
+int32_t SetSocketFeature_0_4(PP_Resource udp_socket,
+ PP_UDPSocketFeature_Private name,
+ PP_Var value) {
+ if (name != PP_UDPSOCKETFEATURE_ADDRESS_REUSE &&
+ name != PP_UDPSOCKETFEATURE_BROADCAST) {
+ return PP_ERROR_BADARGUMENT;
+ }
+ return SetSocketFeature_0_5(udp_socket, name, value);
+}
+
int32_t Bind(PP_Resource udp_socket,
const PP_NetAddress_Private *addr,
PP_CompletionCallback callback) {
@@ -56,10 +66,26 @@ PP_Bool GetBoundAddress(PP_Resource udp_socket,
return enter.object()->GetBoundAddress(addr);
}
-int32_t RecvFrom(PP_Resource udp_socket,
- char* buffer,
- int32_t num_bytes,
- PP_CompletionCallback callback) {
+int32_t RecvFrom_0_4(PP_Resource udp_socket,
+ char* buffer,
+ int32_t num_bytes,
+ PP_CompletionCallback callback) {
+#ifdef NDEBUG
+ EnterUDP enter(udp_socket, callback, false);
+#else
+ EnterUDP enter(udp_socket, callback, true);
+#endif
+ if (enter.failed())
+ return enter.retval();
+ return enter.SetResult(enter.object()->RecvFrom_0_4(buffer, num_bytes,
+ enter.callback()));
+}
+
+int32_t RecvFrom_0_5(PP_Resource udp_socket,
+ char* buffer,
+ int32_t num_bytes,
+ PP_NetAddress_Private* addr,
+ PP_CompletionCallback callback) {
#ifdef NDEBUG
EnterUDP enter(udp_socket, callback, false);
#else
@@ -67,8 +93,8 @@ int32_t RecvFrom(PP_Resource udp_socket,
#endif
if (enter.failed())
return enter.retval();
- return enter.SetResult(enter.object()->RecvFrom(buffer, num_bytes,
- enter.callback()));
+ return enter.SetResult(enter.object()->RecvFrom_0_5(buffer, num_bytes, addr,
+ enter.callback()));
}
PP_Bool GetRecvFromAddress(PP_Resource udp_socket,
@@ -101,7 +127,7 @@ const PPB_UDPSocket_Private_0_2 g_ppb_udp_socket_thunk_0_2 = {
&Create,
&IsUDPSocket,
&Bind,
- &RecvFrom,
+ &RecvFrom_0_4,
&GetRecvFromAddress,
&SendTo,
&Close
@@ -112,7 +138,7 @@ const PPB_UDPSocket_Private_0_3 g_ppb_udp_socket_thunk_0_3 = {
&IsUDPSocket,
&Bind,
&GetBoundAddress,
- &RecvFrom,
+ &RecvFrom_0_4,
&GetRecvFromAddress,
&SendTo,
&Close
@@ -121,15 +147,26 @@ const PPB_UDPSocket_Private_0_3 g_ppb_udp_socket_thunk_0_3 = {
const PPB_UDPSocket_Private_0_4 g_ppb_udp_socket_thunk_0_4 = {
&Create,
&IsUDPSocket,
- &SetSocketFeature,
+ &SetSocketFeature_0_4,
&Bind,
&GetBoundAddress,
- &RecvFrom,
+ &RecvFrom_0_4,
&GetRecvFromAddress,
&SendTo,
&Close
};
+const PPB_UDPSocket_Private_0_5 g_ppb_udp_socket_thunk_0_5 = {
+ &Create,
+ &IsUDPSocket,
+ &SetSocketFeature_0_5,
+ &Bind,
+ &GetBoundAddress,
+ &RecvFrom_0_5,
+ &SendTo,
+ &Close
+};
+
} // namespace
const PPB_UDPSocket_Private_0_2* GetPPB_UDPSocket_Private_0_2_Thunk() {
@@ -144,5 +181,9 @@ const PPB_UDPSocket_Private_0_4* GetPPB_UDPSocket_Private_0_4_Thunk() {
return &g_ppb_udp_socket_thunk_0_4;
}
+const PPB_UDPSocket_Private_0_5* GetPPB_UDPSocket_Private_0_5_Thunk() {
+ return &g_ppb_udp_socket_thunk_0_5;
+}
+
} // namespace thunk
} // namespace ppapi