Bug 1190730 - Patch 4/5: Make runnable arrays member variables, r=joliu
authorBen Tian <btian@mozilla.com>
Fri, 07 Aug 2015 10:38:21 +0800
changeset 288675 84662b3e75d42552656c4a47541a6251dfd7672c
parent 288674 099de7856b3d286766046ae43ef3921b69af6f76
child 288676 4198f0ba0ec3f8354bd746df03de5801e2c11203
push id5067
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:04:52 +0000
treeherdermozilla-beta@14221ffe5b2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjoliu
bugs1190730
milestone42.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 1190730 - Patch 4/5: Make runnable arrays member variables, r=joliu
dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp
dom/bluetooth/bluedroid/BluetoothServiceBluedroid.h
--- a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp
@@ -87,30 +87,16 @@ using namespace mozilla::ipc;
 USING_BLUETOOTH_NAMESPACE
 
 static BluetoothInterface* sBtInterface;
 
 static nsTArray<nsRefPtr<BluetoothProfileController> > sControllerArray;
 static InfallibleTArray<BluetoothNamedValue> sRemoteDevicesPack;
 static nsTArray<int> sRequestedDeviceCountArray;
 
-static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sSetPropertyRunnableArray;
-static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sGetDeviceRunnableArray;
-
-static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sBondingRunnableArray;
-static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sUnbondingRunnableArray;
-
-#ifndef MOZ_B2G_BT_API_V1
-static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sChangeAdapterStateRunnableArray;
-static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sChangeDiscoveryRunnableArray;
-static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sFetchUuidsRunnableArray;
-#else
-// Missing in Bluetooth v1
-#endif
-
 /*
  *  Static methods
  */
 
 ControlPlayStatus
 BluetoothServiceBluedroid::PlayStatusStringToControlPlayStatus(
   const nsAString& aPlayStatus)
 {
@@ -319,18 +305,18 @@ public:
       BluetoothGattManager::InitGattInterface
 #else
       // Missing in Bluetooth v1
 #endif
     };
 
     MOZ_ASSERT(NS_IsMainThread());
 
-    // Register all the bluedroid callbacks before enable() get called
-    // It is required to register a2dp callbacks before a2dp media task starts up.
+    // Register all the bluedroid callbacks before enable() gets called. This is
+    // required to register a2dp callbacks before a2dp media task starts up.
     // If any interface cannot be initialized, turn on bluetooth core anyway.
     nsRefPtr<ProfileInitResultHandler> res =
       new ProfileInitResultHandler(MOZ_ARRAY_LENGTH(sInitManager));
 
     for (size_t i = 0; i < MOZ_ARRAY_LENGTH(sInitManager); ++i) {
       sInitManager[i](res);
     }
   }
@@ -419,42 +405,43 @@ BluetoothServiceBluedroid::BluetoothServ
   , mDiscoverableTimeout(0)
 #endif
   , mIsRestart(false)
   , mIsFirstTimeToggleOffBt(false)
 {
   sBtInterface = BluetoothInterface::GetInstance();
   if (!sBtInterface) {
     BT_LOGR("Error! Failed to get instance of bluetooth interface");
+    return;
   }
 }
 
 BluetoothServiceBluedroid::~BluetoothServiceBluedroid()
 {
 }
 
 #ifndef MOZ_B2G_BT_API_V1
 nsresult
 BluetoothServiceBluedroid::StartInternal(BluetoothReplyRunnable* aRunnable)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   // aRunnable will be a nullptr while startup
   if (aRunnable) {
-    sChangeAdapterStateRunnableArray.AppendElement(aRunnable);
+    mChangeAdapterStateRunnables.AppendElement(aRunnable);
   }
 
   nsresult ret = StartGonkBluetooth();
   if (NS_FAILED(ret)) {
     BluetoothService::AcknowledgeToggleBt(false);
 
     // Reject Promise
     if (aRunnable) {
       DispatchReplyError(aRunnable, NS_LITERAL_STRING("StartBluetoothError"));
-      sChangeAdapterStateRunnableArray.RemoveElement(aRunnable);
+      mChangeAdapterStateRunnables.RemoveElement(aRunnable);
     }
 
     BT_LOGR("Error");
   }
 
   return ret;
 }
 
@@ -486,27 +473,27 @@ BluetoothServiceBluedroid::StopInternal(
     } else if (!profileName.EqualsLiteral("OPP") &&
                !profileName.EqualsLiteral("PBAP")) {
       sProfiles[i]->Reset();
     }
   }
 
   // aRunnable will be a nullptr during starup and shutdown
   if (aRunnable) {
-    sChangeAdapterStateRunnableArray.AppendElement(aRunnable);
+    mChangeAdapterStateRunnables.AppendElement(aRunnable);
   }
 
   nsresult ret = StopGonkBluetooth();
   if (NS_FAILED(ret)) {
     BluetoothService::AcknowledgeToggleBt(true);
 
     // Reject Promise
     if (aRunnable) {
       DispatchReplyError(aRunnable, NS_LITERAL_STRING("StopBluetoothError"));
-      sChangeAdapterStateRunnableArray.RemoveElement(aRunnable);
+      mChangeAdapterStateRunnables.RemoveElement(aRunnable);
     }
 
     BT_LOGR("Error");
   }
 
   return ret;
 }
 #else
@@ -829,45 +816,49 @@ BluetoothServiceBluedroid::GetDefaultAda
 }
 #endif
 
 class BluetoothServiceBluedroid::GetRemoteDevicePropertiesResultHandler
   final
   : public BluetoothResultHandler
 {
 public:
-  GetRemoteDevicePropertiesResultHandler(const nsAString& aDeviceAddress)
-  : mDeviceAddress(aDeviceAddress)
+  GetRemoteDevicePropertiesResultHandler(
+    nsTArray<nsRefPtr<BluetoothReplyRunnable>>& aRunnableArray,
+    const nsAString& aDeviceAddress)
+  : mRunnableArray(aRunnableArray)
+  , mDeviceAddress(aDeviceAddress)
   { }
 
   void OnError(BluetoothStatus aStatus) override
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     BT_WARNING("GetRemoteDeviceProperties(%s) failed: %d",
                NS_ConvertUTF16toUTF8(mDeviceAddress).get(), aStatus);
 
     /* dispatch result after final pending operation */
     if (--sRequestedDeviceCountArray[0] == 0) {
-      if (!sGetDeviceRunnableArray.IsEmpty()) {
+      if (!mRunnableArray.IsEmpty()) {
 #ifndef MOZ_B2G_BT_API_V1
-        DispatchReplyError(sGetDeviceRunnableArray[0],
+        DispatchReplyError(mRunnableArray[0],
           NS_LITERAL_STRING("GetRemoteDeviceProperties failed"));
 #else
-        DispatchReplySuccess(sGetDeviceRunnableArray[0], sRemoteDevicesPack);
+        DispatchReplySuccess(mRunnableArray[0], sRemoteDevicesPack);
 #endif
-        sGetDeviceRunnableArray.RemoveElementAt(0);
+        mRunnableArray.RemoveElementAt(0);
       }
 
       sRequestedDeviceCountArray.RemoveElementAt(0);
       sRemoteDevicesPack.Clear();
     }
   }
 
 private:
+  nsTArray<nsRefPtr<BluetoothReplyRunnable>> mRunnableArray;
   nsString mDeviceAddress;
 };
 
 nsresult
 BluetoothServiceBluedroid::GetConnectedDevicePropertiesInternal(
   uint16_t aServiceUuid, BluetoothReplyRunnable* aRunnable)
 {
   MOZ_ASSERT(NS_IsMainThread());
@@ -891,22 +882,23 @@ BluetoothServiceBluedroid::GetConnectedD
   int requestedDeviceCount = deviceAddresses.Length();
   if (requestedDeviceCount == 0) {
     InfallibleTArray<BluetoothNamedValue> emptyArr;
     DispatchReplySuccess(aRunnable, emptyArr);
     return NS_OK;
   }
 
   sRequestedDeviceCountArray.AppendElement(requestedDeviceCount);
-  sGetDeviceRunnableArray.AppendElement(aRunnable);
+  mGetDeviceRunnables.AppendElement(aRunnable);
 
   for (int i = 0; i < requestedDeviceCount; i++) {
     // Retrieve all properties of devices
     sBtInterface->GetRemoteDeviceProperties(deviceAddresses[i],
-      new GetRemoteDevicePropertiesResultHandler(deviceAddresses[i]));
+      new GetRemoteDevicePropertiesResultHandler(mGetDeviceRunnables,
+                                                 deviceAddresses[i]));
   }
 
   return NS_OK;
 }
 
 nsresult
 BluetoothServiceBluedroid::GetPairedDevicePropertiesInternal(
   const nsTArray<nsString>& aDeviceAddress, BluetoothReplyRunnable* aRunnable)
@@ -924,41 +916,45 @@ BluetoothServiceBluedroid::GetPairedDevi
   }
 #else
   if (requestedDeviceCount == 0) {
     DispatchReplySuccess(aRunnable, InfallibleTArray<BluetoothNamedValue>());
     return NS_OK;
   }
 
   sRequestedDeviceCountArray.AppendElement(requestedDeviceCount);
-  sGetDeviceRunnableArray.AppendElement(aRunnable);
+  mGetDeviceRunnables.AppendElement(aRunnable);
 #endif
 
   for (int i = 0; i < requestedDeviceCount; i++) {
     // Retrieve all properties of devices
     sBtInterface->GetRemoteDeviceProperties(aDeviceAddress[i],
-      new GetRemoteDevicePropertiesResultHandler(aDeviceAddress[i]));
+      new GetRemoteDevicePropertiesResultHandler(mGetDeviceRunnables,
+                                                 aDeviceAddress[i]));
   }
 
   return NS_OK;
 }
 
 class BluetoothServiceBluedroid::StartDiscoveryResultHandler final
   : public BluetoothResultHandler
 {
 public:
-  StartDiscoveryResultHandler(BluetoothReplyRunnable* aRunnable)
-  : mRunnable(aRunnable)
+  StartDiscoveryResultHandler(
+    nsTArray<nsRefPtr<BluetoothReplyRunnable>>& aRunnableArray,
+    BluetoothReplyRunnable* aRunnable)
+  : mRunnableArray(aRunnableArray)
+  , mRunnable(aRunnable)
   { }
 
 #ifndef MOZ_B2G_BT_API_V1
   void OnError(BluetoothStatus aStatus) override
   {
     MOZ_ASSERT(NS_IsMainThread());
-    sChangeDiscoveryRunnableArray.RemoveElement(mRunnable);
+    mRunnableArray.RemoveElement(mRunnable);
     DispatchReplyError(mRunnable, aStatus);
   }
 #else
   void StartDiscovery() override
   {
     MOZ_ASSERT(NS_IsMainThread());
     DispatchReplySuccess(mRunnable);
   }
@@ -966,48 +962,53 @@ public:
   void OnError(BluetoothStatus aStatus) override
   {
     MOZ_ASSERT(NS_IsMainThread());
     ReplyStatusError(mRunnable, aStatus, NS_LITERAL_STRING("StartDiscovery"));
   }
 #endif
 
 private:
+  nsTArray<nsRefPtr<BluetoothReplyRunnable>> mRunnableArray;
   BluetoothReplyRunnable* mRunnable;
 };
 
 void
 BluetoothServiceBluedroid::StartDiscoveryInternal(
   BluetoothReplyRunnable* aRunnable)
 {
   MOZ_ASSERT(NS_IsMainThread());
   ENSURE_BLUETOOTH_IS_READY_VOID(aRunnable);
 
 #ifndef MOZ_B2G_BT_API_V1
-  sChangeDiscoveryRunnableArray.AppendElement(aRunnable);
+  mChangeDiscoveryRunnables.AppendElement(aRunnable);
+  sBtInterface->StartDiscovery(
+    new StartDiscoveryResultHandler(mChangeDiscoveryRunnables, aRunnable));
 #else
-  // Missing in bluetooth1
+  sBtInterface->StartDiscovery(
+    new StartDiscoveryResultHandler(nullptr, aRunnable));
 #endif
-
-  sBtInterface->StartDiscovery(new StartDiscoveryResultHandler(aRunnable));
 }
 
 class BluetoothServiceBluedroid::CancelDiscoveryResultHandler final
   : public BluetoothResultHandler
 {
 public:
-  CancelDiscoveryResultHandler(BluetoothReplyRunnable* aRunnable)
-  : mRunnable(aRunnable)
+  CancelDiscoveryResultHandler(
+    nsTArray<nsRefPtr<BluetoothReplyRunnable>>& aRunnableArray,
+    BluetoothReplyRunnable* aRunnable)
+  : mRunnableArray(aRunnableArray)
+  , mRunnable(aRunnable)
   { }
 
 #ifndef MOZ_B2G_BT_API_V1
   void OnError(BluetoothStatus aStatus) override
   {
     MOZ_ASSERT(NS_IsMainThread());
-    sChangeDiscoveryRunnableArray.RemoveElement(mRunnable);
+    mRunnableArray.RemoveElement(mRunnable);
     DispatchReplyError(mRunnable, aStatus);
   }
 #else
   void CancelDiscovery() override
   {
     MOZ_ASSERT(NS_IsMainThread());
     DispatchReplySuccess(mRunnable);
   }
@@ -1015,118 +1016,131 @@ public:
   void OnError(BluetoothStatus aStatus) override
   {
     MOZ_ASSERT(NS_IsMainThread());
     ReplyStatusError(mRunnable, aStatus, NS_LITERAL_STRING("StopDiscovery"));
   }
 #endif
 
 private:
+  nsTArray<nsRefPtr<BluetoothReplyRunnable>> mRunnableArray;
   BluetoothReplyRunnable* mRunnable;
 };
 
 #ifndef MOZ_B2G_BT_API_V1
 class BluetoothServiceBluedroid::GetRemoteServicesResultHandler final
   : public BluetoothResultHandler
 {
 public:
-  GetRemoteServicesResultHandler(BluetoothReplyRunnable* aRunnable)
-  : mRunnable(aRunnable)
+  GetRemoteServicesResultHandler(
+    nsTArray<nsRefPtr<BluetoothReplyRunnable>>& aRunnableArray,
+    BluetoothReplyRunnable* aRunnable)
+  : mRunnableArray(aRunnableArray)
+  , mRunnable(aRunnable)
   { }
 
   void OnError(BluetoothStatus aStatus) override
   {
     MOZ_ASSERT(NS_IsMainThread());
-    sFetchUuidsRunnableArray.RemoveElement(mRunnable);
+    mRunnableArray.RemoveElement(mRunnable);
     DispatchReplyError(mRunnable, aStatus);
   }
 
 private:
+  nsTArray<nsRefPtr<BluetoothReplyRunnable>> mRunnableArray;
   BluetoothReplyRunnable* mRunnable;
 };
 
 nsresult
 BluetoothServiceBluedroid::FetchUuidsInternal(
   const nsAString& aDeviceAddress, BluetoothReplyRunnable* aRunnable)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   ENSURE_BLUETOOTH_IS_READY(aRunnable, NS_OK);
 
   /*
    * get_remote_services request will not be performed by bluedroid
    * if it is currently discovering nearby remote devices.
    */
   if (mDiscovering) {
-    sBtInterface->CancelDiscovery(new CancelDiscoveryResultHandler(aRunnable));
+    sBtInterface->CancelDiscovery(
+      new CancelDiscoveryResultHandler(mChangeDiscoveryRunnables, aRunnable));
   }
 
-  sFetchUuidsRunnableArray.AppendElement(aRunnable);
+  mFetchUuidsRunnables.AppendElement(aRunnable);
 
   sBtInterface->GetRemoteServices(aDeviceAddress,
-    new GetRemoteServicesResultHandler(aRunnable));
+    new GetRemoteServicesResultHandler(mFetchUuidsRunnables, aRunnable));
 
   return NS_OK;
 }
 #else
 // Missing in bluetooth1
 #endif
 
 void
 BluetoothServiceBluedroid::StopDiscoveryInternal(
   BluetoothReplyRunnable* aRunnable)
 {
   MOZ_ASSERT(NS_IsMainThread());
   ENSURE_BLUETOOTH_IS_READY_VOID(aRunnable);
 
 #ifndef MOZ_B2G_BT_API_V1
-  sChangeDiscoveryRunnableArray.AppendElement(aRunnable);
+  mChangeDiscoveryRunnables.AppendElement(aRunnable);
+  sBtInterface->CancelDiscovery(
+    new CancelDiscoveryResultHandler(mChangeDiscoveryRunnables,
+                                     aRunnable));
 #else
-  // Missing in bluetooth1
+  sBtInterface->CancelDiscovery(
+    new CancelDiscoveryResultHandler(nullptr, aRunnable));
 #endif
-
-  sBtInterface->CancelDiscovery(new CancelDiscoveryResultHandler(aRunnable));
 }
 
 class BluetoothServiceBluedroid::SetAdapterPropertyResultHandler final
   : public BluetoothResultHandler
 {
 public:
-  SetAdapterPropertyResultHandler(BluetoothReplyRunnable* aRunnable)
-  : mRunnable(aRunnable)
+  SetAdapterPropertyResultHandler(
+    nsTArray<nsRefPtr<BluetoothReplyRunnable>>& aRunnableArray,
+    BluetoothReplyRunnable* aRunnable)
+  : mRunnableArray(aRunnableArray)
+  , mRunnable(aRunnable)
   { }
 
   void OnError(BluetoothStatus aStatus) override
   {
     MOZ_ASSERT(NS_IsMainThread());
 
 #ifndef MOZ_B2G_BT_API_V1
-    sSetPropertyRunnableArray.RemoveElement(mRunnable);
+    mRunnableArray.RemoveElement(mRunnable);
     DispatchReplyError(mRunnable, aStatus);
 #else
     ReplyStatusError(mRunnable, aStatus, NS_LITERAL_STRING("SetProperty"));
 #endif
   }
 private:
+  nsTArray<nsRefPtr<BluetoothReplyRunnable>> mRunnableArray;
   BluetoothReplyRunnable* mRunnable;
 };
 
 nsresult
 BluetoothServiceBluedroid::SetProperty(BluetoothObjectType aType,
                                        const BluetoothNamedValue& aValue,
                                        BluetoothReplyRunnable* aRunnable)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   ENSURE_BLUETOOTH_IS_READY(aRunnable, NS_OK);
 
-  sSetPropertyRunnableArray.AppendElement(aRunnable);
+  mSetAdapterPropertyRunnables.AppendElement(aRunnable);
 
   sBtInterface->SetAdapterProperty(aValue,
-    new SetAdapterPropertyResultHandler(aRunnable));
+    new SetAdapterPropertyResultHandler(mSetAdapterPropertyRunnables,
+                                        aRunnable));
 
   return NS_OK;
 }
 
 nsresult
 BluetoothServiceBluedroid::GetServiceChannel(
   const nsAString& aDeviceAddress,
   const nsAString& aServiceUuid,
@@ -1142,90 +1156,99 @@ BluetoothServiceBluedroid::UpdateSdpReco
 {
   return true;
 }
 
 class BluetoothServiceBluedroid::CreateBondResultHandler final
   : public BluetoothResultHandler
 {
 public:
-  CreateBondResultHandler(BluetoothReplyRunnable* aRunnable)
-  : mRunnable(aRunnable)
+  CreateBondResultHandler(
+    nsTArray<nsRefPtr<BluetoothReplyRunnable>>& aRunnableArray,
+    BluetoothReplyRunnable* aRunnable)
+  : mRunnableArray(aRunnableArray)
+  , mRunnable(aRunnable)
   {
     MOZ_ASSERT(mRunnable);
   }
 
   void OnError(BluetoothStatus aStatus) override
   {
-    sBondingRunnableArray.RemoveElement(mRunnable);
+    mRunnableArray.RemoveElement(mRunnable);
 
 #ifndef MOZ_B2G_BT_API_V1
     DispatchReplyError(mRunnable, aStatus);
 #else
     ReplyStatusError(mRunnable, aStatus, NS_LITERAL_STRING("CreatedPairedDevice"));
 #endif
   }
 
 private:
+  nsTArray<nsRefPtr<BluetoothReplyRunnable>> mRunnableArray;
   nsRefPtr<BluetoothReplyRunnable> mRunnable;
 };
 
 nsresult
 BluetoothServiceBluedroid::CreatePairedDeviceInternal(
   const nsAString& aDeviceAddress, int aTimeout,
   BluetoothReplyRunnable* aRunnable)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   ENSURE_BLUETOOTH_IS_READY(aRunnable, NS_OK);
 
-  sBondingRunnableArray.AppendElement(aRunnable);
+  mCreateBondRunnables.AppendElement(aRunnable);
 
   sBtInterface->CreateBond(aDeviceAddress, TRANSPORT_AUTO,
-                           new CreateBondResultHandler(aRunnable));
+    new CreateBondResultHandler(mCreateBondRunnables, aRunnable));
+
   return NS_OK;
 }
 
 class BluetoothServiceBluedroid::RemoveBondResultHandler final
   : public BluetoothResultHandler
 {
 public:
-  RemoveBondResultHandler(BluetoothReplyRunnable* aRunnable)
-  : mRunnable(aRunnable)
+  RemoveBondResultHandler(
+    nsTArray<nsRefPtr<BluetoothReplyRunnable>>& aRunnableArray,
+    BluetoothReplyRunnable* aRunnable)
+  : mRunnableArray(aRunnableArray)
+  , mRunnable(aRunnable)
   {
     MOZ_ASSERT(mRunnable);
   }
 
   void OnError(BluetoothStatus aStatus) override
   {
-    sUnbondingRunnableArray.RemoveElement(mRunnable);
+    mRunnableArray.RemoveElement(mRunnable);
 
 #ifndef MOZ_B2G_BT_API_V1
     DispatchReplyError(mRunnable, aStatus);
 #else
     ReplyStatusError(mRunnable, aStatus, NS_LITERAL_STRING("RemoveDevice"));
 #endif
   }
 
 private:
+  nsTArray<nsRefPtr<BluetoothReplyRunnable>> mRunnableArray;
   nsRefPtr<BluetoothReplyRunnable> mRunnable;
 };
 
 nsresult
 BluetoothServiceBluedroid::RemoveDeviceInternal(
   const nsAString& aDeviceAddress, BluetoothReplyRunnable* aRunnable)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   ENSURE_BLUETOOTH_IS_READY(aRunnable, NS_OK);
 
-  sUnbondingRunnableArray.AppendElement(aRunnable);
+  mRemoveBondRunnables.AppendElement(aRunnable);
 
   sBtInterface->RemoveBond(aDeviceAddress,
-                           new RemoveBondResultHandler(aRunnable));
+    new RemoveBondResultHandler(mRemoveBondRunnables, aRunnable));
 
   return NS_OK;
 }
 
 class BluetoothServiceBluedroid::PinReplyResultHandler final
   : public BluetoothResultHandler
 {
 public:
@@ -1416,18 +1439,18 @@ BluetoothServiceBluedroid::ConnectDiscon
 
   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
+   * If the request is the first element of the queue, start from here. Note
+   * that other requests are pushed into the queue and popped out after the
    * first one is completed. See NextBluetoothProfileController() for details.
    */
   if (sControllerArray.Length() == 1) {
     sControllerArray[0]->StartSession();
   }
 }
 
 void
@@ -1862,22 +1885,22 @@ BluetoothServiceBluedroid::AdapterStateC
     // We enable the Bluetooth adapter here. Disabling is implemented
     // in |CleanupResultHandler|, which runs at the end of the shutdown
     // procedure. We cannot disable the adapter immediately, because re-
     // enabling it might interfere with the shutdown procedure.
     BluetoothService::AcknowledgeToggleBt(true);
 
     // Bluetooth just enabled, clear profile controllers and runnable arrays.
     sControllerArray.Clear();
-    sChangeDiscoveryRunnableArray.Clear();
-    sSetPropertyRunnableArray.Clear();
-    sGetDeviceRunnableArray.Clear();
-    sFetchUuidsRunnableArray.Clear();
-    sBondingRunnableArray.Clear();
-    sUnbondingRunnableArray.Clear();
+    mChangeDiscoveryRunnables.Clear();
+    mSetAdapterPropertyRunnables.Clear();
+    mGetDeviceRunnables.Clear();
+    mFetchUuidsRunnables.Clear();
+    mCreateBondRunnables.Clear();
+    mRemoveBondRunnables.Clear();
     mDeviceNameMap.Clear();
 
     // Bluetooth scan mode is SCAN_MODE_CONNECTABLE by default, i.e., it should
     // be connectable and non-discoverable.
     NS_ENSURE_TRUE_VOID(sBtInterface);
     sBtInterface->SetAdapterProperty(
       BluetoothNamedValue(NS_ConvertUTF8toUTF16("Discoverable"), false),
       new SetAdapterPropertyDiscoverableResultHandler());
@@ -1890,19 +1913,19 @@ BluetoothServiceBluedroid::AdapterStateC
 
     BluetoothPbapManager* pbap = BluetoothPbapManager::Get();
     if (!pbap || !pbap->Listen()) {
       BT_LOGR("Fail to start BluetoothPbapManager listening");
     }
   }
 
   // Resolve promise if existed
-  if (!sChangeAdapterStateRunnableArray.IsEmpty()) {
-    DispatchReplySuccess(sChangeAdapterStateRunnableArray[0]);
-    sChangeAdapterStateRunnableArray.RemoveElementAt(0);
+  if (!mChangeAdapterStateRunnables.IsEmpty()) {
+    DispatchReplySuccess(mChangeAdapterStateRunnables[0]);
+    mChangeAdapterStateRunnables.RemoveElementAt(0);
   }
 
   // After ProfileManagers deinit and cleanup, now restart bluetooth daemon
   if (mIsRestart && !aState) {
     BT_LOGR("mIsRestart and off, now restart");
     StartBluetooth(false, nullptr);
   }
 
@@ -1939,20 +1962,20 @@ BluetoothServiceBluedroid::AdapterStateC
     }
   }
 
   BluetoothService::AcknowledgeToggleBt(isBtEnabled);
 
   if (isBtEnabled) {
     // Bluetooth just enabled, clear profile controllers and runnable arrays.
     sControllerArray.Clear();
-    sBondingRunnableArray.Clear();
-    sGetDeviceRunnableArray.Clear();
-    sSetPropertyRunnableArray.Clear();
-    sUnbondingRunnableArray.Clear();
+    mCreateBondRunnables.Clear();
+    mGetDeviceRunnables.Clear();
+    mSetAdapterPropertyRunnables.Clear();
+    mRemoveBondRunnables.Clear();
 
     // Bluetooth scan mode is SCAN_MODE_CONNECTABLE by default, i.e., It should
     // be connectable and non-discoverable.
     NS_ENSURE_TRUE_VOID(sBtInterface);
     sBtInterface->SetAdapterProperty(
       BluetoothNamedValue(NS_ConvertUTF8toUTF16("Discoverable"), false),
       new SetAdapterPropertyDiscoverableResultHandler());
 
@@ -2043,19 +2066,19 @@ BluetoothServiceBluedroid::AdapterProper
 
   NS_ENSURE_TRUE_VOID(propertiesArray.Length() > 0);
 
   DistributeSignal(NS_LITERAL_STRING("PropertyChanged"),
                    NS_LITERAL_STRING(KEY_ADAPTER),
                    BluetoothValue(propertiesArray));
 
   // Send reply for SetProperty
-  if (!sSetPropertyRunnableArray.IsEmpty()) {
-    DispatchReplySuccess(sSetPropertyRunnableArray[0]);
-    sSetPropertyRunnableArray.RemoveElementAt(0);
+  if (!mSetAdapterPropertyRunnables.IsEmpty()) {
+    DispatchReplySuccess(mSetAdapterPropertyRunnables[0]);
+    mSetAdapterPropertyRunnables.RemoveElementAt(0);
   }
 #else
   MOZ_ASSERT(NS_IsMainThread());
 
   InfallibleTArray<BluetoothNamedValue> props;
 
   for (int i = 0; i < aNumProperties; i++) {
 
@@ -2111,19 +2134,19 @@ BluetoothServiceBluedroid::AdapterProper
 
   NS_ENSURE_TRUE_VOID(props.Length() > 0);
 
   DistributeSignal(BluetoothSignal(NS_LITERAL_STRING("PropertyChanged"),
                                    NS_LITERAL_STRING(KEY_ADAPTER),
                                    BluetoothValue(props)));
 
   // Send reply for SetProperty
-  if (!sSetPropertyRunnableArray.IsEmpty()) {
-    DispatchReplySuccess(sSetPropertyRunnableArray[0]);
-    sSetPropertyRunnableArray.RemoveElementAt(0);
+  if (!mSetAdapterPropertyRunnables.IsEmpty()) {
+    DispatchReplySuccess(mSetAdapterPropertyRunnables[0]);
+    mSetAdapterPropertyRunnables.RemoveElementAt(0);
   }
 #endif
 }
 
 /**
  * RemoteDevicePropertiesNotification will be called
  *
  *   (1) automatically by Bluedroid when BT is turning on, or
@@ -2195,21 +2218,21 @@ BluetoothServiceBluedroid::RemoteDeviceP
   // can exchange |DispatchReplySuccess| with other operations without
   // changing the order of (1,2) and (3).
 
   // Update to registered BluetoothDevice objects
   BluetoothSignal signal(NS_LITERAL_STRING("PropertyChanged"),
                          nsString(aBdAddr), propertiesArray);
 
   // FetchUuids task
-  if (!sFetchUuidsRunnableArray.IsEmpty()) {
+  if (!mFetchUuidsRunnables.IsEmpty()) {
     // propertiesArray contains Address and Uuids only
-    DispatchReplySuccess(sFetchUuidsRunnableArray[0],
+    DispatchReplySuccess(mFetchUuidsRunnables[0],
                          propertiesArray[1].value()); /* Uuids */
-    sFetchUuidsRunnableArray.RemoveElementAt(0);
+    mFetchUuidsRunnables.RemoveElementAt(0);
     DistributeSignal(signal);
     return;
   }
 
   // GetDevices task
   if (sRequestedDeviceCountArray.IsEmpty()) {
     // This is possible because the callback would be called after turning
     // Bluetooth on.
@@ -2217,19 +2240,19 @@ BluetoothServiceBluedroid::RemoteDeviceP
     return;
   }
 
   // Use address as the index
   sRemoteDevicesPack.AppendElement(
     BluetoothNamedValue(nsString(aBdAddr), propertiesArray));
 
   if (--sRequestedDeviceCountArray[0] == 0) {
-    if (!sGetDeviceRunnableArray.IsEmpty()) {
-      DispatchReplySuccess(sGetDeviceRunnableArray[0], sRemoteDevicesPack);
-      sGetDeviceRunnableArray.RemoveElementAt(0);
+    if (!mGetDeviceRunnables.IsEmpty()) {
+      DispatchReplySuccess(mGetDeviceRunnables[0], sRemoteDevicesPack);
+      mGetDeviceRunnables.RemoveElementAt(0);
     }
 
     sRequestedDeviceCountArray.RemoveElementAt(0);
     sRemoteDevicesPack.Clear();
   }
 
   DistributeSignal(signal);
 #else
@@ -2322,19 +2345,19 @@ BluetoothServiceBluedroid::RemoteDeviceP
     return;
   }
 
   // Use address as the index
   sRemoteDevicesPack.AppendElement(
     BluetoothNamedValue(nsString(aBdAddr), props));
 
   if (--sRequestedDeviceCountArray[0] == 0) {
-    if (!sGetDeviceRunnableArray.IsEmpty()) {
-      DispatchReplySuccess(sGetDeviceRunnableArray[0], sRemoteDevicesPack);
-      sGetDeviceRunnableArray.RemoveElementAt(0);
+    if (!mGetDeviceRunnables.IsEmpty()) {
+      DispatchReplySuccess(mGetDeviceRunnables[0], sRemoteDevicesPack);
+      mGetDeviceRunnables.RemoveElementAt(0);
     }
 
     sRequestedDeviceCountArray.RemoveElementAt(0);
     sRemoteDevicesPack.Clear();
   }
 
   // Update to registered BluetoothDevice objects
   DistributeSignal(BluetoothSignal(NS_LITERAL_STRING("PropertyChanged"),
@@ -2448,19 +2471,19 @@ BluetoothServiceBluedroid::DiscoveryStat
   InfallibleTArray<BluetoothNamedValue> propertiesArray;
   BT_APPEND_NAMED_VALUE(propertiesArray, "Discovering", mDiscovering);
 
   DistributeSignal(NS_LITERAL_STRING("PropertyChanged"),
                    NS_LITERAL_STRING(KEY_ADAPTER),
                    BluetoothValue(propertiesArray));
 
   // Reply that Promise is resolved
-  if (!sChangeDiscoveryRunnableArray.IsEmpty()) {
-    DispatchReplySuccess(sChangeDiscoveryRunnableArray[0]);
-    sChangeDiscoveryRunnableArray.RemoveElementAt(0);
+  if (!mChangeDiscoveryRunnables.IsEmpty()) {
+    DispatchReplySuccess(mChangeDiscoveryRunnables[0]);
+    mChangeDiscoveryRunnables.RemoveElementAt(0);
   }
 #else
   MOZ_ASSERT(NS_IsMainThread());
 
   mDiscovering = aState;
 
   DistributeSignal(
     BluetoothSignal(NS_LITERAL_STRING(DISCOVERY_STATE_CHANGED_ID),
@@ -2613,24 +2636,24 @@ BluetoothServiceBluedroid::BondStateChan
     if (!bonded) { // Active/passive pair failed
       BT_LOGR("Pair failed! Abort pairing.");
 
       // Notify adapter of pairing aborted
       DistributeSignal(NS_LITERAL_STRING(PAIRING_ABORTED_ID),
                        NS_LITERAL_STRING(KEY_ADAPTER));
 
       // Reject pair promise
-      if (!sBondingRunnableArray.IsEmpty()) {
-        DispatchReplyError(sBondingRunnableArray[0], aStatus);
-        sBondingRunnableArray.RemoveElementAt(0);
+      if (!mCreateBondRunnables.IsEmpty()) {
+        DispatchReplyError(mCreateBondRunnables[0], aStatus);
+        mCreateBondRunnables.RemoveElementAt(0);
       }
-    } else if (!sUnbondingRunnableArray.IsEmpty()) { // Active unpair failed
+    } else if (!mRemoveBondRunnables.IsEmpty()) { // Active unpair failed
       // Reject unpair promise
-      DispatchReplyError(sUnbondingRunnableArray[0], aStatus);
-      sUnbondingRunnableArray.RemoveElementAt(0);
+      DispatchReplyError(mRemoveBondRunnables[0], aStatus);
+      mRemoveBondRunnables.RemoveElementAt(0);
     }
 
     return;
   }
 
   // Query pairing device name from hash table
   nsString remoteBdAddr(aRemoteBdAddr);
   nsString remotebdName;
@@ -2661,22 +2684,22 @@ BluetoothServiceBluedroid::BondStateChan
   // Notify adapter of device paired/unpaired
   BT_INSERT_NAMED_VALUE(propertiesArray, 0, "Address", remoteBdAddr);
   DistributeSignal(bonded ? NS_LITERAL_STRING(DEVICE_PAIRED_ID)
                           : NS_LITERAL_STRING(DEVICE_UNPAIRED_ID),
                    NS_LITERAL_STRING(KEY_ADAPTER),
                    BluetoothValue(propertiesArray));
 
   // Resolve existing pair/unpair promise
-  if (bonded && !sBondingRunnableArray.IsEmpty()) {
-    DispatchReplySuccess(sBondingRunnableArray[0]);
-    sBondingRunnableArray.RemoveElementAt(0);
-  } else if (!bonded && !sUnbondingRunnableArray.IsEmpty()) {
-    DispatchReplySuccess(sUnbondingRunnableArray[0]);
-    sUnbondingRunnableArray.RemoveElementAt(0);
+  if (bonded && !mCreateBondRunnables.IsEmpty()) {
+    DispatchReplySuccess(mCreateBondRunnables[0]);
+    mCreateBondRunnables.RemoveElementAt(0);
+  } else if (!bonded && !mRemoveBondRunnables.IsEmpty()) {
+    DispatchReplySuccess(mRemoveBondRunnables[0]);
+    mRemoveBondRunnables.RemoveElementAt(0);
   }
 #else
   if (aState == BOND_STATE_BONDED &&
       mBondedAddresses.Contains(aRemoteBdAddr)) {
     // See bug 940271 for more details about this case.
     return;
   }
 
@@ -2698,24 +2721,24 @@ BluetoothServiceBluedroid::BondStateChan
       InfallibleTArray<BluetoothNamedValue> propertiesChangeArray;
       BT_APPEND_NAMED_VALUE(propertiesChangeArray, "Devices",
                             mBondedAddresses);
 
       DistributeSignal(BluetoothSignal(NS_LITERAL_STRING("PropertyChanged"),
                                        NS_LITERAL_STRING(KEY_ADAPTER),
                                        BluetoothValue(propertiesChangeArray)));
 
-      if (bonded && !sBondingRunnableArray.IsEmpty()) {
-        DispatchReplySuccess(sBondingRunnableArray[0]);
-
-        sBondingRunnableArray.RemoveElementAt(0);
-      } else if (!bonded && !sUnbondingRunnableArray.IsEmpty()) {
-        DispatchReplySuccess(sUnbondingRunnableArray[0]);
-
-        sUnbondingRunnableArray.RemoveElementAt(0);
+      if (bonded && !mCreateBondRunnables.IsEmpty()) {
+        DispatchReplySuccess(mCreateBondRunnables[0]);
+
+        mCreateBondRunnables.RemoveElementAt(0);
+      } else if (!bonded && !mRemoveBondRunnables.IsEmpty()) {
+        DispatchReplySuccess(mRemoveBondRunnables[0]);
+
+        mRemoveBondRunnables.RemoveElementAt(0);
       }
 
       // Update bonding status to gaia
       InfallibleTArray<BluetoothNamedValue> propertiesArray;
       BT_APPEND_NAMED_VALUE(propertiesArray, "address", nsString(aRemoteBdAddr));
       BT_APPEND_NAMED_VALUE(propertiesArray, "status", bonded);
 
       DistributeSignal(
@@ -2728,30 +2751,30 @@ BluetoothServiceBluedroid::BondStateChan
     case STATUS_AUTH_FAILURE:
     case STATUS_RMT_DEV_DOWN:
     {
       InfallibleTArray<BluetoothNamedValue> propertiesArray;
       DistributeSignal(BluetoothSignal(NS_LITERAL_STRING("Cancel"),
                                  NS_LITERAL_STRING(KEY_LOCAL_AGENT),
                                  BluetoothValue(propertiesArray)));
 
-      if (!sBondingRunnableArray.IsEmpty()) {
-        DispatchReplyError(sBondingRunnableArray[0],
+      if (!mCreateBondRunnables.IsEmpty()) {
+        DispatchReplyError(mCreateBondRunnables[0],
                            NS_LITERAL_STRING("Authentication failure"));
-        sBondingRunnableArray.RemoveElementAt(0);
+        mCreateBondRunnables.RemoveElementAt(0);
       }
       break;
     }
     default:
       BT_WARNING("Got an unhandled status of BondStateChangedCallback!");
       // Dispatch a reply to unblock the waiting status of pairing.
-      if (!sBondingRunnableArray.IsEmpty()) {
-        DispatchReplyError(sBondingRunnableArray[0],
+      if (!mCreateBondRunnables.IsEmpty()) {
+        DispatchReplyError(mCreateBondRunnables[0],
                            NS_LITERAL_STRING("Internal failure"));
-        sBondingRunnableArray.RemoveElementAt(0);
+        mCreateBondRunnables.RemoveElementAt(0);
       }
       break;
   }
 #endif
 }
 
 void
 BluetoothServiceBluedroid::AclStateChangedNotification(
--- a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.h
+++ b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.h
@@ -406,17 +406,27 @@ protected:
 #else
   uint32_t mDiscoverableTimeout;
 #endif
 
   // Backend error recovery
   bool mIsRestart;
   bool mIsFirstTimeToggleOffBt;
 
+  // Runnable arrays
+  nsTArray<nsRefPtr<BluetoothReplyRunnable>> mSetAdapterPropertyRunnables;
+  nsTArray<nsRefPtr<BluetoothReplyRunnable>> mGetDeviceRunnables;
+  nsTArray<nsRefPtr<BluetoothReplyRunnable>> mCreateBondRunnables;
+  nsTArray<nsRefPtr<BluetoothReplyRunnable>> mRemoveBondRunnables;
+
 #ifndef MOZ_B2G_BT_API_V1
+  nsTArray<nsRefPtr<BluetoothReplyRunnable>> mChangeAdapterStateRunnables;
+  nsTArray<nsRefPtr<BluetoothReplyRunnable>> mChangeDiscoveryRunnables;
+  nsTArray<nsRefPtr<BluetoothReplyRunnable>> mFetchUuidsRunnables;
+
   // <address, name> mapping table for remote devices
   nsDataHashtable<nsStringHashKey, nsString> mDeviceNameMap;
 #endif
 
 };
 
 END_BLUETOOTH_NAMESPACE