mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1010221 - Let CacheFileInputStream::ReadSegments loop over all preloaded chunks, r=michal
This commit is contained in:
parent
a5f9f97f00
commit
d781d97aa8
@ -1362,6 +1362,50 @@ CacheFile::RemoveChunkInternal(CacheFileChunk *aChunk, bool aCacheChunk)
|
||||
mChunks.Remove(aChunk->Index());
|
||||
}
|
||||
|
||||
int64_t
|
||||
CacheFile::BytesFromChunk(uint32_t aIndex)
|
||||
{
|
||||
AssertOwnsLock();
|
||||
|
||||
if (!mDataSize)
|
||||
return 0;
|
||||
|
||||
uint32_t lastChunk = (mDataSize - 1) / kChunkSize;
|
||||
if (aIndex > lastChunk)
|
||||
return 0;
|
||||
|
||||
uint32_t i;
|
||||
for (i = aIndex; i <= lastChunk; ++i) {
|
||||
CacheFileChunk * chunk;
|
||||
|
||||
chunk = mChunks.GetWeak(i);
|
||||
if (chunk) {
|
||||
MOZ_ASSERT(i == lastChunk || chunk->mDataSize == kChunkSize);
|
||||
if (chunk->IsReady()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// don't search this chunk in cached
|
||||
break;
|
||||
}
|
||||
|
||||
chunk = mCachedChunks.GetWeak(i);
|
||||
if (chunk) {
|
||||
MOZ_ASSERT(i == lastChunk || chunk->mDataSize == kChunkSize);
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// theoretic bytes in advance
|
||||
int64_t advance = int64_t(i - aIndex) * kChunkSize;
|
||||
// real bytes till the end of the file
|
||||
int64_t tail = mDataSize - (aIndex * kChunkSize);
|
||||
|
||||
return std::min(advance, tail);
|
||||
}
|
||||
|
||||
nsresult
|
||||
CacheFile::RemoveInput(CacheFileInputStream *aInput)
|
||||
{
|
||||
|
@ -140,6 +140,8 @@ private:
|
||||
nsresult RemoveChunk(CacheFileChunk *aChunk);
|
||||
void RemoveChunkInternal(CacheFileChunk *aChunk, bool aCacheChunk);
|
||||
|
||||
int64_t BytesFromChunk(uint32_t aIndex);
|
||||
|
||||
nsresult RemoveInput(CacheFileInputStream *aInput);
|
||||
nsresult RemoveOutput(CacheFileOutputStream *aOutput);
|
||||
nsresult NotifyChunkListener(CacheFileChunkListener *aCallback,
|
||||
|
@ -89,9 +89,8 @@ CacheFileInputStream::Available(uint64_t *_retval)
|
||||
*_retval = 0;
|
||||
|
||||
if (mChunk) {
|
||||
int64_t canRead;
|
||||
const char *buf;
|
||||
CanRead(&canRead, &buf);
|
||||
int64_t canRead = mFile->BytesFromChunk(mChunk->Index());
|
||||
canRead -= (mPos % kChunkSize);
|
||||
|
||||
if (canRead > 0)
|
||||
*_retval = canRead;
|
||||
@ -188,6 +187,8 @@ CacheFileInputStream::ReadSegments(nsWriteSegmentFun aWriter, void *aClosure,
|
||||
|
||||
nsresult rv;
|
||||
|
||||
*_retval = 0;
|
||||
|
||||
if (mClosed) {
|
||||
LOG(("CacheFileInputStream::ReadSegments() - Stream is closed. [this=%p, "
|
||||
"status=0x%08x]", this, mStatus));
|
||||
@ -195,67 +196,78 @@ CacheFileInputStream::ReadSegments(nsWriteSegmentFun aWriter, void *aClosure,
|
||||
if NS_FAILED(mStatus)
|
||||
return mStatus;
|
||||
|
||||
*_retval = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
EnsureCorrectChunk(false);
|
||||
if (NS_FAILED(mStatus))
|
||||
return mStatus;
|
||||
|
||||
if (!mChunk) {
|
||||
if (mListeningForChunk == -1) {
|
||||
*_retval = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
else {
|
||||
return NS_BASE_STREAM_WOULD_BLOCK;
|
||||
}
|
||||
}
|
||||
while (true) {
|
||||
if (NS_FAILED(mStatus))
|
||||
return mStatus;
|
||||
|
||||
int64_t canRead;
|
||||
const char *buf;
|
||||
CanRead(&canRead, &buf);
|
||||
|
||||
if (canRead < 0) {
|
||||
// file was truncated ???
|
||||
MOZ_ASSERT(false, "SetEOF is currenty not implemented?!");
|
||||
*_retval = 0;
|
||||
rv = NS_OK;
|
||||
}
|
||||
else if (canRead > 0) {
|
||||
uint32_t toRead = std::min(static_cast<uint32_t>(canRead), aCount);
|
||||
|
||||
// We need to release the lock to avoid lock re-entering
|
||||
#ifdef DEBUG
|
||||
int64_t oldPos = mPos;
|
||||
#endif
|
||||
mInReadSegments = true;
|
||||
lock.Unlock();
|
||||
rv = aWriter(this, aClosure, buf, 0, toRead, _retval);
|
||||
lock.Lock();
|
||||
mInReadSegments = false;
|
||||
#ifdef DEBUG
|
||||
MOZ_ASSERT(oldPos == mPos);
|
||||
#endif
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
MOZ_ASSERT(*_retval <= toRead,
|
||||
"writer should not write more than we asked it to write");
|
||||
mPos += *_retval;
|
||||
if (!mChunk) {
|
||||
if (mListeningForChunk == -1) {
|
||||
return NS_OK;
|
||||
}
|
||||
else {
|
||||
return NS_BASE_STREAM_WOULD_BLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
EnsureCorrectChunk(!(canRead < aCount && mPos % kChunkSize == 0));
|
||||
int64_t canRead;
|
||||
const char *buf;
|
||||
CanRead(&canRead, &buf);
|
||||
|
||||
rv = NS_OK;
|
||||
}
|
||||
else {
|
||||
if (mFile->mOutput)
|
||||
rv = NS_BASE_STREAM_WOULD_BLOCK;
|
||||
else {
|
||||
*_retval = 0;
|
||||
if (canRead < 0) {
|
||||
// file was truncated ???
|
||||
MOZ_ASSERT(false, "SetEOF is currenty not implemented?!");
|
||||
rv = NS_OK;
|
||||
}
|
||||
else if (canRead > 0) {
|
||||
uint32_t toRead = std::min(static_cast<uint32_t>(canRead), aCount);
|
||||
|
||||
// We need to release the lock to avoid lock re-entering
|
||||
#ifdef DEBUG
|
||||
int64_t oldPos = mPos;
|
||||
#endif
|
||||
mInReadSegments = true;
|
||||
lock.Unlock();
|
||||
uint32_t read;
|
||||
rv = aWriter(this, aClosure, buf, 0, toRead, &read);
|
||||
lock.Lock();
|
||||
mInReadSegments = false;
|
||||
#ifdef DEBUG
|
||||
MOZ_ASSERT(oldPos == mPos);
|
||||
#endif
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
MOZ_ASSERT(read <= toRead,
|
||||
"writer should not write more than we asked it to write");
|
||||
|
||||
*_retval += read;
|
||||
mPos += read;
|
||||
aCount -= read;
|
||||
|
||||
// The last chunk is released after the caller closes this stream.
|
||||
EnsureCorrectChunk(false);
|
||||
|
||||
if (mChunk && aCount) {
|
||||
// We have the next chunk! Go on.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
rv = NS_OK;
|
||||
}
|
||||
else {
|
||||
if (mFile->mOutput)
|
||||
rv = NS_BASE_STREAM_WOULD_BLOCK;
|
||||
else {
|
||||
rv = NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
LOG(("CacheFileInputStream::ReadSegments() [this=%p, rv=0x%08x, retval=%d",
|
||||
|
Loading…
Reference in New Issue
Block a user