mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1247644
- Don't do any I/O on doomed and unused HTTP cache entries, r=michal
This commit is contained in:
parent
48b434174d
commit
1c6a5ba1fc
@ -928,6 +928,13 @@ void CacheEntry::OnHandleClosed(CacheEntryHandle const* aHandle)
|
||||
|
||||
mozilla::MutexAutoLock lock(mLock);
|
||||
|
||||
if (IsDoomed() && mHandlesCount == 0 && NS_SUCCEEDED(mFileStatus)) {
|
||||
// This entry is no longer referenced from outside and is doomed.
|
||||
// Tell the file to kill the handle, i.e. bypass any I/O operations
|
||||
// on it except removing the file.
|
||||
mFile->Kill();
|
||||
}
|
||||
|
||||
if (mWriter != aHandle) {
|
||||
LOG((" not the writer"));
|
||||
return;
|
||||
@ -1117,8 +1124,10 @@ NS_IMETHODIMP CacheEntry::OpenInputStream(int64_t offset, nsIInputStream * *_ret
|
||||
|
||||
nsresult rv;
|
||||
|
||||
RefPtr<CacheEntryHandle> selfHandle = NewHandle();
|
||||
|
||||
nsCOMPtr<nsIInputStream> stream;
|
||||
rv = mFile->OpenInputStream(getter_AddRefs(stream));
|
||||
rv = mFile->OpenInputStream(selfHandle, getter_AddRefs(stream));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsISeekableStream> seekable =
|
||||
|
@ -194,6 +194,7 @@ CacheFile::CacheFile()
|
||||
, mPreloadChunkCount(0)
|
||||
, mStatus(NS_OK)
|
||||
, mDataSize(-1)
|
||||
, mKill(false)
|
||||
, mOutput(nullptr)
|
||||
{
|
||||
LOG(("CacheFile::CacheFile() [this=%p]", this));
|
||||
@ -204,7 +205,7 @@ CacheFile::~CacheFile()
|
||||
LOG(("CacheFile::~CacheFile() [this=%p]", this));
|
||||
|
||||
MutexAutoLock lock(mLock);
|
||||
if (!mMemoryOnly && mReady) {
|
||||
if (!mMemoryOnly && mReady && !mKill) {
|
||||
// mReady flag indicates we have metadata plus in a valid state.
|
||||
WriteMetadataIfNeededLocked(true);
|
||||
}
|
||||
@ -703,8 +704,18 @@ CacheFile::OnFileRenamed(CacheFileHandle *aHandle, nsresult aResult)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
bool CacheFile::IsKilled()
|
||||
{
|
||||
bool killed = mKill;
|
||||
if (killed) {
|
||||
LOG(("CacheFile is killed, this=%p", this));
|
||||
}
|
||||
|
||||
return killed;
|
||||
}
|
||||
|
||||
nsresult
|
||||
CacheFile::OpenInputStream(nsIInputStream **_retval)
|
||||
CacheFile::OpenInputStream(nsICacheEntry *aEntryHandle, nsIInputStream **_retval)
|
||||
{
|
||||
CacheFileAutoLock lock(this);
|
||||
|
||||
@ -735,7 +746,7 @@ CacheFile::OpenInputStream(nsIInputStream **_retval)
|
||||
// the last input stream is closed.
|
||||
mPreloadWithoutInputStreams = false;
|
||||
|
||||
CacheFileInputStream *input = new CacheFileInputStream(this);
|
||||
CacheFileInputStream *input = new CacheFileInputStream(this, aEntryHandle);
|
||||
|
||||
LOG(("CacheFile::OpenInputStream() - Creating new input stream %p [this=%p]",
|
||||
input, this));
|
||||
@ -907,6 +918,9 @@ nsresult
|
||||
CacheFile::SetElement(const char *aKey, const char *aValue)
|
||||
{
|
||||
CacheFileAutoLock lock(this);
|
||||
|
||||
LOG(("CacheFile::SetElement() this=%p", this));
|
||||
|
||||
MOZ_ASSERT(mMetadata);
|
||||
NS_ENSURE_TRUE(mMetadata, NS_ERROR_UNEXPECTED);
|
||||
|
||||
@ -941,6 +955,10 @@ nsresult
|
||||
CacheFile::SetExpirationTime(uint32_t aExpirationTime)
|
||||
{
|
||||
CacheFileAutoLock lock(this);
|
||||
|
||||
LOG(("CacheFile::SetExpirationTime() this=%p, expiration=%u",
|
||||
this, aExpirationTime));
|
||||
|
||||
MOZ_ASSERT(mMetadata);
|
||||
NS_ENSURE_TRUE(mMetadata, NS_ERROR_UNEXPECTED);
|
||||
|
||||
@ -966,6 +984,10 @@ nsresult
|
||||
CacheFile::SetFrecency(uint32_t aFrecency)
|
||||
{
|
||||
CacheFileAutoLock lock(this);
|
||||
|
||||
LOG(("CacheFile::SetFrecency() this=%p, frecency=%u",
|
||||
this, aFrecency));
|
||||
|
||||
MOZ_ASSERT(mMetadata);
|
||||
NS_ENSURE_TRUE(mMetadata, NS_ERROR_UNEXPECTED);
|
||||
|
||||
@ -1021,6 +1043,9 @@ nsresult
|
||||
CacheFile::OnFetched()
|
||||
{
|
||||
CacheFileAutoLock lock(this);
|
||||
|
||||
LOG(("CacheFile::OnFetched() this=%p", this));
|
||||
|
||||
MOZ_ASSERT(mMetadata);
|
||||
NS_ENSURE_TRUE(mMetadata, NS_ERROR_UNEXPECTED);
|
||||
|
||||
|
@ -74,15 +74,17 @@ public:
|
||||
NS_IMETHOD OnFileDoomed(CacheFileHandle *aHandle, nsresult aResult) override;
|
||||
NS_IMETHOD OnEOFSet(CacheFileHandle *aHandle, nsresult aResult) override;
|
||||
NS_IMETHOD OnFileRenamed(CacheFileHandle *aHandle, nsresult aResult) override;
|
||||
virtual bool IsKilled() override;
|
||||
|
||||
NS_IMETHOD OnMetadataRead(nsresult aResult) override;
|
||||
NS_IMETHOD OnMetadataWritten(nsresult aResult) override;
|
||||
|
||||
NS_IMETHOD OpenInputStream(nsIInputStream **_retval);
|
||||
NS_IMETHOD OpenInputStream(nsICacheEntry *aCacheEntryHandle, nsIInputStream **_retval);
|
||||
NS_IMETHOD OpenOutputStream(CacheOutputCloseListener *aCloseListener, nsIOutputStream **_retval);
|
||||
NS_IMETHOD SetMemoryOnly();
|
||||
NS_IMETHOD Doom(CacheFileListener *aCallback);
|
||||
|
||||
void Kill() { mKill = true; }
|
||||
nsresult ThrowMemoryCachedData();
|
||||
|
||||
// metadata forwarders
|
||||
@ -198,6 +200,7 @@ private:
|
||||
RefPtr<CacheFileMetadata> mMetadata;
|
||||
nsCOMPtr<CacheFileListener> mListener;
|
||||
nsCOMPtr<CacheFileIOListener> mDoomAfterOpenListener;
|
||||
Atomic<bool, Relaxed> mKill;
|
||||
|
||||
nsRefPtrHashtable<nsUint32HashKey, CacheFileChunk> mChunks;
|
||||
nsClassHashtable<nsUint32HashKey, ChunkListeners> mChunkListeners;
|
||||
|
@ -594,6 +594,12 @@ CacheFileChunk::OnFileRenamed(CacheFileHandle *aHandle, nsresult aResult)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheFileChunk::IsKilled()
|
||||
{
|
||||
return mFile->IsKilled();
|
||||
}
|
||||
|
||||
bool
|
||||
CacheFileChunk::IsReady() const
|
||||
{
|
||||
|
@ -94,6 +94,7 @@ public:
|
||||
NS_IMETHOD OnFileDoomed(CacheFileHandle *aHandle, nsresult aResult) override;
|
||||
NS_IMETHOD OnEOFSet(CacheFileHandle *aHandle, nsresult aResult) override;
|
||||
NS_IMETHOD OnFileRenamed(CacheFileHandle *aHandle, nsresult aResult) override;
|
||||
virtual bool IsKilled() override;
|
||||
|
||||
bool IsReady() const;
|
||||
bool IsDirty() const;
|
||||
|
@ -663,7 +663,7 @@ public:
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (mHandle->IsClosed()) {
|
||||
if (mHandle->IsClosed() || (mCallback && mCallback->IsKilled())) {
|
||||
rv = NS_ERROR_NOT_INITIALIZED;
|
||||
} else {
|
||||
rv = CacheFileIOManager::gInstance->ReadInternal(
|
||||
@ -713,7 +713,7 @@ public:
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (mHandle->IsClosed()) {
|
||||
if (mHandle->IsClosed() || (mCallback && mCallback->IsKilled())) {
|
||||
// We usually get here only after the internal shutdown
|
||||
// (i.e. mShuttingDown == true). Pretend write has succeeded
|
||||
// to avoid any past-shutdown file dooming.
|
||||
@ -886,7 +886,7 @@ public:
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (mHandle->IsClosed()) {
|
||||
if (mHandle->IsClosed() || (mCallback && mCallback->IsKilled())) {
|
||||
rv = NS_ERROR_NOT_INITIALIZED;
|
||||
} else {
|
||||
rv = CacheFileIOManager::gInstance->TruncateSeekSetEOFInternal(
|
||||
@ -1919,7 +1919,7 @@ CacheFileIOManager::Write(CacheFileHandle *aHandle, int64_t aOffset,
|
||||
nsresult rv;
|
||||
RefPtr<CacheFileIOManager> ioMan = gInstance;
|
||||
|
||||
if (aHandle->IsClosed() || !ioMan) {
|
||||
if (aHandle->IsClosed() || (aCallback && aCallback->IsKilled()) || !ioMan) {
|
||||
if (!aCallback) {
|
||||
// When no callback is provided, CacheFileIOManager is responsible for
|
||||
// releasing the buffer. We must release it even in case of failure.
|
||||
@ -2329,7 +2329,7 @@ CacheFileIOManager::TruncateSeekSetEOF(CacheFileHandle *aHandle,
|
||||
nsresult rv;
|
||||
RefPtr<CacheFileIOManager> ioMan = gInstance;
|
||||
|
||||
if (aHandle->IsClosed() || !ioMan) {
|
||||
if (aHandle->IsClosed() || (aCallback && aCallback->IsKilled()) || !ioMan) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
@ -3791,6 +3791,8 @@ CacheFileIOManager::CreateCacheTree()
|
||||
nsresult
|
||||
CacheFileIOManager::OpenNSPRHandle(CacheFileHandle *aHandle, bool aCreate)
|
||||
{
|
||||
LOG(("CacheFileIOManager::OpenNSPRHandle BEGIN, handle=%p", aHandle));
|
||||
|
||||
MOZ_ASSERT(CacheFileIOManager::IsOnIOThreadOrCeased());
|
||||
MOZ_ASSERT(!aHandle->mFD);
|
||||
MOZ_ASSERT(mHandlesByLastUsed.IndexOf(aHandle) == mHandlesByLastUsed.NoIndex);
|
||||
@ -3860,6 +3862,9 @@ CacheFileIOManager::OpenNSPRHandle(CacheFileHandle *aHandle, bool aCreate)
|
||||
}
|
||||
|
||||
mHandlesByLastUsed.AppendElement(aHandle);
|
||||
|
||||
LOG(("CacheFileIOManager::OpenNSPRHandle END, handle=%p", aHandle));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -234,6 +234,8 @@ public:
|
||||
NS_IMETHOD OnFileDoomed(CacheFileHandle *aHandle, nsresult aResult) = 0;
|
||||
NS_IMETHOD OnEOFSet(CacheFileHandle *aHandle, nsresult aResult) = 0;
|
||||
NS_IMETHOD OnFileRenamed(CacheFileHandle *aHandle, nsresult aResult) = 0;
|
||||
|
||||
virtual bool IsKilled() { return false; }
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(CacheFileIOListener, CACHEFILEIOLISTENER_IID)
|
||||
|
@ -42,7 +42,7 @@ NS_INTERFACE_MAP_BEGIN(CacheFileInputStream)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIInputStream)
|
||||
NS_INTERFACE_MAP_END_THREADSAFE
|
||||
|
||||
CacheFileInputStream::CacheFileInputStream(CacheFile *aFile)
|
||||
CacheFileInputStream::CacheFileInputStream(CacheFile *aFile, nsISupports *aEntry)
|
||||
: mFile(aFile)
|
||||
, mPos(0)
|
||||
, mClosed(false)
|
||||
@ -50,6 +50,7 @@ CacheFileInputStream::CacheFileInputStream(CacheFile *aFile)
|
||||
, mWaitingForUpdate(false)
|
||||
, mListeningForChunk(-1)
|
||||
, mCallbackFlags(0)
|
||||
, mCacheEntryHandle(aEntry)
|
||||
{
|
||||
LOG(("CacheFileInputStream::CacheFileInputStream() [this=%p]", this));
|
||||
MOZ_COUNT_CTOR(CacheFileInputStream);
|
||||
@ -240,6 +241,8 @@ CacheFileInputStream::CloseWithStatusLocked(nsresult aStatus)
|
||||
|
||||
MaybeNotifyListener();
|
||||
|
||||
mFile->ReleaseOutsideLock(mCacheEntryHandle.forget());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "nsAutoPtr.h"
|
||||
#include "CacheFileChunk.h"
|
||||
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
@ -27,7 +26,7 @@ class CacheFileInputStream : public nsIAsyncInputStream
|
||||
NS_DECL_NSISEEKABLESTREAM
|
||||
|
||||
public:
|
||||
explicit CacheFileInputStream(CacheFile *aFile);
|
||||
explicit CacheFileInputStream(CacheFile *aFile, nsISupports *aEntry);
|
||||
|
||||
NS_IMETHOD OnChunkRead(nsresult aResult, CacheFileChunk *aChunk) override;
|
||||
NS_IMETHOD OnChunkWritten(nsresult aResult, CacheFileChunk *aChunk) override;
|
||||
@ -64,6 +63,8 @@ private:
|
||||
nsCOMPtr<nsIInputStreamCallback> mCallback;
|
||||
uint32_t mCallbackFlags;
|
||||
nsCOMPtr<nsIEventTarget> mCallbackTarget;
|
||||
// Held purely for referencing purposes
|
||||
RefPtr<nsISupports> mCacheEntryHandle;
|
||||
};
|
||||
|
||||
|
||||
|
@ -116,6 +116,7 @@ public:
|
||||
|
||||
NS_IMETHOD OnMetadataRead(nsresult aResult) = 0;
|
||||
NS_IMETHOD OnMetadataWritten(nsresult aResult) = 0;
|
||||
virtual bool IsKilled() = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(CacheFileMetadataListener,
|
||||
@ -183,6 +184,7 @@ public:
|
||||
NS_IMETHOD OnFileDoomed(CacheFileHandle *aHandle, nsresult aResult) override;
|
||||
NS_IMETHOD OnEOFSet(CacheFileHandle *aHandle, nsresult aResult) override;
|
||||
NS_IMETHOD OnFileRenamed(CacheFileHandle *aHandle, nsresult aResult) override;
|
||||
virtual bool IsKilled() override { return mListener && mListener->IsKilled(); }
|
||||
|
||||
// Memory reporting
|
||||
size_t SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
|
||||
|
Loading…
Reference in New Issue
Block a user