Bug 913372 - Patch 2: Set mController to null before invoking callback function, r=echou
☠☠ backed out by 87424d2c2a6e ☠ ☠
authorGina Yeh <gyeh@mozilla.com>
Fri, 25 Oct 2013 14:21:56 +0800
changeset 166930 cfd0b69ef12b44681c7546a14a5d7aecb6293851
parent 166929 704e9cae5ed6ff6b72464db9a815d3c254e01e5c
child 166931 10ad5c75e10227caf1a9d6b22d629fac74518e15
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 2: Set mController to null before invoking callback function, r=echou For each profile manager, we'd like to make sure that the data member of mController is nulled out before invoking the callback function. Because, in the callback function, we continue to handle the next connect/disconnect request, and we'd like to null out mController of previous request before handling the new one.
dom/bluetooth/BluetoothA2dpManager.cpp
dom/bluetooth/BluetoothHfpManager.cpp
dom/bluetooth/BluetoothHfpManager.h
dom/bluetooth/BluetoothHidManager.cpp
dom/bluetooth/BluetoothOppManager.cpp
dom/bluetooth/BluetoothOppManager.h
--- a/dom/bluetooth/BluetoothA2dpManager.cpp
+++ b/dom/bluetooth/BluetoothA2dpManager.cpp
@@ -202,33 +202,33 @@ BluetoothA2dpManager::OnConnect(const ns
   MOZ_ASSERT(NS_IsMainThread());
 
   /**
    * On the one hand, notify the controller that we've done for outbound
    * connections. On the other hand, we do nothing for inbound connections.
    */
   NS_ENSURE_TRUE_VOID(mController);
 
-  mController->OnConnect(aErrorStr);
-  mController = nullptr;
+  nsRefPtr<BluetoothProfileController> controller = mController.forget();
+  controller->OnConnect(aErrorStr);
 }
 
 void
 BluetoothA2dpManager::OnDisconnect(const nsAString& aErrorStr)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   /**
    * On the one hand, notify the controller that we've done for outbound
    * connections. On the other hand, we do nothing for inbound connections.
    */
   NS_ENSURE_TRUE_VOID(mController);
 
-  mController->OnDisconnect(aErrorStr);
-  mController = nullptr;
+  nsRefPtr<BluetoothProfileController> controller = mController.forget();
+  controller->OnDisconnect(aErrorStr);
 }
 
 /* HandleSinkPropertyChanged update sink state in A2dp
  *
  * Possible values: "disconnected", "disconnecting",
  *                  "connecting", "connected",
  *                  "playing"
  *
--- a/dom/bluetooth/BluetoothHfpManager.cpp
+++ b/dom/bluetooth/BluetoothHfpManager.cpp
@@ -337,17 +337,17 @@ Call::IsActive()
 {
   return (mState == nsITelephonyProvider::CALL_STATE_CONNECTED);
 }
 #endif // MOZ_B2G_RIL
 
 /**
  *  BluetoothHfpManager
  */
-BluetoothHfpManager::BluetoothHfpManager()
+BluetoothHfpManager::BluetoothHfpManager() : mController(nullptr)
 {
   Reset();
 }
 
 #ifdef MOZ_B2G_RIL
 void
 BluetoothHfpManager::ResetCallArray()
 {
@@ -387,21 +387,17 @@ BluetoothHfpManager::Reset()
 
 #ifdef MOZ_B2G_RIL
   // We disable BSIR by default as it requires OEM implement BT SCO + SPEAKER
   // output audio path in audio driver. OEM can enable BSIR by setting
   // mBSIR=true here.
   //
   // Please see Bug 878728 for more information.
   mBSIR = false;
-#endif
 
-  mController = nullptr;
-
-#ifdef MOZ_B2G_RIL
   ResetCallArray();
 #endif
 }
 
 bool
 BluetoothHfpManager::Init()
 {
   MOZ_ASSERT(NS_IsMainThread());
@@ -1138,17 +1134,16 @@ BluetoothHfpManager::Disconnect(Bluetoot
     }
     return;
   }
 
   MOZ_ASSERT(!mController);
 
   mController = aController;
   mSocket->Disconnect();
-  mSocket = nullptr;
 }
 
 #ifdef MOZ_B2G_RIL
 void
 BluetoothHfpManager::SendCCWA(const nsAString& aNumber, int aType)
 {
   if (mCCWA) {
     nsAutoCString ccwaMsg("+CCWA: \"");
@@ -1705,16 +1700,18 @@ BluetoothHfpManager::OnGetServiceChannel
     } else if (NS_FAILED(bs->GetServiceChannel(aDeviceAddress,
                                                hspUuid, this))) {
       OnConnect(NS_LITERAL_STRING(ERR_NO_AVAILABLE_RESOURCE));
     }
 
     return;
   }
 
+  MOZ_ASSERT(mSocket);
+
   if (!mSocket->Connect(NS_ConvertUTF16toUTF8(aDeviceAddress), aChannel)) {
     OnConnect(NS_LITERAL_STRING("SocketConnectionError"));
   }
 }
 
 void
 BluetoothHfpManager::OnScoConnectSuccess()
 {
@@ -1867,18 +1864,18 @@ BluetoothHfpManager::OnConnect(const nsA
   }
 
   /**
    * On the one hand, notify the controller that we've done for outbound
    * connections. On the other hand, we do nothing for inbound connections.
    */
   NS_ENSURE_TRUE_VOID(mController);
 
-  mController->OnConnect(aErrorStr);
-  mController = nullptr;
+  nsRefPtr<BluetoothProfileController> controller = mController.forget();
+  controller->OnConnect(aErrorStr);
 }
 
 void
 BluetoothHfpManager::OnDisconnect(const nsAString& aErrorStr)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   // Start listening
@@ -1886,13 +1883,13 @@ BluetoothHfpManager::OnDisconnect(const 
   Listen();
 
   /**
    * On the one hand, notify the controller that we've done for outbound
    * connections. On the other hand, we do nothing for inbound connections.
    */
   NS_ENSURE_TRUE_VOID(mController);
 
-  mController->OnDisconnect(aErrorStr);
-  mController = nullptr;
+  nsRefPtr<BluetoothProfileController> controller = mController.forget();
+  controller->OnDisconnect(aErrorStr);
 }
 
 NS_IMPL_ISUPPORTS1(BluetoothHfpManager, nsIObserver)
--- a/dom/bluetooth/BluetoothHfpManager.h
+++ b/dom/bluetooth/BluetoothHfpManager.h
@@ -203,17 +203,16 @@ private:
   nsString mDeviceAddress;
 #ifdef MOZ_B2G_RIL
   nsString mMsisdn;
   nsString mOperatorName;
 
   nsTArray<Call> mCurrentCallArray;
   nsAutoPtr<BluetoothRilListener> mListener;
 #endif
-  nsRefPtr<BluetoothReplyRunnable> mRunnable;
   nsRefPtr<BluetoothProfileController> mController;
   nsRefPtr<BluetoothReplyRunnable> mScoRunnable;
 
   // If a connection has been established, mSocket will be the socket
   // communicating with the remote socket. We maintain the invariant that if
   // mSocket is non-null, mHandsfreeSocket and mHeadsetSocket must be null (and
   // vice versa).
   nsRefPtr<BluetoothSocket> mSocket;
--- a/dom/bluetooth/BluetoothHidManager.cpp
+++ b/dom/bluetooth/BluetoothHidManager.cpp
@@ -162,33 +162,33 @@ BluetoothHidManager::OnConnect(const nsA
   MOZ_ASSERT(NS_IsMainThread());
 
   /**
    * On the one hand, notify the controller that we've done for outbound
    * connections. On the other hand, we do nothing for inbound connections.
    */
   NS_ENSURE_TRUE_VOID(mController);
 
-  mController->OnConnect(aErrorStr);
-  mController = nullptr;
+  nsRefPtr<BluetoothProfileController> controller = mController.forget();
+  controller->OnConnect(aErrorStr);
 }
 
 void
 BluetoothHidManager::OnDisconnect(const nsAString& aErrorStr)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   /**
    * On the one hand, notify the controller that we've done for outbound
    * connections. On the other hand, we do nothing for inbound connections.
    */
   NS_ENSURE_TRUE_VOID(mController);
 
-  mController->OnDisconnect(aErrorStr);
-  mController = nullptr;
+  nsRefPtr<BluetoothProfileController> controller = mController.forget();
+  controller->OnDisconnect(aErrorStr);
 }
 
 bool
 BluetoothHidManager::IsConnected()
 {
   return mConnected;
 }
 
--- a/dom/bluetooth/BluetoothOppManager.cpp
+++ b/dom/bluetooth/BluetoothOppManager.cpp
@@ -286,17 +286,16 @@ BluetoothOppManager::Disconnect(Bluetoot
     }
     return;
   }
 
   MOZ_ASSERT(!mController);
 
   mController = aController;
   mSocket->Disconnect();
-  mSocket = nullptr;
 }
 
 void
 BluetoothOppManager::HandleShutdown()
 {
   MOZ_ASSERT(NS_IsMainThread());
   sInShutdown = true;
   Disconnect(nullptr);
@@ -1478,29 +1477,29 @@ BluetoothOppManager::OnConnect(const nsA
   }
 
   /**
    * On the one hand, notify the controller that we've done for outbound
    * connections. On the other hand, we do nothing for inbound connections.
    */
   NS_ENSURE_TRUE_VOID(mController);
 
-  mController->OnConnect(aErrorStr);
-  mController = nullptr;
+  nsRefPtr<BluetoothProfileController> controller = mController.forget();
+  controller->OnConnect(aErrorStr);
 }
 
 void
 BluetoothOppManager::OnDisconnect(const nsAString& aErrorStr)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   mSocket = nullptr;
   Listen();
 
   /**
    * On the one hand, notify the controller that we've done for outbound
    * connections. On the other hand, we do nothing for inbound connections.
    */
   NS_ENSURE_TRUE_VOID(mController);
 
-  mController->OnDisconnect(aErrorStr);
-  mController = nullptr;
+  nsRefPtr<BluetoothProfileController> controller = mController.forget();
+  controller->OnDisconnect(aErrorStr);
 }
--- a/dom/bluetooth/BluetoothOppManager.h
+++ b/dom/bluetooth/BluetoothOppManager.h
@@ -16,17 +16,16 @@
 #include "nsCOMArray.h"
 
 class nsIOutputStream;
 class nsIInputStream;
 class nsIVolumeMountLock;
 
 BEGIN_BLUETOOTH_NAMESPACE
 
-class BluetoothReplyRunnable;
 class BluetoothSocket;
 class ObexHeaderSet;
 
 class BluetoothOppManager : public BluetoothSocketObserver
                           , public BluetoothProfileManagerBase
 {
 public:
   NS_DECL_ISUPPORTS
@@ -213,17 +212,16 @@ private:
   /**
    * A seperate member thread is required because our read calls can block
    * execution, which is not allowed to happen on the IOThread.
    */
   nsCOMPtr<nsIThread> mReadFileThread;
   nsCOMPtr<nsIOutputStream> mOutputStream;
   nsCOMPtr<nsIInputStream> mInputStream;
   nsCOMPtr<nsIVolumeMountLock> mMountLock;
-  nsRefPtr<BluetoothReplyRunnable> mRunnable;
   nsRefPtr<BluetoothProfileController> mController;
   nsRefPtr<DeviceStorageFile> mDsFile;
 
   // If a connection has been established, mSocket will be the socket
   // communicating with the remote socket. We maintain the invariant that if
   // mSocket is non-null, mRfcommSocket and mL2capSocket must be null (and vice
   // versa).
   nsRefPtr<BluetoothSocket> mSocket;