Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(85)

Unified Diff: dbus/bus.cc

Issue 12211022: Call get_dispatch_status function to handle Disconnected signal. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Addressing comments Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « dbus/bus.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: dbus/bus.cc
diff --git a/dbus/bus.cc b/dbus/bus.cc
index 4096049417884f76044a275adbadb5e060f59636..6bd404c96622bc67c0ddbd0254f33cfa86694fa2 100644
--- a/dbus/bus.cc
+++ b/dbus/bus.cc
@@ -1,9 +1,6 @@
// Copyright (c) 2012 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.
-//
-// TODO(satorux):
-// - Handle "disconnected" signal.
#include "dbus/bus.h"
@@ -24,6 +21,11 @@ namespace dbus {
namespace {
+const char kDisconnectedSignal[] = "Disconnected";
+const char kDisconnectedMatchRule[] =
+ "type='signal', path='/org/freedesktop/DBus/Local',"
+ "interface='org.freedesktop.DBus.Local', member='Disconnected'";
+
// The class is used for watching the file descriptor used for D-Bus
// communication.
class Watch : public base::MessagePumpLibevent::Watcher {
@@ -364,12 +366,19 @@ bool Bus::Connect() {
// We shouldn't exit on the disconnected signal.
dbus_connection_set_exit_on_disconnect(connection_, false);
+ // Watch Disconnected signal.
+ AddFilterFunction(Bus::OnConnectionDisconnectedFilter, this);
+ AddMatch(kDisconnectedMatchRule, error.get());
+
return true;
}
void Bus::ShutdownAndBlock() {
AssertOnDBusThread();
+ if (shutdown_completed_)
+ return; // Already shutdowned, just return.
satorux1 2013/02/08 13:39:06 Do we need this? Looks unnecessary.
+
// Unregister the exported objects.
for (ExportedObjectTable::iterator iter = exported_object_table_.begin();
iter != exported_object_table_.end(); ++iter) {
@@ -403,6 +412,11 @@ void Bus::ShutdownAndBlock() {
// Private connection should be closed.
if (connection_) {
+ // Remove Disconnected watcher.
+ ScopedDBusError error;
+ RemoveFilterFunction(Bus::OnConnectionDisconnectedFilter, this);
+ RemoveMatch(kDisconnectedMatchRule, error.get());
+
if (connection_type_ == PRIVATE)
dbus_connection_close(connection_);
// dbus_connection_close() won't unref.
@@ -704,9 +718,12 @@ void Bus::ProcessAllIncomingDataIfAny() {
AssertOnDBusThread();
// As mentioned at the class comment in .h file, connection_ can be NULL.
- if (!connection_ || !dbus_connection_get_is_connected(connection_))
+ if (!connection_)
return;
+ // It is safe and necessary to call dbus_connection_get_dispatch_status even
+ // if the connection is lost. Otherwise we will miss "Disconnected" signal.
+ // (crbug.com/174431)
if (dbus_connection_get_dispatch_status(connection_) ==
DBUS_DISPATCH_DATA_REMAINS) {
while (dbus_connection_dispatch(connection_) ==
@@ -842,9 +859,6 @@ void Bus::OnDispatchStatusChanged(DBusConnection* connection,
DCHECK_EQ(connection, connection_);
AssertOnDBusThread();
- if (!dbus_connection_get_is_connected(connection))
- return;
-
// We cannot call ProcessAllIncomingDataIfAny() here, as calling
// dbus_connection_dispatch() inside DBusDispatchStatusFunction is
// prohibited by the D-Bus library. Hence, we post a task here instead.
@@ -854,6 +868,21 @@ void Bus::OnDispatchStatusChanged(DBusConnection* connection,
this));
}
+void Bus::OnConnectionDisconnected(DBusConnection* connection) {
+ AssertOnDBusThread();
+
+ if (!connection)
+ return;
+ DCHECK(!dbus_connection_get_is_connected(connection));
+
+ if (shutdown_completed_)
+ return; // Do nothing if the shutdown is already completed.
+
+ // Unexpected disconnection, maybe the peer closes the connection.
+ DCHECK_EQ(connection, connection_);
+ ShutdownAndBlock();
+}
+
dbus_bool_t Bus::OnAddWatchThunk(DBusWatch* raw_watch, void* data) {
Bus* self = static_cast<Bus*>(data);
return self->OnAddWatch(raw_watch);
@@ -891,4 +920,19 @@ void Bus::OnDispatchStatusChangedThunk(DBusConnection* connection,
self->OnDispatchStatusChanged(connection, status);
}
+DBusHandlerResult Bus::OnConnectionDisconnectedFilter(
+ DBusConnection *connection,
+ DBusMessage *message,
+ void *data) {
+ if (dbus_message_is_signal(message,
+ DBUS_INTERFACE_LOCAL,
+ kDisconnectedSignal)) {
+ Bus* self = static_cast<Bus*>(data);
+ self->AssertOnDBusThread();
+ self->OnConnectionDisconnected(connection);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
} // namespace dbus
« no previous file with comments | « dbus/bus.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698