Skip to content

Commit e1ae615

Browse files
authored
Add TaskSignal.any() (#72)
1 parent 949d9f9 commit e1ae615

File tree

3 files changed

+76
-14
lines changed

3 files changed

+76
-14
lines changed

spec/controlling-tasks.md

Lines changed: 66 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,14 @@ The `TaskSignal` Interface {#sec-task-signal}
9090
---------------------
9191

9292
<pre class='idl'>
93+
dictionary TaskSignalAnyInit {
94+
(TaskPriority or TaskSignal) priority = "user-visible";
95+
};
96+
9397
[Exposed=(Window, Worker)]
9498
interface TaskSignal : AbortSignal {
99+
[NewObject] static TaskSignal _any(sequence&lt;AbortSignal> signals, optional TaskSignalAnyInit init = {});
100+
95101
readonly attribute TaskPriority priority;
96102

97103
attribute EventHandler onprioritychange;
@@ -103,22 +109,38 @@ accept an {{AbortSignal}}. Additionally, {{Scheduler/postTask()}} accepts an
103109
{{AbortSignal}}, which can be useful if dynamic prioritization is not needed.
104110

105111
<dl class="domintro non-normative">
112+
<dt><code>TaskSignal . <a method for=TaskSignal lt="any(signals, init)">any</a>(|signals|, |init|)</code>
113+
<dd>Returns a {{TaskSignal}} instance which will be aborted if any of |signals| is aborted. Its
114+
[=AbortSignal/abort reason=] will be set to whichever one of |signals| caused it to be aborted.
115+
The signal's [=TaskSignal/priority=] will be determined by |init|'s {{TaskSignalAnyInit/priority}},
116+
which can either be a fixed {{TaskPriority}} or a {{TaskSignal}}, in which case the new signal's
117+
[=TaskSignal/priority=] will change along with this signal.
118+
106119
<dt><code>signal . {{TaskSignal/priority}}</code>
107-
<dd>
108-
<p>Returns the {{TaskPriority}} of the signal.
109-
</dd>
120+
<dd><p>Returns the {{TaskPriority}} of the signal.
110121
</dl>
111122

112-
A {{TaskSignal}} object has an associated {{TaskPriority}}
113-
<dfn for=TaskSignal>priority</dfn>.
123+
A {{TaskSignal}} object has an associated <dfn for=TaskSignal>priority</dfn> (a {{TaskPriority}}).
114124

115-
A {{TaskSignal}} object has an associated <dfn for=TaskSignal>priority changing</dfn>
116-
[=boolean=], intially set to false.
125+
A {{TaskSignal}} object has an associated <dfn for=TaskSignal>priority changing</dfn> (a
126+
[=boolean=]), which is intially set to false.
117127

118128
A {{TaskSignal}} object has associated <dfn for=TaskSignal>priority change algorithms</dfn>,
119-
which is a [=set=] of algorithms, initialized to a new empty [=set=]. These
120-
algorithms are to be executed when its [=TaskSignal/priority changing=] value
121-
is true.
129+
(a [=set=] of algorithms that are to be executed when its [=TaskSignal/priority changing=] value
130+
is true), which is initially empty.
131+
132+
A {{TaskSignal}} object has an associated <dfn for=TaskSignal>source signal</dfn> (a weak refernece
133+
to a {{TaskSignal}} that the object is dependent on for its [=TaskSignal/priority=]), which is
134+
initially null.
135+
136+
A {{TaskSignal}} object has associated <dfn for=TaskSignal>dependent signals</dfn> (a weak [=set=]
137+
of {{TaskSignal}} objects that are dependent on the object for their [=TaskSignal/priority=]), which
138+
is initially empty.
139+
140+
A {{TaskSignal}} object has an associated <dfn for=TaskSignal>dependent</dfn> (a
141+
boolean), which is initially false.
142+
143+
<br>
122144

123145
The <dfn attribute for="TaskSignal">priority</dfn> getter steps are to return
124146
[=this=]'s [=TaskSignal/priority=].
@@ -132,9 +154,34 @@ To <dfn for="TaskSignal">add a priority change algorithm</dfn> |algorithm| to a
132154
{{TaskSignal}} object |signal|, [=set/append=] |algorithm| to |signal|'s
133155
[=TaskSignal/priority change algorithms=].
134156

157+
<br>
158+
159+
A {{TaskSignal}} <dfn for=TaskSignal lt="has fixed priority|have fixed priority">has fixed priority</dfn>
160+
if it is a [=TaskSignal/dependent=] signal with a null [=TaskSignal/source signal=].
161+
162+
<div algorithm>
163+
The static <dfn method for=TaskSignal><code>any(|signals|, |init|)</code></dfn> method steps are:
164+
165+
1. Let |resultSignal| be the result of <a for=AbortSignal>creating a dependent signal</a> from
166+
|signals| using the {{TaskSignal}} interface and the [=current realm=].
167+
1. Set |resultSignal|'s [=TaskSignal/dependent=] to true.
168+
1. If |init|["{{TaskSignalAnyInit/priority}}"] is a {{TaskPriority}}, then:
169+
1. Set |resultSignal|'s [=TaskSignal/priority=] to |init|["{{TaskSignalAnyInit/priority}}"].
170+
1. Otherwise:
171+
1. Let |sourceSignal| be |init|["{{TaskSignalAnyInit/priority}}"].
172+
1. Set |resultSignal|'s [=TaskSignal/priority=] to |sourceSignal|'s [=TaskSignal/priority=].
173+
1. If |sourceSignal| does not [=TaskSignal/have fixed priority=], then:
174+
1. If |sourceSignal|'s [=TaskSignal/dependent=] is true, then set |sourceSignal| to
175+
|sourceSignal|'s [=TaskSignal/source signal=].
176+
1. Assert: |sourceSignal| is not [=TaskSignal/dependent=].
177+
1. Set |resultSignal|'s [=TaskSignal/source signal=] to a weak reference to |sourceSignal|.
178+
1. [=set/Append=] |resultSignal| to |sourceSignal|'s [=TaskSignal/dependent signals=].
179+
1. Return |resultSignal|.
180+
</div>
181+
135182
<div algorithm>
136183
To <dfn for="TaskSignal">signal priority change</dfn> on a {{TaskSignal}}
137-
object |signal|, given a {{TaskPriority}} |priority|, run the following steps:
184+
object |signal|, given a {{TaskPriority}} |priority|:
138185

139186
1. If |signal|'s [=TaskSignal/priority changing=] is true, then [=exception/throw=]
140187
a "{{NotAllowedError!!exception}}" {{DOMException}}.
@@ -147,9 +194,17 @@ To <dfn for="TaskSignal">add a priority change algorithm</dfn> |algorithm| to a
147194
1. [=Fire an event=] named {{TaskSignal/prioritychange}} at |signal| using
148195
{{TaskPriorityChangeEvent}}, with its {{TaskPriorityChangeEvent/previousPriority}}
149196
attribute initialized to |previousPriority|.
197+
1. [=list/iterate|For each=] |dependentSignal| of |signal|'s [=TaskSignal/dependent signals=],
198+
[=TaskSignal/signal priority change=] on |dependentSignal| with |priority|.
150199
1. Set |signal|'s [=TaskSignal/priority changing=] to false.
151200
</div>
152201

202+
### Garbage Collection ### {#sec-task-signal-garbage-collection}
203+
204+
A [=TaskSignal/dependent=] {{TaskSignal}} object must not be garbage collected while its
205+
[=TaskSignal/source signal=] is non-null and it has registered event listeners for its
206+
{{TaskSignal/prioritychange}} event or its [=TaskSignal/priority change algorithms=] is non-empty.
207+
153208
Examples {#sec-controlling-tasks-examples}
154209
---------------------
155210

spec/index.bs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,12 +89,16 @@ spec: HTML; urlPrefix: https://html.spec.whatwg.org/multipage/;
8989
text: associated Document; for:Window; url: window-object.html#concept-document-window
9090
type: dfn
9191
text: runnable; for:task; url: webappapis.html#concept-task-runnable
92-
spec: dom; urlPrefix: https://dom.spec.whatwg.org/#;
92+
spec: dom; urlPrefix: https://dom.spec.whatwg.org/#
9393
type: dfn;
94+
text: creating a dependent signal; for:AbortSignal; url: create-a-dependent-abort-signal
9495
text: signal; for: AbortController; url: abortcontroller-signal
9596
spec: requestidlecallback; urlPrefix: https://www.w3.org/TR/requestidlecallback/#;
9697
type: method;
9798
text: requestIdleCallback(); for: Window; url: dom-window-requestidlecallback
99+
spec: ECMASCRIPT urlPrefix: https://tc39.es/ecma262/#;
100+
type: dfn
101+
text: current realm; url: current-realm
98102
</pre>
99103

100104
<pre class=include>

spec/scheduling-tasks.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,8 +264,11 @@ see [whatwg/html#5925](https://github.com/whatwg/html/issues/5925).
264264
for a {{Scheduler}} |scheduler| given an {{AbortSignal}} or null |signal|, and
265265
a {{TaskPriority}} or null |priority|:
266266

267-
1. If |priority| is null and |signal| is not null and |signal| [=implements=]
268-
the {{TaskSignal}} interface, then
267+
1. If |priority| is null, |signal| is not null and [=implements=] the {{TaskSignal}} interface,
268+
and |signal| [=TaskSignal/has fixed priority=], then set |priority| to |signal|'s
269+
[=TaskSignal/priority=].
270+
1. If |priority| is null and |signal| is not null and [=implements=] the {{TaskSignal}} interface,
271+
then
269272
1. If |scheduler|'s [=Scheduler/dynamic priority task queue map=] does not
270273
[=map/contain=] |signal|, then
271274
1. Let |queue| be the result of [=creating a scheduler task queue=] given

0 commit comments

Comments
 (0)