зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1140051 Avoid Cache shutdown assert when Manager alive, but not active. r=ehsan
This commit is contained in:
Родитель
d1329c9051
Коммит
1fe91838f1
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include "mozilla/dom/cache/Manager.h"
|
#include "mozilla/dom/cache/Manager.h"
|
||||||
|
|
||||||
|
#include "mozilla/AutoRestore.h"
|
||||||
#include "mozilla/Mutex.h"
|
#include "mozilla/Mutex.h"
|
||||||
#include "mozilla/StaticMutex.h"
|
#include "mozilla/StaticMutex.h"
|
||||||
#include "mozilla/StaticPtr.h"
|
#include "mozilla/StaticPtr.h"
|
||||||
|
@ -197,9 +198,7 @@ public:
|
||||||
MOZ_ALWAYS_TRUE(sFactory->mManagerList.RemoveElement(aManager));
|
MOZ_ALWAYS_TRUE(sFactory->mManagerList.RemoveElement(aManager));
|
||||||
|
|
||||||
// clean up the factory singleton if there are no more managers
|
// clean up the factory singleton if there are no more managers
|
||||||
if (sFactory->mManagerList.IsEmpty()) {
|
MaybeDestroyInstance();
|
||||||
DestroyInstance();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -236,6 +235,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Factory()
|
Factory()
|
||||||
|
: mInSyncShutdown(false)
|
||||||
{
|
{
|
||||||
MOZ_COUNT_CTOR(cache::Manager::Factory);
|
MOZ_COUNT_CTOR(cache::Manager::Factory);
|
||||||
}
|
}
|
||||||
|
@ -244,6 +244,7 @@ private:
|
||||||
{
|
{
|
||||||
MOZ_COUNT_DTOR(cache::Manager::Factory);
|
MOZ_COUNT_DTOR(cache::Manager::Factory);
|
||||||
MOZ_ASSERT(mManagerList.IsEmpty());
|
MOZ_ASSERT(mManagerList.IsEmpty());
|
||||||
|
MOZ_ASSERT(!mInSyncShutdown);
|
||||||
}
|
}
|
||||||
|
|
||||||
static nsresult
|
static nsresult
|
||||||
|
@ -264,7 +265,7 @@ private:
|
||||||
|
|
||||||
// Cannot use ClearOnShutdown() because we're on the background thread.
|
// Cannot use ClearOnShutdown() because we're on the background thread.
|
||||||
// This is automatically cleared when Factory::Remove() calls
|
// This is automatically cleared when Factory::Remove() calls
|
||||||
// DestroyInstance().
|
// MaybeDestroyInstance().
|
||||||
MOZ_ASSERT(!sBackgroundThread);
|
MOZ_ASSERT(!sBackgroundThread);
|
||||||
sBackgroundThread = NS_GetCurrentThread();
|
sBackgroundThread = NS_GetCurrentThread();
|
||||||
}
|
}
|
||||||
|
@ -285,11 +286,19 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
DestroyInstance()
|
MaybeDestroyInstance()
|
||||||
{
|
{
|
||||||
mozilla::ipc::AssertIsOnBackgroundThread();
|
mozilla::ipc::AssertIsOnBackgroundThread();
|
||||||
MOZ_ASSERT(sFactory);
|
MOZ_ASSERT(sFactory);
|
||||||
|
|
||||||
|
// If the factory is is still in use then we cannot delete yet. This
|
||||||
|
// could be due to managers still existing or because we are in the
|
||||||
|
// middle of shutting down. We need to be careful not to delete ourself
|
||||||
|
// synchronously during shutdown.
|
||||||
|
if (!sFactory->mManagerList.IsEmpty() || sFactory->mInSyncShutdown) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Be clear about what we are locking. sFactory is bg thread only, so
|
// Be clear about what we are locking. sFactory is bg thread only, so
|
||||||
// we don't need to lock it here. Just protect sBackgroundThread.
|
// we don't need to lock it here. Just protect sBackgroundThread.
|
||||||
{
|
{
|
||||||
|
@ -320,11 +329,21 @@ private:
|
||||||
|
|
||||||
MOZ_ASSERT(!sFactory->mManagerList.IsEmpty());
|
MOZ_ASSERT(!sFactory->mManagerList.IsEmpty());
|
||||||
|
|
||||||
ManagerList::ForwardIterator iter(sFactory->mManagerList);
|
{
|
||||||
while (iter.HasMore()) {
|
// Note that we are synchronously calling shutdown code here. If any
|
||||||
nsRefPtr<Manager> manager = iter.GetNext();
|
// of the shutdown code synchronously decides to delete the Factory
|
||||||
manager->Shutdown();
|
// we need to delay that delete until the end of this method.
|
||||||
|
AutoRestore<bool> restore(sFactory->mInSyncShutdown);
|
||||||
|
sFactory->mInSyncShutdown = true;
|
||||||
|
|
||||||
|
ManagerList::ForwardIterator iter(sFactory->mManagerList);
|
||||||
|
while (iter.HasMore()) {
|
||||||
|
nsRefPtr<Manager> manager = iter.GetNext();
|
||||||
|
manager->Shutdown();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MaybeDestroyInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
class ShutdownAllRunnable MOZ_FINAL : public nsRunnable
|
class ShutdownAllRunnable MOZ_FINAL : public nsRunnable
|
||||||
|
@ -363,6 +382,11 @@ private:
|
||||||
// PBackground thread only.
|
// PBackground thread only.
|
||||||
typedef nsTObserverArray<Manager*> ManagerList;
|
typedef nsTObserverArray<Manager*> ManagerList;
|
||||||
ManagerList mManagerList;
|
ManagerList mManagerList;
|
||||||
|
|
||||||
|
// This flag is set when we are looping through the list and calling
|
||||||
|
// Shutdown() on each Manager. We need to be careful not to synchronously
|
||||||
|
// trigger the deletion of the factory while still executing this loop.
|
||||||
|
bool mInSyncShutdown;
|
||||||
};
|
};
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
|
Загрузка…
Ссылка в новой задаче