diff options
author | nduca@chromium.org <nduca@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-20 20:14:27 +0000 |
---|---|---|
committer | nduca@chromium.org <nduca@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-20 20:14:27 +0000 |
commit | 3051897f2c24104ab458961a350c3a3690cfad4d (patch) | |
tree | 5c46f2771ae0da5c201e33a5367d42ecc0128d8a /ipc | |
parent | 801fb650cad03a139ccb2b9d6da668ef8133f2c4 (diff) | |
download | chromium_src-3051897f2c24104ab458961a350c3a3690cfad4d.zip chromium_src-3051897f2c24104ab458961a350c3a3690cfad4d.tar.gz chromium_src-3051897f2c24104ab458961a350c3a3690cfad4d.tar.bz2 |
Add IPC::ForwardingMessageFilter.
Review URL: https://chromiumcodereview.appspot.com/10796057
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@147708 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ipc')
-rw-r--r-- | ipc/ipc.gypi | 2 | ||||
-rw-r--r-- | ipc/ipc_forwarding_message_filter.cc | 60 | ||||
-rw-r--r-- | ipc/ipc_forwarding_message_filter.h | 75 |
3 files changed, 137 insertions, 0 deletions
diff --git a/ipc/ipc.gypi b/ipc/ipc.gypi index e199cd2..e1eb740 100644 --- a/ipc/ipc.gypi +++ b/ipc/ipc.gypi @@ -28,6 +28,8 @@ 'ipc_channel_win.h', 'ipc_descriptors.h', 'ipc_export.h', + 'ipc_forwarding_message_filter.cc', + 'ipc_forwarding_message_filter.h', 'ipc_listener.h', 'ipc_logging.cc', 'ipc_logging.h', diff --git a/ipc/ipc_forwarding_message_filter.cc b/ipc/ipc_forwarding_message_filter.cc new file mode 100644 index 0000000..48f6e5f --- /dev/null +++ b/ipc/ipc_forwarding_message_filter.cc @@ -0,0 +1,60 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ipc/ipc_forwarding_message_filter.h" + +#include "base/bind.h" +#include "base/location.h" + +namespace IPC { + +ForwardingMessageFilter::ForwardingMessageFilter( + const uint32* message_ids_to_filter, + size_t num_message_ids_to_filter, + base::TaskRunner* target_task_runner, + const Handler& handler) + : target_task_runner_(target_task_runner), + handler_(handler) { + DCHECK(target_task_runner_); + DCHECK(!handler_.is_null()); + for (size_t i = 0; i < num_message_ids_to_filter; i++) + message_ids_to_filter_.insert(message_ids_to_filter[i]); +} + +void ForwardingMessageFilter::AddRoute(int routing_id) { + base::AutoLock locked(routes_lock_); + routes_.insert(routing_id); +} + +void ForwardingMessageFilter::RemoveRoute(int routing_id) { + base::AutoLock locked(routes_lock_); + routes_.erase(routing_id); +} + +bool ForwardingMessageFilter::OnMessageReceived(const Message& message) { + if (message_ids_to_filter_.find(message.type()) == + message_ids_to_filter_.end()) + return false; + + { + base::AutoLock locked(routes_lock_); + if (routes_.find(message.routing_id()) == routes_.end()) + return false; + } + + target_task_runner_->PostTask( + FROM_HERE, + base::Bind(&ForwardingMessageFilter::ForwardToHandler, this, message)); + return true; +} + +ForwardingMessageFilter::~ForwardingMessageFilter() { +} + +void ForwardingMessageFilter::ForwardToHandler(const Message& message) { + DCHECK(target_task_runner_->RunsTasksOnCurrentThread()); + handler_.Run(message); +} + +} // namespace IPC diff --git a/ipc/ipc_forwarding_message_filter.h b/ipc/ipc_forwarding_message_filter.h new file mode 100644 index 0000000..5b404c5 --- /dev/null +++ b/ipc/ipc_forwarding_message_filter.h @@ -0,0 +1,75 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IPC_IPC_FORWARDING_MESSAGE_FILTER_H_ +#define IPC_IPC_FORWARDING_MESSAGE_FILTER_H_ + +#include <set> + +#include "base/bind.h" +#include "base/callback_forward.h" +#include "base/synchronization/lock.h" +#include "base/task_runner.h" +#include "ipc/ipc_channel_proxy.h" + +namespace IPC { + +// This class can be used to intercept routed messages and +// deliver them to a different task runner than they would otherwise +// be sent. Messages are filtered based on +// based on routing_id as well as type (see message_ids_to_filter and AddRoute +// and RemoveRoute). +// +// The user of this class implements ForwardingMessageFilter::Client, +// which will receive the intercepted messages, on the specified target thread. +class IPC_EXPORT ForwardingMessageFilter : public ChannelProxy::MessageFilter { + public: + + // The handler is invoked on the thread associated with + // |target_task_runner| with messages that were intercepted by this filter. + typedef base::Callback<void(const Message&)> Handler; + + // This filter will intercept |message_ids_to_filter| and post + // them to the provided |target_task_runner|, where they will be given + // to |handler|. + // + // The caller must ensure that |handler| outlives the lifetime of the filter. + ForwardingMessageFilter( + const uint32* message_ids_to_filter, + size_t num_message_ids_to_filter, + base::TaskRunner* target_task_runner, + const Handler& handler); + + // Define the message routes to be filtered. + void AddRoute(int routing_id); + void RemoveRoute(int routing_id); + + // ChannelProxy::MessageFilter methods: + virtual bool OnMessageReceived(const Message& message) OVERRIDE; + + private: + friend class ChannelProxy::MessageFilter; + virtual ~ForwardingMessageFilter(); + + void ForwardToHandler(const Message& message); + + std::set<int> message_ids_to_filter_; + + // The handler_ only gets Run on the thread corresponding to + // target_task_runner_. + scoped_refptr<base::TaskRunner> target_task_runner_; + Handler handler_; + + // Protects access to routes_. + base::Lock routes_lock_; + + // Indicates the routing_ids for which messages should be filtered. + std::set<int> routes_; + + DISALLOW_COPY_AND_ASSIGN(ForwardingMessageFilter); +}; + +} // namespace IPC + +#endif // IPC_IPC_FORWARDING_MESSAGE_FILTER_H_ |