michael@0: // Copyright (c) 2008 The Chromium Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: michael@0: #ifndef CHROME_COMMON_IPC_CHANNEL_WIN_H_ michael@0: #define CHROME_COMMON_IPC_CHANNEL_WIN_H_ michael@0: michael@0: #include "chrome/common/ipc_channel.h" michael@0: michael@0: #include michael@0: #include michael@0: michael@0: #include "base/message_loop.h" michael@0: michael@0: class NonThreadSafe; michael@0: michael@0: namespace IPC { michael@0: michael@0: class Channel::ChannelImpl : public MessageLoopForIO::IOHandler { michael@0: public: michael@0: // Mirror methods of Channel, see ipc_channel.h for description. michael@0: ChannelImpl(const std::wstring& channel_id, Mode mode, Listener* listener); michael@0: ChannelImpl(const std::wstring& channel_id, HANDLE server_pipe, michael@0: Mode mode, Listener* listener); michael@0: ~ChannelImpl() { michael@0: if (pipe_ != INVALID_HANDLE_VALUE) { michael@0: Close(); michael@0: } michael@0: } michael@0: bool Connect(); michael@0: void Close(); michael@0: HANDLE GetServerPipeHandle() const; michael@0: Listener* set_listener(Listener* listener) { michael@0: Listener* old = listener_; michael@0: listener_ = listener; michael@0: return old; michael@0: } michael@0: bool Send(Message* message); michael@0: michael@0: // See the comment in ipc_channel.h for info on Unsound_IsClosed() and michael@0: // Unsound_NumQueuedMessages(). michael@0: bool Unsound_IsClosed() const; michael@0: uint32_t Unsound_NumQueuedMessages() const; michael@0: michael@0: private: michael@0: void Init(Mode mode, Listener* listener); michael@0: michael@0: void OutputQueuePush(Message* msg); michael@0: void OutputQueuePop(); michael@0: michael@0: const std::wstring PipeName(const std::wstring& channel_id) const; michael@0: bool CreatePipe(const std::wstring& channel_id, Mode mode); michael@0: bool EnqueueHelloMessage(); michael@0: michael@0: bool ProcessConnection(); michael@0: bool ProcessIncomingMessages(MessageLoopForIO::IOContext* context, michael@0: DWORD bytes_read); michael@0: bool ProcessOutgoingMessages(MessageLoopForIO::IOContext* context, michael@0: DWORD bytes_written); michael@0: michael@0: // MessageLoop::IOHandler implementation. michael@0: virtual void OnIOCompleted(MessageLoopForIO::IOContext* context, michael@0: DWORD bytes_transfered, DWORD error); michael@0: private: michael@0: struct State { michael@0: explicit State(ChannelImpl* channel); michael@0: ~State(); michael@0: MessageLoopForIO::IOContext context; michael@0: bool is_pending; michael@0: }; michael@0: michael@0: State input_state_; michael@0: State output_state_; michael@0: michael@0: HANDLE pipe_; michael@0: michael@0: Listener* listener_; michael@0: michael@0: // Messages to be sent are queued here. michael@0: std::queue output_queue_; michael@0: michael@0: // We read from the pipe into this buffer michael@0: char input_buf_[Channel::kReadBufferSize]; michael@0: michael@0: // Large messages that span multiple pipe buffers, get built-up using michael@0: // this buffer. michael@0: std::string input_overflow_buf_; michael@0: michael@0: // In server-mode, we have to wait for the client to connect before we michael@0: // can begin reading. We make use of the input_state_ when performing michael@0: // the connect operation in overlapped mode. michael@0: bool waiting_connect_; michael@0: michael@0: // This flag is set when processing incoming messages. It is used to michael@0: // avoid recursing through ProcessIncomingMessages, which could cause michael@0: // problems. TODO(darin): make this unnecessary michael@0: bool processing_incoming_; michael@0: michael@0: // This flag is set after Close() is run on the channel. michael@0: bool closed_; michael@0: michael@0: // This variable is updated so it matches output_queue_.size(), except we can michael@0: // read output_queue_length_ from any thread (if we're OK getting an michael@0: // occasional out-of-date or bogus value). We use output_queue_length_ to michael@0: // implement Unsound_NumQueuedMessages. michael@0: size_t output_queue_length_; michael@0: michael@0: ScopedRunnableMethodFactory factory_; michael@0: michael@0: scoped_ptr thread_check_; michael@0: michael@0: DISALLOW_COPY_AND_ASSIGN(ChannelImpl); michael@0: }; michael@0: michael@0: } // namespace IPC michael@0: michael@0: #endif // CHROME_COMMON_IPC_CHANNEL_WIN_H_