Closed Bug 1596781 Opened 5 years ago Closed 5 years ago

Idle callbacks are not called if a nested event loop is running

Categories

(Core :: DOM: Core & HTML, defect)

defect
Not set
normal

Tracking

()

RESOLVED INVALID

People

(Reporter: mconley, Unassigned)

Details

STR:

  1. Have a single tab opened to some web site
  2. Open up the Browser Content Toolbox
  3. Put the following into the toolbox console, but don't press enter yet:
tabs[0].content.requestIdleCallback(() => { Cu.reportError("Idle callback fired!") };
  1. Open up the webpage devtools toolbox for the current tab
  2. Type in alert("Running a nested event loop"); in the console and press enter to open an alert modal, and run a nested event loop.
  3. Press "enter" in the Browser Content Toolbox

ER:

The "Idle callback fired" message should eventually fire.

AR:

The "Idle callback fired" message never fires. Dismissing the alert dialog with "OK" will cause it to fire shortly after.

I guess it comes as no big surprise that our nested event loops cause us to behave somewhat differently - however, if there are important things that we expect to run in an idle callback, we might find that they never run because the current tab (or a background tab in the same process!) has a modal dialog open.

Fwiw, I'm in the middle of rejiggering idle handling somewhat; once it's done, I'll take a look at what's going on here.

Flags: needinfo?(bzbarsky)
Whiteboard: [qf] → [qf:p3:responsiveness]

Timers don't run either, by design.
We shouldn't run any page JS when alert() is up, but we do - that is the bug.

mconley, why should web page run anything while alert() is up and running?

If chrome JS wants to run idle runnables, it shouldn't use <web_page_window>.requestIdleCallback

Status: NEW → RESOLVED
Closed: 5 years ago
Component: DOM: Events → DOM: Core & HTML
Flags: needinfo?(mconley)
Resolution: --- → INVALID
Whiteboard: [qf:p3:responsiveness]

Oh, this is requesting an idle callback on the same page as the one that put up the alert? Yeah, that should not work. Idle callbacks in other pages should work fine.

Flags: needinfo?(bzbarsky)

(In reply to Olli Pettay [:smaug] from comment #2)

If chrome JS wants to run idle runnables, it shouldn't use <web_page_window>.requestIdleCallback

Hm - there are a few instances of privileged JS calling things like content.requestIdleCallback, content.setTimeout, content.requestAnimationFrame, etc - mainly as a way of making it so that those functions don't get called once the document unloads.

Presuming we switch to using things like ChromeUtils.idleDispatch again, I guess we should be checking for each one that the window that we care about still exists? Or would it be possible to make it so that privileged JS callbacks can still be called when in this state?

Flags: needinfo?(mconley) → needinfo?(bugs)

Adding a special case for chrome js to be able to use window.setTimeout/requestIdleCallback/etc and expecting to get called always would be just confusing IMO. API named the same way but behaving very differently.
Could ChromeUtils have helper methods for this, so that it would check the existence of the same window as what was used when callback was set? Hopefully such helper methods would make it clear that they behave differently to the methods on the window object.

Flags: needinfo?(bugs)
You need to log in before you can comment on or make changes to this bug.