mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 23:02:20 +00:00
Bug 1399520 - Avoid race condition. r=dragana
MozReview-Commit-ID: 6Pd2HXqBgX4
This commit is contained in:
parent
7746cd0200
commit
b4603106d0
@ -43,11 +43,27 @@ NS_IMPL_QUERY_INTERFACE(nsJAR, nsIZipReader)
|
||||
NS_IMPL_ADDREF(nsJAR)
|
||||
|
||||
// Custom Release method works with nsZipReaderCache...
|
||||
// Release might be called from multi-thread, we have to
|
||||
// take this function carefully to avoid delete-after-use.
|
||||
MozExternalRefCountType nsJAR::Release(void)
|
||||
{
|
||||
nsrefcnt count;
|
||||
NS_PRECONDITION(0 != mRefCnt, "dup release");
|
||||
count = --mRefCnt;
|
||||
|
||||
RefPtr<nsZipReaderCache> cache;
|
||||
if (mRefCnt == 2) { // don't use a lock too frequently
|
||||
// Use a mutex here to guarantee mCache is not racing and the target instance
|
||||
// is still valid to increase ref-count.
|
||||
MutexAutoLock lock(mLock);
|
||||
cache = mCache;
|
||||
mCache = nullptr;
|
||||
}
|
||||
if (cache) {
|
||||
DebugOnly<nsresult> rv = cache->ReleaseZip(this);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv), "failed to release zip file");
|
||||
}
|
||||
|
||||
count = --mRefCnt; // don't access any member variable after this line
|
||||
NS_LOG_RELEASE(this, count, "nsJAR");
|
||||
if (0 == count) {
|
||||
mRefCnt = 1; /* stabilize */
|
||||
@ -56,13 +72,7 @@ MozExternalRefCountType nsJAR::Release(void)
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
if (1 == count && mCache) {
|
||||
#ifdef DEBUG
|
||||
nsresult rv =
|
||||
#endif
|
||||
mCache->ReleaseZip(this);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "failed to release zip file");
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "mozilla/Logging.h"
|
||||
#include "prinrval.h"
|
||||
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsCOMPtr.h"
|
||||
@ -75,8 +76,9 @@ class nsJAR final : public nsIZipReader
|
||||
mReleaseTime = PR_INTERVAL_NO_TIMEOUT;
|
||||
}
|
||||
|
||||
void SetZipReaderCache(nsZipReaderCache* cache) {
|
||||
mCache = cache;
|
||||
void SetZipReaderCache(nsZipReaderCache* aCache) {
|
||||
mozilla::MutexAutoLock lock(mLock);
|
||||
mCache = aCache;
|
||||
}
|
||||
|
||||
nsresult GetNSPRFileDesc(PRFileDesc** aNSPRFileDesc);
|
||||
@ -89,7 +91,7 @@ class nsJAR final : public nsIZipReader
|
||||
RefPtr<nsZipArchive> mZip; // The underlying zip archive
|
||||
PRIntervalTime mReleaseTime; // used by nsZipReaderCache for flushing entries
|
||||
nsZipReaderCache* mCache; // if cached, this points to the cache it's contained in
|
||||
mozilla::Mutex mLock;
|
||||
mozilla::Mutex mLock; // protect mCache and mZip
|
||||
int64_t mMtime;
|
||||
bool mOpened;
|
||||
bool mIsOmnijar;
|
||||
|
Loading…
Reference in New Issue
Block a user