diff options
author | satorux@chromium.org <satorux@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-23 22:08:38 +0000 |
---|---|---|
committer | satorux@chromium.org <satorux@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-23 22:08:38 +0000 |
commit | 0ad9ef8e4c41b13a5f889a485677f225d7e5a934 (patch) | |
tree | c326fa4fd1f1c7473fbbd80205efd1c91e9a1ddc /dbus | |
parent | cf426a373b10dbcf900772d0be23d0d33927cb6d (diff) | |
download | chromium_src-0ad9ef8e4c41b13a5f889a485677f225d7e5a934.zip chromium_src-0ad9ef8e4c41b13a5f889a485677f225d7e5a934.tar.gz chromium_src-0ad9ef8e4c41b13a5f889a485677f225d7e5a934.tar.bz2 |
dbus: Fix a bug where we were emitting spurious error messages.
Error messages like "Requested to remove an unknown match rule:
type='signal', interface='...'" were emitted at shutdown of Bus
object if an object proxy was connected to more than one signal of
the same interface.
TEST=changed the end_to_end_async_unittest to reproduce this bug, and confirm that the error messages were gone after fixing object_proxy.{cc,h}
BUG=chromium-os:23382
Review URL: http://codereview.chromium.org/8681002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@111423 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'dbus')
-rw-r--r-- | dbus/end_to_end_async_unittest.cc | 21 | ||||
-rw-r--r-- | dbus/object_proxy.cc | 30 | ||||
-rw-r--r-- | dbus/object_proxy.h | 4 |
3 files changed, 42 insertions, 13 deletions
diff --git a/dbus/end_to_end_async_unittest.cc b/dbus/end_to_end_async_unittest.cc index 7ba782b..2f486f4 100644 --- a/dbus/end_to_end_async_unittest.cc +++ b/dbus/end_to_end_async_unittest.cc @@ -55,7 +55,8 @@ class EndToEndAsyncTest : public testing::Test { "/org/chromium/TestObject"); ASSERT_TRUE(bus_->HasDBusThread()); - // Connect to the "Test" signal from the remote object. + // Connect to the "Test" signal of "org.chromium.TestInterface" from + // the remote object. object_proxy_->ConnectToSignal( "org.chromium.TestInterface", "Test", @@ -63,6 +64,18 @@ class EndToEndAsyncTest : public testing::Test { base::Unretained(this)), base::Bind(&EndToEndAsyncTest::OnConnected, base::Unretained(this))); + // Connect to the "Test2" signal of "org.chromium.TestInterface" from + // the remote object. There was a bug where we were emitting error + // messages like "Requested to remove an unknown match rule: ..." at + // the shutdown of Bus when an object proxy is connected to more than + // one signal of the same interface. See crosbug.com/23382 for details. + object_proxy_->ConnectToSignal( + "org.chromium.TestInterface", + "Test2", + base::Bind(&EndToEndAsyncTest::OnTest2Signal, + base::Unretained(this)), + base::Bind(&EndToEndAsyncTest::OnConnected, + base::Unretained(this))); // Wait until the object proxy is connected to the signal. message_loop_.Run(); } @@ -122,6 +135,12 @@ class EndToEndAsyncTest : public testing::Test { message_loop_.Quit(); } + // Called when the "Test2" signal is received, in the main thread. + void OnTest2Signal(dbus::Signal* signal) { + dbus::MessageReader reader(signal); + message_loop_.Quit(); + } + // Called when connected to the signal. void OnConnected(const std::string& interface_name, const std::string& signal_name, diff --git a/dbus/object_proxy.cc b/dbus/object_proxy.cc index d9a53d9..5da5901 100644 --- a/dbus/object_proxy.cc +++ b/dbus/object_proxy.cc @@ -134,14 +134,16 @@ void ObjectProxy::Detach() { } } - for (size_t i = 0; i < match_rules_.size(); ++i) { + for (std::set<std::string>::iterator iter = match_rules_.begin(); + iter != match_rules_.end(); ++iter) { ScopedDBusError error; - bus_->RemoveMatch(match_rules_[i], error.get()); + bus_->RemoveMatch(*iter, error.get()); if (error.is_set()) { // There is nothing we can do to recover, so just print the error. - LOG(ERROR) << "Failed to remove match rule: " << match_rules_[i]; + LOG(ERROR) << "Failed to remove match rule: " << *iter; } } + match_rules_.clear(); } // static @@ -304,14 +306,22 @@ void ObjectProxy::ConnectToSignalInternal( const std::string match_rule = base::StringPrintf("type='signal', interface='%s'", interface_name.c_str()); - ScopedDBusError error; - bus_->AddMatch(match_rule, error.get());; - if (error.is_set()) { - LOG(ERROR) << "Failed to add match rule: " << match_rule; + + // Add the match rule if we don't have it. + if (match_rules_.find(match_rule) == match_rules_.end()) { + ScopedDBusError error; + bus_->AddMatch(match_rule, error.get());; + if (error.is_set()) { + LOG(ERROR) << "Failed to add match rule: " << match_rule; + } else { + // Store the match rule, so that we can remove this in Detach(). + match_rules_.insert(match_rule); + // Add the signal callback to the method table. + method_table_[absolute_signal_name] = signal_callback; + success = true; + } } else { - // Store the match rule, so that we can remove this in Detach(). - match_rules_.push_back(match_rule); - // Add the signal callback to the method table. + // We already have the match rule. method_table_[absolute_signal_name] = signal_callback; success = true; } diff --git a/dbus/object_proxy.h b/dbus/object_proxy.h index dcba44d..ef45305 100644 --- a/dbus/object_proxy.h +++ b/dbus/object_proxy.h @@ -9,8 +9,8 @@ #include <dbus/dbus.h> #include <map> +#include <set> #include <string> -#include <vector> #include "base/callback.h" #include "base/memory/ref_counted.h" @@ -192,7 +192,7 @@ class ObjectProxy : public base::RefCountedThreadSafe<ObjectProxy> { typedef std::map<std::string, SignalCallback> MethodTable; MethodTable method_table_; - std::vector<std::string> match_rules_; + std::set<std::string> match_rules_; DISALLOW_COPY_AND_ASSIGN(ObjectProxy); }; |