test_ping_submitted and test_new_tab_on_restore read Glean metrics as soon as
the browser reports itself started up. That signal
(browser-idle-startup-tasks-finished, which is what Marionette waits on) says
nothing about FOG, which is initialized from a startup idle task, so the read
can land while Glean is still pre-init.
That is not a slow read, it is an unrecoverable hang: block_on_dispatcher posts
its barrier to the unbounded queue while the dispatcher worker is still parked
on the pre-init channel, and the queue is only flushed by initializeFOG, which
needs the main thread. So a blocking Glean read from the main thread in that
window deadlocks the browser, with no crash and no stack.
The race itself is pre-existing: FOG is initialized by StartupTelemetry's
browser-idle-startup consumer, behind awaits on UsageReporting and
TelemetryReportingPolicy, so it could always finish after the notification.
Part 1 is what makes it reproduce. Porting _schedulePerWindowIdleTasks to
category-manager invocation replaces window.requestIdleCallback with
ChromeUtils.idleDispatch, so the per-window tasks and the notification that
follows them move off the window's idle callback list and onto the
thread-level idle queue that browser-idle-startup already uses. That changes
when the notification fires relative to initializeFOG, and the tests started
hanging instead of racing benignly.
Expose whether initializeFOG has been called, and wait for it before each read.
Differential Revision: https://phabricator.services.mozilla.com/D323262