bug 670277 - Fix WARNING: NS_ENSURE_TRUE(mState == STATE_TRANSFERRING) r=biesi
authorPatrick McManus <mcmanus@ducksong.com>
Thu, 26 Jan 2012 16:04:54 -0500
changeset 85515 c4b103adf7fc4bf141b1bb9d2109372524c3949d
parent 85514 60020371c71ba8b2960c5f5fc5efcaa7be8028e8
child 85516 91cbd6eb803c5d679c812eeec40e25c4c79ba976
push id5362
push usermcmanus@ducksong.com
push dateThu, 26 Jan 2012 21:10:43 +0000
treeherdermozilla-inbound@c4b103adf7fc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbiesi
bugs670277
milestone12.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 670277 - Fix WARNING: NS_ENSURE_TRUE(mState == STATE_TRANSFERRING) r=biesi
netwerk/base/src/nsSocketTransport2.cpp
netwerk/base/src/nsSocketTransport2.h
--- a/netwerk/base/src/nsSocketTransport2.cpp
+++ b/netwerk/base/src/nsSocketTransport2.cpp
@@ -717,16 +717,17 @@ nsSocketTransport::nsSocketTransport()
     , mProxyTransparent(false)
     , mProxyTransparentResolvesHost(false)
     , mConnectionFlags(0)
     , mState(STATE_CLOSED)
     , mAttached(false)
     , mInputClosed(true)
     , mOutputClosed(true)
     , mResolving(false)
+    , mNetAddrIsSet(false)
     , mLock("nsSocketTransport.mLock")
     , mFD(nsnull)
     , mFDref(0)
     , mFDconnected(false)
     , mInput(this)
     , mOutput(this)
     , mQoSBits(0x00)
 {
@@ -853,16 +854,17 @@ nsSocketTransport::InitWithConnectedSock
         port = addr->ipv6.port;
     mPort = PR_ntohs(port);
 
     memcpy(&mNetAddr, addr, sizeof(PRNetAddr));
 
     mPollFlags = (PR_POLL_READ | PR_POLL_WRITE | PR_POLL_EXCEPT);
     mPollTimeout = mTimeouts[TIMEOUT_READ_WRITE];
     mState = STATE_TRANSFERRING;
+    mNetAddrIsSet = true;
 
     mFD = fd;
     mFDref = 1;
     mFDconnected = 1;
 
     // make sure new socket is non-blocking
     PRSocketOptionData opt;
     opt.option = PR_SockOpt_Nonblocking;
@@ -1394,16 +1396,20 @@ void
 nsSocketTransport::OnSocketConnected()
 {
     SOCKET_LOG(("  advancing to STATE_TRANSFERRING\n"));
 
     mPollFlags = (PR_POLL_READ | PR_POLL_WRITE | PR_POLL_EXCEPT);
     mPollTimeout = mTimeouts[TIMEOUT_READ_WRITE];
     mState = STATE_TRANSFERRING;
 
+    // Set the mNetAddrIsSet flag only when state has reached TRANSFERRING
+    // because we need to make sure its value does not change due to failover
+    mNetAddrIsSet = true;
+
     // assign mFD (must do this within the transport lock), but take care not
     // to trample over mFDref if mFD is already set.
     {
         MutexAutoLock lock(mLock);
         NS_ASSERTION(mFD, "no socket");
         NS_ASSERTION(mFDref == 1, "wrong socket ref count");
         mFDconnected = true;
     }
@@ -1910,17 +1916,21 @@ nsSocketTransport::GetPort(PRInt32 *port
 NS_IMETHODIMP
 nsSocketTransport::GetPeerAddr(PRNetAddr *addr)
 {
     // once we are in the connected state, mNetAddr will not change.
     // so if we can verify that we are in the connected state, then
     // we can freely access mNetAddr from any thread without being
     // inside a critical section.
 
-    NS_ENSURE_TRUE(mState == STATE_TRANSFERRING, NS_ERROR_NOT_AVAILABLE);
+    if (!mNetAddrIsSet) {
+        SOCKET_LOG(("nsSocketTransport::GetPeerAddr [this=%p state=%d] "
+                    "NOT_AVAILABLE because not yet connected.", this, mState));
+        return NS_ERROR_NOT_AVAILABLE;
+    }
 
     memcpy(addr, &mNetAddr, sizeof(mNetAddr));
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSocketTransport::GetSelfAddr(PRNetAddr *addr)
 {
--- a/netwerk/base/src/nsSocketTransport2.h
+++ b/netwerk/base/src/nsSocketTransport2.h
@@ -221,17 +221,21 @@ private:
     bool mOutputClosed;
 
     // this flag is used to determine if the results of a host lookup arrive
     // recursively or not.  this flag is not protected by any lock.
     bool mResolving;
 
     nsCOMPtr<nsICancelable> mDNSRequest;
     nsCOMPtr<nsIDNSRecord>  mDNSRecord;
+
+    // mNetAddr is valid from GetPeerAddr() once we have
+    // reached STATE_TRANSFERRING. It must not change after that.
     PRNetAddr               mNetAddr;
+    bool                    mNetAddrIsSet;
 
     // socket methods (these can only be called on the socket thread):
 
     void     SendStatus(nsresult status);
     nsresult ResolveHost();
     nsresult BuildSocket(PRFileDesc *&, bool &, bool &); 
     nsresult InitiateSocket();
     bool     RecoverFromError();