fixes bug 163841 "Mozilla hangs in PR_Lock at ptsynch.c:190" r=dougt sr=rpotts

This commit is contained in:
darin%netscape.com 2002-08-29 04:30:54 +00:00
Родитель 32844f7719
Коммит 30b3e1cdfa
6 изменённых файлов: 53 добавлений и 96 удалений

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

@ -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;
}

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

@ -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

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

@ -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);
}

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

@ -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_

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

@ -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()) {

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

@ -86,7 +86,6 @@ private:
nsDiskCacheBinding * mBinding;
nsDiskCacheDevice * mDevice;
nsCOMPtr<nsCacheLock> mDeviceLock;
nsDiskCacheOutputStream * mOutStream;
PRInt32 mInStreamCount;
nsCOMPtr<nsILocalFile> mLocalFile;