Index: ppapi/proxy/udp_socket_resource_base.cc |
diff --git a/ppapi/proxy/udp_socket_resource_base.cc b/ppapi/proxy/udp_socket_resource_base.cc |
index e61e16be3675e69f0500a4b8da4828115d67a698..ed231f8f6b3fd6f840d66c86edbbd97aeb949ebc 100644 |
--- a/ppapi/proxy/udp_socket_resource_base.cc |
+++ b/ppapi/proxy/udp_socket_resource_base.cc |
@@ -4,32 +4,40 @@ |
#include "ppapi/proxy/udp_socket_resource_base.h" |
-#include <algorithm> |
#include <cstring> |
#include "base/logging.h" |
#include "ppapi/c/pp_bool.h" |
-#include "ppapi/c/pp_completion_callback.h" |
#include "ppapi/c/pp_errors.h" |
#include "ppapi/proxy/error_conversion.h" |
#include "ppapi/proxy/plugin_globals.h" |
#include "ppapi/proxy/ppapi_messages.h" |
#include "ppapi/shared_impl/socket_option_data.h" |
#include "ppapi/thunk/enter.h" |
-#include "ppapi/thunk/resource_creation_api.h" |
namespace ppapi { |
namespace proxy { |
-const int32_t UDPSocketResourceBase::kMaxReadSize = 128 * 1024; |
const int32_t UDPSocketResourceBase::kMaxWriteSize = 128 * 1024; |
const int32_t UDPSocketResourceBase::kMaxSendBufferSize = |
1024 * UDPSocketResourceBase::kMaxWriteSize; |
-const int32_t UDPSocketResourceBase::kMaxReceiveBufferSize = |
- 1024 * UDPSocketResourceBase::kMaxReadSize; |
-const size_t UDPSocketResourceBase::kPluginReceiveBufferSlots = 32u; |
const size_t UDPSocketResourceBase::kPluginSendBufferSlots = 8u; |
+namespace { |
+ |
+void RunCallback(scoped_refptr<TrackedCallback> callback, |
+ int32_t pp_result, |
+ bool private_api) { |
+ callback->Run(ConvertNetworkAPIErrorForCompatibility(pp_result, private_api)); |
+} |
+ |
+void PostAbortIfNecessary(const scoped_refptr<TrackedCallback>& callback) { |
+ if (TrackedCallback::IsPending(callback)) |
+ callback->PostAbort(); |
+} |
+ |
+} // namespace |
+ |
UDPSocketResourceBase::UDPSocketResourceBase(Connection connection, |
PP_Instance instance, |
bool private_api) |
@@ -38,26 +46,19 @@ UDPSocketResourceBase::UDPSocketResourceBase(Connection connection, |
bind_called_(false), |
bound_(false), |
closed_(false), |
- read_buffer_(NULL), |
- bytes_to_read_(-1), |
- recvfrom_addr_resource_(NULL) { |
- recvfrom_addr_.size = 0; |
- memset(recvfrom_addr_.data, 0, |
- arraysize(recvfrom_addr_.data) * sizeof(*recvfrom_addr_.data)); |
- bound_addr_.size = 0; |
- memset(bound_addr_.data, 0, |
- arraysize(bound_addr_.data) * sizeof(*bound_addr_.data)); |
- |
+ recv_filter_(PluginGlobals::Get()->udp_socket_filter()), |
+ bound_addr_() { |
+ recv_filter_->AddUDPResource( |
+ pp_instance(), pp_resource(), private_api, |
+ base::Bind(&UDPSocketResourceBase::SlotBecameAvailable, pp_resource())); |
if (private_api) |
SendCreate(BROWSER, PpapiHostMsg_UDPSocket_CreatePrivate()); |
else |
SendCreate(BROWSER, PpapiHostMsg_UDPSocket_Create()); |
- |
- PluginGlobals::Get()->resource_reply_thread_registrar()->HandleOnIOThread( |
- PpapiPluginMsg_UDPSocket_PushRecvResult::ID); |
} |
UDPSocketResourceBase::~UDPSocketResourceBase() { |
+ CloseImpl(); |
} |
int32_t UDPSocketResourceBase::SetOptionImpl( |
@@ -165,45 +166,21 @@ PP_Bool UDPSocketResourceBase::GetBoundAddressImpl( |
} |
int32_t UDPSocketResourceBase::RecvFromImpl( |
- char* buffer, |
+ char* buffer_out, |
int32_t num_bytes, |
PP_Resource* addr, |
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; |
- |
- if (recv_buffers_.empty()) { |
- read_buffer_ = buffer; |
- bytes_to_read_ = std::min(num_bytes, kMaxReadSize); |
- recvfrom_addr_resource_ = addr; |
- recvfrom_callback_ = callback; |
- |
- return PP_OK_COMPLETIONPENDING; |
- } else { |
- RecvBuffer& front = recv_buffers_.front(); |
- |
- if (num_bytes < static_cast<int32_t>(front.data.size())) |
- return PP_ERROR_MESSAGE_TOO_BIG; |
- |
- int32_t result = SetRecvFromOutput(front.result, front.data, front.addr, |
- buffer, num_bytes, addr); |
- |
- recv_buffers_.pop(); |
- Post(BROWSER, PpapiHostMsg_UDPSocket_RecvSlotAvailable()); |
- |
- return result; |
- } |
+ return recv_filter_->RequestData(pp_resource(), num_bytes, buffer_out, addr, |
+ callback); |
} |
PP_Bool UDPSocketResourceBase::GetRecvFromAddressImpl( |
PP_NetAddress_Private* addr) { |
if (!addr) |
return PP_FALSE; |
- *addr = recvfrom_addr_; |
+ *addr = recv_filter_->GetLastAddrPrivate(pp_resource()); |
return PP_TRUE; |
} |
@@ -243,16 +220,13 @@ void UDPSocketResourceBase::CloseImpl() { |
Post(BROWSER, PpapiHostMsg_UDPSocket_Close()); |
- PostAbortIfNecessary(&bind_callback_); |
- PostAbortIfNecessary(&recvfrom_callback_); |
+ PostAbortIfNecessary(bind_callback_); |
while (!sendto_callbacks_.empty()) { |
scoped_refptr<TrackedCallback> callback = sendto_callbacks_.front(); |
sendto_callbacks_.pop(); |
- PostAbortIfNecessary(&callback); |
+ PostAbortIfNecessary(callback); |
} |
- |
- read_buffer_ = NULL; |
- bytes_to_read_ = -1; |
+ recv_filter_->RemoveUDPResource(pp_resource()); |
} |
int32_t UDPSocketResourceBase::JoinGroupImpl( |
@@ -285,29 +259,11 @@ int32_t UDPSocketResourceBase::LeaveGroupImpl( |
return PP_OK_COMPLETIONPENDING; |
} |
-void UDPSocketResourceBase::OnReplyReceived( |
- const ResourceMessageReplyParams& params, |
- const IPC::Message& msg) { |
- PPAPI_BEGIN_MESSAGE_MAP(UDPSocketResourceBase, msg) |
- PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL( |
- PpapiPluginMsg_UDPSocket_PushRecvResult, |
- OnPluginMsgPushRecvResult) |
- PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL_UNHANDLED( |
- PluginResource::OnReplyReceived(params, msg)) |
- PPAPI_END_MESSAGE_MAP() |
-} |
- |
-void UDPSocketResourceBase::PostAbortIfNecessary( |
- scoped_refptr<TrackedCallback>* callback) { |
- if (TrackedCallback::IsPending(*callback)) |
- (*callback)->PostAbort(); |
-} |
- |
void UDPSocketResourceBase::OnPluginMsgGeneralReply( |
scoped_refptr<TrackedCallback> callback, |
const ResourceMessageReplyParams& params) { |
if (TrackedCallback::IsPending(callback)) |
- RunCallback(callback, params.result()); |
+ RunCallback(callback, params.result(), private_api_); |
} |
void UDPSocketResourceBase::OnPluginMsgBindReply( |
@@ -323,50 +279,7 @@ void UDPSocketResourceBase::OnPluginMsgBindReply( |
if (params.result() == PP_OK) |
bound_ = true; |
bound_addr_ = bound_addr; |
- RunCallback(bind_callback_, params.result()); |
-} |
- |
-void UDPSocketResourceBase::OnPluginMsgPushRecvResult( |
- const ResourceMessageReplyParams& params, |
- int32_t result, |
- const std::string& data, |
- const PP_NetAddress_Private& addr) { |
- // TODO(yzshen): Support passing in a non-const string ref, so that we can |
- // eliminate one copy when storing the data in the buffer. |
- |
- DCHECK_LT(recv_buffers_.size(), kPluginReceiveBufferSlots); |
- |
- if (!TrackedCallback::IsPending(recvfrom_callback_) || !read_buffer_) { |
- recv_buffers_.push(RecvBuffer()); |
- RecvBuffer& back = recv_buffers_.back(); |
- back.result = result; |
- back.data = data; |
- back.addr = addr; |
- |
- return; |
- } |
- |
- DCHECK_EQ(recv_buffers_.size(), 0u); |
- |
- if (bytes_to_read_ < static_cast<int32_t>(data.size())) { |
- recv_buffers_.push(RecvBuffer()); |
- RecvBuffer& back = recv_buffers_.back(); |
- back.result = result; |
- back.data = data; |
- back.addr = addr; |
- |
- result = PP_ERROR_MESSAGE_TOO_BIG; |
- } else { |
- result = SetRecvFromOutput(result, data, addr, read_buffer_, bytes_to_read_, |
- recvfrom_addr_resource_); |
- Post(BROWSER, PpapiHostMsg_UDPSocket_RecvSlotAvailable()); |
- } |
- |
- read_buffer_ = NULL; |
- bytes_to_read_ = -1; |
- recvfrom_addr_resource_ = NULL; |
- |
- RunCallback(recvfrom_callback_, result); |
+ RunCallback(bind_callback_, params.result(), private_api_); |
} |
void UDPSocketResourceBase::OnPluginMsgSendToReply( |
@@ -383,43 +296,21 @@ void UDPSocketResourceBase::OnPluginMsgSendToReply( |
return; |
if (params.result() == PP_OK) |
- RunCallback(callback, bytes_written); |
+ RunCallback(callback, bytes_written, private_api_); |
else |
- RunCallback(callback, params.result()); |
+ RunCallback(callback, params.result(), private_api_); |
} |
-void UDPSocketResourceBase::RunCallback(scoped_refptr<TrackedCallback> callback, |
- int32_t pp_result) { |
- callback->Run(ConvertNetworkAPIErrorForCompatibility(pp_result, |
- private_api_)); |
-} |
- |
-int32_t UDPSocketResourceBase::SetRecvFromOutput( |
- int32_t browser_result, |
- const std::string& data, |
- const PP_NetAddress_Private& addr, |
- char* output_buffer, |
- int32_t num_bytes, |
- PP_Resource* output_addr) { |
- DCHECK_GE(num_bytes, static_cast<int32_t>(data.size())); |
- |
- int32_t result = browser_result; |
- if (result == PP_OK && output_addr) { |
- thunk::EnterResourceCreationNoLock enter(pp_instance()); |
- if (enter.succeeded()) { |
- *output_addr = enter.functions()->CreateNetAddressFromNetAddressPrivate( |
- pp_instance(), addr); |
- } else { |
- result = PP_ERROR_FAILED; |
- } |
- } |
- |
- if (result == PP_OK && !data.empty()) |
- memcpy(output_buffer, data.c_str(), data.size()); |
- |
- recvfrom_addr_ = addr; |
+// static |
+void UDPSocketResourceBase::SlotBecameAvailable(PP_Resource resource) { |
+ ProxyLock::AssertAcquired(); |
+ thunk::EnterResourceNoLock<thunk::PPB_UDPSocket_API> enter(resource, false); |
+ if (enter.failed()) |
+ return; |
+ auto thiz(static_cast<UDPSocketResourceBase*>(enter.resource())); |
- return result == PP_OK ? static_cast<int32_t>(data.size()) : result; |
+ if (!thiz->closed_) |
+ thiz->Post(BROWSER, PpapiHostMsg_UDPSocket_RecvSlotAvailable()); |
} |
} // namespace proxy |