Bug 1042192 - Use Cache2 I/O thread for callbacks from CacheFileIOManager, r=sworkman

This commit is contained in:
Michal Novotny 2014-08-18 15:36:27 +02:00
parent 4ddc2a5161
commit bb35753e96
11 changed files with 223 additions and 234 deletions

View File

@ -265,7 +265,7 @@ CacheFile::Init(const nsACString &aKey,
mOpeningFile = true;
mListener = aCallback;
rv = CacheFileIOManager::OpenFile(mKey, flags, true, this);
rv = CacheFileIOManager::OpenFile(mKey, flags, this);
if (NS_FAILED(rv)) {
mListener = nullptr;
mOpeningFile = false;
@ -330,6 +330,13 @@ CacheFile::OnChunkRead(nsresult aResult, CacheFileChunk *aChunk)
nsresult
CacheFile::OnChunkWritten(nsresult aResult, CacheFileChunk *aChunk)
{
// In case the chunk was reused, made dirty and released between calls to
// CacheFileChunk::Write() and CacheFile::OnChunkWritten(), we must write
// the chunk to the disk again. When the chunk is unused and is dirty simply
// addref and release (outside the lock) the chunk which ensures that
// CacheFile::DeactivateChunk() will be called again.
nsRefPtr<CacheFileChunk> deactivateChunkAgain;
CacheFileAutoLock lock(this);
nsresult rv;
@ -367,6 +374,14 @@ CacheFile::OnChunkWritten(nsresult aResult, CacheFileChunk *aChunk)
return NS_OK;
}
if (aChunk->IsDirty()) {
LOG(("CacheFile::OnChunkWritten() - Unused chunk is dirty. We must go "
"through deactivation again. [this=%p, chunk=%p]", this, aChunk));
deactivateChunkAgain = aChunk;
return NS_OK;
}
bool keepChunk = false;
if (NS_SUCCEEDED(aResult)) {
keepChunk = ShouldCacheChunk(aChunk->Index());
@ -1594,7 +1609,12 @@ CacheFile::QueueChunkListener(uint32_t aIndex,
MOZ_ASSERT(aCallback);
ChunkListenerItem *item = new ChunkListenerItem();
item->mTarget = NS_GetCurrentThread();
item->mTarget = CacheFileIOManager::IOTarget();
if (!item->mTarget) {
LOG(("CacheFile::QueueChunkListener() - Cannot get Cache I/O thread! Using "
"main thread for callback."));
item->mTarget = do_GetMainThread();
}
item->mCallback = aCallback;
ChunkListeners *listeners;

View File

@ -201,7 +201,7 @@ CacheFileChunk::Read(CacheFileHandle *aHandle, uint32_t aLen,
DoMemoryReport(MemorySize());
rv = CacheFileIOManager::Read(aHandle, mIndex * kChunkSize, mRWBuf, aLen,
true, this);
this);
if (NS_WARN_IF(NS_FAILED(rv))) {
rv = mIndex ? NS_ERROR_FILE_CORRUPTED : NS_ERROR_FILE_NOT_FOUND;
SetError(rv);
@ -267,7 +267,14 @@ CacheFileChunk::WaitForUpdate(CacheFileChunkListener *aCallback)
#endif
ChunkListenerItem *item = new ChunkListenerItem();
item->mTarget = NS_GetCurrentThread();
item->mTarget = CacheFileIOManager::IOTarget();
if (!item->mTarget) {
LOG(("CacheFileChunk::WaitForUpdate() - Cannot get Cache I/O thread! Using "
"main thread for callback."));
item->mTarget = do_GetMainThread();
}
item->mCallback = aCallback;
MOZ_ASSERT(item->mTarget);
item->mCallback = aCallback;
mUpdateListeners.AppendElement(item);

View File

@ -550,22 +550,13 @@ protected:
class OpenFileEvent : public nsRunnable {
public:
OpenFileEvent(const nsACString &aKey,
uint32_t aFlags, bool aResultOnAnyThread,
OpenFileEvent(const nsACString &aKey, uint32_t aFlags,
CacheFileIOListener *aCallback)
: mFlags(aFlags)
, mResultOnAnyThread(aResultOnAnyThread)
, mCallback(aCallback)
, mRV(NS_ERROR_FAILURE)
, mKey(aKey)
{
MOZ_COUNT_CTOR(OpenFileEvent);
if (!aResultOnAnyThread) {
mTarget = static_cast<nsIEventTarget*>(NS_GetCurrentThread());
MOZ_ASSERT(mTarget);
}
mIOMan = CacheFileIOManager::gInstance;
MOZ_EVENT_TRACER_NAME_OBJECT(static_cast<nsIRunnable*>(this), aKey.BeginReading());
@ -581,53 +572,38 @@ protected:
public:
NS_IMETHOD Run()
{
if (mResultOnAnyThread || mTarget) {
mRV = NS_OK;
nsresult rv = NS_OK;
if (!(mFlags & CacheFileIOManager::SPECIAL_FILE)) {
SHA1Sum sum;
sum.update(mKey.BeginReading(), mKey.Length());
sum.finish(mHash);
if (!(mFlags & CacheFileIOManager::SPECIAL_FILE)) {
SHA1Sum sum;
sum.update(mKey.BeginReading(), mKey.Length());
sum.finish(mHash);
}
MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::open-background");
if (!mIOMan) {
rv = NS_ERROR_NOT_INITIALIZED;
} else {
if (mFlags & CacheFileIOManager::SPECIAL_FILE) {
rv = mIOMan->OpenSpecialFileInternal(mKey, mFlags,
getter_AddRefs(mHandle));
} else {
rv = mIOMan->OpenFileInternal(&mHash, mKey, mFlags,
getter_AddRefs(mHandle));
}
MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this),
"net::cache::open-background");
if (NS_SUCCEEDED(mRV)) {
if (!mIOMan) {
mRV = NS_ERROR_NOT_INITIALIZED;
} else {
if (mFlags & CacheFileIOManager::SPECIAL_FILE) {
mRV = mIOMan->OpenSpecialFileInternal(mKey, mFlags,
getter_AddRefs(mHandle));
} else {
mRV = mIOMan->OpenFileInternal(&mHash, mKey, mFlags,
getter_AddRefs(mHandle));
}
mIOMan = nullptr;
if (mHandle) {
MOZ_EVENT_TRACER_NAME_OBJECT(mHandle.get(), mKey.get());
if (mHandle->Key().IsEmpty()) {
mHandle->Key() = mKey;
}
}
mIOMan = nullptr;
if (mHandle) {
MOZ_EVENT_TRACER_NAME_OBJECT(mHandle.get(), mKey.get());
if (mHandle->Key().IsEmpty()) {
mHandle->Key() = mKey;
}
}
MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::open-background");
MOZ_EVENT_TRACER_WAIT(static_cast<nsIRunnable*>(this), "net::cache::open-result");
if (mTarget) {
nsCOMPtr<nsIEventTarget> target;
mTarget.swap(target);
return target->Dispatch(this, nsIEventTarget::DISPATCH_NORMAL);
}
}
MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::open-background");
if (!mTarget) {
MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::open-result");
mCallback->OnFileOpened(mHandle, mRV);
MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::open-result");
}
MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::open-result");
mCallback->OnFileOpened(mHandle, rv);
MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::open-result");
return NS_OK;
}
@ -635,33 +611,24 @@ public:
protected:
SHA1Sum::Hash mHash;
uint32_t mFlags;
bool mResultOnAnyThread;
nsCOMPtr<CacheFileIOListener> mCallback;
nsCOMPtr<nsIEventTarget> mTarget;
nsRefPtr<CacheFileIOManager> mIOMan;
nsRefPtr<CacheFileHandle> mHandle;
nsresult mRV;
nsCString mKey;
};
class ReadEvent : public nsRunnable {
public:
ReadEvent(CacheFileHandle *aHandle, int64_t aOffset, char *aBuf,
int32_t aCount, bool aResultOnAnyThread, CacheFileIOListener *aCallback)
int32_t aCount, CacheFileIOListener *aCallback)
: mHandle(aHandle)
, mOffset(aOffset)
, mBuf(aBuf)
, mCount(aCount)
, mResultOnAnyThread(aResultOnAnyThread)
, mCallback(aCallback)
, mRV(NS_ERROR_FAILURE)
{
MOZ_COUNT_CTOR(ReadEvent);
if (!aResultOnAnyThread) {
mTarget = static_cast<nsIEventTarget*>(NS_GetCurrentThread());
}
MOZ_EVENT_TRACER_NAME_OBJECT(static_cast<nsIRunnable*>(this), aHandle->Key().get());
MOZ_EVENT_TRACER_WAIT(static_cast<nsIRunnable*>(this), "net::cache::read-background");
}
@ -675,30 +642,20 @@ protected:
public:
NS_IMETHOD Run()
{
if (mResultOnAnyThread || mTarget) {
MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::read-background");
if (mHandle->IsClosed()) {
mRV = NS_ERROR_NOT_INITIALIZED;
} else {
mRV = CacheFileIOManager::gInstance->ReadInternal(
mHandle, mOffset, mBuf, mCount);
}
MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::read-background");
nsresult rv;
MOZ_EVENT_TRACER_WAIT(static_cast<nsIRunnable*>(this), "net::cache::read-result");
if (mTarget) {
nsCOMPtr<nsIEventTarget> target;
mTarget.swap(target);
return target->Dispatch(this, nsIEventTarget::DISPATCH_NORMAL);
}
MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::read-background");
if (mHandle->IsClosed()) {
rv = NS_ERROR_NOT_INITIALIZED;
} else {
rv = CacheFileIOManager::gInstance->ReadInternal(
mHandle, mOffset, mBuf, mCount);
}
MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::read-background");
if (!mTarget && mCallback) {
MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::read-result");
mCallback->OnDataRead(mHandle, mBuf, mRV);
MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::read-result");
}
MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::read-result");
mCallback->OnDataRead(mHandle, mBuf, rv);
MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::read-result");
return NS_OK;
}
@ -708,10 +665,7 @@ protected:
int64_t mOffset;
char *mBuf;
int32_t mCount;
bool mResultOnAnyThread;
nsCOMPtr<CacheFileIOListener> mCallback;
nsCOMPtr<nsIEventTarget> mTarget;
nsresult mRV;
};
class WriteEvent : public nsRunnable {
@ -724,10 +678,8 @@ public:
, mCount(aCount)
, mValidate(aValidate)
, mCallback(aCallback)
, mRV(NS_ERROR_FAILURE)
{
MOZ_COUNT_CTOR(WriteEvent);
mTarget = static_cast<nsIEventTarget*>(NS_GetCurrentThread());
MOZ_EVENT_TRACER_NAME_OBJECT(static_cast<nsIRunnable*>(this), aHandle->Key().get());
MOZ_EVENT_TRACER_WAIT(static_cast<nsIRunnable*>(this), "net::cache::write-background");
@ -746,30 +698,26 @@ protected:
public:
NS_IMETHOD Run()
{
if (mTarget) {
MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::write-background");
if (mHandle->IsClosed()) {
mRV = NS_ERROR_NOT_INITIALIZED;
} else {
mRV = CacheFileIOManager::gInstance->WriteInternal(
mHandle, mOffset, mBuf, mCount, mValidate);
}
MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::write-background");
nsresult rv;
MOZ_EVENT_TRACER_WAIT(static_cast<nsIRunnable*>(this), "net::cache::write-result");
nsCOMPtr<nsIEventTarget> target;
mTarget.swap(target);
target->Dispatch(this, nsIEventTarget::DISPATCH_NORMAL);
MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::write-background");
if (mHandle->IsClosed()) {
rv = NS_ERROR_NOT_INITIALIZED;
} else {
MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::write-result");
if (mCallback) {
mCallback->OnDataWritten(mHandle, mBuf, mRV);
} else {
free(const_cast<char *>(mBuf));
mBuf = nullptr;
}
MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::write-result");
rv = CacheFileIOManager::gInstance->WriteInternal(
mHandle, mOffset, mBuf, mCount, mValidate);
}
MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::write-background");
MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::write-result");
if (mCallback) {
mCallback->OnDataWritten(mHandle, mBuf, rv);
} else {
free(const_cast<char *>(mBuf));
mBuf = nullptr;
}
MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::write-result");
return NS_OK;
}
@ -780,8 +728,6 @@ protected:
int32_t mCount;
bool mValidate;
nsCOMPtr<CacheFileIOListener> mCallback;
nsCOMPtr<nsIEventTarget> mTarget;
nsresult mRV;
};
class DoomFileEvent : public nsRunnable {
@ -790,10 +736,8 @@ public:
CacheFileIOListener *aCallback)
: mCallback(aCallback)
, mHandle(aHandle)
, mRV(NS_ERROR_FAILURE)
{
MOZ_COUNT_CTOR(DoomFileEvent);
mTarget = static_cast<nsIEventTarget*>(NS_GetCurrentThread());
MOZ_EVENT_TRACER_NAME_OBJECT(static_cast<nsIRunnable*>(this), aHandle->Key().get());
MOZ_EVENT_TRACER_WAIT(static_cast<nsIRunnable*>(this), "net::cache::doom-background");
@ -808,26 +752,22 @@ protected:
public:
NS_IMETHOD Run()
{
if (mTarget) {
MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::doom-background");
if (mHandle->IsClosed()) {
mRV = NS_ERROR_NOT_INITIALIZED;
} else {
mRV = CacheFileIOManager::gInstance->DoomFileInternal(mHandle);
}
MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::doom-background");
nsresult rv;
MOZ_EVENT_TRACER_WAIT(static_cast<nsIRunnable*>(this), "net::cache::doom-result");
nsCOMPtr<nsIEventTarget> target;
mTarget.swap(target);
target->Dispatch(this, nsIEventTarget::DISPATCH_NORMAL);
MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::doom-background");
if (mHandle->IsClosed()) {
rv = NS_ERROR_NOT_INITIALIZED;
} else {
MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::doom-result");
if (mCallback) {
mCallback->OnFileDoomed(mHandle, mRV);
}
MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::doom-result");
rv = CacheFileIOManager::gInstance->DoomFileInternal(mHandle);
}
MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::doom-background");
MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::doom-result");
if (mCallback) {
mCallback->OnFileDoomed(mHandle, rv);
}
MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::doom-result");
return NS_OK;
}
@ -835,7 +775,6 @@ protected:
nsCOMPtr<CacheFileIOListener> mCallback;
nsCOMPtr<nsIEventTarget> mTarget;
nsRefPtr<CacheFileHandle> mHandle;
nsresult mRV;
};
class DoomFileByKeyEvent : public nsRunnable {
@ -843,7 +782,6 @@ public:
DoomFileByKeyEvent(const nsACString &aKey,
CacheFileIOListener *aCallback)
: mCallback(aCallback)
, mRV(NS_ERROR_FAILURE)
{
MOZ_COUNT_CTOR(DoomFileByKeyEvent);
@ -851,9 +789,7 @@ public:
sum.update(aKey.BeginReading(), aKey.Length());
sum.finish(mHash);
mTarget = static_cast<nsIEventTarget*>(NS_GetCurrentThread());
mIOMan = CacheFileIOManager::gInstance;
MOZ_ASSERT(mTarget);
}
protected:
@ -865,31 +801,26 @@ protected:
public:
NS_IMETHOD Run()
{
if (mTarget) {
if (!mIOMan) {
mRV = NS_ERROR_NOT_INITIALIZED;
} else {
mRV = mIOMan->DoomFileByKeyInternal(&mHash, false);
mIOMan = nullptr;
}
nsresult rv;
nsCOMPtr<nsIEventTarget> target;
mTarget.swap(target);
target->Dispatch(this, nsIEventTarget::DISPATCH_NORMAL);
if (!mIOMan) {
rv = NS_ERROR_NOT_INITIALIZED;
} else {
if (mCallback) {
mCallback->OnFileDoomed(nullptr, mRV);
}
rv = mIOMan->DoomFileByKeyInternal(&mHash, false);
mIOMan = nullptr;
}
if (mCallback) {
mCallback->OnFileDoomed(nullptr, rv);
}
return NS_OK;
}
protected:
SHA1Sum::Hash mHash;
nsCOMPtr<CacheFileIOListener> mCallback;
nsCOMPtr<nsIEventTarget> mTarget;
nsRefPtr<CacheFileIOManager> mIOMan;
nsresult mRV;
};
class ReleaseNSPRHandleEvent : public nsRunnable {
@ -928,10 +859,8 @@ public:
, mTruncatePos(aTruncatePos)
, mEOFPos(aEOFPos)
, mCallback(aCallback)
, mRV(NS_ERROR_FAILURE)
{
MOZ_COUNT_CTOR(TruncateSeekSetEOFEvent);
mTarget = static_cast<nsIEventTarget*>(NS_GetCurrentThread());
}
protected:
@ -943,22 +872,19 @@ protected:
public:
NS_IMETHOD Run()
{
if (mTarget) {
if (mHandle->IsClosed()) {
mRV = NS_ERROR_NOT_INITIALIZED;
} else {
mRV = CacheFileIOManager::gInstance->TruncateSeekSetEOFInternal(
mHandle, mTruncatePos, mEOFPos);
}
nsresult rv;
nsCOMPtr<nsIEventTarget> target;
mTarget.swap(target);
target->Dispatch(this, nsIEventTarget::DISPATCH_NORMAL);
if (mHandle->IsClosed()) {
rv = NS_ERROR_NOT_INITIALIZED;
} else {
if (mCallback) {
mCallback->OnEOFSet(mHandle, mRV);
}
rv = CacheFileIOManager::gInstance->TruncateSeekSetEOFInternal(
mHandle, mTruncatePos, mEOFPos);
}
if (mCallback) {
mCallback->OnEOFSet(mHandle, rv);
}
return NS_OK;
}
@ -967,8 +893,6 @@ protected:
int64_t mTruncatePos;
int64_t mEOFPos;
nsCOMPtr<CacheFileIOListener> mCallback;
nsCOMPtr<nsIEventTarget> mTarget;
nsresult mRV;
};
class RenameFileEvent : public nsRunnable {
@ -978,10 +902,8 @@ public:
: mHandle(aHandle)
, mNewName(aNewName)
, mCallback(aCallback)
, mRV(NS_ERROR_FAILURE)
{
MOZ_COUNT_CTOR(RenameFileEvent);
mTarget = static_cast<nsIEventTarget*>(NS_GetCurrentThread());
}
protected:
@ -993,22 +915,19 @@ protected:
public:
NS_IMETHOD Run()
{
if (mTarget) {
if (mHandle->IsClosed()) {
mRV = NS_ERROR_NOT_INITIALIZED;
} else {
mRV = CacheFileIOManager::gInstance->RenameFileInternal(mHandle,
mNewName);
}
nsresult rv;
nsCOMPtr<nsIEventTarget> target;
mTarget.swap(target);
target->Dispatch(this, nsIEventTarget::DISPATCH_NORMAL);
if (mHandle->IsClosed()) {
rv = NS_ERROR_NOT_INITIALIZED;
} else {
if (mCallback) {
mCallback->OnFileRenamed(mHandle, mRV);
}
rv = CacheFileIOManager::gInstance->RenameFileInternal(mHandle,
mNewName);
}
if (mCallback) {
mCallback->OnFileRenamed(mHandle, rv);
}
return NS_OK;
}
@ -1016,8 +935,6 @@ protected:
nsRefPtr<CacheFileHandle> mHandle;
nsCString mNewName;
nsCOMPtr<CacheFileIOListener> mCallback;
nsCOMPtr<nsIEventTarget> mTarget;
nsresult mRV;
};
class InitIndexEntryEvent : public nsRunnable {
@ -1604,8 +1521,7 @@ CacheFileIOManager::Notify(nsITimer * aTimer)
// static
nsresult
CacheFileIOManager::OpenFile(const nsACString &aKey,
uint32_t aFlags, bool aResultOnAnyThread,
CacheFileIOListener *aCallback)
uint32_t aFlags, CacheFileIOListener *aCallback)
{
LOG(("CacheFileIOManager::OpenFile() [key=%s, flags=%d, listener=%p]",
PromiseFlatCString(aKey).get(), aFlags, aCallback));
@ -1618,7 +1534,7 @@ CacheFileIOManager::OpenFile(const nsACString &aKey,
}
bool priority = aFlags & CacheFileIOManager::PRIORITY;
nsRefPtr<OpenFileEvent> ev = new OpenFileEvent(aKey, aFlags, aResultOnAnyThread, aCallback);
nsRefPtr<OpenFileEvent> ev = new OpenFileEvent(aKey, aFlags, aCallback);
rv = ioMan->mIOThread->Dispatch(ev, priority
? CacheIOThread::OPEN_PRIORITY
: CacheIOThread::OPEN);
@ -1874,7 +1790,7 @@ CacheFileIOManager::CloseHandleInternal(CacheFileHandle *aHandle)
// static
nsresult
CacheFileIOManager::Read(CacheFileHandle *aHandle, int64_t aOffset,
char *aBuf, int32_t aCount, bool aResultOnAnyThread,
char *aBuf, int32_t aCount,
CacheFileIOListener *aCallback)
{
LOG(("CacheFileIOManager::Read() [handle=%p, offset=%lld, count=%d, "
@ -1888,7 +1804,7 @@ CacheFileIOManager::Read(CacheFileHandle *aHandle, int64_t aOffset,
}
nsRefPtr<ReadEvent> ev = new ReadEvent(aHandle, aOffset, aBuf, aCount,
aResultOnAnyThread, aCallback);
aCallback);
rv = ioMan->mIOThread->Dispatch(ev, aHandle->IsPriority()
? CacheIOThread::READ_PRIORITY
: CacheIOThread::READ);

View File

@ -241,10 +241,9 @@ public:
static nsresult ShutdownMetadataWriteScheduling();
static nsresult OpenFile(const nsACString &aKey,
uint32_t aFlags, bool aResultOnAnyThread,
CacheFileIOListener *aCallback);
uint32_t aFlags, CacheFileIOListener *aCallback);
static nsresult Read(CacheFileHandle *aHandle, int64_t aOffset,
char *aBuf, int32_t aCount, bool aResultOnAnyThread,
char *aBuf, int32_t aCount,
CacheFileIOListener *aCallback);
static nsresult Write(CacheFileHandle *aHandle, int64_t aOffset,
const char *aBuf, int32_t aCount, bool aValidate,

View File

@ -539,8 +539,14 @@ CacheFileInputStream::NotifyListener()
MOZ_ASSERT(mCallback);
if (!mCallbackTarget)
mCallbackTarget = NS_GetCurrentThread();
if (!mCallbackTarget) {
mCallbackTarget = CacheFileIOManager::IOTarget();
if (!mCallbackTarget) {
LOG(("CacheFileInputStream::NotifyListener() - Cannot get Cache I/O "
"thread! Using main thread for callback."));
mCallbackTarget = do_GetMainThread();
}
}
nsCOMPtr<nsIInputStreamCallback> asyncCallback =
NS_NewInputStreamReadyEvent(mCallback, mCallbackTarget);

View File

@ -206,7 +206,7 @@ CacheFileMetadata::ReadMetadata(CacheFileMetadataListener *aListener)
"offset=%lld, filesize=%lld [this=%p]", offset, size, this));
mListener = aListener;
rv = CacheFileIOManager::Read(mHandle, offset, mBuf, mBufSize, true, this);
rv = CacheFileIOManager::Read(mHandle, offset, mBuf, mBufSize, this);
if (NS_FAILED(rv)) {
LOG(("CacheFileMetadata::ReadMetadata() - CacheFileIOManager::Read() failed"
" synchronously, creating empty metadata. [this=%p, rv=0x%08x]",
@ -661,7 +661,7 @@ CacheFileMetadata::OnDataRead(CacheFileHandle *aHandle, char *aBuf,
LOG(("CacheFileMetadata::OnDataRead() - We need to read %d more bytes to "
"have full metadata. [this=%p]", missing, this));
rv = CacheFileIOManager::Read(mHandle, realOffset, mBuf, missing, true, this);
rv = CacheFileIOManager::Read(mHandle, realOffset, mBuf, missing, this);
if (NS_FAILED(rv)) {
LOG(("CacheFileMetadata::OnDataRead() - CacheFileIOManager::Read() "
"failed synchronously, creating empty metadata. [this=%p, "

View File

@ -419,8 +419,14 @@ CacheFileOutputStream::NotifyListener()
MOZ_ASSERT(mCallback);
if (!mCallbackTarget)
mCallbackTarget = NS_GetCurrentThread();
if (!mCallbackTarget) {
mCallbackTarget = CacheFileIOManager::IOTarget();
if (!mCallbackTarget) {
LOG(("CacheFileOutputStream::NotifyListener() - Cannot get Cache I/O "
"thread! Using main thread for callback."));
mCallbackTarget = do_GetMainThread();
}
}
nsCOMPtr<nsIOutputStreamCallback> asyncCallback =
NS_NewOutputStreamReadyEvent(mCallback, mCallbackTarget);

View File

@ -1565,7 +1565,6 @@ CacheIndex::WriteIndexToDisk()
rv = CacheFileIOManager::OpenFile(NS_LITERAL_CSTRING(kTempIndexName),
CacheFileIOManager::SPECIAL_FILE |
CacheFileIOManager::CREATE,
true,
mIndexFileOpener);
if (NS_FAILED(rv)) {
LOG(("CacheIndex::WriteIndexToDisk() - Can't open file [rv=0x%08x]", rv));
@ -2011,7 +2010,6 @@ CacheIndex::ReadIndexFromDisk()
rv = CacheFileIOManager::OpenFile(NS_LITERAL_CSTRING(kIndexName),
CacheFileIOManager::SPECIAL_FILE |
CacheFileIOManager::OPEN,
true,
mIndexFileOpener);
if (NS_FAILED(rv)) {
LOG(("CacheIndex::ReadIndexFromDisk() - CacheFileIOManager::OpenFile() "
@ -2024,7 +2022,6 @@ CacheIndex::ReadIndexFromDisk()
rv = CacheFileIOManager::OpenFile(NS_LITERAL_CSTRING(kJournalName),
CacheFileIOManager::SPECIAL_FILE |
CacheFileIOManager::OPEN,
true,
mJournalFileOpener);
if (NS_FAILED(rv)) {
LOG(("CacheIndex::ReadIndexFromDisk() - CacheFileIOManager::OpenFile() "
@ -2036,7 +2033,6 @@ CacheIndex::ReadIndexFromDisk()
rv = CacheFileIOManager::OpenFile(NS_LITERAL_CSTRING(kTempIndexName),
CacheFileIOManager::SPECIAL_FILE |
CacheFileIOManager::OPEN,
true,
mTmpFileOpener);
if (NS_FAILED(rv)) {
LOG(("CacheIndex::ReadIndexFromDisk() - CacheFileIOManager::OpenFile() "
@ -2077,7 +2073,7 @@ CacheIndex::StartReadingIndex()
mRWBufPos = std::min(mRWBufSize,
static_cast<uint32_t>(mIndexHandle->FileSize()));
rv = CacheFileIOManager::Read(mIndexHandle, 0, mRWBuf, mRWBufPos, true, this);
rv = CacheFileIOManager::Read(mIndexHandle, 0, mRWBuf, mRWBufPos, this);
if (NS_FAILED(rv)) {
LOG(("CacheIndex::StartReadingIndex() - CacheFileIOManager::Read() failed "
"synchronously [rv=0x%08x]", rv));
@ -2202,7 +2198,7 @@ CacheIndex::ParseRecords()
mRWBufPos = pos + toRead;
rv = CacheFileIOManager::Read(mIndexHandle, fileOffset, mRWBuf + pos, toRead,
true, this);
this);
if (NS_FAILED(rv)) {
LOG(("CacheIndex::ParseRecords() - CacheFileIOManager::Read() failed "
"synchronously [rv=0x%08x]", rv));
@ -2240,7 +2236,7 @@ CacheIndex::StartReadingJournal()
mRWBufPos = std::min(mRWBufSize,
static_cast<uint32_t>(mJournalHandle->FileSize()));
rv = CacheFileIOManager::Read(mJournalHandle, 0, mRWBuf, mRWBufPos, true, this);
rv = CacheFileIOManager::Read(mJournalHandle, 0, mRWBuf, mRWBufPos, this);
if (NS_FAILED(rv)) {
LOG(("CacheIndex::StartReadingJournal() - CacheFileIOManager::Read() failed"
" synchronously [rv=0x%08x]", rv));
@ -2315,7 +2311,7 @@ CacheIndex::ParseJournal()
mRWBufPos = pos + toRead;
rv = CacheFileIOManager::Read(mJournalHandle, fileOffset, mRWBuf + pos,
toRead, true, this);
toRead, this);
if (NS_FAILED(rv)) {
LOG(("CacheIndex::ParseJournal() - CacheFileIOManager::Read() failed "
"synchronously [rv=0x%08x]", rv));

View File

@ -1495,9 +1495,11 @@ CacheStorageService::CheckStorageEntry(CacheStorage const* aStorage,
namespace { // anon
class CacheEntryDoomByKeyCallback : public CacheFileIOListener
, public nsIRunnable
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIRUNNABLE
explicit CacheEntryDoomByKeyCallback(nsICacheEntryDoomCallback* aCallback)
: mCallback(aCallback) { }
@ -1513,6 +1515,7 @@ private:
NS_IMETHOD OnFileRenamed(CacheFileHandle *aHandle, nsresult aResult) { return NS_OK; }
nsCOMPtr<nsICacheEntryDoomCallback> mCallback;
nsresult mResult;
};
CacheEntryDoomByKeyCallback::~CacheEntryDoomByKeyCallback()
@ -1527,11 +1530,23 @@ NS_IMETHODIMP CacheEntryDoomByKeyCallback::OnFileDoomed(CacheFileHandle *aHandle
if (!mCallback)
return NS_OK;
mCallback->OnCacheEntryDoomed(aResult);
mResult = aResult;
if (NS_IsMainThread()) {
Run();
} else {
NS_DispatchToMainThread(this);
}
return NS_OK;
}
NS_IMPL_ISUPPORTS(CacheEntryDoomByKeyCallback, CacheFileIOListener);
NS_IMETHODIMP CacheEntryDoomByKeyCallback::Run()
{
mCallback->OnCacheEntryDoomed(mResult);
return NS_OK;
}
NS_IMPL_ISUPPORTS(CacheEntryDoomByKeyCallback, CacheFileIOListener, nsIRunnable);
} // anon
@ -1603,8 +1618,22 @@ CacheStorageService::DoomStorageEntry(CacheStorage const* aStorage,
return NS_OK;
}
if (aCallback)
aCallback->OnCacheEntryDoomed(NS_ERROR_NOT_AVAILABLE);
class Callback : public nsRunnable
{
public:
Callback(nsICacheEntryDoomCallback* aCallback) : mCallback(aCallback) { }
NS_IMETHODIMP Run()
{
mCallback->OnCacheEntryDoomed(NS_ERROR_NOT_AVAILABLE);
return NS_OK;
}
nsCOMPtr<nsICacheEntryDoomCallback> mCallback;
};
if (aCallback) {
nsRefPtr<nsRunnable> callback = new Callback(aCallback);
return NS_DispatchToMainThread(callback);
}
return NS_OK;
}
@ -1700,7 +1729,7 @@ CacheStorageService::DoomStorageEntries(nsCSubstring const& aContextKey,
if (aCallback) {
nsRefPtr<nsRunnable> callback = new Callback(aCallback);
return NS_DispatchToCurrentThread(callback);
return NS_DispatchToMainThread(callback);
}
return NS_OK;

View File

@ -4,25 +4,33 @@ function run_test()
var storage = getCacheStorage("disk");
var mc = new MultipleCallbacks(4, function() {
syncWithCacheIOThread(function() {
// Method asyncVisitStorage() gets the data from index on Cache I/O thread
// with INDEX priority, so it is ensured that index contains information
// about all pending writes. However, OpenCallback emulates network latency
// by postponing the writes using do_execute_soon. We must do the same here
// to make sure that all writes are posted to Cache I/O thread before we
// visit the storage.
do_execute_soon(function() {
syncWithCacheIOThread(function() {
var expectedConsumption = newCacheBackEndUsed()
? 4096
: 48;
var expectedConsumption = newCacheBackEndUsed()
? 4096
: 48;
storage.asyncVisitStorage(
// Test should store 4 entries
new VisitCallback(4, expectedConsumption, ["http://a/", "http://b/", "http://c/", "http://d/"], function() {
storage.asyncVisitStorage(
// Still 4 entries expected, now don't walk them
new VisitCallback(4, expectedConsumption, null, function() {
finish_cache2_test();
}),
false
);
}),
true
);
storage.asyncVisitStorage(
// Test should store 4 entries
new VisitCallback(4, expectedConsumption, ["http://a/", "http://b/", "http://c/", "http://d/"], function() {
storage.asyncVisitStorage(
// Still 4 entries expected, now don't walk them
new VisitCallback(4, expectedConsumption, null, function() {
finish_cache2_test();
}),
false
);
}),
true
);
});
});
}, !newCacheBackEndUsed());

View File

@ -22,10 +22,12 @@ function run_test()
asyncOpenCacheEntry("http://read/", "disk", Ci.nsICacheStorage.OPEN_NORMALLY, LoadContextInfo.default,
new OpenCallback(NEW|WAITFORWRITE, "", payload, function(entry) {
var is = entry.openInputStream(0);
do_check_eq(is.available(), kChunkSize + 10);
var payloadCheck = read_stream(is, kChunkSize + 10);
do_check_true(payloadCheck == payload); // not using do_check_eq since logger will fail for the 1/4MB string
finish_cache2_test();
pumpReadStream(is, function(read) {
do_check_eq(read.length, kChunkSize + 10);
is.close();
do_check_true(read == payload); // not using do_check_eq since logger will fail for the 1/4MB string
finish_cache2_test();
});
})
);