Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(161)

Unified Diff: ppapi/proxy/handle_converter.cc

Issue 11894003: PPAPI/NaCl: Move handle extraction code to ppapi/proxy (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merge Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ppapi/proxy/handle_converter.h ('k') | ppapi/proxy/ppapi_messages.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ppapi/proxy/handle_converter.cc
diff --git a/chrome/nacl/nacl_ipc_adapter.cc b/ppapi/proxy/handle_converter.cc
similarity index 23%
copy from chrome/nacl/nacl_ipc_adapter.cc
copy to ppapi/proxy/handle_converter.cc
index a50c714891433fea6708a20704dffa0b1d015d04..a6690628bbee4d590b9f6a044bd6d28f5a96b3f5 100644
--- a/chrome/nacl/nacl_ipc_adapter.cc
+++ b/ppapi/proxy/handle_converter.cc
@@ -1,98 +1,21 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/nacl/nacl_ipc_adapter.h"
+#include "ppapi/proxy/handle_converter.h"
-#include <limits.h>
-#include <string.h>
-
-#include "base/basictypes.h"
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/shared_memory.h"
-#include "build/build_config.h"
-#include "ipc/ipc_channel.h"
+#include "ipc/ipc_message.h"
#include "ipc/ipc_message_macros.h"
-#include "ipc/ipc_platform_file.h"
-#include "native_client/src/trusted/desc/nacl_desc_custom.h"
-#include "native_client/src/trusted/desc/nacl_desc_wrapper.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/resource_message_params.h"
+#include "ppapi/proxy/serialized_handle.h"
-namespace {
-
-enum BufferSizeStatus {
- // The buffer contains a full message with no extra bytes.
- MESSAGE_IS_COMPLETE,
-
- // The message doesn't fit and the buffer contains only some of it.
- MESSAGE_IS_TRUNCATED,
-
- // The buffer contains a full message + extra data.
- MESSAGE_HAS_EXTRA_DATA
-};
-
-BufferSizeStatus GetBufferStatus(const char* data, size_t len) {
- if (len < sizeof(NaClIPCAdapter::NaClMessageHeader))
- return MESSAGE_IS_TRUNCATED;
-
- const NaClIPCAdapter::NaClMessageHeader* header =
- reinterpret_cast<const NaClIPCAdapter::NaClMessageHeader*>(data);
- uint32 message_size =
- sizeof(NaClIPCAdapter::NaClMessageHeader) + header->payload_size;
-
- if (len == message_size)
- return MESSAGE_IS_COMPLETE;
- if (len > message_size)
- return MESSAGE_HAS_EXTRA_DATA;
- return MESSAGE_IS_TRUNCATED;
-}
-
-// This object allows the NaClDesc to hold a reference to a NaClIPCAdapter and
-// forward calls to it.
-struct DescThunker {
- explicit DescThunker(NaClIPCAdapter* adapter_param)
- : adapter(adapter_param) {
- }
- scoped_refptr<NaClIPCAdapter> adapter;
-};
-
-NaClIPCAdapter* ToAdapter(void* handle) {
- return static_cast<DescThunker*>(handle)->adapter.get();
-}
-
-// NaClDescCustom implementation.
-void NaClDescCustomDestroy(void* handle) {
- delete static_cast<DescThunker*>(handle);
-}
-
-ssize_t NaClDescCustomSendMsg(void* handle, const NaClImcTypedMsgHdr* msg,
- int /* flags */) {
- return static_cast<ssize_t>(ToAdapter(handle)->Send(msg));
-}
-
-ssize_t NaClDescCustomRecvMsg(void* handle, NaClImcTypedMsgHdr* msg,
- int /* flags */) {
- return static_cast<ssize_t>(ToAdapter(handle)->BlockingReceive(msg));
-}
-
-NaClDesc* MakeNaClDescCustom(NaClIPCAdapter* adapter) {
- NaClDescCustomFuncs funcs = NACL_DESC_CUSTOM_FUNCS_INITIALIZER;
- funcs.Destroy = NaClDescCustomDestroy;
- funcs.SendMsg = NaClDescCustomSendMsg;
- funcs.RecvMsg = NaClDescCustomRecvMsg;
- // NaClDescMakeCustomDesc gives us a reference on the returned NaClDesc.
- return NaClDescMakeCustomDesc(new DescThunker(adapter), &funcs);
+namespace IPC {
+class Message;
}
-void DeleteChannel(IPC::Channel* channel) {
- delete channel;
-}
+namespace {
-// TODO(dmichael): Move all this handle conversion code to ppapi/proxy.
-// crbug.com/165201
void WriteHandle(int handle_index,
const ppapi::proxy::SerializedHandle& handle,
IPC::Message* message) {
@@ -196,9 +119,9 @@ void ConvertHandlesImpl(const Tuple4<A, B, C, D>& t1, Handles* handles,
}
template <class MessageType>
-class HandleConverter {
+class HandleConverterImpl {
public:
- explicit HandleConverter(const IPC::Message* msg)
+ explicit HandleConverterImpl(const IPC::Message* msg)
: msg_(static_cast<const MessageType*>(msg)) {
}
bool ConvertMessage(Handles* handles, IPC::Message* out_msg) {
@@ -233,499 +156,103 @@ class HandleConverter {
} // namespace
-class NaClIPCAdapter::RewrittenMessage
- : public base::RefCounted<RewrittenMessage> {
- public:
- RewrittenMessage();
-
- bool is_consumed() const { return data_read_cursor_ == data_len_; }
-
- void SetData(const NaClIPCAdapter::NaClMessageHeader& header,
- const void* payload, size_t payload_length);
-
- int Read(NaClImcTypedMsgHdr* msg);
-
- void AddDescriptor(nacl::DescWrapper* desc) { descs_.push_back(desc); }
-
- size_t desc_count() const { return descs_.size(); }
-
- private:
- friend class base::RefCounted<RewrittenMessage>;
- ~RewrittenMessage() {}
-
- scoped_array<char> data_;
- size_t data_len_;
-
- // Offset into data where the next read will happen. This will be equal to
- // data_len_ when all data has been consumed.
- size_t data_read_cursor_;
-
- // Wrapped descriptors for transfer to untrusted code.
- ScopedVector<nacl::DescWrapper> descs_;
-};
-
-NaClIPCAdapter::RewrittenMessage::RewrittenMessage()
- : data_len_(0),
- data_read_cursor_(0) {
-}
-
-void NaClIPCAdapter::RewrittenMessage::SetData(
- const NaClIPCAdapter::NaClMessageHeader& header,
- const void* payload,
- size_t payload_length) {
- DCHECK(!data_.get() && data_len_ == 0);
- size_t header_len = sizeof(NaClIPCAdapter::NaClMessageHeader);
- data_len_ = header_len + payload_length;
- data_.reset(new char[data_len_]);
-
- memcpy(data_.get(), &header, sizeof(NaClIPCAdapter::NaClMessageHeader));
- memcpy(&data_[header_len], payload, payload_length);
-}
-
-int NaClIPCAdapter::RewrittenMessage::Read(NaClImcTypedMsgHdr* msg) {
- CHECK(data_len_ >= data_read_cursor_);
- char* dest_buffer = static_cast<char*>(msg->iov[0].base);
- size_t dest_buffer_size = msg->iov[0].length;
- size_t bytes_to_write = std::min(dest_buffer_size,
- data_len_ - data_read_cursor_);
- if (bytes_to_write == 0)
- return 0;
-
- memcpy(dest_buffer, &data_[data_read_cursor_], bytes_to_write);
- data_read_cursor_ += bytes_to_write;
-
- // Once all data has been consumed, transfer any file descriptors.
- if (is_consumed()) {
- nacl_abi_size_t desc_count = static_cast<nacl_abi_size_t>(descs_.size());
- CHECK(desc_count <= msg->ndesc_length);
- msg->ndesc_length = desc_count;
- for (nacl_abi_size_t i = 0; i < desc_count; i++) {
- // Copy the NaClDesc to the buffer and add a ref so it won't be freed
- // when we clear our ScopedVector.
- msg->ndescv[i] = descs_[i]->desc();
- NaClDescRef(descs_[i]->desc());
- }
- descs_.clear();
- } else {
- msg->ndesc_length = 0;
- }
- return static_cast<int>(bytes_to_write);
-}
-
-NaClIPCAdapter::LockedData::LockedData()
- : channel_closed_(false) {
-}
-
-NaClIPCAdapter::LockedData::~LockedData() {
-}
-
-NaClIPCAdapter::IOThreadData::IOThreadData() {
-}
-
-NaClIPCAdapter::IOThreadData::~IOThreadData() {
-}
-
-NaClIPCAdapter::NaClIPCAdapter(const IPC::ChannelHandle& handle,
- base::TaskRunner* runner)
- : lock_(),
- cond_var_(&lock_),
- task_runner_(runner),
- locked_data_() {
- io_thread_data_.channel_.reset(
- new IPC::Channel(handle, IPC::Channel::MODE_SERVER, this));
- // Note, we can not PostTask for ConnectChannelOnIOThread here. If we did,
- // and that task ran before this constructor completes, the reference count
- // would go to 1 and then to 0 because of the Task, before we've been returned
- // to the owning scoped_refptr, which is supposed to give us our first
- // ref-count.
-}
-
-NaClIPCAdapter::NaClIPCAdapter(scoped_ptr<IPC::Channel> channel,
- base::TaskRunner* runner)
- : lock_(),
- cond_var_(&lock_),
- task_runner_(runner),
- locked_data_() {
- io_thread_data_.channel_ = channel.Pass();
-}
-
-void NaClIPCAdapter::ConnectChannel() {
- task_runner_->PostTask(FROM_HERE,
- base::Bind(&NaClIPCAdapter::ConnectChannelOnIOThread, this));
-}
-
-// Note that this message is controlled by the untrusted code. So we should be
-// skeptical of anything it contains and quick to give up if anything is fishy.
-int NaClIPCAdapter::Send(const NaClImcTypedMsgHdr* msg) {
- if (msg->iov_length != 1)
- return -1;
-
- base::AutoLock lock(lock_);
-
- const char* input_data = static_cast<char*>(msg->iov[0].base);
- size_t input_data_len = msg->iov[0].length;
- if (input_data_len > IPC::Channel::kMaximumMessageSize) {
- ClearToBeSent();
- return -1;
- }
-
- // current_message[_len] refers to the total input data received so far.
- const char* current_message;
- size_t current_message_len;
- bool did_append_input_data;
- if (locked_data_.to_be_sent_.empty()) {
- // No accumulated data, we can avoid a copy by referring to the input
- // buffer (the entire message fitting in one call is the common case).
- current_message = input_data;
- current_message_len = input_data_len;
- did_append_input_data = false;
- } else {
- // We've already accumulated some data, accumulate this new data and
- // point to the beginning of the buffer.
-
- // Make sure our accumulated message size doesn't overflow our max. Since
- // we know that data_len < max size (checked above) and our current
- // accumulated value is also < max size, we just need to make sure that
- // 2x max size can never overflow.
- COMPILE_ASSERT(IPC::Channel::kMaximumMessageSize < (UINT_MAX / 2),
- MaximumMessageSizeWillOverflow);
- size_t new_size = locked_data_.to_be_sent_.size() + input_data_len;
- if (new_size > IPC::Channel::kMaximumMessageSize) {
- ClearToBeSent();
- return -1;
- }
-
- locked_data_.to_be_sent_.append(input_data, input_data_len);
- current_message = &locked_data_.to_be_sent_[0];
- current_message_len = locked_data_.to_be_sent_.size();
- did_append_input_data = true;
- }
-
- // Check the total data we've accumulated so far to see if it contains a full
- // message.
- switch (GetBufferStatus(current_message, current_message_len)) {
- case MESSAGE_IS_COMPLETE: {
- // Got a complete message, can send it out. This will be the common case.
- bool success = SendCompleteMessage(current_message, current_message_len);
- ClearToBeSent();
- return success ? static_cast<int>(input_data_len) : -1;
- }
- case MESSAGE_IS_TRUNCATED:
- // For truncated messages, just accumulate the new data (if we didn't
- // already do so above) and go back to waiting for more.
- if (!did_append_input_data)
- locked_data_.to_be_sent_.append(input_data, input_data_len);
- return static_cast<int>(input_data_len);
- case MESSAGE_HAS_EXTRA_DATA:
- default:
- // When the plugin gives us too much data, it's an error.
- ClearToBeSent();
- return -1;
- }
-}
-
-int NaClIPCAdapter::BlockingReceive(NaClImcTypedMsgHdr* msg) {
- if (msg->iov_length != 1)
- return -1;
-
- int retval = 0;
- {
- base::AutoLock lock(lock_);
- while (locked_data_.to_be_received_.empty() &&
- !locked_data_.channel_closed_)
- cond_var_.Wait();
- if (locked_data_.channel_closed_) {
- retval = -1;
- } else {
- retval = LockedReceive(msg);
- DCHECK(retval > 0);
- }
- }
- cond_var_.Signal();
- return retval;
-}
-
-void NaClIPCAdapter::CloseChannel() {
- {
- base::AutoLock lock(lock_);
- locked_data_.channel_closed_ = true;
- }
- cond_var_.Signal();
-
- task_runner_->PostTask(FROM_HERE,
- base::Bind(&NaClIPCAdapter::CloseChannelOnIOThread, this));
-}
-
-NaClDesc* NaClIPCAdapter::MakeNaClDesc() {
- return MakeNaClDescCustom(this);
-}
-
-#if defined(OS_POSIX)
-int NaClIPCAdapter::TakeClientFileDescriptor() {
- return io_thread_data_.channel_->TakeClientFileDescriptor();
-}
-#endif
-
#define CASE_FOR_MESSAGE(MESSAGE_TYPE) \
case MESSAGE_TYPE::ID: { \
- HandleConverter<MESSAGE_TYPE> extractor(&msg); \
- if (!extractor.ConvertMessage(&handles, new_msg_ptr)) \
+ HandleConverterImpl<MESSAGE_TYPE> extractor(&msg); \
+ if (!extractor.ConvertMessage(handles, new_msg_ptr->get())) \
return false; \
break; \
}
#define CASE_FOR_REPLY(MESSAGE_TYPE) \
case MESSAGE_TYPE::ID: { \
- HandleConverter<MESSAGE_TYPE> extractor(&msg); \
+ HandleConverterImpl<MESSAGE_TYPE> extractor(&msg); \
if (!extractor.ConvertReply( \
- &handles, \
- static_cast<IPC::SyncMessage*>(new_msg_ptr))) \
+ handles, \
+ static_cast<IPC::SyncMessage*>(new_msg_ptr->get()))) \
return false; \
break; \
}
-bool NaClIPCAdapter::OnMessageReceived(const IPC::Message& msg) {
- {
- base::AutoLock lock(lock_);
-
- scoped_refptr<RewrittenMessage> rewritten_msg(new RewrittenMessage);
-
- // Pointer to the "new" message we will rewrite on Windows. On posix, this
- // isn't necessary, so it will stay NULL.
- IPC::Message* new_msg_ptr = NULL;
- IPC::Message new_msg(msg.routing_id(), msg.type(), msg.priority());
+namespace ppapi {
+namespace proxy {
+
+class SerializedHandle;
+
+HandleConverter::HandleConverter() {
+}
+
+bool HandleConverter::ConvertNativeHandlesToPosix(
+ const IPC::Message& msg,
+ std::vector<SerializedHandle>* handles,
+ scoped_ptr<IPC::Message>* new_msg_ptr) {
+ DCHECK(handles);
+ DCHECK(new_msg_ptr);
+ DCHECK(!new_msg_ptr->get());
+
+ // In Windows, we need to re-write the contents of the message. This is
+ // because in Windows IPC code, native HANDLE values are serialized in the
+ // body of the message.
+ //
+ // In POSIX, we only serialize an index in to a FileDescriptorSet, and the
+ // actual file descriptors are sent out-of-band. So on Windows, to make a
+ // message that's compatible with Windows, we need to write a new message that
+ // has simple indices in the message body instead of the HANDLEs.
+ //
+ // NOTE: This means on Windows, new_msg_ptr's serialized contents are not
+ // compatible with Windows IPC deserialization code; it is intended to be
+ // passed to NaCl.
#if defined(OS_WIN)
- new_msg_ptr = &new_msg;
+ new_msg_ptr->reset(
+ new IPC::Message(msg.routing_id(), msg.type(), msg.priority()));
#else
- // Even on POSIX, we have to rewrite messages to create channels, because
- // these contain a handle with an invalid (place holder) descriptor. The
- // message sending code sees this and doesn't pass the descriptor over
- // correctly.
- if (msg.type() == PpapiMsg_CreateNaClChannel::ID)
- new_msg_ptr = &new_msg;
+ // Even on POSIX, we have to rewrite messages to create channels, because
+ // these contain a handle with an invalid (place holder) descriptor. The
+ // message sending code sees this and doesn't pass the descriptor over
+ // correctly.
+ if (msg.type() == PpapiMsg_CreateNaClChannel::ID) {
+ new_msg_ptr->reset(
+ new IPC::Message(msg.routing_id(), msg.type(), msg.priority()));
+ }
#endif
- Handles handles;
- switch (msg.type()) {
- CASE_FOR_MESSAGE(PpapiMsg_CreateNaClChannel)
- CASE_FOR_MESSAGE(PpapiMsg_PPBAudio_NotifyAudioStreamCreated)
- CASE_FOR_MESSAGE(PpapiPluginMsg_ResourceReply)
- case IPC_REPLY_ID: {
- int id = IPC::SyncMessage::GetMessageId(msg);
- LockedData::PendingSyncMsgMap::iterator iter(
- locked_data_.pending_sync_msgs_.find(id));
- if (iter == locked_data_.pending_sync_msgs_.end()) {
- NOTREACHED();
- return false;
- }
- uint32_t type = iter->second;
- locked_data_.pending_sync_msgs_.erase(iter);
- switch (type) {
- CASE_FOR_REPLY(PpapiHostMsg_PPBGraphics3D_GetTransferBuffer)
- CASE_FOR_REPLY(PpapiHostMsg_PPBImageData_CreateNaCl)
- CASE_FOR_REPLY(PpapiHostMsg_ResourceSyncCall)
- default:
- // Do nothing for messages we don't know.
- break;
- }
- break;
+ switch (msg.type()) {
+ CASE_FOR_MESSAGE(PpapiMsg_CreateNaClChannel)
+ CASE_FOR_MESSAGE(PpapiMsg_PPBAudio_NotifyAudioStreamCreated)
+ CASE_FOR_MESSAGE(PpapiPluginMsg_ResourceReply)
+ case IPC_REPLY_ID: {
+ int id = IPC::SyncMessage::GetMessageId(msg);
+ PendingSyncMsgMap::iterator iter(pending_sync_msgs_.find(id));
+ if (iter == pending_sync_msgs_.end()) {
+ NOTREACHED();
+ return false;
}
- default:
- // Do nothing for messages we don't know.
- break;
- }
- // Now add any descriptors we found to rewritten_msg. |handles| is usually
- // empty, unless we read a message containing a FD or handle.
- nacl::DescWrapperFactory factory;
- for (Handles::const_iterator iter = handles.begin();
- iter != handles.end();
- ++iter) {
- scoped_ptr<nacl::DescWrapper> nacl_desc;
- switch (iter->type()) {
- case ppapi::proxy::SerializedHandle::SHARED_MEMORY: {
- const base::SharedMemoryHandle& shm_handle = iter->shmem();
- uint32_t size = iter->size();
- nacl_desc.reset(factory.ImportShmHandle(
-#if defined(OS_WIN)
- reinterpret_cast<const NaClHandle>(shm_handle),
-#else
- shm_handle.fd,
-#endif
- static_cast<size_t>(size)));
- break;
- }
- case ppapi::proxy::SerializedHandle::SOCKET: {
- nacl_desc.reset(factory.ImportSyncSocketHandle(
-#if defined(OS_WIN)
- reinterpret_cast<const NaClHandle>(iter->descriptor())
-#else
- iter->descriptor().fd
-#endif
- ));
- break;
- }
- case ppapi::proxy::SerializedHandle::CHANNEL_HANDLE: {
- // Check that this came from a PpapiMsg_CreateNaClChannel message.
- // This code here is only appropriate for that message.
- DCHECK(msg.type() == PpapiMsg_CreateNaClChannel::ID);
- IPC::ChannelHandle channel_handle =
- IPC::Channel::GenerateVerifiedChannelID("nacl");
- scoped_refptr<NaClIPCAdapter> ipc_adapter(
- new NaClIPCAdapter(channel_handle, task_runner_));
- ipc_adapter->ConnectChannel();
-#if defined(OS_POSIX)
- channel_handle.socket = base::FileDescriptor(
- ipc_adapter->TakeClientFileDescriptor(), true);
-#endif
- nacl_desc.reset(factory.MakeGeneric(ipc_adapter->MakeNaClDesc()));
- // Send back a message that the channel was created.
- scoped_ptr<IPC::Message> response(
- new PpapiHostMsg_ChannelCreated(channel_handle));
- task_runner_->PostTask(FROM_HERE,
- base::Bind(&NaClIPCAdapter::SendMessageOnIOThread, this,
- base::Passed(&response)));
- break;
- }
- case ppapi::proxy::SerializedHandle::FILE:
- // TODO(raymes): Handle file handles for NaCl.
- NOTIMPLEMENTED();
- break;
- case ppapi::proxy::SerializedHandle::INVALID: {
- // Nothing to do. TODO(dmichael): Should we log this? Or is it
- // sometimes okay to pass an INVALID handle?
+ uint32_t type = iter->second;
+ pending_sync_msgs_.erase(iter);
+ switch (type) {
+ CASE_FOR_REPLY(PpapiHostMsg_PPBGraphics3D_GetTransferBuffer)
+ CASE_FOR_REPLY(PpapiHostMsg_PPBImageData_CreateNaCl)
+ CASE_FOR_REPLY(PpapiHostMsg_ResourceSyncCall)
+ default:
+ // Do nothing for messages we don't know.
break;
- }
- // No default, so the compiler will warn us if new types get added.
}
- if (nacl_desc.get())
- rewritten_msg->AddDescriptor(nacl_desc.release());
+ break;
}
- if (new_msg_ptr && !handles.empty())
- SaveMessage(*new_msg_ptr, rewritten_msg.get());
- else
- SaveMessage(msg, rewritten_msg.get());
- }
- cond_var_.Signal();
- return true;
-}
-
-void NaClIPCAdapter::OnChannelConnected(int32 peer_pid) {
-}
-
-void NaClIPCAdapter::OnChannelError() {
- CloseChannel();
-}
-
-NaClIPCAdapter::~NaClIPCAdapter() {
- // Make sure the channel is deleted on the IO thread.
- task_runner_->PostTask(FROM_HERE,
- base::Bind(&DeleteChannel, io_thread_data_.channel_.release()));
-}
-
-int NaClIPCAdapter::LockedReceive(NaClImcTypedMsgHdr* msg) {
- lock_.AssertAcquired();
-
- if (locked_data_.to_be_received_.empty())
- return 0;
- scoped_refptr<RewrittenMessage> current =
- locked_data_.to_be_received_.front();
-
- int retval = current->Read(msg);
-
- // When a message is entirely consumed, remove if from the waiting queue.
- if (current->is_consumed())
- locked_data_.to_be_received_.pop();
-
- return retval;
-}
-
-bool NaClIPCAdapter::SendCompleteMessage(const char* buffer,
- size_t buffer_len) {
- // The message will have already been validated, so we know it's large enough
- // for our header.
- const NaClMessageHeader* header =
- reinterpret_cast<const NaClMessageHeader*>(buffer);
-
- // Length of the message not including the body. The data passed to us by the
- // plugin should match that in the message header. This should have already
- // been validated by GetBufferStatus.
- int body_len = static_cast<int>(buffer_len - sizeof(NaClMessageHeader));
- DCHECK(body_len == static_cast<int>(header->payload_size));
-
- // We actually discard the flags and only copy the ones we care about. This
- // is just because message doesn't have a constructor that takes raw flags.
- scoped_ptr<IPC::Message> msg(
- new IPC::Message(header->routing, header->type,
- IPC::Message::PRIORITY_NORMAL));
- if (header->flags & IPC::Message::SYNC_BIT)
- msg->set_sync();
- if (header->flags & IPC::Message::REPLY_BIT)
- msg->set_reply();
- if (header->flags & IPC::Message::REPLY_ERROR_BIT)
- msg->set_reply_error();
- if (header->flags & IPC::Message::UNBLOCK_BIT)
- msg->set_unblock(true);
-
- msg->WriteBytes(&buffer[sizeof(NaClMessageHeader)], body_len);
-
- // Technically we didn't have to do any of the previous work in the lock. But
- // sometimes our buffer will point to the to_be_sent_ string which is
- // protected by the lock, and it's messier to factor Send() such that it can
- // unlock for us. Holding the lock for the message construction, which is
- // just some memcpys, shouldn't be a big deal.
- lock_.AssertAcquired();
- if (locked_data_.channel_closed_)
- return false; // TODO(brettw) clean up handles here when we add support!
-
- // Store the type of all sync messages so that later we can translate the
- // reply if necessary.
- if (msg->is_sync()) {
- int id = IPC::SyncMessage::GetMessageId(*msg);
- locked_data_.pending_sync_msgs_[id] = msg->type();
+ default:
+ // Do nothing for messages we don't know.
+ break;
}
- // Actual send must be done on the I/O thread.
- task_runner_->PostTask(FROM_HERE,
- base::Bind(&NaClIPCAdapter::SendMessageOnIOThread, this,
- base::Passed(&msg)));
return true;
}
-void NaClIPCAdapter::ClearToBeSent() {
- lock_.AssertAcquired();
-
- // Don't let the string keep its buffer behind our back.
- std::string empty;
- locked_data_.to_be_sent_.swap(empty);
-}
-
-void NaClIPCAdapter::ConnectChannelOnIOThread() {
- if (!io_thread_data_.channel_->Connect())
- NOTREACHED();
-}
-
-void NaClIPCAdapter::CloseChannelOnIOThread() {
- io_thread_data_.channel_->Close();
-}
-
-void NaClIPCAdapter::SendMessageOnIOThread(scoped_ptr<IPC::Message> message) {
- io_thread_data_.channel_->Send(message.release());
-}
-
-void NaClIPCAdapter::SaveMessage(const IPC::Message& msg,
- RewrittenMessage* rewritten_msg) {
- lock_.AssertAcquired();
- // There is some padding in this structure (the "padding" member is 16
- // bits but this then gets padded to 32 bits). We want to be sure not to
- // leak data to the untrusted plugin, so zero everything out first.
- NaClMessageHeader header;
- memset(&header, 0, sizeof(NaClMessageHeader));
+void HandleConverter::RegisterSyncMessageForReply(const IPC::Message& msg) {
+ DCHECK(msg.is_sync());
- header.payload_size = static_cast<uint32>(msg.payload_size());
- header.routing = msg.routing_id();
- header.type = msg.type();
- header.flags = msg.flags();
- header.num_fds = static_cast<int>(rewritten_msg->desc_count());
+ int msg_id = IPC::SyncMessage::GetMessageId(msg);
+ DCHECK(pending_sync_msgs_.find(msg_id) == pending_sync_msgs_.end());
- rewritten_msg->SetData(header, msg.payload(), msg.payload_size());
- locked_data_.to_be_received_.push(rewritten_msg);
+ pending_sync_msgs_[msg_id] = msg.type();
}
+} // namespace proxy
+} // namespace ppapi
« no previous file with comments | « ppapi/proxy/handle_converter.h ('k') | ppapi/proxy/ppapi_messages.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698