Backed out changeset 6357eb31cec6 (bug 455311) for causing performance regression bug 458065.

This commit is contained in:
L. David Baron 2008-10-05 19:55:41 -07:00
Родитель edcf45724a
Коммит d9056fab22
13 изменённых файлов: 44 добавлений и 127 удалений

Просмотреть файл

@ -62,7 +62,7 @@ class ScopedRequestSuspender {
public: public:
ScopedRequestSuspender(nsIRequest *request) ScopedRequestSuspender(nsIRequest *request)
: mRequest(request) { : mRequest(request) {
if (mRequest && NS_FAILED(mRequest->Suspend())) { if (NS_FAILED(mRequest->Suspend())) {
NS_WARNING("Couldn't suspend pump"); NS_WARNING("Couldn't suspend pump");
mRequest = nsnull; mRequest = nsnull;
} }
@ -94,8 +94,7 @@ nsBaseChannel::nsBaseChannel()
} }
nsresult nsresult
nsBaseChannel::Redirect(nsIChannel *newChannel, PRUint32 redirectFlags, nsBaseChannel::Redirect(nsIChannel *newChannel, PRUint32 redirectFlags)
PRBool openNewChannel)
{ {
SUSPEND_PUMP_FOR_SCOPE(); SUSPEND_PUMP_FOR_SCOPE();
@ -148,11 +147,9 @@ nsBaseChannel::Redirect(nsIChannel *newChannel, PRUint32 redirectFlags,
// unaffected, so we defer tearing down our channel until we have succeeded // unaffected, so we defer tearing down our channel until we have succeeded
// with the redirect. // with the redirect.
if (openNewChannel) { rv = newChannel->AsyncOpen(mListener, mListenerContext);
rv = newChannel->AsyncOpen(mListener, mListenerContext); if (NS_FAILED(rv))
if (NS_FAILED(rv)) return rv;
return rv;
}
// close down this channel // close down this channel
Cancel(NS_BINDING_REDIRECTED); Cancel(NS_BINDING_REDIRECTED);
@ -219,17 +216,10 @@ nsresult
nsBaseChannel::BeginPumpingData() nsBaseChannel::BeginPumpingData()
{ {
nsCOMPtr<nsIInputStream> stream; nsCOMPtr<nsIInputStream> stream;
nsCOMPtr<nsIChannel> channel; nsresult rv = OpenContentStream(PR_TRUE, getter_AddRefs(stream));
nsresult rv = OpenContentStream(PR_TRUE, getter_AddRefs(stream),
getter_AddRefs(channel));
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return rv; return rv;
NS_ASSERTION(!stream || !channel, "Got both a channel and a stream?");
if (channel)
return NS_DispatchToCurrentThread(new RedirectRunnable(this, channel));
// By assigning mPump, we flag this channel as pending (see IsPending). It's // By assigning mPump, we flag this channel as pending (see IsPending). It's
// important that the pending flag is set when we call into the stream (the // important that the pending flag is set when we call into the stream (the
// call to AsyncRead results in the stream's AsyncWait method being called) // call to AsyncRead results in the stream's AsyncWait method being called)
@ -244,29 +234,6 @@ nsBaseChannel::BeginPumpingData()
return rv; return rv;
} }
void
nsBaseChannel::HandleAsyncRedirect(nsIChannel* newChannel)
{
NS_ASSERTION(!mPump, "Shouldn't have gotten here");
nsresult rv = Redirect(newChannel, nsIChannelEventSink::REDIRECT_INTERNAL,
PR_TRUE);
if (NS_FAILED(rv)) {
// Notify our consumer ourselves
Cancel(rv);
mListener->OnStartRequest(this, mListenerContext);
mListener->OnStopRequest(this, mListenerContext, mStatus);
mListener = nsnull;
mListenerContext = nsnull;
}
if (mLoadGroup)
mLoadGroup->RemoveRequest(this, nsnull, mStatus);
// Drop notification callbacks to prevent cycles.
mCallbacks = nsnull;
CallbacksChanged();
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// nsBaseChannel::nsISupports // nsBaseChannel::nsISupports
@ -484,15 +451,8 @@ nsBaseChannel::Open(nsIInputStream **result)
NS_ENSURE_TRUE(!mPump, NS_ERROR_IN_PROGRESS); NS_ENSURE_TRUE(!mPump, NS_ERROR_IN_PROGRESS);
NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_IN_PROGRESS); NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_IN_PROGRESS);
nsCOMPtr<nsIChannel> chan; nsresult rv = OpenContentStream(PR_FALSE, result);
nsresult rv = OpenContentStream(PR_FALSE, result, getter_AddRefs(chan)); if (rv == NS_ERROR_NOT_IMPLEMENTED)
NS_ASSERTION(!chan || !*result, "Got both a channel and a stream?");
if (NS_SUCCEEDED(rv) && chan) {
rv = Redirect(chan, nsIChannelEventSink::REDIRECT_INTERNAL, PR_FALSE);
if (NS_FAILED(rv))
return rv;
rv = chan->Open(result);
} else if (rv == NS_ERROR_NOT_IMPLEMENTED)
return NS_ImplementChannelOpen(this, result); return NS_ImplementChannelOpen(this, result);
mWasOpened = NS_SUCCEEDED(rv); mWasOpened = NS_SUCCEEDED(rv);

Просмотреть файл

@ -52,7 +52,6 @@
#include "nsIInterfaceRequestor.h" #include "nsIInterfaceRequestor.h"
#include "nsIProgressEventSink.h" #include "nsIProgressEventSink.h"
#include "nsITransport.h" #include "nsITransport.h"
#include "nsThreadUtils.h"
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// nsBaseChannel is designed to be subclassed. The subclass is responsible for // nsBaseChannel is designed to be subclassed. The subclass is responsible for
@ -104,12 +103,7 @@ private:
// need to implement ReadSegments. If async is false, this method may return // need to implement ReadSegments. If async is false, this method may return
// NS_ERROR_NOT_IMPLEMENTED to cause the basechannel to implement Open in // NS_ERROR_NOT_IMPLEMENTED to cause the basechannel to implement Open in
// terms of AsyncOpen (see NS_ImplementChannelOpen). // terms of AsyncOpen (see NS_ImplementChannelOpen).
// A callee is allowed to return an nsIChannel instead of an nsIInputStream. virtual nsresult OpenContentStream(PRBool async, nsIInputStream **stream) = 0;
// That case will be treated as a redirect to the new channel. By default
// *channel will be set to null by the caller, so callees who don't want to
// return one an just not touch it.
virtual nsresult OpenContentStream(PRBool async, nsIInputStream **stream,
nsIChannel** channel) = 0;
// The basechannel calls this method from its OnTransportStatus method to // The basechannel calls this method from its OnTransportStatus method to
// determine whether to call nsIProgressEventSink::OnStatus in addition to // determine whether to call nsIProgressEventSink::OnStatus in addition to
@ -132,14 +126,12 @@ public:
// Methods provided for use by the derived class: // Methods provided for use by the derived class:
// Redirect to another channel. This method takes care of notifying // Redirect to another channel. This method takes care of notifying
// observers of this redirect as well as of opening the new channel, if asked // observers of this redirect as well as of opening the new channel. It also
// to do so. It also cancels |this| with the status code // cancels |this| with the status code NS_BINDING_REDIRECTED. A failure
// NS_BINDING_REDIRECTED. A failure return from this method means that the // return from this method means that the redirect could not be performed (no
// redirect could not be performed (no channel was opened; this channel // channel was opened; this channel wasn't canceled.) The redirectFlags
// wasn't canceled.) The redirectFlags parameter consists of the flag values // parameter consists of the flag values defined on nsIChannelEventSink.
// defined on nsIChannelEventSink. nsresult Redirect(nsIChannel *newChannel, PRUint32 redirectFlags);
nsresult Redirect(nsIChannel *newChannel, PRUint32 redirectFlags,
PRBool openNewChannel);
// Tests whether a type hint was set. Subclasses can use this to decide // Tests whether a type hint was set. Subclasses can use this to decide
// whether to call SetContentType. // whether to call SetContentType.
@ -241,31 +233,6 @@ private:
OnCallbacksChanged(); OnCallbacksChanged();
} }
// Handle an async redirect callback. This will only be called if we
// returned success from AsyncOpen while posting a redirect runnable.
void HandleAsyncRedirect(nsIChannel* newChannel);
class RedirectRunnable : public nsRunnable
{
public:
RedirectRunnable(nsBaseChannel* chan, nsIChannel* newChannel)
: mChannel(chan), mNewChannel(newChannel)
{
NS_PRECONDITION(newChannel, "Must have channel to redirect to");
}
NS_IMETHOD Run()
{
mChannel->HandleAsyncRedirect(mNewChannel);
return NS_OK;
}
private:
nsRefPtr<nsBaseChannel> mChannel;
nsCOMPtr<nsIChannel> mNewChannel;
};
friend class RedirectRunnable;
nsRefPtr<nsInputStreamPump> mPump; nsRefPtr<nsInputStreamPump> mPump;
nsCOMPtr<nsIInterfaceRequestor> mCallbacks; nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
nsCOMPtr<nsIProgressEventSink> mProgressSink; nsCOMPtr<nsIProgressEventSink> mProgressSink;

Просмотреть файл

@ -41,8 +41,7 @@
// nsInputStreamChannel // nsInputStreamChannel
nsresult nsresult
nsInputStreamChannel::OpenContentStream(PRBool async, nsIInputStream **result, nsInputStreamChannel::OpenContentStream(PRBool async, nsIInputStream **result)
nsIChannel** channel)
{ {
NS_ENSURE_TRUE(mContentStream, NS_ERROR_NOT_INITIALIZED); NS_ENSURE_TRUE(mContentStream, NS_ERROR_NOT_INITIALIZED);

Просмотреть файл

@ -55,8 +55,7 @@ public:
protected: protected:
virtual ~nsInputStreamChannel() {} virtual ~nsInputStreamChannel() {}
virtual nsresult OpenContentStream(PRBool async, nsIInputStream **result, virtual nsresult OpenContentStream(PRBool async, nsIInputStream **result);
nsIChannel** channel);
private: private:
nsCOMPtr<nsIInputStream> mContentStream; nsCOMPtr<nsIInputStream> mContentStream;

Просмотреть файл

@ -51,8 +51,7 @@
#include "prmem.h" #include "prmem.h"
nsresult nsresult
nsDataChannel::OpenContentStream(PRBool async, nsIInputStream **result, nsDataChannel::OpenContentStream(PRBool async, nsIInputStream **result)
nsIChannel** channel)
{ {
NS_ENSURE_TRUE(URI(), NS_ERROR_NOT_INITIALIZED); NS_ENSURE_TRUE(URI(), NS_ERROR_NOT_INITIALIZED);

Просмотреть файл

@ -52,8 +52,7 @@ public:
} }
protected: protected:
virtual nsresult OpenContentStream(PRBool async, nsIInputStream **result, virtual nsresult OpenContentStream(PRBool async, nsIInputStream **result);
nsIChannel** channel);
}; };
#endif /* nsDataChannel_h___ */ #endif /* nsDataChannel_h___ */

Просмотреть файл

@ -307,8 +307,7 @@ nsFileChannel::MakeFileInputStream(nsIFile *file,
} }
nsresult nsresult
nsFileChannel::OpenContentStream(PRBool async, nsIInputStream **result, nsFileChannel::OpenContentStream(PRBool async, nsIInputStream **result)
nsIChannel** channel)
{ {
// NOTE: the resulting file is a clone, so it is safe to pass it to the // NOTE: the resulting file is a clone, so it is safe to pass it to the
// file input stream which will be read on a background thread. // file input stream which will be read on a background thread.
@ -317,24 +316,6 @@ nsFileChannel::OpenContentStream(PRBool async, nsIInputStream **result,
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return rv; return rv;
nsCOMPtr<nsIFileProtocolHandler> fileHandler;
rv = NS_GetFileProtocolHandler(getter_AddRefs(fileHandler));
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsIURI> newURI;
rv = fileHandler->ReadURLFile(file, getter_AddRefs(newURI));
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIChannel> newChannel;
rv = NS_NewChannel(getter_AddRefs(newChannel), newURI);
if (NS_FAILED(rv))
return rv;
*result = nsnull;
newChannel.forget(channel);
return NS_OK;
}
nsCOMPtr<nsIInputStream> stream; nsCOMPtr<nsIInputStream> stream;
if (mUploadStream) { if (mUploadStream) {

Просмотреть файл

@ -65,8 +65,7 @@ protected:
nsresult MakeFileInputStream(nsIFile *file, nsCOMPtr<nsIInputStream> &stream, nsresult MakeFileInputStream(nsIFile *file, nsCOMPtr<nsIInputStream> &stream,
nsCString &contentType); nsCString &contentType);
virtual nsresult OpenContentStream(PRBool async, nsIInputStream **result, virtual nsresult OpenContentStream(PRBool async, nsIInputStream **result);
nsIChannel** channel);
private: private:
nsCOMPtr<nsIInputStream> mUploadStream; nsCOMPtr<nsIInputStream> mUploadStream;

Просмотреть файл

@ -278,12 +278,30 @@ nsFileProtocolHandler::NewURI(const nsACString &spec,
NS_IMETHODIMP NS_IMETHODIMP
nsFileProtocolHandler::NewChannel(nsIURI *uri, nsIChannel **result) nsFileProtocolHandler::NewChannel(nsIURI *uri, nsIChannel **result)
{ {
nsresult rv;
// This file may be a url file
nsCOMPtr<nsIFileURL> url(do_QueryInterface(uri));
if (url) {
nsCOMPtr<nsIFile> file;
rv = url->GetFile(getter_AddRefs(file));
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIURI> uri;
rv = ReadURLFile(file, getter_AddRefs(uri));
if (NS_SUCCEEDED(rv)) {
rv = NS_NewChannel(result, uri);
if (NS_SUCCEEDED(rv))
return rv;
}
}
}
nsFileChannel *chan = new nsFileChannel(uri); nsFileChannel *chan = new nsFileChannel(uri);
if (!chan) if (!chan)
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(chan); NS_ADDREF(chan);
nsresult rv = chan->Init(); rv = chan->Init();
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
NS_RELEASE(chan); NS_RELEASE(chan);
return rv; return rv;

Просмотреть файл

@ -143,8 +143,7 @@ nsFtpChannel::GetProxyInfo(nsIProxyInfo** aProxyInfo)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
nsresult nsresult
nsFtpChannel::OpenContentStream(PRBool async, nsIInputStream **result, nsFtpChannel::OpenContentStream(PRBool async, nsIInputStream **result)
nsIChannel** channel)
{ {
if (!async) if (!async)
return NS_ERROR_NOT_IMPLEMENTED; return NS_ERROR_NOT_IMPLEMENTED;

Просмотреть файл

@ -117,8 +117,7 @@ public:
protected: protected:
virtual ~nsFtpChannel() {} virtual ~nsFtpChannel() {}
virtual nsresult OpenContentStream(PRBool async, nsIInputStream **result, virtual nsresult OpenContentStream(PRBool async, nsIInputStream **result);
nsIChannel** channel);
virtual PRBool GetStatusArg(nsresult status, nsString &statusArg); virtual PRBool GetStatusArg(nsresult status, nsString &statusArg);
virtual void OnCallbacksChanged(); virtual void OnCallbacksChanged();

Просмотреть файл

@ -469,8 +469,7 @@ nsGopherChannel::GetProxyInfo(nsIProxyInfo** aProxyInfo)
} }
nsresult nsresult
nsGopherChannel::OpenContentStream(PRBool async, nsIInputStream **result, nsGopherChannel::OpenContentStream(PRBool async, nsIInputStream **result)
nsIChannel** channel)
{ {
// Implement nsIChannel::Open in terms of nsIChannel::AsyncOpen // Implement nsIChannel::Open in terms of nsIChannel::AsyncOpen
if (!async) if (!async)

Просмотреть файл

@ -59,8 +59,7 @@ public:
protected: protected:
virtual ~nsGopherChannel() {} virtual ~nsGopherChannel() {}
virtual nsresult OpenContentStream(PRBool async, nsIInputStream **result, virtual nsresult OpenContentStream(PRBool async, nsIInputStream **result);
nsIChannel** channel);
virtual PRBool GetStatusArg(nsresult status, nsString &statusArg); virtual PRBool GetStatusArg(nsresult status, nsString &statusArg);
private: private: