Bug 923647: Replace GetDefaultAdapterAdapter by non-blocking implementation, r=echou
authorThomas Zimmermann <tdz@users.sourceforge.net>
Fri, 25 Oct 2013 09:50:07 +0200
changeset 165989 f5b93f82ff3a66e57ec297e93b058c0d232dcfca
parent 165988 07df1f279a081415d6bb3e6abf2f499abb6d41dc
child 165990 c0b0f4cdb19f962714e03a598e0ab478c0ebf30f
push id3066
push userakeybl@mozilla.com
push dateMon, 09 Dec 2013 19:58:46 +0000
treeherdermozilla-beta@a31a0dce83aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersechou
bugs923647
milestone27.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 923647: Replace GetDefaultAdapterAdapter by non-blocking implementation, r=echou GetDefaultAdapter blocks while querying the default Bluetooth adapter. This patch replaces the function with a non-blocking call to DBus. The reply is handled in a callback function. As a side effect, this change also removes an invalid warning in cases where no default adapter is available, and enabling Bluetooth seems a bit faster.
dom/bluetooth/linux/BluetoothDBusService.cpp
--- a/dom/bluetooth/linux/BluetoothDBusService.cpp
+++ b/dom/bluetooth/linux/BluetoothDBusService.cpp
@@ -1573,37 +1573,41 @@ EventFilter(DBusConnection* aConn, DBusM
     task = new DistributeBluetoothSignalTask(signal);
   }
 
   NS_DispatchToMainThread(task);
 
   return DBUS_HANDLER_RESULT_HANDLED;
 }
 
-static bool
-GetDefaultAdapterPath(BluetoothValue& aValue, nsString& aError)
+static void
+OnDefaultAdapterReply(DBusMessage* aReply, void* aData)
 {
-  // This could block. It should never be run on the main thread.
-  MOZ_ASSERT(!NS_IsMainThread());
+  MOZ_ASSERT(!NS_IsMainThread()); // DBus thread
+
+  if (!aReply || dbus_message_is_error(aReply, DBUS_ERROR_TIMEOUT)) {
+    return;
+  }
 
   DBusError err;
   dbus_error_init(&err);
 
-  DBusMessage* msg;
-  bool success = gThreadConnection->SendWithError(&msg, &err, 1000, "/",
-                                                  DBUS_MANAGER_IFACE,
-                                                  "DefaultAdapter",
-                                                  DBUS_TYPE_INVALID);
-  NS_ENSURE_TRUE(success, false);
-
-  UnpackObjectPathMessage(msg, &err, aValue, aError);
-
-  dbus_message_unref(msg);
-
-  return aError.IsEmpty();
+  BluetoothValue v;
+  nsAutoString errorString;
+
+  UnpackObjectPathMessage(aReply, &err, v, errorString);
+
+  if (!errorString.IsEmpty()) {
+    return;
+  }
+
+  nsRefPtr<PrepareAdapterRunnable> b = new PrepareAdapterRunnable(v.get_nsString());
+  if (NS_FAILED(NS_DispatchToMainThread(b))) {
+    BT_WARNING("Failed to dispatch to main thread!");
+  }
 }
 
 bool
 BluetoothDBusService::IsReady()
 {
   if (!IsEnabled() || !mConnection || !gThreadConnection || IsToggling()) {
     BT_WARNING("Bluetooth service is not ready yet!");
     return false;
@@ -1664,27 +1668,27 @@ BluetoothDBusService::StartInternal()
     BT_WARNING("Cannot create DBus Event Filter for DBus Thread!");
     return NS_ERROR_FAILURE;
   }
 
   if (!sPairingReqTable) {
     sPairingReqTable = new nsDataHashtable<nsStringHashKey, DBusMessage* >;
   }
 
-  BluetoothValue v;
-  nsAutoString replyError;
-  if (!GetDefaultAdapterPath(v, replyError)) {
-    // Adapter path is not ready yet
-    // Let's do PrepareAdapterRunnable when we receive signal 'AdapterAdded'
-  } else {
-    // Adapter path has been ready. let's do PrepareAdapterRunnable now
-    nsRefPtr<PrepareAdapterRunnable> b = new PrepareAdapterRunnable(v.get_nsString());
-    if (NS_FAILED(NS_DispatchToMainThread(b))) {
-      BT_WARNING("Failed to dispatch to main thread!");
-    }
+  // Normally we'll receive the signal 'AdapterAdded' for the default
+  // adapter from the DBus daemon during start up. If we restart after
+  // a crash, the default adapter might already be available, so we ask
+  // the daemon explicitly here.
+  bool success = mConnection->SendWithReply(OnDefaultAdapterReply, nullptr,
+                                            1000, "/",
+                                            DBUS_ADAPTER_IFACE,
+                                            "DefaultAdapter",
+                                            DBUS_TYPE_INVALID);
+  if (!success) {
+    BT_WARNING("Failed to query default adapter!");
   }
 
   return NS_OK;
 }
 
 PLDHashOperator
 UnrefDBusMessages(const nsAString& key, DBusMessage* value, void* arg)
 {