diff --git a/netwerk/protocol/ftp/src/nsConnectionCacheObj.h b/netwerk/protocol/ftp/src/nsConnectionCacheObj.h index 18ac8de5bf44..98e78f6225bc 100644 --- a/netwerk/protocol/ftp/src/nsConnectionCacheObj.h +++ b/netwerk/protocol/ftp/src/nsConnectionCacheObj.h @@ -23,6 +23,7 @@ #ifndef __nsconnectioncacheobj__h____ #define __nsconnectioncacheobj__h____ +#include "nsCOMPtr.h" #include "nsIChannel.h" #include "nsIInputStream.h" #include "nsIOutputStream.h" @@ -40,27 +41,16 @@ public: nsIOutputStream *aOutputStream) { mSocketTransport = aChannel; - NS_ADDREF(mSocketTransport); - mInputStream = aInputStream; - NS_ADDREF(mInputStream); - mOutputStream = aOutputStream; - NS_ADDREF(mOutputStream); - mServerType = 0; mList = PR_FALSE; }; - ~nsConnectionCacheObj() - { - NS_RELEASE(mSocketTransport); - NS_RELEASE(mInputStream); - NS_RELEASE(mOutputStream); - }; + ~nsConnectionCacheObj() {;}; - nsIChannel *mSocketTransport; // the connection - nsIInputStream *mInputStream; // to read from server - nsIOutputStream *mOutputStream; // to write to server + nsCOMPtr mSocketTransport; // the connection + nsCOMPtr mInputStream; // to read from server + nsCOMPtr mOutputStream; // to write to server PRUint32 mServerType; // what kind of server is it. nsCAutoString mCwd; // what dir are we in PRBool mList; // are we sending LIST or NLST diff --git a/netwerk/protocol/ftp/src/nsFTPChannel.cpp b/netwerk/protocol/ftp/src/nsFTPChannel.cpp index 13fa7b7bf568..c3f811af96f4 100644 --- a/netwerk/protocol/ftp/src/nsFTPChannel.cpp +++ b/netwerk/protocol/ftp/src/nsFTPChannel.cpp @@ -55,21 +55,25 @@ nsFTPChannel::nsFTPChannel() { mContentLength = -1; mConnThread = nsnull; mAsyncOpen = PR_FALSE; + mLock = nsnull; } nsFTPChannel::~nsFTPChannel() { NS_ASSERTION(!mConnThread, "FTP: connection thread ref still exists"); PR_LOG(gFTPLog, PR_LOG_ALWAYS, ("~nsFTPChannel() called")); + if (mLock) PR_DestroyLock(mLock); } -NS_IMPL_ISUPPORTS7(nsFTPChannel, - nsPIFTPChannel, - nsIChannel, - nsIRequest, - nsIInterfaceRequestor, - nsIProgressEventSink, - nsIStreamListener, - nsIStreamObserver); +NS_IMPL_THREADSAFE_ADDREF(nsFTPChannel); +NS_IMPL_THREADSAFE_RELEASE(nsFTPChannel); +NS_IMPL_QUERY_INTERFACE7(nsFTPChannel, + nsPIFTPChannel, + nsIChannel, + nsIRequest, + nsIInterfaceRequestor, + nsIProgressEventSink, + nsIStreamListener, + nsIStreamObserver); nsresult nsFTPChannel::Init(const char* verb, @@ -114,6 +118,9 @@ nsFTPChannel::Init(const char* verb, mBufferSegmentSize = bufferSegmentSize; mBufferMaxSize = bufferMaxSize; + NS_ASSERTION(!mLock, "Init should only be called once on a channel"); + mLock = PR_NewLock(); + if (!mLock) return NS_ERROR_OUT_OF_MEMORY; return rv; } @@ -154,8 +161,6 @@ nsFTPChannel::IsPending(PRBool *result) { NS_IMETHODIMP nsFTPChannel::Cancel(void) { - nsresult rv = NS_OK; - if (mProxyChannel) return mProxyChannel->Cancel(); @@ -468,6 +473,7 @@ nsFTPChannel::GetContentType(char* *aContentType) { if (!aContentType) return NS_ERROR_NULL_POINTER; + nsAutoLock lock(mLock); *aContentType = nsnull; if (mContentType.IsEmpty()) { NS_WITH_SERVICE(nsIMIMEService, MIMEService, kMIMEServiceCID, &rv); @@ -493,14 +499,15 @@ nsFTPChannel::GetContentType(char* *aContentType) { NS_IMETHODIMP nsFTPChannel::SetContentType(const char *aContentType) { + nsAutoLock lock(mLock); mContentType = aContentType; - return NS_OK; } NS_IMETHODIMP nsFTPChannel::GetContentLength(PRInt32 *aContentLength) { + nsAutoLock lock(mLock); *aContentLength = mContentLength; return NS_OK; } @@ -560,21 +567,19 @@ nsFTPChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallb NS_IMETHODIMP nsFTPChannel::SetContentLength(PRInt32 aLength) { + nsAutoLock lock(mLock); mContentLength = aLength; return NS_OK; } NS_IMETHODIMP nsFTPChannel::Stopped(nsresult aStatus, const PRUnichar *aMsg) { - nsresult rv = NS_OK; + nsAutoLock lock(mLock); // the underlying connection thread has gone away. mConnected = PR_FALSE; - NS_ASSERTION(mConnThread, "lost the connection thread"); + NS_ASSERTION(mConnThread, "lost the connection thread before Stopped"); NS_RELEASE(mConnThread); - if (mLoadGroup) - rv = mLoadGroup->RemoveChannel(this, nsnull, aStatus, aMsg); - - return rv; + return NS_OK; } // nsIInterfaceRequestor method @@ -620,12 +625,12 @@ NS_IMETHODIMP nsFTPChannel::OnStopRequest(nsIChannel* aChannel, nsISupports* aContext, nsresult aStatus, const PRUnichar* aMsg) { nsresult rv = NS_OK; - if (mProxyChannel) { - if (mLoadGroup) { - rv = mLoadGroup->RemoveChannel(this, nsnull, aStatus, aMsg); - if (NS_FAILED(rv)) return rv; - } + + if (mLoadGroup) { + rv = mLoadGroup->RemoveChannel(this, nsnull, aStatus, aMsg); + if (NS_FAILED(rv)) return rv; } + if (mObserver) { rv = mObserver->OnStopRequest(this, aContext, aStatus, aMsg); if (NS_FAILED(rv)) return rv; diff --git a/netwerk/protocol/ftp/src/nsFTPChannel.h b/netwerk/protocol/ftp/src/nsFTPChannel.h index 6509f005642e..2fca7e92a78d 100644 --- a/netwerk/protocol/ftp/src/nsFTPChannel.h +++ b/netwerk/protocol/ftp/src/nsFTPChannel.h @@ -38,6 +38,7 @@ #include "netCore.h" #include "nsXPIDLString.h" #include "nsIStreamListener.h" +#include "nsAutoLock.h" class nsFTPChannel : public nsPIFTPChannel, public nsIInterfaceRequestor, @@ -104,6 +105,7 @@ protected: PRUint32 mBufferMaxSize; nsCOMPtr mProxyChannel; // a proxy channel nsXPIDLCString mHost; + PRLock* mLock; }; #endif /* nsFTPChannel_h___ */ diff --git a/netwerk/protocol/ftp/src/nsFtpConnectionThread.cpp b/netwerk/protocol/ftp/src/nsFtpConnectionThread.cpp index 8b23676f1e67..47b14205cd39 100644 --- a/netwerk/protocol/ftp/src/nsFtpConnectionThread.cpp +++ b/netwerk/protocol/ftp/src/nsFtpConnectionThread.cpp @@ -60,8 +60,9 @@ static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID); extern PRLogModuleInfo* gFTPLog; #endif /* PR_LOGGING */ - -NS_IMPL_ISUPPORTS3(nsFtpConnectionThread, nsIRunnable, nsIRequest, nsIStreamObserver); +NS_IMPL_THREADSAFE_ADDREF(nsFtpConnectionThread); +NS_IMPL_THREADSAFE_RELEASE(nsFtpConnectionThread); +NS_IMPL_QUERY_INTERFACE3(nsFtpConnectionThread, nsIRunnable, nsIRequest, nsIStreamObserver); nsFtpConnectionThread::nsFtpConnectionThread() { NS_INIT_REFCNT(); @@ -1676,22 +1677,10 @@ nsFtpConnectionThread::Init(nsIProtocolHandler* aHandler, NS_WITH_SERVICE(nsIProxyObjectManager, pIProxyObjectManager, kProxyObjectManagerCID, &rv); if(NS_FAILED(rv)) return rv; - // This proxied channel is used to set channel related - // state on the *real* channel back in the main thread. - rv = pIProxyObjectManager->GetProxyObject(NS_UI_THREAD_EVENTQ, - NS_GET_IID(nsPIFTPChannel), - aChannel, - PROXY_SYNC | PROXY_ALWAYS, - getter_AddRefs(mFTPChannel)); + mFTPChannel = do_QueryInterface(aChannel, &rv); if (NS_FAILED(rv)) return rv; - // get a proxied ptr to the FTP protocol handler service so we can control - // the connection cache from here. - rv = pIProxyObjectManager->GetProxyObject(NS_UI_THREAD_EVENTQ, - NS_GET_IID(nsIConnectionCache), - aHandler, - PROXY_SYNC | PROXY_ALWAYS, - getter_AddRefs(mConnCache)); + mConnCache = do_QueryInterface(aHandler, &rv); return rv; } diff --git a/netwerk/protocol/ftp/src/nsFtpProtocolHandler.cpp b/netwerk/protocol/ftp/src/nsFtpProtocolHandler.cpp index 341e97c3859d..3ed799fdfe40 100644 --- a/netwerk/protocol/ftp/src/nsFtpProtocolHandler.cpp +++ b/netwerk/protocol/ftp/src/nsFtpProtocolHandler.cpp @@ -61,13 +61,16 @@ static NS_DEFINE_CID(kHTTPHandlerCID, NS_IHTTPHANDLER_CID); nsFtpProtocolHandler::~nsFtpProtocolHandler() { PR_LOG(gFTPLog, PR_LOG_ALWAYS, ("~nsFtpProtocolHandler() called")); + if (mLock) PR_DestroyLock(mLock); } -NS_IMPL_ISUPPORTS4(nsFtpProtocolHandler, - nsIProtocolHandler, - nsIConnectionCache, - nsIObserver, - nsIProxy) +NS_IMPL_THREADSAFE_ADDREF(nsFtpProtocolHandler); +NS_IMPL_THREADSAFE_RELEASE(nsFtpProtocolHandler); +NS_IMPL_QUERY_INTERFACE4(nsFtpProtocolHandler, + nsIProtocolHandler, + nsIConnectionCache, + nsIObserver, + nsIProxy); nsresult nsFtpProtocolHandler::Init() { @@ -93,6 +96,10 @@ nsFtpProtocolHandler::Init() { nsAutoString topic(NS_XPCOM_SHUTDOWN_OBSERVER_ID); obsServ->AddObserver(this, topic.GetUnicode()); } + + mLock = PR_NewLock(); + if (!mLock) return NS_ERROR_OUT_OF_MEMORY; + return rv; } @@ -241,6 +248,7 @@ NS_IMETHODIMP nsFtpProtocolHandler::RemoveConn(const char *aKey, nsConnectionCacheObj* *_retval) { NS_ASSERTION(_retval, "null pointer"); nsStringKey key(aKey); + nsAutoLock lock(mLock); *_retval = (nsConnectionCacheObj*)mRootConnectionList->Remove(&key); return NS_OK; } @@ -249,6 +257,7 @@ NS_IMETHODIMP nsFtpProtocolHandler::InsertConn(const char *aKey, nsConnectionCacheObj *aConn) { NS_ASSERTION(aConn, "null pointer"); nsStringKey key(aKey); + nsAutoLock lock(mLock); mRootConnectionList->Put(&key, aConn); return NS_OK; } diff --git a/netwerk/protocol/ftp/src/nsFtpProtocolHandler.h b/netwerk/protocol/ftp/src/nsFtpProtocolHandler.h index e2d3a52ee550..fdbbe06832cf 100644 --- a/netwerk/protocol/ftp/src/nsFtpProtocolHandler.h +++ b/netwerk/protocol/ftp/src/nsFtpProtocolHandler.h @@ -31,6 +31,7 @@ #include "nsIThreadPool.h" #include "nsIObserverService.h" #include "nsIProtocolProxyService.h" +#include "nsAutoLock.h" // {25029490-F132-11d2-9588-00805F369F95} #define NS_FTPPROTOCOLHANDLER_CID \ @@ -49,7 +50,7 @@ public: NS_DECL_NSIPROXY // nsFtpProtocolHandler methods: - nsFtpProtocolHandler() { + nsFtpProtocolHandler() { NS_INIT_REFCNT(); mProxyPort = -1; }; @@ -65,6 +66,7 @@ protected: nsCOMPtr mProxySvc; nsCAutoString mProxyHost; PRInt32 mProxyPort; + PRLock* mLock; }; #define NS_FTP_MIN_CONNECTION_COUNT 1