Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(228)

Side by Side Diff: ipc/ipc_channel_proxy.h

Issue 5513001: Add a base class for objects that want to filter messages on the UI thread. ... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Fix possible race condition Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef IPC_IPC_CHANNEL_PROXY_H__ 5 #ifndef IPC_IPC_CHANNEL_PROXY_H__
6 #define IPC_IPC_CHANNEL_PROXY_H__ 6 #define IPC_IPC_CHANNEL_PROXY_H__
7 #pragma once 7 #pragma once
8 8
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/lock.h"
11 #include "base/ref_counted.h" 12 #include "base/ref_counted.h"
12 #include "ipc/ipc_channel.h" 13 #include "ipc/ipc_channel.h"
13 14
14 class MessageLoop; 15 class MessageLoop;
15 16
16 namespace IPC { 17 namespace IPC {
17 18
18 class SendTask; 19 class SendTask;
19 20
20 //----------------------------------------------------------------------------- 21 //-----------------------------------------------------------------------------
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 }; 98 };
98 99
99 // Initializes a channel proxy. The channel_id and mode parameters are 100 // Initializes a channel proxy. The channel_id and mode parameters are
100 // passed directly to the underlying IPC::Channel. The listener is called on 101 // passed directly to the underlying IPC::Channel. The listener is called on
101 // the thread that creates the ChannelProxy. The filter's OnMessageReceived 102 // the thread that creates the ChannelProxy. The filter's OnMessageReceived
102 // method is called on the thread where the IPC::Channel is running. The 103 // method is called on the thread where the IPC::Channel is running. The
103 // filter may be null if the consumer is not interested in handling messages 104 // filter may be null if the consumer is not interested in handling messages
104 // on the background thread. Any message not handled by the filter will be 105 // on the background thread. Any message not handled by the filter will be
105 // dispatched to the listener. The given message loop indicates where the 106 // dispatched to the listener. The given message loop indicates where the
106 // IPC::Channel should be created. 107 // IPC::Channel should be created.
107 ChannelProxy(const std::string& channel_id, Channel::Mode mode, 108 ChannelProxy(const std::string& channel_id,
108 Channel::Listener* listener, MessageFilter* filter, 109 Channel::Mode mode,
110 Channel::Listener* listener,
109 MessageLoop* ipc_thread_loop); 111 MessageLoop* ipc_thread_loop);
110 112
111 virtual ~ChannelProxy(); 113 virtual ~ChannelProxy();
112 114
113 // Close the IPC::Channel. This operation completes asynchronously, once the 115 // Close the IPC::Channel. This operation completes asynchronously, once the
114 // background thread processes the command to close the channel. It is ok to 116 // background thread processes the command to close the channel. It is ok to
115 // call this method multiple times. Redundant calls are ignored. 117 // call this method multiple times. Redundant calls are ignored.
116 // 118 //
117 // WARNING: The MessageFilter object held by the ChannelProxy is also 119 // WARNING: The MessageFilter object held by the ChannelProxy is also
118 // released asynchronously, and it may in fact have its final reference 120 // released asynchronously, and it may in fact have its final reference
119 // released on the background thread. The caller should be careful to deal 121 // released on the background thread. The caller should be careful to deal
120 // with / allow for this possibility. 122 // with / allow for this possibility.
121 void Close(); 123 void Close();
122 124
123 // Send a message asynchronously. The message is routed to the background 125 // Send a message asynchronously. The message is routed to the background
124 // thread where it is passed to the IPC::Channel's Send method. 126 // thread where it is passed to the IPC::Channel's Send method.
125 virtual bool Send(Message* message); 127 virtual bool Send(Message* message);
126 128
127 // Used to intercept messages as they are received on the background thread. 129 // Used to intercept messages as they are received on the background thread.
128 // 130 //
129 // Ordinarily, messages sent to the ChannelProxy are routed to the matching 131 // Ordinarily, messages sent to the ChannelProxy are routed to the matching
130 // listener on the worker thread. This API allows code to intercept messages 132 // listener on the worker thread. This API allows code to intercept messages
131 // before they are sent to the worker thread. 133 // before they are sent to the worker thread.
134 // If you call this before the target process is launched, then you're
135 // guaranteed to not miss any messages. But if you call this anytime after,
136 // then some messages might be missed since the filter is added internally on
137 // internally on the IO thread.
132 void AddFilter(MessageFilter* filter); 138 void AddFilter(MessageFilter* filter);
133 void RemoveFilter(MessageFilter* filter); 139 void RemoveFilter(MessageFilter* filter);
134 140
135 // Called to clear the pointer to the IPC message loop when it's going away. 141 // Called to clear the pointer to the IPC message loop when it's going away.
136 void ClearIPCMessageLoop(); 142 void ClearIPCMessageLoop();
137 143
138 #if defined(OS_POSIX) 144 #if defined(OS_POSIX)
139 // Calls through to the underlying channel's methods. 145 // Calls through to the underlying channel's methods.
140 // TODO(playmobil): For now this is only implemented in the case of 146 // TODO(playmobil): For now this is only implemented in the case of
141 // create_pipe_now = true, we need to figure this out for the latter case. 147 // create_pipe_now = true, we need to figure this out for the latter case.
142 int GetClientFileDescriptor() const; 148 int GetClientFileDescriptor() const;
143 #endif // defined(OS_POSIX) 149 #endif // defined(OS_POSIX)
144 150
145 protected: 151 protected:
146 class Context; 152 class Context;
147 // A subclass uses this constructor if it needs to add more information 153 // A subclass uses this constructor if it needs to add more information
148 // to the internal state. If create_pipe_now is true, the pipe is created 154 // to the internal state. If create_pipe_now is true, the pipe is created
149 // immediately. Otherwise it's created on the IO thread. 155 // immediately. Otherwise it's created on the IO thread.
150 ChannelProxy(const std::string& channel_id, Channel::Mode mode, 156 ChannelProxy(const std::string& channel_id,
151 MessageLoop* ipc_thread_loop, Context* context, 157 Channel::Mode mode,
158 MessageLoop* ipc_thread_loop,
159 Context* context,
152 bool create_pipe_now); 160 bool create_pipe_now);
153 161
154 // Used internally to hold state that is referenced on the IPC thread. 162 // Used internally to hold state that is referenced on the IPC thread.
155 class Context : public base::RefCountedThreadSafe<Context>, 163 class Context : public base::RefCountedThreadSafe<Context>,
156 public Channel::Listener { 164 public Channel::Listener {
157 public: 165 public:
158 Context(Channel::Listener* listener, MessageFilter* filter, 166 Context(Channel::Listener* listener, MessageLoop* ipc_thread);
159 MessageLoop* ipc_thread);
160 void ClearIPCMessageLoop() { ipc_message_loop_ = NULL; } 167 void ClearIPCMessageLoop() { ipc_message_loop_ = NULL; }
161 MessageLoop* ipc_message_loop() const { return ipc_message_loop_; } 168 MessageLoop* ipc_message_loop() const { return ipc_message_loop_; }
162 const std::string& channel_id() const { return channel_id_; } 169 const std::string& channel_id() const { return channel_id_; }
163 170
164 // Dispatches a message on the listener thread. 171 // Dispatches a message on the listener thread.
165 void OnDispatchMessage(const Message& message); 172 void OnDispatchMessage(const Message& message);
166 173
167 protected: 174 protected:
168 friend class base::RefCountedThreadSafe<Context>; 175 friend class base::RefCountedThreadSafe<Context>;
169 virtual ~Context() { } 176 virtual ~Context() { }
(...skipping 19 matching lines...) Expand all
189 // more messages, so we honor that wish by forgetting them! 196 // more messages, so we honor that wish by forgetting them!
190 virtual void Clear() { listener_ = NULL; } 197 virtual void Clear() { listener_ = NULL; }
191 198
192 private: 199 private:
193 friend class ChannelProxy; 200 friend class ChannelProxy;
194 friend class SendTask; 201 friend class SendTask;
195 202
196 // Create the Channel 203 // Create the Channel
197 void CreateChannel(const std::string& id, const Channel::Mode& mode); 204 void CreateChannel(const std::string& id, const Channel::Mode& mode);
198 205
199 // Methods called via InvokeLater: 206 // Methods called on the IO thread.
200 void OnSendMessage(Message* message_ptr); 207 void OnSendMessage(Message* message_ptr);
201 void OnAddFilter(MessageFilter* filter); 208 void OnAddFilter();
202 void OnRemoveFilter(MessageFilter* filter); 209 void OnRemoveFilter(MessageFilter* filter);
210
211 // Methods called on the listener thread.
212 void AddFilter(MessageFilter* filter);
203 void OnDispatchConnected(); 213 void OnDispatchConnected();
204 void OnDispatchError(); 214 void OnDispatchError();
205 215
206 MessageLoop* listener_message_loop_; 216 MessageLoop* listener_message_loop_;
207 Channel::Listener* listener_; 217 Channel::Listener* listener_;
208 218
209 // List of filters. This is only accessed on the IPC thread. 219 // List of filters. This is only accessed on the IPC thread.
210 std::vector<scoped_refptr<MessageFilter> > filters_; 220 std::vector<scoped_refptr<MessageFilter> > filters_;
211 MessageLoop* ipc_message_loop_; 221 MessageLoop* ipc_message_loop_;
212 Channel* channel_; 222 Channel* channel_;
213 std::string channel_id_; 223 std::string channel_id_;
214 int peer_pid_; 224 int peer_pid_;
215 bool channel_connected_called_; 225 bool channel_connected_called_;
226
227 // Holds filters between the AddFilter call on the listerner thread and the
228 // IPC thread when they're added to filters_.
229 std::vector<scoped_refptr<MessageFilter> > pending_filters_;
230 // Lock for pending_filters_.
231 Lock pending_filters_lock_;
216 }; 232 };
217 233
218 Context* context() { return context_; } 234 Context* context() { return context_; }
219 235
220 private: 236 private:
221 friend class SendTask; 237 friend class SendTask;
222 238
223 void Init(const std::string& channel_id, Channel::Mode mode, 239 void Init(const std::string& channel_id, Channel::Mode mode,
224 MessageLoop* ipc_thread_loop, bool create_pipe_now); 240 MessageLoop* ipc_thread_loop, bool create_pipe_now);
225 241
226 // By maintaining this indirection (ref-counted) to our internal state, we 242 // By maintaining this indirection (ref-counted) to our internal state, we
227 // can safely be destroyed while the background thread continues to do stuff 243 // can safely be destroyed while the background thread continues to do stuff
228 // that involves this data. 244 // that involves this data.
229 scoped_refptr<Context> context_; 245 scoped_refptr<Context> context_;
230 }; 246 };
231 247
232 } // namespace IPC 248 } // namespace IPC
233 249
234 #endif // IPC_IPC_CHANNEL_PROXY_H__ 250 #endif // IPC_IPC_CHANNEL_PROXY_H__
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698