Bug 1059081 - Add a threadsafe wrapper for persistent nsMultiplexStream queues. r=nfroyd

This commit is contained in:
Josh Matthews 2015-05-14 07:55:57 -04:00
parent 4c83bb9931
commit 0861ad41c9

View File

@ -59,6 +59,7 @@ private:
const char* aFromRawSegment, uint32_t aToOffset,
uint32_t aCount, uint32_t* aWriteCount);
Mutex mLock; // Protects access to all data members.
nsTArray<nsCOMPtr<nsIInputStream>> mStreams;
uint32_t mCurrentStream;
bool mStartedReadingCurrent;
@ -119,7 +120,8 @@ TellMaybeSeek(nsISeekableStream* aSeekable, int64_t* aResult)
}
nsMultiplexInputStream::nsMultiplexInputStream()
: mCurrentStream(0),
: mLock("nsMultiplexInputStream lock"),
mCurrentStream(0),
mStartedReadingCurrent(false),
mStatus(NS_OK)
{
@ -129,6 +131,7 @@ nsMultiplexInputStream::nsMultiplexInputStream()
NS_IMETHODIMP
nsMultiplexInputStream::GetCount(uint32_t* aCount)
{
MutexAutoLock lock(mLock);
*aCount = mStreams.Length();
return NS_OK;
}
@ -150,6 +153,7 @@ SeekableStreamAtBeginning(nsIInputStream* aStream)
NS_IMETHODIMP
nsMultiplexInputStream::AppendStream(nsIInputStream* aStream)
{
MutexAutoLock lock(mLock);
NS_ASSERTION(SeekableStreamAtBeginning(aStream),
"Appended stream not at beginning.");
return mStreams.AppendElement(aStream) ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
@ -159,6 +163,7 @@ nsMultiplexInputStream::AppendStream(nsIInputStream* aStream)
NS_IMETHODIMP
nsMultiplexInputStream::InsertStream(nsIInputStream* aStream, uint32_t aIndex)
{
MutexAutoLock lock(mLock);
NS_ASSERTION(SeekableStreamAtBeginning(aStream),
"Inserted stream not at beginning.");
mStreams.InsertElementAt(aIndex, aStream);
@ -173,6 +178,7 @@ nsMultiplexInputStream::InsertStream(nsIInputStream* aStream, uint32_t aIndex)
NS_IMETHODIMP
nsMultiplexInputStream::RemoveStream(uint32_t aIndex)
{
MutexAutoLock lock(mLock);
mStreams.RemoveElementAt(aIndex);
if (mCurrentStream > aIndex) {
--mCurrentStream;
@ -187,6 +193,7 @@ nsMultiplexInputStream::RemoveStream(uint32_t aIndex)
NS_IMETHODIMP
nsMultiplexInputStream::GetStream(uint32_t aIndex, nsIInputStream** aResult)
{
MutexAutoLock lock(mLock);
*aResult = mStreams.SafeElementAt(aIndex, nullptr);
if (NS_WARN_IF(!*aResult)) {
return NS_ERROR_NOT_AVAILABLE;
@ -200,6 +207,7 @@ nsMultiplexInputStream::GetStream(uint32_t aIndex, nsIInputStream** aResult)
NS_IMETHODIMP
nsMultiplexInputStream::Close()
{
MutexAutoLock lock(mLock);
mStatus = NS_BASE_STREAM_CLOSED;
nsresult rv = NS_OK;
@ -219,6 +227,7 @@ nsMultiplexInputStream::Close()
NS_IMETHODIMP
nsMultiplexInputStream::Available(uint64_t* aResult)
{
MutexAutoLock lock(mLock);
if (NS_FAILED(mStatus)) {
return mStatus;
}
@ -243,6 +252,7 @@ nsMultiplexInputStream::Available(uint64_t* aResult)
NS_IMETHODIMP
nsMultiplexInputStream::Read(char* aBuf, uint32_t aCount, uint32_t* aResult)
{
MutexAutoLock lock(mLock);
// It is tempting to implement this method in terms of ReadSegments, but
// that would prevent this class from being used with streams that only
// implement Read (e.g., file streams).
@ -294,6 +304,8 @@ NS_IMETHODIMP
nsMultiplexInputStream::ReadSegments(nsWriteSegmentFun aWriter, void* aClosure,
uint32_t aCount, uint32_t* aResult)
{
MutexAutoLock lock(mLock);
if (mStatus == NS_BASE_STREAM_CLOSED) {
*aResult = 0;
return NS_OK;
@ -371,6 +383,8 @@ nsMultiplexInputStream::ReadSegCb(nsIInputStream* aIn, void* aClosure,
NS_IMETHODIMP
nsMultiplexInputStream::IsNonBlocking(bool* aNonBlocking)
{
MutexAutoLock lock(mLock);
uint32_t len = mStreams.Length();
if (len == 0) {
// Claim to be non-blocking, since we won't block the caller.
@ -399,6 +413,8 @@ nsMultiplexInputStream::IsNonBlocking(bool* aNonBlocking)
NS_IMETHODIMP
nsMultiplexInputStream::Seek(int32_t aWhence, int64_t aOffset)
{
MutexAutoLock lock(mLock);
if (NS_FAILED(mStatus)) {
return mStatus;
}
@ -640,6 +656,8 @@ nsMultiplexInputStream::Seek(int32_t aWhence, int64_t aOffset)
NS_IMETHODIMP
nsMultiplexInputStream::Tell(int64_t* aResult)
{
MutexAutoLock lock(mLock);
if (NS_FAILED(mStatus)) {
return mStatus;
}
@ -697,6 +715,8 @@ void
nsMultiplexInputStream::Serialize(InputStreamParams& aParams,
FileDescriptorArray& aFileDescriptors)
{
MutexAutoLock lock(mLock);
MultiplexInputStreamParams params;
uint32_t streamCount = mStreams.Length();