diff options
Diffstat (limited to 'chrome/nacl/nacl_ipc_adapter.cc')
-rw-r--r-- | chrome/nacl/nacl_ipc_adapter.cc | 90 |
1 files changed, 74 insertions, 16 deletions
diff --git a/chrome/nacl/nacl_ipc_adapter.cc b/chrome/nacl/nacl_ipc_adapter.cc index 74bf685..f76fa0d 100644 --- a/chrome/nacl/nacl_ipc_adapter.cc +++ b/chrome/nacl/nacl_ipc_adapter.cc @@ -12,6 +12,7 @@ #include "base/location.h" #include "base/memory/scoped_ptr.h" #include "build/build_config.h" +#include "native_client/src/trusted/desc/nacl_desc_custom.h" namespace { @@ -42,6 +43,55 @@ BufferSizeStatus GetBufferStatus(const char* data, size_t len) { 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 */) { + if (msg->iov_length != 1) + return -1; + return static_cast<ssize_t>( + ToAdapter(handle)->Send(static_cast<char*>(msg->iov[0].base), + msg->iov[0].length)); +} + +ssize_t NaClDescCustomRecvMsg(void* handle, NaClImcTypedMsgHdr* msg, + int /* flags */) { + if (msg->iov_length != 1) + return -1; + return static_cast<ssize_t>( + ToAdapter(handle)->BlockingReceive(static_cast<char*>(msg->iov[0].base), + msg->iov[0].length)); +} + +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); +} + +void DeleteChannel(IPC::Channel* channel) { + delete channel; +} + } // namespace class NaClIPCAdapter::RewrittenMessage @@ -54,18 +104,18 @@ class NaClIPCAdapter::RewrittenMessage void SetData(const NaClIPCAdapter::NaClMessageHeader& header, const void* payload, size_t payload_length); - int Read(char* dest_buffer, int dest_buffer_size); + int Read(char* dest_buffer, size_t dest_buffer_size); private: friend class base::RefCounted<RewrittenMessage>; ~RewrittenMessage() {} scoped_array<char> data_; - int data_len_; + 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. - int data_read_cursor_; + size_t data_read_cursor_; }; NaClIPCAdapter::RewrittenMessage::RewrittenMessage() @@ -78,8 +128,8 @@ void NaClIPCAdapter::RewrittenMessage::SetData( const void* payload, size_t payload_length) { DCHECK(!data_.get() && data_len_ == 0); - int header_len = sizeof(NaClIPCAdapter::NaClMessageHeader); - data_len_ = header_len + static_cast<int>(payload_length); + 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)); @@ -87,15 +137,16 @@ void NaClIPCAdapter::RewrittenMessage::SetData( } int NaClIPCAdapter::RewrittenMessage::Read(char* dest_buffer, - int dest_buffer_size) { - int bytes_to_write = std::min(dest_buffer_size, - data_len_ - data_read_cursor_); + size_t dest_buffer_size) { + CHECK(data_len_ >= data_read_cursor_); + 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; - return bytes_to_write; + return static_cast<int>(bytes_to_write); } NaClIPCAdapter::LockedData::LockedData() : channel_closed_(false) { @@ -116,8 +167,10 @@ NaClIPCAdapter::NaClIPCAdapter(const IPC::ChannelHandle& handle, cond_var_(&lock_), task_runner_(runner), locked_data_() { + io_thread_data_.channel_.reset( + new IPC::Channel(handle, IPC::Channel::MODE_SERVER, this)); task_runner_->PostTask(FROM_HERE, - base::Bind(&NaClIPCAdapter::CreateChannelOnIOThread, this, handle)); + base::Bind(&NaClIPCAdapter::ConnectChannelOnIOThread, this)); } NaClIPCAdapter::NaClIPCAdapter(scoped_ptr<IPC::Channel> channel, @@ -195,7 +248,7 @@ int NaClIPCAdapter::Send(const char* input_data, size_t input_data_len) { } int NaClIPCAdapter::BlockingReceive(char* output_buffer, - int output_buffer_size) { + size_t output_buffer_size) { int retval = 0; { base::AutoLock lock(lock_); @@ -224,6 +277,10 @@ void NaClIPCAdapter::CloseChannel() { base::Bind(&NaClIPCAdapter::CloseChannelOnIOThread, this)); } +NaClDesc* NaClIPCAdapter::MakeNaClDesc() { + return MakeNaClDescCustom(this); +} + bool NaClIPCAdapter::OnMessageReceived(const IPC::Message& message) { { base::AutoLock lock(lock_); @@ -256,9 +313,13 @@ void NaClIPCAdapter::OnChannelError() { } 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(char* output_buffer, int output_buffer_size) { +int NaClIPCAdapter::LockedReceive(char* output_buffer, + size_t output_buffer_size) { lock_.AssertAcquired(); if (locked_data_.to_be_received_.empty()) @@ -327,10 +388,7 @@ void NaClIPCAdapter::ClearToBeSent() { locked_data_.to_be_sent_.swap(empty); } -void NaClIPCAdapter::CreateChannelOnIOThread( - const IPC::ChannelHandle& handle) { - io_thread_data_.channel_.reset( - new IPC::Channel(handle, IPC::Channel::MODE_SERVER, this)); +void NaClIPCAdapter::ConnectChannelOnIOThread() { if (!io_thread_data_.channel_->Connect()) NOTREACHED(); } |