зеркало из https://github.com/mozilla/gecko-dev.git
r=rpotts. a=jar (checkin on red approval = leaf). built, run and pre-checkin tested on all three platforms. 28042. The FTP thread is now threadsafe, and I've reduced the amount of proxy object usage.
This commit is contained in:
Родитель
bc4e8ed4e4
Коммит
c6e8443b96
|
@ -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<nsIChannel> mSocketTransport; // the connection
|
||||
nsCOMPtr<nsIInputStream> mInputStream; // to read from server
|
||||
nsCOMPtr<nsIOutputStream> 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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<nsIChannel> mProxyChannel; // a proxy channel
|
||||
nsXPIDLCString mHost;
|
||||
PRLock* mLock;
|
||||
};
|
||||
|
||||
#endif /* nsFTPChannel_h___ */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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<nsIProtocolProxyService> mProxySvc;
|
||||
nsCAutoString mProxyHost;
|
||||
PRInt32 mProxyPort;
|
||||
PRLock* mLock;
|
||||
};
|
||||
|
||||
#define NS_FTP_MIN_CONNECTION_COUNT 1
|
||||
|
|
Загрузка…
Ссылка в новой задаче