зеркало из https://github.com/mozilla/gecko-dev.git
fixes bug 163841 "Mozilla hangs in PR_Lock at ptsynch.c:190" r=dougt sr=rpotts
This commit is contained in:
Родитель
32844f7719
Коммит
30b3e1cdfa
|
@ -118,38 +118,3 @@ ClientKeyFromCacheKey(const nsACString& key, char ** result)
|
|||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS0(nsCacheLock);
|
||||
|
||||
|
||||
nsCacheLock::nsCacheLock()
|
||||
: mLock(nsnull)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
}
|
||||
|
||||
|
||||
nsCacheLock::~nsCacheLock()
|
||||
{
|
||||
if (!mLock) return;
|
||||
|
||||
PR_DestroyLock(mLock);
|
||||
}
|
||||
|
||||
|
||||
nsCacheLock *
|
||||
nsCacheLock::Create()
|
||||
{
|
||||
nsCacheLock * cacheLock = new nsCacheLock;
|
||||
if (!cacheLock) return nsnull;
|
||||
cacheLock->mLock = PR_NewLock();
|
||||
if (!cacheLock->mLock) {
|
||||
delete cacheLock;
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
NS_ADDREF(cacheLock);
|
||||
return cacheLock;
|
||||
}
|
||||
|
|
|
@ -62,21 +62,4 @@ extern nsresult ClientIDFromCacheKey(const nsACString& key, char ** result);
|
|||
extern nsresult ClientKeyFromCacheKey(const nsACString& key, char ** result);
|
||||
|
||||
|
||||
class nsCacheLock : public nsISupports {
|
||||
public:
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISUPPORTS_IID)
|
||||
|
||||
nsCacheLock();
|
||||
virtual ~nsCacheLock();
|
||||
|
||||
static nsCacheLock * Create();
|
||||
PRLock * GetPRLock() { return mLock; }
|
||||
|
||||
private:
|
||||
PRLock * mLock;
|
||||
};
|
||||
|
||||
|
||||
#endif // _nsCache_h
|
||||
|
|
|
@ -319,9 +319,9 @@ static nsCOMPtr<nsIFileTransportService> gFileTransportService;
|
|||
#endif
|
||||
|
||||
nsDiskCacheDevice::nsDiskCacheDevice()
|
||||
: mDeviceLock(nsnull)
|
||||
, mCacheCapacity(0)
|
||||
: mCacheCapacity(0)
|
||||
, mCacheMap(nsnull)
|
||||
, mInitialized(PR_FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -370,13 +370,7 @@ nsDiskCacheDevice::Init()
|
|||
if (NS_FAILED(rv)) goto error_exit;
|
||||
}
|
||||
|
||||
mDeviceLock = nsCacheLock::Create();
|
||||
if (mDeviceLock == nsnull) {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
goto error_exit;
|
||||
}
|
||||
// creation of lock indicates successful initialization
|
||||
|
||||
mInitialized = PR_TRUE;
|
||||
return NS_OK;
|
||||
|
||||
error_exit:
|
||||
|
@ -392,25 +386,24 @@ error_exit:
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* NOTE: called while holding the cache service lock
|
||||
*/
|
||||
nsresult
|
||||
nsDiskCacheDevice::Shutdown()
|
||||
{
|
||||
if (Initialized()) {
|
||||
{ // code block for nsAutoLock
|
||||
nsAutoLock lock(mDeviceLock->GetPRLock());
|
||||
// check cache limits in case we need to evict.
|
||||
EvictDiskCacheEntries((PRInt32)mCacheCapacity);
|
||||
// check cache limits in case we need to evict.
|
||||
EvictDiskCacheEntries((PRInt32)mCacheCapacity);
|
||||
|
||||
// write out persistent information about the cache.
|
||||
(void) mCacheMap->Close();
|
||||
delete mCacheMap;
|
||||
mCacheMap = nsnull;
|
||||
// write out persistent information about the cache.
|
||||
(void) mCacheMap->Close();
|
||||
delete mCacheMap;
|
||||
mCacheMap = nsnull;
|
||||
|
||||
mBindery.Reset();
|
||||
}
|
||||
mBindery.Reset();
|
||||
|
||||
// no longer initialized.
|
||||
mDeviceLock = nsnull;
|
||||
mInitialized = PR_FALSE;
|
||||
}
|
||||
|
||||
// release the reference to the cached file transport service.
|
||||
|
@ -449,6 +442,8 @@ nsDiskCacheDevice::GetDeviceID()
|
|||
* cases: key not in disk cache, hash number free
|
||||
* key not in disk cache, hash number used
|
||||
* key in disk cache
|
||||
*
|
||||
* NOTE: called while holding the cache service lock
|
||||
*/
|
||||
nsCacheEntry *
|
||||
nsDiskCacheDevice::FindEntry(nsCString * key)
|
||||
|
@ -459,8 +454,6 @@ nsDiskCacheDevice::FindEntry(nsCString * key)
|
|||
nsDiskCacheBinding * binding = nsnull;
|
||||
PLDHashNumber hashNumber = nsDiskCache::Hash(key->get());
|
||||
|
||||
nsAutoLock lock(mDeviceLock->GetPRLock()); // grab device lock
|
||||
|
||||
#if DEBUG /*because we shouldn't be called for active entries */
|
||||
binding = mBindery.FindActiveBinding(hashNumber);
|
||||
NS_ASSERTION(!binding, "### FindEntry() called for a bound entry.");
|
||||
|
@ -494,11 +487,12 @@ nsDiskCacheDevice::FindEntry(nsCString * key)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* NOTE: called while holding the cache service lock
|
||||
*/
|
||||
nsresult
|
||||
nsDiskCacheDevice::DeactivateEntry(nsCacheEntry * entry)
|
||||
{
|
||||
nsAutoLock lock(mDeviceLock->GetPRLock()); // grab device lock
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
nsDiskCacheBinding * binding = GetCacheEntryBinding(entry);
|
||||
NS_ASSERTION(binding, "DeactivateEntry: binding == nsnull");
|
||||
|
@ -536,13 +530,14 @@ nsDiskCacheDevice::DeactivateEntry(nsCacheEntry * entry)
|
|||
* walk matching hashnumber list to find lowest generation number
|
||||
* take generation number from other (data/meta) location,
|
||||
* or walk active list
|
||||
*
|
||||
* NOTE: called while holding the cache service lock
|
||||
*/
|
||||
nsresult
|
||||
nsDiskCacheDevice::BindEntry(nsCacheEntry * entry)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsDiskCacheRecord record, oldRecord;
|
||||
nsAutoLock lock(mDeviceLock->GetPRLock()); // grab device lock
|
||||
|
||||
// create a new record for this entry
|
||||
record.SetHashNumber(nsDiskCache::Hash(entry->Key()->get()));
|
||||
|
@ -584,10 +579,12 @@ nsDiskCacheDevice::BindEntry(nsCacheEntry * entry)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* NOTE: called while holding the cache service lock
|
||||
*/
|
||||
void
|
||||
nsDiskCacheDevice::DoomEntry(nsCacheEntry * entry)
|
||||
{
|
||||
nsAutoLock lock(mDeviceLock->GetPRLock()); // grab device lock
|
||||
nsDiskCacheBinding * binding = GetCacheEntryBinding(entry);
|
||||
NS_ASSERTION(binding, "DoomEntry: binding == nsnull");
|
||||
if (!binding) return;
|
||||
|
@ -601,6 +598,9 @@ nsDiskCacheDevice::DoomEntry(nsCacheEntry * entry)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* NOTE: called while holding the cache service lock
|
||||
*/
|
||||
nsresult
|
||||
nsDiskCacheDevice::GetTransportForEntry(nsCacheEntry * entry,
|
||||
nsCacheAccessMode mode,
|
||||
|
@ -609,7 +609,6 @@ nsDiskCacheDevice::GetTransportForEntry(nsCacheEntry * entry,
|
|||
NS_ENSURE_ARG_POINTER(entry);
|
||||
NS_ENSURE_ARG_POINTER(result);
|
||||
|
||||
nsAutoLock lock(mDeviceLock->GetPRLock()); // grab device lock
|
||||
nsresult rv;
|
||||
nsDiskCacheBinding * binding = GetCacheEntryBinding(entry);
|
||||
NS_ASSERTION(binding, "GetTransportForEntry: binding == nsnull");
|
||||
|
@ -628,6 +627,9 @@ nsDiskCacheDevice::GetTransportForEntry(nsCacheEntry * entry,
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* NOTE: called while holding the cache service lock
|
||||
*/
|
||||
nsresult
|
||||
nsDiskCacheDevice::GetFileForEntry(nsCacheEntry * entry,
|
||||
nsIFile ** result)
|
||||
|
@ -635,7 +637,6 @@ nsDiskCacheDevice::GetFileForEntry(nsCacheEntry * entry,
|
|||
NS_ENSURE_ARG_POINTER(result);
|
||||
*result = nsnull;
|
||||
|
||||
nsAutoLock lock(mDeviceLock->GetPRLock()); // grab device lock
|
||||
nsresult rv;
|
||||
|
||||
nsDiskCacheBinding * binding = GetCacheEntryBinding(entry);
|
||||
|
@ -672,12 +673,13 @@ nsDiskCacheDevice::GetFileForEntry(nsCacheEntry * entry,
|
|||
|
||||
|
||||
/**
|
||||
* This routine will get called every time an open descriptor is written to.
|
||||
* This routine will get called every time an open descriptor is written to.
|
||||
*
|
||||
* NOTE: called while holding the cache service lock
|
||||
*/
|
||||
nsresult
|
||||
nsDiskCacheDevice::OnDataSizeChange(nsCacheEntry * entry, PRInt32 deltaSize)
|
||||
{
|
||||
nsAutoLock lock(mDeviceLock->GetPRLock()); // grab device lock
|
||||
nsDiskCacheBinding * binding = GetCacheEntryBinding(entry);
|
||||
NS_ASSERTION(binding, "OnDataSizeChange: binding == nsnull");
|
||||
if (!binding) return NS_ERROR_UNEXPECTED;
|
||||
|
@ -945,12 +947,14 @@ nsDiskCacheDevice::getCacheDirectory(nsILocalFile ** result)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* NOTE: called while holding the cache service lock
|
||||
*/
|
||||
void
|
||||
nsDiskCacheDevice::SetCapacity(PRUint32 capacity)
|
||||
{
|
||||
mCacheCapacity = capacity * 1024;
|
||||
if (Initialized()) {
|
||||
nsAutoLock lock(mDeviceLock->GetPRLock()); // grab device lock
|
||||
// start evicting entries if the new size is smaller!
|
||||
EvictDiskCacheEntries((PRInt32)mCacheCapacity);
|
||||
}
|
||||
|
|
|
@ -79,8 +79,7 @@ public:
|
|||
PRUint32 getCacheSize();
|
||||
PRUint32 getEntryCount();
|
||||
|
||||
nsCacheLock * DeviceLock() { return mDeviceLock; }
|
||||
PRBool Initialized() { return (mDeviceLock != nsnull); }
|
||||
PRBool Initialized() { return mInitialized; }
|
||||
nsDiskCacheMap * CacheMap() { return mCacheMap; }
|
||||
|
||||
private:
|
||||
|
@ -94,11 +93,11 @@ private:
|
|||
/**
|
||||
* Member variables
|
||||
*/
|
||||
nsCOMPtr<nsCacheLock> mDeviceLock;
|
||||
nsCOMPtr<nsILocalFile> mCacheDirectory;
|
||||
nsDiskCacheBindery mBindery;
|
||||
PRUint32 mCacheCapacity; // XXX need soft/hard limits, currentTotal
|
||||
nsDiskCacheMap * mCacheMap;
|
||||
PRPackedBool mInitialized;
|
||||
};
|
||||
|
||||
#endif // _nsDiskCacheDevice_h_
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "nsDiskCache.h"
|
||||
#include "nsDiskCacheDevice.h"
|
||||
#include "nsDiskCacheStreams.h"
|
||||
#include "nsCacheService.h"
|
||||
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIOutputStream.h"
|
||||
|
@ -327,13 +328,20 @@ nsDiskCacheStreamIO::nsDiskCacheStreamIO(nsDiskCacheBinding * binding)
|
|||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
mDevice = (nsDiskCacheDevice *)mBinding->mCacheEntry->CacheDevice();
|
||||
mDeviceLock = mDevice->DeviceLock();
|
||||
|
||||
// acquire "death grip" on cache service
|
||||
nsCacheService *service = nsCacheService::GlobalInstance();
|
||||
NS_ADDREF(service);
|
||||
}
|
||||
|
||||
|
||||
nsDiskCacheStreamIO::~nsDiskCacheStreamIO()
|
||||
{
|
||||
(void) Close(NS_OK);
|
||||
|
||||
// release "death grip" on cache service
|
||||
nsCacheService *service = nsCacheService::GlobalInstance();
|
||||
NS_RELEASE(service);
|
||||
}
|
||||
|
||||
|
||||
|
@ -367,7 +375,7 @@ nsDiskCacheStreamIO::GetInputStream(nsIInputStream ** inputStream)
|
|||
NS_ENSURE_ARG_POINTER(inputStream);
|
||||
*inputStream = nsnull;
|
||||
|
||||
nsAutoLock lock(mDeviceLock->GetPRLock()); // grab device lock
|
||||
nsAutoLock lock(nsCacheService::ServiceLock()); // grab service lock
|
||||
if (!mBinding) return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
if (mOutStream) {
|
||||
|
@ -411,7 +419,7 @@ nsDiskCacheStreamIO::GetOutputStream(nsIOutputStream ** outputStream)
|
|||
NS_ENSURE_ARG_POINTER(outputStream);
|
||||
*outputStream = nsnull;
|
||||
|
||||
nsAutoLock lock(mDeviceLock->GetPRLock()); // grab device lock
|
||||
nsAutoLock lock(nsCacheService::ServiceLock()); // grab service lock
|
||||
if (!mBinding) return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
NS_ASSERTION(!mOutStream, "already have an output stream open");
|
||||
|
@ -468,7 +476,7 @@ nsDiskCacheStreamIO::GetContentLength(PRInt32 *contentLength)
|
|||
nsresult
|
||||
nsDiskCacheStreamIO::CloseOutputStream(nsDiskCacheOutputStream * outputStream)
|
||||
{
|
||||
nsAutoLock lock(mDeviceLock->GetPRLock()); // grab device lock
|
||||
nsAutoLock lock(nsCacheService::ServiceLock()); // grab service lock
|
||||
nsresult rv;
|
||||
|
||||
if (outputStream != mOutStream) {
|
||||
|
@ -556,7 +564,7 @@ nsDiskCacheStreamIO::Write( const char * buffer,
|
|||
PRUint32 * bytesWritten)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsAutoLock lock(mDeviceLock->GetPRLock()); // grab device lock
|
||||
nsAutoLock lock(nsCacheService::ServiceLock()); // grab service lock
|
||||
if (!mBinding) return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
if (mInStreamCount) {
|
||||
|
@ -774,12 +782,11 @@ nsresult
|
|||
nsDiskCacheStreamIO::Seek(PRInt32 whence, PRInt32 offset)
|
||||
{
|
||||
PRInt32 newPos;
|
||||
nsAutoLock lock(mDeviceLock->GetPRLock()); // grab device lock
|
||||
nsAutoLock lock(nsCacheService::ServiceLock()); // grab service lock
|
||||
if (!mBinding) return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
if (PRUint32(offset) > mStreamEnd) return NS_ERROR_FAILURE;
|
||||
|
||||
|
||||
if (mFD) {
|
||||
|
||||
// do we have data in the buffer that needs to be flushed?
|
||||
|
@ -878,7 +885,7 @@ nsDiskCacheStreamIO::SetEOF()
|
|||
{
|
||||
nsresult rv;
|
||||
NS_ASSERTION(mStreamPos <= mStreamEnd, "bad stream");
|
||||
nsAutoLock lock(mDeviceLock->GetPRLock()); // grab device lock
|
||||
nsAutoLock lock(nsCacheService::ServiceLock()); // grab service lock
|
||||
if (!mBinding) return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
if (mBinding->mRecord.DataLocationInitialized()) {
|
||||
|
|
|
@ -86,7 +86,6 @@ private:
|
|||
|
||||
nsDiskCacheBinding * mBinding;
|
||||
nsDiskCacheDevice * mDevice;
|
||||
nsCOMPtr<nsCacheLock> mDeviceLock;
|
||||
nsDiskCacheOutputStream * mOutStream;
|
||||
PRInt32 mInStreamCount;
|
||||
nsCOMPtr<nsILocalFile> mLocalFile;
|
||||
|
|
Загрузка…
Ссылка в новой задаче