Bug 850249 - Remove Off-Main-Thread XPCWrappedJS refcounting from Wifi Listeners. r=mcmanus
authorBobby Holley <bobbyholley@gmail.com>
Fri, 15 Mar 2013 16:02:01 -0700
changeset 136208 00dbfbea1ba84bfc94660393027b782cfaa196dc
parent 136207 8c1fa23505247e7f550f466b003388afad9ca8ca
child 136209 b9fb91275c69590447df1c1fdc922f0982721a3c
push id336
push userakeybl@mozilla.com
push dateMon, 17 Jun 2013 22:53:19 +0000
treeherdermozilla-release@574a39cdf657 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmcmanus
bugs850249
milestone22.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 850249 - Remove Off-Main-Thread XPCWrappedJS refcounting from Wifi Listeners. r=mcmanus
netwerk/wifi/nsWifiMonitor.cpp
netwerk/wifi/nsWifiMonitor.h
netwerk/wifi/nsWifiMonitorGonk.cpp
--- a/netwerk/wifi/nsWifiMonitor.cpp
+++ b/netwerk/wifi/nsWifiMonitor.cpp
@@ -1,13 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsCOMPtr.h"
+#include "nsProxyRelease.h"
 #include "nsComponentManagerUtils.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
 #include "nsXPCOM.h"
 #include "nsXPCOMCID.h"
 #include "nsIObserver.h"
 #include "nsIObserverService.h"
 #include "nsWifiMonitor.h"
@@ -73,17 +74,17 @@ NS_IMETHODIMP nsWifiMonitor::StartWatchi
     if (NS_FAILED(rv))
       return rv;
   }
 
   ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
   mKeepGoing = true;
 
-  mListeners.AppendElement(nsWifiListener(aListener));
+  mListeners.AppendElement(nsWifiListener(new nsMainThreadPtrHolder<nsIWifiListener>(aListener)));
 
   // tell ourselves that we have a new watcher.
   mon.Notify();
   return NS_OK;
 }
 
 NS_IMETHODIMP nsWifiMonitor::StopWatching(nsIWifiListener *aListener)
 {
@@ -106,61 +107,63 @@ NS_IMETHODIMP nsWifiMonitor::StopWatchin
     mKeepGoing = false;
     mon.Notify();
     mThread = nullptr;
   }
 
   return NS_OK;
 }
 
+typedef nsTArray<nsMainThreadPtrHandle<nsIWifiListener> > WifiListenerArray;
+
 class nsPassErrorToWifiListeners MOZ_FINAL : public nsIRunnable
 {
  public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIRUNNABLE
 
-  nsPassErrorToWifiListeners(nsAutoPtr<nsCOMArray<nsIWifiListener> > aListeners,
+  nsPassErrorToWifiListeners(nsAutoPtr<WifiListenerArray> aListeners,
                              nsresult aResult)
   : mListeners(aListeners),
     mResult(aResult)
   {}
 
  private:
-  nsAutoPtr<nsCOMArray<nsIWifiListener> > mListeners;
+  nsAutoPtr<WifiListenerArray> mListeners;
   nsresult mResult;
 };
 
 NS_IMPL_THREADSAFE_ISUPPORTS1(nsPassErrorToWifiListeners,
                               nsIRunnable)
 
 NS_IMETHODIMP nsPassErrorToWifiListeners::Run()
 {
   LOG(("About to send error to the wifi listeners\n"));
-  for (int32_t i = 0; i < mListeners->Count(); i++) {
+  for (size_t i = 0; i < mListeners->Length(); i++) {
     (*mListeners)[i]->OnError(mResult);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP nsWifiMonitor::Run()
 {
   LOG(("@@@@@ wifi monitor run called\n"));
 
   PR_SetCurrentThreadName("Wifi Monitor");
 
   nsresult rv = DoScan();
 
   if (mKeepGoing && NS_FAILED(rv)) {
-    nsAutoPtr<nsCOMArray<nsIWifiListener> > currentListeners(
-                           new nsCOMArray<nsIWifiListener>(mListeners.Length()));
+    nsAutoPtr<WifiListenerArray> currentListeners(
+                           new WifiListenerArray(mListeners.Length()));
     if (!currentListeners)
       return NS_ERROR_OUT_OF_MEMORY;
 
     for (uint32_t i = 0; i < mListeners.Length(); i++)
-      currentListeners->AppendObject(mListeners[i].mListener);
+      currentListeners->AppendElement(mListeners[i].mListener);
 
     nsCOMPtr<nsIThread> thread = do_GetMainThread();
     if (!thread)
       return NS_ERROR_UNEXPECTED;
 
     nsCOMPtr<nsIRunnable> runnable(new nsPassErrorToWifiListeners(currentListeners, rv));
     if (!runnable)
       return NS_ERROR_OUT_OF_MEMORY;
@@ -172,60 +175,60 @@ NS_IMETHODIMP nsWifiMonitor::Run()
 }
 
 class nsCallWifiListeners MOZ_FINAL : public nsIRunnable
 {
  public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIRUNNABLE
 
-  nsCallWifiListeners(nsAutoPtr<nsCOMArray<nsIWifiListener> > aListeners,
+  nsCallWifiListeners(nsAutoPtr<WifiListenerArray> aListeners,
                       nsAutoPtr<nsTArray<nsIWifiAccessPoint*> > aAccessPoints)
   : mListeners(aListeners),
     mAccessPoints(aAccessPoints)
   {}
 
  private:
-  nsAutoPtr<nsCOMArray<nsIWifiListener> > mListeners;
+  nsAutoPtr<WifiListenerArray> mListeners;
   nsAutoPtr<nsTArray<nsIWifiAccessPoint*> > mAccessPoints;
 };
 
 NS_IMPL_THREADSAFE_ISUPPORTS1(nsCallWifiListeners,
                               nsIRunnable)
 
 NS_IMETHODIMP nsCallWifiListeners::Run()
 {
   LOG(("About to send data to the wifi listeners\n"));
-  for (int32_t i = 0; i < mListeners->Count(); i++) {
+  for (size_t i = 0; i < mListeners->Length(); i++) {
     (*mListeners)[i]->OnChange(mAccessPoints->Elements(), mAccessPoints->Length());
   }
   return NS_OK;
 }
 
 nsresult
 nsWifiMonitor::CallWifiListeners(const nsCOMArray<nsWifiAccessPoint> &aAccessPoints,
                                  bool aAccessPointsChanged)
 {
-    nsAutoPtr<nsCOMArray<nsIWifiListener> > currentListeners(
-                           new nsCOMArray<nsIWifiListener>(mListeners.Length()));
+    nsAutoPtr<WifiListenerArray> currentListeners(
+                           new WifiListenerArray(mListeners.Length()));
     if (!currentListeners)
       return NS_ERROR_OUT_OF_MEMORY;
 
     {
       ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
       for (uint32_t i = 0; i < mListeners.Length(); i++) {
         if (!mListeners[i].mHasSentData || aAccessPointsChanged) {
           mListeners[i].mHasSentData = true;
-          currentListeners->AppendObject(mListeners[i].mListener);
+          currentListeners->AppendElement(mListeners[i].mListener);
         }
       }
     }
 
-    if (currentListeners->Count() > 0)
+    if (currentListeners->Length() > 0)
     {
       uint32_t resultCount = aAccessPoints.Count();
       nsAutoPtr<nsTArray<nsIWifiAccessPoint*> > accessPoints(
                                new nsTArray<nsIWifiAccessPoint *>(resultCount));
       if (!accessPoints)
         return NS_ERROR_OUT_OF_MEMORY;
 
       for (uint32_t i = 0; i < resultCount; i++)
--- a/netwerk/wifi/nsWifiMonitor.h
+++ b/netwerk/wifi/nsWifiMonitor.h
@@ -3,16 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef __nsWifiMonitor__
 #define __nsWifiMonitor__
 
 #include "nsIWifiMonitor.h"
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
+#include "nsProxyRelease.h"
 #include "nsIThread.h"
 #include "nsIRunnable.h"
 #include "nsCOMArray.h"
 #include "nsIWifiMonitor.h"
 #include "mozilla/ReentrantMonitor.h"
 #include "prlog.h"
 #include "nsIObserver.h"
 #include "nsTArray.h"
@@ -26,24 +27,24 @@ extern PRLogModuleInfo *gWifiMonitorLog;
 #define LOG(args)     PR_LOG(gWifiMonitorLog, PR_LOG_DEBUG, args)
 
 class nsWifiAccessPoint;
 
 class nsWifiListener
 {
  public:
 
-  nsWifiListener(nsIWifiListener* aListener)
+  nsWifiListener(nsMainThreadPtrHolder<nsIWifiListener>* aListener)
   {
     mListener = aListener;
     mHasSentData = false;
   }
   ~nsWifiListener() {}
 
-  nsCOMPtr<nsIWifiListener> mListener;
+  nsMainThreadPtrHandle<nsIWifiListener> mListener;
   bool mHasSentData;
 };
 
 #ifndef MOZ_WIDGET_GONK
 class nsWifiMonitor MOZ_FINAL : nsIRunnable, nsIWifiMonitor, nsIObserver
 {
  public:
   NS_DECL_ISUPPORTS
--- a/netwerk/wifi/nsWifiMonitorGonk.cpp
+++ b/netwerk/wifi/nsWifiMonitorGonk.cpp
@@ -52,17 +52,17 @@ NS_IMETHODIMP
 nsWifiMonitor::StartWatching(nsIWifiListener *aListener)
 {
   LOG(("@@@@@ nsWifiMonitor::StartWatching\n"));
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   if (!aListener) {
     return NS_ERROR_NULL_POINTER;
   }
 
-  mListeners.AppendElement(nsWifiListener(aListener));
+  mListeners.AppendElement(nsWifiListener(new nsMainThreadPtrHolder<nsIWifiListener>(aListener)));
 
   if (!mTimer) {
     mTimer = do_CreateInstance("@mozilla.org/timer;1");
     mTimer->Init(this, 5000, nsITimer::TYPE_REPEATING_SLACK);
   }
   return NS_OK;
 }