diff options
author | dmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-12 09:34:54 +0000 |
---|---|---|
committer | dmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-12 09:34:54 +0000 |
commit | 915186d9ef2cf4cba2838909c7dea7ac92ee639e (patch) | |
tree | 84337f157dc1069d7c891c73884d6aac2ac5c9e8 /chrome/nacl | |
parent | 15af2b58ceeddb4bdb08fc9c58f9f9de3b372687 (diff) | |
download | chromium_src-915186d9ef2cf4cba2838909c7dea7ac92ee639e.zip chromium_src-915186d9ef2cf4cba2838909c7dea7ac92ee639e.tar.gz chromium_src-915186d9ef2cf4cba2838909c7dea7ac92ee639e.tar.bz2 |
PPAPI/NaCl: Wrap NaClIPCAdapter in a NaClCustomDesc
BUG=116317
TEST=
Review URL: https://chromiumcodereview.appspot.com/10356063
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@136754 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/nacl')
-rw-r--r-- | chrome/nacl/nacl_ipc_adapter.cc | 90 | ||||
-rw-r--r-- | chrome/nacl/nacl_ipc_adapter.h | 12 | ||||
-rw-r--r-- | chrome/nacl/nacl_ipc_manager.cc | 65 | ||||
-rw-r--r-- | chrome/nacl/nacl_ipc_manager.h | 68 |
4 files changed, 83 insertions, 152 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(); } diff --git a/chrome/nacl/nacl_ipc_adapter.h b/chrome/nacl/nacl_ipc_adapter.h index b809830..2c82356 100644 --- a/chrome/nacl/nacl_ipc_adapter.h +++ b/chrome/nacl/nacl_ipc_adapter.h @@ -17,6 +17,8 @@ #include "base/task_runner.h" #include "ipc/ipc_channel.h" +struct NaClDesc; + // Adapts a Chrome IPC channel to an IPC channel that we expose to Native // Client. This provides a mapping in both directions, so when IPC messages // come in from another process, we rewrite them and allow them to be received @@ -66,11 +68,15 @@ class NaClIPCAdapter : public base::RefCountedThreadSafe<NaClIPCAdapter>, // Implementation of recvmsg. Returns the number of bytes read or -1 on // failure. This will block until there's an error or there is data to // read. - int BlockingReceive(char* output_buffer, int output_buffer_size); + int BlockingReceive(char* output_buffer, size_t output_buffer_size); // Closes the IPC channel. void CloseChannel(); + // Make a NaClDesc that refers to this NaClIPCAdapter. Note that the returned + // NaClDesc is reference-counted, and a reference is returned. + NaClDesc* MakeNaClDesc(); + // Listener implementation. virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; virtual void OnChannelConnected(int32 peer_pid) OVERRIDE; @@ -115,7 +121,7 @@ class NaClIPCAdapter : public base::RefCountedThreadSafe<NaClIPCAdapter>, virtual ~NaClIPCAdapter(); // Reads up to the given amount of data. Returns 0 if nothing is waiting. - int LockedReceive(char* output_buffer, int output_buffer_size); + int LockedReceive(char* output_buffer, size_t output_buffer_size); // Sends a message that we know has been completed to the Chrome process. bool SendCompleteMessage(const char* buffer, size_t buffer_len); @@ -125,7 +131,7 @@ class NaClIPCAdapter : public base::RefCountedThreadSafe<NaClIPCAdapter>, // for future use which we don't want. void ClearToBeSent(); - void CreateChannelOnIOThread(const IPC::ChannelHandle& handle); + void ConnectChannelOnIOThread(); void CloseChannelOnIOThread(); void SendMessageOnIOThread(scoped_ptr<IPC::Message> message); diff --git a/chrome/nacl/nacl_ipc_manager.cc b/chrome/nacl/nacl_ipc_manager.cc deleted file mode 100644 index 646afb1..0000000 --- a/chrome/nacl/nacl_ipc_manager.cc +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) 2012 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_manager.h" - -#include "chrome/nacl/nacl_ipc_adapter.h" -#include "content/common/child_process.h" - -NaClIPCManager::NaClIPCManager() { -} - -NaClIPCManager::~NaClIPCManager() { -} - -void NaClIPCManager::Init( - scoped_refptr<base::MessageLoopProxy> io_thread_proxy) { - io_thread_proxy_ = io_thread_proxy; -} - -void* NaClIPCManager::CreateChannel(const IPC::ChannelHandle& handle) { - DCHECK(io_thread_proxy_.get()); - scoped_refptr<NaClIPCAdapter> adapter( - new NaClIPCAdapter(handle, io_thread_proxy_.get())); - - // Use the object's address as the handle given to nacl. We just need a - // unique void* to give to nacl for us to look it up when we get calls on - // this handle in the future. - void* nacl_handle = adapter.get(); - adapters_.insert(std::make_pair(nacl_handle, adapter)); - return nacl_handle; -} - -void NaClIPCManager::DestroyChannel(void* handle) { - scoped_refptr<NaClIPCAdapter> adapter = GetAdapter(handle); - if (!adapter.get()) - return; - adapter->CloseChannel(); -} - -int NaClIPCManager::SendMessage(void* handle, - const char* data, - int data_length) { - scoped_refptr<NaClIPCAdapter> adapter = GetAdapter(handle); - if (!adapter.get()) - return -1; - return adapter->Send(data, data_length); -} - -int NaClIPCManager::ReceiveMessage(void* handle, - char* buffer, - int buffer_length) { - scoped_refptr<NaClIPCAdapter> adapter = GetAdapter(handle); - if (!adapter.get()) - return -1; - return adapter->BlockingReceive(buffer, buffer_length); -} - -scoped_refptr<NaClIPCAdapter> NaClIPCManager::GetAdapter(void* handle) { - base::AutoLock lock(lock_); - AdapterMap::iterator found = adapters_.find(handle); - if (found == adapters_.end()) - return scoped_refptr<NaClIPCAdapter>(); - return found->second; -} diff --git a/chrome/nacl/nacl_ipc_manager.h b/chrome/nacl/nacl_ipc_manager.h deleted file mode 100644 index 83f3d72..0000000 --- a/chrome/nacl/nacl_ipc_manager.h +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) 2012 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. - -#ifndef CHROME_NACL_NACL_IPC_MANAGER_H_ -#define CHROME_NACL_NACL_IPC_MANAGER_H_ -#pragma once - -#include <map> - -#include "base/memory/ref_counted.h" -#include "base/message_loop_proxy.h" -#include "base/synchronization/lock.h" - -namespace IPC { -struct ChannelHandle; -} - -class NaClIPCAdapter; - -// This class manages all IPC channels exposed to NaCl. We give NaCl void* -// "handles" to identify channels. When the untrusted nacl code does operations -// on these handles, this class maps them to the corresponding adapter object. -// -// This class must be threadsafe since nacl send/recvmsg functions can be -// called on any thread. -class NaClIPCManager { - public: - NaClIPCManager(); - ~NaClIPCManager(); - - // Init must be called before creating any channels. - void Init(scoped_refptr<base::MessageLoopProxy> io_thread_proxy); - - // Creates a nacl channel associated with the given channel handle (normally - // this will come from the browser process). Returns the handle that should - // be given to nacl to associated with this IPC channel. - void* CreateChannel(const IPC::ChannelHandle& handle); - - // Destroys the channel with the given handle. - void DestroyChannel(void* handle); - - // Implementation of sendmsg on the given channel. The return value is the - // number of bytes written or -1 on failure. - int SendMessage(void* handle, const char* data, int data_length); - - // Implementation of recvmsg on the given channel. The return value is the - // number of bytes received or -1 on failure. - int ReceiveMessage(void* handle, char* buffer, int buffer_length); - - private: - // Looks up the adapter if given a handle. The pointer wil be null on - // failures. - scoped_refptr<NaClIPCAdapter> GetAdapter(void* handle); - - scoped_refptr<base::MessageLoopProxy> io_thread_proxy_; - - // Lock around all data below. - base::Lock lock_; - - // All active IPC channels. Locked by lock_ above. - typedef std::map<void*, scoped_refptr<NaClIPCAdapter> > AdapterMap; - AdapterMap adapters_; - - DISALLOW_COPY_AND_ASSIGN(NaClIPCManager); -}; - -#endif // CHROME_NACL_NACL_IPC_MANAGER_H_ |