summaryrefslogtreecommitdiffstats
path: root/chrome/nacl
diff options
context:
space:
mode:
authordmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-12 09:34:54 +0000
committerdmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-12 09:34:54 +0000
commit915186d9ef2cf4cba2838909c7dea7ac92ee639e (patch)
tree84337f157dc1069d7c891c73884d6aac2ac5c9e8 /chrome/nacl
parent15af2b58ceeddb4bdb08fc9c58f9f9de3b372687 (diff)
downloadchromium_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.cc90
-rw-r--r--chrome/nacl/nacl_ipc_adapter.h12
-rw-r--r--chrome/nacl/nacl_ipc_manager.cc65
-rw-r--r--chrome/nacl/nacl_ipc_manager.h68
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_