diff options
author | keybuk@chromium.org <keybuk@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-14 01:18:35 +0000 |
---|---|---|
committer | keybuk@chromium.org <keybuk@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-14 01:18:35 +0000 |
commit | d7361fdcda06ab78b9777c923790e0c7b71b0a06 (patch) | |
tree | 0bb60552bdb3395ba4c3575c1d74931e10e8f96c /dbus | |
parent | 1ccb64670a56a335c8b0c5242541bb139b45e84c (diff) | |
download | chromium_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.cc | 29 | ||||
-rw-r--r-- | dbus/bus.h | 13 | ||||
-rw-r--r-- | dbus/bus_unittest.cc | 31 |
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(); @@ -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); |