summaryrefslogtreecommitdiffstats
path: root/chrome/common
diff options
context:
space:
mode:
authoragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-11 18:59:20 +0000
committeragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-11 18:59:20 +0000
commit5fe733dee6afd3ab897cafbfcdcc1450264409b0 (patch)
tree64d39f452e1aee1076356da52d836c902e8b92eb /chrome/common
parent072f6f57560ab3616915b0aa9f61331deb2cf260 (diff)
downloadchromium_src-5fe733dee6afd3ab897cafbfcdcc1450264409b0.zip
chromium_src-5fe733dee6afd3ab897cafbfcdcc1450264409b0.tar.gz
chromium_src-5fe733dee6afd3ab897cafbfcdcc1450264409b0.tar.bz2
POSIX: Transfer network data using shared memory
This patch adds the long planned support for sharing memory on POSIX by transporting file descriptors. It largely builds on the shared memory cleanup work by jrg. We move FileDescriptor out of chrome/common/file_descriptor_posix.h and into base/file_descriptor_posix.h. Since all that's left in the chrome/common verion is the DescriptorSet, those files are renamed to descriptor_set.[h|cc]. The SharedMemoryHandle on POSIX then becomes a typedef to a FileDescriptor and thus can be serialised over IPC. After that, it's mostly a case of cleaning up those snippets of code which considered SharedMemoryHandles to be scaler values. Review URL: http://codereview.chromium.org/21208 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@9580 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/common')
-rw-r--r--chrome/common/common.scons2
-rw-r--r--chrome/common/descriptor_set_posix.cc (renamed from chrome/common/file_descriptor_posix.cc)28
-rw-r--r--chrome/common/descriptor_set_posix.h (renamed from chrome/common/file_descriptor_posix.h)37
-rw-r--r--chrome/common/ipc_channel_posix.cc2
-rw-r--r--chrome/common/ipc_channel_posix.h2
-rw-r--r--chrome/common/ipc_message.h2
-rw-r--r--chrome/common/ipc_message_utils.h12
-rw-r--r--chrome/common/ipc_send_fds_test.cc9
-rw-r--r--chrome/common/ipc_tests.cc2
-rw-r--r--chrome/common/resource_dispatcher.cc3
10 files changed, 49 insertions, 50 deletions
diff --git a/chrome/common/common.scons b/chrome/common/common.scons
index 7eca809..829da06 100644
--- a/chrome/common/common.scons
+++ b/chrome/common/common.scons
@@ -219,7 +219,7 @@ if not env.Bit('windows'):
# TODO(port): This is temporary so we can link.
input_files.Append(
'temp_scaffolding_stubs.cc',
- 'file_descriptor_posix.cc',
+ 'descriptor_set_posix.cc',
)
# TODO(port): Port these.
diff --git a/chrome/common/file_descriptor_posix.cc b/chrome/common/descriptor_set_posix.cc
index 7db9514..82f2899 100644
--- a/chrome/common/file_descriptor_posix.cc
+++ b/chrome/common/descriptor_set_posix.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/common/file_descriptor_posix.h"
+#include "chrome/common/descriptor_set_posix.h"
#include "base/logging.h"
@@ -29,20 +29,27 @@ DescriptorSet::~DescriptorSet() {
}
}
-void DescriptorSet::Add(int fd) {
- struct FileDescriptor sd;
+bool DescriptorSet::Add(int fd) {
+ if (descriptors_.size() == MAX_DESCRIPTORS_PER_MESSAGE)
+ return false;
+
+ struct base::FileDescriptor sd;
sd.fd = fd;
sd.auto_close = false;
descriptors_.push_back(sd);
- DCHECK(descriptors_.size() <= MAX_DESCRIPTORS_PER_MESSAGE);
+ return true;
}
-void DescriptorSet::AddAndAutoClose(int fd) {
- struct FileDescriptor sd;
+bool DescriptorSet::AddAndAutoClose(int fd) {
+ if (descriptors_.size() == MAX_DESCRIPTORS_PER_MESSAGE)
+ return false;
+
+ struct base::FileDescriptor sd;
sd.fd = fd;
sd.auto_close = true;
descriptors_.push_back(sd);
DCHECK(descriptors_.size() <= MAX_DESCRIPTORS_PER_MESSAGE);
+ return true;
}
int DescriptorSet::NextDescriptor() {
@@ -53,19 +60,22 @@ int DescriptorSet::NextDescriptor() {
}
void DescriptorSet::GetDescriptors(int* buffer) const {
- for (std::vector<FileDescriptor>::const_iterator
+ DCHECK_EQ(next_descriptor_, 0u);
+
+ for (std::vector<base::FileDescriptor>::const_iterator
i = descriptors_.begin(); i != descriptors_.end(); ++i) {
*(buffer++) = i->fd;
}
}
void DescriptorSet::CommitAll() {
- for (std::vector<FileDescriptor>::iterator
+ for (std::vector<base::FileDescriptor>::iterator
i = descriptors_.begin(); i != descriptors_.end(); ++i) {
if (i->auto_close)
close(i->fd);
}
descriptors_.clear();
+ next_descriptor_ = 0;
}
void DescriptorSet::SetDescriptors(const int* buffer, unsigned count) {
@@ -74,7 +84,7 @@ void DescriptorSet::SetDescriptors(const int* buffer, unsigned count) {
descriptors_.reserve(count);
for (unsigned i = 0; i < count; ++i) {
- struct FileDescriptor sd;
+ struct base::FileDescriptor sd;
sd.fd = buffer[i];
sd.auto_close = true;
descriptors_.push_back(sd);
diff --git a/chrome/common/file_descriptor_posix.h b/chrome/common/descriptor_set_posix.h
index 43590b0..36a0433 100644
--- a/chrome/common/file_descriptor_posix.h
+++ b/chrome/common/descriptor_set_posix.h
@@ -2,30 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_COMMON_FILE_DESCRIPTOR_POSIX_H_
-#define CHROME_COMMON_FILE_DESCRIPTOR_POSIX_H_
+#ifndef CHROME_COMMON_DESCRIPTOR_SET_POSIX_H_
+#define CHROME_COMMON_DESCRIPTOR_SET_POSIX_H_
#include <vector>
-// -----------------------------------------------------------------------------
-// A FileDescriptor is a structure for use in IPC messages. It allows one to
-// send descriptors over an IPC channel.
-//
-// In the Windows world, processes can peek and poke the HANDLE table of other
-// processes. On POSIX, in order to transmit descriptors we need to include
-// them in a control-message (a side-channel on the UNIX domain socket).
-// Serialising this type adds descriptors to a vector in the IPC Message, from
-// which the IPC channel can package them up for the kernel.
-// -----------------------------------------------------------------------------
-struct FileDescriptor {
- FileDescriptor()
- : fd(-1),
- auto_close(false) { }
-
- int fd;
- // If true, close this descriptor after it has been sent.
- bool auto_close;
-};
+#include "base/basictypes.h"
+#include "base/file_descriptor_posix.h"
// -----------------------------------------------------------------------------
// A DescriptorSet is an ordered set of POSIX file descriptors. These are
@@ -52,11 +35,11 @@ class DescriptorSet {
// ---------------------------------------------------------------------------
// Interfaces for building during message serialisation...
- // Add a descriptor to the end of the set
- void Add(int fd);
+ // Add a descriptor to the end of the set. Returns false iff the set is full.
+ bool Add(int fd);
// Add a descriptor to the end of the set and automatically close it after
- // transmission.
- void AddAndAutoClose(int fd);
+ // transmission. Returns false iff the set is full.
+ bool AddAndAutoClose(int fd);
// ---------------------------------------------------------------------------
@@ -115,10 +98,12 @@ class DescriptorSet {
// these descriptors are sent as control data. After sending, any descriptors
// with a true flag are closed. If this message has been received, then these
// are the descriptors which were received and all close flags are true.
- std::vector<FileDescriptor> descriptors_;
+ std::vector<base::FileDescriptor> descriptors_;
// When deserialising the message, the descriptors will be extracted
// one-by-one. This contains the index of the next unused descriptor.
unsigned next_descriptor_;
+
+ DISALLOW_COPY_AND_ASSIGN(DescriptorSet);
};
#endif // CHROME_COMMON_FILE_DESCRIPTOR_POSIX_H_
diff --git a/chrome/common/ipc_channel_posix.cc b/chrome/common/ipc_channel_posix.cc
index b688c77..d9f44dd 100644
--- a/chrome/common/ipc_channel_posix.cc
+++ b/chrome/common/ipc_channel_posix.cc
@@ -28,7 +28,7 @@
#include "base/singleton.h"
#include "chrome/common/chrome_counters.h"
#include "chrome/common/chrome_switches.h"
-#include "chrome/common/file_descriptor_posix.h"
+#include "chrome/common/descriptor_set_posix.h"
#include "chrome/common/ipc_message_utils.h"
namespace IPC {
diff --git a/chrome/common/ipc_channel_posix.h b/chrome/common/ipc_channel_posix.h
index 555d463..d6ed17d 100644
--- a/chrome/common/ipc_channel_posix.h
+++ b/chrome/common/ipc_channel_posix.h
@@ -14,7 +14,7 @@
#include <vector>
#include "base/message_loop.h"
-#include "chrome/common/file_descriptor_posix.h"
+#include "chrome/common/descriptor_set_posix.h"
namespace IPC {
diff --git a/chrome/common/ipc_message.h b/chrome/common/ipc_message.h
index 0af3b44..8aedbe3 100644
--- a/chrome/common/ipc_message.h
+++ b/chrome/common/ipc_message.h
@@ -17,7 +17,7 @@
#define IPC_MESSAGE_LOG_ENABLED
#endif
#elif defined(OS_POSIX)
-#include "chrome/common/file_descriptor_posix.h"
+#include "chrome/common/descriptor_set_posix.h"
#endif
namespace IPC {
diff --git a/chrome/common/ipc_message_utils.h b/chrome/common/ipc_message_utils.h
index bd38df0..e7dd7e3 100644
--- a/chrome/common/ipc_message_utils.h
+++ b/chrome/common/ipc_message_utils.h
@@ -13,7 +13,7 @@
#include "base/string_util.h"
#include "base/tuple.h"
#if defined(OS_POSIX)
-#include "chrome/common/file_descriptor_posix.h"
+#include "chrome/common/descriptor_set_posix.h"
#endif
#include "chrome/common/ipc_sync_message.h"
#include "chrome/common/thumbnail_score.h"
@@ -668,13 +668,15 @@ struct ParamTraits<gfx::Size> {
#if defined(OS_POSIX)
template<>
-struct ParamTraits<FileDescriptor> {
- typedef FileDescriptor param_type;
+struct ParamTraits<base::FileDescriptor> {
+ typedef base::FileDescriptor param_type;
static void Write(Message* m, const param_type& p) {
if (p.auto_close) {
- m->descriptor_set()->AddAndAutoClose(p.fd);
+ if (!m->descriptor_set()->AddAndAutoClose(p.fd))
+ NOTREACHED();
} else {
- m->descriptor_set()->Add(p.fd);
+ if (!m->descriptor_set()->Add(p.fd))
+ NOTREACHED();
}
}
static bool Read(const Message* m, void** iter, param_type* r) {
diff --git a/chrome/common/ipc_send_fds_test.cc b/chrome/common/ipc_send_fds_test.cc
index ca22bd5..e7cb207 100644
--- a/chrome/common/ipc_send_fds_test.cc
+++ b/chrome/common/ipc_send_fds_test.cc
@@ -47,10 +47,11 @@ class MyChannelDescriptorListener : public IPC::Channel::Listener {
virtual void OnMessageReceived(const IPC::Message& message) {
void* iter = NULL;
- FileDescriptor descriptor;
+ base::FileDescriptor descriptor;
ASSERT_TRUE(
- IPC::ParamTraits<FileDescriptor>::Read(&message, &iter, &descriptor));
+ IPC::ParamTraits<base::FileDescriptor>::Read(
+ &message, &iter, &descriptor));
VerifyAndCloseDescriptor(descriptor.fd, expected_inode_num_);
MessageLoop::current()->Quit();
@@ -67,7 +68,7 @@ void TestDescriptorServer(IPC::Channel &chan,
base::ProcessHandle process_handle) {
ASSERT_TRUE(process_handle);
- FileDescriptor descriptor;
+ base::FileDescriptor descriptor;
const int fd = open(kDevRandomPath, O_RDONLY);
ASSERT_GE(fd, 0);
descriptor.auto_close = true;
@@ -76,7 +77,7 @@ void TestDescriptorServer(IPC::Channel &chan,
IPC::Message* message = new IPC::Message(0, // routing_id
3, // message type
IPC::Message::PRIORITY_NORMAL);
- IPC::ParamTraits<FileDescriptor>::Write(message, descriptor);
+ IPC::ParamTraits<base::FileDescriptor>::Write(message, descriptor);
chan.Send(message);
// Run message loop.
diff --git a/chrome/common/ipc_tests.cc b/chrome/common/ipc_tests.cc
index 2544e43..4b24406 100644
--- a/chrome/common/ipc_tests.cc
+++ b/chrome/common/ipc_tests.cc
@@ -27,7 +27,7 @@
#include "base/thread.h"
#include "chrome/common/chrome_switches.h"
#if defined(OS_POSIX)
-#include "chrome/common/file_descriptor_posix.h"
+#include "chrome/common/descriptor_set_posix.h"
#endif
#include "chrome/common/ipc_channel.h"
#include "chrome/common/ipc_channel_proxy.h"
diff --git a/chrome/common/resource_dispatcher.cc b/chrome/common/resource_dispatcher.cc
index 7f64d32..e9db613 100644
--- a/chrome/common/resource_dispatcher.cc
+++ b/chrome/common/resource_dispatcher.cc
@@ -342,7 +342,8 @@ void ResourceDispatcher::OnReceivedData(int request_id,
sender->Send(
new ViewHostMsg_DataReceived_ACK(MSG_ROUTING_NONE, request_id));
- DCHECK((shm_handle && data_len > 0) || (!shm_handle && !data_len));
+ const bool shm_valid = base::SharedMemory::IsHandleValid(shm_handle);
+ DCHECK((shm_valid && data_len > 0) || (!shm_valid && !data_len));
base::SharedMemory shared_mem(shm_handle, true); // read only
PendingRequestList::iterator it = pending_requests_.find(request_id);