From 8bc9e8de94914d325725b1bd3a7c89871b1d50ef Mon Sep 17 00:00:00 2001 From: Steve Workman Date: Sat, 28 Sep 2013 11:28:43 -0700 Subject: [PATCH] Bug 867755 - Make DiscardTracker thread-safe r=seth --- image/src/DiscardTracker.cpp | 18 +++++++++++------- image/src/DiscardTracker.h | 3 +++ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/image/src/DiscardTracker.cpp b/image/src/DiscardTracker.cpp index c0708b4bf5ac..f180a32b43a4 100644 --- a/image/src/DiscardTracker.cpp +++ b/image/src/DiscardTracker.cpp @@ -23,6 +23,7 @@ static const char* sDiscardTimeoutPref = "image.mem.min_discard_timeout_ms"; /* static */ uint32_t DiscardTracker::sMinDiscardTimeoutMs = 10000; /* static */ uint32_t DiscardTracker::sMaxDecodedImageKB = 42 * 1024; /* static */ PRLock * DiscardTracker::sAllocationLock = nullptr; +/* static */ mozilla::Mutex* DiscardTracker::sNodeListMutex = nullptr; /* * When we notice we're using too much memory for decoded images, we enqueue a @@ -50,7 +51,7 @@ DiscardTracker::Reset(Node *node) // We shouldn't call Reset() with a null |img| pointer, on images which can't // be discarded, or on animated images (which should be marked as // non-discardable, anyway). - MOZ_ASSERT(NS_IsMainThread()); + MutexAutoLock lock(*sNodeListMutex); MOZ_ASSERT(sInitialized); MOZ_ASSERT(node->img); MOZ_ASSERT(node->img->CanDiscard()); @@ -81,7 +82,7 @@ DiscardTracker::Reset(Node *node) void DiscardTracker::Remove(Node *node) { - MOZ_ASSERT(NS_IsMainThread()); + MutexAutoLock lock(*sNodeListMutex); if (node->isInList()) node->remove(); @@ -96,8 +97,6 @@ DiscardTracker::Remove(Node *node) void DiscardTracker::Shutdown() { - MOZ_ASSERT(NS_IsMainThread()); - if (sTimer) { sTimer->Cancel(); sTimer = nullptr; @@ -106,6 +105,9 @@ DiscardTracker::Shutdown() // Clear the sDiscardableImages linked list so that its destructor // (LinkedList.h) finds an empty array, which is required after bug 803688. DiscardAll(); + + delete sNodeListMutex; + sNodeListMutex = nullptr; } /* @@ -114,7 +116,7 @@ DiscardTracker::Shutdown() void DiscardTracker::DiscardAll() { - MOZ_ASSERT(NS_IsMainThread()); + MutexAutoLock lock(*sNodeListMutex); if (!sInitialized) return; @@ -153,8 +155,6 @@ DiscardTracker::InformAllocation(int64_t bytes) nsresult DiscardTracker::Initialize() { - MOZ_ASSERT(NS_IsMainThread()); - // Watch the timeout pref for changes. Preferences::RegisterCallback(DiscardTimeoutChangedCallback, sDiscardTimeoutPref); @@ -169,6 +169,10 @@ DiscardTracker::Initialize() // Create a lock for safegarding the 64-bit sCurrentDecodedImageBytes sAllocationLock = PR_NewLock(); + // Create a lock for the node list. + MOZ_ASSERT(!sNodeListMutex); + sNodeListMutex = new Mutex("image::DiscardTracker"); + // Mark us as initialized sInitialized = true; diff --git a/image/src/DiscardTracker.h b/image/src/DiscardTracker.h index ee1a4dfa5c37..4eb7704fd708 100644 --- a/image/src/DiscardTracker.h +++ b/image/src/DiscardTracker.h @@ -8,9 +8,11 @@ #include "mozilla/Atomics.h" #include "mozilla/LinkedList.h" +#include "mozilla/Mutex.h" #include "mozilla/TimeStamp.h" #include "prlock.h" #include "nsThreadUtils.h" +#include "nsAutoPtr.h" class nsITimer; @@ -119,6 +121,7 @@ class DiscardTracker static uint32_t sMaxDecodedImageKB; // Lock for safegarding the 64-bit sCurrentDecodedImageBytes static PRLock *sAllocationLock; + static mozilla::Mutex* sNodeListMutex; }; } // namespace image