Bug 667535 - Remove xpcom/proxy use in netwerk/wifi (since this can lead to off-thread scripted QI) (r=dougt)
authorLuke Wagner <luke@mozilla.com>
Wed, 27 Jul 2011 09:26:20 -0700
changeset 73437 169712c5c68b0d32744e101c0fca0776e8650c4f
parent 73422 da50621162f38bf00c3c0815e8e8346b12bf8908
child 73438 0737efca777e16746dd9435bad830164d3f2f5fd
push id20871
push usereakhgari@mozilla.com
push dateThu, 28 Jul 2011 14:37:48 +0000
treeherdermozilla-central@fe48bbfeff94 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdougt
bugs667535
milestone8.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 667535 - Remove xpcom/proxy use in netwerk/wifi (since this can lead to off-thread scripted QI) (r=dougt)
netwerk/wifi/nsWifiMonitor.cpp
netwerk/wifi/nsWifiMonitor.h
netwerk/wifi/nsWifiScannerMac.cpp
netwerk/wifi/nsWifiScannerSolaris.cpp
netwerk/wifi/nsWifiScannerUnix.cpp
netwerk/wifi/nsWifiScannerWin.cpp
--- a/netwerk/wifi/nsWifiMonitor.cpp
+++ b/netwerk/wifi/nsWifiMonitor.cpp
@@ -41,18 +41,18 @@
 #include "nsComponentManagerUtils.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
 #include "nsXPCOM.h"
 #include "nsXPCOMCID.h"
 #include "nsIObserver.h"
 #include "nsIObserverService.h"
 #include "nsWifiMonitor.h"
+#include "nsWifiAccessPoint.h"
 
-#include "nsIProxyObjectManager.h"
 #include "nsServiceManagerUtils.h"
 #include "nsComponentManagerUtils.h"
 #include "mozilla/Services.h"
 
 using namespace mozilla;
 
 #if defined(PR_LOGGING)
 PRLogModuleInfo *gWifiMonitorLog;
@@ -141,39 +141,143 @@ NS_IMETHODIMP nsWifiMonitor::StopWatchin
     mKeepGoing = PR_FALSE;
     mon.Notify();
     mThread = nsnull;
   }
 
   return NS_OK;
 }
 
+class nsPassErrorToWifiListeners : public nsIRunnable
+{
+ public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIRUNNABLE
+
+  nsPassErrorToWifiListeners(nsAutoPtr<nsCOMArray<nsIWifiListener> > aListeners,
+                             nsresult aResult)
+  : mListeners(aListeners),
+    mResult(aResult)
+  {}
+
+ private:
+  nsAutoPtr<nsCOMArray<nsIWifiListener> > mListeners;
+  nsresult mResult;
+};
+
+NS_IMPL_THREADSAFE_ISUPPORTS1(nsPassErrorToWifiListeners,
+                              nsIRunnable)
+
+NS_IMETHODIMP nsPassErrorToWifiListeners::Run()
+{
+  LOG(("About to send error to the wifi listeners\n"));
+  for (PRInt32 i = 0; i < mListeners->Count(); i++) {
+    nsresult rv = (*mListeners)[i]->OnError(mResult);
+    LOG( ("... sent %d\n", rv));
+  }
+  return NS_OK;
+}
 
 NS_IMETHODIMP nsWifiMonitor::Run()
 {
   LOG(("@@@@@ wifi monitor run called\n"));
 
   nsresult rv = DoScan();
 
   if (mKeepGoing && NS_FAILED(rv)) {
-
-    nsCOMPtr<nsIProxyObjectManager> proxyObjMgr = do_GetService("@mozilla.org/xpcomproxy;1");
+    nsAutoPtr<nsCOMArray<nsIWifiListener> > currentListeners(
+                           new nsCOMArray<nsIWifiListener>(mListeners.Length()));
+    if (!currentListeners)
+      return NS_ERROR_OUT_OF_MEMORY;
 
-    // send error
-    for (PRUint32 i = 0; i < mListeners.Length(); i++) {
-      LOG(("About to send error to a listener\n"));
+    for (PRUint32 i = 0; i < mListeners.Length(); i++)
+      currentListeners->AppendObject(mListeners[i].mListener);
 
-      nsCOMPtr<nsIWifiListener> proxy;
-      proxyObjMgr->GetProxyForObject(NS_PROXY_TO_MAIN_THREAD,
-                                     NS_GET_IID(nsIWifiListener),
-                                     mListeners[i].mListener,
-                                     NS_PROXY_SYNC | NS_PROXY_ALWAYS,
-                                     getter_AddRefs(proxy));
+    nsCOMPtr<nsIThread> thread = do_GetMainThread();
+    if (!thread)
+      return NS_ERROR_UNEXPECTED;
 
-      if (proxy) {
-        proxy->OnError(rv);
-        LOG( ("... sent %d\n", rv));
-      }
-    }
+    nsCOMPtr<nsIRunnable> runnable(new nsPassErrorToWifiListeners(currentListeners, rv));
+    if (!runnable)
+      return NS_ERROR_OUT_OF_MEMORY;
+
+    thread->Dispatch(runnable, NS_DISPATCH_SYNC);
   }
 
   return NS_OK;
 }
+
+class nsCallWifiListeners : public nsIRunnable
+{
+ public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIRUNNABLE
+
+  nsCallWifiListeners(nsAutoPtr<nsCOMArray<nsIWifiListener> > aListeners,
+                      nsAutoPtr<nsTArray<nsIWifiAccessPoint*> > aAccessPoints)
+  : mListeners(aListeners),
+    mAccessPoints(aAccessPoints)
+  {}
+
+ private:
+  nsAutoPtr<nsCOMArray<nsIWifiListener> > 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 (PRInt32 i = 0; i < mListeners->Count(); i++) {
+    nsresult rv = (*mListeners)[i]->OnChange(mAccessPoints->Elements(),
+                                             mAccessPoints->Length());
+    LOG( ("... sent %d\n", rv));
+  }
+  return NS_OK;
+}
+
+nsresult
+nsWifiMonitor::CallWifiListeners(const nsCOMArray<nsWifiAccessPoint> &aAccessPoints,
+                                 PRBool aAccessPointsChanged)
+{
+    nsAutoPtr<nsCOMArray<nsIWifiListener> > currentListeners(
+                           new nsCOMArray<nsIWifiListener>(mListeners.Length()));
+    if (!currentListeners)
+      return NS_ERROR_OUT_OF_MEMORY;
+
+    {
+      ReentrantMonitorAutoEnter mon(mReentrantMonitor);
+
+      for (PRUint32 i = 0; i < mListeners.Length(); i++) {
+        if (!mListeners[i].mHasSentData || aAccessPointsChanged) {
+          mListeners[i].mHasSentData = PR_TRUE;
+          currentListeners->AppendObject(mListeners[i].mListener);
+        }
+      }
+    }
+
+    if (currentListeners->Count() > 0)
+    {
+      PRUint32 resultCount = aAccessPoints.Count();
+      nsAutoPtr<nsTArray<nsIWifiAccessPoint*> > accessPoints(
+                               new nsTArray<nsIWifiAccessPoint *>(resultCount));
+      if (!accessPoints)
+        return NS_ERROR_OUT_OF_MEMORY;
+
+      for (PRUint32 i = 0; i < resultCount; i++)
+        accessPoints->AppendElement(aAccessPoints[i]);
+
+      nsCOMPtr<nsIThread> thread = do_GetMainThread();
+      if (!thread)
+        return NS_ERROR_UNEXPECTED;
+
+      nsCOMPtr<nsIRunnable> runnable(
+                      new nsCallWifiListeners(currentListeners, accessPoints));
+      if (!runnable)
+        return NS_ERROR_OUT_OF_MEMORY;
+
+      thread->Dispatch(runnable, NS_DISPATCH_SYNC);
+    }
+
+    return NS_OK;
+}
--- a/netwerk/wifi/nsWifiMonitor.h
+++ b/netwerk/wifi/nsWifiMonitor.h
@@ -52,16 +52,18 @@
 #ifndef __nsWifiMonitor__
 #define __nsWifiMonitor__
 
 #if defined(PR_LOGGING)
 extern PRLogModuleInfo *gWifiMonitorLog;
 #endif
 #define LOG(args)     PR_LOG(gWifiMonitorLog, PR_LOG_DEBUG, args)
 
+class nsWifiAccessPoint;
+
 class nsWifiListener
 {
  public:
 
   nsWifiListener(nsIWifiListener* aListener)
   {
     mListener = aListener;
     mHasSentData = PR_FALSE;
@@ -87,16 +89,19 @@ class nsWifiMonitor : nsIRunnable, nsIWi
 
   nsresult DoScan();
 
 #if defined(XP_MACOSX)
   nsresult DoScanWithCoreWLAN();
   nsresult DoScanOld();
 #endif
 
+  nsresult CallWifiListeners(const nsCOMArray<nsWifiAccessPoint> &aAccessPoints,
+                             PRBool aAccessPointsChanged);
+
   PRBool mKeepGoing;
   nsCOMPtr<nsIThread> mThread;
 
   nsTArray<nsWifiListener> mListeners;
 
   mozilla::ReentrantMonitor mReentrantMonitor;
 
 };
--- a/netwerk/wifi/nsWifiScannerMac.cpp
+++ b/netwerk/wifi/nsWifiScannerMac.cpp
@@ -43,17 +43,16 @@
 
 #include "osx_wifi.h"
 
 #include "nsAutoPtr.h"
 #include "nsCOMArray.h"
 #include "nsWifiMonitor.h"
 #include "nsWifiAccessPoint.h"
 
-#include "nsIProxyObjectManager.h"
 #include "nsServiceManagerUtils.h"
 #include "nsComponentManagerUtils.h"
 #include "nsIMutableArray.h"
 
 using namespace mozilla;
 
 // defined in osx_corewlan.mm
 // basically relaces accesspoints in the passed reference
@@ -69,65 +68,20 @@ nsWifiMonitor::DoScanWithCoreWLAN()
   nsCOMArray<nsWifiAccessPoint> accessPoints;
 
   do {
     nsresult rv = GetAccessPointsFromWLAN(accessPoints);
     if (NS_FAILED(rv))
       return rv;
 
     PRBool accessPointsChanged = !AccessPointsEqual(accessPoints, lastAccessPoints);
-    nsCOMArray<nsIWifiListener> currentListeners;
-
-    {
-      ReentrantMonitorAutoEnter mon(mReentrantMonitor);
-
-      for (PRUint32 i = 0; i < mListeners.Length(); i++) {
-        if (!mListeners[i].mHasSentData || accessPointsChanged) {
-          mListeners[i].mHasSentData = PR_TRUE;
-          currentListeners.AppendObject(mListeners[i].mListener);
-        }
-      }
-    }
-
     ReplaceArray(lastAccessPoints, accessPoints);
 
-    if (currentListeners.Count() > 0)
-    {
-      PRUint32 resultCount = lastAccessPoints.Count();
-      nsIWifiAccessPoint** result = static_cast<nsIWifiAccessPoint**> (nsMemory::Alloc(sizeof(nsIWifiAccessPoint*) * resultCount));
-      if (!result) {
-        return NS_ERROR_OUT_OF_MEMORY;
-      }
-
-      for (PRUint32 i = 0; i < resultCount; i++)
-        result[i] = lastAccessPoints[i];
-
-      for (PRInt32 i = 0; i < currentListeners.Count(); i++) {
-
-        LOG(("About to send data to the wifi listeners\n"));
-
-        nsCOMPtr<nsIWifiListener> proxy;
-        nsCOMPtr<nsIProxyObjectManager> proxyObjMgr = do_GetService("@mozilla.org/xpcomproxy;1");
-        proxyObjMgr->GetProxyForObject(NS_PROXY_TO_MAIN_THREAD,
-                                       NS_GET_IID(nsIWifiListener),
-                                       currentListeners[i],
-                                       NS_PROXY_SYNC | NS_PROXY_ALWAYS,
-                                       getter_AddRefs(proxy));
-        if (!proxy) {
-          LOG(("There is no proxy available.  this should never happen\n"));
-        }
-        else
-        {
-          nsresult rv = proxy->OnChange(result, resultCount);
-          LOG( ("... sent %d\n", rv));
-        }
-      }
-
-      nsMemory::Free(result);
-    }
+    rv = CallWifiListeners(lastAccessPoints, accessPointsChanged);
+    NS_ENSURE_SUCCESS(rv, rv);
 
     // wait for some reasonable amount of time.  pref?
     LOG(("waiting on monitor\n"));
 
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     mon.Wait(PR_SecondsToInterval(60));
   }
   while (mKeepGoing);
@@ -204,65 +158,22 @@ nsWifiMonitor::DoScanOld()
 
       ap->setSSID(reinterpret_cast<const char*>(access_point_info->name),
                   access_point_info->nameLen);
 
       accessPoints.AppendObject(ap);
     }
 
     PRBool accessPointsChanged = !AccessPointsEqual(accessPoints, lastAccessPoints);
-    nsCOMArray<nsIWifiListener> currentListeners;
-
-    {
-      ReentrantMonitorAutoEnter mon(mReentrantMonitor);
-
-      for (PRUint32 i = 0; i < mListeners.Length(); i++) {
-        if (!mListeners[i].mHasSentData || accessPointsChanged) {
-          mListeners[i].mHasSentData = PR_TRUE;
-          currentListeners.AppendObject(mListeners[i].mListener);
-        }
-      }
-    }
-
     ReplaceArray(lastAccessPoints, accessPoints);
 
-    if (currentListeners.Count() > 0)
-    {
-      PRUint32 resultCount = lastAccessPoints.Count();
-      nsIWifiAccessPoint** result = static_cast<nsIWifiAccessPoint**> (nsMemory::Alloc(sizeof(nsIWifiAccessPoint*) * resultCount));
-      if (!result) {
+    nsresult rv = CallWifiListeners(lastAccessPoints, accessPointsChanged);
+    if (NS_FAILED(rv)) {
         dlclose(apple_80211_library);
-        return NS_ERROR_OUT_OF_MEMORY;
-      }
-
-      for (PRUint32 i = 0; i < resultCount; i++)
-        result[i] = lastAccessPoints[i];
-
-      for (PRInt32 i = 0; i < currentListeners.Count(); i++) {
-
-        LOG(("About to send data to the wifi listeners\n"));
-
-        nsCOMPtr<nsIWifiListener> proxy;
-        nsCOMPtr<nsIProxyObjectManager> proxyObjMgr = do_GetService("@mozilla.org/xpcomproxy;1");
-        proxyObjMgr->GetProxyForObject(NS_PROXY_TO_MAIN_THREAD,
-                                       NS_GET_IID(nsIWifiListener),
-                                       currentListeners[i],
-                                       NS_PROXY_SYNC | NS_PROXY_ALWAYS,
-                                       getter_AddRefs(proxy));
-        if (!proxy) {
-          LOG(("There is no proxy available.  this should never happen\n"));
-        }
-        else
-        {
-          nsresult rv = proxy->OnChange(result, resultCount);
-          LOG( ("... sent %d\n", rv));
-        }
-      }
-
-      nsMemory::Free(result);
+        return rv;
     }
 
     // wait for some reasonable amount of time.  pref?
     LOG(("waiting on monitor\n"));
 
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     mon.Wait(PR_SecondsToInterval(60));
   }
--- a/netwerk/wifi/nsWifiScannerSolaris.cpp
+++ b/netwerk/wifi/nsWifiScannerSolaris.cpp
@@ -36,17 +36,16 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsWifiMonitor.h"
 #include "nsWifiAccessPoint.h"
 
-#include "nsIProxyObjectManager.h"
 #include "nsServiceManagerUtils.h"
 #include "nsComponentManagerUtils.h"
 #include "nsIMutableArray.h"
 
 #include "plstr.h"
 #include <glib.h>
 
 #define DLADM_STRSIZE 256
@@ -166,65 +165,20 @@ nsWifiMonitor::DoScan()
   nsCOMArray<nsWifiAccessPoint> accessPoints;
 
   while (mKeepGoing) {
 
     accessPoints.Clear();
     do_dladm(accessPoints);
 
     PRBool accessPointsChanged = !AccessPointsEqual(accessPoints, lastAccessPoints);
-    nsCOMArray<nsIWifiListener> currentListeners;
-
-    {
-      MonitorAutoEnter mon(mMonitor);
-
-      for (PRUint32 i = 0; i < mListeners.Length(); i++) {
-        if (!mListeners[i].mHasSentData || accessPointsChanged) {
-          mListeners[i].mHasSentData = PR_TRUE;
-          currentListeners.AppendObject(mListeners[i].mListener);
-        }
-      }
-    }
-
     ReplaceArray(lastAccessPoints, accessPoints);
 
-    if (currentListeners.Count() > 0)
-    {
-      PRUint32 resultCount = lastAccessPoints.Count();
-      nsIWifiAccessPoint** result = static_cast<nsIWifiAccessPoint**> (nsMemory::Alloc(sizeof(nsIWifiAccessPoint*) * resultCount));
-      if (!result) {
-        return NS_ERROR_OUT_OF_MEMORY;
-      }
-
-      for (PRUint32 i = 0; i < resultCount; i++)
-        result[i] = lastAccessPoints[i];
-
-      for (PRInt32 i = 0; i < currentListeners.Count(); i++) {
-
-        LOG(("About to send data to the wifi listeners\n"));
-
-        nsCOMPtr<nsIWifiListener> proxy;
-        nsCOMPtr<nsIProxyObjectManager> proxyObjMgr = do_GetService("@mozilla.org/xpcomproxy;1");
-        proxyObjMgr->GetProxyForObject(NS_PROXY_TO_MAIN_THREAD,
-                                       NS_GET_IID(nsIWifiListener),
-                                       currentListeners[i],
-                                       NS_PROXY_SYNC | NS_PROXY_ALWAYS,
-                                       getter_AddRefs(proxy));
-        if (!proxy) {
-          LOG(("There is no proxy available.  this should never happen\n"));
-        }
-        else
-        {
-          nsresult rv = proxy->OnChange(result, resultCount);
-          LOG( ("... sent %d\n", rv));
-        }
-      }
-
-      nsMemory::Free(result);
-    }
+    nsresult rv = CallWifiListeners(lastAccessPoints, accessPointsChanged);
+    NS_ENSURE_SUCCESS(rv, rv);
 
     LOG(("waiting on monitor\n"));
 
     MonitorAutoEnter mon(mMonitor);
     mon.Wait(PR_SecondsToInterval(60));
   }
 
   return NS_OK;
--- a/netwerk/wifi/nsWifiScannerUnix.cpp
+++ b/netwerk/wifi/nsWifiScannerUnix.cpp
@@ -39,20 +39,20 @@
 
 #include "iwlib.h"
 
 #include "dlfcn.h"
 
 #include "nsWifiMonitor.h"
 #include "nsWifiAccessPoint.h"
 
-#include "nsIProxyObjectManager.h"
 #include "nsServiceManagerUtils.h"
 #include "nsComponentManagerUtils.h"
 #include "nsIMutableArray.h"
+#include "nsThreadUtils.h"
 
 using namespace mozilla;
 
 
 typedef int (*iw_open_t)(void);
 
 typedef void (*iw_enum_t)(int	skfd,
 			  iw_enum_handler fn,
@@ -118,113 +118,81 @@ static int scan_wifi(int skfd, char* ifn
 
   accessPoints->AppendObject(ap);
   return 0;
 }
 
 nsresult
 nsWifiMonitor::DoScan()
 {
-  void* iwlib_handle = dlopen("libiw.so", RTLD_NOW);
+  static void* iwlib_handle = NULL;
+
   if (!iwlib_handle) {
-    iwlib_handle = dlopen("libiw.so.29", RTLD_NOW);
+    iwlib_handle = dlopen("libiw.so", RTLD_NOW);
     if (!iwlib_handle) {
-      iwlib_handle = dlopen("libiw.so.30", RTLD_NOW);
+      iwlib_handle = dlopen("libiw.so.29", RTLD_NOW);
       if (!iwlib_handle) {
-        LOG(("Could not load libiw\n"));
-        return NS_ERROR_NOT_AVAILABLE;
+        iwlib_handle = dlopen("libiw.so.30", RTLD_NOW);
+        if (!iwlib_handle) {
+          LOG(("Could not load libiw\n"));
+          return NS_ERROR_NOT_AVAILABLE;
+        }
       }
     }
   }
   else {
     LOG(("Loaded libiw\n"));
   }
 
-  iw_open_t iw_open = (iw_open_t) dlsym(iwlib_handle, "iw_sockets_open");
-  iw_enum_t iw_enum = (iw_enum_t) dlsym(iwlib_handle, "iw_enum_devices");
-  iw_stats_t iw_stats = (iw_stats_t)dlsym(iwlib_handle, "iw_get_stats");
+  static iw_open_t iw_open = NULL;
+  if (!iw_open)
+    iw_open = (iw_open_t) dlsym(iwlib_handle, "iw_sockets_open");
+
+  static iw_enum_t iw_enum = NULL;
+  if (!iw_enum)
+    iw_enum = (iw_enum_t) dlsym(iwlib_handle, "iw_enum_devices");
+
+  static iw_stats_t iw_stats = NULL;
+  if (!iw_stats)
+    iw_stats = (iw_stats_t)dlsym(iwlib_handle, "iw_get_stats");
 
   if (!iw_open || !iw_enum || !iw_stats) {
-    dlclose(iwlib_handle);
     LOG(("Could not load a symbol from iwlib.so\n"));
     return NS_ERROR_FAILURE;
   }
 
   int skfd = (*iw_open)();
 
   if (skfd < 0) {
-    dlclose(iwlib_handle);
+    LOG(("Could not iw_open\n"));
     return NS_ERROR_FAILURE;
   }
 
+  struct SocketsGuard {
+    int skfd;
+    SocketsGuard(int skfd) : skfd(skfd) {}
+    ~SocketsGuard() { iw_sockets_close(skfd); }
+  } guard(skfd);
+
   nsCOMArray<nsWifiAccessPoint> lastAccessPoints;
   nsCOMArray<nsWifiAccessPoint> accessPoints;
 
   char* args[] = {(char*) &accessPoints, (char*) iw_stats, nsnull };
 
   while (mKeepGoing) {
-
     accessPoints.Clear();
 
     (*iw_enum)(skfd, &scan_wifi, args, 1);
 
     PRBool accessPointsChanged = !AccessPointsEqual(accessPoints, lastAccessPoints);
-    nsCOMArray<nsIWifiListener> currentListeners;
-
-    {
-      ReentrantMonitorAutoEnter mon(mReentrantMonitor);
-
-      for (PRUint32 i = 0; i < mListeners.Length(); i++) {
-        if (!mListeners[i].mHasSentData || accessPointsChanged) {
-          mListeners[i].mHasSentData = PR_TRUE;
-          currentListeners.AppendObject(mListeners[i].mListener);
-        }
-      }
-    }
-
     ReplaceArray(lastAccessPoints, accessPoints);
 
-    if (currentListeners.Count() > 0)
-    {
-      PRUint32 resultCount = lastAccessPoints.Count();
-      nsIWifiAccessPoint** result = static_cast<nsIWifiAccessPoint**> (nsMemory::Alloc(sizeof(nsIWifiAccessPoint*) * resultCount));
-      if (!result) {
-        dlclose(iwlib_handle);
-        return NS_ERROR_OUT_OF_MEMORY;
-      }
-
-      for (PRUint32 i = 0; i < resultCount; i++)
-        result[i] = lastAccessPoints[i];
-
-      for (PRInt32 i = 0; i < currentListeners.Count(); i++) {
-
-        LOG(("About to send data to the wifi listeners\n"));
-
-        nsCOMPtr<nsIWifiListener> proxy;
-        nsCOMPtr<nsIProxyObjectManager> proxyObjMgr = do_GetService("@mozilla.org/xpcomproxy;1");
-        proxyObjMgr->GetProxyForObject(NS_PROXY_TO_MAIN_THREAD,
-                                       NS_GET_IID(nsIWifiListener),
-                                       currentListeners[i],
-                                       NS_PROXY_SYNC | NS_PROXY_ALWAYS,
-                                       getter_AddRefs(proxy));
-        if (!proxy) {
-          LOG(("There is no proxy available.  this should never happen\n"));
-        }
-        else
-        {
-          nsresult rv = proxy->OnChange(result, resultCount);
-          LOG( ("... sent %d\n", rv));
-        }
-      }
-
-      nsMemory::Free(result);
-    }
+    nsresult rv = CallWifiListeners(lastAccessPoints, accessPointsChanged);
+    NS_ENSURE_SUCCESS(rv, rv);
 
     LOG(("waiting on monitor\n"));
 
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     mon.Wait(PR_SecondsToInterval(60));
   }
 
-  iw_sockets_close(skfd);
-
   return NS_OK;
 }
--- a/netwerk/wifi/nsWifiScannerWin.cpp
+++ b/netwerk/wifi/nsWifiScannerWin.cpp
@@ -44,17 +44,16 @@
 
 #include <ntddndis.h>
 #include "winioctl.h"
 #include "stdlib.h"
 
 #include "nsWifiMonitor.h"
 #include "nsWifiAccessPoint.h"
 
-#include "nsIProxyObjectManager.h"
 #include "nsServiceManagerUtils.h"
 #include "nsComponentManagerUtils.h"
 #include "nsIMutableArray.h"
 
 using namespace mozilla;
 
 nsresult
 nsWifiMonitor::DoScan()
@@ -146,63 +145,20 @@ nsWifiMonitor::DoScan()
       // Free interface_list.
       (*WlanFreeMemory)(interface_list);
 
       // Close the handle.
       (*WlanCloseHandle)(wlan_handle, NULL);
 
 
       PRBool accessPointsChanged = !AccessPointsEqual(accessPoints, lastAccessPoints);
-      nsCOMArray<nsIWifiListener> currentListeners;
-
-      {
-        ReentrantMonitorAutoEnter mon(mReentrantMonitor);
-
-        for (PRUint32 i = 0; i < mListeners.Length(); i++) {
-          if (!mListeners[i].mHasSentData || accessPointsChanged) {
-            mListeners[i].mHasSentData = PR_TRUE;
-            currentListeners.AppendObject(mListeners[i].mListener);
-          }
-        }
-      }
-
       ReplaceArray(lastAccessPoints, accessPoints);
 
-      if (currentListeners.Count() > 0) {
-        PRUint32 resultCount = lastAccessPoints.Count();
-        nsIWifiAccessPoint** result = static_cast<nsIWifiAccessPoint**> (nsMemory::Alloc(sizeof(nsIWifiAccessPoint*) * resultCount));
-        if (!result)
-          return NS_ERROR_OUT_OF_MEMORY;
-
-        for (PRUint32 i = 0; i < resultCount; i++)
-          result[i] = lastAccessPoints[i];
-
-        for (PRInt32 i = 0; i < currentListeners.Count(); i++) {
-
-          LOG(("About to send data to the wifi listeners\n"));
-
-          nsCOMPtr<nsIWifiListener> proxy;
-          nsCOMPtr<nsIProxyObjectManager> proxyObjMgr = do_GetService("@mozilla.org/xpcomproxy;1");
-          proxyObjMgr->GetProxyForObject(NS_PROXY_TO_MAIN_THREAD,
-                                         NS_GET_IID(nsIWifiListener),
-                                         currentListeners[i],
-                                         NS_PROXY_SYNC | NS_PROXY_ALWAYS,
-                                         getter_AddRefs(proxy));
-          if (!proxy) {
-            LOG(("There is no proxy available.  this should never happen\n"));
-          }
-          else
-          {
-            nsresult rv = proxy->OnChange(result, resultCount);
-            LOG( ("... sent %d\n", rv));
-          }
-        }
-
-        nsMemory::Free(result);
-      }
+      nsresult rv = CallWifiListeners(lastAccessPoints, accessPointsChanged);
+      NS_ENSURE_SUCCESS(rv, rv);
 
       // wait for some reasonable amount of time.  pref?
       LOG(("waiting on monitor\n"));
 
       ReentrantMonitorAutoEnter mon(mReentrantMonitor);
       mon.Wait(PR_SecondsToInterval(60));
     }
     while (mKeepGoing);