OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #ifndef IPC_IPC_CHANNEL_POSIX_H_ |
| 6 #define IPC_IPC_CHANNEL_POSIX_H_ |
| 7 |
| 8 #include "ipc/ipc_channel.h" |
| 9 |
| 10 #include <sys/socket.h> // for CMSG macros |
| 11 |
| 12 #include <queue> |
| 13 #include <string> |
| 14 #include <vector> |
| 15 |
| 16 #include "base/message_loop.h" |
| 17 #include "ipc/file_descriptor_set_posix.h" |
| 18 |
| 19 namespace IPC { |
| 20 |
| 21 // Store that channel name |name| is available via socket |socket|. |
| 22 // Used when the channel has been precreated by another process on |
| 23 // our behalf and they've just shipped us the socket. |
| 24 void AddChannelSocket(const std::string& name, int socket); |
| 25 |
| 26 // Remove the channel name mapping, and close the corresponding socket. |
| 27 void RemoveAndCloseChannelSocket(const std::string& name); |
| 28 |
| 29 // Construct a socket pair appropriate for IPC: UNIX domain, nonblocking. |
| 30 // Returns false on error. |
| 31 bool SocketPair(int* fd1, int* fd2); |
| 32 |
| 33 // An implementation of ChannelImpl for POSIX systems that works via |
| 34 // socketpairs. See the .cc file for an overview of the implementation. |
| 35 class Channel::ChannelImpl : public MessageLoopForIO::Watcher { |
| 36 public: |
| 37 // Mirror methods of Channel, see ipc_channel.h for description. |
| 38 ChannelImpl(const std::string& channel_id, Mode mode, Listener* listener); |
| 39 ~ChannelImpl() { Close(); } |
| 40 bool Connect(); |
| 41 void Close(); |
| 42 void set_listener(Listener* listener) { listener_ = listener; } |
| 43 bool Send(Message* message); |
| 44 int GetClientFileDescriptor() const; |
| 45 |
| 46 private: |
| 47 bool CreatePipe(const std::string& channel_id, Mode mode); |
| 48 |
| 49 bool ProcessIncomingMessages(); |
| 50 bool ProcessOutgoingMessages(); |
| 51 |
| 52 // MessageLoopForIO::Watcher implementation. |
| 53 virtual void OnFileCanReadWithoutBlocking(int fd); |
| 54 virtual void OnFileCanWriteWithoutBlocking(int fd); |
| 55 |
| 56 Mode mode_; |
| 57 |
| 58 // After accepting one client connection on our server socket we want to |
| 59 // stop listening. |
| 60 MessageLoopForIO::FileDescriptorWatcher server_listen_connection_watcher_; |
| 61 MessageLoopForIO::FileDescriptorWatcher read_watcher_; |
| 62 MessageLoopForIO::FileDescriptorWatcher write_watcher_; |
| 63 |
| 64 // Indicates whether we're currently blocked waiting for a write to complete. |
| 65 bool is_blocked_on_write_; |
| 66 |
| 67 // If sending a message blocks then we use this variable |
| 68 // to keep track of where we are. |
| 69 size_t message_send_bytes_written_; |
| 70 |
| 71 // If the kTestingChannelID flag is specified, we use a FIFO instead of |
| 72 // a socketpair(). |
| 73 bool uses_fifo_; |
| 74 |
| 75 // File descriptor we're listening on for new connections in the FIFO case; |
| 76 // unused otherwise. |
| 77 int server_listen_pipe_; |
| 78 |
| 79 // The pipe used for communication. |
| 80 int pipe_; |
| 81 |
| 82 // For a server, the client end of our socketpair() -- the other end of our |
| 83 // pipe_ that is passed to the client. |
| 84 int client_pipe_; |
| 85 |
| 86 // The "name" of our pipe. On Windows this is the global identifier for |
| 87 // the pipe. On POSIX it's used as a key in a local map of file descriptors. |
| 88 std::string pipe_name_; |
| 89 |
| 90 Listener* listener_; |
| 91 |
| 92 // Messages to be sent are queued here. |
| 93 std::queue<Message*> output_queue_; |
| 94 |
| 95 // We read from the pipe into this buffer |
| 96 char input_buf_[Channel::kReadBufferSize]; |
| 97 |
| 98 enum { |
| 99 // We assume a worst case: kReadBufferSize bytes of messages, where each |
| 100 // message has no payload and a full complement of descriptors. |
| 101 MAX_READ_FDS = (Channel::kReadBufferSize / sizeof(IPC::Message::Header)) * |
| 102 FileDescriptorSet::MAX_DESCRIPTORS_PER_MESSAGE, |
| 103 }; |
| 104 |
| 105 // This is a control message buffer large enough to hold kMaxReadFDs |
| 106 #if defined(OS_MACOSX) |
| 107 // TODO(agl): OSX appears to have non-constant CMSG macros! |
| 108 char input_cmsg_buf_[1024]; |
| 109 #else |
| 110 char input_cmsg_buf_[CMSG_SPACE(sizeof(int) * MAX_READ_FDS)]; |
| 111 #endif |
| 112 |
| 113 // Large messages that span multiple pipe buffers, get built-up using |
| 114 // this buffer. |
| 115 std::string input_overflow_buf_; |
| 116 std::vector<int> input_overflow_fds_; |
| 117 |
| 118 // In server-mode, we have to wait for the client to connect before we |
| 119 // can begin reading. We make use of the input_state_ when performing |
| 120 // the connect operation in overlapped mode. |
| 121 bool waiting_connect_; |
| 122 |
| 123 // This flag is set when processing incoming messages. It is used to |
| 124 // avoid recursing through ProcessIncomingMessages, which could cause |
| 125 // problems. TODO(darin): make this unnecessary |
| 126 bool processing_incoming_; |
| 127 |
| 128 ScopedRunnableMethodFactory<ChannelImpl> factory_; |
| 129 |
| 130 DISALLOW_COPY_AND_ASSIGN(ChannelImpl); |
| 131 }; |
| 132 |
| 133 } // namespace IPC |
| 134 |
| 135 #endif // IPC_IPC_CHANNEL_POSIX_H_ |
OLD | NEW |