зеркало из https://github.com/mozilla/gecko-dev.git
fixes bug 309424 "mozilla 1.5beta1 freezes & goes into 95+% cpu usage browsing blackisha.com" r=biesi sr=bzbarsky
This commit is contained in:
Родитель
63b6ca598d
Коммит
5927d4d73a
|
@ -75,6 +75,7 @@
|
||||||
#include "nsIAuthPrompt.h"
|
#include "nsIAuthPrompt.h"
|
||||||
#include "nsIStringStream.h"
|
#include "nsIStringStream.h"
|
||||||
#include "nsIStreamConverterService.h"
|
#include "nsIStreamConverterService.h"
|
||||||
|
#include "nsICachingChannel.h"
|
||||||
|
|
||||||
static const char* kLoadAsData = "loadAsData";
|
static const char* kLoadAsData = "loadAsData";
|
||||||
#define LOADSTR NS_LITERAL_STRING("load")
|
#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_SENT | \
|
||||||
XML_HTTP_REQUEST_STOPPED)
|
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
|
// Helper proxy class to be used when expecting an
|
||||||
// multipart/x-mixed-replace stream of XML documents.
|
// 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
|
// allow our consumers to specify a "cache key" to access old POST
|
||||||
// responses, so they are not worth caching.
|
// responses, so they are not worth caching.
|
||||||
if ((mState & XML_HTTP_REQUEST_MULTIPART) || method.EqualsLiteral("POST")) {
|
if ((mState & XML_HTTP_REQUEST_MULTIPART) || method.EqualsLiteral("POST")) {
|
||||||
nsLoadFlags flags;
|
AddLoadFlags(mChannel,
|
||||||
mChannel->GetLoadFlags(&flags);
|
nsIRequest::LOAD_BYPASS_CACHE | nsIRequest::INHIBIT_CACHING);
|
||||||
flags |= nsIRequest::LOAD_BYPASS_CACHE | nsIRequest::INHIBIT_CACHING;
|
}
|
||||||
mChannel->SetLoadFlags(flags);
|
// 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
|
// Since we expect XML data, set the type hint accordingly
|
||||||
|
|
|
@ -115,6 +115,19 @@ interface nsICachingChannel : nsISupports
|
||||||
* Caching channel specific load flags:
|
* 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
|
* 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
|
* has been evicted. An error of NS_ERROR_DOCUMENT_NOT_CACHED will be sent
|
||||||
|
|
|
@ -73,6 +73,11 @@
|
||||||
#include "nsIVariant.h"
|
#include "nsIVariant.h"
|
||||||
#include "nsChannelProperties.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_DEFINE_CID(kStreamListenerTeeCID, NS_STREAMLISTENERTEE_CID);
|
||||||
|
|
||||||
static NS_METHOD DiscardSegments(nsIInputStream *input,
|
static NS_METHOD DiscardSegments(nsIInputStream *input,
|
||||||
|
@ -1310,11 +1315,11 @@ nsHttpChannel::OpenCacheEntry(PRBool offline, PRBool *delayed)
|
||||||
if (offline || (mLoadFlags & INHIBIT_CACHING)) {
|
if (offline || (mLoadFlags & INHIBIT_CACHING)) {
|
||||||
// If we have been asked to bypass the cache and not write to the
|
// If we have been asked to bypass the cache and not write to the
|
||||||
// cache, then don't use the cache at all.
|
// 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;
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
accessRequested = nsICache::ACCESS_READ;
|
accessRequested = nsICache::ACCESS_READ;
|
||||||
}
|
}
|
||||||
else if (mLoadFlags & LOAD_BYPASS_CACHE)
|
else if (BYPASS_LOCAL_CACHE(mLoadFlags))
|
||||||
accessRequested = nsICache::ACCESS_WRITE; // replace cache entry
|
accessRequested = nsICache::ACCESS_WRITE; // replace cache entry
|
||||||
else
|
else
|
||||||
accessRequested = nsICache::ACCESS_READ_WRITE; // normal browsing
|
accessRequested = nsICache::ACCESS_READ_WRITE; // normal browsing
|
||||||
|
@ -1325,7 +1330,12 @@ nsHttpChannel::OpenCacheEntry(PRBool offline, PRBool *delayed)
|
||||||
rv = session->OpenCacheEntry(cacheKey, accessRequested, PR_FALSE,
|
rv = session->OpenCacheEntry(cacheKey, accessRequested, PR_FALSE,
|
||||||
getter_AddRefs(mCacheEntry));
|
getter_AddRefs(mCacheEntry));
|
||||||
if (rv == NS_ERROR_CACHE_WAIT_FOR_VALIDATION) {
|
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);
|
rv = session->AsyncOpenCacheEntry(cacheKey, accessRequested, this);
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
// we'll have to wait for the cache entry
|
// we'll have to wait for the cache entry
|
||||||
|
|
Загрузка…
Ссылка в новой задаче