ChromeUtils.importESModule({global: "current"}) waits for in-flight module
loads in the target global by spinning the event loop until
ModuleLoaderBase::HasFetchingModules() (i.e. until mFetchingModules is empty).
CancelFetchingModules() canceled the in-flight requests but deliberately left
them in mFetchingModules, relying on their fetch/compile completions to remove
the entries later. During shutdown those completions never arrive, so
HasFetchingModules() stays true forever and the spinning importESModule never
returns, hanging shutdown until the terminator kills the process ("Shutdown
hanging at step AppShutdownConfirmed"). Because the importESModule call is on
the stack, its global is also kept alive, which surfaces as a leaked
about:preferences#experimental window.
Clear mFetchingModules after canceling the requests so HasFetchingModules()
becomes false and the spin can exit. A late fetch/compile completion is handled
gracefully by OnFetchComplete's "key not found in mFetchingModules" path.
Differential Revision: https://phabricator.services.mozilla.com/D310889