Bug 722033 - Use asyncOpenCacheEntry() in nsHttpChannel when flag LOAD_BYPASS_LOCAL_CACHE_IF_BUSY is set

This commit is contained in:
Michal Novotny 2012-03-22 23:53:10 +01:00
parent d306834e3e
commit 19e7c0e85c
6 changed files with 60 additions and 79 deletions

View File

@ -1020,7 +1020,8 @@ public:
nsnull);
// Don't delete the request if it was queued
if (rv != NS_ERROR_CACHE_WAIT_FOR_VALIDATION)
if (!(mRequest->IsBlocking() &&
rv == NS_ERROR_CACHE_WAIT_FOR_VALIDATION))
delete mRequest;
return NS_OK;
@ -1662,11 +1663,13 @@ nsCacheService::ProcessRequest(nsCacheRequest * request,
// entry->RequestAccess queues request on entry
rv = entry->RequestAccess(request, &accessGranted);
if (rv != NS_ERROR_CACHE_WAIT_FOR_VALIDATION) break;
if (request->mListener) // async exits - validate, doom, or close will resume
return rv;
if (request->IsBlocking()) {
if (request->mListener) {
// async exits - validate, doom, or close will resume
return rv;
}
// XXX this is probably wrong...
Unlock();
rv = request->WaitForValidation();
@ -1773,7 +1776,8 @@ nsCacheService::OpenCacheEntry(nsCacheSession * session,
rv = gService->ProcessRequest(request, true, result);
// delete requests that have completed
if (!(listener && (rv == NS_ERROR_CACHE_WAIT_FOR_VALIDATION)))
if (!(listener && blockingMode &&
(rv == NS_ERROR_CACHE_WAIT_FOR_VALIDATION)))
delete request;
}

View File

@ -102,13 +102,14 @@ nsCacheSession::OpenCacheEntry(const nsACString & key,
NS_IMETHODIMP nsCacheSession::AsyncOpenCacheEntry(const nsACString & key,
nsCacheAccessMode accessRequested,
nsICacheListener *listener)
nsICacheListener *listener,
bool noWait)
{
nsresult rv;
rv = nsCacheService::OpenCacheEntry(this,
key,
accessRequested,
nsICache::BLOCKING,
!noWait,
listener,
nsnull); // no result

View File

@ -46,7 +46,7 @@
interface nsICacheEntryDescriptor;
interface nsICacheListener;
[scriptable, uuid(ae9e84b5-3e2d-457e-8fcd-5bbd2a8b832e)]
[scriptable, uuid(2ec1026f-e3a5-481c-908e-8d559235b721)]
interface nsICacheSession : nsISupports
{
/**
@ -76,13 +76,17 @@ interface nsICacheSession : nsISupports
in boolean blockingMode);
/**
* Asynchronous cache access. Does not block the calling thread.
* Instead, the listener will be notified when the descriptor is
* available.
* Asynchronous cache access. Does not block the calling thread. Instead,
* the listener will be notified when the descriptor is available. If
* 'noWait' is set to true, the listener will be notified immediately with
* status NS_ERROR_CACHE_WAIT_FOR_VALIDATION rather than queuing the request
* when another descriptor has been given WRITE access but hasn't validated
* the entry yet.
*/
void asyncOpenCacheEntry(in ACString key,
in nsCacheAccessMode accessRequested,
in nsICacheListener listener);
void asyncOpenCacheEntry(in ACString key,
in nsCacheAccessMode accessRequested,
in nsICacheListener listener,
[optional] in boolean noWait);
/**
* Evict all entries for this session's clientID according to its storagePolicy.

View File

@ -2288,7 +2288,7 @@ nsFtpState::CheckCache()
}
if (rv == NS_ERROR_CACHE_WAIT_FOR_VALIDATION) {
rv = session->AsyncOpenCacheEntry(key, accessReq, this);
rv = session->AsyncOpenCacheEntry(key, accessReq, this, false);
return NS_SUCCEEDED(rv);
}

View File

@ -2117,40 +2117,23 @@ nsHttpChannel::OpenCacheEntry()
getter_AddRefs(session));
NS_ENSURE_SUCCESS(rv, rv);
if (mLoadFlags & LOAD_BYPASS_LOCAL_CACHE_IF_BUSY) {
// must use synchronous open for LOAD_BYPASS_LOCAL_CACHE_IF_BUSY
rv = session->OpenCacheEntry(cacheKey,
nsICache::ACCESS_READ, false,
getter_AddRefs(mCacheEntry));
if (NS_SUCCEEDED(rv)) {
mCacheEntry->GetAccessGranted(&mCacheAccess);
LOG(("nsHttpChannel::OpenCacheEntry [this=%p grantedAccess=%d]",
this, mCacheAccess));
mLoadedFromApplicationCache = true;
return NS_OK;
} else if (rv == NS_ERROR_CACHE_WAIT_FOR_VALIDATION) {
LOG(("bypassing local cache since it is busy\n"));
// Don't try to load normal cache entry
return NS_ERROR_NOT_AVAILABLE;
}
} 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);
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,
mLoadFlags & LOAD_BYPASS_LOCAL_CACHE_IF_BUSY);
if (NS_SUCCEEDED(rv)) {
mAsyncCacheOpen = true;
return NS_OK;
}
if (NS_SUCCEEDED(rv)) {
mAsyncCacheOpen = true;
return NS_OK;
}
// sync or async opening failed
// opening cache entry failed
return OnOfflineCacheEntryAvailable(nsnull, nsICache::ACCESS_NONE,
rv, true);
}
@ -2174,6 +2157,12 @@ nsHttpChannel::OnOfflineCacheEntryAvailable(nsICacheEntryDescriptor *aEntry,
mCacheAccess = aAccess;
}
if (aEntryStatus == NS_ERROR_CACHE_WAIT_FOR_VALIDATION) {
LOG(("bypassing local cache since it is busy\n"));
// Don't try to load normal cache entry
return aIsSync ? NS_ERROR_NOT_AVAILABLE : Connect(false);
}
if (mCanceled && NS_FAILED(mStatus)) {
LOG(("channel was canceled [this=%p status=%x]\n", this, mStatus));
return mStatus;
@ -2260,38 +2249,17 @@ nsHttpChannel::OpenNormalCacheEntry(bool aIsSync)
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");
}
mOnCacheEntryAvailableCallback =
&nsHttpChannel::OnNormalCacheEntryAvailable;
rv = session->AsyncOpenCacheEntry(
cacheKey,
accessRequested,
this,
mLoadFlags & LOAD_BYPASS_LOCAL_CACHE_IF_BUSY);
// must use synchronous open for LOAD_BYPASS_LOCAL_CACHE_IF_BUSY
rv = session->OpenCacheEntry(cacheKey, accessRequested, false,
getter_AddRefs(mCacheEntry));
if (NS_SUCCEEDED(rv)) {
mCacheEntry->GetAccessGranted(&mCacheAccess);
LOG(("nsHttpChannel::OpenCacheEntry [this=%p grantedAccess=%d]",
this, mCacheAccess));
}
else if (rv == NS_ERROR_CACHE_WAIT_FOR_VALIDATION) {
LOG(("bypassing local cache since it is busy\n"));
rv = NS_ERROR_NOT_AVAILABLE;
}
}
else {
mOnCacheEntryAvailableCallback =
&nsHttpChannel::OnNormalCacheEntryAvailable;
rv = session->AsyncOpenCacheEntry(cacheKey, accessRequested, this);
if (NS_SUCCEEDED(rv)) {
mAsyncCacheOpen = true;
return NS_OK;
}
if (NS_SUCCEEDED(rv)) {
mAsyncCacheOpen = true;
return NS_OK;
}
if (!aIsSync)
@ -2314,6 +2282,10 @@ nsHttpChannel::OnNormalCacheEntryAvailable(nsICacheEntryDescriptor *aEntry,
mCacheAccess = aAccess;
}
if (aEntryStatus == NS_ERROR_CACHE_WAIT_FOR_VALIDATION) {
LOG(("bypassing local cache since it is busy\n"));
}
if (mCanceled && NS_FAILED(mStatus)) {
LOG(("channel was canceled [this=%p status=%x]\n", this, mStatus));
return mStatus;

View File

@ -709,7 +709,7 @@ nsWyciwygChannel::OpenCacheEntry(const nsACString & aCacheKey,
rv = cacheSession->OpenCacheEntry(aCacheKey, aAccessMode, false,
getter_AddRefs(mCacheEntry));
else
rv = cacheSession->AsyncOpenCacheEntry(aCacheKey, aAccessMode, this);
rv = cacheSession->AsyncOpenCacheEntry(aCacheKey, aAccessMode, this, false);
return rv;
}