diff --git a/xpcom/io/nsStringStream.cpp b/xpcom/io/nsStringStream.cpp index 511f2b9034b1..4f687e257bbc 100644 --- a/xpcom/io/nsStringStream.cpp +++ b/xpcom/io/nsStringStream.cpp @@ -22,6 +22,7 @@ #include "nsIClassInfoImpl.h" #include "mozilla/Attributes.h" #include "mozilla/ipc/InputStreamUtils.h" +#include "mozilla/ReentrantMonitor.h" #include "nsIIPCSerializableInputStream.h" using namespace mozilla::ipc; @@ -48,7 +49,7 @@ class nsStringInputStream final : public nsIStringInputStream, NS_DECL_NSIIPCSERIALIZABLEINPUTSTREAM NS_DECL_NSICLONEABLEINPUTSTREAM - nsStringInputStream() : mOffset(0) { Clear(); } + nsStringInputStream() : mOffset(0), mMon("nsStringInputStream") { Clear(); } nsresult Init(nsCString&& aString); @@ -69,9 +70,13 @@ class nsStringInputStream final : public nsIStringInputStream, nsDependentCSubstring mData; uint32_t mOffset; + + mozilla::ReentrantMonitor mMon; }; nsresult nsStringInputStream::Init(nsCString&& aString) { + ReentrantMonitorAutoEnter lock(mMon); + if (!mData.Assign(std::move(aString), fallible)) { return NS_ERROR_OUT_OF_MEMORY; } @@ -109,6 +114,8 @@ nsStringInputStream::GetType(uint16_t* aType) { NS_IMETHODIMP nsStringInputStream::GetData(nsACString& data) { + ReentrantMonitorAutoEnter lock(mMon); + // The stream doesn't have any data when it is closed. We could fake it // and return an empty string here, but it seems better to keep this return // value consistent with the behavior of the other 'getter' methods. @@ -122,6 +129,8 @@ nsStringInputStream::GetData(nsACString& data) { NS_IMETHODIMP nsStringInputStream::SetData(const nsACString& aData) { + ReentrantMonitorAutoEnter lock(mMon); + if (NS_WARN_IF(!mData.Assign(aData, fallible))) { return NS_ERROR_OUT_OF_MEMORY; } @@ -142,6 +151,8 @@ nsStringInputStream::ToString(char** aResult) { NS_IMETHODIMP nsStringInputStream::SetData(const char* aData, int32_t aDataLen) { + ReentrantMonitorAutoEnter lock(mMon); + if (NS_WARN_IF(!aData)) { return NS_ERROR_INVALID_ARG; } @@ -156,6 +167,8 @@ nsStringInputStream::SetData(const char* aData, int32_t aDataLen) { NS_IMETHODIMP nsStringInputStream::AdoptData(char* aData, int32_t aDataLen) { + ReentrantMonitorAutoEnter lock(mMon); + if (NS_WARN_IF(!aData)) { return NS_ERROR_INVALID_ARG; } @@ -166,6 +179,8 @@ nsStringInputStream::AdoptData(char* aData, int32_t aDataLen) { NS_IMETHODIMP nsStringInputStream::ShareData(const char* aData, int32_t aDataLen) { + ReentrantMonitorAutoEnter lock(mMon); + if (NS_WARN_IF(!aData)) { return NS_ERROR_INVALID_ARG; } @@ -181,6 +196,8 @@ nsStringInputStream::ShareData(const char* aData, int32_t aDataLen) { NS_IMETHODIMP_(size_t) nsStringInputStream::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) { + ReentrantMonitorAutoEnter lock(mMon); + size_t n = aMallocSizeOf(this); n += mData.SizeOfExcludingThisIfUnshared(aMallocSizeOf); return n; @@ -192,12 +209,16 @@ nsStringInputStream::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) { NS_IMETHODIMP nsStringInputStream::Close() { + ReentrantMonitorAutoEnter lock(mMon); + Clear(); return NS_OK; } NS_IMETHODIMP nsStringInputStream::Available(uint64_t* aLength) { + ReentrantMonitorAutoEnter lock(mMon); + NS_ASSERTION(aLength, "null ptr"); if (Closed()) { @@ -217,6 +238,8 @@ nsStringInputStream::Read(char* aBuf, uint32_t aCount, uint32_t* aReadCount) { NS_IMETHODIMP nsStringInputStream::ReadSegments(nsWriteSegmentFun aWriter, void* aClosure, uint32_t aCount, uint32_t* aResult) { + ReentrantMonitorAutoEnter lock(mMon); + NS_ASSERTION(aResult, "null ptr"); NS_ASSERTION(Length() >= mOffset, "bad stream state"); @@ -258,6 +281,8 @@ nsStringInputStream::IsNonBlocking(bool* aNonBlocking) { NS_IMETHODIMP nsStringInputStream::Seek(int32_t aWhence, int64_t aOffset) { + ReentrantMonitorAutoEnter lock(mMon); + if (Closed()) { return NS_BASE_STREAM_CLOSED; } @@ -289,6 +314,8 @@ nsStringInputStream::Seek(int32_t aWhence, int64_t aOffset) { NS_IMETHODIMP nsStringInputStream::SetEOF() { + ReentrantMonitorAutoEnter lock(mMon); + if (Closed()) { return NS_BASE_STREAM_CLOSED; } @@ -303,6 +330,8 @@ nsStringInputStream::SetEOF() { NS_IMETHODIMP nsStringInputStream::Tell(int64_t* aOutWhere) { + ReentrantMonitorAutoEnter lock(mMon); + if (Closed()) { return NS_BASE_STREAM_CLOSED; } @@ -352,6 +381,8 @@ void nsStringInputStream::SerializeInternal(InputStreamParams& aParams, bool aDelayedStart, uint32_t aMaxSize, uint32_t* aSizeUsed, M* aManager) { + ReentrantMonitorAutoEnter lock(mMon); + MOZ_ASSERT(aSizeUsed); *aSizeUsed = 0; @@ -397,6 +428,8 @@ nsStringInputStream::GetCloneable(bool* aCloneableOut) { NS_IMETHODIMP nsStringInputStream::Clone(nsIInputStream** aCloneOut) { + ReentrantMonitorAutoEnter lock(mMon); + RefPtr ref = new nsStringInputStream(); nsresult rv = ref->SetData(mData); if (NS_WARN_IF(NS_FAILED(rv))) {