backing out patch for bug 332730

This commit is contained in:
darin%meer.net 2006-06-20 17:50:49 +00:00
Родитель c817605fe1
Коммит 989912102d
8 изменённых файлов: 94 добавлений и 212 удалений

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

@ -45,6 +45,7 @@
#include "nsCacheMetaData.h" #include "nsCacheMetaData.h"
#include "nsCacheRequest.h" #include "nsCacheRequest.h"
#include "nsThreadUtils.h" #include "nsThreadUtils.h"
#include "nsProxyRelease.h"
#include "nsError.h" #include "nsError.h"
#include "nsICacheService.h" #include "nsICacheService.h"
#include "nsCache.h" #include "nsCache.h"
@ -83,8 +84,14 @@ nsCacheEntry::~nsCacheEntry()
if (IsStreamData()) return; if (IsStreamData()) return;
if (mData) // proxy release of of memory cache nsISupports objects
nsCacheService::ReleaseObject_Locked(mData, mThread); if (!mData) return;
nsISupports *data = nsnull;
mData.swap(data); // this reference will be owned by the proxy
// release our reference before switching threads
NS_ProxyRelease(mThread, data);
} }
@ -134,12 +141,8 @@ nsCacheEntry::TouchData()
void void
nsCacheEntry::SetData(nsISupports * data) nsCacheEntry::SetThread()
{ {
if (mData)
nsCacheService::ReleaseObject_Locked(mData, mThread);
NS_ADDREF(mData = data);
mThread = do_GetCurrentThread(); mThread = do_GetCurrentThread();
} }

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

@ -104,13 +104,15 @@ public:
* Data accessors * Data accessors
*/ */
nsISupports *Data() { return mData; } nsISupports *Data() { return mData; }
void SetData( nsISupports * data); void SetData( nsISupports * data) { mData = data; }
PRUint32 DataSize() { return mDataSize; } PRUint32 DataSize() { return mDataSize; }
void SetDataSize( PRUint32 size) { mDataSize = size; } void SetDataSize( PRUint32 size) { mDataSize = size; }
void TouchData(); void TouchData();
void SetThread();
/** /**
* Meta data accessors * Meta data accessors
*/ */
@ -239,7 +241,7 @@ private:
PRUint32 mDataSize; // 4 PRUint32 mDataSize; // 4
nsCacheDevice * mCacheDevice; // 4 nsCacheDevice * mCacheDevice; // 4
nsCOMPtr<nsISupports> mSecurityInfo; // nsCOMPtr<nsISupports> mSecurityInfo; //
nsISupports * mData; // strong ref nsCOMPtr<nsISupports> mData; //
nsCOMPtr<nsIThread> mThread; nsCOMPtr<nsIThread> mThread;
nsCacheMetaData mMetaData; // 4 nsCacheMetaData mMetaData; // 4
PRCList mRequestQ; // 8 PRCList mRequestQ; // 8

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

@ -46,6 +46,7 @@
#include "nsReadableUtils.h" #include "nsReadableUtils.h"
#include "nsIOutputStream.h" #include "nsIOutputStream.h"
#include "nsCRT.h" #include "nsCRT.h"
#include "nsAutoLock.h"
NS_IMPL_THREADSAFE_ISUPPORTS2(nsCacheEntryDescriptor, NS_IMPL_THREADSAFE_ISUPPORTS2(nsCacheEntryDescriptor,
nsICacheEntryDescriptor, nsICacheEntryDescriptor,
@ -80,8 +81,7 @@ NS_IMETHODIMP
nsCacheEntryDescriptor::GetClientID(char ** result) nsCacheEntryDescriptor::GetClientID(char ** result)
{ {
NS_ENSURE_ARG_POINTER(result); NS_ENSURE_ARG_POINTER(result);
nsAutoLock lock(nsCacheService::ServiceLock());
nsCacheServiceAutoLock lock;
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
return ClientIDFromCacheKey(*(mCacheEntry->Key()), result); return ClientIDFromCacheKey(*(mCacheEntry->Key()), result);
@ -92,7 +92,7 @@ NS_IMETHODIMP
nsCacheEntryDescriptor::GetDeviceID(char ** result) nsCacheEntryDescriptor::GetDeviceID(char ** result)
{ {
NS_ENSURE_ARG_POINTER(result); NS_ENSURE_ARG_POINTER(result);
nsCacheServiceAutoLock lock; nsAutoLock lock(nsCacheService::ServiceLock());
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
*result = nsCRT::strdup(mCacheEntry->GetDeviceID()); *result = nsCRT::strdup(mCacheEntry->GetDeviceID());
@ -103,7 +103,7 @@ nsCacheEntryDescriptor::GetDeviceID(char ** result)
NS_IMETHODIMP NS_IMETHODIMP
nsCacheEntryDescriptor::GetKey(nsACString &result) nsCacheEntryDescriptor::GetKey(nsACString &result)
{ {
nsCacheServiceAutoLock lock; nsAutoLock lock(nsCacheService::ServiceLock());
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
return ClientKeyFromCacheKey(*(mCacheEntry->Key()), result); return ClientKeyFromCacheKey(*(mCacheEntry->Key()), result);
@ -114,7 +114,7 @@ NS_IMETHODIMP
nsCacheEntryDescriptor::GetFetchCount(PRInt32 *result) nsCacheEntryDescriptor::GetFetchCount(PRInt32 *result)
{ {
NS_ENSURE_ARG_POINTER(result); NS_ENSURE_ARG_POINTER(result);
nsCacheServiceAutoLock lock; nsAutoLock lock(nsCacheService::ServiceLock());
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
*result = mCacheEntry->FetchCount(); *result = mCacheEntry->FetchCount();
@ -126,7 +126,7 @@ NS_IMETHODIMP
nsCacheEntryDescriptor::GetLastFetched(PRUint32 *result) nsCacheEntryDescriptor::GetLastFetched(PRUint32 *result)
{ {
NS_ENSURE_ARG_POINTER(result); NS_ENSURE_ARG_POINTER(result);
nsCacheServiceAutoLock lock; nsAutoLock lock(nsCacheService::ServiceLock());
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
*result = mCacheEntry->LastFetched(); *result = mCacheEntry->LastFetched();
@ -138,7 +138,7 @@ NS_IMETHODIMP
nsCacheEntryDescriptor::GetLastModified(PRUint32 *result) nsCacheEntryDescriptor::GetLastModified(PRUint32 *result)
{ {
NS_ENSURE_ARG_POINTER(result); NS_ENSURE_ARG_POINTER(result);
nsCacheServiceAutoLock lock; nsAutoLock lock(nsCacheService::ServiceLock());
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
*result = mCacheEntry->LastModified(); *result = mCacheEntry->LastModified();
@ -150,7 +150,7 @@ NS_IMETHODIMP
nsCacheEntryDescriptor::GetExpirationTime(PRUint32 *result) nsCacheEntryDescriptor::GetExpirationTime(PRUint32 *result)
{ {
NS_ENSURE_ARG_POINTER(result); NS_ENSURE_ARG_POINTER(result);
nsCacheServiceAutoLock lock; nsAutoLock lock(nsCacheService::ServiceLock());
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
*result = mCacheEntry->ExpirationTime(); *result = mCacheEntry->ExpirationTime();
@ -161,7 +161,7 @@ nsCacheEntryDescriptor::GetExpirationTime(PRUint32 *result)
NS_IMETHODIMP NS_IMETHODIMP
nsCacheEntryDescriptor::SetExpirationTime(PRUint32 expirationTime) nsCacheEntryDescriptor::SetExpirationTime(PRUint32 expirationTime)
{ {
nsCacheServiceAutoLock lock; nsAutoLock lock(nsCacheService::ServiceLock());
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
mCacheEntry->SetExpirationTime(expirationTime); mCacheEntry->SetExpirationTime(expirationTime);
@ -173,7 +173,7 @@ nsCacheEntryDescriptor::SetExpirationTime(PRUint32 expirationTime)
NS_IMETHODIMP nsCacheEntryDescriptor::IsStreamBased(PRBool *result) NS_IMETHODIMP nsCacheEntryDescriptor::IsStreamBased(PRBool *result)
{ {
NS_ENSURE_ARG_POINTER(result); NS_ENSURE_ARG_POINTER(result);
nsCacheServiceAutoLock lock; nsAutoLock lock(nsCacheService::ServiceLock());
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
*result = mCacheEntry->IsStreamData(); *result = mCacheEntry->IsStreamData();
@ -184,7 +184,7 @@ NS_IMETHODIMP nsCacheEntryDescriptor::IsStreamBased(PRBool *result)
NS_IMETHODIMP nsCacheEntryDescriptor::GetDataSize(PRUint32 *result) NS_IMETHODIMP nsCacheEntryDescriptor::GetDataSize(PRUint32 *result)
{ {
NS_ENSURE_ARG_POINTER(result); NS_ENSURE_ARG_POINTER(result);
nsCacheServiceAutoLock lock; nsAutoLock lock(nsCacheService::ServiceLock());
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
*result = mCacheEntry->DataSize(); *result = mCacheEntry->DataSize();
@ -195,7 +195,7 @@ NS_IMETHODIMP nsCacheEntryDescriptor::GetDataSize(PRUint32 *result)
nsresult nsresult
nsCacheEntryDescriptor::RequestDataSizeChange(PRInt32 deltaSize) nsCacheEntryDescriptor::RequestDataSizeChange(PRInt32 deltaSize)
{ {
nsCacheServiceAutoLock lock; nsAutoLock lock(nsCacheService::ServiceLock());
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
nsresult rv; nsresult rv;
@ -213,7 +213,7 @@ nsCacheEntryDescriptor::RequestDataSizeChange(PRInt32 deltaSize)
NS_IMETHODIMP NS_IMETHODIMP
nsCacheEntryDescriptor::SetDataSize(PRUint32 dataSize) nsCacheEntryDescriptor::SetDataSize(PRUint32 dataSize)
{ {
nsCacheServiceAutoLock lock; nsAutoLock lock(nsCacheService::ServiceLock());
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
// XXX review for signed/unsigned math errors // XXX review for signed/unsigned math errors
@ -241,7 +241,7 @@ nsCacheEntryDescriptor::OpenInputStream(PRUint32 offset, nsIInputStream ** resul
NS_ENSURE_ARG_POINTER(result); NS_ENSURE_ARG_POINTER(result);
{ {
nsCacheServiceAutoLock lock; nsAutoLock lock(nsCacheService::ServiceLock());
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
if (!mCacheEntry->IsStreamData()) return NS_ERROR_CACHE_DATA_IS_NOT_STREAM; if (!mCacheEntry->IsStreamData()) return NS_ERROR_CACHE_DATA_IS_NOT_STREAM;
@ -264,7 +264,7 @@ nsCacheEntryDescriptor::OpenOutputStream(PRUint32 offset, nsIOutputStream ** res
NS_ENSURE_ARG_POINTER(result); NS_ENSURE_ARG_POINTER(result);
{ {
nsCacheServiceAutoLock lock; nsAutoLock lock(nsCacheService::ServiceLock());
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
if (!mCacheEntry->IsStreamData()) return NS_ERROR_CACHE_DATA_IS_NOT_STREAM; if (!mCacheEntry->IsStreamData()) return NS_ERROR_CACHE_DATA_IS_NOT_STREAM;
@ -286,7 +286,7 @@ NS_IMETHODIMP
nsCacheEntryDescriptor::GetCacheElement(nsISupports ** result) nsCacheEntryDescriptor::GetCacheElement(nsISupports ** result)
{ {
NS_ENSURE_ARG_POINTER(result); NS_ENSURE_ARG_POINTER(result);
nsCacheServiceAutoLock lock; nsAutoLock lock(nsCacheService::ServiceLock());
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
if (mCacheEntry->IsStreamData()) return NS_ERROR_CACHE_DATA_IS_STREAM; if (mCacheEntry->IsStreamData()) return NS_ERROR_CACHE_DATA_IS_STREAM;
@ -298,7 +298,7 @@ nsCacheEntryDescriptor::GetCacheElement(nsISupports ** result)
NS_IMETHODIMP NS_IMETHODIMP
nsCacheEntryDescriptor::SetCacheElement(nsISupports * cacheElement) nsCacheEntryDescriptor::SetCacheElement(nsISupports * cacheElement)
{ {
nsCacheServiceAutoLock lock; nsAutoLock lock(nsCacheService::ServiceLock());
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
if (mCacheEntry->IsStreamData()) return NS_ERROR_CACHE_DATA_IS_STREAM; if (mCacheEntry->IsStreamData()) return NS_ERROR_CACHE_DATA_IS_STREAM;
@ -319,7 +319,7 @@ NS_IMETHODIMP
nsCacheEntryDescriptor::GetStoragePolicy(nsCacheStoragePolicy *result) nsCacheEntryDescriptor::GetStoragePolicy(nsCacheStoragePolicy *result)
{ {
NS_ENSURE_ARG_POINTER(result); NS_ENSURE_ARG_POINTER(result);
nsCacheServiceAutoLock lock; nsAutoLock lock(nsCacheService::ServiceLock());
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
return mCacheEntry->StoragePolicy(); return mCacheEntry->StoragePolicy();
@ -329,7 +329,7 @@ nsCacheEntryDescriptor::GetStoragePolicy(nsCacheStoragePolicy *result)
NS_IMETHODIMP NS_IMETHODIMP
nsCacheEntryDescriptor::SetStoragePolicy(nsCacheStoragePolicy policy) nsCacheEntryDescriptor::SetStoragePolicy(nsCacheStoragePolicy policy)
{ {
nsCacheServiceAutoLock lock; nsAutoLock lock(nsCacheService::ServiceLock());
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
// XXX validate policy against session? // XXX validate policy against session?
@ -347,7 +347,7 @@ NS_IMETHODIMP
nsCacheEntryDescriptor::GetFile(nsIFile ** result) nsCacheEntryDescriptor::GetFile(nsIFile ** result)
{ {
NS_ENSURE_ARG_POINTER(result); NS_ENSURE_ARG_POINTER(result);
nsCacheServiceAutoLock lock; nsAutoLock lock(nsCacheService::ServiceLock());
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
return nsCacheService::GetFileForEntry(mCacheEntry, result); return nsCacheService::GetFileForEntry(mCacheEntry, result);
@ -358,7 +358,7 @@ NS_IMETHODIMP
nsCacheEntryDescriptor::GetSecurityInfo(nsISupports ** result) nsCacheEntryDescriptor::GetSecurityInfo(nsISupports ** result)
{ {
NS_ENSURE_ARG_POINTER(result); NS_ENSURE_ARG_POINTER(result);
nsCacheServiceAutoLock lock; nsAutoLock lock(nsCacheService::ServiceLock());
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
return mCacheEntry->GetSecurityInfo(result); return mCacheEntry->GetSecurityInfo(result);
@ -368,7 +368,7 @@ nsCacheEntryDescriptor::GetSecurityInfo(nsISupports ** result)
NS_IMETHODIMP NS_IMETHODIMP
nsCacheEntryDescriptor::SetSecurityInfo(nsISupports * securityInfo) nsCacheEntryDescriptor::SetSecurityInfo(nsISupports * securityInfo)
{ {
nsCacheServiceAutoLock lock; nsAutoLock lock(nsCacheService::ServiceLock());
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
mCacheEntry->SetSecurityInfo(securityInfo); mCacheEntry->SetSecurityInfo(securityInfo);
@ -380,7 +380,7 @@ nsCacheEntryDescriptor::SetSecurityInfo(nsISupports * securityInfo)
NS_IMETHODIMP NS_IMETHODIMP
nsCacheEntryDescriptor::Doom() nsCacheEntryDescriptor::Doom()
{ {
nsCacheServiceAutoLock lock; nsAutoLock lock(nsCacheService::ServiceLock());
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
return nsCacheService::DoomEntry(mCacheEntry); return nsCacheService::DoomEntry(mCacheEntry);
@ -390,7 +390,7 @@ nsCacheEntryDescriptor::Doom()
NS_IMETHODIMP NS_IMETHODIMP
nsCacheEntryDescriptor::DoomAndFailPendingRequests(nsresult status) nsCacheEntryDescriptor::DoomAndFailPendingRequests(nsresult status)
{ {
nsCacheServiceAutoLock lock; nsAutoLock lock(nsCacheService::ServiceLock());
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
return NS_ERROR_NOT_IMPLEMENTED; return NS_ERROR_NOT_IMPLEMENTED;
@ -400,7 +400,7 @@ nsCacheEntryDescriptor::DoomAndFailPendingRequests(nsresult status)
NS_IMETHODIMP NS_IMETHODIMP
nsCacheEntryDescriptor::MarkValid() nsCacheEntryDescriptor::MarkValid()
{ {
nsCacheServiceAutoLock lock; nsAutoLock lock(nsCacheService::ServiceLock());
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
nsresult rv = nsCacheService::ValidateEntry(mCacheEntry); nsresult rv = nsCacheService::ValidateEntry(mCacheEntry);
@ -411,7 +411,7 @@ nsCacheEntryDescriptor::MarkValid()
NS_IMETHODIMP NS_IMETHODIMP
nsCacheEntryDescriptor::Close() nsCacheEntryDescriptor::Close()
{ {
nsCacheServiceAutoLock lock; nsAutoLock lock(nsCacheService::ServiceLock());
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
// XXX perhaps closing descriptors should clear/sever transports // XXX perhaps closing descriptors should clear/sever transports
@ -430,7 +430,7 @@ nsCacheEntryDescriptor::GetMetaDataElement(const char *key, char **result)
NS_ENSURE_ARG_POINTER(key); NS_ENSURE_ARG_POINTER(key);
*result = nsnull; *result = nsnull;
nsCacheServiceAutoLock lock; nsAutoLock lock(nsCacheService::ServiceLock());
NS_ENSURE_TRUE(mCacheEntry, NS_ERROR_NOT_AVAILABLE); NS_ENSURE_TRUE(mCacheEntry, NS_ERROR_NOT_AVAILABLE);
const char *value; const char *value;
@ -450,7 +450,7 @@ nsCacheEntryDescriptor::SetMetaDataElement(const char *key, const char *value)
{ {
NS_ENSURE_ARG_POINTER(key); NS_ENSURE_ARG_POINTER(key);
nsCacheServiceAutoLock lock; nsAutoLock lock(nsCacheService::ServiceLock());
NS_ENSURE_TRUE(mCacheEntry, NS_ERROR_NOT_AVAILABLE); NS_ENSURE_TRUE(mCacheEntry, NS_ERROR_NOT_AVAILABLE);
// XXX allow null value, for clearing key? // XXX allow null value, for clearing key?
@ -465,7 +465,7 @@ nsCacheEntryDescriptor::SetMetaDataElement(const char *key, const char *value)
NS_IMETHODIMP NS_IMETHODIMP
nsCacheEntryDescriptor::VisitMetaData(nsICacheMetaDataVisitor * visitor) nsCacheEntryDescriptor::VisitMetaData(nsICacheMetaDataVisitor * visitor)
{ {
nsCacheServiceAutoLock lock; // XXX check callers, we're calling out of module nsAutoLock lock(nsCacheService::ServiceLock()); // XXX check callers, we're calling out of module
NS_ENSURE_ARG_POINTER(visitor); NS_ENSURE_ARG_POINTER(visitor);
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
@ -484,7 +484,7 @@ NS_IMPL_THREADSAFE_ISUPPORTS1(nsCacheEntryDescriptor::nsInputStreamWrapper,
nsresult nsCacheEntryDescriptor:: nsresult nsCacheEntryDescriptor::
nsInputStreamWrapper::LazyInit() nsInputStreamWrapper::LazyInit()
{ {
nsCacheServiceAutoLock lock; nsAutoLock lock(nsCacheService::ServiceLock());
nsCacheAccessMode mode; nsCacheAccessMode mode;
nsresult rv = mDescriptor->GetAccessGranted(&mode); nsresult rv = mDescriptor->GetAccessGranted(&mode);
@ -561,7 +561,7 @@ NS_IMPL_THREADSAFE_ISUPPORTS1(nsCacheEntryDescriptor::nsOutputStreamWrapper,
nsresult nsCacheEntryDescriptor:: nsresult nsCacheEntryDescriptor::
nsOutputStreamWrapper::LazyInit() nsOutputStreamWrapper::LazyInit()
{ {
nsCacheServiceAutoLock lock; nsAutoLock lock(nsCacheService::ServiceLock());
nsCacheAccessMode mode; nsCacheAccessMode mode;
nsresult rv = mDescriptor->GetAccessGranted(&mode); nsresult rv = mDescriptor->GetAccessGranted(&mode);

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

@ -46,7 +46,6 @@
#include "nsICache.h" #include "nsICache.h"
#include "nsICacheListener.h" #include "nsICacheListener.h"
#include "nsCacheSession.h" #include "nsCacheSession.h"
#include "nsCacheService.h"
class nsCacheRequest : public PRCList class nsCacheRequest : public PRCList
@ -74,7 +73,6 @@ private:
if (session->WillDoomEntriesIfExpired()) MarkDoomEntriesIfExpired(); if (session->WillDoomEntriesIfExpired()) MarkDoomEntriesIfExpired();
if (blockingMode == nsICache::BLOCKING) MarkBlockingMode(); if (blockingMode == nsICache::BLOCKING) MarkBlockingMode();
MarkWaitingForValidation(); MarkWaitingForValidation();
NS_IF_ADDREF(mListener);
} }
~nsCacheRequest() ~nsCacheRequest()
@ -84,9 +82,6 @@ private:
if (mLock) PR_DestroyLock(mLock); if (mLock) PR_DestroyLock(mLock);
if (mCondVar) PR_DestroyCondVar(mCondVar); if (mCondVar) PR_DestroyCondVar(mCondVar);
NS_ASSERTION(PR_CLIST_IS_EMPTY(this), "request still on a list"); NS_ASSERTION(PR_CLIST_IS_EMPTY(this), "request still on a list");
if (mListener)
nsCacheService::ReleaseObject_Locked(mListener, mThread);
} }
/** /**
@ -191,7 +186,7 @@ private:
*/ */
nsCString * mKey; nsCString * mKey;
PRUint32 mInfo; PRUint32 mInfo;
nsICacheListener * mListener; // strong ref nsCOMPtr<nsICacheListener> mListener;
nsCOMPtr<nsIThread> mThread; nsCOMPtr<nsIThread> mThread;
PRLock * mLock; PRLock * mLock;
PRCondVar * mCondVar; PRCondVar * mCondVar;

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

@ -55,6 +55,7 @@
#include "nsDiskCacheDevice.h" #include "nsDiskCacheDevice.h"
#endif #endif
#include "nsAutoLock.h"
#include "nsIObserverService.h" #include "nsIObserverService.h"
#include "nsIPrefService.h" #include "nsIPrefService.h"
#include "nsIPrefBranch.h" #include "nsIPrefBranch.h"
@ -63,7 +64,6 @@
#include "nsDirectoryServiceDefs.h" #include "nsDirectoryServiceDefs.h"
#include "nsAppDirectoryServiceDefs.h" #include "nsAppDirectoryServiceDefs.h"
#include "nsThreadUtils.h" #include "nsThreadUtils.h"
#include "nsProxyRelease.h"
#include "nsVoidArray.h" #include "nsVoidArray.h"
#include "nsDeleteDir.h" #include "nsDeleteDir.h"
#include <math.h> // for log() #include <math.h> // for log()
@ -466,7 +466,7 @@ nsCacheService * nsCacheService::gService = nsnull;
NS_IMPL_THREADSAFE_ISUPPORTS1(nsCacheService, nsICacheService) NS_IMPL_THREADSAFE_ISUPPORTS1(nsCacheService, nsICacheService)
nsCacheService::nsCacheService() nsCacheService::nsCacheService()
: mLock(nsnull), : mCacheServiceLock(nsnull),
mInitialized(PR_FALSE), mInitialized(PR_FALSE),
mEnableMemoryDevice(PR_TRUE), mEnableMemoryDevice(PR_TRUE),
mEnableDiskDevice(PR_TRUE), mEnableDiskDevice(PR_TRUE),
@ -488,11 +488,7 @@ nsCacheService::nsCacheService()
PR_INIT_CLIST(&mDoomedEntries); PR_INIT_CLIST(&mDoomedEntries);
// allocate service lock // allocate service lock
mLock = PR_NewLock(); mCacheServiceLock = PR_NewLock();
#if defined(DEBUG)
mLockedThread = nsnull;
#endif
} }
nsCacheService::~nsCacheService() nsCacheService::~nsCacheService()
@ -500,7 +496,7 @@ nsCacheService::~nsCacheService()
if (mInitialized) // Shutdown hasn't been called yet. if (mInitialized) // Shutdown hasn't been called yet.
(void) Shutdown(); (void) Shutdown();
PR_DestroyLock(mLock); PR_DestroyLock(mCacheServiceLock);
gService = nsnull; gService = nsnull;
} }
@ -512,7 +508,7 @@ nsCacheService::Init()
if (mInitialized) if (mInitialized)
return NS_ERROR_ALREADY_INITIALIZED; return NS_ERROR_ALREADY_INITIALIZED;
if (mLock == nsnull) if (mCacheServiceLock == nsnull)
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
CACHE_LOG_INIT(); CACHE_LOG_INIT();
@ -538,7 +534,7 @@ nsCacheService::Init()
void void
nsCacheService::Shutdown() nsCacheService::Shutdown()
{ {
nsCacheServiceAutoLock lock; nsAutoLock lock(mCacheServiceLock);
NS_ASSERTION(mInitialized, NS_ASSERTION(mInitialized,
"can't shutdown nsCacheService unless it has been initialized."); "can't shutdown nsCacheService unless it has been initialized.");
@ -644,7 +640,7 @@ nsCacheService::EvictEntriesForClient(const char * clientID,
} }
} }
nsCacheServiceAutoLock lock; nsAutoLock lock(mCacheServiceLock);
nsresult rv = NS_OK; nsresult rv = NS_OK;
#ifdef NECKO_DISK_CACHE #ifdef NECKO_DISK_CACHE
@ -681,7 +677,7 @@ nsCacheService::IsStorageEnabledForPolicy(nsCacheStoragePolicy storagePolicy,
PRBool * result) PRBool * result)
{ {
if (gService == nsnull) return NS_ERROR_NOT_AVAILABLE; if (gService == nsnull) return NS_ERROR_NOT_AVAILABLE;
nsCacheServiceAutoLock lock; nsAutoLock lock(gService->mCacheServiceLock);
*result = gService->IsStorageEnabledForPolicy_Locked(storagePolicy); *result = gService->IsStorageEnabledForPolicy_Locked(storagePolicy);
return NS_OK; return NS_OK;
@ -711,7 +707,7 @@ NS_IMETHODIMP nsCacheService::VisitEntries(nsICacheVisitor *visitor)
{ {
NS_ENSURE_ARG_POINTER(visitor); NS_ENSURE_ARG_POINTER(visitor);
nsCacheServiceAutoLock lock; nsAutoLock lock(mCacheServiceLock);
if (!(mEnableDiskDevice || mEnableMemoryDevice)) if (!(mEnableDiskDevice || mEnableMemoryDevice))
return NS_ERROR_NOT_AVAILABLE; return NS_ERROR_NOT_AVAILABLE;
@ -843,63 +839,25 @@ nsCacheService::CreateRequest(nsCacheSession * session,
} }
class nsCacheListenerEvent : public nsRunnable
{
public:
nsCacheListenerEvent(nsICacheListener *listener,
nsICacheEntryDescriptor *descriptor,
nsCacheAccessMode accessGranted,
nsresult status)
: mListener(listener) // transfers reference
, mDescriptor(descriptor) // transfers reference (may be null)
, mAccessGranted(accessGranted)
, mStatus(status)
{}
NS_IMETHOD Run()
{
mListener->OnCacheEntryAvailable(mDescriptor, mAccessGranted, mStatus);
NS_RELEASE(mListener);
NS_IF_RELEASE(mDescriptor);
return NS_OK;
}
private:
// We explicitly leak mListener or mDescriptor if Run is not called
// because otherwise we cannot guarantee that they are destroyed on
// the right thread.
nsICacheListener *mListener;
nsICacheEntryDescriptor *mDescriptor;
nsCacheAccessMode mAccessGranted;
nsresult mStatus;
};
nsresult nsresult
nsCacheService::NotifyListener(nsCacheRequest * request, nsCacheService::NotifyListener(nsCacheRequest * request,
nsICacheEntryDescriptor * descriptor, nsICacheEntryDescriptor * descriptor,
nsCacheAccessMode accessGranted, nsCacheAccessMode accessGranted,
nsresult status) nsresult error)
{ {
nsresult rv;
nsCOMPtr<nsICacheListener> listenerProxy;
NS_ASSERTION(request->mThread, "no thread set in async request!"); NS_ASSERTION(request->mThread, "no thread set in async request!");
// Swap ownership, and release listener on target thread... rv = NS_GetProxyForObject(request->mThread,
nsICacheListener *listener = request->mListener; NS_GET_IID(nsICacheListener),
request->mListener = nsnull; request->mListener,
NS_PROXY_ASYNC | NS_PROXY_ALWAYS,
getter_AddRefs(listenerProxy));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIRunnable> ev = return listenerProxy->OnCacheEntryAvailable(descriptor, accessGranted, error);
new nsCacheListenerEvent(listener, descriptor,
accessGranted, status);
if (!ev) {
// Better to leak listener and descriptor if we fail because we don't
// want to destroy them inside the cache service lock or on potentially
// the wrong thread.
return NS_ERROR_OUT_OF_MEMORY;
}
return request->mThread->Dispatch(ev, NS_DISPATCH_NORMAL);
} }
@ -908,7 +866,7 @@ nsCacheService::ProcessRequest(nsCacheRequest * request,
PRBool calledFromOpenCacheEntry, PRBool calledFromOpenCacheEntry,
nsICacheEntryDescriptor ** result) nsICacheEntryDescriptor ** result)
{ {
// !!! must be called with mLock held !!! // !!! must be called with mCacheServiceLock held !!!
nsresult rv; nsresult rv;
nsCacheEntry * entry = nsnull; nsCacheEntry * entry = nsnull;
nsCacheAccessMode accessGranted = nsICache::ACCESS_NONE; nsCacheAccessMode accessGranted = nsICache::ACCESS_NONE;
@ -928,10 +886,9 @@ nsCacheService::ProcessRequest(nsCacheRequest * request,
return rv; return rv;
if (request->IsBlocking()) { if (request->IsBlocking()) {
// XXX this is probably wrong... PR_Unlock(mCacheServiceLock);
Unlock();
rv = request->WaitForValidation(); rv = request->WaitForValidation();
Lock(); PR_Lock(mCacheServiceLock);
} }
PR_REMOVE_AND_INIT_LINK(request); PR_REMOVE_AND_INIT_LINK(request);
@ -947,10 +904,10 @@ nsCacheService::ProcessRequest(nsCacheRequest * request,
// loop back around to look for another entry // loop back around to look for another entry
} }
nsICacheEntryDescriptor *descriptor = nsnull; nsCOMPtr<nsICacheEntryDescriptor> descriptor;
if (NS_SUCCEEDED(rv)) if (NS_SUCCEEDED(rv))
rv = entry->CreateDescriptor(request, accessGranted, &descriptor); rv = entry->CreateDescriptor(request, accessGranted, getter_AddRefs(descriptor));
if (request->mListener) { // Asynchronous if (request->mListener) { // Asynchronous
@ -963,7 +920,7 @@ nsCacheService::ProcessRequest(nsCacheRequest * request,
rv = rv2; // trigger delete request rv = rv2; // trigger delete request
} }
} else { // Synchronous } else { // Synchronous
*result = descriptor; NS_IF_ADDREF(*result = descriptor);
} }
return rv; return rv;
} }
@ -983,7 +940,7 @@ nsCacheService::OpenCacheEntry(nsCacheSession * session,
nsCacheRequest * request = nsnull; nsCacheRequest * request = nsnull;
nsCacheServiceAutoLock lock; nsAutoLock lock(gService->mCacheServiceLock);
nsresult rv = gService->CreateRequest(session, nsresult rv = gService->CreateRequest(session,
key, key,
accessRequested, accessRequested,
@ -1201,7 +1158,7 @@ void
nsCacheService::OnProfileShutdown(PRBool cleanse) nsCacheService::OnProfileShutdown(PRBool cleanse)
{ {
if (!gService) return; if (!gService) return;
nsCacheServiceAutoLock lock; nsAutoLock lock(gService->mCacheServiceLock);
gService->DoomActiveEntries(); gService->DoomActiveEntries();
gService->ClearDoomList(); gService->ClearDoomList();
@ -1229,7 +1186,7 @@ nsCacheService::OnProfileChanged()
{ {
if (!gService) return; if (!gService) return;
nsCacheServiceAutoLock lock; nsAutoLock lock(gService->mCacheServiceLock);
gService->mEnableDiskDevice = gService->mObserver->DiskCacheEnabled(); gService->mEnableDiskDevice = gService->mObserver->DiskCacheEnabled();
gService->mEnableMemoryDevice = gService->mObserver->MemoryCacheEnabled(); gService->mEnableMemoryDevice = gService->mObserver->MemoryCacheEnabled();
@ -1267,7 +1224,7 @@ void
nsCacheService::SetDiskCacheEnabled(PRBool enabled) nsCacheService::SetDiskCacheEnabled(PRBool enabled)
{ {
if (!gService) return; if (!gService) return;
nsCacheServiceAutoLock lock; nsAutoLock lock(gService->mCacheServiceLock);
gService->mEnableDiskDevice = enabled; gService->mEnableDiskDevice = enabled;
} }
@ -1276,7 +1233,7 @@ void
nsCacheService::SetDiskCacheCapacity(PRInt32 capacity) nsCacheService::SetDiskCacheCapacity(PRInt32 capacity)
{ {
if (!gService) return; if (!gService) return;
nsCacheServiceAutoLock lock; nsAutoLock lock(gService->mCacheServiceLock);
#ifdef NECKO_DISK_CACHE #ifdef NECKO_DISK_CACHE
if (gService->mDiskDevice) { if (gService->mDiskDevice) {
@ -1292,7 +1249,7 @@ void
nsCacheService::SetMemoryCache() nsCacheService::SetMemoryCache()
{ {
if (!gService) return; if (!gService) return;
nsCacheServiceAutoLock lock; nsAutoLock lock(gService->mCacheServiceLock);
gService->mEnableMemoryDevice = gService->mObserver->MemoryCacheEnabled(); gService->mEnableMemoryDevice = gService->mObserver->MemoryCacheEnabled();
@ -1381,51 +1338,19 @@ nsCacheService::OnDataSizeChange(nsCacheEntry * entry, PRInt32 deltaSize)
return device->OnDataSizeChange(entry, deltaSize); return device->OnDataSizeChange(entry, deltaSize);
} }
void
nsCacheService::Lock() PRLock *
nsCacheService::ServiceLock()
{ {
PR_Lock(gService->mLock); NS_ASSERTION(gService, "nsCacheService::gService is null.");
return gService->mCacheServiceLock;
#if defined(DEBUG)
gService->mLockedThread = PR_GetCurrentThread();
#endif
}
void
nsCacheService::Unlock()
{
NS_ASSERTION(gService->mLockedThread == PR_GetCurrentThread(), "oops");
nsTArray<nsISupports*> doomed;
doomed.SwapElements(gService->mDoomedObjects);
#if defined(DEBUG)
gService->mLockedThread = nsnull;
#endif
PR_Unlock(gService->mLock);
for (PRUint32 i = 0; i < doomed.Length(); ++i)
doomed[i]->Release();
}
void
nsCacheService::ReleaseObject_Locked(nsISupports * obj,
nsIEventTarget * target)
{
NS_ASSERTION(gService->mLockedThread == PR_GetCurrentThread(), "oops");
PRBool isCur;
if (!target || NS_SUCCEEDED(target->IsOnCurrentThread(&isCur)) && isCur) {
gService->mDoomedObjects.AppendElement(obj);
} else {
NS_ProxyRelease(target, obj);
}
} }
nsresult nsresult
nsCacheService::SetCacheElement(nsCacheEntry * entry, nsISupports * element) nsCacheService::SetCacheElement(nsCacheEntry * entry, nsISupports * element)
{ {
entry->SetThread();
entry->SetData(element); entry->SetData(element);
entry->TouchData(); entry->TouchData();
return NS_OK; return NS_OK;
@ -1564,10 +1489,10 @@ nsCacheService::ProcessPendingRequests(nsCacheEntry * entry)
// XXX if (newWriter) NS_ASSERTION( accessGranted == request->AccessRequested(), "why not?"); // XXX if (newWriter) NS_ASSERTION( accessGranted == request->AccessRequested(), "why not?");
// entry->CreateDescriptor dequeues request, and queues descriptor // entry->CreateDescriptor dequeues request, and queues descriptor
nsICacheEntryDescriptor *descriptor = nsnull; nsCOMPtr<nsICacheEntryDescriptor> descriptor;
rv = entry->CreateDescriptor(request, rv = entry->CreateDescriptor(request,
accessGranted, accessGranted,
&descriptor); getter_AddRefs(descriptor));
// post call to listener to report error or descriptor // post call to listener to report error or descriptor
rv = NotifyListener(request, descriptor, accessGranted, rv); rv = NotifyListener(request, descriptor, accessGranted, rv);

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

@ -49,18 +49,15 @@
#include "nsCacheDevice.h" #include "nsCacheDevice.h"
#include "nsCacheEntry.h" #include "nsCacheEntry.h"
#include "prlock.h" #include "nspr.h"
#include "prthread.h"
#include "nsIObserver.h" #include "nsIObserver.h"
#include "nsString.h" #include "nsString.h"
#include "nsProxiedService.h" #include "nsProxiedService.h"
#include "nsTArray.h"
class nsCacheRequest; class nsCacheRequest;
class nsCacheProfilePrefObserver; class nsCacheProfilePrefObserver;
class nsDiskCacheDevice; class nsDiskCacheDevice;
class nsMemoryCacheDevice; class nsMemoryCacheDevice;
class nsCacheServiceAutoLock;
/****************************************************************************** /******************************************************************************
@ -117,6 +114,8 @@ public:
static nsresult OnDataSizeChange(nsCacheEntry * entry, PRInt32 deltaSize); static nsresult OnDataSizeChange(nsCacheEntry * entry, PRInt32 deltaSize);
static PRLock * ServiceLock();
static nsresult SetCacheElement(nsCacheEntry * entry, nsISupports * element); static nsresult SetCacheElement(nsCacheEntry * entry, nsISupports * element);
static nsresult ValidateEntry(nsCacheEntry * entry); static nsresult ValidateEntry(nsCacheEntry * entry);
@ -133,14 +132,6 @@ public:
static PRBool IsStorageEnabledForPolicy_Locked(nsCacheStoragePolicy policy); static PRBool IsStorageEnabledForPolicy_Locked(nsCacheStoragePolicy policy);
// This method may be called to release an object while the cache service
// lock is being held. If a non-null target is specified and the target
// does not correspond to the current thread, then the release will be
// proxied to the specified target. Otherwise, the object will be added to
// the list of objects to be released when the cache service is unlocked.
static void ReleaseObject_Locked(nsISupports * object,
nsIEventTarget * target = nsnull);
/** /**
* Methods called by nsCacheProfilePrefObserver * Methods called by nsCacheProfilePrefObserver
*/ */
@ -155,15 +146,11 @@ public:
nsresult Init(); nsresult Init();
void Shutdown(); void Shutdown();
private: private:
friend class nsCacheServiceAutoLock;
/** /**
* Internal Methods * Internal Methods
*/ */
static void Lock();
static void Unlock();
nsresult CreateDiskDevice(); nsresult CreateDiskDevice();
nsresult CreateMemoryDevice(); nsresult CreateMemoryDevice();
@ -179,9 +166,6 @@ private:
nsresult EvictEntriesForClient(const char * clientID, nsresult EvictEntriesForClient(const char * clientID,
nsCacheStoragePolicy storagePolicy); nsCacheStoragePolicy storagePolicy);
// Notifies request listener asynchronously on the request's thread, and
// releases the descriptor on the request's thread. If this method fails,
// the descriptor is not released.
nsresult NotifyListener(nsCacheRequest * request, nsresult NotifyListener(nsCacheRequest * request,
nsICacheEntryDescriptor * descriptor, nsICacheEntryDescriptor * descriptor,
nsCacheAccessMode accessGranted, nsCacheAccessMode accessGranted,
@ -228,13 +212,7 @@ private:
nsCacheProfilePrefObserver * mObserver; nsCacheProfilePrefObserver * mObserver;
PRLock * mLock; PRLock * mCacheServiceLock;
#if defined(DEBUG)
PRThread * mLockedThread; // The thread holding mLock
#endif
nsTArray<nsISupports*> mDoomedObjects;
PRBool mInitialized; PRBool mInitialized;
@ -261,20 +239,5 @@ private:
PRUint32 mDeactivatedUnboundEntries; PRUint32 mDeactivatedUnboundEntries;
}; };
/******************************************************************************
* nsCacheServiceAutoLock
******************************************************************************/
// Instantiate this class to acquire the cache service lock for a particular
// execution scope.
class nsCacheServiceAutoLock {
public:
nsCacheServiceAutoLock() {
nsCacheService::Lock();
}
~nsCacheServiceAutoLock() {
nsCacheService::Unlock();
}
};
#endif // _nsCacheService_h_ #endif // _nsCacheService_h_

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

@ -44,6 +44,8 @@
#include "nsDiskCacheStreams.h" #include "nsDiskCacheStreams.h"
#include "nsCacheService.h" #include "nsCacheService.h"
#include "nsAutoLock.h"
// Assumptions: // Assumptions:
@ -441,7 +443,7 @@ nsDiskCacheStreamIO::ClearBinding()
nsresult nsresult
nsDiskCacheStreamIO::CloseOutputStream(nsDiskCacheOutputStream * outputStream) nsDiskCacheStreamIO::CloseOutputStream(nsDiskCacheOutputStream * outputStream)
{ {
nsCacheServiceAutoLock lock; // grab service lock nsAutoLock lock(nsCacheService::ServiceLock()); // grab service lock
nsresult rv; nsresult rv;
if (outputStream != mOutStream) { if (outputStream != mOutStream) {
@ -558,7 +560,7 @@ nsDiskCacheStreamIO::Write( const char * buffer,
PRUint32 * bytesWritten) PRUint32 * bytesWritten)
{ {
nsresult rv = NS_OK; nsresult rv = NS_OK;
nsCacheServiceAutoLock lock; // grab service lock nsAutoLock lock(nsCacheService::ServiceLock()); // grab service lock
if (!mBinding) return NS_ERROR_NOT_AVAILABLE; if (!mBinding) return NS_ERROR_NOT_AVAILABLE;
if (mInStreamCount) { if (mInStreamCount) {

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

@ -500,14 +500,6 @@ class nsTArray : public nsTArray_base {
return RemoveElement(item, nsDefaultComparator<elem_type, Item>()); return RemoveElement(item, nsDefaultComparator<elem_type, Item>());
} }
// This method causes the elements contained in this array and the given
// array to be swapped.
void SwapElements(self_type& other) {
Header *h = other.mHdr;
other.mHdr = mHdr;
mHdr = h;
}
// //
// Allocation // Allocation
// //