diff options
author | jeremy@chromium.org <jeremy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-12-10 22:28:11 +0000 |
---|---|---|
committer | jeremy@chromium.org <jeremy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-12-10 22:28:11 +0000 |
commit | 514411fcb4657f575eeb3e39a9056478a28306a0 (patch) | |
tree | be2bcacf0d4cffd91ceded1f4e03bc3d6ae3d6e6 /chrome/common | |
parent | f20b9e922a26e045af6bc7a5c3c46d78abb04aac (diff) | |
download | chromium_src-514411fcb4657f575eeb3e39a9056478a28306a0.zip chromium_src-514411fcb4657f575eeb3e39a9056478a28306a0.tar.gz chromium_src-514411fcb4657f575eeb3e39a9056478a28306a0.tar.bz2 |
Refactor IPC::Channel to have a common header.
Review URL: http://codereview.chromium.org/11024
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@6743 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/common')
-rw-r--r-- | chrome/common/common.scons | 2 | ||||
-rw-r--r-- | chrome/common/common.vcproj | 2 | ||||
-rw-r--r-- | chrome/common/ipc_channel.h | 111 | ||||
-rw-r--r-- | chrome/common/ipc_channel_posix.cc | 71 | ||||
-rw-r--r-- | chrome/common/ipc_channel_posix.h | 93 | ||||
-rw-r--r-- | chrome/common/ipc_channel_proxy.h | 2 | ||||
-rw-r--r-- | chrome/common/ipc_channel_win.cc (renamed from chrome/common/ipc_channel.cc) | 82 | ||||
-rw-r--r-- | chrome/common/ipc_channel_win.h | 81 | ||||
-rw-r--r-- | chrome/common/ipc_fuzzing_tests.cc | 4 | ||||
-rw-r--r-- | chrome/common/resource_dispatcher.cc | 1 | ||||
-rw-r--r-- | chrome/common/resource_dispatcher.h | 2 |
11 files changed, 295 insertions, 156 deletions
diff --git a/chrome/common/common.scons b/chrome/common/common.scons index 0116edf..5f4d8fa 100644 --- a/chrome/common/common.scons +++ b/chrome/common/common.scons @@ -90,7 +90,7 @@ if env['PLATFORM'] == 'win32': 'gfx/icon_util.cc', 'gfx/path.cc', 'gfx/text_elider.cc', - 'ipc_channel.cc', + 'ipc_channel_win.cc', 'ipc_channel_proxy.cc', 'ipc_logging.cc', 'ipc_message_utils.cc', diff --git a/chrome/common/common.vcproj b/chrome/common/common.vcproj index 7293656..e1331e0 100644 --- a/chrome/common/common.vcproj +++ b/chrome/common/common.vcproj @@ -221,7 +221,7 @@ Name="ipc"
>
<File
- RelativePath=".\ipc_channel.cc"
+ RelativePath=".\ipc_channel_win.cc"
>
</File>
<File
diff --git a/chrome/common/ipc_channel.h b/chrome/common/ipc_channel.h index ac234b8..bd7bf05 100644 --- a/chrome/common/ipc_channel.h +++ b/chrome/common/ipc_channel.h @@ -5,22 +5,13 @@ #ifndef CHROME_COMMON_IPC_CHANNEL_H_ #define CHROME_COMMON_IPC_CHANNEL_H_ -#include <queue> - -#include "base/message_loop.h" #include "chrome/common/ipc_message.h" namespace IPC { //------------------------------------------------------------------------------ -class Channel : public Message::Sender, -#if defined(OS_WIN) - public MessageLoopForIO::IOHandler -#elif defined(OS_POSIX) - public MessageLoopForIO::FileWatcher -#endif - { +class Channel : public Message::Sender { // Security tests need access to the pipe handle. friend class ChannelTest; @@ -47,10 +38,13 @@ class Channel : public Message::Sender, MODE_CLIENT }; - // The maximum message size in bytes. Attempting to receive a - // message of this size or bigger results in a channel error. enum { - kMaximumMessageSize = 256 * 1024 * 1024 + // 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. @@ -65,7 +59,7 @@ class Channel : public Message::Sender, // Channel(const std::wstring& channel_id, Mode mode, Listener* listener); - ~Channel() { Close(); } + ~Channel(); // Connect the pipe. On the server side, this will initiate // waiting for connections. On the client, it attempts to @@ -78,7 +72,7 @@ class Channel : public Message::Sender, void Close(); // Modify the Channel's listener. - void set_listener(Listener* listener) { listener_ = listener; } + void set_listener(Listener* listener); // Send a message over the Channel to the listener on the other end. // @@ -92,87 +86,9 @@ class Channel : public Message::Sender, virtual bool Send(Message* message); private: - const std::wstring PipeName(const std::wstring& channel_id) const; - bool CreatePipe(const std::wstring& channel_id, Mode mode); -#if defined(OS_WIN) - 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: - enum { - BUF_SIZE = 4096 - }; - - struct State { - explicit State(Channel* channel); - ~State(); - MessageLoopForIO::IOContext context; - bool is_pending; - }; - - State input_state_; - State output_state_; - - HANDLE pipe_; -#elif defined(OS_POSIX) - bool ProcessIncomingMessages(); - bool ProcessOutgoingMessages(); - - void OnFileReadReady(int fd); - void OnFileWriteReady(int fd); - - - Mode mode_; - - // TODO(playmobil): do we need to change BUF_SIZE ? - private: - enum { - BUF_SIZE = 4096 - }; - - // PIMPL to encapsulate libevent structures. - struct EventHolder; - EventHolder *server_listen_connection_event_; - EventHolder *read_event_; - EventHolder *write_event_; - - // If sending a message blocks then we use this variable - // to keep track of where we are. - size_t message_send_bytes_written_; - - int server_listen_pipe_; - int pipe_; - std::string pipe_name_; -#endif // defined(OS_POSIX) - 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_[BUF_SIZE]; - - // 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<Channel> factory_; + // 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 @@ -186,7 +102,6 @@ class Channel : public Message::Sender, }; }; -} +} // namespace IPC #endif // CHROME_COMMON_IPC_CHANNEL_H_ - diff --git a/chrome/common/ipc_channel_posix.cc b/chrome/common/ipc_channel_posix.cc index 092e8a1..45573ae 100644 --- a/chrome/common/ipc_channel_posix.cc +++ b/chrome/common/ipc_channel_posix.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/common/ipc_channel.h" +#include "chrome/common/ipc_channel_posix.h" #include <fcntl.h> #include <sys/types.h> @@ -17,7 +17,6 @@ #include "base/string_util.h" #include "chrome/common/chrome_counters.h" #include "chrome/common/ipc_message_utils.h" -#include "third_party/libevent/event.h" namespace IPC { @@ -140,25 +139,10 @@ bool ClientConnectToFifo(const std::string &pipe_name, int* client_socket) { } } // namespace - //------------------------------------------------------------------------------ -// PIMPL wrapper for libevent event. -// TODO(playmobil): MessageLoopForIO needs to better encapsulate libevent. -struct Channel::EventHolder { - EventHolder() : is_active(false) {} - ~EventHolder() {} - - bool is_active; - - // libevent's set functions set all the needed members of this struct, so no - // need to initialize before use. - struct event event; -}; - -//------------------------------------------------------------------------------ - -Channel::Channel(const std::wstring& channel_id, Mode mode, Listener* listener) +Channel::ChannelImpl::ChannelImpl(const std::wstring& channel_id, Mode mode, + Listener* listener) : mode_(mode), server_listen_connection_event_(new EventHolder()), read_event_(new EventHolder()), @@ -178,7 +162,8 @@ Channel::Channel(const std::wstring& channel_id, Mode mode, Listener* listener) } } -const std::wstring Channel::PipeName(const std::wstring& channel_id) const { +const std::wstring Channel::ChannelImpl::PipeName( + const std::wstring& channel_id) const { std::wostringstream ss; // TODO(playmobil): This should live in the Chrome user data directory. // TODO(playmobil): Cleanup any stale fifos. @@ -186,7 +171,8 @@ const std::wstring Channel::PipeName(const std::wstring& channel_id) const { return ss.str(); } -bool Channel::CreatePipe(const std::wstring& channel_id, Mode mode) { +bool Channel::ChannelImpl::CreatePipe(const std::wstring& channel_id, + Mode mode) { DCHECK(server_listen_pipe_ == -1 && pipe_ == -1); // TODO(playmobil): Should we just change pipe_name to be a normal string @@ -217,7 +203,7 @@ bool Channel::CreatePipe(const std::wstring& channel_id, Mode mode) { return true; } -bool Channel::Connect() { +bool Channel::ChannelImpl::Connect() { if (mode_ == MODE_SERVER) { if (server_listen_pipe_ == -1) { return false; @@ -245,7 +231,7 @@ bool Channel::Connect() { return true; } -bool Channel::ProcessIncomingMessages() { +bool Channel::ChannelImpl::ProcessIncomingMessages() { ssize_t bytes_read = 0; for (;;) { @@ -257,7 +243,7 @@ bool Channel::ProcessIncomingMessages() { // recv() returns 0 if the connection has closed or EAGAIN if no data is // waiting on the pipe. do { - bytes_read = read(pipe_, input_buf_, BUF_SIZE); + bytes_read = read(pipe_, input_buf_, Channel::kReadBufferSize); } while (bytes_read == -1 && errno == EINTR); if (bytes_read < 0) { if (errno == EAGAIN) { @@ -322,7 +308,7 @@ bool Channel::ProcessIncomingMessages() { return true; } -bool Channel::ProcessOutgoingMessages() { +bool Channel::ChannelImpl::ProcessOutgoingMessages() { DCHECK(!waiting_connect_); // Why are we trying to send messages if there's // no connection? @@ -384,7 +370,7 @@ bool Channel::ProcessOutgoingMessages() { return true; } -bool Channel::Send(Message* message) { +bool Channel::ChannelImpl::Send(Message* message) { chrome::Counters::ipc_send_counter().Increment(); #ifdef IPC_MESSAGE_DEBUG_EXTRA DLOG(INFO) << "sending message @" << message << " on channel @" << this @@ -409,7 +395,7 @@ bool Channel::Send(Message* message) { } // Called by libevent when we can read from th pipe without blocking. -void Channel::OnFileReadReady(int fd) { +void Channel::ChannelImpl::OnFileReadReady(int fd) { bool send_server_hello_msg = false; if (waiting_connect_ && mode_ == MODE_SERVER) { if (!ServerAcceptFifoConnection(server_listen_pipe_, &pipe_)) { @@ -449,14 +435,14 @@ void Channel::OnFileReadReady(int fd) { } // Called by libevent when we can write to the pipe without blocking. -void Channel::OnFileWriteReady(int fd) { +void Channel::ChannelImpl::OnFileWriteReady(int fd) { if (!ProcessOutgoingMessages()) { Close(); listener_->OnChannelError(); } } -void Channel::Close() { +void Channel::ChannelImpl::Close() { // Close can be called multiple time, so we need to make sure we're // idempotent. @@ -501,4 +487,31 @@ void Channel::Close() { } } +//------------------------------------------------------------------------------ +// 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/chrome/common/ipc_channel_posix.h b/chrome/common/ipc_channel_posix.h new file mode 100644 index 0000000..b2849dc --- /dev/null +++ b/chrome/common/ipc_channel_posix.h @@ -0,0 +1,93 @@ +// 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 CHROME_COMMON_IPC_CHANNEL_POSIX_H_ +#define CHROME_COMMON_IPC_CHANNEL_POSIX_H_ + +#include "chrome/common/ipc_channel.h" + +#include <queue> +#include <string> + +#include "base/message_loop.h" +#include "third_party/libevent/event.h" + +namespace IPC { + +class Channel::ChannelImpl : public MessageLoopForIO::FileWatcher { + 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 ProcessIncomingMessages(); + bool ProcessOutgoingMessages(); + + void OnFileReadReady(int fd); + void OnFileWriteReady(int fd); + + Mode mode_; + + // Wrapper for Libevent event. + // TODO(playmobil): MessageLoopForIO needs to better encapsulate libevent. + struct EventHolder { + EventHolder() : is_active(false) {} + ~EventHolder() {} + + bool is_active; + + // libevent's set functions set all the needed members of this struct, so no + // need to initialize before use. + struct event event; + }; + + EventHolder *server_listen_connection_event_; + EventHolder *read_event_; + EventHolder *write_event_; + + // If sending a message blocks then we use this variable + // to keep track of where we are. + size_t message_send_bytes_written_; + + int server_listen_pipe_; + int pipe_; + 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]; + + // 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_; + + DISALLOW_COPY_AND_ASSIGN(ChannelImpl); +}; + +} // namespace IPC + +#endif // CHROME_COMMON_IPC_CHANNEL_POSIX_H_ diff --git a/chrome/common/ipc_channel_proxy.h b/chrome/common/ipc_channel_proxy.h index 2b08c09..0b88cb7 100644 --- a/chrome/common/ipc_channel_proxy.h +++ b/chrome/common/ipc_channel_proxy.h @@ -10,6 +10,8 @@ #include "base/ref_counted.h" #include "chrome/common/ipc_channel.h" +class MessageLoop; + namespace IPC { //----------------------------------------------------------------------------- diff --git a/chrome/common/ipc_channel.cc b/chrome/common/ipc_channel_win.cc index 4ffadc3..a38305a 100644 --- a/chrome/common/ipc_channel.cc +++ b/chrome/common/ipc_channel_win.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/common/ipc_channel.h" +#include "chrome/common/ipc_channel_win.h" #include <windows.h> #include <sstream> @@ -14,24 +14,23 @@ #include "chrome/common/ipc_logging.h" #include "chrome/common/ipc_message_utils.h" -using namespace std; - namespace IPC { - //------------------------------------------------------------------------------ -Channel::State::State(Channel* channel) : is_pending(false) { +Channel::ChannelImpl::State::State(ChannelImpl* channel) : is_pending(false) { memset(&context.overlapped, 0, sizeof(context.overlapped)); context.handler = channel; } -Channel::State::~State() { - COMPILE_ASSERT(!offsetof(Channel::State, context), starts_with_io_context); +Channel::ChannelImpl::State::~State() { + COMPILE_ASSERT(!offsetof(Channel::ChannelImpl::State, context), + starts_with_io_context); } //------------------------------------------------------------------------------ -Channel::Channel(const wstring& channel_id, Mode mode, Listener* listener) +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), @@ -46,7 +45,7 @@ Channel::Channel(const wstring& channel_id, Mode mode, Listener* listener) } } -void Channel::Close() { +void Channel::ChannelImpl::Close() { bool waited = false; if (input_state_.is_pending || output_state_.is_pending) { CancelIo(pipe_); @@ -77,7 +76,7 @@ void Channel::Close() { } } -bool Channel::Send(Message* message) { +bool Channel::ChannelImpl::Send(Message* message) { chrome::Counters::ipc_send_counter().Increment(); #ifdef IPC_MESSAGE_DEBUG_EXTRA DLOG(INFO) << "sending message @" << message << " on channel @" << this @@ -101,16 +100,18 @@ bool Channel::Send(Message* message) { return true; } -const wstring Channel::PipeName(const wstring& channel_id) const { - wostringstream ss; +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::CreatePipe(const wstring& channel_id, Mode mode) { +bool Channel::ChannelImpl::CreatePipe(const std::wstring& channel_id, + Mode mode) { DCHECK(pipe_ == INVALID_HANDLE_VALUE); - const wstring pipe_name = PipeName(channel_id); + const std::wstring pipe_name = PipeName(channel_id); if (mode == MODE_SERVER) { SECURITY_ATTRIBUTES security_attributes = {0}; security_attributes.bInheritHandle = FALSE; @@ -126,8 +127,10 @@ bool Channel::CreatePipe(const wstring& channel_id, Mode mode) { FILE_FLAG_FIRST_PIPE_INSTANCE, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, 1, // number of pipe instances - BUF_SIZE, // output buffer size (XXX tune) - BUF_SIZE, // input buffer size (XXX tune) + // 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); @@ -161,7 +164,7 @@ bool Channel::CreatePipe(const wstring& channel_id, Mode mode) { return true; } -bool Channel::Connect() { +bool Channel::ChannelImpl::Connect() { DLOG(WARNING) << "Connect called twice"; if (pipe_ == INVALID_HANDLE_VALUE) @@ -178,7 +181,7 @@ bool Channel::Connect() { // to true, we indicate to OnIOCompleted that this is the special // initialization signal. MessageLoopForIO::current()->PostTask(FROM_HERE, factory_.NewRunnableMethod( - &Channel::OnIOCompleted, &input_state_.context, 0, 0)); + &Channel::ChannelImpl::OnIOCompleted, &input_state_.context, 0, 0)); } if (!waiting_connect_) @@ -186,7 +189,7 @@ bool Channel::Connect() { return true; } -bool Channel::ProcessConnection() { +bool Channel::ChannelImpl::ProcessConnection() { if (input_state_.is_pending) input_state_.is_pending = false; @@ -219,8 +222,9 @@ bool Channel::ProcessConnection() { return true; } -bool Channel::ProcessIncomingMessages(MessageLoopForIO::IOContext* context, - DWORD bytes_read) { +bool Channel::ChannelImpl::ProcessIncomingMessages( + MessageLoopForIO::IOContext* context, + DWORD bytes_read) { if (input_state_.is_pending) { input_state_.is_pending = false; DCHECK(context); @@ -240,7 +244,7 @@ bool Channel::ProcessIncomingMessages(MessageLoopForIO::IOContext* context, // Read from pipe... BOOL ok = ReadFile(pipe_, input_buf_, - BUF_SIZE, + Channel::kReadBufferSize, &bytes_read, &input_state_.context.overlapped); if (!ok) { @@ -304,8 +308,9 @@ bool Channel::ProcessIncomingMessages(MessageLoopForIO::IOContext* context, return true; } -bool Channel::ProcessOutgoingMessages(MessageLoopForIO::IOContext* context, - DWORD bytes_written) { +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? @@ -362,7 +367,7 @@ bool Channel::ProcessOutgoingMessages(MessageLoopForIO::IOContext* context, return true; } -void Channel::OnIOCompleted(MessageLoopForIO::IOContext* context, +void Channel::ChannelImpl::OnIOCompleted(MessageLoopForIO::IOContext* context, DWORD bytes_transfered, DWORD error) { bool ok; if (context == &input_state_.context) { @@ -392,4 +397,31 @@ void Channel::OnIOCompleted(MessageLoopForIO::IOContext* context, } } +//------------------------------------------------------------------------------ +// 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/chrome/common/ipc_channel_win.h b/chrome/common/ipc_channel_win.h new file mode 100644 index 0000000..fcd8abe --- /dev/null +++ b/chrome/common/ipc_channel_win.h @@ -0,0 +1,81 @@ +// 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 CHROME_COMMON_IPC_CHANNEL_WIN_H_ +#define CHROME_COMMON_IPC_CHANNEL_WIN_H_ + +#include "chrome/common/ipc_channel.h" + +#include <queue> +#include <string> + +#include "base/message_loop.h" + +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_; + + DISALLOW_COPY_AND_ASSIGN(ChannelImpl); +}; + +} // namespace IPC + +#endif // CHROME_COMMON_IPC_CHANNEL_WIN_H_ diff --git a/chrome/common/ipc_fuzzing_tests.cc b/chrome/common/ipc_fuzzing_tests.cc index cec05fb..0c729f8 100644 --- a/chrome/common/ipc_fuzzing_tests.cc +++ b/chrome/common/ipc_fuzzing_tests.cc @@ -7,13 +7,13 @@ #include <string> #include <sstream> -#include "chrome/common/ipc_tests.h" - +#include "base/message_loop.h" #include "base/platform_thread.h" #include "base/process_util.h" #include "chrome/common/ipc_channel.h" #include "chrome/common/ipc_channel_proxy.h" #include "chrome/common/ipc_message_utils.h" +#include "chrome/common/ipc_tests.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/multiprocess_func_list.h" diff --git a/chrome/common/resource_dispatcher.cc b/chrome/common/resource_dispatcher.cc index d3c7a33..ecf58e6 100644 --- a/chrome/common/resource_dispatcher.cc +++ b/chrome/common/resource_dispatcher.cc @@ -7,6 +7,7 @@ #include "chrome/common/resource_dispatcher.h" #include "base/basictypes.h" +#include "base/message_loop.h" #include "base/shared_memory.h" #include "base/string_util.h" #include "chrome/common/render_messages.h" diff --git a/chrome/common/resource_dispatcher.h b/chrome/common/resource_dispatcher.h index c290e10..e948045 100644 --- a/chrome/common/resource_dispatcher.h +++ b/chrome/common/resource_dispatcher.h @@ -9,6 +9,8 @@ #include <windows.h> +#include <queue> + #include "base/hash_tables.h" #include "base/task.h" #include "chrome/common/ipc_channel.h" |