зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset d0b284052d29 for Talos regression investigation on tp4.
This commit is contained in:
Родитель
a6a3b44e9d
Коммит
45466cd1fa
|
@ -54,7 +54,6 @@ class nsCacheRequest : public PRCList
|
||||||
private:
|
private:
|
||||||
friend class nsCacheService;
|
friend class nsCacheService;
|
||||||
friend class nsCacheEntry;
|
friend class nsCacheEntry;
|
||||||
friend class nsProcessRequestEvent;
|
|
||||||
|
|
||||||
nsCacheRequest( nsCString * key,
|
nsCacheRequest( nsCString * key,
|
||||||
nsICacheListener * listener,
|
nsICacheListener * listener,
|
||||||
|
|
|
@ -614,44 +614,6 @@ nsCacheProfilePrefObserver::MemoryCacheCapacity()
|
||||||
return capacity;
|
return capacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* nsProcessRequestEvent
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
class nsProcessRequestEvent : public nsRunnable {
|
|
||||||
public:
|
|
||||||
nsProcessRequestEvent(nsCacheRequest *aRequest)
|
|
||||||
{
|
|
||||||
mRequest = aRequest;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHOD Run()
|
|
||||||
{
|
|
||||||
nsresult rv;
|
|
||||||
|
|
||||||
NS_ASSERTION(mRequest->mListener,
|
|
||||||
"Sync OpenCacheEntry() posted to background thread!");
|
|
||||||
|
|
||||||
nsCacheServiceAutoLock lock;
|
|
||||||
rv = nsCacheService::gService->ProcessRequest(mRequest,
|
|
||||||
PR_FALSE,
|
|
||||||
nsnull);
|
|
||||||
|
|
||||||
// Don't delete the request if it was queued
|
|
||||||
if (rv != NS_ERROR_CACHE_WAIT_FOR_VALIDATION)
|
|
||||||
delete mRequest;
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual ~nsProcessRequestEvent() {}
|
|
||||||
|
|
||||||
private:
|
|
||||||
nsCacheRequest *mRequest;
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* nsCacheService
|
* nsCacheService
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
@ -719,13 +681,8 @@ nsCacheService::Init()
|
||||||
|
|
||||||
CACHE_LOG_INIT();
|
CACHE_LOG_INIT();
|
||||||
|
|
||||||
nsresult rv = NS_NewThread(getter_AddRefs(mCacheIOThread));
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
NS_WARNING("Can't create cache IO thread");
|
|
||||||
}
|
|
||||||
|
|
||||||
// initialize hashtable for active cache entries
|
// initialize hashtable for active cache entries
|
||||||
rv = mActiveEntries.Init();
|
nsresult rv = mActiveEntries.Init();
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
// create profile/preference observer
|
// create profile/preference observer
|
||||||
|
@ -746,9 +703,6 @@ nsCacheService::Init()
|
||||||
void
|
void
|
||||||
nsCacheService::Shutdown()
|
nsCacheService::Shutdown()
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIThread> cacheIOThread;
|
|
||||||
|
|
||||||
{
|
|
||||||
nsCacheServiceAutoLock lock;
|
nsCacheServiceAutoLock lock;
|
||||||
NS_ASSERTION(mInitialized,
|
NS_ASSERTION(mInitialized,
|
||||||
"can't shutdown nsCacheService unless it has been initialized.");
|
"can't shutdown nsCacheService unless it has been initialized.");
|
||||||
|
@ -780,13 +734,7 @@ nsCacheService::Shutdown()
|
||||||
#if defined(NECKO_DISK_CACHE) && defined(PR_LOGGING)
|
#if defined(NECKO_DISK_CACHE) && defined(PR_LOGGING)
|
||||||
LogCacheStatistics();
|
LogCacheStatistics();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mCacheIOThread.swap(cacheIOThread);
|
|
||||||
}
|
}
|
||||||
} // lock
|
|
||||||
|
|
||||||
if (cacheIOThread)
|
|
||||||
cacheIOThread->Shutdown();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -999,17 +947,6 @@ NS_IMETHODIMP nsCacheService::EvictEntries(nsCacheStoragePolicy storagePolicy)
|
||||||
return EvictEntriesForClient(nsnull, storagePolicy);
|
return EvictEntriesForClient(nsnull, storagePolicy);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsCacheService::GetCacheIOTarget(nsIEventTarget * *aCacheIOTarget)
|
|
||||||
{
|
|
||||||
nsCacheServiceAutoLock lock;
|
|
||||||
|
|
||||||
if (!mCacheIOThread)
|
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
|
||||||
|
|
||||||
NS_ADDREF(*aCacheIOTarget = mCacheIOThread);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal Methods
|
* Internal Methods
|
||||||
*/
|
*/
|
||||||
|
@ -1298,28 +1235,11 @@ nsCacheService::OpenCacheEntry(nsCacheSession * session,
|
||||||
|
|
||||||
CACHE_LOG_DEBUG(("Created request %p\n", request));
|
CACHE_LOG_DEBUG(("Created request %p\n", request));
|
||||||
|
|
||||||
// Process the request on the background thread if we are on the main thread
|
rv = gService->ProcessRequest(request, PR_TRUE, result);
|
||||||
// and the the request is asynchronous
|
|
||||||
if (NS_IsMainThread() && listener && gService->mCacheIOThread) {
|
|
||||||
nsCOMPtr<nsIRunnable> ev =
|
|
||||||
new nsProcessRequestEvent(request);
|
|
||||||
if (ev) {
|
|
||||||
rv = gService->mCacheIOThread->Dispatch(ev, NS_DISPATCH_NORMAL);
|
|
||||||
} else {
|
|
||||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
// delete request if we didn't post the event
|
// delete requests that have completed
|
||||||
if (NS_FAILED(rv))
|
if (!(listener && (rv == NS_ERROR_CACHE_WAIT_FOR_VALIDATION)))
|
||||||
delete request;
|
delete request;
|
||||||
}
|
|
||||||
else {
|
|
||||||
rv = gService->ProcessRequest(request, PR_TRUE, result);
|
|
||||||
|
|
||||||
// delete requests that have completed
|
|
||||||
if (!(listener && (rv == NS_ERROR_CACHE_WAIT_FOR_VALIDATION)))
|
|
||||||
delete request;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -1859,7 +1779,7 @@ nsCacheService::ReleaseObject_Locked(nsISupports * obj,
|
||||||
NS_ASSERTION(gService->mLockedThread == PR_GetCurrentThread(), "oops");
|
NS_ASSERTION(gService->mLockedThread == PR_GetCurrentThread(), "oops");
|
||||||
|
|
||||||
PRBool isCur;
|
PRBool isCur;
|
||||||
if (!target || (NS_SUCCEEDED(target->IsOnCurrentThread(&isCur)) && isCur)) {
|
if (!target || NS_SUCCEEDED(target->IsOnCurrentThread(&isCur)) && isCur) {
|
||||||
gService->mDoomedObjects.AppendElement(obj);
|
gService->mDoomedObjects.AppendElement(obj);
|
||||||
} else {
|
} else {
|
||||||
NS_ProxyRelease(target, obj);
|
NS_ProxyRelease(target, obj);
|
||||||
|
|
|
@ -166,7 +166,6 @@ public:
|
||||||
private:
|
private:
|
||||||
friend class nsCacheServiceAutoLock;
|
friend class nsCacheServiceAutoLock;
|
||||||
friend class nsOfflineCacheDevice;
|
friend class nsOfflineCacheDevice;
|
||||||
friend class nsProcessRequestEvent;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal Methods
|
* Internal Methods
|
||||||
|
@ -246,8 +245,6 @@ private:
|
||||||
PRThread * mLockedThread; // The thread holding mLock
|
PRThread * mLockedThread; // The thread holding mLock
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nsCOMPtr<nsIThread> mCacheIOThread;
|
|
||||||
|
|
||||||
nsTArray<nsISupports*> mDoomedObjects;
|
nsTArray<nsISupports*> mDoomedObjects;
|
||||||
|
|
||||||
PRBool mInitialized;
|
PRBool mInitialized;
|
||||||
|
|
|
@ -54,7 +54,6 @@
|
||||||
#include "nsArrayUtils.h"
|
#include "nsArrayUtils.h"
|
||||||
#include "nsIArray.h"
|
#include "nsIArray.h"
|
||||||
#include "nsIVariant.h"
|
#include "nsIVariant.h"
|
||||||
#include "nsThreadUtils.h"
|
|
||||||
|
|
||||||
#include "mozIStorageService.h"
|
#include "mozIStorageService.h"
|
||||||
#include "mozIStorageStatement.h"
|
#include "mozIStorageStatement.h"
|
||||||
|
@ -172,7 +171,7 @@ DCacheHash(const char * key)
|
||||||
* nsOfflineCacheEvictionFunction
|
* nsOfflineCacheEvictionFunction
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NS_IMPL_THREADSAFE_ISUPPORTS1(nsOfflineCacheEvictionFunction, mozIStorageFunction)
|
NS_IMPL_ISUPPORTS1(nsOfflineCacheEvictionFunction, mozIStorageFunction)
|
||||||
|
|
||||||
// helper function for directly exposing the same data file binding
|
// helper function for directly exposing the same data file binding
|
||||||
// path algorithm used in nsOfflineCacheBinding::Create
|
// path algorithm used in nsOfflineCacheBinding::Create
|
||||||
|
@ -769,37 +768,11 @@ nsApplicationCache::GetUsage(PRUint32 *usage)
|
||||||
return mDevice->GetUsage(mClientID, usage);
|
return mDevice->GetUsage(mClientID, usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* nsCloseDBEvent
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
class nsCloseDBEvent : public nsRunnable {
|
|
||||||
public:
|
|
||||||
nsCloseDBEvent(mozIStorageConnection *aDB)
|
|
||||||
{
|
|
||||||
mDB = aDB;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHOD Run()
|
|
||||||
{
|
|
||||||
mDB->Close();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual ~nsCloseDBEvent() {}
|
|
||||||
|
|
||||||
private:
|
|
||||||
nsCOMPtr<mozIStorageConnection> mDB;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* nsOfflineCacheDevice
|
* nsOfflineCacheDevice
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NS_IMPL_THREADSAFE_ISUPPORTS1(nsOfflineCacheDevice, nsIApplicationCacheService)
|
NS_IMPL_ISUPPORTS1(nsOfflineCacheDevice, nsIApplicationCacheService)
|
||||||
|
|
||||||
nsOfflineCacheDevice::nsOfflineCacheDevice()
|
nsOfflineCacheDevice::nsOfflineCacheDevice()
|
||||||
: mDB(nsnull)
|
: mDB(nsnull)
|
||||||
|
@ -1013,8 +986,6 @@ nsOfflineCacheDevice::Init()
|
||||||
rv = ss->OpenDatabase(indexFile, getter_AddRefs(mDB));
|
rv = ss->OpenDatabase(indexFile, getter_AddRefs(mDB));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
mInitThread = do_GetCurrentThread();
|
|
||||||
|
|
||||||
mDB->ExecuteSimpleSQL(NS_LITERAL_CSTRING("PRAGMA synchronous = OFF;"));
|
mDB->ExecuteSimpleSQL(NS_LITERAL_CSTRING("PRAGMA synchronous = OFF;"));
|
||||||
|
|
||||||
// XXX ... other initialization steps
|
// XXX ... other initialization steps
|
||||||
|
@ -1230,7 +1201,6 @@ nsOfflineCacheDevice::Shutdown()
|
||||||
if (mCaches.IsInitialized())
|
if (mCaches.IsInitialized())
|
||||||
mCaches.EnumerateRead(ShutdownApplicationCache, this);
|
mCaches.EnumerateRead(ShutdownApplicationCache, this);
|
||||||
|
|
||||||
{
|
|
||||||
EvictionObserver evictionObserver(mDB, mEvictionFunction);
|
EvictionObserver evictionObserver(mDB, mEvictionFunction);
|
||||||
|
|
||||||
// Delete all rows whose clientID is not an active clientID.
|
// Delete all rows whose clientID is not an active clientID.
|
||||||
|
@ -1257,51 +1227,9 @@ nsOfflineCacheDevice::Shutdown()
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
NS_WARNING("Failed to clean up namespaces.");
|
NS_WARNING("Failed to clean up namespaces.");
|
||||||
|
|
||||||
|
mDB = 0;
|
||||||
mEvictionFunction = 0;
|
mEvictionFunction = 0;
|
||||||
|
|
||||||
mStatement_CacheSize = nsnull;
|
|
||||||
mStatement_ApplicationCacheSize = nsnull;
|
|
||||||
mStatement_EntryCount = nsnull;
|
|
||||||
mStatement_UpdateEntry = nsnull;
|
|
||||||
mStatement_UpdateEntrySize = nsnull;
|
|
||||||
mStatement_UpdateEntryFlags = nsnull;
|
|
||||||
mStatement_DeleteEntry = nsnull;
|
|
||||||
mStatement_FindEntry = nsnull;
|
|
||||||
mStatement_BindEntry = nsnull;
|
|
||||||
mStatement_ClearDomain = nsnull;
|
|
||||||
mStatement_MarkEntry = nsnull;
|
|
||||||
mStatement_UnmarkEntry = nsnull;
|
|
||||||
mStatement_GetTypes = nsnull;
|
|
||||||
mStatement_FindNamespaceEntry = nsnull;
|
|
||||||
mStatement_InsertNamespaceEntry = nsnull;
|
|
||||||
mStatement_CleanupUnmarked = nsnull;
|
|
||||||
mStatement_GatherEntries = nsnull;
|
|
||||||
mStatement_ActivateClient = nsnull;
|
|
||||||
mStatement_DeactivateGroup = nsnull;
|
|
||||||
mStatement_FindClient = nsnull;
|
|
||||||
mStatement_FindClientByNamespace = nsnull;
|
|
||||||
mStatement_EnumerateGroups = nsnull;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close Database on the correct thread
|
|
||||||
PRBool isOnCurrentThread = PR_TRUE;
|
|
||||||
if (mInitThread)
|
|
||||||
mInitThread->IsOnCurrentThread(&isOnCurrentThread);
|
|
||||||
|
|
||||||
if (!isOnCurrentThread) {
|
|
||||||
nsCOMPtr<nsIRunnable> ev = new nsCloseDBEvent(mDB);
|
|
||||||
|
|
||||||
if (ev) {
|
|
||||||
mInitThread->Dispatch(ev, NS_DISPATCH_NORMAL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
mDB->Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
mDB = nsnull;
|
|
||||||
mInitThread = nsnull;
|
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -275,8 +275,6 @@ private:
|
||||||
nsInterfaceHashtable<nsCStringHashKey, nsIWeakReference> mCaches;
|
nsInterfaceHashtable<nsCStringHashKey, nsIWeakReference> mCaches;
|
||||||
nsClassHashtable<nsCStringHashKey, nsCString> mActiveCachesByGroup;
|
nsClassHashtable<nsCStringHashKey, nsCString> mActiveCachesByGroup;
|
||||||
nsCStringHashSet mActiveCaches;
|
nsCStringHashSet mActiveCaches;
|
||||||
|
|
||||||
nsCOMPtr<nsIThread> mInitThread;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // nsOfflineCacheDevice_h__
|
#endif // nsOfflineCacheDevice_h__
|
||||||
|
|
|
@ -47,9 +47,8 @@ interface nsISimpleEnumerator;
|
||||||
interface nsICacheListener;
|
interface nsICacheListener;
|
||||||
interface nsICacheSession;
|
interface nsICacheSession;
|
||||||
interface nsICacheVisitor;
|
interface nsICacheVisitor;
|
||||||
interface nsIEventTarget;
|
|
||||||
|
|
||||||
[scriptable, uuid(14dbe1e9-f3bc-45af-92f4-2c574fcd4e39)]
|
[scriptable, uuid(de114eb4-29fc-4959-b2f7-2d03eb9bc771)]
|
||||||
interface nsICacheService : nsISupports
|
interface nsICacheService : nsISupports
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -88,11 +87,6 @@ interface nsICacheService : nsISupports
|
||||||
* everything.
|
* everything.
|
||||||
*/
|
*/
|
||||||
void evictEntries(in nsCacheStoragePolicy storagePolicy);
|
void evictEntries(in nsCacheStoragePolicy storagePolicy);
|
||||||
|
|
||||||
/**
|
|
||||||
* Event target which is used for I/O operations
|
|
||||||
*/
|
|
||||||
readonly attribute nsIEventTarget cacheIOTarget;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
%{C++
|
%{C++
|
||||||
|
|
|
@ -115,8 +115,6 @@ nsHttpChannel::nsHttpChannel()
|
||||||
, mCacheAccess(0)
|
, mCacheAccess(0)
|
||||||
, mPostID(0)
|
, mPostID(0)
|
||||||
, mRequestTime(0)
|
, mRequestTime(0)
|
||||||
, mOnCacheEntryAvailableCallback(nsnull)
|
|
||||||
, mAsyncCacheOpen(PR_FALSE)
|
|
||||||
, mPendingAsyncCallOnResume(nsnull)
|
, mPendingAsyncCallOnResume(nsnull)
|
||||||
, mSuspendCount(0)
|
, mSuspendCount(0)
|
||||||
, mApplyConversion(PR_TRUE)
|
, mApplyConversion(PR_TRUE)
|
||||||
|
@ -200,6 +198,8 @@ nsHttpChannel::Connect(PRBool firstTime)
|
||||||
|
|
||||||
// true when called from AsyncOpen
|
// true when called from AsyncOpen
|
||||||
if (firstTime) {
|
if (firstTime) {
|
||||||
|
PRBool delayed = PR_FALSE;
|
||||||
|
|
||||||
// are we offline?
|
// are we offline?
|
||||||
PRBool offline = gIOService->IsOffline();
|
PRBool offline = gIOService->IsOffline();
|
||||||
if (offline)
|
if (offline)
|
||||||
|
@ -214,7 +214,7 @@ nsHttpChannel::Connect(PRBool firstTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
// open a cache entry for this channel...
|
// open a cache entry for this channel...
|
||||||
rv = OpenCacheEntry();
|
rv = OpenCacheEntry(offline, &delayed);
|
||||||
|
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
LOG(("OpenCacheEntry failed [rv=%x]\n", rv));
|
LOG(("OpenCacheEntry failed [rv=%x]\n", rv));
|
||||||
|
@ -238,7 +238,7 @@ nsHttpChannel::Connect(PRBool firstTime)
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NS_SUCCEEDED(rv) && mAsyncCacheOpen)
|
if (NS_SUCCEEDED(rv) && delayed)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,14 +271,6 @@ nsHttpChannel::Connect(PRBool firstTime)
|
||||||
return NS_ERROR_DOCUMENT_NOT_CACHED;
|
return NS_ERROR_DOCUMENT_NOT_CACHED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (mLoadFlags & LOAD_ONLY_FROM_CACHE) {
|
|
||||||
// If we have a fallback URI (and we're not already
|
|
||||||
// falling back), process the fallback asynchronously.
|
|
||||||
if (!mFallbackChannel && !mFallbackKey.IsEmpty()) {
|
|
||||||
return AsyncCall(&nsHttpChannel::HandleAsyncFallback);
|
|
||||||
}
|
|
||||||
return NS_ERROR_DOCUMENT_NOT_CACHED;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check to see if authorization headers should be included
|
// check to see if authorization headers should be included
|
||||||
mAuthProvider->AddAuthorizationHeaders();
|
mAuthProvider->AddAuthorizationHeaders();
|
||||||
|
@ -1692,11 +1684,11 @@ IsSubRangeRequest(nsHttpRequestHead &aRequestHead)
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsHttpChannel::OpenCacheEntry()
|
nsHttpChannel::OpenCacheEntry(PRBool offline, PRBool *delayed)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
mAsyncCacheOpen = PR_FALSE;
|
*delayed = PR_FALSE;
|
||||||
mLoadedFromApplicationCache = PR_FALSE;
|
mLoadedFromApplicationCache = PR_FALSE;
|
||||||
|
|
||||||
LOG(("nsHttpChannel::OpenCacheEntry [this=%p]", this));
|
LOG(("nsHttpChannel::OpenCacheEntry [this=%p]", this));
|
||||||
|
@ -1732,10 +1724,23 @@ nsHttpChannel::OpenCacheEntry()
|
||||||
|
|
||||||
GenerateCacheKey(mPostID, cacheKey);
|
GenerateCacheKey(mPostID, cacheKey);
|
||||||
|
|
||||||
|
// Get a cache session with appropriate storage policy
|
||||||
|
nsCacheStoragePolicy storagePolicy = DetermineStoragePolicy();
|
||||||
|
|
||||||
// Set the desired cache access mode accordingly...
|
// Set the desired cache access mode accordingly...
|
||||||
nsCacheAccessMode accessRequested;
|
nsCacheAccessMode accessRequested;
|
||||||
rv = DetermineCacheAccess(&accessRequested);
|
if (offline || (mLoadFlags & INHIBIT_CACHING)) {
|
||||||
if NS_FAILED(rv) return rv;
|
// If we have been asked to bypass the cache and not write to the
|
||||||
|
// cache, then don't use the cache at all. Unless we're actually
|
||||||
|
// offline, which takes precedence over BYPASS_LOCAL_CACHE.
|
||||||
|
if (BYPASS_LOCAL_CACHE(mLoadFlags) && !offline)
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
accessRequested = nsICache::ACCESS_READ;
|
||||||
|
}
|
||||||
|
else if (BYPASS_LOCAL_CACHE(mLoadFlags))
|
||||||
|
accessRequested = nsICache::ACCESS_WRITE; // replace cache entry
|
||||||
|
else
|
||||||
|
accessRequested = nsICache::ACCESS_READ_WRITE; // normal browsing
|
||||||
|
|
||||||
if (!mApplicationCache && mInheritApplicationCache) {
|
if (!mApplicationCache && mInheritApplicationCache) {
|
||||||
// Pick up an application cache from the notification
|
// Pick up an application cache from the notification
|
||||||
|
@ -1764,6 +1769,10 @@ nsHttpChannel::OpenCacheEntry()
|
||||||
|
|
||||||
nsCOMPtr<nsICacheSession> session;
|
nsCOMPtr<nsICacheSession> session;
|
||||||
|
|
||||||
|
// Will be set to true if we've found the right session, but need
|
||||||
|
// to open the cache entry asynchronously.
|
||||||
|
PRBool waitingForValidation = PR_FALSE;
|
||||||
|
|
||||||
// If we have an application cache, we check it first.
|
// If we have an application cache, we check it first.
|
||||||
if (mApplicationCache) {
|
if (mApplicationCache) {
|
||||||
nsCAutoString appCacheClientID;
|
nsCAutoString appCacheClientID;
|
||||||
|
@ -1779,217 +1788,107 @@ nsHttpChannel::OpenCacheEntry()
|
||||||
getter_AddRefs(session));
|
getter_AddRefs(session));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
if (mLoadFlags & LOAD_BYPASS_LOCAL_CACHE_IF_BUSY) {
|
// we'll try to synchronously open the cache entry... however,
|
||||||
// must use synchronous open for LOAD_BYPASS_LOCAL_CACHE_IF_BUSY
|
// it may be in use and not yet validated, in which case we'll
|
||||||
rv = session->OpenCacheEntry(cacheKey,
|
// try asynchronously opening the cache entry.
|
||||||
nsICache::ACCESS_READ, PR_FALSE,
|
//
|
||||||
getter_AddRefs(mCacheEntry));
|
// We open with ACCESS_READ only, because we don't want to
|
||||||
if (NS_SUCCEEDED(rv)) {
|
// overwrite the offline cache entry non-atomically.
|
||||||
mCacheEntry->GetAccessGranted(&mCacheAccess);
|
// ACCESS_READ will prevent us from writing to the offline
|
||||||
LOG(("nsHttpChannel::OpenCacheEntry [this=%p grantedAccess=%d]",
|
// cache as a normal cache entry.
|
||||||
this, mCacheAccess));
|
rv = session->OpenCacheEntry(cacheKey,
|
||||||
mLoadedFromApplicationCache = PR_TRUE;
|
nsICache::ACCESS_READ, PR_FALSE,
|
||||||
return NS_OK;
|
getter_AddRefs(mCacheEntry));
|
||||||
} else if (rv == NS_ERROR_CACHE_WAIT_FOR_VALIDATION) {
|
if (rv == NS_ERROR_CACHE_WAIT_FOR_VALIDATION) {
|
||||||
LOG(("bypassing local cache since it is busy\n"));
|
accessRequested = nsICache::ACCESS_READ;
|
||||||
// Don't try to load normal cache entry
|
waitingForValidation = PR_TRUE;
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
rv = NS_OK;
|
||||||
}
|
|
||||||
} else {
|
|
||||||
mOnCacheEntryAvailableCallback =
|
|
||||||
&nsHttpChannel::OnOfflineCacheEntryAvailable;
|
|
||||||
// We open with ACCESS_READ only, because we don't want to
|
|
||||||
// overwrite the offline cache entry non-atomically.
|
|
||||||
// ACCESS_READ will prevent us from writing to the offline
|
|
||||||
// cache as a normal cache entry.
|
|
||||||
rv = session->AsyncOpenCacheEntry(cacheKey,
|
|
||||||
nsICache::ACCESS_READ,
|
|
||||||
this);
|
|
||||||
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
mAsyncCacheOpen = PR_TRUE;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// sync or async opening failed
|
if (NS_FAILED(rv) && !mCacheForOfflineUse && !mFallbackChannel) {
|
||||||
return OnOfflineCacheEntryAvailable(nsnull, nsICache::ACCESS_NONE,
|
// Check for namespace match.
|
||||||
rv, PR_TRUE);
|
nsCOMPtr<nsIApplicationCacheNamespace> namespaceEntry;
|
||||||
}
|
rv = mApplicationCache->GetMatchingNamespace
|
||||||
|
(cacheKey, getter_AddRefs(namespaceEntry));
|
||||||
return OpenNormalCacheEntry(PR_TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsHttpChannel::OnOfflineCacheEntryAvailable(nsICacheEntryDescriptor *aEntry,
|
|
||||||
nsCacheAccessMode aAccess,
|
|
||||||
nsresult aEntryStatus,
|
|
||||||
PRBool aIsSync)
|
|
||||||
{
|
|
||||||
nsresult rv;
|
|
||||||
|
|
||||||
if (NS_SUCCEEDED(aEntryStatus)) {
|
|
||||||
// We successfully opened an offline cache session and the entry,
|
|
||||||
// so indicate we will load from the offline cache.
|
|
||||||
mLoadedFromApplicationCache = PR_TRUE;
|
|
||||||
mCacheEntry = aEntry;
|
|
||||||
mCacheAccess = aAccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mCanceled && NS_FAILED(mStatus)) {
|
|
||||||
LOG(("channel was canceled [this=%p status=%x]\n", this, mStatus));
|
|
||||||
return mStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NS_SUCCEEDED(aEntryStatus))
|
|
||||||
// Called from OnCacheEntryAvailable, advance to the next state
|
|
||||||
return Connect(PR_FALSE);
|
|
||||||
|
|
||||||
if (!mCacheForOfflineUse && !mFallbackChannel) {
|
|
||||||
nsCAutoString cacheKey;
|
|
||||||
GenerateCacheKey(mPostID, cacheKey);
|
|
||||||
|
|
||||||
// Check for namespace match.
|
|
||||||
nsCOMPtr<nsIApplicationCacheNamespace> namespaceEntry;
|
|
||||||
rv = mApplicationCache->GetMatchingNamespace
|
|
||||||
(cacheKey, getter_AddRefs(namespaceEntry));
|
|
||||||
if (NS_FAILED(rv) && !aIsSync)
|
|
||||||
return Connect(PR_FALSE);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
PRUint32 namespaceType = 0;
|
|
||||||
if (!namespaceEntry ||
|
|
||||||
NS_FAILED(namespaceEntry->GetItemType(&namespaceType)) ||
|
|
||||||
(namespaceType &
|
|
||||||
(nsIApplicationCacheNamespace::NAMESPACE_FALLBACK |
|
|
||||||
nsIApplicationCacheNamespace::NAMESPACE_OPPORTUNISTIC |
|
|
||||||
nsIApplicationCacheNamespace::NAMESPACE_BYPASS)) == 0) {
|
|
||||||
// When loading from an application cache, only items
|
|
||||||
// on the whitelist or matching a
|
|
||||||
// fallback/opportunistic namespace should hit the
|
|
||||||
// network...
|
|
||||||
mLoadFlags |= LOAD_ONLY_FROM_CACHE;
|
|
||||||
|
|
||||||
// ... and if there were an application cache entry,
|
|
||||||
// we would have found it earlier.
|
|
||||||
return aIsSync ? NS_ERROR_CACHE_KEY_NOT_FOUND : Connect(PR_FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (namespaceType &
|
|
||||||
nsIApplicationCacheNamespace::NAMESPACE_FALLBACK) {
|
|
||||||
rv = namespaceEntry->GetData(mFallbackKey);
|
|
||||||
if (NS_FAILED(rv) && !aIsSync)
|
|
||||||
return Connect(PR_FALSE);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
PRUint32 namespaceType = 0;
|
||||||
|
if (!namespaceEntry ||
|
||||||
|
NS_FAILED(namespaceEntry->GetItemType(&namespaceType)) ||
|
||||||
|
(namespaceType &
|
||||||
|
(nsIApplicationCacheNamespace::NAMESPACE_FALLBACK |
|
||||||
|
nsIApplicationCacheNamespace::NAMESPACE_OPPORTUNISTIC |
|
||||||
|
nsIApplicationCacheNamespace::NAMESPACE_BYPASS)) == 0) {
|
||||||
|
// When loading from an application cache, only items
|
||||||
|
// on the whitelist or matching a
|
||||||
|
// fallback/opportunistic namespace should hit the
|
||||||
|
// network...
|
||||||
|
mLoadFlags |= LOAD_ONLY_FROM_CACHE;
|
||||||
|
|
||||||
|
// ... and if there were an application cache entry,
|
||||||
|
// we would have found it earlier.
|
||||||
|
return NS_ERROR_CACHE_KEY_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (namespaceType &
|
||||||
|
nsIApplicationCacheNamespace::NAMESPACE_FALLBACK) {
|
||||||
|
rv = namespaceEntry->GetData(mFallbackKey);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((namespaceType &
|
||||||
|
nsIApplicationCacheNamespace::NAMESPACE_OPPORTUNISTIC) &&
|
||||||
|
mLoadFlags & LOAD_DOCUMENT_URI) {
|
||||||
|
// Document loads for items in an opportunistic namespace
|
||||||
|
// should be placed in the offline cache.
|
||||||
|
nsCString clientID;
|
||||||
|
mApplicationCache->GetClientID(clientID);
|
||||||
|
|
||||||
|
mCacheForOfflineUse = !clientID.IsEmpty();
|
||||||
|
SetOfflineCacheClientID(clientID);
|
||||||
|
mCachingOpportunistically = PR_TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else if (NS_SUCCEEDED(rv)) {
|
||||||
if ((namespaceType &
|
// We successfully opened an offline cache session and the entry,
|
||||||
nsIApplicationCacheNamespace::NAMESPACE_OPPORTUNISTIC) &&
|
// now indiciate we load from the offline cache.
|
||||||
mLoadFlags & LOAD_DOCUMENT_URI) {
|
mLoadedFromApplicationCache = PR_TRUE;
|
||||||
// Document loads for items in an opportunistic namespace
|
|
||||||
// should be placed in the offline cache.
|
|
||||||
nsCString clientID;
|
|
||||||
mApplicationCache->GetClientID(clientID);
|
|
||||||
|
|
||||||
mCacheForOfflineUse = !clientID.IsEmpty();
|
|
||||||
SetOfflineCacheClientID(clientID);
|
|
||||||
mCachingOpportunistically = PR_TRUE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return OpenNormalCacheEntry(aIsSync);
|
if (!mCacheEntry && !waitingForValidation) {
|
||||||
}
|
rv = gHttpHandler->GetCacheSession(storagePolicy,
|
||||||
|
getter_AddRefs(session));
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsHttpChannel::OpenNormalCacheEntry(PRBool aIsSync)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(!mCacheEntry, "We have already mCacheEntry");
|
|
||||||
|
|
||||||
nsresult rv;
|
|
||||||
|
|
||||||
nsCAutoString cacheKey;
|
|
||||||
GenerateCacheKey(mPostID, cacheKey);
|
|
||||||
|
|
||||||
nsCacheStoragePolicy storagePolicy = DetermineStoragePolicy();
|
|
||||||
|
|
||||||
nsCOMPtr<nsICacheSession> session;
|
|
||||||
rv = gHttpHandler->GetCacheSession(storagePolicy,
|
|
||||||
getter_AddRefs(session));
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
nsCacheAccessMode accessRequested;
|
|
||||||
rv = DetermineCacheAccess(&accessRequested);
|
|
||||||
if NS_FAILED(rv) return rv;
|
|
||||||
|
|
||||||
if (mLoadFlags & LOAD_BYPASS_LOCAL_CACHE_IF_BUSY) {
|
|
||||||
if (!aIsSync) {
|
|
||||||
// Unexpected state: we were called from OnCacheEntryAvailable(),
|
|
||||||
// so LOAD_BYPASS_LOCAL_CACHE_IF_BUSY shouldn't be set. Unless
|
|
||||||
// somebody altered mLoadFlags between OpenCacheEntry() and
|
|
||||||
// OnCacheEntryAvailable()...
|
|
||||||
NS_WARNING(
|
|
||||||
"OpenNormalCacheEntry() called from OnCacheEntryAvailable() "
|
|
||||||
"when LOAD_BYPASS_LOCAL_CACHE_IF_BUSY was specified");
|
|
||||||
}
|
|
||||||
|
|
||||||
// must use synchronous open for LOAD_BYPASS_LOCAL_CACHE_IF_BUSY
|
|
||||||
rv = session->OpenCacheEntry(cacheKey, accessRequested, PR_FALSE,
|
rv = session->OpenCacheEntry(cacheKey, accessRequested, PR_FALSE,
|
||||||
getter_AddRefs(mCacheEntry));
|
getter_AddRefs(mCacheEntry));
|
||||||
if (NS_SUCCEEDED(rv)) {
|
if (rv == NS_ERROR_CACHE_WAIT_FOR_VALIDATION) {
|
||||||
mCacheEntry->GetAccessGranted(&mCacheAccess);
|
waitingForValidation = PR_TRUE;
|
||||||
LOG(("nsHttpChannel::OpenCacheEntry [this=%p grantedAccess=%d]",
|
rv = NS_OK;
|
||||||
this, mCacheAccess));
|
|
||||||
}
|
}
|
||||||
else if (rv == NS_ERROR_CACHE_WAIT_FOR_VALIDATION) {
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (waitingForValidation) {
|
||||||
|
// 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"));
|
LOG(("bypassing local cache since it is busy\n"));
|
||||||
rv = NS_ERROR_NOT_AVAILABLE;
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else {
|
|
||||||
mOnCacheEntryAvailableCallback =
|
|
||||||
&nsHttpChannel::OnNormalCacheEntryAvailable;
|
|
||||||
rv = session->AsyncOpenCacheEntry(cacheKey, accessRequested, this);
|
rv = session->AsyncOpenCacheEntry(cacheKey, accessRequested, this);
|
||||||
if (NS_SUCCEEDED(rv)) {
|
if (NS_FAILED(rv)) return rv;
|
||||||
mAsyncCacheOpen = PR_TRUE;
|
// we'll have to wait for the cache entry
|
||||||
return NS_OK;
|
*delayed = PR_TRUE;
|
||||||
}
|
}
|
||||||
|
else if (NS_SUCCEEDED(rv)) {
|
||||||
|
mCacheEntry->GetAccessGranted(&mCacheAccess);
|
||||||
|
LOG(("nsHttpChannel::OpenCacheEntry [this=%p grantedAccess=%d]", this, mCacheAccess));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!aIsSync)
|
|
||||||
// Called from OnCacheEntryAvailable, advance to the next state
|
|
||||||
rv = Connect(PR_FALSE);
|
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsHttpChannel::OnNormalCacheEntryAvailable(nsICacheEntryDescriptor *aEntry,
|
|
||||||
nsCacheAccessMode aAccess,
|
|
||||||
nsresult aEntryStatus,
|
|
||||||
PRBool aIsSync)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(!aIsSync, "aIsSync should be false");
|
|
||||||
|
|
||||||
if (NS_SUCCEEDED(aEntryStatus)) {
|
|
||||||
mCacheEntry = aEntry;
|
|
||||||
mCacheAccess = aAccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mCanceled && NS_FAILED(mStatus)) {
|
|
||||||
LOG(("channel was canceled [this=%p status=%x]\n", this, mStatus));
|
|
||||||
return mStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((mLoadFlags & LOAD_ONLY_FROM_CACHE) && NS_FAILED(aEntryStatus))
|
|
||||||
// if this channel is only allowed to pull from the cache, then
|
|
||||||
// we must fail if we were unable to open a cache entry.
|
|
||||||
return NS_ERROR_DOCUMENT_NOT_CACHED;
|
|
||||||
|
|
||||||
// advance to the next state...
|
|
||||||
return Connect(PR_FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsHttpChannel::OpenOfflineCacheEntryForWriting()
|
nsHttpChannel::OpenOfflineCacheEntryForWriting()
|
||||||
|
@ -2816,26 +2715,20 @@ nsHttpChannel::InstallCacheListener(PRUint32 offset)
|
||||||
do_CreateInstance(kStreamListenerTeeCID, &rv);
|
do_CreateInstance(kStreamListenerTeeCID, &rv);
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
nsCOMPtr<nsICacheService> serv =
|
|
||||||
do_GetService(NS_CACHESERVICE_CONTRACTID, &rv);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIEventTarget> cacheIOTarget;
|
|
||||||
serv->GetCacheIOTarget(getter_AddRefs(cacheIOTarget));
|
|
||||||
|
|
||||||
nsCacheStoragePolicy policy;
|
nsCacheStoragePolicy policy;
|
||||||
rv = mCacheEntry->GetStoragePolicy(&policy);
|
rv = mCacheEntry->GetStoragePolicy(&policy);
|
||||||
|
|
||||||
if (NS_FAILED(rv) || policy == nsICache::STORE_ON_DISK_AS_FILE ||
|
if (!gHttpHandler->mCacheWriteThread ||
|
||||||
!cacheIOTarget) {
|
NS_FAILED(rv) ||
|
||||||
LOG(("nsHttpChannel::InstallCacheListener sync tee %p rv=%x policy=%d "
|
policy == nsICache::STORE_ON_DISK_AS_FILE) {
|
||||||
"cacheIOTarget=%p", tee.get(), rv, policy, cacheIOTarget.get()));
|
LOG(("nsHttpChannel::InstallCacheListener sync tee %p\n", tee.get()));
|
||||||
rv = tee->Init(mListener, out, nsnull);
|
rv = tee->Init(mListener, out, nsnull);
|
||||||
} else {
|
} else {
|
||||||
LOG(("nsHttpChannel::InstallCacheListener async tee %p", tee.get()));
|
LOG(("nsHttpChannel::InstallCacheListener async tee %p\n",
|
||||||
rv = tee->InitAsync(mListener, cacheIOTarget, out, nsnull);
|
tee.get()));
|
||||||
|
rv = tee->InitAsync(mListener, gHttpHandler->mCacheWriteThread, out, nsnull);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
mListener = tee;
|
mListener = tee;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -4188,8 +4081,6 @@ nsHttpChannel::OnCacheEntryAvailable(nsICacheEntryDescriptor *entry,
|
||||||
nsCacheAccessMode access,
|
nsCacheAccessMode access,
|
||||||
nsresult status)
|
nsresult status)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
|
||||||
|
|
||||||
LOG(("nsHttpChannel::OnCacheEntryAvailable [this=%p entry=%p "
|
LOG(("nsHttpChannel::OnCacheEntryAvailable [this=%p entry=%p "
|
||||||
"access=%x status=%x]\n", this, entry, access, status));
|
"access=%x status=%x]\n", this, entry, access, status));
|
||||||
|
|
||||||
|
@ -4198,24 +4089,28 @@ nsHttpChannel::OnCacheEntryAvailable(nsICacheEntryDescriptor *entry,
|
||||||
if (!mIsPending)
|
if (!mIsPending)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
nsOnCacheEntryAvailableCallback callback = mOnCacheEntryAvailableCallback;
|
// otherwise, we have to handle this event.
|
||||||
mOnCacheEntryAvailableCallback = nsnull;
|
if (NS_SUCCEEDED(status)) {
|
||||||
|
mCacheEntry = entry;
|
||||||
|
mCacheAccess = access;
|
||||||
|
}
|
||||||
|
|
||||||
NS_ASSERTION(callback,
|
nsresult rv;
|
||||||
"nsHttpChannel::OnCacheEntryAvailable called without callback");
|
|
||||||
rv = ((*this).*callback)(entry, access, status, PR_FALSE);
|
|
||||||
|
|
||||||
|
if (mCanceled && NS_FAILED(mStatus)) {
|
||||||
|
LOG(("channel was canceled [this=%p status=%x]\n", this, mStatus));
|
||||||
|
rv = mStatus;
|
||||||
|
}
|
||||||
|
else if ((mLoadFlags & LOAD_ONLY_FROM_CACHE) && NS_FAILED(status))
|
||||||
|
// if this channel is only allowed to pull from the cache, then
|
||||||
|
// we must fail if we were unable to open a cache entry.
|
||||||
|
rv = NS_ERROR_DOCUMENT_NOT_CACHED;
|
||||||
|
else
|
||||||
|
// advance to the next state...
|
||||||
|
rv = Connect(PR_FALSE);
|
||||||
|
|
||||||
|
// a failure from Connect means that we have to abort the channel.
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
LOG(("AsyncOpenCacheEntry failed [rv=%x]\n", rv));
|
|
||||||
if (mLoadFlags & LOAD_ONLY_FROM_CACHE) {
|
|
||||||
// If we have a fallback URI (and we're not already
|
|
||||||
// falling back), process the fallback asynchronously.
|
|
||||||
if (!mFallbackChannel && !mFallbackKey.IsEmpty()) {
|
|
||||||
rv = AsyncCall(&nsHttpChannel::HandleAsyncFallback);
|
|
||||||
if (NS_SUCCEEDED(rv))
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CloseCacheEntry(PR_TRUE);
|
CloseCacheEntry(PR_TRUE);
|
||||||
AsyncAbort(rv);
|
AsyncAbort(rv);
|
||||||
}
|
}
|
||||||
|
@ -4682,27 +4577,6 @@ nsHttpChannel::DetermineStoragePolicy()
|
||||||
return policy;
|
return policy;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsHttpChannel::DetermineCacheAccess(nsCacheAccessMode *_retval)
|
|
||||||
{
|
|
||||||
PRBool offline = gIOService->IsOffline();
|
|
||||||
|
|
||||||
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. Unless we're actually
|
|
||||||
// offline, which takes precedence over BYPASS_LOCAL_CACHE.
|
|
||||||
if (BYPASS_LOCAL_CACHE(mLoadFlags) && !offline)
|
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
|
||||||
*_retval = nsICache::ACCESS_READ;
|
|
||||||
}
|
|
||||||
else if (BYPASS_LOCAL_CACHE(mLoadFlags))
|
|
||||||
*_retval = nsICache::ACCESS_WRITE; // replace cache entry
|
|
||||||
else
|
|
||||||
*_retval = nsICache::ACCESS_READ_WRITE; // normal browsing
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
nsHttpChannel::AsyncOnExamineCachedResponse()
|
nsHttpChannel::AsyncOnExamineCachedResponse()
|
||||||
{
|
{
|
||||||
|
|
|
@ -216,16 +216,7 @@ private:
|
||||||
nsresult ResolveProxy();
|
nsresult ResolveProxy();
|
||||||
|
|
||||||
// cache specific methods
|
// cache specific methods
|
||||||
nsresult OpenCacheEntry();
|
nsresult OpenCacheEntry(PRBool offline, PRBool *delayed);
|
||||||
nsresult OnOfflineCacheEntryAvailable(nsICacheEntryDescriptor *aEntry,
|
|
||||||
nsCacheAccessMode aAccess,
|
|
||||||
nsresult aResult,
|
|
||||||
PRBool aSync);
|
|
||||||
nsresult OpenNormalCacheEntry(PRBool aSync);
|
|
||||||
nsresult OnNormalCacheEntryAvailable(nsICacheEntryDescriptor *aEntry,
|
|
||||||
nsCacheAccessMode aAccess,
|
|
||||||
nsresult aResult,
|
|
||||||
PRBool aSync);
|
|
||||||
nsresult OpenOfflineCacheEntryForWriting();
|
nsresult OpenOfflineCacheEntryForWriting();
|
||||||
nsresult GenerateCacheKey(PRUint32 postID, nsACString &key);
|
nsresult GenerateCacheKey(PRUint32 postID, nsACString &key);
|
||||||
nsresult UpdateExpirationTime();
|
nsresult UpdateExpirationTime();
|
||||||
|
@ -243,7 +234,6 @@ private:
|
||||||
nsresult InstallOfflineCacheListener();
|
nsresult InstallOfflineCacheListener();
|
||||||
void MaybeInvalidateCacheEntryForSubsequentGet();
|
void MaybeInvalidateCacheEntryForSubsequentGet();
|
||||||
nsCacheStoragePolicy DetermineStoragePolicy();
|
nsCacheStoragePolicy DetermineStoragePolicy();
|
||||||
nsresult DetermineCacheAccess(nsCacheAccessMode *_retval);
|
|
||||||
void AsyncOnExamineCachedResponse();
|
void AsyncOnExamineCachedResponse();
|
||||||
|
|
||||||
// Handle the bogus Content-Encoding Apache sometimes sends
|
// Handle the bogus Content-Encoding Apache sometimes sends
|
||||||
|
@ -274,11 +264,6 @@ private:
|
||||||
PRUint32 mPostID;
|
PRUint32 mPostID;
|
||||||
PRUint32 mRequestTime;
|
PRUint32 mRequestTime;
|
||||||
|
|
||||||
typedef nsresult (nsHttpChannel:: *nsOnCacheEntryAvailableCallback)(
|
|
||||||
nsICacheEntryDescriptor *, nsCacheAccessMode, nsresult, PRBool);
|
|
||||||
nsOnCacheEntryAvailableCallback mOnCacheEntryAvailableCallback;
|
|
||||||
PRBool mAsyncCacheOpen;
|
|
||||||
|
|
||||||
nsCOMPtr<nsICacheEntryDescriptor> mOfflineCacheEntry;
|
nsCOMPtr<nsICacheEntryDescriptor> mOfflineCacheEntry;
|
||||||
nsCacheAccessMode mOfflineCacheAccess;
|
nsCacheAccessMode mOfflineCacheAccess;
|
||||||
nsCString mOfflineCacheClientID;
|
nsCString mOfflineCacheClientID;
|
||||||
|
|
|
@ -294,6 +294,14 @@ nsHttpHandler::Init()
|
||||||
rv = InitConnectionMgr();
|
rv = InitConnectionMgr();
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
rv = NS_NewThread(getter_AddRefs(mCacheWriteThread));
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
mCacheWriteThread = nsnull;
|
||||||
|
LOG(("Failed creating cache-write thread - writes will be synchronous"));
|
||||||
|
} else {
|
||||||
|
LOG(("Created cache-write thread = %p", mCacheWriteThread.get()));
|
||||||
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIXULAppInfo> appInfo =
|
nsCOMPtr<nsIXULAppInfo> appInfo =
|
||||||
do_GetService("@mozilla.org/xre/app-info;1");
|
do_GetService("@mozilla.org/xre/app-info;1");
|
||||||
if (appInfo)
|
if (appInfo)
|
||||||
|
@ -313,6 +321,7 @@ nsHttpHandler::Init()
|
||||||
mObserverService->AddObserver(this, "profile-change-net-restore", PR_TRUE);
|
mObserverService->AddObserver(this, "profile-change-net-restore", PR_TRUE);
|
||||||
mObserverService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_TRUE);
|
mObserverService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_TRUE);
|
||||||
mObserverService->AddObserver(this, "net:clear-active-logins", PR_TRUE);
|
mObserverService->AddObserver(this, "net:clear-active-logins", PR_TRUE);
|
||||||
|
mObserverService->AddObserver(this, "xpcom-shutdown-threads", PR_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
StartPruneDeadConnectionsTimer();
|
StartPruneDeadConnectionsTimer();
|
||||||
|
@ -1771,6 +1780,18 @@ nsHttpHandler::Observe(nsISupports *subject,
|
||||||
else if (strcmp(topic, "net:clear-active-logins") == 0) {
|
else if (strcmp(topic, "net:clear-active-logins") == 0) {
|
||||||
mAuthCache.ClearAll();
|
mAuthCache.ClearAll();
|
||||||
}
|
}
|
||||||
|
else if (strcmp(topic, "xpcom-shutdown-threads") == 0) {
|
||||||
|
// Shutdown the cache write thread. This must be done after shutting down
|
||||||
|
// the cache service, because the (memory) cache entries' storage streams
|
||||||
|
// get released on the thread on which they were first written to, which
|
||||||
|
// is this thread.
|
||||||
|
if (mCacheWriteThread) {
|
||||||
|
LOG((" shutting down cache-write thread...\n"));
|
||||||
|
mCacheWriteThread->Shutdown();
|
||||||
|
LOG((" cache-write thread shutdown complete\n"));
|
||||||
|
mCacheWriteThread = nsnull;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -210,6 +210,8 @@ public:
|
||||||
static nsresult GenerateHostPort(const nsCString& host, PRInt32 port,
|
static nsresult GenerateHostPort(const nsCString& host, PRInt32 port,
|
||||||
nsCString& hostLine);
|
nsCString& hostLine);
|
||||||
|
|
||||||
|
// The thread used to implement async cache-writes
|
||||||
|
nsCOMPtr<nsIThread> mCacheWriteThread;
|
||||||
private:
|
private:
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
Загрузка…
Ссылка в новой задаче