summaryrefslogtreecommitdiffstats
path: root/dbus/bus.cc
diff options
context:
space:
mode:
Diffstat (limited to 'dbus/bus.cc')
-rw-r--r--dbus/bus.cc33
1 files changed, 23 insertions, 10 deletions
diff --git a/dbus/bus.cc b/dbus/bus.cc
index 1b766acd..3651332 100644
--- a/dbus/bus.cc
+++ b/dbus/bus.cc
@@ -14,6 +14,7 @@
#include "base/stl_util.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
+#include "base/time.h"
#include "dbus/exported_object.h"
#include "dbus/object_proxy.h"
#include "dbus/scoped_dbus_error.h"
@@ -178,11 +179,13 @@ Bus::Bus(const Options& options)
: bus_type_(options.bus_type),
connection_type_(options.connection_type),
dbus_thread_(options.dbus_thread),
+ on_shutdown_(false /* manual_reset */, false /* initially_signaled */),
connection_(NULL),
origin_loop_(MessageLoop::current()),
origin_thread_id_(base::PlatformThread::CurrentId()),
dbus_thread_id_(base::kInvalidThreadId),
async_operations_set_up_(false),
+ shutdown_completed_(false),
num_pending_watches_(0),
num_pending_timeouts_(0) {
if (dbus_thread_) {
@@ -299,21 +302,31 @@ void Bus::ShutdownAndBlock() {
}
// Private connection should be closed.
- if (connection_ && connection_type_ == PRIVATE) {
- dbus_connection_close(connection_);
+ if (connection_) {
+ if (connection_type_ == PRIVATE)
+ dbus_connection_close(connection_);
+ // dbus_connection_close() won't unref.
+ dbus_connection_unref(connection_);
}
- // dbus_connection_close() won't unref.
- dbus_connection_unref(connection_);
connection_ = NULL;
+ shutdown_completed_ = true;
}
-void Bus::Shutdown(OnShutdownCallback callback) {
+void Bus::ShutdownOnDBusThreadAndBlock() {
AssertOnOriginThread();
+ DCHECK(dbus_thread_);
- PostTaskToDBusThread(FROM_HERE, base::Bind(&Bus::ShutdownInternal,
- this,
- callback));
+ PostTaskToDBusThread(FROM_HERE, base::Bind(
+ &Bus::ShutdownOnDBusThreadAndBlockInternal,
+ this));
+
+ // Wait until the shutdown is complete on the D-Bus thread.
+ // The shutdown should not hang, but set timeout just in case.
+ const int kTimeoutSecs = 3;
+ const base::TimeDelta timeout(base::TimeDelta::FromSeconds(kTimeoutSecs));
+ const bool signaled = on_shutdown_.TimedWait(timeout);
+ LOG_IF(ERROR, !signaled) << "Failed to shutdown the bus";
}
bool Bus::RequestOwnership(const std::string& service_name) {
@@ -535,11 +548,11 @@ void Bus::UnregisterObjectPath(const std::string& object_path) {
registered_object_paths_.erase(object_path);
}
-void Bus::ShutdownInternal(OnShutdownCallback callback) {
+void Bus::ShutdownOnDBusThreadAndBlockInternal() {
AssertOnDBusThread();
ShutdownAndBlock();
- PostTaskToOriginThread(FROM_HERE, callback);
+ on_shutdown_.Signal();
}
void Bus::ProcessAllIncomingDataIfAny() {