Bug 1195729: Fix ref-counting of Bluetooth result handlers for failed send operations, r=brsun
authorThomas Zimmermann <tdz@users.sourceforge.net>
Mon, 24 Aug 2015 15:21:38 +0200
changeset 258959 f31e07e4ce38e46916d97c3026c7b8016bb88d3a
parent 258958 15d7e071384cc59cf1c0fc3f242230de0b243066
child 258960 1bc0550f786eb5383b1c40470f940be4b5d78b0f
push id29267
push userryanvm@gmail.com
push dateTue, 25 Aug 2015 00:33:40 +0000
treeherdermozilla-central@ef0614cdd437 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbrsun
bugs1195729
milestone43.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 1195729: Fix ref-counting of Bluetooth result handlers for failed send operations, r=brsun Usually references to Bluetooth result handlers are kept until the command's response has been received and the result handler ran. If sending the command fails, the extra reference has to be dropped. With this patch, Gecko will correctly dereference Bluetooth result handlers when send operations fail. Thanks to Bruce Sun for finding this bug.
dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.cpp
dom/bluetooth/bluedroid/BluetoothDaemonAvrcpInterface.cpp
dom/bluetooth/bluedroid/BluetoothDaemonGattInterface.cpp
dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.cpp
dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp
dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.cpp
--- a/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.cpp
@@ -27,18 +27,23 @@ BluetoothDaemonA2dpModule::SetNotificati
 {
   sNotificationHandler = aNotificationHandler;
 }
 
 nsresult
 BluetoothDaemonA2dpModule::Send(DaemonSocketPDU* aPDU,
                                 BluetoothA2dpResultHandler* aRes)
 {
-  aRes->AddRef(); // Keep reference for response
-  return Send(aPDU, static_cast<void*>(aRes));
+  nsRefPtr<BluetoothA2dpResultHandler> res(aRes);
+  nsresult rv = Send(aPDU, static_cast<void*>(res.get()));
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  unused << res.forget(); // Keep reference for response
+  return NS_OK;
 }
 
 void
 BluetoothDaemonA2dpModule::HandleSvc(const DaemonSocketPDUHeader& aHeader,
                                      DaemonSocketPDU& aPDU, void* aUserData)
 {
   static void (BluetoothDaemonA2dpModule::* const HandleOp[])(
     const DaemonSocketPDUHeader&, DaemonSocketPDU&, void*) = {
--- a/dom/bluetooth/bluedroid/BluetoothDaemonAvrcpInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonAvrcpInterface.cpp
@@ -27,20 +27,23 @@ BluetoothDaemonAvrcpModule::SetNotificat
 {
   sNotificationHandler = aNotificationHandler;
 }
 
 nsresult
 BluetoothDaemonAvrcpModule::Send(DaemonSocketPDU* aPDU,
                                  BluetoothAvrcpResultHandler* aRes)
 {
-  if (aRes) {
-    aRes->AddRef(); // Keep reference for response
+  nsRefPtr<BluetoothAvrcpResultHandler> res(aRes);
+  nsresult rv = Send(aPDU, static_cast<void*>(res.get()));
+  if (NS_FAILED(rv)) {
+    return rv;
   }
-  return Send(aPDU, static_cast<void*>(aRes));
+  unused << res.forget(); // Keep reference for response
+  return NS_OK;
 }
 
 void
 BluetoothDaemonAvrcpModule::HandleSvc(const DaemonSocketPDUHeader& aHeader,
                                       DaemonSocketPDU& aPDU, void* aUserData)
 {
   static void (BluetoothDaemonAvrcpModule::* const HandleOp[])(
     const DaemonSocketPDUHeader&, DaemonSocketPDU&, void*) = {
--- a/dom/bluetooth/bluedroid/BluetoothDaemonGattInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonGattInterface.cpp
@@ -27,20 +27,23 @@ BluetoothDaemonGattModule::SetNotificati
 {
   sNotificationHandler = aNotificationHandler;
 }
 
 nsresult
 BluetoothDaemonGattModule::Send(DaemonSocketPDU* aPDU,
                                 BluetoothGattResultHandler* aRes)
 {
-  if (aRes) {
-    aRes->AddRef(); // Keep reference for response
+  nsRefPtr<BluetoothGattResultHandler> res(aRes);
+  nsresult rv = Send(aPDU, static_cast<void*>(res.get()));
+  if (NS_FAILED(rv)) {
+    return rv;
   }
-  return Send(aPDU, static_cast<void*>(aRes));
+  unused << res.forget(); // Keep reference for response
+  return NS_OK;
 }
 
 void
 BluetoothDaemonGattModule::HandleSvc(const DaemonSocketPDUHeader& aHeader,
                                      DaemonSocketPDU& aPDU, void* aUserData)
 {
   static void (BluetoothDaemonGattModule::* const HandleOp[])(
     const DaemonSocketPDUHeader&, DaemonSocketPDU&, void*) = {
--- a/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.cpp
@@ -30,18 +30,23 @@ BluetoothDaemonHandsfreeModule::SetNotif
 {
   sNotificationHandler = aNotificationHandler;
 }
 
 nsresult
 BluetoothDaemonHandsfreeModule::Send(DaemonSocketPDU* aPDU,
                                      BluetoothHandsfreeResultHandler* aRes)
 {
-  aRes->AddRef(); // Keep reference for response
-  return Send(aPDU, static_cast<void*>(aRes));
+  nsRefPtr<BluetoothHandsfreeResultHandler> res(aRes);
+  nsresult rv = Send(aPDU, static_cast<void*>(res.get()));
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  unused << res.forget(); // Keep reference for response
+  return NS_OK;
 }
 
 void
 BluetoothDaemonHandsfreeModule::HandleSvc(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU, void* aUserData)
 {
   static void (BluetoothDaemonHandsfreeModule::* const HandleOp[])(
     const DaemonSocketPDUHeader&, DaemonSocketPDU&, void*) = {
--- a/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp
@@ -132,18 +132,23 @@ protected:
       return; // Return early if no result handler has been set
     }
 
     (this->*(HandleRsp[aHeader.mOpcode]))(aHeader, aPDU, res);
   }
 
   nsresult Send(DaemonSocketPDU* aPDU, BluetoothSetupResultHandler* aRes)
   {
-    aRes->AddRef(); // Keep reference for response
-    return Send(aPDU, static_cast<void*>(aRes));
+    nsRefPtr<BluetoothSetupResultHandler> res(aRes);
+    nsresult rv = Send(aPDU, static_cast<void*>(res.get()));
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+    unused << res.forget(); // Keep reference for response
+    return NS_OK;
   }
 
 private:
 
   // Responses
   //
 
   typedef mozilla::ipc::DaemonResultRunnable0<
@@ -605,18 +610,23 @@ protected:
 
     MOZ_ASSERT(!NS_IsMainThread());
 
     (this->*(HandleOp[!!(aHeader.mOpcode & 0x80)]))(aHeader, aPDU, aUserData);
   }
 
   nsresult Send(DaemonSocketPDU* aPDU, BluetoothResultHandler* aRes)
   {
-    aRes->AddRef(); // Keep reference for response
-    return Send(aPDU, static_cast<void*>(aRes));
+    nsRefPtr<BluetoothResultHandler> res(aRes);
+    nsresult rv = Send(aPDU, static_cast<void*>(res.get()));
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+    unused << res.forget(); // Keep reference for response
+    return NS_OK;
   }
 
 private:
 
   // Responses
   //
 
   typedef mozilla::ipc::DaemonResultRunnable0<
--- a/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.cpp
@@ -186,18 +186,23 @@ BluetoothDaemonSocketModule::HandleSvc(c
 
   (this->*(HandleRsp[aHeader.mOpcode]))(aHeader, aPDU, res);
 }
 
 nsresult
 BluetoothDaemonSocketModule::Send(DaemonSocketPDU* aPDU,
                                   BluetoothSocketResultHandler* aRes)
 {
-  aRes->AddRef(); // Keep reference for response
-  return Send(aPDU, static_cast<void*>(aRes));
+  nsRefPtr<BluetoothSocketResultHandler> res(aRes);
+  nsresult rv = Send(aPDU, static_cast<void*>(res.get()));
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  unused << res.forget(); // Keep reference for response
+  return NS_OK;
 }
 
 uint8_t
 BluetoothDaemonSocketModule::SocketFlags(bool aEncrypt, bool aAuth)
 {
   return (0x01 * aEncrypt) | (0x02 * aAuth);
 }