Bug 1085266 - NetworkActivityMonitor PRIOMethods changed to be static, because not attached nsUDPSockets were crashing if SocketTransportService had been shut down. A small fix to nsUDPSocket destructor has been added. r=michal, a=lmandel
authorDragana Damjanovic <dd.mozilla@gmail.com>
Tue, 04 Nov 2014 01:23:00 -0500
changeset 225964 dfe08b30f41f
parent 225963 f6b893ef9186
child 225965 57e502f33317
push id4088
push userryanvm@gmail.com
push date2014-11-06 15:24 +0000
treeherdermozilla-beta@dfe08b30f41f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmichal, lmandel
bugs1085266
milestone34.0
Bug 1085266 - NetworkActivityMonitor PRIOMethods changed to be static, because not attached nsUDPSockets were crashing if SocketTransportService had been shut down. A small fix to nsUDPSocket destructor has been added. r=michal, a=lmandel
netwerk/base/src/NetworkActivityMonitor.cpp
netwerk/base/src/NetworkActivityMonitor.h
netwerk/base/src/nsUDPSocket.cpp
--- a/netwerk/base/src/NetworkActivityMonitor.cpp
+++ b/netwerk/base/src/NetworkActivityMonitor.cpp
@@ -170,20 +170,22 @@ public:
     return NS_OK;
   }
 private:
   nsCOMPtr<nsIObserverService>      mObs;
   NetworkActivityMonitor::Direction mDirection;
 };
 
 NetworkActivityMonitor * NetworkActivityMonitor::gInstance = nullptr;
+static PRDescIdentity sNetActivityMonitorLayerIdentity;
+static PRIOMethods sNetActivityMonitorLayerMethods;
+static PRIOMethods *sNetActivityMonitorLayerMethodsPtr = nullptr;
 
 NetworkActivityMonitor::NetworkActivityMonitor()
-  : mLayerIdentity(PR_INVALID_IO_LAYER)
-  , mBlipInterval(PR_INTERVAL_NO_TIMEOUT)
+  : mBlipInterval(PR_INTERVAL_NO_TIMEOUT)
 {
   MOZ_COUNT_CTOR(NetworkActivityMonitor);
 
   NS_ASSERTION(gInstance==nullptr,
                "multiple NetworkActivityMonitor instances!");
 }
 
 NetworkActivityMonitor::~NetworkActivityMonitor()
@@ -219,27 +221,31 @@ NetworkActivityMonitor::Shutdown()
 
   delete gInstance;
   return NS_OK;
 }
 
 nsresult
 NetworkActivityMonitor::Init_Internal(int32_t blipInterval)
 {
-  mLayerIdentity = PR_GetUniqueIdentity("network activity monitor layer");
-  mLayerMethods  = *PR_GetDefaultIOMethods();
-  mLayerMethods.connect    = nsNetMon_Connect;
-  mLayerMethods.read       = nsNetMon_Read;
-  mLayerMethods.write      = nsNetMon_Write;
-  mLayerMethods.writev     = nsNetMon_Writev;
-  mLayerMethods.recv       = nsNetMon_Recv;
-  mLayerMethods.send       = nsNetMon_Send;
-  mLayerMethods.recvfrom   = nsNetMon_RecvFrom;
-  mLayerMethods.sendto     = nsNetMon_SendTo;
-  mLayerMethods.acceptread = nsNetMon_AcceptRead;
+  if (!sNetActivityMonitorLayerMethodsPtr) {
+    sNetActivityMonitorLayerIdentity =
+      PR_GetUniqueIdentity("network activity monitor layer");
+    sNetActivityMonitorLayerMethods  = *PR_GetDefaultIOMethods();
+    sNetActivityMonitorLayerMethods.connect    = nsNetMon_Connect;
+    sNetActivityMonitorLayerMethods.read       = nsNetMon_Read;
+    sNetActivityMonitorLayerMethods.write      = nsNetMon_Write;
+    sNetActivityMonitorLayerMethods.writev     = nsNetMon_Writev;
+    sNetActivityMonitorLayerMethods.recv       = nsNetMon_Recv;
+    sNetActivityMonitorLayerMethods.send       = nsNetMon_Send;
+    sNetActivityMonitorLayerMethods.recvfrom   = nsNetMon_RecvFrom;
+    sNetActivityMonitorLayerMethods.sendto     = nsNetMon_SendTo;
+    sNetActivityMonitorLayerMethods.acceptread = nsNetMon_AcceptRead;
+    sNetActivityMonitorLayerMethodsPtr = &sNetActivityMonitorLayerMethods;
+  }
 
   mBlipInterval = PR_MillisecondsToInterval(blipInterval);
   // Set the last notification times to time that has just expired, so any
   // activity even right now will trigger notification.
   mLastNotificationTime[kUpload] = PR_IntervalNow() - mBlipInterval;
   mLastNotificationTime[kDownload] = mLastNotificationTime[kUpload];
 
   return NS_OK;
@@ -249,18 +255,18 @@ nsresult
 NetworkActivityMonitor::AttachIOLayer(PRFileDesc *fd)
 {
   if (!gInstance)
     return NS_OK;
 
   PRFileDesc * layer;
   PRStatus     status;
 
-  layer = PR_CreateIOLayerStub(gInstance->mLayerIdentity,
-                               &gInstance->mLayerMethods);
+  layer = PR_CreateIOLayerStub(sNetActivityMonitorLayerIdentity,
+                               sNetActivityMonitorLayerMethodsPtr);
   if (!layer) {
     return NS_ERROR_FAILURE;
   }
 
   status = PR_PushIOLayer(fd, PR_NSPR_IO_LAYER, layer);
 
   if (status == PR_FAILURE) {
     PR_DELETE(layer);
--- a/netwerk/base/src/NetworkActivityMonitor.h
+++ b/netwerk/base/src/NetworkActivityMonitor.h
@@ -31,17 +31,15 @@ public:
   static nsresult AttachIOLayer(PRFileDesc *fd);
   static nsresult DataInOut(Direction direction);
 
 private:
   nsresult Init_Internal(int32_t blipInterval);
   void PostNotification(Direction direction);
 
   static NetworkActivityMonitor * gInstance;
-  PRDescIdentity                  mLayerIdentity;
-  PRIOMethods                     mLayerMethods;
   PRIntervalTime                  mBlipInterval;
   PRIntervalTime                  mLastNotificationTime[2];
 };
 
 }} // namespace mozilla::net
 
 #endif /* NetworkActivityMonitor_h___ */
--- a/netwerk/base/src/nsUDPSocket.cpp
+++ b/netwerk/base/src/nsUDPSocket.cpp
@@ -269,17 +269,20 @@ nsUDPSocket::nsUDPSocket()
   }
 
   mSts = gSocketTransportService;
   MOZ_COUNT_CTOR(nsUDPSocket);
 }
 
 nsUDPSocket::~nsUDPSocket()
 {
-  Close(); // just in case :)
+  if (mFD) {
+    PR_Close(mFD);
+    mFD = nullptr;
+  }
 
   MOZ_COUNT_DTOR(nsUDPSocket);
 }
 
 void
 nsUDPSocket::AddOutputBytes(uint64_t aBytes)
 {
   mByteWriteCount += aBytes;