Bug 1797688 - Part 9: Make gXPCOMThreadsShutDown DEBUG only. r=xpcom-reviewers,mccr8

`gXPCOMThreadsShutDown` is needed for the assertion in `ThreadEventTarget::Dispatch` but we do not want other shutdown checks to rely on it, as it is too specific for this case. If we ever would really need this checkpoint in time during runtime in release we should consider to make it become a new `ShutdownPhase` in between.

We move the state to `ThreadEventTarget` and have a `DEBUG` only method to prime that assertion over there.

Differential Revision: https://phabricator.services.mozilla.com/D160627
This commit is contained in:
Jens Stutte 2022-11-01 14:08:46 +00:00
Родитель 3c26de87f1
Коммит 941061692d
4 изменённых файлов: 28 добавлений и 7 удалений

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

@ -4,6 +4,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ThreadEventTarget.h"
#include "XPCOMModule.h"
#include "base/basictypes.h"
@ -146,8 +147,6 @@ nsresult nsLocalFileConstructor(const nsIID& aIID, void** aInstancePtr) {
nsComponentManagerImpl* nsComponentManagerImpl::gComponentManager = nullptr;
bool gXPCOMShuttingDown = false;
mozilla::Atomic<bool, mozilla::SequentiallyConsistent> gXPCOMThreadsShutDown(
false);
bool gXPCOMMainThreadEventsAreDoomed = false;
char16_t* gGREBinPath = nullptr;
@ -591,7 +590,11 @@ nsresult ShutdownXPCOM(nsIServiceManager* aServMgr) {
mozilla::AppShutdown::AdvanceShutdownPhase(
mozilla::ShutdownPhase::XPCOMShutdownThreads);
gXPCOMThreadsShutDown = true;
#ifdef DEBUG
// Prime an assertion at ThreadEventTarget::Dispatch to avoid late
// dispatches to non main-thread threads.
ThreadEventTarget::XPCOMShutdownThreadsNotificationFinished();
#endif
NS_ProcessPendingEvents(thread);
// Shutdown the timer thread and all timers that might still be alive

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

@ -31,8 +31,6 @@ DECL_CLASS(nsIDebug2);
#ifdef __cplusplus
extern bool gXPCOMShuttingDown;
extern mozilla::Atomic<bool, mozilla::SequentiallyConsistent>
gXPCOMThreadsShutDown;
extern bool gXPCOMMainThreadEventsAreDoomed;
#endif

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

@ -16,11 +16,20 @@
#include "nsThreadManager.h"
#include "nsThreadSyncDispatch.h"
#include "nsThreadUtils.h"
#include "nsXPCOMPrivate.h" // for gXPCOMThreadsShutDown
#include "ThreadDelay.h"
using namespace mozilla;
#ifdef DEBUG
// This flag will be set right after XPCOMShutdownThreads finished but before
// we continue with other processing. It is exclusively meant to prime the
// assertion of ThreadEventTarget::Dispatch as early as possible.
// Please use AppShutdown::IsInOrBeyond(ShutdownPhase::???)
// elsewhere to check for shutdown phases.
static mozilla::Atomic<bool, mozilla::SequentiallyConsistent>
gXPCOMThreadsShutDownNotified(false);
#endif
ThreadEventTarget::ThreadEventTarget(ThreadTargetSink* aSink,
bool aIsMainThread)
: mSink(aSink)
@ -47,6 +56,13 @@ ThreadEventTarget::DispatchFromScript(nsIRunnable* aRunnable, uint32_t aFlags) {
return Dispatch(do_AddRef(aRunnable), aFlags);
}
#ifdef DEBUG
// static
void ThreadEventTarget::XPCOMShutdownThreadsNotificationFinished() {
gXPCOMThreadsShutDownNotified = true;
}
#endif
NS_IMETHODIMP
ThreadEventTarget::Dispatch(already_AddRefed<nsIRunnable> aEvent,
uint32_t aFlags) {
@ -57,7 +73,7 @@ ThreadEventTarget::Dispatch(already_AddRefed<nsIRunnable> aEvent,
return NS_ERROR_INVALID_ARG;
}
NS_ASSERTION(!gXPCOMThreadsShutDown || mIsMainThread ||
NS_ASSERTION(!gXPCOMThreadsShutDownNotified || mIsMainThread ||
PR_GetCurrentThread() == mThread,
"Dispatch to non-main thread after xpcom-shutdown-threads");

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

@ -43,6 +43,10 @@ class ThreadEventTarget final : public nsISerialEventTarget {
return aMallocSizeOf(this) + n;
}
#ifdef DEBUG
static void XPCOMShutdownThreadsNotificationFinished();
#endif
private:
~ThreadEventTarget();