diff options
author | dmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-25 00:07:30 +0000 |
---|---|---|
committer | dmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-25 00:07:30 +0000 |
commit | 7412204291319c7099206d8e4964b981737e2170 (patch) | |
tree | e96de76e7864b31e664b5a902b2e3f4959d86843 /ipc/message_filter_router.cc | |
parent | a8f2a3efb04eea886d198c2dcc87bed6cf472dd6 (diff) | |
download | chromium_src-7412204291319c7099206d8e4964b981737e2170.zip chromium_src-7412204291319c7099206d8e4964b981737e2170.tar.gz chromium_src-7412204291319c7099206d8e4964b981737e2170.tar.bz2 |
Move IPC::MessageFilter and router to a separate file
There are no changes in implementation in this CL. This is in preparation
for making IPC::Channel support filters on the Channel's thread.
BUG=364241
TBR=cpu@chromium.org,nduca@chromium.org
cpu: OWNERS for win8
nduca: OWNERS for components/tracing
Review URL: https://codereview.chromium.org/245443005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@266057 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ipc/message_filter_router.cc')
-rw-r--r-- | ipc/message_filter_router.cc | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/ipc/message_filter_router.cc b/ipc/message_filter_router.cc new file mode 100644 index 0000000..81e4028 --- /dev/null +++ b/ipc/message_filter_router.cc @@ -0,0 +1,92 @@ +// Copyright 2014 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/message_filter_router.h" + +#include "ipc/ipc_message_macros.h" +#include "ipc/ipc_message_utils.h" +#include "ipc/message_filter.h" + +namespace IPC { + +namespace { + +bool TryFiltersImpl(MessageFilterRouter::MessageFilters& filters, + const IPC::Message& message) { + for (size_t i = 0; i < filters.size(); ++i) { + if (filters[i]->OnMessageReceived(message)) { + return true; + } + } + return false; +} + +bool RemoveFilterImpl(MessageFilterRouter::MessageFilters& filters, + MessageFilter* filter) { + MessageFilterRouter::MessageFilters::iterator it = + std::remove(filters.begin(), filters.end(), filter); + if (it == filters.end()) + return false; + + filters.erase(it, filters.end()); + return true; +} + +bool ValidMessageClass(int message_class) { + return message_class >= 0 && message_class < LastIPCMsgStart; +} + +} // namespace + +MessageFilterRouter::MessageFilterRouter() {} +MessageFilterRouter::~MessageFilterRouter() {} + +void MessageFilterRouter::AddFilter(MessageFilter* filter) { + // Determine if the filter should be applied to all messages, or only + // messages of a certain class. + std::vector<uint32> supported_message_classes; + if (filter->GetSupportedMessageClasses(&supported_message_classes)) { + DCHECK(!supported_message_classes.empty()); + for (size_t i = 0; i < supported_message_classes.size(); ++i) { + const int message_class = supported_message_classes[i]; + DCHECK(ValidMessageClass(message_class)); + // Safely ignore repeated subscriptions to a given message class for the + // current filter being added. + if (!message_class_filters_[message_class].empty() && + message_class_filters_[message_class].back() == filter) { + continue; + } + message_class_filters_[message_class].push_back(filter); + } + } else { + global_filters_.push_back(filter); + } +} + +void MessageFilterRouter::RemoveFilter(MessageFilter* filter) { + if (RemoveFilterImpl(global_filters_, filter)) + return; + + for (size_t i = 0; i < arraysize(message_class_filters_); ++i) + RemoveFilterImpl(message_class_filters_[i], filter); +} + +bool MessageFilterRouter::TryFilters(const Message& message) { + if (TryFiltersImpl(global_filters_, message)) + return true; + + const int message_class = IPC_MESSAGE_CLASS(message); + if (!ValidMessageClass(message_class)) + return false; + + return TryFiltersImpl(message_class_filters_[message_class], message); +} + +void MessageFilterRouter::Clear() { + global_filters_.clear(); + for (size_t i = 0; i < arraysize(message_class_filters_); ++i) + message_class_filters_[i].clear(); +} + +} // namespace IPC |