mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 405407: Merge nsDiskCacheStreamIO and nsDiskCacheStreamOutput. Patch originally by Alfred Kayser, updated by Josh Aas, final fix from Michal Novotny. r=michal
This commit is contained in:
parent
c5dab9e8b0
commit
da1a55564c
1
netwerk/cache/nsCacheEntryDescriptor.h
vendored
1
netwerk/cache/nsCacheEntryDescriptor.h
vendored
@ -159,6 +159,7 @@ private:
|
||||
{
|
||||
nsCacheServiceAutoLock lock(LOCK_TELEM(NSOUTPUTSTREAMWRAPPER_CLOSE));
|
||||
mDescriptor->mOutput = nullptr;
|
||||
mOutput = nullptr;
|
||||
}
|
||||
NS_RELEASE(mDescriptor);
|
||||
}
|
||||
|
482
netwerk/cache/nsDiskCacheStreams.cpp
vendored
482
netwerk/cache/nsDiskCacheStreams.cpp
vendored
@ -15,14 +15,16 @@
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
|
||||
|
||||
|
||||
// Assumptions:
|
||||
// - cache descriptors live for life of streams
|
||||
// - streams will only be used by FileTransport,
|
||||
// they will not be directly accessible to clients
|
||||
// - overlapped I/O is NOT supported
|
||||
|
||||
// we pick 16k as the max buffer size because that is the threshold above which
|
||||
// we are unable to store the data in the cache block files
|
||||
// see nsDiskCacheMap.[cpp,h]
|
||||
#define kMaxBufferSize (16 * 1024)
|
||||
|
||||
/******************************************************************************
|
||||
* nsDiskCacheInputStream
|
||||
@ -178,152 +180,13 @@ nsDiskCacheInputStream::IsNonBlocking(bool * nonBlocking)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* nsDiskCacheOutputStream
|
||||
*****************************************************************************/
|
||||
class nsDiskCacheOutputStream : public nsIOutputStream
|
||||
, public nsIDiskCacheStreamInternal
|
||||
{
|
||||
public:
|
||||
nsDiskCacheOutputStream( nsDiskCacheStreamIO * parent);
|
||||
virtual ~nsDiskCacheOutputStream();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOUTPUTSTREAM
|
||||
NS_DECL_NSIDISKCACHESTREAMINTERNAL
|
||||
|
||||
void ReleaseStreamIO() { NS_IF_RELEASE(mStreamIO); }
|
||||
|
||||
private:
|
||||
nsDiskCacheStreamIO * mStreamIO; // backpointer to parent
|
||||
bool mClosed;
|
||||
};
|
||||
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS2(nsDiskCacheOutputStream,
|
||||
nsIOutputStream,
|
||||
nsIDiskCacheStreamInternal)
|
||||
|
||||
nsDiskCacheOutputStream::nsDiskCacheOutputStream( nsDiskCacheStreamIO * parent)
|
||||
: mStreamIO(parent)
|
||||
, mClosed(false)
|
||||
{
|
||||
NS_ADDREF(mStreamIO);
|
||||
}
|
||||
|
||||
|
||||
nsDiskCacheOutputStream::~nsDiskCacheOutputStream()
|
||||
{
|
||||
Close();
|
||||
ReleaseStreamIO();
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDiskCacheOutputStream::Close()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
mozilla::TimeStamp start = mozilla::TimeStamp::Now();
|
||||
|
||||
if (!mClosed) {
|
||||
mClosed = true;
|
||||
// tell parent streamIO we are closing
|
||||
rv = mStreamIO->CloseOutputStream(this);
|
||||
}
|
||||
|
||||
mozilla::Telemetry::ID id;
|
||||
if (NS_IsMainThread())
|
||||
id = mozilla::Telemetry::NETWORK_DISK_CACHE_OUTPUT_STREAM_CLOSE_MAIN_THREAD;
|
||||
else
|
||||
id = mozilla::Telemetry::NETWORK_DISK_CACHE_OUTPUT_STREAM_CLOSE;
|
||||
|
||||
mozilla::Telemetry::AccumulateTimeDelta(id, start);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDiskCacheOutputStream::CloseInternal()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
mozilla::TimeStamp start = mozilla::TimeStamp::Now();
|
||||
|
||||
if (!mClosed) {
|
||||
mClosed = true;
|
||||
// tell parent streamIO we are closing
|
||||
rv = mStreamIO->CloseOutputStreamInternal(this);
|
||||
}
|
||||
|
||||
mozilla::Telemetry::ID id;
|
||||
if (NS_IsMainThread())
|
||||
id = mozilla::Telemetry::NETWORK_DISK_CACHE_OUTPUT_STREAM_CLOSE_INTERNAL_MAIN_THREAD;
|
||||
else
|
||||
id = mozilla::Telemetry::NETWORK_DISK_CACHE_OUTPUT_STREAM_CLOSE_INTERNAL;
|
||||
|
||||
mozilla::Telemetry::AccumulateTimeDelta(id, start);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDiskCacheOutputStream::Flush()
|
||||
{
|
||||
if (mClosed) return NS_BASE_STREAM_CLOSED;
|
||||
// yeah, yeah, well get to it...eventually...
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDiskCacheOutputStream::Write(const char *buf, uint32_t count, uint32_t *bytesWritten)
|
||||
{
|
||||
if (mClosed) return NS_BASE_STREAM_CLOSED;
|
||||
return mStreamIO->Write(buf, count, bytesWritten);
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDiskCacheOutputStream::WriteFrom(nsIInputStream *inStream, uint32_t count, uint32_t *bytesWritten)
|
||||
{
|
||||
NS_NOTREACHED("WriteFrom");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDiskCacheOutputStream::WriteSegments( nsReadSegmentFun reader,
|
||||
void * closure,
|
||||
uint32_t count,
|
||||
uint32_t * bytesWritten)
|
||||
{
|
||||
NS_NOTREACHED("WriteSegments");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDiskCacheOutputStream::IsNonBlocking(bool * nonBlocking)
|
||||
{
|
||||
*nonBlocking = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* nsDiskCacheStreamIO
|
||||
*****************************************************************************/
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS0(nsDiskCacheStreamIO)
|
||||
|
||||
// we pick 16k as the max buffer size because that is the threshold above which
|
||||
// we are unable to store the data in the cache block files
|
||||
// see nsDiskCacheMap.[cpp,h]
|
||||
#define kMaxBufferSize (16 * 1024)
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS2(nsDiskCacheStreamIO, nsIOutputStream, nsIDiskCacheStreamInternal)
|
||||
|
||||
nsDiskCacheStreamIO::nsDiskCacheStreamIO(nsDiskCacheBinding * binding)
|
||||
: mBinding(binding)
|
||||
, mOutStream(nullptr)
|
||||
, mInStreamCount(0)
|
||||
, mFD(nullptr)
|
||||
, mStreamPos(0)
|
||||
@ -332,6 +195,7 @@ nsDiskCacheStreamIO::nsDiskCacheStreamIO(nsDiskCacheBinding * binding)
|
||||
, mBufEnd(0)
|
||||
, mBufSize(0)
|
||||
, mBufDirty(false)
|
||||
, mOutputStreamIsOpen(false)
|
||||
, mBuffer(nullptr)
|
||||
{
|
||||
mDevice = (nsDiskCacheDevice *)mBinding->mCacheEntry->CacheDevice();
|
||||
@ -344,7 +208,16 @@ nsDiskCacheStreamIO::nsDiskCacheStreamIO(nsDiskCacheBinding * binding)
|
||||
|
||||
nsDiskCacheStreamIO::~nsDiskCacheStreamIO()
|
||||
{
|
||||
Close();
|
||||
if (mOutputStreamIsOpen) {
|
||||
nsCacheService::AssertOwnsLock();
|
||||
CloseInternal();
|
||||
}
|
||||
|
||||
NS_ASSERTION(!mOutputStreamIsOpen, "output stream still open");
|
||||
NS_ASSERTION(mInStreamCount == 0, "input stream still open");
|
||||
NS_ASSERTION(!mFD, "file descriptor not closed");
|
||||
|
||||
DeleteBuffer();
|
||||
|
||||
// release "death grip" on cache service
|
||||
nsCacheService *service = nsCacheService::GlobalInstance();
|
||||
@ -352,18 +225,38 @@ nsDiskCacheStreamIO::~nsDiskCacheStreamIO()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
NS_IMETHODIMP
|
||||
nsDiskCacheStreamIO::WriteFrom(nsIInputStream *inStream, uint32_t count, uint32_t *bytesWritten)
|
||||
{
|
||||
NS_NOTREACHED("WriteFrom");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDiskCacheStreamIO::WriteSegments(nsReadSegmentFun reader,
|
||||
void * closure,
|
||||
uint32_t count,
|
||||
uint32_t * bytesWritten)
|
||||
{
|
||||
NS_NOTREACHED("WriteSegments");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDiskCacheStreamIO::IsNonBlocking(bool * nonBlocking)
|
||||
{
|
||||
*nonBlocking = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDiskCacheStreamIO::Close()
|
||||
{
|
||||
// this should only be called from our destructor
|
||||
// no one is interested in us anymore, so we don't need to grab any locks
|
||||
|
||||
// assert streams closed
|
||||
NS_ASSERTION(!mOutStream, "output stream still open");
|
||||
NS_ASSERTION(mInStreamCount == 0, "input stream still open");
|
||||
NS_ASSERTION(!mFD, "file descriptor not closed");
|
||||
|
||||
DeleteBuffer();
|
||||
nsCacheServiceAutoLock lock(LOCK_TELEM(NSDISKCACHESTREAMIO_CLOSEOUTPUTSTREAM));
|
||||
return CloseInternal();
|
||||
}
|
||||
|
||||
|
||||
@ -378,8 +271,8 @@ nsDiskCacheStreamIO::GetInputStream(uint32_t offset, nsIInputStream ** inputStre
|
||||
|
||||
if (!mBinding) return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
if (mOutStream) {
|
||||
NS_WARNING("already have an output stream open");
|
||||
if (mOutputStreamIsOpen) {
|
||||
NS_WARNING("already have the output stream open");
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
@ -423,10 +316,10 @@ nsDiskCacheStreamIO::GetOutputStream(uint32_t offset, nsIOutputStream ** outputS
|
||||
*outputStream = nullptr;
|
||||
|
||||
if (!mBinding) return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
NS_ASSERTION(!mOutStream, "already have an output stream open");
|
||||
|
||||
NS_ASSERTION(!mOutputStreamIsOpen, "already have the output stream open");
|
||||
NS_ASSERTION(mInStreamCount == 0, "we already have input streams open");
|
||||
if (mOutStream || mInStreamCount) return NS_ERROR_NOT_AVAILABLE;
|
||||
if (mOutputStreamIsOpen || mInStreamCount) return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
// mBuffer lazily allocated, but might exist if a previous stream already
|
||||
// created one.
|
||||
@ -434,69 +327,97 @@ nsDiskCacheStreamIO::GetOutputStream(uint32_t offset, nsIOutputStream ** outputS
|
||||
mStreamPos = 0;
|
||||
mStreamEnd = mBinding->mCacheEntry->DataSize();
|
||||
|
||||
nsresult rv;
|
||||
if (offset) {
|
||||
rv = Seek(PR_SEEK_SET, offset);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (offset > mStreamEnd) {
|
||||
NS_WARNING("seek offset out of range");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
rv = SetEOF();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// create a new output stream
|
||||
mOutStream = new nsDiskCacheOutputStream(this);
|
||||
if (!mOutStream) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(*outputStream = mOutStream);
|
||||
nsresult rv;
|
||||
// Seek and truncate at the desired offset
|
||||
if (mBinding->mRecord.DataLocationInitialized() &&
|
||||
(mBinding->mRecord.DataFile() == 0)) {
|
||||
// File storage, seek in file
|
||||
rv = OpenCacheFile(PR_WRONLY | PR_CREATE_FILE, &mFD);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (offset) {
|
||||
int32_t newPos = PR_Seek(mFD, offset, PR_SEEK_SET);
|
||||
if (newPos == -1) {
|
||||
return NS_ErrorAccordingToNSPR();
|
||||
}
|
||||
}
|
||||
|
||||
// Truncate at start position (offset)
|
||||
rv = nsDiskCache::Truncate(mFD, offset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mStreamPos = mStreamEnd = offset;
|
||||
UpdateFileSize();
|
||||
} else if (offset) {
|
||||
// else, read and seek in mBuffer
|
||||
rv = ReadCacheBlocks();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Start writing at the provided offset
|
||||
mBufEnd = mBufPos = offset;
|
||||
mStreamPos = mStreamEnd = offset;
|
||||
}
|
||||
|
||||
mOutputStreamIsOpen = true;
|
||||
// return myself as the output stream
|
||||
NS_ADDREF(*outputStream = this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsDiskCacheStreamIO::ClearBinding()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (mBinding && mOutStream)
|
||||
if (mBinding && mOutputStreamIsOpen)
|
||||
rv = Flush();
|
||||
mBinding = nullptr;
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDiskCacheStreamIO::CloseOutputStream(nsDiskCacheOutputStream * outputStream)
|
||||
{
|
||||
nsCacheServiceAutoLock lock(LOCK_TELEM(NSDISKCACHESTREAMIO_CLOSEOUTPUTSTREAM)); // grab service lock
|
||||
return CloseOutputStreamInternal(outputStream);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDiskCacheStreamIO::CloseOutputStreamInternal(
|
||||
nsDiskCacheOutputStream * outputStream)
|
||||
NS_IMETHODIMP
|
||||
nsDiskCacheStreamIO::CloseInternal()
|
||||
{
|
||||
nsresult rv;
|
||||
mozilla::TimeStamp start = mozilla::TimeStamp::Now();
|
||||
|
||||
if (outputStream != mOutStream) {
|
||||
NS_WARNING("mismatched output streams");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
// output stream is closing
|
||||
if (!mBinding) { // if we're severed, just clear member variables
|
||||
NS_ASSERTION(!mBufDirty, "oops");
|
||||
mOutStream = nullptr;
|
||||
outputStream->ReleaseStreamIO();
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
if (mOutputStreamIsOpen) {
|
||||
if (!mBinding) { // if we're severed, just clear member variables
|
||||
NS_ASSERTION(!mBufDirty, "oops");
|
||||
} else {
|
||||
nsresult rv = Flush();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
mOutputStreamIsOpen = PR_FALSE;
|
||||
}
|
||||
|
||||
rv = Flush();
|
||||
if (NS_FAILED(rv))
|
||||
NS_WARNING("Flush() failed");
|
||||
// Make sure to always close the FileDescriptor
|
||||
if (mFD) {
|
||||
(void) PR_Close(mFD);
|
||||
mFD = nullptr;
|
||||
}
|
||||
|
||||
mOutStream = nullptr;
|
||||
return rv;
|
||||
mozilla::Telemetry::ID id;
|
||||
if (NS_IsMainThread())
|
||||
id = mozilla::Telemetry::NETWORK_DISK_CACHE_OUTPUT_STREAM_CLOSE_INTERNAL_MAIN_THREAD;
|
||||
else
|
||||
id = mozilla::Telemetry::NETWORK_DISK_CACHE_OUTPUT_STREAM_CLOSE_INTERNAL;
|
||||
|
||||
mozilla::Telemetry::AccumulateTimeDelta(id, start);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDiskCacheStreamIO::Flush()
|
||||
{
|
||||
if (!mOutputStreamIsOpen) return NS_BASE_STREAM_CLOSED;
|
||||
|
||||
NS_ASSERTION(mBinding, "oops");
|
||||
|
||||
CACHE_LOG_DEBUG(("CACHE: Flush [%x doomed=%u]\n",
|
||||
@ -589,12 +510,15 @@ nsDiskCacheStreamIO::Flush()
|
||||
// never have both output and input streams open
|
||||
// OnDataSizeChanged() will have already been called to update entry->DataSize()
|
||||
|
||||
nsresult
|
||||
NS_IMETHODIMP
|
||||
nsDiskCacheStreamIO::Write( const char * buffer,
|
||||
uint32_t count,
|
||||
uint32_t * bytesWritten)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (!mOutputStreamIsOpen) {
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
}
|
||||
|
||||
nsCacheServiceAutoLock lock(LOCK_TELEM(NSDISKCACHESTREAMIO_WRITE)); // grab service lock
|
||||
if (!mBinding) return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
@ -661,7 +585,7 @@ nsDiskCacheStreamIO::Write( const char * buffer,
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -770,7 +694,7 @@ nsDiskCacheStreamIO::FlushBufferToFile()
|
||||
record->SetDataFileGeneration(mBinding->mGeneration);
|
||||
|
||||
// allocate file
|
||||
rv = OpenCacheFile(PR_RDWR | PR_CREATE_FILE, &mFD);
|
||||
rv = OpenCacheFile(PR_WRONLY | PR_CREATE_FILE, &mFD);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
int64_t dataSize = mBinding->mCacheEntry->PredictedDataSize();
|
||||
@ -806,159 +730,3 @@ nsDiskCacheStreamIO::DeleteBuffer()
|
||||
mBufSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// NOTE: called with service lock held
|
||||
nsresult
|
||||
nsDiskCacheStreamIO::Seek(int32_t whence, int32_t offset)
|
||||
{
|
||||
int32_t newPos;
|
||||
if (!mBinding) return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
if (uint32_t(offset) > mStreamEnd) return NS_ERROR_FAILURE;
|
||||
|
||||
if (mBinding->mRecord.DataLocationInitialized()) {
|
||||
if (mBinding->mRecord.DataFile() == 0) {
|
||||
if (!mFD) {
|
||||
// we need an mFD, we better open it now
|
||||
nsresult rv = OpenCacheFile(PR_RDWR | PR_CREATE_FILE, &mFD);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mFD) {
|
||||
// do we have data in the buffer that needs to be flushed?
|
||||
if (mBufDirty) {
|
||||
// XXX optimization: are we just moving within the current buffer?
|
||||
nsresult rv = FlushBufferToFile();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
newPos = PR_Seek(mFD, offset, (PRSeekWhence)whence);
|
||||
if (newPos == -1)
|
||||
return NS_ErrorAccordingToNSPR();
|
||||
|
||||
mStreamPos = (uint32_t) newPos;
|
||||
mBufPos = 0;
|
||||
mBufEnd = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// else, seek in mBuffer
|
||||
|
||||
switch(whence) {
|
||||
case PR_SEEK_SET:
|
||||
newPos = offset;
|
||||
break;
|
||||
|
||||
case PR_SEEK_CUR: // relative from current posistion
|
||||
newPos = offset + (uint32_t)mStreamPos;
|
||||
break;
|
||||
|
||||
case PR_SEEK_END: // relative from end
|
||||
newPos = offset + (uint32_t)mBufEnd;
|
||||
break;
|
||||
|
||||
default:
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// read data into mBuffer if not read yet.
|
||||
if (mStreamEnd && !mBufEnd) {
|
||||
if (newPos > 0) {
|
||||
nsresult rv = ReadCacheBlocks();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
}
|
||||
|
||||
// stream buffer sanity checks
|
||||
NS_ASSERTION(mBufEnd <= kMaxBufferSize, "bad stream");
|
||||
NS_ASSERTION(mBufPos <= mBufEnd, "bad stream");
|
||||
NS_ASSERTION(mStreamPos == mBufPos, "bad stream");
|
||||
NS_ASSERTION(mStreamEnd == mBufEnd, "bad stream");
|
||||
|
||||
if ((newPos < 0) || (uint32_t(newPos) > mBufEnd)) {
|
||||
NS_WARNING("seek offset out of range");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
mStreamPos = newPos;
|
||||
mBufPos = newPos;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
// called only from nsDiskCacheOutputStream::Tell
|
||||
nsresult
|
||||
nsDiskCacheStreamIO::Tell(uint32_t * result)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(result);
|
||||
*result = mStreamPos;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
// NOTE: called with service lock held
|
||||
nsresult
|
||||
nsDiskCacheStreamIO::SetEOF()
|
||||
{
|
||||
nsresult rv;
|
||||
bool needToCloseFD = false;
|
||||
|
||||
NS_ASSERTION(mStreamPos <= mStreamEnd, "bad stream");
|
||||
if (!mBinding) return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
if (mBinding->mRecord.DataLocationInitialized()) {
|
||||
if (mBinding->mRecord.DataFile() == 0) {
|
||||
if (!mFD) {
|
||||
// we need an mFD, we better open it now
|
||||
rv = OpenCacheFile(PR_RDWR | PR_CREATE_FILE, &mFD);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
needToCloseFD = true;
|
||||
}
|
||||
} else {
|
||||
// data in cache block files
|
||||
if ((mStreamPos != 0) && (mStreamPos != mBufPos)) {
|
||||
// only read data if there will be some left after truncation
|
||||
rv = ReadCacheBlocks();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
// We need to make sure we reflect this change in Flush().
|
||||
// In particular, if mStreamPos is 0 and we never write to
|
||||
// the buffer, we want the storage to be deleted.
|
||||
mBufDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (mFD) {
|
||||
rv = nsDiskCache::Truncate(mFD, mStreamPos);
|
||||
#ifdef DEBUG
|
||||
uint32_t oldSizeK = (mStreamEnd + 0x03FF) >> 10;
|
||||
NS_ASSERTION(mBinding->mRecord.DataFileSize() == oldSizeK, "bad disk cache entry size");
|
||||
} else {
|
||||
// data stored in buffer.
|
||||
NS_ASSERTION(mStreamEnd <= kMaxBufferSize, "buffer truncation inadequate");
|
||||
NS_ASSERTION(mBufPos == mStreamPos, "bad stream");
|
||||
NS_ASSERTION(mBuffer ? mBufEnd == mStreamEnd : true, "bad stream");
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_ASSERTION(mStreamEnd == mBinding->mCacheEntry->DataSize(), "cache entry not updated");
|
||||
// we expect nsCacheEntryDescriptor::TransportWrapper::OpenOutputStream()
|
||||
// to eventually update the cache entry
|
||||
|
||||
mStreamEnd = mStreamPos;
|
||||
mBufEnd = mBufPos;
|
||||
|
||||
if (mFD) {
|
||||
UpdateFileSize();
|
||||
if (needToCloseFD) {
|
||||
(void) PR_Close(mFD);
|
||||
mFD = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
22
netwerk/cache/nsDiskCacheStreams.h
vendored
22
netwerk/cache/nsDiskCacheStreams.h
vendored
@ -14,30 +14,25 @@
|
||||
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsIDiskCacheStreamInternal.h"
|
||||
|
||||
#include "pratom.h"
|
||||
|
||||
class nsDiskCacheInputStream;
|
||||
class nsDiskCacheOutputStream;
|
||||
class nsDiskCacheDevice;
|
||||
|
||||
class nsDiskCacheStreamIO : public nsISupports {
|
||||
class nsDiskCacheStreamIO : public nsIOutputStream, nsIDiskCacheStreamInternal {
|
||||
public:
|
||||
nsDiskCacheStreamIO(nsDiskCacheBinding * binding);
|
||||
virtual ~nsDiskCacheStreamIO();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOUTPUTSTREAM
|
||||
NS_DECL_NSIDISKCACHESTREAMINTERNAL
|
||||
|
||||
nsresult GetInputStream(uint32_t offset, nsIInputStream ** inputStream);
|
||||
nsresult GetOutputStream(uint32_t offset, nsIOutputStream ** outputStream);
|
||||
|
||||
nsresult CloseOutputStream(nsDiskCacheOutputStream * outputStream);
|
||||
nsresult CloseOutputStreamInternal(nsDiskCacheOutputStream * outputStream);
|
||||
|
||||
nsresult Write( const char * buffer,
|
||||
uint32_t count,
|
||||
uint32_t * bytesWritten);
|
||||
|
||||
nsresult Seek(int32_t whence, int32_t offset);
|
||||
nsresult Tell(uint32_t * position);
|
||||
nsresult SetEOF();
|
||||
@ -55,20 +50,14 @@ public:
|
||||
// and OS/2 requires that it not be private
|
||||
nsDiskCacheStreamIO() { NS_NOTREACHED("oops"); }
|
||||
private:
|
||||
|
||||
|
||||
void Close();
|
||||
nsresult OpenCacheFile(int flags, PRFileDesc ** fd);
|
||||
nsresult ReadCacheBlocks();
|
||||
nsresult FlushBufferToFile();
|
||||
void UpdateFileSize();
|
||||
void DeleteBuffer();
|
||||
nsresult Flush();
|
||||
|
||||
|
||||
nsDiskCacheBinding * mBinding; // not an owning reference
|
||||
nsDiskCacheDevice * mDevice;
|
||||
nsDiskCacheOutputStream * mOutStream; // not an owning reference
|
||||
int32_t mInStreamCount;
|
||||
nsCOMPtr<nsIFile> mLocalFile;
|
||||
PRFileDesc * mFD;
|
||||
@ -78,7 +67,8 @@ private:
|
||||
uint32_t mBufPos; // current mark in buffer
|
||||
uint32_t mBufEnd; // current end of data in buffer
|
||||
uint32_t mBufSize; // current end of buffer
|
||||
bool mBufDirty;
|
||||
bool mBufDirty; // Where there is unflushed data in the buffer
|
||||
bool mOutputStreamIsOpen; // Whether the output stream is open (for writing...)
|
||||
char * mBuffer;
|
||||
|
||||
};
|
||||
|
@ -1602,18 +1602,6 @@
|
||||
"n_buckets": 10,
|
||||
"description": "Total Time spent (ms) during disk cache revalidation"
|
||||
},
|
||||
"NETWORK_DISK_CACHE_OUTPUT_STREAM_CLOSE": {
|
||||
"kind": "exponential",
|
||||
"high": "10000",
|
||||
"n_buckets": 10,
|
||||
"description": "Time spent in nsDiskCacheOutputStream::Close() on non-main thread (ms)"
|
||||
},
|
||||
"NETWORK_DISK_CACHE_OUTPUT_STREAM_CLOSE_MAIN_THREAD": {
|
||||
"kind": "exponential",
|
||||
"high": "10000",
|
||||
"n_buckets": 10,
|
||||
"description": "Time spent in nsDiskCacheOutputStream::Close() on the main thread (ms)"
|
||||
},
|
||||
"NETWORK_DISK_CACHE_OUTPUT_STREAM_CLOSE_INTERNAL": {
|
||||
"kind": "exponential",
|
||||
"high": "10000",
|
||||
|
Loading…
Reference in New Issue
Block a user