diff --git a/netwerk/cache/src/nsCacheEntry.cpp b/netwerk/cache/src/nsCacheEntry.cpp index cb1754847d17..f1f1cad8fb87 100644 --- a/netwerk/cache/src/nsCacheEntry.cpp +++ b/netwerk/cache/src/nsCacheEntry.cpp @@ -45,6 +45,7 @@ #include "nsCacheMetaData.h" #include "nsCacheRequest.h" #include "nsThreadUtils.h" +#include "nsProxyRelease.h" #include "nsError.h" #include "nsICacheService.h" #include "nsCache.h" @@ -83,8 +84,14 @@ nsCacheEntry::~nsCacheEntry() if (IsStreamData()) return; - if (mData) - nsCacheService::ReleaseObject_Locked(mData, mThread); + // proxy release of of memory cache nsISupports objects + 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 -nsCacheEntry::SetData(nsISupports * data) +nsCacheEntry::SetThread() { - if (mData) - nsCacheService::ReleaseObject_Locked(mData, mThread); - - NS_ADDREF(mData = data); mThread = do_GetCurrentThread(); } diff --git a/netwerk/cache/src/nsCacheEntry.h b/netwerk/cache/src/nsCacheEntry.h index be42b5eb874d..9f8861860530 100644 --- a/netwerk/cache/src/nsCacheEntry.h +++ b/netwerk/cache/src/nsCacheEntry.h @@ -104,13 +104,15 @@ public: * Data accessors */ nsISupports *Data() { return mData; } - void SetData( nsISupports * data); + void SetData( nsISupports * data) { mData = data; } PRUint32 DataSize() { return mDataSize; } void SetDataSize( PRUint32 size) { mDataSize = size; } void TouchData(); + void SetThread(); + /** * Meta data accessors */ @@ -239,7 +241,7 @@ private: PRUint32 mDataSize; // 4 nsCacheDevice * mCacheDevice; // 4 nsCOMPtr mSecurityInfo; // - nsISupports * mData; // strong ref + nsCOMPtr mData; // nsCOMPtr mThread; nsCacheMetaData mMetaData; // 4 PRCList mRequestQ; // 8 diff --git a/netwerk/cache/src/nsCacheEntryDescriptor.cpp b/netwerk/cache/src/nsCacheEntryDescriptor.cpp index a951bd60f41f..e6a691a6f060 100644 --- a/netwerk/cache/src/nsCacheEntryDescriptor.cpp +++ b/netwerk/cache/src/nsCacheEntryDescriptor.cpp @@ -46,6 +46,7 @@ #include "nsReadableUtils.h" #include "nsIOutputStream.h" #include "nsCRT.h" +#include "nsAutoLock.h" NS_IMPL_THREADSAFE_ISUPPORTS2(nsCacheEntryDescriptor, nsICacheEntryDescriptor, @@ -80,8 +81,7 @@ NS_IMETHODIMP nsCacheEntryDescriptor::GetClientID(char ** result) { NS_ENSURE_ARG_POINTER(result); - - nsCacheServiceAutoLock lock; + nsAutoLock lock(nsCacheService::ServiceLock()); if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; return ClientIDFromCacheKey(*(mCacheEntry->Key()), result); @@ -92,7 +92,7 @@ NS_IMETHODIMP nsCacheEntryDescriptor::GetDeviceID(char ** result) { NS_ENSURE_ARG_POINTER(result); - nsCacheServiceAutoLock lock; + nsAutoLock lock(nsCacheService::ServiceLock()); if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; *result = nsCRT::strdup(mCacheEntry->GetDeviceID()); @@ -103,7 +103,7 @@ nsCacheEntryDescriptor::GetDeviceID(char ** result) NS_IMETHODIMP nsCacheEntryDescriptor::GetKey(nsACString &result) { - nsCacheServiceAutoLock lock; + nsAutoLock lock(nsCacheService::ServiceLock()); if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; return ClientKeyFromCacheKey(*(mCacheEntry->Key()), result); @@ -114,7 +114,7 @@ NS_IMETHODIMP nsCacheEntryDescriptor::GetFetchCount(PRInt32 *result) { NS_ENSURE_ARG_POINTER(result); - nsCacheServiceAutoLock lock; + nsAutoLock lock(nsCacheService::ServiceLock()); if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; *result = mCacheEntry->FetchCount(); @@ -126,7 +126,7 @@ NS_IMETHODIMP nsCacheEntryDescriptor::GetLastFetched(PRUint32 *result) { NS_ENSURE_ARG_POINTER(result); - nsCacheServiceAutoLock lock; + nsAutoLock lock(nsCacheService::ServiceLock()); if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; *result = mCacheEntry->LastFetched(); @@ -138,7 +138,7 @@ NS_IMETHODIMP nsCacheEntryDescriptor::GetLastModified(PRUint32 *result) { NS_ENSURE_ARG_POINTER(result); - nsCacheServiceAutoLock lock; + nsAutoLock lock(nsCacheService::ServiceLock()); if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; *result = mCacheEntry->LastModified(); @@ -150,7 +150,7 @@ NS_IMETHODIMP nsCacheEntryDescriptor::GetExpirationTime(PRUint32 *result) { NS_ENSURE_ARG_POINTER(result); - nsCacheServiceAutoLock lock; + nsAutoLock lock(nsCacheService::ServiceLock()); if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; *result = mCacheEntry->ExpirationTime(); @@ -161,7 +161,7 @@ nsCacheEntryDescriptor::GetExpirationTime(PRUint32 *result) NS_IMETHODIMP nsCacheEntryDescriptor::SetExpirationTime(PRUint32 expirationTime) { - nsCacheServiceAutoLock lock; + nsAutoLock lock(nsCacheService::ServiceLock()); if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; mCacheEntry->SetExpirationTime(expirationTime); @@ -173,7 +173,7 @@ nsCacheEntryDescriptor::SetExpirationTime(PRUint32 expirationTime) NS_IMETHODIMP nsCacheEntryDescriptor::IsStreamBased(PRBool *result) { NS_ENSURE_ARG_POINTER(result); - nsCacheServiceAutoLock lock; + nsAutoLock lock(nsCacheService::ServiceLock()); if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; *result = mCacheEntry->IsStreamData(); @@ -184,7 +184,7 @@ NS_IMETHODIMP nsCacheEntryDescriptor::IsStreamBased(PRBool *result) NS_IMETHODIMP nsCacheEntryDescriptor::GetDataSize(PRUint32 *result) { NS_ENSURE_ARG_POINTER(result); - nsCacheServiceAutoLock lock; + nsAutoLock lock(nsCacheService::ServiceLock()); if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; *result = mCacheEntry->DataSize(); @@ -195,7 +195,7 @@ NS_IMETHODIMP nsCacheEntryDescriptor::GetDataSize(PRUint32 *result) nsresult nsCacheEntryDescriptor::RequestDataSizeChange(PRInt32 deltaSize) { - nsCacheServiceAutoLock lock; + nsAutoLock lock(nsCacheService::ServiceLock()); if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; nsresult rv; @@ -213,7 +213,7 @@ nsCacheEntryDescriptor::RequestDataSizeChange(PRInt32 deltaSize) NS_IMETHODIMP nsCacheEntryDescriptor::SetDataSize(PRUint32 dataSize) { - nsCacheServiceAutoLock lock; + nsAutoLock lock(nsCacheService::ServiceLock()); if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; // XXX review for signed/unsigned math errors @@ -241,7 +241,7 @@ nsCacheEntryDescriptor::OpenInputStream(PRUint32 offset, nsIInputStream ** resul NS_ENSURE_ARG_POINTER(result); { - nsCacheServiceAutoLock lock; + nsAutoLock lock(nsCacheService::ServiceLock()); if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; 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); { - nsCacheServiceAutoLock lock; + nsAutoLock lock(nsCacheService::ServiceLock()); if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; if (!mCacheEntry->IsStreamData()) return NS_ERROR_CACHE_DATA_IS_NOT_STREAM; @@ -286,7 +286,7 @@ NS_IMETHODIMP nsCacheEntryDescriptor::GetCacheElement(nsISupports ** result) { NS_ENSURE_ARG_POINTER(result); - nsCacheServiceAutoLock lock; + nsAutoLock lock(nsCacheService::ServiceLock()); if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; if (mCacheEntry->IsStreamData()) return NS_ERROR_CACHE_DATA_IS_STREAM; @@ -298,7 +298,7 @@ nsCacheEntryDescriptor::GetCacheElement(nsISupports ** result) NS_IMETHODIMP nsCacheEntryDescriptor::SetCacheElement(nsISupports * cacheElement) { - nsCacheServiceAutoLock lock; + nsAutoLock lock(nsCacheService::ServiceLock()); if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; if (mCacheEntry->IsStreamData()) return NS_ERROR_CACHE_DATA_IS_STREAM; @@ -319,7 +319,7 @@ NS_IMETHODIMP nsCacheEntryDescriptor::GetStoragePolicy(nsCacheStoragePolicy *result) { NS_ENSURE_ARG_POINTER(result); - nsCacheServiceAutoLock lock; + nsAutoLock lock(nsCacheService::ServiceLock()); if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; return mCacheEntry->StoragePolicy(); @@ -329,7 +329,7 @@ nsCacheEntryDescriptor::GetStoragePolicy(nsCacheStoragePolicy *result) NS_IMETHODIMP nsCacheEntryDescriptor::SetStoragePolicy(nsCacheStoragePolicy policy) { - nsCacheServiceAutoLock lock; + nsAutoLock lock(nsCacheService::ServiceLock()); if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; // XXX validate policy against session? @@ -347,7 +347,7 @@ NS_IMETHODIMP nsCacheEntryDescriptor::GetFile(nsIFile ** result) { NS_ENSURE_ARG_POINTER(result); - nsCacheServiceAutoLock lock; + nsAutoLock lock(nsCacheService::ServiceLock()); if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; return nsCacheService::GetFileForEntry(mCacheEntry, result); @@ -358,7 +358,7 @@ NS_IMETHODIMP nsCacheEntryDescriptor::GetSecurityInfo(nsISupports ** result) { NS_ENSURE_ARG_POINTER(result); - nsCacheServiceAutoLock lock; + nsAutoLock lock(nsCacheService::ServiceLock()); if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; return mCacheEntry->GetSecurityInfo(result); @@ -368,7 +368,7 @@ nsCacheEntryDescriptor::GetSecurityInfo(nsISupports ** result) NS_IMETHODIMP nsCacheEntryDescriptor::SetSecurityInfo(nsISupports * securityInfo) { - nsCacheServiceAutoLock lock; + nsAutoLock lock(nsCacheService::ServiceLock()); if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; mCacheEntry->SetSecurityInfo(securityInfo); @@ -380,7 +380,7 @@ nsCacheEntryDescriptor::SetSecurityInfo(nsISupports * securityInfo) NS_IMETHODIMP nsCacheEntryDescriptor::Doom() { - nsCacheServiceAutoLock lock; + nsAutoLock lock(nsCacheService::ServiceLock()); if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; return nsCacheService::DoomEntry(mCacheEntry); @@ -390,7 +390,7 @@ nsCacheEntryDescriptor::Doom() NS_IMETHODIMP nsCacheEntryDescriptor::DoomAndFailPendingRequests(nsresult status) { - nsCacheServiceAutoLock lock; + nsAutoLock lock(nsCacheService::ServiceLock()); if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; return NS_ERROR_NOT_IMPLEMENTED; @@ -400,7 +400,7 @@ nsCacheEntryDescriptor::DoomAndFailPendingRequests(nsresult status) NS_IMETHODIMP nsCacheEntryDescriptor::MarkValid() { - nsCacheServiceAutoLock lock; + nsAutoLock lock(nsCacheService::ServiceLock()); if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; nsresult rv = nsCacheService::ValidateEntry(mCacheEntry); @@ -411,7 +411,7 @@ nsCacheEntryDescriptor::MarkValid() NS_IMETHODIMP nsCacheEntryDescriptor::Close() { - nsCacheServiceAutoLock lock; + nsAutoLock lock(nsCacheService::ServiceLock()); if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; // XXX perhaps closing descriptors should clear/sever transports @@ -430,7 +430,7 @@ nsCacheEntryDescriptor::GetMetaDataElement(const char *key, char **result) NS_ENSURE_ARG_POINTER(key); *result = nsnull; - nsCacheServiceAutoLock lock; + nsAutoLock lock(nsCacheService::ServiceLock()); NS_ENSURE_TRUE(mCacheEntry, NS_ERROR_NOT_AVAILABLE); const char *value; @@ -450,7 +450,7 @@ nsCacheEntryDescriptor::SetMetaDataElement(const char *key, const char *value) { NS_ENSURE_ARG_POINTER(key); - nsCacheServiceAutoLock lock; + nsAutoLock lock(nsCacheService::ServiceLock()); NS_ENSURE_TRUE(mCacheEntry, NS_ERROR_NOT_AVAILABLE); // XXX allow null value, for clearing key? @@ -465,7 +465,7 @@ nsCacheEntryDescriptor::SetMetaDataElement(const char *key, const char *value) NS_IMETHODIMP 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); if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; @@ -484,7 +484,7 @@ NS_IMPL_THREADSAFE_ISUPPORTS1(nsCacheEntryDescriptor::nsInputStreamWrapper, nsresult nsCacheEntryDescriptor:: nsInputStreamWrapper::LazyInit() { - nsCacheServiceAutoLock lock; + nsAutoLock lock(nsCacheService::ServiceLock()); nsCacheAccessMode mode; nsresult rv = mDescriptor->GetAccessGranted(&mode); @@ -561,7 +561,7 @@ NS_IMPL_THREADSAFE_ISUPPORTS1(nsCacheEntryDescriptor::nsOutputStreamWrapper, nsresult nsCacheEntryDescriptor:: nsOutputStreamWrapper::LazyInit() { - nsCacheServiceAutoLock lock; + nsAutoLock lock(nsCacheService::ServiceLock()); nsCacheAccessMode mode; nsresult rv = mDescriptor->GetAccessGranted(&mode); diff --git a/netwerk/cache/src/nsCacheRequest.h b/netwerk/cache/src/nsCacheRequest.h index 899c16dcede1..68d6fc336c4d 100644 --- a/netwerk/cache/src/nsCacheRequest.h +++ b/netwerk/cache/src/nsCacheRequest.h @@ -46,7 +46,6 @@ #include "nsICache.h" #include "nsICacheListener.h" #include "nsCacheSession.h" -#include "nsCacheService.h" class nsCacheRequest : public PRCList @@ -74,7 +73,6 @@ private: if (session->WillDoomEntriesIfExpired()) MarkDoomEntriesIfExpired(); if (blockingMode == nsICache::BLOCKING) MarkBlockingMode(); MarkWaitingForValidation(); - NS_IF_ADDREF(mListener); } ~nsCacheRequest() @@ -84,9 +82,6 @@ private: if (mLock) PR_DestroyLock(mLock); if (mCondVar) PR_DestroyCondVar(mCondVar); 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; PRUint32 mInfo; - nsICacheListener * mListener; // strong ref + nsCOMPtr mListener; nsCOMPtr mThread; PRLock * mLock; PRCondVar * mCondVar; diff --git a/netwerk/cache/src/nsCacheService.cpp b/netwerk/cache/src/nsCacheService.cpp index b23f4654160d..4508d35070ec 100644 --- a/netwerk/cache/src/nsCacheService.cpp +++ b/netwerk/cache/src/nsCacheService.cpp @@ -55,6 +55,7 @@ #include "nsDiskCacheDevice.h" #endif +#include "nsAutoLock.h" #include "nsIObserverService.h" #include "nsIPrefService.h" #include "nsIPrefBranch.h" @@ -63,7 +64,6 @@ #include "nsDirectoryServiceDefs.h" #include "nsAppDirectoryServiceDefs.h" #include "nsThreadUtils.h" -#include "nsProxyRelease.h" #include "nsVoidArray.h" #include "nsDeleteDir.h" #include // for log() @@ -466,7 +466,7 @@ nsCacheService * nsCacheService::gService = nsnull; NS_IMPL_THREADSAFE_ISUPPORTS1(nsCacheService, nsICacheService) nsCacheService::nsCacheService() - : mLock(nsnull), + : mCacheServiceLock(nsnull), mInitialized(PR_FALSE), mEnableMemoryDevice(PR_TRUE), mEnableDiskDevice(PR_TRUE), @@ -488,11 +488,7 @@ nsCacheService::nsCacheService() PR_INIT_CLIST(&mDoomedEntries); // allocate service lock - mLock = PR_NewLock(); - -#if defined(DEBUG) - mLockedThread = nsnull; -#endif + mCacheServiceLock = PR_NewLock(); } nsCacheService::~nsCacheService() @@ -500,7 +496,7 @@ nsCacheService::~nsCacheService() if (mInitialized) // Shutdown hasn't been called yet. (void) Shutdown(); - PR_DestroyLock(mLock); + PR_DestroyLock(mCacheServiceLock); gService = nsnull; } @@ -512,7 +508,7 @@ nsCacheService::Init() if (mInitialized) return NS_ERROR_ALREADY_INITIALIZED; - if (mLock == nsnull) + if (mCacheServiceLock == nsnull) return NS_ERROR_OUT_OF_MEMORY; CACHE_LOG_INIT(); @@ -538,7 +534,7 @@ nsCacheService::Init() void nsCacheService::Shutdown() { - nsCacheServiceAutoLock lock; + nsAutoLock lock(mCacheServiceLock); NS_ASSERTION(mInitialized, "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; #ifdef NECKO_DISK_CACHE @@ -681,7 +677,7 @@ nsCacheService::IsStorageEnabledForPolicy(nsCacheStoragePolicy storagePolicy, PRBool * result) { if (gService == nsnull) return NS_ERROR_NOT_AVAILABLE; - nsCacheServiceAutoLock lock; + nsAutoLock lock(gService->mCacheServiceLock); *result = gService->IsStorageEnabledForPolicy_Locked(storagePolicy); return NS_OK; @@ -711,7 +707,7 @@ NS_IMETHODIMP nsCacheService::VisitEntries(nsICacheVisitor *visitor) { NS_ENSURE_ARG_POINTER(visitor); - nsCacheServiceAutoLock lock; + nsAutoLock lock(mCacheServiceLock); if (!(mEnableDiskDevice || mEnableMemoryDevice)) 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 nsCacheService::NotifyListener(nsCacheRequest * request, nsICacheEntryDescriptor * descriptor, nsCacheAccessMode accessGranted, - nsresult status) + nsresult error) { + nsresult rv; + + nsCOMPtr listenerProxy; NS_ASSERTION(request->mThread, "no thread set in async request!"); - // Swap ownership, and release listener on target thread... - nsICacheListener *listener = request->mListener; - request->mListener = nsnull; + rv = NS_GetProxyForObject(request->mThread, + NS_GET_IID(nsICacheListener), + request->mListener, + NS_PROXY_ASYNC | NS_PROXY_ALWAYS, + getter_AddRefs(listenerProxy)); + if (NS_FAILED(rv)) return rv; - nsCOMPtr ev = - 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); + return listenerProxy->OnCacheEntryAvailable(descriptor, accessGranted, error); } @@ -908,7 +866,7 @@ nsCacheService::ProcessRequest(nsCacheRequest * request, PRBool calledFromOpenCacheEntry, nsICacheEntryDescriptor ** result) { - // !!! must be called with mLock held !!! + // !!! must be called with mCacheServiceLock held !!! nsresult rv; nsCacheEntry * entry = nsnull; nsCacheAccessMode accessGranted = nsICache::ACCESS_NONE; @@ -928,10 +886,9 @@ nsCacheService::ProcessRequest(nsCacheRequest * request, return rv; if (request->IsBlocking()) { - // XXX this is probably wrong... - Unlock(); + PR_Unlock(mCacheServiceLock); rv = request->WaitForValidation(); - Lock(); + PR_Lock(mCacheServiceLock); } PR_REMOVE_AND_INIT_LINK(request); @@ -947,10 +904,10 @@ nsCacheService::ProcessRequest(nsCacheRequest * request, // loop back around to look for another entry } - nsICacheEntryDescriptor *descriptor = nsnull; + nsCOMPtr descriptor; if (NS_SUCCEEDED(rv)) - rv = entry->CreateDescriptor(request, accessGranted, &descriptor); + rv = entry->CreateDescriptor(request, accessGranted, getter_AddRefs(descriptor)); if (request->mListener) { // Asynchronous @@ -963,7 +920,7 @@ nsCacheService::ProcessRequest(nsCacheRequest * request, rv = rv2; // trigger delete request } } else { // Synchronous - *result = descriptor; + NS_IF_ADDREF(*result = descriptor); } return rv; } @@ -983,7 +940,7 @@ nsCacheService::OpenCacheEntry(nsCacheSession * session, nsCacheRequest * request = nsnull; - nsCacheServiceAutoLock lock; + nsAutoLock lock(gService->mCacheServiceLock); nsresult rv = gService->CreateRequest(session, key, accessRequested, @@ -1201,7 +1158,7 @@ void nsCacheService::OnProfileShutdown(PRBool cleanse) { if (!gService) return; - nsCacheServiceAutoLock lock; + nsAutoLock lock(gService->mCacheServiceLock); gService->DoomActiveEntries(); gService->ClearDoomList(); @@ -1229,7 +1186,7 @@ nsCacheService::OnProfileChanged() { if (!gService) return; - nsCacheServiceAutoLock lock; + nsAutoLock lock(gService->mCacheServiceLock); gService->mEnableDiskDevice = gService->mObserver->DiskCacheEnabled(); gService->mEnableMemoryDevice = gService->mObserver->MemoryCacheEnabled(); @@ -1267,7 +1224,7 @@ void nsCacheService::SetDiskCacheEnabled(PRBool enabled) { if (!gService) return; - nsCacheServiceAutoLock lock; + nsAutoLock lock(gService->mCacheServiceLock); gService->mEnableDiskDevice = enabled; } @@ -1276,7 +1233,7 @@ void nsCacheService::SetDiskCacheCapacity(PRInt32 capacity) { if (!gService) return; - nsCacheServiceAutoLock lock; + nsAutoLock lock(gService->mCacheServiceLock); #ifdef NECKO_DISK_CACHE if (gService->mDiskDevice) { @@ -1292,7 +1249,7 @@ void nsCacheService::SetMemoryCache() { if (!gService) return; - nsCacheServiceAutoLock lock; + nsAutoLock lock(gService->mCacheServiceLock); gService->mEnableMemoryDevice = gService->mObserver->MemoryCacheEnabled(); @@ -1381,51 +1338,19 @@ nsCacheService::OnDataSizeChange(nsCacheEntry * entry, PRInt32 deltaSize) return device->OnDataSizeChange(entry, deltaSize); } -void -nsCacheService::Lock() + +PRLock * +nsCacheService::ServiceLock() { - PR_Lock(gService->mLock); - -#if defined(DEBUG) - gService->mLockedThread = PR_GetCurrentThread(); -#endif -} - -void -nsCacheService::Unlock() -{ - NS_ASSERTION(gService->mLockedThread == PR_GetCurrentThread(), "oops"); - - nsTArray 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); - } + NS_ASSERTION(gService, "nsCacheService::gService is null."); + return gService->mCacheServiceLock; } nsresult nsCacheService::SetCacheElement(nsCacheEntry * entry, nsISupports * element) { + entry->SetThread(); entry->SetData(element); entry->TouchData(); return NS_OK; @@ -1564,10 +1489,10 @@ nsCacheService::ProcessPendingRequests(nsCacheEntry * entry) // XXX if (newWriter) NS_ASSERTION( accessGranted == request->AccessRequested(), "why not?"); // entry->CreateDescriptor dequeues request, and queues descriptor - nsICacheEntryDescriptor *descriptor = nsnull; + nsCOMPtr descriptor; rv = entry->CreateDescriptor(request, accessGranted, - &descriptor); + getter_AddRefs(descriptor)); // post call to listener to report error or descriptor rv = NotifyListener(request, descriptor, accessGranted, rv); diff --git a/netwerk/cache/src/nsCacheService.h b/netwerk/cache/src/nsCacheService.h index 72797881572a..c1eff46f3413 100644 --- a/netwerk/cache/src/nsCacheService.h +++ b/netwerk/cache/src/nsCacheService.h @@ -49,18 +49,15 @@ #include "nsCacheDevice.h" #include "nsCacheEntry.h" -#include "prlock.h" -#include "prthread.h" +#include "nspr.h" #include "nsIObserver.h" #include "nsString.h" #include "nsProxiedService.h" -#include "nsTArray.h" class nsCacheRequest; class nsCacheProfilePrefObserver; class nsDiskCacheDevice; class nsMemoryCacheDevice; -class nsCacheServiceAutoLock; /****************************************************************************** @@ -117,6 +114,8 @@ public: static nsresult OnDataSizeChange(nsCacheEntry * entry, PRInt32 deltaSize); + static PRLock * ServiceLock(); + static nsresult SetCacheElement(nsCacheEntry * entry, nsISupports * element); static nsresult ValidateEntry(nsCacheEntry * entry); @@ -133,14 +132,6 @@ public: 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 */ @@ -155,15 +146,11 @@ public: nsresult Init(); void Shutdown(); private: - friend class nsCacheServiceAutoLock; /** * Internal Methods */ - static void Lock(); - static void Unlock(); - nsresult CreateDiskDevice(); nsresult CreateMemoryDevice(); @@ -179,9 +166,6 @@ private: nsresult EvictEntriesForClient(const char * clientID, 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, nsICacheEntryDescriptor * descriptor, nsCacheAccessMode accessGranted, @@ -228,13 +212,7 @@ private: nsCacheProfilePrefObserver * mObserver; - PRLock * mLock; - -#if defined(DEBUG) - PRThread * mLockedThread; // The thread holding mLock -#endif - - nsTArray mDoomedObjects; + PRLock * mCacheServiceLock; PRBool mInitialized; @@ -261,20 +239,5 @@ private: 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_ diff --git a/netwerk/cache/src/nsDiskCacheStreams.cpp b/netwerk/cache/src/nsDiskCacheStreams.cpp index f5f11a94be07..fe3d91bf87ff 100644 --- a/netwerk/cache/src/nsDiskCacheStreams.cpp +++ b/netwerk/cache/src/nsDiskCacheStreams.cpp @@ -44,6 +44,8 @@ #include "nsDiskCacheStreams.h" #include "nsCacheService.h" +#include "nsAutoLock.h" + // Assumptions: @@ -441,7 +443,7 @@ nsDiskCacheStreamIO::ClearBinding() nsresult nsDiskCacheStreamIO::CloseOutputStream(nsDiskCacheOutputStream * outputStream) { - nsCacheServiceAutoLock lock; // grab service lock + nsAutoLock lock(nsCacheService::ServiceLock()); // grab service lock nsresult rv; if (outputStream != mOutStream) { @@ -558,7 +560,7 @@ nsDiskCacheStreamIO::Write( const char * buffer, PRUint32 * bytesWritten) { nsresult rv = NS_OK; - nsCacheServiceAutoLock lock; // grab service lock + nsAutoLock lock(nsCacheService::ServiceLock()); // grab service lock if (!mBinding) return NS_ERROR_NOT_AVAILABLE; if (mInStreamCount) { diff --git a/xpcom/glue/nsTArray.h b/xpcom/glue/nsTArray.h index ac334bfb417e..1c67f55fd834 100644 --- a/xpcom/glue/nsTArray.h +++ b/xpcom/glue/nsTArray.h @@ -500,14 +500,6 @@ class nsTArray : public nsTArray_base { return RemoveElement(item, nsDefaultComparator()); } - // 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 //