From f97d629cf9b825d75b7f7151d5a2fb38b57d0594 Mon Sep 17 00:00:00 2001 From: Anne van Kesteren Date: Thu, 7 Feb 2019 11:18:48 +0100 Subject: [PATCH] Tie event loops to agents The concept of a browsing context event loop does not make much sense in a world where cross-site navigations are increasingly getting more isolated from each other. Helps with #4198. --- source | 227 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 112 insertions(+), 115 deletions(-) diff --git a/source b/source index 12ae6fe4cde..b96662fb9d5 100644 --- a/source +++ b/source @@ -8035,9 +8035,8 @@ interface DOMStringList {

Serializable objects support being serialized, and later deserialized, in a way that is independent of any given JavaScript Realm. This allows them to be stored on - disk and later restored, or cloned across document and worker boundaries (including across - documents of different origins or in different event loops).

+ disk and later restored, or cloned across agent and even agent cluster + boundaries.

Not all objects are serializable objects, and not all aspects of objects that are serializable objects are necessarily preserved when they are serialized.

@@ -8149,8 +8148,8 @@ interface DOMStringList {

Transferable objects

-

Transferable objects support being transferred across event loops. Transferring is effectively recreating the object while sharing a +

Transferable objects support being transferred across agents. Transferring is effectively recreating the object while sharing a reference to the underlying data and then detaching the object being transferred. This is useful to transfer ownership of expensive resources. Not all objects are transferable objects and not all aspects of objects that are transferable objects are @@ -65809,10 +65808,10 @@ interface OffscreenCanvasRenderingContext2D {

  • Queue a task in the placeholder canvas element's - relevant settings object's responsible event loop (which will be a - browsing context event loop) to set the placeholder canvas element's - output bitmap to be a reference to image.

    + relevant agent's event loop (which will be a window event + loop) to set the placeholder + canvas element's output bitmap to be a reference to + image.

    If image has different dimensions than the bitmap previously referenced as the placeholder canvas @@ -65824,9 +65823,9 @@ interface OffscreenCanvasRenderingContext2D {

    Implementations are encouraged to short-circuit the graphics update steps of - the browsing context event loop for the purposes of updating the - contents of a placeholder canvas - element to the display. This could mean, for example, that the window event loop for the purposes of updating the contents of a placeholder canvas element to the + display. This could mean, for example, that the commit() method can copy the bitmap contents directly to a graphics buffer that is mapped to the physical display location of the placeholder canvas element. This or @@ -77636,11 +77635,6 @@ console.assert(iframeWindow.frameElement === null); any other group. Each such group is a unit of related similar-origin browsing contexts.

    -

    There is also at most one event loop per unit of related - similar-origin browsing contexts (though several units of related similar-origin browsing contexts can - have a shared event loop).

    - @@ -79141,13 +79135,8 @@ interface BarProp {
    The responsible event loop
    -
    - -

    Return the event loop that is associated with the unit of related - similar-origin browsing contexts to which window's browsing - context belongs.

    - -
    +

    Return the event loop associated with window's relevant + agent.

    The responsible document
    @@ -80679,9 +80668,9 @@ interface History {

    The session history event loop helps coordinate cross-browsing-context transitions of the joint session history: since each browsing context might, at any - particular time, have a different event loop (this can happen if the user agent has - more than one event loop per unit of related browsing contexts), - transitions would otherwise have to involve cross-event-loop synchronization.

    + particular time, have a different event loop (this can happen if the user navigates + from example.com to shop.example), transitions would + otherwise have to involve cross-event-loop synchronization.


    @@ -86772,8 +86761,8 @@ interface ApplicationCache : EventTarget { data-x="concept-document-url">URL of the Document after it has been reset using document.open().

    -

    If the responsible event loop is not a browsing context event loop, - then the environment settings object has no responsible document.

    +

    If the responsible event loop is not a window event loop, then the + environment settings object has no responsible document.

    @@ -88912,7 +88901,7 @@ import "https://example.com/foo/../module2.mjs";

    JavaScript is expected to define agents in more detail; in particular that they hold a set of realms: tc39/ecma262 issue #882.

    + href="https://github.com/tc39/ecma262/issues/1357">tc39/ecma262 issue #1357.

    Conceptually, the agent concept is an architecture-independent, idealized "thread" in which JavaScript code runs. Such code can involve multiple globals/PromiseRejectionEventInit : EventInit {

    To coordinate events, user interaction, scripts, rendering, networking, and so forth, user agents must use event loops as - described in this section. There are two kinds of event loops: those for browsing contexts, and those for workers.

    + described in this section. Each agent has an associated event loop.

    + +

    In the future, this standard hopes to define exactly when event loops can be created or reused.

    + +

    A window event loop is the event loop used by similar-origin window agents. User agents may share an + event loop across similar-origin window + agents.

    + -

    There must be at least one browsing context event loop per user - agent, and at most one per unit of related similar-origin browsing contexts.

    +

    This specification does not currently describe how to handle the complications + arising from navigating between similar-origin window agents. E.g., when a browsing context navigates from https://example.com/ to https://shop.example/.

    -

    When there is more than one event loop for a unit of related - browsing contexts, complications arise when a browsing context in that group - is navigated such that it switches from one unit of related - similar-origin browsing contexts to another. This specification does not currently describe - how to handle these complications.

    +

    A worker event loop is the event loop used by dedicated worker agents, shared worker + agents, and service worker agents. There must be + one worker event loop per such agent.

    -

    A browsing context event loop always has at least one browsing - context. If such an event loop's browsing - contexts all go away, then the event loop goes away as well. A browsing - context always has an event loop coordinating its activities.

    +

    A worklet event loop is the event loop used by worklet agents.

    -

    Worker event loops are simpler: each worker has one - event loop, and the worker processing model - manages the event loop's lifetime.

    +

    As detailed in issue #4213 the situation for worklets is + more complicated.

    @@ -89435,11 +89432,11 @@ dictionary PromiseRejectionEventInit : EventInit { -

    Each task in a browsing context event - loop is associated with a Document; if the task was queued in the context of - an element, then it is the element's node document; if the task was queued in the context - of a browsing context, then it is the browsing context's active - document at the time the task was queued; if the task was queued by or for a Each task in a window event loop is associated + with a Document; if the task was queued in the context of an element, then it is the + element's node document; if the task was queued in the context of a browsing + context, then it is the browsing context's active document at the + time the task was queued; if the task was queued by or for a script then the document is the responsible document specified by the script's settings object.

    @@ -89447,6 +89444,7 @@ dictionary PromiseRejectionEventInit : EventInit { the event loop that is handling tasks for the task's associated Document or worker.

    +

    When a user agent is to queue a task, it must add the given task to one of the task queues of the relevant event @@ -89454,7 +89452,7 @@ dictionary PromiseRejectionEventInit : EventInit {

    Each task is defined as coming from a specific task source. All the tasks from one particular task source and - destined to a particular event loop (e.g. the callbacks generated by timers of a + destined to a particular event loop (e.g., the callbacks generated by timers of a Document, the events fired for mouse movements over that Document, the tasks queued for the parser of that Document) must always be added to the same task queue, but tasks from different PromiseRejectionEventInit : EventInit {

  • Let oldestTask be the oldest task on one of the event loop's task queues, if any, - ignoring, in the case of a browsing context event loop, tasks whose - associated Documents are not fully active. The user agent may pick any - task queue. If there is no task to select, then jump to the microtasks step + ignoring, in the case of a window event loop, tasks whose associated + Documents are not fully active. The user agent may pick any task + queue. If there is no task to select, then jump to the microtasks step below.

  • @@ -89544,9 +89542,8 @@ dictionary PromiseRejectionEventInit : EventInit {
  • -

    Update the rendering: If this event loop is a - browsing context event loop (as opposed to a worker event loop), then run the following substeps.

    +

    Update the rendering: if this is a window event loop, + then:

    1. @@ -89670,15 +89667,23 @@ dictionary PromiseRejectionEventInit : EventInit {
  • -
  • If this is a browsing context event loop (as opposed to a worker event loop), and there are no tasks in the event loop's task queues which are associated with a Document that is - fully active, and the event loop's microtask queue is - empty, and none of the browsing contexts have a - rendering opportunity, then for each browsing context, run the steps in - the start an idle period algorithm, passing the Window associated with - that browsing context.

  • +
  • +

    If all of the following are true + +

    + +

    then for each browsing context, run the steps in the start an idle period + algorithm, passing the Window associated with that browsing + context.

    +
  • Report the duration of the update the rendering step by performing the @@ -89699,14 +89704,16 @@ dictionary PromiseRejectionEventInit : EventInit {

  • -

    If this is a worker event loop (i.e., one running for - a WorkerGlobalScope):

    +

    If this is a worker event loop, then:

    1. -

      If this is a supported +

      If this event loop's agent's single realm's global object is a supported DedicatedWorkerGlobalScope and the user agent believes that it would benefit from having its rendering updated at this time, then:

      +
      1. Let now be the current high resolution time. PromiseRejectionEventInit : EventInit {

      Similar to the notes for updating the - rendering in a browsing context event loop, a user agent can - determine the rate of rendering in the dedicated worker.

      + rendering in a window event loop, a user agent can determine the rate of + rendering in the dedicated worker.

    2. If there are no tasks in the event @@ -92148,7 +92155,7 @@ scheduleWork(); // queues a task to do lots of work a callback on the microtask queue. This allows their code to run after the currently-executing task has run to completion and the JavaScript execution context stack is empty, but without yielding control back to the - browser's event loop, as would be the case when using, for example, event loop, as would be the case when using, for example, setTimeout(f, 0).

      Authors ought to be aware that scheduling a lot of microtasks has the same performance @@ -96867,26 +96874,24 @@ dictionary PostMessageOptions {

      When a port's port message queue is enabled, the event loop must use it as one of its task sources. When a port's owner specifies a responsible event loop that is a - browsing context event loop, all tasks queued on its port - message queue must be associated with the responsible document specified by - the port's owner.

      - -

      If the port's owner specifies a - responsible document that is fully active, but the event listeners all - have scripts whose settings objects specify responsible documents that are not fully - active, then the messages will be lost.

      + data-x="concept-port-owner">owner's responsible event loop is a window + event loop, all tasks queued on its port message queue must be associated with the port's + owner's responsible document.

      + +

      If the port's owner's responsible + document is fully active, but the event listeners all have scripts whose settings objects specify responsible documents that are not fully active, then the + messages will be lost.

      Each event loop has a task source called the unshipped port message queue. This is a virtual task source: it must act as if it contained the tasks of each port message queue of each MessagePort whose has been shipped flag is false, whose port - message queue is enabled, and whose owner - specifies that event loop as the responsible event loop, in the order in - which they were added to their respective task source. When a is enabled, and whose owner's + responsible event loop is that event loop, in the order in which they + were added to their respective task source. When a task would be removed from the unshipped port message queue, it must instead be removed from its port message queue.

      @@ -96977,10 +96982,10 @@ dictionary PostMessageOptions { data-x="event-message">message
      events in dataHolder.[[PortMessageQueue]] to the port message queue of value, if any, leaving value's port message queue in its initial disabled state, and, if - value's owner specifies a responsible - event loop that is a browsing context event loop, associating - the moved tasks with the responsible document - specified by value's owner.

    3. + value's owner's responsible event + loop is a window event loop, associating the moved tasks with value's owner's responsible document.

    4. If dataHolder.[[RemotePort]] is not null, then entangle dataHolder.[[RemotePort]] and value. (This will disentangle @@ -97351,10 +97356,9 @@ interface BroadcastChannel : EventTarget {

      The tasks must use the DOM manipulation task source, and, for those where the event loop specified by the target BroadcastChannel object's BroadcastChannel settings - object is a browsing context event loop, must be associated - with the responsible document specified by that target - BroadcastChannel object's BroadcastChannel settings - object.

      + object is a window event loop, must be associated with the responsible + document specified by that target BroadcastChannel object's + BroadcastChannel settings object.

    @@ -98145,19 +98149,16 @@ interface SharedWorkerGlobalScope : WorkerGlobalScope {

    The event loop

    -

    Each WorkerGlobalScope object has a distinct event loop, separate - from those used by units of related - similar-origin browsing contexts. This event loop has no associated - browsing context, and its task queues only have +

    A worker event loop's task queues only have events, callbacks, and networking activity as tasks. These event loops are created by the run a - worker algorithm.

    + w-nodev> These worker event loops are created by the + run a worker algorithm.

    -

    Each WorkerGlobalScope object also has a closing flag, which must be initially - false, but which can get set to true by the algorithms in the processing model - section belowwhen the worker is requested to close.

    +

    Each WorkerGlobalScope object has a closing flag, which must be initially false, but which can get set to true by the + algorithms in the processing model section belowwhen the worker is requested to + close.

    Once the WorkerGlobalScope's closing flag is set to true, the event @@ -98605,7 +98606,7 @@ interface SharedWorkerGlobalScope : WorkerGlobalScope {

  • Let inherited origin be outside settings's origin.

  • -
  • Let worker event loop be a newly created event +

  • Let worker event loop be a newly created worker event loop.

  • Let realm be the value of execution context's Realm @@ -98651,12 +98652,8 @@ interface SharedWorkerGlobalScope : WorkerGlobalScope {

    The responsible document
    -
    - -

    Not applicable (the responsible event loop is not a browsing context - event loop).

    - -
    +

    Not applicable (the responsible event loop is not a window event + loop).

    The API URL character encoding