summaryrefslogtreecommitdiffstats
path: root/dbus
diff options
context:
space:
mode:
authorkeybuk@chromium.org <keybuk@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-14 01:18:35 +0000
committerkeybuk@chromium.org <keybuk@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-14 01:18:35 +0000
commitd7361fdcda06ab78b9777c923790e0c7b71b0a06 (patch)
tree0bb60552bdb3395ba4c3575c1d74931e10e8f96c /dbus
parent1ccb64670a56a335c8b0c5242541bb139b45e84c (diff)
downloadchromium_src-d7361fdcda06ab78b9777c923790e0c7b71b0a06.zip
chromium_src-d7361fdcda06ab78b9777c923790e0c7b71b0a06.tar.gz
chromium_src-d7361fdcda06ab78b9777c923790e0c7b71b0a06.tar.bz2
dbus: allow unregistering of exported objects
Not all objects are permanent, some are transient and if we ever re-use the object path, we want a new instance of the exported object to be created rather than re-use an existing one. BUG=chromium-os:21320 TEST=dbus_unittests and included change to agent service provider Change-Id: I09882bbe2f70356182ac301c4260473051333424 Review URL: http://codereview.chromium.org/9691025 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@126527 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'dbus')
-rw-r--r--dbus/bus.cc29
-rw-r--r--dbus/bus.h13
-rw-r--r--dbus/bus_unittest.cc31
3 files changed, 73 insertions, 0 deletions
diff --git a/dbus/bus.cc b/dbus/bus.cc
index 9d4a436..91ba252 100644
--- a/dbus/bus.cc
+++ b/dbus/bus.cc
@@ -250,6 +250,35 @@ ExportedObject* Bus::GetExportedObject(const ObjectPath& object_path) {
return exported_object.get();
}
+void Bus::UnregisterExportedObject(const ObjectPath& object_path) {
+ AssertOnOriginThread();
+
+ // Remove the registered object from the table first, to allow a new
+ // GetExportedObject() call to return a new object, rather than this one.
+ ExportedObjectTable::iterator iter = exported_object_table_.find(object_path);
+ if (iter == exported_object_table_.end())
+ return;
+
+ scoped_refptr<ExportedObject> exported_object = iter->second;
+ exported_object_table_.erase(iter);
+
+ // Post the task to perform the final unregistration to the D-Bus thread.
+ // Since the registration also happens on the D-Bus thread in
+ // TryRegisterObjectPath(), and the message loop proxy we post to is a
+ // MessageLoopProxy which inherits from SequencedTaskRunner, there is a
+ // guarantee that this will happen before any future registration call.
+ PostTaskToDBusThread(FROM_HERE, base::Bind(
+ &Bus::UnregisterExportedObjectInternal,
+ this, exported_object));
+}
+
+void Bus::UnregisterExportedObjectInternal(
+ scoped_refptr<dbus::ExportedObject> exported_object) {
+ AssertOnDBusThread();
+
+ exported_object->Unregister();
+}
+
bool Bus::Connect() {
// dbus_bus_get_private() and dbus_bus_get() are blocking calls.
AssertOnDBusThread();
diff --git a/dbus/bus.h b/dbus/bus.h
index 2684dcd..8e3ceea 100644
--- a/dbus/bus.h
+++ b/dbus/bus.h
@@ -226,6 +226,15 @@ class Bus : public base::RefCountedThreadSafe<Bus> {
// Must be called in the origin thread.
virtual ExportedObject* GetExportedObject(const ObjectPath& object_path);
+ // Unregisters the exported object for the given object path |object_path|.
+ //
+ // Getting an exported object for the same object path after this call
+ // will return a new object, method calls on any remaining copies of the
+ // previous object will not be called.
+ //
+ // Must be called in the origin thread.
+ virtual void UnregisterExportedObject(const ObjectPath& object_path);
+
// Shuts down the bus and blocks until it's done. More specifically, this
// function does the following:
//
@@ -420,6 +429,10 @@ class Bus : public base::RefCountedThreadSafe<Bus> {
private:
friend class base::RefCountedThreadSafe<Bus>;
+ // Helper function used for UnregisterExportedObject().
+ void UnregisterExportedObjectInternal(
+ scoped_refptr<dbus::ExportedObject> exported_object);
+
// Helper function used for ShutdownOnDBusThreadAndBlock().
void ShutdownOnDBusThreadAndBlockInternal();
diff --git a/dbus/bus_unittest.cc b/dbus/bus_unittest.cc
index 4e7e8fd7..4011556b 100644
--- a/dbus/bus_unittest.cc
+++ b/dbus/bus_unittest.cc
@@ -108,6 +108,37 @@ TEST(BusTest, GetExportedObject) {
bus->ShutdownAndBlock();
}
+TEST(BusTest, UnregisterExportedObject) {
+ // Start the D-Bus thread.
+ base::Thread::Options thread_options;
+ thread_options.message_loop_type = MessageLoop::TYPE_IO;
+ base::Thread dbus_thread("D-Bus thread");
+ dbus_thread.StartWithOptions(thread_options);
+
+ // Create the bus.
+ dbus::Bus::Options options;
+ options.dbus_thread_message_loop_proxy = dbus_thread.message_loop_proxy();
+ scoped_refptr<dbus::Bus> bus = new dbus::Bus(options);
+ ASSERT_FALSE(bus->shutdown_completed());
+
+ dbus::ExportedObject* object_proxy1 =
+ bus->GetExportedObject(dbus::ObjectPath("/org/chromium/TestObject"));
+ ASSERT_TRUE(object_proxy1);
+
+ bus->UnregisterExportedObject(dbus::ObjectPath("/org/chromium/TestObject"));
+
+ // This should return a new object.
+ dbus::ExportedObject* object_proxy2 =
+ bus->GetExportedObject(dbus::ObjectPath("/org/chromium/TestObject"));
+ ASSERT_TRUE(object_proxy2);
+ EXPECT_NE(object_proxy1, object_proxy2);
+
+ // Shut down synchronously.
+ bus->ShutdownOnDBusThreadAndBlock();
+ EXPECT_TRUE(bus->shutdown_completed());
+ dbus_thread.Stop();
+}
+
TEST(BusTest, ShutdownAndBlock) {
dbus::Bus::Options options;
scoped_refptr<dbus::Bus> bus = new dbus::Bus(options);