fixes bug 309424 "mozilla 1.5beta1 freezes & goes into 95+% cpu usage browsing blackisha.com" r=biesi sr=bzbarsky

This commit is contained in:
darin%meer.net 2005-10-20 18:19:24 +00:00
Родитель 63b6ca598d
Коммит 5927d4d73a
3 изменённых файлов: 45 добавлений и 7 удалений

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

@ -75,6 +75,7 @@
#include "nsIAuthPrompt.h"
#include "nsIStringStream.h"
#include "nsIStreamConverterService.h"
#include "nsICachingChannel.h"
static const char* kLoadAsData = "loadAsData";
#define LOADSTR NS_LITERAL_STRING("load")
@ -112,6 +113,15 @@ static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
XML_HTTP_REQUEST_SENT | \
XML_HTTP_REQUEST_STOPPED)
// This helper function adds the given load flags to the request's existing
// load flags.
static void AddLoadFlags(nsIRequest *request, nsLoadFlags newFlags)
{
nsLoadFlags flags;
request->GetLoadFlags(&flags);
flags |= newFlags;
request->SetLoadFlags(flags);
}
// Helper proxy class to be used when expecting an
// multipart/x-mixed-replace stream of XML documents.
@ -1585,10 +1595,15 @@ nsXMLHttpRequest::Send(nsIVariant *aBody)
// allow our consumers to specify a "cache key" to access old POST
// responses, so they are not worth caching.
if ((mState & XML_HTTP_REQUEST_MULTIPART) || method.EqualsLiteral("POST")) {
nsLoadFlags flags;
mChannel->GetLoadFlags(&flags);
flags |= nsIRequest::LOAD_BYPASS_CACHE | nsIRequest::INHIBIT_CACHING;
mChannel->SetLoadFlags(flags);
AddLoadFlags(mChannel,
nsIRequest::LOAD_BYPASS_CACHE | nsIRequest::INHIBIT_CACHING);
}
// When we are sync loading, we need to bypass the local cache when it would
// otherwise block us waiting for exclusive access to the cache. If we don't
// do this, then we could dead lock in some cases (see bug 309424).
else if (mState & XML_HTTP_REQUEST_SYNCLOOPING) {
AddLoadFlags(mChannel,
nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE_IF_BUSY);
}
// Since we expect XML data, set the type hint accordingly

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

@ -115,6 +115,19 @@ interface nsICachingChannel : nsISupports
* Caching channel specific load flags:
*/
/**
* This load flag causes the local cache to be skipped when fetching a
* request. Unlike LOAD_BYPASS_CACHE, it does not force an end-to-end load
* (i.e., it does not affect proxy caches).
*/
const unsigned long LOAD_BYPASS_LOCAL_CACHE = 1 << 28;
/**
* This load flag causes the local cache to be skipped if the request
* would otherwise block waiting to access the cache.
*/
const unsigned long LOAD_BYPASS_LOCAL_CACHE_IF_BUSY = 1 << 29;
/**
* This load flag inhibits fetching from the net if the data in the cache
* has been evicted. An error of NS_ERROR_DOCUMENT_NOT_CACHED will be sent

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

@ -73,6 +73,11 @@
#include "nsIVariant.h"
#include "nsChannelProperties.h"
// True if the local cache should be bypassed when processing a request.
#define BYPASS_LOCAL_CACHE(loadFlags) \
(loadFlags & (nsIRequest::LOAD_BYPASS_CACHE | \
nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE))
static NS_DEFINE_CID(kStreamListenerTeeCID, NS_STREAMLISTENERTEE_CID);
static NS_METHOD DiscardSegments(nsIInputStream *input,
@ -1310,11 +1315,11 @@ nsHttpChannel::OpenCacheEntry(PRBool offline, PRBool *delayed)
if (offline || (mLoadFlags & INHIBIT_CACHING)) {
// If we have been asked to bypass the cache and not write to the
// cache, then don't use the cache at all.
if (mLoadFlags & LOAD_BYPASS_CACHE && !offline)
if (BYPASS_LOCAL_CACHE(mLoadFlags) && !offline)
return NS_ERROR_NOT_AVAILABLE;
accessRequested = nsICache::ACCESS_READ;
}
else if (mLoadFlags & LOAD_BYPASS_CACHE)
else if (BYPASS_LOCAL_CACHE(mLoadFlags))
accessRequested = nsICache::ACCESS_WRITE; // replace cache entry
else
accessRequested = nsICache::ACCESS_READ_WRITE; // normal browsing
@ -1325,7 +1330,12 @@ nsHttpChannel::OpenCacheEntry(PRBool offline, PRBool *delayed)
rv = session->OpenCacheEntry(cacheKey, accessRequested, PR_FALSE,
getter_AddRefs(mCacheEntry));
if (rv == NS_ERROR_CACHE_WAIT_FOR_VALIDATION) {
// access to the cache entry has been denied
// access to the cache entry has been denied (because the cache entry
// is probably in use by another channel).
if (mLoadFlags & LOAD_BYPASS_LOCAL_CACHE_IF_BUSY) {
LOG(("bypassing local cache since it is busy\n"));
return NS_ERROR_NOT_AVAILABLE;
}
rv = session->AsyncOpenCacheEntry(cacheKey, accessRequested, this);
if (NS_FAILED(rv)) return rv;
// we'll have to wait for the cache entry