Skip to content

Commit 7df02a4

Browse files
Avoid array manipulation in parallel (#1243)
* Avoiding creating arrays in parallel. Fixes #1240. * Avoiding creating arrays in parallel. Fixes #1241. * Specifying Realm * Otherwise to else
1 parent 979ead7 commit 7df02a4

File tree

2 files changed

+94
-82
lines changed

2 files changed

+94
-82
lines changed

docs/index.bs

Lines changed: 48 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe
550550
[NewObject] Promise<ServiceWorkerRegistration> register(USVString scriptURL, optional RegistrationOptions options);
551551

552552
[NewObject] Promise<any> getRegistration(optional USVString clientURL = "");
553-
[NewObject] Promise<sequence<ServiceWorkerRegistration>> getRegistrations();
553+
[NewObject] Promise<FrozenArray<ServiceWorkerRegistration>> getRegistrations();
554554

555555
void startMessages();
556556

@@ -653,13 +653,16 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe
653653

654654
<dfn method for="ServiceWorkerContainer"><code>getRegistrations()</code></dfn> method *must* run these steps:
655655

656-
1. Let |client| be the <a>context object</a>'s [=ServiceWorkerContainer/service worker client=].
657-
1. Let |promise| be a new <a>promise</a>.
658-
1. Run the following substeps <a>in parallel</a>:
659-
1. Let |array| be an empty array.
660-
1. [=map/For each=] |key| → |value| of <a>scope to registration map</a>:
661-
1. If the [=url/origin=] of the result of <a lt="URL parser">parsing</a> |key| is the <a lt="same origin">same</a> as |client|'s [=environment settings object/origin=], and |value|'s <a>uninstalling flag</a> is unset, add the {{ServiceWorkerRegistration}} object associated with |value| to the |array|.
662-
1. Resolve |promise| with |array|.
656+
1. Let |client| be the [=context object=]'s [=ServiceWorkerContainer/service worker client=].
657+
1. Let |promise| be [=a new promise=].
658+
1. Run the following steps [=in parallel=]:
659+
1. Let |registrations| be a new [=list=].
660+
1. [=map/For each=] |scope| → |registration| of [=scope to registration map=]:
661+
1. If the [=url/origin=] of the result of [=URL parser|parsing=] |scope| is the [=same origin|same=] as |client|'s [=environment settings object/origin=], and |registration|'s [=uninstalling flag=] is unset, then [=append=] |registration| to |registrations|.
662+
1. [=Queue a task=] on |promise|'s [=relevant settings object=]'s [=responsible event loop=], using the [=DOM manipulation task source=], to run the following steps:
663+
1. Let |registrationObjects| be a new [=list=].
664+
1. [=list/For each=] |registration| of |registrations|, [=append=] the {{ServiceWorkerRegistration}} object associated with |registration| to |registrationObjects|.
665+
1. [=Resolve=] |promise| with [=create a frozen array|a new frozen array of=] |registrationObjects| in |promise|'s [=relevant Realm=].
663666
1. Return |promise|.
664667
</section>
665668

@@ -1128,7 +1131,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe
11281131
interface Clients {
11291132
// The objects returned will be new instances every time
11301133
[NewObject] Promise&lt;any&gt; get(DOMString id);
1131-
[NewObject] Promise&lt;sequence&lt;Client&gt;&gt; matchAll(optional ClientQueryOptions options);
1134+
[NewObject] Promise&lt;FrozenArray&lt;Client&gt;&gt; matchAll(optional ClientQueryOptions options);
11321135
[NewObject] Promise&lt;WindowClient?&gt; openWindow(USVString url);
11331136
[NewObject] Promise&lt;void&gt; claim();
11341137
};
@@ -1185,55 +1188,58 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe
11851188
1. Return |promise|.
11861189
</section>
11871190

1188-
<section algorithm="clients-getall">
1189-
<h4 id="clients-getall">{{Clients/matchAll(options)}}</h4>
1191+
<section algorithm="clients-matchall">
1192+
<h4 id="clients-matchall">{{Clients/matchAll(options)}}</h4>
11901193

11911194
The <dfn method for="Clients"><code>matchAll(|options|)</code></dfn> method *must* run these steps:
11921195

1193-
1. Let |promise| be a new <a>promise</a>.
1194-
1. Run these substeps <a>in parallel</a>:
1195-
1. Let |targetClients| be an empty array.
1196-
1. For each [=/service worker client=] |client| whose [=service worker client/origin=] is the <a lt="same origin">same</a> as the associated [=ServiceWorkerGlobalScope/service worker=]'s [=environment settings object/origin=]:
1196+
1. Let |promise| be [=a new promise=].
1197+
1. Run the following steps [=in parallel=]:
1198+
1. Let |targetClients| be a new [=list=].
1199+
1. For each [=/service worker client=] |client| whose [=service worker client/origin=] is the [=same origin|same=] as the associated [=ServiceWorkerGlobalScope/service worker=]'s [=environment settings object/origin=]:
11971200
1. If |client| is an [=environment settings object=], then:
1198-
1. If |client| is not a <a>secure context</a>, continue to the next iteration of the loop.
1201+
1. If |client| is not a [=secure context=], [=continue=].
11991202
1. Else:
1200-
1. If |client|’s <a>creation URL</a> is not a <a>potentially trustworthy URL</a>, continue to the next iteration of the loop.
1201-
1. If |options|.{{ClientQueryOptions/includeUncontrolled}} is false, then:
1202-
1. If |client|'s <a>active service worker</a> is not the associated [=ServiceWorkerGlobalScope/service worker=], continue to the next iteration of the loop.
1203-
1. If |options|.{{ClientQueryOptions/includeReserved}} is false, then:
1204-
1. If |client|'s [=environment/execution ready flag=] is unset, continue to the next iteration of the loop.
1203+
1. If |client|’s [=creation URL=] is not a [=potentially trustworthy URL=], [=continue=].
1204+
1. If |options|["{{ClientQueryOptions/includeUncontrolled}}"] is false, and if |client|'s [=active service worker=] is not the associated [=ServiceWorkerGlobalScope/service worker=], [=continue=].
1205+
1. If |options|["{{ClientQueryOptions/includeReserved}}"] is false, and if |client|'s [=environment/execution ready flag=] is unset, [=continue=].
12051206
1. Add |client| to |targetClients|.
1206-
1. Let |matchedClients| be an empty array.
1207+
1. Let |matchedWindowData| be a new [=list=].
1208+
1. Let |matchedClients| be a new [=list=].
12071209
1. For each [=/service worker client=] |client| in |targetClients|:
1208-
1. If |options|.{{ClientQueryOptions/type}} is {{ClientType/"window"}} or {{ClientType/"all"}}, and |client| is not an [=environment settings object=] or is a [=window client=], then:
1210+
1. If |options|["{{ClientQueryOptions/type}}"] is {{ClientType/"window"}} or {{ClientType/"all"}}, and |client| is not an [=environment settings object=] or is a [=window client=], then:
1211+
1. Let |windowData| be «[ "client" → |client|, "ancestorOriginsList" → a new [=list=] ]».
12091212
1. Let |browsingContext| be null.
12101213
1. Let |isClientEnumerable| be true.
1211-
1. Let |visibilityState| be the empty string.
1212-
1. Let |focusState| be false.
1213-
1. Let |ancestorOriginsList| be the empty list.
12141214
1. If |client| is an [=environment settings object=], set |browsingContext| to |client|'s [=environment settings object/global object=]'s [=/browsing context=].
12151215
1. Else, set |browsingContext| to |client|’s [=environment/target browsing context=].
1216-
1. <a>Queue a task</a> |task| to run the following substeps on |browsingContext|'s <a>event loop</a> using the <a>user interaction task source</a>:
1217-
1. If |browsingContext| has been <a lt="a browsing context is discarded">discarded</a>, set |isClientEnumerable| to false and abort these steps.
1218-
1. If |client| is a window client and |client|'s <a>responsible document</a> is not |browsingContext|'s <a>active document</a>, set |isClientEnumerable| to false and abort these steps.
1219-
1. Set |visibilityState| to |browsingContext|'s <a>active document</a>'s {{Document/visibilityState}} attribute value.
1220-
1. Set |focusState| to the result of running the <a>has focus steps</a> with |browsingContext|'s <a>active document</a> as the argument.
1221-
1. It |client| is a <a>window client</a>, set |ancestorOriginsList| to |browsingContext|'s <a>active document</a>'s <a>relevant global object</a>'s {{Location}} object's [=Location/ancestor origins list=]'s associated list.
1216+
1. [=Queue a task=] |task| to run the following substeps on |browsingContext|'s [=event loop=] using the [=user interaction task source=]:
1217+
1. If |browsingContext| has been [=a browsing context is discarded|discarded=], then set |isClientEnumerable| to false and abort these steps.
1218+
1. If |client| is a window client and |client|'s [=responsible document=] is not |browsingContext|'s [=active document=], then set |isClientEnumerable| to false and abort these steps.
1219+
1. Set |windowData|["`visibilityState`"] to |browsingContext|'s [=active document=]'s {{Document/visibilityState}} attribute value.
1220+
1. Set |windowData|["`focusState`"] to the result of running the [=has focus steps=] with |browsingContext|'s [=active document=] as the argument.
1221+
1. If |client| is a [=window client=], then set |windowData|["`ancestorOriginsList`"] to |browsingContext|'s [=active document=]'s [=relevant global object=]'s {{Location}} object's [=Location/ancestor origins list=]'s associated list.
12221222
1. Wait for |task| to have executed.
12231223

12241224
Note: Wait is a blocking wait, but implementers may run the iterations in parallel as long as the state is not broken.
12251225

12261226
1. If |isClientEnumerable| is true, then:
1227-
1. Let |windowClient| be the result of running <a>Create Window Client</a> algorithm with |client|, |visibilityState|, |focusState|, and |ancestorOriginsList| as the arguments.
1228-
1. Add |windowClient| to |matchedClients|.
1229-
1. Else if |options|.{{ClientQueryOptions/type}} is {{ClientType/"worker"}} or {{ClientType/"all"}} and |client| is a [=dedicated worker client=], or |options|.{{ClientQueryOptions/type}} is {{ClientType/"sharedworker"}} or {{ClientType/"all"}} and |client| is a [=shared worker client=], then:
1230-
1. Let |clientObject| be the result of running <a>Create Client</a> algorithm with |client| as the argument.
1231-
1. Add |clientObject| to |matchedClients|.
1232-
1. Sort |matchedClients| such that:
1233-
* {{WindowClient}} objects are always placed before {{Client}} objects whose associated [=Client/service worker clients=] are <a>worker clients</a>.
1234-
* {{WindowClient}} objects that have been <a lt="focusing steps">focused</a> are placed first sorted in the most recently <a lt="focusing steps">focused</a> order, and {{WindowClient}} objects that have never been <a lt="focusing steps">focused</a> are placed next sorted in their [=Client/service worker clients=]' creation order.
1235-
* {{Client}} objects whose associated [=Client/service worker clients=] are <a>worker clients</a> are placed next sorted in their [=Client/service worker clients=]' creation order.
1236-
1. Resolve |promise| with |matchedClients|.
1227+
1. Add |windowData| to |matchedWindowData|.
1228+
1. Else if |options|["{{ClientQueryOptions/type}}"] is {{ClientType/"worker"}} or {{ClientType/"all"}} and |client| is a [=dedicated worker client=], or |options|["{{ClientQueryOptions/type}}"] is {{ClientType/"sharedworker"}} or {{ClientType/"all"}} and |client| is a [=shared worker client=], then:
1229+
1. Add |client| to |matchedClients|.
1230+
1. [=Queue a task=] on |promise|'s [=relevant settings object=]'s [=responsible event loop=], using the [=DOM manipulation task source=], to run the following steps:
1231+
1. Let |clientObjects| be a new [=list=].
1232+
1. [=list/For each=] |windowData| in |matchedWindowData|:
1233+
1. Let |windowClient| be the result of running [=Create Window Client=] algorithm with |windowData|["`client`"], |windowData|["`visibilityState`"], |windowData|["`focusState`"], and |windowData|["`ancestorOriginsList`"] as the arguments.
1234+
1. [=Append=] |windowClient| to |clientObjects|.
1235+
1. [=list/For each=] |client| in |matchedClients|:
1236+
1. Let |clientObject| be the result of running [=Create Client=] algorithm with |client| as the argument.
1237+
1. [=Append=] |clientObject| to |clientObjects|.
1238+
1. Sort |matchedClients| such that:
1239+
* {{WindowClient}} objects are always placed before {{Client}} objects whose associated [=Client/service worker clients=] are [=worker clients=].
1240+
* {{WindowClient}} objects that have been [=focusing steps|focused=] are placed first sorted in the most recently [=focusing steps|focused=] order, and {{WindowClient}} objects that have never been [=focusing steps|focused=] are placed next sorted in their [=Client/service worker clients=]' creation order.
1241+
* {{Client}} objects whose associated [=Client/service worker clients=] are [=worker clients=] are placed next sorted in their [=Client/service worker clients=]' creation order.
1242+
1. [=Resolve=] |promise| with [=create a frozen array|a new frozen array of=] |clientObjects| in |promise|'s [=relevant Realm=].
12371243
1. Return |promise|.
12381244
</section>
12391245

0 commit comments

Comments
 (0)