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

Unified Diff: ipc/ipc_channel_proxy.cc

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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ipc/ipc_channel_proxy.h ('k') | ipc/ipc_sync_channel.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ipc/ipc_channel_proxy.cc
===================================================================
--- ipc/ipc_channel_proxy.cc (revision 67520)
+++ ipc/ipc_channel_proxy.cc (working copy)
@@ -61,7 +61,6 @@
//------------------------------------------------------------------------------
ChannelProxy::Context::Context(Channel::Listener* listener,
- MessageFilter* filter,
MessageLoop* ipc_message_loop)
: listener_message_loop_(MessageLoop::current()),
listener_(listener),
@@ -69,8 +68,6 @@
channel_(NULL),
peer_pid_(0),
channel_connected_called_(false) {
- if (filter)
- filters_.push_back(make_scoped_refptr(filter));
}
void ChannelProxy::Context::CreateChannel(const std::string& id,
@@ -118,6 +115,12 @@
// Called on the IPC::Channel thread
void ChannelProxy::Context::OnChannelConnected(int32 peer_pid) {
+ // Add any pending filters. This avoids a race condition where someone
+ // creates a ChannelProxy, calls AddFilter, and then right after starts the
+ // peer process. The IO thread could receive a message before the task to add
+ // the filter is run on the IO thread.
+ OnAddFilter();
+
peer_pid_ = peer_pid;
for (size_t i = 0; i < filters_.size(); ++i)
filters_[i]->OnChannelConnected(peer_pid);
@@ -189,13 +192,24 @@
}
// Called on the IPC::Channel thread
-void ChannelProxy::Context::OnAddFilter(MessageFilter* filter) {
- filters_.push_back(make_scoped_refptr(filter));
+void ChannelProxy::Context::OnAddFilter() {
+ std::vector<scoped_refptr<MessageFilter> > filters;
+ {
+ AutoLock auto_lock(pending_filters_lock_);
+ filters.swap(pending_filters_);
+ }
- // If the channel has already been created, then we need to send this message
- // so that the filter gets access to the Channel.
- if (channel_)
- filter->OnFilterAdded(channel_);
+ for (size_t i = 0; i < filters.size(); ++i) {
+ filters_.push_back(filters[i]);
+
+ // If the channel has already been created, then we need to send this
+ // message so that the filter gets access to the Channel.
+ if (channel_)
+ filters[i]->OnFilterAdded(channel_);
+ // Ditto for the peer process id.
+ if (peer_pid_)
+ filters[i]->OnChannelConnected(peer_pid_);
+ }
}
// Called on the IPC::Channel thread
@@ -212,6 +226,15 @@
}
// Called on the listener's thread
+void ChannelProxy::Context::AddFilter(MessageFilter* filter) {
+ AutoLock auto_lock(pending_filters_lock_);
+ pending_filters_.push_back(make_scoped_refptr(filter));
+ ipc_message_loop_->PostTask(
+ FROM_HERE,
+ NewRunnableMethod(this, &Context::OnAddFilter));
+}
+
+// Called on the listener's thread
void ChannelProxy::Context::OnDispatchMessage(const Message& message) {
if (!listener_)
return;
@@ -255,15 +278,18 @@
//-----------------------------------------------------------------------------
-ChannelProxy::ChannelProxy(const std::string& channel_id, Channel::Mode mode,
- Channel::Listener* listener, MessageFilter* filter,
+ChannelProxy::ChannelProxy(const std::string& channel_id,
+ Channel::Mode mode,
+ Channel::Listener* listener,
MessageLoop* ipc_thread)
- : context_(new Context(listener, filter, ipc_thread)) {
+ : context_(new Context(listener, ipc_thread)) {
Init(channel_id, mode, ipc_thread, true);
}
-ChannelProxy::ChannelProxy(const std::string& channel_id, Channel::Mode mode,
- MessageLoop* ipc_thread, Context* context,
+ChannelProxy::ChannelProxy(const std::string& channel_id,
+ Channel::Mode mode,
+ MessageLoop* ipc_thread,
+ Context* context,
bool create_pipe_now)
: context_(context) {
Init(channel_id, mode, ipc_thread, create_pipe_now);
@@ -314,12 +340,7 @@
}
void ChannelProxy::AddFilter(MessageFilter* filter) {
- context_->ipc_message_loop()->PostTask(
- FROM_HERE,
- NewRunnableMethod(
- context_.get(),
- &Context::OnAddFilter,
- make_scoped_refptr(filter)));
+ context_->AddFilter(filter);
}
void ChannelProxy::RemoveFilter(MessageFilter* filter) {
« no previous file with comments | « ipc/ipc_channel_proxy.h ('k') | ipc/ipc_sync_channel.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698