-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Editorial: expose "run steps after a timeout" #7349
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -93936,7 +93936,7 @@ import "https://example.com/foo/../module2.mjs";</code></pre> | |
</ol> | ||
</li> | ||
|
||
<li> | ||
<li id="idle-deadline-computation"> | ||
<p>If all of the following are true | ||
|
||
<ul class="brief"> | ||
|
@@ -96426,12 +96426,21 @@ enum <dfn enum>DOMParserSupportedType</dfn> { | |
|
||
<div w-nodev> | ||
|
||
<p>Objects that implement the <code>WindowOrWorkerGlobalScope</code> mixin have a <dfn | ||
export>map of active timers</dfn>, which is a <span>map</span>, initially empty. Each | ||
<span data-x="map key">key</span> in this map is identified by a number, which must be unique | ||
within the list for the lifetime of the object that implements the | ||
<code>WindowOrWorkerGlobalScope</code> mixin, and each <span data-x="map value">value</span> is a | ||
<code>DOMHighResTimeStamp</code>, representing the expiry time for that timer.</p> | ||
<p>Objects that implement the <code>WindowOrWorkerGlobalScope</code> mixin have a <dfn>map of | ||
active timers</dfn>, which is a <span>map</span>, initially empty. Each <span data-x="map | ||
key">key</span> in this map is an identifier for a timer, and each <span data-x="map | ||
value">value</span> is a <code>DOMHighResTimeStamp</code>, representing the expiry time for that | ||
timer.</p> | ||
|
||
<p class="note">For entries put in the <span>map of active timers</span> by the <span>timer | ||
initialization steps</span>, i.e., by <code data-x="dom-setTimeout">setTimeout()</code> and <code | ||
data-x="dom-setInterval">setInterval()</code>, the keys are numbers. For other specifications | ||
that use the <span>run steps after a timeout</span> algorithm, the identifier is a unique | ||
non-numeric value. Only the numeric-keyed timers are affected by <code | ||
data-x="dom-clearTimeout">clearTimeout()</code> and <code | ||
data-x="dom-clearInterval">clearInterval()</code>, but all timers contribute to <a | ||
href="#idle-deadline-computation">idle deadline computation</a>, and are cleared when the | ||
relevant global is destroyed.</p> | ||
|
||
<hr> | ||
|
||
|
@@ -96474,8 +96483,8 @@ enum <dfn enum>DOMParserSupportedType</dfn> { | |
|
||
<li><p>If <var>previousId</var> was given, let <var>id</var> be <var>previousId</var>; | ||
otherwise, let <var>id</var> be an <span>implementation-defined</span> integer that is greater | ||
than zero that will identify the timeout to be set by this call in <var>global</var>'s <span>map | ||
of active timers</span>.</p></li> | ||
than zero and does not already <span data-x="map exists">exist</span> in <var>global</var>'s | ||
<span>map of active timers</span>.</p></li> | ||
|
||
<li> | ||
<p>If the <span>surrounding agent</span>'s <span data-x="concept-agent-event-loop">event | ||
|
@@ -96580,50 +96589,19 @@ enum <dfn enum>DOMParserSupportedType</dfn> { | |
|
||
<li><p>Set <var>task</var>'s <dfn>timer nesting level</dfn> to <var>nesting level</var>.</p></li> | ||
|
||
<li><p>Let <var>startTime</var> be the <span>current high resolution time</span>.</p></li> | ||
|
||
<li><p><span data-x="map set">Set</span> <var>global</var>'s <span>map of active | ||
timers</span>[<var>id</var>] to <var>startTime</var> plus <var>timeout</var>.</p></li> | ||
<li><p>Let <var>completionStep</var> be an algorithm step which <span data-x="queue a global | ||
task">queues a global task</span> on the <dfn export>timer task source</dfn> given | ||
<var>global</var> to run <var>task</var>.</p></li> | ||
|
||
<li> | ||
<p>Run the following steps <span>in parallel</span>:</p> | ||
|
||
<ol> | ||
<li> | ||
<p>If <var>global</var> is a <code>Window</code> object, wait until <var>global</var>'s <span | ||
data-x="concept-document-window">associated <code>Document</code></span> has been <span>fully | ||
active</span> for a further <var>timeout</var> milliseconds (not necessarily | ||
consecutively).</p> | ||
|
||
<p>Otherwise, <var>global</var> is a <code>WorkerGlobalScope</code> object; wait | ||
until <var>timeout</var> milliseconds have passed with the worker not suspended (not | ||
necessarily consecutively).</p> | ||
</li> | ||
|
||
<li><p>Wait until any invocations of this algorithm that had the same <var>global</var>, that | ||
started before this one, and whose <var>timeout</var> is equal to or less than this one's, | ||
have completed.</p></li> | ||
|
||
<li> | ||
<p>Optionally, wait a further <span>implementation-defined</span> length of time.</p> | ||
|
||
<p class="note">This is intended to allow user agents to pad timeouts as needed to optimize | ||
the power usage of the device. For example, some processors have a low-power mode where the | ||
granularity of timers is reduced; on such platforms, user agents can slow timers down to fit | ||
this schedule instead of requiring the processor to use the more accurate mode with its | ||
associated higher power usage.</p> | ||
</li> | ||
<p><span>Run steps after a timeout</span> given <var>global</var>, "<code | ||
data-x="">setTimeout/setInterval</code>", <var>timeout</var>, <var>completionStep</var>, and | ||
<var>id</var>.</p> | ||
|
||
<li> | ||
<p><span>Queue a global task</span> on the <dfn>timer task source</dfn> given | ||
<var>global</var> to run <var>task</var>.</p> | ||
|
||
<p class="note">Once the task has been processed, if <var>repeat</var> is false, it is safe | ||
to remove the entry for <var>id</var> from the <span>map of active timers</span> (there is no | ||
way for the entry's existence to be detected past this point, so it does not technically | ||
matter one way or the other).</p> | ||
</li> | ||
</ol> | ||
<p class="note">Once the task has been processed, if <var>repeat</var> is false, it is safe to | ||
remove the entry for <var>id</var> from the <span>map of active timers</span> (there is no way | ||
for the entry's existence to be detected past this point, so it does not technically matter one | ||
way or the other).</p> | ||
</li> | ||
|
||
<li><p>Return <var>id</var>.</p></li> | ||
|
@@ -96675,6 +96653,69 @@ function scheduleWork() { | |
scheduleWork(); // queues a task to do lots of work</code></pre> | ||
</div> | ||
|
||
<div w-nodev> | ||
|
||
<p>To <dfn export>run steps after a timeout</dfn>, given a <code>WindowOrWorkerGlobalScope</code> | ||
<var>global</var>, a string <var>orderingIdentifier</var>, a number <var>milliseconds</var>, a | ||
set of steps <var>completionSteps</var>, and an optional value <var>timerKey</var>:</p> | ||
|
||
<ol> | ||
<li><p>Assert: if <var>timerKey</var> is given, then the caller of this algorithm is the | ||
<span>timer initialization steps</span>. (Other specifications must not pass | ||
<var>timerKey</var>.)</p></li> | ||
|
||
<li><p>If <var>timerKey</var> is not given, then set it to a new unique non-numeric | ||
value.</p></li> | ||
|
||
<li><p>Let <var>startTime</var> be the <span>current high resolution time</span>.</p></li> | ||
|
||
<li><p><span data-x="map set">Set</span> <var>global</var>'s <span>map of active | ||
timers</span>[<var>timerKey</var>] to <var>startTime</var> plus | ||
<var>milliseconds</var>.</p></li> | ||
|
||
<li> | ||
<p>Run the following steps <span>in parallel</span>:</p> | ||
|
||
<ol> | ||
<li> | ||
<p>If <var>global</var> is a <code>Window</code> object, wait until <var>global</var>'s <span | ||
data-x="concept-document-window">associated <code>Document</code></span> has been <span>fully | ||
active</span> for a further <var>milliseconds</var> milliseconds (not necessarily | ||
consecutively).</p> | ||
|
||
<p>Otherwise, <var>global</var> is a <code>WorkerGlobalScope</code> object; wait until | ||
<var>milliseconds</var> milliseconds have passed with the worker not suspended (not | ||
necessarily consecutively).</p> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this xref "active needed worker"? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The interaction with the closing flag in https://html.spec.whatwg.org/#worker-processing-model:suspendable-worker makes me not 100% sure they are equivalent, so I'll leave it for now... |
||
</li> | ||
|
||
<li><p>Wait until any invocations of this algorithm that had the same <var>global</var> and | ||
<var>orderingIdentifier</var>, that started before this one, and whose <var>milliseconds</var> | ||
is equal to or less than this one's, have completed.</p></li> | ||
|
||
<li> | ||
<p>Optionally, wait a further <span>implementation-defined</span> length of time.</p> | ||
|
||
<p class="note">This is intended to allow user agents to pad timeouts as needed to optimize | ||
the power usage of the device. For example, some processors have a low-power mode where the | ||
granularity of timers is reduced; on such platforms, user agents can slow timers down to fit | ||
this schedule instead of requiring the processor to use the more accurate mode with its | ||
associated higher power usage.</p> | ||
</li> | ||
|
||
<li><p>Perform <var>completionSteps</var>.</p></li> | ||
</ol> | ||
</li> | ||
</ol> | ||
|
||
<p class="note"><span>Run steps after a timeout</span> is meant to be used by other | ||
specifications that want to execute developer-supplied code after a developer-supplied timeout, | ||
in a similar manner to <code data-x="dom-setTimeout">setTimeout()</code>. (Note, however, it does | ||
not have the nesting and clamping behavior of <code data-x="dom-setTimeout">setTimeout()</code>.) | ||
Such specifications can choose an <var>orderingIdentifier</var> to ensure ordering within their | ||
specification's timeouts, while not constraining ordering with respect to other specification's | ||
timeouts.</p> | ||
|
||
</div> | ||
|
||
<h3>Microtask queuing</h3> | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This implies that a now-cleared ID can be reused, even if less than 2^31 timers have been created so far. But this is probably best left for #7358.