|
1 // Copyright (c) 2006-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 CHROME_COMMON_IPC_CHANNEL_H_ |
|
6 #define CHROME_COMMON_IPC_CHANNEL_H_ |
|
7 |
|
8 #include <queue> |
|
9 #include "chrome/common/ipc_message.h" |
|
10 |
|
11 namespace IPC { |
|
12 |
|
13 //------------------------------------------------------------------------------ |
|
14 |
|
15 class Channel : public Message::Sender { |
|
16 // Security tests need access to the pipe handle. |
|
17 friend class ChannelTest; |
|
18 |
|
19 public: |
|
20 // Implemented by consumers of a Channel to receive messages. |
|
21 class Listener { |
|
22 public: |
|
23 virtual ~Listener() {} |
|
24 |
|
25 // Called when a message is received. |
|
26 virtual void OnMessageReceived(const Message& message) = 0; |
|
27 |
|
28 // Called when the channel is connected and we have received the internal |
|
29 // Hello message from the peer. |
|
30 virtual void OnChannelConnected(int32_t peer_pid) {} |
|
31 |
|
32 // Called when an error is detected that causes the channel to close. |
|
33 // This method is not called when a channel is closed normally. |
|
34 virtual void OnChannelError() {} |
|
35 |
|
36 // If the listener has queued messages, swap them for |queue| like so |
|
37 // swap(impl->my_queued_messages, queue); |
|
38 virtual void GetQueuedMessages(std::queue<Message>& queue) {} |
|
39 }; |
|
40 |
|
41 enum Mode { |
|
42 MODE_SERVER, |
|
43 MODE_CLIENT |
|
44 }; |
|
45 |
|
46 enum { |
|
47 // The maximum message size in bytes. Attempting to receive a |
|
48 // message of this size or bigger results in a channel error. |
|
49 kMaximumMessageSize = 256 * 1024 * 1024, |
|
50 |
|
51 // Ammount of data to read at once from the pipe. |
|
52 kReadBufferSize = 4 * 1024 |
|
53 }; |
|
54 |
|
55 // Initialize a Channel. |
|
56 // |
|
57 // |channel_id| identifies the communication Channel. |
|
58 // |mode| specifies whether this Channel is to operate in server mode or |
|
59 // client mode. In server mode, the Channel is responsible for setting up the |
|
60 // IPC object, whereas in client mode, the Channel merely connects to the |
|
61 // already established IPC object. |
|
62 // |listener| receives a callback on the current thread for each newly |
|
63 // received message. |
|
64 // |
|
65 Channel(const std::wstring& channel_id, Mode mode, Listener* listener); |
|
66 |
|
67 // XXX it would nice not to have yet more platform-specific code in |
|
68 // here but it's just not worth the trouble. |
|
69 # if defined(OS_POSIX) |
|
70 // Connect to a pre-created channel |fd| as |mode|. |
|
71 Channel(int fd, Mode mode, Listener* listener); |
|
72 # elif defined(OS_WIN) |
|
73 // Connect to a pre-created channel as |mode|. Clients connect to |
|
74 // the pre-existing server pipe, and servers take over |server_pipe|. |
|
75 Channel(const std::wstring& channel_id, void* server_pipe, |
|
76 Mode mode, Listener* listener); |
|
77 # endif |
|
78 |
|
79 ~Channel(); |
|
80 |
|
81 // Connect the pipe. On the server side, this will initiate |
|
82 // waiting for connections. On the client, it attempts to |
|
83 // connect to a pre-existing pipe. Note, calling Connect() |
|
84 // will not block the calling thread and may complete |
|
85 // asynchronously. |
|
86 bool Connect(); |
|
87 |
|
88 // Close this Channel explicitly. May be called multiple times. |
|
89 void Close(); |
|
90 |
|
91 // Modify the Channel's listener. |
|
92 Listener* set_listener(Listener* listener); |
|
93 |
|
94 // Send a message over the Channel to the listener on the other end. |
|
95 // |
|
96 // |message| must be allocated using operator new. This object will be |
|
97 // deleted once the contents of the Message have been sent. |
|
98 // |
|
99 // If you Send() a message on a Close()'d channel, we delete the message |
|
100 // immediately. |
|
101 virtual bool Send(Message* message); |
|
102 |
|
103 // Unsound_IsClosed() and Unsound_NumQueuedMessages() are safe to call from |
|
104 // any thread, but the value returned may be out of date, because we don't |
|
105 // use any synchronization when reading or writing it. |
|
106 bool Unsound_IsClosed() const; |
|
107 uint32_t Unsound_NumQueuedMessages() const; |
|
108 |
|
109 #if defined(OS_POSIX) |
|
110 // On POSIX an IPC::Channel wraps a socketpair(), this method returns the |
|
111 // FD # for the client end of the socket and the equivalent FD# to use for |
|
112 // mapping it into the Child process. |
|
113 // This method may only be called on the server side of a channel. |
|
114 // |
|
115 // If the kTestingChannelID flag is specified on the command line then |
|
116 // a named FIFO is used as the channel transport mechanism rather than a |
|
117 // socketpair() in which case this method returns -1 for both parameters. |
|
118 void GetClientFileDescriptorMapping(int *src_fd, int *dest_fd) const; |
|
119 |
|
120 // Return the file descriptor for communication with the peer. |
|
121 int GetFileDescriptor() const; |
|
122 |
|
123 // Reset the file descriptor for communication with the peer. |
|
124 void ResetFileDescriptor(int fd); |
|
125 |
|
126 // Close the client side of the socketpair. |
|
127 void CloseClientFileDescriptor(); |
|
128 |
|
129 #elif defined(OS_WIN) |
|
130 // Return the server pipe handle. |
|
131 void* GetServerPipeHandle() const; |
|
132 #endif // defined(OS_POSIX) |
|
133 |
|
134 private: |
|
135 // PIMPL to which all channel calls are delegated. |
|
136 class ChannelImpl; |
|
137 ChannelImpl *channel_impl_; |
|
138 |
|
139 enum { |
|
140 #if defined(OS_MACOSX) |
|
141 // If the channel receives a message that contains file descriptors, then |
|
142 // it will reply back with this message, indicating that the message has |
|
143 // been received. The sending channel can then close any descriptors that |
|
144 // had been marked as auto_close. This works around a sendmsg() bug on BSD |
|
145 // where the kernel can eagerly close file descriptors that are in message |
|
146 // queues but not yet delivered. |
|
147 RECEIVED_FDS_MESSAGE_TYPE = kuint16max - 1, |
|
148 #endif |
|
149 |
|
150 // The Hello message is internal to the Channel class. It is sent |
|
151 // by the peer when the channel is connected. The message contains |
|
152 // just the process id (pid). The message has a special routing_id |
|
153 // (MSG_ROUTING_NONE) and type (HELLO_MESSAGE_TYPE). |
|
154 HELLO_MESSAGE_TYPE = kuint16max // Maximum value of message type (uint16_t), |
|
155 // to avoid conflicting with normal |
|
156 // message types, which are enumeration |
|
157 // constants starting from 0. |
|
158 }; |
|
159 }; |
|
160 |
|
161 } // namespace IPC |
|
162 |
|
163 #endif // CHROME_COMMON_IPC_CHANNEL_H_ |