removing extraneous channel member, and ensuring that final releases used by the FTP thread are made on the owning thread.

This commit is contained in:
valeski%netscape.com 2000-05-03 21:20:32 +00:00
parent 7ee2674e50
commit b1f5ae2519
4 changed files with 85 additions and 14 deletions

View File

@ -103,4 +103,3 @@ nsFTPAsyncWriteEvent::HandleEvent()
if (NS_FAILED(rv)) return rv;
return mChannel->AsyncWrite(mInStream, mObserver, mContext);
}

View File

@ -55,7 +55,7 @@ class nsFTPAsyncReadEvent : public nsAsyncEvent
{
public:
nsFTPAsyncReadEvent(nsIStreamListener* listener, nsIChannel* channel, nsISupports* context);
virtual ~nsFTPAsyncReadEvent() {}
virtual ~nsFTPAsyncReadEvent() {};
NS_IMETHOD HandleEvent();
protected:
@ -72,7 +72,7 @@ public:
nsIStreamObserver* observer,
nsIChannel* channel,
nsISupports* context);
virtual ~nsFTPAsyncWriteEvent() {}
virtual ~nsFTPAsyncWriteEvent() {};
NS_IMETHOD HandleEvent();
protected:
@ -81,4 +81,19 @@ protected:
PRUint32 mWriteCount;
};
// Release event. This is used to marshall the release
// of the channel over to the calling/owning thread.
class nsFTPReleaseEvent : public nsAsyncEvent
{
public:
nsFTPReleaseEvent(nsISupports *aRef)
: nsAsyncEvent(nsnull, nsnull) { mRef = aRef; };
virtual ~nsFTPReleaseEvent() {};
// nothing to do but have the destructor called.
NS_IMETHOD HandleEvent() { return NS_OK; };
protected:
nsCOMPtr<nsISupports> mRef;
};
#endif // ___nsasyncevent_h____

View File

@ -874,7 +874,8 @@ nsFtpConnectionThread::S_pass() {
PRUnichar *passwd = nsnull;
PRBool retval;
nsAutoString message;
nsAutoString title; title.AssignWithConversion("Password");
nsAutoString title;
title.AssignWithConversion("Password");
nsXPIDLCString host;
rv = mURL->GetHost(getter_Copies(host));
@ -1047,7 +1048,7 @@ nsFtpConnectionThread::R_cwd() {
if (mResponseCode/100 == 2) {
mCwd = mCwdAttempt;
nsresult rv = mFTPChannel->SetContentType("application/http-index-format");
nsresult rv = mChannel->SetContentType("application/http-index-format");
if (NS_FAILED(rv)) return FTP_ERROR;
// success
@ -1085,7 +1086,7 @@ nsFtpConnectionThread::R_size() {
PRInt32 conversionError;
mLength = mResponseMsg.ToInteger(&conversionError);
rv = mFTPChannel->SetContentLength(mLength);
rv = mChannel->SetContentLength(mLength);
if (NS_FAILED(rv)) return FTP_ERROR;
}
@ -1356,7 +1357,7 @@ nsFtpConnectionThread::R_pasv() {
// we're connected figure out what type of transfer we're doing (ascii or binary)
nsXPIDLCString type;
rv = mFTPChannel->GetContentType(getter_Copies(type));
rv = mChannel->GetContentType(getter_Copies(type));
nsCAutoString typeStr;
if (NS_FAILED(rv) || !type)
typeStr = "bin";
@ -1447,10 +1448,71 @@ nsFtpConnectionThread::Run() {
if(NS_FAILED(rv)) return rv;
rv = Process(); // turn the crank.
mListener = 0;
mChannel = 0;
if (NS_FAILED(rv)) return rv;
// before releaseing the refs to these cached members,
// marshall over a ref so we're sure the final release
// of these members doesn't occur on our thread.
NS_ASSERTION(mListener, "no listener implies no-one is handling data");
nsFTPReleaseEvent *event =
new nsFTPReleaseEvent(NS_STATIC_CAST(nsISupports*, mListener));
if (!event) return NS_ERROR_OUT_OF_MEMORY;
rv = event->Fire(mEventQueue);
if (NS_FAILED(rv)) return rv;
mListener = 0; // ditch our ref.
if (mListenerContext) {
event = new nsFTPReleaseEvent(NS_STATIC_CAST(nsISupports*, mListenerContext));
if (!event) return NS_ERROR_OUT_OF_MEMORY;
rv = event->Fire(mEventQueue);
if (NS_FAILED(rv)) return rv;
mListenerContext = 0;
}
if (mObserver) {
event = new nsFTPReleaseEvent(NS_STATIC_CAST(nsISupports*, mObserver));
if (!event) return NS_ERROR_OUT_OF_MEMORY;
rv = event->Fire(mEventQueue);
if (NS_FAILED(rv)) return rv;
mObserver = 0;
}
if (mObserverContext) {
event = new nsFTPReleaseEvent(NS_STATIC_CAST(nsISupports*, mObserverContext));
if (!event) return NS_ERROR_OUT_OF_MEMORY;
rv = event->Fire(mEventQueue);
if (NS_FAILED(rv)) return rv;
mObserverContext = 0;
}
event = new nsFTPReleaseEvent(NS_STATIC_CAST(nsISupports*, mChannel));
if (!event) return NS_ERROR_OUT_OF_MEMORY;
rv = event->Fire(mEventQueue);
if (NS_FAILED(rv)) return rv;
mChannel = 0; // ditch our ref
event = new nsFTPReleaseEvent(NS_STATIC_CAST(nsISupports*, mConnCache));
if (!event) return NS_ERROR_OUT_OF_MEMORY;
rv = event->Fire(mEventQueue);
if (NS_FAILED(rv)) return rv;
mConnCache = 0;
if (mPrompter) {
event = new nsFTPReleaseEvent(NS_STATIC_CAST(nsISupports*, mPrompter));
if (!event) return NS_ERROR_OUT_OF_MEMORY;
rv = event->Fire(mEventQueue);
if (NS_FAILED(rv)) return rv;
mPrompter = 0;
}
if (mWriteStream) {
event = new nsFTPReleaseEvent(NS_STATIC_CAST(nsISupports*, mWriteStream));
if (!event) return NS_ERROR_OUT_OF_MEMORY;
rv = event->Fire(mEventQueue);
if (NS_FAILED(rv)) return rv;
mWriteStream = 0;
}
return rv;
}
@ -1573,7 +1635,6 @@ nsFtpConnectionThread::Init(nsIProtocolHandler* aHandler,
// parameter validation
NS_ASSERTION(aChannel, "FTP: thread needs a channel");
// setup internal member variables
mChannel = aChannel; // a straight com ptr to the channel
rv = aChannel->GetURI(getter_AddRefs(mURL));
@ -1629,9 +1690,6 @@ nsFtpConnectionThread::Init(nsIProtocolHandler* aHandler,
rv = eqs->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(mEventQueue));
if (NS_FAILED(rv)) return rv;
mFTPChannel = do_QueryInterface(aChannel, &rv);
if (NS_FAILED(rv)) return rv;
mConnCache = do_QueryInterface(aHandler, &rv);
return rv;
}

View File

@ -201,7 +201,6 @@ private:
PRBool mConnected; // are we connected.
PRBool mSentStart; // have we sent an OnStartRequest() notification
PRUint8 mSuspendCount;// number of times we've been suspended.
nsCOMPtr<nsIChannel> mFTPChannel;// used to synchronize w/ our owning channel.
PRUint32 mBufferSegmentSize;
PRUint32 mBufferMaxSize;
PRLock *mLock;