Bug 997688 - nsSocketTransport should track SocketTransportService via smart ptr r=sworkman
authorPatrick McManus <mcmanus@ducksong.com>
Tue, 15 Apr 2014 23:00:39 -0400
changeset 198721 caf503c905c024715145b014bf02245d117b357f
parent 198720 c0d6c8a242e55d86f997e915fe64484ad2a083d4
child 198722 2ec02b778be10e4d51cc31cd1ee96c7ca90420cc
push id486
push userasasaki@mozilla.com
push dateMon, 14 Jul 2014 18:39:42 +0000
treeherdermozilla-release@d33428174ff1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssworkman
bugs997688
milestone31.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 997688 - nsSocketTransport should track SocketTransportService via smart ptr r=sworkman
netwerk/base/src/nsSocketTransport2.cpp
netwerk/base/src/nsSocketTransport2.h
--- a/netwerk/base/src/nsSocketTransport2.cpp
+++ b/netwerk/base/src/nsSocketTransport2.cpp
@@ -759,46 +759,42 @@ nsSocketTransport::nsSocketTransport()
     , mInputClosed(true)
     , mOutputClosed(true)
     , mResolving(false)
     , mNetAddrIsSet(false)
     , mLock("nsSocketTransport.mLock")
     , mFD(MOZ_THIS_IN_INITIALIZER_LIST())
     , mFDref(0)
     , mFDconnected(false)
+    , mSocketTransportService(gSocketTransportService)
     , mInput(MOZ_THIS_IN_INITIALIZER_LIST())
     , mOutput(MOZ_THIS_IN_INITIALIZER_LIST())
     , mQoSBits(0x00)
     , mKeepaliveEnabled(false)
     , mKeepaliveIdleTimeS(-1)
     , mKeepaliveRetryIntervalS(-1)
     , mKeepaliveProbeCount(-1)
 {
     SOCKET_LOG(("creating nsSocketTransport @%p\n", this));
 
-    NS_ADDREF(gSocketTransportService);
-
     mTimeouts[TIMEOUT_CONNECT]    = UINT16_MAX; // no timeout
     mTimeouts[TIMEOUT_READ_WRITE] = UINT16_MAX; // no timeout
 }
 
 nsSocketTransport::~nsSocketTransport()
 {
     SOCKET_LOG(("destroying nsSocketTransport @%p\n", this));
 
     // cleanup socket type info
     if (mTypes) {
         uint32_t i;
         for (i=0; i<mTypeCount; ++i)
             PL_strfree(mTypes[i]);
         free(mTypes);
     }
- 
-    nsSocketTransportService *serv = gSocketTransportService;
-    NS_RELEASE(serv); // nulls argument
 }
 
 nsresult
 nsSocketTransport::Init(const char **types, uint32_t typeCount,
                         const nsACString &host, uint16_t port,
                         nsIProxyInfo *givenProxyInfo)
 {
     MOZ_EVENT_TRACER_NAME_OBJECT(this, host.BeginReading());
@@ -956,17 +952,17 @@ nsSocketTransport::PostEvent(uint32_t ty
 {
     SOCKET_LOG(("nsSocketTransport::PostEvent [this=%p type=%u status=%x param=%p]\n",
         this, type, status, param));
 
     nsCOMPtr<nsIRunnable> event = new nsSocketEvent(this, type, status, param);
     if (!event)
         return NS_ERROR_OUT_OF_MEMORY;
 
-    return gSocketTransportService->Dispatch(event, NS_DISPATCH_NORMAL);
+    return mSocketTransportService->Dispatch(event, NS_DISPATCH_NORMAL);
 }
 
 void
 nsSocketTransport::SendStatus(nsresult status)
 {
     SOCKET_LOG(("nsSocketTransport::SendStatus [this=%p status=%x]\n", this, status));
 
     nsCOMPtr<nsITransportEventSink> sink;
@@ -1214,29 +1210,29 @@ nsSocketTransport::InitiateSocket()
     // in a race to call AttachSocket once notified.  for this reason, when
     // we get notified, we just re-enter this function.  as a result, we are
     // sure to ask again before calling AttachSocket.  in this way we deal
     // with the race condition.  though it isn't the most elegant solution,
     // it is far simpler than trying to build a system that would guarantee
     // FIFO ordering (which wouldn't even be that valuable IMO).  see bug
     // 194402 for more info.
     //
-    if (!gSocketTransportService->CanAttachSocket()) {
+    if (!mSocketTransportService->CanAttachSocket()) {
         nsCOMPtr<nsIRunnable> event =
                 new nsSocketEvent(this, MSG_RETRY_INIT_SOCKET);
         if (!event)
             return NS_ERROR_OUT_OF_MEMORY;
-        return gSocketTransportService->NotifyWhenCanAttachSocket(event);
+        return mSocketTransportService->NotifyWhenCanAttachSocket(event);
     }
 
     //
     // if we already have a connected socket, then just attach and return.
     //
     if (mFD.IsInitialized()) {
-        rv = gSocketTransportService->AttachSocket(mFD, this);
+        rv = mSocketTransportService->AttachSocket(mFD, this);
         if (NS_SUCCEEDED(rv))
             mAttached = true;
         return rv;
     }
 
     //
     // create new socket fd, push io layers, etc.
     //
@@ -1268,31 +1264,31 @@ nsSocketTransport::InitiateSocket()
     opt.option = PR_SockOpt_NoDelay;
     opt.value.no_delay = true;
     PR_SetSocketOption(fd, &opt);
 
     // if the network.tcp.sendbuffer preference is set, use it to size SO_SNDBUF
     // The Windows default of 8KB is too small and as of vista sp1, autotuning
     // only applies to receive window
     int32_t sndBufferSize;
-    gSocketTransportService->GetSendBufferSize(&sndBufferSize);
+    mSocketTransportService->GetSendBufferSize(&sndBufferSize);
     if (sndBufferSize > 0) {
         opt.option = PR_SockOpt_SendBufferSize;
         opt.value.send_buffer_size = sndBufferSize;
         PR_SetSocketOption(fd, &opt);
     }
 
     if (mQoSBits) {
         opt.option = PR_SockOpt_IpTypeOfService;
         opt.value.tos = mQoSBits;
         PR_SetSocketOption(fd, &opt);
     }
 
     // inform socket transport about this newly created socket...
-    rv = gSocketTransportService->AttachSocket(fd, this);
+    rv = mSocketTransportService->AttachSocket(fd, this);
     if (NS_FAILED(rv)) {
         PR_Close(fd);
         return rv;
     }
     mAttached = true;
 
     // assign mFD so that we can properly handle OnSocketDetached before we've
     // established a connection.
@@ -1459,17 +1455,17 @@ nsSocketTransport::RecoverFromError()
         }
     }
 
 #if defined(XP_WIN)
     // If not trying next address, try to make a connection using dialup. 
     // Retry if that connection is made.
     if (!tryAgain) {
         bool autodialEnabled;
-        gSocketTransportService->GetAutodialEnabled(&autodialEnabled);
+        mSocketTransportService->GetAutodialEnabled(&autodialEnabled);
         if (autodialEnabled) {
           tryAgain = nsNativeConnectionHelper::OnConnectionFailed(
                        NS_ConvertUTF8toUTF16(SocketHost()).get());
 	    }
     }
 #endif
 
     // prepare to try again.
@@ -1961,17 +1957,17 @@ nsSocketTransport::OpenInputStream(uint3
 
         // create a pipe
         nsCOMPtr<nsIAsyncOutputStream> pipeOut;
         rv = NS_NewPipe2(getter_AddRefs(pipeIn), getter_AddRefs(pipeOut),
                          !openBlocking, true, segsize, segcount);
         if (NS_FAILED(rv)) return rv;
 
         // async copy from socket to pipe
-        rv = NS_AsyncCopy(&mInput, pipeOut, gSocketTransportService,
+        rv = NS_AsyncCopy(&mInput, pipeOut, mSocketTransportService,
                           NS_ASYNCCOPY_VIA_WRITESEGMENTS, segsize);
         if (NS_FAILED(rv)) return rv;
 
         *result = pipeIn;
     }
     else
         *result = &mInput;
 
@@ -2007,17 +2003,17 @@ nsSocketTransport::OpenOutputStream(uint
 
         // create a pipe
         nsCOMPtr<nsIAsyncInputStream> pipeIn;
         rv = NS_NewPipe2(getter_AddRefs(pipeIn), getter_AddRefs(pipeOut),
                          true, !openBlocking, segsize, segcount);
         if (NS_FAILED(rv)) return rv;
 
         // async copy from socket to pipe
-        rv = NS_AsyncCopy(pipeIn, &mOutput, gSocketTransportService,
+        rv = NS_AsyncCopy(pipeIn, &mOutput, mSocketTransportService,
                           NS_ASYNCCOPY_VIA_READSEGMENTS, segsize);
         if (NS_FAILED(rv)) return rv;
 
         *result = pipeOut;
     }
     else
         *result = &mOutput;
 
@@ -2446,17 +2442,17 @@ nsSocketTransport::SetKeepaliveEnabledIn
 
     PRFileDescAutoLock fd(this);
     if (NS_WARN_IF(!fd.IsInitialized())) {
         return NS_ERROR_NOT_INITIALIZED;
     }
 
     // Only enable if keepalives are globally enabled, but ensure other
     // options are set correctly on the fd.
-    bool enable = aEnable && gSocketTransportService->IsKeepaliveEnabled();
+    bool enable = aEnable && mSocketTransportService->IsKeepaliveEnabled();
     nsresult rv = fd.SetKeepaliveVals(enable,
                                       mKeepaliveIdleTimeS,
                                       mKeepaliveRetryIntervalS,
                                       mKeepaliveProbeCount);
     if (NS_WARN_IF(NS_FAILED(rv))) {
         SOCKET_LOG(("  SetKeepaliveVals failed rv[0x%x]", rv));
         return rv;
     }
@@ -2478,31 +2474,31 @@ nsSocketTransport::GetKeepaliveEnabled(b
 }
 
 nsresult
 nsSocketTransport::EnsureKeepaliveValsAreInitialized()
 {
     nsresult rv = NS_OK;
     int32_t val = -1;
     if (mKeepaliveIdleTimeS == -1) {
-        rv = gSocketTransportService->GetKeepaliveIdleTime(&val);
+        rv = mSocketTransportService->GetKeepaliveIdleTime(&val);
         if (NS_WARN_IF(NS_FAILED(rv))) {
             return rv;
         }
         mKeepaliveIdleTimeS = val;
     }
     if (mKeepaliveRetryIntervalS == -1) {
-        rv = gSocketTransportService->GetKeepaliveRetryInterval(&val);
+        rv = mSocketTransportService->GetKeepaliveRetryInterval(&val);
         if (NS_WARN_IF(NS_FAILED(rv))) {
             return rv;
         }
         mKeepaliveRetryIntervalS = val;
     }
     if (mKeepaliveProbeCount == -1) {
-        rv = gSocketTransportService->GetKeepaliveProbeCount(&val);
+        rv = mSocketTransportService->GetKeepaliveProbeCount(&val);
         if (NS_WARN_IF(NS_FAILED(rv))) {
             return rv;
         }
         mKeepaliveProbeCount = val;
     }
     return NS_OK;
 }
 
@@ -2529,17 +2525,17 @@ nsSocketTransport::SetKeepaliveEnabled(b
         }
     }
     SOCKET_LOG(("nsSocketTransport::SetKeepaliveEnabled [%p] "
                 "%s, idle time[%ds] retry interval[%ds] packet count[%d]: "
                 "globally %s.",
                 this, aEnable ? "enabled" : "disabled",
                 mKeepaliveIdleTimeS, mKeepaliveRetryIntervalS,
                 mKeepaliveProbeCount,
-                gSocketTransportService->IsKeepaliveEnabled() ?
+                mSocketTransportService->IsKeepaliveEnabled() ?
                 "enabled" : "disabled"));
 
     // Set mKeepaliveEnabled here so that state is maintained; it is possible
     // that we're in between fds, e.g. the 1st IP address failed, so we're about
     // to retry on a 2nd from the DNS record.
     mKeepaliveEnabled = aEnable;
 
     rv = SetKeepaliveEnabledInternal(aEnable);
@@ -2578,17 +2574,17 @@ nsSocketTransport::SetKeepaliveVals(int3
         return NS_OK;
     }
     mKeepaliveIdleTimeS = aIdleTime;
     mKeepaliveRetryIntervalS = aRetryInterval;
 
     nsresult rv = NS_OK;
     if (mKeepaliveProbeCount == -1) {
         int32_t val = -1;
-        nsresult rv = gSocketTransportService->GetKeepaliveProbeCount(&val);
+        nsresult rv = mSocketTransportService->GetKeepaliveProbeCount(&val);
         if (NS_WARN_IF(NS_FAILED(rv))) {
             return rv;
         }
         mKeepaliveProbeCount = val;
     }
 
     SOCKET_LOG(("nsSocketTransport::SetKeepaliveVals [%p] "
                 "keepalive %s, idle time[%ds] retry interval[%ds] "
--- a/netwerk/base/src/nsSocketTransport2.h
+++ b/netwerk/base/src/nsSocketTransport2.h
@@ -18,16 +18,17 @@
 #include "nsIAsyncInputStream.h"
 #include "nsIAsyncOutputStream.h"
 #include "nsIDNSListener.h"
 #include "nsIClassInfo.h"
 #include "mozilla/net/DNS.h"
 #include "nsASocketHandler.h"
 
 #include "prerror.h"
+#include "nsAutoPtr.h"
 
 class nsSocketTransport;
 class nsICancelable;
 class nsIDNSRecord;
 class nsIInterfaceRequestor;
 
 nsresult
 ErrorAccordingToNSPR(PRErrorCode errorCode);
@@ -324,16 +325,21 @@ private:
     // socket input/output objects.  these may be accessed on any thread with
     // the exception of some specific methods (XXX).
 
     Mutex            mLock;  // protects members in this section.
     LockedPRFileDesc mFD;
     nsrefcnt         mFDref;       // mFD is closed when mFDref goes to zero.
     bool             mFDconnected; // mFD is available to consumer when TRUE.
 
+    // A delete protector reference to gSocketTransportService held for lifetime
+    // of 'this'. Sometimes used interchangably with gSocketTransportService due
+    // to scoping.
+    nsRefPtr<nsSocketTransportService> mSocketTransportService;
+
     nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
     nsCOMPtr<nsITransportEventSink> mEventSink;
     nsCOMPtr<nsISupports>           mSecInfo;
 
     nsSocketInputStream  mInput;
     nsSocketOutputStream mOutput;
 
     friend class nsSocketInputStream;