Bug 913372 - Patch 3: Make a queue for active connection requests, r=echou
authorGina Yeh <gyeh@mozilla.com>
Mon, 28 Oct 2013 12:07:15 +0800
changeset 167222 00f66158905b97d35c99c0ab1cd9d042fd2abe41
parent 167221 af4f7b0cebe4a0bd5d5082ad74cb3c1d15451226
child 167223 b1536bdf87ae722d469dd42e2a403ebe93bce259
push id428
push userbbajaj@mozilla.com
push dateTue, 28 Jan 2014 00:16:25 +0000
treeherdermozilla-release@cd72a7ff3a75 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersechou
bugs913372
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 913372 - Patch 3: Make a queue for active connection requests, r=echou
dom/bluetooth/linux/BluetoothDBusService.cpp
--- a/dom/bluetooth/linux/BluetoothDBusService.cpp
+++ b/dom/bluetooth/linux/BluetoothDBusService.cpp
@@ -172,17 +172,17 @@ static const char* sBluetoothDBusSignals
  */
 static nsRefPtr<RawDBusConnection> gThreadConnection;
 static nsDataHashtable<nsStringHashKey, DBusMessage* >* sPairingReqTable;
 static nsTArray<uint32_t> sAuthorizedServiceClass;
 static nsString sAdapterPath;
 static Atomic<int32_t> sIsPairing(0);
 static int sConnectedDeviceCount = 0;
 static StaticAutoPtr<Monitor> sStopBluetoothMonitor;
-StaticRefPtr<BluetoothProfileController> sController;
+static nsTArray<nsRefPtr<BluetoothProfileController> > sControllerArray;
 
 typedef void (*UnpackFunc)(DBusMessage*, DBusError*, BluetoothValue&, nsAString&);
 typedef bool (*FilterFunc)(const BluetoothValue&);
 
 BluetoothDBusService::BluetoothDBusService()
 {
   sStopBluetoothMonitor = new Monitor("BluetoothService.sStopBluetoothMonitor");
 }
@@ -1747,16 +1747,17 @@ BluetoothDBusService::StopInternal()
   // unref stored DBusMessages before clear the hashtable
   sPairingReqTable->EnumerateRead(UnrefDBusMessages, nullptr);
   sPairingReqTable->Clear();
 
   sIsPairing = 0;
   sConnectedDeviceCount = 0;
 
   sAuthorizedServiceClass.Clear();
+  sControllerArray.Clear();
 
   StopDBus();
   return NS_OK;
 }
 
 bool
 BluetoothDBusService::IsEnabledInternal()
 {
@@ -2554,74 +2555,65 @@ BluetoothDBusService::SetPairingConfirma
   dbus_message_unref(reply);
 
   sPairingReqTable->Remove(aDeviceAddress);
   DispatchBluetoothReply(aRunnable, v, errorStr);
   return result;
 }
 
 static void
-DestroyBluetoothProfileController()
+NextBluetoothProfileController()
+{
+  sControllerArray[0] = nullptr;
+  sControllerArray.RemoveElementAt(0);
+
+  if (!sControllerArray.IsEmpty()) {
+    sControllerArray[0]->Start();
+  }
+}
+
+static void
+ConnectDisconnect(bool aConnect, const nsAString& aDeviceAddress,
+                  BluetoothReplyRunnable* aRunnable,
+                  uint16_t aServiceUuid, uint32_t aCod = 0)
 {
-  sController = nullptr;
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(aRunnable);
+
+  BluetoothProfileController* controller =
+    new BluetoothProfileController(aConnect, aDeviceAddress, aRunnable,
+                                   NextBluetoothProfileController,
+                                   aServiceUuid, aCod);
+  sControllerArray.AppendElement(controller);
+
+  /**
+   * If the request is the first element of the quene, start from here. Note
+   * that other request is pushed into the quene and is popped out after the
+   * first one is completed. See NextBluetoothProfileController() for details.
+   */
+  if (sControllerArray.Length() == 1) {
+    sControllerArray[0]->Start();
+  }
 }
 
 void
 BluetoothDBusService::Connect(const nsAString& aDeviceAddress,
                               uint32_t aCod,
                               uint16_t aServiceUuid,
                               BluetoothReplyRunnable* aRunnable)
 {
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(aRunnable);
-
-  BluetoothServiceClass serviceClass =
-    BluetoothUuidHelper::GetBluetoothServiceClass(aServiceUuid);
-
-  if (sController) {
-    DispatchBluetoothReply(aRunnable, BluetoothValue(),
-                           NS_LITERAL_STRING(ERR_NO_AVAILABLE_RESOURCE));
-    return;
-  }
-
-  sController =
-    new BluetoothProfileController(aDeviceAddress, aRunnable,
-                                   DestroyBluetoothProfileController);
-  if (aServiceUuid) {
-    sController->Connect(serviceClass);
-  } else {
-    sController->Connect(aCod);
-  }
+  ConnectDisconnect(true, aDeviceAddress, aRunnable, aServiceUuid, aCod);
 }
 
 void
 BluetoothDBusService::Disconnect(const nsAString& aDeviceAddress,
                                  uint16_t aServiceUuid,
                                  BluetoothReplyRunnable* aRunnable)
 {
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(aRunnable);
-
-  BluetoothServiceClass serviceClass =
-    BluetoothUuidHelper::GetBluetoothServiceClass(aServiceUuid);
-
-  if (sController) {
-    DispatchBluetoothReply(aRunnable, BluetoothValue(),
-                           NS_LITERAL_STRING(ERR_NO_AVAILABLE_RESOURCE));
-    return;
-  }
-
-  sController =
-    new BluetoothProfileController(aDeviceAddress, aRunnable,
-                                   DestroyBluetoothProfileController);
-  if (aServiceUuid) {
-    sController->Disconnect(serviceClass);
-  } else {
-    sController->Disconnect();
-  }
+  ConnectDisconnect(false, aDeviceAddress, aRunnable, aServiceUuid);
 }
 
 bool
 BluetoothDBusService::IsConnected(const uint16_t aServiceUuid)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   BluetoothProfileManagerBase* profile =