Fix race condition in nsCacheRequest WaitForValidation().

Force !streamBased to set storagePolicy to nsICache:STORE_IN_MEMORY when creating nsCacheSessions.

Fix ProcessRequest() to refrain from creating a descriptor for ACCESS_READ requests when no entry is found (found by pavlov).
This commit is contained in:
gordon%netscape.com 2001-03-06 03:26:13 +00:00
Родитель ae1d87a803
Коммит 98bc4c37ef
3 изменённых файлов: 16 добавлений и 5 удалений

14
netwerk/cache/src/nsCacheRequest.h поставляемый
Просмотреть файл

@ -54,6 +54,7 @@ private:
SetAccessRequested(accessRequested); SetAccessRequested(accessRequested);
if (streamBased) MarkStreamBased(); if (streamBased) MarkStreamBased();
SetStoragePolicy(storagePolicy); SetStoragePolicy(storagePolicy);
MarkWaitingForValidation();
} }
~nsCacheRequest() ~nsCacheRequest()
@ -111,6 +112,11 @@ private:
nsresult nsresult
WaitForValidation(void) WaitForValidation(void)
{ {
if (!WaitingForValidation()) { // flag already cleared
MarkWaitingForValidation(); // set up for next time
return NS_OK; // early exit;
}
if (!mLock) { if (!mLock) {
mLock = PR_NewLock(); mLock = PR_NewLock();
if (!mLock) return NS_ERROR_OUT_OF_MEMORY; if (!mLock) return NS_ERROR_OUT_OF_MEMORY;
@ -122,14 +128,14 @@ private:
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
} }
} }
PRStatus status; PRStatus status;
PR_Lock(mLock); PR_Lock(mLock);
while (WaitingForValidation() && (status == PR_SUCCESS) ) { while (WaitingForValidation() && (status == PR_SUCCESS) ) {
status = PR_WaitCondVar(mCondVar, PR_INTERVAL_NO_TIMEOUT); status = PR_WaitCondVar(mCondVar, PR_INTERVAL_NO_TIMEOUT);
} }
MarkWaitingForValidation(); // set up for next time
PR_Unlock(mLock); PR_Unlock(mLock);
NS_ASSERTION(status == PR_SUCCESS, "PR_WaitCondVar() returned PR_FAILURE?"); NS_ASSERTION(status == PR_SUCCESS, "PR_WaitCondVar() returned PR_FAILURE?");
if (status == PR_FAILURE) if (status == PR_FAILURE)
return NS_ERROR_UNEXPECTED; return NS_ERROR_UNEXPECTED;
@ -138,10 +144,12 @@ private:
} }
void WakeUp(void) { void WakeUp(void) {
PR_Lock(mLock);
DoneWaitingForValidation(); DoneWaitingForValidation();
if (mLock) {
PR_Lock(mLock);
PR_NotifyCondVar(mCondVar); PR_NotifyCondVar(mCondVar);
PR_Unlock(mLock); PR_Unlock(mLock);
}
} }
/** /**

6
netwerk/cache/src/nsCacheService.cpp поставляемый
Просмотреть файл

@ -282,6 +282,7 @@ nsCacheService::ProcessRequest(nsCacheRequest * request,
if (request->mListener) // async exits - validate, doom, or close will resume if (request->mListener) // async exits - validate, doom, or close will resume
return rv; return rv;
// XXX allocate condvar for request if necessary
PR_Unlock(mCacheServiceLock); PR_Unlock(mCacheServiceLock);
rv = request->WaitForValidation(); rv = request->WaitForValidation();
PR_Lock(mCacheServiceLock); PR_Lock(mCacheServiceLock);
@ -300,8 +301,9 @@ nsCacheService::ProcessRequest(nsCacheRequest * request,
} }
nsCOMPtr<nsICacheEntryDescriptor> descriptor; nsCOMPtr<nsICacheEntryDescriptor> descriptor;
rv = entry->CreateDescriptor(request, accessGranted, getter_AddRefs(descriptor)); if (NS_SUCCEEDED(rv))
rv = entry->CreateDescriptor(request, accessGranted, getter_AddRefs(descriptor));
if (request->mListener) { // Asynchronous if (request->mListener) { // Asynchronous
// call listener to report error or descriptor // call listener to report error or descriptor

1
netwerk/cache/src/nsCacheSession.cpp поставляемый
Просмотреть файл

@ -38,6 +38,7 @@ nsCacheSession::nsCacheSession(const char * clientID,
mStreamBased(streamBased) mStreamBased(streamBased)
{ {
NS_INIT_ISUPPORTS(); NS_INIT_ISUPPORTS();
if (!streamBased) mStoragePolicy = nsICache::STORE_IN_MEMORY;
} }
nsCacheSession::~nsCacheSession() nsCacheSession::~nsCacheSession()