Bug 1768581 - Part 4: Postpone main nsThread destruction after full XPCOM shutdown. r=xpcom-reviewers,nika

Some debug infrastructure like MOZ_WEAKPTR_INIT_THREAD_SAFETY_CHECK  that can apparently be triggered by nsComponentManagerImpl::gComponentManager->FreeService() seem to rely on the existence of a serial event target even if they do not post any events. So it seems sound to keep a representation of the main thread as nsThread object until after final XPCOM shutdown.
But nsThreadManager::ShutdownMainThread() does more, it processes the last round of events, removes the thread's observer  and closes down the background event target. We do not want to move these operations to happen later than before, such that we split the nsThread release into a separate function and move that together with AbstractThread::ShutdownMainThread() behind FreeService().

Depends on D160628

Differential Revision: https://phabricator.services.mozilla.com/D162497
This commit is contained in:
Jens Stutte 2022-12-12 15:21:28 +00:00
Родитель db3cae107a
Коммит f933869f5f
3 изменённых файлов: 18 добавлений и 5 удалений

Просмотреть файл

@ -619,8 +619,8 @@ nsresult ShutdownXPCOM(nsIServiceManager* aServMgr) {
// that will be processed inside AdvanceShutdownPhase.
AppShutdown::AdvanceShutdownPhase(ShutdownPhase::XPCOMShutdownFinal);
// Shutdown the main thread, processing our last round of events, and then
// mark that we've finished main thread event processing.
// Shutdown the main thread, processing our very last round of events, and
// then mark that we've finished main thread event processing.
nsThreadManager::get().ShutdownMainThread();
gXPCOMMainThreadEventsAreDoomed = true;
@ -629,8 +629,6 @@ nsresult ShutdownXPCOM(nsIServiceManager* aServMgr) {
mozilla::dom::JSExecutionManager::Shutdown();
}
AbstractThread::ShutdownMainThread();
// XPCOM is officially in shutdown mode NOW
// Set this only after the observers have been notified as this
// will cause servicemanager to become inaccessible.
@ -645,6 +643,10 @@ nsresult ShutdownXPCOM(nsIServiceManager* aServMgr) {
nsComponentManagerImpl::gComponentManager->FreeServices();
}
// Remove the remaining main thread representations
nsThreadManager::get().ReleaseMainThread();
AbstractThread::ShutdownMainThread();
// Release the directory service
nsDirectoryService::gService = nullptr;

Просмотреть файл

@ -421,6 +421,12 @@ void nsThreadManager::ShutdownMainThread() {
mMainThread->SetObserver(nullptr);
mBackgroundEventTarget = nullptr;
}
void nsThreadManager::ReleaseMainThread() {
MOZ_ASSERT(!mInitialized, "Must have called BeginShutdown");
MOZ_ASSERT(!mBackgroundEventTarget, "Must have called ShutdownMainThread");
MOZ_ASSERT(mMainThread);
// Release main thread object.
mMainThread = nullptr;

Просмотреть файл

@ -37,9 +37,14 @@ class nsThreadManager : public nsIThreadManager {
void ShutdownNonMainThreads();
// Finish shutting down all threads. This function must be called after
// ShutdownNonMainThreads and will take the main thread out of commission.
// ShutdownNonMainThreads and will delete the BackgroundEventTarget and
// take the main thread event target out of commission, but without
// releasing the underlying nsThread object.
void ShutdownMainThread();
// Release the underlying main thread nsThread object.
void ReleaseMainThread();
// Called by nsThread to inform the ThreadManager it exists. This method
// must be called when the given thread is the current thread.
void RegisterCurrentThread(nsThread& aThread);