author | Chris Jones <jones.chris.g@gmail.com> |
Thu, 31 Mar 2011 18:57:38 -0500 | |
changeset 64568 | e03c3a6df3cb8adc9d2f2c82c319c7127a8f6ace |
parent 64527 | 4beec31b9ea9ca3006ba1ed3daa46c7daca4200a |
child 64569 | 9d3277cdd833297b2fb7833b9bae39b81f6af366 |
push id | 19364 |
push user | cjones@mozilla.com |
push date | Thu, 31 Mar 2011 23:58:37 +0000 |
treeherder | mozilla-central@9d3277cdd833 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
bugs | 618052 |
milestone | 2.2a1pre |
backs out | 4beec31b9ea9ca3006ba1ed3daa46c7daca4200a |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/content/media/nsBuiltinDecoderReader.h +++ b/content/media/nsBuiltinDecoderReader.h @@ -37,16 +37,17 @@ * * ***** END LICENSE BLOCK ***** */ #if !defined(nsBuiltinDecoderReader_h_) #define nsBuiltinDecoderReader_h_ #include <nsDeque.h> #include "Layers.h" #include "ImageLayers.h" +#include "nsAutoLock.h" #include "nsClassHashtable.h" #include "mozilla/TimeStamp.h" #include "nsSize.h" #include "nsRect.h" #include "mozilla/Monitor.h" class nsBuiltinDecoderStateMachine;
--- a/content/media/nsMediaCache.cpp +++ b/content/media/nsMediaCache.cpp @@ -31,33 +31,31 @@ * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -#include "mozilla/Monitor.h" #include "mozilla/XPCOM.h" #include "nsMediaCache.h" +#include "nsAutoLock.h" #include "nsContentUtils.h" #include "nsDirectoryServiceUtils.h" #include "nsDirectoryServiceDefs.h" #include "nsNetUtil.h" #include "prio.h" #include "nsThreadUtils.h" #include "nsMediaStream.h" #include "nsMathUtils.h" #include "prlog.h" #include "nsIPrivateBrowsingService.h" -using namespace mozilla; - #ifdef PR_LOGGING PRLogModuleInfo* gMediaCacheLog; #define LOG(type, msg) PR_LOG(gMediaCacheLog, type, msg) #else #define LOG(type, msg) #endif // Readahead blocks for non-seekable streams will be limited to this @@ -74,16 +72,19 @@ static const PRUint32 REPLAY_DELAY = 30; // When looking for a reusable block, scan forward this many blocks // from the desired "best" block location to look for free blocks, // before we resort to scanning the whole cache. The idea is to try to // store runs of stream blocks close-to-consecutively in the cache if we // can. static const PRUint32 FREE_BLOCK_SCAN_LIMIT = 16; +using mozilla::TimeStamp; +using mozilla::TimeDuration; + #ifdef DEBUG // Turn this on to do very expensive cache state validation // #define DEBUG_VERIFY_CACHE #endif // There is at most one media cache (although that could quite easily be // relaxed if we wanted to manage multiple caches with independent // size limits). @@ -129,31 +130,34 @@ class nsMediaCache { public: friend class nsMediaCacheStream::BlockList; typedef nsMediaCacheStream::BlockList BlockList; enum { BLOCK_SIZE = nsMediaCacheStream::BLOCK_SIZE }; nsMediaCache() : mNextResourceID(1), - mMonitor("nsMediaCache.mMonitor"), + mMonitor(nsAutoMonitor::NewMonitor("media.cache")), mFD(nsnull), mFDCurrentPos(0), mUpdateQueued(PR_FALSE) #ifdef DEBUG , mInUpdate(PR_FALSE) #endif { MOZ_COUNT_CTOR(nsMediaCache); } ~nsMediaCache() { NS_ASSERTION(mStreams.IsEmpty(), "Stream(s) still open!"); Truncate(); NS_ASSERTION(mIndex.Length() == 0, "Blocks leaked?"); if (mFD) { PR_Close(mFD); } + if (mMonitor) { + nsAutoMonitor::DestroyMonitor(mMonitor); + } MOZ_COUNT_DTOR(nsMediaCache); } // Main thread only. Creates the backing cache file. If this fails, // then the cache is still in a semi-valid state; mFD will be null, // so all I/O on the cache file will fail. nsresult Init(); // Shut down the global cache if it's no longer needed. We shut down @@ -222,17 +226,17 @@ public: #ifdef DEBUG_VERIFY_CACHE // Verify invariants, especially block list invariants void Verify(); #else void Verify() {} #endif - Monitor& GetMonitor() { return mMonitor; } + PRMonitor* Monitor() { return mMonitor; } /** * An iterator that makes it easy to iterate through all streams that * have a given resource ID and are not closed. */ class ResourceStreamIterator { public: ResourceStreamIterator(PRInt64 aResourceID) : @@ -345,17 +349,17 @@ protected: // resource IDs to streams. PRInt64 mNextResourceID; // This member is main-thread only. It contains all the streams. nsTArray<nsMediaCacheStream*> mStreams; // The monitor protects all the data members here. Also, off-main-thread // readers that need to block will Wait() on this monitor. When new // data becomes available in the cache, we NotifyAll() on this monitor. - Monitor mMonitor; + PRMonitor* mMonitor; // The Blocks describing the cache entries. nsTArray<Block> mIndex; // The file descriptor of the cache file. The file will be deleted // by the operating system when this is closed. PRFileDesc* mFD; // The current file offset in the cache file. PRInt64 mFDCurrentPos; // The list of free blocks; they are not ordered. @@ -540,16 +544,21 @@ nsMediaCacheStream::BlockList::NotifyBlo } nsresult nsMediaCache::Init() { NS_ASSERTION(NS_IsMainThread(), "Only call on main thread"); NS_ASSERTION(!mFD, "Cache file already open?"); + if (!mMonitor) { + // the constructor failed + return NS_ERROR_OUT_OF_MEMORY; + } + nsCOMPtr<nsIFile> tmp; nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(tmp)); NS_ENSURE_SUCCESS(rv,rv); nsCOMPtr<nsILocalFile> tmpFile = do_QueryInterface(tmp); NS_ENSURE_TRUE(tmpFile != nsnull, NS_ERROR_FAILURE); // We put the media cache file in @@ -603,17 +612,17 @@ nsMediaCache::Flush() return; gMediaCache->FlushInternal(); } void nsMediaCache::FlushInternal() { - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); for (PRUint32 blockIndex = 0; blockIndex < mIndex.Length(); ++blockIndex) { FreeBlock(blockIndex); } // Truncate file, close it, and reopen Truncate(); NS_ASSERTION(mIndex.Length() == 0, "Blocks leaked?"); @@ -658,17 +667,17 @@ InitMediaCache() gMediaCache = nsnull; } } nsresult nsMediaCache::ReadCacheFile(PRInt64 aOffset, void* aData, PRInt32 aLength, PRInt32* aBytes) { - mMonitor.AssertCurrentThreadIn(); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(mMonitor); if (!mFD) return NS_ERROR_FAILURE; if (mFDCurrentPos != aOffset) { PROffset64 offset = PR_Seek64(mFD, aOffset, PR_SEEK_SET); if (offset != aOffset) return NS_ERROR_FAILURE; @@ -680,17 +689,17 @@ nsMediaCache::ReadCacheFile(PRInt64 aOff mFDCurrentPos += amount; *aBytes = amount; return NS_OK; } nsresult nsMediaCache::ReadCacheFileAllBytes(PRInt64 aOffset, void* aData, PRInt32 aLength) { - mMonitor.AssertCurrentThreadIn(); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(mMonitor); PRInt64 offset = aOffset; PRInt32 count = aLength; // Cast to char* so we can do byte-wise pointer arithmetic char* data = static_cast<char*>(aData); while (count > 0) { PRInt32 bytes; nsresult rv = ReadCacheFile(offset, data, count, &bytes); @@ -703,17 +712,17 @@ nsMediaCache::ReadCacheFileAllBytes(PRIn offset += bytes; } return NS_OK; } nsresult nsMediaCache::WriteCacheFile(PRInt64 aOffset, const void* aData, PRInt32 aLength) { - mMonitor.AssertCurrentThreadIn(); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(mMonitor); if (!mFD) return NS_ERROR_FAILURE; if (mFDCurrentPos != aOffset) { PROffset64 offset = PR_Seek64(mFD, aOffset, PR_SEEK_SET); if (offset != aOffset) return NS_ERROR_FAILURE; @@ -744,17 +753,17 @@ static PRInt32 GetMaxBlocks() maxBlocks = PR_MAX(maxBlocks, 1); return PRInt32(PR_MIN(maxBlocks, PR_INT32_MAX)); } PRInt32 nsMediaCache::FindBlockForIncomingData(TimeStamp aNow, nsMediaCacheStream* aStream) { - mMonitor.AssertCurrentThreadIn(); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(mMonitor); PRInt32 blockIndex = FindReusableBlock(aNow, aStream, aStream->mChannelOffset/BLOCK_SIZE, PR_INT32_MAX); if (blockIndex < 0 || !IsBlockFree(blockIndex)) { // The block returned is already allocated. // Don't reuse it if a) there's room to expand the cache or // b) the data we're going to store in the free block is not higher @@ -787,17 +796,17 @@ nsMediaCache::BlockIsReusable(PRInt32 aB return PR_TRUE; } void nsMediaCache::AppendMostReusableBlock(BlockList* aBlockList, nsTArray<PRUint32>* aResult, PRInt32 aBlockIndexLimit) { - mMonitor.AssertCurrentThreadIn(); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(mMonitor); PRInt32 blockIndex = aBlockList->GetLastBlock(); if (blockIndex < 0) return; do { // Don't consider blocks for pinned streams, or blocks that are // beyond the specified limit, or a block that contains a stream's // current read position (such a block contains both played data @@ -811,17 +820,17 @@ nsMediaCache::AppendMostReusableBlock(Bl } PRInt32 nsMediaCache::FindReusableBlock(TimeStamp aNow, nsMediaCacheStream* aForStream, PRInt32 aForStreamBlock, PRInt32 aMaxSearchBlockIndex) { - mMonitor.AssertCurrentThreadIn(); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(mMonitor); PRUint32 length = PR_MIN(PRUint32(aMaxSearchBlockIndex), mIndex.Length()); if (aForStream && aForStreamBlock > 0 && PRUint32(aForStreamBlock) <= aForStream->mBlocks.Length()) { PRInt32 prevCacheBlock = aForStream->mBlocks[aForStreamBlock - 1]; if (prevCacheBlock >= 0) { PRUint32 freeBlockScanEnd = @@ -905,17 +914,17 @@ nsMediaCache::GetBlockOwner(PRInt32 aBlo return &block->mOwners[i]; } return nsnull; } void nsMediaCache::SwapBlocks(PRInt32 aBlockIndex1, PRInt32 aBlockIndex2) { - mMonitor.AssertCurrentThreadIn(); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(mMonitor); Block* block1 = &mIndex[aBlockIndex1]; Block* block2 = &mIndex[aBlockIndex2]; block1->mOwners.SwapElements(block2->mOwners); // Now all references to block1 have to be replaced with block2 and // vice versa. @@ -985,17 +994,17 @@ nsMediaCache::AddBlockOwnerAsReadahead(P aStream->mBlocks[aStreamBlockIndex] = aBlockIndex; bo->mClass = READAHEAD_BLOCK; InsertReadaheadBlock(bo, aBlockIndex); } void nsMediaCache::FreeBlock(PRInt32 aBlock) { - mMonitor.AssertCurrentThreadIn(); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(mMonitor); Block* block = &mIndex[aBlock]; if (block->mOwners.IsEmpty()) { // already free return; } LOG(PR_LOG_DEBUG, ("Released block %d", aBlock)); @@ -1008,17 +1017,17 @@ nsMediaCache::FreeBlock(PRInt32 aBlock) block->mOwners.Clear(); mFreeBlocks.AddFirstBlock(aBlock); Verify(); } TimeDuration nsMediaCache::PredictNextUse(TimeStamp aNow, PRInt32 aBlock) { - mMonitor.AssertCurrentThreadIn(); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(mMonitor); NS_ASSERTION(!IsBlockFree(aBlock), "aBlock is free"); Block* block = &mIndex[aBlock]; // Blocks can be belong to multiple streams. The predicted next use // time is the earliest time predicted by any of the streams. TimeDuration result; for (PRUint32 i = 0; i < block->mOwners.Length(); ++i) { BlockOwner* bo = &block->mOwners[i]; @@ -1058,17 +1067,17 @@ nsMediaCache::PredictNextUse(TimeStamp a } } return result; } TimeDuration nsMediaCache::PredictNextUseForIncomingData(nsMediaCacheStream* aStream) { - mMonitor.AssertCurrentThreadIn(); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(mMonitor); PRInt64 bytesAhead = aStream->mChannelOffset - aStream->mStreamOffset; if (bytesAhead <= -BLOCK_SIZE) { // Hmm, no idea when data behind us will be used. Guess 24 hours. return TimeDuration::FromSeconds(24*60*60); } if (bytesAhead <= 0) return TimeDuration(0); @@ -1086,17 +1095,17 @@ nsMediaCache::Update() // The action to use for each stream. We store these so we can make // decisions while holding the cache lock but implement those decisions // without holding the cache lock, since we need to call out to // stream, decoder and element code. nsAutoTArray<StreamAction,10> actions; { - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); mUpdateQueued = PR_FALSE; #ifdef DEBUG mInUpdate = PR_TRUE; #endif PRInt32 maxBlocks = GetMaxBlocks(); TimeStamp now = TimeStamp::Now(); @@ -1368,18 +1377,18 @@ nsMediaCache::Update() default: break; } if (NS_FAILED(rv)) { // Close the streams that failed due to error. This will cause all // client Read and Seek operations on those streams to fail. Blocked // Reads will also be woken up. - MonitorAutoEnter mon(mMonitor); - stream->CloseInternal(mon); + nsAutoMonitor mon(mMonitor); + stream->CloseInternal(&mon); } } } class UpdateEvent : public nsRunnable { public: NS_IMETHOD Run() @@ -1389,34 +1398,34 @@ public: } return NS_OK; } }; void nsMediaCache::QueueUpdate() { - mMonitor.AssertCurrentThreadIn(); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(mMonitor); // Queuing an update while we're in an update raises a high risk of // triggering endless events NS_ASSERTION(!mInUpdate, "Queuing an update while we're in an update"); if (mUpdateQueued) return; mUpdateQueued = PR_TRUE; nsCOMPtr<nsIRunnable> event = new UpdateEvent(); NS_DispatchToMainThread(event); } #ifdef DEBUG_VERIFY_CACHE void nsMediaCache::Verify() { - mMonitor.AssertCurrentThreadIn(); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(mMonitor); mFreeBlocks.Verify(); for (PRUint32 i = 0; i < mStreams.Length(); ++i) { nsMediaCacheStream* stream = mStreams[i]; stream->mReadaheadBlocks.Verify(); stream->mPlayedBlocks.Verify(); stream->mMetadataBlocks.Verify(); @@ -1438,17 +1447,17 @@ nsMediaCache::Verify() } } #endif void nsMediaCache::InsertReadaheadBlock(BlockOwner* aBlockOwner, PRInt32 aBlockIndex) { - mMonitor.AssertCurrentThreadIn(); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(mMonitor); // Find the last block whose stream block is before aBlockIndex's // stream block, and insert after it nsMediaCacheStream* stream = aBlockOwner->mStream; PRInt32 readaheadIndex = stream->mReadaheadBlocks.GetLastBlock(); while (readaheadIndex >= 0) { BlockOwner* bo = GetBlockOwner(readaheadIndex, stream); NS_ASSERTION(bo, "stream must own its blocks"); @@ -1464,17 +1473,17 @@ nsMediaCache::InsertReadaheadBlock(Block stream->mReadaheadBlocks.AddFirstBlock(aBlockIndex); Verify(); } void nsMediaCache::AllocateAndWriteBlock(nsMediaCacheStream* aStream, const void* aData, nsMediaCacheStream::ReadMode aMode) { - mMonitor.AssertCurrentThreadIn(); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(mMonitor); PRInt32 streamBlockIndex = aStream->mChannelOffset/BLOCK_SIZE; // Remove all cached copies of this block ResourceStreamIterator iter(aStream->mResourceID); while (nsMediaCacheStream* stream = iter.Next()) { while (streamBlockIndex >= PRInt32(stream->mBlocks.Length())) { stream->mBlocks.AppendElement(-1); @@ -1542,39 +1551,39 @@ nsMediaCache::AllocateAndWriteBlock(nsMe QueueUpdate(); } void nsMediaCache::OpenStream(nsMediaCacheStream* aStream) { NS_ASSERTION(NS_IsMainThread(), "Only call on main thread"); - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); LOG(PR_LOG_DEBUG, ("Stream %p opened", aStream)); mStreams.AppendElement(aStream); aStream->mResourceID = mNextResourceID++; // Queue an update since a new stream has been opened. gMediaCache->QueueUpdate(); } void nsMediaCache::ReleaseStream(nsMediaCacheStream* aStream) { NS_ASSERTION(NS_IsMainThread(), "Only call on main thread"); - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); LOG(PR_LOG_DEBUG, ("Stream %p closed", aStream)); mStreams.RemoveElement(aStream); } void nsMediaCache::ReleaseStreamBlocks(nsMediaCacheStream* aStream) { - mMonitor.AssertCurrentThreadIn(); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(mMonitor); // XXX scanning the entire stream doesn't seem great, if not much of it // is cached, but the only easy alternative is to scan the entire cache // which isn't better PRUint32 length = aStream->mBlocks.Length(); for (PRUint32 i = 0; i < length; ++i) { PRInt32 blockIndex = aStream->mBlocks[i]; if (blockIndex >= 0) { @@ -1604,17 +1613,17 @@ nsMediaCache::Truncate() } } void nsMediaCache::NoteBlockUsage(nsMediaCacheStream* aStream, PRInt32 aBlockIndex, nsMediaCacheStream::ReadMode aMode, TimeStamp aNow) { - mMonitor.AssertCurrentThreadIn(); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(mMonitor); if (aBlockIndex < 0) { // this block is not in the cache yet return; } BlockOwner* bo = GetBlockOwner(aBlockIndex, aStream); if (!bo) { @@ -1636,17 +1645,17 @@ nsMediaCache::NoteBlockUsage(nsMediaCach GetListForBlock(bo)->AddFirstBlock(aBlockIndex); bo->mLastUseTime = aNow; Verify(); } void nsMediaCache::NoteSeek(nsMediaCacheStream* aStream, PRInt64 aOldOffset) { - mMonitor.AssertCurrentThreadIn(); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(mMonitor); if (aOldOffset < aStream->mStreamOffset) { // We seeked forward. Convert blocks from readahead to played. // Any readahead block that intersects the seeked-over range must // be converted. PRInt32 blockIndex = aOldOffset/BLOCK_SIZE; PRInt32 endIndex = PR_MIN((aStream->mStreamOffset + BLOCK_SIZE - 1)/BLOCK_SIZE, @@ -1692,26 +1701,26 @@ nsMediaCache::NoteSeek(nsMediaCacheStrea } } void nsMediaCacheStream::NotifyDataLength(PRInt64 aLength) { NS_ASSERTION(NS_IsMainThread(), "Only call on main thread"); - MonitorAutoEnter mon(gMediaCache->GetMonitor()); + nsAutoMonitor mon(gMediaCache->Monitor()); mStreamLength = aLength; } void nsMediaCacheStream::NotifyDataStarted(PRInt64 aOffset) { NS_ASSERTION(NS_IsMainThread(), "Only call on main thread"); - MonitorAutoEnter mon(gMediaCache->GetMonitor()); + nsAutoMonitor mon(gMediaCache->Monitor()); NS_WARN_IF_FALSE(aOffset == mChannelOffset, "Server is giving us unexpected offset"); mChannelOffset = aOffset; if (mStreamLength >= 0) { // If we started reading at a certain offset, then for sure // the stream is at least that long. mStreamLength = PR_MAX(mStreamLength, mChannelOffset); } @@ -1752,17 +1761,17 @@ nsMediaCacheStream::UpdatePrincipal(nsIP } void nsMediaCacheStream::NotifyDataReceived(PRInt64 aSize, const char* aData, nsIPrincipal* aPrincipal) { NS_ASSERTION(NS_IsMainThread(), "Only call on main thread"); - MonitorAutoEnter mon(gMediaCache->GetMonitor()); + nsAutoMonitor mon(gMediaCache->Monitor()); PRInt64 size = aSize; const char* data = aData; LOG(PR_LOG_DEBUG, ("Stream %p DataReceived at %lld count=%lld", this, (long long)mChannelOffset, (long long)aSize)); // We process the data one block (or part of a block) at a time while (size > 0) { @@ -1821,17 +1830,17 @@ nsMediaCacheStream::NotifyDataReceived(P mon.NotifyAll(); } void nsMediaCacheStream::NotifyDataEnded(nsresult aStatus) { NS_ASSERTION(NS_IsMainThread(), "Only call on main thread"); - MonitorAutoEnter mon(gMediaCache->GetMonitor()); + nsAutoMonitor mon(gMediaCache->Monitor()); PRInt32 blockOffset = PRInt32(mChannelOffset%BLOCK_SIZE); if (blockOffset > 0) { // Write back the partial block memset(reinterpret_cast<char*>(mPartialBlockBuffer) + blockOffset, 0, BLOCK_SIZE - blockOffset); gMediaCache->AllocateAndWriteBlock(this, mPartialBlockBuffer, mMetadataInPartialBlockBuffer ? MODE_METADATA : MODE_PLAYBACK); @@ -1859,113 +1868,113 @@ nsMediaCacheStream::~nsMediaCacheStream( gMediaCache->ReleaseStream(this); nsMediaCache::MaybeShutdown(); } } void nsMediaCacheStream::SetSeekable(PRBool aIsSeekable) { - MonitorAutoEnter mon(gMediaCache->GetMonitor()); + nsAutoMonitor mon(gMediaCache->Monitor()); NS_ASSERTION(mIsSeekable || aIsSeekable || mChannelOffset == 0, "channel offset must be zero when we become non-seekable"); mIsSeekable = aIsSeekable; // Queue an Update since we may change our strategy for dealing // with this stream gMediaCache->QueueUpdate(); } PRBool nsMediaCacheStream::IsSeekable() { - MonitorAutoEnter mon(gMediaCache->GetMonitor()); + nsAutoMonitor mon(gMediaCache->Monitor()); return mIsSeekable; } void nsMediaCacheStream::Close() { NS_ASSERTION(NS_IsMainThread(), "Only call on main thread"); - MonitorAutoEnter mon(gMediaCache->GetMonitor()); - CloseInternal(mon); + nsAutoMonitor mon(gMediaCache->Monitor()); + CloseInternal(&mon); // Queue an Update since we may have created more free space. Don't do // it from CloseInternal since that gets called by Update() itself // sometimes, and we try to not to queue updates from Update(). gMediaCache->QueueUpdate(); } void -nsMediaCacheStream::CloseInternal(MonitorAutoEnter& aMonitor) +nsMediaCacheStream::CloseInternal(nsAutoMonitor* aMonitor) { NS_ASSERTION(NS_IsMainThread(), "Only call on main thread"); if (mClosed) return; mClosed = PR_TRUE; gMediaCache->ReleaseStreamBlocks(this); // Wake up any blocked readers - aMonitor.NotifyAll(); + aMonitor->NotifyAll(); } void nsMediaCacheStream::Pin() { - MonitorAutoEnter mon(gMediaCache->GetMonitor()); + nsAutoMonitor mon(gMediaCache->Monitor()); ++mPinCount; // Queue an Update since we may no longer want to read more into the // cache, if this stream's block have become non-evictable gMediaCache->QueueUpdate(); } void nsMediaCacheStream::Unpin() { - MonitorAutoEnter mon(gMediaCache->GetMonitor()); + nsAutoMonitor mon(gMediaCache->Monitor()); NS_ASSERTION(mPinCount > 0, "Unbalanced Unpin"); --mPinCount; // Queue an Update since we may be able to read more into the // cache, if this stream's block have become evictable gMediaCache->QueueUpdate(); } PRInt64 nsMediaCacheStream::GetLength() { - MonitorAutoEnter mon(gMediaCache->GetMonitor()); + nsAutoMonitor mon(gMediaCache->Monitor()); return mStreamLength; } PRInt64 nsMediaCacheStream::GetNextCachedData(PRInt64 aOffset) { - MonitorAutoEnter mon(gMediaCache->GetMonitor()); + nsAutoMonitor mon(gMediaCache->Monitor()); return GetNextCachedDataInternal(aOffset); } PRInt64 nsMediaCacheStream::GetCachedDataEnd(PRInt64 aOffset) { - MonitorAutoEnter mon(gMediaCache->GetMonitor()); + nsAutoMonitor mon(gMediaCache->Monitor()); return GetCachedDataEndInternal(aOffset); } PRBool nsMediaCacheStream::IsDataCachedToEndOfStream(PRInt64 aOffset) { - MonitorAutoEnter mon(gMediaCache->GetMonitor()); + nsAutoMonitor mon(gMediaCache->Monitor()); if (mStreamLength < 0) return PR_FALSE; return GetCachedDataEndInternal(aOffset) >= mStreamLength; } PRInt64 nsMediaCacheStream::GetCachedDataEndInternal(PRInt64 aOffset) { - gMediaCache->GetMonitor().AssertCurrentThreadIn(); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(gMediaCache->Monitor()); PRUint32 startBlockIndex = aOffset/BLOCK_SIZE; PRUint32 blockIndex = startBlockIndex; while (blockIndex < mBlocks.Length() && mBlocks[blockIndex] != -1) { ++blockIndex; } PRInt64 result = blockIndex*BLOCK_SIZE; if (blockIndex == mChannelOffset/BLOCK_SIZE) { // The block containing mChannelOffset may be partially read but not @@ -1978,17 +1987,17 @@ nsMediaCacheStream::GetCachedDataEndInte result = PR_MIN(result, mStreamLength); } return PR_MAX(result, aOffset); } PRInt64 nsMediaCacheStream::GetNextCachedDataInternal(PRInt64 aOffset) { - gMediaCache->GetMonitor().AssertCurrentThreadIn(); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(gMediaCache->Monitor()); if (aOffset == mStreamLength) return -1; PRUint32 startBlockIndex = aOffset/BLOCK_SIZE; PRUint32 channelBlockIndex = mChannelOffset/BLOCK_SIZE; if (startBlockIndex == channelBlockIndex && aOffset < mChannelOffset) { @@ -2025,40 +2034,40 @@ nsMediaCacheStream::GetNextCachedDataInt NS_NOTREACHED("Should return in loop"); return -1; } void nsMediaCacheStream::SetReadMode(ReadMode aMode) { - MonitorAutoEnter mon(gMediaCache->GetMonitor()); + nsAutoMonitor mon(gMediaCache->Monitor()); if (aMode == mCurrentMode) return; mCurrentMode = aMode; gMediaCache->QueueUpdate(); } void nsMediaCacheStream::SetPlaybackRate(PRUint32 aBytesPerSecond) { NS_ASSERTION(aBytesPerSecond > 0, "Zero playback rate not allowed"); - MonitorAutoEnter mon(gMediaCache->GetMonitor()); + nsAutoMonitor mon(gMediaCache->Monitor()); if (aBytesPerSecond == mPlaybackBytesPerSecond) return; mPlaybackBytesPerSecond = aBytesPerSecond; gMediaCache->QueueUpdate(); } nsresult nsMediaCacheStream::Seek(PRInt32 aWhence, PRInt64 aOffset) { NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread"); - MonitorAutoEnter mon(gMediaCache->GetMonitor()); + nsAutoMonitor mon(gMediaCache->Monitor()); if (mClosed) return NS_ERROR_FAILURE; PRInt64 oldOffset = mStreamOffset; switch (aWhence) { case PR_SEEK_END: if (mStreamLength < 0) return NS_ERROR_FAILURE; @@ -2082,26 +2091,26 @@ nsMediaCacheStream::Seek(PRInt32 aWhence return NS_OK; } PRInt64 nsMediaCacheStream::Tell() { NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread"); - MonitorAutoEnter mon(gMediaCache->GetMonitor()); + nsAutoMonitor mon(gMediaCache->Monitor()); return mStreamOffset; } nsresult nsMediaCacheStream::Read(char* aBuffer, PRUint32 aCount, PRUint32* aBytes) { NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread"); - MonitorAutoEnter mon(gMediaCache->GetMonitor()); + nsAutoMonitor mon(gMediaCache->Monitor()); if (mClosed) return NS_ERROR_FAILURE; PRUint32 count = 0; // Read one block (or part of a block) at a time while (count < aCount) { PRUint32 streamBlock = PRUint32(mStreamOffset/BLOCK_SIZE); PRUint32 offsetInStreamBlock = @@ -2176,17 +2185,17 @@ nsMediaCacheStream::Read(char* aBuffer, return NS_OK; } nsresult nsMediaCacheStream::ReadFromCache(char* aBuffer, PRInt64 aOffset, PRInt64 aCount) { - MonitorAutoEnter mon(gMediaCache->GetMonitor()); + nsAutoMonitor mon(gMediaCache->Monitor()); if (mClosed) return NS_ERROR_FAILURE; // Read one block (or part of a block) at a time PRUint32 count = 0; PRInt64 streamOffset = aOffset; while (count < aCount) { PRUint32 streamBlock = PRUint32(streamOffset/BLOCK_SIZE); @@ -2254,17 +2263,17 @@ nsMediaCacheStream::InitAsClone(nsMediaC return NS_OK; nsresult rv = Init(); if (NS_FAILED(rv)) return rv; mResourceID = aOriginal->mResourceID; // Grab cache blocks from aOriginal as readahead blocks for our stream - MonitorAutoEnter mon(gMediaCache->GetMonitor()); + nsAutoMonitor mon(gMediaCache->Monitor()); mPrincipal = aOriginal->mPrincipal; mStreamLength = aOriginal->mStreamLength; mIsSeekable = aOriginal->mIsSeekable; // Cloned streams are initially suspended, since there is no channel open // initially for a clone. mCacheSuspended = PR_TRUE; @@ -2284,17 +2293,17 @@ nsMediaCacheStream::InitAsClone(nsMediaC return NS_OK; } nsresult nsMediaCacheStream::GetCachedRanges(nsTArray<nsByteRange>& aRanges) { // Take the monitor, so that the cached data ranges can't grow while we're // trying to loop over them. - MonitorAutoEnter mon(gMediaCache->GetMonitor()); + nsAutoMonitor mon(gMediaCache->Monitor()); // We must be pinned while running this, otherwise the cached data ranges may // shrink while we're trying to loop over them. NS_ASSERTION(mPinCount > 0, "Must be pinned"); PRInt64 startOffset = GetNextCachedData(0); while (startOffset >= 0) { PRInt64 endOffset = GetCachedDataEnd(startOffset);
--- a/content/media/nsMediaCache.h +++ b/content/media/nsMediaCache.h @@ -35,23 +35,21 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #ifndef nsMediaCache_h_ #define nsMediaCache_h_ #include "nsTArray.h" +#include "nsAutoLock.h" #include "nsIPrincipal.h" #include "nsCOMPtr.h" class nsByteRange; -namespace mozilla { -class MonitorAutoEnter; -} /** * Media applications want fast, "on demand" random access to media data, * for pausing, seeking, etc. But we are primarily interested * in transporting media data using HTTP over the Internet, which has * high latency to open a connection, requires a new connection for every * seek, may not even support seeking on some connections (especially * live streams), and uses a push model --- data comes from the server @@ -206,18 +204,16 @@ class nsMediaChannelStream; /** * If the cache fails to initialize then Init will fail, so nonstatic * methods of this class can assume gMediaCache is non-null. * * This class can be directly embedded as a value. */ class nsMediaCacheStream { - typedef mozilla::MonitorAutoEnter MonitorAutoEnter; - public: enum { // This needs to be a power of two BLOCK_SIZE = 32768 }; enum ReadMode { MODE_METADATA, MODE_PLAYBACK @@ -428,17 +424,17 @@ private: // This method assumes that the cache monitor is held and can be called on // any thread. PRInt64 GetNextCachedDataInternal(PRInt64 aOffset); // A helper function to do the work of closing the stream. Assumes // that the cache monitor is held. Main thread only. // aMonitor is the nsAutoMonitor wrapper holding the cache monitor. // This is used to NotifyAll to wake up threads that might be // blocked on reading from this stream. - void CloseInternal(MonitorAutoEnter& aMonitor); + void CloseInternal(nsAutoMonitor* aMonitor); // Update mPrincipal given that data has been received from aPrincipal void UpdatePrincipal(nsIPrincipal* aPrincipal); // These fields are main-thread-only. nsMediaChannelStream* mClient; nsCOMPtr<nsIPrincipal> mPrincipal; // This is a unique ID representing the resource we're loading. // All streams with the same mResourceID are loading the same
--- a/content/media/nsMediaDecoder.cpp +++ b/content/media/nsMediaDecoder.cpp @@ -42,27 +42,26 @@ #include "prlog.h" #include "prmem.h" #include "nsIFrame.h" #include "nsIDocument.h" #include "nsThreadUtils.h" #include "nsIDOMHTMLMediaElement.h" #include "nsNetUtil.h" #include "nsHTMLMediaElement.h" +#include "nsAutoLock.h" #include "nsIRenderingContext.h" #include "gfxContext.h" #include "nsPresContext.h" #include "nsDOMError.h" #include "nsDisplayList.h" #ifdef MOZ_SVG #include "nsSVGEffects.h" #endif -using namespace mozilla; - // Number of milliseconds between progress events as defined by spec #define PROGRESS_MS 350 // Number of milliseconds of no data before a stall event is fired as defined by spec #define STALL_MS 3000 // Number of estimated seconds worth of data we need to have buffered // ahead of the current playback position before we allow the media decoder @@ -71,36 +70,42 @@ using namespace mozilla; // nsMediaDecoder::CanPlayThrough() calculation more stable in the case of // fluctuating bitrates. #define CAN_PLAY_THROUGH_MARGIN 10 nsMediaDecoder::nsMediaDecoder() : mElement(0), mRGBWidth(-1), mRGBHeight(-1), - mVideoUpdateLock("nsMediaDecoder.mVideoUpdateLock"), + mVideoUpdateLock(nsnull), mPixelAspectRatio(1.0), mFrameBufferLength(0), mPinnedForSeek(PR_FALSE), mSizeChanged(PR_FALSE), mImageContainerSizeChanged(PR_FALSE), mShuttingDown(PR_FALSE) { MOZ_COUNT_CTOR(nsMediaDecoder); } nsMediaDecoder::~nsMediaDecoder() { + if (mVideoUpdateLock) { + nsAutoLock::DestroyLock(mVideoUpdateLock); + mVideoUpdateLock = nsnull; + } MOZ_COUNT_DTOR(nsMediaDecoder); } PRBool nsMediaDecoder::Init(nsHTMLMediaElement* aElement) { mElement = aElement; - return PR_TRUE; + mVideoUpdateLock = nsAutoLock::NewLock("nsMediaDecoder::mVideoUpdateLock"); + + return mVideoUpdateLock != nsnull; } void nsMediaDecoder::Shutdown() { StopProgress(); mElement = nsnull; } @@ -132,17 +137,17 @@ void nsMediaDecoder::Invalidate() { if (!mElement) return; nsIFrame* frame = mElement->GetPrimaryFrame(); PRBool invalidateFrame = PR_FALSE; { - MutexAutoLock lock(mVideoUpdateLock); + nsAutoLock lock(mVideoUpdateLock); // Get mImageContainerSizeChanged while holding the lock. invalidateFrame = mImageContainerSizeChanged; mImageContainerSizeChanged = PR_FALSE; if (mSizeChanged) { nsIntSize scaledSize(mRGBWidth, mRGBHeight); // Apply the aspect ratio to produce the intrinsic size we report @@ -248,17 +253,17 @@ void nsMediaDecoder::FireTimeUpdate() mElement->FireTimeUpdate(PR_TRUE); } void nsMediaDecoder::SetVideoData(const gfxIntSize& aSize, float aPixelAspectRatio, Image* aImage, TimeStamp aTarget) { - MutexAutoLock lock(mVideoUpdateLock); + nsAutoLock lock(mVideoUpdateLock); if (mRGBWidth != aSize.width || mRGBHeight != aSize.height || mPixelAspectRatio != aPixelAspectRatio) { mRGBWidth = aSize.width; mRGBHeight = aSize.height; mPixelAspectRatio = aPixelAspectRatio; mSizeChanged = PR_TRUE; } @@ -277,17 +282,17 @@ void nsMediaDecoder::SetVideoData(const } } mPaintTarget = aTarget; } double nsMediaDecoder::GetFrameDelay() { - MutexAutoLock lock(mVideoUpdateLock); + nsAutoLock lock(mVideoUpdateLock); return mPaintDelay.ToSeconds(); } void nsMediaDecoder::PinForSeek() { nsMediaStream* stream = GetCurrentStream(); if (!stream || mPinnedForSeek) { return;
--- a/content/media/nsMediaDecoder.h +++ b/content/media/nsMediaDecoder.h @@ -43,17 +43,16 @@ #include "nsIPrincipal.h" #include "nsSize.h" #include "prlog.h" #include "gfxContext.h" #include "gfxRect.h" #include "nsITimer.h" #include "ImageLayers.h" #include "mozilla/Monitor.h" -#include "mozilla/Mutex.h" class nsHTMLMediaElement; class nsMediaStream; class nsIStreamListener; class nsTimeRanges; // The size to use for audio data frames in MozAudioAvailable events. // This value is per channel, and is chosen to give ~43 fps of events, @@ -85,17 +84,16 @@ private: class nsMediaDecoder : public nsIObserver { public: typedef mozilla::TimeStamp TimeStamp; typedef mozilla::TimeDuration TimeDuration; typedef mozilla::layers::ImageContainer ImageContainer; typedef mozilla::layers::Image Image; typedef mozilla::Monitor Monitor; - typedef mozilla::Mutex Mutex; nsMediaDecoder(); virtual ~nsMediaDecoder(); // Create a new decoder of the same type as this one. virtual nsMediaDecoder* Clone() = 0; // Perform any initialization required for the decoder. @@ -438,17 +436,17 @@ protected: // is used in the decoder backend threads and the main thread // to ensure that repainting the video does not use these // values while they are out of sync (width changed but // not height yet, etc). // Backends that are updating the height, width or writing // to the RGB buffer must obtain this lock first to ensure that // the video element does not use video data or sizes that are // in the midst of being changed. - Mutex mVideoUpdateLock; + PRLock* mVideoUpdateLock; // Pixel aspect ratio (ratio of the pixel width to pixel height) float mPixelAspectRatio; // The framebuffer size to use for audioavailable events. PRUint32 mFrameBufferLength; // PR_TRUE when our media stream has been pinned. We pin the stream
--- a/content/media/nsMediaStream.cpp +++ b/content/media/nsMediaStream.cpp @@ -30,21 +30,21 @@ * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -#include "mozilla/Mutex.h" #include "nsDebug.h" #include "nsMediaStream.h" #include "nsMediaDecoder.h" #include "nsNetUtil.h" +#include "nsAutoLock.h" #include "nsThreadUtils.h" #include "nsIFile.h" #include "nsIFileChannel.h" #include "nsIHttpChannel.h" #include "nsISeekableStream.h" #include "nsIInputStream.h" #include "nsIOutputStream.h" #include "nsIRequestObserver.h" @@ -56,35 +56,38 @@ #include "nsDOMError.h" #include "nsICachingChannel.h" #include "nsURILoader.h" #include "nsIAsyncVerifyRedirectCallback.h" #define HTTP_OK_CODE 200 #define HTTP_PARTIAL_RESPONSE_CODE 206 -using namespace mozilla; +using mozilla::TimeStamp; nsMediaChannelStream::nsMediaChannelStream(nsMediaDecoder* aDecoder, nsIChannel* aChannel, nsIURI* aURI) : nsMediaStream(aDecoder, aChannel, aURI), mOffset(0), mSuspendCount(0), mReopenOnError(PR_FALSE), mIgnoreClose(PR_FALSE), mCacheStream(this), - mLock("nsMediaChannelStream.mLock"), + mLock(nsAutoLock::NewLock("media.channel.stream")), mCacheSuspendCount(0) { } nsMediaChannelStream::~nsMediaChannelStream() { if (mListener) { // Kill its reference to us since we're going away mListener->Revoke(); } + if (mLock) { + nsAutoLock::DestroyLock(mLock); + } } // nsMediaChannelStream::Listener just observes the channel and // forwards notifications to the nsMediaChannelStream. We use multiple // listener objects so that when we open a new stream for a seek we can // disconnect the old listener from the nsMediaChannelStream and hook up // a new listener, so notifications from the old channel are discarded // and don't confuse us. @@ -263,17 +266,17 @@ nsMediaChannelStream::OnStartRequest(nsI PRBool fromCache = PR_FALSE; rv = cc->IsFromCache(&fromCache); if (NS_SUCCEEDED(rv) && !fromCache) { cc->SetCacheAsFile(PR_TRUE); } } { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); mChannelStatistics.Start(TimeStamp::Now()); } mReopenOnError = PR_FALSE; mIgnoreClose = PR_FALSE; if (mSuspendCount > 0) { // Re-suspend the channel if it needs to be suspended mChannel->Suspend(); @@ -289,17 +292,17 @@ nsMediaChannelStream::OnStartRequest(nsI nsresult nsMediaChannelStream::OnStopRequest(nsIRequest* aRequest, nsresult aStatus) { NS_ASSERTION(mChannel.get() == aRequest, "Wrong channel!"); NS_ASSERTION(mSuspendCount == 0, "How can OnStopRequest fire while we're suspended?"); { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); mChannelStatistics.Stop(TimeStamp::Now()); } // Note that aStatus might have succeeded --- this might be a normal close // --- even in situations where the server cut us off because we were // suspended. So we need to "reopen on error" in that case too. The only // cases where we don't need to reopen are when *we* closed the stream. // But don't reopen if we need to seek and we don't think we can... that would @@ -375,17 +378,17 @@ nsMediaChannelStream::CopySegmentToCache nsresult nsMediaChannelStream::OnDataAvailable(nsIRequest* aRequest, nsIInputStream* aStream, PRUint32 aCount) { NS_ASSERTION(mChannel.get() == aRequest, "Wrong channel!"); { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); mChannelStatistics.AddBytes(aCount); } CopySegmentClosure closure; nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager(); if (secMan && mChannel) { secMan->GetChannelPrincipal(mChannel, getter_AddRefs(closure.mPrincipal)); } @@ -404,16 +407,18 @@ nsMediaChannelStream::OnDataAvailable(ns return NS_OK; } nsresult nsMediaChannelStream::Open(nsIStreamListener **aStreamListener) { NS_ASSERTION(NS_IsMainThread(), "Only call on main thread"); + if (!mLock) + return NS_ERROR_OUT_OF_MEMORY; nsresult rv = mCacheStream.Init(); if (NS_FAILED(rv)) return rv; NS_ASSERTION(mOffset == 0, "Who set mOffset already?"); if (!mChannel) { // When we're a clone, the decoder might ask us to Open even though // we haven't established an mChannel (because we might not need one) @@ -539,17 +544,17 @@ nsMediaStream* nsMediaChannelStream::Clo return stream; } void nsMediaChannelStream::CloseChannel() { NS_ASSERTION(NS_IsMainThread(), "Only call on main thread"); { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); mChannelStatistics.Stop(TimeStamp::Now()); } if (mListener) { mListener->Revoke(); mListener = nsnull; } @@ -618,17 +623,17 @@ void nsMediaChannelStream::Suspend(PRBoo if (mChannel) { if (aCloseImmediately && mCacheStream.IsSeekable()) { // Kill off our channel right now, but don't tell anyone about it. mIgnoreClose = PR_TRUE; CloseChannel(); element->DownloadSuspended(); } else if (mSuspendCount == 0) { { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); mChannelStatistics.Stop(TimeStamp::Now()); } mChannel->Suspend(); element->DownloadSuspended(); } } ++mSuspendCount; @@ -646,17 +651,17 @@ void nsMediaChannelStream::Resume() } NS_ASSERTION(mSuspendCount > 0, "Resume without previous Suspend!"); --mSuspendCount; if (mSuspendCount == 0) { if (mChannel) { // Just wake up our existing channel { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); mChannelStatistics.Start(TimeStamp::Now()); } // if an error occurs after Resume, assume it's because the server // timed out the connection and we should reopen it. mReopenOnError = PR_TRUE; mChannel->Resume(); element->DownloadResumed(); } else { @@ -752,17 +757,17 @@ nsMediaChannelStream::CacheClientSeek(PR CloseChannel(); if (aResume) { NS_ASSERTION(mSuspendCount > 0, "Too many resumes!"); // No need to mess with the channel, since we're making a new one --mSuspendCount; { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); NS_ASSERTION(mCacheSuspendCount > 0, "CacheClientSeek(aResume=true) without previous CacheClientSuspend!"); --mCacheSuspendCount; } } nsresult rv = RecreateChannel(); if (NS_FAILED(rv)) return rv; @@ -770,31 +775,31 @@ nsMediaChannelStream::CacheClientSeek(PR mOffset = aOffset; return OpenChannel(nsnull); } nsresult nsMediaChannelStream::CacheClientSuspend() { { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); ++mCacheSuspendCount; } Suspend(PR_FALSE); mDecoder->NotifySuspendedStatusChanged(); return NS_OK; } nsresult nsMediaChannelStream::CacheClientResume() { Resume(); { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); NS_ASSERTION(mCacheSuspendCount > 0, "CacheClientResume without previous CacheClientSuspend!"); --mCacheSuspendCount; } mDecoder->NotifySuspendedStatusChanged(); return NS_OK; } @@ -814,24 +819,24 @@ PRBool nsMediaChannelStream::IsDataCachedToEndOfStream(PRInt64 aOffset) { return mCacheStream.IsDataCachedToEndOfStream(aOffset); } PRBool nsMediaChannelStream::IsSuspendedByCache() { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); return mCacheSuspendCount > 0; } PRBool nsMediaChannelStream::IsSuspended() { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); return mSuspendCount > 0; } void nsMediaChannelStream::SetReadMode(nsMediaCacheStream::ReadMode aMode) { mCacheStream.SetReadMode(aMode); } @@ -852,36 +857,39 @@ void nsMediaChannelStream::Unpin() { mCacheStream.Unpin(); } double nsMediaChannelStream::GetDownloadRate(PRPackedBool* aIsReliable) { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); return mChannelStatistics.GetRate(TimeStamp::Now(), aIsReliable); } PRInt64 nsMediaChannelStream::GetLength() { return mCacheStream.GetLength(); } class nsMediaFileStream : public nsMediaStream { public: nsMediaFileStream(nsMediaDecoder* aDecoder, nsIChannel* aChannel, nsIURI* aURI) : nsMediaStream(aDecoder, aChannel, aURI), mSize(-1), - mLock("nsMediaFileStream.mLock") + mLock(nsAutoLock::NewLock("media.file.stream")) { } ~nsMediaFileStream() { + if (mLock) { + nsAutoLock::DestroyLock(mLock); + } } // Main thread virtual nsresult Open(nsIStreamListener** aStreamListener); virtual nsresult Close(); virtual void Suspend(PRBool aCloseImmediately) {} virtual void Resume() {} virtual already_AddRefed<nsIPrincipal> GetCurrentPrincipal(); @@ -922,17 +930,17 @@ private: // The file size, or -1 if not known. Immutable after Open(). PRInt64 mSize; // This lock handles synchronisation between calls to Close() and // the Read, Seek, etc calls. Close must not be called while a // Read or Seek is in progress since it resets various internal // values to null. // This lock protects mSeekable and mInput. - Mutex mLock; + PRLock* mLock; // Seekable stream interface to file. This can be used from any // thread. nsCOMPtr<nsISeekableStream> mSeekable; // Input stream for the media data. This can be used from any // thread. nsCOMPtr<nsIInputStream> mInput; @@ -1028,17 +1036,17 @@ nsresult nsMediaFileStream::Open(nsIStre NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL); return NS_OK; } nsresult nsMediaFileStream::Close() { NS_ASSERTION(NS_IsMainThread(), "Only call on main thread"); - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); if (mChannel) { mChannel->Cancel(NS_ERROR_PARSED_DATA_CACHED); mChannel = nsnull; mInput = nsnull; mSeekable = nsnull; } return NS_OK; @@ -1074,17 +1082,17 @@ nsMediaStream* nsMediaFileStream::CloneD if (NS_FAILED(rv)) return nsnull; return new nsMediaFileStream(aDecoder, channel, mURI); } nsresult nsMediaFileStream::ReadFromCache(char* aBuffer, PRInt64 aOffset, PRUint32 aCount) { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); if (!mInput || !mSeekable) return NS_ERROR_FAILURE; PRInt64 offset = 0; nsresult res = mSeekable->Tell(&offset); NS_ENSURE_SUCCESS(res,res); res = mSeekable->Seek(nsISeekableStream::NS_SEEK_SET, aOffset); NS_ENSURE_SUCCESS(res,res); PRUint32 bytesRead = 0; @@ -1103,37 +1111,37 @@ nsresult nsMediaFileStream::ReadFromCach NS_ENSURE_SUCCESS(res,res); // Else we succeed if the reset-seek succeeds. return seekres; } nsresult nsMediaFileStream::Read(char* aBuffer, PRUint32 aCount, PRUint32* aBytes) { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); if (!mInput) return NS_ERROR_FAILURE; return mInput->Read(aBuffer, aCount, aBytes); } nsresult nsMediaFileStream::Seek(PRInt32 aWhence, PRInt64 aOffset) { NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread"); - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); if (!mSeekable) return NS_ERROR_FAILURE; return mSeekable->Seek(aWhence, aOffset); } PRInt64 nsMediaFileStream::Tell() { NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread"); - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); if (!mSeekable) return 0; PRInt64 offset = 0; mSeekable->Tell(&offset); return offset; }
--- a/content/media/nsMediaStream.h +++ b/content/media/nsMediaStream.h @@ -33,24 +33,24 @@ * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #if !defined(nsMediaStream_h_) #define nsMediaStream_h_ -#include "mozilla/Mutex.h" #include "mozilla/XPCOM.h" #include "nsIChannel.h" #include "nsIPrincipal.h" #include "nsIURI.h" #include "nsIStreamListener.h" #include "nsIChannelEventSink.h" #include "nsIInterfaceRequestor.h" +#include "prlock.h" #include "nsMediaCache.h" // For HTTP seeking, if number of bytes needing to be // seeked forward is less than this value then a read is // done rather than a byte range request. #define SEEK_VS_READ_THRESHOLD (32*1024) #define HTTP_REQUESTED_RANGE_NOT_SATISFIABLE_CODE 416 @@ -339,18 +339,16 @@ protected: * Much of its functionality is actually delegated to nsMediaCache via * an underlying nsMediaCacheStream. * * All synchronization is performed by nsMediaCacheStream; all off-main- * thread operations are delegated directly to that object. */ class nsMediaChannelStream : public nsMediaStream { - typedef mozilla::Mutex Mutex; - public: nsMediaChannelStream(nsMediaDecoder* aDecoder, nsIChannel* aChannel, nsIURI* aURI); ~nsMediaChannelStream(); // These are called on the main thread by nsMediaCache. These must // not block or grab locks, because the media cache is holding its lock. // Notify that data is available from the cache. This can happen even // if this stream didn't read any data, since another stream might have @@ -465,14 +463,14 @@ protected: // When this flag is set, we should not report the next close of the // channel. PRPackedBool mIgnoreClose; // Any thread access nsMediaCacheStream mCacheStream; // This lock protects mChannelStatistics and mCacheSuspendCount - Mutex mLock; + PRLock* mLock; nsChannelStatistics mChannelStatistics; PRUint32 mCacheSuspendCount; }; #endif
--- a/dom/src/threads/nsDOMThreadService.cpp +++ b/dom/src/threads/nsDOMThreadService.cpp @@ -54,16 +54,17 @@ #include "nsIScriptGlobalObject.h" #include "nsIServiceManager.h" #include "nsISupportsPriority.h" #include "nsIThreadPool.h" #include "nsIXPConnect.h" #include "nsPIDOMWindow.h" // Other includes +#include "nsAutoLock.h" #include "nsAutoPtr.h" #include "nsContentUtils.h" #include "nsDeque.h" #include "nsGlobalWindow.h" #include "nsIClassInfoImpl.h" #include "nsStringBuffer.h" #include "nsThreadUtils.h" #include "nsXPCOM.h" @@ -76,18 +77,16 @@ #include "nsDOMWorker.h" #include "nsDOMWorkerEvents.h" #include "nsDOMWorkerMacros.h" #include "nsDOMWorkerMessageHandler.h" #include "nsDOMWorkerPool.h" #include "nsDOMWorkerSecurityManager.h" #include "nsDOMWorkerTimeout.h" -using namespace mozilla; - #ifdef PR_LOGGING PRLogModuleInfo *gDOMThreadsLog = nsnull; #endif #define LOG(_args) PR_LOG(gDOMThreadsLog, PR_LOG_DEBUG, _args) // The maximum number of threads in the internal thread pool #define THREADPOOL_MAX_THREADS 3 @@ -368,17 +367,17 @@ public: ClearQueue(); } void PutRunnable(nsIRunnable* aRunnable, PRIntervalTime aTimeoutInterval, PRBool aClearQueue) { NS_ASSERTION(aRunnable, "Null pointer!"); - gDOMThreadService->mMonitor.AssertCurrentThreadIn(); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(gDOMThreadService->mMonitor); if (NS_LIKELY(!aTimeoutInterval)) { NS_ADDREF(aRunnable); mRunnables.Push(aRunnable); } else { NS_ASSERTION(!mCloseRunnable, "More than one close runnable?!"); if (aClearQueue) { @@ -461,17 +460,17 @@ public: // replaced outside of a request. JSAutoRequest ar2(cx); // This is usually due to a parse error in the worker script... JS_SetGlobalObject(cx, NULL); JS_SetContextPrivate(cx, NULL); } - MonitorAutoEnter mon(gDOMThreadService->mMonitor); + nsAutoMonitor mon(gDOMThreadService->mMonitor); killWorkerWhenDone = mKillWorkerWhenDone; gDOMThreadService->WorkerComplete(this); mon.NotifyAll(); } } if (killWorkerWhenDone) { nsCOMPtr<nsIRunnable> runnable = new nsDOMWorkerKillRunnable(mWorker); @@ -491,17 +490,17 @@ protected: // Loop until all the runnables are dead. } } void RunQueue(JSContext* aCx, PRBool* aCloseRunnableSet) { while (1) { nsCOMPtr<nsIRunnable> runnable; { - MonitorAutoEnter mon(gDOMThreadService->mMonitor); + nsAutoMonitor mon(gDOMThreadService->mMonitor); runnable = dont_AddRef((nsIRunnable*)mRunnables.PopFront()); if (!runnable && mCloseRunnable) { PRIntervalTime expirationTime; if (mCloseTimeoutInterval == PR_INTERVAL_NO_TIMEOUT) { expirationTime = mCloseTimeoutInterval; } @@ -568,17 +567,17 @@ DOMWorkerOperationCallback(JSContext* aC PRBool extraThreadAllowed = NS_SUCCEEDED(gDOMThreadService->ChangeThreadPoolMaxThreads(1)); // Flush JIT caches now before suspending to avoid holding memory that we // are not going to use. JS_FlushCaches(aCx); for (;;) { - MonitorAutoEnter mon(worker->Pool()->GetMonitor()); + nsAutoMonitor mon(worker->Pool()->Monitor()); // There's a small chance that the worker was canceled after our check // above in which case we shouldn't wait here. We're guaranteed not to // race here because the pool reenters its monitor after canceling each // worker in order to notify its condition variable. canceled = worker->IsCanceled(); if (!canceled && worker->IsSuspended()) { mon.Wait(); @@ -724,17 +723,17 @@ DOMWorkerErrorReporter(JSContext* aCx, } } /******************************************************************************* * nsDOMThreadService */ nsDOMThreadService::nsDOMThreadService() -: mMonitor("nsDOMThreadServer.mMonitor"), +: mMonitor(nsnull), mNavigatorStringsLoaded(PR_FALSE) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); #ifdef PR_LOGGING if (!gDOMThreadsLog) { gDOMThreadsLog = PR_NewLogModule("nsDOMThreads"); } #endif @@ -743,16 +742,20 @@ nsDOMThreadService::nsDOMThreadService() nsDOMThreadService::~nsDOMThreadService() { LOG(("DOM Thread service destroyed")); NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); Cleanup(); + + if (mMonitor) { + nsAutoMonitor::DestroyMonitor(mMonitor); + } } NS_IMPL_THREADSAFE_ISUPPORTS3(nsDOMThreadService, nsIEventTarget, nsIObserver, nsIThreadPoolListener) nsresult nsDOMThreadService::Init() @@ -779,16 +782,19 @@ nsDOMThreadService::Init() NS_ENSURE_SUCCESS(rv, rv); rv = mThreadPool->SetThreadLimit(THREADPOOL_MAX_THREADS); NS_ENSURE_SUCCESS(rv, rv); rv = mThreadPool->SetIdleThreadLimit(THREADPOOL_IDLE_THREADS); NS_ENSURE_SUCCESS(rv, rv); + mMonitor = nsAutoMonitor::NewMonitor("nsDOMThreadService::mMonitor"); + NS_ENSURE_TRUE(mMonitor, NS_ERROR_OUT_OF_MEMORY); + PRBool success = mWorkersInProgress.Init(); NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY); success = mPools.Init(); NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY); success = mThreadsafeContractIDs.Init(); NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY); @@ -879,17 +885,17 @@ nsDOMThreadService::Cleanup() // This will either be called at 'xpcom-shutdown' or earlier if the call to // Init fails somehow. We can therefore assume that all services will still // be available here. // Cancel all workers that weren't tied to a window. CancelWorkersForGlobal(nsnull); { - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); NS_ASSERTION(!mPools.Count(), "Live workers left!"); mPools.Clear(); NS_ASSERTION(!mSuspendedWorkers.Length(), "Suspended workers left!"); mSuspendedWorkers.Clear(); } @@ -944,17 +950,17 @@ nsDOMThreadService::Dispatch(nsDOMWorker if (aWorker->IsClosing() && !aTimeoutInterval) { LOG(("Will not dispatch runnable [0x%p] for closing worker [0x%p]", static_cast<void*>(aRunnable), static_cast<void*>(aWorker))); return NS_ERROR_NOT_AVAILABLE; } nsRefPtr<nsDOMWorkerRunnable> workerRunnable; { - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); if (mWorkersInProgress.Get(aWorker, getter_AddRefs(workerRunnable))) { workerRunnable->PutRunnable(aRunnable, aTimeoutInterval, aClearQueue); return NS_OK; } workerRunnable = new nsDOMWorkerRunnable(aWorker); NS_ENSURE_TRUE(workerRunnable, NS_ERROR_OUT_OF_MEMORY); @@ -967,17 +973,17 @@ nsDOMThreadService::Dispatch(nsDOMWorker nsresult rv = mThreadPool->Dispatch(workerRunnable, NS_DISPATCH_NORMAL); // XXX This is a mess and it could probably be removed once we have an // infallible malloc implementation. if (NS_FAILED(rv)) { NS_WARNING("Failed to dispatch runnable to thread pool!"); - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); // We exited the monitor after inserting the runnable into the table so make // sure we're removing the right one! nsRefPtr<nsDOMWorkerRunnable> tableRunnable; if (mWorkersInProgress.Get(aWorker, getter_AddRefs(tableRunnable)) && workerRunnable == tableRunnable) { mWorkersInProgress.Remove(aWorker); @@ -995,45 +1001,45 @@ void nsDOMThreadService::SetWorkerTimeout(nsDOMWorker* aWorker, PRIntervalTime aTimeoutInterval) { NS_ASSERTION(aWorker, "Null pointer!"); NS_ASSERTION(aTimeoutInterval, "No timeout specified!"); NS_ASSERTION(mThreadPool, "Dispatch called after 'xpcom-shutdown'!"); - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); nsRefPtr<nsDOMWorkerRunnable> workerRunnable; if (mWorkersInProgress.Get(aWorker, getter_AddRefs(workerRunnable))) { workerRunnable->SetCloseRunnableTimeout(aTimeoutInterval); } } void nsDOMThreadService::WorkerComplete(nsDOMWorkerRunnable* aRunnable) { - mMonitor.AssertCurrentThreadIn(); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(mMonitor); #ifdef DEBUG nsRefPtr<nsDOMWorker>& debugWorker = aRunnable->mWorker; nsRefPtr<nsDOMWorkerRunnable> runnable; NS_ASSERTION(mWorkersInProgress.Get(debugWorker, getter_AddRefs(runnable)) && runnable == aRunnable, "Removing a worker that isn't in our hashtable?!"); #endif mWorkersInProgress.Remove(aRunnable->mWorker); } PRBool nsDOMThreadService::QueueSuspendedWorker(nsDOMWorkerRunnable* aRunnable) { - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); #ifdef DEBUG { // Make sure that the runnable is in mWorkersInProgress. nsRefPtr<nsDOMWorkerRunnable> current; mWorkersInProgress.Get(aRunnable->mWorker, getter_AddRefs(current)); NS_ASSERTION(current == aRunnable, "Something crazy wrong here!"); } @@ -1080,49 +1086,49 @@ nsDOMThreadService::CreateJSContext() return cx.forget(); } already_AddRefed<nsDOMWorkerPool> nsDOMThreadService::GetPoolForGlobal(nsIScriptGlobalObject* aGlobalObject, PRBool aRemove) { - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); nsRefPtr<nsDOMWorkerPool> pool; mPools.Get(aGlobalObject, getter_AddRefs(pool)); if (aRemove) { mPools.Remove(aGlobalObject); } return pool.forget(); } void nsDOMThreadService::TriggerOperationCallbackForPool(nsDOMWorkerPool* aPool) { - mMonitor.AssertCurrentThreadIn(); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(mMonitor); // See if we need to trigger the operation callback on any currently running // contexts. PRUint32 contextCount = mJSContexts.Length(); for (PRUint32 index = 0; index < contextCount; index++) { JSContext*& cx = mJSContexts[index]; nsDOMWorker* worker = (nsDOMWorker*)JS_GetContextPrivate(cx); if (worker && worker->Pool() == aPool) { JS_TriggerOperationCallback(cx); } } } void nsDOMThreadService::RescheduleSuspendedWorkerForPool(nsDOMWorkerPool* aPool) { - mMonitor.AssertCurrentThreadIn(); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(mMonitor); PRUint32 count = mSuspendedWorkers.Length(); if (!count) { // Nothing to do here. return; } nsTArray<nsDOMWorkerRunnable*> others(count); @@ -1156,59 +1162,59 @@ nsDOMThreadService::RescheduleSuspendedW void nsDOMThreadService::CancelWorkersForGlobal(nsIScriptGlobalObject* aGlobalObject) { nsRefPtr<nsDOMWorkerPool> pool = GetPoolForGlobal(aGlobalObject, PR_TRUE); if (pool) { pool->Cancel(); - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); TriggerOperationCallbackForPool(pool); RescheduleSuspendedWorkerForPool(pool); } } void nsDOMThreadService::SuspendWorkersForGlobal(nsIScriptGlobalObject* aGlobalObject) { NS_ASSERTION(aGlobalObject, "Null pointer!"); nsRefPtr<nsDOMWorkerPool> pool = GetPoolForGlobal(aGlobalObject, PR_FALSE); if (pool) { pool->Suspend(); - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); TriggerOperationCallbackForPool(pool); } } void nsDOMThreadService::ResumeWorkersForGlobal(nsIScriptGlobalObject* aGlobalObject) { NS_ASSERTION(aGlobalObject, "Null pointer!"); nsRefPtr<nsDOMWorkerPool> pool = GetPoolForGlobal(aGlobalObject, PR_FALSE); if (pool) { pool->Resume(); - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); TriggerOperationCallbackForPool(pool); RescheduleSuspendedWorkerForPool(pool); } } void nsDOMThreadService::NoteEmptyPool(nsDOMWorkerPool* aPool) { NS_ASSERTION(aPool, "Null pointer!"); - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); mPools.Remove(aPool->ScriptGlobalObject()); } void nsDOMThreadService::TimeoutReady(nsDOMWorkerTimeout* aTimeout) { nsRefPtr<nsDOMWorkerTimeoutRunnable> runnable = new nsDOMWorkerTimeoutRunnable(aTimeout); @@ -1217,17 +1223,17 @@ nsDOMThreadService::TimeoutReady(nsDOMWo Dispatch(aTimeout->GetWorker(), runnable); } nsresult nsDOMThreadService::ChangeThreadPoolMaxThreads(PRInt16 aDelta) { NS_ENSURE_ARG(aDelta == 1 || aDelta == -1); - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); PRUint32 currentThreadCount; nsresult rv = mThreadPool->GetThreadLimit(¤tThreadCount); NS_ENSURE_SUCCESS(rv, rv); PRInt32 newThreadCount = (PRInt32)currentThreadCount + (PRInt32)aDelta; NS_ASSERTION(newThreadCount >= THREADPOOL_MAX_THREADS, "Can't go below initial thread count!"); @@ -1255,17 +1261,17 @@ nsDOMThreadService::ChangeThreadPoolMaxT } void nsDOMThreadService::NoteThreadsafeContractId(const nsACString& aContractId, PRBool aIsThreadsafe) { NS_ASSERTION(!aContractId.IsEmpty(), "Empty contract id!"); - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); #ifdef DEBUG { PRBool isThreadsafe; if (mThreadsafeContractIDs.Get(aContractId, &isThreadsafe)) { NS_ASSERTION(aIsThreadsafe == isThreadsafe, "Inconsistent threadsafety!"); } } @@ -1276,17 +1282,17 @@ nsDOMThreadService::NoteThreadsafeContra } } ThreadsafeStatus nsDOMThreadService::GetContractIdThreadsafeStatus(const nsACString& aContractId) { NS_ASSERTION(!aContractId.IsEmpty(), "Empty contract id!"); - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); PRBool isThreadsafe; if (mThreadsafeContractIDs.Get(aContractId, &isThreadsafe)) { return isThreadsafe ? Threadsafe : NotThreadsafe; } return Unknown; } @@ -1387,17 +1393,17 @@ nsDOMThreadService::OnThreadCreated() PRStatus status = PR_SetThreadPrivate(gJSContextIndex, cx); if (status != PR_SUCCESS) { NS_WARNING("Failed to set context on thread!"); nsContentUtils::XPConnect()->ReleaseJSContext(cx, PR_TRUE); return NS_ERROR_FAILURE; } - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); #ifdef DEBUG JSContext** newContext = #endif mJSContexts.AppendElement(cx); // We ensure the capacity of this array in Init. NS_ASSERTION(newContext, "Should never fail!"); @@ -1416,17 +1422,17 @@ nsDOMThreadService::OnThreadShuttingDown LOG(("Thread shutting down")); NS_ASSERTION(gJSContextIndex != BAD_TLS_INDEX, "No context index!"); JSContext* cx = (JSContext*)PR_GetThreadPrivate(gJSContextIndex); NS_WARN_IF_FALSE(cx, "Thread died with no context?"); if (cx) { { - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); mJSContexts.RemoveElement(cx); } JSContext* pushedCx; gThreadJSContextStack->Pop(&pushedCx); NS_ASSERTION(pushedCx == cx, "Popped the wrong context!"); gThreadJSContextStack->SetSafeJSContext(nsnull); @@ -1462,17 +1468,17 @@ nsDOMThreadService::RegisterWorker(nsDOM nsCOMPtr<nsIScriptGlobalObject> newGlobal(do_QueryInterface(innerWindow)); NS_ENSURE_TRUE(newGlobal, NS_ERROR_NO_INTERFACE); aGlobalObject = newGlobal; } nsRefPtr<nsDOMWorkerPool> pool; { - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); if (!mThreadPool) { // Shutting down! return NS_ERROR_ILLEGAL_DURING_SHUTDOWN; } mPools.Get(aGlobalObject, getter_AddRefs(pool)); } @@ -1511,17 +1517,17 @@ nsDOMThreadService::RegisterWorker(nsDOM } pool = new nsDOMWorkerPool(aGlobalObject, document); NS_ENSURE_TRUE(pool, NS_ERROR_OUT_OF_MEMORY); rv = pool->Init(); NS_ENSURE_SUCCESS(rv, rv); - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); PRBool success = mPools.Put(aGlobalObject, pool); NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY); } rv = pool->NoteWorker(aWorker); NS_ENSURE_SUCCESS(rv, rv);
--- a/dom/src/threads/nsDOMThreadService.h +++ b/dom/src/threads/nsDOMThreadService.h @@ -42,23 +42,23 @@ // Interfaces #include "nsIEventTarget.h" #include "nsIObserver.h" #include "nsIThreadPool.h" // Other includes #include "jsapi.h" -#include "mozilla/Monitor.h" #include "nsAutoPtr.h" #include "nsCOMPtr.h" #include "nsDataHashtable.h" #include "nsRefPtrHashtable.h" #include "nsStringGlue.h" #include "nsTPtrArray.h" +#include "prmon.h" #include "prlog.h" #ifdef PR_LOGGING extern PRLogModuleInfo* gDOMThreadsLog; #endif class nsDOMWorker; class nsDOMWorkerPool; @@ -180,17 +180,17 @@ private: // Our internal thread pool. nsCOMPtr<nsIThreadPool> mThreadPool; // Maps nsIScriptGlobalObject* to nsDOMWorkerPool. nsRefPtrHashtable<nsVoidPtrHashKey, nsDOMWorkerPool> mPools; // mMonitor protects all access to mWorkersInProgress and // mCreationsInProgress. - mozilla::Monitor mMonitor; + PRMonitor* mMonitor; // A map from nsDOMWorkerThread to nsDOMWorkerRunnable. nsRefPtrHashtable<nsVoidPtrHashKey, nsDOMWorkerRunnable> mWorkersInProgress; // A list of active JSContexts that we've created. Always protected with // mMonitor. nsTArray<JSContext*> mJSContexts;
--- a/dom/src/threads/nsDOMWorker.cpp +++ b/dom/src/threads/nsDOMWorker.cpp @@ -43,16 +43,17 @@ #include "nsIJSRuntimeService.h" #include "nsIXPConnect.h" #include "jscntxt.h" #ifdef MOZ_SHARK #include "jsdbgapi.h" #endif #include "nsAtomicRefcnt.h" +#include "nsAutoLock.h" #include "nsAXPCNativeCallContext.h" #include "nsContentUtils.h" #include "nsDOMClassInfo.h" #include "nsDOMClassInfoID.h" #include "nsGlobalWindow.h" #include "nsJSON.h" #include "nsJSUtils.h" #include "nsProxyRelease.h" @@ -64,18 +65,16 @@ #include "nsDOMWorkerEvents.h" #include "nsDOMWorkerLocation.h" #include "nsDOMWorkerNavigator.h" #include "nsDOMWorkerPool.h" #include "nsDOMWorkerScriptLoader.h" #include "nsDOMWorkerTimeout.h" #include "nsDOMWorkerXHR.h" -using namespace mozilla; - class TestComponentThreadsafetyRunnable : public nsIRunnable { public: NS_DECL_ISUPPORTS TestComponentThreadsafetyRunnable(const nsACString& aContractId, PRBool aService) : mContractId(aContractId), @@ -1347,17 +1346,17 @@ nsDOMWorkerFeature::Release() NS_IMPL_QUERY_INTERFACE0(nsDOMWorkerFeature) nsDOMWorker::nsDOMWorker(nsDOMWorker* aParent, nsIXPConnectWrappedNative* aParentWN, WorkerPrivilegeModel aPrivilegeModel) : mParent(aParent), mParentWN(aParentWN), mPrivilegeModel(aPrivilegeModel), - mLock("nsDOMWorker.mLock"), + mLock(nsnull), mInnerScope(nsnull), mGlobal(NULL), mNextTimeoutId(0), mFeatureSuspendDepth(0), mWrappedNative(nsnull), mErrorHandlerRecursionCount(0), mStatus(eRunning), mExpirationTime(0), @@ -1371,16 +1370,20 @@ nsDOMWorker::nsDOMWorker(nsDOMWorker* aP } nsDOMWorker::~nsDOMWorker() { if (mPool) { mPool->NoteDyingWorker(this); } + if (mLock) { + nsAutoLock::DestroyLock(mLock); + } + NS_ASSERTION(!mFeatures.Length(), "Live features!"); NS_ASSERTION(!mQueuedRunnables.Length(), "Events that never ran!"); nsCOMPtr<nsIThread> mainThread; NS_GetMainThread(getter_AddRefs(mainThread)); nsIPrincipal* principal; mPrincipal.forget(&principal); @@ -1492,31 +1495,31 @@ nsDOMWorker::PreCreate(nsISupports* aObj return NS_OK; } NS_IMETHODIMP nsDOMWorker::PostCreate(nsIXPConnectWrappedNative* aWrapper, JSContext* /* aCx */, JSObject* /* aObj */) { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); mWrappedNative = aWrapper; return NS_OK; } NS_IMETHODIMP nsDOMWorker::Trace(nsIXPConnectWrappedNative* /* aWrapper */, JSTracer* aTracer, JSObject* /*aObj */) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); PRBool canceled = PR_FALSE; { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); canceled = mStatus == eKilled; } if (!canceled) { nsDOMWorkerMessageHandler::Trace(aTracer); } return NS_OK; @@ -1529,17 +1532,17 @@ nsDOMWorker::Finalize(nsIXPConnectWrappe { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); // Don't leave dangling JSObject pointers in our handlers! ClearAllListeners(); // Clear our wrapped native now that it has died. { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); mWrappedNative = nsnull; } // Do this *after* we null out mWrappedNative so that we don't hand out a // freed pointer. if (TerminateInternal(PR_TRUE) == NS_ERROR_ILLEGAL_DURING_SHUTDOWN) { // We're shutting down, jump right to Kill. Kill(); @@ -1664,16 +1667,19 @@ nsDOMWorker::InitializeInternal(nsIScrip rv = NS_NewURI(getter_AddRefs(mBaseURI), filename); NS_ENSURE_SUCCESS(rv, rv); } } NS_ASSERTION(mPrincipal, "Should have set the principal!"); } + mLock = nsAutoLock::NewLock("nsDOMWorker::mLock"); + NS_ENSURE_TRUE(mLock, NS_ERROR_OUT_OF_MEMORY); + NS_ASSERTION(!mGlobal, "Already got a global?!"); nsCOMPtr<nsIXPConnectJSObjectHolder> thisWrapped; jsval v; rv = nsContentUtils::WrapNative(aCx, aObj, static_cast<nsIWorker*>(this), &v, getter_AddRefs(thisWrapped)); NS_ENSURE_SUCCESS(rv, rv); @@ -1722,17 +1728,17 @@ nsDOMWorker::Cancel() // canceled while close runnable is running) except that it always reports // that it is canceled when running on the main thread. This status trumps all // others (except eKilled). Have to do this because the window that created // us has gone away and had its scope cleared so XPConnect will assert all // over the place if we try to run anything. PRBool enforceTimeout = PR_FALSE; { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); NS_ASSERTION(mStatus != eCanceled, "Canceled more than once?!"); if (mStatus == eKilled) { return; } DOMWorkerStatus oldStatus = mStatus; @@ -1784,17 +1790,17 @@ nsDOMWorker::Kill() if (mKillTimer) { mKillTimer->Cancel(); mKillTimer = nsnull; } PRUint32 count, index; nsAutoTArray<nsRefPtr<nsDOMWorkerFeature>, 20> features; { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); if (mStatus == eKilled) { NS_ASSERTION(mFeatures.Length() == 0, "Features added after killed!"); return; } mStatus = eKilled; count = mFeatures.Length(); @@ -1833,17 +1839,17 @@ nsDOMWorker::Kill() void nsDOMWorker::Suspend() { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); PRBool shouldSuspendFeatures; { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); NS_ASSERTION(!mSuspended, "Suspended more than once!"); shouldSuspendFeatures = !mSuspended; mSuspended = PR_TRUE; } if (shouldSuspendFeatures) { SuspendFeatures(); } @@ -1851,17 +1857,17 @@ nsDOMWorker::Suspend() void nsDOMWorker::Resume() { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); PRBool shouldResumeFeatures; { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); #ifdef DEBUG // Should only have a mismatch if GC or Cancel happened while suspended. if (!mSuspended) { NS_ASSERTION(mStatus == eCanceled || (mStatus == eTerminated && !mWrappedNative), "Not suspended!"); } #endif @@ -1879,17 +1885,17 @@ nsDOMWorker::Resume() NS_DispatchToCurrentThread(mQueuedRunnables[index]); } mQueuedRunnables.Clear(); } PRBool nsDOMWorker::IsCanceled() { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); return IsCanceledNoLock(); } PRBool nsDOMWorker::IsCanceledNoLock() { // If we haven't started the close process then we're not canceled. if (mStatus == eRunning) { @@ -1913,24 +1919,24 @@ nsDOMWorker::IsCanceledNoLock() (mExpirationTime && mExpirationTime != PR_INTERVAL_NO_TIMEOUT && mExpirationTime <= PR_IntervalNow()) || (mStatus == eCanceled && NS_IsMainThread()); } PRBool nsDOMWorker::IsClosing() { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); return mStatus != eRunning; } PRBool nsDOMWorker::IsSuspended() { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); return mSuspended; } nsresult nsDOMWorker::PostMessageInternal(PRBool aToInner) { nsIXPConnect* xpc = nsContentUtils::XPConnect(); NS_ENSURE_TRUE(xpc, NS_ERROR_UNEXPECTED); @@ -2192,34 +2198,34 @@ nsDOMWorker::SetPool(nsDOMWorkerPool* aP mPool = aPool; } already_AddRefed<nsIXPConnectWrappedNative> nsDOMWorker::GetWrappedNative() { nsCOMPtr<nsIXPConnectWrappedNative> wrappedNative; { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); wrappedNative = mWrappedNative; } return wrappedNative.forget(); } nsresult nsDOMWorker::AddFeature(nsDOMWorkerFeature* aFeature, JSContext* aCx) { NS_ASSERTION(aFeature, "Null pointer!"); PRBool shouldSuspend; { // aCx may be null. JSAutoSuspendRequest asr(aCx); - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); if (mStatus == eKilled) { // No features may be added after we've been canceled. Sorry. return NS_ERROR_FAILURE; } nsDOMWorkerFeature** newFeature = mFeatures.AppendElement(aFeature); NS_ENSURE_TRUE(newFeature, NS_ERROR_OUT_OF_MEMORY); @@ -2242,34 +2248,34 @@ nsDOMWorker::RemoveFeature(nsDOMWorkerFe NS_ASSERTION(aFeature, "Null pointer!"); // This *must* be a nsRefPtr so that we call Release after setting FreeToDie. nsRefPtr<nsDOMWorkerFeature> feature(aFeature); { // aCx may be null. JSAutoSuspendRequest asr(aCx); - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); #ifdef DEBUG PRBool removed = #endif mFeatures.RemoveElement(aFeature); NS_ASSERTION(removed, "Feature not in the list!"); aFeature->FreeToDie(PR_TRUE); } } void nsDOMWorker::CancelTimeoutWithId(PRUint32 aId) { nsRefPtr<nsDOMWorkerFeature> foundFeature; { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); PRUint32 count = mFeatures.Length(); for (PRUint32 index = 0; index < count; index++) { nsDOMWorkerFeature*& feature = mFeatures[index]; if (feature->HasId() && feature->GetId() == aId) { foundFeature = feature; feature->FreeToDie(PR_TRUE); mFeatures.RemoveElementAt(index); break; @@ -2282,17 +2288,17 @@ nsDOMWorker::CancelTimeoutWithId(PRUint3 } } void nsDOMWorker::SuspendFeatures() { nsAutoTArray<nsRefPtr<nsDOMWorkerFeature>, 20> features; { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); // We don't really have to worry about overflow here because the only way // to do this is through recursive script loading, which uses the stack. We // would exceed our stack limit long before this counter. NS_ASSERTION(mFeatureSuspendDepth < PR_UINT32_MAX, "Shouldn't happen!"); if (++mFeatureSuspendDepth != 1) { // Allow nested suspending of timeouts. return; @@ -2311,17 +2317,17 @@ nsDOMWorker::SuspendFeatures() } } void nsDOMWorker::ResumeFeatures() { nsAutoTArray<nsRefPtr<nsDOMWorkerFeature>, 20> features; { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); NS_ASSERTION(mFeatureSuspendDepth > 0, "Shouldn't happen!"); if (--mFeatureSuspendDepth != 0) { return; } features.AppendElements(mFeatures); } @@ -2372,30 +2378,30 @@ nsDOMWorker::FireCloseRunnable(PRInterva PRBool aFromFinalize) { // Resume the worker (but not its features) if we're currently suspended. This // should only ever happen if we are being called from Cancel (page falling // out of bfcache or quitting) or Finalize, in which case all we really want // to do is unblock the waiting thread. PRBool wakeUp; { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); NS_ASSERTION(mExpirationTime == 0, "Close runnable should not be scheduled already!"); if ((wakeUp = mSuspended)) { NS_ASSERTION(mStatus == eCanceled || (mStatus == eTerminated && aFromFinalize), "How can this happen otherwise?!"); mSuspended = PR_FALSE; } } if (wakeUp) { - MonitorAutoEnter mon(mPool->GetMonitor()); + nsAutoMonitor mon(mPool->Monitor()); mon.NotifyAll(); } nsRefPtr<nsDOMWorkerEvent> event = new nsDOMWorkerEvent(); NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY); nsresult rv = event->InitEvent(NS_LITERAL_STRING("close"), PR_FALSE, PR_FALSE); @@ -2419,17 +2425,17 @@ nsDOMWorker::FireCloseRunnable(PRInterva return nsDOMThreadService::get()->Dispatch(this, runnable, aTimeoutInterval, aClearQueue); } nsresult nsDOMWorker::Close() { { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); NS_ASSERTION(mStatus != eKilled, "This should be impossible!"); if (mStatus != eRunning) { return NS_OK; } mStatus = eClosed; } nsresult rv = FireCloseRunnable(PR_INTERVAL_NO_TIMEOUT, PR_FALSE, PR_FALSE); @@ -2437,17 +2443,17 @@ nsDOMWorker::Close() return NS_OK; } nsresult nsDOMWorker::TerminateInternal(PRBool aFromFinalize) { { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); #ifdef DEBUG if (!aFromFinalize) { NS_ASSERTION(mStatus != eCanceled, "Shouldn't be able to get here!"); } #endif if (mStatus == eRunning) { // This is the beginning of the close process, fire an event and prevent @@ -2484,31 +2490,31 @@ nsDOMWorker::GetParent() nsRefPtr<nsDOMWorker> parent(mParent); return parent.forget(); } void nsDOMWorker::SetExpirationTime(PRIntervalTime aExpirationTime) { { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); NS_ASSERTION(mStatus != eRunning && mStatus != eKilled, "Bad status!"); NS_ASSERTION(!mExpirationTime || mExpirationTime == PR_INTERVAL_NO_TIMEOUT, "Overwriting a timeout that was previously set!"); mExpirationTime = aExpirationTime; } } #ifdef DEBUG PRIntervalTime nsDOMWorker::GetExpirationTime() { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); return mExpirationTime; } #endif // static JSObject* nsDOMWorker::ReadStructuredClone(JSContext* aCx, JSStructuredCloneReader* aReader, @@ -2583,17 +2589,17 @@ nsDOMWorker::RemoveEventListener(const n aUseCapture); } NS_IMETHODIMP nsDOMWorker::DispatchEvent(nsIDOMEvent* aEvent, PRBool* _retval) { { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); if (IsCanceledNoLock()) { return NS_OK; } if (mStatus == eTerminated) { nsCOMPtr<nsIWorkerMessageEvent> messageEvent(do_QueryInterface(aEvent)); if (messageEvent) { // This is a message event targeted to a terminated worker. Ignore it. return NS_OK; @@ -2624,17 +2630,17 @@ nsDOMWorker::AddEventListener(const nsAS /** * See nsIWorker */ NS_IMETHODIMP nsDOMWorker::PostMessage(/* JSObject aMessage */) { { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); // There's no reason to dispatch this message after the close handler has // been triggered since it will never be allowed to run. if (mStatus != eRunning) { return NS_OK; } } return PostMessageInternal(PR_TRUE);
--- a/dom/src/threads/nsDOMWorker.h +++ b/dom/src/threads/nsDOMWorker.h @@ -43,20 +43,20 @@ #include "nsIDOMWorkers.h" #include "nsIJSNativeInitializer.h" #include "nsIPrincipal.h" #include "nsITimer.h" #include "nsIURI.h" #include "nsIXPCScriptable.h" #include "jsapi.h" -#include "mozilla/Mutex.h" #include "nsAutoPtr.h" #include "nsCOMPtr.h" #include "nsTPtrArray.h" +#include "prlock.h" #include "nsDOMWorkerMessageHandler.h" // {1295EFB5-8644-42B2-8B8E-80EEF56E4284} #define NS_WORKERFACTORY_CID \ {0x1295efb5, 0x8644, 0x42b2, \ {0x8b, 0x8e, 0x80, 0xee, 0xf5, 0x6e, 0x42, 0x84} } @@ -138,18 +138,16 @@ private: }; class nsDOMWorker : public nsDOMWorkerMessageHandler, public nsIWorker, public nsITimerCallback, public nsIJSNativeInitializer, public nsIXPCScriptable { - typedef mozilla::Mutex Mutex; - friend class nsDOMWorkerFeature; friend class nsDOMWorkerFunctions; friend class nsDOMWorkerScope; friend class nsDOMWorkerScriptLoader; friend class nsDOMWorkerTimeout; friend class nsDOMWorkerXHR; friend class nsDOMWorkerXHRProxy; friend class nsReportErrorRunnable; @@ -211,17 +209,17 @@ public: PRBool SetGlobalForContext(JSContext* aCx, nsLazyAutoRequest *aRequest, JSAutoEnterCompartment *aComp); void SetPool(nsDOMWorkerPool* aPool); nsDOMWorkerPool* Pool() { return mPool; } - Mutex& GetLock() { + PRLock* Lock() { return mLock; } already_AddRefed<nsIXPConnectWrappedNative> GetWrappedNative(); already_AddRefed<nsDOMWorker> GetParent(); nsDOMWorkerScope* GetInnerScope() { return mInnerScope; @@ -349,17 +347,17 @@ private: // reflection alive, so we only hold one strong reference to mParentWN. nsDOMWorker* mParent; nsCOMPtr<nsIXPConnectWrappedNative> mParentWN; // Whether or not this worker has chrome privileges. Never changed after the // worker is created. WorkerPrivilegeModel mPrivilegeModel; - Mutex mLock; + PRLock* mLock; nsRefPtr<nsDOMWorkerPool> mPool; nsDOMWorkerScope* mInnerScope; nsCOMPtr<nsIXPConnectWrappedNative> mScopeWN; JSObject* mGlobal; PRUint32 mNextTimeoutId;
--- a/dom/src/threads/nsDOMWorkerPool.cpp +++ b/dom/src/threads/nsDOMWorkerPool.cpp @@ -45,34 +45,33 @@ #include "nsIJSContextStack.h" #include "nsIScriptGlobalObject.h" #include "nsIServiceManager.h" #include "nsIThreadManager.h" #include "nsIXPConnect.h" #include "nsPIDOMWindow.h" // Other includes +#include "nsAutoLock.h" #include "nsContentUtils.h" #include "nsDOMJSUtils.h" #include "nsProxyRelease.h" #include "nsThreadUtils.h" // DOMWorker includes #include "nsDOMThreadService.h" #include "nsDOMWorker.h" -using namespace mozilla; - #define LOG(_args) PR_LOG(gDOMThreadsLog, PR_LOG_DEBUG, _args) nsDOMWorkerPool::nsDOMWorkerPool(nsIScriptGlobalObject* aGlobalObject, nsIDocument* aDocument) : mParentGlobal(aGlobalObject), mParentDocument(aDocument), - mMonitor("nsDOMWorkerPool.mMonitor"), + mMonitor(nsnull), mCanceled(PR_FALSE), mSuspended(PR_FALSE), mWindowID(aDocument ? aDocument->OuterWindowID() : 0) { } nsDOMWorkerPool::~nsDOMWorkerPool() { @@ -85,37 +84,45 @@ nsDOMWorkerPool::~nsDOMWorkerPool() NS_ProxyRelease(mainThread, global, PR_FALSE); } nsIDocument* document; mParentDocument.forget(&document); if (document) { NS_ProxyRelease(mainThread, document, PR_FALSE); } + + if (mMonitor) { + nsAutoMonitor::DestroyMonitor(mMonitor); + } } NS_IMPL_THREADSAFE_ADDREF(nsDOMWorkerPool) NS_IMPL_THREADSAFE_RELEASE(nsDOMWorkerPool) nsresult nsDOMWorkerPool::Init() { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); + + mMonitor = nsAutoMonitor::NewMonitor("nsDOMWorkerPool::mMonitor"); + NS_ENSURE_TRUE(mMonitor, NS_ERROR_OUT_OF_MEMORY); + return NS_OK; } nsresult nsDOMWorkerPool::NoteWorker(nsDOMWorker* aWorker) { NS_ASSERTION(aWorker, "Null pointer!"); PRBool suspendWorker; { - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); if (mCanceled) { return NS_ERROR_ABORT; } nsDOMWorker** newWorker = mWorkers.AppendElement(aWorker); NS_ENSURE_TRUE(newWorker, NS_ERROR_OUT_OF_MEMORY); @@ -132,17 +139,17 @@ nsDOMWorkerPool::NoteWorker(nsDOMWorker* void nsDOMWorkerPool::NoteDyingWorker(nsDOMWorker* aWorker) { NS_ASSERTION(aWorker, "Null pointer!"); PRBool removeFromThreadService = PR_FALSE; { - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); NS_ASSERTION(mWorkers.Contains(aWorker), "Worker from a different pool?!"); mWorkers.RemoveElement(aWorker); if (!mCanceled && !mWorkers.Length()) { removeFromThreadService = PR_TRUE; } } @@ -151,17 +158,17 @@ nsDOMWorkerPool::NoteDyingWorker(nsDOMWo nsRefPtr<nsDOMWorkerPool> kungFuDeathGrip(this); nsDOMThreadService::get()->NoteEmptyPool(this); } } void nsDOMWorkerPool::GetWorkers(nsTArray<nsDOMWorker*>& aArray) { - mMonitor.AssertCurrentThreadIn(); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(mMonitor); NS_ASSERTION(!aArray.Length(), "Should be empty!"); #ifdef DEBUG nsDOMWorker** newWorkers = #endif aArray.AppendElements(mWorkers); NS_WARN_IF_FALSE(newWorkers, "Out of memory!"); } @@ -169,41 +176,41 @@ nsDOMWorkerPool::GetWorkers(nsTArray<nsD void nsDOMWorkerPool::Cancel() { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(!mCanceled, "Canceled more than once!"); nsAutoTArray<nsDOMWorker*, 10> workers; { - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); mCanceled = PR_TRUE; GetWorkers(workers); } PRUint32 count = workers.Length(); if (count) { for (PRUint32 index = 0; index < count; index++) { workers[index]->Cancel(); } - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); mon.NotifyAll(); } } void nsDOMWorkerPool::Suspend() { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); nsAutoTArray<nsDOMWorker*, 10> workers; { - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); NS_ASSERTION(!mSuspended, "Suspended more than once!"); mSuspended = PR_TRUE; GetWorkers(workers); } PRUint32 count = workers.Length(); @@ -214,25 +221,25 @@ nsDOMWorkerPool::Suspend() void nsDOMWorkerPool::Resume() { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); nsAutoTArray<nsDOMWorker*, 10> workers; { - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); NS_ASSERTION(mSuspended, "Not suspended!"); mSuspended = PR_FALSE; GetWorkers(workers); } PRUint32 count = workers.Length(); if (count) { for (PRUint32 index = 0; index < count; index++) { workers[index]->Resume(); } - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); mon.NotifyAll(); } }
--- a/dom/src/threads/nsDOMWorkerPool.h +++ b/dom/src/threads/nsDOMWorkerPool.h @@ -37,31 +37,29 @@ * * ***** END LICENSE BLOCK ***** */ #ifndef __NSDOMWORKERPOOL_H__ #define __NSDOMWORKERPOOL_H__ // Other includes #include "jsapi.h" -#include "mozilla/Monitor.h" #include "nsCOMPtr.h" #include "nsStringGlue.h" #include "nsTArray.h" +#include "prmon.h" class nsDOMWorker; class nsIDocument; class nsIScriptContext; class nsIScriptError; class nsIScriptGlobalObject; class nsDOMWorkerPool { - typedef mozilla::Monitor Monitor; - public: nsDOMWorkerPool(nsIScriptGlobalObject* aGlobalObject, nsIDocument* aDocument); NS_IMETHOD_(nsrefcnt) AddRef(); NS_IMETHOD_(nsrefcnt) Release(); nsIScriptGlobalObject* ScriptGlobalObject() { @@ -76,17 +74,17 @@ public: void Cancel(); void Suspend(); void Resume(); nsresult NoteWorker(nsDOMWorker* aWorker); void NoteDyingWorker(nsDOMWorker* aWorker); - Monitor& GetMonitor() { + PRMonitor* Monitor() { return mMonitor; } const PRUint64 WindowID() const { return mWindowID; } private: @@ -102,17 +100,17 @@ private: // Reference to the document that created this pool. nsCOMPtr<nsIDocument> mParentDocument; // Weak array of workers. The idea is that workers can be garbage collected // independently of the owning pool and other workers. nsTArray<nsDOMWorker*> mWorkers; // Monitor for suspending and resuming workers. - Monitor mMonitor; + PRMonitor* mMonitor; PRPackedBool mCanceled; PRPackedBool mSuspended; const PRUint64 mWindowID; }; #endif /* __NSDOMWORKERPOOL_H__ */
--- a/dom/src/threads/nsDOMWorkerScriptLoader.cpp +++ b/dom/src/threads/nsDOMWorkerScriptLoader.cpp @@ -44,16 +44,17 @@ #include "nsIHttpChannel.h" #include "nsIIOService.h" #include "nsIProtocolHandler.h" #include "nsIRequest.h" #include "nsIScriptSecurityManager.h" #include "nsIStreamLoader.h" // Other includes +#include "nsAutoLock.h" #include "nsContentErrors.h" #include "nsContentPolicyUtils.h" #include "nsContentUtils.h" #include "nsISupportsPrimitives.h" #include "nsNetError.h" #include "nsNetUtil.h" #include "nsScriptLoader.h" #include "nsThreadUtils.h" @@ -64,18 +65,16 @@ #include "nsIContentSecurityPolicy.h" // DOMWorker includes #include "nsDOMWorkerPool.h" #include "nsDOMWorkerSecurityManager.h" #include "nsDOMThreadService.h" #include "nsDOMWorkerTimeout.h" -using namespace mozilla; - #define LOG(_args) PR_LOG(gDOMThreadsLog, PR_LOG_DEBUG, _args) nsDOMWorkerScriptLoader::nsDOMWorkerScriptLoader(nsDOMWorker* aWorker) : nsDOMWorkerFeature(aWorker), mTarget(nsnull), mScriptCount(0), mCanceled(PR_FALSE), mForWorker(PR_FALSE) @@ -299,17 +298,17 @@ nsDOMWorkerScriptLoader::Cancel() #endif request->Cancel(NS_BINDING_ABORTED); NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Failed to cancel channel!"); } } nsAutoTArray<ScriptLoaderRunnable*, 10> runnables; { - MutexAutoLock lock(mWorker->GetLock()); + nsAutoLock lock(mWorker->Lock()); runnables.AppendElements(mPendingRunnables); mPendingRunnables.Clear(); } PRUint32 runnableCount = runnables.Length(); for (PRUint32 index = 0; index < runnableCount; index++) { runnables[index]->Revoke(); } @@ -749,29 +748,29 @@ nsDOMWorkerScriptLoader::ResumeWorkerEve mWorker->ResumeFeatures(); } nsDOMWorkerScriptLoader:: ScriptLoaderRunnable::ScriptLoaderRunnable(nsDOMWorkerScriptLoader* aLoader) : mRevoked(PR_FALSE), mLoader(aLoader) { - MutexAutoLock lock(aLoader->GetLock()); + nsAutoLock lock(aLoader->Lock()); #ifdef DEBUG nsDOMWorkerScriptLoader::ScriptLoaderRunnable** added = #endif aLoader->mPendingRunnables.AppendElement(this); NS_ASSERTION(added, "This shouldn't fail because we SetCapacity earlier!"); } nsDOMWorkerScriptLoader:: ScriptLoaderRunnable::~ScriptLoaderRunnable() { if (!mRevoked) { - MutexAutoLock lock(mLoader->GetLock()); + nsAutoLock lock(mLoader->Lock()); #ifdef DEBUG PRBool removed = #endif mLoader->mPendingRunnables.RemoveElement(this); NS_ASSERTION(removed, "Someone has changed the array!"); } }
--- a/dom/src/threads/nsDOMWorkerScriptLoader.h +++ b/dom/src/threads/nsDOMWorkerScriptLoader.h @@ -49,16 +49,17 @@ // Other includes #include "jsapi.h" #include "nsAutoPtr.h" #include "nsAutoJSValHolder.h" #include "nsCOMPtr.h" #include "nsStringGlue.h" #include "nsTArray.h" +#include "prlock.h" #include "nsDOMWorker.h" class nsIThread; /** * This class takes a list of script URLs, downloads the scripts, compiles the * scripts, and then finally executes them. Due to platform limitations all @@ -85,18 +86,16 @@ class nsIThread; * * Currently if *anything* after 2 fails then we cancel any pending loads and * bail out entirely. */ class nsDOMWorkerScriptLoader : public nsDOMWorkerFeature, public nsIRunnable, public nsIStreamLoaderObserver { - typedef mozilla::Mutex Mutex; - friend class AutoSuspendWorkerEvents; friend class ScriptLoaderRunnable; public: NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSIRUNNABLE NS_DECL_NSISTREAMLOADEROBSERVER @@ -128,18 +127,18 @@ private: PRUint32 aStringLen, const PRUint8* aString); void NotifyDone(); void SuspendWorkerEvents(); void ResumeWorkerEvents(); - Mutex& GetLock() { - return mWorker->GetLock(); + PRLock* Lock() { + return mWorker->Lock(); } class ScriptLoaderRunnable : public nsIRunnable { public: NS_DECL_ISUPPORTS protected:
--- a/dom/src/threads/nsDOMWorkerXHR.cpp +++ b/dom/src/threads/nsDOMWorkerXHR.cpp @@ -40,31 +40,30 @@ // Interfaces #include "nsIDocument.h" #include "nsIDOMEvent.h" #include "nsIThread.h" #include "nsIXPConnect.h" // Other includes +#include "nsAutoLock.h" #include "nsAXPCNativeCallContext.h" #include "nsComponentManagerUtils.h" #include "nsContentUtils.h" #include "nsIClassInfoImpl.h" #include "nsJSUtils.h" #include "nsThreadUtils.h" // DOMWorker includes #include "nsDOMThreadService.h" #include "nsDOMWorkerEvents.h" #include "nsDOMWorkerPool.h" #include "nsDOMWorkerXHRProxy.h" -using namespace mozilla; - // The list of event types that we support. This list and the defines based on // it determine the sizes of the listener arrays in nsDOMWorkerXHRProxy. Make // sure that any event types shared by both the XHR and Upload objects are // together at the beginning of the list. Any changes made to this list may // affect sMaxUploadEventTypes, so make sure that it is adjusted accordingly or // things will break! const char* const nsDOMWorkerXHREventTarget::sListenerTypes[] = { // nsIXMLHttpRequestEventTarget listeners. @@ -489,17 +488,17 @@ nsDOMWorkerXHR::Cancel() // Just in case mUpload holds the only ref to this object we make sure to stay // alive through this call. nsRefPtr<nsDOMWorkerXHR> kungFuDeathGrip(this); { // This lock is here to prevent a race between Cancel and GetUpload, not to // protect mCanceled. - MutexAutoLock lock(mWorker->GetLock()); + nsAutoLock lock(mWorker->Lock()); mCanceled = PR_TRUE; mUpload = nsnull; } if (mXHRProxy) { mXHRProxy->Destroy(); mXHRProxy = nsnull; @@ -825,17 +824,17 @@ nsDOMWorkerXHR::GetUpload(nsIXMLHttpRequ { NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!"); nsRefPtr<nsDOMWorker> worker = mWorker; if (!worker) { return NS_ERROR_ABORT; } - MutexAutoLock lock(worker->GetLock()); + nsAutoLock lock(worker->Lock()); if (mCanceled) { return NS_ERROR_ABORT; } NS_ENSURE_ARG_POINTER(aUpload); if (!mUpload) {
--- a/dom/src/threads/nsDOMWorkerXHR.h +++ b/dom/src/threads/nsDOMWorkerXHR.h @@ -43,16 +43,17 @@ #include "nsIClassInfo.h" #include "nsIXMLHttpRequest.h" #include "nsIXPCScriptable.h" // Other includes #include "nsAutoPtr.h" #include "nsCOMPtr.h" #include "nsTArray.h" +#include "prlock.h" // DOMWorker includes #include "nsDOMWorker.h" #include "nsDOMWorkerMacros.h" #include "nsDOMWorkerXHRProxy.h" // Convenience defines for event *indexes* in the sListenerTypes array. #define LISTENER_TYPE_ABORT 0 @@ -86,18 +87,16 @@ protected: class nsDOMWorkerXHRUpload; class nsDOMWorkerXHR : public nsDOMWorkerFeature, public nsDOMWorkerXHREventTarget, public nsIXMLHttpRequest, public nsIXPCScriptable { - typedef mozilla::Mutex Mutex; - friend class nsDOMWorkerXHREvent; friend class nsDOMWorkerXHRLastProgressOrLoadEvent; friend class nsDOMWorkerXHRProxy; friend class nsDOMWorkerXHRUpload; public: NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSIXMLHTTPREQUEST @@ -112,18 +111,18 @@ public: virtual void Cancel(); virtual nsresult SetOnXListener(const nsAString& aType, nsIDOMEventListener* aListener); private: virtual ~nsDOMWorkerXHR(); - Mutex& GetLock() { - return mWorker->GetLock(); + PRLock* Lock() { + return mWorker->Lock(); } already_AddRefed<nsIXPConnectWrappedNative> GetWrappedNative() { nsCOMPtr<nsIXPConnectWrappedNative> wrappedNative(mWrappedNative); return wrappedNative.forget(); } nsRefPtr<nsDOMWorkerXHRProxy> mXHRProxy;
--- a/dom/src/threads/nsDOMWorkerXHRProxy.cpp +++ b/dom/src/threads/nsDOMWorkerXHRProxy.cpp @@ -44,34 +44,33 @@ #include "nsIDOMProgressEvent.h" #include "nsILoadGroup.h" #include "nsIRequest.h" #include "nsIThread.h" #include "nsIVariant.h" #include "nsIXMLHttpRequest.h" // Other includes +#include "nsAutoLock.h" #include "nsComponentManagerUtils.h" #include "nsIClassInfoImpl.h" #include "nsThreadUtils.h" #include "nsXMLHttpRequest.h" #include "prinrval.h" #include "prthread.h" // DOMWorker includes #include "nsDOMThreadService.h" #include "nsDOMWorker.h" #include "nsDOMWorkerEvents.h" #include "nsDOMWorkerMacros.h" #include "nsDOMWorkerPool.h" #include "nsDOMWorkerXHR.h" #include "nsDOMWorkerXHRProxiedFunctions.h" -using namespace mozilla; - #define MAX_XHR_LISTENER_TYPE nsDOMWorkerXHREventTarget::sMaxXHREventTypes #define MAX_UPLOAD_LISTENER_TYPE nsDOMWorkerXHREventTarget::sMaxUploadEventTypes #define RUN_PROXIED_FUNCTION(_name, _args) \ PR_BEGIN_MACRO \ NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!"); \ \ if (mCanceled) { \ @@ -177,17 +176,17 @@ public: : mProxy(aProxy) { NS_ASSERTION(aProxy, "Null pointer!"); } NS_IMETHOD Run() { nsRefPtr<nsDOMWorkerXHREvent> lastProgressOrLoadEvent; if (!mProxy->mCanceled) { - MutexAutoLock lock(mProxy->mWorkerXHR->GetLock()); + nsAutoLock lock(mProxy->mWorkerXHR->Lock()); mProxy->mLastProgressOrLoadEvent.swap(lastProgressOrLoadEvent); if (mProxy->mCanceled) { return NS_ERROR_ABORT; } } if (lastProgressOrLoadEvent) { return lastProgressOrLoadEvent->Run(); @@ -371,17 +370,17 @@ nsDOMWorkerXHRProxy::GetXMLHttpRequest() } nsresult nsDOMWorkerXHRProxy::Destroy() { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); { - MutexAutoLock lock(mWorkerXHR->GetLock()); + nsAutoLock lock(mWorkerXHR->Lock()); mCanceled = PR_TRUE; mLastProgressOrLoadEvent = nsnull; mLastXHRState = nsnull; } DestroyInternal(); @@ -461,17 +460,17 @@ nsDOMWorkerXHRProxy::DestroyInternal() if (mOwnedByXHR) { mXHR->Abort(); } else { // There's a slight chance that Send was called yet we've canceled before // necko has fired its OnStartRequest notification. Guard against that here. nsRefPtr<nsDOMWorkerXHRFinishSyncXHRRunnable> syncFinishedRunnable; { - MutexAutoLock lock(mWorkerXHR->GetLock()); + nsAutoLock lock(mWorkerXHR->Lock()); mSyncFinishedRunnable.swap(syncFinishedRunnable); } if (syncFinishedRunnable) { syncFinishedRunnable->Dispatch(); } } @@ -576,17 +575,17 @@ nsDOMWorkerXHRProxy::UploadEventListener nsresult nsDOMWorkerXHRProxy::HandleWorkerEvent(nsDOMWorkerXHREvent* aEvent, PRBool aUploadEvent) { NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(aEvent, "Should not be null!"); { - MutexAutoLock lock(mWorkerXHR->GetLock()); + nsAutoLock lock(mWorkerXHR->Lock()); if (mCanceled || (aEvent->mChannelID != -1 && aEvent->mChannelID != mChannelID)) { return NS_OK; } mLastXHRState = aEvent->ForgetState(); } @@ -601,17 +600,17 @@ nsDOMWorkerXHRProxy::HandleWorkerEvent(n if (type == LISTENER_TYPE_ABORT || type == LISTENER_TYPE_ERROR || type == LISTENER_TYPE_LOAD) { nsAutoPtr<ProgressInfo>& progressInfo = aUploadEvent ? mUploadProgressInfo : mDownloadProgressInfo; progressInfo = nsnull; // Dummy memory barrier. - MutexAutoLock lock(mWorkerXHR->GetLock()); + nsAutoLock lock(mWorkerXHR->Lock()); } nsIDOMEventTarget* target = aUploadEvent ? static_cast<nsDOMWorkerMessageHandler*>(mWorkerXHR->mUpload) : static_cast<nsDOMWorkerMessageHandler*>(mWorkerXHR); return target->DispatchEvent(static_cast<nsDOMWorkerEvent*>(aEvent), nsnull); } @@ -765,17 +764,17 @@ nsDOMWorkerXHRProxy::HandleEvent(nsIDOME progressEvent->GetLengthComputable(&progressInfo->computable); progressEvent->GetLoaded(&progressInfo->loaded); progressEvent->GetTotal(&progressInfo->total); } } NS_ASSERTION(!syncFinishedRunnable, "This shouldn't be set!"); - MutexAutoLock lock(mWorkerXHR->GetLock()); + nsAutoLock lock(mWorkerXHR->Lock()); mSyncFinishedRunnable.swap(syncFinishedRunnable); } else { requestDone = PR_FALSE; } if (mCanceled) { // When Abort is called on nsXMLHttpRequest (either from a proxied Abort @@ -807,17 +806,17 @@ nsDOMWorkerXHRProxy::HandleEvent(nsIDOME nsCOMPtr<nsIRunnable> runnable(newEvent); if (type == LISTENER_TYPE_LOAD || type == LISTENER_TYPE_PROGRESS) { runnable = new nsDOMWorkerXHRLastProgressOrLoadEvent(this); NS_ENSURE_TRUE(runnable, NS_ERROR_OUT_OF_MEMORY); { - MutexAutoLock lock(mWorkerXHR->GetLock()); + nsAutoLock lock(mWorkerXHR->Lock()); if (mCanceled) { return NS_ERROR_ABORT; } mLastProgressOrLoadEvent.swap(newEvent); if (newEvent) { @@ -953,17 +952,17 @@ nsDOMWorkerXHRProxy::Send(nsIVariant* aB { NS_ASSERTION(!mSyncXHRThread, "Shouldn't reenter here!"); if (mSyncRequest) { mSyncXHRThread = NS_GetCurrentThread(); NS_ENSURE_TRUE(mSyncXHRThread, NS_ERROR_FAILURE); - MutexAutoLock lock(mWorkerXHR->GetLock()); + nsAutoLock lock(mWorkerXHR->Lock()); if (mCanceled) { return NS_ERROR_ABORT; } mSyncFinishedRunnable = new nsDOMWorkerXHRFinishSyncXHRRunnable(this, mSyncXHRThread); NS_ENSURE_TRUE(mSyncFinishedRunnable, NS_ERROR_FAILURE); @@ -978,17 +977,17 @@ nsresult nsDOMWorkerXHRProxy::SendAsBinary(const nsAString& aBody) { NS_ASSERTION(!mSyncXHRThread, "Shouldn't reenter here!"); if (mSyncRequest) { mSyncXHRThread = NS_GetCurrentThread(); NS_ENSURE_TRUE(mSyncXHRThread, NS_ERROR_FAILURE); - MutexAutoLock lock(mWorkerXHR->GetLock()); + nsAutoLock lock(mWorkerXHR->Lock()); if (mCanceled) { return NS_ERROR_ABORT; } mSyncFinishedRunnable = new nsDOMWorkerXHRFinishSyncXHRRunnable(this, mSyncXHRThread); NS_ENSURE_TRUE(mSyncFinishedRunnable, NS_ERROR_FAILURE);
--- a/editor/txmgr/tests/TestTXMgr.cpp +++ b/editor/txmgr/tests/TestTXMgr.cpp @@ -4618,27 +4618,20 @@ simple_stress_test() *******************************************************************/ printf("\n-----------------------------------------------------\n"); printf("- Simple Transaction Stress Test:\n"); printf("-----------------------------------------------------\n"); SimpleTransactionFactory factory; - PRInt32 iterations = -#ifdef DEBUG - 10 -#else // // 1500 iterations sends 1,125,750 transactions through the system!! // - 1500 -#endif - ; - return stress_test(&factory, iterations); + return stress_test(&factory, 1500); } nsresult aggregation_stress_test() { /******************************************************************* * * Initialize globals for test. @@ -4654,27 +4647,20 @@ aggregation_stress_test() *******************************************************************/ printf("\n-----------------------------------------------------\n"); printf("- Aggregate Transaction Stress Test:\n"); printf("-----------------------------------------------------\n"); AggregateTransactionFactory factory(3, 4); - PRInt32 iterations = -#ifdef DEBUG - 10 -#else // // 500 iterations sends 2,630,250 transactions through the system!! // - 500 -#endif - ; - return stress_test(&factory, iterations); + return stress_test(&factory, 500); } nsresult aggregation_batch_stress_test() { /******************************************************************* * * Initialize globals for test. @@ -4690,27 +4676,20 @@ aggregation_batch_stress_test() *******************************************************************/ printf("\n-----------------------------------------------------\n"); printf("- Aggregate Batch Transaction Stress Test:\n"); printf("-----------------------------------------------------\n"); AggregateTransactionFactory factory(3, 4, BATCH_FLAG); - PRInt32 iterations = -#ifdef DEBUG - 10 -#else // // 500 iterations sends 2,630,250 transactions through the system!! // - iterations = 500 -#endif - ; - return stress_test(&factory, iterations); + return stress_test(&factory, 500); } int main (int argc, char *argv[]) { ScopedXPCOM xpcom("nsITransactionManager"); if (xpcom.failed()) return 1;
--- a/embedding/components/windowwatcher/src/nsWindowWatcher.cpp +++ b/embedding/components/windowwatcher/src/nsWindowWatcher.cpp @@ -37,16 +37,17 @@ * * ***** END LICENSE BLOCK ***** */ //#define USEWEAKREFS // (haven't quite figured that out yet) #include "nsWindowWatcher.h" #include "nsAutoWindowStateHelper.h" +#include "nsAutoLock.h" #include "nsCRT.h" #include "nsNetUtil.h" #include "nsWWJSUtils.h" #include "plstr.h" #include "nsIContentUtils.h" #include "nsIBaseWindow.h" #include "nsIDocShell.h" @@ -95,18 +96,16 @@ #include "nsIPrefBranch.h" #include "nsIPrefService.h" #ifdef USEWEAKREFS #include "nsIWeakReference.h" #endif -using namespace mozilla; - static const char *sJSStackContractID="@mozilla.org/js/xpc/ContextStack;1"; /**************************************************************** ******************** nsWatcherWindowEntry ********************** ****************************************************************/ class nsWindowWatcher; @@ -334,30 +333,36 @@ NS_IMPL_RELEASE(nsWindowWatcher) NS_IMPL_QUERY_INTERFACE3(nsWindowWatcher, nsIWindowWatcher, nsIPromptFactory, nsPIWindowWatcher) nsWindowWatcher::nsWindowWatcher() : mEnumeratorList(), mOldestWindow(0), - mListLock("nsWindowWatcher.mListLock") + mListLock(0) { } nsWindowWatcher::~nsWindowWatcher() { // delete data while (mOldestWindow) RemoveWindow(mOldestWindow); + + if (mListLock) + nsAutoLock::DestroyLock(mListLock); } nsresult nsWindowWatcher::Init() { + mListLock = nsAutoLock::NewLock("nsWindowWatcher::mListLock"); + if (!mListLock) + return NS_ERROR_OUT_OF_MEMORY; return NS_OK; } NS_IMETHODIMP nsWindowWatcher::OpenWindow(nsIDOMWindow *aParent, const char *aUrl, const char *aName, const char *aFeatures, @@ -1063,17 +1068,17 @@ nsWindowWatcher::UnregisterNotification( } NS_IMETHODIMP nsWindowWatcher::GetWindowEnumerator(nsISimpleEnumerator** _retval) { if (!_retval) return NS_ERROR_INVALID_ARG; - MutexAutoLock lock(mListLock); + nsAutoLock lock(mListLock); nsWatcherWindowEnumerator *enumerator = new nsWatcherWindowEnumerator(this); if (enumerator) return CallQueryInterface(enumerator, _retval); return NS_ERROR_OUT_OF_MEMORY; } NS_IMETHODIMP @@ -1159,17 +1164,17 @@ nsWindowWatcher::AddWindow(nsIDOMWindow NS_ASSERTION(win->IsOuterWindow(), "Uh, the active window must be an outer window!"); } #endif { nsWatcherWindowEntry *info; - MutexAutoLock lock(mListLock); + nsAutoLock lock(mListLock); // if we already have an entry for this window, adjust // its chrome mapping and return info = FindWindowEntry(aWindow); if (info) { nsCOMPtr<nsISupportsWeakReference> supportsweak(do_QueryInterface(aChrome)); if (supportsweak) { supportsweak->GetWeakReference(getter_AddRefs(info->mChromeWeak)); @@ -1259,17 +1264,17 @@ nsWindowWatcher::FindWindowEntry(nsIDOMW nsresult nsWindowWatcher::RemoveWindow(nsWatcherWindowEntry *inInfo) { PRUint32 ctr, count = mEnumeratorList.Length(); { // notify the enumerators - MutexAutoLock lock(mListLock); + nsAutoLock lock(mListLock); for (ctr = 0; ctr < count; ++ctr) mEnumeratorList[ctr]->WindowRemoved(inInfo); // remove the element from the list if (inInfo == mOldestWindow) mOldestWindow = inInfo->mYounger == mOldestWindow ? 0 : inInfo->mYounger; inInfo->Unlink(); } @@ -1295,17 +1300,17 @@ nsresult nsWindowWatcher::RemoveWindow(n NS_IMETHODIMP nsWindowWatcher::GetChromeForWindow(nsIDOMWindow *aWindow, nsIWebBrowserChrome **_retval) { if (!aWindow || !_retval) return NS_ERROR_INVALID_ARG; *_retval = 0; - MutexAutoLock lock(mListLock); + nsAutoLock lock(mListLock); nsWatcherWindowEntry *info = FindWindowEntry(aWindow); if (info) { if (info->mChromeWeak != nsnull) { return info->mChromeWeak-> QueryReferent(NS_GET_IID(nsIWebBrowserChrome), reinterpret_cast<void**>(_retval)); } *_retval = info->mChrome;
--- a/embedding/components/windowwatcher/src/nsWindowWatcher.h +++ b/embedding/components/windowwatcher/src/nsWindowWatcher.h @@ -39,17 +39,16 @@ #define __nsWindowWatcher_h__ // {a21bfa01-f349-4394-a84c-8de5cf0737d0} #define NS_WINDOWWATCHER_CID \ {0xa21bfa01, 0xf349, 0x4394, {0xa8, 0x4c, 0x8d, 0xe5, 0xcf, 0x7, 0x37, 0xd0}} #include "nsCOMPtr.h" #include "jspubtd.h" -#include "mozilla/Mutex.h" #include "nsIWindowCreator.h" // for stupid compilers #include "nsIWindowWatcher.h" #include "nsIPromptFactory.h" #include "nsPIWindowWatcher.h" #include "nsTArray.h" class nsIURI; class nsIDocShellTreeItem; @@ -57,16 +56,17 @@ class nsIDocShellTreeOwner; class nsIWebBrowserChrome; class nsString; class nsWatcherWindowEnumerator; class nsIScriptContext; class nsPromptService; struct JSContext; struct JSObject; struct nsWatcherWindowEntry; +struct PRLock; struct SizeSpec; class nsWindowWatcher : public nsIWindowWatcher, public nsPIWindowWatcher, public nsIPromptFactory { friend class nsWatcherWindowEnumerator; @@ -140,15 +140,15 @@ protected: const SizeSpec & aSizeSpec); static void GetWindowTreeItem(nsIDOMWindow *inWindow, nsIDocShellTreeItem **outTreeItem); static void GetWindowTreeOwner(nsIDOMWindow *inWindow, nsIDocShellTreeOwner **outTreeOwner); nsTArray<nsWatcherWindowEnumerator*> mEnumeratorList; nsWatcherWindowEntry *mOldestWindow; - mozilla::Mutex mListLock; + PRLock *mListLock; nsCOMPtr<nsIWindowCreator> mWindowCreator; }; #endif
--- a/gfx/src/nsRegion.cpp +++ b/gfx/src/nsRegion.cpp @@ -29,16 +29,17 @@ * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ +#include "prlock.h" #include "nsRegion.h" #include "nsISupportsImpl.h" #include "nsTArray.h" /* * The SENTINEL values below guaranties that a < or > * comparison with it will be false for all values of the * underlying nscoord type. E.g. this is always false: @@ -103,17 +104,24 @@ inline void nsRegion::nsRectFast::UnionR #define INIT_MEM_CHUNK_ENTRIES 100 #define INCR_MEM_CHUNK_ENTRIES 100 class RgnRectMemoryAllocator { nsRegion::RgnRect* mFreeListHead; PRUint32 mFreeEntries; void* mChunkListHead; -#if defined (DEBUG) +#if 0 + PRLock* mLock; + + void InitLock () { mLock = PR_NewLock (); } + void DestroyLock () { PR_DestroyLock (mLock); } + void Lock () { PR_Lock (mLock); } + void Unlock () { PR_Unlock (mLock); } +#elif defined (DEBUG) NS_DECL_OWNINGTHREAD void InitLock () { NS_ASSERT_OWNINGTHREAD (RgnRectMemoryAllocator); } void DestroyLock () { NS_ASSERT_OWNINGTHREAD (RgnRectMemoryAllocator); } void Lock () { NS_ASSERT_OWNINGTHREAD (RgnRectMemoryAllocator); } void Unlock () { NS_ASSERT_OWNINGTHREAD (RgnRectMemoryAllocator); } #else void InitLock () { }
--- a/intl/strres/src/nsStringBundle.cpp +++ b/intl/strres/src/nsStringBundle.cpp @@ -54,45 +54,46 @@ #include "nsNetUtil.h" #include "nsIURL.h" #include "nsIComponentManager.h" #include "nsIMemory.h" #include "nsIObserverService.h" #include "pratom.h" #include "prmem.h" #include "nsCOMArray.h" +#include "nsAutoLock.h" #include "nsTextFormatter.h" #include "nsIErrorService.h" #include "nsITimelineService.h" #include "nsICategoryManager.h" #include "nsPrintfCString.h" // for async loading #ifdef ASYNC_LOADING #include "nsIBinaryInputStream.h" #include "nsIStringStream.h" #endif #include "prenv.h" #include "nsCRT.h" -using namespace mozilla; - static NS_DEFINE_CID(kErrorServiceCID, NS_ERRORSERVICE_CID); static NS_DEFINE_CID(kPersistentPropertiesCID, NS_IPERSISTENTPROPERTIES_CID); nsStringBundle::~nsStringBundle() { + if (mMonitor) + nsAutoMonitor::DestroyMonitor(mMonitor); } nsStringBundle::nsStringBundle(const char* aURLSpec, nsIStringBundleOverride* aOverrideStrings) : mPropertiesURL(aURLSpec), mOverrideStrings(aOverrideStrings), - mMonitor("nsStringBundle.mMonitor"), + mMonitor(0), mAttemptedLoad(PR_FALSE), mLoaded(PR_FALSE) { } nsresult nsStringBundle::LoadProperties() { @@ -106,16 +107,20 @@ nsStringBundle::LoadProperties() return NS_ERROR_UNEXPECTED; } mAttemptedLoad = PR_TRUE; nsresult rv; + mMonitor = nsAutoMonitor::NewMonitor("StringBundle monitor"); + if (!mMonitor) + return NS_ERROR_OUT_OF_MEMORY; + // do it synchronously nsCOMPtr<nsIURI> uri; rv = NS_NewURI(getter_AddRefs(uri), mPropertiesURL); if (NS_FAILED(rv)) return rv; // We don't use NS_OpenURI because we want to tweak the channel nsCOMPtr<nsIChannel> channel; rv = NS_NewChannel(getter_AddRefs(channel), uri); @@ -143,17 +148,17 @@ nsStringBundle::LoadProperties() return rv; } nsresult nsStringBundle::GetStringFromID(PRInt32 aID, nsAString& aResult) { - MonitorAutoEnter automon(mMonitor); + nsAutoMonitor automon(mMonitor); nsCAutoString name; name.AppendInt(aID, 10); nsresult rv; // try override first if (mOverrideStrings) { rv = mOverrideStrings->GetStringFromName(mPropertiesURL, @@ -264,17 +269,17 @@ nsStringBundle::GetStringFromName(const { NS_ENSURE_ARG_POINTER(aName); NS_ENSURE_ARG_POINTER(aResult); nsresult rv; rv = LoadProperties(); if (NS_FAILED(rv)) return rv; - MonitorAutoEnter automon(mMonitor); + nsAutoMonitor automon(mMonitor); *aResult = nsnull; nsAutoString tmpstr; rv = GetStringFromName(nsDependentString(aName), tmpstr); if (NS_FAILED(rv)) { #if 0 // it is not uncommon for apps to request a string name which may not exist // so be quiet about it.
--- a/intl/strres/src/nsStringBundle.h +++ b/intl/strres/src/nsStringBundle.h @@ -33,23 +33,23 @@ * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #ifndef nsStringBundle_h__ #define nsStringBundle_h__ -#include "mozilla/Monitor.h" #include "nsIStringBundle.h" #include "nsCOMPtr.h" #include "nsIPersistentProperties2.h" #include "nsString.h" #include "nsCOMArray.h" #include "nsIStringBundleOverride.h" +#include "nsAutoLock.h" class nsStringBundle : public nsIStringBundle { public: // init version nsStringBundle(const char* aURLSpec, nsIStringBundleOverride*); nsresult LoadProperties(); virtual ~nsStringBundle(); @@ -66,17 +66,17 @@ protected: nsresult GetStringFromID(PRInt32 aID, nsAString& aResult); nsresult GetStringFromName(const nsAString& aName, nsAString& aResult); nsresult GetCombinedEnumeration(nsIStringBundleOverride* aOverrideString, nsISimpleEnumerator** aResult); private: nsCString mPropertiesURL; nsCOMPtr<nsIStringBundleOverride> mOverrideStrings; - mozilla::Monitor mMonitor; + PRMonitor* mMonitor; PRPackedBool mAttemptedLoad; PRPackedBool mLoaded; public: static nsresult FormatString(const PRUnichar *formatStr, const PRUnichar **aParams, PRUint32 aLength, PRUnichar **aResult); };
--- a/intl/uconv/src/nsUNIXCharset.cpp +++ b/intl/uconv/src/nsUNIXCharset.cpp @@ -54,16 +54,17 @@ #endif #ifdef HAVE_NL_TYPES_H #include <nl_types.h> #endif #if HAVE_LANGINFO_CODESET #include <langinfo.h> #endif #include "nsPlatformCharset.h" +#include "nsAutoLock.h" #include "prinit.h" #include "nsUnicharUtils.h" static const char* kUnixCharsets[][3] = { #include "unixcharset.properties.h" }; NS_IMPL_THREADSAFE_ISUPPORTS1(nsPlatformCharset, nsIPlatformCharset)
--- a/js/src/xpconnect/src/xpcjsruntime.cpp +++ b/js/src/xpconnect/src/xpcjsruntime.cpp @@ -44,18 +44,16 @@ #include "WrapperFactory.h" #include "dom_quickstubs.h" #include "jsgcchunk.h" #include "nsIMemoryReporter.h" #include "mozilla/FunctionTimer.h" #include "prsystem.h" -using namespace mozilla; - /***************************************************************************/ const char* XPCJSRuntime::mStrings[] = { "constructor", // IDX_CONSTRUCTOR "toString", // IDX_TO_STRING "toSource", // IDX_TO_SOURCE "lastResult", // IDX_LAST_RESULT "returnCode", // IDX_RETURN_CODE @@ -336,20 +334,20 @@ XPCJSRuntime::RemoveJSHolder(void* aHold void XPCJSRuntime::TraceJS(JSTracer* trc, void* data) { XPCJSRuntime* self = (XPCJSRuntime*)data; // Skip this part if XPConnect is shutting down. We get into // bad locking problems with the thread iteration otherwise. if(!self->GetXPConnect()->IsShuttingDown()) { - Mutex* threadLock = XPCPerThreadData::GetLock(); + PRLock* threadLock = XPCPerThreadData::GetLock(); if(threadLock) { // scoped lock - MutexAutoLock lock(*threadLock); + nsAutoLock lock(threadLock); XPCPerThreadData* iterp = nsnull; XPCPerThreadData* thread; while(nsnull != (thread = XPCPerThreadData::IterateThreads(&iterp))) { // Trace those AutoMarkingPtr lists! @@ -754,20 +752,20 @@ JSBool XPCJSRuntime::GCCallback(JSContex // we need to do this marking to avoid collecting those sets // that might no longer be otherwise reachable from the wrappers // or the wrapperprotos. // Skip this part if XPConnect is shutting down. We get into // bad locking problems with the thread iteration otherwise. if(!self->GetXPConnect()->IsShuttingDown()) { - Mutex* threadLock = XPCPerThreadData::GetLock(); + PRLock* threadLock = XPCPerThreadData::GetLock(); if(threadLock) { // scoped lock - MutexAutoLock lock(*threadLock); + nsAutoLock lock(threadLock); XPCPerThreadData* iterp = nsnull; XPCPerThreadData* thread; while(nsnull != (thread = XPCPerThreadData::IterateThreads(&iterp))) { // Mark those AutoMarkingPtr lists! @@ -848,23 +846,23 @@ JSBool XPCJSRuntime::GCCallback(JSContex // on our wrapped natives that we are not actually using. // // XXX We may decide to not do this on *every* gc cycle. // Skip this part if XPConnect is shutting down. We get into // bad locking problems with the thread iteration otherwise. if(!self->GetXPConnect()->IsShuttingDown()) { - Mutex* threadLock = XPCPerThreadData::GetLock(); + PRLock* threadLock = XPCPerThreadData::GetLock(); if(threadLock) { // Do the marking... { // scoped lock - MutexAutoLock lock(*threadLock); + nsAutoLock lock(threadLock); XPCPerThreadData* iterp = nsnull; XPCPerThreadData* thread; while(nsnull != (thread = XPCPerThreadData::IterateThreads(&iterp))) { XPCCallContext* ccxp = thread->GetCallContext();
--- a/js/src/xpconnect/src/xpcprivate.h +++ b/js/src/xpconnect/src/xpcprivate.h @@ -76,34 +76,33 @@ #include "nsIXPConnect.h" #include "nsIInterfaceInfo.h" #include "nsIInterfaceInfoManager.h" #include "nsIXPCScriptable.h" #include "nsIXPCSecurityManager.h" #include "nsIJSRuntimeService.h" #include "nsWeakReference.h" #include "nsCOMPtr.h" +#include "nsAutoLock.h" #include "nsXPTCUtils.h" #include "xptinfo.h" #include "xpcforwards.h" #include "xpclog.h" #include "xpccomponents.h" #include "xpcexception.h" #include "xpcjsid.h" #include "prlong.h" #include "prmem.h" #include "prenv.h" #include "prclist.h" #include "nsString.h" #include "nsReadableUtils.h" #include "nsXPIDLString.h" #include "nsAutoJSValHolder.h" #include "mozilla/AutoRestore.h" -#include "mozilla/Monitor.h" -#include "mozilla/Mutex.h" #include "nsDataHashtable.h" #include "nsThreadUtils.h" #include "nsIJSContextStack.h" #include "nsDeque.h" #include "nsIConsoleService.h" #include "nsIScriptError.h" @@ -346,61 +345,78 @@ typedef nsDataHashtable<xpc::PtrAndPrinc /***************************************************************************/ // Auto locking support class... // We PROMISE to never screw this up. #ifdef _MSC_VER #pragma warning(disable : 4355) // OK to pass "this" in member initializer #endif -typedef mozilla::Monitor XPCLock; +typedef PRMonitor XPCLock; static inline void xpc_Wait(XPCLock* lock) { NS_ASSERTION(lock, "xpc_Wait called with null lock!"); - lock->Wait(); +#ifdef DEBUG + PRStatus result = +#endif + PR_Wait(lock, PR_INTERVAL_NO_TIMEOUT); + NS_ASSERTION(PR_SUCCESS == result, "bad result from PR_Wait!"); } static inline void xpc_NotifyAll(XPCLock* lock) { NS_ASSERTION(lock, "xpc_NotifyAll called with null lock!"); - lock->NotifyAll(); +#ifdef DEBUG + PRStatus result = +#endif + PR_NotifyAll(lock); + NS_ASSERTION(PR_SUCCESS == result, "bad result from PR_NotifyAll!"); } // This is a cloned subset of nsAutoMonitor. We want the use of a monitor - // mostly because we need reenterability - but we also want to support passing // a null monitor in without things blowing up. This is used for wrappers that // are guaranteed to be used only on one thread. We avoid lock overhead by // using a null monitor. By changing this class we can avoid having multiplte // code paths or (conditional) manual calls to PR_{Enter,Exit}Monitor. // // Note that xpconnect only makes *one* monitor and *mostly* holds it locked // only through very small critical sections. -class NS_STACK_CLASS XPCAutoLock { +class NS_STACK_CLASS XPCAutoLock : public nsAutoLockBase { public: static XPCLock* NewLock(const char* name) - {return new mozilla::Monitor(name);} + {return nsAutoMonitor::NewMonitor(name);} static void DestroyLock(XPCLock* lock) - {delete lock;} + {nsAutoMonitor::DestroyMonitor(lock);} XPCAutoLock(XPCLock* lock MOZILLA_GUARD_OBJECT_NOTIFIER_PARAM) - : mLock(lock) +#ifdef DEBUG_jband + : nsAutoLockBase(lock ? (void*) lock : (void*) this, eAutoMonitor), +#else + : nsAutoLockBase(lock, eAutoMonitor), +#endif + mLock(lock) { MOZILLA_GUARD_OBJECT_NOTIFIER_INIT; if(mLock) - mLock->Enter(); + PR_EnterMonitor(mLock); } ~XPCAutoLock() { if(mLock) { - mLock->Exit(); +#ifdef DEBUG + PRStatus status = +#endif + PR_ExitMonitor(mLock); + NS_ASSERTION(status == PR_SUCCESS, "PR_ExitMonitor failed"); } } private: XPCLock* mLock; MOZILLA_DECL_USE_GUARD_OBJECT_NOTIFIER // Not meant to be implemented. This makes it a compiler error to @@ -416,32 +432,37 @@ private: static void* operator new(size_t /*size*/) CPP_THROW_NEW { return nsnull; } static void operator delete(void* /*memory*/) {} }; /************************************************/ -class NS_STACK_CLASS XPCAutoUnlock { +class NS_STACK_CLASS XPCAutoUnlock : public nsAutoUnlockBase { public: XPCAutoUnlock(XPCLock* lock MOZILLA_GUARD_OBJECT_NOTIFIER_PARAM) - : mLock(lock) + : nsAutoUnlockBase(lock), + mLock(lock) { MOZILLA_GUARD_OBJECT_NOTIFIER_INIT; if(mLock) { - mLock->Exit(); +#ifdef DEBUG + PRStatus status = +#endif + PR_ExitMonitor(mLock); + NS_ASSERTION(status == PR_SUCCESS, "PR_ExitMonitor failed"); } } ~XPCAutoUnlock() { if(mLock) - mLock->Enter(); + PR_EnterMonitor(mLock); } private: XPCLock* mLock; MOZILLA_DECL_USE_GUARD_OBJECT_NOTIFIER // Not meant to be implemented. This makes it a compiler error to // construct or assign an XPCAutoUnlock object incorrectly. @@ -3647,18 +3668,16 @@ private: /**************************************************************/ // All of our thread local storage. #define BAD_TLS_INDEX ((PRUint32) -1) class XPCPerThreadData { - typedef mozilla::Mutex Mutex; - public: // Get the instance of this object for the current thread static inline XPCPerThreadData* GetData(JSContext *cx) { if(cx) { NS_ASSERTION(cx->thread, "Uh, JS context w/o a thread?"); @@ -3739,17 +3758,17 @@ public: {XPCWrappedNative* old = mResolvingWrapper; mResolvingWrapper = w; return old;} void Cleanup(); void ReleaseNatives(); PRBool IsValid() const {return mJSContextStack != nsnull;} - static Mutex* GetLock() {return gLock;} + static PRLock* GetLock() {return gLock;} // Must be called with the threads locked. static XPCPerThreadData* IterateThreads(XPCPerThreadData** iteratorp); AutoMarkingPtr** GetAutoRootsAdr() {return &mAutoRoots;} void TraceJS(JSTracer* trc); void MarkAutoRootsAfterJSFinalize(); @@ -3785,17 +3804,17 @@ private: JSBool mExceptionManagerNotAvailable; AutoMarkingPtr* mAutoRoots; #ifdef XPC_CHECK_WRAPPER_THREADSAFETY JSUint32 mWrappedNativeThreadsafetyReportDepth; #endif PRThread* mThread; - static Mutex* gLock; + static PRLock* gLock; static XPCPerThreadData* gThreads; static PRUintn gTLSIndex; // Cached value of cx->thread on the main thread. static void *sMainJSThread; // Cached per thread data for the main thread. Only safe to access // if cx->thread == sMainJSThread.
--- a/js/src/xpconnect/src/xpcthreadcontext.cpp +++ b/js/src/xpconnect/src/xpcthreadcontext.cpp @@ -38,23 +38,20 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ /* Implement global service to track stack of JSContext per thread. */ #include "xpcprivate.h" #include "XPCWrapper.h" -#include "mozilla/Mutex.h" #include "nsDOMJSUtils.h" #include "nsIScriptGlobalObject.h" #include "nsNullPrincipal.h" -using namespace mozilla; - /***************************************************************************/ XPCJSContextStack::XPCJSContextStack() : mStack(), mSafeJSContext(nsnull), mOwnSafeJSContext(nsnull) { // empty... @@ -339,17 +336,17 @@ XPCJSContextStack::SetSafeJSContext(JSCo mSafeJSContext = aSafeJSContext; return NS_OK; } /***************************************************************************/ PRUintn XPCPerThreadData::gTLSIndex = BAD_TLS_INDEX; -Mutex* XPCPerThreadData::gLock = nsnull; +PRLock* XPCPerThreadData::gLock = nsnull; XPCPerThreadData* XPCPerThreadData::gThreads = nsnull; XPCPerThreadData *XPCPerThreadData::sMainThreadData = nsnull; void * XPCPerThreadData::sMainJSThread = nsnull; XPCPerThreadData::XPCPerThreadData() : mJSContextStack(new XPCJSContextStack()), mNextThread(nsnull), mCallContext(nsnull), @@ -361,17 +358,17 @@ XPCPerThreadData::XPCPerThreadData() mAutoRoots(nsnull) #ifdef XPC_CHECK_WRAPPER_THREADSAFETY , mWrappedNativeThreadsafetyReportDepth(0) #endif { MOZ_COUNT_CTOR(xpcPerThreadData); if(gLock) { - MutexAutoLock lock(*gLock); + nsAutoLock lock(gLock); mNextThread = gThreads; gThreads = this; } } void XPCPerThreadData::Cleanup() { @@ -395,17 +392,17 @@ XPCPerThreadData::~XPCPerThreadData() MOZ_COUNT_DTOR(xpcPerThreadData); Cleanup(); // Unlink 'this' from the list of threads. if(gLock) { - MutexAutoLock lock(*gLock); + nsAutoLock lock(gLock); if(gThreads == this) gThreads = mNextThread; else { XPCPerThreadData* cur = gThreads; while(cur) { if(cur->mNextThread == this) @@ -417,17 +414,17 @@ XPCPerThreadData::~XPCPerThreadData() } } if (!gThreads) doDestroyLock = PR_TRUE; } if(gLock && doDestroyLock) { - delete gLock; + nsAutoLock::DestroyLock(gLock); gLock = nsnull; } } static void xpc_ThreadDataDtorCB(void* ptr) { XPCPerThreadData* data = (XPCPerThreadData*) ptr; @@ -463,22 +460,24 @@ void XPCPerThreadData::MarkAutoRootsAfte // static XPCPerThreadData* XPCPerThreadData::GetDataImpl(JSContext *cx) { XPCPerThreadData* data; if(!gLock) { - gLock = new Mutex("XPCPerThreadData.gLock"); + gLock = nsAutoLock::NewLock("XPCPerThreadData::gLock"); + if(!gLock) + return nsnull; } if(gTLSIndex == BAD_TLS_INDEX) { - MutexAutoLock lock(*gLock); + nsAutoLock lock(gLock); // check again now that we have the lock... if(gTLSIndex == BAD_TLS_INDEX) { if(PR_FAILURE == PR_NewThreadPrivateIndex(&gTLSIndex, xpc_ThreadDataDtorCB)) { NS_ERROR("PR_NewThreadPrivateIndex failed!"); gTLSIndex = BAD_TLS_INDEX; @@ -529,17 +528,17 @@ XPCPerThreadData::CleanupAllThreads() // the lock. Yuk! XPCJSContextStack** stacks = nsnull; int count = 0; int i; if(gLock) { - MutexAutoLock lock(*gLock); + nsAutoLock lock(gLock); for(XPCPerThreadData* cur = gThreads; cur; cur = cur->mNextThread) count++; stacks = (XPCJSContextStack**) new XPCJSContextStack*[count] ; if(stacks) { i = 0;
--- a/modules/libjar/nsJAR.cpp +++ b/modules/libjar/nsJAR.cpp @@ -50,18 +50,16 @@ #include "mozilla/Omnijar.h" #ifdef XP_UNIX #include <sys/stat.h> #elif defined (XP_WIN) || defined(XP_OS2) #include <io.h> #endif -using namespace mozilla; - //---------------------------------------------- // nsJARManifestItem declaration //---------------------------------------------- /* * nsJARManifestItem contains meta-information pertaining * to an individual JAR entry, taken from the * META-INF/MANIFEST.MF and META-INF/ *.SF files. * This is security-critical information, defined here so it is not @@ -120,19 +118,18 @@ DeleteManifestEntry(nsHashKey* aKey, voi // The following initialization makes a guess of 10 entries per jarfile. nsJAR::nsJAR(): mZip(new nsZipArchive()), mManifestData(nsnull, nsnull, DeleteManifestEntry, nsnull, 10), mParsedManifest(PR_FALSE), mGlobalStatus(JAR_MANIFEST_NOT_PARSED), mReleaseTime(PR_INTERVAL_NO_TIMEOUT), mCache(nsnull), - mLock("nsJAR::mLock"), - mTotalItemsInManifest(0), - mOpened(PR_FALSE) + mLock(nsnull), + mTotalItemsInManifest(0) { } nsJAR::~nsJAR() { Close(); } @@ -166,21 +163,23 @@ nsrefcnt nsJAR::Release(void) //---------------------------------------------- // nsIZipReader implementation //---------------------------------------------- NS_IMETHODIMP nsJAR::Open(nsIFile* zipFile) { NS_ENSURE_ARG_POINTER(zipFile); - if (mOpened) return NS_ERROR_FAILURE; // Already open! + if (mLock) return NS_ERROR_FAILURE; // Already open! mZipFile = zipFile; mOuterZipEntry.Truncate(); - mOpened = PR_TRUE; + + mLock = nsAutoLock::NewLock("nsJAR::mLock"); + NS_ENSURE_TRUE(mLock, NS_ERROR_OUT_OF_MEMORY); #ifdef MOZ_OMNIJAR // The omnijar is special, it is opened early on and closed late // this avoids reopening it PRBool equals; nsresult rv = zipFile->Equals(mozilla::OmnijarPath(), &equals); if (NS_SUCCEEDED(rv) && equals) { mZip = mozilla::OmnijarReader(); @@ -190,27 +189,28 @@ nsJAR::Open(nsIFile* zipFile) return mZip->OpenArchive(zipFile); } NS_IMETHODIMP nsJAR::OpenInner(nsIZipReader *aZipReader, const char *aZipEntry) { NS_ENSURE_ARG_POINTER(aZipReader); NS_ENSURE_ARG_POINTER(aZipEntry); - if (mOpened) return NS_ERROR_FAILURE; // Already open! + if (mLock) return NS_ERROR_FAILURE; // Already open! PRBool exist; nsresult rv = aZipReader->HasEntry(nsDependentCString(aZipEntry), &exist); NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_TRUE(exist, NS_ERROR_FILE_NOT_FOUND); rv = aZipReader->GetFile(getter_AddRefs(mZipFile)); NS_ENSURE_SUCCESS(rv, rv); - mOpened = PR_TRUE; + mLock = nsAutoLock::NewLock("nsJAR::mLock"); + NS_ENSURE_TRUE(mLock, NS_ERROR_OUT_OF_MEMORY); mOuterZipEntry.Assign(aZipEntry); nsRefPtr<nsZipHandle> handle; rv = nsZipHandle::Init(static_cast<nsJAR*>(aZipReader)->mZip.get(), aZipEntry, getter_AddRefs(handle)); if (NS_FAILED(rv)) return rv; @@ -224,17 +224,21 @@ nsJAR::GetFile(nsIFile* *result) *result = mZipFile; NS_IF_ADDREF(*result); return NS_OK; } NS_IMETHODIMP nsJAR::Close() { - mOpened = PR_FALSE; + if (mLock) { + nsAutoLock::DestroyLock(mLock); + mLock = nsnull; + } + mParsedManifest = PR_FALSE; mManifestData.Reset(); mGlobalStatus = JAR_MANIFEST_NOT_PARSED; mTotalItemsInManifest = 0; #ifdef MOZ_OMNIJAR if (mZip == mozilla::OmnijarReader()) { mZip.forget(); @@ -251,17 +255,17 @@ nsJAR::Test(const char *aEntryName) return mZip->Test(aEntryName); } NS_IMETHODIMP nsJAR::Extract(const char *zipEntry, nsIFile* outFile) { // nsZipArchive and zlib are not thread safe // we need to use a lock to prevent bug #51267 - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); nsresult rv; nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(outFile, &rv); if (NS_FAILED(rv)) return rv; nsZipItem *item = mZip->GetItem(zipEntry); NS_ENSURE_TRUE(item, NS_ERROR_FILE_TARGET_DOES_NOT_EXIST); @@ -1051,17 +1055,17 @@ nsJARItem::GetLastModifiedTime(PRTime* a } //////////////////////////////////////////////////////////////////////////////// // nsIZipReaderCache NS_IMPL_THREADSAFE_ISUPPORTS3(nsZipReaderCache, nsIZipReaderCache, nsIObserver, nsISupportsWeakReference) nsZipReaderCache::nsZipReaderCache() - : mLock("nsZipReaderCache.mLock") + : mLock(nsnull) , mZips(16) #ifdef ZIP_CACHE_HIT_RATE , mZipCacheLookups(0), mZipCacheHits(0), mZipCacheFlushes(0), mZipSyncMisses(0) #endif @@ -1079,46 +1083,49 @@ nsZipReaderCache::Init(PRUint32 cacheSiz if (os) { os->AddObserver(this, "memory-pressure", PR_TRUE); os->AddObserver(this, "chrome-flush-caches", PR_TRUE); os->AddObserver(this, "flush-cache-entry", PR_TRUE); } // ignore failure of the observer registration. - return NS_OK; + mLock = nsAutoLock::NewLock("nsZipReaderCache::mLock"); + return mLock ? NS_OK : NS_ERROR_OUT_OF_MEMORY; } static PRBool DropZipReaderCache(nsHashKey *aKey, void *aData, void* closure) { nsJAR* zip = (nsJAR*)aData; zip->SetZipReaderCache(nsnull); return PR_TRUE; } nsZipReaderCache::~nsZipReaderCache() { + if (mLock) + nsAutoLock::DestroyLock(mLock); mZips.Enumerate(DropZipReaderCache, nsnull); #ifdef ZIP_CACHE_HIT_RATE printf("nsZipReaderCache size=%d hits=%d lookups=%d rate=%f%% flushes=%d missed %d\n", mCacheSize, mZipCacheHits, mZipCacheLookups, (float)mZipCacheHits / mZipCacheLookups, mZipCacheFlushes, mZipSyncMisses); #endif } NS_IMETHODIMP nsZipReaderCache::GetZip(nsIFile* zipFile, nsIZipReader* *result) { NS_ENSURE_ARG_POINTER(zipFile); nsresult rv; nsCOMPtr<nsIZipReader> antiLockZipGrip; - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); #ifdef ZIP_CACHE_HIT_RATE mZipCacheLookups++; #endif nsCAutoString uri; rv = zipFile->GetNativePath(uri); if (NS_FAILED(rv)) return rv; @@ -1235,17 +1242,17 @@ FindZip(nsHashKey *aKey, void *aData, vo } return PR_TRUE; } nsresult nsZipReaderCache::ReleaseZip(nsJAR* zip) { nsresult rv; - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); // It is possible that two thread compete for this zip. The dangerous // case is where one thread Releases the zip and discovers that the ref // count has gone to one. Before it can call this ReleaseZip method // another thread calls our GetZip method. The ref count goes to two. That // second thread then Releases the zip and the ref count goes to one. It // then tries to enter this ReleaseZip method and blocks while the first // thread is still here. The first thread continues and remove the zip from @@ -1324,17 +1331,17 @@ FindFlushableZip(nsHashKey *aKey, void * } NS_IMETHODIMP nsZipReaderCache::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *aSomeData) { if (strcmp(aTopic, "memory-pressure") == 0) { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); while (PR_TRUE) { nsHashKey* flushable = nsnull; mZips.Enumerate(FindFlushableZip, &flushable); if ( ! flushable ) break; #ifdef DEBUG PRBool removed = #endif @@ -1357,17 +1364,17 @@ nsZipReaderCache::Observe(nsISupports *a nsCAutoString uri; if (NS_FAILED(file->GetNativePath(uri))) return NS_OK; uri.Insert(NS_LITERAL_CSTRING("file:"), 0); nsCStringKey key(uri); - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); nsJAR* zip = static_cast<nsJAR*>(static_cast<nsIZipReader*>(mZips.Get(&key))); if (!zip) return NS_OK; #ifdef ZIP_CACHE_HIT_RATE mZipCacheFlushes++; #endif
--- a/modules/libjar/nsJAR.h +++ b/modules/libjar/nsJAR.h @@ -47,23 +47,23 @@ #include "pratom.h" #include "prmem.h" #include "prio.h" #include "plstr.h" #include "prlog.h" #include "prtypes.h" #include "prinrval.h" -#include "mozilla/Mutex.h" #include "nsIComponentManager.h" #include "nsCOMPtr.h" #include "nsString.h" #include "nsIFile.h" #include "nsStringEnumerator.h" #include "nsHashtable.h" +#include "nsAutoLock.h" #include "nsIZipReader.h" #include "nsZipArchive.h" #include "nsIPrincipal.h" #include "nsISignatureVerifier.h" #include "nsIObserverService.h" #include "nsWeakReference.h" #include "nsIObserver.h" @@ -135,21 +135,20 @@ class nsJAR : public nsIZipReader nsCString mOuterZipEntry; // The entry in the zip this zip is reading from nsAutoPtr<nsZipArchive> mZip; // The underlying zip archive nsObjectHashtable mManifestData; // Stores metadata for each entry PRBool mParsedManifest; // True if manifest has been parsed nsCOMPtr<nsIPrincipal> mPrincipal; // The entity which signed this file PRInt16 mGlobalStatus; // Global signature verification status PRIntervalTime mReleaseTime; // used by nsZipReaderCache for flushing entries nsZipReaderCache* mCache; // if cached, this points to the cache it's contained in - mozilla::Mutex mLock; + PRLock* mLock; PRInt64 mMtime; PRInt32 mTotalItemsInManifest; - PRBool mOpened; - + nsresult ParseManifest(); void ReportError(const char* aFilename, PRInt16 errorCode); nsresult LoadEntry(const char* aFilename, char** aBuf, PRUint32* aBufLen = nsnull); PRInt32 ReadLine(const char** src); nsresult ParseOneFile(const char* filebuf, PRInt16 aFileType); nsresult VerifyEntry(nsJARManifestItem* aEntry, const char* aEntryData, PRUint32 aLen); @@ -225,17 +224,17 @@ public: NS_DECL_NSIOBSERVER nsZipReaderCache(); virtual ~nsZipReaderCache(); nsresult ReleaseZip(nsJAR* reader); protected: - mozilla::Mutex mLock; + PRLock* mLock; PRInt32 mCacheSize; nsSupportsHashtable mZips; #ifdef ZIP_CACHE_HIT_RATE PRUint32 mZipCacheLookups; PRUint32 mZipCacheHits; PRUint32 mZipCacheFlushes; PRUint32 mZipSyncMisses;
--- a/modules/plugin/base/src/nsNPAPIPlugin.cpp +++ b/modules/plugin/base/src/nsNPAPIPlugin.cpp @@ -46,16 +46,17 @@ #include "prtypes.h" #include "prmem.h" #include "prenv.h" #include "prclist.h" #include "jscntxt.h" +#include "nsAutoLock.h" #include "nsNPAPIPlugin.h" #include "nsNPAPIPluginInstance.h" #include "nsNPAPIPluginStreamListener.h" #include "nsIServiceManager.h" #include "nsThreadUtils.h" #include "nsIPrivateBrowsingService.h" #include "nsIPluginStreamListener.h" @@ -102,17 +103,16 @@ #endif #include "nsJSNPRuntime.h" #include "nsIHttpAuthManager.h" #include "nsICookieService.h" #include "nsNetUtil.h" -#include "mozilla/Mutex.h" #include "mozilla/PluginLibrary.h" using mozilla::PluginLibrary; #include "mozilla/PluginPRLibrary.h" using mozilla::PluginPRLibrary; #ifdef MOZ_IPC #include "mozilla/plugins/PluginModuleParent.h" @@ -122,17 +122,16 @@ using mozilla::plugins::PluginModulePare #ifdef MOZ_X11 #include "mozilla/X11Util.h" #endif #ifdef XP_WIN #include <windows.h> #endif -using namespace mozilla; using namespace mozilla::plugins::parent; // We should make this const... static NPNetscapeFuncs sBrowserFuncs = { sizeof(sBrowserFuncs), (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR, _geturl, _posturl, @@ -186,17 +185,17 @@ static NPNetscapeFuncs sBrowserFuncs = { _unscheduletimer, _popupcontextmenu, _convertpoint, NULL, // handleevent, unimplemented NULL, // unfocusinstance, unimplemented _urlredirectresponse }; -static Mutex *sPluginThreadAsyncCallLock = nsnull; +static PRLock *sPluginThreadAsyncCallLock = nsnull; static PRCList sPendingAsyncCalls = PR_INIT_STATIC_CLIST(&sPendingAsyncCalls); // POST/GET stream type enum eNPPStreamTypeInternal { eNPPStreamTypeInternal_Get, eNPPStreamTypeInternal_Post }; @@ -225,17 +224,17 @@ void NS_NotifyPluginCall(PRIntervalTime static void CheckClassInitialized() { static PRBool initialized = PR_FALSE; if (initialized) return; if (!sPluginThreadAsyncCallLock) - sPluginThreadAsyncCallLock = new Mutex("nsNPAPIPlugin.sPluginThreadAsyncCallLock"); + sPluginThreadAsyncCallLock = nsAutoLock::NewLock("sPluginThreadAsyncCallLock"); initialized = PR_TRUE; NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,("NPN callbacks initialized\n")); } NS_IMPL_ISUPPORTS1(nsNPAPIPlugin, nsIPlugin) @@ -836,17 +835,17 @@ nsPluginThreadRunnable::nsPluginThreadRu mFunc = nsnull; return; } PR_INIT_CLIST(this); { - MutexAutoLock lock(*sPluginThreadAsyncCallLock); + nsAutoLock lock(sPluginThreadAsyncCallLock); nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata; if (!inst || !inst->IsRunning()) { // The plugin was stopped, ignore this async call. mFunc = nsnull; return; } @@ -857,17 +856,17 @@ nsPluginThreadRunnable::nsPluginThreadRu nsPluginThreadRunnable::~nsPluginThreadRunnable() { if (!sPluginThreadAsyncCallLock) { return; } { - MutexAutoLock lock(*sPluginThreadAsyncCallLock); + nsAutoLock lock(sPluginThreadAsyncCallLock); PR_REMOVE_LINK(this); } } NS_IMETHODIMP nsPluginThreadRunnable::Run() { @@ -883,17 +882,17 @@ nsPluginThreadRunnable::Run() void OnPluginDestroy(NPP instance) { if (!sPluginThreadAsyncCallLock) { return; } { - MutexAutoLock lock(*sPluginThreadAsyncCallLock); + nsAutoLock lock(sPluginThreadAsyncCallLock); if (PR_CLIST_IS_EMPTY(&sPendingAsyncCalls)) { return; } nsPluginThreadRunnable *r = (nsPluginThreadRunnable *)PR_LIST_HEAD(&sPendingAsyncCalls); @@ -909,33 +908,38 @@ OnPluginDestroy(NPP instance) void OnShutdown() { NS_ASSERTION(PR_CLIST_IS_EMPTY(&sPendingAsyncCalls), "Pending async plugin call list not cleaned up!"); if (sPluginThreadAsyncCallLock) { - delete sPluginThreadAsyncCallLock; + nsAutoLock::DestroyLock(sPluginThreadAsyncCallLock); sPluginThreadAsyncCallLock = nsnull; } } -AsyncCallbackAutoLock::AsyncCallbackAutoLock() +void +EnterAsyncPluginThreadCallLock() { - sPluginThreadAsyncCallLock->Lock(); + if (sPluginThreadAsyncCallLock) { + PR_Lock(sPluginThreadAsyncCallLock); + } } -AsyncCallbackAutoLock::~AsyncCallbackAutoLock() +void +ExitAsyncPluginThreadCallLock() { - sPluginThreadAsyncCallLock->Unlock(); + if (sPluginThreadAsyncCallLock) { + PR_Unlock(sPluginThreadAsyncCallLock); + } } - NPP NPPStack::sCurrentNPP = nsnull; const char * PeekException() { return gNPPException; }
--- a/modules/plugin/base/src/nsNPAPIPlugin.h +++ b/modules/plugin/base/src/nsNPAPIPlugin.h @@ -378,25 +378,20 @@ void PopException(); void OnPluginDestroy(NPP instance); void OnShutdown(); -/** - * within a lexical scope, locks and unlocks the mutex used to - * serialize modifications to plugin async callback state. - */ -struct NS_STACK_CLASS AsyncCallbackAutoLock -{ - AsyncCallbackAutoLock(); - ~AsyncCallbackAutoLock(); -}; +void +EnterAsyncPluginThreadCallLock(); +void +ExitAsyncPluginThreadCallLock(); class NPPStack { public: static NPP Peek() { return sCurrentNPP; }
--- a/modules/plugin/base/src/nsNPAPIPluginInstance.cpp +++ b/modules/plugin/base/src/nsNPAPIPluginInstance.cpp @@ -184,21 +184,20 @@ NS_IMETHODIMP nsNPAPIPluginInstance::Sto // If there's code from this plugin instance on the stack, delay the // destroy. if (PluginDestructionGuard::DelayDestroy(this)) { return NS_OK; } // Make sure we lock while we're writing to mRunning after we've // started as other threads might be checking that inside a lock. - { - AsyncCallbackAutoLock lock; - mRunning = DESTROYING; - mStopTime = TimeStamp::Now(); - } + EnterAsyncPluginThreadCallLock(); + mRunning = DESTROYING; + mStopTime = TimeStamp::Now(); + ExitAsyncPluginThreadCallLock(); OnPluginDestroy(&mNPP); // clean up open streams while (mStreamListeners.Length() > 0) { nsRefPtr<nsNPAPIPluginStreamListener> currentListener(mStreamListeners[0]); currentListener->CleanUpStream(NPRES_USER_BREAK); mStreamListeners.RemoveElement(currentListener);
--- a/netwerk/base/src/nsAsyncStreamCopier.cpp +++ b/netwerk/base/src/nsAsyncStreamCopier.cpp @@ -36,67 +36,68 @@ * ***** END LICENSE BLOCK ***** */ #include "nsIOService.h" #include "nsAsyncStreamCopier.h" #include "nsIEventTarget.h" #include "nsStreamUtils.h" #include "nsNetSegmentUtils.h" #include "nsNetUtil.h" +#include "nsAutoLock.h" #include "prlog.h" -using namespace mozilla; - #if defined(PR_LOGGING) // // NSPR_LOG_MODULES=nsStreamCopier:5 // static PRLogModuleInfo *gStreamCopierLog = nsnull; #endif #define LOG(args) PR_LOG(gStreamCopierLog, PR_LOG_DEBUG, args) //----------------------------------------------------------------------------- nsAsyncStreamCopier::nsAsyncStreamCopier() - : mLock("nsAsyncStreamCopier.mLock") + : mLock(nsnull) , mMode(NS_ASYNCCOPY_VIA_READSEGMENTS) , mChunkSize(nsIOService::gDefaultSegmentSize) , mStatus(NS_OK) , mIsPending(PR_FALSE) { #if defined(PR_LOGGING) if (!gStreamCopierLog) gStreamCopierLog = PR_NewLogModule("nsStreamCopier"); #endif LOG(("Creating nsAsyncStreamCopier @%x\n", this)); } nsAsyncStreamCopier::~nsAsyncStreamCopier() { LOG(("Destroying nsAsyncStreamCopier @%x\n", this)); + if (mLock) + nsAutoLock::DestroyLock(mLock); } PRBool nsAsyncStreamCopier::IsComplete(nsresult *status) { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); if (status) *status = mStatus; return !mIsPending; } void nsAsyncStreamCopier::Complete(nsresult status) { LOG(("nsAsyncStreamCopier::Complete [this=%x status=%x]\n", this, status)); nsCOMPtr<nsIRequestObserver> observer; nsCOMPtr<nsISupports> ctx; { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); mCopierCtx = nsnull; if (mIsPending) { mIsPending = PR_FALSE; mStatus = status; // setup OnStopRequest callback and release references... observer = mObserver; @@ -151,17 +152,17 @@ nsAsyncStreamCopier::GetStatus(nsresult return NS_OK; } NS_IMETHODIMP nsAsyncStreamCopier::Cancel(nsresult status) { nsCOMPtr<nsISupports> copierCtx; { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); if (!mIsPending) return NS_OK; copierCtx.swap(mCopierCtx); } if (NS_SUCCEEDED(status)) { NS_WARNING("cancel with non-failure status code"); status = NS_BASE_STREAM_CLOSED; @@ -223,16 +224,21 @@ nsAsyncStreamCopier::Init(nsIInputStream PRBool sourceBuffered, PRBool sinkBuffered, PRUint32 chunkSize, PRBool closeSource, PRBool closeSink) { NS_ASSERTION(sourceBuffered || sinkBuffered, "at least one stream must be buffered"); + NS_ASSERTION(!mLock, "already initialized"); + mLock = nsAutoLock::NewLock("nsAsyncStreamCopier::mLock"); + if (!mLock) + return NS_ERROR_OUT_OF_MEMORY; + if (chunkSize == 0) chunkSize = nsIOService::gDefaultSegmentSize; mChunkSize = chunkSize; mSource = source; mSink = sink; mCloseSource = closeSource; mCloseSink = closeSink;
--- a/netwerk/base/src/nsAsyncStreamCopier.h +++ b/netwerk/base/src/nsAsyncStreamCopier.h @@ -37,19 +37,19 @@ #ifndef nsAsyncStreamCopier_h__ #define nsAsyncStreamCopier_h__ #include "nsIAsyncStreamCopier.h" #include "nsIAsyncInputStream.h" #include "nsIAsyncOutputStream.h" #include "nsIRequestObserver.h" -#include "mozilla/Mutex.h" #include "nsStreamUtils.h" #include "nsCOMPtr.h" +#include "prlock.h" //----------------------------------------------------------------------------- class nsAsyncStreamCopier : public nsIAsyncStreamCopier { public: NS_DECL_ISUPPORTS NS_DECL_NSIREQUEST @@ -73,17 +73,17 @@ private: nsCOMPtr<nsIRequestObserver> mObserver; nsCOMPtr<nsISupports> mObserverContext; nsCOMPtr<nsIEventTarget> mTarget; nsCOMPtr<nsISupports> mCopierCtx; - mozilla::Mutex mLock; + PRLock *mLock; nsAsyncCopyMode mMode; PRUint32 mChunkSize; nsresult mStatus; PRPackedBool mIsPending; PRPackedBool mCloseSource; PRPackedBool mCloseSink; };
--- a/netwerk/base/src/nsPACMan.cpp +++ b/netwerk/base/src/nsPACMan.cpp @@ -42,16 +42,17 @@ #include "nsIDNSListener.h" #include "nsICancelable.h" #include "nsIAuthPrompt.h" #include "nsIPromptFactory.h" #include "nsIHttpChannel.h" #include "nsIPrefService.h" #include "nsIPrefBranch.h" #include "nsNetUtil.h" +#include "nsAutoLock.h" #include "nsAutoPtr.h" #include "nsCRT.h" #include "prmon.h" #include "nsIAsyncVerifyRedirectCallback.h" //----------------------------------------------------------------------------- // Check to see if the underlying request was not an error page in the case of
--- a/netwerk/base/src/nsProtocolProxyService.cpp +++ b/netwerk/base/src/nsProtocolProxyService.cpp @@ -38,16 +38,17 @@ * ***** END LICENSE BLOCK ***** */ #include "nsProtocolProxyService.h" #include "nsProxyInfo.h" #include "nsIClassInfoImpl.h" #include "nsIServiceManager.h" #include "nsXPIDLString.h" #include "nsIProxyAutoConfig.h" +#include "nsAutoLock.h" #include "nsIIOService.h" #include "nsIObserverService.h" #include "nsIProtocolHandler.h" #include "nsIProtocolProxyCallback.h" #include "nsICancelable.h" #include "nsIDNSService.h" #include "nsIPrefService.h" #include "nsIPrefBranch2.h"
--- a/netwerk/base/src/nsServerSocket.cpp +++ b/netwerk/base/src/nsServerSocket.cpp @@ -35,24 +35,23 @@ * * ***** END LICENSE BLOCK ***** */ #include "nsIProxyObjectManager.h" #include "nsIServiceManager.h" #include "nsSocketTransport2.h" #include "nsServerSocket.h" #include "nsProxyRelease.h" +#include "nsAutoLock.h" #include "nsAutoPtr.h" #include "nsNetError.h" #include "nsNetCID.h" #include "prnetdb.h" #include "prio.h" -using namespace mozilla; - static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID); //----------------------------------------------------------------------------- typedef void (nsServerSocket:: *nsServerSocketFunc)(void); static nsresult PostEvent(nsServerSocket *s, nsServerSocketFunc func) @@ -67,17 +66,17 @@ PostEvent(nsServerSocket *s, nsServerSoc return gSocketTransportService->Dispatch(ev, NS_DISPATCH_NORMAL); } //----------------------------------------------------------------------------- // nsServerSocket //----------------------------------------------------------------------------- nsServerSocket::nsServerSocket() - : mLock("nsServerSocket.mLock") + : mLock(nsnull) , mFD(nsnull) , mAttached(PR_FALSE) { // we want to be able to access the STS directly, and it may not have been // constructed yet. the STS constructor sets gSocketTransportService. if (!gSocketTransportService) { // This call can fail if we're offline, for example. @@ -87,16 +86,19 @@ nsServerSocket::nsServerSocket() // make sure the STS sticks around as long as we do NS_IF_ADDREF(gSocketTransportService); } nsServerSocket::~nsServerSocket() { Close(); // just in case :) + if (mLock) + nsAutoLock::DestroyLock(mLock); + // release our reference to the STS nsSocketTransportService *serv = gSocketTransportService; NS_IF_RELEASE(serv); } void nsServerSocket::OnMsgClose() { @@ -239,17 +241,17 @@ nsServerSocket::OnSocketDetached(PRFileD if (mListener) { mListener->OnStopListening(this, mCondition); // need to atomically clear mListener. see our Close() method. nsIServerSocketListener *listener = nsnull; { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); mListener.swap(listener); } // XXX we need to proxy the release to the listener's target thread to work // around bug 337492. if (listener) NS_ProxyRelease(mListenerTarget, listener); } } @@ -283,16 +285,23 @@ nsServerSocket::Init(PRInt32 aPort, PRBo return InitWithAddress(&addr, aBackLog); } NS_IMETHODIMP nsServerSocket::InitWithAddress(const PRNetAddr *aAddr, PRInt32 aBackLog) { NS_ENSURE_TRUE(mFD == nsnull, NS_ERROR_ALREADY_INITIALIZED); + if (!mLock) + { + mLock = nsAutoLock::NewLock("nsServerSocket::mLock"); + if (!mLock) + return NS_ERROR_OUT_OF_MEMORY; + } + // // configure listening socket... // mFD = PR_OpenTCPSocket(aAddr->raw.family); if (!mFD) { NS_WARNING("unable to create server socket"); @@ -339,18 +348,19 @@ nsServerSocket::InitWithAddress(const PR fail: Close(); return NS_ERROR_FAILURE; } NS_IMETHODIMP nsServerSocket::Close() { + NS_ENSURE_TRUE(mLock, NS_ERROR_NOT_INITIALIZED); { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); // we want to proxy the close operation to the socket thread if a listener // has been set. otherwise, we should just close the socket here... if (!mListener) { if (mFD) { PR_Close(mFD); mFD = nsnull; @@ -363,17 +373,17 @@ nsServerSocket::Close() NS_IMETHODIMP nsServerSocket::AsyncListen(nsIServerSocketListener *aListener) { // ensuring mFD implies ensuring mLock NS_ENSURE_TRUE(mFD, NS_ERROR_NOT_INITIALIZED); NS_ENSURE_TRUE(mListener == nsnull, NS_ERROR_IN_PROGRESS); { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); nsresult rv = NS_GetProxyForObject(NS_PROXY_TO_CURRENT_THREAD, NS_GET_IID(nsIServerSocketListener), aListener, NS_PROXY_ASYNC | NS_PROXY_ALWAYS, getter_AddRefs(mListener)); if (NS_FAILED(rv)) return rv; mListenerTarget = NS_GetCurrentThread();
--- a/netwerk/base/src/nsServerSocket.h +++ b/netwerk/base/src/nsServerSocket.h @@ -35,17 +35,16 @@ * * ***** END LICENSE BLOCK ***** */ #ifndef nsServerSocket_h__ #define nsServerSocket_h__ #include "nsIServerSocket.h" #include "nsSocketTransportService2.h" -#include "mozilla/Mutex.h" //----------------------------------------------------------------------------- class nsServerSocket : public nsASocketHandler , public nsIServerSocket { public: NS_DECL_ISUPPORTS @@ -63,17 +62,17 @@ public: private: void OnMsgClose(); void OnMsgAttach(); // try attaching our socket (mFD) to the STS's poll list. nsresult TryAttach(); // lock protects access to mListener; so it is not cleared while being used. - mozilla::Mutex mLock; + PRLock *mLock; PRFileDesc *mFD; PRNetAddr mAddr; nsCOMPtr<nsIServerSocketListener> mListener; nsCOMPtr<nsIEventTarget> mListenerTarget; PRBool mAttached; }; //-----------------------------------------------------------------------------
--- a/netwerk/base/src/nsSocketTransport2.cpp +++ b/netwerk/base/src/nsSocketTransport2.cpp @@ -45,16 +45,17 @@ #include "nsSocketTransport2.h" #include "nsAtomicRefcnt.h" #include "nsIOService.h" #include "nsStreamUtils.h" #include "nsNetSegmentUtils.h" #include "nsTransportUtils.h" #include "nsProxyInfo.h" #include "nsNetCID.h" +#include "nsAutoLock.h" #include "nsAutoPtr.h" #include "nsCOMPtr.h" #include "netCore.h" #include "nsInt64.h" #include "prmem.h" #include "plstr.h" #include "prnetdb.h" #include "prerror.h" @@ -69,18 +70,16 @@ #include "nsIPipe.h" #include "nsIProgrammingLanguage.h" #include "nsIClassInfoImpl.h" #if defined(XP_WIN) || defined(MOZ_PLATFORM_MAEMO) #include "nsNativeConnectionHelper.h" #endif -using namespace mozilla; - //----------------------------------------------------------------------------- static NS_DEFINE_CID(kSocketProviderServiceCID, NS_SOCKETPROVIDERSERVICE_CID); static NS_DEFINE_CID(kDNSServiceCID, NS_DNSSERVICE_CID); //----------------------------------------------------------------------------- class nsSocketEvent : public nsRunnable @@ -233,17 +232,17 @@ nsSocketInputStream::OnSocketReady(nsres { SOCKET_LOG(("nsSocketInputStream::OnSocketReady [this=%x cond=%x]\n", this, condition)); NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread"); nsCOMPtr<nsIInputStreamCallback> callback; { - MutexAutoLock lock(mTransport->mLock); + nsAutoLock lock(mTransport->mLock); // update condition, but be careful not to erase an already // existing error condition. if (NS_SUCCEEDED(mCondition)) mCondition = condition; // ignore event if only waiting for closure and not closed. if (NS_FAILED(mCondition) || !(mCallbackFlags & WAIT_CLOSURE_ONLY)) { @@ -286,34 +285,34 @@ NS_IMETHODIMP nsSocketInputStream::Available(PRUint32 *avail) { SOCKET_LOG(("nsSocketInputStream::Available [this=%x]\n", this)); *avail = 0; PRFileDesc *fd; { - MutexAutoLock lock(mTransport->mLock); + nsAutoLock lock(mTransport->mLock); if (NS_FAILED(mCondition)) return mCondition; fd = mTransport->GetFD_Locked(); if (!fd) return NS_OK; } // cannot hold lock while calling NSPR. (worried about the fact that PSM // synchronously proxies notifications over to the UI thread, which could // mistakenly try to re-enter this code.) PRInt32 n = PR_Available(fd); nsresult rv; { - MutexAutoLock lock(mTransport->mLock); + nsAutoLock lock(mTransport->mLock); mTransport->ReleaseFD_Locked(fd); if (n >= 0) *avail = n; else { PRErrorCode code = PR_GetError(); if (code == PR_WOULD_BLOCK_ERROR) @@ -331,17 +330,17 @@ NS_IMETHODIMP nsSocketInputStream::Read(char *buf, PRUint32 count, PRUint32 *countRead) { SOCKET_LOG(("nsSocketInputStream::Read [this=%x count=%u]\n", this, count)); *countRead = 0; PRFileDesc *fd; { - MutexAutoLock lock(mTransport->mLock); + nsAutoLock lock(mTransport->mLock); if (NS_FAILED(mCondition)) return (mCondition == NS_BASE_STREAM_CLOSED) ? NS_OK : mCondition; fd = mTransport->GetFD_Locked(); if (!fd) return NS_BASE_STREAM_WOULD_BLOCK; } @@ -352,17 +351,17 @@ nsSocketInputStream::Read(char *buf, PRU // synchronously proxies notifications over to the UI thread, which could // mistakenly try to re-enter this code.) PRInt32 n = PR_Read(fd, buf, count); SOCKET_LOG((" PR_Read returned [n=%d]\n", n)); nsresult rv; { - MutexAutoLock lock(mTransport->mLock); + nsAutoLock lock(mTransport->mLock); #ifdef ENABLE_SOCKET_TRACING if (n > 0) mTransport->TraceInBuf(buf, n); #endif mTransport->ReleaseFD_Locked(fd); @@ -405,17 +404,17 @@ NS_IMETHODIMP nsSocketInputStream::CloseWithStatus(nsresult reason) { SOCKET_LOG(("nsSocketInputStream::CloseWithStatus [this=%x reason=%x]\n", this, reason)); // may be called from any thread nsresult rv; { - MutexAutoLock lock(mTransport->mLock); + nsAutoLock lock(mTransport->mLock); if (NS_SUCCEEDED(mCondition)) rv = mCondition = reason; else rv = NS_OK; } if (NS_FAILED(rv)) mTransport->OnInputClosed(rv); @@ -430,17 +429,17 @@ nsSocketInputStream::AsyncWait(nsIInputS { SOCKET_LOG(("nsSocketInputStream::AsyncWait [this=%x]\n", this)); // This variable will be non-null when we want to call the callback // directly from this function, but outside the lock. // (different from callback when target is not null) nsCOMPtr<nsIInputStreamCallback> directCallback; { - MutexAutoLock lock(mTransport->mLock); + nsAutoLock lock(mTransport->mLock); if (callback && target) { // // build event proxy // // failure to create an event proxy (most likely out of memory) // shouldn't alter the state of the transport. // @@ -492,17 +491,17 @@ nsSocketOutputStream::OnSocketReady(nsre { SOCKET_LOG(("nsSocketOutputStream::OnSocketReady [this=%x cond=%x]\n", this, condition)); NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread"); nsCOMPtr<nsIOutputStreamCallback> callback; { - MutexAutoLock lock(mTransport->mLock); + nsAutoLock lock(mTransport->mLock); // update condition, but be careful not to erase an already // existing error condition. if (NS_SUCCEEDED(mCondition)) mCondition = condition; // ignore event if only waiting for closure and not closed. if (NS_FAILED(mCondition) || !(mCallbackFlags & WAIT_CLOSURE_ONLY)) { @@ -554,17 +553,17 @@ nsSocketOutputStream::Write(const char * *countWritten = 0; if (count == 0) return NS_OK; PRFileDesc *fd; { - MutexAutoLock lock(mTransport->mLock); + nsAutoLock lock(mTransport->mLock); if (NS_FAILED(mCondition)) return mCondition; fd = mTransport->GetFD_Locked(); if (!fd) return NS_BASE_STREAM_WOULD_BLOCK; } @@ -576,17 +575,17 @@ nsSocketOutputStream::Write(const char * // mistakenly try to re-enter this code.) PRInt32 n = PR_Write(fd, buf, count); SOCKET_LOG((" PR_Write returned [n=%d]\n", n)); NS_ASSERTION(n != 0, "unexpected return value"); nsresult rv; { - MutexAutoLock lock(mTransport->mLock); + nsAutoLock lock(mTransport->mLock); #ifdef ENABLE_SOCKET_TRACING if (n > 0) mTransport->TraceOutBuf(buf, n); #endif mTransport->ReleaseFD_Locked(fd); @@ -647,17 +646,17 @@ NS_IMETHODIMP nsSocketOutputStream::CloseWithStatus(nsresult reason) { SOCKET_LOG(("nsSocketOutputStream::CloseWithStatus [this=%x reason=%x]\n", this, reason)); // may be called from any thread nsresult rv; { - MutexAutoLock lock(mTransport->mLock); + nsAutoLock lock(mTransport->mLock); if (NS_SUCCEEDED(mCondition)) rv = mCondition = reason; else rv = NS_OK; } if (NS_FAILED(rv)) mTransport->OnOutputClosed(rv); @@ -668,17 +667,17 @@ NS_IMETHODIMP nsSocketOutputStream::AsyncWait(nsIOutputStreamCallback *callback, PRUint32 flags, PRUint32 amount, nsIEventTarget *target) { SOCKET_LOG(("nsSocketOutputStream::AsyncWait [this=%x]\n", this)); { - MutexAutoLock lock(mTransport->mLock); + nsAutoLock lock(mTransport->mLock); if (callback && target) { // // build event proxy // // failure to create an event proxy (most likely out of memory) // shouldn't alter the state of the transport. // @@ -709,17 +708,17 @@ nsSocketTransport::nsSocketTransport() , mProxyTransparent(PR_FALSE) , mProxyTransparentResolvesHost(PR_FALSE) , mConnectionFlags(0) , mState(STATE_CLOSED) , mAttached(PR_FALSE) , mInputClosed(PR_TRUE) , mOutputClosed(PR_TRUE) , mResolving(PR_FALSE) - , mLock("nsSocketTransport.mLock") + , mLock(nsAutoLock::NewLock("nsSocketTransport::mLock")) , mFD(nsnull) , mFDref(0) , mFDconnected(PR_FALSE) , mInput(this) , mOutput(this) , mQoSBits(0x00) { SOCKET_LOG(("creating nsSocketTransport @%x\n", this)); @@ -736,26 +735,32 @@ nsSocketTransport::~nsSocketTransport() // cleanup socket type info if (mTypes) { PRUint32 i; for (i=0; i<mTypeCount; ++i) PL_strfree(mTypes[i]); free(mTypes); } + + if (mLock) + nsAutoLock::DestroyLock(mLock); nsSocketTransportService *serv = gSocketTransportService; NS_RELEASE(serv); // nulls argument } nsresult nsSocketTransport::Init(const char **types, PRUint32 typeCount, const nsACString &host, PRUint16 port, nsIProxyInfo *givenProxyInfo) { + if (!mLock) + return NS_ERROR_OUT_OF_MEMORY; + nsCOMPtr<nsProxyInfo> proxyInfo; if (givenProxyInfo) { proxyInfo = do_QueryInterface(givenProxyInfo); NS_ENSURE_ARG(proxyInfo); } // init socket type info @@ -827,16 +832,19 @@ nsSocketTransport::Init(const char **typ } return NS_OK; } nsresult nsSocketTransport::InitWithConnectedSocket(PRFileDesc *fd, const PRNetAddr *addr) { + if (!mLock) + return NS_ERROR_OUT_OF_MEMORY; + NS_ASSERTION(!mFD, "already initialized"); char buf[64]; PR_NetAddrToString(addr, buf, sizeof(buf)); mHost.Assign(buf); PRUint16 port; if (addr->raw.family == PR_AF_INET) @@ -884,17 +892,17 @@ nsSocketTransport::PostEvent(PRUint32 ty void nsSocketTransport::SendStatus(nsresult status) { SOCKET_LOG(("nsSocketTransport::SendStatus [this=%x status=%x]\n", this, status)); nsCOMPtr<nsITransportEventSink> sink; PRUint64 progress; { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); sink = mEventSink; switch (status) { case STATUS_SENDING_TO: progress = mOutput.ByteCount(); break; case STATUS_RECEIVING_FROM: progress = mInput.ByteCount(); break; @@ -1027,17 +1035,17 @@ nsSocketTransport::BuildSocket(PRFileDes break; // if the service was ssl or starttls, we want to hold onto the socket info PRBool isSSL = (strcmp(mTypes[i], "ssl") == 0); if (isSSL || (strcmp(mTypes[i], "starttls") == 0)) { // remember security info and give notification callbacks to PSM... nsCOMPtr<nsIInterfaceRequestor> callbacks; { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); mSecInfo = secinfo; callbacks = mCallbacks; SOCKET_LOG((" [secinfo=%x callbacks=%x]\n", mSecInfo.get(), mCallbacks.get())); } // don't call into PSM while holding mLock!! nsCOMPtr<nsISSLSocketControl> secCtrl(do_QueryInterface(secinfo)); if (secCtrl) secCtrl->SetNotificationCallbacks(callbacks); @@ -1146,17 +1154,17 @@ nsSocketTransport::InitiateSocket() PR_Close(fd); return rv; } mAttached = PR_TRUE; // assign mFD so that we can properly handle OnSocketDetached before we've // established a connection. { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); mFD = fd; mFDref = 1; mFDconnected = PR_FALSE; } SOCKET_LOG((" advancing to STATE_CONNECTING\n")); mState = STATE_CONNECTING; mPollTimeout = mTimeouts[TIMEOUT_CONNECT]; @@ -1360,17 +1368,17 @@ nsSocketTransport::OnSocketConnected() mPollFlags = (PR_POLL_READ | PR_POLL_WRITE | PR_POLL_EXCEPT); mPollTimeout = mTimeouts[TIMEOUT_READ_WRITE]; mState = STATE_TRANSFERRING; // assign mFD (must do this within the transport lock), but take care not // to trample over mFDref if mFD is already set. { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); NS_ASSERTION(mFD, "no socket"); NS_ASSERTION(mFDref == 1, "wrong socket ref count"); mFDconnected = PR_TRUE; } SendStatus(STATUS_CONNECTED_TO); } @@ -1627,17 +1635,17 @@ nsSocketTransport::OnSocketDetached(PRFi // We should be careful not to release mEventSink and mCallbacks while // we're locked, because releasing it might require acquiring the lock // again, so we just null out mEventSink and mCallbacks while we're // holding the lock, and let the stack based objects' destuctors take // care of destroying it if needed. nsCOMPtr<nsIInterfaceRequestor> ourCallbacks; nsCOMPtr<nsITransportEventSink> ourEventSink; { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); if (mFD) { ReleaseFD_Locked(mFD); // flag mFD as unusable; this prevents other consumers from // acquiring a reference to mFD. mFDconnected = PR_FALSE; } // We must release mCallbacks and mEventSink to avoid memory leak @@ -1768,33 +1776,33 @@ nsSocketTransport::Close(nsresult reason mInput.CloseWithStatus(reason); mOutput.CloseWithStatus(reason); return NS_OK; } NS_IMETHODIMP nsSocketTransport::GetSecurityInfo(nsISupports **secinfo) { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); NS_IF_ADDREF(*secinfo = mSecInfo); return NS_OK; } NS_IMETHODIMP nsSocketTransport::GetSecurityCallbacks(nsIInterfaceRequestor **callbacks) { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); NS_IF_ADDREF(*callbacks = mCallbacks); return NS_OK; } NS_IMETHODIMP nsSocketTransport::SetSecurityCallbacks(nsIInterfaceRequestor *callbacks) { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); mCallbacks = callbacks; // XXX should we tell PSM about this? return NS_OK; } NS_IMETHODIMP nsSocketTransport::SetEventSink(nsITransportEventSink *sink, nsIEventTarget *target) @@ -1803,46 +1811,46 @@ nsSocketTransport::SetEventSink(nsITrans if (target) { nsresult rv = net_NewTransportEventSinkProxy(getter_AddRefs(temp), sink, target); if (NS_FAILED(rv)) return rv; sink = temp.get(); } - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); mEventSink = sink; return NS_OK; } NS_IMETHODIMP nsSocketTransport::IsAlive(PRBool *result) { *result = PR_FALSE; PRFileDesc *fd; { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); if (NS_FAILED(mCondition)) return NS_OK; fd = GetFD_Locked(); if (!fd) return NS_OK; } // XXX do some idle-time based checks?? char c; PRInt32 rval = PR_Recv(fd, &c, 1, PR_MSG_PEEK, 0); if ((rval > 0) || (rval < 0 && PR_GetError() == PR_WOULD_BLOCK_ERROR)) *result = PR_TRUE; { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); ReleaseFD_Locked(fd); } return NS_OK; } NS_IMETHODIMP nsSocketTransport::GetHost(nsACString &host) { @@ -1875,28 +1883,28 @@ NS_IMETHODIMP nsSocketTransport::GetSelfAddr(PRNetAddr *addr) { // we must not call any PR methods on our file descriptor // while holding mLock since those methods might re-enter // socket transport code. PRFileDesc *fd; { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); fd = GetFD_Locked(); } if (!fd) return NS_ERROR_NOT_CONNECTED; nsresult rv = (PR_GetSockName(fd, addr) == PR_SUCCESS) ? NS_OK : NS_ERROR_FAILURE; { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); ReleaseFD_Locked(fd); } return rv; } NS_IMETHODIMP nsSocketTransport::GetTimeout(PRUint32 type, PRUint32 *value)
--- a/netwerk/base/src/nsSocketTransport2.h +++ b/netwerk/base/src/nsSocketTransport2.h @@ -37,17 +37,16 @@ #ifndef nsSocketTransport2_h__ #define nsSocketTransport2_h__ #ifdef DEBUG_darinf #define ENABLE_SOCKET_TRACING #endif -#include "mozilla/Mutex.h" #include "nsSocketTransportService2.h" #include "nsString.h" #include "nsCOMPtr.h" #include "nsInt64.h" #include "nsISocketTransport.h" #include "nsIInterfaceRequestor.h" #include "nsIAsyncInputStream.h" @@ -130,18 +129,16 @@ private: //----------------------------------------------------------------------------- class nsSocketTransport : public nsASocketHandler , public nsISocketTransport , public nsIDNSListener , public nsIClassInfo { - typedef mozilla::Mutex Mutex; - public: NS_DECL_ISUPPORTS NS_DECL_NSITRANSPORT NS_DECL_NSISOCKETTRANSPORT NS_DECL_NSIDNSLISTENER NS_DECL_NSICLASSINFO nsSocketTransport(); @@ -252,17 +249,17 @@ private: // called when the socket is connected void OnSocketConnected(); //------------------------------------------------------------------------- // socket input/output objects. these may be accessed on any thread with // the exception of some specific methods (XXX). - Mutex mLock; // protects members in this section + PRLock *mLock; // protects members in this section PRFileDesc *mFD; nsrefcnt mFDref; // mFD is closed when mFDref goes to zero. PRBool mFDconnected; // mFD is available to consumer when TRUE. nsCOMPtr<nsIInterfaceRequestor> mCallbacks; nsCOMPtr<nsITransportEventSink> mEventSink; nsCOMPtr<nsISupports> mSecInfo;
--- a/netwerk/base/src/nsSocketTransportService2.cpp +++ b/netwerk/base/src/nsSocketTransportService2.cpp @@ -38,46 +38,46 @@ #ifdef MOZ_LOGGING #define FORCE_PR_LOG #endif #include "nsSocketTransportService2.h" #include "nsSocketTransport2.h" #include "nsReadableUtils.h" +#include "nsAutoLock.h" #include "nsNetError.h" #include "prnetdb.h" +#include "prlock.h" #include "prerror.h" #include "plstr.h" #include "nsIPrefService.h" #include "nsIPrefBranch2.h" #include "nsServiceManagerUtils.h" #include "nsIOService.h" #include "mozilla/FunctionTimer.h" -using namespace mozilla; - #if defined(PR_LOGGING) PRLogModuleInfo *gSocketTransportLog = nsnull; #endif nsSocketTransportService *gSocketTransportService = nsnull; PRThread *gSocketThread = nsnull; #define SEND_BUFFER_PREF "network.tcp.sendbuffer" //----------------------------------------------------------------------------- // ctor/dtor (called on the main/UI thread by the service manager) nsSocketTransportService::nsSocketTransportService() : mThread(nsnull) , mThreadEvent(nsnull) , mAutodialEnabled(PR_FALSE) - , mLock("nsSocketTransportService::mLock") + , mLock(nsAutoLock::NewLock("nsSocketTransportService::mLock")) , mInitialized(PR_FALSE) , mShuttingDown(PR_FALSE) , mActiveCount(0) , mIdleCount(0) , mSendBufferSize(0) { #if defined(PR_LOGGING) gSocketTransportLog = PR_NewLogModule("nsSocketTransport"); @@ -88,30 +88,33 @@ nsSocketTransportService::nsSocketTransp NS_ASSERTION(!gSocketTransportService, "must not instantiate twice"); gSocketTransportService = this; } nsSocketTransportService::~nsSocketTransportService() { NS_ASSERTION(NS_IsMainThread(), "wrong thread"); NS_ASSERTION(!mInitialized, "not shutdown properly"); + + if (mLock) + nsAutoLock::DestroyLock(mLock); if (mThreadEvent) PR_DestroyPollableEvent(mThreadEvent); gSocketTransportService = nsnull; } //----------------------------------------------------------------------------- // event queue (any thread) already_AddRefed<nsIThread> nsSocketTransportService::GetThreadSafely() { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); nsIThread* result = mThread; NS_IF_ADDREF(result); return result; } NS_IMETHODIMP nsSocketTransportService::Dispatch(nsIRunnable *event, PRUint32 flags) { @@ -375,16 +378,18 @@ NS_IMPL_THREADSAFE_ISUPPORTS6(nsSocketTr nsIObserver) // called from main thread only NS_IMETHODIMP nsSocketTransportService::Init() { NS_TIME_FUNCTION; + NS_ENSURE_TRUE(mLock, NS_ERROR_OUT_OF_MEMORY); + if (!NS_IsMainThread()) { NS_ERROR("wrong thread"); return NS_ERROR_UNEXPECTED; } if (mInitialized) return NS_OK; @@ -415,17 +420,17 @@ nsSocketTransportService::Init() NS_TIME_FUNCTION_MARK("Created thread"); nsCOMPtr<nsIThread> thread; nsresult rv = NS_NewThread(getter_AddRefs(thread), this); if (NS_FAILED(rv)) return rv; { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); // Install our mThread, protecting against concurrent readers thread.swap(mThread); } nsCOMPtr<nsIPrefBranch2> tmpPrefService = do_GetService(NS_PREFSERVICE_CONTRACTID); if (tmpPrefService) tmpPrefService->AddObserver(SEND_BUFFER_PREF, this, PR_FALSE); UpdatePrefs(); @@ -446,30 +451,30 @@ nsSocketTransportService::Shutdown() if (!mInitialized) return NS_OK; if (mShuttingDown) return NS_ERROR_UNEXPECTED; { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); // signal the socket thread to shutdown mShuttingDown = PR_TRUE; if (mThreadEvent) PR_SetPollableEvent(mThreadEvent); // else wait for Poll timeout } // join with thread mThread->Shutdown(); { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); // Drop our reference to mThread and make sure that any concurrent // readers are excluded mThread = nsnull; } nsCOMPtr<nsIPrefBranch2> tmpPrefService = do_GetService(NS_PREFSERVICE_CONTRACTID); if (tmpPrefService) tmpPrefService->RemoveObserver(SEND_BUFFER_PREF, this); @@ -518,17 +523,17 @@ nsSocketTransportService::SetAutodialEna { mAutodialEnabled = value; return NS_OK; } NS_IMETHODIMP nsSocketTransportService::OnDispatchedEvent(nsIThreadInternal *thread) { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); if (mThreadEvent) PR_SetPollableEvent(mThreadEvent); return NS_OK; } NS_IMETHODIMP nsSocketTransportService::OnProcessNextEvent(nsIThreadInternal *thread, PRBool mayWait, PRUint32 depth) @@ -575,17 +580,17 @@ nsSocketTransportService::Run() threadInt->SetObserver(this); for (;;) { // process all pending events NS_ProcessPendingEvents(thread); // now that our event queue is empty, check to see if we should exit { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); if (mShuttingDown) break; } // wait for and process the next pending event NS_ProcessNextEvent(thread); } @@ -710,17 +715,17 @@ nsSocketTransportService::DoPollIteratio if (PR_WaitForPollableEvent(mThreadEvent) != PR_SUCCESS) { // On Windows, the TCP loopback connection in the // pollable event may become broken when a laptop // switches between wired and wireless networks or // wakes up from hibernation. We try to create a // new pollable event. If that fails, we fall back // on "busy wait". { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); PR_DestroyPollableEvent(mThreadEvent); mThreadEvent = PR_NewPollableEvent(); } if (!mThreadEvent) { NS_WARNING("running socket transport thread without " "a pollable event"); SOCKET_LOG(("running socket transport thread without " "a pollable event"));
--- a/netwerk/base/src/nsSocketTransportService2.h +++ b/netwerk/base/src/nsSocketTransportService2.h @@ -45,17 +45,16 @@ #include "nsEventQueue.h" #include "nsCOMPtr.h" #include "pldhash.h" #include "prinrval.h" #include "prlog.h" #include "prio.h" #include "nsASocketHandler.h" #include "nsIObserver.h" -#include "mozilla/Mutex.h" //----------------------------------------------------------------------------- #if defined(PR_LOGGING) // // set NSPR_LOG_MODULES=nsSocketTransport:5 // extern PRLogModuleInfo *gSocketTransportLog; @@ -71,18 +70,16 @@ extern PRLogModuleInfo *gSocketTransport //----------------------------------------------------------------------------- class nsSocketTransportService : public nsPISocketTransportService , public nsIEventTarget , public nsIThreadObserver , public nsIRunnable , public nsIObserver { - typedef mozilla::Mutex Mutex; - public: NS_DECL_ISUPPORTS NS_DECL_NSPISOCKETTRANSPORTSERVICE NS_DECL_NSISOCKETTRANSPORTSERVICE NS_DECL_NSIEVENTTARGET NS_DECL_NSITHREADOBSERVER NS_DECL_NSIRUNNABLE NS_DECL_NSIOBSERVER @@ -124,17 +121,17 @@ private: // Returns mThread, protecting the get-and-addref with mLock already_AddRefed<nsIThread> GetThreadSafely(); //------------------------------------------------------------------------- // initialization and shutdown (any thread) //------------------------------------------------------------------------- - Mutex mLock; + PRLock *mLock; PRPackedBool mInitialized; PRPackedBool mShuttingDown; // indicates whether we are currently in the // process of shutting down //------------------------------------------------------------------------- // socket lists (socket thread only) //
--- a/netwerk/base/src/nsStreamTransportService.cpp +++ b/netwerk/base/src/nsStreamTransportService.cpp @@ -33,16 +33,17 @@ * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #include "nsStreamTransportService.h" #include "nsXPCOMCIDInternal.h" #include "nsNetSegmentUtils.h" +#include "nsAutoLock.h" #include "nsInt64.h" #include "nsTransportUtils.h" #include "nsStreamUtils.h" #include "nsNetError.h" #include "nsNetCID.h" #include "nsIServiceManager.h" #include "nsIAsyncInputStream.h"
--- a/netwerk/base/src/nsTransportUtils.cpp +++ b/netwerk/base/src/nsTransportUtils.cpp @@ -29,58 +29,59 @@ * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -#include "mozilla/Mutex.h" #include "nsTransportUtils.h" #include "nsITransport.h" #include "nsProxyRelease.h" #include "nsThreadUtils.h" +#include "nsAutoLock.h" #include "nsAutoPtr.h" #include "nsCOMPtr.h" -using namespace mozilla; - //----------------------------------------------------------------------------- class nsTransportStatusEvent; class nsTransportEventSinkProxy : public nsITransportEventSink { public: NS_DECL_ISUPPORTS NS_DECL_NSITRANSPORTEVENTSINK nsTransportEventSinkProxy(nsITransportEventSink *sink, nsIEventTarget *target, PRBool coalesceAll) : mSink(sink) , mTarget(target) - , mLock("nsTransportEventSinkProxy.mLock") + , mLock(nsAutoLock::NewLock("nsTransportEventSinkProxy::mLock")) , mLastEvent(nsnull) , mCoalesceAll(coalesceAll) { NS_ADDREF(mSink); } virtual ~nsTransportEventSinkProxy() { + if (mLock) + nsAutoLock::DestroyLock(mLock); + // our reference to mSink could be the last, so be sure to release // it on the target thread. otherwise, we could get into trouble. NS_ProxyRelease(mTarget, mSink); } nsITransportEventSink *mSink; nsCOMPtr<nsIEventTarget> mTarget; - Mutex mLock; + PRLock *mLock; nsTransportStatusEvent *mLastEvent; PRBool mCoalesceAll; }; class nsTransportStatusEvent : public nsRunnable { public: nsTransportStatusEvent(nsTransportEventSinkProxy *proxy, @@ -97,17 +98,17 @@ public: ~nsTransportStatusEvent() {} NS_IMETHOD Run() { // since this event is being handled, we need to clear the proxy's ref. // if not coalescing all, then last event may not equal self! { - MutexAutoLock lock(mProxy->mLock); + nsAutoLock lock(mProxy->mLock); if (mProxy->mLastEvent == this) mProxy->mLastEvent = nsnull; } mProxy->mSink->OnTransportStatus(mTransport, mStatus, mProgress, mProgressMax); return nsnull; } @@ -127,17 +128,17 @@ NS_IMETHODIMP nsTransportEventSinkProxy::OnTransportStatus(nsITransport *transport, nsresult status, PRUint64 progress, PRUint64 progressMax) { nsresult rv = NS_OK; nsRefPtr<nsTransportStatusEvent> event; { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); // try to coalesce events! ;-) if (mLastEvent && (mCoalesceAll || mLastEvent->mStatus == status)) { mLastEvent->mStatus = status; mLastEvent->mProgress = progress; mLastEvent->mProgressMax = progressMax; } else { @@ -148,17 +149,17 @@ nsTransportEventSinkProxy::OnTransportSt mLastEvent = event; // weak ref } } if (event) { rv = mTarget->Dispatch(event, NS_DISPATCH_NORMAL); if (NS_FAILED(rv)) { NS_WARNING("unable to post transport status event"); - MutexAutoLock lock(mLock); // cleanup.. don't reference anymore! + nsAutoLock lock(mLock); // cleanup.. don't reference anymore! mLastEvent = nsnull; } } return rv; } //-----------------------------------------------------------------------------
--- a/netwerk/build/nsNetModule.cpp +++ b/netwerk/build/nsNetModule.cpp @@ -249,17 +249,17 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsFt #include "nsHttpActivityDistributor.h" NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpNTLMAuth) #undef LOG #undef LOG_ENABLED NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsHttpHandler, Init) NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsHttpsHandler, Init) NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsHttpAuthManager, Init) NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpChannelAuthProvider) -NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpActivityDistributor) +NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsHttpActivityDistributor, Init) NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpBasicAuth) NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpDigestAuth) #endif // !NECKO_PROTOCOL_http #ifdef NECKO_PROTOCOL_res // resource #include "nsResProtocolHandler.h" NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsResProtocolHandler, Init)
--- a/netwerk/cache/nsCacheRequest.h +++ b/netwerk/cache/nsCacheRequest.h @@ -37,62 +37,58 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #ifndef _nsCacheRequest_h_ #define _nsCacheRequest_h_ #include "nspr.h" -#include "mozilla/CondVar.h" -#include "mozilla/Mutex.h" #include "nsCOMPtr.h" #include "nsICache.h" #include "nsICacheListener.h" #include "nsCacheSession.h" #include "nsCacheService.h" class nsCacheRequest : public PRCList { - typedef mozilla::CondVar CondVar; - typedef mozilla::MutexAutoLock MutexAutoLock; - typedef mozilla::Mutex Mutex; - private: friend class nsCacheService; friend class nsCacheEntry; friend class nsProcessRequestEvent; nsCacheRequest( nsCString * key, nsICacheListener * listener, nsCacheAccessMode accessRequested, PRBool blockingMode, nsCacheSession * session) : mKey(key), mInfo(0), mListener(listener), - mLock("nsCacheRequest.mLock"), - mCondVar(mLock, "nsCacheRequest.mCondVar") + mLock(nsnull), + mCondVar(nsnull) { MOZ_COUNT_CTOR(nsCacheRequest); PR_INIT_CLIST(this); SetAccessRequested(accessRequested); SetStoragePolicy(session->StoragePolicy()); if (session->IsStreamBased()) MarkStreamBased(); if (session->WillDoomEntriesIfExpired()) MarkDoomEntriesIfExpired(); if (blockingMode == nsICache::BLOCKING) MarkBlockingMode(); MarkWaitingForValidation(); NS_IF_ADDREF(mListener); } ~nsCacheRequest() { MOZ_COUNT_DTOR(nsCacheRequest); delete mKey; + if (mLock) PR_DestroyLock(mLock); + if (mCondVar) PR_DestroyCondVar(mCondVar); NS_ASSERTION(PR_CLIST_IS_EMPTY(this), "request still on a list"); if (mListener) nsCacheService::ReleaseObject_Locked(mListener, mThread); } /** * Simple Accessors @@ -150,36 +146,56 @@ private: nsresult WaitForValidation(void) { if (!WaitingForValidation()) { // flag already cleared MarkWaitingForValidation(); // set up for next time return NS_OK; // early exit; } - { - MutexAutoLock lock(mLock); - while (WaitingForValidation()) { - mCondVar.Wait(); + + if (!mLock) { + mLock = PR_NewLock(); + if (!mLock) return NS_ERROR_OUT_OF_MEMORY; + + NS_ASSERTION(!mCondVar,"we have mCondVar, but didn't have mLock?"); + mCondVar = PR_NewCondVar(mLock); + if (!mCondVar) { + PR_DestroyLock(mLock); + return NS_ERROR_OUT_OF_MEMORY; } - MarkWaitingForValidation(); // set up for next time - } + } + PRStatus status = PR_SUCCESS; + PR_Lock(mLock); + while (WaitingForValidation() && (status == PR_SUCCESS) ) { + status = PR_WaitCondVar(mCondVar, PR_INTERVAL_NO_TIMEOUT); + } + MarkWaitingForValidation(); // set up for next time + PR_Unlock(mLock); + + NS_ASSERTION(status == PR_SUCCESS, "PR_WaitCondVar() returned PR_FAILURE?"); + if (status == PR_FAILURE) + return NS_ERROR_UNEXPECTED; + return NS_OK; } void WakeUp(void) { DoneWaitingForValidation(); - MutexAutoLock lock(mLock); - mCondVar.Notify(); + if (mLock) { + PR_Lock(mLock); + PR_NotifyCondVar(mCondVar); + PR_Unlock(mLock); + } } /** * Data members */ nsCString * mKey; PRUint32 mInfo; nsICacheListener * mListener; // strong ref nsCOMPtr<nsIThread> mThread; - Mutex mLock; - CondVar mCondVar; + PRLock * mLock; + PRCondVar * mCondVar; }; #endif // _nsCacheRequest_h_
--- a/netwerk/cache/nsCacheService.cpp +++ b/netwerk/cache/nsCacheService.cpp @@ -75,18 +75,16 @@ #include "mozilla/Services.h" #include "mozilla/FunctionTimer.h" #ifdef MOZ_IPC #include "mozilla/net/NeckoCommon.h" #endif -using namespace mozilla; - /****************************************************************************** * nsCacheProfilePrefObserver *****************************************************************************/ #ifdef XP_MAC #pragma mark nsCacheProfilePrefObserver #endif #define DISK_CACHE_ENABLE_PREF "browser.cache.disk.enable" @@ -272,21 +270,22 @@ private: class nsBlockOnCacheThreadEvent : public nsRunnable { public: nsBlockOnCacheThreadEvent() { } NS_IMETHOD Run() { - nsCacheServiceAutoLock autoLock; + mozilla::MonitorAutoEnter + autoMonitor(nsCacheService::gService->mMonitor); #ifdef PR_LOGGING CACHE_LOG_DEBUG(("nsBlockOnCacheThreadEvent [%p]\n", this)); #endif - nsCacheService::gService->mCondVar.Notify(); + autoMonitor.Notify(); return NS_OK; } }; nsresult nsCacheProfilePrefObserver::Install() { @@ -805,31 +804,36 @@ nsCacheService::DispatchToCacheIOThread( { if (!gService->mCacheIOThread) return NS_ERROR_NOT_AVAILABLE; return gService->mCacheIOThread->Dispatch(event, NS_DISPATCH_NORMAL); } nsresult nsCacheService::SyncWithCacheIOThread() { - gService->mLock.AssertCurrentThreadOwns(); + NS_ASSERTION(gService->mLockedThread == PR_GetCurrentThread(), + "not holding cache-lock"); if (!gService->mCacheIOThread) return NS_ERROR_NOT_AVAILABLE; + mozilla::MonitorAutoEnter autoMonitor(gService->mMonitor); + nsCOMPtr<nsIRunnable> event = new nsBlockOnCacheThreadEvent(); // dispatch event - it will notify the monitor when it's done nsresult rv = gService->mCacheIOThread->Dispatch(event, NS_DISPATCH_NORMAL); if (NS_FAILED(rv)) { NS_WARNING("Failed dispatching block-event"); return NS_ERROR_UNEXPECTED; } + Unlock(); // wait until notified, then return - rv = gService->mCondVar.Wait(); + rv = autoMonitor.Wait(); + Lock(); return rv; } PRBool nsCacheProfilePrefObserver::DiskCacheEnabled() { @@ -976,18 +980,18 @@ private: #pragma mark nsCacheService #endif nsCacheService * nsCacheService::gService = nsnull; NS_IMPL_THREADSAFE_ISUPPORTS1(nsCacheService, nsICacheService) nsCacheService::nsCacheService() - : mLock("nsCacheService.mLock"), - mCondVar(mLock, "nsCacheService.mCondVar"), + : mLock(nsnull), + mMonitor("block-on-cache-monitor"), mInitialized(PR_FALSE), mEnableMemoryDevice(PR_TRUE), mEnableDiskDevice(PR_TRUE), mMemoryDevice(nsnull), mDiskDevice(nsnull), mOfflineDevice(nsnull), mTotalEntries(0), mCacheHits(0), @@ -998,23 +1002,31 @@ nsCacheService::nsCacheService() mDeactivateFailures(0), mDeactivatedUnboundEntries(0) { NS_ASSERTION(gService==nsnull, "multiple nsCacheService instances!"); gService = this; // create list of cache devices PR_INIT_CLIST(&mDoomedEntries); + + // allocate service lock + mLock = PR_NewLock(); + +#if defined(DEBUG) + mLockedThread = nsnull; +#endif } nsCacheService::~nsCacheService() { if (mInitialized) // Shutdown hasn't been called yet. (void) Shutdown(); + PR_DestroyLock(mLock); gService = nsnull; } nsresult nsCacheService::Init() { NS_TIME_FUNCTION; @@ -1024,16 +1036,19 @@ nsCacheService::Init() return NS_ERROR_ALREADY_INITIALIZED; #ifdef MOZ_IPC if (mozilla::net::IsNeckoChild()) { return NS_ERROR_UNEXPECTED; } #endif + if (mLock == nsnull) + return NS_ERROR_OUT_OF_MEMORY; + CACHE_LOG_INIT(); nsresult rv = NS_NewThread(getter_AddRefs(mCacheIOThread)); if (NS_FAILED(rv)) { NS_WARNING("Can't create cache IO thread"); } // initialize hashtable for active cache entries @@ -2191,38 +2206,45 @@ nsCacheService::OnDataSizeChange(nsCache if (!device) return NS_ERROR_UNEXPECTED; return device->OnDataSizeChange(entry, deltaSize); } void nsCacheService::Lock() { - gService->mLock.Lock(); + PR_Lock(gService->mLock); + +#if defined(DEBUG) + gService->mLockedThread = PR_GetCurrentThread(); +#endif } void nsCacheService::Unlock() { - gService->mLock.AssertCurrentThreadOwns(); + NS_ASSERTION(gService->mLockedThread == PR_GetCurrentThread(), "oops"); nsTArray<nsISupports*> doomed; doomed.SwapElements(gService->mDoomedObjects); - gService->mLock.Unlock(); +#if defined(DEBUG) + gService->mLockedThread = nsnull; +#endif + PR_Unlock(gService->mLock); for (PRUint32 i = 0; i < doomed.Length(); ++i) doomed[i]->Release(); } void nsCacheService::ReleaseObject_Locked(nsISupports * obj, nsIEventTarget * target) { - gService->mLock.AssertCurrentThreadOwns(); + NS_ASSERTION(gService->mLockedThread == PR_GetCurrentThread(), "oops"); PRBool isCur; if (!target || (NS_SUCCEEDED(target->IsOnCurrentThread(&isCur)) && isCur)) { gService->mDoomedObjects.AppendElement(obj); } else { NS_ProxyRelease(target, obj); } }
--- a/netwerk/cache/nsCacheService.h +++ b/netwerk/cache/nsCacheService.h @@ -45,23 +45,23 @@ #ifndef _nsCacheService_h_ #define _nsCacheService_h_ #include "nsICacheService.h" #include "nsCacheSession.h" #include "nsCacheDevice.h" #include "nsCacheEntry.h" +#include "prlock.h" #include "prthread.h" #include "nsIObserver.h" #include "nsString.h" #include "nsProxiedService.h" #include "nsTArray.h" -#include "mozilla/CondVar.h" -#include "mozilla/Mutex.h" +#include "mozilla/Monitor.h" class nsCacheRequest; class nsCacheProfilePrefObserver; class nsDiskCacheDevice; class nsMemoryCacheDevice; class nsOfflineCacheDevice; class nsCacheServiceAutoLock; @@ -167,20 +167,16 @@ public: static void SetOfflineCacheCapacity(PRInt32 capacity); static void SetMemoryCache(); static void OnEnterExitPrivateBrowsing(); nsresult Init(); void Shutdown(); - - static void AssertOwnsLock() - { gService->mLock.AssertCurrentThreadOwns(); } - private: friend class nsCacheServiceAutoLock; friend class nsOfflineCacheDevice; friend class nsProcessRequestEvent; friend class nsSetSmartSizeEvent; friend class nsBlockOnCacheThreadEvent; /** @@ -253,18 +249,23 @@ private: /** * Data Members */ static nsCacheService * gService; // there can be only one... nsCacheProfilePrefObserver * mObserver; - mozilla::Mutex mLock; - mozilla::CondVar mCondVar; + PRLock * mLock; + + mozilla::Monitor mMonitor; + +#if defined(DEBUG) + PRThread * mLockedThread; // The thread holding mLock +#endif nsCOMPtr<nsIThread> mCacheIOThread; nsTArray<nsISupports*> mDoomedObjects; PRBool mInitialized; PRBool mEnableMemoryDevice;
--- a/netwerk/cache/nsDiskCacheDevice.cpp +++ b/netwerk/cache/nsDiskCacheDevice.cpp @@ -70,16 +70,17 @@ #include "nsCache.h" #include "nsDeleteDir.h" #include "nsICacheVisitor.h" #include "nsReadableUtils.h" #include "nsIInputStream.h" #include "nsIOutputStream.h" +#include "nsAutoLock.h" #include "nsCRT.h" #include "nsCOMArray.h" #include "nsISimpleEnumerator.h" #include "mozilla/FunctionTimer.h" static const char DISK_CACHE_DEVICE_ID[] = { "disk" }; @@ -392,18 +393,16 @@ nsDiskCacheDevice::Init() /** * NOTE: called while holding the cache service lock */ nsresult nsDiskCacheDevice::Shutdown() { - nsCacheService::AssertOwnsLock(); - nsresult rv = Shutdown_Private(PR_TRUE); if (NS_FAILED(rv)) return rv; if (mCacheDirectory) { // delete any trash files left-over before shutting down. nsCOMPtr<nsIFile> trashDir; GetTrashDir(mCacheDirectory, &trashDir);
--- a/netwerk/dns/nsDNSService2.cpp +++ b/netwerk/dns/nsDNSService2.cpp @@ -41,32 +41,31 @@ #include "nsICancelable.h" #include "nsIProxyObjectManager.h" #include "nsIPrefService.h" #include "nsIPrefBranch.h" #include "nsIPrefBranch2.h" #include "nsIServiceManager.h" #include "nsReadableUtils.h" #include "nsString.h" +#include "nsAutoLock.h" #include "nsAutoPtr.h" #include "nsNetCID.h" #include "nsNetError.h" #include "nsDNSPrefetch.h" #include "nsIProtocolProxyService.h" #include "prsystem.h" #include "prnetdb.h" #include "prmon.h" #include "prio.h" #include "plstr.h" #include "nsIOService.h" #include "mozilla/FunctionTimer.h" -using namespace mozilla; - static const char kPrefDnsCacheEntries[] = "network.dnsCacheEntries"; static const char kPrefDnsCacheExpiration[] = "network.dnsCacheExpiration"; static const char kPrefEnableIDN[] = "network.enableIDN"; static const char kPrefIPv4OnlyDomains[] = "network.dns.ipv4OnlyDomains"; static const char kPrefDisableIPv6[] = "network.dns.disableIPv6"; static const char kPrefDisablePrefetch[] = "network.dns.disablePrefetch"; //----------------------------------------------------------------------------- @@ -101,55 +100,54 @@ nsDNSRecord::GetCanonicalName(nsACString { // this method should only be called if we have a CNAME NS_ENSURE_TRUE(mHostRecord->flags & nsHostResolver::RES_CANON_NAME, NS_ERROR_NOT_AVAILABLE); // if the record is for an IP address literal, then the canonical // host name is the IP address literal. const char *cname; - { - MutexAutoLock lock(*mHostRecord->addr_info_lock); - if (mHostRecord->addr_info) - cname = PR_GetCanonNameFromAddrInfo(mHostRecord->addr_info); - else - cname = mHostRecord->host; - result.Assign(cname); - } + PR_Lock(mHostRecord->addr_info_lock); + if (mHostRecord->addr_info) + cname = PR_GetCanonNameFromAddrInfo(mHostRecord->addr_info); + else + cname = mHostRecord->host; + result.Assign(cname); + PR_Unlock(mHostRecord->addr_info_lock); return NS_OK; } NS_IMETHODIMP nsDNSRecord::GetNextAddr(PRUint16 port, PRNetAddr *addr) { // not a programming error to poke the DNS record when it has no more // entries. just fail without any debug warnings. this enables consumers // to enumerate the DNS record without calling HasMore. if (mDone) return NS_ERROR_NOT_AVAILABLE; - mHostRecord->addr_info_lock->Lock(); + PR_Lock(mHostRecord->addr_info_lock); if (mHostRecord->addr_info) { if (!mIter) mIterGenCnt = mHostRecord->addr_info_gencnt; else if (mIterGenCnt != mHostRecord->addr_info_gencnt) { // mHostRecord->addr_info has changed, so mIter is invalid. // Restart the iteration. Alternatively, we could just fail. mIter = nsnull; mIterGenCnt = mHostRecord->addr_info_gencnt; } mIter = PR_EnumerateAddrInfo(mIter, mHostRecord->addr_info, port, addr); - mHostRecord->addr_info_lock->Unlock(); + PR_Unlock(mHostRecord->addr_info_lock); if (!mIter) { mDone = PR_TRUE; return NS_ERROR_NOT_AVAILABLE; } } else { - mHostRecord->addr_info_lock->Unlock(); + PR_Unlock(mHostRecord->addr_info_lock); if (!mHostRecord->addr) { // Both mHostRecord->addr_info and mHostRecord->addr are null. // This can happen if mHostRecord->addr_info expired and the // attempt to reresolve it failed. return NS_ERROR_NOT_AVAILABLE; } memcpy(addr, mHostRecord->addr, sizeof(PRNetAddr)); // set given port @@ -303,35 +301,38 @@ nsDNSSyncRequest::OnLookupComplete(nsHos mHostRecord = hostRecord; PR_Notify(mMonitor); PR_ExitMonitor(mMonitor); } //----------------------------------------------------------------------------- nsDNSService::nsDNSService() - : mLock("nsDNSServer.mLock") - , mFirstTime(PR_TRUE) + : mLock(nsnull) { } nsDNSService::~nsDNSService() { + if (mLock) + nsAutoLock::DestroyLock(mLock); } NS_IMPL_THREADSAFE_ISUPPORTS3(nsDNSService, nsIDNSService, nsPIDNSService, nsIObserver) NS_IMETHODIMP nsDNSService::Init() { NS_TIME_FUNCTION; NS_ENSURE_TRUE(!mResolver, NS_ERROR_ALREADY_INITIALIZED); + PRBool firstTime = (mLock == nsnull); + // prefs PRUint32 maxCacheEntries = 400; PRUint32 maxCacheLifetime = 3; // minutes PRBool enableIDN = PR_TRUE; PRBool disableIPv6 = PR_FALSE; PRBool disablePrefetch = PR_FALSE; int proxyType = nsIProtocolProxyService::PROXYCONFIG_DIRECT; @@ -351,18 +352,20 @@ nsDNSService::Init() prefs->GetBoolPref(kPrefDisableIPv6, &disableIPv6); prefs->GetCharPref(kPrefIPv4OnlyDomains, getter_Copies(ipv4OnlyDomains)); prefs->GetBoolPref(kPrefDisablePrefetch, &disablePrefetch); // If a manual proxy is in use, disable prefetch implicitly prefs->GetIntPref("network.proxy.type", &proxyType); } - if (mFirstTime) { - mFirstTime = PR_FALSE; + if (firstTime) { + mLock = nsAutoLock::NewLock("nsDNSService::mLock"); + if (!mLock) + return NS_ERROR_OUT_OF_MEMORY; // register as prefs observer if (prefs) { prefs->AddObserver(kPrefDnsCacheEntries, this, PR_FALSE); prefs->AddObserver(kPrefDnsCacheExpiration, this, PR_FALSE); prefs->AddObserver(kPrefEnableIDN, this, PR_FALSE); prefs->AddObserver(kPrefIPv4OnlyDomains, this, PR_FALSE); prefs->AddObserver(kPrefDisableIPv6, this, PR_FALSE); @@ -388,34 +391,34 @@ nsDNSService::Init() return NS_OK; nsRefPtr<nsHostResolver> res; nsresult rv = nsHostResolver::Create(maxCacheEntries, maxCacheLifetime, getter_AddRefs(res)); if (NS_SUCCEEDED(rv)) { // now, set all of our member variables while holding the lock - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); mResolver = res; mIDN = idn; mIPv4OnlyDomains = ipv4OnlyDomains; // exchanges buffer ownership mDisableIPv6 = disableIPv6; // Disable prefetching either by explicit preference or if a manual proxy is configured mDisablePrefetch = disablePrefetch || (proxyType == nsIProtocolProxyService::PROXYCONFIG_MANUAL); } return rv; } NS_IMETHODIMP nsDNSService::Shutdown() { nsRefPtr<nsHostResolver> res; { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); res = mResolver; mResolver = nsnull; } if (res) res->Shutdown(); return NS_OK; } @@ -426,17 +429,17 @@ nsDNSService::AsyncResolve(const nsACStr nsIEventTarget *target, nsICancelable **result) { // grab reference to global host resolver and IDN service. beware // simultaneous shutdown!! nsRefPtr<nsHostResolver> res; nsCOMPtr<nsIIDNService> idn; { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); if (mDisablePrefetch && (flags & RESOLVE_SPECULATE)) return NS_ERROR_DNS_LOOKUP_QUEUE_FULL; res = mResolver; idn = mIDN; } if (!res) @@ -485,17 +488,17 @@ nsDNSService::Resolve(const nsACString & PRUint32 flags, nsIDNSRecord **result) { // grab reference to global host resolver and IDN service. beware // simultaneous shutdown!! nsRefPtr<nsHostResolver> res; nsCOMPtr<nsIIDNService> idn; { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); res = mResolver; idn = mIDN; } NS_ENSURE_TRUE(res, NS_ERROR_OFFLINE); const nsACString *hostPtr = &hostname; nsresult rv; @@ -580,17 +583,17 @@ nsDNSService::Observe(nsISupports *subje } PRUint16 nsDNSService::GetAFForLookup(const nsACString &host) { if (mDisableIPv6) return PR_AF_INET; - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); PRUint16 af = PR_AF_UNSPEC; if (!mIPv4OnlyDomains.IsEmpty()) { const char *domain, *domainEnd, *end; PRUint32 hostLen, domainLen; // see if host is in one of the IPv4-only domains
--- a/netwerk/dns/nsDNSService2.h +++ b/netwerk/dns/nsDNSService2.h @@ -35,17 +35,17 @@ * ***** END LICENSE BLOCK ***** */ #include "nsPIDNSService.h" #include "nsIIDNService.h" #include "nsIObserver.h" #include "nsHostResolver.h" #include "nsAutoPtr.h" #include "nsString.h" -#include "mozilla/Mutex.h" +#include "prlock.h" class nsDNSService : public nsPIDNSService , public nsIObserver { public: NS_DECL_ISUPPORTS NS_DECL_NSPIDNSSERVICE NS_DECL_NSIDNSSERVICE @@ -56,18 +56,17 @@ public: private: PRUint16 GetAFForLookup(const nsACString &host); nsRefPtr<nsHostResolver> mResolver; nsCOMPtr<nsIIDNService> mIDN; // mLock protects access to mResolver and mIPv4OnlyDomains - mozilla::Mutex mLock; + PRLock *mLock; // mIPv4OnlyDomains is a comma-separated list of domains for which only // IPv4 DNS lookups are performed. This allows the user to disable IPv6 on // a per-domain basis and work around broken DNS servers. See bug 68796. nsAdoptingCString mIPv4OnlyDomains; PRBool mDisableIPv6; PRBool mDisablePrefetch; - PRBool mFirstTime; };
--- a/netwerk/dns/nsHostResolver.cpp +++ b/netwerk/dns/nsHostResolver.cpp @@ -48,31 +48,31 @@ #define RES_RETRY_ON_FAILURE #endif #include <stdlib.h> #include "nsHostResolver.h" #include "nsNetError.h" #include "nsISupportsBase.h" #include "nsISupportsUtils.h" +#include "nsAutoLock.h" #include "nsAutoPtr.h" #include "pratom.h" #include "prthread.h" #include "prerror.h" +#include "prcvar.h" #include "prtime.h" #include "prlong.h" #include "prlog.h" #include "pldhash.h" #include "plstr.h" #include "nsURLHelper.h" #include "mozilla/FunctionTimer.h" -using namespace mozilla; - //---------------------------------------------------------------------------- // Use a persistent thread pool in order to avoid spinning up new threads all the time. // In particular, thread creation results in a res_init() call from libc which is // quite expensive. // // The pool dynamically grows between 0 and MAX_RESOLVER_THREADS in size. New requests // go first to an idle thread. If that cannot be found and there are fewer than MAX_RESOLVER_THREADS @@ -176,28 +176,36 @@ private: // this macro filters out any flags that are not used when constructing the // host key. the significant flags are those that would affect the resulting // host record (i.e., the flags that are passed down to PR_GetAddrInfoByName). #define RES_KEY_FLAGS(_f) ((_f) & nsHostResolver::RES_CANON_NAME) nsresult nsHostRecord::Create(const nsHostKey *key, nsHostRecord **result) { + PRLock *lock = PR_NewLock(); + if (!lock) + return NS_ERROR_OUT_OF_MEMORY; + size_t hostLen = strlen(key->host) + 1; size_t size = hostLen + sizeof(nsHostRecord); nsHostRecord *rec = (nsHostRecord*) ::operator new(size); + if (!rec) { + PR_DestroyLock(lock); + return NS_ERROR_OUT_OF_MEMORY; + } rec->host = ((char *) rec) + sizeof(nsHostRecord); rec->flags = key->flags; rec->af = key->af; rec->_refc = 1; // addref NS_LOG_ADDREF(rec, 1, "nsHostRecord", sizeof(nsHostRecord)); - rec->addr_info_lock = new Mutex("nsHostRecord.addr_info_lock"); + rec->addr_info_lock = lock; rec->addr_info = nsnull; rec->addr_info_gencnt = 0; rec->addr = nsnull; rec->expiration = NowInMinutes(); rec->resolving = PR_FALSE; rec->onQueue = PR_FALSE; rec->usingAnyThread = PR_FALSE; PR_INIT_CLIST(rec); @@ -206,17 +214,20 @@ nsHostRecord::Create(const nsHostKey *ke memcpy((char *) rec->host, key->host, hostLen); *result = rec; return NS_OK; } nsHostRecord::~nsHostRecord() { - delete addr_info_lock; + if (addr_info_lock) + PR_DestroyLock(addr_info_lock); + if (addr_info) + PR_FreeAddrInfo(addr_info); if (addr) free(addr); } //---------------------------------------------------------------------------- struct nsHostDBEnt : PLDHashEntryHdr { @@ -314,18 +325,18 @@ HostDB_RemoveEntry(PLDHashTable *table, } //---------------------------------------------------------------------------- nsHostResolver::nsHostResolver(PRUint32 maxCacheEntries, PRUint32 maxCacheLifetime) : mMaxCacheEntries(maxCacheEntries) , mMaxCacheLifetime(maxCacheLifetime) - , mLock("nsHostResolver.mLock") - , mIdleThreadCV(mLock, "nsHostResolver.mIdleThreadCV") + , mLock(nsnull) + , mIdleThreadCV(nsnull) , mNumIdleThreads(0) , mThreadCount(0) , mActiveAnyThreadCount(0) , mEvictionQSize(0) , mPendingCount(0) , mShutdown(PR_TRUE) { mCreationTime = PR_Now(); @@ -335,24 +346,38 @@ nsHostResolver::nsHostResolver(PRUint32 PR_INIT_CLIST(&mEvictionQ); mLongIdleTimeout = PR_SecondsToInterval(LongIdleTimeoutSeconds); mShortIdleTimeout = PR_SecondsToInterval(ShortIdleTimeoutSeconds); } nsHostResolver::~nsHostResolver() { + if (mIdleThreadCV) + PR_DestroyCondVar(mIdleThreadCV); + + if (mLock) + nsAutoLock::DestroyLock(mLock); + PL_DHashTableFinish(&mDB); } nsresult nsHostResolver::Init() { NS_TIME_FUNCTION; + mLock = nsAutoLock::NewLock("nsHostResolver::mLock"); + if (!mLock) + return NS_ERROR_OUT_OF_MEMORY; + + mIdleThreadCV = PR_NewCondVar(mLock); + if (!mIdleThreadCV) + return NS_ERROR_OUT_OF_MEMORY; + PL_DHashTableInit(&mDB, &gHostDB_ops, nsnull, sizeof(nsHostDBEnt), 0); mShutdown = PR_FALSE; #if defined(HAVE_RES_NINIT) // We want to make sure the system is using the correct resolver settings, // so we force it to reload those settings whenever we startup a subsequent // nsHostResolver instance. We assume that there is no reason to do this @@ -388,29 +413,29 @@ nsHostResolver::Shutdown() PRCList pendingQHigh, pendingQMed, pendingQLow, evictionQ; PR_INIT_CLIST(&pendingQHigh); PR_INIT_CLIST(&pendingQMed); PR_INIT_CLIST(&pendingQLow); PR_INIT_CLIST(&evictionQ); { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); mShutdown = PR_TRUE; MoveCList(mHighQ, pendingQHigh); MoveCList(mMediumQ, pendingQMed); MoveCList(mLowQ, pendingQLow); MoveCList(mEvictionQ, evictionQ); mEvictionQSize = 0; mPendingCount = 0; if (mNumIdleThreads) - mIdleThreadCV.NotifyAll(); + PR_NotifyAllCondVar(mIdleThreadCV); // empty host database PL_DHashTableEnumerate(&mDB, HostDB_RemoveEntry, nsnull); } ClearPendingQueue(&pendingQHigh); ClearPendingQueue(&pendingQMed); ClearPendingQueue(&pendingQLow); @@ -482,17 +507,17 @@ nsHostResolver::ResolveHost(const char if (!net_IsValidHostName(nsDependentCString(host))) return NS_ERROR_UNKNOWN_HOST; // if result is set inside the lock, then we need to issue the // callback before returning. nsRefPtr<nsHostRecord> result; nsresult status = NS_OK, rv = NS_OK; { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); if (mShutdown) rv = NS_ERROR_NOT_INITIALIZED; else { PRNetAddr tempAddr; // unfortunately, PR_StringToNetAddr does not properly initialize // the output buffer in the case of IPv6 input. see bug 223145. @@ -572,17 +597,17 @@ nsHostResolver::ResolveHost(const char // Move from (low|med) to high. MoveQueue(he->rec, mHighQ); he->rec->flags = flags; ConditionallyCreateThread(he->rec); } else if (IsMediumPriority(flags) && IsLowPriority(he->rec->flags)) { // Move from low to med. MoveQueue(he->rec, mMediumQ); he->rec->flags = flags; - mIdleThreadCV.Notify(); + PR_NotifyCondVar(mIdleThreadCV); } } } } } if (result) callback->OnLookupComplete(this, result, status); return rv; @@ -592,17 +617,17 @@ void nsHostResolver::DetachCallback(const char *host, PRUint16 flags, PRUint16 af, nsResolveHostCallback *callback, nsresult status) { nsRefPtr<nsHostRecord> rec; { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); nsHostKey key = { host, flags, af }; nsHostDBEnt *he = static_cast<nsHostDBEnt *> (PL_DHashTableOperate(&mDB, &key, PL_DHASH_LOOKUP)); if (he && he->rec) { // walk list looking for |callback|... we cannot assume // that it will be there! PRCList *node = he->rec->callbacks.next; @@ -623,17 +648,17 @@ nsHostResolver::DetachCallback(const cha callback->OnLookupComplete(this, rec, status); } nsresult nsHostResolver::ConditionallyCreateThread(nsHostRecord *rec) { if (mNumIdleThreads) { // wake up idle thread to process this lookup - mIdleThreadCV.Notify(); + PR_NotifyCondVar(mIdleThreadCV); } else if ((mThreadCount < HighThreadThreshold) || (IsHighPriority(rec->flags) && mThreadCount < MAX_RESOLVER_THREADS)) { // dispatch new worker thread NS_ADDREF_THIS(); // owning reference passed to thread mThreadCount++; PRThread *thr = PR_CreateThread(PR_SYSTEM_THREAD, @@ -704,17 +729,17 @@ nsHostResolver::DeQueue(PRCList &aQ, nsH } PRBool nsHostResolver::GetHostToLookup(nsHostRecord **result) { PRBool timedOut = PR_FALSE; PRIntervalTime epoch, now, timeout; - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); timeout = (mNumIdleThreads >= HighThreadThreshold) ? mShortIdleTimeout : mLongIdleTimeout; epoch = PR_IntervalNow(); while (!mShutdown) { // remove next record from Q; hand over owning reference. Check high, then med, then low if (!PR_CLIST_IS_EMPTY(&mHighQ)) { @@ -744,17 +769,17 @@ nsHostResolver::GetHostToLookup(nsHostRe break; // wait for one or more of the following to occur: // (1) the pending queue has a host record to process // (2) the shutdown flag has been set // (3) the thread has been idle for too long mNumIdleThreads++; - mIdleThreadCV.Wait(timeout); + PR_WaitCondVar(mIdleThreadCV, timeout); mNumIdleThreads--; now = PR_IntervalNow(); if ((PRIntervalTime)(now - epoch) >= timeout) timedOut = PR_TRUE; else { // It is possible that PR_WaitCondVar() was interrupted and returned early, @@ -773,30 +798,29 @@ nsHostResolver::GetHostToLookup(nsHostRe void nsHostResolver::OnLookupComplete(nsHostRecord *rec, nsresult status, PRAddrInfo *result) { // get the list of pending callbacks for this lookup, and notify // them that the lookup is complete. PRCList cbs; PR_INIT_CLIST(&cbs); { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); // grab list of callbacks to notify MoveCList(rec->callbacks, cbs); // update record fields. We might have a rec->addr_info already if a // previous lookup result expired and we're reresolving it.. PRAddrInfo *old_addr_info; - { - MutexAutoLock lock(*rec->addr_info_lock); - old_addr_info = rec->addr_info; - rec->addr_info = result; - rec->addr_info_gencnt++; - } + PR_Lock(rec->addr_info_lock); + old_addr_info = rec->addr_info; + rec->addr_info = result; + rec->addr_info_gencnt++; + PR_Unlock(rec->addr_info_lock); if (old_addr_info) PR_FreeAddrInfo(old_addr_info); rec->expiration = NowInMinutes(); if (result) { rec->expiration += mMaxCacheLifetime; rec->negative = PR_FALSE; } else {
--- a/netwerk/dns/nsHostResolver.h +++ b/netwerk/dns/nsHostResolver.h @@ -35,21 +35,20 @@ * * ***** END LICENSE BLOCK ***** */ #ifndef nsHostResolver_h__ #define nsHostResolver_h__ #include "nscore.h" #include "nsAtomicRefcnt.h" +#include "prcvar.h" #include "prclist.h" #include "prnetdb.h" #include "pldhash.h" -#include "mozilla/CondVar.h" -#include "mozilla/Mutex.h" #include "nsISupportsImpl.h" class nsHostResolver; class nsHostRecord; class nsResolveHostCallback; /* XXX move this someplace more generic */ #define NS_DECL_REFCOUNTED_THREADSAFE(classname) \ @@ -81,18 +80,16 @@ struct nsHostKey PRUint16 af; }; /** * nsHostRecord - ref counted object type stored in host resolver cache. */ class nsHostRecord : public PRCList, public nsHostKey { - typedef mozilla::Mutex Mutex; - public: NS_DECL_REFCOUNTED_THREADSAFE(nsHostRecord) /* instantiates a new host record */ static nsresult Create(const nsHostKey *key, nsHostRecord **record); /* a fully resolved host record has either a non-null |addr_info| or |addr| * field. if |addr_info| is null, it implies that the |host| is an IP @@ -106,17 +103,17 @@ public: /* the lock protects |addr_info| and |addr_info_gencnt| because they * are mutable and accessed by the resolver worker thread and the * nsDNSService2 class. |addr| doesn't change after it has been * assigned a value. only the resolver worker thread modifies * nsHostRecord (and only in nsHostResolver::OnLookupComplete); * the other threads just read it. therefore the resolver worker * thread doesn't need to lock when reading |addr_info|. */ - Mutex *addr_info_lock; + PRLock *addr_info_lock; int addr_info_gencnt; /* generation count of |addr_info| */ PRAddrInfo *addr_info; PRNetAddr *addr; PRBool negative; /* True if this record is a cache of a failed lookup. Negative cache entries are valid just like any other (though never for more than 60 seconds), but a use of that negative entry forces an asynchronous refresh. */ @@ -169,19 +166,16 @@ public: nsresult status) = 0; }; /** * nsHostResolver - an asynchronous host name resolver. */ class nsHostResolver { - typedef mozilla::CondVar CondVar; - typedef mozilla::Mutex Mutex; - public: /** * host resolver instances are reference counted. */ NS_DECL_REFCOUNTED_THREADSAFE(nsHostResolver) /** * creates an addref'd instance of a nsHostResolver object. @@ -248,18 +242,18 @@ private: nsresult ConditionallyCreateThread(nsHostRecord *rec); static void MoveQueue(nsHostRecord *aRec, PRCList &aDestQ); static void ThreadFunc(void *); PRUint32 mMaxCacheEntries; PRUint32 mMaxCacheLifetime; - Mutex mLock; - CondVar mIdleThreadCV; + PRLock *mLock; + PRCondVar *mIdleThreadCV; // non-null if idle thread PRUint32 mNumIdleThreads; PRUint32 mThreadCount; PRUint32 mActiveAnyThreadCount; PLDHashTable mDB; PRCList mHighQ; PRCList mMediumQ; PRCList mLowQ; PRCList mEvictionQ;
--- a/netwerk/protocol/ftp/nsFTPChannel.h +++ b/netwerk/protocol/ftp/nsFTPChannel.h @@ -50,16 +50,17 @@ #include "nsCOMPtr.h" #include "nsIProtocolHandler.h" #include "nsIProgressEventSink.h" #include "nsIInterfaceRequestor.h" #include "nsIInterfaceRequestorUtils.h" #include "nsFtpConnectionThread.h" #include "netCore.h" #include "nsIStreamListener.h" +#include "nsAutoLock.h" #include "nsIFTPChannel.h" #include "nsIUploadChannel.h" #include "nsIProxyInfo.h" #include "nsIProxiedChannel.h" #include "nsIResumableChannel.h" #include "nsHashPropertyBag.h" #include "nsFtpProtocolHandler.h"
--- a/netwerk/protocol/ftp/nsFtpConnectionThread.h +++ b/netwerk/protocol/ftp/nsFtpConnectionThread.h @@ -55,16 +55,17 @@ #include "prnetdb.h" #include "prtime.h" #include "nsString.h" #include "nsIFTPChannel.h" #include "nsIProtocolHandler.h" #include "nsCOMPtr.h" #include "nsIAsyncInputStream.h" #include "nsIOutputStream.h" +#include "nsAutoLock.h" #include "nsAutoPtr.h" #include "nsIPrompt.h" #include "nsITransport.h" #include "nsIProxyInfo.h" #include "nsFtpControlConnection.h" #include "nsICacheEntryDescriptor.h"
--- a/netwerk/protocol/ftp/nsFtpControlConnection.h +++ b/netwerk/protocol/ftp/nsFtpControlConnection.h @@ -42,16 +42,17 @@ #include "nsCOMPtr.h" #include "nsIURI.h" #include "nsIStreamListener.h" #include "nsIRequest.h" #include "nsISocketTransport.h" #include "nsIOutputStream.h" #include "nsIAsyncInputStream.h" +#include "nsAutoLock.h" #include "nsAutoPtr.h" #include "nsString.h" class nsIProxyInfo; class nsITransportEventSink; class nsFtpControlConnectionListener : public nsISupports { public:
--- a/netwerk/protocol/http/nsHttp.cpp +++ b/netwerk/protocol/http/nsHttp.cpp @@ -33,18 +33,18 @@ * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #include "nsHttp.h" +#include "nsAutoLock.h" #include "pldhash.h" -#include "mozilla/Mutex.h" #include "nsCRT.h" #include "prbit.h" #if defined(PR_LOGGING) PRLogModuleInfo *gHttpLog = nsnull; #endif // define storage for all atoms @@ -55,30 +55,28 @@ PRLogModuleInfo *gHttpLog = nsnull; // find out how many atoms we have #define HTTP_ATOM(_name, _value) Unused_ ## _name, enum { #include "nsHttpAtomList.h" NUM_HTTP_ATOMS }; #undef HTTP_ATOM -using namespace mozilla; - // we keep a linked list of atoms allocated on the heap for easy clean up when // the atom table is destroyed. The structure and value string are allocated // as one contiguous block. struct HttpHeapAtom { struct HttpHeapAtom *next; char value[1]; }; static struct PLDHashTable sAtomTable = {0}; static struct HttpHeapAtom *sHeapAtoms = nsnull; -static Mutex *sLock = nsnull; +static PRLock *sLock = nsnull; HttpHeapAtom * NewHeapAtom(const char *value) { int len = strlen(value); HttpHeapAtom *a = reinterpret_cast<HttpHeapAtom *>(malloc(sizeof(*a) + len)); if (!a) @@ -126,17 +124,19 @@ static const PLDHashTableOps ops = { // We put the atoms in a hash table for speedy lookup.. see ResolveAtom. nsresult nsHttp::CreateAtomTable() { NS_ASSERTION(!sAtomTable.ops, "atom table already initialized"); if (!sLock) { - sLock = new Mutex("nsHttp.sLock"); + sLock = nsAutoLock::NewLock("nsHttp::sLock"); + if (!sLock) + return NS_ERROR_OUT_OF_MEMORY; } // The capacity for this table is initialized to a value greater than the // number of known atoms (NUM_HTTP_ATOMS) because we expect to encounter a // few random headers right off the bat. if (!PL_DHashTableInit(&sAtomTable, &ops, nsnull, sizeof(PLDHashEntryStub), NUM_HTTP_ATOMS + 10)) { sAtomTable.ops = nsnull; @@ -174,31 +174,31 @@ nsHttp::DestroyAtomTable() while (sHeapAtoms) { HttpHeapAtom *next = sHeapAtoms->next; free(sHeapAtoms); sHeapAtoms = next; } if (sLock) { - delete sLock; + nsAutoLock::DestroyLock(sLock); sLock = nsnull; } } // this function may be called from multiple threads nsHttpAtom nsHttp::ResolveAtom(const char *str) { nsHttpAtom atom = { nsnull }; if (!str || !sAtomTable.ops) return atom; - MutexAutoLock lock(*sLock); + nsAutoLock lock(sLock); PLDHashEntryStub *stub = reinterpret_cast<PLDHashEntryStub *> (PL_DHashTableOperate(&sAtomTable, str, PL_DHASH_ADD)); if (!stub) return atom; // out of memory if (stub->key) { atom._val = reinterpret_cast<const char *>(stub->key);
--- a/netwerk/protocol/http/nsHttpActivityDistributor.cpp +++ b/netwerk/protocol/http/nsHttpActivityDistributor.cpp @@ -33,21 +33,20 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #include "nsHttpActivityDistributor.h" #include "nsIChannel.h" #include "nsCOMPtr.h" #include "nsAutoPtr.h" +#include "nsAutoLock.h" #include "nsNetUtil.h" #include "nsThreadUtils.h" -using namespace mozilla; - class nsHttpActivityEvent : public nsRunnable { public: nsHttpActivityEvent(nsISupports *aHttpChannel, PRUint32 aActivityType, PRUint32 aActivitySubtype, PRTime aTimestamp, PRUint64 aExtraSizeData, @@ -87,35 +86,37 @@ private: nsCOMArray<nsIHttpActivityObserver> mObservers; }; NS_IMPL_THREADSAFE_ISUPPORTS2(nsHttpActivityDistributor, nsIHttpActivityDistributor, nsIHttpActivityObserver) nsHttpActivityDistributor::nsHttpActivityDistributor() - : mLock("nsHttpActivityDistributor.mLock") + : mLock(nsnull) { } nsHttpActivityDistributor::~nsHttpActivityDistributor() { + if (mLock) + nsAutoLock::DestroyLock(mLock); } NS_IMETHODIMP nsHttpActivityDistributor::ObserveActivity(nsISupports *aHttpChannel, PRUint32 aActivityType, PRUint32 aActivitySubtype, PRTime aTimestamp, PRUint64 aExtraSizeData, const nsACString & aExtraStringData) { nsRefPtr<nsIRunnable> event; { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); if (!mObservers.Count()) return NS_OK; event = new nsHttpActivityEvent(aHttpChannel, aActivityType, aActivitySubtype, aTimestamp, aExtraSizeData, aExtraStringData, &mObservers); @@ -123,34 +124,46 @@ nsHttpActivityDistributor::ObserveActivi NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY); return NS_DispatchToMainThread(event); } NS_IMETHODIMP nsHttpActivityDistributor::GetIsActive(PRBool *isActive) { NS_ENSURE_ARG_POINTER(isActive); - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); *isActive = !!mObservers.Count(); return NS_OK; } NS_IMETHODIMP nsHttpActivityDistributor::AddObserver(nsIHttpActivityObserver *aObserver) { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); if (!mObservers.AppendObject(aObserver)) return NS_ERROR_OUT_OF_MEMORY; return NS_OK; } NS_IMETHODIMP nsHttpActivityDistributor::RemoveObserver(nsIHttpActivityObserver *aObserver) { - MutexAutoLock lock(mLock); + nsAutoLock lock(mLock); if (!mObservers.RemoveObject(aObserver)) return NS_ERROR_FAILURE; return NS_OK; } + +nsresult +nsHttpActivityDistributor::Init() +{ + NS_ENSURE_TRUE(!mLock, NS_ERROR_ALREADY_INITIALIZED); + + mLock = nsAutoLock::NewLock("nsHttpActivityDistributor::mLock"); + if (!mLock) + return NS_ERROR_OUT_OF_MEMORY; + + return NS_OK; +}
--- a/netwerk/protocol/http/nsHttpActivityDistributor.h +++ b/netwerk/protocol/http/nsHttpActivityDistributor.h @@ -34,26 +34,27 @@ * * ***** END LICENSE BLOCK ***** */ #ifndef nsHttpActivityDistributor_h__ #define nsHttpActivityDistributor_h__ #include "nsIHttpActivityObserver.h" #include "nsCOMArray.h" -#include "mozilla/Mutex.h" +#include "prlock.h" class nsHttpActivityDistributor : public nsIHttpActivityDistributor { public: NS_DECL_ISUPPORTS NS_DECL_NSIHTTPACTIVITYOBSERVER NS_DECL_NSIHTTPACTIVITYDISTRIBUTOR nsHttpActivityDistributor(); virtual ~nsHttpActivityDistributor(); + nsresult Init(); protected: nsCOMArray<nsIHttpActivityObserver> mObservers; - mozilla::Mutex mLock; + PRLock *mLock; }; #endif // nsHttpActivityDistributor_h__
--- a/netwerk/protocol/http/nsHttpConnection.cpp +++ b/netwerk/protocol/http/nsHttpConnection.cpp @@ -45,16 +45,17 @@ #include "nsIOService.h" #include "nsISocketTransportService.h" #include "nsISocketTransport.h" #include "nsIServiceManager.h" #include "nsISSLSocketControl.h" #include "nsStringStream.h" #include "netCore.h" #include "nsNetCID.h" +#include "nsAutoLock.h" #include "prmem.h" #ifdef DEBUG // defined by the socket transport service while active extern PRThread *gSocketThread; #endif static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID);
--- a/netwerk/protocol/http/nsHttpConnection.h +++ b/netwerk/protocol/http/nsHttpConnection.h @@ -40,16 +40,17 @@ #define nsHttpConnection_h__ #include "nsHttp.h" #include "nsHttpConnectionInfo.h" #include "nsAHttpConnection.h" #include "nsAHttpTransaction.h" #include "nsXPIDLString.h" #include "nsCOMPtr.h" +#include "prlock.h" #include "nsAutoPtr.h" #include "nsIStreamListener.h" #include "nsISocketTransport.h" #include "nsIAsyncInputStream.h" #include "nsIAsyncOutputStream.h" #include "nsIInterfaceRequestor.h"
--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp +++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp @@ -35,26 +35,25 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #include "nsHttpConnectionMgr.h" #include "nsHttpConnection.h" #include "nsHttpPipeline.h" #include "nsHttpHandler.h" +#include "nsAutoLock.h" #include "nsNetCID.h" #include "nsCOMPtr.h" #include "nsNetUtil.h" #include "nsIServiceManager.h" #include "nsIObserverService.h" -using namespace mozilla; - // defined by the socket transport service while active extern PRThread *gSocketThread; static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID); //----------------------------------------------------------------------------- @@ -76,33 +75,36 @@ InsertTransactionSorted(nsTArray<nsHttpT } pendingQ.InsertElementAt(0, trans); } //----------------------------------------------------------------------------- nsHttpConnectionMgr::nsHttpConnectionMgr() : mRef(0) - , mMonitor("nsHttpConnectionMgr.mMonitor") + , mMonitor(nsAutoMonitor::NewMonitor("nsHttpConnectionMgr")) , mMaxConns(0) , mMaxConnsPerHost(0) , mMaxConnsPerProxy(0) , mMaxPersistConnsPerHost(0) , mMaxPersistConnsPerProxy(0) , mIsShuttingDown(PR_FALSE) , mNumActiveConns(0) , mNumIdleConns(0) , mTimeOfNextWakeUp(LL_MAXUINT) { LOG(("Creating nsHttpConnectionMgr @%x\n", this)); } nsHttpConnectionMgr::~nsHttpConnectionMgr() { LOG(("Destroying nsHttpConnectionMgr @%x\n", this)); + + if (mMonitor) + nsAutoMonitor::DestroyMonitor(mMonitor); } nsresult nsHttpConnectionMgr::EnsureSocketThreadTargetIfOnline() { nsresult rv; nsCOMPtr<nsIEventTarget> sts; nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv); @@ -110,17 +112,17 @@ nsHttpConnectionMgr::EnsureSocketThreadT PRBool offline = PR_TRUE; ioService->GetOffline(&offline); if (!offline) { sts = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv); } } - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); // do nothing if already initialized or if we've shut down if (mSocketThreadTarget || mIsShuttingDown) return NS_OK; mSocketThreadTarget = sts; return rv; @@ -133,17 +135,17 @@ nsHttpConnectionMgr::Init(PRUint16 maxCo PRUint16 maxPersistConnsPerHost, PRUint16 maxPersistConnsPerProxy, PRUint16 maxRequestDelay, PRUint16 maxPipelinedRequests) { LOG(("nsHttpConnectionMgr::Init\n")); { - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); mMaxConns = maxConns; mMaxConnsPerHost = maxConnsPerHost; mMaxConnsPerProxy = maxConnsPerProxy; mMaxPersistConnsPerHost = maxPersistConnsPerHost; mMaxPersistConnsPerProxy = maxPersistConnsPerProxy; mMaxRequestDelay = maxRequestDelay; mMaxPipelinedRequests = maxPipelinedRequests; @@ -154,17 +156,17 @@ nsHttpConnectionMgr::Init(PRUint16 maxCo return EnsureSocketThreadTargetIfOnline(); } nsresult nsHttpConnectionMgr::Shutdown() { LOG(("nsHttpConnectionMgr::Shutdown\n")); - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); // do nothing if already shutdown if (!mSocketThreadTarget) return NS_OK; nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgShutdown); // release our reference to the STS to prevent further events @@ -187,17 +189,17 @@ nsresult nsHttpConnectionMgr::PostEvent(nsConnEventHandler handler, PRInt32 iparam, void *vparam) { // This object doesn't get reinitialized if the offline state changes, so our // socket thread target might be uninitialized if we were offline when this // object was being initialized, and we go online later on. This call takes // care of initializing the socket thread target if that's the case. EnsureSocketThreadTargetIfOnline(); - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); nsresult rv; if (!mSocketThreadTarget) { NS_WARNING("cannot post event if not initialized"); rv = NS_ERROR_NOT_INITIALIZED; } else { nsRefPtr<nsIRunnable> event = new nsConnEvent(this, handler, iparam, vparam); @@ -312,17 +314,17 @@ nsresult nsHttpConnectionMgr::GetSocketThreadTarget(nsIEventTarget **target) { // This object doesn't get reinitialized if the offline state changes, so our // socket thread target might be uninitialized if we were offline when this // object was being initialized, and we go online later on. This call takes // care of initializing the socket thread target if that's the case. EnsureSocketThreadTargetIfOnline(); - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); NS_IF_ADDREF(*target = mSocketThreadTarget); return NS_OK; } void nsHttpConnectionMgr::AddTransactionToPipeline(nsHttpPipeline *pipeline) { LOG(("nsHttpConnectionMgr::AddTransactionToPipeline [pipeline=%x]\n", pipeline)); @@ -870,17 +872,17 @@ nsHttpConnectionMgr::ProcessNewTransacti void nsHttpConnectionMgr::OnMsgShutdown(PRInt32, void *) { LOG(("nsHttpConnectionMgr::OnMsgShutdown\n")); mCT.Reset(ShutdownPassCB, this); // signal shutdown complete - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); mon.Notify(); } void nsHttpConnectionMgr::OnMsgNewTransaction(PRInt32 priority, void *param) { LOG(("nsHttpConnectionMgr::OnMsgNewTransaction [trans=%p]\n", param));
--- a/netwerk/protocol/http/nsHttpConnectionMgr.h +++ b/netwerk/protocol/http/nsHttpConnectionMgr.h @@ -41,17 +41,17 @@ #include "nsHttpConnectionInfo.h" #include "nsHttpConnection.h" #include "nsHttpTransaction.h" #include "nsTArray.h" #include "nsThreadUtils.h" #include "nsHashtable.h" #include "nsAutoPtr.h" -#include "mozilla/Monitor.h" +#include "prmon.h" #include "nsIObserver.h" #include "nsITimer.h" class nsHttpPipeline; //----------------------------------------------------------------------------- @@ -182,17 +182,17 @@ private: nsHttpConnection *mConn; }; //------------------------------------------------------------------------- // NOTE: these members may be accessed from any thread (use mMonitor) //------------------------------------------------------------------------- PRInt32 mRef; - mozilla::Monitor mMonitor; + PRMonitor *mMonitor; nsCOMPtr<nsIEventTarget> mSocketThreadTarget; // connection limits PRUint16 mMaxConns; PRUint16 mMaxConnsPerHost; PRUint16 mMaxConnsPerProxy; PRUint16 mMaxPersistConnsPerHost; PRUint16 mMaxPersistConnsPerProxy;
--- a/netwerk/protocol/http/nsHttpHandler.cpp +++ b/netwerk/protocol/http/nsHttpHandler.cpp @@ -64,16 +64,17 @@ #include "nsIPrefService.h" #include "nsIPrefBranch2.h" #include "nsIPrefLocalizedString.h" #include "nsISocketProviderService.h" #include "nsISocketProvider.h" #include "nsPrintfCString.h" #include "nsCOMPtr.h" #include "nsNetCID.h" +#include "nsAutoLock.h" #include "prprf.h" #include "nsReadableUtils.h" #include "nsQuickSort.h" #include "nsNetUtil.h" #include "nsIOService.h" #include "nsAsyncRedirectVerifyHelper.h" #include "nsSocketTransportService2.h"
--- a/netwerk/protocol/http/nsHttpPipeline.cpp +++ b/netwerk/protocol/http/nsHttpPipeline.cpp @@ -42,16 +42,17 @@ #include "nsHttpHandler.h" #include "nsIOService.h" #include "nsIRequest.h" #include "nsISocketTransport.h" #include "nsIStringStream.h" #include "nsIPipe.h" #include "nsCOMPtr.h" #include "nsComponentManagerUtils.h" +#include "nsAutoLock.h" #ifdef DEBUG #include "prthread.h" // defined by the socket transport service while active extern PRThread *gSocketThread; #endif //-----------------------------------------------------------------------------
--- a/netwerk/protocol/http/nsHttpTransaction.cpp +++ b/netwerk/protocol/http/nsHttpTransaction.cpp @@ -48,16 +48,17 @@ #include "nsHttpConnection.h" #include "nsHttpRequestHead.h" #include "nsHttpResponseHead.h" #include "nsHttpChunkedDecoder.h" #include "nsTransportUtils.h" #include "nsNetUtil.h" #include "nsProxyRelease.h" #include "nsIOService.h" +#include "nsAutoLock.h" #include "nsAtomicRefcnt.h" #include "nsISeekableStream.h" #include "nsISocketTransport.h" #include "nsMultiplexInputStream.h" #include "nsStringStream.h" #include "nsComponentManagerUtils.h" // do_CreateInstance
--- a/netwerk/protocol/res/nsResProtocolHandler.cpp +++ b/netwerk/protocol/res/nsResProtocolHandler.cpp @@ -38,16 +38,17 @@ * * ***** END LICENSE BLOCK ***** */ #ifdef MOZ_IPC #include "mozilla/chrome/RegistryMessageUtils.h" #endif #include "nsResProtocolHandler.h" +#include "nsAutoLock.h" #include "nsIURL.h" #include "nsIIOService.h" #include "nsIServiceManager.h" #include "nsILocalFile.h" #include "prenv.h" #include "prmem.h" #include "prprf.h" #include "nsXPIDLString.h"
--- a/netwerk/wifi/nsWifiMonitor.cpp +++ b/netwerk/wifi/nsWifiMonitor.cpp @@ -38,64 +38,66 @@ * ***** END LICENSE BLOCK ***** */ #include "nsCOMPtr.h" #include "nsComponentManagerUtils.h" #include "nsServiceManagerUtils.h" #include "nsThreadUtils.h" #include "nsXPCOM.h" #include "nsXPCOMCID.h" +#include "nsAutoLock.h" #include "nsIObserver.h" #include "nsIObserverService.h" #include "nsWifiMonitor.h" #include "nsIProxyObjectManager.h" #include "nsServiceManagerUtils.h" #include "nsComponentManagerUtils.h" #include "mozilla/Services.h" -using namespace mozilla; - #if defined(PR_LOGGING) PRLogModuleInfo *gWifiMonitorLog; #endif NS_IMPL_THREADSAFE_ISUPPORTS3(nsWifiMonitor, nsIRunnable, nsIObserver, nsIWifiMonitor) nsWifiMonitor::nsWifiMonitor() : mKeepGoing(PR_TRUE) -, mMonitor("nsWifiMonitor.mMonitor") { #if defined(PR_LOGGING) gWifiMonitorLog = PR_NewLogModule("WifiMonitor"); #endif + mMonitor = nsAutoMonitor::NewMonitor("nsWifiMonitor"); + nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService(); if (obsSvc) obsSvc->AddObserver(this, "xpcom-shutdown", PR_FALSE); LOG(("@@@@@ wifimonitor created\n")); } nsWifiMonitor::~nsWifiMonitor() { + if (mMonitor) + nsAutoMonitor::DestroyMonitor(mMonitor); } NS_IMETHODIMP nsWifiMonitor::Observe(nsISupports *subject, const char *topic, const PRUnichar *data) { if (!strcmp(topic, "xpcom-shutdown")) { LOG(("Shutting down\n")); mKeepGoing = PR_FALSE; - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); mon.Notify(); } return NS_OK; } NS_IMETHODIMP nsWifiMonitor::StartWatching(nsIWifiListener *aListener) { @@ -104,17 +106,17 @@ NS_IMETHODIMP nsWifiMonitor::StartWatchi nsresult rv = NS_OK; if (!mThread) { rv = NS_NewThread(getter_AddRefs(mThread), this); if (NS_FAILED(rv)) return rv; } - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); mKeepGoing = PR_TRUE; mListeners.AppendElement(nsWifiListener(aListener)); // tell ourselves that we have a new watcher. mon.Notify(); return NS_OK; @@ -122,17 +124,17 @@ NS_IMETHODIMP nsWifiMonitor::StartWatchi NS_IMETHODIMP nsWifiMonitor::StopWatching(nsIWifiListener *aListener) { if (!aListener) return NS_ERROR_NULL_POINTER; LOG(("removing listener\n")); - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); for (PRUint32 i = 0; i < mListeners.Length(); i++) { if (mListeners[i].mListener == aListener) { mListeners.RemoveElementAt(i); break; } }
--- a/netwerk/wifi/nsWifiMonitor.h +++ b/netwerk/wifi/nsWifiMonitor.h @@ -35,21 +35,22 @@ * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #include "nsIWifiMonitor.h" #include "nsCOMPtr.h" #include "nsAutoPtr.h" +#include "nsAutoLock.h" #include "nsIThread.h" #include "nsIRunnable.h" #include "nsCOMArray.h" #include "nsIWifiMonitor.h" -#include "mozilla/Monitor.h" +#include "prmon.h" #include "prlog.h" #include "nsIObserver.h" #include "nsTArray.h" #ifndef __nsWifiMonitor__ #define __nsWifiMonitor__ #if defined(PR_LOGGING) @@ -92,13 +93,13 @@ class nsWifiMonitor : nsIRunnable, nsIWi nsresult DoScanOld(); #endif PRBool mKeepGoing; nsCOMPtr<nsIThread> mThread; nsTArray<nsWifiListener> mListeners; - mozilla::Monitor mMonitor; + PRMonitor* mMonitor; }; #endif
--- a/netwerk/wifi/nsWifiScannerMac.cpp +++ b/netwerk/wifi/nsWifiScannerMac.cpp @@ -48,18 +48,16 @@ #include "nsWifiMonitor.h" #include "nsWifiAccessPoint.h" #include "nsIProxyObjectManager.h" #include "nsServiceManagerUtils.h" #include "nsComponentManagerUtils.h" #include "nsIMutableArray.h" -using namespace mozilla; - // defined in osx_corewlan.mm // basically relaces accesspoints in the passed reference // it lives in a separate file so that we can use objective c. extern nsresult GetAccessPointsFromWLAN(nsCOMArray<nsWifiAccessPoint> &accessPoints); nsresult nsWifiMonitor::DoScanWithCoreWLAN() { @@ -72,17 +70,17 @@ nsWifiMonitor::DoScanWithCoreWLAN() nsresult rv = GetAccessPointsFromWLAN(accessPoints); if (NS_FAILED(rv)) return rv; PRBool accessPointsChanged = !AccessPointsEqual(accessPoints, lastAccessPoints); nsCOMArray<nsIWifiListener> currentListeners; { - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); for (PRUint32 i = 0; i < mListeners.Length(); i++) { if (!mListeners[i].mHasSentData || accessPointsChanged) { mListeners[i].mHasSentData = PR_TRUE; currentListeners.AppendObject(mListeners[i].mListener); } } } @@ -122,17 +120,17 @@ nsWifiMonitor::DoScanWithCoreWLAN() } nsMemory::Free(result); } // wait for some reasonable amount of time. pref? LOG(("waiting on monitor\n")); - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); mon.Wait(PR_SecondsToInterval(60)); } while (mKeepGoing); return NS_OK; } nsresult @@ -207,17 +205,17 @@ nsWifiMonitor::DoScanOld() accessPoints.AppendObject(ap); } PRBool accessPointsChanged = !AccessPointsEqual(accessPoints, lastAccessPoints); nsCOMArray<nsIWifiListener> currentListeners; { - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); for (PRUint32 i = 0; i < mListeners.Length(); i++) { if (!mListeners[i].mHasSentData || accessPointsChanged) { mListeners[i].mHasSentData = PR_TRUE; currentListeners.AppendObject(mListeners[i].mListener); } } } @@ -258,17 +256,17 @@ nsWifiMonitor::DoScanOld() } nsMemory::Free(result); } // wait for some reasonable amount of time. pref? LOG(("waiting on monitor\n")); - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); mon.Wait(PR_SecondsToInterval(60)); } while (mKeepGoing); (*WirelessDetach_function_)(wifi_context_); dlclose(apple_80211_library);
--- a/netwerk/wifi/nsWifiScannerUnix.cpp +++ b/netwerk/wifi/nsWifiScannerUnix.cpp @@ -36,25 +36,26 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #include "iwlib.h" #include "dlfcn.h" +#include "nsAutoPtr.h" #include "nsWifiMonitor.h" #include "nsWifiAccessPoint.h" #include "nsIProxyObjectManager.h" #include "nsServiceManagerUtils.h" #include "nsComponentManagerUtils.h" #include "nsIMutableArray.h" -using namespace mozilla; + typedef int (*iw_open_t)(void); typedef void (*iw_enum_t)(int skfd, iw_enum_handler fn, char *args[], int count); @@ -165,17 +166,17 @@ nsWifiMonitor::DoScan() accessPoints.Clear(); (*iw_enum)(skfd, &scan_wifi, args, 1); PRBool accessPointsChanged = !AccessPointsEqual(accessPoints, lastAccessPoints); nsCOMArray<nsIWifiListener> currentListeners; { - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); for (PRUint32 i = 0; i < mListeners.Length(); i++) { if (!mListeners[i].mHasSentData || accessPointsChanged) { mListeners[i].mHasSentData = PR_TRUE; currentListeners.AppendObject(mListeners[i].mListener); } } } @@ -215,16 +216,16 @@ nsWifiMonitor::DoScan() } } nsMemory::Free(result); } LOG(("waiting on monitor\n")); - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); mon.Wait(PR_SecondsToInterval(60)); } iw_sockets_close(skfd); return NS_OK; }
--- a/netwerk/wifi/nsWifiScannerWin.cpp +++ b/netwerk/wifi/nsWifiScannerWin.cpp @@ -41,26 +41,25 @@ #include "windows.h" #include "wlanapi.h" #include <ntddndis.h> #include "winioctl.h" #include "stdlib.h" +#include "nsAutoPtr.h" #include "nsWifiMonitor.h" #include "nsWifiAccessPoint.h" #include "nsIProxyObjectManager.h" #include "nsServiceManagerUtils.h" #include "nsComponentManagerUtils.h" #include "nsIMutableArray.h" -using namespace mozilla; - nsresult nsWifiMonitor::DoScan() { HINSTANCE wlan_library = LoadLibrary("Wlanapi.dll"); if (!wlan_library) return NS_ERROR_NOT_AVAILABLE; WlanOpenHandleFunction WlanOpenHandle = (WlanOpenHandleFunction) GetProcAddress(wlan_library, "WlanOpenHandle"); @@ -149,17 +148,17 @@ nsWifiMonitor::DoScan() // Close the handle. (*WlanCloseHandle)(wlan_handle, NULL); PRBool accessPointsChanged = !AccessPointsEqual(accessPoints, lastAccessPoints); nsCOMArray<nsIWifiListener> currentListeners; { - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); for (PRUint32 i = 0; i < mListeners.Length(); i++) { if (!mListeners[i].mHasSentData || accessPointsChanged) { mListeners[i].mHasSentData = PR_TRUE; currentListeners.AppendObject(mListeners[i].mListener); } } } @@ -197,15 +196,15 @@ nsWifiMonitor::DoScan() } nsMemory::Free(result); } // wait for some reasonable amount of time. pref? LOG(("waiting on monitor\n")); - MonitorAutoEnter mon(mMonitor); + nsAutoMonitor mon(mMonitor); mon.Wait(PR_SecondsToInterval(60)); } while (mKeepGoing); return NS_OK; }
--- a/parser/htmlparser/src/nsParser.cpp +++ b/parser/htmlparser/src/nsParser.cpp @@ -49,16 +49,17 @@ #include "nsICacheEntryDescriptor.h" #include "nsICharsetAlias.h" #include "nsICharsetConverterManager.h" #include "nsIInputStream.h" #include "CNavDTD.h" #include "prenv.h" #include "prlock.h" #include "prcvar.h" +#include "nsAutoLock.h" #include "nsParserCIID.h" #include "nsReadableUtils.h" #include "nsCOMPtr.h" #include "nsExpatDriver.h" #include "nsIServiceManager.h" #include "nsICategoryManager.h" #include "nsISupportsPrimitives.h" #include "nsIFragmentContentSink.h" @@ -67,20 +68,16 @@ #include "nsIDocument.h" #include "nsNetUtil.h" #include "nsScriptLoader.h" #include "nsDataHashtable.h" #include "nsIThreadPool.h" #include "nsXPCOMCIDInternal.h" #include "nsMimeTypes.h" #include "nsViewSourceHTML.h" -#include "mozilla/CondVar.h" -#include "mozilla/Mutex.h" - -using namespace mozilla; #define NS_PARSER_FLAG_PARSER_ENABLED 0x00000002 #define NS_PARSER_FLAG_OBSERVERS_ENABLED 0x00000004 #define NS_PARSER_FLAG_PENDING_CONTINUE_EVENT 0x00000008 #define NS_PARSER_FLAG_CAN_INTERRUPT 0x00000010 #define NS_PARSER_FLAG_FLUSH_TOKENS 0x00000020 #define NS_PARSER_FLAG_CAN_TOKENIZE 0x00000040 @@ -196,18 +193,18 @@ public: private: Type *mHoldee; Reaper mReaper; }; class nsSpeculativeScriptThread : public nsIRunnable { public: nsSpeculativeScriptThread() - : mLock("nsSpeculativeScriptThread.mLock"), - mCVar(mLock, "nsSpeculativeScriptThread.mCVar"), + : mLock(nsAutoLock::DestroyLock), + mCVar(PR_DestroyCondVar), mKeepParsing(PR_FALSE), mCurrentlyParsing(PR_FALSE), mNumConsumed(0), mContext(nsnull), mTerminated(PR_FALSE) { } ~nsSpeculativeScriptThread() { @@ -266,18 +263,18 @@ private: void FlushURIs(); // These members are only accessed on the speculatively parsing thread. nsTokenAllocator mTokenAllocator; // The following members are shared across the main thread and the // speculatively parsing thread. - Mutex mLock; - CondVar mCVar; + Holder<PRLock> mLock; + Holder<PRCondVar> mCVar; volatile PRBool mKeepParsing; volatile PRBool mCurrentlyParsing; nsRefPtr<nsHTMLTokenizer> mTokenizer; nsAutoPtr<nsScanner> mScanner; enum { kBatchPrefetchURIs = 5 }; nsAutoTArray<PrefetchEntry, kBatchPrefetchURIs> mURIs; @@ -410,20 +407,20 @@ nsSpeculativeScriptThread::Run() // gathered so far so we don't end up waiting for the parser's current // load to finish. if (!mURIs.IsEmpty()) { FlushURIs(); } } { - MutexAutoLock al(mLock); + nsAutoLock al(mLock.get()); mCurrentlyParsing = PR_FALSE; - mCVar.Notify(); + PR_NotifyCondVar(mCVar.get()); } return NS_OK; } nsresult nsSpeculativeScriptThread::StartParsing(nsParser *aParser) { NS_ASSERTION(NS_IsMainThread(), "Called on the wrong thread"); @@ -440,17 +437,27 @@ nsSpeculativeScriptThread::StartParsing( nsCOMPtr<nsIDocument> doc = do_QueryInterface(sink->GetTarget()); if (!doc) { return NS_OK; } nsAutoString toScan; CParserContext *context = aParser->PeekContext(); - if (!mTokenizer) { + if (!mLock.get()) { + mLock = nsAutoLock::NewLock("nsSpeculativeScriptThread::mLock"); + if (!mLock.get()) { + return NS_ERROR_OUT_OF_MEMORY; + } + + mCVar = PR_NewCondVar(mLock.get()); + if (!mCVar.get()) { + return NS_ERROR_OUT_OF_MEMORY; + } + if (!mPreloadedURIs.Init(15)) { return NS_ERROR_OUT_OF_MEMORY; } mTokenizer = new nsHTMLTokenizer(context->mDTDMode, context->mDocType, context->mParserCommand, 0); if (!mTokenizer) { return NS_ERROR_OUT_OF_MEMORY; @@ -507,22 +514,27 @@ nsSpeculativeScriptThread::StartParsing( return aParser->ThreadPool()->Dispatch(this, NS_DISPATCH_NORMAL); } void nsSpeculativeScriptThread::StopParsing(PRBool /*aFromDocWrite*/) { NS_ASSERTION(NS_IsMainThread(), "Can't stop parsing from another thread"); + if (!mLock.get()) { + // If we bailed early out of StartParsing, don't do anything. + return; + } + { - MutexAutoLock al(mLock); + nsAutoLock al(mLock.get()); mKeepParsing = PR_FALSE; if (mCurrentlyParsing) { - mCVar.Wait(); + PR_WaitCondVar(mCVar.get(), PR_INTERVAL_NO_TIMEOUT); NS_ASSERTION(!mCurrentlyParsing, "Didn't actually stop parsing?"); } } // The thread is now idle. if (mTerminated) { // If we're terminated, then we need to ensure that we release our document // and tokenizer here on the main thread so that our last reference to them
--- a/security/manager/boot/src/nsSecureBrowserUIImpl.cpp +++ b/security/manager/boot/src/nsSecureBrowserUIImpl.cpp @@ -80,18 +80,17 @@ #include "nsISecurityWarningDialogs.h" #include "nsISecurityInfoProvider.h" #include "nsIProxyObjectManager.h" #include "imgIRequest.h" #include "nsThreadUtils.h" #include "nsNetUtil.h" #include "nsNetCID.h" #include "nsCRT.h" - -using namespace mozilla; +#include "nsAutoLock.h" #define SECURITY_STRING_BUNDLE_URL "chrome://pipnss/locale/security.properties" #define IS_SECURE(state) ((state & 0xFFFF) == STATE_IS_SECURE) #if defined(PR_LOGGING) // // Log module for nsSecureBrowserUI logging... @@ -155,46 +154,48 @@ class nsAutoAtomic { PRInt32 &mI; private: nsAutoAtomic(); // not accessible }; #endif nsSecureBrowserUIImpl::nsSecureBrowserUIImpl() - : mMonitor("nsSecureBrowserUIImpl.mMonitor") - , mNotifiedSecurityState(lis_no_security) + : mNotifiedSecurityState(lis_no_security) , mNotifiedToplevelIsEV(PR_FALSE) , mNewToplevelSecurityState(STATE_IS_INSECURE) , mNewToplevelIsEV(PR_FALSE) , mNewToplevelSecurityStateKnown(PR_TRUE) , mIsViewSource(PR_FALSE) , mSubRequestsHighSecurity(0) , mSubRequestsLowSecurity(0) , mSubRequestsBrokenSecurity(0) , mSubRequestsNoSecurity(0) #ifdef DEBUG , mOnStateLocationChangeReentranceDetection(0) #endif { + mMonitor = nsAutoMonitor::NewMonitor("security.secureBrowserUIImplMonitor"); mTransferringRequests.ops = nsnull; ResetStateTracking(); #if defined(PR_LOGGING) if (!gSecureDocLog) gSecureDocLog = PR_NewLogModule("nsSecureBrowserUI"); #endif /* PR_LOGGING */ } nsSecureBrowserUIImpl::~nsSecureBrowserUIImpl() { if (mTransferringRequests.ops) { PL_DHashTableFinish(&mTransferringRequests); mTransferringRequests.ops = nsnull; } + if (mMonitor) + nsAutoMonitor::DestroyMonitor(mMonitor); } NS_IMPL_THREADSAFE_ISUPPORTS6(nsSecureBrowserUIImpl, nsISecureBrowserUI, nsIWebProgressListener, nsIFormSubmitObserver, nsIObserver, nsISupportsWeakReference, @@ -272,17 +273,17 @@ nsSecureBrowserUIImpl::Init(nsIDOMWindow return NS_OK; } NS_IMETHODIMP nsSecureBrowserUIImpl::GetState(PRUint32* aState) { - MonitorAutoEnter lock(mMonitor); + nsAutoMonitor lock(mMonitor); return MapInternalToExternalState(aState, mNotifiedSecurityState, mNotifiedToplevelIsEV); } // static already_AddRefed<nsISupports> nsSecureBrowserUIImpl::ExtractSecurityInfo(nsIRequest* aRequest) { nsISupports *retval = nsnull; @@ -336,17 +337,17 @@ nsSecureBrowserUIImpl::MapInternalToExte NS_IMETHODIMP nsSecureBrowserUIImpl::GetTooltipText(nsAString& aText) { lockIconState state; nsXPIDLString tooltip; { - MonitorAutoEnter lock(mMonitor); + nsAutoMonitor lock(mMonitor); state = mNotifiedSecurityState; tooltip = mInfoTooltip; } if (state == lis_mixed_security) { GetBundleString(NS_LITERAL_STRING("SecurityButtonMixedContentTooltipText").get(), aText); @@ -455,17 +456,17 @@ nsSecureBrowserUIImpl::Notify(nsIDOMHTML { NS_WARNING("If you see this and can explain why it should be allowed, note in Bug 332324"); *cancelSubmit = PR_TRUE; return NS_OK; } nsCOMPtr<nsIDOMWindow> window; { - MonitorAutoEnter lock(mMonitor); + nsAutoMonitor lock(mMonitor); window = do_QueryReferent(mWindow); NS_ASSERTION(window, "Window has gone away?!"); } PRBool isChild; IsChildOfDomWindow(window, postingWindow, &isChild); // This notify call is not for our window, ignore it. @@ -491,17 +492,17 @@ nsSecureBrowserUIImpl::OnProgressChange( PRInt32 aMaxTotalProgress) { NS_NOTREACHED("notification excluded in AddProgressListener(...)"); return NS_OK; } void nsSecureBrowserUIImpl::ResetStateTracking() { - MonitorAutoEnter lock(mMonitor); + nsAutoMonitor lock(mMonitor); mInfoTooltip.Truncate(); mDocumentRequestsInProgress = 0; if (mTransferringRequests.ops) { PL_DHashTableFinish(&mTransferringRequests); mTransferringRequests.ops = nsnull; } PL_DHashTableInit(&mTransferringRequests, &gMapOps, nsnull, @@ -553,17 +554,17 @@ nsSecureBrowserUIImpl::EvaluateAndUpdate } } } // assume temp_NewToplevelSecurityState was set in this scope! // see code that is directly above { - MonitorAutoEnter lock(mMonitor); + nsAutoMonitor lock(mMonitor); mNewToplevelSecurityStateKnown = PR_TRUE; mNewToplevelSecurityState = temp_NewToplevelSecurityState; mNewToplevelIsEV = temp_NewToplevelIsEV; if (updateStatus) { mSSLStatus = temp_SSLStatus; } if (updateTooltip) { mInfoTooltip = temp_InfoTooltip; @@ -586,17 +587,17 @@ nsSecureBrowserUIImpl::EvaluateAndUpdate void nsSecureBrowserUIImpl::UpdateSubrequestMembers(nsISupports *securityInfo) { // For wyciwyg channels in subdocuments we only update our // subrequest state members. PRUint32 reqState = GetSecurityStateFromSecurityInfo(securityInfo); // the code above this line should run without a lock - MonitorAutoEnter lock(mMonitor); + nsAutoMonitor lock(mMonitor); if (reqState & STATE_IS_SECURE) { if (reqState & STATE_SECURE_LOW || reqState & STATE_SECURE_MED) { PR_LOG(gSecureDocLog, PR_LOG_DEBUG, ("SecureUI:%p: OnStateChange: subreq LOW\n", this)); ++mSubRequestsLowSecurity; } else { PR_LOG(gSecureDocLog, PR_LOG_DEBUG, @@ -719,29 +720,29 @@ nsSecureBrowserUIImpl::OnStateChange(nsI aWebProgress->GetDOMWindow(getter_AddRefs(windowForProgress)); nsCOMPtr<nsIDOMWindow> window; PRBool isViewSource; nsCOMPtr<nsINetUtil> ioService; { - MonitorAutoEnter lock(mMonitor); + nsAutoMonitor lock(mMonitor); window = do_QueryReferent(mWindow); NS_ASSERTION(window, "Window has gone away?!"); isViewSource = mIsViewSource; ioService = mIOService; } if (!ioService) { ioService = do_GetService(NS_IOSERVICE_CONTRACTID); if (ioService) { - MonitorAutoEnter lock(mMonitor); + nsAutoMonitor lock(mMonitor); mIOService = ioService; } } PRBool isNoContentResponse = PR_FALSE; nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aRequest); if (httpChannel) { @@ -1008,30 +1009,30 @@ nsSecureBrowserUIImpl::OnStateChange(nsI if (aProgressStateFlags & STATE_TRANSFERRING && aProgressStateFlags & STATE_IS_REQUEST) { // The listing of a request in mTransferringRequests // means, there has already been data transfered. - MonitorAutoEnter lock(mMonitor); + nsAutoMonitor lock(mMonitor); PL_DHashTableOperate(&mTransferringRequests, aRequest, PL_DHASH_ADD); return NS_OK; } PRBool requestHasTransferedData = PR_FALSE; if (aProgressStateFlags & STATE_STOP && aProgressStateFlags & STATE_IS_REQUEST) { - { /* scope for the MonitorAutoEnter */ - MonitorAutoEnter lock(mMonitor); + { /* scope for the nsAutoMonitor */ + nsAutoMonitor lock(mMonitor); PLDHashEntryHdr *entry = PL_DHashTableOperate(&mTransferringRequests, aRequest, PL_DHASH_LOOKUP); if (PL_DHASH_ENTRY_IS_BUSY(entry)) { PL_DHashTableOperate(&mTransferringRequests, aRequest, PL_DHASH_REMOVE); requestHasTransferedData = PR_TRUE; } } @@ -1079,17 +1080,17 @@ nsSecureBrowserUIImpl::OnStateChange(nsI nsCOMPtr<nsIAssociatedContentSecurity> prevContentSecurity; PRInt32 newSubHigh = 0; PRInt32 newSubLow = 0; PRInt32 newSubBroken = 0; PRInt32 newSubNo = 0; { - MonitorAutoEnter lock(mMonitor); + nsAutoMonitor lock(mMonitor); inProgress = (mDocumentRequestsInProgress!=0); if (allowSecurityStateChange && !inProgress) { saveSubHigh = mSubRequestsHighSecurity; saveSubLow = mSubRequestsLowSecurity; saveSubBroken = mSubRequestsBrokenSecurity; saveSubNo = mSubRequestsNoSecurity; @@ -1149,17 +1150,17 @@ nsSecureBrowserUIImpl::OnStateChange(nsI newContentSecurity->GetCountSubRequestsLowSecurity(&newSubLow); newContentSecurity->GetCountSubRequestsBrokenSecurity(&newSubBroken); newContentSecurity->GetCountSubRequestsNoSecurity(&newSubNo); } } } { - MonitorAutoEnter lock(mMonitor); + nsAutoMonitor lock(mMonitor); if (allowSecurityStateChange && !inProgress) { ResetStateTracking(); mSubRequestsHighSecurity = newSubHigh; mSubRequestsLowSecurity = newSubLow; mSubRequestsBrokenSecurity = newSubBroken; mSubRequestsNoSecurity = newSubNo; @@ -1185,17 +1186,17 @@ nsSecureBrowserUIImpl::OnStateChange(nsI isToplevelProgress && loadFlags & nsIChannel::LOAD_DOCUMENT_URI) { PRInt32 temp_DocumentRequestsInProgress; nsCOMPtr<nsISecurityEventSink> temp_ToplevelEventSink; { - MonitorAutoEnter lock(mMonitor); + nsAutoMonitor lock(mMonitor); temp_DocumentRequestsInProgress = mDocumentRequestsInProgress; if (allowSecurityStateChange) { temp_ToplevelEventSink = mToplevelEventSink; } } if (temp_DocumentRequestsInProgress <= 0) @@ -1213,17 +1214,17 @@ nsSecureBrowserUIImpl::OnStateChange(nsI { if (allowSecurityStateChange) { ObtainEventSink(channel, temp_ToplevelEventSink); } } { - MonitorAutoEnter lock(mMonitor); + nsAutoMonitor lock(mMonitor); if (allowSecurityStateChange) { mToplevelEventSink = temp_ToplevelEventSink; } --mDocumentRequestsInProgress; } if (allowSecurityStateChange && requestHasTransferedData) { @@ -1258,17 +1259,17 @@ nsSecureBrowserUIImpl::OnStateChange(nsI // At this point, we are learning about the security state of a sub-document. // We must not update the security state based on the sub content, // if the new top level state is not yet known. // // We skip updating the security state in this case. PRBool temp_NewToplevelSecurityStateKnown; { - MonitorAutoEnter lock(mMonitor); + nsAutoMonitor lock(mMonitor); temp_NewToplevelSecurityStateKnown = mNewToplevelSecurityStateKnown; } if (temp_NewToplevelSecurityStateKnown) return UpdateSecurityState(aRequest, PR_FALSE, PR_FALSE, PR_FALSE); } return NS_OK; @@ -1304,17 +1305,17 @@ nsresult nsSecureBrowserUIImpl::UpdateSe return rv; } // must not fail, by definition, only trivial assignments // or string operations are allowed // returns true if our overall state has changed and we must send out notifications PRBool nsSecureBrowserUIImpl::UpdateMyFlags(PRBool &showWarning, lockIconState &warnSecurityState) { - MonitorAutoEnter lock(mMonitor); + nsAutoMonitor lock(mMonitor); PRBool mustTellTheWorld = PR_FALSE; lockIconState newSecurityState; if (mNewToplevelSecurityState & STATE_IS_SECURE) { if (mNewToplevelSecurityState & STATE_SECURE_LOW || @@ -1454,17 +1455,17 @@ nsresult nsSecureBrowserUIImpl::TellTheW lockIconState warnSecurityState, nsIRequest* aRequest) { nsCOMPtr<nsISecurityEventSink> temp_ToplevelEventSink; lockIconState temp_NotifiedSecurityState; PRBool temp_NotifiedToplevelIsEV; { - MonitorAutoEnter lock(mMonitor); + nsAutoMonitor lock(mMonitor); temp_ToplevelEventSink = mToplevelEventSink; temp_NotifiedSecurityState = mNotifiedSecurityState; temp_NotifiedToplevelIsEV = mNotifiedToplevelIsEV; } if (temp_ToplevelEventSink) { PRUint32 newState = STATE_IS_INSECURE; @@ -1541,17 +1542,17 @@ nsSecureBrowserUIImpl::OnLocationChange( ("SecureUI:%p: OnLocationChange: view-source\n", this)); } updateIsViewSource = PR_TRUE; temp_IsViewSource = vs; } { - MonitorAutoEnter lock(mMonitor); + nsAutoMonitor lock(mMonitor); if (updateIsViewSource) { mIsViewSource = temp_IsViewSource; } mCurrentURI = aLocation; window = do_QueryReferent(mWindow); NS_ASSERTION(window, "Window has gone away?!"); } @@ -1589,17 +1590,17 @@ nsSecureBrowserUIImpl::OnLocationChange( // At this point, we are learning about the security state of a sub-document. // We must not update the security state based on the sub content, if the new // top level state is not yet known. // // We skip updating the security state in this case. PRBool temp_NewToplevelSecurityStateKnown; { - MonitorAutoEnter lock(mMonitor); + nsAutoMonitor lock(mMonitor); temp_NewToplevelSecurityStateKnown = mNewToplevelSecurityStateKnown; } if (temp_NewToplevelSecurityStateKnown) return UpdateSecurityState(aRequest, PR_TRUE, PR_FALSE, PR_FALSE); return NS_OK; } @@ -1640,17 +1641,17 @@ nsSecureBrowserUIImpl::OnSecurityChange( } // nsISSLStatusProvider methods NS_IMETHODIMP nsSecureBrowserUIImpl::GetSSLStatus(nsISupports** _result) { NS_ENSURE_ARG_POINTER(_result); - MonitorAutoEnter lock(mMonitor); + nsAutoMonitor lock(mMonitor); switch (mNotifiedSecurityState) { case lis_mixed_security: case lis_low_security: case lis_high_security: break; @@ -1692,17 +1693,17 @@ nsSecureBrowserUIImpl::IsURLJavaScript(n void nsSecureBrowserUIImpl::GetBundleString(const PRUnichar* name, nsAString &outString) { nsCOMPtr<nsIStringBundle> temp_StringBundle; { - MonitorAutoEnter lock(mMonitor); + nsAutoMonitor lock(mMonitor); temp_StringBundle = mStringBundle; } if (temp_StringBundle && name) { PRUnichar *ptrv = nsnull; if (NS_SUCCEEDED(temp_StringBundle->GetStringFromName(name, &ptrv))) outString = ptrv; @@ -1836,17 +1837,17 @@ ConfirmEnteringSecure() { nsCOMPtr<nsISecurityWarningDialogs> dialogs; GetNSSDialogs(getter_AddRefs(dialogs)); if (!dialogs) return PR_FALSE; // Should this allow PR_TRUE for unimplemented? nsCOMPtr<nsIDOMWindow> window; { - MonitorAutoEnter lock(mMonitor); + nsAutoMonitor lock(mMonitor); window = do_QueryReferent(mWindow); NS_ASSERTION(window, "Window has gone away?!"); } nsCOMPtr<nsIInterfaceRequestor> ctx = new nsUIContext(window); PRBool confirms; dialogs->ConfirmEnteringSecure(ctx, &confirms); @@ -1859,17 +1860,17 @@ ConfirmEnteringWeak() { nsCOMPtr<nsISecurityWarningDialogs> dialogs; GetNSSDialogs(getter_AddRefs(dialogs)); if (!dialogs) return PR_FALSE; // Should this allow PR_TRUE for unimplemented? nsCOMPtr<nsIDOMWindow> window; { - MonitorAutoEnter lock(mMonitor); + nsAutoMonitor lock(mMonitor); window = do_QueryReferent(mWindow); NS_ASSERTION(window, "Window has gone away?!"); } nsCOMPtr<nsIInterfaceRequestor> ctx = new nsUIContext(window); PRBool confirms; dialogs->ConfirmEnteringWeak(ctx, &confirms); @@ -1882,17 +1883,17 @@ ConfirmLeavingSecure() { nsCOMPtr<nsISecurityWarningDialogs> dialogs; GetNSSDialogs(getter_AddRefs(dialogs)); if (!dialogs) return PR_FALSE; // Should this allow PR_TRUE for unimplemented? nsCOMPtr<nsIDOMWindow> window; { - MonitorAutoEnter lock(mMonitor); + nsAutoMonitor lock(mMonitor); window = do_QueryReferent(mWindow); NS_ASSERTION(window, "Window has gone away?!"); } nsCOMPtr<nsIInterfaceRequestor> ctx = new nsUIContext(window); PRBool confirms; dialogs->ConfirmLeavingSecure(ctx, &confirms); @@ -1905,17 +1906,17 @@ ConfirmMixedMode() { nsCOMPtr<nsISecurityWarningDialogs> dialogs; GetNSSDialogs(getter_AddRefs(dialogs)); if (!dialogs) return PR_FALSE; // Should this allow PR_TRUE for unimplemented? nsCOMPtr<nsIDOMWindow> window; { - MonitorAutoEnter lock(mMonitor); + nsAutoMonitor lock(mMonitor); window = do_QueryReferent(mWindow); NS_ASSERTION(window, "Window has gone away?!"); } nsCOMPtr<nsIInterfaceRequestor> ctx = new nsUIContext(window); PRBool confirms; dialogs->ConfirmMixedMode(ctx, &confirms); @@ -1935,17 +1936,17 @@ ConfirmPostToInsecure() nsCOMPtr<nsISecurityWarningDialogs> dialogs; GetNSSDialogs(getter_AddRefs(dialogs)); if (!dialogs) return PR_FALSE; // Should this allow PR_TRUE for unimplemented? nsCOMPtr<nsIDOMWindow> window; { - MonitorAutoEnter lock(mMonitor); + nsAutoMonitor lock(mMonitor); window = do_QueryReferent(mWindow); NS_ASSERTION(window, "Window has gone away?!"); } nsCOMPtr<nsIInterfaceRequestor> ctx = new nsUIContext(window); PRBool result; @@ -1967,17 +1968,17 @@ ConfirmPostToInsecureFromSecure() nsCOMPtr<nsISecurityWarningDialogs> dialogs; GetNSSDialogs(getter_AddRefs(dialogs)); if (!dialogs) return PR_FALSE; // Should this allow PR_TRUE for unimplemented? nsCOMPtr<nsIDOMWindow> window; { - MonitorAutoEnter lock(mMonitor); + nsAutoMonitor lock(mMonitor); window = do_QueryReferent(mWindow); NS_ASSERTION(window, "Window has gone away?!"); } nsCOMPtr<nsIInterfaceRequestor> ctx = new nsUIContext(window); PRBool result;
--- a/security/manager/boot/src/nsSecureBrowserUIImpl.h +++ b/security/manager/boot/src/nsSecureBrowserUIImpl.h @@ -37,17 +37,16 @@ * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #ifndef nsSecureBrowserUIImpl_h_ #define nsSecureBrowserUIImpl_h_ -#include "mozilla/Monitor.h" #include "nsCOMPtr.h" #include "nsXPIDLString.h" #include "nsString.h" #include "nsIObserver.h" #include "nsIDOMElement.h" #include "nsIDOMWindow.h" #include "nsIDOMHTMLFormElement.h" #include "nsIStringBundle.h" @@ -56,16 +55,17 @@ #include "nsIWebProgressListener.h" #include "nsIFormSubmitObserver.h" #include "nsIURI.h" #include "nsISecurityEventSink.h" #include "nsWeakReference.h" #include "nsISSLStatusProvider.h" #include "nsIAssociatedContentSecurity.h" #include "pldhash.h" +#include "prmon.h" #include "nsINetUtil.h" class nsITransportSecurityInfo; class nsISecurityWarningDialogs; class nsIChannel; #define NS_SECURE_BROWSER_UI_CID \ { 0xcc75499a, 0x1dd1, 0x11b2, {0x8a, 0x82, 0xca, 0x41, 0x0a, 0xc9, 0x07, 0xb8}} @@ -92,17 +92,17 @@ public: NS_DECL_NSISSLSTATUSPROVIDER NS_IMETHOD Notify(nsIDOMHTMLFormElement* formNode, nsIDOMWindowInternal* window, nsIURI *actionURL, PRBool* cancelSubmit); NS_IMETHOD NotifyInvalidSubmit(nsIDOMHTMLFormElement* formNode, nsIArray* invalidElements) { return NS_OK; }; protected: - mozilla::Monitor mMonitor; + PRMonitor *mMonitor; nsWeakPtr mWindow; nsCOMPtr<nsINetUtil> mIOService; nsCOMPtr<nsIStringBundle> mStringBundle; nsCOMPtr<nsIURI> mCurrentURI; nsCOMPtr<nsISecurityEventSink> mToplevelEventSink; enum lockIconState {
--- a/security/manager/ssl/src/nsCertOverrideService.cpp +++ b/security/manager/ssl/src/nsCertOverrideService.cpp @@ -47,28 +47,27 @@ #include "nsNetUtil.h" #include "nsILineInputStream.h" #include "nsIObserver.h" #include "nsIObserverService.h" #include "nsISupportsPrimitives.h" #include "nsPromiseFlatString.h" #include "nsProxiedService.h" #include "nsStringBuffer.h" +#include "nsAutoLock.h" #include "nsAutoPtr.h" #include "nspr.h" #include "pk11pub.h" #include "certdb.h" #include "sechash.h" #include "ssl.h" // For SSL_ClearSessionCache #include "nsNSSCleaner.h" NSSCleanupAutoPtrClass(CERTCertificate, CERT_DestroyCertificate) -using namespace mozilla; - static const char kCertOverrideFileName[] = "cert_override.txt"; void nsCertOverride::convertBitsToString(OverrideBits ob, nsACString &str) { str.Truncate(); if (ob & ob_Mismatch) @@ -115,22 +114,24 @@ nsCertOverride::convertStringToBits(cons } NS_IMPL_THREADSAFE_ISUPPORTS3(nsCertOverrideService, nsICertOverrideService, nsIObserver, nsISupportsWeakReference) nsCertOverrideService::nsCertOverrideService() - : monitor("nsCertOverrideService.monitor") { + monitor = nsAutoMonitor::NewMonitor("security.certOverrideServiceMonitor"); } nsCertOverrideService::~nsCertOverrideService() { + if (monitor) + nsAutoMonitor::DestroyMonitor(monitor); } nsresult nsCertOverrideService::Init() { if (!mSettingsTable.Init()) return NS_ERROR_OUT_OF_MEMORY; @@ -174,50 +175,50 @@ nsCertOverrideService::Observe(nsISuppor const char *aTopic, const PRUnichar *aData) { // check the topic if (!nsCRT::strcmp(aTopic, "profile-before-change")) { // The profile is about to change, // or is going away because the application is shutting down. - MonitorAutoEnter lock(monitor); + nsAutoMonitor lock(monitor); if (!nsCRT::strcmp(aData, NS_LITERAL_STRING("shutdown-cleanse").get())) { RemoveAllFromMemory(); // delete the storage file if (mSettingsFile) { mSettingsFile->Remove(PR_FALSE); } } else { RemoveAllFromMemory(); } } else if (!nsCRT::strcmp(aTopic, "profile-do-change")) { // The profile has already changed. // Now read from the new profile location. // we also need to update the cached file location - MonitorAutoEnter lock(monitor); + nsAutoMonitor lock(monitor); nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(mSettingsFile)); if (NS_SUCCEEDED(rv)) { mSettingsFile->AppendNative(NS_LITERAL_CSTRING(kCertOverrideFileName)); } Read(); } return NS_OK; } void nsCertOverrideService::RemoveAllFromMemory() { - MonitorAutoEnter lock(monitor); + nsAutoMonitor lock(monitor); mSettingsTable.Clear(); } PR_STATIC_CALLBACK(PLDHashOperator) RemoveTemporariesCallback(nsCertOverrideEntry *aEntry, void *aArg) { if (aEntry && aEntry->mSettings.mIsTemporary) { @@ -227,26 +228,26 @@ RemoveTemporariesCallback(nsCertOverride return PL_DHASH_NEXT; } void nsCertOverrideService::RemoveAllTemporaryOverrides() { { - MonitorAutoEnter lock(monitor); + nsAutoMonitor lock(monitor); mSettingsTable.EnumerateEntries(RemoveTemporariesCallback, nsnull); // no need to write, as temporaries are never written to disk } } nsresult nsCertOverrideService::Read() { - MonitorAutoEnter lock(monitor); + nsAutoMonitor lock(monitor); nsresult rv; nsCOMPtr<nsIInputStream> fileInputStream; rv = NS_NewLocalFileInputStream(getter_AddRefs(fileInputStream), mSettingsFile); if (NS_FAILED(rv)) { return rv; } @@ -355,17 +356,17 @@ WriteEntryCallback(nsCertOverrideEntry * } return PL_DHASH_NEXT; } nsresult nsCertOverrideService::Write() { - MonitorAutoEnter lock(monitor); + nsAutoMonitor lock(monitor); if (!mSettingsFile) { return NS_ERROR_NULL_POINTER; } nsresult rv; nsCOMPtr<nsIOutputStream> fileOutputStream; rv = NS_NewSafeLocalFileOutputStream(getter_AddRefs(fileOutputStream), @@ -549,17 +550,17 @@ nsCertOverrideService::RememberValidityO ++dbkey_walk) { char c = *dbkey_walk; if (c == '\r' || c == '\n') { *dbkey_walk = ' '; } } { - MonitorAutoEnter lock(monitor); + nsAutoMonitor lock(monitor); AddEntryToList(aHostName, aPort, aTemporary ? aCert : nsnull, // keep a reference to the cert for temporary overrides aTemporary, mDottedOidForStoringNewHashes, fpStr, (nsCertOverride::OverrideBits)aOverrideBits, nsDependentCString(dbkey)); Write(); @@ -588,17 +589,17 @@ nsCertOverrideService::HasMatchingOverri *_retval = PR_FALSE; *aOverrideBits = nsCertOverride::ob_None; nsCAutoString hostPort; GetHostWithPort(aHostName, aPort, hostPort); nsCertOverride settings; { - MonitorAutoEnter lock(monitor); + nsAutoMonitor lock(monitor); nsCertOverrideEntry *entry = mSettingsTable.GetEntry(hostPort.get()); if (!entry) return NS_OK; settings = entry->mSettings; // copy } @@ -635,17 +636,17 @@ nsCertOverrideService::GetValidityOverri *_found = PR_FALSE; *aOverrideBits = nsCertOverride::ob_None; nsCAutoString hostPort; GetHostWithPort(aHostName, aPort, hostPort); nsCertOverride settings; { - MonitorAutoEnter lock(monitor); + nsAutoMonitor lock(monitor); nsCertOverrideEntry *entry = mSettingsTable.GetEntry(hostPort.get()); if (entry) { *_found = PR_TRUE; settings = entry->mSettings; // copy } } @@ -667,17 +668,17 @@ nsCertOverrideService::AddEntryToList(co const nsACString &fingerprint, nsCertOverride::OverrideBits ob, const nsACString &dbKey) { nsCAutoString hostPort; GetHostWithPort(aHostName, aPort, hostPort); { - MonitorAutoEnter lock(monitor); + nsAutoMonitor lock(monitor); nsCertOverrideEntry *entry = mSettingsTable.PutEntry(hostPort.get()); if (!entry) { NS_ERROR("can't insert a null entry!"); return NS_ERROR_OUT_OF_MEMORY; } entry->mHostWithPort = hostPort; @@ -702,17 +703,17 @@ nsCertOverrideService::ClearValidityOver if (aPort == 0 && aHostName.EqualsLiteral("all:temporary-certificates")) { RemoveAllTemporaryOverrides(); return NS_OK; } nsCAutoString hostPort; GetHostWithPort(aHostName, aPort, hostPort); { - MonitorAutoEnter lock(monitor); + nsAutoMonitor lock(monitor); mSettingsTable.RemoveEntry(hostPort.get()); Write(); } SSL_ClearSessionCache(); return NS_OK; } NS_IMETHODIMP @@ -832,17 +833,17 @@ nsCertOverrideService::IsCertUsedForOver cai.cert = aCert; cai.aCheckTemporaries = aCheckTemporaries; cai.aCheckPermanents = aCheckPermanents; cai.counter = 0; cai.mOidTagForStoringNewHashes = mOidTagForStoringNewHashes; cai.mDottedOidForStoringNewHashes = mDottedOidForStoringNewHashes; { - MonitorAutoEnter lock(monitor); + nsAutoMonitor lock(monitor); mSettingsTable.EnumerateEntries(FindMatchingCertCallback, &cai); } *_retval = cai.counter; return NS_OK; } struct nsCertAndPointerAndCallback { @@ -898,17 +899,17 @@ nsCertOverrideService::EnumerateCertOver nsCertAndPointerAndCallback capac; capac.cert = aCert; capac.userdata = aUserData; capac.enumerator = enumerator; capac.mOidTagForStoringNewHashes = mOidTagForStoringNewHashes; capac.mDottedOidForStoringNewHashes = mDottedOidForStoringNewHashes; { - MonitorAutoEnter lock(monitor); + nsAutoMonitor lock(monitor); mSettingsTable.EnumerateEntries(EnumerateCertOverridesCallback, &capac); } return NS_OK; } void nsCertOverrideService::GetHostWithPort(const nsACString & aHostName, PRInt32 aPort, nsACString& _retval) {
--- a/security/manager/ssl/src/nsCertOverrideService.h +++ b/security/manager/ssl/src/nsCertOverrideService.h @@ -36,22 +36,22 @@ * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #ifndef __NSCERTOVERRIDESERVICE_H__ #define __NSCERTOVERRIDESERVICE_H__ -#include "mozilla/Monitor.h" #include "nsICertOverrideService.h" #include "nsTHashtable.h" #include "nsIObserver.h" #include "nsString.h" #include "nsIFile.h" +#include "prmon.h" #include "secoidt.h" #include "nsWeakReference.h" class nsCertOverride { public: enum OverrideBits { ob_None=0, ob_Untrusted=1, ob_Mismatch=2, @@ -185,17 +185,17 @@ public: void *aUserData); // Concates host name and the port number. If the port number is -1 then // port 443 is automatically used. This method ensures there is always a port // number separated with colon. static void GetHostWithPort(const nsACString & aHostName, PRInt32 aPort, nsACString& _retval); protected: - mozilla::Monitor monitor; + PRMonitor *monitor; nsCOMPtr<nsIFile> mSettingsFile; nsTHashtable<nsCertOverrideEntry> mSettingsTable; SECOidTag mOidTagForStoringNewHashes; nsCString mDottedOidForStoringNewHashes; void RemoveAllFromMemory(); nsresult Read();
--- a/security/manager/ssl/src/nsCertVerificationThread.cpp +++ b/security/manager/ssl/src/nsCertVerificationThread.cpp @@ -31,21 +31,20 @@ * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #include "nsMemory.h" +#include "nsAutoLock.h" #include "nsAutoPtr.h" #include "nsCertVerificationThread.h" -using namespace mozilla; - nsCertVerificationThread *nsCertVerificationThread::verification_thread_singleton; NS_IMPL_THREADSAFE_ISUPPORTS1(nsCertVerificationResult, nsICertVerificationResult) void nsCertVerificationJob::Run() { if (!mListener || !mCert) return; @@ -111,54 +110,54 @@ nsCertVerificationThread::~nsCertVerific nsresult nsCertVerificationThread::addJob(nsBaseVerificationJob *aJob) { if (!aJob || !verification_thread_singleton) return NS_ERROR_FAILURE; if (!verification_thread_singleton->mThreadHandle) return NS_ERROR_OUT_OF_MEMORY; - MutexAutoLock threadLock(verification_thread_singleton->mMutex); + nsAutoLock threadLock(verification_thread_singleton->mMutex); verification_thread_singleton->mJobQ.Push(aJob); - verification_thread_singleton->mCond.NotifyAll(); + PR_NotifyAllCondVar(verification_thread_singleton->mCond); return NS_OK; } void nsCertVerificationThread::Run(void) { while (PR_TRUE) { nsBaseVerificationJob *job = nsnull; { - MutexAutoLock threadLock(verification_thread_singleton->mMutex); + nsAutoLock threadLock(verification_thread_singleton->mMutex); while (!mExitRequested && (0 == verification_thread_singleton->mJobQ.GetSize())) { // no work to do ? let's wait a moment - mCond.Wait(); + PR_WaitCondVar(mCond, PR_INTERVAL_NO_TIMEOUT); } if (mExitRequested) break; job = static_cast<nsBaseVerificationJob*>(mJobQ.PopFront()); } if (job) { job->Run(); delete job; } } { - MutexAutoLock threadLock(verification_thread_singleton->mMutex); + nsAutoLock threadLock(verification_thread_singleton->mMutex); while (verification_thread_singleton->mJobQ.GetSize()) { nsCertVerificationJob *job = static_cast<nsCertVerificationJob*>(mJobQ.PopFront()); delete job; } } }
--- a/security/manager/ssl/src/nsClientAuthRemember.cpp +++ b/security/manager/ssl/src/nsClientAuthRemember.cpp @@ -43,40 +43,40 @@ #include "nsCRT.h" #include "nsNetUtil.h" #include "nsIObserverService.h" #include "nsNetUtil.h" #include "nsISupportsPrimitives.h" #include "nsPromiseFlatString.h" #include "nsProxiedService.h" #include "nsStringBuffer.h" +#include "nsAutoLock.h" #include "nspr.h" #include "pk11pub.h" #include "certdb.h" #include "sechash.h" #include "ssl.h" // For SSL_ClearSessionCache #include "nsNSSCleaner.h" - -using namespace mozilla; - NSSCleanupAutoPtrClass(CERTCertificate, CERT_DestroyCertificate) NS_IMPL_THREADSAFE_ISUPPORTS2(nsClientAuthRememberService, nsIObserver, nsISupportsWeakReference) nsClientAuthRememberService::nsClientAuthRememberService() - : monitor("nsClientAuthRememberService.monitor") { + monitor = nsAutoMonitor::NewMonitor("security.clientAuthRememberServiceMonitor"); } nsClientAuthRememberService::~nsClientAuthRememberService() { RemoveAllFromMemory(); + if (monitor) + nsAutoMonitor::DestroyMonitor(monitor); } nsresult nsClientAuthRememberService::Init() { if (!mSettingsTable.Init()) return NS_ERROR_OUT_OF_MEMORY; @@ -105,26 +105,26 @@ nsClientAuthRememberService::Observe(nsI const char *aTopic, const PRUnichar *aData) { // check the topic if (!nsCRT::strcmp(aTopic, "profile-before-change")) { // The profile is about to change, // or is going away because the application is shutting down. - MonitorAutoEnter lock(monitor); + nsAutoMonitor lock(monitor); RemoveAllFromMemory(); } return NS_OK; } void nsClientAuthRememberService::ClearRememberedDecisions() { - MonitorAutoEnter lock(monitor); + nsAutoMonitor lock(monitor); RemoveAllFromMemory(); } void nsClientAuthRememberService::RemoveAllFromMemory() { mSettingsTable.Clear(); } @@ -160,17 +160,17 @@ nsClientAuthRememberService::RememberDec return NS_ERROR_INVALID_ARG; nsCAutoString fpStr; nsresult rv = GetCertFingerprintByOidTag(aServerCert, SEC_OID_SHA256, fpStr); if (NS_FAILED(rv)) return rv; { - MonitorAutoEnter lock(monitor); + nsAutoMonitor lock(monitor); if (aClientCert) { nsNSSCertificate pipCert(aClientCert); char *dbkey = NULL; rv = pipCert.GetDbKey(&dbkey); if (NS_SUCCEEDED(rv) && dbkey) { AddEntryToList(aHostName, fpStr, nsDependentCString(dbkey)); } @@ -206,17 +206,17 @@ nsClientAuthRememberService::HasRemember if (NS_FAILED(rv)) return rv; nsCAutoString hostCert; GetHostWithCert(aHostName, fpStr, hostCert); nsClientAuthRemember settings; { - MonitorAutoEnter lock(monitor); + nsAutoMonitor lock(monitor); nsClientAuthRememberEntry *entry = mSettingsTable.GetEntry(hostCert.get()); if (!entry) return NS_OK; settings = entry->mSettings; // copy } aCertDBKey = settings.mDBKey; *_retval = PR_TRUE; @@ -228,17 +228,17 @@ nsClientAuthRememberService::AddEntryToL const nsACString &fingerprint, const nsACString &db_key) { nsCAutoString hostCert; GetHostWithCert(aHostName, fingerprint, hostCert); { - MonitorAutoEnter lock(monitor); + nsAutoMonitor lock(monitor); nsClientAuthRememberEntry *entry = mSettingsTable.PutEntry(hostCert.get()); if (!entry) { NS_ERROR("can't insert a null entry!"); return NS_ERROR_OUT_OF_MEMORY; } entry->mHostWithCert = hostCert;
--- a/security/manager/ssl/src/nsClientAuthRemember.h +++ b/security/manager/ssl/src/nsClientAuthRemember.h @@ -35,24 +35,24 @@ * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #ifndef __NSCLIENTAUTHREMEMBER_H__ #define __NSCLIENTAUTHREMEMBER_H__ -#include "mozilla/Monitor.h" #include "nsTHashtable.h" #include "nsIObserver.h" #include "nsIX509Cert.h" #include "nsAutoPtr.h" #include "nsNSSCertificate.h" #include "nsString.h" #include "nsWeakReference.h" +#include "prmon.h" class nsClientAuthRemember { public: nsClientAuthRemember() { } @@ -158,17 +158,17 @@ public: CERTCertificate *aServerCert, CERTCertificate *aClientCert); nsresult HasRememberedDecision(const nsACString & aHostName, CERTCertificate *aServerCert, nsACString & aCertDBKey, PRBool *_retval); void ClearRememberedDecisions(); protected: - mozilla::Monitor monitor; + PRMonitor *monitor; nsTHashtable<nsClientAuthRememberEntry> mSettingsTable; void RemoveAllFromMemory(); nsresult AddEntryToList(const nsACString &host, const nsACString &server_fingerprint, const nsACString &db_key); };
--- a/security/manager/ssl/src/nsKeygenThread.cpp +++ b/security/manager/ssl/src/nsKeygenThread.cpp @@ -39,81 +39,85 @@ #include "pk11func.h" #include "nsCOMPtr.h" #include "nsProxiedService.h" #include "nsThreadUtils.h" #include "nsKeygenThread.h" #include "nsIObserver.h" #include "nsNSSShutDown.h" -using namespace mozilla; - NS_IMPL_THREADSAFE_ISUPPORTS1(nsKeygenThread, nsIKeygenThread) nsKeygenThread::nsKeygenThread() -:mutex("nsKeygenThread.mutex"), +:mutex(nsnull), iAmRunning(PR_FALSE), keygenReady(PR_FALSE), statusDialogClosed(PR_FALSE), alreadyReceivedParams(PR_FALSE), privateKey(nsnull), publicKey(nsnull), slot(nsnull), keyGenMechanism(0), params(nsnull), isPerm(PR_FALSE), isSensitive(PR_FALSE), wincx(nsnull), threadHandle(nsnull) { + mutex = PR_NewLock(); } nsKeygenThread::~nsKeygenThread() { + if (mutex) { + PR_DestroyLock(mutex); + } } void nsKeygenThread::SetParams( PK11SlotInfo *a_slot, PRUint32 a_keyGenMechanism, void *a_params, PRBool a_isPerm, PRBool a_isSensitive, void *a_wincx ) { nsNSSShutDownPreventionLock locker; - MutexAutoLock lock(mutex); + PR_Lock(mutex); if (!alreadyReceivedParams) { alreadyReceivedParams = PR_TRUE; if (a_slot) { slot = PK11_ReferenceSlot(a_slot); } else { slot = nsnull; } keyGenMechanism = a_keyGenMechanism; params = a_params; isPerm = a_isPerm; isSensitive = a_isSensitive; wincx = a_wincx; } + + PR_Unlock(mutex); } nsresult nsKeygenThread::GetParams( SECKEYPrivateKey **a_privateKey, SECKEYPublicKey **a_publicKey) { if (!a_privateKey || !a_publicKey) { return NS_ERROR_FAILURE; } nsresult rv; - - MutexAutoLock lock(mutex); + + PR_Lock(mutex); // GetParams must not be called until thread creator called // Join on this thread. NS_ASSERTION(keygenReady, "logic error in nsKeygenThread::GetParams"); if (keygenReady) { *a_privateKey = privateKey; *a_publicKey = publicKey; @@ -122,105 +126,118 @@ nsresult nsKeygenThread::GetParams( publicKey = 0; rv = NS_OK; } else { rv = NS_ERROR_FAILURE; } + PR_Unlock(mutex); + return rv; } static void PR_CALLBACK nsKeygenThreadRunner(void *arg) { nsKeygenThread *self = static_cast<nsKeygenThread *>(arg); self->Run(); } nsresult nsKeygenThread::StartKeyGeneration(nsIObserver* aObserver) { + if (!mutex) + return NS_OK; + if (!aObserver) return NS_OK; nsCOMPtr<nsIObserver> obs; NS_GetProxyForObject( NS_PROXY_TO_MAIN_THREAD, NS_GET_IID(nsIObserver), aObserver, NS_PROXY_SYNC | NS_PROXY_ALWAYS, getter_AddRefs(obs)); - MutexAutoLock lock(mutex); + PR_Lock(mutex); if (iAmRunning || keygenReady) { + PR_Unlock(mutex); return NS_OK; } observer.swap(obs); iAmRunning = PR_TRUE; threadHandle = PR_CreateThread(PR_USER_THREAD, nsKeygenThreadRunner, static_cast<void*>(this), PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); // bool thread_started_ok = (threadHandle != nsnull); // we might want to return "thread started ok" to caller in the future NS_ASSERTION(threadHandle, "Could not create nsKeygenThreadRunner thread\n"); + + PR_Unlock(mutex); return NS_OK; } nsresult nsKeygenThread::UserCanceled(PRBool *threadAlreadyClosedDialog) { if (!threadAlreadyClosedDialog) return NS_OK; *threadAlreadyClosedDialog = PR_FALSE; - MutexAutoLock lock(mutex); + if (!mutex) + return NS_OK; + + PR_Lock(mutex); if (keygenReady) *threadAlreadyClosedDialog = statusDialogClosed; // User somehow closed the dialog, but we will not cancel. // Bad luck, we told him not do, and user still has to wait. // However, we remember that it's closed and will not close // it again to avoid problems. statusDialogClosed = PR_TRUE; + PR_Unlock(mutex); + return NS_OK; } void nsKeygenThread::Run(void) { nsNSSShutDownPreventionLock locker; PRBool canGenerate = PR_FALSE; - { - MutexAutoLock lock(mutex); + PR_Lock(mutex); + if (alreadyReceivedParams) { canGenerate = PR_TRUE; keygenReady = PR_FALSE; } - } + + PR_Unlock(mutex); if (canGenerate) privateKey = PK11_GenerateKeyPair(slot, keyGenMechanism, params, &publicKey, isPerm, isSensitive, wincx); // This call gave us ownership over privateKey and publicKey. // But as the params structure is owner by our caller, // we effectively transferred ownership to the caller. // As long as key generation can't be canceled, we don't need // to care for cleaning this up. nsCOMPtr<nsIObserver> obs; - { - MutexAutoLock lock(mutex); + PR_Lock(mutex); keygenReady = PR_TRUE; iAmRunning = PR_FALSE; // forget our parameters if (slot) { PK11_FreeSlot(slot); slot = 0; @@ -228,17 +245,18 @@ void nsKeygenThread::Run(void) keyGenMechanism = 0; params = 0; wincx = 0; if (!statusDialogClosed) obs = observer; observer = nsnull; - } + + PR_Unlock(mutex); if (obs) obs->Observe(nsnull, "keygen-finished", nsnull); } void nsKeygenThread::Join() { if (!threadHandle)
--- a/security/manager/ssl/src/nsKeygenThread.h +++ b/security/manager/ssl/src/nsKeygenThread.h @@ -37,26 +37,25 @@ * ***** END LICENSE BLOCK ***** */ #ifndef _NSKEYGENTHREAD_H_ #define _NSKEYGENTHREAD_H_ #include "keyhi.h" #include "nspr.h" -#include "mozilla/Mutex.h" #include "nsIKeygenThread.h" #include "nsCOMPtr.h" class nsIObserver; class nsKeygenThread : public nsIKeygenThread { private: - mozilla::Mutex mutex; + PRLock *mutex; nsCOMPtr<nsIObserver> observer; PRBool iAmRunning; PRBool keygenReady; PRBool statusDialogClosed; PRBool alreadyReceivedParams;
--- a/security/manager/ssl/src/nsNSSCallbacks.cpp +++ b/security/manager/ssl/src/nsNSSCallbacks.cpp @@ -59,30 +59,29 @@ #include "nsIInterfaceRequestorUtils.h" #include "nsProtectedAuthThread.h" #include "nsITokenDialogs.h" #include "nsCRT.h" #include "nsNSSShutDown.h" #include "nsIUploadChannel.h" #include "nsSSLThread.h" #include "nsThreadUtils.h" +#include "nsAutoLock.h" #include "nsIThread.h" #include "nsIWindowWatcher.h" #include "nsIPrompt.h" #include "nsProxyRelease.h" #include "nsIConsoleService.h" #include "ssl.h" #include "cert.h" #include "ocsp.h" #include "nssb64.h" #include "secerr.h" -using namespace mozilla; - static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID); NSSCleanupAutoPtrClass(CERTCertificate, CERT_DestroyCertificate) #ifdef PR_LOGGING extern PRLogModuleInfo* gPIPNSSLog; #endif class nsHTTPDownloadEvent : public nsRunnable { @@ -368,18 +367,21 @@ nsNSSHttpRequestSession::internal_send_r { acceptableResultSize = *http_response_data_len; *http_response_data_len = 0; } if (!mListener) return SECFailure; - Mutex& waitLock = mListener->mLock; - CondVar& waitCondition = mListener->mCondition; + if (NS_FAILED(mListener->InitLocks())) + return SECFailure; + + PRLock *waitLock = mListener->mLock; + PRCondVar *waitCondition = mListener->mCondition; volatile PRBool &waitFlag = mListener->mWaitFlag; waitFlag = PR_TRUE; nsRefPtr<nsHTTPDownloadEvent> event = new nsHTTPDownloadEvent; if (!event) return SECFailure; event->mListener = mListener; @@ -391,17 +393,17 @@ nsNSSHttpRequestSession::internal_send_r { event->mResponsibleForDoneSignal = PR_FALSE; return SECFailure; } PRBool request_canceled = PR_FALSE; { - MutexAutoLock locker(waitLock); + nsAutoLock locker(waitLock); const PRIntervalTime start_time = PR_IntervalNow(); PRIntervalTime wait_interval; PRBool running_on_main_thread = NS_IsMainThread(); if (running_on_main_thread) { // let's process events quickly @@ -419,21 +421,22 @@ nsNSSHttpRequestSession::internal_send_r if (running_on_main_thread) { // Networking runs on the main thread, which we happen to block here. // Processing events will allow the OCSP networking to run while we // are waiting. Thanks a lot to Darin Fisher for rewriting the // thread manager. Thanks a lot to Christian Biesinger who // made me aware of this possibility. (kaie) - MutexAutoUnlock unlock(waitLock); + locker.unlock(); NS_ProcessNextEvent(nsnull); + locker.lock(); } - waitCondition.Wait(wait_interval); + PR_WaitCondVar(waitCondition, wait_interval); if (!waitFlag) break; if (!request_canceled) { PRBool wantExit = nsSSLThread::exitRequested(); PRBool timeout = @@ -549,53 +552,78 @@ void nsNSSHttpInterface::registerHttpCli void nsNSSHttpInterface::unregisterHttpClient() { SEC_RegisterDefaultHttpClient(nsnull); } nsHTTPListener::nsHTTPListener() : mResultData(nsnull), mResultLen(0), - mLock("nsHTTPListener.mLock"), - mCondition(mLock, "nsHTTPListener.mCondition"), + mLock(nsnull), + mCondition(nsnull), mWaitFlag(PR_TRUE), mResponsibleForDoneSignal(PR_FALSE), mLoadGroup(nsnull), mLoadGroupOwnerThread(nsnull) { } +nsresult nsHTTPListener::InitLocks() +{ + mLock = nsAutoLock::NewLock("nsHttpListener::mLock"); + if (!mLock) + return NS_ERROR_OUT_OF_MEMORY; + + mCondition = PR_NewCondVar(mLock); + if (!mCondition) + { + nsAutoLock::DestroyLock(mLock); + mLock = nsnull; + return NS_ERROR_OUT_OF_MEMORY; + } + + return NS_OK; +} + nsHTTPListener::~nsHTTPListener() { if (mResponsibleForDoneSignal) send_done_signal(); + if (mCondition) + PR_DestroyCondVar(mCondition); + + if (mLock) + nsAutoLock::DestroyLock(mLock); + if (mLoader) { nsCOMPtr<nsIThread> mainThread(do_GetMainThread()); NS_ProxyRelease(mainThread, mLoader); } } NS_IMPL_THREADSAFE_ISUPPORTS1(nsHTTPListener, nsIStreamLoaderObserver) void nsHTTPListener::FreeLoadGroup(PRBool aCancelLoad) { nsILoadGroup *lg = nsnull; - MutexAutoLock locker(mLock); + if (mLock) { + nsAutoLock locker(mLock); - if (mLoadGroup) { - if (mLoadGroupOwnerThread != PR_GetCurrentThread()) { - NS_ASSERTION(PR_FALSE, - "attempt to access nsHTTPDownloadEvent::mLoadGroup on multiple threads, leaking it!"); - } - else { - lg = mLoadGroup; - mLoadGroup = nsnull; + if (mLoadGroup) { + if (mLoadGroupOwnerThread != PR_GetCurrentThread()) { + NS_ASSERTION(PR_FALSE, + "attempt to access nsHTTPDownloadEvent::mLoadGroup on multiple threads, leaking it!"); + } + else { + lg = mLoadGroup; + mLoadGroup = nsnull; + } } } if (lg) { if (aCancelLoad) { lg->Cancel(NS_ERROR_ABORT); } NS_RELEASE(lg); @@ -655,19 +683,19 @@ nsHTTPListener::OnStreamComplete(nsIStre return aStatus; } void nsHTTPListener::send_done_signal() { mResponsibleForDoneSignal = PR_FALSE; { - MutexAutoLock locker(mLock); + nsAutoLock locker(mLock); mWaitFlag = PR_FALSE; - mCondition.NotifyAll(); + PR_NotifyAllCondVar(mCondition); } } static char* ShowProtectedAuthPrompt(PK11SlotInfo* slot, nsIInterfaceRequestor *ir) { char* protAuthRetVal = nsnull;
--- a/security/manager/ssl/src/nsNSSCallbacks.h +++ b/security/manager/ssl/src/nsNSSCallbacks.h @@ -40,18 +40,16 @@ #ifndef _NSNSSCALLBACKS_H_ #define _NSNSSCALLBACKS_H_ #include "pk11func.h" #include "nspr.h" #include "ocspt.h" #include "nsIStreamLoader.h" -#include "mozilla/CondVar.h" -#include "mozilla/Mutex.h" char* PR_CALLBACK PK11PasswordPrompt(PK11SlotInfo *slot, PRBool retry, void* arg); void PR_CALLBACK HandshakeCallback(PRFileDesc *fd, void *client_data); SECStatus PR_CALLBACK AuthCertificateCallback(void* client_data, PRFileDesc* fd, PRBool checksig, PRBool isServer); @@ -78,18 +76,20 @@ public: PRBool mHttpRequestSucceeded; PRUint16 mHttpResponseCode; nsCString mHttpResponseContentType; const PRUint8* mResultData; // not owned, refers to mLoader PRUint32 mResultLen; - mozilla::Mutex mLock; - mozilla::CondVar mCondition; + nsresult InitLocks(); + + PRLock *mLock; + PRCondVar *mCondition; volatile PRBool mWaitFlag; PRBool mResponsibleForDoneSignal; void send_done_signal();