diff options
-rw-r--r-- | chrome/test/ppapi/ppapi_browsertest.cc | 4 | ||||
-rw-r--r-- | content/browser/renderer_host/pepper/pepper_udp_socket_private_message_filter.cc | 179 | ||||
-rw-r--r-- | content/browser/renderer_host/pepper/pepper_udp_socket_private_message_filter.h | 50 | ||||
-rw-r--r-- | ppapi/api/private/ppb_udp_socket_private.idl | 74 | ||||
-rw-r--r-- | ppapi/c/pp_macros.h | 4 | ||||
-rw-r--r-- | ppapi/c/private/ppb_udp_socket_private.h | 88 | ||||
-rw-r--r-- | ppapi/cpp/private/udp_socket_private.cc | 45 | ||||
-rw-r--r-- | ppapi/cpp/private/udp_socket_private.h | 4 | ||||
-rw-r--r-- | ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c | 71 | ||||
-rw-r--r-- | ppapi/proxy/ppapi_messages.h | 3 | ||||
-rw-r--r-- | ppapi/proxy/udp_socket_private_resource.cc | 119 | ||||
-rw-r--r-- | ppapi/proxy/udp_socket_private_resource.h | 52 | ||||
-rw-r--r-- | ppapi/tests/test_udp_socket_private.cc | 174 | ||||
-rw-r--r-- | ppapi/tests/test_udp_socket_private.h | 10 | ||||
-rw-r--r-- | ppapi/thunk/interfaces_ppb_private_no_permissions.h | 2 | ||||
-rw-r--r-- | ppapi/thunk/ppb_udp_socket_private_api.h | 10 | ||||
-rw-r--r-- | ppapi/thunk/ppb_udp_socket_private_thunk.cc | 67 |
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 |