1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/chromium/src/chrome/common/ipc_channel_posix.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,170 @@ 1.4 +// Copyright (c) 2008 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +#ifndef CHROME_COMMON_IPC_CHANNEL_POSIX_H_ 1.9 +#define CHROME_COMMON_IPC_CHANNEL_POSIX_H_ 1.10 + 1.11 +#include "chrome/common/ipc_channel.h" 1.12 + 1.13 +#include <sys/socket.h> // for CMSG macros 1.14 + 1.15 +#include <queue> 1.16 +#include <string> 1.17 +#include <vector> 1.18 +#include <list> 1.19 + 1.20 +#include "base/message_loop.h" 1.21 +#include "chrome/common/file_descriptor_set_posix.h" 1.22 + 1.23 +namespace IPC { 1.24 + 1.25 +// An implementation of ChannelImpl for POSIX systems that works via 1.26 +// socketpairs. See the .cc file for an overview of the implementation. 1.27 +class Channel::ChannelImpl : public MessageLoopForIO::Watcher { 1.28 + public: 1.29 + // Mirror methods of Channel, see ipc_channel.h for description. 1.30 + ChannelImpl(const std::wstring& channel_id, Mode mode, Listener* listener); 1.31 + ChannelImpl(int fd, Mode mode, Listener* listener); 1.32 + ~ChannelImpl() { Close(); } 1.33 + bool Connect(); 1.34 + void Close(); 1.35 + Listener* set_listener(Listener* listener) { 1.36 + Listener* old = listener_; 1.37 + listener_ = listener; 1.38 + return old; 1.39 + } 1.40 + bool Send(Message* message); 1.41 + void GetClientFileDescriptorMapping(int *src_fd, int *dest_fd) const; 1.42 + 1.43 + void ResetFileDescriptor(int fd); 1.44 + 1.45 + int GetFileDescriptor() const { 1.46 + return pipe_; 1.47 + } 1.48 + void CloseClientFileDescriptor(); 1.49 + 1.50 + // See the comment in ipc_channel.h for info on Unsound_IsClosed() and 1.51 + // Unsound_NumQueuedMessages(). 1.52 + bool Unsound_IsClosed() const; 1.53 + uint32_t Unsound_NumQueuedMessages() const; 1.54 + 1.55 + private: 1.56 + void Init(Mode mode, Listener* listener); 1.57 + bool CreatePipe(const std::wstring& channel_id, Mode mode); 1.58 + bool EnqueueHelloMessage(); 1.59 + 1.60 + bool ProcessIncomingMessages(); 1.61 + bool ProcessOutgoingMessages(); 1.62 + 1.63 + // MessageLoopForIO::Watcher implementation. 1.64 + virtual void OnFileCanReadWithoutBlocking(int fd); 1.65 + virtual void OnFileCanWriteWithoutBlocking(int fd); 1.66 + 1.67 +#if defined(OS_MACOSX) 1.68 + void CloseDescriptors(uint32_t pending_fd_id); 1.69 +#endif 1.70 + 1.71 + void OutputQueuePush(Message* msg); 1.72 + void OutputQueuePop(); 1.73 + 1.74 + Mode mode_; 1.75 + 1.76 + // After accepting one client connection on our server socket we want to 1.77 + // stop listening. 1.78 + MessageLoopForIO::FileDescriptorWatcher server_listen_connection_watcher_; 1.79 + MessageLoopForIO::FileDescriptorWatcher read_watcher_; 1.80 + MessageLoopForIO::FileDescriptorWatcher write_watcher_; 1.81 + 1.82 + // Indicates whether we're currently blocked waiting for a write to complete. 1.83 + bool is_blocked_on_write_; 1.84 + 1.85 + // If sending a message blocks then we use this variable 1.86 + // to keep track of where we are. 1.87 + size_t message_send_bytes_written_; 1.88 + 1.89 + // If the kTestingChannelID flag is specified, we use a FIFO instead of 1.90 + // a socketpair(). 1.91 + bool uses_fifo_; 1.92 + 1.93 + int server_listen_pipe_; 1.94 + int pipe_; 1.95 + int client_pipe_; // The client end of our socketpair(). 1.96 + 1.97 + // The "name" of our pipe. On Windows this is the global identifier for 1.98 + // the pipe. On POSIX it's used as a key in a local map of file descriptors. 1.99 + std::string pipe_name_; 1.100 + 1.101 + Listener* listener_; 1.102 + 1.103 + // Messages to be sent are queued here. 1.104 + std::queue<Message*> output_queue_; 1.105 + 1.106 + // We read from the pipe into this buffer 1.107 + char input_buf_[Channel::kReadBufferSize]; 1.108 + 1.109 + enum { 1.110 + // We assume a worst case: kReadBufferSize bytes of messages, where each 1.111 + // message has no payload and a full complement of descriptors. 1.112 + MAX_READ_FDS = (Channel::kReadBufferSize / sizeof(IPC::Message::Header)) * 1.113 + FileDescriptorSet::MAX_DESCRIPTORS_PER_MESSAGE 1.114 + }; 1.115 + 1.116 + // This is a control message buffer large enough to hold kMaxReadFDs 1.117 +#if defined(OS_MACOSX) || defined(OS_NETBSD) 1.118 + // TODO(agl): OSX appears to have non-constant CMSG macros! 1.119 + char input_cmsg_buf_[1024]; 1.120 +#else 1.121 + char input_cmsg_buf_[CMSG_SPACE(sizeof(int) * MAX_READ_FDS)]; 1.122 +#endif 1.123 + 1.124 + // Large messages that span multiple pipe buffers, get built-up using 1.125 + // this buffer. 1.126 + std::string input_overflow_buf_; 1.127 + std::vector<int> input_overflow_fds_; 1.128 + 1.129 + // In server-mode, we have to wait for the client to connect before we 1.130 + // can begin reading. We make use of the input_state_ when performing 1.131 + // the connect operation in overlapped mode. 1.132 + bool waiting_connect_; 1.133 + 1.134 + // This flag is set when processing incoming messages. It is used to 1.135 + // avoid recursing through ProcessIncomingMessages, which could cause 1.136 + // problems. TODO(darin): make this unnecessary 1.137 + bool processing_incoming_; 1.138 + 1.139 + // This flag is set after we've closed the channel. 1.140 + bool closed_; 1.141 + 1.142 +#if defined(OS_MACOSX) 1.143 + struct PendingDescriptors { 1.144 + uint32_t id; 1.145 + scoped_refptr<FileDescriptorSet> fds; 1.146 + 1.147 + PendingDescriptors() : id(0) { } 1.148 + PendingDescriptors(uint32_t id, FileDescriptorSet *fds) 1.149 + : id(id), 1.150 + fds(fds) 1.151 + { } 1.152 + }; 1.153 + 1.154 + std::list<PendingDescriptors> pending_fds_; 1.155 + 1.156 + // A generation ID for RECEIVED_FD messages. 1.157 + uint32_t last_pending_fd_id_; 1.158 +#endif 1.159 + 1.160 + // This variable is updated so it matches output_queue_.size(), except we can 1.161 + // read output_queue_length_ from any thread (if we're OK getting an 1.162 + // occasional out-of-date or bogus value). We use output_queue_length_ to 1.163 + // implement Unsound_NumQueuedMessages. 1.164 + size_t output_queue_length_; 1.165 + 1.166 + ScopedRunnableMethodFactory<ChannelImpl> factory_; 1.167 + 1.168 + DISALLOW_COPY_AND_ASSIGN(ChannelImpl); 1.169 +}; 1.170 + 1.171 +} // namespace IPC 1.172 + 1.173 +#endif // CHROME_COMMON_IPC_CHANNEL_POSIX_H_