make sure PR_Close is on STS thread draft
authorShih-Chiang Chien <schien@mozilla.com>
Fri, 30 Dec 2016 18:47:35 +0800
changeset 454801 8bdf639406d9e68e502cf6f00849798210590a51
parent 454799 2de163dd0ecde72c47a11fc28e532181b06ca5b4
child 540822 a0d010e5aa24ab51ed1f48bd7511f503ac7f8ce3
push id40054
push userschien@mozilla.com
push dateFri, 30 Dec 2016 10:56:55 +0000
milestone53.0a1
make sure PR_Close is on STS thread MozReview-Commit-ID: JGeKEKgqsKL
netwerk/base/nsUDPSocket.cpp
--- a/netwerk/base/nsUDPSocket.cpp
+++ b/netwerk/base/nsUDPSocket.cpp
@@ -742,60 +742,75 @@ nsUDPSocket::GetLocalAddr(nsINetAddr * *
   result.forget(aResult);
 
   return NS_OK;
 }
 
 void
 nsUDPSocket::CloseSocket()
 {
-  if (mFD) {
-    if (gIOService->IsNetTearingDown() &&
-        ((PR_IntervalNow() - gIOService->NetTearingDownStarted()) >
-         gSocketTransportService->MaxTimeForPrClosePref())) {
-      // If shutdown last to long, let the socket leak and do not close it.
-      UDPSOCKET_LOG(("Intentional leak"));
-    } else {
+  if (!mFD) {
+    return;
+  }
+
+  PRFileDesc* fd = mFD;
+  mFD = nullptr;
 
-      PRIntervalTime closeStarted = 0;
-      if (gSocketTransportService->IsTelemetryEnabledAndNotSleepPhase()) {
-        closeStarted = PR_IntervalNow();
-      }
+  if (gIOService->IsNetTearingDown() &&
+      ((PR_IntervalNow() - gIOService->NetTearingDownStarted()) >
+       gSocketTransportService->MaxTimeForPrClosePref())) {
+    // If shutdown last to long, let the socket leak and do not close it.
+    UDPSOCKET_LOG(("Intentional leak"));
+    return;
+  }
 
-      PR_Close(mFD);
+  nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([fd]() {
+    PRIntervalTime closeStarted = 0;
+    if (gSocketTransportService->IsTelemetryEnabledAndNotSleepPhase()) {
+      closeStarted = PR_IntervalNow();
+    }
+
+    PR_Close(fd);
 
-      if (gSocketTransportService->IsTelemetryEnabledAndNotSleepPhase()) {
-        PRIntervalTime now = PR_IntervalNow();
-        if (gIOService->IsNetTearingDown()) {
-          Telemetry::Accumulate(Telemetry::PRCLOSE_UDP_BLOCKING_TIME_SHUTDOWN,
-                                PR_IntervalToMilliseconds(now - closeStarted));
+    if (gSocketTransportService->IsTelemetryEnabledAndNotSleepPhase()) {
+      PRIntervalTime now = PR_IntervalNow();
+      if (gIOService->IsNetTearingDown()) {
+        Telemetry::Accumulate(Telemetry::PRCLOSE_UDP_BLOCKING_TIME_SHUTDOWN,
+                              PR_IntervalToMilliseconds(now - closeStarted));
 
-        } else if (PR_IntervalToSeconds(now - gIOService->LastConnectivityChange())
-                   < 60) {
-          Telemetry::Accumulate(Telemetry::PRCLOSE_UDP_BLOCKING_TIME_CONNECTIVITY_CHANGE,
-                                PR_IntervalToMilliseconds(now - closeStarted));
+      } else if (PR_IntervalToSeconds(now - gIOService->LastConnectivityChange())
+                 < 60) {
+        Telemetry::Accumulate(Telemetry::PRCLOSE_UDP_BLOCKING_TIME_CONNECTIVITY_CHANGE,
+                              PR_IntervalToMilliseconds(now - closeStarted));
 
-        } else if (PR_IntervalToSeconds(now - gIOService->LastNetworkLinkChange())
-                   < 60) {
-          Telemetry::Accumulate(Telemetry::PRCLOSE_UDP_BLOCKING_TIME_LINK_CHANGE,
-                                PR_IntervalToMilliseconds(now - closeStarted));
+      } else if (PR_IntervalToSeconds(now - gIOService->LastNetworkLinkChange())
+                 < 60) {
+        Telemetry::Accumulate(Telemetry::PRCLOSE_UDP_BLOCKING_TIME_LINK_CHANGE,
+                              PR_IntervalToMilliseconds(now - closeStarted));
 
-        } else if (PR_IntervalToSeconds(now - gIOService->LastOfflineStateChange())
-                   < 60) {
-          Telemetry::Accumulate(Telemetry::PRCLOSE_UDP_BLOCKING_TIME_OFFLINE,
-                                PR_IntervalToMilliseconds(now - closeStarted));
+      } else if (PR_IntervalToSeconds(now - gIOService->LastOfflineStateChange())
+                 < 60) {
+        Telemetry::Accumulate(Telemetry::PRCLOSE_UDP_BLOCKING_TIME_OFFLINE,
+                              PR_IntervalToMilliseconds(now - closeStarted));
 
-        } else {
-          Telemetry::Accumulate(Telemetry::PRCLOSE_UDP_BLOCKING_TIME_NORMAL,
-                                PR_IntervalToMilliseconds(now - closeStarted));
-        }
+      } else {
+        Telemetry::Accumulate(Telemetry::PRCLOSE_UDP_BLOCKING_TIME_NORMAL,
+                              PR_IntervalToMilliseconds(now - closeStarted));
       }
     }
-    mFD = nullptr;
+  });
+
+  bool onSTSThread;
+  gSocketTransportService->IsOnCurrentThread(&onSTSThread);
+  if (!onSTSThread) {
+    gSocketTransportService->Dispatch(runnable, NS_DISPATCH_NORMAL);
+    return;
   }
+
+  runnable->Run();
 }
 
 NS_IMETHODIMP
 nsUDPSocket::GetAddress(NetAddr *aResult)
 {
   // no need to enter the lock here
   memcpy(aResult, &mAddr, sizeof(mAddr));
   return NS_OK;