summaryrefslogtreecommitdiffstats
path: root/ipc
diff options
context:
space:
mode:
Diffstat (limited to 'ipc')
-rw-r--r--ipc/file_descriptor_set_posix.cc118
-rw-r--r--ipc/file_descriptor_set_posix.h108
-rw-r--r--ipc/file_descriptor_set_unittest.cc157
-rw-r--r--ipc/ipc.gyp82
-rw-r--r--ipc/ipc_channel.h123
-rw-r--r--ipc/ipc_channel_posix.cc803
-rw-r--r--ipc/ipc_channel_posix.h112
-rw-r--r--ipc/ipc_channel_proxy.cc305
-rw-r--r--ipc/ipc_channel_proxy.h206
-rw-r--r--ipc/ipc_channel_win.cc440
-rw-r--r--ipc/ipc_channel_win.h85
-rw-r--r--ipc/ipc_counters.cc27
-rw-r--r--ipc/ipc_counters.h22
-rw-r--r--ipc/ipc_fuzzing_tests.cc435
-rw-r--r--ipc/ipc_logging.cc301
-rw-r--r--ipc/ipc_logging.h113
-rw-r--r--ipc/ipc_message.cc124
-rw-r--r--ipc/ipc_message.h279
-rw-r--r--ipc/ipc_message_macros.h1140
-rw-r--r--ipc/ipc_message_utils.cc76
-rw-r--r--ipc/ipc_message_utils.h1258
-rw-r--r--ipc/ipc_send_fds_test.cc186
-rw-r--r--ipc/ipc_switches.cc17
-rw-r--r--ipc/ipc_switches.h19
-rw-r--r--ipc/ipc_sync_channel.cc453
-rw-r--r--ipc/ipc_sync_channel.h159
-rw-r--r--ipc/ipc_sync_channel_unittest.cc1013
-rw-r--r--ipc/ipc_sync_message.cc126
-rw-r--r--ipc/ipc_sync_message.h96
-rw-r--r--ipc/ipc_sync_message_unittest.cc253
-rw-r--r--ipc/ipc_sync_message_unittest.h98
-rw-r--r--ipc/ipc_test_sink.cc51
-rw-r--r--ipc/ipc_test_sink.h84
-rw-r--r--ipc/ipc_tests.cc480
-rw-r--r--ipc/ipc_tests.h47
35 files changed, 0 insertions, 9396 deletions
diff --git a/ipc/file_descriptor_set_posix.cc b/ipc/file_descriptor_set_posix.cc
deleted file mode 100644
index 3b04553..0000000
--- a/ipc/file_descriptor_set_posix.cc
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright (c) 2006-2008 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 "ipc/file_descriptor_set_posix.h"
-
-#include "base/logging.h"
-
-FileDescriptorSet::FileDescriptorSet()
- : consumed_descriptor_highwater_(0) {
-}
-
-FileDescriptorSet::~FileDescriptorSet() {
- if (consumed_descriptor_highwater_ == descriptors_.size())
- return;
-
- LOG(WARNING) << "FileDescriptorSet destroyed with unconsumed descriptors";
- // We close all the descriptors where the close flag is set. If this
- // message should have been transmitted, then closing those with close
- // flags set mirrors the expected behaviour.
- //
- // If this message was received with more descriptors than expected
- // (which could a DOS against the browser by a rogue renderer) then all
- // the descriptors have their close flag set and we free all the extra
- // kernel resources.
- for (unsigned i = consumed_descriptor_highwater_;
- i < descriptors_.size(); ++i) {
- if (descriptors_[i].auto_close)
- close(descriptors_[i].fd);
- }
-}
-
-bool FileDescriptorSet::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);
- return true;
-}
-
-bool FileDescriptorSet::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 FileDescriptorSet::GetDescriptorAt(unsigned index) const {
- if (index >= descriptors_.size())
- return -1;
-
- // We should always walk the descriptors in order, so it's reasonable to
- // enforce this. Consider the case where a compromised renderer sends us
- // the following message:
- //
- // ExampleMsg:
- // num_fds:2 msg:FD(index = 1) control:SCM_RIGHTS {n, m}
- //
- // Here the renderer sent us a message which should have a descriptor, but
- // actually sent two in an attempt to fill our fd table and kill us. By
- // setting the index of the descriptor in the message to 1 (it should be
- // 0), we would record a highwater of 1 and then consider all the
- // descriptors to have been used.
- //
- // So we can either track of the use of each descriptor in a bitset, or we
- // can enforce that we walk the indexes strictly in order.
- //
- // There's one more wrinkle: When logging messages, we may reparse them. So
- // we have an exception: When the consumed_descriptor_highwater_ is at the
- // end of the array and index 0 is requested, we reset the highwater value.
- if (index == 0 && consumed_descriptor_highwater_ == descriptors_.size())
- consumed_descriptor_highwater_ = 0;
-
- if (index != consumed_descriptor_highwater_)
- return -1;
-
- consumed_descriptor_highwater_ = index + 1;
- return descriptors_[index].fd;
-}
-
-void FileDescriptorSet::GetDescriptors(int* buffer) const {
- for (std::vector<base::FileDescriptor>::const_iterator
- i = descriptors_.begin(); i != descriptors_.end(); ++i) {
- *(buffer++) = i->fd;
- }
-}
-
-void FileDescriptorSet::CommitAll() {
- for (std::vector<base::FileDescriptor>::iterator
- i = descriptors_.begin(); i != descriptors_.end(); ++i) {
- if (i->auto_close)
- close(i->fd);
- }
- descriptors_.clear();
- consumed_descriptor_highwater_ = 0;
-}
-
-void FileDescriptorSet::SetDescriptors(const int* buffer, unsigned count) {
- DCHECK_LE(count, MAX_DESCRIPTORS_PER_MESSAGE);
- DCHECK_EQ(descriptors_.size(), 0u);
- DCHECK_EQ(consumed_descriptor_highwater_, 0u);
-
- descriptors_.reserve(count);
- for (unsigned i = 0; i < count; ++i) {
- struct base::FileDescriptor sd;
- sd.fd = buffer[i];
- sd.auto_close = true;
- descriptors_.push_back(sd);
- }
-}
diff --git a/ipc/file_descriptor_set_posix.h b/ipc/file_descriptor_set_posix.h
deleted file mode 100644
index c3d26ba8..0000000
--- a/ipc/file_descriptor_set_posix.h
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright (c) 2006-2009 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 IPC_FILE_DESCRIPTOR_SET_POSIX_H_
-#define IPC_FILE_DESCRIPTOR_SET_POSIX_H_
-
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/file_descriptor_posix.h"
-#include "base/ref_counted.h"
-
-// -----------------------------------------------------------------------------
-// A FileDescriptorSet is an ordered set of POSIX file descriptors. These are
-// associated with IPC messages so that descriptors can be transmitted over a
-// UNIX domain socket.
-// -----------------------------------------------------------------------------
-class FileDescriptorSet : public base::RefCountedThreadSafe<FileDescriptorSet> {
- public:
- FileDescriptorSet();
- ~FileDescriptorSet();
-
- // This is the maximum number of descriptors per message. We need to know this
- // because the control message kernel interface has to be given a buffer which
- // is large enough to store all the descriptor numbers. Otherwise the kernel
- // tells us that it truncated the control data and the extra descriptors are
- // lost.
- //
- // In debugging mode, it's a fatal error to try and add more than this number
- // of descriptors to a FileDescriptorSet.
- enum {
- MAX_DESCRIPTORS_PER_MESSAGE = 4,
- };
-
- // ---------------------------------------------------------------------------
- // Interfaces for building during message serialisation...
-
- // 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. Returns false iff the set is full.
- bool AddAndAutoClose(int fd);
-
- // ---------------------------------------------------------------------------
-
-
- // ---------------------------------------------------------------------------
- // Interfaces for accessing during message deserialisation...
-
- // Return the number of descriptors
- unsigned size() const { return descriptors_.size(); }
- // Return true if no unconsumed descriptors remain
- bool empty() const { return descriptors_.empty(); }
- // Fetch the nth descriptor from the beginning of the set. Code using this
- // /must/ access the descriptors in order, except that it may wrap from the
- // end to index 0 again.
- //
- // This interface is designed for the deserialising code as it doesn't
- // support close flags.
- // returns: file descriptor, or -1 on error
- int GetDescriptorAt(unsigned n) const;
-
- // ---------------------------------------------------------------------------
-
-
- // ---------------------------------------------------------------------------
- // Interfaces for transmission...
-
- // Fill an array with file descriptors without 'consuming' them. CommitAll
- // must be called after these descriptors have been transmitted.
- // buffer: (output) a buffer of, at least, size() integers.
- void GetDescriptors(int* buffer) const;
- // This must be called after transmitting the descriptors returned by
- // GetDescriptors. It marks all the descriptors as consumed and closes those
- // which are auto-close.
- void CommitAll();
-
- // ---------------------------------------------------------------------------
-
-
- // ---------------------------------------------------------------------------
- // Interfaces for receiving...
-
- // Set the contents of the set from the given buffer. This set must be empty
- // before calling. The auto-close flag is set on all the descriptors so that
- // unconsumed descriptors are closed on destruction.
- void SetDescriptors(const int* buffer, unsigned count);
-
- // ---------------------------------------------------------------------------
-
- private:
- // A vector of descriptors and close flags. If this message is sent, then
- // 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<base::FileDescriptor> descriptors_;
-
- // This contains the index of the next descriptor which should be consumed.
- // It's used in a couple of ways. Firstly, at destruction we can check that
- // all the descriptors have been read (with GetNthDescriptor). Secondly, we
- // can check that they are read in order.
- mutable unsigned consumed_descriptor_highwater_;
-
- DISALLOW_COPY_AND_ASSIGN(FileDescriptorSet);
-};
-
-#endif // IPC_FILE_DESCRIPTOR_SET_POSIX_H_
diff --git a/ipc/file_descriptor_set_unittest.cc b/ipc/file_descriptor_set_unittest.cc
deleted file mode 100644
index 0d158b2..0000000
--- a/ipc/file_descriptor_set_unittest.cc
+++ /dev/null
@@ -1,157 +0,0 @@
-// Copyright (c) 2006-2009 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.
-
-// This test is POSIX only.
-
-#include <unistd.h>
-#include <fcntl.h>
-
-#include "base/basictypes.h"
-#include "ipc/file_descriptor_set_posix.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-// The FileDescriptorSet will try and close some of the descriptor numbers
-// which we given it. This is the base descriptor value. It's great enough such
-// that no real descriptor will accidently be closed.
-static const int kFDBase = 50000;
-
-TEST(FileDescriptorSet, BasicAdd) {
- scoped_refptr<FileDescriptorSet> set = new FileDescriptorSet;
-
- ASSERT_EQ(set->size(), 0u);
- ASSERT_TRUE(set->empty());
- ASSERT_TRUE(set->Add(kFDBase));
- ASSERT_EQ(set->size(), 1u);
- ASSERT_TRUE(!set->empty());
-
- // Empties the set and stops a warning about deleting a set with unconsumed
- // descriptors
- set->CommitAll();
-}
-
-TEST(FileDescriptorSet, BasicAddAndClose) {
- scoped_refptr<FileDescriptorSet> set = new FileDescriptorSet;
-
- ASSERT_EQ(set->size(), 0u);
- ASSERT_TRUE(set->empty());
- ASSERT_TRUE(set->AddAndAutoClose(kFDBase));
- ASSERT_EQ(set->size(), 1u);
- ASSERT_TRUE(!set->empty());
-
- set->CommitAll();
-}
-
-TEST(FileDescriptorSet, MaxSize) {
- scoped_refptr<FileDescriptorSet> set = new FileDescriptorSet;
-
- for (unsigned i = 0;
- i < FileDescriptorSet::MAX_DESCRIPTORS_PER_MESSAGE; ++i) {
- ASSERT_TRUE(set->Add(kFDBase + 1 + i));
- }
-
- ASSERT_TRUE(!set->Add(kFDBase));
-
- set->CommitAll();
-}
-
-TEST(FileDescriptorSet, SetDescriptors) {
- scoped_refptr<FileDescriptorSet> set = new FileDescriptorSet;
-
- ASSERT_TRUE(set->empty());
- set->SetDescriptors(NULL, 0);
- ASSERT_TRUE(set->empty());
-
- static const int fds[] = {kFDBase};
- set->SetDescriptors(fds, 1);
- ASSERT_TRUE(!set->empty());
- ASSERT_EQ(set->size(), 1u);
-
- set->CommitAll();
-}
-
-TEST(FileDescriptorSet, GetDescriptors) {
- scoped_refptr<FileDescriptorSet> set = new FileDescriptorSet;
-
- set->GetDescriptors(NULL);
- ASSERT_TRUE(set->Add(kFDBase));
-
- int fds[1];
- fds[0] = 0;
- set->GetDescriptors(fds);
- ASSERT_EQ(fds[0], kFDBase);
- set->CommitAll();
- ASSERT_TRUE(set->empty());
-}
-
-TEST(FileDescriptorSet, WalkInOrder) {
- scoped_refptr<FileDescriptorSet> set = new FileDescriptorSet;
-
- ASSERT_TRUE(set->Add(kFDBase));
- ASSERT_TRUE(set->Add(kFDBase + 1));
- ASSERT_TRUE(set->Add(kFDBase + 2));
-
- ASSERT_EQ(set->GetDescriptorAt(0), kFDBase);
- ASSERT_EQ(set->GetDescriptorAt(1), kFDBase + 1);
- ASSERT_EQ(set->GetDescriptorAt(2), kFDBase + 2);
-
- set->CommitAll();
-}
-
-TEST(FileDescriptorSet, WalkWrongOrder) {
- scoped_refptr<FileDescriptorSet> set = new FileDescriptorSet;
-
- ASSERT_TRUE(set->Add(kFDBase));
- ASSERT_TRUE(set->Add(kFDBase + 1));
- ASSERT_TRUE(set->Add(kFDBase + 2));
-
- ASSERT_EQ(set->GetDescriptorAt(0), kFDBase);
- ASSERT_EQ(set->GetDescriptorAt(2), -1);
-
- set->CommitAll();
-}
-
-TEST(FileDescriptorSet, WalkCycle) {
- scoped_refptr<FileDescriptorSet> set = new FileDescriptorSet;
-
- ASSERT_TRUE(set->Add(kFDBase));
- ASSERT_TRUE(set->Add(kFDBase + 1));
- ASSERT_TRUE(set->Add(kFDBase + 2));
-
- ASSERT_EQ(set->GetDescriptorAt(0), kFDBase);
- ASSERT_EQ(set->GetDescriptorAt(1), kFDBase + 1);
- ASSERT_EQ(set->GetDescriptorAt(2), kFDBase + 2);
- ASSERT_EQ(set->GetDescriptorAt(0), kFDBase);
- ASSERT_EQ(set->GetDescriptorAt(1), kFDBase + 1);
- ASSERT_EQ(set->GetDescriptorAt(2), kFDBase + 2);
- ASSERT_EQ(set->GetDescriptorAt(0), kFDBase);
- ASSERT_EQ(set->GetDescriptorAt(1), kFDBase + 1);
- ASSERT_EQ(set->GetDescriptorAt(2), kFDBase + 2);
-
- set->CommitAll();
-}
-
-TEST(FileDescriptorSet, DontClose) {
- scoped_refptr<FileDescriptorSet> set = new FileDescriptorSet;
-
- const int fd = open("/dev/null", O_RDONLY);
- ASSERT_TRUE(set->Add(fd));
- set->CommitAll();
-
- const int duped = dup(fd);
- ASSERT_GE(duped, 0);
- close(duped);
- close(fd);
-}
-
-TEST(FileDescriptorSet, DoClose) {
- scoped_refptr<FileDescriptorSet> set = new FileDescriptorSet;
-
- const int fd = open("/dev/null", O_RDONLY);
- ASSERT_TRUE(set->AddAndAutoClose(fd));
- set->CommitAll();
-
- const int duped = dup(fd);
- ASSERT_EQ(duped, -1);
- close(fd);
-}
diff --git a/ipc/ipc.gyp b/ipc/ipc.gyp
deleted file mode 100644
index a2c1adc..0000000
--- a/ipc/ipc.gyp
+++ /dev/null
@@ -1,82 +0,0 @@
-# Copyright (c) 2009 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.
-
-{
- 'variables': {
- 'chromium_code': 1,
- },
- 'includes': [
- '../build/common.gypi',
- ],
-
- 'targets': [
- {
- 'target_name': 'ipc',
- 'type': 'static_library',
- 'dependencies': [
- '../base/base.gyp:base',
- '../base/base.gyp:base_gfx',
- ],
- 'sources': [
- 'ipc_channel.h',
- 'ipc_channel_proxy.cc',
- 'ipc_channel_proxy.h',
- 'ipc_counters.cc',
- 'ipc_logging.cc',
- 'ipc_logging.h',
- 'ipc_message.cc',
- 'ipc_message.h',
- 'ipc_message_macros.h',
- 'ipc_message_utils.cc',
- 'ipc_message_utils.h',
- 'ipc_sync_channel.cc',
- 'ipc_sync_channel.h',
- 'ipc_sync_message.cc',
- 'ipc_sync_message.h',
- 'ipc_switches.cc',
- ],
-
- 'conditions': [
- ['OS=="linux"', {'sources': [
- 'ipc_channel_posix.cc',
- 'ipc_channel_posix.h',
- 'file_descriptor_set_posix.cc',
- ]}],
- ['OS=="mac"', {'sources': [
- 'ipc_channel_posix.cc',
- 'ipc_channel_posix.h',
- ]}],
- ['OS=="win"', {'sources': [
- 'ipc_channel_win.cc',
- 'ipc_channel_win.h',
- ]}],
- ],
- },
- {
- 'target_name': 'ipc_tests',
- 'type': 'executable',
- 'dependencies': [
- 'ipc',
- '../base/base.gyp:base',
- '../testing/gtest.gyp:gtest',
- ],
- 'sources': [
- 'ipc_fuzzing_tests.cc',
- 'ipc_sync_channel_unittest.cc',
- 'ipc_sync_message_unittest.cc',
- 'ipc_sync_message_unittest.h',
- 'ipc_tests.cc',
- 'ipc_tests.h',
- ],
- 'conditions': [
- ['OS=="linux"', {'sources': [
- 'ipc_send_fds_test.cc',
- ]}],
- ['OS=="mac"', {'sources': [
- 'ipc_send_fds_test.cc',
- ]}],
- ],
- },
- ],
-}
diff --git a/ipc/ipc_channel.h b/ipc/ipc_channel.h
deleted file mode 100644
index 1ecffdf..0000000
--- a/ipc/ipc_channel.h
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright (c) 2006-2008 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 IPC_IPC_CHANNEL_H_
-#define IPC_IPC_CHANNEL_H_
-
-#include "ipc/ipc_message.h"
-
-namespace IPC {
-
-//------------------------------------------------------------------------------
-
-class Channel : public Message::Sender {
- // Security tests need access to the pipe handle.
- friend class ChannelTest;
-
- public:
- // Implemented by consumers of a Channel to receive messages.
- class Listener {
- public:
- virtual ~Listener() {}
-
- // Called when a message is received.
- virtual void OnMessageReceived(const Message& message) = 0;
-
- // Called when the channel is connected and we have received the internal
- // Hello message from the peer.
- virtual void OnChannelConnected(int32 peer_pid) {}
-
- // Called when an error is detected that causes the channel to close.
- // This method is not called when a channel is closed normally.
- virtual void OnChannelError() {}
- };
-
- enum Mode {
- MODE_SERVER,
- MODE_CLIENT
- };
-
- enum {
- // The maximum message size in bytes. Attempting to receive a
- // message of this size or bigger results in a channel error.
- kMaximumMessageSize = 256 * 1024 * 1024,
-
- // Ammount of data to read at once from the pipe.
- kReadBufferSize = 4 * 1024
- };
-
- // Initialize a Channel.
- //
- // |channel_id| identifies the communication Channel.
- // |mode| specifies whether this Channel is to operate in server mode or
- // client mode. In server mode, the Channel is responsible for setting up the
- // IPC object, whereas in client mode, the Channel merely connects to the
- // already established IPC object.
- // |listener| receives a callback on the current thread for each newly
- // received message.
- //
- Channel(const std::wstring& channel_id, Mode mode, Listener* listener);
-
- ~Channel();
-
- // Connect the pipe. On the server side, this will initiate
- // waiting for connections. On the client, it attempts to
- // connect to a pre-existing pipe. Note, calling Connect()
- // will not block the calling thread and may complete
- // asynchronously.
- bool Connect();
-
- // Close this Channel explicitly. May be called multiple times.
- void Close();
-
- // Modify the Channel's listener.
- void set_listener(Listener* listener);
-
- // Send a message over the Channel to the listener on the other end.
- //
- // |message| must be allocated using operator new. This object will be
- // deleted once the contents of the Message have been sent.
- //
- // FIXME bug 551500: the channel does not notice failures, so if the
- // renderer crashes, it will silently succeed, leaking the parameter.
- // At least the leak will be fixed by...
- //
- virtual bool Send(Message* message);
-
-#if defined(OS_POSIX)
- // On POSIX an IPC::Channel wraps a socketpair(), this method returns the
- // FD # for the client end of the socket and the equivalent FD# to use for
- // mapping it into the Child process.
- // This method may only be called on the server side of a channel.
- //
- // If the kTestingChannelID flag is specified on the command line then
- // a named FIFO is used as the channel transport mechanism rather than a
- // socketpair() in which case this method returns -1 for both parameters.
- void GetClientFileDescriptorMapping(int *src_fd, int *dest_fd);
-
- // Call this method on the server side of the IPC Channel once a client is
- // connected in order to close the client side of the socketpair().
- void OnClientConnected();
-#endif // defined(OS_POSIX)
-
- private:
- // PIMPL to which all channel calls are delegated.
- class ChannelImpl;
- ChannelImpl *channel_impl_;
-
- // The Hello message is internal to the Channel class. It is sent
- // by the peer when the channel is connected. The message contains
- // just the process id (pid). The message has a special routing_id
- // (MSG_ROUTING_NONE) and type (HELLO_MESSAGE_TYPE).
- enum {
- HELLO_MESSAGE_TYPE = kuint16max // Maximum value of message type (uint16),
- // to avoid conflicting with normal
- // message types, which are enumeration
- // constants starting from 0.
- };
-};
-
-} // namespace IPC
-
-#endif // IPC_IPC_CHANNEL_H_
diff --git a/ipc/ipc_channel_posix.cc b/ipc/ipc_channel_posix.cc
deleted file mode 100644
index 96209a0..0000000
--- a/ipc/ipc_channel_posix.cc
+++ /dev/null
@@ -1,803 +0,0 @@
-// Copyright (c) 2008 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 "ipc/ipc_channel_posix.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stddef.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/un.h>
-
-#include <string>
-#include <map>
-
-#include "base/command_line.h"
-#include "base/lock.h"
-#include "base/logging.h"
-#include "base/process_util.h"
-#include "base/scoped_ptr.h"
-#include "base/string_util.h"
-#include "base/singleton.h"
-#include "ipc/ipc_counters.h"
-#include "ipc/ipc_switches.h"
-#include "ipc/file_descriptor_set_posix.h"
-#include "ipc/ipc_logging.h"
-#include "ipc/ipc_message_utils.h"
-
-namespace IPC {
-
-//------------------------------------------------------------------------------
-namespace {
-
-// When running as a browser, we install the client socket in a specific file
-// descriptor number (@kClientChannelFd). However, we also have to support the
-// case where we are running unittests in the same process.
-//
-// We do not support forking without execing.
-//
-// Case 1: normal running
-// The IPC server object will install a mapping in PipeMap from the
-// name which it was given to the client pipe. When forking the client, the
-// GetClientFileDescriptorMapping will ensure that the socket is installed in
-// the magic slot (@kClientChannelFd). The client will search for the
-// mapping, but it won't find any since we are in a new process. Thus the
-// magic fd number is returned. Once the client connects, the server will
-// close it's copy of the client socket and remove the mapping.
-//
-// Case 2: unittests - client and server in the same process
-// The IPC server will install a mapping as before. The client will search
-// for a mapping and find out. It duplicates the file descriptor and
-// connects. Once the client connects, the server will close the original
-// copy of the client socket and remove the mapping. Thus, when the client
-// object closes, it will close the only remaining copy of the client socket
-// in the fd table and the server will see EOF on its side.
-//
-// TODO(port): a client process cannot connect to multiple IPC channels with
-// this scheme.
-
-class PipeMap {
- public:
- // Lookup a given channel id. Return -1 if not found.
- int Lookup(const std::string& channel_id) {
- AutoLock locked(lock_);
-
- ChannelToFDMap::const_iterator i = map_.find(channel_id);
- if (i == map_.end())
- return -1;
- return i->second;
- }
-
- // Remove the mapping for the given channel id. No error is signaled if the
- // channel_id doesn't exist
- void Remove(const std::string& channel_id) {
- AutoLock locked(lock_);
-
- ChannelToFDMap::iterator i = map_.find(channel_id);
- if (i != map_.end())
- map_.erase(i);
- }
-
- // Insert a mapping from @channel_id to @fd. It's a fatal error to insert a
- // mapping if one already exists for the given channel_id
- void Insert(const std::string& channel_id, int fd) {
- AutoLock locked(lock_);
- DCHECK(fd != -1);
-
- ChannelToFDMap::const_iterator i = map_.find(channel_id);
- CHECK(i == map_.end()) << "Creating second IPC server for '"
- << channel_id
- << "' while first still exists";
- map_[channel_id] = fd;
- }
-
- private:
- Lock lock_;
- typedef std::map<std::string, int> ChannelToFDMap;
- ChannelToFDMap map_;
-};
-
-// This is the file descriptor number that a client process expects to find its
-// IPC socket.
-static const int kClientChannelFd = 3;
-
-// Used to map a channel name to the equivalent FD # in the client process.
-int ChannelNameToClientFD(const std::string& channel_id) {
- // See the large block comment above PipeMap for the reasoning here.
- const int fd = Singleton<PipeMap>()->Lookup(channel_id);
- if (fd != -1)
- return dup(fd);
-
- // If we don't find an entry, we assume that the correct value has been
- // inserted in the magic slot.
- return kClientChannelFd;
-}
-
-//------------------------------------------------------------------------------
-sockaddr_un sizecheck;
-const size_t kMaxPipeNameLength = sizeof(sizecheck.sun_path);
-
-// Creates a Fifo with the specified name ready to listen on.
-bool CreateServerFifo(const std::string &pipe_name, int* server_listen_fd) {
- DCHECK(server_listen_fd);
- DCHECK_GT(pipe_name.length(), 0u);
- DCHECK_LT(pipe_name.length(), kMaxPipeNameLength);
-
- if (pipe_name.length() == 0 || pipe_name.length() >= kMaxPipeNameLength) {
- return false;
- }
-
- // Create socket.
- int fd = socket(AF_UNIX, SOCK_STREAM, 0);
- if (fd < 0) {
- return false;
- }
-
- // Make socket non-blocking
- if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
- close(fd);
- return false;
- }
-
- // Delete any old FS instances.
- unlink(pipe_name.c_str());
-
- // Create unix_addr structure
- struct sockaddr_un unix_addr;
- memset(&unix_addr, 0, sizeof(unix_addr));
- unix_addr.sun_family = AF_UNIX;
- snprintf(unix_addr.sun_path, kMaxPipeNameLength, "%s", pipe_name.c_str());
- size_t unix_addr_len = offsetof(struct sockaddr_un, sun_path) +
- strlen(unix_addr.sun_path) + 1;
-
- // Bind the socket.
- if (bind(fd, reinterpret_cast<const sockaddr*>(&unix_addr),
- unix_addr_len) != 0) {
- close(fd);
- return false;
- }
-
- // Start listening on the socket.
- const int listen_queue_length = 1;
- if (listen(fd, listen_queue_length) != 0) {
- close(fd);
- return false;
- }
-
- *server_listen_fd = fd;
- return true;
-}
-
-// Accept a connection on a fifo.
-bool ServerAcceptFifoConnection(int server_listen_fd, int* server_socket) {
- DCHECK(server_socket);
-
- int accept_fd = accept(server_listen_fd, NULL, 0);
- if (accept_fd < 0)
- return false;
- if (fcntl(accept_fd, F_SETFL, O_NONBLOCK) == -1) {
- close(accept_fd);
- return false;
- }
-
- *server_socket = accept_fd;
- return true;
-}
-
-bool ClientConnectToFifo(const std::string &pipe_name, int* client_socket) {
- DCHECK(client_socket);
- DCHECK_LT(pipe_name.length(), kMaxPipeNameLength);
-
- // Create socket.
- int fd = socket(AF_UNIX, SOCK_STREAM, 0);
- if (fd < 0) {
- LOG(ERROR) << "fd is invalid";
- return false;
- }
-
- // Make socket non-blocking
- if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
- LOG(ERROR) << "fcntl failed";
- close(fd);
- return false;
- }
-
- // Create server side of socket.
- struct sockaddr_un server_unix_addr;
- memset(&server_unix_addr, 0, sizeof(server_unix_addr));
- server_unix_addr.sun_family = AF_UNIX;
- snprintf(server_unix_addr.sun_path, kMaxPipeNameLength, "%s",
- pipe_name.c_str());
- size_t server_unix_addr_len = offsetof(struct sockaddr_un, sun_path) +
- strlen(server_unix_addr.sun_path) + 1;
-
- int ret_val = -1;
- do {
- ret_val = connect(fd, reinterpret_cast<sockaddr*>(&server_unix_addr),
- server_unix_addr_len);
- } while (ret_val == -1 && errno == EINTR);
- if (ret_val != 0) {
- close(fd);
- return false;
- }
-
- *client_socket = fd;
- return true;
-}
-
-} // namespace
-//------------------------------------------------------------------------------
-
-Channel::ChannelImpl::ChannelImpl(const std::wstring& channel_id, Mode mode,
- Listener* listener)
- : mode_(mode),
- is_blocked_on_write_(false),
- message_send_bytes_written_(0),
- uses_fifo_(CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kIPCUseFIFO)),
- server_listen_pipe_(-1),
- pipe_(-1),
- client_pipe_(-1),
- listener_(listener),
- waiting_connect_(true),
- processing_incoming_(false),
- factory_(this) {
- if (!CreatePipe(channel_id, mode)) {
- // The pipe may have been closed already.
- LOG(WARNING) << "Unable to create pipe named \"" << channel_id <<
- "\" in " << (mode == MODE_SERVER ? "server" : "client") <<
- " mode error(" << strerror(errno) << ").";
- }
-}
-
-const std::wstring Channel::ChannelImpl::PipeName(
- const std::wstring& channel_id) const {
- // TODO(playmobil): This should live in the Chrome user data directory.
- // TODO(playmobil): Cleanup any stale fifos.
- return L"/var/tmp/chrome_" + channel_id;
-}
-
-bool Channel::ChannelImpl::CreatePipe(const std::wstring& channel_id,
- Mode mode) {
- DCHECK(server_listen_pipe_ == -1 && pipe_ == -1);
- pipe_name_ = WideToUTF8(PipeName(channel_id));
-
- if (uses_fifo_) {
- // TODO(playmobil): Should we just change pipe_name to be a normal string
- // everywhere?
-
- if (mode == MODE_SERVER) {
- if (!CreateServerFifo(pipe_name_, &server_listen_pipe_)) {
- return false;
- }
- } else {
- if (!ClientConnectToFifo(pipe_name_, &pipe_)) {
- return false;
- }
- waiting_connect_ = false;
- }
- } else {
- // socketpair()
- if (mode == MODE_SERVER) {
- int pipe_fds[2];
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipe_fds) != 0) {
- return false;
- }
- // Set both ends to be non-blocking.
- if (fcntl(pipe_fds[0], F_SETFL, O_NONBLOCK) == -1 ||
- fcntl(pipe_fds[1], F_SETFL, O_NONBLOCK) == -1) {
- close(pipe_fds[0]);
- close(pipe_fds[1]);
- return false;
- }
- pipe_ = pipe_fds[0];
- client_pipe_ = pipe_fds[1];
-
- Singleton<PipeMap>()->Insert(pipe_name_, client_pipe_);
- } else {
- pipe_ = ChannelNameToClientFD(pipe_name_);
- DCHECK(pipe_ > 0);
- waiting_connect_ = false;
- }
- }
-
- // Create the Hello message to be sent when Connect is called
- scoped_ptr<Message> msg(new Message(MSG_ROUTING_NONE,
- HELLO_MESSAGE_TYPE,
- IPC::Message::PRIORITY_NORMAL));
- if (!msg->WriteInt(base::GetCurrentProcId())) {
- Close();
- return false;
- }
-
- output_queue_.push(msg.release());
- return true;
-}
-
-bool Channel::ChannelImpl::Connect() {
- if (mode_ == MODE_SERVER && uses_fifo_) {
- if (server_listen_pipe_ == -1) {
- return false;
- }
- MessageLoopForIO::current()->WatchFileDescriptor(
- server_listen_pipe_,
- true,
- MessageLoopForIO::WATCH_READ,
- &server_listen_connection_watcher_,
- this);
- } else {
- if (pipe_ == -1) {
- return false;
- }
- MessageLoopForIO::current()->WatchFileDescriptor(
- pipe_,
- true,
- MessageLoopForIO::WATCH_READ,
- &read_watcher_,
- this);
- waiting_connect_ = false;
- }
-
- if (!waiting_connect_)
- return ProcessOutgoingMessages();
- return true;
-}
-
-bool Channel::ChannelImpl::ProcessIncomingMessages() {
- ssize_t bytes_read = 0;
-
- struct msghdr msg = {0};
- struct iovec iov = {input_buf_, Channel::kReadBufferSize};
-
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_control = input_cmsg_buf_;
-
- for (;;) {
- msg.msg_controllen = sizeof(input_cmsg_buf_);
-
- if (bytes_read == 0) {
- if (pipe_ == -1)
- return false;
-
- // Read from pipe.
- // recvmsg() returns 0 if the connection has closed or EAGAIN if no data
- // is waiting on the pipe.
- do {
- bytes_read = recvmsg(pipe_, &msg, MSG_DONTWAIT);
- } while (bytes_read == -1 && errno == EINTR);
-
- if (bytes_read < 0) {
- if (errno == EAGAIN) {
- return true;
- } else {
- LOG(ERROR) << "pipe error (" << pipe_ << "): " << strerror(errno);
- return false;
- }
- } else if (bytes_read == 0) {
- // The pipe has closed...
- Close();
- return false;
- }
- }
- DCHECK(bytes_read);
-
- if (client_pipe_ != -1) {
- Singleton<PipeMap>()->Remove(pipe_name_);
- close(client_pipe_);
- client_pipe_ = -1;
- }
-
- // a pointer to an array of |num_wire_fds| file descriptors from the read
- const int* wire_fds = NULL;
- unsigned num_wire_fds = 0;
-
- // walk the list of control messages and, if we find an array of file
- // descriptors, save a pointer to the array
-
- // This next if statement is to work around an OSX issue where
- // CMSG_FIRSTHDR will return non-NULL in the case that controllen == 0.
- // Here's a test case:
- //
- // int main() {
- // struct msghdr msg;
- // msg.msg_control = &msg;
- // msg.msg_controllen = 0;
- // if (CMSG_FIRSTHDR(&msg))
- // printf("Bug found!\n");
- // }
- if (msg.msg_controllen > 0) {
- // On OSX, CMSG_FIRSTHDR doesn't handle the case where controllen is 0
- // and will return a pointer into nowhere.
- for (struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg); cmsg;
- cmsg = CMSG_NXTHDR(&msg, cmsg)) {
- if (cmsg->cmsg_level == SOL_SOCKET &&
- cmsg->cmsg_type == SCM_RIGHTS) {
- const unsigned payload_len = cmsg->cmsg_len - CMSG_LEN(0);
- DCHECK(payload_len % sizeof(int) == 0);
- wire_fds = reinterpret_cast<int*>(CMSG_DATA(cmsg));
- num_wire_fds = payload_len / 4;
-
- if (msg.msg_flags & MSG_CTRUNC) {
- LOG(ERROR) << "SCM_RIGHTS message was truncated"
- << " cmsg_len:" << cmsg->cmsg_len
- << " fd:" << pipe_;
- for (unsigned i = 0; i < num_wire_fds; ++i)
- close(wire_fds[i]);
- return false;
- }
- break;
- }
- }
- }
-
- // Process messages from input buffer.
- const char *p;
- const char *end;
- if (input_overflow_buf_.empty()) {
- p = input_buf_;
- end = p + bytes_read;
- } else {
- if (input_overflow_buf_.size() >
- static_cast<size_t>(kMaximumMessageSize - bytes_read)) {
- input_overflow_buf_.clear();
- LOG(ERROR) << "IPC message is too big";
- return false;
- }
- input_overflow_buf_.append(input_buf_, bytes_read);
- p = input_overflow_buf_.data();
- end = p + input_overflow_buf_.size();
- }
-
- // A pointer to an array of |num_fds| file descriptors which includes any
- // fds that have spilled over from a previous read.
- const int* fds;
- unsigned num_fds;
- unsigned fds_i = 0; // the index of the first unused descriptor
-
- if (input_overflow_fds_.empty()) {
- fds = wire_fds;
- num_fds = num_wire_fds;
- } else {
- const size_t prev_size = input_overflow_fds_.size();
- input_overflow_fds_.resize(prev_size + num_wire_fds);
- memcpy(&input_overflow_fds_[prev_size], wire_fds,
- num_wire_fds * sizeof(int));
- fds = &input_overflow_fds_[0];
- num_fds = input_overflow_fds_.size();
- }
-
- while (p < end) {
- const char* message_tail = Message::FindNext(p, end);
- if (message_tail) {
- int len = static_cast<int>(message_tail - p);
- Message m(p, len);
- if (m.header()->num_fds) {
- // the message has file descriptors
- const char* error = NULL;
- if (m.header()->num_fds > num_fds - fds_i) {
- // the message has been completely received, but we didn't get
- // enough file descriptors.
- error = "Message needs unreceived descriptors";
- }
-
- if (m.header()->num_fds >
- FileDescriptorSet::MAX_DESCRIPTORS_PER_MESSAGE) {
- // There are too many descriptors in this message
- error = "Message requires an excessive number of descriptors";
- }
-
- if (error) {
- LOG(WARNING) << error
- << " channel:" << this
- << " message-type:" << m.type()
- << " header()->num_fds:" << m.header()->num_fds
- << " num_fds:" << num_fds
- << " fds_i:" << fds_i;
- // close the existing file descriptors so that we don't leak them
- for (unsigned i = fds_i; i < num_fds; ++i)
- close(fds[i]);
- input_overflow_fds_.clear();
- // abort the connection
- return false;
- }
-
- m.file_descriptor_set()->SetDescriptors(
- &fds[fds_i], m.header()->num_fds);
- fds_i += m.header()->num_fds;
- }
-#ifdef IPC_MESSAGE_DEBUG_EXTRA
- DLOG(INFO) << "received message on channel @" << this <<
- " with type " << m.type();
-#endif
- if (m.routing_id() == MSG_ROUTING_NONE &&
- m.type() == HELLO_MESSAGE_TYPE) {
- // The Hello message contains only the process id.
- listener_->OnChannelConnected(MessageIterator(m).NextInt());
- } else {
- listener_->OnMessageReceived(m);
- }
- p = message_tail;
- } else {
- // Last message is partial.
- break;
- }
- }
- input_overflow_buf_.assign(p, end - p);
- input_overflow_fds_ = std::vector<int>(&fds[fds_i], &fds[num_fds]);
-
- // When the input data buffer is empty, the overflow fds should be too. If
- // this is not the case, we probably have a rogue renderer which is trying
- // to fill our descriptor table.
- if (input_overflow_buf_.empty() && !input_overflow_fds_.empty()) {
- // We close these descriptors in Close()
- return false;
- }
-
- bytes_read = 0; // Get more data.
- }
-
- return true;
-}
-
-bool Channel::ChannelImpl::ProcessOutgoingMessages() {
- DCHECK(!waiting_connect_); // Why are we trying to send messages if there's
- // no connection?
- is_blocked_on_write_ = false;
-
- if (output_queue_.empty())
- return true;
-
- if (pipe_ == -1)
- return false;
-
- // Write out all the messages we can till the write blocks or there are no
- // more outgoing messages.
- while (!output_queue_.empty()) {
- Message* msg = output_queue_.front();
-
- size_t amt_to_write = msg->size() - message_send_bytes_written_;
- DCHECK(amt_to_write != 0);
- const char *out_bytes = reinterpret_cast<const char*>(msg->data()) +
- message_send_bytes_written_;
- ssize_t bytes_written = -1;
- do {
- struct msghdr msgh = {0};
- struct iovec iov = {const_cast<char*>(out_bytes), amt_to_write};
- msgh.msg_iov = &iov;
- msgh.msg_iovlen = 1;
- char buf[CMSG_SPACE(
- sizeof(int[FileDescriptorSet::MAX_DESCRIPTORS_PER_MESSAGE]))];
-
- if (message_send_bytes_written_ == 0 &&
- !msg->file_descriptor_set()->empty()) {
- // This is the first chunk of a message which has descriptors to send
- struct cmsghdr *cmsg;
- const unsigned num_fds = msg->file_descriptor_set()->size();
-
- DCHECK_LE(num_fds, FileDescriptorSet::MAX_DESCRIPTORS_PER_MESSAGE);
-
- msgh.msg_control = buf;
- msgh.msg_controllen = CMSG_SPACE(sizeof(int) * num_fds);
- cmsg = CMSG_FIRSTHDR(&msgh);
- cmsg->cmsg_level = SOL_SOCKET;
- cmsg->cmsg_type = SCM_RIGHTS;
- cmsg->cmsg_len = CMSG_LEN(sizeof(int) * num_fds);
- msg->file_descriptor_set()->GetDescriptors(
- reinterpret_cast<int*>(CMSG_DATA(cmsg)));
- msgh.msg_controllen = cmsg->cmsg_len;
-
- msg->header()->num_fds = num_fds;
- }
-
- bytes_written = sendmsg(pipe_, &msgh, MSG_DONTWAIT);
- if (bytes_written > 0)
- msg->file_descriptor_set()->CommitAll();
- } while (bytes_written == -1 && errno == EINTR);
-
- if (bytes_written < 0 && errno != EAGAIN) {
- LOG(ERROR) << "pipe error: " << strerror(errno);
- return false;
- }
-
- if (static_cast<size_t>(bytes_written) != amt_to_write) {
- if (bytes_written > 0) {
- // If write() fails with EAGAIN then bytes_written will be -1.
- message_send_bytes_written_ += bytes_written;
- }
-
- // Tell libevent to call us back once things are unblocked.
- is_blocked_on_write_ = true;
- MessageLoopForIO::current()->WatchFileDescriptor(
- pipe_,
- false, // One shot
- MessageLoopForIO::WATCH_WRITE,
- &write_watcher_,
- this);
- return true;
- } else {
- message_send_bytes_written_ = 0;
-
- // Message sent OK!
-#ifdef IPC_MESSAGE_DEBUG_EXTRA
- DLOG(INFO) << "sent message @" << msg << " on channel @" << this <<
- " with type " << msg->type();
-#endif
- output_queue_.pop();
- delete msg;
- }
- }
- return true;
-}
-
-bool Channel::ChannelImpl::Send(Message* message) {
- Counters::ipc_send_counter().Increment();
-#ifdef IPC_MESSAGE_DEBUG_EXTRA
- DLOG(INFO) << "sending message @" << message << " on channel @" << this
- << " with type " << message->type()
- << " (" << output_queue_.size() << " in queue)";
-#endif
-
-#ifdef IPC_MESSAGE_LOG_ENABLED
- Logging::current()->OnSendMessage(message, L"");
-#endif
-
- output_queue_.push(message);
- if (!waiting_connect_) {
- if (!is_blocked_on_write_) {
- if (!ProcessOutgoingMessages())
- return false;
- }
- }
-
- return true;
-}
-
-void Channel::ChannelImpl::GetClientFileDescriptorMapping(int *src_fd,
- int *dest_fd) {
- DCHECK(mode_ == MODE_SERVER);
- *src_fd = client_pipe_;
- *dest_fd = kClientChannelFd;
-}
-
-void Channel::ChannelImpl::OnClientConnected() {
- // WARNING: this isn't actually called when a client connects.
- DCHECK(mode_ == MODE_SERVER);
-}
-
-// Called by libevent when we can read from th pipe without blocking.
-void Channel::ChannelImpl::OnFileCanReadWithoutBlocking(int fd) {
- bool send_server_hello_msg = false;
- if (waiting_connect_ && mode_ == MODE_SERVER) {
- // In the case of a socketpair() the server starts listening on its end
- // of the pipe in Connect().
- DCHECK(uses_fifo_);
-
- if (!ServerAcceptFifoConnection(server_listen_pipe_, &pipe_)) {
- Close();
- }
-
- // No need to watch the listening socket any longer since only one client
- // can connect. So unregister with libevent.
- server_listen_connection_watcher_.StopWatchingFileDescriptor();
-
- // Start watching our end of the socket.
- MessageLoopForIO::current()->WatchFileDescriptor(
- pipe_,
- true,
- MessageLoopForIO::WATCH_READ,
- &read_watcher_,
- this);
-
- waiting_connect_ = false;
- send_server_hello_msg = true;
- }
-
- if (!waiting_connect_ && fd == pipe_) {
- if (!ProcessIncomingMessages()) {
- Close();
- listener_->OnChannelError();
- }
- }
-
- // If we're a server and handshaking, then we want to make sure that we
- // only send our handshake message after we've processed the client's.
- // This gives us a chance to kill the client if the incoming handshake
- // is invalid.
- if (send_server_hello_msg) {
- // This should be our first write so there's no chance we can block here...
- DCHECK(is_blocked_on_write_ == false);
- ProcessOutgoingMessages();
- }
-}
-
-// Called by libevent when we can write to the pipe without blocking.
-void Channel::ChannelImpl::OnFileCanWriteWithoutBlocking(int fd) {
- if (!ProcessOutgoingMessages()) {
- Close();
- listener_->OnChannelError();
- }
-}
-
-void Channel::ChannelImpl::Close() {
- // Close can be called multiple time, so we need to make sure we're
- // idempotent.
-
- // Unregister libevent for the listening socket and close it.
- server_listen_connection_watcher_.StopWatchingFileDescriptor();
-
- if (server_listen_pipe_ != -1) {
- close(server_listen_pipe_);
- server_listen_pipe_ = -1;
- }
-
- // Unregister libevent for the FIFO and close it.
- read_watcher_.StopWatchingFileDescriptor();
- write_watcher_.StopWatchingFileDescriptor();
- if (pipe_ != -1) {
- close(pipe_);
- pipe_ = -1;
- }
- if (client_pipe_ != -1) {
- Singleton<PipeMap>()->Remove(pipe_name_);
- close(client_pipe_);
- client_pipe_ = -1;
- }
-
- // Unlink the FIFO
- unlink(pipe_name_.c_str());
-
- while (!output_queue_.empty()) {
- Message* m = output_queue_.front();
- output_queue_.pop();
- delete m;
- }
-
- // Close any outstanding, received file descriptors
- for (std::vector<int>::iterator
- i = input_overflow_fds_.begin(); i != input_overflow_fds_.end(); ++i) {
- close(*i);
- }
- input_overflow_fds_.clear();
-}
-
-//------------------------------------------------------------------------------
-// Channel's methods simply call through to ChannelImpl.
-Channel::Channel(const std::wstring& channel_id, Mode mode,
- Listener* listener)
- : channel_impl_(new ChannelImpl(channel_id, mode, listener)) {
-}
-
-Channel::~Channel() {
- delete channel_impl_;
-}
-
-bool Channel::Connect() {
- return channel_impl_->Connect();
-}
-
-void Channel::Close() {
- channel_impl_->Close();
-}
-
-void Channel::set_listener(Listener* listener) {
- channel_impl_->set_listener(listener);
-}
-
-bool Channel::Send(Message* message) {
- return channel_impl_->Send(message);
-}
-
-void Channel::GetClientFileDescriptorMapping(int *src_fd, int *dest_fd) {
- return channel_impl_->GetClientFileDescriptorMapping(src_fd, dest_fd);
-}
-
-void Channel::OnClientConnected() {
- return channel_impl_->OnClientConnected();
-}
-
-
-} // namespace IPC
diff --git a/ipc/ipc_channel_posix.h b/ipc/ipc_channel_posix.h
deleted file mode 100644
index 53fba1b9..0000000
--- a/ipc/ipc_channel_posix.h
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright (c) 2008 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 IPC_IPC_CHANNEL_POSIX_H_
-#define IPC_IPC_CHANNEL_POSIX_H_
-
-#include "ipc/ipc_channel.h"
-
-#include <sys/socket.h> // for CMSG macros
-
-#include <queue>
-#include <string>
-#include <vector>
-
-#include "base/message_loop.h"
-#include "ipc/file_descriptor_set_posix.h"
-
-namespace IPC {
-
-class Channel::ChannelImpl : public MessageLoopForIO::Watcher {
- public:
- // Mirror methods of Channel, see ipc_channel.h for description.
- ChannelImpl(const std::wstring& channel_id, Mode mode, Listener* listener);
- ~ChannelImpl() { Close(); }
- bool Connect();
- void Close();
- void set_listener(Listener* listener) { listener_ = listener; }
- bool Send(Message* message);
- void GetClientFileDescriptorMapping(int *src_fd, int *dest_fd);
- void OnClientConnected();
-
- private:
- const std::wstring PipeName(const std::wstring& channel_id) const;
- bool CreatePipe(const std::wstring& channel_id, Mode mode);
-
- bool ProcessIncomingMessages();
- bool ProcessOutgoingMessages();
-
- void OnFileCanReadWithoutBlocking(int fd);
- void OnFileCanWriteWithoutBlocking(int fd);
-
- Mode mode_;
-
- // After accepting one client connection on our server socket we want to
- // stop listening.
- MessageLoopForIO::FileDescriptorWatcher server_listen_connection_watcher_;
- MessageLoopForIO::FileDescriptorWatcher read_watcher_;
- MessageLoopForIO::FileDescriptorWatcher write_watcher_;
-
- // Indicates whether we're currently blocked waiting for a write to complete.
- bool is_blocked_on_write_;
-
- // If sending a message blocks then we use this variable
- // to keep track of where we are.
- size_t message_send_bytes_written_;
-
- // If the kTestingChannelID flag is specified, we use a FIFO instead of
- // a socketpair().
- bool uses_fifo_;
-
- int server_listen_pipe_;
- int pipe_;
- int client_pipe_; // The client end of our socketpair().
- std::string pipe_name_;
-
- Listener* listener_;
-
- // Messages to be sent are queued here.
- std::queue<Message*> output_queue_;
-
- // We read from the pipe into this buffer
- char input_buf_[Channel::kReadBufferSize];
-
- enum {
- // We assume a worst case: kReadBufferSize bytes of messages, where each
- // message has no payload and a full complement of descriptors.
- MAX_READ_FDS = (Channel::kReadBufferSize / sizeof(IPC::Message::Header)) *
- FileDescriptorSet::MAX_DESCRIPTORS_PER_MESSAGE,
- };
-
- // This is a control message buffer large enough to hold kMaxReadFDs
-#if defined(OS_MACOSX)
- // TODO(agl): OSX appears to have non-constant CMSG macros!
- char input_cmsg_buf_[1024];
-#else
- char input_cmsg_buf_[CMSG_SPACE(sizeof(int) * MAX_READ_FDS)];
-#endif
-
- // Large messages that span multiple pipe buffers, get built-up using
- // this buffer.
- std::string input_overflow_buf_;
- std::vector<int> input_overflow_fds_;
-
- // In server-mode, we have to wait for the client to connect before we
- // can begin reading. We make use of the input_state_ when performing
- // the connect operation in overlapped mode.
- bool waiting_connect_;
-
- // This flag is set when processing incoming messages. It is used to
- // avoid recursing through ProcessIncomingMessages, which could cause
- // problems. TODO(darin): make this unnecessary
- bool processing_incoming_;
-
- ScopedRunnableMethodFactory<ChannelImpl> factory_;
-
- DISALLOW_COPY_AND_ASSIGN(ChannelImpl);
-};
-
-} // namespace IPC
-
-#endif // IPC_IPC_CHANNEL_POSIX_H_
diff --git a/ipc/ipc_channel_proxy.cc b/ipc/ipc_channel_proxy.cc
deleted file mode 100644
index a07c677..0000000
--- a/ipc/ipc_channel_proxy.cc
+++ /dev/null
@@ -1,305 +0,0 @@
-// Copyright (c) 2006-2008 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 "base/message_loop.h"
-#include "base/thread.h"
-#include "ipc/ipc_channel_proxy.h"
-#include "ipc/ipc_logging.h"
-#include "ipc/ipc_message_utils.h"
-
-namespace IPC {
-
-//-----------------------------------------------------------------------------
-
-ChannelProxy::Context::Context(Channel::Listener* listener,
- MessageFilter* filter,
- MessageLoop* ipc_message_loop)
- : listener_message_loop_(MessageLoop::current()),
- listener_(listener),
- ipc_message_loop_(ipc_message_loop),
- channel_(NULL),
- peer_pid_(0),
- channel_connected_called_(false) {
- if (filter)
- filters_.push_back(filter);
-}
-
-void ChannelProxy::Context::CreateChannel(const std::wstring& id,
- const Channel::Mode& mode) {
- DCHECK(channel_ == NULL);
- channel_id_ = id;
- channel_ = new Channel(id, mode, this);
-}
-
-bool ChannelProxy::Context::TryFilters(const Message& message) {
-#ifdef IPC_MESSAGE_LOG_ENABLED
- Logging* logger = Logging::current();
- if (logger->Enabled())
- logger->OnPreDispatchMessage(message);
-#endif
-
- for (size_t i = 0; i < filters_.size(); ++i) {
- if (filters_[i]->OnMessageReceived(message)) {
-#ifdef IPC_MESSAGE_LOG_ENABLED
- if (logger->Enabled())
- logger->OnPostDispatchMessage(message, channel_id_);
-#endif
- return true;
- }
- }
- return false;
-}
-
-// Called on the IPC::Channel thread
-void ChannelProxy::Context::OnMessageReceived(const Message& message) {
- // First give a chance to the filters to process this message.
- if (!TryFilters(message))
- OnMessageReceivedNoFilter(message);
-}
-
-// Called on the IPC::Channel thread
-void ChannelProxy::Context::OnMessageReceivedNoFilter(const Message& message) {
- // NOTE: This code relies on the listener's message loop not going away while
- // this thread is active. That should be a reasonable assumption, but it
- // feels risky. We may want to invent some more indirect way of referring to
- // a MessageLoop if this becomes a problem.
- listener_message_loop_->PostTask(FROM_HERE, NewRunnableMethod(
- this, &Context::OnDispatchMessage, message));
-}
-
-// Called on the IPC::Channel thread
-void ChannelProxy::Context::OnChannelConnected(int32 peer_pid) {
- peer_pid_ = peer_pid;
- for (size_t i = 0; i < filters_.size(); ++i)
- filters_[i]->OnChannelConnected(peer_pid);
-
- // See above comment about using listener_message_loop_ here.
- listener_message_loop_->PostTask(FROM_HERE, NewRunnableMethod(
- this, &Context::OnDispatchConnected));
-}
-
-// Called on the IPC::Channel thread
-void ChannelProxy::Context::OnChannelError() {
- // See above comment about using listener_message_loop_ here.
- listener_message_loop_->PostTask(FROM_HERE, NewRunnableMethod(
- this, &Context::OnDispatchError));
-}
-
-// Called on the IPC::Channel thread
-void ChannelProxy::Context::OnChannelOpened() {
- DCHECK(channel_ != NULL);
-
- // Assume a reference to ourselves on behalf of this thread. This reference
- // will be released when we are closed.
- AddRef();
-
- if (!channel_->Connect()) {
- OnChannelError();
- return;
- }
-
- for (size_t i = 0; i < filters_.size(); ++i)
- filters_[i]->OnFilterAdded(channel_);
-}
-
-// Called on the IPC::Channel thread
-void ChannelProxy::Context::OnChannelClosed() {
- // It's okay for IPC::ChannelProxy::Close to be called more than once, which
- // would result in this branch being taken.
- if (!channel_)
- return;
-
- for (size_t i = 0; i < filters_.size(); ++i) {
- filters_[i]->OnChannelClosing();
- filters_[i]->OnFilterRemoved();
- }
-
- // We don't need the filters anymore.
- filters_.clear();
-
- delete channel_;
- channel_ = NULL;
-
- // Balance with the reference taken during startup. This may result in
- // self-destruction.
- Release();
-}
-
-// Called on the IPC::Channel thread
-void ChannelProxy::Context::OnSendMessage(Message* message) {
- if (!channel_->Send(message))
- OnChannelError();
-}
-
-// Called on the IPC::Channel thread
-void ChannelProxy::Context::OnAddFilter(MessageFilter* filter) {
- filters_.push_back(filter);
-
- // If the channel has already been created, then we need to send this message
- // so that the filter gets access to the Channel.
- if (channel_)
- filter->OnFilterAdded(channel_);
-
- // Balances the AddRef in ChannelProxy::AddFilter.
- filter->Release();
-}
-
-// Called on the IPC::Channel thread
-void ChannelProxy::Context::OnRemoveFilter(MessageFilter* filter) {
- for (size_t i = 0; i < filters_.size(); ++i) {
- if (filters_[i].get() == filter) {
- filter->OnFilterRemoved();
- filters_.erase(filters_.begin() + i);
- return;
- }
- }
-
- NOTREACHED() << "filter to be removed not found";
-}
-
-// Called on the listener's thread
-void ChannelProxy::Context::OnDispatchMessage(const Message& message) {
- if (!listener_)
- return;
-
- OnDispatchConnected();
-
-#ifdef IPC_MESSAGE_LOG_ENABLED
- Logging* logger = Logging::current();
- if (message.type() == IPC_LOGGING_ID) {
- logger->OnReceivedLoggingMessage(message);
- return;
- }
-
- if (logger->Enabled())
- logger->OnPreDispatchMessage(message);
-#endif
-
- listener_->OnMessageReceived(message);
-
-#ifdef IPC_MESSAGE_LOG_ENABLED
- if (logger->Enabled())
- logger->OnPostDispatchMessage(message, channel_id_);
-#endif
-}
-
-// Called on the listener's thread
-void ChannelProxy::Context::OnDispatchConnected() {
- if (channel_connected_called_)
- return;
-
- channel_connected_called_ = true;
- if (listener_)
- listener_->OnChannelConnected(peer_pid_);
-}
-
-// Called on the listener's thread
-void ChannelProxy::Context::OnDispatchError() {
- if (listener_)
- listener_->OnChannelError();
-}
-
-//-----------------------------------------------------------------------------
-
-ChannelProxy::ChannelProxy(const std::wstring& channel_id, Channel::Mode mode,
- Channel::Listener* listener, MessageFilter* filter,
- MessageLoop* ipc_thread)
- : context_(new Context(listener, filter, ipc_thread)) {
- Init(channel_id, mode, ipc_thread, true);
-}
-
-ChannelProxy::ChannelProxy(const std::wstring& channel_id, Channel::Mode mode,
- MessageLoop* ipc_thread, Context* context,
- bool create_pipe_now)
- : context_(context) {
- Init(channel_id, mode, ipc_thread, create_pipe_now);
-}
-
-void ChannelProxy::Init(const std::wstring& channel_id, Channel::Mode mode,
- MessageLoop* ipc_thread_loop, bool create_pipe_now) {
- if (create_pipe_now) {
- // Create the channel immediately. This effectively sets up the
- // low-level pipe so that the client can connect. Without creating
- // the pipe immediately, it is possible for a listener to attempt
- // to connect and get an error since the pipe doesn't exist yet.
- context_->CreateChannel(channel_id, mode);
- } else {
-#if defined(OS_POSIX)
- // TODO(playmobil): On POSIX, IPC::Channel uses a socketpair(), one side of
- // which needs to be mapped into the child process' address space.
- // To know the value of the client side FD we need to have already
- // created a socketpair which currently occurs in IPC::Channel's
- // constructor.
- // If we lazilly construct the IPC::Channel then the caller has no way
- // of knowing the FD #.
- //
- // We can solve this either by having the Channel's creation launch the
- // subprocess itself or by creating the socketpair() externally.
- NOTIMPLEMENTED();
-#endif // defined(OS_POSIX)
- context_->ipc_message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
- context_.get(), &Context::CreateChannel, channel_id, mode));
- }
-
- // complete initialization on the background thread
- context_->ipc_message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
- context_.get(), &Context::OnChannelOpened));
-}
-
-void ChannelProxy::Close() {
- // Clear the backpointer to the listener so that any pending calls to
- // Context::OnDispatchMessage or OnDispatchError will be ignored. It is
- // possible that the channel could be closed while it is receiving messages!
- context_->Clear();
-
- if (context_->ipc_message_loop()) {
- context_->ipc_message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
- context_.get(), &Context::OnChannelClosed));
- }
-}
-
-bool ChannelProxy::Send(Message* message) {
-#ifdef IPC_MESSAGE_LOG_ENABLED
- Logging::current()->OnSendMessage(message, context_->channel_id());
-#endif
-
- context_->ipc_message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
- context_.get(), &Context::OnSendMessage, message));
- return true;
-}
-
-void ChannelProxy::AddFilter(MessageFilter* filter) {
- // We want to addref the filter to prevent it from
- // being destroyed before the OnAddFilter call is invoked.
- filter->AddRef();
- context_->ipc_message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
- context_.get(), &Context::OnAddFilter, filter));
-}
-
-void ChannelProxy::RemoveFilter(MessageFilter* filter) {
- context_->ipc_message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
- context_.get(), &Context::OnRemoveFilter, filter));
-}
-
-#if defined(OS_POSIX)
-// See the TODO regarding lazy initialization of the channel in
-// ChannelProxy::Init().
-// We assume that IPC::Channel::GetClientFileDescriptorMapping() is thread-safe.
-void ChannelProxy::GetClientFileDescriptorMapping(int *src_fd, int *dest_fd) {
- Channel *channel = context_.get()->channel_;
- DCHECK(channel); // Channel must have been created first.
- channel->GetClientFileDescriptorMapping(src_fd, dest_fd);
-}
-
-// We assume that IP::Channel::OnClientConnected() is thread-safe.
-void ChannelProxy::OnClientConnected() {
- Channel *channel = context_.get()->channel_;
- DCHECK(channel); // Channel must have been created first.
- channel->OnClientConnected();
-}
-#endif
-
-//-----------------------------------------------------------------------------
-
-} // namespace IPC
diff --git a/ipc/ipc_channel_proxy.h b/ipc/ipc_channel_proxy.h
deleted file mode 100644
index 7f78a7e..0000000
--- a/ipc/ipc_channel_proxy.h
+++ /dev/null
@@ -1,206 +0,0 @@
-// Copyright (c) 2006-2008 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 IPC_IPC_CHANNEL_PROXY_H__
-#define IPC_IPC_CHANNEL_PROXY_H__
-
-#include <vector>
-#include "base/lock.h"
-#include "base/ref_counted.h"
-#include "ipc/ipc_channel.h"
-
-class MessageLoop;
-
-namespace IPC {
-
-//-----------------------------------------------------------------------------
-// IPC::ChannelProxy
-//
-// This class is a helper class that is useful when you wish to run an IPC
-// channel on a background thread. It provides you with the option of either
-// handling IPC messages on that background thread or having them dispatched to
-// your main thread (the thread on which the IPC::ChannelProxy is created).
-//
-// The API for an IPC::ChannelProxy is very similar to that of an IPC::Channel.
-// When you send a message to an IPC::ChannelProxy, the message is routed to
-// the background thread, where it is then passed to the IPC::Channel's Send
-// method. This means that you can send a message from your thread and your
-// message will be sent over the IPC channel when possible instead of being
-// delayed until your thread returns to its message loop. (Often IPC messages
-// will queue up on the IPC::Channel when there is a lot of traffic, and the
-// channel will not get cycles to flush its message queue until the thread, on
-// which it is running, returns to its message loop.)
-//
-// An IPC::ChannelProxy can have a MessageFilter associated with it, which will
-// be notified of incoming messages on the IPC::Channel's thread. This gives
-// the consumer of IPC::ChannelProxy the ability to respond to incoming
-// messages on this background thread instead of on their own thread, which may
-// be bogged down with other processing. The result can be greatly improved
-// latency for messages that can be handled on a background thread.
-//
-// The consumer of IPC::ChannelProxy is responsible for allocating the Thread
-// instance where the IPC::Channel will be created and operated.
-//
-class ChannelProxy : public Message::Sender {
- public:
- // A class that receives messages on the thread where the IPC channel is
- // running. It can choose to prevent the default action for an IPC message.
- class MessageFilter : public base::RefCountedThreadSafe<MessageFilter> {
- public:
- virtual ~MessageFilter() {}
-
- // Called on the background thread to provide the filter with access to the
- // channel. Called when the IPC channel is initialized or when AddFilter
- // is called if the channel is already initialized.
- virtual void OnFilterAdded(Channel* channel) {}
-
- // Called on the background thread when the filter has been removed from
- // the ChannelProxy and when the Channel is closing. After a filter is
- // removed, it will not be called again.
- virtual void OnFilterRemoved() {}
-
- // Called to inform the filter that the IPC channel is connected and we
- // have received the internal Hello message from the peer.
- virtual void OnChannelConnected(int32 peer_pid) {}
-
- // Called to inform the filter that the IPC channel will be destroyed.
- // OnFilterRemoved is called immediately after this.
- virtual void OnChannelClosing() {}
-
- // Return true to indicate that the message was handled, or false to let
- // the message be handled in the default way.
- virtual bool OnMessageReceived(const Message& message) {
- return false;
- }
- };
-
- // Initializes a channel proxy. The channel_id and mode parameters are
- // passed directly to the underlying IPC::Channel. The listener is called on
- // the thread that creates the ChannelProxy. The filter's OnMessageReceived
- // method is called on the thread where the IPC::Channel is running. The
- // filter may be null if the consumer is not interested in handling messages
- // on the background thread. Any message not handled by the filter will be
- // dispatched to the listener. The given message loop indicates where the
- // IPC::Channel should be created.
- ChannelProxy(const std::wstring& channel_id, Channel::Mode mode,
- Channel::Listener* listener, MessageFilter* filter,
- MessageLoop* ipc_thread_loop);
-
- ~ChannelProxy() {
- Close();
- }
-
- // Close the IPC::Channel. This operation completes asynchronously, once the
- // background thread processes the command to close the channel. It is ok to
- // call this method multiple times. Redundant calls are ignored.
- //
- // WARNING: The MessageFilter object held by the ChannelProxy is also
- // released asynchronously, and it may in fact have its final reference
- // released on the background thread. The caller should be careful to deal
- // with / allow for this possibility.
- void Close();
-
- // Send a message asynchronously. The message is routed to the background
- // thread where it is passed to the IPC::Channel's Send method.
- virtual bool Send(Message* message);
-
- // Used to intercept messages as they are received on the background thread.
- //
- // Ordinarily, messages sent to the ChannelProxy are routed to the matching
- // listener on the worker thread. This API allows code to intercept messages
- // before they are sent to the worker thread.
- void AddFilter(MessageFilter* filter);
- void RemoveFilter(MessageFilter* filter);
-
-#if defined(OS_POSIX)
- // Calls through to the underlying channel's methods.
- // TODO(playmobil): For now this is only implemented in the case of
- // create_pipe_now = true, we need to figure this out for the latter case.
- void GetClientFileDescriptorMapping(int *src_fd, int *dest_fd);
- void OnClientConnected();
-#endif // defined(OS_POSIX)
-
- protected:
- class Context;
- // A subclass uses this constructor if it needs to add more information
- // to the internal state. If create_pipe_now is true, the pipe is created
- // immediately. Otherwise it's created on the IO thread.
- ChannelProxy(const std::wstring& channel_id, Channel::Mode mode,
- MessageLoop* ipc_thread_loop, Context* context,
- bool create_pipe_now);
-
- // Used internally to hold state that is referenced on the IPC thread.
- class Context : public base::RefCountedThreadSafe<Context>,
- public Channel::Listener {
- public:
- Context(Channel::Listener* listener, MessageFilter* filter,
- MessageLoop* ipc_thread);
- virtual ~Context() { }
- MessageLoop* ipc_message_loop() const { return ipc_message_loop_; }
- const std::wstring& channel_id() const { return channel_id_; }
-
- // Dispatches a message on the listener thread.
- void OnDispatchMessage(const Message& message);
-
- protected:
- // IPC::Channel::Listener methods:
- virtual void OnMessageReceived(const Message& message);
- virtual void OnChannelConnected(int32 peer_pid);
- virtual void OnChannelError();
-
- // Like OnMessageReceived but doesn't try the filters.
- void OnMessageReceivedNoFilter(const Message& message);
-
- // Gives the filters a chance at processing |message|.
- // Returns true if the message was processed, false otherwise.
- bool TryFilters(const Message& message);
-
- // Like Open and Close, but called on the IPC thread.
- virtual void OnChannelOpened();
- virtual void OnChannelClosed();
-
- // Called on the consumers thread when the ChannelProxy is closed. At that
- // point the consumer is telling us that they don't want to receive any
- // more messages, so we honor that wish by forgetting them!
- virtual void Clear() { listener_ = NULL; }
-
- private:
- friend class ChannelProxy;
- // Create the Channel
- void CreateChannel(const std::wstring& id, const Channel::Mode& mode);
-
- // Methods called via InvokeLater:
- void OnSendMessage(Message* message_ptr);
- void OnAddFilter(MessageFilter* filter);
- void OnRemoveFilter(MessageFilter* filter);
- void OnDispatchConnected();
- void OnDispatchError();
-
- MessageLoop* listener_message_loop_;
- Channel::Listener* listener_;
-
- // List of filters. This is only accessed on the IPC thread.
- std::vector<scoped_refptr<MessageFilter> > filters_;
- MessageLoop* ipc_message_loop_;
- Channel* channel_;
- std::wstring channel_id_;
- int peer_pid_;
- bool channel_connected_called_;
- };
-
- Context* context() { return context_; }
-
- private:
- void Init(const std::wstring& channel_id, Channel::Mode mode,
- MessageLoop* ipc_thread_loop, bool create_pipe_now);
-
- // By maintaining this indirection (ref-counted) to our internal state, we
- // can safely be destroyed while the background thread continues to do stuff
- // that involves this data.
- scoped_refptr<Context> context_;
-};
-
-} // namespace IPC
-
-#endif // IPC_IPC_CHANNEL_PROXY_H__
diff --git a/ipc/ipc_channel_win.cc b/ipc/ipc_channel_win.cc
deleted file mode 100644
index 950b140..0000000
--- a/ipc/ipc_channel_win.cc
+++ /dev/null
@@ -1,440 +0,0 @@
-// Copyright (c) 2006-2008 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 "ipc/ipc_channel_win.h"
-
-#include <windows.h>
-#include <sstream>
-
-#include "base/compiler_specific.h"
-#include "base/logging.h"
-#include "base/non_thread_safe.h"
-#include "base/win_util.h"
-#include "ipc/ipc_counters.h"
-#include "ipc/ipc_logging.h"
-#include "ipc/ipc_message_utils.h"
-
-namespace IPC {
-//------------------------------------------------------------------------------
-
-Channel::ChannelImpl::State::State(ChannelImpl* channel) : is_pending(false) {
- memset(&context.overlapped, 0, sizeof(context.overlapped));
- context.handler = channel;
-}
-
-Channel::ChannelImpl::State::~State() {
- COMPILE_ASSERT(!offsetof(Channel::ChannelImpl::State, context),
- starts_with_io_context);
-}
-
-//------------------------------------------------------------------------------
-
-Channel::ChannelImpl::ChannelImpl(const std::wstring& channel_id, Mode mode,
- Listener* listener)
- : ALLOW_THIS_IN_INITIALIZER_LIST(input_state_(this)),
- ALLOW_THIS_IN_INITIALIZER_LIST(output_state_(this)),
- pipe_(INVALID_HANDLE_VALUE),
- listener_(listener),
- waiting_connect_(mode == MODE_SERVER),
- processing_incoming_(false),
- ALLOW_THIS_IN_INITIALIZER_LIST(factory_(this)) {
- if (!CreatePipe(channel_id, mode)) {
- // The pipe may have been closed already.
- LOG(WARNING) << "Unable to create pipe named \"" << channel_id <<
- "\" in " << (mode == 0 ? "server" : "client") << " mode.";
- }
-}
-
-void Channel::ChannelImpl::Close() {
- if (thread_check_.get()) {
- DCHECK(thread_check_->CalledOnValidThread());
- }
-
- bool waited = false;
- if (input_state_.is_pending || output_state_.is_pending) {
- CancelIo(pipe_);
- waited = true;
- }
-
- // Closing the handle at this point prevents us from issuing more requests
- // form OnIOCompleted().
- if (pipe_ != INVALID_HANDLE_VALUE) {
- CloseHandle(pipe_);
- pipe_ = INVALID_HANDLE_VALUE;
- }
-
- // Make sure all IO has completed.
- base::Time start = base::Time::Now();
- while (input_state_.is_pending || output_state_.is_pending) {
- MessageLoopForIO::current()->WaitForIOCompletion(INFINITE, this);
- }
- if (waited) {
- // We want to see if we block the message loop for too long.
- UMA_HISTOGRAM_TIMES("AsyncIO.IPCChannelClose", base::Time::Now() - start);
- }
-
- while (!output_queue_.empty()) {
- Message* m = output_queue_.front();
- output_queue_.pop();
- delete m;
- }
-}
-
-bool Channel::ChannelImpl::Send(Message* message) {
- DCHECK(thread_check_->CalledOnValidThread());
- Counters::ipc_send_counter().Increment();
-#ifdef IPC_MESSAGE_DEBUG_EXTRA
- DLOG(INFO) << "sending message @" << message << " on channel @" << this
- << " with type " << message->type()
- << " (" << output_queue_.size() << " in queue)";
-#endif
-
-#ifdef IPC_MESSAGE_LOG_ENABLED
- Logging::current()->OnSendMessage(message, L"");
-#endif
-
- output_queue_.push(message);
- // ensure waiting to write
- if (!waiting_connect_) {
- if (!output_state_.is_pending) {
- if (!ProcessOutgoingMessages(NULL, 0))
- return false;
- }
- }
-
- return true;
-}
-
-const std::wstring Channel::ChannelImpl::PipeName(
- const std::wstring& channel_id) const {
- std::wostringstream ss;
- // XXX(darin): get application name from somewhere else
- ss << L"\\\\.\\pipe\\chrome." << channel_id;
- return ss.str();
-}
-
-bool Channel::ChannelImpl::CreatePipe(const std::wstring& channel_id,
- Mode mode) {
- DCHECK(pipe_ == INVALID_HANDLE_VALUE);
- const std::wstring pipe_name = PipeName(channel_id);
- if (mode == MODE_SERVER) {
- SECURITY_ATTRIBUTES security_attributes = {0};
- security_attributes.bInheritHandle = FALSE;
- security_attributes.nLength = sizeof(SECURITY_ATTRIBUTES);
- if (!win_util::GetLogonSessionOnlyDACL(
- reinterpret_cast<SECURITY_DESCRIPTOR**>(
- &security_attributes.lpSecurityDescriptor))) {
- NOTREACHED();
- }
-
- pipe_ = CreateNamedPipeW(pipe_name.c_str(),
- PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED |
- FILE_FLAG_FIRST_PIPE_INSTANCE,
- PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
- 1, // number of pipe instances
- // output buffer size (XXX tune)
- Channel::kReadBufferSize,
- // input buffer size (XXX tune)
- Channel::kReadBufferSize,
- 5000, // timeout in milliseconds (XXX tune)
- &security_attributes);
- LocalFree(security_attributes.lpSecurityDescriptor);
- } else {
- pipe_ = CreateFileW(pipe_name.c_str(),
- GENERIC_READ | GENERIC_WRITE,
- 0,
- NULL,
- OPEN_EXISTING,
- SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION |
- FILE_FLAG_OVERLAPPED,
- NULL);
- }
- if (pipe_ == INVALID_HANDLE_VALUE) {
- // If this process is being closed, the pipe may be gone already.
- LOG(WARNING) << "failed to create pipe: " << GetLastError();
- return false;
- }
-
- // Create the Hello message to be sent when Connect is called
- scoped_ptr<Message> m(new Message(MSG_ROUTING_NONE,
- HELLO_MESSAGE_TYPE,
- IPC::Message::PRIORITY_NORMAL));
- if (!m->WriteInt(GetCurrentProcessId())) {
- CloseHandle(pipe_);
- pipe_ = INVALID_HANDLE_VALUE;
- return false;
- }
-
- output_queue_.push(m.release());
- return true;
-}
-
-bool Channel::ChannelImpl::Connect() {
- DLOG(WARNING) << "Connect called twice";
-
- if (!thread_check_.get())
- thread_check_.reset(new NonThreadSafe());
-
- if (pipe_ == INVALID_HANDLE_VALUE)
- return false;
-
- MessageLoopForIO::current()->RegisterIOHandler(pipe_, this);
-
- // Check to see if there is a client connected to our pipe...
- if (waiting_connect_)
- ProcessConnection();
-
- if (!input_state_.is_pending) {
- // Complete setup asynchronously. By not setting input_state_.is_pending
- // to true, we indicate to OnIOCompleted that this is the special
- // initialization signal.
- MessageLoopForIO::current()->PostTask(FROM_HERE, factory_.NewRunnableMethod(
- &Channel::ChannelImpl::OnIOCompleted, &input_state_.context, 0, 0));
- }
-
- if (!waiting_connect_)
- ProcessOutgoingMessages(NULL, 0);
- return true;
-}
-
-bool Channel::ChannelImpl::ProcessConnection() {
- DCHECK(thread_check_->CalledOnValidThread());
- if (input_state_.is_pending)
- input_state_.is_pending = false;
-
- // Do we have a client connected to our pipe?
- if (INVALID_HANDLE_VALUE == pipe_)
- return false;
-
- BOOL ok = ConnectNamedPipe(pipe_, &input_state_.context.overlapped);
-
- DWORD err = GetLastError();
- if (ok) {
- // Uhm, the API documentation says that this function should never
- // return success when used in overlapped mode.
- NOTREACHED();
- return false;
- }
-
- switch (err) {
- case ERROR_IO_PENDING:
- input_state_.is_pending = true;
- break;
- case ERROR_PIPE_CONNECTED:
- waiting_connect_ = false;
- break;
- default:
- NOTREACHED();
- return false;
- }
-
- return true;
-}
-
-bool Channel::ChannelImpl::ProcessIncomingMessages(
- MessageLoopForIO::IOContext* context,
- DWORD bytes_read) {
- DCHECK(thread_check_->CalledOnValidThread());
- if (input_state_.is_pending) {
- input_state_.is_pending = false;
- DCHECK(context);
-
- if (!context || !bytes_read)
- return false;
- } else {
- // This happens at channel initialization.
- DCHECK(!bytes_read && context == &input_state_.context);
- }
-
- for (;;) {
- if (bytes_read == 0) {
- if (INVALID_HANDLE_VALUE == pipe_)
- return false;
-
- // Read from pipe...
- BOOL ok = ReadFile(pipe_,
- input_buf_,
- Channel::kReadBufferSize,
- &bytes_read,
- &input_state_.context.overlapped);
- if (!ok) {
- DWORD err = GetLastError();
- if (err == ERROR_IO_PENDING) {
- input_state_.is_pending = true;
- return true;
- }
- LOG(ERROR) << "pipe error: " << err;
- return false;
- }
- input_state_.is_pending = true;
- return true;
- }
- DCHECK(bytes_read);
-
- // Process messages from input buffer.
-
- const char* p, *end;
- if (input_overflow_buf_.empty()) {
- p = input_buf_;
- end = p + bytes_read;
- } else {
- if (input_overflow_buf_.size() > (kMaximumMessageSize - bytes_read)) {
- input_overflow_buf_.clear();
- LOG(ERROR) << "IPC message is too big";
- return false;
- }
- input_overflow_buf_.append(input_buf_, bytes_read);
- p = input_overflow_buf_.data();
- end = p + input_overflow_buf_.size();
- }
-
- while (p < end) {
- const char* message_tail = Message::FindNext(p, end);
- if (message_tail) {
- int len = static_cast<int>(message_tail - p);
- const Message m(p, len);
-#ifdef IPC_MESSAGE_DEBUG_EXTRA
- DLOG(INFO) << "received message on channel @" << this <<
- " with type " << m.type();
-#endif
- if (m.routing_id() == MSG_ROUTING_NONE &&
- m.type() == HELLO_MESSAGE_TYPE) {
- // The Hello message contains only the process id.
- listener_->OnChannelConnected(MessageIterator(m).NextInt());
- } else {
- listener_->OnMessageReceived(m);
- }
- p = message_tail;
- } else {
- // Last message is partial.
- break;
- }
- }
- input_overflow_buf_.assign(p, end - p);
-
- bytes_read = 0; // Get more data.
- }
-
- return true;
-}
-
-bool Channel::ChannelImpl::ProcessOutgoingMessages(
- MessageLoopForIO::IOContext* context,
- DWORD bytes_written) {
- DCHECK(!waiting_connect_); // Why are we trying to send messages if there's
- // no connection?
- DCHECK(thread_check_->CalledOnValidThread());
-
- if (output_state_.is_pending) {
- DCHECK(context);
- output_state_.is_pending = false;
- if (!context || bytes_written == 0) {
- DWORD err = GetLastError();
- LOG(ERROR) << "pipe error: " << err;
- return false;
- }
- // Message was sent.
- DCHECK(!output_queue_.empty());
- Message* m = output_queue_.front();
- output_queue_.pop();
- delete m;
- }
-
- if (output_queue_.empty())
- return true;
-
- if (INVALID_HANDLE_VALUE == pipe_)
- return false;
-
- // Write to pipe...
- Message* m = output_queue_.front();
- BOOL ok = WriteFile(pipe_,
- m->data(),
- m->size(),
- &bytes_written,
- &output_state_.context.overlapped);
- if (!ok) {
- DWORD err = GetLastError();
- if (err == ERROR_IO_PENDING) {
- output_state_.is_pending = true;
-
-#ifdef IPC_MESSAGE_DEBUG_EXTRA
- DLOG(INFO) << "sent pending message @" << m << " on channel @" <<
- this << " with type " << m->type();
-#endif
-
- return true;
- }
- LOG(ERROR) << "pipe error: " << err;
- return false;
- }
-
-#ifdef IPC_MESSAGE_DEBUG_EXTRA
- DLOG(INFO) << "sent message @" << m << " on channel @" << this <<
- " with type " << m->type();
-#endif
-
- output_state_.is_pending = true;
- return true;
-}
-
-void Channel::ChannelImpl::OnIOCompleted(MessageLoopForIO::IOContext* context,
- DWORD bytes_transfered, DWORD error) {
- bool ok;
- DCHECK(thread_check_->CalledOnValidThread());
- if (context == &input_state_.context) {
- if (waiting_connect_) {
- if (!ProcessConnection())
- return;
- // We may have some messages queued up to send...
- if (!output_queue_.empty() && !output_state_.is_pending)
- ProcessOutgoingMessages(NULL, 0);
- if (input_state_.is_pending)
- return;
- // else, fall-through and look for incoming messages...
- }
- // we don't support recursion through OnMessageReceived yet!
- DCHECK(!processing_incoming_);
- processing_incoming_ = true;
- ok = ProcessIncomingMessages(context, bytes_transfered);
- processing_incoming_ = false;
- } else {
- DCHECK(context == &output_state_.context);
- ok = ProcessOutgoingMessages(context, bytes_transfered);
- }
- if (!ok && INVALID_HANDLE_VALUE != pipe_) {
- // We don't want to re-enter Close().
- Close();
- listener_->OnChannelError();
- }
-}
-
-//------------------------------------------------------------------------------
-// Channel's methods simply call through to ChannelImpl.
-Channel::Channel(const std::wstring& channel_id, Mode mode,
- Listener* listener)
- : channel_impl_(new ChannelImpl(channel_id, mode, listener)) {
-}
-
-Channel::~Channel() {
- delete channel_impl_;
-}
-
-bool Channel::Connect() {
- return channel_impl_->Connect();
-}
-
-void Channel::Close() {
- channel_impl_->Close();
-}
-
-void Channel::set_listener(Listener* listener) {
- channel_impl_->set_listener(listener);
-}
-
-bool Channel::Send(Message* message) {
- return channel_impl_->Send(message);
-}
-
-} // namespace IPC
diff --git a/ipc/ipc_channel_win.h b/ipc/ipc_channel_win.h
deleted file mode 100644
index 998b7f8..0000000
--- a/ipc/ipc_channel_win.h
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright (c) 2008 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 IPC_IPC_CHANNEL_WIN_H_
-#define IPC_IPC_CHANNEL_WIN_H_
-
-#include "ipc/ipc_channel.h"
-
-#include <queue>
-#include <string>
-
-#include "base/message_loop.h"
-
-class NonThreadSafe;
-
-namespace IPC {
-
-class Channel::ChannelImpl : public MessageLoopForIO::IOHandler {
- public:
- // Mirror methods of Channel, see ipc_channel.h for description.
- ChannelImpl(const std::wstring& channel_id, Mode mode, Listener* listener);
- ~ChannelImpl() { Close(); }
- bool Connect();
- void Close();
- void set_listener(Listener* listener) { listener_ = listener; }
- bool Send(Message* message);
- private:
- const std::wstring PipeName(const std::wstring& channel_id) const;
- bool CreatePipe(const std::wstring& channel_id, Mode mode);
-
- bool ProcessConnection();
- bool ProcessIncomingMessages(MessageLoopForIO::IOContext* context,
- DWORD bytes_read);
- bool ProcessOutgoingMessages(MessageLoopForIO::IOContext* context,
- DWORD bytes_written);
-
- // MessageLoop::IOHandler implementation.
- virtual void OnIOCompleted(MessageLoopForIO::IOContext* context,
- DWORD bytes_transfered, DWORD error);
- private:
- struct State {
- explicit State(ChannelImpl* channel);
- ~State();
- MessageLoopForIO::IOContext context;
- bool is_pending;
- };
-
- State input_state_;
- State output_state_;
-
- HANDLE pipe_;
-
- Listener* listener_;
-
- // Messages to be sent are queued here.
- std::queue<Message*> output_queue_;
-
- // We read from the pipe into this buffer
- char input_buf_[Channel::kReadBufferSize];
-
- // Large messages that span multiple pipe buffers, get built-up using
- // this buffer.
- std::string input_overflow_buf_;
-
- // In server-mode, we have to wait for the client to connect before we
- // can begin reading. We make use of the input_state_ when performing
- // the connect operation in overlapped mode.
- bool waiting_connect_;
-
- // This flag is set when processing incoming messages. It is used to
- // avoid recursing through ProcessIncomingMessages, which could cause
- // problems. TODO(darin): make this unnecessary
- bool processing_incoming_;
-
- ScopedRunnableMethodFactory<ChannelImpl> factory_;
-
- scoped_ptr<NonThreadSafe> thread_check_;
-
- DISALLOW_COPY_AND_ASSIGN(ChannelImpl);
-};
-
-} // namespace IPC
-
-#endif // IPC_IPC_CHANNEL_WIN_H_
diff --git a/ipc/ipc_counters.cc b/ipc/ipc_counters.cc
deleted file mode 100644
index 29bf3b5..0000000
--- a/ipc/ipc_counters.cc
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2009 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 "ipc/ipc_counters.h"
-
-#include "base/stats_counters.h"
-
-namespace IPC {
-
-// Note: We use the construct-on-first-use pattern here, because we don't
-// want to fight with any static initializer ordering problems later.
-// The downside of this is that the objects don't ever get cleaned up.
-// But they are small and this is okay.
-
-// Note: Because these are constructed on-first-use, there is a slight
-// race condition - two threads could initialize the same counter.
-// If this happened, the stats table would still work just fine;
-// we'd leak the extraneous StatsCounter object once, and that
-// would be it. But these are small objects, so this is ok.
-
-StatsCounter& Counters::ipc_send_counter() {
- static StatsCounter* ctr = new StatsCounter("IPC.SendMsgCount");
- return *ctr;
-}
-
-} // namespace IPC
diff --git a/ipc/ipc_counters.h b/ipc/ipc_counters.h
deleted file mode 100644
index 647632a..0000000
--- a/ipc/ipc_counters.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) 2009 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.
-
-// Counters used within the browser.
-
-#ifndef IPC_COMMON_IPC_COUNTERS_H_
-#define IPC_COMMON_IPC_COUNTERS_H_
-
-class StatsCounter;
-
-namespace IPC {
-
-class Counters {
- public:
- // The number of messages sent on IPC channels.
- static StatsCounter& ipc_send_counter();
-};
-
-} // namespace IPC
-
-#endif // IPC_COMMON_IPC_COUNTERS_H_
diff --git a/ipc/ipc_fuzzing_tests.cc b/ipc/ipc_fuzzing_tests.cc
deleted file mode 100644
index 6b4f899..0000000
--- a/ipc/ipc_fuzzing_tests.cc
+++ /dev/null
@@ -1,435 +0,0 @@
-// Copyright (c) 2006-2008 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 <stdio.h>
-#include <iostream>
-#include <string>
-#include <sstream>
-
-#include "base/message_loop.h"
-#include "base/platform_thread.h"
-#include "base/process_util.h"
-#include "ipc/ipc_channel.h"
-#include "ipc/ipc_channel_proxy.h"
-#include "ipc/ipc_message_utils.h"
-#include "ipc/ipc_tests.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/multiprocess_func_list.h"
-
-TEST(IPCMessageIntegrity, ReadBeyondBufferStr) {
- //This was BUG 984408.
- uint32 v1 = kuint32max - 1;
- int v2 = 666;
- IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
- EXPECT_TRUE(m.WriteInt(v1));
- EXPECT_TRUE(m.WriteInt(v2));
-
- void* iter = NULL;
- std::string vs;
- EXPECT_FALSE(m.ReadString(&iter, &vs));
-}
-
-TEST(IPCMessageIntegrity, ReadBeyondBufferWStr) {
- //This was BUG 984408.
- uint32 v1 = kuint32max - 1;
- int v2 = 777;
- IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
- EXPECT_TRUE(m.WriteInt(v1));
- EXPECT_TRUE(m.WriteInt(v2));
-
- void* iter = NULL;
- std::wstring vs;
- EXPECT_FALSE(m.ReadWString(&iter, &vs));
-}
-
-TEST(IPCMessageIntegrity, ReadBytesBadIterator) {
- // This was BUG 1035467.
- IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
- EXPECT_TRUE(m.WriteInt(1));
- EXPECT_TRUE(m.WriteInt(2));
-
- void* iter = NULL;
- const char* data = NULL;
- EXPECT_FALSE(m.ReadBytes(&iter, &data, sizeof(int)));
-}
-
-TEST(IPCMessageIntegrity, ReadVectorNegativeSize) {
- // A slight variation of BUG 984408. Note that the pickling of vector<char>
- // has a specialized template which is not vulnerable to this bug. So here
- // try to hit the non-specialized case vector<P>.
- IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
- EXPECT_TRUE(m.WriteInt(-1)); // This is the count of elements.
- EXPECT_TRUE(m.WriteInt(1));
- EXPECT_TRUE(m.WriteInt(2));
- EXPECT_TRUE(m.WriteInt(3));
-
- std::vector<double> vec;
- void* iter = 0;
- EXPECT_FALSE(ReadParam(&m, &iter, &vec));
-}
-
-TEST(IPCMessageIntegrity, ReadVectorTooLarge1) {
- // This was BUG 1006367. This is the large but positive length case. Again
- // we try to hit the non-specialized case vector<P>.
- IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
- EXPECT_TRUE(m.WriteInt(0x21000003)); // This is the count of elements.
- EXPECT_TRUE(m.WriteInt64(1));
- EXPECT_TRUE(m.WriteInt64(2));
-
- std::vector<int64> vec;
- void* iter = 0;
- EXPECT_FALSE(ReadParam(&m, &iter, &vec));
-}
-
-TEST(IPCMessageIntegrity, ReadVectorTooLarge2) {
- // This was BUG 1006367. This is the large but positive with an additional
- // integer overflow when computing the actual byte size. Again we try to hit
- // the non-specialized case vector<P>.
- IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
- EXPECT_TRUE(m.WriteInt(0x71000000)); // This is the count of elements.
- EXPECT_TRUE(m.WriteInt64(1));
- EXPECT_TRUE(m.WriteInt64(2));
-
- std::vector<int64> vec;
- void* iter = 0;
- EXPECT_FALSE(ReadParam(&m, &iter, &vec));
-}
-
-// We don't actually use the messages defined in this file, but we do this
-// to get to the IPC macros.
-#if 0
-// This for tools which parse #include lines, but cannot process when we
-// include via a macro name.
-#include "ipc/ipc_sync_message_unittest.h"
-#endif
-#define MESSAGES_INTERNAL_FILE "ipc/ipc_sync_message_unittest.h"
-#include "ipc/ipc_message_macros.h"
-
-enum IPCMessageIds {
- UNUSED_IPC_TYPE,
- SERVER_FIRST_IPC_TYPE, // 1st Test message tag.
- SERVER_SECOND_IPC_TYPE, // 2nd Test message tag.
- SERVER_THIRD_IPC_TYPE, // 3rd Test message tag.
- CLIENT_MALFORMED_IPC, // Sent to client if server detects bad message.
- CLIENT_UNHANDLED_IPC // Sent to client if server detects unhanded IPC.
-};
-
-// Generic message class that is an int followed by a wstring.
-class MsgClassIS : public IPC::MessageWithTuple< Tuple2<int, std::wstring> > {
- public:
- enum { ID = SERVER_FIRST_IPC_TYPE };
- MsgClassIS(const int& arg1, const std::wstring& arg2)
- : IPC::MessageWithTuple< Tuple2<int, std::wstring> >(
- MSG_ROUTING_CONTROL, ID, MakeTuple(arg1, arg2)) {}
-};
-
-// Generic message class that is a wstring followed by an int.
-class MsgClassSI : public IPC::MessageWithTuple< Tuple2<std::wstring, int> > {
- public:
- enum { ID = SERVER_SECOND_IPC_TYPE };
- MsgClassSI(const std::wstring& arg1, const int& arg2)
- : IPC::MessageWithTuple< Tuple2<std::wstring, int> >(
- MSG_ROUTING_CONTROL, ID, MakeTuple(arg1, arg2)) {}
-};
-
-// Message to create a mutex in the IPC server, using the received name.
-class MsgDoMutex : public IPC::MessageWithTuple< Tuple2<std::wstring, int> > {
- public:
- enum { ID = SERVER_THIRD_IPC_TYPE };
- MsgDoMutex(const std::wstring& mutex_name, const int& unused)
- : IPC::MessageWithTuple< Tuple2<std::wstring, int> >(
- MSG_ROUTING_CONTROL, ID, MakeTuple(mutex_name, unused)) {}
-};
-
-class SimpleListener : public IPC::Channel::Listener {
- public:
- SimpleListener() : other_(NULL) {
- }
- void Init(IPC::Message::Sender* s) {
- other_ = s;
- }
- protected:
- IPC::Message::Sender* other_;
-};
-
-enum {
- FUZZER_ROUTING_ID = 5
-};
-
-// The fuzzer server class. It runs in a child process and expects
-// only two IPC calls; after that it exits the message loop which
-// terminates the child process.
-class FuzzerServerListener : public SimpleListener {
- public:
- FuzzerServerListener() : message_count_(2), pending_messages_(0) {
- }
- virtual void OnMessageReceived(const IPC::Message& msg) {
- if (msg.routing_id() == MSG_ROUTING_CONTROL) {
- ++pending_messages_;
- IPC_BEGIN_MESSAGE_MAP(FuzzerServerListener, msg)
- IPC_MESSAGE_HANDLER(MsgClassIS, OnMsgClassISMessage)
- IPC_MESSAGE_HANDLER(MsgClassSI, OnMsgClassSIMessage)
- IPC_END_MESSAGE_MAP()
- if (pending_messages_) {
- // Probably a problem de-serializing the message.
- ReplyMsgNotHandled(msg.type());
- }
- }
- }
-
- private:
- void OnMsgClassISMessage(int value, const std::wstring& text) {
- UseData(MsgClassIS::ID, value, text);
- RoundtripAckReply(FUZZER_ROUTING_ID, MsgClassIS::ID, value);
- Cleanup();
- }
-
- void OnMsgClassSIMessage(const std::wstring& text, int value) {
- UseData(MsgClassSI::ID, value, text);
- RoundtripAckReply(FUZZER_ROUTING_ID, MsgClassSI::ID, value);
- Cleanup();
- }
-
- bool RoundtripAckReply(int routing, int type_id, int reply) {
- IPC::Message* message = new IPC::Message(routing, type_id,
- IPC::Message::PRIORITY_NORMAL);
- message->WriteInt(reply + 1);
- message->WriteInt(reply);
- return other_->Send(message);
- }
-
- void Cleanup() {
- --message_count_;
- --pending_messages_;
- if (0 == message_count_)
- MessageLoop::current()->Quit();
- }
-
- void ReplyMsgNotHandled(int type_id) {
- RoundtripAckReply(FUZZER_ROUTING_ID, CLIENT_UNHANDLED_IPC, type_id);
- Cleanup();
- }
-
- void UseData(int caller, int value, const std::wstring& text) {
- std::wostringstream wos;
- wos << L"IPC fuzzer:" << caller << " [" << value << L" " << text << L"]\n";
- std::wstring output = wos.str();
- LOG(WARNING) << output.c_str();
- };
-
- int message_count_;
- int pending_messages_;
-};
-
-class FuzzerClientListener : public SimpleListener {
- public:
- FuzzerClientListener() : last_msg_(NULL) {
- }
-
- virtual void OnMessageReceived(const IPC::Message& msg) {
- last_msg_ = new IPC::Message(msg);
- MessageLoop::current()->Quit();
- }
-
- bool ExpectMessage(int value, int type_id) {
- if (!MsgHandlerInternal(type_id))
- return false;
- int msg_value1 = 0;
- int msg_value2 = 0;
- void* iter = NULL;
- if (!last_msg_->ReadInt(&iter, &msg_value1))
- return false;
- if (!last_msg_->ReadInt(&iter, &msg_value2))
- return false;
- if ((msg_value2 + 1) != msg_value1)
- return false;
- if (msg_value2 != value)
- return false;
-
- delete last_msg_;
- last_msg_ = NULL;
- return true;
- }
-
- bool ExpectMsgNotHandled(int type_id) {
- return ExpectMessage(type_id, CLIENT_UNHANDLED_IPC);
- }
-
- private:
- bool MsgHandlerInternal(int type_id) {
- MessageLoop::current()->Run();
- if (NULL == last_msg_)
- return false;
- if (FUZZER_ROUTING_ID != last_msg_->routing_id())
- return false;
- return (type_id == last_msg_->type());
- };
-
- IPC::Message* last_msg_;
-};
-
-// Runs the fuzzing server child mode. Returns when the preset number
-// of messages have been received.
-MULTIPROCESS_TEST_MAIN(RunFuzzServer) {
- MessageLoopForIO main_message_loop;
- FuzzerServerListener listener;
- IPC::Channel chan(kFuzzerChannel, IPC::Channel::MODE_CLIENT, &listener);
- chan.Connect();
- listener.Init(&chan);
- MessageLoop::current()->Run();
- return 0;
-}
-
-class IPCFuzzingTest : public IPCChannelTest {
-};
-
-// This test makes sure that the FuzzerClientListener and FuzzerServerListener
-// are working properly by generating two well formed IPC calls.
-TEST_F(IPCFuzzingTest, SanityTest) {
- FuzzerClientListener listener;
- IPC::Channel chan(kFuzzerChannel, IPC::Channel::MODE_SERVER,
- &listener);
- base::ProcessHandle server_process = SpawnChild(FUZZER_SERVER, &chan);
- ASSERT_TRUE(server_process);
- PlatformThread::Sleep(1000);
- ASSERT_TRUE(chan.Connect());
- listener.Init(&chan);
-
- IPC::Message* msg = NULL;
- int value = 43;
- msg = new MsgClassIS(value, L"expect 43");
- chan.Send(msg);
- EXPECT_TRUE(listener.ExpectMessage(value, MsgClassIS::ID));
-
- msg = new MsgClassSI(L"expect 44", ++value);
- chan.Send(msg);
- EXPECT_TRUE(listener.ExpectMessage(value, MsgClassSI::ID));
-
- EXPECT_TRUE(base::WaitForSingleProcess(server_process, 5000));
- base::CloseProcessHandle(server_process);
-}
-
-// This test uses a payload that is smaller than expected.
-// This generates an error while unpacking the IPC buffer which in
-// In debug this triggers an assertion and in release it is ignored(!!). Right
-// after we generate another valid IPC to make sure framing is working
-// properly.
-#ifdef NDEBUG
-TEST_F(IPCFuzzingTest, MsgBadPayloadShort) {
- FuzzerClientListener listener;
- IPC::Channel chan(kFuzzerChannel, IPC::Channel::MODE_SERVER,
- &listener);
- base::ProcessHandle server_process = SpawnChild(FUZZER_SERVER, &chan);
- ASSERT_TRUE(server_process);
- PlatformThread::Sleep(1000);
- ASSERT_TRUE(chan.Connect());
- listener.Init(&chan);
-
- IPC::Message* msg = new IPC::Message(MSG_ROUTING_CONTROL, MsgClassIS::ID,
- IPC::Message::PRIORITY_NORMAL);
- msg->WriteInt(666);
- chan.Send(msg);
- EXPECT_TRUE(listener.ExpectMsgNotHandled(MsgClassIS::ID));
-
- msg = new MsgClassSI(L"expect one", 1);
- chan.Send(msg);
- EXPECT_TRUE(listener.ExpectMessage(1, MsgClassSI::ID));
-
- EXPECT_TRUE(base::WaitForSingleProcess(server_process, 5000));
- base::CloseProcessHandle(server_process);
-}
-#endif // NDEBUG
-
-// This test uses a payload that has too many arguments, but so the payload
-// size is big enough so the unpacking routine does not generate an error as
-// in the case of MsgBadPayloadShort test.
-// This test does not pinpoint a flaw (per se) as by design we don't carry
-// type information on the IPC message.
-TEST_F(IPCFuzzingTest, MsgBadPayloadArgs) {
- FuzzerClientListener listener;
- IPC::Channel chan(kFuzzerChannel, IPC::Channel::MODE_SERVER,
- &listener);
- base::ProcessHandle server_process = SpawnChild(FUZZER_SERVER, &chan);
- ASSERT_TRUE(server_process);
- PlatformThread::Sleep(1000);
- ASSERT_TRUE(chan.Connect());
- listener.Init(&chan);
-
- IPC::Message* msg = new IPC::Message(MSG_ROUTING_CONTROL, MsgClassSI::ID,
- IPC::Message::PRIORITY_NORMAL);
- msg->WriteWString(L"d");
- msg->WriteInt(0);
- msg->WriteInt(0x65); // Extra argument.
-
- chan.Send(msg);
- EXPECT_TRUE(listener.ExpectMessage(0, MsgClassSI::ID));
-
- // Now send a well formed message to make sure the receiver wasn't
- // thrown out of sync by the extra argument.
- msg = new MsgClassIS(3, L"expect three");
- chan.Send(msg);
- EXPECT_TRUE(listener.ExpectMessage(3, MsgClassIS::ID));
-
- EXPECT_TRUE(base::WaitForSingleProcess(server_process, 5000));
- base::CloseProcessHandle(server_process);
-}
-
-// This class is for testing the IPC_BEGIN_MESSAGE_MAP_EX macros.
-class ServerMacroExTest {
- public:
- ServerMacroExTest() : unhandled_msgs_(0) {
- }
- virtual bool OnMessageReceived(const IPC::Message& msg) {
- bool msg_is_ok = false;
- IPC_BEGIN_MESSAGE_MAP_EX(ServerMacroExTest, msg, msg_is_ok)
- IPC_MESSAGE_HANDLER(MsgClassIS, OnMsgClassISMessage)
- IPC_MESSAGE_HANDLER(MsgClassSI, OnMsgClassSIMessage)
- IPC_MESSAGE_UNHANDLED(++unhandled_msgs_)
- IPC_END_MESSAGE_MAP_EX()
- return msg_is_ok;
- }
-
- int unhandled_msgs() const {
- return unhandled_msgs_;
- }
-
- private:
- void OnMsgClassISMessage(int value, const std::wstring& text) {
- }
- void OnMsgClassSIMessage(const std::wstring& text, int value) {
- }
-
- int unhandled_msgs_;
-};
-
-TEST_F(IPCFuzzingTest, MsgMapExMacro) {
- IPC::Message* msg = NULL;
- ServerMacroExTest server;
-
- // Test the regular messages.
- msg = new MsgClassIS(3, L"text3");
- EXPECT_TRUE(server.OnMessageReceived(*msg));
- delete msg;
- msg = new MsgClassSI(L"text2", 2);
- EXPECT_TRUE(server.OnMessageReceived(*msg));
- delete msg;
-
-#ifdef NDEBUG
- // Test a bad message.
- msg = new IPC::Message(MSG_ROUTING_CONTROL, MsgClassSI::ID,
- IPC::Message::PRIORITY_NORMAL);
- msg->WriteInt(2);
- EXPECT_FALSE(server.OnMessageReceived(*msg));
- delete msg;
-
- msg = new IPC::Message(MSG_ROUTING_CONTROL, MsgClassIS::ID,
- IPC::Message::PRIORITY_NORMAL);
- msg->WriteInt(0x64);
- msg->WriteInt(0x32);
- EXPECT_FALSE(server.OnMessageReceived(*msg));
- delete msg;
-
- EXPECT_EQ(0, server.unhandled_msgs());
-#endif
-}
diff --git a/ipc/ipc_logging.cc b/ipc/ipc_logging.cc
deleted file mode 100644
index baa9cc30f..0000000
--- a/ipc/ipc_logging.cc
+++ /dev/null
@@ -1,301 +0,0 @@
-// Copyright (c) 2006-2008 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 "ipc/ipc_logging.h"
-
-#include "base/command_line.h"
-#include "base/logging.h"
-#include "base/message_loop.h"
-#include "base/string_util.h"
-#include "base/thread.h"
-#include "base/time.h"
-#include "base/waitable_event.h"
-#include "base/waitable_event_watcher.h"
-#include "ipc/ipc_sync_message.h"
-#include "ipc/ipc_switches.h"
-#include "ipc/ipc_message_utils.h"
-
-#if defined(OS_POSIX)
-#include "base/string_util.h"
-#include <unistd.h>
-#endif
-
-#ifdef IPC_MESSAGE_LOG_ENABLED
-
-using base::Time;
-
-// IPC::Logging is allocated as a singleton, so we don't need any kind of
-// special retention program.
-template <>
-struct RunnableMethodTraits<IPC::Logging> {
- static void RetainCallee(IPC::Logging*) {}
- static void ReleaseCallee(IPC::Logging*) {}
-};
-
-namespace IPC {
-
-const wchar_t kLoggingEventName[] = L"ChromeIPCLog.%d";
-const int kLogSendDelayMs = 100;
-
-// We use a pointer to the function table to avoid any linker dependencies on
-// all the traits used as IPC message parameters.
-Logging::LogFunction *Logging::log_function_mapping_;
-
-Logging::Logging()
- : logging_event_on_(NULL),
- logging_event_off_(NULL),
- enabled_(false),
- queue_invoke_later_pending_(false),
- sender_(NULL),
- main_thread_(MessageLoop::current()),
- consumer_(NULL) {
- // Create an event for this browser instance that's set when logging is
- // enabled, so child processes can know when logging is enabled.
-
-#if defined(OS_WIN)
- // On Windows we have a couple of named events which switch logging on and
- // off.
- int browser_pid;
- const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
- std::wstring process_type =
- parsed_command_line.GetSwitchValue(switches::kProcessType);
- if (process_type.empty()) {
- browser_pid = GetCurrentProcessId();
- } else {
- std::wstring channel_name =
- parsed_command_line.GetSwitchValue(switches::kProcessChannelID);
-
- browser_pid = _wtoi(channel_name.c_str());
- DCHECK(browser_pid != 0);
- }
-
- std::wstring event_name = GetEventName(browser_pid, true);
- logging_event_on_.reset(new base::WaitableEvent(
- CreateEvent(NULL, TRUE, FALSE, event_name.c_str())));
-
- event_name = GetEventName(browser_pid, false);
- logging_event_off_.reset(new base::WaitableEvent(
- CreateEvent(NULL, TRUE, FALSE, event_name.c_str())));
-
- RegisterWaitForEvent(true);
-#elif defined(OS_POSIX)
- if (getenv("CHROME_IPC_LOGGING"))
- enabled_ = true;
-#endif
-
- MessageLoop::current()->AddDestructionObserver(this);
-}
-
-Logging::~Logging() {
-}
-
-Logging* Logging::current() {
- return Singleton<Logging>::get();
-}
-
-void Logging::RegisterWaitForEvent(bool enabled) {
- watcher_.StopWatching();
- watcher_.StartWatching(
- enabled ? logging_event_on_.get() : logging_event_off_.get(), this);
-}
-
-void Logging::OnWaitableEventSignaled(base::WaitableEvent* event) {
- enabled_ = event == logging_event_on_.get();
- RegisterWaitForEvent(!enabled_);
-}
-
-void Logging::WillDestroyCurrentMessageLoop() {
- watcher_.StopWatching();
-}
-
-// static
-void Logging::SetLoggerFunctions(LogFunction *functions) {
- log_function_mapping_ = functions;
-}
-
-#if defined(OS_WIN)
-std::wstring Logging::GetEventName(bool enabled) {
- return current()->GetEventName(GetCurrentProcessId(), enabled);
-}
-#endif
-
-std::wstring Logging::GetEventName(int browser_pid, bool enabled) {
- std::wstring result = StringPrintf(kLoggingEventName, browser_pid);
- result += enabled ? L"on" : L"off";
- return result;
-}
-
-void Logging::SetConsumer(Consumer* consumer) {
- consumer_ = consumer;
-}
-
-void Logging::Enable() {
- logging_event_off_->Reset();
- logging_event_on_->Signal();
-}
-
-void Logging::Disable() {
- logging_event_on_->Reset();
- logging_event_off_->Signal();
-}
-
-void Logging::OnSendLogs() {
- queue_invoke_later_pending_ = false;
- if (!sender_)
- return;
-
- Message* msg = new Message(
- MSG_ROUTING_CONTROL, IPC_LOGGING_ID, Message::PRIORITY_NORMAL);
- WriteParam(msg, queued_logs_);
- queued_logs_.clear();
- sender_->Send(msg);
-}
-
-void Logging::SetIPCSender(IPC::Message::Sender* sender) {
- sender_ = sender;
-}
-
-void Logging::OnReceivedLoggingMessage(const Message& message) {
- std::vector<LogData> data;
- void* iter = NULL;
- if (!ReadParam(&message, &iter, &data))
- return;
-
- for (size_t i = 0; i < data.size(); ++i) {
- Log(data[i]);
- }
-}
-
-void Logging::OnSendMessage(Message* message, const std::wstring& channel_id) {
- if (!Enabled())
- return;
-
- if (message->is_reply()) {
- LogData* data = message->sync_log_data();
- if (!data)
- return;
-
- // This is actually the delayed reply to a sync message. Create a string
- // of the output parameters, add it to the LogData that was earlier stashed
- // with the reply, and log the result.
- data->channel = channel_id;
- GenerateLogData(L"", *message, data);
- Log(*data);
- delete data;
- message->set_sync_log_data(NULL);
- } else {
- // If the time has already been set (i.e. by ChannelProxy), keep that time
- // instead as it's more accurate.
- if (!message->sent_time())
- message->set_sent_time(Time::Now().ToInternalValue());
- }
-}
-
-void Logging::OnPreDispatchMessage(const Message& message) {
- message.set_received_time(Time::Now().ToInternalValue());
-}
-
-void Logging::OnPostDispatchMessage(const Message& message,
- const std::wstring& channel_id) {
- if (!Enabled() ||
-#if defined(OS_WIN)
- !message.sent_time() ||
-#endif
- message.dont_log())
- return;
-
- LogData data;
- GenerateLogData(channel_id, message, &data);
-
- if (MessageLoop::current() == main_thread_) {
- Log(data);
- } else {
- main_thread_->PostTask(FROM_HERE, NewRunnableMethod(
- this, &Logging::Log, data));
- }
-}
-
-void Logging::GetMessageText(uint16 type, std::wstring* name,
- const Message* message,
- std::wstring* params) {
- if (!log_function_mapping_)
- return;
-
- int message_class = type >> 12;
- if (log_function_mapping_[message_class] != NULL) {
- log_function_mapping_[message_class](type, name, message, params);
- } else {
- DLOG(INFO) << "No logger function associated with message class " <<
- message_class;
- }
-}
-
-void Logging::Log(const LogData& data) {
-#if defined(OS_WIN)
- if (consumer_) {
- // We're in the browser process.
- consumer_->Log(data);
- } else {
- // We're in the renderer or plugin processes.
- if (sender_) {
- queued_logs_.push_back(data);
- if (!queue_invoke_later_pending_) {
- queue_invoke_later_pending_ = true;
- MessageLoop::current()->PostDelayedTask(FROM_HERE, NewRunnableMethod(
- this, &Logging::OnSendLogs), kLogSendDelayMs);
- }
- }
- }
-#elif defined(OS_POSIX)
- // On POSIX, for now, we just dump the log to stderr
- fprintf(stderr, "ipc %s %d %s %s %s\n",
- WideToUTF8(data.channel).c_str(),
- data.type,
- WideToUTF8(data.flags).c_str(),
- WideToUTF8(data.message_name).c_str(),
- WideToUTF8(data.params).c_str());
-#endif
-}
-
-void GenerateLogData(const std::wstring& channel, const Message& message,
- LogData* data) {
- if (message.is_reply()) {
- // "data" should already be filled in.
- std::wstring params;
- Logging::GetMessageText(data->type, NULL, &message, &params);
-
- if (!data->params.empty() && !params.empty())
- data->params += L", ";
-
- data->flags += L" DR";
-
- data->params += params;
- } else {
- std::wstring flags;
- if (message.is_sync())
- flags = L"S";
-
- if (message.is_reply())
- flags += L"R";
-
- if (message.is_reply_error())
- flags += L"E";
-
- std::wstring params, message_name;
- Logging::GetMessageText(message.type(), &message_name, &message, &params);
-
- data->channel = channel;
- data->type = message.type();
- data->flags = flags;
- data->sent = message.sent_time();
- data->receive = message.received_time();
- data->dispatch = Time::Now().ToInternalValue();
- data->params = params;
- data->message_name = message_name;
- }
-}
-
-} // namespace IPC
-
-#endif // IPC_MESSAGE_LOG_ENABLED
diff --git a/ipc/ipc_logging.h b/ipc/ipc_logging.h
deleted file mode 100644
index 4d8f81d4d..0000000
--- a/ipc/ipc_logging.h
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright (c) 2006-2008 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 IPC_IPC_LOGGING_H_
-#define IPC_IPC_LOGGING_H_
-
-#include "ipc/ipc_message.h" // For IPC_MESSAGE_LOG_ENABLED.
-
-#ifdef IPC_MESSAGE_LOG_ENABLED
-
-#include "base/lock.h"
-#include "base/message_loop.h"
-#include "base/singleton.h"
-#include "base/waitable_event_watcher.h"
-#include "ipc/ipc_message_utils.h"
-
-class MessageLoop;
-
-namespace IPC {
-
-class Message;
-
-// One instance per process. Needs to be created on the main thread (the UI
-// thread in the browser) but OnPreDispatchMessage/OnPostDispatchMessage
-// can be called on other threads.
-class Logging : public base::WaitableEventWatcher::Delegate,
- public MessageLoop::DestructionObserver {
- public:
- // Implemented by consumers of log messages.
- class Consumer {
- public:
- virtual void Log(const LogData& data) = 0;
- };
-
- void SetConsumer(Consumer* consumer);
-
- ~Logging();
- static Logging* current();
-
- void Enable();
- void Disable();
- bool Enabled() const { return enabled_; }
-
- // Called by child processes to give the logger object the channel to send
- // logging data to the browser process.
- void SetIPCSender(Message::Sender* sender);
-
- // Called in the browser process when logging data from a child process is
- // received.
- void OnReceivedLoggingMessage(const Message& message);
-
- void OnSendMessage(Message* message, const std::wstring& channel_id);
- void OnPreDispatchMessage(const Message& message);
- void OnPostDispatchMessage(const Message& message,
- const std::wstring& channel_id);
-
- // Returns the name of the logging enabled/disabled events so that the
- // sandbox can add them to to the policy. If true, gets the name of the
- // enabled event, if false, gets the name of the disabled event.
- static std::wstring GetEventName(bool enabled);
-
- // Like the *MsgLog functions declared for each message class, except this
- // calls the correct one based on the message type automatically. Defined in
- // ipc_logging.cc.
- static void GetMessageText(uint16 type, std::wstring* name,
- const Message* message, std::wstring* params);
-
- // WaitableEventWatcher::Delegate implementation
- void OnWaitableEventSignaled(base::WaitableEvent* event);
-
- // MessageLoop::DestructionObserver implementation
- void WillDestroyCurrentMessageLoop();
-
- typedef void (*LogFunction)(uint16 type,
- std::wstring* name,
- const Message* msg,
- std::wstring* params);
-
- static void SetLoggerFunctions(LogFunction *functions);
-
- private:
- friend struct DefaultSingletonTraits<Logging>;
- Logging();
-
- std::wstring GetEventName(int browser_pid, bool enabled);
- void OnSendLogs();
- void Log(const LogData& data);
-
- void RegisterWaitForEvent(bool enabled);
-
- base::WaitableEventWatcher watcher_;
-
- scoped_ptr<base::WaitableEvent> logging_event_on_;
- scoped_ptr<base::WaitableEvent> logging_event_off_;
- bool enabled_;
-
- std::vector<LogData> queued_logs_;
- bool queue_invoke_later_pending_;
-
- Message::Sender* sender_;
- MessageLoop* main_thread_;
-
- Consumer* consumer_;
-
- static LogFunction *log_function_mapping_;
-};
-
-} // namespace IPC
-
-#endif // IPC_MESSAGE_LOG_ENABLED
-
-#endif // IPC_IPC_LOGGING_H_
diff --git a/ipc/ipc_message.cc b/ipc/ipc_message.cc
deleted file mode 100644
index 7a2b5cd..0000000
--- a/ipc/ipc_message.cc
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright (c) 2006-2008 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 "ipc/ipc_message.h"
-
-#include "base/logging.h"
-#include "build/build_config.h"
-
-#if defined(OS_POSIX)
-#include "ipc/file_descriptor_set_posix.h"
-#endif
-
-namespace IPC {
-
-//------------------------------------------------------------------------------
-
-Message::~Message() {
-}
-
-Message::Message()
- : Pickle(sizeof(Header)) {
- header()->routing = header()->type = header()->flags = 0;
-#if defined(OS_POSIX)
- header()->num_fds = 0;
-#endif
- InitLoggingVariables();
-}
-
-Message::Message(int32 routing_id, uint16 type, PriorityValue priority)
- : Pickle(sizeof(Header)) {
- header()->routing = routing_id;
- header()->type = type;
- header()->flags = priority;
-#if defined(OS_POSIX)
- header()->num_fds = 0;
-#endif
- InitLoggingVariables();
-}
-
-Message::Message(const char* data, int data_len) : Pickle(data, data_len) {
- InitLoggingVariables();
-}
-
-Message::Message(const Message& other) : Pickle(other) {
- InitLoggingVariables();
-#if defined(OS_POSIX)
- file_descriptor_set_ = other.file_descriptor_set_;
-#endif
-}
-
-void Message::InitLoggingVariables() {
-#ifdef IPC_MESSAGE_LOG_ENABLED
- received_time_ = 0;
- dont_log_ = false;
- log_data_ = NULL;
-#endif
-}
-
-Message& Message::operator=(const Message& other) {
- *static_cast<Pickle*>(this) = other;
-#if defined(OS_POSIX)
- file_descriptor_set_ = other.file_descriptor_set_;
-#endif
- return *this;
-}
-
-#ifdef IPC_MESSAGE_LOG_ENABLED
-void Message::set_sent_time(int64 time) {
- DCHECK((header()->flags & HAS_SENT_TIME_BIT) == 0);
- header()->flags |= HAS_SENT_TIME_BIT;
- WriteInt64(time);
-}
-
-int64 Message::sent_time() const {
- if ((header()->flags & HAS_SENT_TIME_BIT) == 0)
- return 0;
-
- const char* data = end_of_payload();
- data -= sizeof(int64);
- return *(reinterpret_cast<const int64*>(data));
-}
-
-void Message::set_received_time(int64 time) const {
- received_time_ = time;
-}
-#endif
-
-#if defined(OS_POSIX)
-bool Message::WriteFileDescriptor(const base::FileDescriptor& descriptor) {
- // We write the index of the descriptor so that we don't have to
- // keep the current descriptor as extra decoding state when deserialising.
- WriteInt(file_descriptor_set()->size());
- if (descriptor.auto_close) {
- return file_descriptor_set()->AddAndAutoClose(descriptor.fd);
- } else {
- return file_descriptor_set()->Add(descriptor.fd);
- }
-}
-
-bool Message::ReadFileDescriptor(void** iter,
- base::FileDescriptor* descriptor) const {
- int descriptor_index;
- if (!ReadInt(iter, &descriptor_index))
- return false;
-
- FileDescriptorSet* file_descriptor_set = file_descriptor_set_.get();
- if (!file_descriptor_set)
- return false;
-
- descriptor->fd = file_descriptor_set->GetDescriptorAt(descriptor_index);
- descriptor->auto_close = false;
-
- return descriptor->fd >= 0;
-}
-
-void Message::EnsureFileDescriptorSet() {
- if (file_descriptor_set_.get() == NULL)
- file_descriptor_set_ = new FileDescriptorSet;
-}
-
-#endif
-
-} // namespace IPC
diff --git a/ipc/ipc_message.h b/ipc/ipc_message.h
deleted file mode 100644
index 6357c0b..0000000
--- a/ipc/ipc_message.h
+++ /dev/null
@@ -1,279 +0,0 @@
-// Copyright (c) 2006-2008 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 IPC_IPC_MESSAGE_H__
-#define IPC_IPC_MESSAGE_H__
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/pickle.h"
-
-#ifndef NDEBUG
-#define IPC_MESSAGE_LOG_ENABLED
-#endif
-
-#if defined(OS_POSIX)
-#include "base/ref_counted.h"
-#endif
-
-namespace base {
-class FileDescriptor;
-}
-
-class FileDescriptorSet;
-
-namespace IPC {
-
-//------------------------------------------------------------------------------
-
-class Channel;
-class Message;
-struct LogData;
-
-class Message : public Pickle {
- public:
- // Implemented by objects that can send IPC messages across a channel.
- class Sender {
- public:
- virtual ~Sender() {}
-
- // Sends the given IPC message. The implementor takes ownership of the
- // given Message regardless of whether or not this method succeeds. This
- // is done to make this method easier to use. Returns true on success and
- // false otherwise.
- virtual bool Send(Message* msg) = 0;
- };
-
- enum PriorityValue {
- PRIORITY_LOW = 1,
- PRIORITY_NORMAL,
- PRIORITY_HIGH
- };
-
- virtual ~Message();
-
- Message();
-
- // Initialize a message with a user-defined type, priority value, and
- // destination WebView ID.
- Message(int32 routing_id, uint16 type, PriorityValue priority);
-
- // Initializes a message from a const block of data. The data is not copied;
- // instead the data is merely referenced by this message. Only const methods
- // should be used on the message when initialized this way.
- Message(const char* data, int data_len);
-
- Message(const Message& other);
- Message& operator=(const Message& other);
-
- PriorityValue priority() const {
- return static_cast<PriorityValue>(header()->flags & PRIORITY_MASK);
- }
-
- // True if this is a synchronous message.
- bool is_sync() const {
- return (header()->flags & SYNC_BIT) != 0;
- }
-
- // Set this on a reply to a synchronous message.
- void set_reply() {
- header()->flags |= REPLY_BIT;
- }
-
- bool is_reply() const {
- return (header()->flags & REPLY_BIT) != 0;
- }
-
- // Set this on a reply to a synchronous message to indicate that no receiver
- // was found.
- void set_reply_error() {
- header()->flags |= REPLY_ERROR_BIT;
- }
-
- bool is_reply_error() const {
- return (header()->flags & REPLY_ERROR_BIT) != 0;
- }
-
- // Normally when a receiver gets a message and they're blocked on a
- // synchronous message Send, they buffer a message. Setting this flag causes
- // the receiver to be unblocked and the message to be dispatched immediately.
- void set_unblock(bool unblock) {
- if (unblock) {
- header()->flags |= UNBLOCK_BIT;
- } else {
- header()->flags &= ~UNBLOCK_BIT;
- }
- }
-
- bool should_unblock() const {
- return (header()->flags & UNBLOCK_BIT) != 0;
- }
-
- // Tells the receiver that the caller is pumping messages while waiting
- // for the result.
- bool is_caller_pumping_messages() const {
- return (header()->flags & PUMPING_MSGS_BIT) != 0;
- }
-
- uint16 type() const {
- return header()->type;
- }
-
- int32 routing_id() const {
- return header()->routing;
- }
-
- void set_routing_id(int32 new_id) {
- header()->routing = new_id;
- }
-
- template<class T>
- static bool Dispatch(const Message* msg, T* obj, void (T::*func)()) {
- (obj->*func)();
- return true;
- }
-
- template<class T>
- static bool Dispatch(const Message* msg, T* obj, void (T::*func)() const) {
- (obj->*func)();
- return true;
- }
-
- template<class T>
- static bool Dispatch(const Message* msg, T* obj,
- void (T::*func)(const Message&)) {
- (obj->*func)(*msg);
- return true;
- }
-
- template<class T>
- static bool Dispatch(const Message* msg, T* obj,
- void (T::*func)(const Message&) const) {
- (obj->*func)(*msg);
- return true;
- }
-
- // Used for async messages with no parameters.
- static void Log(const Message* msg, std::wstring* l) {
- }
-
- // Find the end of the message data that starts at range_start. Returns NULL
- // if the entire message is not found in the given data range.
- static const char* FindNext(const char* range_start, const char* range_end) {
- return Pickle::FindNext(sizeof(Header), range_start, range_end);
- }
-
-#if defined(OS_POSIX)
- // On POSIX, a message supports reading / writing FileDescriptor objects.
- // This is used to pass a file descriptor to the peer of an IPC channel.
-
- // Add a descriptor to the end of the set. Returns false iff the set is full.
- bool WriteFileDescriptor(const base::FileDescriptor& descriptor);
- // Get a file descriptor from the message. Returns false on error.
- // iter: a Pickle iterator to the current location in the message.
- bool ReadFileDescriptor(void** iter, base::FileDescriptor* descriptor) const;
-#endif
-
-#ifdef IPC_MESSAGE_LOG_ENABLED
- // Adds the outgoing time from Time::Now() at the end of the message and sets
- // a bit to indicate that it's been added.
- void set_sent_time(int64 time);
- int64 sent_time() const;
-
- void set_received_time(int64 time) const;
- int64 received_time() const { return received_time_; }
- void set_output_params(const std::wstring& op) const { output_params_ = op; }
- const std::wstring& output_params() const { return output_params_; }
- // The following four functions are needed so we can log sync messages with
- // delayed replies. We stick the log data from the sent message into the
- // reply message, so that when it's sent and we have the output parameters
- // we can log it. As such, we set a flag on the sent message to not log it.
- void set_sync_log_data(LogData* data) const { log_data_ = data; }
- LogData* sync_log_data() const { return log_data_; }
- void set_dont_log() const { dont_log_ = true; }
- bool dont_log() const { return dont_log_; }
-#endif
-
- protected:
- friend class Channel;
- friend class MessageReplyDeserializer;
- friend class SyncMessage;
-
- void set_sync() {
- header()->flags |= SYNC_BIT;
- }
-
- // flags
- enum {
- PRIORITY_MASK = 0x0003,
- SYNC_BIT = 0x0004,
- REPLY_BIT = 0x0008,
- REPLY_ERROR_BIT = 0x0010,
- UNBLOCK_BIT = 0x0020,
- PUMPING_MSGS_BIT= 0x0040,
- HAS_SENT_TIME_BIT = 0x0080,
- };
-
-#pragma pack(push, 2)
- struct Header : Pickle::Header {
- int32 routing; // ID of the view that this message is destined for
- uint16 type; // specifies the user-defined message type
- uint16 flags; // specifies control flags for the message
-#if defined(OS_POSIX)
- uint32 num_fds; // the number of descriptors included with this message
-#endif
- };
-#pragma pack(pop)
-
- Header* header() {
- return headerT<Header>();
- }
- const Header* header() const {
- return headerT<Header>();
- }
-
- void InitLoggingVariables();
-
-#if defined(OS_POSIX)
- // The set of file descriptors associated with this message.
- scoped_refptr<FileDescriptorSet> file_descriptor_set_;
-
- // Ensure that a FileDescriptorSet is allocated
- void EnsureFileDescriptorSet();
-
- FileDescriptorSet* file_descriptor_set() {
- EnsureFileDescriptorSet();
- return file_descriptor_set_.get();
- }
- const FileDescriptorSet* file_descriptor_set() const {
- return file_descriptor_set_.get();
- }
-#endif
-
-#ifdef IPC_MESSAGE_LOG_ENABLED
- // Used for logging.
- mutable int64 received_time_;
- mutable std::wstring output_params_;
- mutable LogData* log_data_;
- mutable bool dont_log_;
-#endif
-};
-
-//------------------------------------------------------------------------------
-
-} // namespace IPC
-
-enum SpecialRoutingIDs {
- // indicates that we don't have a routing ID yet.
- MSG_ROUTING_NONE = -2,
-
- // indicates a general message not sent to a particular tab.
- MSG_ROUTING_CONTROL = kint32max,
-};
-
-#define IPC_REPLY_ID 0xFFF0 // Special message id for replies
-#define IPC_LOGGING_ID 0xFFF1 // Special message id for logging
-
-#endif // IPC_IPC_MESSAGE_H__
diff --git a/ipc/ipc_message_macros.h b/ipc/ipc_message_macros.h
deleted file mode 100644
index 8bddb7f..0000000
--- a/ipc/ipc_message_macros.h
+++ /dev/null
@@ -1,1140 +0,0 @@
-// Copyright (c) 2006-2008 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.
-
-// This header is meant to be included in multiple passes, hence no traditional
-// header guard.
-//
-// In the first pass, IPC_MESSAGE_MACROS_ENUMS should be defined, which will
-// create enums for each of the messages defined with the IPC_MESSAGE_* macros.
-//
-// In the second pass, either IPC_MESSAGE_MACROS_DEBUGSTRINGS or
-// IPC_MESSAGE_MACROS_CLASSES should be defined (if both, DEBUGSTRINGS takes
-// precedence). Only one .cc file should have DEBUGSTRINGS defined, as this
-// will create helper functions mapping message types to strings. Having
-// CLASSES defined will create classes for each of the messages defined with
-// the IPC_MESSAGE_* macros.
-//
-// "Sync" messages are just synchronous calls, the Send() call doesn't return
-// until a reply comes back. Input parameters are first (const TYPE&), and
-// To declare a sync message, use the IPC_SYNC_ macros. The numbers at the
-// end show how many input/output parameters there are (i.e. 1_2 is 1 in, 2
-// out). The caller does a Send([route id, ], in1, &out1, &out2).
-// The receiver's handler function will be
-// void OnSyncMessageName(const type1& in1, type2* out1, type3* out2)
-//
-//
-// A caller can also send a synchronous message, while the receiver can respond
-// at a later time. This is transparent from the sender's size. The receiver
-// needs to use a different handler that takes in a IPC::Message* as the output
-// type, stash the message, and when it has the data it can Send the message.
-//
-// Use the IPC_MESSAGE_HANDLER_DELAY_REPLY macro instead of IPC_MESSAGE_HANDLER
-// IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_SyncMessageName,
-// OnSyncMessageName)
-//
-// The handler function will look like:
-// void OnSyncMessageName(const type1& in1, IPC::Message* reply_msg);
-//
-// Receiver stashes the IPC::Message* pointer, and when it's ready, it does:
-// ViewHostMsg_SyncMessageName::WriteReplyParams(reply_msg, out1, out2);
-// Send(reply_msg);
-
-#include "ipc/ipc_message_utils.h"
-
-#ifndef MESSAGES_INTERNAL_FILE
-#error This file should only be included by X_messages.h, which needs to define MESSAGES_INTERNAL_FILE first.
-#endif
-
-#ifndef IPC_MESSAGE_MACROS_INCLUDE_BLOCK
-#define IPC_MESSAGE_MACROS_INCLUDE_BLOCK
-
-// Multi-pass include of X_messages_internal.h. Preprocessor magic allows
-// us to use 1 header to define the enums and classes for our render messages.
-#define IPC_MESSAGE_MACROS_ENUMS
-#include MESSAGES_INTERNAL_FILE
-
-#define IPC_MESSAGE_MACROS_CLASSES
-#include MESSAGES_INTERNAL_FILE
-
-#ifdef IPC_MESSAGE_MACROS_LOG_ENABLED
-#define IPC_MESSAGE_MACROS_LOG
-#include MESSAGES_INTERNAL_FILE
-#endif
-
-#undef MESSAGES_INTERNAL_FILE
-#undef IPC_MESSAGE_MACROS_INCLUDE_BLOCK
-
-#endif
-
-
-// Undefine the macros from the previous pass (if any).
-#undef IPC_BEGIN_MESSAGES
-#undef IPC_END_MESSAGES
-#undef IPC_MESSAGE_CONTROL0
-#undef IPC_MESSAGE_CONTROL1
-#undef IPC_MESSAGE_CONTROL2
-#undef IPC_MESSAGE_CONTROL3
-#undef IPC_MESSAGE_CONTROL4
-#undef IPC_MESSAGE_CONTROL5
-#undef IPC_MESSAGE_ROUTED0
-#undef IPC_MESSAGE_ROUTED1
-#undef IPC_MESSAGE_ROUTED2
-#undef IPC_MESSAGE_ROUTED3
-#undef IPC_MESSAGE_ROUTED4
-#undef IPC_MESSAGE_ROUTED5
-#undef IPC_MESSAGE_ROUTED6
-#undef IPC_SYNC_MESSAGE_CONTROL0_0
-#undef IPC_SYNC_MESSAGE_CONTROL0_1
-#undef IPC_SYNC_MESSAGE_CONTROL0_2
-#undef IPC_SYNC_MESSAGE_CONTROL0_3
-#undef IPC_SYNC_MESSAGE_CONTROL1_0
-#undef IPC_SYNC_MESSAGE_CONTROL1_1
-#undef IPC_SYNC_MESSAGE_CONTROL1_2
-#undef IPC_SYNC_MESSAGE_CONTROL1_3
-#undef IPC_SYNC_MESSAGE_CONTROL2_0
-#undef IPC_SYNC_MESSAGE_CONTROL2_1
-#undef IPC_SYNC_MESSAGE_CONTROL2_2
-#undef IPC_SYNC_MESSAGE_CONTROL2_3
-#undef IPC_SYNC_MESSAGE_CONTROL3_1
-#undef IPC_SYNC_MESSAGE_CONTROL3_2
-#undef IPC_SYNC_MESSAGE_CONTROL3_3
-#undef IPC_SYNC_MESSAGE_CONTROL4_1
-#undef IPC_SYNC_MESSAGE_CONTROL4_2
-#undef IPC_SYNC_MESSAGE_ROUTED0_0
-#undef IPC_SYNC_MESSAGE_ROUTED0_1
-#undef IPC_SYNC_MESSAGE_ROUTED0_2
-#undef IPC_SYNC_MESSAGE_ROUTED0_3
-#undef IPC_SYNC_MESSAGE_ROUTED1_0
-#undef IPC_SYNC_MESSAGE_ROUTED1_1
-#undef IPC_SYNC_MESSAGE_ROUTED1_2
-#undef IPC_SYNC_MESSAGE_ROUTED1_3
-#undef IPC_SYNC_MESSAGE_ROUTED1_4
-#undef IPC_SYNC_MESSAGE_ROUTED2_0
-#undef IPC_SYNC_MESSAGE_ROUTED2_1
-#undef IPC_SYNC_MESSAGE_ROUTED2_2
-#undef IPC_SYNC_MESSAGE_ROUTED2_3
-#undef IPC_SYNC_MESSAGE_ROUTED3_0
-#undef IPC_SYNC_MESSAGE_ROUTED3_1
-#undef IPC_SYNC_MESSAGE_ROUTED3_2
-#undef IPC_SYNC_MESSAGE_ROUTED3_3
-#undef IPC_SYNC_MESSAGE_ROUTED4_0
-#undef IPC_SYNC_MESSAGE_ROUTED4_1
-#undef IPC_SYNC_MESSAGE_ROUTED4_2
-
-#if defined(IPC_MESSAGE_MACROS_ENUMS)
-#undef IPC_MESSAGE_MACROS_ENUMS
-
-// TODO(jabdelmalek): we're using the lowest 12 bits of type for the message
-// id, and the highest 4 bits for the channel type. This constrains us to
-// 16 channel types (currently using 8) and 4K messages per type. Should
-// really make type be 32 bits, but then we break automation with older Chrome
-// builds..
-// Do label##PreStart so that automation messages keep the same id as before.
-#define IPC_BEGIN_MESSAGES(label) \
- enum label##MsgType { \
- label##Start = label##MsgStart << 12, \
- label##PreStart = (label##MsgStart << 12) - 1,
-
-#define IPC_END_MESSAGES(label) \
- label##End \
- };
-
-#define IPC_MESSAGE_CONTROL0(msg_class) \
- msg_class##__ID,
-
-#define IPC_MESSAGE_CONTROL1(msg_class, type1) \
- msg_class##__ID,
-
-#define IPC_MESSAGE_CONTROL2(msg_class, type1, type2) \
- msg_class##__ID,
-
-#define IPC_MESSAGE_CONTROL3(msg_class, type1, type2, type3) \
- msg_class##__ID,
-
-#define IPC_MESSAGE_CONTROL4(msg_class, type1, type2, type3, type4) \
- msg_class##__ID,
-
-#define IPC_MESSAGE_CONTROL5(msg_class, type1, type2, type3, type4, type5) \
- msg_class##__ID,
-
-#define IPC_MESSAGE_ROUTED0(msg_class) \
- msg_class##__ID,
-
-#define IPC_MESSAGE_ROUTED1(msg_class, type1) \
- msg_class##__ID,
-
-#define IPC_MESSAGE_ROUTED2(msg_class, type1, type2) \
- msg_class##__ID,
-
-#define IPC_MESSAGE_ROUTED3(msg_class, type1, type2, type3) \
- msg_class##__ID,
-
-#define IPC_MESSAGE_ROUTED4(msg_class, type1, type2, type3, type4) \
- msg_class##__ID,
-
-#define IPC_MESSAGE_ROUTED5(msg_class, type1, type2, type3, type4, type5) \
- msg_class##__ID,
-
-#define IPC_MESSAGE_ROUTED6(msg_class, type1, type2, type3, type4, type5, type6) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_CONTROL0_0(msg_class) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_CONTROL0_1(msg_class, type1_out) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_CONTROL0_2(msg_class, type1_out, type2_out) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_CONTROL0_3(msg_class, type1_out, type2_out, type3_out) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_CONTROL1_0(msg_class, type1_in) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_CONTROL1_1(msg_class, type1_in, type1_out) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_CONTROL1_2(msg_class, type1_in, type1_out, type2_out) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_CONTROL1_3(msg_class, type1_in, type1_out, type2_out, type3_out) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_CONTROL2_0(msg_class, type1_in, type2_in) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_CONTROL2_1(msg_class, type1_in, type2_in, type1_out) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_CONTROL2_2(msg_class, type1_in, type2_in, type1_out, type2_out) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_CONTROL2_3(msg_class, type1_in, type2_in, type1_out, type2_out, type3_out) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_CONTROL3_1(msg_class, type1_in, type2_in, type3_in, type1_out) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_CONTROL3_2(msg_class, type1_in, type2_in, type3_in, type1_out, type2_out) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_CONTROL3_3(msg_class, type1_in, type2_in, type3_in, type1_out, type2_out, type3_out) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_CONTROL4_1(msg_class, type1_in, type2_in, type3_in, type4_in, type1_out) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_CONTROL4_2(msg_class, type1_in, type2_in, type3_in, type4_in, type1_out, type2_out) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_ROUTED0_0(msg_class) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_ROUTED0_1(msg_class, type1_out) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_ROUTED0_2(msg_class, type1_out, type2_out) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_ROUTED0_3(msg_class, type1_out, type2_out, type3_out) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_ROUTED1_0(msg_class, type1_in) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_ROUTED1_1(msg_class, type1_in, type1_out) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_ROUTED1_2(msg_class, type1_in, type1_out, type2_out) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_ROUTED1_3(msg_class, type1_in, type1_out, type2_out, type3_out) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_ROUTED1_4(msg_class, type1_in, type1_out, type2_out, type3_out, type4_out) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_ROUTED2_0(msg_class, type1_in, type2_in) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_ROUTED2_1(msg_class, type1_in, type2_in, type1_out) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_ROUTED2_2(msg_class, type1_in, type2_in, type1_out, type2_out) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_ROUTED2_3(msg_class, type1_in, type2_in, type1_out, type2_out, type3_out) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_ROUTED3_0(msg_class, type1_in, type2_in, type3_in) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_ROUTED3_1(msg_class, type1_in, type2_in, type3_in, type1_out) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_ROUTED3_2(msg_class, type1_in, type2_in, type3_in, type1_out, type2_out) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_ROUTED3_3(msg_class, type1_in, type2_in, type3_in, type1_out, type2_out, type3_out) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_ROUTED4_0(msg_class, type1_in, type2_in, type3_in, type4_in) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_ROUTED4_1(msg_class, type1_in, type2_in, type3_in, type4_in, type1_out) \
- msg_class##__ID,
-
-#define IPC_SYNC_MESSAGE_ROUTED4_2(msg_class, type1_in, type2_in, type3_in, type4_in, type1_out, type2_out) \
- msg_class##__ID,
-
-// Message crackers and handlers.
-// Prefer to use the IPC_BEGIN_MESSAGE_MAP_EX to the older macros since they
-// allow you to detect when a message could not be de-serialized. Usage:
-//
-// void MyClass::OnMessageReceived(const IPC::Message& msg) {
-// bool msg_is_good = false;
-// IPC_BEGIN_MESSAGE_MAP_EX(MyClass, msg, msg_is_good)
-// IPC_MESSAGE_HANDLER(MsgClassOne, OnMsgClassOne)
-// ...more handlers here ...
-// IPC_MESSAGE_HANDLER(MsgClassTen, OnMsgClassTen)
-// IPC_END_MESSAGE_MAP_EX()
-// if (!msg_is_good) {
-// // Signal error here or terminate offending process.
-// }
-// }
-
-#define IPC_DEFINE_MESSAGE_MAP(class_name) \
-void class_name::OnMessageReceived(const IPC::Message& msg) \
- IPC_BEGIN_MESSAGE_MAP(class_name, msg)
-
-#define IPC_BEGIN_MESSAGE_MAP_EX(class_name, msg, msg_is_ok) \
- { \
- typedef class_name _IpcMessageHandlerClass; \
- const IPC::Message& ipc_message__ = msg; \
- bool& msg_is_ok__ = msg_is_ok; \
- switch (ipc_message__.type()) { \
-
-#define IPC_BEGIN_MESSAGE_MAP(class_name, msg) \
- { \
- typedef class_name _IpcMessageHandlerClass; \
- const IPC::Message& ipc_message__ = msg; \
- bool msg_is_ok__ = true; \
- switch (ipc_message__.type()) { \
-
-#define IPC_MESSAGE_FORWARD(msg_class, obj, member_func) \
- case msg_class::ID: \
- msg_is_ok__ = msg_class::Dispatch(&ipc_message__, obj, &member_func); \
- break;
-
-#define IPC_MESSAGE_HANDLER(msg_class, member_func) \
- IPC_MESSAGE_FORWARD(msg_class, this, _IpcMessageHandlerClass::member_func)
-
-#define IPC_MESSAGE_FORWARD_DELAY_REPLY(msg_class, obj, member_func) \
- case msg_class::ID: \
- msg_class::DispatchDelayReply(&ipc_message__, obj, &member_func); \
- break;
-
-#define IPC_MESSAGE_HANDLER_DELAY_REPLY(msg_class, member_func) \
- IPC_MESSAGE_FORWARD_DELAY_REPLY(msg_class, this, _IpcMessageHandlerClass::member_func)
-
-#define IPC_MESSAGE_HANDLER_GENERIC(msg_class, code) \
- case msg_class::ID: \
- code; \
- break;
-
-#define IPC_REPLY_HANDLER(func) \
- case IPC_REPLY_ID: \
- func(ipc_message__); \
- break;
-
-
-#define IPC_MESSAGE_UNHANDLED(code) \
- default: \
- code; \
- break;
-
-#define IPC_MESSAGE_UNHANDLED_ERROR() \
- IPC_MESSAGE_UNHANDLED(NOTREACHED() << \
- "Invalid message with type = " << \
- ipc_message__.type())
-
-#define IPC_END_MESSAGE_MAP() \
- DCHECK(msg_is_ok__); \
- } \
-}
-
-#define IPC_END_MESSAGE_MAP_EX() \
- } \
-}
-
-#elif defined(IPC_MESSAGE_MACROS_LOG)
-#undef IPC_MESSAGE_MACROS_LOG
-
-#ifndef IPC_LOG_TABLE_CREATED
-#define IPC_LOG_TABLE_CREATED
-typedef void (*LogFunction)(uint16 type,
- std::wstring* name,
- const IPC::Message* msg,
- std::wstring* params);
-
-LogFunction g_log_function_mapping[LastMsgIndex];
-#endif
-
-
-#define IPC_BEGIN_MESSAGES(label) \
- void label##MsgLog(uint16 type, std::wstring* name, const IPC::Message* msg, std::wstring* params) { \
- switch (type) {
-
-#define IPC_END_MESSAGES(label) \
- default: \
- if (name) \
- *name = L"[UNKNOWN " L ## #label L" MSG"; \
- } \
- } \
- class LoggerRegisterHelper##label { \
- public: \
- LoggerRegisterHelper##label() { \
- g_log_function_mapping[label##MsgStart] = label##MsgLog; \
- } \
- }; \
- LoggerRegisterHelper##label g_LoggerRegisterHelper##label;
-
-#define IPC_MESSAGE_LOG(msg_class) \
- case msg_class##__ID: \
- if (name) \
- *name = L ## #msg_class; \
- if (msg && params) \
- msg_class::Log(msg, params); \
- break;
-
-#define IPC_MESSAGE_CONTROL0(msg_class) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_MESSAGE_CONTROL1(msg_class, type1) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_MESSAGE_CONTROL2(msg_class, type1, type2) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_MESSAGE_CONTROL3(msg_class, type1, type2, type3) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_MESSAGE_CONTROL4(msg_class, type1, type2, type3, type4) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_MESSAGE_CONTROL5(msg_class, type1, type2, type3, type4, type5) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_MESSAGE_ROUTED0(msg_class) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_MESSAGE_ROUTED1(msg_class, type1) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_MESSAGE_ROUTED2(msg_class, type1, type2) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_MESSAGE_ROUTED3(msg_class, type1, type2, type3) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_MESSAGE_ROUTED4(msg_class, type1, type2, type3, type4) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_MESSAGE_ROUTED5(msg_class, type1, type2, type3, type4, type5) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_MESSAGE_ROUTED6(msg_class, type1, type2, type3, type4, type5, type6) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_CONTROL0_0(msg_class) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_CONTROL0_1(msg_class, type1_out) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_CONTROL0_2(msg_class, type1_out, type2_out) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_CONTROL0_3(msg_class, type1_out, type2_out, type3_out) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_CONTROL1_0(msg_class, type1_in) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_CONTROL1_1(msg_class, type1_in, type1_out) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_CONTROL1_2(msg_class, type1_in, type1_out, type2_out) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_CONTROL1_3(msg_class, type1_in, type1_out, type2_out, type3_out) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_CONTROL2_0(msg_class, type1_in, type2_in) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_CONTROL2_1(msg_class, type1_in, type2_in, type1_out) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_CONTROL2_2(msg_class, type1_in, type2_in, type1_out, type2_out) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_CONTROL2_3(msg_class, type1_in, type2_in, type1_out, type2_out, type3_out) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_CONTROL3_1(msg_class, type1_in, type2_in, type3_in, type1_out) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_CONTROL3_2(msg_class, type1_in, type2_in, type3_in, type1_out, type2_out) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_CONTROL3_3(msg_class, type1_in, type2_in, type3_in, type1_out, type2_out, type3_out) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_CONTROL4_1(msg_class, type1_in, type2_in, type3_in, type4_in, type1_out) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_CONTROL4_2(msg_class, type1_in, type2_in, type3_in, type4_in, type1_out, type2_out) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_ROUTED0_0(msg_class) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_ROUTED0_1(msg_class, type1_out) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_ROUTED0_2(msg_class, type1_out, type2_out) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_ROUTED0_3(msg_class, type1_out, type2_out, type3_out) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_ROUTED1_0(msg_class, type1_in) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_ROUTED1_1(msg_class, type1_in, type1_out) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_ROUTED1_2(msg_class, type1_in, type1_out, type2_out) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_ROUTED1_3(msg_class, type1_in, type1_out, type2_out, type3_out) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_ROUTED1_4(msg_class, type1_in, type1_out, type2_out, type3_out, type4_out) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_ROUTED2_0(msg_class, type1_in, type2_in) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_ROUTED2_1(msg_class, type1_in, type2_in, type1_out) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_ROUTED2_2(msg_class, type1_in, type2_in, type1_out, type2_out) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_ROUTED2_3(msg_class, type1_in, type2_in, type1_out, type2_out, type3_out) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_ROUTED3_0(msg_class, type1_in, type2_in, type3_in) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_ROUTED3_1(msg_class, type1_in, type2_in, type3_in, type1_out) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_ROUTED3_2(msg_class, type1_in, type2_in, type3_in, type1_out, type2_out) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_ROUTED3_3(msg_class, type1_in, type2_in, type3_in, type1_out, type2_out, type3_out) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_ROUTED4_0(msg_class, type1_in, type2_in, type3_in, type4_in) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_ROUTED4_1(msg_class, type1_in, type2_in, type3_in, type4_in, type1_out) \
- IPC_MESSAGE_LOG(msg_class)
-
-#define IPC_SYNC_MESSAGE_ROUTED4_2(msg_class, type1_in, type2_in, type3_in, type4_in, type1_out, type2_out) \
- IPC_MESSAGE_LOG(msg_class)
-
-#elif defined(IPC_MESSAGE_MACROS_CLASSES)
-#undef IPC_MESSAGE_MACROS_CLASSES
-
-#define IPC_BEGIN_MESSAGES(label)
-#define IPC_END_MESSAGES(label)
-
-#define IPC_MESSAGE_CONTROL0(msg_class) \
- class msg_class : public IPC::Message { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class() \
- : IPC::Message(MSG_ROUTING_CONTROL, \
- ID, \
- PRIORITY_NORMAL) {} \
- };
-
-#define IPC_MESSAGE_CONTROL1(msg_class, type1) \
- class msg_class : public IPC::MessageWithTuple<type1> { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(const type1& arg1) \
- : IPC::MessageWithTuple<type1>(MSG_ROUTING_CONTROL, \
- ID, \
- arg1) {} \
- };
-
-#define IPC_MESSAGE_CONTROL2(msg_class, type1, type2) \
- class msg_class : public IPC::MessageWithTuple< Tuple2<type1, type2> > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(const type1& arg1, const type2& arg2) \
- : IPC::MessageWithTuple< Tuple2<type1, type2> >( \
- MSG_ROUTING_CONTROL, \
- ID, \
- MakeTuple(arg1, arg2)) {} \
- };
-
-#define IPC_MESSAGE_CONTROL3(msg_class, type1, type2, type3) \
- class msg_class : \
- public IPC::MessageWithTuple< Tuple3<type1, type2, type3> > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(const type1& arg1, const type2& arg2, const type3& arg3) \
- : IPC::MessageWithTuple< Tuple3<type1, type2, type3> >( \
- MSG_ROUTING_CONTROL, \
- ID, \
- MakeTuple(arg1, arg2, arg3)) {} \
- };
-
-#define IPC_MESSAGE_CONTROL4(msg_class, type1, type2, type3, type4) \
- class msg_class : \
- public IPC::MessageWithTuple< Tuple4<type1, type2, type3, type4> > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(const type1& arg1, const type2& arg2, const type3& arg3, \
- const type4& arg4) \
- : IPC::MessageWithTuple< Tuple4<type1, type2, type3, type4> >( \
- MSG_ROUTING_CONTROL, \
- ID, \
- MakeTuple(arg1, arg2, arg3, arg4)) {} \
- };
-
-#define IPC_MESSAGE_CONTROL5(msg_class, type1, type2, type3, type4, type5) \
- class msg_class : \
- public IPC::MessageWithTuple< Tuple5<type1, type2, type3, type4, type5> > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(const type1& arg1, const type2& arg2, \
- const type3& arg3, const type4& arg4, const type5& arg5) \
- : IPC::MessageWithTuple< Tuple5<type1, type2, type3, type4, type5> >( \
- MSG_ROUTING_CONTROL, \
- ID, \
- MakeTuple(arg1, arg2, arg3, arg4, arg5)) {} \
- };
-
-#define IPC_MESSAGE_ROUTED0(msg_class) \
- class msg_class : public IPC::Message { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(int32 routing_id) \
- : IPC::Message(routing_id, ID, PRIORITY_NORMAL) {} \
- };
-
-#define IPC_MESSAGE_ROUTED1(msg_class, type1) \
- class msg_class : public IPC::MessageWithTuple<type1> { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(int32 routing_id, const type1& arg1) \
- : IPC::MessageWithTuple<type1>(routing_id, ID, arg1) {} \
- };
-
-#define IPC_MESSAGE_ROUTED2(msg_class, type1, type2) \
- class msg_class : public IPC::MessageWithTuple< Tuple2<type1, type2> > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(int32 routing_id, const type1& arg1, const type2& arg2) \
- : IPC::MessageWithTuple< Tuple2<type1, type2> >( \
- routing_id, ID, MakeTuple(arg1, arg2)) {} \
- };
-
-#define IPC_MESSAGE_ROUTED3(msg_class, type1, type2, type3) \
- class msg_class : \
- public IPC::MessageWithTuple< Tuple3<type1, type2, type3> > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(int32 routing_id, const type1& arg1, const type2& arg2, \
- const type3& arg3) \
- : IPC::MessageWithTuple< Tuple3<type1, type2, type3> >( \
- routing_id, ID, MakeTuple(arg1, arg2, arg3)) {} \
- };
-
-#define IPC_MESSAGE_ROUTED4(msg_class, type1, type2, type3, type4) \
- class msg_class : \
- public IPC::MessageWithTuple< Tuple4<type1, type2, type3, type4> > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(int32 routing_id, const type1& arg1, const type2& arg2, \
- const type3& arg3, const type4& arg4) \
- : IPC::MessageWithTuple< Tuple4<type1, type2, type3, type4> >( \
- routing_id, ID, MakeTuple(arg1, arg2, arg3, arg4)) {} \
- };
-
-#define IPC_MESSAGE_ROUTED5(msg_class, type1, type2, type3, type4, type5) \
- class msg_class : \
- public IPC::MessageWithTuple< Tuple5<type1, type2, type3, type4, type5> > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(int32 routing_id, const type1& arg1, const type2& arg2, \
- const type3& arg3, const type4& arg4, const type5& arg5) \
- : IPC::MessageWithTuple< Tuple5<type1, type2, type3, type4, type5> >( \
- routing_id, ID, MakeTuple(arg1, arg2, arg3, arg4, arg5)) {} \
- };
-
-#define IPC_MESSAGE_ROUTED6(msg_class, type1, type2, type3, type4, type5, \
- type6) \
- class msg_class : \
- public IPC::MessageWithTuple< Tuple6<type1, type2, type3, type4, type5, \
- type6> > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(int32 routing_id, const type1& arg1, const type2& arg2, \
- const type3& arg3, const type4& arg4, const type5& arg5, \
- const type6& arg6) \
- : IPC::MessageWithTuple< Tuple6<type1, type2, type3, type4, type5, \
- type6> >( \
- routing_id, ID, MakeTuple(arg1, arg2, arg3, arg4, arg5, arg6)) {} \
- };
-
-#define IPC_SYNC_MESSAGE_CONTROL0_0(msg_class) \
- class msg_class : public IPC::MessageWithReply<Tuple0, Tuple0 > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class() \
- : IPC::MessageWithReply<Tuple0, Tuple0 >( \
- MSG_ROUTING_CONTROL, ID, \
- MakeTuple(), MakeTuple()) {} \
- };
-
-#define IPC_SYNC_MESSAGE_CONTROL0_1(msg_class, type1_out) \
- class msg_class : public IPC::MessageWithReply<Tuple0, Tuple1<type1_out&> > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(type1_out* arg1) \
- : IPC::MessageWithReply<Tuple0, Tuple1<type1_out&> >( \
- MSG_ROUTING_CONTROL, \
- ID, \
- MakeTuple(), MakeRefTuple(*arg1)) {} \
- };
-
-#define IPC_SYNC_MESSAGE_CONTROL0_2(msg_class, type1_out, type2_out) \
- class msg_class : \
- public IPC::MessageWithReply<Tuple0, Tuple2<type1_out&, type2_out&> > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(type1_out* arg1, type2_out* arg2) \
- : IPC::MessageWithReply<Tuple0, Tuple2<type1_out&, type2_out&> >( \
- MSG_ROUTING_CONTROL, \
- ID, \
- MakeTuple(), MakeRefTuple(*arg1, *arg2)) {} \
- };
-
-#define IPC_SYNC_MESSAGE_CONTROL0_3(msg_class, type1_out, type2_out, type3_out) \
- class msg_class : \
- public IPC::MessageWithReply<Tuple0, \
- Tuple3<type1_out&, type2_out&, type3_out&> >{ \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(type1_out* arg1, type2_out* arg2, type3_out* arg3) \
- : IPC::MessageWithReply<Tuple0, \
- Tuple3<type1_out&, type2_out&, type3_out&> >(MSG_ROUTING_CONTROL, \
- ID, \
- MakeTuple(), MakeRefTuple(*arg1, *arg2, *arg3)) {} \
- };
-
-#define IPC_SYNC_MESSAGE_CONTROL1_0(msg_class, type1_in) \
- class msg_class : \
- public IPC::MessageWithReply<type1_in, Tuple0 > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(const type1_in& arg1) \
- : IPC::MessageWithReply<type1_in, Tuple0 >( \
- MSG_ROUTING_CONTROL, ID, \
- arg1, MakeTuple()) {} \
- };
-
-#define IPC_SYNC_MESSAGE_CONTROL1_1(msg_class, type1_in, type1_out) \
- class msg_class : \
- public IPC::MessageWithReply<type1_in, Tuple1<type1_out&> > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(const type1_in& arg1, type1_out* arg2) \
- : IPC::MessageWithReply<type1_in, Tuple1<type1_out&> >( \
- MSG_ROUTING_CONTROL, ID, \
- arg1, MakeRefTuple(*arg2)) {} \
- };
-
-#define IPC_SYNC_MESSAGE_CONTROL1_2(msg_class, type1_in, type1_out, type2_out) \
- class msg_class : \
- public IPC::MessageWithReply<type1_in, Tuple2<type1_out&, type2_out&> > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(const type1_in& arg1, type1_out* arg2, type2_out* arg3) \
- : IPC::MessageWithReply<type1_in, Tuple2<type1_out&, type2_out&> >( \
- MSG_ROUTING_CONTROL, ID, \
- arg1, MakeRefTuple(*arg2, *arg3)) {} \
- };
-
-#define IPC_SYNC_MESSAGE_CONTROL1_3(msg_class, type1_in, type1_out, type2_out, type3_out) \
- class msg_class : \
- public IPC::MessageWithReply<type1_in, \
- Tuple3<type1_out&, type2_out&, type3_out&> >{ \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(const type1_in& arg1, type1_out* arg2, type2_out* arg3, type3_out* arg4) \
- : IPC::MessageWithReply<type1_in, \
- Tuple3<type1_out&, type2_out&, type3_out&> >(MSG_ROUTING_CONTROL, \
- ID, \
- arg1, MakeRefTuple(*arg2, *arg3, *arg4)) {} \
- };
-
-#define IPC_SYNC_MESSAGE_CONTROL2_0(msg_class, type1_in, type2_in) \
- class msg_class : \
- public IPC::MessageWithReply<Tuple2<type1_in, type2_in>, Tuple0 > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(const type1_in& arg1, const type2_in& arg2) \
- : IPC::MessageWithReply<Tuple2<type1_in, type2_in>, Tuple0 >( \
- MSG_ROUTING_CONTROL, ID, \
- MakeTuple(arg1, arg2), MakeTuple()) {} \
- };
-
-#define IPC_SYNC_MESSAGE_CONTROL2_1(msg_class, type1_in, type2_in, type1_out) \
- class msg_class : \
- public IPC::MessageWithReply<Tuple2<type1_in, type2_in>, Tuple1<type1_out&> > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(const type1_in& arg1, const type2_in& arg2, type1_out* arg3) \
- : IPC::MessageWithReply<Tuple2<type1_in, type2_in>, Tuple1<type1_out&> >( \
- MSG_ROUTING_CONTROL, ID, \
- MakeTuple(arg1, arg2), MakeRefTuple(*arg3)) {} \
- };
-
-#define IPC_SYNC_MESSAGE_CONTROL2_2(msg_class, type1_in, type2_in, type1_out, type2_out) \
- class msg_class : \
- public IPC::MessageWithReply<Tuple2<type1_in, type2_in>, \
- Tuple2<type1_out&, type2_out&> > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(const type1_in& arg1, const type2_in& arg2, type1_out* arg3, type2_out* arg4) \
- : IPC::MessageWithReply<Tuple2<type1_in, type2_in>, \
- Tuple2<type1_out&, type2_out&> >(MSG_ROUTING_CONTROL, ID, \
- MakeTuple(arg1, arg2), MakeRefTuple(*arg3, *arg4)) {} \
- };
-
-#define IPC_SYNC_MESSAGE_CONTROL2_3(msg_class, type1_in, type2_in, type1_out, type2_out, type3_out) \
- class msg_class : \
- public IPC::MessageWithReply<Tuple2<type1_in, type2_in>, \
- Tuple3<type1_out&, type2_out&, type3_out&> > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(const type1_in& arg1, const type2_in& arg2, type1_out* arg3, type2_out* arg4, type3_out* arg5) \
- : IPC::MessageWithReply<Tuple2<type1_in, type2_in>, \
- Tuple3<type1_out&, type2_out&, type3_out&> >(MSG_ROUTING_CONTROL, \
- ID, \
- MakeTuple(arg1, arg2), MakeRefTuple(*arg3, *arg4, *arg5)) {} \
- };
-
-#define IPC_SYNC_MESSAGE_CONTROL3_1(msg_class, type1_in, type2_in, type3_in, type1_out) \
- class msg_class : \
- public IPC::MessageWithReply<Tuple3<type1_in, type2_in, type3_in>, \
- Tuple1<type1_out&> > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(const type1_in& arg1, const type2_in& arg2, const type3_in& arg3, type1_out* arg4) \
- : IPC::MessageWithReply<Tuple3<type1_in, type2_in, type3_in>, \
- Tuple1<type1_out&> >(MSG_ROUTING_CONTROL, ID, \
- MakeTuple(arg1, arg2, arg3), MakeRefTuple(*arg4)) {} \
- };
-
-#define IPC_SYNC_MESSAGE_CONTROL3_2(msg_class, type1_in, type2_in, type3_in, type1_out, type2_out) \
- class msg_class : \
- public IPC::MessageWithReply<Tuple3<type1_in, type2_in, type3_in>, \
- Tuple2<type1_out&, type2_out&> > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(const type1_in& arg1, const type2_in& arg2, const type3_in& arg3, type1_out* arg4, type2_out* arg5) \
- : IPC::MessageWithReply<Tuple3<type1_in, type2_in, type3_in>, \
- Tuple2<type1_out&, type2_out&> >(MSG_ROUTING_CONTROL, ID, \
- MakeTuple(arg1, arg2, arg3), MakeRefTuple(*arg4, *arg5)) {} \
- };
-
-#define IPC_SYNC_MESSAGE_CONTROL3_3(msg_class, type1_in, type2_in, type3_in, type1_out, type2_out, type3_out) \
- class msg_class : \
- public IPC::MessageWithReply<Tuple3<type1_in, type2_in, type3_in>, \
- Tuple3<type1_out&, type2_out&, type3_out&> > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(const type1_in& arg1, const type2_in& arg2, const type3_in& arg3, type1_out* arg4, type2_out* arg5, type3_out* arg6) \
- : IPC::MessageWithReply<Tuple3<type1_in, type2_in, type3_in>, \
- Tuple3<type1_out&, type2_out&, type3_out&> >(MSG_ROUTING_CONTROL, \
- ID, \
- MakeTuple(arg1, arg2, arg3), MakeRefTuple(*arg4, *arg5, *arg6)) {} \
- };
-
-#define IPC_SYNC_MESSAGE_CONTROL4_1(msg_class, type1_in, type2_in, type3_in, type4_in, type1_out) \
- class msg_class : \
- public IPC::MessageWithReply<Tuple4<type1_in, type2_in, type3_in, type4_in>, \
- Tuple1<type1_out&> > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(const type1_in& arg1, const type2_in& arg2, const type3_in& arg3, const type4_in& arg4, type1_out* arg6) \
- : IPC::MessageWithReply<Tuple4<type1_in, type2_in, type3_in, type4_in>, \
- Tuple1<type1_out&> >(MSG_ROUTING_CONTROL, ID, \
- MakeTuple(arg1, arg2, arg3, arg4), MakeRefTuple(*arg6)) {} \
- };
-
-#define IPC_SYNC_MESSAGE_CONTROL4_2(msg_class, type1_in, type2_in, type3_in, type4_in, type1_out, type2_out) \
- class msg_class : \
- public IPC::MessageWithReply<Tuple4<type1_in, type2_in, type3_in, type4_in>, \
- Tuple2<type1_out&, type2_out&> > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(const type1_in& arg1, const type2_in& arg2, const type3_in& arg3, const type4_in& arg4, type1_out* arg5, type2_out* arg6) \
- : IPC::MessageWithReply<Tuple4<type1_in, type2_in, type3_in, type4_in>, \
- Tuple2<type1_out&, type2_out&> >(MSG_ROUTING_CONTROL, ID, \
- MakeTuple(arg1, arg2, arg3, arg4), MakeRefTuple(*arg5, *arg6)) {} \
- };
-
-#define IPC_SYNC_MESSAGE_ROUTED0_1(msg_class, type1_out) \
- class msg_class : public IPC::MessageWithReply<Tuple0, Tuple1<type1_out&> > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(int routing_id, type1_out* arg1) \
- : IPC::MessageWithReply<Tuple0, Tuple1<type1_out&> >( \
- routing_id, ID, \
- MakeTuple(), MakeRefTuple(*arg1)) {} \
- };
-
-#define IPC_SYNC_MESSAGE_ROUTED0_0(msg_class) \
- class msg_class : public IPC::MessageWithReply<Tuple0, Tuple0 > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(int routing_id) \
- : IPC::MessageWithReply<Tuple0, Tuple0 >( \
- routing_id, ID, \
- MakeTuple(), MakeTuple()) {} \
- };
-
-#define IPC_SYNC_MESSAGE_ROUTED0_2(msg_class, type1_out, type2_out) \
- class msg_class : \
- public IPC::MessageWithReply<Tuple0, Tuple2<type1_out&, type2_out&> > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(int routing_id, type1_out* arg1, type2_out* arg2) \
- : IPC::MessageWithReply<Tuple0, Tuple2<type1_out&, type2_out&> >( \
- routing_id, ID, \
- MakeTuple(), MakeRefTuple(*arg1, *arg2)) {} \
- };
-
-#define IPC_SYNC_MESSAGE_ROUTED0_3(msg_class, type1_out, type2_out, type3_out) \
- class msg_class : \
- public IPC::MessageWithReply<Tuple0, \
- Tuple3<type1_out&, type2_out&, type3_out&> >{ \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(int routing_id, type1_out* arg1, type2_out* arg2, type3_out* arg3) \
- : IPC::MessageWithReply<Tuple0, \
- Tuple3<type1_out&, type2_out&, type3_out&> >(routing_id, ID, \
- MakeTuple(), MakeRefTuple(*arg1, *arg2, *arg3)) {} \
- };
-
-#define IPC_SYNC_MESSAGE_ROUTED1_0(msg_class, type1_in) \
- class msg_class : \
- public IPC::MessageWithReply<type1_in, Tuple0 > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(int routing_id, const type1_in& arg1) \
- : IPC::MessageWithReply<type1_in, Tuple0 >( \
- routing_id, ID, \
- arg1, MakeTuple()) {} \
- };
-
-#define IPC_SYNC_MESSAGE_ROUTED1_1(msg_class, type1_in, type1_out) \
- class msg_class : \
- public IPC::MessageWithReply<type1_in, Tuple1<type1_out&> > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(int routing_id, const type1_in& arg1, type1_out* arg2) \
- : IPC::MessageWithReply<type1_in, Tuple1<type1_out&> >( \
- routing_id, ID, \
- arg1, MakeRefTuple(*arg2)) {} \
- };
-
-#define IPC_SYNC_MESSAGE_ROUTED1_2(msg_class, type1_in, type1_out, type2_out) \
- class msg_class : \
- public IPC::MessageWithReply<type1_in, Tuple2<type1_out&, type2_out&> > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(int routing_id, const type1_in& arg1, type1_out* arg2, type2_out* arg3) \
- : IPC::MessageWithReply<type1_in, Tuple2<type1_out&, type2_out&> >( \
- routing_id, ID, \
- arg1, MakeRefTuple(*arg2, *arg3)) {} \
- };
-
-#define IPC_SYNC_MESSAGE_ROUTED1_3(msg_class, type1_in, type1_out, type2_out, type3_out) \
- class msg_class : \
- public IPC::MessageWithReply<type1_in, \
- Tuple3<type1_out&, type2_out&, type3_out&> >{ \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(int routing_id, const type1_in& arg1, type1_out* arg2, type2_out* arg3, type3_out* arg4) \
- : IPC::MessageWithReply<type1_in, \
- Tuple3<type1_out&, type2_out&, type3_out&> >(routing_id, ID, \
- arg1, MakeRefTuple(*arg2, *arg3, *arg4)) {} \
- };
-
-#define IPC_SYNC_MESSAGE_ROUTED1_4(msg_class, type1_in, type1_out, type2_out, type3_out, type4_out) \
- class msg_class : \
- public IPC::MessageWithReply<type1_in, \
- Tuple4<type1_out&, type2_out&, type3_out&, type4_out&> >{ \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(int routing_id, const type1_in& arg1, type1_out* arg2, type2_out* arg3, type3_out* arg4, type4_out* arg5) \
- : IPC::MessageWithReply<type1_in, \
- Tuple4<type1_out&, type2_out&, type3_out&, type4_out&> >(routing_id, ID, \
- arg1, MakeRefTuple(*arg2, *arg3, *arg4, *arg5)) {} \
- };
-
-#define IPC_SYNC_MESSAGE_ROUTED2_0(msg_class, type1_in, type2_in) \
- class msg_class : \
- public IPC::MessageWithReply<Tuple2<type1_in, type2_in>, Tuple0 > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(int routing_id, const type1_in& arg1, const type2_in& arg2) \
- : IPC::MessageWithReply<Tuple2<type1_in, type2_in>, Tuple0 >( \
- routing_id, ID, \
- MakeTuple(arg1, arg2), MakeTuple()) {} \
- };
-
-#define IPC_SYNC_MESSAGE_ROUTED2_1(msg_class, type1_in, type2_in, type1_out) \
- class msg_class : \
- public IPC::MessageWithReply<Tuple2<type1_in, type2_in>, Tuple1<type1_out&> > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(int routing_id, const type1_in& arg1, const type2_in& arg2, type1_out* arg3) \
- : IPC::MessageWithReply<Tuple2<type1_in, type2_in>, Tuple1<type1_out&> >( \
- routing_id, ID, \
- MakeTuple(arg1, arg2), MakeRefTuple(*arg3)) {} \
- };
-
-#define IPC_SYNC_MESSAGE_ROUTED2_2(msg_class, type1_in, type2_in, type1_out, type2_out) \
- class msg_class : \
- public IPC::MessageWithReply<Tuple2<type1_in, type2_in>, \
- Tuple2<type1_out&, type2_out&> > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(int routing_id, const type1_in& arg1, const type2_in& arg2, type1_out* arg3, type2_out* arg4) \
- : IPC::MessageWithReply<Tuple2<type1_in, type2_in>, \
- Tuple2<type1_out&, type2_out&> >(routing_id, ID, \
- MakeTuple(arg1, arg2), MakeRefTuple(*arg3, *arg4)) {} \
- };
-
-#define IPC_SYNC_MESSAGE_ROUTED2_3(msg_class, type1_in, type2_in, type1_out, type2_out, type3_out) \
- class msg_class : \
- public IPC::MessageWithReply<Tuple2<type1_in, type2_in>, \
- Tuple3<type1_out&, type2_out&, type3_out&> > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(int routing_id, const type1_in& arg1, const type2_in& arg2, type1_out* arg3, type2_out* arg4, type3_out* arg5) \
- : IPC::MessageWithReply<Tuple2<type1_in, type2_in>, \
- Tuple3<type1_out&, type2_out&, type3_out&> >(routing_id, ID, \
- MakeTuple(arg1, arg2), MakeRefTuple(*arg3, *arg4, *arg5)) {} \
- };
-
-#define IPC_SYNC_MESSAGE_ROUTED3_0(msg_class, type1_in, type2_in, type3_in) \
- class msg_class : \
- public IPC::MessageWithReply<Tuple3<type1_in, type2_in, type3_in>, Tuple0 > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(int routing_id, const type1_in& arg1, const type2_in& arg2, const type3_in& arg3) \
- : IPC::MessageWithReply<Tuple3<type1_in, type2_in, type3_in>, Tuple0>( \
- routing_id, ID, \
- MakeTuple(arg1, arg2, arg3), MakeTuple()) {} \
- };
-
-#define IPC_SYNC_MESSAGE_ROUTED3_1(msg_class, type1_in, type2_in, type3_in, type1_out) \
- class msg_class : \
- public IPC::MessageWithReply<Tuple3<type1_in, type2_in, type3_in>, \
- Tuple1<type1_out&> > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(int routing_id, const type1_in& arg1, const type2_in& arg2, const type3_in& arg3, type1_out* arg4) \
- : IPC::MessageWithReply<Tuple3<type1_in, type2_in, type3_in>, \
- Tuple1<type1_out&> >(routing_id, ID, \
- MakeTuple(arg1, arg2, arg3), MakeRefTuple(*arg4)) {} \
- };
-
-#define IPC_SYNC_MESSAGE_ROUTED3_2(msg_class, type1_in, type2_in, type3_in, type1_out, type2_out) \
- class msg_class : \
- public IPC::MessageWithReply<Tuple3<type1_in, type2_in, type3_in>, \
- Tuple2<type1_out&, type2_out&> > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(int routing_id, const type1_in& arg1, const type2_in& arg2, const type3_in& arg3, type1_out* arg4, type2_out* arg5) \
- : IPC::MessageWithReply<Tuple3<type1_in, type2_in, type3_in>, \
- Tuple2<type1_out&, type2_out&> >(routing_id, ID, \
- MakeTuple(arg1, arg2, arg3), MakeRefTuple(*arg4, *arg5)) {} \
- };
-
-#define IPC_SYNC_MESSAGE_ROUTED3_3(msg_class, type1_in, type2_in, type3_in, type1_out, type2_out, type3_out) \
- class msg_class : \
- public IPC::MessageWithReply<Tuple3<type1_in, type2_in, type3_in>, \
- Tuple3<type1_out&, type2_out&, type3_out&> > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(int routing_id, const type1_in& arg1, const type2_in& arg2, const type3_in& arg3, type1_out* arg4, type2_out* arg5, type3_out* arg6) \
- : IPC::MessageWithReply<Tuple3<type1_in, type2_in, type3_in>, \
- Tuple3<type1_out&, type2_out&, type3_out&> >(routing_id, ID, \
- MakeTuple(arg1, arg2, arg3), MakeRefTuple(*arg4, *arg5, *arg6)) {} \
- };
-
-#define IPC_SYNC_MESSAGE_ROUTED4_0(msg_class, type1_in, type2_in, type3_in, type4_in) \
- class msg_class : \
- public IPC::MessageWithReply<Tuple4<type1_in, type2_in, type3_in, type4_in>, \
- Tuple0 > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(int routing_id, const type1_in& arg1, const type2_in& arg2, const type3_in& arg3, const type4_in& arg4) \
- : IPC::MessageWithReply<Tuple4<type1_in, type2_in, type3_in, type4_in>, \
- Tuple0 >(routing_id, ID, \
- MakeTuple(arg1, arg2, arg3, arg4), MakeTuple()) {} \
- };
-
-#define IPC_SYNC_MESSAGE_ROUTED4_1(msg_class, type1_in, type2_in, type3_in, type4_in, type1_out) \
- class msg_class : \
- public IPC::MessageWithReply<Tuple4<type1_in, type2_in, type3_in, type4_in>, \
- Tuple1<type1_out&> > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(int routing_id, const type1_in& arg1, const type2_in& arg2, const type3_in& arg3, const type4_in& arg4, type1_out* arg6) \
- : IPC::MessageWithReply<Tuple4<type1_in, type2_in, type3_in, type4_in>, \
- Tuple1<type1_out&> >(routing_id, ID, \
- MakeTuple(arg1, arg2, arg3, arg4), MakeRefTuple(*arg6)) {} \
- };
-
-#define IPC_SYNC_MESSAGE_ROUTED4_2(msg_class, type1_in, type2_in, type3_in, type4_in, type1_out, type2_out) \
- class msg_class : \
- public IPC::MessageWithReply<Tuple4<type1_in, type2_in, type3_in, type4_in>, \
- Tuple2<type1_out&, type2_out&> > { \
- public: \
- enum { ID = msg_class##__ID }; \
- msg_class(int routing_id, const type1_in& arg1, const type2_in& arg2, const type3_in& arg3, const type4_in& arg4, type1_out* arg5, type2_out* arg6) \
- : IPC::MessageWithReply<Tuple4<type1_in, type2_in, type3_in, type4_in>, \
- Tuple2<type1_out&, type2_out&> >(routing_id, ID, \
- MakeTuple(arg1, arg2, arg3, arg4), MakeRefTuple(*arg5, *arg6)) {} \
- };
-
-#endif // #if defined()
diff --git a/ipc/ipc_message_utils.cc b/ipc/ipc_message_utils.cc
deleted file mode 100644
index 2ee7025..0000000
--- a/ipc/ipc_message_utils.cc
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) 2006-2008 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 "ipc/ipc_message_utils.h"
-
-#include "base/gfx/rect.h"
-
-namespace IPC {
-
-void ParamTraits<gfx::Point>::Write(Message* m, const gfx::Point& p) {
- m->WriteInt(p.x());
- m->WriteInt(p.y());
-}
-
-bool ParamTraits<gfx::Point>::Read(const Message* m, void** iter,
- gfx::Point* r) {
- int x, y;
- if (!m->ReadInt(iter, &x) ||
- !m->ReadInt(iter, &y))
- return false;
- r->set_x(x);
- r->set_y(y);
- return true;
-}
-
-void ParamTraits<gfx::Point>::Log(const gfx::Point& p, std::wstring* l) {
- l->append(StringPrintf(L"(%d, %d)", p.x(), p.y()));
-}
-
-void ParamTraits<gfx::Rect>::Write(Message* m, const gfx::Rect& p) {
- m->WriteInt(p.x());
- m->WriteInt(p.y());
- m->WriteInt(p.width());
- m->WriteInt(p.height());
-}
-
-bool ParamTraits<gfx::Rect>::Read(const Message* m, void** iter, gfx::Rect* r) {
- int x, y, w, h;
- if (!m->ReadInt(iter, &x) ||
- !m->ReadInt(iter, &y) ||
- !m->ReadInt(iter, &w) ||
- !m->ReadInt(iter, &h))
- return false;
- r->set_x(x);
- r->set_y(y);
- r->set_width(w);
- r->set_height(h);
- return true;
-}
-
-void ParamTraits<gfx::Rect>::Log(const gfx::Rect& p, std::wstring* l) {
- l->append(StringPrintf(L"(%d, %d, %d, %d)", p.x(), p.y(),
- p.width(), p.height()));
-}
-
-void ParamTraits<gfx::Size>::Write(Message* m, const gfx::Size& p) {
- m->WriteInt(p.width());
- m->WriteInt(p.height());
-}
-
-bool ParamTraits<gfx::Size>::Read(const Message* m, void** iter, gfx::Size* r) {
- int w, h;
- if (!m->ReadInt(iter, &w) ||
- !m->ReadInt(iter, &h))
- return false;
- r->set_width(w);
- r->set_height(h);
- return true;
-}
-
-void ParamTraits<gfx::Size>::Log(const gfx::Size& p, std::wstring* l) {
- l->append(StringPrintf(L"(%d, %d)", p.width(), p.height()));
-}
-
-} // namespace IPC
diff --git a/ipc/ipc_message_utils.h b/ipc/ipc_message_utils.h
deleted file mode 100644
index 582b491..0000000
--- a/ipc/ipc_message_utils.h
+++ /dev/null
@@ -1,1258 +0,0 @@
-// Copyright (c) 2006-2008 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 IPC_IPC_MESSAGE_UTILS_H_
-#define IPC_IPC_MESSAGE_UTILS_H_
-
-#include <string>
-#include <vector>
-#include <map>
-
-#include "base/file_path.h"
-#include "base/string_util.h"
-#include "base/string16.h"
-#include "base/time.h"
-#include "base/tuple.h"
-#if defined(OS_POSIX)
-#include "ipc/file_descriptor_set_posix.h"
-#endif
-#include "ipc/ipc_sync_message.h"
-
-// Forward declarations.
-namespace gfx {
-class Point;
-class Rect;
-class Size;
-} // namespace gfx
-
-// Used by IPC_BEGIN_MESSAGES so that each message class starts from a unique
-// base. Messages have unique IDs across channels in order for the IPC logging
-// code to figure out the message class from its ID.
-enum IPCMessageStart {
- // By using a start value of 0 for automation messages, we keep backward
- // compatibility with old builds.
- AutomationMsgStart = 0,
- ViewMsgStart,
- ViewHostMsgStart,
- PluginProcessMsgStart,
- PluginProcessHostMsgStart,
- PluginMsgStart,
- PluginHostMsgStart,
- NPObjectMsgStart,
- TestMsgStart,
- DevToolsAgentMsgStart,
- DevToolsClientMsgStart,
- WorkerProcessMsgStart,
- WorkerProcessHostMsgStart,
- WorkerMsgStart,
- WorkerHostMsgStart,
- // NOTE: When you add a new message class, also update
- // IPCStatusView::IPCStatusView to ensure logging works.
- // NOTE: this enum is used by IPC_MESSAGE_MACRO to generate a unique message
- // id. Only 4 bits are used for the message type, so if this enum needs more
- // than 16 entries, that code needs to be updated.
- LastMsgIndex
-};
-
-COMPILE_ASSERT(LastMsgIndex <= 16, need_to_update_IPC_MESSAGE_MACRO);
-
-namespace IPC {
-
-//-----------------------------------------------------------------------------
-// An iterator class for reading the fields contained within a Message.
-
-class MessageIterator {
- public:
- explicit MessageIterator(const Message& m) : msg_(m), iter_(NULL) {
- }
- int NextInt() const {
- int val;
- if (!msg_.ReadInt(&iter_, &val))
- NOTREACHED();
- return val;
- }
- intptr_t NextIntPtr() const {
- intptr_t val;
- if (!msg_.ReadIntPtr(&iter_, &val))
- NOTREACHED();
- return val;
- }
- const std::string NextString() const {
- std::string val;
- if (!msg_.ReadString(&iter_, &val))
- NOTREACHED();
- return val;
- }
- const std::wstring NextWString() const {
- std::wstring val;
- if (!msg_.ReadWString(&iter_, &val))
- NOTREACHED();
- return val;
- }
- const void NextData(const char** data, int* length) const {
- if (!msg_.ReadData(&iter_, data, length)) {
- NOTREACHED();
- }
- }
- private:
- const Message& msg_;
- mutable void* iter_;
-};
-
-//-----------------------------------------------------------------------------
-// ParamTraits specializations, etc.
-
-template <class P> struct ParamTraits {};
-
-template <class P>
-static inline void WriteParam(Message* m, const P& p) {
- ParamTraits<P>::Write(m, p);
-}
-
-template <class P>
-static inline bool ReadParam(const Message* m, void** iter, P* p) {
- return ParamTraits<P>::Read(m, iter, p);
-}
-
-template <class P>
-static inline void LogParam(const P& p, std::wstring* l) {
- ParamTraits<P>::Log(p, l);
-}
-
-template <>
-struct ParamTraits<bool> {
- typedef bool param_type;
- static void Write(Message* m, const param_type& p) {
- m->WriteBool(p);
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- return m->ReadBool(iter, r);
- }
- static void Log(const param_type& p, std::wstring* l) {
- l->append(p ? L"true" : L"false");
- }
-};
-
-template <>
-struct ParamTraits<int> {
- typedef int param_type;
- static void Write(Message* m, const param_type& p) {
- m->WriteInt(p);
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- return m->ReadInt(iter, r);
- }
- static void Log(const param_type& p, std::wstring* l) {
- l->append(StringPrintf(L"%d", p));
- }
-};
-
-template <>
-struct ParamTraits<long> {
- typedef long param_type;
- static void Write(Message* m, const param_type& p) {
- m->WriteLong(p);
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- return m->ReadLong(iter, r);
- }
- static void Log(const param_type& p, std::wstring* l) {
- l->append(StringPrintf(L"%l", p));
- }
-};
-
-template <>
-struct ParamTraits<size_t> {
- typedef size_t param_type;
- static void Write(Message* m, const param_type& p) {
- m->WriteSize(p);
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- return m->ReadSize(iter, r);
- }
- static void Log(const param_type& p, std::wstring* l) {
- l->append(StringPrintf(L"%u", p));
- }
-};
-
-#if defined(OS_MACOSX)
-// On Linux size_t & uint32 can be the same type.
-// TODO(playmobil): Fix compilation if this is not the case.
-template <>
-struct ParamTraits<uint32> {
- typedef uint32 param_type;
- static void Write(Message* m, const param_type& p) {
- m->WriteUInt32(p);
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- return m->ReadUInt32(iter, r);
- }
- static void Log(const param_type& p, std::wstring* l) {
- l->append(StringPrintf(L"%u", p));
- }
-};
-#endif // defined(OS_MACOSX)
-
-template <>
-struct ParamTraits<int64> {
- typedef int64 param_type;
- static void Write(Message* m, const param_type& p) {
- m->WriteInt64(p);
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- return m->ReadInt64(iter, r);
- }
- static void Log(const param_type& p, std::wstring* l) {
- l->append(StringPrintf(L"%I64d", p));
- }
-};
-
-template <>
-struct ParamTraits<uint64> {
- typedef uint64 param_type;
- static void Write(Message* m, const param_type& p) {
- m->WriteInt64(static_cast<int64>(p));
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
- }
- static void Log(const param_type& p, std::wstring* l) {
- l->append(StringPrintf(L"%I64u", p));
- }
-};
-
-template <>
-struct ParamTraits<double> {
- typedef double param_type;
- static void Write(Message* m, const param_type& p) {
- m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- const char *data;
- int data_size = 0;
- bool result = m->ReadData(iter, &data, &data_size);
- if (result && data_size == sizeof(param_type)) {
- memcpy(r, data, sizeof(param_type));
- } else {
- result = false;
- NOTREACHED();
- }
-
- return result;
- }
- static void Log(const param_type& p, std::wstring* l) {
- l->append(StringPrintf(L"e", p));
- }
-};
-
-template <>
-struct ParamTraits<wchar_t> {
- typedef wchar_t param_type;
- static void Write(Message* m, const param_type& p) {
- m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- const char *data;
- int data_size = 0;
- bool result = m->ReadData(iter, &data, &data_size);
- if (result && data_size == sizeof(param_type)) {
- memcpy(r, data, sizeof(param_type));
- } else {
- result = false;
- NOTREACHED();
- }
-
- return result;
- }
- static void Log(const param_type& p, std::wstring* l) {
- l->append(StringPrintf(L"%lc", p));
- }
-};
-
-template <>
-struct ParamTraits<base::Time> {
- typedef base::Time param_type;
- static void Write(Message* m, const param_type& p) {
- ParamTraits<int64>::Write(m, p.ToInternalValue());
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- int64 value;
- if (!ParamTraits<int64>::Read(m, iter, &value))
- return false;
- *r = base::Time::FromInternalValue(value);
- return true;
- }
- static void Log(const param_type& p, std::wstring* l) {
- ParamTraits<int64>::Log(p.ToInternalValue(), l);
- }
-};
-
-#if defined(OS_WIN)
-template <>
-struct ParamTraits<LOGFONT> {
- typedef LOGFONT param_type;
- static void Write(Message* m, const param_type& p) {
- m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- const char *data;
- int data_size = 0;
- bool result = m->ReadData(iter, &data, &data_size);
- if (result && data_size == sizeof(LOGFONT)) {
- memcpy(r, data, sizeof(LOGFONT));
- } else {
- result = false;
- NOTREACHED();
- }
-
- return result;
- }
- static void Log(const param_type& p, std::wstring* l) {
- l->append(StringPrintf(L"<LOGFONT>"));
- }
-};
-
-template <>
-struct ParamTraits<MSG> {
- typedef MSG param_type;
- static void Write(Message* m, const param_type& p) {
- m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- const char *data;
- int data_size = 0;
- bool result = m->ReadData(iter, &data, &data_size);
- if (result && data_size == sizeof(MSG)) {
- memcpy(r, data, sizeof(MSG));
- } else {
- result = false;
- NOTREACHED();
- }
-
- return result;
- }
-};
-#endif // defined(OS_WIN)
-
-template <>
-struct ParamTraits<std::string> {
- typedef std::string param_type;
- static void Write(Message* m, const param_type& p) {
- m->WriteString(p);
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- return m->ReadString(iter, r);
- }
- static void Log(const param_type& p, std::wstring* l) {
- l->append(UTF8ToWide(p));
- }
-};
-
-template <>
-struct ParamTraits<std::vector<unsigned char> > {
- typedef std::vector<unsigned char> param_type;
- static void Write(Message* m, const param_type& p) {
- if (p.size() == 0) {
- m->WriteData(NULL, 0);
- } else {
- m->WriteData(reinterpret_cast<const char*>(&p.front()),
- static_cast<int>(p.size()));
- }
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- const char *data;
- int data_size = 0;
- if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
- return false;
- r->resize(data_size);
- if (data_size)
- memcpy(&r->front(), data, data_size);
- return true;
- }
- static void Log(const param_type& p, std::wstring* l) {
- for (size_t i = 0; i < p.size(); ++i)
- l->push_back(p[i]);
- }
-};
-
-template <>
-struct ParamTraits<std::vector<char> > {
- typedef std::vector<char> param_type;
- static void Write(Message* m, const param_type& p) {
- if (p.size() == 0) {
- m->WriteData(NULL, 0);
- } else {
- m->WriteData(&p.front(), static_cast<int>(p.size()));
- }
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- const char *data;
- int data_size = 0;
- if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
- return false;
- r->resize(data_size);
- if (data_size)
- memcpy(&r->front(), data, data_size);
- return true;
- }
- static void Log(const param_type& p, std::wstring* l) {
- for (size_t i = 0; i < p.size(); ++i)
- l->push_back(p[i]);
- }
-};
-
-template <class P>
-struct ParamTraits<std::vector<P> > {
- typedef std::vector<P> param_type;
- static void Write(Message* m, const param_type& p) {
- WriteParam(m, static_cast<int>(p.size()));
- for (size_t i = 0; i < p.size(); i++)
- WriteParam(m, p[i]);
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- int size;
- if (!m->ReadLength(iter, &size))
- return false;
- // Resizing beforehand is not safe, see BUG 1006367 for details.
- if (m->IteratorHasRoomFor(*iter, size * sizeof(P))) {
- r->resize(size);
- for (int i = 0; i < size; i++) {
- if (!ReadParam(m, iter, &(*r)[i]))
- return false;
- }
- } else {
- for (int i = 0; i < size; i++) {
- P element;
- if (!ReadParam(m, iter, &element))
- return false;
- r->push_back(element);
- }
- }
- return true;
- }
- static void Log(const param_type& p, std::wstring* l) {
- for (size_t i = 0; i < p.size(); ++i) {
- if (i != 0)
- l->append(L" ");
-
- LogParam((p[i]), l);
- }
- }
-};
-
-template <class K, class V>
-struct ParamTraits<std::map<K, V> > {
- typedef std::map<K, V> param_type;
- static void Write(Message* m, const param_type& p) {
- WriteParam(m, static_cast<int>(p.size()));
- typename param_type::const_iterator iter;
- for (iter = p.begin(); iter != p.end(); ++iter) {
- WriteParam(m, iter->first);
- WriteParam(m, iter->second);
- }
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- int size;
- if (!ReadParam(m, iter, &size) || size < 0)
- return false;
- for (int i = 0; i < size; ++i) {
- K k;
- if (!ReadParam(m, iter, &k))
- return false;
- V& value = (*r)[k];
- if (!ReadParam(m, iter, &value))
- return false;
- }
- return true;
- }
- static void Log(const param_type& p, std::wstring* l) {
- l->append(L"<std::map>");
- }
-};
-
-
-template <>
-struct ParamTraits<std::wstring> {
- typedef std::wstring param_type;
- static void Write(Message* m, const param_type& p) {
- m->WriteWString(p);
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- return m->ReadWString(iter, r);
- }
- static void Log(const param_type& p, std::wstring* l) {
- l->append(p);
- }
-};
-
-// If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
-// need this trait.
-#if !defined(WCHAR_T_IS_UTF16)
-template <>
-struct ParamTraits<string16> {
- typedef string16 param_type;
- static void Write(Message* m, const param_type& p) {
- m->WriteString16(p);
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- return m->ReadString16(iter, r);
- }
- static void Log(const param_type& p, std::wstring* l) {
- l->append(UTF16ToWide(p));
- }
-};
-#endif
-
-// and, a few more useful types...
-#if defined(OS_WIN)
-template <>
-struct ParamTraits<HANDLE> {
- typedef HANDLE param_type;
- static void Write(Message* m, const param_type& p) {
- m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
- return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
- }
- static void Log(const param_type& p, std::wstring* l) {
- l->append(StringPrintf(L"0x%X", p));
- }
-};
-
-template <>
-struct ParamTraits<HCURSOR> {
- typedef HCURSOR param_type;
- static void Write(Message* m, const param_type& p) {
- m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
- return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
- }
- static void Log(const param_type& p, std::wstring* l) {
- l->append(StringPrintf(L"0x%X", p));
- }
-};
-
-template <>
-struct ParamTraits<HWND> {
- typedef HWND param_type;
- static void Write(Message* m, const param_type& p) {
- m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
- return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
- }
- static void Log(const param_type& p, std::wstring* l) {
- l->append(StringPrintf(L"0x%X", p));
- }
-};
-
-template <>
-struct ParamTraits<HRGN> {
- typedef HRGN param_type;
- static void Write(Message* m, const param_type& p) {
- int data_size = GetRegionData(p, 0, NULL);
- if (data_size) {
- char* bytes = new char[data_size];
- GetRegionData(p, data_size, reinterpret_cast<LPRGNDATA>(bytes));
- m->WriteData(reinterpret_cast<const char*>(bytes), data_size);
- delete [] bytes;
- } else {
- m->WriteData(NULL, 0);
- }
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- bool res = FALSE;
- const char *data;
- int data_size = 0;
- res = m->ReadData(iter, &data, &data_size);
- if (data_size) {
- *r = ExtCreateRegion(NULL, data_size,
- reinterpret_cast<CONST RGNDATA*>(data));
- } else {
- res = TRUE;
- *r = CreateRectRgn(0, 0, 0, 0);
- }
- return res;
- }
- static void Log(const param_type& p, std::wstring* l) {
- l->append(StringPrintf(L"0x%X", p));
- }
-};
-
-template <>
-struct ParamTraits<HACCEL> {
- typedef HACCEL param_type;
- static void Write(Message* m, const param_type& p) {
- m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
- return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
- }
-};
-
-template <>
-struct ParamTraits<POINT> {
- typedef POINT param_type;
- static void Write(Message* m, const param_type& p) {
- m->WriteInt(p.x);
- m->WriteInt(p.y);
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- int x, y;
- if (!m->ReadInt(iter, &x) || !m->ReadInt(iter, &y))
- return false;
- r->x = x;
- r->y = y;
- return true;
- }
- static void Log(const param_type& p, std::wstring* l) {
- l->append(StringPrintf(L"(%d, %d)", p.x, p.y));
- }
-};
-#endif // defined(OS_WIN)
-
-template <>
-struct ParamTraits<FilePath> {
- typedef FilePath param_type;
- static void Write(Message* m, const param_type& p) {
- ParamTraits<FilePath::StringType>::Write(m, p.value());
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- FilePath::StringType value;
- if (!ParamTraits<FilePath::StringType>::Read(m, iter, &value))
- return false;
- *r = FilePath(value);
- return true;
- }
- static void Log(const param_type& p, std::wstring* l) {
- ParamTraits<FilePath::StringType>::Log(p.value(), l);
- }
-};
-
-template <>
-struct ParamTraits<gfx::Point> {
- typedef gfx::Point param_type;
- static void Write(Message* m, const param_type& p);
- static bool Read(const Message* m, void** iter, param_type* r);
- static void Log(const param_type& p, std::wstring* l);
-};
-
-template <>
-struct ParamTraits<gfx::Rect> {
- typedef gfx::Rect param_type;
- static void Write(Message* m, const param_type& p);
- static bool Read(const Message* m, void** iter, param_type* r);
- static void Log(const param_type& p, std::wstring* l);
-};
-
-template <>
-struct ParamTraits<gfx::Size> {
- typedef gfx::Size param_type;
- static void Write(Message* m, const param_type& p);
- static bool Read(const Message* m, void** iter, param_type* r);
- static void Log(const param_type& p, std::wstring* l);
-};
-
-#if defined(OS_POSIX)
-// FileDescriptors may be serialised over IPC channels on POSIX. On the
-// receiving side, the FileDescriptor is a valid duplicate of the file
-// descriptor which was transmitted: *it is not just a copy of the integer like
-// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
-// this case, the receiving end will see a value of -1. *Zero is a valid file
-// descriptor*.
-//
-// The received file descriptor will have the |auto_close| flag set to true. The
-// code which handles the message is responsible for taking ownership of it.
-// File descriptors are OS resources and must be closed when no longer needed.
-//
-// When sending a file descriptor, the file descriptor must be valid at the time
-// of transmission. Since transmission is not synchronous, one should consider
-// dup()ing any file descriptors to be transmitted and setting the |auto_close|
-// flag, which causes the file descriptor to be closed after writing.
-template<>
-struct ParamTraits<base::FileDescriptor> {
- typedef base::FileDescriptor param_type;
- static void Write(Message* m, const param_type& p) {
- const bool valid = p.fd >= 0;
- WriteParam(m, valid);
-
- if (valid) {
- if (!m->WriteFileDescriptor(p))
- NOTREACHED();
- }
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- bool valid;
- if (!ReadParam(m, iter, &valid))
- return false;
-
- if (!valid) {
- r->fd = -1;
- r->auto_close = false;
- return true;
- }
-
- return m->ReadFileDescriptor(iter, r);
- }
- static void Log(const param_type& p, std::wstring* l) {
- if (p.auto_close) {
- l->append(StringPrintf(L"FD(%d auto-close)", p.fd));
- } else {
- l->append(StringPrintf(L"FD(%d)", p.fd));
- }
- }
-};
-#endif // defined(OS_POSIX)
-
-#if defined(OS_WIN)
-template <>
-struct ParamTraits<XFORM> {
- typedef XFORM param_type;
- static void Write(Message* m, const param_type& p) {
- m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM));
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- const char *data;
- int data_size = 0;
- bool result = m->ReadData(iter, &data, &data_size);
- if (result && data_size == sizeof(XFORM)) {
- memcpy(r, data, sizeof(XFORM));
- } else {
- result = false;
- NOTREACHED();
- }
-
- return result;
- }
- static void Log(const param_type& p, std::wstring* l) {
- l->append(L"<XFORM>");
- }
-};
-#endif // defined(OS_WIN)
-
-struct LogData {
- std::wstring channel;
- uint16 type;
- std::wstring flags;
- int64 sent; // Time that the message was sent (i.e. at Send()).
- int64 receive; // Time before it was dispatched (i.e. before calling
- // OnMessageReceived).
- int64 dispatch; // Time after it was dispatched (i.e. after calling
- // OnMessageReceived).
- std::wstring message_name;
- std::wstring params;
-};
-
-template <>
-struct ParamTraits<LogData> {
- typedef LogData param_type;
- static void Write(Message* m, const param_type& p) {
- WriteParam(m, p.channel);
- WriteParam(m, static_cast<int>(p.type));
- WriteParam(m, p.flags);
- WriteParam(m, p.sent);
- WriteParam(m, p.receive);
- WriteParam(m, p.dispatch);
- WriteParam(m, p.params);
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- int type;
- bool result =
- ReadParam(m, iter, &r->channel) &&
- ReadParam(m, iter, &type) &&
- ReadParam(m, iter, &r->flags) &&
- ReadParam(m, iter, &r->sent) &&
- ReadParam(m, iter, &r->receive) &&
- ReadParam(m, iter, &r->dispatch) &&
- ReadParam(m, iter, &r->params);
- r->type = static_cast<uint16>(type);
- return result;
- }
- static void Log(const param_type& p, std::wstring* l) {
- // Doesn't make sense to implement this!
- }
-};
-
-
-template <>
-struct ParamTraits<Message> {
- static void Write(Message* m, const Message& p) {
- m->WriteInt(p.size());
- m->WriteData(reinterpret_cast<const char*>(p.data()), p.size());
- }
- static bool Read(const Message* m, void** iter, Message* r) {
- int size;
- if (!m->ReadInt(iter, &size))
- return false;
- const char* data;
- if (!m->ReadData(iter, &data, &size))
- return false;
- *r = Message(data, size);
- return true;
- }
- static void Log(const Message& p, std::wstring* l) {
- l->append(L"<IPC::Message>");
- }
-};
-
-template <>
-struct ParamTraits<Tuple0> {
- typedef Tuple0 param_type;
- static void Write(Message* m, const param_type& p) {
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- return true;
- }
- static void Log(const param_type& p, std::wstring* l) {
- }
-};
-
-template <class A>
-struct ParamTraits< Tuple1<A> > {
- typedef Tuple1<A> param_type;
- static void Write(Message* m, const param_type& p) {
- WriteParam(m, p.a);
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- return ReadParam(m, iter, &r->a);
- }
- static void Log(const param_type& p, std::wstring* l) {
- LogParam(p.a, l);
- }
-};
-
-template <class A, class B>
-struct ParamTraits< Tuple2<A, B> > {
- typedef Tuple2<A, B> param_type;
- static void Write(Message* m, const param_type& p) {
- WriteParam(m, p.a);
- WriteParam(m, p.b);
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- return (ReadParam(m, iter, &r->a) &&
- ReadParam(m, iter, &r->b));
- }
- static void Log(const param_type& p, std::wstring* l) {
- LogParam(p.a, l);
- l->append(L", ");
- LogParam(p.b, l);
- }
-};
-
-template <class A, class B, class C>
-struct ParamTraits< Tuple3<A, B, C> > {
- typedef Tuple3<A, B, C> param_type;
- static void Write(Message* m, const param_type& p) {
- WriteParam(m, p.a);
- WriteParam(m, p.b);
- WriteParam(m, p.c);
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- return (ReadParam(m, iter, &r->a) &&
- ReadParam(m, iter, &r->b) &&
- ReadParam(m, iter, &r->c));
- }
- static void Log(const param_type& p, std::wstring* l) {
- LogParam(p.a, l);
- l->append(L", ");
- LogParam(p.b, l);
- l->append(L", ");
- LogParam(p.c, l);
- }
-};
-
-template <class A, class B, class C, class D>
-struct ParamTraits< Tuple4<A, B, C, D> > {
- typedef Tuple4<A, B, C, D> param_type;
- static void Write(Message* m, const param_type& p) {
- WriteParam(m, p.a);
- WriteParam(m, p.b);
- WriteParam(m, p.c);
- WriteParam(m, p.d);
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- return (ReadParam(m, iter, &r->a) &&
- ReadParam(m, iter, &r->b) &&
- ReadParam(m, iter, &r->c) &&
- ReadParam(m, iter, &r->d));
- }
- static void Log(const param_type& p, std::wstring* l) {
- LogParam(p.a, l);
- l->append(L", ");
- LogParam(p.b, l);
- l->append(L", ");
- LogParam(p.c, l);
- l->append(L", ");
- LogParam(p.d, l);
- }
-};
-
-template <class A, class B, class C, class D, class E>
-struct ParamTraits< Tuple5<A, B, C, D, E> > {
- typedef Tuple5<A, B, C, D, E> param_type;
- static void Write(Message* m, const param_type& p) {
- WriteParam(m, p.a);
- WriteParam(m, p.b);
- WriteParam(m, p.c);
- WriteParam(m, p.d);
- WriteParam(m, p.e);
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- return (ReadParam(m, iter, &r->a) &&
- ReadParam(m, iter, &r->b) &&
- ReadParam(m, iter, &r->c) &&
- ReadParam(m, iter, &r->d) &&
- ReadParam(m, iter, &r->e));
- }
- static void Log(const param_type& p, std::wstring* l) {
- LogParam(p.a, l);
- l->append(L", ");
- LogParam(p.b, l);
- l->append(L", ");
- LogParam(p.c, l);
- l->append(L", ");
- LogParam(p.d, l);
- l->append(L", ");
- LogParam(p.e, l);
- }
-};
-
-template <class A, class B, class C, class D, class E, class F>
-struct ParamTraits< Tuple6<A, B, C, D, E, F> > {
- typedef Tuple6<A, B, C, D, E, F> param_type;
- static void Write(Message* m, const param_type& p) {
- WriteParam(m, p.a);
- WriteParam(m, p.b);
- WriteParam(m, p.c);
- WriteParam(m, p.d);
- WriteParam(m, p.e);
- WriteParam(m, p.f);
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- return (ReadParam(m, iter, &r->a) &&
- ReadParam(m, iter, &r->b) &&
- ReadParam(m, iter, &r->c) &&
- ReadParam(m, iter, &r->d) &&
- ReadParam(m, iter, &r->e) &&
- ReadParam(m, iter, &r->f));
- }
- static void Log(const param_type& p, std::wstring* l) {
- LogParam(p.a, l);
- l->append(L", ");
- LogParam(p.b, l);
- l->append(L", ");
- LogParam(p.c, l);
- l->append(L", ");
- LogParam(p.d, l);
- l->append(L", ");
- LogParam(p.e, l);
- l->append(L", ");
- LogParam(p.f, l);
- }
-};
-
-
-
-//-----------------------------------------------------------------------------
-// Generic message subclasses
-
-// Used for asynchronous messages.
-template <class ParamType>
-class MessageWithTuple : public Message {
- public:
- typedef ParamType Param;
-
- MessageWithTuple(int32 routing_id, uint16 type, const Param& p)
- : Message(routing_id, type, PRIORITY_NORMAL) {
- WriteParam(this, p);
- }
-
- static bool Read(const Message* msg, Param* p) {
- void* iter = NULL;
- bool rv = ReadParam(msg, &iter, p);
- DCHECK(rv) << "Error deserializing message " << msg->type();
- return rv;
- }
-
- // Generic dispatcher. Should cover most cases.
- template<class T, class Method>
- static bool Dispatch(const Message* msg, T* obj, Method func) {
- Param p;
- if (Read(msg, &p)) {
- DispatchToMethod(obj, func, p);
- return true;
- }
- return false;
- }
-
- // The following dispatchers exist for the case where the callback function
- // needs the message as well. They assume that "Param" is a type of Tuple
- // (except the one arg case, as there is no Tuple1).
- template<class T, typename TA>
- static bool Dispatch(const Message* msg, T* obj,
- void (T::*func)(const Message&, TA)) {
- Param p;
- if (Read(msg, &p)) {
- (obj->*func)(*msg, p);
- return true;
- }
- return false;
- }
-
- template<class T, typename TA, typename TB>
- static bool Dispatch(const Message* msg, T* obj,
- void (T::*func)(const Message&, TA, TB)) {
- Param p;
- if (Read(msg, &p)) {
- (obj->*func)(*msg, p.a, p.b);
- return true;
- }
- return false;
- }
-
- template<class T, typename TA, typename TB, typename TC>
- static bool Dispatch(const Message* msg, T* obj,
- void (T::*func)(const Message&, TA, TB, TC)) {
- Param p;
- if (Read(msg, &p)) {
- (obj->*func)(*msg, p.a, p.b, p.c);
- return true;
- }
- return false;
- }
-
- template<class T, typename TA, typename TB, typename TC, typename TD>
- static bool Dispatch(const Message* msg, T* obj,
- void (T::*func)(const Message&, TA, TB, TC, TD)) {
- Param p;
- if (Read(msg, &p)) {
- (obj->*func)(*msg, p.a, p.b, p.c, p.d);
- return true;
- }
- return false;
- }
-
- template<class T, typename TA, typename TB, typename TC, typename TD,
- typename TE>
- static bool Dispatch(const Message* msg, T* obj,
- void (T::*func)(const Message&, TA, TB, TC, TD, TE)) {
- Param p;
- if (Read(msg, &p)) {
- (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e);
- return true;
- }
- return false;
- }
-
- static void Log(const Message* msg, std::wstring* l) {
- Param p;
- if (Read(msg, &p))
- LogParam(p, l);
- }
-
- // Functions used to do manual unpacking. Only used by the automation code,
- // these should go away once that code uses SyncChannel.
- template<typename TA, typename TB>
- static bool Read(const IPC::Message* msg, TA* a, TB* b) {
- ParamType params;
- if (!Read(msg, &params))
- return false;
- *a = params.a;
- *b = params.b;
- return true;
- }
-
- template<typename TA, typename TB, typename TC>
- static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c) {
- ParamType params;
- if (!Read(msg, &params))
- return false;
- *a = params.a;
- *b = params.b;
- *c = params.c;
- return true;
- }
-
- template<typename TA, typename TB, typename TC, typename TD>
- static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d) {
- ParamType params;
- if (!Read(msg, &params))
- return false;
- *a = params.a;
- *b = params.b;
- *c = params.c;
- *d = params.d;
- return true;
- }
-
- template<typename TA, typename TB, typename TC, typename TD, typename TE>
- static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d, TE* e) {
- ParamType params;
- if (!Read(msg, &params))
- return false;
- *a = params.a;
- *b = params.b;
- *c = params.c;
- *d = params.d;
- *e = params.e;
- return true;
- }
-};
-
-// This class assumes that its template argument is a RefTuple (a Tuple with
-// reference elements).
-template <class RefTuple>
-class ParamDeserializer : public MessageReplyDeserializer {
- public:
- explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
-
- bool SerializeOutputParameters(const IPC::Message& msg, void* iter) {
- return ReadParam(&msg, &iter, &out_);
- }
-
- RefTuple out_;
-};
-
-// defined in ipc_logging.cc
-void GenerateLogData(const std::wstring& channel, const Message& message,
- LogData* data);
-
-// Used for synchronous messages.
-template <class SendParamType, class ReplyParamType>
-class MessageWithReply : public SyncMessage {
- public:
- typedef SendParamType SendParam;
- typedef ReplyParamType ReplyParam;
-
- MessageWithReply(int32 routing_id, uint16 type,
- const SendParam& send, const ReplyParam& reply)
- : SyncMessage(routing_id, type, PRIORITY_NORMAL,
- new ParamDeserializer<ReplyParam>(reply)) {
- WriteParam(this, send);
- }
-
- static void Log(const Message* msg, std::wstring* l) {
- if (msg->is_sync()) {
- SendParam p;
- void* iter = SyncMessage::GetDataIterator(msg);
- ReadParam(msg, &iter, &p);
- LogParam(p, l);
-
-#if defined(IPC_MESSAGE_LOG_ENABLED)
- const std::wstring& output_params = msg->output_params();
- if (!l->empty() && !output_params.empty())
- l->append(L", ");
-
- l->append(output_params);
-#endif
- } else {
- // This is an outgoing reply. Now that we have the output parameters, we
- // can finally log the message.
- typename ReplyParam::ValueTuple p;
- void* iter = SyncMessage::GetDataIterator(msg);
- ReadParam(msg, &iter, &p);
- LogParam(p, l);
- }
- }
-
- template<class T, class Method>
- static bool Dispatch(const Message* msg, T* obj, Method func) {
- SendParam send_params;
- void* iter = GetDataIterator(msg);
- Message* reply = GenerateReply(msg);
- bool error;
- if (ReadParam(msg, &iter, &send_params)) {
- typename ReplyParam::ValueTuple reply_params;
- DispatchToMethod(obj, func, send_params, &reply_params);
- WriteParam(reply, reply_params);
- error = false;
-#ifdef IPC_MESSAGE_LOG_ENABLED
- if (msg->received_time() != 0) {
- std::wstring output_params;
- LogParam(reply_params, &output_params);
- msg->set_output_params(output_params);
- }
-#endif
- } else {
- NOTREACHED() << "Error deserializing message " << msg->type();
- reply->set_reply_error();
- error = true;
- }
-
- obj->Send(reply);
- return !error;
- }
-
- template<class T, class Method>
- static bool DispatchDelayReply(const Message* msg, T* obj, Method func) {
- SendParam send_params;
- void* iter = GetDataIterator(msg);
- Message* reply = GenerateReply(msg);
- bool error;
- if (ReadParam(msg, &iter, &send_params)) {
- Tuple1<Message&> t = MakeRefTuple(*reply);
-
-#ifdef IPC_MESSAGE_LOG_ENABLED
- if (msg->sent_time()) {
- // Don't log the sync message after dispatch, as we don't have the
- // output parameters at that point. Instead, save its data and log it
- // with the outgoing reply message when it's sent.
- LogData* data = new LogData;
- GenerateLogData(L"", *msg, data);
- msg->set_dont_log();
- reply->set_sync_log_data(data);
- }
-#endif
- DispatchToMethod(obj, func, send_params, &t);
- error = false;
- } else {
- NOTREACHED() << "Error deserializing message " << msg->type();
- reply->set_reply_error();
- obj->Send(reply);
- error = true;
- }
- return !error;
- }
-
- template<typename TA>
- static void WriteReplyParams(Message* reply, TA a) {
- ReplyParam p(a);
- WriteParam(reply, p);
- }
-
- template<typename TA, typename TB>
- static void WriteReplyParams(Message* reply, TA a, TB b) {
- ReplyParam p(a, b);
- WriteParam(reply, p);
- }
-
- template<typename TA, typename TB, typename TC>
- static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
- ReplyParam p(a, b, c);
- WriteParam(reply, p);
- }
-
- template<typename TA, typename TB, typename TC, typename TD>
- static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
- ReplyParam p(a, b, c, d);
- WriteParam(reply, p);
- }
-
- template<typename TA, typename TB, typename TC, typename TD, typename TE>
- static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
- ReplyParam p(a, b, c, d, e);
- WriteParam(reply, p);
- }
-};
-
-//-----------------------------------------------------------------------------
-
-} // namespace IPC
-
-#endif // IPC_IPC_MESSAGE_UTILS_H_
diff --git a/ipc/ipc_send_fds_test.cc b/ipc/ipc_send_fds_test.cc
deleted file mode 100644
index ff32afc..0000000
--- a/ipc/ipc_send_fds_test.cc
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright (c) 2009 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 "build/build_config.h"
-
-#include "ipc/ipc_tests.h"
-
-#if defined(OS_MACOSX)
-extern "C" {
-#include <sandbox.h>
-}
-#endif
-#include <fcntl.h>
-#include <sys/stat.h>
-
-#include "base/message_loop.h"
-#include "ipc/ipc_channel.h"
-#include "ipc/ipc_message_utils.h"
-
-#if defined(OS_POSIX)
-
-namespace {
-
-const unsigned kNumFDsToSend = 20;
-const char* kDevZeroPath = "/dev/zero";
-
-static void VerifyAndCloseDescriptor(int fd, ino_t inode_num) {
- // Check that we can read from the FD.
- char buf;
- ssize_t amt_read = read(fd, &buf, 1);
- ASSERT_EQ(amt_read, 1);
- ASSERT_EQ(buf, 0); // /dev/zero always reads NUL bytes.
-
- struct stat st;
- ASSERT_EQ(fstat(fd, &st), 0);
-
- ASSERT_EQ(close(fd), 0);
-
- // We compare iNode numbers to check that the file sent over the wire
- // was actually the same physical file as the one we were expecting.
- ASSERT_EQ(inode_num, st.st_ino);
-}
-
-class MyChannelDescriptorListener : public IPC::Channel::Listener {
- public:
- MyChannelDescriptorListener(ino_t expected_inode_num)
- : expected_inode_num_(expected_inode_num),
- num_fds_received_(0) {}
-
- virtual void OnMessageReceived(const IPC::Message& message) {
- void* iter = NULL;
-
- ++num_fds_received_;
- base::FileDescriptor descriptor;
-
- ASSERT_TRUE(
- IPC::ParamTraits<base::FileDescriptor>::Read(
- &message, &iter, &descriptor));
-
- VerifyAndCloseDescriptor(descriptor.fd, expected_inode_num_);
- if (num_fds_received_ == kNumFDsToSend) {
- MessageLoop::current()->Quit();
- }
- }
-
- virtual void OnChannelError() {
- MessageLoop::current()->Quit();
- }
- private:
- ino_t expected_inode_num_;
- unsigned num_fds_received_;
-};
-
-void TestDescriptorServer(IPC::Channel &chan,
- base::ProcessHandle process_handle) {
- ASSERT_TRUE(process_handle);
-
- for (unsigned i = 0; i < kNumFDsToSend; ++i) {
- base::FileDescriptor descriptor;
- const int fd = open(kDevZeroPath, O_RDONLY);
- ASSERT_GE(fd, 0);
- descriptor.auto_close = true;
- descriptor.fd = fd;
-
- IPC::Message* message = new IPC::Message(0, // routing_id
- 3, // message type
- IPC::Message::PRIORITY_NORMAL);
- IPC::ParamTraits<base::FileDescriptor>::Write(message, descriptor);
- chan.Send(message);
- }
-
- // Run message loop.
- MessageLoop::current()->Run();
-
- // Close Channel so client gets its OnChannelError() callback fired.
- chan.Close();
-
- // Cleanup child process.
- EXPECT_TRUE(base::WaitForSingleProcess(process_handle, 5000));
-}
-
-int TestDescriptorClient(ino_t expected_inode_num) {
- MessageLoopForIO main_message_loop;
- MyChannelDescriptorListener listener(expected_inode_num);
-
- // Setup IPC channel.
- IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_CLIENT,
- &listener);
- chan.Connect();
- MessageLoop::current()->Run();
-
- return 0;
-}
-
-} // namespace
-
-// ---------------------------------------------------------------------------
-#if defined(OS_MACOSX)
-// TODO(port): Make this test cross-platform.
-MULTIPROCESS_TEST_MAIN(RunTestDescriptorClientSandboxed) {
- struct stat st;
- const int fd = open(kDevZeroPath, O_RDONLY);
- fstat(fd, &st);
- close(fd);
-
- // Enable the Sandbox.
- char* error_buff = NULL;
- int error = sandbox_init(kSBXProfilePureComputation, SANDBOX_NAMED,
- &error_buff);
- bool success = (error == 0 && error_buff == NULL);
- if (!success) {
- return -1;
- }
-
- sandbox_free_error(error_buff);
-
- // Make sure Sandbox is really enabled.
- if (open(kDevZeroPath, O_RDONLY) != -1) {
- LOG(ERROR) << "Sandbox wasn't properly enabled";
- return -1;
- }
-
- // See if we can receive a file descriptor.
- return TestDescriptorClient(st.st_ino);
-}
-
-// Test that FDs are correctly sent to a sandboxed process.
-TEST_F(IPCChannelTest, DescriptorTestSandboxed) {
- // Setup IPC channel.
- MyChannelDescriptorListener listener(-1);
-
- IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_SERVER,
- &listener);
- chan.Connect();
-
- base::ProcessHandle process_handle = SpawnChild(
- TEST_DESCRIPTOR_CLIENT_SANDBOXED,
- &chan);
- TestDescriptorServer(chan, process_handle);
-}
-#endif // defined(OS_MACOSX)
-
-MULTIPROCESS_TEST_MAIN(RunTestDescriptorClient) {
- struct stat st;
- const int fd = open(kDevZeroPath, O_RDONLY);
- fstat(fd, &st);
- close(fd);
-
- return TestDescriptorClient(st.st_ino);
-}
-
-TEST_F(IPCChannelTest, DescriptorTest) {
- // Setup IPC channel.
- MyChannelDescriptorListener listener(-1);
-
- IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_SERVER,
- &listener);
- chan.Connect();
-
- base::ProcessHandle process_handle = SpawnChild(TEST_DESCRIPTOR_CLIENT,
- &chan);
- TestDescriptorServer(chan, process_handle);
-}
-
-#endif // defined(OS_POSIX)
diff --git a/ipc/ipc_switches.cc b/ipc/ipc_switches.cc
deleted file mode 100644
index 9d45f7b..0000000
--- a/ipc/ipc_switches.cc
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2009 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 "ipc/ipc_switches.h"
-
-namespace switches {
-
-// On POSIX only: use FIFO for IPC channels so that "unrelated" process
-// can connect to a channel, provided it knows its name. For debugging purposes.
-const wchar_t kIPCUseFIFO[] = L"ipc-use-fifo";
-
-// The value of this switch tells the child process which
-// IPC channel the browser expects to use to communicate with it.
-const wchar_t kProcessChannelID[] = L"channel";
-
-} // namespace switches
diff --git a/ipc/ipc_switches.h b/ipc/ipc_switches.h
deleted file mode 100644
index 7dbc746..0000000
--- a/ipc/ipc_switches.h
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2009 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.
-
-// Defines command line switches used by the IPC system
-
-#ifndef IPC_IPC_SWITCHES_H__
-#define IPC_IPC_SWITCHES_H__
-
-#include "base/base_switches.h"
-
-namespace switches {
-
-extern const wchar_t kIPCUseFIFO[];
-extern const wchar_t kProcessChannelID[];
-
-} // namespace switches
-
-#endif // IPC_IPC_SWITCHES_H__
diff --git a/ipc/ipc_sync_channel.cc b/ipc/ipc_sync_channel.cc
deleted file mode 100644
index 137d9fa..0000000
--- a/ipc/ipc_sync_channel.cc
+++ /dev/null
@@ -1,453 +0,0 @@
-// Copyright (c) 2006-2008 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 "ipc/ipc_sync_channel.h"
-
-#include "base/lazy_instance.h"
-#include "base/logging.h"
-#include "base/thread_local.h"
-#include "base/message_loop.h"
-#include "base/waitable_event.h"
-#include "base/waitable_event_watcher.h"
-#include "ipc/ipc_sync_message.h"
-
-using base::TimeDelta;
-using base::TimeTicks;
-using base::WaitableEvent;
-
-namespace IPC {
-// When we're blocked in a Send(), we need to process incoming synchronous
-// messages right away because it could be blocking our reply (either
-// directly from the same object we're calling, or indirectly through one or
-// more other channels). That means that in SyncContext's OnMessageReceived,
-// we need to process sync message right away if we're blocked. However a
-// simple check isn't sufficient, because the listener thread can be in the
-// process of calling Send.
-// To work around this, when SyncChannel filters a sync message, it sets
-// an event that the listener thread waits on during its Send() call. This
-// allows us to dispatch incoming sync messages when blocked. The race
-// condition is handled because if Send is in the process of being called, it
-// will check the event. In case the listener thread isn't sending a message,
-// we queue a task on the listener thread to dispatch the received messages.
-// The messages are stored in this queue object that's shared among all
-// SyncChannel objects on the same thread (since one object can receive a
-// sync message while another one is blocked).
-
-class SyncChannel::ReceivedSyncMsgQueue :
- public base::RefCountedThreadSafe<ReceivedSyncMsgQueue> {
- public:
- // Returns the ReceivedSyncMsgQueue instance for this thread, creating one
- // if necessary. Call RemoveContext on the same thread when done.
- static ReceivedSyncMsgQueue* AddContext() {
- // We want one ReceivedSyncMsgQueue per listener thread (i.e. since multiple
- // SyncChannel objects can block the same thread).
- ReceivedSyncMsgQueue* rv = lazy_tls_ptr_.Pointer()->Get();
- if (!rv) {
- rv = new ReceivedSyncMsgQueue();
- ReceivedSyncMsgQueue::lazy_tls_ptr_.Pointer()->Set(rv);
- }
- rv->listener_count_++;
- return rv;
- }
-
- ~ReceivedSyncMsgQueue() {
- }
-
- // Called on IPC thread when a synchronous message or reply arrives.
- void QueueMessage(const Message& msg, SyncChannel::SyncContext* context) {
- bool was_task_pending;
- {
- AutoLock auto_lock(message_lock_);
-
- was_task_pending = task_pending_;
- task_pending_ = true;
-
- // We set the event in case the listener thread is blocked (or is about
- // to). In case it's not, the PostTask dispatches the messages.
- message_queue_.push_back(QueuedMessage(new Message(msg), context));
- }
-
- dispatch_event_.Signal();
- if (!was_task_pending) {
- listener_message_loop_->PostTask(FROM_HERE, NewRunnableMethod(
- this, &ReceivedSyncMsgQueue::DispatchMessagesTask));
- }
- }
-
- void QueueReply(const Message &msg, SyncChannel::SyncContext* context) {
- received_replies_.push_back(QueuedMessage(new Message(msg), context));
- }
-
- // Called on the listener's thread to process any queues synchronous
- // messages.
- void DispatchMessagesTask() {
- {
- AutoLock auto_lock(message_lock_);
- task_pending_ = false;
- }
- DispatchMessages();
- }
-
- void DispatchMessages() {
- while (true) {
- Message* message;
- scoped_refptr<SyncChannel::SyncContext> context;
- {
- AutoLock auto_lock(message_lock_);
- if (message_queue_.empty())
- break;
-
- message = message_queue_.front().message;
- context = message_queue_.front().context;
- message_queue_.pop_front();
- }
-
- context->OnDispatchMessage(*message);
- delete message;
- }
- }
-
- // SyncChannel calls this in its destructor.
- void RemoveContext(SyncContext* context) {
- AutoLock auto_lock(message_lock_);
-
- SyncMessageQueue::iterator iter = message_queue_.begin();
- while (iter != message_queue_.end()) {
- if (iter->context == context) {
- delete iter->message;
- iter = message_queue_.erase(iter);
- } else {
- iter++;
- }
- }
-
- if (--listener_count_ == 0) {
- DCHECK(lazy_tls_ptr_.Pointer()->Get());
- lazy_tls_ptr_.Pointer()->Set(NULL);
- }
- }
-
- WaitableEvent* dispatch_event() { return &dispatch_event_; }
- MessageLoop* listener_message_loop() { return listener_message_loop_; }
-
- // Holds a pointer to the per-thread ReceivedSyncMsgQueue object.
- static base::LazyInstance<base::ThreadLocalPointer<ReceivedSyncMsgQueue> >
- lazy_tls_ptr_;
-
- // Called on the ipc thread to check if we can unblock any current Send()
- // calls based on a queued reply.
- void DispatchReplies() {
- for (size_t i = 0; i < received_replies_.size(); ++i) {
- Message* message = received_replies_[i].message;
- if (received_replies_[i].context->TryToUnblockListener(message)) {
- delete message;
- received_replies_.erase(received_replies_.begin() + i);
- return;
- }
- }
- }
-
- private:
- // See the comment in SyncChannel::SyncChannel for why this event is created
- // as manual reset.
- ReceivedSyncMsgQueue() :
- dispatch_event_(true, false),
- listener_message_loop_(MessageLoop::current()),
- task_pending_(false),
- listener_count_(0) {
- }
-
- // Holds information about a queued synchronous message or reply.
- struct QueuedMessage {
- QueuedMessage(Message* m, SyncContext* c) : message(m), context(c) { }
- Message* message;
- scoped_refptr<SyncChannel::SyncContext> context;
- };
-
- typedef std::deque<QueuedMessage> SyncMessageQueue;
- SyncMessageQueue message_queue_;
-
- std::vector<QueuedMessage> received_replies_;
-
- // Set when we got a synchronous message that we must respond to as the
- // sender needs its reply before it can reply to our original synchronous
- // message.
- WaitableEvent dispatch_event_;
- MessageLoop* listener_message_loop_;
- Lock message_lock_;
- bool task_pending_;
- int listener_count_;
-};
-
-base::LazyInstance<base::ThreadLocalPointer<SyncChannel::ReceivedSyncMsgQueue> >
- SyncChannel::ReceivedSyncMsgQueue::lazy_tls_ptr_(base::LINKER_INITIALIZED);
-
-SyncChannel::SyncContext::SyncContext(
- Channel::Listener* listener,
- MessageFilter* filter,
- MessageLoop* ipc_thread,
- WaitableEvent* shutdown_event)
- : ChannelProxy::Context(listener, filter, ipc_thread),
- received_sync_msgs_(ReceivedSyncMsgQueue::AddContext()),
- shutdown_event_(shutdown_event) {
-}
-
-SyncChannel::SyncContext::~SyncContext() {
- while (!deserializers_.empty())
- Pop();
-}
-
-// Adds information about an outgoing sync message to the context so that
-// we know how to deserialize the reply. Returns a handle that's set when
-// the reply has arrived.
-void SyncChannel::SyncContext::Push(SyncMessage* sync_msg) {
- // The event is created as manual reset because in between Signal and
- // OnObjectSignalled, another Send can happen which would stop the watcher
- // from being called. The event would get watched later, when the nested
- // Send completes, so the event will need to remain set.
- PendingSyncMsg pending(SyncMessage::GetMessageId(*sync_msg),
- sync_msg->GetReplyDeserializer(),
- new WaitableEvent(true, false));
- AutoLock auto_lock(deserializers_lock_);
- deserializers_.push_back(pending);
-}
-
-bool SyncChannel::SyncContext::Pop() {
- bool result;
- {
- AutoLock auto_lock(deserializers_lock_);
- PendingSyncMsg msg = deserializers_.back();
- delete msg.deserializer;
- delete msg.done_event;
- msg.done_event = NULL;
- deserializers_.pop_back();
- result = msg.send_result;
- }
-
- // We got a reply to a synchronous Send() call that's blocking the listener
- // thread. However, further down the call stack there could be another
- // blocking Send() call, whose reply we received after we made this last
- // Send() call. So check if we have any queued replies available that
- // can now unblock the listener thread.
- ipc_message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
- received_sync_msgs_.get(), &ReceivedSyncMsgQueue::DispatchReplies));
-
- return result;
-}
-
-WaitableEvent* SyncChannel::SyncContext::GetSendDoneEvent() {
- AutoLock auto_lock(deserializers_lock_);
- return deserializers_.back().done_event;
-}
-
-WaitableEvent* SyncChannel::SyncContext::GetDispatchEvent() {
- return received_sync_msgs_->dispatch_event();
-}
-
-void SyncChannel::SyncContext::DispatchMessages() {
- received_sync_msgs_->DispatchMessages();
-}
-
-bool SyncChannel::SyncContext::TryToUnblockListener(const Message* msg) {
- AutoLock auto_lock(deserializers_lock_);
- if (deserializers_.empty() ||
- !SyncMessage::IsMessageReplyTo(*msg, deserializers_.back().id)) {
- return false;
- }
-
- if (!msg->is_reply_error()) {
- deserializers_.back().send_result = deserializers_.back().deserializer->
- SerializeOutputParameters(*msg);
- }
- deserializers_.back().done_event->Signal();
-
- return true;
-}
-
-void SyncChannel::SyncContext::Clear() {
- CancelPendingSends();
- received_sync_msgs_->RemoveContext(this);
-
- Context::Clear();
-}
-
-void SyncChannel::SyncContext::OnMessageReceived(const Message& msg) {
- // Give the filters a chance at processing this message.
- if (TryFilters(msg))
- return;
-
- if (TryToUnblockListener(&msg))
- return;
-
- if (msg.should_unblock()) {
- received_sync_msgs_->QueueMessage(msg, this);
- return;
- }
-
- if (msg.is_reply()) {
- received_sync_msgs_->QueueReply(msg, this);
- return;
- }
-
- return Context::OnMessageReceivedNoFilter(msg);
-}
-
-void SyncChannel::SyncContext::OnChannelError() {
- CancelPendingSends();
- shutdown_watcher_.StopWatching();
- Context::OnChannelError();
-}
-
-void SyncChannel::SyncContext::OnChannelOpened() {
- shutdown_watcher_.StartWatching(shutdown_event_, this);
- Context::OnChannelOpened();
-}
-
-void SyncChannel::SyncContext::OnChannelClosed() {
- shutdown_watcher_.StopWatching();
- Context::OnChannelClosed();
-}
-
-void SyncChannel::SyncContext::OnSendTimeout(int message_id) {
- AutoLock auto_lock(deserializers_lock_);
- PendingSyncMessageQueue::iterator iter;
- for (iter = deserializers_.begin(); iter != deserializers_.end(); iter++) {
- if (iter->id == message_id) {
- iter->done_event->Signal();
- break;
- }
- }
-}
-
-void SyncChannel::SyncContext::CancelPendingSends() {
- AutoLock auto_lock(deserializers_lock_);
- PendingSyncMessageQueue::iterator iter;
- for (iter = deserializers_.begin(); iter != deserializers_.end(); iter++)
- iter->done_event->Signal();
-}
-
-void SyncChannel::SyncContext::OnWaitableEventSignaled(WaitableEvent* event) {
- DCHECK(event == shutdown_event_);
- // Process shut down before we can get a reply to a synchronous message.
- // Cancel pending Send calls, which will end up setting the send done event.
- CancelPendingSends();
-}
-
-
-SyncChannel::SyncChannel(
- const std::wstring& channel_id, Channel::Mode mode,
- Channel::Listener* listener, MessageFilter* filter,
- MessageLoop* ipc_message_loop, bool create_pipe_now,
- WaitableEvent* shutdown_event)
- : ChannelProxy(
- channel_id, mode, ipc_message_loop,
- new SyncContext(listener, filter, ipc_message_loop, shutdown_event),
- create_pipe_now),
- sync_messages_with_no_timeout_allowed_(true) {
- // Ideally we only want to watch this object when running a nested message
- // loop. However, we don't know when it exits if there's another nested
- // message loop running under it or not, so we wouldn't know whether to
- // stop or keep watching. So we always watch it, and create the event as
- // manual reset since the object watcher might otherwise reset the event
- // when we're doing a WaitMany.
- dispatch_watcher_.StartWatching(sync_context()->GetDispatchEvent(), this);
-}
-
-SyncChannel::~SyncChannel() {
-}
-
-bool SyncChannel::Send(Message* message) {
- return SendWithTimeout(message, base::kNoTimeout);
-}
-
-bool SyncChannel::SendWithTimeout(Message* message, int timeout_ms) {
- if (!message->is_sync()) {
- ChannelProxy::Send(message);
- return true;
- }
-
- // *this* might get deleted in WaitForReply.
- scoped_refptr<SyncContext> context(sync_context());
- if (context->shutdown_event()->IsSignaled()) {
- delete message;
- return false;
- }
-
- DCHECK(sync_messages_with_no_timeout_allowed_ ||
- timeout_ms != base::kNoTimeout);
- SyncMessage* sync_msg = static_cast<SyncMessage*>(message);
- context->Push(sync_msg);
- int message_id = SyncMessage::GetMessageId(*sync_msg);
- WaitableEvent* pump_messages_event = sync_msg->pump_messages_event();
-
- ChannelProxy::Send(message);
-
- if (timeout_ms != base::kNoTimeout) {
- // We use the sync message id so that when a message times out, we don't
- // confuse it with another send that is either above/below this Send in
- // the call stack.
- context->ipc_message_loop()->PostDelayedTask(FROM_HERE,
- NewRunnableMethod(context.get(),
- &SyncContext::OnSendTimeout, message_id), timeout_ms);
- }
-
- // Wait for reply, or for any other incoming synchronous messages.
- WaitForReply(pump_messages_event);
-
- return context->Pop();
-}
-
-void SyncChannel::WaitForReply(WaitableEvent* pump_messages_event) {
- while (true) {
- WaitableEvent* objects[] = {
- sync_context()->GetDispatchEvent(),
- sync_context()->GetSendDoneEvent(),
- pump_messages_event
- };
-
- unsigned count = pump_messages_event ? 3: 2;
- unsigned result = WaitableEvent::WaitMany(objects, count);
- if (result == 0 /* dispatch event */) {
- // We're waiting for a reply, but we received a blocking synchronous
- // call. We must process it or otherwise a deadlock might occur.
- sync_context()->GetDispatchEvent()->Reset();
- sync_context()->DispatchMessages();
- continue;
- }
-
- if (result == 2 /* pump_messages_event */)
- WaitForReplyWithNestedMessageLoop(); // Start a nested message loop.
-
- break;
- }
-}
-
-void SyncChannel::WaitForReplyWithNestedMessageLoop() {
- WaitableEvent* old_done_event = send_done_watcher_.GetWatchedEvent();
- send_done_watcher_.StopWatching();
- send_done_watcher_.StartWatching(sync_context()->GetSendDoneEvent(), this);
- bool old_state = MessageLoop::current()->NestableTasksAllowed();
- MessageLoop::current()->SetNestableTasksAllowed(true);
- MessageLoop::current()->Run();
- MessageLoop::current()->SetNestableTasksAllowed(old_state);
- if (old_done_event)
- send_done_watcher_.StartWatching(old_done_event, this);
-}
-
-void SyncChannel::OnWaitableEventSignaled(WaitableEvent* event) {
- WaitableEvent* dispatch_event = sync_context()->GetDispatchEvent();
- if (event == dispatch_event) {
- // The call to DispatchMessages might delete this object, so reregister
- // the object watcher first.
- dispatch_event->Reset();
- dispatch_watcher_.StartWatching(dispatch_event, this);
- sync_context()->DispatchMessages();
- } else {
- // We got the reply, timed out or the process shutdown.
- DCHECK(event == sync_context()->GetSendDoneEvent());
- MessageLoop::current()->Quit();
- }
-}
-
-} // namespace IPC
diff --git a/ipc/ipc_sync_channel.h b/ipc/ipc_sync_channel.h
deleted file mode 100644
index d802d91..0000000
--- a/ipc/ipc_sync_channel.h
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright (c) 2006-2008 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 COMMON_IPC_SYNC_SENDER_H__
-#define COMMON_IPC_SYNC_SENDER_H__
-
-#include <string>
-#include <deque>
-#include "base/basictypes.h"
-#include "base/lock.h"
-#include "base/ref_counted.h"
-#include "base/scoped_handle.h"
-#include "base/waitable_event.h"
-#include "base/waitable_event_watcher.h"
-#include "ipc/ipc_channel_proxy.h"
-
-namespace IPC {
-
-class SyncMessage;
-class MessageReplyDeserializer;
-
-// This is similar to IPC::ChannelProxy, with the added feature of supporting
-// sending synchronous messages.
-// Note that care must be taken that the lifetime of the ipc_thread argument
-// is more than this object. If the message loop goes away while this object
-// is running and it's used to send a message, then it will use the invalid
-// message loop pointer to proxy it to the ipc thread.
-class SyncChannel : public ChannelProxy,
- public base::WaitableEventWatcher::Delegate {
- public:
- SyncChannel(const std::wstring& channel_id, Channel::Mode mode,
- Channel::Listener* listener, MessageFilter* filter,
- MessageLoop* ipc_message_loop, bool create_pipe_now,
- base::WaitableEvent* shutdown_event);
- ~SyncChannel();
-
- virtual bool Send(Message* message);
- virtual bool SendWithTimeout(Message* message, int timeout_ms);
-
- // Whether we allow sending messages with no time-out.
- void set_sync_messages_with_no_timeout_allowed(bool value) {
- sync_messages_with_no_timeout_allowed_ = value;
- }
-
- protected:
- class ReceivedSyncMsgQueue;
- friend class ReceivedSyncMsgQueue;
-
- // SyncContext holds the per object data for SyncChannel, so that SyncChannel
- // can be deleted while it's being used in a different thread. See
- // ChannelProxy::Context for more information.
- class SyncContext : public Context,
- public base::WaitableEventWatcher::Delegate {
- public:
- SyncContext(Channel::Listener* listener,
- MessageFilter* filter,
- MessageLoop* ipc_thread,
- base::WaitableEvent* shutdown_event);
-
- ~SyncContext();
-
- // Adds information about an outgoing sync message to the context so that
- // we know how to deserialize the reply.
- void Push(IPC::SyncMessage* sync_msg);
-
- // Cleanly remove the top deserializer (and throw it away). Returns the
- // result of the Send call for that message.
- bool Pop();
-
- // Returns an event that's set when the send is complete, timed out or the
- // process shut down.
- base::WaitableEvent* GetSendDoneEvent();
-
- // Returns an event that's set when an incoming message that's not the reply
- // needs to get dispatched (by calling SyncContext::DispatchMessages).
- base::WaitableEvent* GetDispatchEvent();
-
- void DispatchMessages();
-
- // Checks if the given message is blocking the listener thread because of a
- // synchronous send. If it is, the thread is unblocked and true is
- // returned. Otherwise the function returns false.
- bool TryToUnblockListener(const Message* msg);
-
- // Called on the IPC thread when a sync send that runs a nested message loop
- // times out.
- void OnSendTimeout(int message_id);
-
- base::WaitableEvent* shutdown_event() { return shutdown_event_; }
-
- private:
- // IPC::ChannelProxy methods that we override.
-
- // Called on the listener thread.
- virtual void Clear();
-
- // Called on the IPC thread.
- virtual void OnMessageReceived(const Message& msg);
- virtual void OnChannelError();
- virtual void OnChannelOpened();
- virtual void OnChannelClosed();
-
- // Cancels all pending Send calls.
- void CancelPendingSends();
-
- // WaitableEventWatcher::Delegate implementation.
- virtual void OnWaitableEventSignaled(base::WaitableEvent* arg);
-
- // When sending a synchronous message, this structure contains an object
- // that knows how to deserialize the response.
- struct PendingSyncMsg {
- PendingSyncMsg(int id, IPC::MessageReplyDeserializer* d,
- base::WaitableEvent* e) :
- id(id), deserializer(d), done_event(e), send_result(false) { }
- int id;
- IPC::MessageReplyDeserializer* deserializer;
- base::WaitableEvent* done_event;
- bool send_result;
- };
-
- typedef std::deque<PendingSyncMsg> PendingSyncMessageQueue;
- PendingSyncMessageQueue deserializers_;
- Lock deserializers_lock_;
-
- scoped_refptr<ReceivedSyncMsgQueue> received_sync_msgs_;
-
- base::WaitableEvent* shutdown_event_;
- base::WaitableEventWatcher shutdown_watcher_;
- };
-
- private:
- // WaitableEventWatcher::Delegate implementation.
- virtual void OnWaitableEventSignaled(base::WaitableEvent* arg);
-
- SyncContext* sync_context() {
- return reinterpret_cast<SyncContext*>(context());
- }
-
- // Both these functions wait for a reply, timeout or process shutdown. The
- // latter one also runs a nested message loop in the meantime.
- void WaitForReply(base::WaitableEvent* pump_messages_event);
-
- // Runs a nested message loop until a reply arrives, times out, or the process
- // shuts down.
- void WaitForReplyWithNestedMessageLoop();
-
- bool sync_messages_with_no_timeout_allowed_;
-
- // Used to signal events between the IPC and listener threads.
- base::WaitableEventWatcher send_done_watcher_;
- base::WaitableEventWatcher dispatch_watcher_;
-
- DISALLOW_EVIL_CONSTRUCTORS(SyncChannel);
-};
-
-} // namespace IPC
-
-#endif // COMMON_IPC_SYNC_SENDER_H__
diff --git a/ipc/ipc_sync_channel_unittest.cc b/ipc/ipc_sync_channel_unittest.cc
deleted file mode 100644
index 056a084..0000000
--- a/ipc/ipc_sync_channel_unittest.cc
+++ /dev/null
@@ -1,1013 +0,0 @@
-// Copyright (c) 2006-2008 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.
-//
-// Unit test for SyncChannel.
-
-#include <string>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/logging.h"
-#include "base/message_loop.h"
-#include "base/platform_thread.h"
-#include "base/string_util.h"
-#include "base/thread.h"
-#include "base/waitable_event.h"
-#include "ipc/ipc_message.h"
-#include "ipc/ipc_sync_channel.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-#if 0
-// This for tools which parse #include lines, but cannot process when we
-// include via a macro name.
-#include "ipc/ipc_sync_message_unittest.h"
-#endif
-#define MESSAGES_INTERNAL_FILE "ipc/ipc_sync_message_unittest.h"
-#include "ipc/ipc_message_macros.h"
-
-using namespace IPC;
-using base::WaitableEvent;
-
-namespace {
-
-// Base class for a "process" with listener and IPC threads.
-class Worker : public Channel::Listener, public Message::Sender {
- public:
- // Will create a channel without a name.
- Worker(Channel::Mode mode, const std::string& thread_name)
- : done_(new WaitableEvent(false, false)),
- channel_created_(new WaitableEvent(false, false)),
- mode_(mode),
- ipc_thread_((thread_name + "_ipc").c_str()),
- listener_thread_((thread_name + "_listener").c_str()),
- overrided_thread_(NULL),
- shutdown_event_(true, false) { }
-
- // Will create a named channel and use this name for the threads' name.
- Worker(const std::wstring& channel_name, Channel::Mode mode)
- : done_(new WaitableEvent(false, false)),
- channel_created_(new WaitableEvent(false, false)),
- channel_name_(channel_name),
- mode_(mode),
- ipc_thread_((WideToUTF8(channel_name) + "_ipc").c_str()),
- listener_thread_((WideToUTF8(channel_name) + "_listener").c_str()),
- overrided_thread_(NULL),
- shutdown_event_(true, false) { }
-
- // The IPC thread needs to outlive SyncChannel, so force the correct order of
- // destruction.
- virtual ~Worker() {
- WaitableEvent listener_done(false, false), ipc_done(false, false);
- ListenerThread()->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
- this, &Worker::OnListenerThreadShutdown1, &listener_done,
- &ipc_done));
- listener_done.Wait();
- ipc_done.Wait();
- ipc_thread_.Stop();
- listener_thread_.Stop();
- }
- void AddRef() { }
- void Release() { }
- bool Send(Message* msg) { return channel_->Send(msg); }
- bool SendWithTimeout(Message* msg, int timeout_ms) {
- return channel_->SendWithTimeout(msg, timeout_ms);
- }
- void WaitForChannelCreation() { channel_created_->Wait(); }
- void CloseChannel() {
- DCHECK(MessageLoop::current() == ListenerThread()->message_loop());
- channel_->Close();
- }
- void Start() {
- StartThread(&listener_thread_, MessageLoop::TYPE_DEFAULT);
- ListenerThread()->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
- this, &Worker::OnStart));
- }
- void OverrideThread(base::Thread* overrided_thread) {
- DCHECK(overrided_thread_ == NULL);
- overrided_thread_ = overrided_thread;
- }
- bool SendAnswerToLife(bool pump, int timeout, bool succeed) {
- int answer = 0;
- SyncMessage* msg = new SyncChannelTestMsg_AnswerToLife(&answer);
- if (pump)
- msg->EnableMessagePumping();
- bool result = SendWithTimeout(msg, timeout);
- DCHECK(result == succeed);
- DCHECK(answer == (succeed ? 42 : 0));
- return result;
- }
- bool SendDouble(bool pump, bool succeed) {
- int answer = 0;
- SyncMessage* msg = new SyncChannelTestMsg_Double(5, &answer);
- if (pump)
- msg->EnableMessagePumping();
- bool result = Send(msg);
- DCHECK(result == succeed);
- DCHECK(answer == (succeed ? 10 : 0));
- return result;
- }
- Channel::Mode mode() { return mode_; }
- WaitableEvent* done_event() { return done_.get(); }
-
- protected:
- // Derived classes need to call this when they've completed their part of
- // the test.
- void Done() { done_->Signal(); }
- // Functions for dervied classes to implement if they wish.
- virtual void Run() { }
- virtual void OnAnswer(int* answer) { NOTREACHED(); }
- virtual void OnAnswerDelay(Message* reply_msg) {
- // The message handler map below can only take one entry for
- // SyncChannelTestMsg_AnswerToLife, so since some classes want
- // the normal version while other want the delayed reply, we
- // call the normal version if the derived class didn't override
- // this function.
- int answer;
- OnAnswer(&answer);
- SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, answer);
- Send(reply_msg);
- }
- virtual void OnDouble(int in, int* out) { NOTREACHED(); }
- virtual void OnDoubleDelay(int in, Message* reply_msg) {
- int result;
- OnDouble(in, &result);
- SyncChannelTestMsg_Double::WriteReplyParams(reply_msg, result);
- Send(reply_msg);
- }
-
- private:
- base::Thread* ListenerThread() {
- return overrided_thread_ ? overrided_thread_ : &listener_thread_;
- }
- // Called on the listener thread to create the sync channel.
- void OnStart() {
- // Link ipc_thread_, listener_thread_ and channel_ altogether.
- StartThread(&ipc_thread_, MessageLoop::TYPE_IO);
- channel_.reset(new SyncChannel(
- channel_name_, mode_, this, NULL, ipc_thread_.message_loop(), true,
- &shutdown_event_));
- channel_created_->Signal();
- Run();
- }
-
- void OnListenerThreadShutdown1(WaitableEvent* listener_event,
- WaitableEvent* ipc_event) {
- // SyncChannel needs to be destructed on the thread that it was created on.
- channel_.reset();
-
- MessageLoop::current()->RunAllPending();
-
- ipc_thread_.message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
- this, &Worker::OnIPCThreadShutdown, listener_event, ipc_event));
- }
-
- void OnIPCThreadShutdown(WaitableEvent* listener_event,
- WaitableEvent* ipc_event) {
- MessageLoop::current()->RunAllPending();
- ipc_event->Signal();
-
- listener_thread_.message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
- this, &Worker::OnListenerThreadShutdown2, listener_event));
- }
-
- void OnListenerThreadShutdown2(WaitableEvent* listener_event) {
- MessageLoop::current()->RunAllPending();
- listener_event->Signal();
- }
-
- void OnMessageReceived(const Message& message) {
- IPC_BEGIN_MESSAGE_MAP(Worker, message)
- IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncChannelTestMsg_Double, OnDoubleDelay)
- IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncChannelTestMsg_AnswerToLife,
- OnAnswerDelay)
- IPC_END_MESSAGE_MAP()
- }
-
- void StartThread(base::Thread* thread, MessageLoop::Type type) {
- base::Thread::Options options;
- options.message_loop_type = type;
- thread->StartWithOptions(options);
- }
-
- scoped_ptr<WaitableEvent> done_;
- scoped_ptr<WaitableEvent> channel_created_;
- std::wstring channel_name_;
- Channel::Mode mode_;
- scoped_ptr<SyncChannel> channel_;
- base::Thread ipc_thread_;
- base::Thread listener_thread_;
- base::Thread* overrided_thread_;
-
- base::WaitableEvent shutdown_event_;
-
- DISALLOW_EVIL_CONSTRUCTORS(Worker);
-};
-
-
-// Starts the test with the given workers. This function deletes the workers
-// when it's done.
-void RunTest(std::vector<Worker*> workers) {
- // First we create the workers that are channel servers, or else the other
- // workers' channel initialization might fail because the pipe isn't created..
- for (size_t i = 0; i < workers.size(); ++i) {
- if (workers[i]->mode() == Channel::MODE_SERVER) {
- workers[i]->Start();
- workers[i]->WaitForChannelCreation();
- }
- }
-
- // now create the clients
- for (size_t i = 0; i < workers.size(); ++i) {
- if (workers[i]->mode() == Channel::MODE_CLIENT)
- workers[i]->Start();
- }
-
- // wait for all the workers to finish
- for (size_t i = 0; i < workers.size(); ++i)
- workers[i]->done_event()->Wait();
-
- for (size_t i = 0; i < workers.size(); ++i)
- delete workers[i];
-}
-
-} // namespace
-
-class IPCSyncChannelTest : public testing::Test {
- private:
- MessageLoop message_loop_;
-};
-
-//-----------------------------------------------------------------------------
-
-namespace {
-
-class SimpleServer : public Worker {
- public:
- SimpleServer(bool pump_during_send)
- : Worker(Channel::MODE_SERVER, "simpler_server"),
- pump_during_send_(pump_during_send) { }
- void Run() {
- SendAnswerToLife(pump_during_send_, base::kNoTimeout, true);
- Done();
- }
-
- bool pump_during_send_;
-};
-
-class SimpleClient : public Worker {
- public:
- SimpleClient() : Worker(Channel::MODE_CLIENT, "simple_client") { }
-
- void OnAnswer(int* answer) {
- *answer = 42;
- Done();
- }
-};
-
-void Simple(bool pump_during_send) {
- std::vector<Worker*> workers;
- workers.push_back(new SimpleServer(pump_during_send));
- workers.push_back(new SimpleClient());
- RunTest(workers);
-}
-
-} // namespace
-
-// Tests basic synchronous call
-TEST_F(IPCSyncChannelTest, Simple) {
- Simple(false);
- Simple(true);
-}
-
-//-----------------------------------------------------------------------------
-
-namespace {
-
-class DelayClient : public Worker {
- public:
- DelayClient() : Worker(Channel::MODE_CLIENT, "delay_client") { }
-
- void OnAnswerDelay(Message* reply_msg) {
- SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, 42);
- Send(reply_msg);
- Done();
- }
-};
-
-void DelayReply(bool pump_during_send) {
- std::vector<Worker*> workers;
- workers.push_back(new SimpleServer(pump_during_send));
- workers.push_back(new DelayClient());
- RunTest(workers);
-}
-
-} // namespace
-
-// Tests that asynchronous replies work
-TEST_F(IPCSyncChannelTest, DelayReply) {
- DelayReply(false);
- DelayReply(true);
-}
-
-//-----------------------------------------------------------------------------
-
-namespace {
-
-class NoHangServer : public Worker {
- public:
- explicit NoHangServer(WaitableEvent* got_first_reply, bool pump_during_send)
- : Worker(Channel::MODE_SERVER, "no_hang_server"),
- got_first_reply_(got_first_reply),
- pump_during_send_(pump_during_send) { }
- void Run() {
- SendAnswerToLife(pump_during_send_, base::kNoTimeout, true);
- got_first_reply_->Signal();
-
- SendAnswerToLife(pump_during_send_, base::kNoTimeout, false);
- Done();
- }
-
- WaitableEvent* got_first_reply_;
- bool pump_during_send_;
-};
-
-class NoHangClient : public Worker {
- public:
- explicit NoHangClient(WaitableEvent* got_first_reply)
- : Worker(Channel::MODE_CLIENT, "no_hang_client"),
- got_first_reply_(got_first_reply) { }
-
- virtual void OnAnswerDelay(Message* reply_msg) {
- // Use the DELAY_REPLY macro so that we can force the reply to be sent
- // before this function returns (when the channel will be reset).
- SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, 42);
- Send(reply_msg);
- got_first_reply_->Wait();
- CloseChannel();
- Done();
- }
-
- WaitableEvent* got_first_reply_;
-};
-
-void NoHang(bool pump_during_send) {
- WaitableEvent got_first_reply(false, false);
- std::vector<Worker*> workers;
- workers.push_back(new NoHangServer(&got_first_reply, pump_during_send));
- workers.push_back(new NoHangClient(&got_first_reply));
- RunTest(workers);
-}
-
-} // namespace
-
-// Tests that caller doesn't hang if receiver dies
-TEST_F(IPCSyncChannelTest, NoHang) {
- NoHang(false);
- NoHang(true);
-}
-
-//-----------------------------------------------------------------------------
-
-namespace {
-
-class UnblockServer : public Worker {
- public:
- UnblockServer(bool pump_during_send)
- : Worker(Channel::MODE_SERVER, "unblock_server"),
- pump_during_send_(pump_during_send) { }
- void Run() {
- SendAnswerToLife(pump_during_send_, base::kNoTimeout, true);
- Done();
- }
-
- void OnDouble(int in, int* out) {
- *out = in * 2;
- }
-
- bool pump_during_send_;
-};
-
-class UnblockClient : public Worker {
- public:
- UnblockClient(bool pump_during_send)
- : Worker(Channel::MODE_CLIENT, "unblock_client"),
- pump_during_send_(pump_during_send) { }
-
- void OnAnswer(int* answer) {
- SendDouble(pump_during_send_, true);
- *answer = 42;
- Done();
- }
-
- bool pump_during_send_;
-};
-
-void Unblock(bool server_pump, bool client_pump) {
- std::vector<Worker*> workers;
- workers.push_back(new UnblockServer(server_pump));
- workers.push_back(new UnblockClient(client_pump));
- RunTest(workers);
-}
-
-} // namespace
-
-// Tests that the caller unblocks to answer a sync message from the receiver.
-TEST_F(IPCSyncChannelTest, Unblock) {
- Unblock(false, false);
- Unblock(false, true);
- Unblock(true, false);
- Unblock(true, true);
-}
-
-//-----------------------------------------------------------------------------
-
-namespace {
-
-class RecursiveServer : public Worker {
- public:
- explicit RecursiveServer(
- bool expected_send_result, bool pump_first, bool pump_second)
- : Worker(Channel::MODE_SERVER, "recursive_server"),
- expected_send_result_(expected_send_result),
- pump_first_(pump_first), pump_second_(pump_second) { }
- void Run() {
- SendDouble(pump_first_, expected_send_result_);
- Done();
- }
-
- void OnDouble(int in, int* out) {
- *out = in * 2;
- SendAnswerToLife(pump_second_, base::kNoTimeout, expected_send_result_);
- }
-
- bool expected_send_result_, pump_first_, pump_second_;
-};
-
-class RecursiveClient : public Worker {
- public:
- explicit RecursiveClient(bool pump_during_send, bool close_channel)
- : Worker(Channel::MODE_CLIENT, "recursive_client"),
- pump_during_send_(pump_during_send), close_channel_(close_channel) { }
-
- void OnDoubleDelay(int in, Message* reply_msg) {
- SendDouble(pump_during_send_, !close_channel_);
- if (close_channel_) {
- delete reply_msg;
- } else {
- SyncChannelTestMsg_Double::WriteReplyParams(reply_msg, in * 2);
- Send(reply_msg);
- }
- Done();
- }
-
- void OnAnswerDelay(Message* reply_msg) {
- if (close_channel_) {
- delete reply_msg;
- CloseChannel();
- } else {
- SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, 42);
- Send(reply_msg);
- }
- }
-
- bool pump_during_send_, close_channel_;
-};
-
-void Recursive(
- bool server_pump_first, bool server_pump_second, bool client_pump) {
- std::vector<Worker*> workers;
- workers.push_back(
- new RecursiveServer(true, server_pump_first, server_pump_second));
- workers.push_back(new RecursiveClient(client_pump, false));
- RunTest(workers);
-}
-
-} // namespace
-
-// Tests a server calling Send while another Send is pending.
-TEST_F(IPCSyncChannelTest, Recursive) {
- Recursive(false, false, false);
- Recursive(false, false, true);
- Recursive(false, true, false);
- Recursive(false, true, true);
- Recursive(true, false, false);
- Recursive(true, false, true);
- Recursive(true, true, false);
- Recursive(true, true, true);
-}
-
-//-----------------------------------------------------------------------------
-
-namespace {
-
-void RecursiveNoHang(
- bool server_pump_first, bool server_pump_second, bool client_pump) {
- std::vector<Worker*> workers;
- workers.push_back(
- new RecursiveServer(false, server_pump_first, server_pump_second));
- workers.push_back(new RecursiveClient(client_pump, true));
- RunTest(workers);
-}
-
-} // namespace
-
-// Tests that if a caller makes a sync call during an existing sync call and
-// the receiver dies, neither of the Send() calls hang.
-TEST_F(IPCSyncChannelTest, RecursiveNoHang) {
- RecursiveNoHang(false, false, false);
- RecursiveNoHang(false, false, true);
- RecursiveNoHang(false, true, false);
- RecursiveNoHang(false, true, true);
- RecursiveNoHang(true, false, false);
- RecursiveNoHang(true, false, true);
- RecursiveNoHang(true, true, false);
- RecursiveNoHang(true, true, true);
-}
-
-//-----------------------------------------------------------------------------
-
-namespace {
-
-class MultipleServer1 : public Worker {
- public:
- MultipleServer1(bool pump_during_send)
- : Worker(L"test_channel1", Channel::MODE_SERVER),
- pump_during_send_(pump_during_send) { }
-
- void Run() {
- SendDouble(pump_during_send_, true);
- Done();
- }
-
- bool pump_during_send_;
-};
-
-class MultipleClient1 : public Worker {
- public:
- MultipleClient1(WaitableEvent* client1_msg_received,
- WaitableEvent* client1_can_reply) :
- Worker(L"test_channel1", Channel::MODE_CLIENT),
- client1_msg_received_(client1_msg_received),
- client1_can_reply_(client1_can_reply) { }
-
- void OnDouble(int in, int* out) {
- client1_msg_received_->Signal();
- *out = in * 2;
- client1_can_reply_->Wait();
- Done();
- }
-
- private:
- WaitableEvent *client1_msg_received_, *client1_can_reply_;
-};
-
-class MultipleServer2 : public Worker {
- public:
- MultipleServer2() : Worker(L"test_channel2", Channel::MODE_SERVER) { }
-
- void OnAnswer(int* result) {
- *result = 42;
- Done();
- }
-};
-
-class MultipleClient2 : public Worker {
- public:
- MultipleClient2(
- WaitableEvent* client1_msg_received, WaitableEvent* client1_can_reply,
- bool pump_during_send)
- : Worker(L"test_channel2", Channel::MODE_CLIENT),
- client1_msg_received_(client1_msg_received),
- client1_can_reply_(client1_can_reply),
- pump_during_send_(pump_during_send) { }
-
- void Run() {
- client1_msg_received_->Wait();
- SendAnswerToLife(pump_during_send_, base::kNoTimeout, true);
- client1_can_reply_->Signal();
- Done();
- }
-
- private:
- WaitableEvent *client1_msg_received_, *client1_can_reply_;
- bool pump_during_send_;
-};
-
-void Multiple(bool server_pump, bool client_pump) {
- std::vector<Worker*> workers;
-
- // A shared worker thread so that server1 and server2 run on one thread.
- base::Thread worker_thread("Multiple");
- worker_thread.Start();
-
- // Server1 sends a sync msg to client1, which blocks the reply until
- // server2 (which runs on the same worker thread as server1) responds
- // to a sync msg from client2.
- WaitableEvent client1_msg_received(false, false);
- WaitableEvent client1_can_reply(false, false);
-
- Worker* worker;
-
- worker = new MultipleServer2();
- worker->OverrideThread(&worker_thread);
- workers.push_back(worker);
-
- worker = new MultipleClient2(
- &client1_msg_received, &client1_can_reply, client_pump);
- workers.push_back(worker);
-
- worker = new MultipleServer1(server_pump);
- worker->OverrideThread(&worker_thread);
- workers.push_back(worker);
-
- worker = new MultipleClient1(
- &client1_msg_received, &client1_can_reply);
- workers.push_back(worker);
-
- RunTest(workers);
-}
-
-} // namespace
-
-// Tests that multiple SyncObjects on the same listener thread can unblock each
-// other.
-TEST_F(IPCSyncChannelTest, Multiple) {
- Multiple(false, false);
- Multiple(false, true);
- Multiple(true, false);
- Multiple(true, true);
-}
-
-//-----------------------------------------------------------------------------
-
-namespace {
-
-class QueuedReplyServer1 : public Worker {
- public:
- QueuedReplyServer1(bool pump_during_send)
- : Worker(L"test_channel1", Channel::MODE_SERVER),
- pump_during_send_(pump_during_send) { }
- void Run() {
- SendDouble(pump_during_send_, true);
- Done();
- }
-
- bool pump_during_send_;
-};
-
-class QueuedReplyClient1 : public Worker {
- public:
- QueuedReplyClient1(WaitableEvent* client1_msg_received,
- WaitableEvent* server2_can_reply) :
- Worker(L"test_channel1", Channel::MODE_CLIENT),
- client1_msg_received_(client1_msg_received),
- server2_can_reply_(server2_can_reply) { }
-
- void OnDouble(int in, int* out) {
- client1_msg_received_->Signal();
- *out = in * 2;
- server2_can_reply_->Wait();
- Done();
- }
-
- private:
- WaitableEvent *client1_msg_received_, *server2_can_reply_;
-};
-
-class QueuedReplyServer2 : public Worker {
- public:
- explicit QueuedReplyServer2(WaitableEvent* server2_can_reply) :
- Worker(L"test_channel2", Channel::MODE_SERVER),
- server2_can_reply_(server2_can_reply) { }
-
- void OnAnswer(int* result) {
- server2_can_reply_->Signal();
-
- // give client1's reply time to reach the server listener thread
- PlatformThread::Sleep(200);
-
- *result = 42;
- Done();
- }
-
- WaitableEvent *server2_can_reply_;
-};
-
-class QueuedReplyClient2 : public Worker {
- public:
- explicit QueuedReplyClient2(
- WaitableEvent* client1_msg_received, bool pump_during_send)
- : Worker(L"test_channel2", Channel::MODE_CLIENT),
- client1_msg_received_(client1_msg_received),
- pump_during_send_(pump_during_send){ }
-
- void Run() {
- client1_msg_received_->Wait();
- SendAnswerToLife(pump_during_send_, base::kNoTimeout, true);
- Done();
- }
-
- WaitableEvent *client1_msg_received_;
- bool pump_during_send_;
-};
-
-void QueuedReply(bool server_pump, bool client_pump) {
- std::vector<Worker*> workers;
-
- // A shared worker thread so that server1 and server2 run on one thread.
- base::Thread worker_thread("QueuedReply");
- worker_thread.Start();
-
- WaitableEvent client1_msg_received(false, false);
- WaitableEvent server2_can_reply(false, false);
-
- Worker* worker;
-
- worker = new QueuedReplyServer2(&server2_can_reply);
- worker->OverrideThread(&worker_thread);
- workers.push_back(worker);
-
- worker = new QueuedReplyClient2(&client1_msg_received, client_pump);
- workers.push_back(worker);
-
- worker = new QueuedReplyServer1(server_pump);
- worker->OverrideThread(&worker_thread);
- workers.push_back(worker);
-
- worker = new QueuedReplyClient1(
- &client1_msg_received, &server2_can_reply);
- workers.push_back(worker);
-
- RunTest(workers);
-}
-
-} // namespace
-
-// While a blocking send is in progress, the listener thread might answer other
-// synchronous messages. This tests that if during the response to another
-// message the reply to the original messages comes, it is queued up correctly
-// and the original Send is unblocked later.
-TEST_F(IPCSyncChannelTest, QueuedReply) {
- QueuedReply(false, false);
- QueuedReply(false, true);
- QueuedReply(true, false);
- QueuedReply(true, true);
-}
-
-//-----------------------------------------------------------------------------
-
-namespace {
-
-class BadServer : public Worker {
- public:
- BadServer(bool pump_during_send)
- : Worker(Channel::MODE_SERVER, "simpler_server"),
- pump_during_send_(pump_during_send) { }
- void Run() {
- int answer = 0;
-
- SyncMessage* msg = new SyncMessage(
- MSG_ROUTING_CONTROL, SyncChannelTestMsg_Double::ID,
- Message::PRIORITY_NORMAL, NULL);
- if (pump_during_send_)
- msg->EnableMessagePumping();
-
- // Temporarily set the minimum logging very high so that the assertion
- // in ipc_message_utils doesn't fire.
- int log_level = logging::GetMinLogLevel();
- logging::SetMinLogLevel(kint32max);
- bool result = Send(msg);
- logging::SetMinLogLevel(log_level);
- DCHECK(!result);
-
- // Need to send another message to get the client to call Done().
- result = Send(new SyncChannelTestMsg_AnswerToLife(&answer));
- DCHECK(result);
- DCHECK(answer == 42);
-
- Done();
- }
-
- bool pump_during_send_;
-};
-
-void BadMessage(bool pump_during_send) {
- std::vector<Worker*> workers;
- workers.push_back(new BadServer(pump_during_send));
- workers.push_back(new SimpleClient());
- RunTest(workers);
-}
-
-} // namespace
-
-// Tests that if a message is not serialized correctly, the Send() will fail.
-TEST_F(IPCSyncChannelTest, BadMessage) {
- BadMessage(false);
- BadMessage(true);
-}
-
-//-----------------------------------------------------------------------------
-
-namespace {
-
-class ChattyClient : public Worker {
- public:
- ChattyClient() :
- Worker(Channel::MODE_CLIENT, "chatty_client") { }
-
- void OnAnswer(int* answer) {
- // The PostMessage limit is 10k. Send 20% more than that.
- const int kMessageLimit = 10000;
- const int kMessagesToSend = kMessageLimit * 120 / 100;
- for (int i = 0; i < kMessagesToSend; ++i) {
- if (!SendDouble(false, true))
- break;
- }
- *answer = 42;
- Done();
- }
-};
-
-void ChattyServer(bool pump_during_send) {
- std::vector<Worker*> workers;
- workers.push_back(new UnblockServer(pump_during_send));
- workers.push_back(new ChattyClient());
- RunTest(workers);
-}
-
-} // namespace
-
-// Tests http://b/1093251 - that sending lots of sync messages while
-// the receiver is waiting for a sync reply does not overflow the PostMessage
-// queue.
-TEST_F(IPCSyncChannelTest, ChattyServer) {
- ChattyServer(false);
- ChattyServer(true);
-}
-
-//------------------------------------------------------------------------------
-
-namespace {
-
-class TimeoutServer : public Worker {
- public:
- TimeoutServer(int timeout_ms,
- std::vector<bool> timeout_seq,
- bool pump_during_send)
- : Worker(Channel::MODE_SERVER, "timeout_server"),
- timeout_ms_(timeout_ms),
- timeout_seq_(timeout_seq),
- pump_during_send_(pump_during_send) {
- }
-
- void Run() {
- for (std::vector<bool>::const_iterator iter = timeout_seq_.begin();
- iter != timeout_seq_.end(); ++iter) {
- SendAnswerToLife(pump_during_send_, timeout_ms_, !*iter);
- }
- Done();
- }
-
- private:
- int timeout_ms_;
- std::vector<bool> timeout_seq_;
- bool pump_during_send_;
-};
-
-class UnresponsiveClient : public Worker {
- public:
- UnresponsiveClient(std::vector<bool> timeout_seq)
- : Worker(Channel::MODE_CLIENT, "unresponsive_client"),
- timeout_seq_(timeout_seq) {
- }
-
- void OnAnswerDelay(Message* reply_msg) {
- DCHECK(!timeout_seq_.empty());
- if (!timeout_seq_[0]) {
- SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, 42);
- Send(reply_msg);
- } else {
- // Don't reply.
- delete reply_msg;
- }
- timeout_seq_.erase(timeout_seq_.begin());
- if (timeout_seq_.empty())
- Done();
- }
-
- private:
- // Whether we should time-out or respond to the various messages we receive.
- std::vector<bool> timeout_seq_;
-};
-
-void SendWithTimeoutOK(bool pump_during_send) {
- std::vector<Worker*> workers;
- std::vector<bool> timeout_seq;
- timeout_seq.push_back(false);
- timeout_seq.push_back(false);
- timeout_seq.push_back(false);
- workers.push_back(new TimeoutServer(5000, timeout_seq, pump_during_send));
- workers.push_back(new SimpleClient());
- RunTest(workers);
-}
-
-void SendWithTimeoutTimeout(bool pump_during_send) {
- std::vector<Worker*> workers;
- std::vector<bool> timeout_seq;
- timeout_seq.push_back(true);
- timeout_seq.push_back(false);
- timeout_seq.push_back(false);
- workers.push_back(new TimeoutServer(100, timeout_seq, pump_during_send));
- workers.push_back(new UnresponsiveClient(timeout_seq));
- RunTest(workers);
-}
-
-void SendWithTimeoutMixedOKAndTimeout(bool pump_during_send) {
- std::vector<Worker*> workers;
- std::vector<bool> timeout_seq;
- timeout_seq.push_back(true);
- timeout_seq.push_back(false);
- timeout_seq.push_back(false);
- timeout_seq.push_back(true);
- timeout_seq.push_back(false);
- workers.push_back(new TimeoutServer(100, timeout_seq, pump_during_send));
- workers.push_back(new UnresponsiveClient(timeout_seq));
- RunTest(workers);
-}
-
-} // namespace
-
-// Tests that SendWithTimeout does not time-out if the response comes back fast
-// enough.
-TEST_F(IPCSyncChannelTest, SendWithTimeoutOK) {
- SendWithTimeoutOK(false);
- SendWithTimeoutOK(true);
-}
-
-// Tests that SendWithTimeout does time-out.
-TEST_F(IPCSyncChannelTest, SendWithTimeoutTimeout) {
- SendWithTimeoutTimeout(false);
- SendWithTimeoutTimeout(true);
-}
-
-// Sends some message that time-out and some that succeed.
-TEST_F(IPCSyncChannelTest, SendWithTimeoutMixedOKAndTimeout) {
- SendWithTimeoutMixedOKAndTimeout(false);
- SendWithTimeoutMixedOKAndTimeout(true);
-}
-
-//------------------------------------------------------------------------------
-
-namespace {
-
-class NestedTask : public Task {
- public:
- NestedTask(Worker* server) : server_(server) { }
- void Run() {
- // Sleep a bit so that we wake up after the reply has been received.
- PlatformThread::Sleep(250);
- server_->SendAnswerToLife(true, base::kNoTimeout, true);
- }
-
- Worker* server_;
-};
-
-static bool timeout_occured = false;
-
-class TimeoutTask : public Task {
- public:
- void Run() {
- timeout_occured = true;
- }
-};
-
-class DoneEventRaceServer : public Worker {
- public:
- DoneEventRaceServer()
- : Worker(Channel::MODE_SERVER, "done_event_race_server") { }
-
- void Run() {
- MessageLoop::current()->PostTask(FROM_HERE, new NestedTask(this));
- MessageLoop::current()->PostDelayedTask(FROM_HERE, new TimeoutTask(), 9000);
- // Even though we have a timeout on the Send, it will succeed since for this
- // bug, the reply message comes back and is deserialized, however the done
- // event wasn't set. So we indirectly use the timeout task to notice if a
- // timeout occurred.
- SendAnswerToLife(true, 10000, true);
- DCHECK(!timeout_occured);
- Done();
- }
-};
-
-} // namespace
-
-// Tests http://b/1474092 - that if after the done_event is set but before
-// OnObjectSignaled is called another message is sent out, then after its
-// reply comes back OnObjectSignaled will be called for the first message.
-TEST_F(IPCSyncChannelTest, DoneEventRace) {
- std::vector<Worker*> workers;
- workers.push_back(new DoneEventRaceServer());
- workers.push_back(new SimpleClient());
- RunTest(workers);
-}
diff --git a/ipc/ipc_sync_message.cc b/ipc/ipc_sync_message.cc
deleted file mode 100644
index 519adb1..0000000
--- a/ipc/ipc_sync_message.cc
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright (c) 2006-2008 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 "build/build_config.h"
-
-#if defined(OS_WIN)
-#include <windows.h>
-#endif
-#include <stack>
-
-#include "base/logging.h"
-#include "base/waitable_event.h"
-#include "ipc/ipc_sync_message.h"
-
-namespace IPC {
-
-uint32 SyncMessage::next_id_ = 0;
-#define kSyncMessageHeaderSize 4
-
-base::WaitableEvent* dummy_event = new base::WaitableEvent(true, true);
-
-SyncMessage::SyncMessage(
- int32 routing_id,
- uint16 type,
- PriorityValue priority,
- MessageReplyDeserializer* deserializer)
- : Message(routing_id, type, priority),
- deserializer_(deserializer),
- pump_messages_event_(NULL)
- {
- set_sync();
- set_unblock(true);
-
- // Add synchronous message data before the message payload.
- SyncHeader header;
- header.message_id = ++next_id_;
- WriteSyncHeader(this, header);
-}
-
-MessageReplyDeserializer* SyncMessage::GetReplyDeserializer() {
- MessageReplyDeserializer* rv = deserializer_;
- DCHECK(rv);
- deserializer_ = NULL;
- return rv;
-}
-
-void SyncMessage::EnableMessagePumping() {
- DCHECK(!pump_messages_event_);
- set_pump_messages_event(dummy_event);
-}
-
-bool SyncMessage::IsMessageReplyTo(const Message& msg, int request_id) {
- if (!msg.is_reply())
- return false;
-
- return GetMessageId(msg) == request_id;
-}
-
-void* SyncMessage::GetDataIterator(const Message* msg) {
- void* iter = const_cast<char*>(msg->payload());
- UpdateIter(&iter, kSyncMessageHeaderSize);
- return iter;
-}
-
-int SyncMessage::GetMessageId(const Message& msg) {
- if (!msg.is_sync() && !msg.is_reply())
- return 0;
-
- SyncHeader header;
- if (!ReadSyncHeader(msg, &header))
- return 0;
-
- return header.message_id;
-}
-
-Message* SyncMessage::GenerateReply(const Message* msg) {
- DCHECK(msg->is_sync());
-
- Message* reply = new Message(msg->routing_id(), IPC_REPLY_ID,
- msg->priority());
- reply->set_reply();
-
- SyncHeader header;
-
- // use the same message id, but this time reply bit is set
- header.message_id = GetMessageId(*msg);
- WriteSyncHeader(reply, header);
-
- return reply;
-}
-
-bool SyncMessage::ReadSyncHeader(const Message& msg, SyncHeader* header) {
- DCHECK(msg.is_sync() || msg.is_reply());
-
- void* iter = NULL;
- bool result = msg.ReadInt(&iter, &header->message_id);
- if (!result) {
- NOTREACHED();
- return false;
- }
-
- return true;
-}
-
-bool SyncMessage::WriteSyncHeader(Message* msg, const SyncHeader& header) {
- DCHECK(msg->is_sync() || msg->is_reply());
- DCHECK(msg->payload_size() == 0);
- bool result = msg->WriteInt(header.message_id);
- if (!result) {
- NOTREACHED();
- return false;
- }
-
- // Note: if you add anything here, you need to update kSyncMessageHeaderSize.
- DCHECK(kSyncMessageHeaderSize == msg->payload_size());
-
- return true;
-}
-
-
-bool MessageReplyDeserializer::SerializeOutputParameters(const Message& msg) {
- return SerializeOutputParameters(msg, SyncMessage::GetDataIterator(&msg));
-}
-
-} // namespace IPC
diff --git a/ipc/ipc_sync_message.h b/ipc/ipc_sync_message.h
deleted file mode 100644
index 3006736..0000000
--- a/ipc/ipc_sync_message.h
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright (c) 2006-2008 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 COMMON_IPC_SYNC_MESSAGE_H__
-#define COMMON_IPC_SYNC_MESSAGE_H__
-
-#if defined(OS_WIN)
-#include <windows.h>
-#endif
-#include <string>
-#include "base/basictypes.h"
-#include "ipc/ipc_message.h"
-
-namespace base {
-class WaitableEvent;
-}
-
-namespace IPC {
-
-class MessageReplyDeserializer;
-
-class SyncMessage : public Message {
- public:
- SyncMessage(int32 routing_id, uint16 type, PriorityValue priority,
- MessageReplyDeserializer* deserializer);
-
- // Call this to get a deserializer for the output parameters.
- // Note that this can only be called once, and the caller is responsible
- // for deleting the deserializer when they're done.
- MessageReplyDeserializer* GetReplyDeserializer();
-
- // If this message can cause the receiver to block while waiting for user
- // input (i.e. by calling MessageBox), then the caller needs to pump window
- // messages and dispatch asynchronous messages while waiting for the reply.
- // If this event is passed in, then window messages will start being pumped
- // when it's set. Note that this behavior will continue even if the event is
- // later reset. The event must be valid until after the Send call returns.
- void set_pump_messages_event(base::WaitableEvent* event) {
- pump_messages_event_ = event;
- if (event) {
- header()->flags |= PUMPING_MSGS_BIT;
- } else {
- header()->flags &= ~PUMPING_MSGS_BIT;
- }
- }
-
- // Call this if you always want to pump messages. You can call this method
- // or set_pump_messages_event but not both.
- void EnableMessagePumping();
-
- base::WaitableEvent* pump_messages_event() const {
- return pump_messages_event_;
- }
-
- // Returns true if the message is a reply to the given request id.
- static bool IsMessageReplyTo(const Message& msg, int request_id);
-
- // Given a reply message, returns an iterator to the beginning of the data
- // (i.e. skips over the synchronous specific data).
- static void* GetDataIterator(const Message* msg);
-
- // Given a synchronous message (or its reply), returns its id.
- static int GetMessageId(const Message& msg);
-
- // Generates a reply message to the given message.
- static Message* GenerateReply(const Message* msg);
-
- private:
- struct SyncHeader {
- // unique ID (unique per sender)
- int message_id;
- };
-
- static bool ReadSyncHeader(const Message& msg, SyncHeader* header);
- static bool WriteSyncHeader(Message* msg, const SyncHeader& header);
-
- MessageReplyDeserializer* deserializer_;
- base::WaitableEvent* pump_messages_event_;
-
- static uint32 next_id_; // for generation of unique ids
-};
-
-// Used to deserialize parameters from a reply to a synchronous message
-class MessageReplyDeserializer {
- public:
- bool SerializeOutputParameters(const Message& msg);
- private:
- // Derived classes need to implement this, using the given iterator (which
- // is skipped past the header for synchronous messages).
- virtual bool SerializeOutputParameters(const Message& msg, void* iter) = 0;
-};
-
-} // namespace IPC
-
-#endif // COMMON_IPC_SYNC_MESSAGE_H__
diff --git a/ipc/ipc_sync_message_unittest.cc b/ipc/ipc_sync_message_unittest.cc
deleted file mode 100644
index 9e3de1f..0000000
--- a/ipc/ipc_sync_message_unittest.cc
+++ /dev/null
@@ -1,253 +0,0 @@
-// Copyright (c) 2006-2008 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.
-//
-// Unit test to make sure that the serialization of synchronous IPC messages
-// works. This ensures that the macros and templates were defined correctly.
-// Doesn't test the IPC channel mechanism.
-
-#include <string.h>
-
-#include "base/basictypes.h"
-#include "ipc/ipc_message.h"
-#include "ipc/ipc_message_utils.h"
-#include "base/logging.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-#if 0
-// This for tools which parse #include lines, but cannot process when we
-// include via a macro name.
-#include "ipc/ipc_sync_message_unittest.h"
-#endif
-#define MESSAGES_INTERNAL_FILE "ipc/ipc_sync_message_unittest.h"
-#include "ipc/ipc_message_macros.h"
-
-static IPC::Message* g_reply;
-
-class TestMessageReceiver {
- public:
-
- void On_0_1(bool* out1) {
- *out1 = false;
- }
-
- void On_0_2(bool* out1, int* out2) {
- *out1 = true;
- *out2 = 2;
- }
-
- void On_0_3(bool* out1, int* out2, std::string* out3) {
- *out1 = false;
- *out2 = 3;
- *out3 = "0_3";
- }
-
- void On_1_1(int in1, bool* out1) {
- DCHECK(in1 == 1);
- *out1 = true;
- }
-
- void On_1_2(bool in1, bool* out1, int* out2) {
- DCHECK(!in1);
- *out1 = true;
- *out2 = 12;
- }
-
- void On_1_3(int in1, std::string* out1, int* out2, bool* out3) {
- DCHECK(in1 == 3);
- *out1 = "1_3";
- *out2 = 13;
- *out3 = false;
- }
-
- void On_2_1(int in1, bool in2, bool* out1) {
- DCHECK(in1 == 1 && !in2);
- *out1 = true;
- }
-
- void On_2_2(bool in1, int in2, bool* out1, int* out2) {
- DCHECK(!in1 && in2 == 2);
- *out1 = true;
- *out2 = 22;
- }
-
- void On_2_3(int in1, bool in2, std::string* out1, int* out2, bool* out3) {
- DCHECK(in1 == 3 && in2);
- *out1 = "2_3";
- *out2 = 23;
- *out3 = false;
- }
-
- void On_3_1(int in1, bool in2, std::string in3, bool* out1) {
- DCHECK(in1 == 1 && !in2 && in3 == "3_1");
- *out1 = true;
- }
-
- void On_3_2(std::string in1, bool in2, int in3, bool* out1, int* out2) {
- DCHECK(in1 == "3_2" && !in2 && in3 == 2);
- *out1 = true;
- *out2 = 32;
- }
-
- void On_3_3(int in1, std::string in2, bool in3, std::string* out1, int* out2,
- bool* out3) {
- DCHECK(in1 == 3 && in2 == "3_3" && in3);
- *out1 = "3_3";
- *out2 = 33;
- *out3 = false;
- }
-
- bool Send(IPC::Message* message) {
- // gets the reply message, stash in global
- DCHECK(g_reply == NULL);
- g_reply = message;
- return true;
- }
-
- void OnMessageReceived(const IPC::Message& msg) {
- IPC_BEGIN_MESSAGE_MAP(TestMessageReceiver, msg)
- IPC_MESSAGE_HANDLER(Msg_C_0_1, On_0_1)
- IPC_MESSAGE_HANDLER(Msg_C_0_2, On_0_2)
- IPC_MESSAGE_HANDLER(Msg_C_0_3, On_0_3)
- IPC_MESSAGE_HANDLER(Msg_C_1_1, On_1_1)
- IPC_MESSAGE_HANDLER(Msg_C_1_2, On_1_2)
- IPC_MESSAGE_HANDLER(Msg_C_1_3, On_1_3)
- IPC_MESSAGE_HANDLER(Msg_C_2_1, On_2_1)
- IPC_MESSAGE_HANDLER(Msg_C_2_2, On_2_2)
- IPC_MESSAGE_HANDLER(Msg_C_2_3, On_2_3)
- IPC_MESSAGE_HANDLER(Msg_C_3_1, On_3_1)
- IPC_MESSAGE_HANDLER(Msg_C_3_2, On_3_2)
- IPC_MESSAGE_HANDLER(Msg_C_3_3, On_3_3)
- IPC_MESSAGE_HANDLER(Msg_R_0_1, On_0_1)
- IPC_MESSAGE_HANDLER(Msg_R_0_2, On_0_2)
- IPC_MESSAGE_HANDLER(Msg_R_0_3, On_0_3)
- IPC_MESSAGE_HANDLER(Msg_R_1_1, On_1_1)
- IPC_MESSAGE_HANDLER(Msg_R_1_2, On_1_2)
- IPC_MESSAGE_HANDLER(Msg_R_1_3, On_1_3)
- IPC_MESSAGE_HANDLER(Msg_R_2_1, On_2_1)
- IPC_MESSAGE_HANDLER(Msg_R_2_2, On_2_2)
- IPC_MESSAGE_HANDLER(Msg_R_2_3, On_2_3)
- IPC_MESSAGE_HANDLER(Msg_R_3_1, On_3_1)
- IPC_MESSAGE_HANDLER(Msg_R_3_2, On_3_2)
- IPC_MESSAGE_HANDLER(Msg_R_3_3, On_3_3)
- IPC_END_MESSAGE_MAP()
- }
-
-};
-
-void Send(IPC::SyncMessage* msg) {
- static TestMessageReceiver receiver;
-
- IPC::MessageReplyDeserializer* reply_serializer = msg->GetReplyDeserializer();
- DCHECK(reply_serializer != NULL);
-
- // "send" the message
- receiver.OnMessageReceived(*msg);
- delete msg;
-
- // get the reply message from the global, and deserialize the output
- // parameters into the output pointers.
- DCHECK(g_reply != NULL);
- bool result = reply_serializer->SerializeOutputParameters(*g_reply);
- DCHECK(result);
- delete g_reply;
- g_reply = NULL;
- delete reply_serializer;
-}
-
-TEST(IPCSyncMessageTest, Main) {
- bool bool1 = true;
- int int1 = 0;
- std::string string1;
-
- Send(new Msg_C_0_1(&bool1));
- DCHECK(!bool1);
-
- Send(new Msg_C_0_2(&bool1, &int1));
- DCHECK(bool1 && int1 == 2);
-
- Send(new Msg_C_0_3(&bool1, &int1, &string1));
- DCHECK(!bool1 && int1 == 3 && string1 == "0_3");
-
- bool1 = false;
- Send(new Msg_C_1_1(1, &bool1));
- DCHECK(bool1);
-
- bool1 = false;
- Send(new Msg_C_1_2(false, &bool1, &int1));
- DCHECK(bool1 && int1 == 12);
-
- bool1 = true;
- Send(new Msg_C_1_3(3, &string1, &int1, &bool1));
- DCHECK(string1 == "1_3" && int1 == 13 && !bool1);
-
- bool1 = false;
- Send(new Msg_C_2_1(1, false, &bool1));
- DCHECK(bool1);
-
- bool1 = false;
- Send(new Msg_C_2_2(false, 2, &bool1, &int1));
- DCHECK(bool1 && int1 == 22);
-
- bool1 = true;
- Send(new Msg_C_2_3(3, true, &string1, &int1, &bool1));
- DCHECK(string1 == "2_3" && int1 == 23 && !bool1);
-
- bool1 = false;
- Send(new Msg_C_3_1(1, false, "3_1", &bool1));
- DCHECK(bool1);
-
- bool1 = false;
- Send(new Msg_C_3_2("3_2", false, 2, &bool1, &int1));
- DCHECK(bool1 && int1 == 32);
-
- bool1 = true;
- Send(new Msg_C_3_3(3, "3_3", true, &string1, &int1, &bool1));
- DCHECK(string1 == "3_3" && int1 == 33 && !bool1);
-
- // Routed messages, just a copy of the above but with extra routing paramater
- Send(new Msg_R_0_1(0, &bool1));
- DCHECK(!bool1);
-
- Send(new Msg_R_0_2(0, &bool1, &int1));
- DCHECK(bool1 && int1 == 2);
-
- Send(new Msg_R_0_3(0, &bool1, &int1, &string1));
- DCHECK(!bool1 && int1 == 3 && string1 == "0_3");
-
- bool1 = false;
- Send(new Msg_R_1_1(0, 1, &bool1));
- DCHECK(bool1);
-
- bool1 = false;
- Send(new Msg_R_1_2(0, false, &bool1, &int1));
- DCHECK(bool1 && int1 == 12);
-
- bool1 = true;
- Send(new Msg_R_1_3(0, 3, &string1, &int1, &bool1));
- DCHECK(string1 == "1_3" && int1 == 13 && !bool1);
-
- bool1 = false;
- Send(new Msg_R_2_1(0, 1, false, &bool1));
- DCHECK(bool1);
-
- bool1 = false;
- Send(new Msg_R_2_2(0, false, 2, &bool1, &int1));
- DCHECK(bool1 && int1 == 22);
-
- bool1 = true;
- Send(new Msg_R_2_3(0, 3, true, &string1, &int1, &bool1));
- DCHECK(string1 == "2_3" && int1 == 23 && !bool1);
-
- bool1 = false;
- Send(new Msg_R_3_1(0, 1, false, "3_1", &bool1));
- DCHECK(bool1);
-
- bool1 = false;
- Send(new Msg_R_3_2(0, "3_2", false, 2, &bool1, &int1));
- DCHECK(bool1 && int1 == 32);
-
- bool1 = true;
- Send(new Msg_R_3_3(0, 3, "3_3", true, &string1, &int1, &bool1));
- DCHECK(string1 == "3_3" && int1 == 33 && !bool1);
-}
diff --git a/ipc/ipc_sync_message_unittest.h b/ipc/ipc_sync_message_unittest.h
deleted file mode 100644
index 7b252b5..0000000
--- a/ipc/ipc_sync_message_unittest.h
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright (c) 2006-2008 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 "ipc/ipc_message_macros.h"
-
-IPC_BEGIN_MESSAGES(Test)
- IPC_SYNC_MESSAGE_CONTROL0_0(SyncChannelTestMsg_NoArgs)
-
- IPC_SYNC_MESSAGE_CONTROL0_1(SyncChannelTestMsg_AnswerToLife,
- int /* answer */)
-
- IPC_SYNC_MESSAGE_CONTROL1_1(SyncChannelTestMsg_Double,
- int /* in */,
- int /* out */)
-
- // out1 is false
- IPC_SYNC_MESSAGE_CONTROL0_1(Msg_C_0_1, bool)
-
- // out1 is true, out2 is 2
- IPC_SYNC_MESSAGE_CONTROL0_2(Msg_C_0_2, bool, int)
-
- // out1 is false, out2 is 3, out3 is "0_3"
- IPC_SYNC_MESSAGE_CONTROL0_3(Msg_C_0_3, bool, int, std::string)
-
- // in1 must be 1, out1 is true
- IPC_SYNC_MESSAGE_CONTROL1_1(Msg_C_1_1, int, bool)
-
- // in1 must be false, out1 is true, out2 is 12
- IPC_SYNC_MESSAGE_CONTROL1_2(Msg_C_1_2, bool, bool, int)
-
- // in1 must be 3, out1 is "1_3", out2 is 13, out3 is false
- IPC_SYNC_MESSAGE_CONTROL1_3(Msg_C_1_3, int, std::string, int, bool)
-
- // in1 must be 1, in2 must be false, out1 is true
- IPC_SYNC_MESSAGE_CONTROL2_1(Msg_C_2_1, int, bool, bool)
-
- // in1 must be false, in2 must be 2, out1 is true, out2 is 22
- IPC_SYNC_MESSAGE_CONTROL2_2(Msg_C_2_2, bool, int, bool, int)
-
- // in1 must be 3, in2 must be true, out1 is "2_3", out2 is 23, out3 is false
- IPC_SYNC_MESSAGE_CONTROL2_3(Msg_C_2_3, int, bool, std::string, int, bool)
-
- // in1 must be 1, in2 must be false, in3 must be "3_1", out1 is true
- IPC_SYNC_MESSAGE_CONTROL3_1(Msg_C_3_1, int, bool, std::string, bool)
-
- // in1 must be "3_3", in2 must be false, in3 must be 2, out1 is true, out2 is
- // 32
- IPC_SYNC_MESSAGE_CONTROL3_2(Msg_C_3_2, std::string, bool, int, bool, int)
-
- // in1 must be 3, in2 must be "3_3", in3 must be true, out1 is "3_3", out2 is
- // 33, out3 is false
- IPC_SYNC_MESSAGE_CONTROL3_3(Msg_C_3_3, int, std::string, bool, std::string,
- int, bool)
-
-
- // NOTE: routed messages are just a copy of the above...
-
- // out1 is false
- IPC_SYNC_MESSAGE_ROUTED0_1(Msg_R_0_1, bool)
-
- // out1 is true, out2 is 2
- IPC_SYNC_MESSAGE_ROUTED0_2(Msg_R_0_2, bool, int)
-
- // out1 is false, out2 is 3, out3 is "0_3"
- IPC_SYNC_MESSAGE_ROUTED0_3(Msg_R_0_3, bool, int, std::string)
-
- // in1 must be 1, out1 is true
- IPC_SYNC_MESSAGE_ROUTED1_1(Msg_R_1_1, int, bool)
-
- // in1 must be false, out1 is true, out2 is 12
- IPC_SYNC_MESSAGE_ROUTED1_2(Msg_R_1_2, bool, bool, int)
-
- // in1 must be 3, out1 is "1_3", out2 is 13, out3 is false
- IPC_SYNC_MESSAGE_ROUTED1_3(Msg_R_1_3, int, std::string, int, bool)
-
- // in1 must be 1, in2 must be false, out1 is true
- IPC_SYNC_MESSAGE_ROUTED2_1(Msg_R_2_1, int, bool, bool)
-
- // in1 must be false, in2 must be 2, out1 is true, out2 is 22
- IPC_SYNC_MESSAGE_ROUTED2_2(Msg_R_2_2, bool, int, bool, int)
-
- // in1 must be 3, in2 must be true, out1 is "2_3", out2 is 23, out3 is false
- IPC_SYNC_MESSAGE_ROUTED2_3(Msg_R_2_3, int, bool, std::string, int, bool)
-
- // in1 must be 1, in2 must be false, in3 must be "3_1", out1 is true
- IPC_SYNC_MESSAGE_ROUTED3_1(Msg_R_3_1, int, bool, std::string, bool)
-
- // in1 must be "3_3", in2 must be false, in3 must be 2, out1 is true, out2
- // is 32
- IPC_SYNC_MESSAGE_ROUTED3_2(Msg_R_3_2, std::string, bool, int, bool, int)
-
- // in1 must be 3, in2 must be "3_3", in3 must be true, out1 is "3_3", out2 is
- // 33, out3 is false
- IPC_SYNC_MESSAGE_ROUTED3_3(Msg_R_3_3, int, std::string, bool, std::string,
- int, bool)
-
-IPC_END_MESSAGES(TestMsg)
diff --git a/ipc/ipc_test_sink.cc b/ipc/ipc_test_sink.cc
deleted file mode 100644
index 1f1ce3f..0000000
--- a/ipc/ipc_test_sink.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2009 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 "ipc/ipc_test_sink.h"
-
-namespace IPC {
-
-TestSink::TestSink() {
-}
-
-TestSink::~TestSink() {
-}
-
-void TestSink::OnMessageReceived(const Message& msg) {
- messages_.push_back(Message(msg));
-}
-
-void TestSink::ClearMessages() {
- messages_.clear();
-}
-
-const Message* TestSink::GetMessageAt(size_t index) const {
- if (index >= messages_.size())
- return NULL;
- return &messages_[index];
-}
-
-const Message* TestSink::GetFirstMessageMatching(uint16 id) const {
- for (size_t i = 0; i < messages_.size(); i++) {
- if (messages_[i].type() == id)
- return &messages_[i];
- }
- return NULL;
-}
-
-const Message* TestSink::GetUniqueMessageMatching(uint16 id) const {
- size_t found_index = 0;
- size_t found_count = 0;
- for (size_t i = 0; i < messages_.size(); i++) {
- if (messages_[i].type() == id) {
- found_count++;
- found_index = i;
- }
- }
- if (found_count != 1)
- return NULL; // Didn't find a unique one.
- return &messages_[found_index];
-}
-
-} // namespace IPC
diff --git a/ipc/ipc_test_sink.h b/ipc/ipc_test_sink.h
deleted file mode 100644
index 851ed8e..0000000
--- a/ipc/ipc_test_sink.h
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright (c) 2009 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 COMMON_IPC_TEST_SINK_H_
-#define COMMON_IPC_TEST_SINK_H_
-
-#include <utility>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "ipc/ipc_message.h"
-
-namespace IPC {
-
-// This test sink provides a "sink" for IPC messages that are sent. It allows
-// the caller to query messages received in various different ways. It is
-// designed for tests for objects that use the IPC system.
-//
-// Typical usage:
-//
-// test_sink.ClearMessages();
-// do_something();
-//
-// // We should have gotten exactly one update state message.
-// EXPECT_TRUE(test_sink.GetUniqeMessageMatching(ViewHostMsg_Update::ID));
-// // ...and no start load messages.
-// EXPECT_FALSE(test_sink.GetFirstMessageMatching(ViewHostMsg_Start::ID));
-//
-// // Now inspect a message. This assumes a message that was declared like
-// // this: IPC_MESSAGE_ROUTED2(ViewMsg_Foo, bool, int)
-// IPC::Message* msg = test_sink.GetFirstMessageMatching(ViewMsg_Foo::ID));
-// ASSERT_TRUE(msg);
-// bool first_param;
-// int second_param;
-// ViewMsg_Foo::Read(msg, &first_param, &second_param);
-//
-// // Go on to the next phase of the test.
-// test_sink.ClearMessages();
-//
-// To hook up the sink, all you need to do is call OnMessageReceived when a
-// message is recieved.
-class TestSink {
- public:
- TestSink();
- ~TestSink();
-
- // Used by the source of the messages to send the message to the sink. This
- // will make a copy of the message and store it in the list.
- void OnMessageReceived(const Message& msg);
-
- // Returns the number of messages in the queue.
- size_t message_count() const { return messages_.size(); }
-
- // Clears the message queue of saved messages.
- void ClearMessages();
-
- // Returns the message at the given index in the queue. The index may be out
- // of range, in which case the return value is NULL. The returned pointer will
- // only be valid until another message is received or the list is cleared.
- const Message* GetMessageAt(size_t index) const;
-
- // Returns the first message with the given ID in the queue. If there is no
- // message with the given ID, returns NULL. The returned pointer will only be
- // valid until another message is received or the list is cleared.
- const Message* GetFirstMessageMatching(uint16 id) const;
-
- // Returns the message with the given ID in the queue. If there is no such
- // message or there is more than one of that message, this will return NULL
- // (with the expectation that you'll do an ASSERT_TRUE() on the result).
- // The returned pointer will only be valid until another message is received
- // or the list is cleared.
- const Message* GetUniqueMessageMatching(uint16 id) const;
-
- private:
- // The actual list of received messages.
- std::vector<Message> messages_;
-
- DISALLOW_COPY_AND_ASSIGN(TestSink);
-};
-
-} // namespace IPC
-
-#endif // COMMON_IPC_TEST_SINK_H_
diff --git a/ipc/ipc_tests.cc b/ipc/ipc_tests.cc
deleted file mode 100644
index 506b888..0000000
--- a/ipc/ipc_tests.cc
+++ /dev/null
@@ -1,480 +0,0 @@
-// Copyright (c) 2006-2008 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 "build/build_config.h"
-
-#if defined(OS_WIN)
-#include <windows.h>
-#elif defined(OS_POSIX)
-#include <sys/types.h>
-#include <unistd.h>
-#endif
-
-#include <stdio.h>
-#include <iostream>
-#include <string>
-
-#include "ipc/ipc_tests.h"
-
-#include "base/at_exit.h"
-#include "base/base_switches.h"
-#include "base/command_line.h"
-#include "base/debug_on_start.h"
-#include "base/perftimer.h"
-#include "base/perf_test_suite.h"
-#include "base/test_suite.h"
-#include "base/thread.h"
-#include "ipc/ipc_channel.h"
-#include "ipc/ipc_channel_proxy.h"
-#include "ipc/ipc_message_utils.h"
-#include "testing/multiprocess_func_list.h"
-
-// Define to enable IPC performance testing instead of the regular unit tests
-// #define PERFORMANCE_TEST
-
-const wchar_t kTestClientChannel[] = L"T1";
-const wchar_t kReflectorChannel[] = L"T2";
-const wchar_t kFuzzerChannel[] = L"F3";
-
-const size_t kLongMessageStringNumBytes = 50000;
-
-#ifndef PERFORMANCE_TEST
-
-void IPCChannelTest::SetUp() {
- MultiProcessTest::SetUp();
-
- // Construct a fresh IO Message loop for the duration of each test.
- message_loop_ = new MessageLoopForIO();
-}
-
-void IPCChannelTest::TearDown() {
- delete message_loop_;
- message_loop_ = NULL;
-
- MultiProcessTest::TearDown();
-}
-
-#if defined(OS_WIN)
-base::ProcessHandle IPCChannelTest::SpawnChild(ChildType child_type,
- IPC::Channel *channel) {
- // kDebugChildren support.
- bool debug_on_start =
- CommandLine::ForCurrentProcess()->HasSwitch(switches::kDebugChildren);
-
- switch (child_type) {
- case TEST_CLIENT:
- return MultiProcessTest::SpawnChild(L"RunTestClient", debug_on_start);
- break;
- case TEST_REFLECTOR:
- return MultiProcessTest::SpawnChild(L"RunReflector", debug_on_start);
- break;
- case FUZZER_SERVER:
- return MultiProcessTest::SpawnChild(L"RunFuzzServer", debug_on_start);
- break;
- default:
- return NULL;
- break;
- }
-}
-#elif defined(OS_POSIX)
-base::ProcessHandle IPCChannelTest::SpawnChild(ChildType child_type,
- IPC::Channel *channel) {
- // kDebugChildren support.
- bool debug_on_start =
- CommandLine::ForCurrentProcess()->HasSwitch(switches::kDebugChildren);
-
- base::file_handle_mapping_vector fds_to_map;
- int src_fd;
- int dest_fd;
- channel->GetClientFileDescriptorMapping(&src_fd, &dest_fd);
- if (src_fd > -1) {
- fds_to_map.push_back(std::pair<int,int>(src_fd, dest_fd));
- }
-
- base::ProcessHandle ret = NULL;
- switch (child_type) {
- case TEST_CLIENT:
- ret = MultiProcessTest::SpawnChild(L"RunTestClient",
- fds_to_map,
- debug_on_start);
- channel->OnClientConnected();
- break;
- case TEST_DESCRIPTOR_CLIENT:
- ret = MultiProcessTest::SpawnChild(L"RunTestDescriptorClient",
- fds_to_map,
- debug_on_start);
- channel->OnClientConnected();
- break;
- case TEST_DESCRIPTOR_CLIENT_SANDBOXED:
- ret = MultiProcessTest::SpawnChild(L"RunTestDescriptorClientSandboxed",
- fds_to_map,
- debug_on_start);
- channel->OnClientConnected();
- break;
- case TEST_REFLECTOR:
- ret = MultiProcessTest::SpawnChild(L"RunReflector",
- fds_to_map,
- debug_on_start);
- channel->OnClientConnected();
- break;
- case FUZZER_SERVER:
- ret = MultiProcessTest::SpawnChild(L"RunFuzzServer",
- fds_to_map,
- debug_on_start);
- channel->OnClientConnected();
- break;
- default:
- return NULL;
- break;
- }
- return ret;
-}
-#endif // defined(OS_POSIX)
-
-TEST_F(IPCChannelTest, BasicMessageTest) {
- int v1 = 10;
- std::string v2("foobar");
- std::wstring v3(L"hello world");
-
- IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
- EXPECT_TRUE(m.WriteInt(v1));
- EXPECT_TRUE(m.WriteString(v2));
- EXPECT_TRUE(m.WriteWString(v3));
-
- void* iter = NULL;
-
- int vi;
- std::string vs;
- std::wstring vw;
-
- EXPECT_TRUE(m.ReadInt(&iter, &vi));
- EXPECT_EQ(v1, vi);
-
- EXPECT_TRUE(m.ReadString(&iter, &vs));
- EXPECT_EQ(v2, vs);
-
- EXPECT_TRUE(m.ReadWString(&iter, &vw));
- EXPECT_EQ(v3, vw);
-
- // should fail
- EXPECT_FALSE(m.ReadInt(&iter, &vi));
- EXPECT_FALSE(m.ReadString(&iter, &vs));
- EXPECT_FALSE(m.ReadWString(&iter, &vw));
-}
-
-static void Send(IPC::Message::Sender* sender, const char* text) {
- static int message_index = 0;
-
- IPC::Message* message = new IPC::Message(0,
- 2,
- IPC::Message::PRIORITY_NORMAL);
- message->WriteInt(message_index++);
- message->WriteString(std::string(text));
-
- // Make sure we can handle large messages.
- char junk[kLongMessageStringNumBytes];
- memset(junk, 'a', sizeof(junk)-1);
- junk[sizeof(junk)-1] = 0;
- message->WriteString(std::string(junk));
-
- // DEBUG: printf("[%u] sending message [%s]\n", GetCurrentProcessId(), text);
- sender->Send(message);
-}
-
-class MyChannelListener : public IPC::Channel::Listener {
- public:
- virtual void OnMessageReceived(const IPC::Message& message) {
- IPC::MessageIterator iter(message);
-
- iter.NextInt();
- const std::string data = iter.NextString();
- const std::string big_string = iter.NextString();
- EXPECT_EQ(kLongMessageStringNumBytes - 1, big_string.length());
-
-
- if (--messages_left_ == 0) {
- MessageLoop::current()->Quit();
- } else {
- Send(sender_, "Foo");
- }
- }
-
- virtual void OnChannelError() {
- // There is a race when closing the channel so the last message may be lost.
- EXPECT_LE(messages_left_, 1);
- MessageLoop::current()->Quit();
- }
-
- void Init(IPC::Message::Sender* s) {
- sender_ = s;
- messages_left_ = 50;
- }
-
- private:
- IPC::Message::Sender* sender_;
- int messages_left_;
-};
-
-TEST_F(IPCChannelTest, ChannelTest) {
- MyChannelListener channel_listener;
- // Setup IPC channel.
- IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_SERVER,
- &channel_listener);
- chan.Connect();
-
- channel_listener.Init(&chan);
-
- base::ProcessHandle process_handle = SpawnChild(TEST_CLIENT, &chan);
- ASSERT_TRUE(process_handle);
-
- Send(&chan, "hello from parent");
-
- // Run message loop.
- MessageLoop::current()->Run();
-
- // Close Channel so client gets its OnChannelError() callback fired.
- chan.Close();
-
- // Cleanup child process.
- EXPECT_TRUE(base::WaitForSingleProcess(process_handle, 5000));
- base::CloseProcessHandle(process_handle);
-}
-
-TEST_F(IPCChannelTest, ChannelProxyTest) {
- MyChannelListener channel_listener;
-
- // The thread needs to out-live the ChannelProxy.
- base::Thread thread("ChannelProxyTestServer");
- base::Thread::Options options;
- options.message_loop_type = MessageLoop::TYPE_IO;
- thread.StartWithOptions(options);
- {
- // setup IPC channel proxy
- IPC::ChannelProxy chan(kTestClientChannel, IPC::Channel::MODE_SERVER,
- &channel_listener, NULL, thread.message_loop());
-
- channel_listener.Init(&chan);
-
-#if defined(OS_WIN)
- base::ProcessHandle process_handle = SpawnChild(TEST_CLIENT, NULL);
-#elif defined(OS_POSIX)
- bool debug_on_start = CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDebugChildren);
- base::file_handle_mapping_vector fds_to_map;
- int src_fd;
- int dest_fd;
- chan.GetClientFileDescriptorMapping(&src_fd, &dest_fd);
- if (src_fd > -1) {
- fds_to_map.push_back(std::pair<int,int>(src_fd, dest_fd));
- }
-
- base::ProcessHandle process_handle = MultiProcessTest::SpawnChild(
- L"RunTestClient",
- fds_to_map,
- debug_on_start);
- chan.OnClientConnected();
-#endif // defined(OS_POXIX)
-
- ASSERT_TRUE(process_handle);
-
- Send(&chan, "hello from parent");
-
- // run message loop
- MessageLoop::current()->Run();
-
- // cleanup child process
- EXPECT_TRUE(base::WaitForSingleProcess(process_handle, 5000));
- base::CloseProcessHandle(process_handle);
- }
- thread.Stop();
-}
-
-MULTIPROCESS_TEST_MAIN(RunTestClient) {
- MessageLoopForIO main_message_loop;
- MyChannelListener channel_listener;
-
- // setup IPC channel
- IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_CLIENT,
- &channel_listener);
- chan.Connect();
- channel_listener.Init(&chan);
- Send(&chan, "hello from child");
- // run message loop
- MessageLoop::current()->Run();
- // return true;
- return NULL;
-}
-
-#endif // !PERFORMANCE_TEST
-
-#ifdef PERFORMANCE_TEST
-
-//-----------------------------------------------------------------------------
-// Manually performance test
-//
-// This test times the roundtrip IPC message cycle. It is enabled with a
-// special preprocessor define to enable it instead of the standard IPC
-// unit tests. This works around some funny termination conditions in the
-// regular unit tests.
-//
-// This test is not automated. To test, you will want to vary the message
-// count and message size in TEST to get the numbers you want.
-//
-// FIXME(brettw): Automate this test and have it run by default.
-
-// This channel listener just replies to all messages with the exact same
-// message. It assumes each message has one string parameter. When the string
-// "quit" is sent, it will exit.
-class ChannelReflectorListener : public IPC::Channel::Listener {
- public:
- explicit ChannelReflectorListener(IPC::Channel *channel) :
- channel_(channel),
- count_messages_(0),
- latency_messages_(0) {
- std::cout << "Reflector up" << std::endl;
- }
-
- ~ChannelReflectorListener() {
- std::cout << "Client Messages: " << count_messages_ << std::endl;
- std::cout << "Client Latency: " << latency_messages_ << std::endl;
- }
-
- virtual void OnMessageReceived(const IPC::Message& message) {
- count_messages_++;
- IPC::MessageIterator iter(message);
- int time = iter.NextInt();
- int msgid = iter.NextInt();
- std::string payload = iter.NextString();
- latency_messages_ += GetTickCount() - time;
-
- // cout << "reflector msg received: " << msgid << endl;
- if (payload == "quit")
- MessageLoop::current()->Quit();
-
- IPC::Message* msg = new IPC::Message(0,
- 2,
- IPC::Message::PRIORITY_NORMAL);
- msg->WriteInt(GetTickCount());
- msg->WriteInt(msgid);
- msg->WriteString(payload);
- channel_->Send(msg);
- }
- private:
- IPC::Channel *channel_;
- int count_messages_;
- int latency_messages_;
-};
-
-class ChannelPerfListener : public IPC::Channel::Listener {
- public:
- ChannelPerfListener(IPC::Channel* channel, int msg_count, int msg_size) :
- count_down_(msg_count),
- channel_(channel),
- count_messages_(0),
- latency_messages_(0) {
- payload_.resize(msg_size);
- for (int i = 0; i < static_cast<int>(payload_.size()); i++)
- payload_[i] = 'a';
- std::cout << "perflistener up" << std::endl;
- }
-
- ~ChannelPerfListener() {
- std::cout << "Server Messages: " << count_messages_ << std::endl;
- std::cout << "Server Latency: " << latency_messages_ << std::endl;
- }
-
- virtual void OnMessageReceived(const IPC::Message& message) {
- count_messages_++;
- // decode the string so this gets counted in the total time
- IPC::MessageIterator iter(message);
- int time = iter.NextInt();
- int msgid = iter.NextInt();
- std::string cur = iter.NextString();
- latency_messages_ += GetTickCount() - time;
-
- // cout << "perflistener got message" << endl;
-
- count_down_--;
- if (count_down_ == 0) {
- IPC::Message* msg = new IPC::Message(0,
- 2,
- IPC::Message::PRIORITY_NORMAL);
- msg->WriteInt(GetTickCount());
- msg->WriteInt(count_down_);
- msg->WriteString("quit");
- channel_->Send(msg);
- SetTimer(NULL, 1, 250, (TIMERPROC) PostQuitMessage);
- return;
- }
-
- IPC::Message* msg = new IPC::Message(0,
- 2,
- IPC::Message::PRIORITY_NORMAL);
- msg->WriteInt(GetTickCount());
- msg->WriteInt(count_down_);
- msg->WriteString(payload_);
- channel_->Send(msg);
- }
-
- private:
- int count_down_;
- std::string payload_;
- IPC::Channel *channel_;
- int count_messages_;
- int latency_messages_;
-};
-
-TEST_F(IPCChannelTest, Performance) {
- // setup IPC channel
- IPC::Channel chan(kReflectorChannel, IPC::Channel::MODE_SERVER, NULL);
- ChannelPerfListener perf_listener(&chan, 10000, 100000);
- chan.set_listener(&perf_listener);
- chan.Connect();
-
- HANDLE process = SpawnChild(TEST_REFLECTOR, &chan);
- ASSERT_TRUE(process);
-
- Sleep(1000);
-
- PerfTimeLogger logger("IPC_Perf");
-
- // this initial message will kick-start the ping-pong of messages
- IPC::Message* message = new IPC::Message(0,
- 2,
- IPC::Message::PRIORITY_NORMAL);
- message->WriteInt(GetTickCount());
- message->WriteInt(-1);
- message->WriteString("Hello");
- chan.Send(message);
-
- // run message loop
- MessageLoop::current()->Run();
-
- // cleanup child process
- WaitForSingleObject(process, 5000);
- CloseHandle(process);
-}
-
-// This message loop bounces all messages back to the sender
-MULTIPROCESS_TEST_MAIN(RunReflector) {
- MessageLoopForIO main_message_loop;
- IPC::Channel chan(kReflectorChannel, IPC::Channel::MODE_CLIENT, NULL);
- ChannelReflectorListener channel_reflector_listener(&chan);
- chan.set_listener(&channel_reflector_listener);
- chan.Connect();
-
- MessageLoop::current()->Run();
- return true;
-}
-
-#endif // PERFORMANCE_TEST
-
-int main(int argc, char** argv) {
-#ifdef PERFORMANCE_TEST
- int retval = PerfTestSuite(argc, argv).Run();
-#else
- int retval = TestSuite(argc, argv).Run();
-#endif
- return retval;
-}
diff --git a/ipc/ipc_tests.h b/ipc/ipc_tests.h
deleted file mode 100644
index 5005eb3..0000000
--- a/ipc/ipc_tests.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2006-2008 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 COMMON_IPC_TESTS_H__
-#define COMMON_IPC_TESTS_H__
-
-#include "base/multiprocess_test.h"
-#include "base/process.h"
-
-// This unit test uses 3 types of child processes, a regular pipe client,
-// a client reflector and a IPC server used for fuzzing tests.
-enum ChildType {
- TEST_CLIENT,
- TEST_DESCRIPTOR_CLIENT,
- TEST_DESCRIPTOR_CLIENT_SANDBOXED,
- TEST_REFLECTOR,
- FUZZER_SERVER
-};
-
-// The different channel names for the child processes.
-extern const wchar_t kTestClientChannel[];
-extern const wchar_t kReflectorChannel[];
-extern const wchar_t kFuzzerChannel[];
-
-class MessageLoopForIO;
-namespace IPC {
-class Channel;
-} // namespace IPC
-
-//Base class to facilitate Spawning IPC Client processes.
-class IPCChannelTest : public MultiProcessTest {
- protected:
-
- // Create a new MessageLoopForIO For each test.
- virtual void SetUp();
- virtual void TearDown();
-
- // Spawns a child process of the specified type
- base::ProcessHandle SpawnChild(ChildType child_type,
- IPC::Channel *channel);
-
- // Created around each test instantiation.
- MessageLoopForIO *message_loop_;
-};
-
-#endif // COMMON_IPC_TESTS_H__