[html5] r7502 - [giow] (0) Provide a way for authors to broadcast to many ports without memory l [...]

whatwg at whatwg.org whatwg at whatwg.org
Fri Nov 2 15:32:32 PDT 2012


Author: ianh
Date: 2012-11-02 15:32:30 -0700 (Fri, 02 Nov 2012)
New Revision: 7502

Modified:
   complete.html
   index
   source
Log:
[giow] (0) Provide a way for authors to broadcast to many ports without memory leaks.
Affected topics: DOM APIs, WebSocket API

Modified: complete.html
===================================================================
--- complete.html	2012-11-02 01:35:37 UTC (rev 7501)
+++ complete.html	2012-11-02 22:32:30 UTC (rev 7502)
@@ -248,7 +248,7 @@
 
   <header class=head id=head><p><a class=logo href=http://www.whatwg.org/><img alt=WHATWG height=101 src=/images/logo width=101></a></p>
    <hgroup><h1 class=allcaps>HTML</h1>
-    <h2 class="no-num no-toc">Living Standard — Last Updated 1 November 2012</h2>
+    <h2 class="no-num no-toc">Living Standard — Last Updated 2 November 2012</h2>
    </hgroup><dl><dt><strong>Web developer edition:</strong></dt>
     <dd><strong><a href=http://developers.whatwg.org/>http://developers.whatwg.org/</a></strong></dd>
     <dt>Multiple-page version:</dt>
@@ -1102,9 +1102,9 @@
        <li><a href=#ports-as-the-basis-of-an-object-capability-model-on-the-web><span class=secno>10.5.1.2 </span>Ports as the basis of an object-capability model on the Web</a></li>
        <li><a href=#ports-as-the-basis-of-abstracting-out-service-implementations><span class=secno>10.5.1.3 </span>Ports as the basis of abstracting out service implementations</a></ol></li>
      <li><a href=#message-channels><span class=secno>10.5.2 </span>Message channels</a></li>
-     <li><a href=#message-ports><span class=secno>10.5.3 </span>Message ports</a>
-      <ol>
-       <li><a href=#ports-and-garbage-collection><span class=secno>10.5.3.1 </span>Ports and garbage collection</a></ol></ol></ol></li>
+     <li><a href=#message-ports><span class=secno>10.5.3 </span>Message ports</a></li>
+     <li><a href=#broadcasting-to-many-ports><span class=secno>10.5.4 </span>Broadcasting to many ports</a></li>
+     <li><a href=#ports-and-garbage-collection><span class=secno>10.5.5 </span>Ports and garbage collection</a></ol></ol></li>
  <li><a href=#webstorage><span class=secno>11 </span>Web storage</a>
   <ol>
    <li><a href=#introduction-12><span class=secno>11.1 </span>Introduction</a></li>
@@ -85730,14 +85730,13 @@
   </dl></div><!--data-component-->
 
 
-<!--POSTMSG-->
 
 
 
-  <div data-component="Web Messaging (editor: Ian Hickson)"><!--TOPIC:DOM APIs-->
+<!--TOPIC:DOM APIs-->
 
-  
 
+
   <h3 id=web-messaging><span class=secno>10.4 </span><dfn id=crossDocumentMessages>Cross-document messaging</dfn></h3>
 
   <p>Web browsers, for security and privacy reasons, prevent documents
@@ -86680,8 +86679,107 @@
   </div>
 
 
-  <h5 id=ports-and-garbage-collection><span class=secno>10.5.3.1 </span>Ports and garbage collection</h5>
+  <h4 id=broadcasting-to-many-ports><span class=secno>10.5.4 </span>Broadcasting to many ports</h4>
 
+  <p>Broadcasting to many ports is in principle relatively simple: keep an array of
+  <code><a href=#messageport>MessagePort</a></code> objects to send messages to, and iterate through the array to send a
+  message. However, this has one rather unfortuante effect: it prevents the ports from being garbage
+  collected, even if the other side has gone away.</p>
+
+  <p>To avoid this problem, the <code><a href=#portcollection>PortCollection</a></code> object can be used. It acts as an opaque
+  array of <code><a href=#messageport>MessagePort</a></code> objects, thus allowing the objects to be garbage collected when
+  they stop being relevant, while still allowing scripts to iterate over the
+  <code><a href=#messageport>MessagePort</a></code> objects.</p>
+
+  <pre class=idl>[<a href=#dom-portcollection title=dom-PortCollection>Constructor</a>] interface <dfn id=portcollection>PortCollection</dfn> {
+  void <a href=#dom-portcollection-add title=dom-PortCollection-add>add</a>(<a href=#messageport>MessagePort</a> port);
+  void <a href=#dom-portcollection-remove title=dom-PortCollection-remove>remove</a>(<a href=#messageport>MessagePort</a> port);
+  void <a href=#dom-portcollection-clear title=dom-PortCollection-clear>clear</a>();
+  void <a href=#dom-portcollection-iterate title=dom-PortCollection-iterate>iterate</a>(<a href=#portcollectioncallback>PortCollectionCallback</a> callback);
+};
+
+callback <dfn id=portcollectioncallback>PortCollectionCallback</dfn> = void (<a href=#messageport>MessagePort</a> port);</pre>
+
+  <dl class=domintro><dt><var title="">portCollection</var> = new <code title=dom-PortCollection><a href=#dom-portcollection>PortCollection</a></code>()</dt>
+
+   <dd>
+
+    <p>Returns a new empty <code><a href=#portcollection>PortCollection</a></code> object.</p>
+
+   </dd>
+
+   <dt><var title="">portCollection</var> . <code title=dom-PortCollection-add><a href=#dom-portcollection-add>add</a></code>(<var title="">port</var>)</dt>
+
+   <dd>
+
+    <p>Adds <var title="">port</var> to the collection, if it isn't already present.</p>
+
+   </dd>
+
+   <dt><var title="">portCollection</var> . <code title=dom-PortCollection-remove><a href=#dom-portcollection-remove>remove</a></code>(<var title="">port</var>)</dt>
+
+   <dd>
+
+    <p>Removes <var title="">port</var> from the collection, if it is present.</p>
+
+   </dd>
+
+   <dt><var title="">portCollection</var> . <code title=dom-PortCollection-clear><a href=#dom-portcollection-clear>clear</a></code>()</dt>
+
+   <dd>
+
+    <p>Removes all ports from the collection.</p>
+
+   </dd>
+
+   <dt><var title="">portCollection</var> . <code title=dom-PortCollection-iterate><a href=#dom-portcollection-iterate>iterate</a></code>(<var title="">callback</var>)</dt>
+
+   <dd>
+
+    <p>Calls <var title="">callback</var> for each port in the collection.</p>
+
+   </dd>
+
+  </dl><div class=impl>
+
+  <p>A <code><a href=#portcollection>PortCollection</a></code> object has an initially empty <dfn id=concept-portcollection-list title=concept-PortCollection-list>list of ports</dfn>. When a <code><a href=#messageport>MessagePort</a></code> object in
+  a <a href=#concept-portcollection-list title=concept-PortCollection-list>list of ports</a> is garbage collected, it must be
+  silently removed from that <a href=#concept-portcollection-list title=concept-PortCollection-list>list of ports</a>. Objects
+  in a <a href=#concept-portcollection-list title=concept-PortCollection-list>list of ports</a> are ordered chronologically by
+  the time at which they were most recently added; the least-recently added <code><a href=#messageport>MessagePort</a></code>
+  object is the first in the list, and the most-recently added <code><a href=#messageport>MessagePort</a></code> is the last
+  in the list.</p>
+
+  <p>The <dfn id=dom-portcollection title=dom-PortCollection><code>PortCollection()</code></dfn> constructor must return
+  a new <code><a href=#portcollection>PortCollection</a></code> object (with an empty <a href=#concept-portcollection-list title=concept-PortCollection-list>list of ports</a>).</p>
+
+  <p>The <dfn id=dom-portcollection-add title=dom-PortCollection-add><code>add()</code></dfn> method must add the
+  <code><a href=#messageport>MessagePort</a></code> given by the argument to the <code><a href=#portcollection>PortCollection</a></code> object's <a href=#concept-portcollection-list title=concept-PortCollection-list>list of ports</a>, unless the <code><a href=#messageport>MessagePort</a></code> is
+  already in the <a href=#concept-portcollection-list title=concept-PortCollection-list>list of ports</a>, in which case the
+  method does nothing. (Calling this method with a port already in the list does not move the port
+  to the end of the list.)</p>
+
+  <p>The <dfn id=dom-portcollection-remove title=dom-PortCollection-remove><code>remove()</code></dfn> method must remove the
+  <code><a href=#messageport>MessagePort</a></code> given by the argument from the <code><a href=#portcollection>PortCollection</a></code> object's <a href=#concept-portcollection-list title=concept-PortCollection-list>list of ports</a>, unless the <code><a href=#messageport>MessagePort</a></code> is
+  not in the <a href=#concept-portcollection-list title=concept-PortCollection-list>list of ports</a>, in which case the
+  method does nothing.</p>
+
+  <p>The <dfn id=dom-portcollection-clear title=dom-PortCollection-clear><code>clear()</code></dfn> method must remove all
+  <code><a href=#messageport>MessagePort</a></code> objects from the <code><a href=#portcollection>PortCollection</a></code> object's <a href=#concept-portcollection-list title=concept-PortCollection-list>list of ports</a>, returning it to the initial empty state.
+  If the <a href=#concept-portcollection-list title=concept-PortCollection-list>list of ports</a> is already empty, the method
+  does nothing.</p>
+
+  <p>The <dfn id=dom-portcollection-iterate title=dom-PortCollection-iterate><code>iterate()</code></dfn> method must invoke its
+  <code><a href=#portcollectioncallback>PortCollectionCallback</a></code> argument once for each <code><a href=#messageport>MessagePort</a></code> object in the
+  object's <a href=#concept-portcollection-list title=concept-PortCollection-list>list of ports</a>, in the order defined
+  above, with each invocation being passed the corresponding <code><a href=#messageport>MessagePort</a></code> object as the
+  callback's sole argument.</p>
+
+  </div>
+
+
+  <h4 id=ports-and-garbage-collection><span class=secno>10.5.5 </span>Ports and garbage collection</h4>
+
   <div class=impl>
 
   <p>When a <code><a href=#messageport>MessagePort</a></code> object <var title="">o</var> is
@@ -86716,23 +86814,25 @@
   <!-- ports in the ports attribute of a MessageEvent that isn't
   dispatched yet are safe because the MessageEvent is safe -->
 
+  <p>There are no strong references from a <code><a href=#portcollection>PortCollection</a></code> object to its
+  <code><a href=#messageport>MessagePort</a></code> objects. (That is in fact the whole point of <code><a href=#portcollection>PortCollection</a></code>
+  objects: they allow for <code><a href=#messageport>MessagePort</a></code> objects to be referenced without preventing them
+  from being garbage collected.)</p>
+
   </div>
 
-  <p class=note>Authors are strongly encouraged to explicitly close
-  <code><a href=#messageport>MessagePort</a></code> objects to disentangle them, so that their
-  resources can be recollected. Creating many <code><a href=#messageport>MessagePort</a></code>
-  objects and discarding them without closing them can lead to high
-  memory usage.</p>
+  <p class=note>Authors are strongly encouraged to explicitly close <code><a href=#messageport>MessagePort</a></code>
+  objects to disentangle them, so that their resources can be recollected. Creating many
+  <code><a href=#messageport>MessagePort</a></code> objects and discarding them without closing them can lead to high
+  transient memory usage since garbage collection is not necessarily performed promptly.</p>
 
 
 
-  </div><!--data-component-->
 
 
 
 
 
-
   <div data-component="Web Storage (editor: Ian Hickson)"><!--TOPIC:Web Storage-->
 
   <h2 id=webstorage><span class=secno>11 </span>Web storage</h2>
@@ -105193,6 +105293,7 @@
    <li><code><a href=#pagetransitionevent>PageTransitionEvent</a></code>
    <li><code><a href=#path>Path</a></code>
    <li><code><a href=#popstateevent>PopStateEvent</a></code>
+   <li><code><a href=#portcollection>PortCollection</a></code>
    <li><code><a href=#propertynodelist>PropertyNodeList</a></code>
    <li><code><a href=#radionodelist>RadioNodeList</a></code>
    <li><code><a href=#sharedworker>SharedWorker</a></code>

Modified: index
===================================================================
--- index	2012-11-02 01:35:37 UTC (rev 7501)
+++ index	2012-11-02 22:32:30 UTC (rev 7502)
@@ -248,7 +248,7 @@
 
   <header class=head id=head><p><a class=logo href=http://www.whatwg.org/><img alt=WHATWG height=101 src=/images/logo width=101></a></p>
    <hgroup><h1 class=allcaps>HTML</h1>
-    <h2 class="no-num no-toc">Living Standard — Last Updated 1 November 2012</h2>
+    <h2 class="no-num no-toc">Living Standard — Last Updated 2 November 2012</h2>
    </hgroup><dl><dt><strong>Web developer edition:</strong></dt>
     <dd><strong><a href=http://developers.whatwg.org/>http://developers.whatwg.org/</a></strong></dd>
     <dt>Multiple-page version:</dt>
@@ -1102,9 +1102,9 @@
        <li><a href=#ports-as-the-basis-of-an-object-capability-model-on-the-web><span class=secno>10.5.1.2 </span>Ports as the basis of an object-capability model on the Web</a></li>
        <li><a href=#ports-as-the-basis-of-abstracting-out-service-implementations><span class=secno>10.5.1.3 </span>Ports as the basis of abstracting out service implementations</a></ol></li>
      <li><a href=#message-channels><span class=secno>10.5.2 </span>Message channels</a></li>
-     <li><a href=#message-ports><span class=secno>10.5.3 </span>Message ports</a>
-      <ol>
-       <li><a href=#ports-and-garbage-collection><span class=secno>10.5.3.1 </span>Ports and garbage collection</a></ol></ol></ol></li>
+     <li><a href=#message-ports><span class=secno>10.5.3 </span>Message ports</a></li>
+     <li><a href=#broadcasting-to-many-ports><span class=secno>10.5.4 </span>Broadcasting to many ports</a></li>
+     <li><a href=#ports-and-garbage-collection><span class=secno>10.5.5 </span>Ports and garbage collection</a></ol></ol></li>
  <li><a href=#webstorage><span class=secno>11 </span>Web storage</a>
   <ol>
    <li><a href=#introduction-12><span class=secno>11.1 </span>Introduction</a></li>
@@ -85730,14 +85730,13 @@
   </dl></div><!--data-component-->
 
 
-<!--POSTMSG-->
 
 
 
-  <div data-component="Web Messaging (editor: Ian Hickson)"><!--TOPIC:DOM APIs-->
+<!--TOPIC:DOM APIs-->
 
-  
 
+
   <h3 id=web-messaging><span class=secno>10.4 </span><dfn id=crossDocumentMessages>Cross-document messaging</dfn></h3>
 
   <p>Web browsers, for security and privacy reasons, prevent documents
@@ -86680,8 +86679,107 @@
   </div>
 
 
-  <h5 id=ports-and-garbage-collection><span class=secno>10.5.3.1 </span>Ports and garbage collection</h5>
+  <h4 id=broadcasting-to-many-ports><span class=secno>10.5.4 </span>Broadcasting to many ports</h4>
 
+  <p>Broadcasting to many ports is in principle relatively simple: keep an array of
+  <code><a href=#messageport>MessagePort</a></code> objects to send messages to, and iterate through the array to send a
+  message. However, this has one rather unfortuante effect: it prevents the ports from being garbage
+  collected, even if the other side has gone away.</p>
+
+  <p>To avoid this problem, the <code><a href=#portcollection>PortCollection</a></code> object can be used. It acts as an opaque
+  array of <code><a href=#messageport>MessagePort</a></code> objects, thus allowing the objects to be garbage collected when
+  they stop being relevant, while still allowing scripts to iterate over the
+  <code><a href=#messageport>MessagePort</a></code> objects.</p>
+
+  <pre class=idl>[<a href=#dom-portcollection title=dom-PortCollection>Constructor</a>] interface <dfn id=portcollection>PortCollection</dfn> {
+  void <a href=#dom-portcollection-add title=dom-PortCollection-add>add</a>(<a href=#messageport>MessagePort</a> port);
+  void <a href=#dom-portcollection-remove title=dom-PortCollection-remove>remove</a>(<a href=#messageport>MessagePort</a> port);
+  void <a href=#dom-portcollection-clear title=dom-PortCollection-clear>clear</a>();
+  void <a href=#dom-portcollection-iterate title=dom-PortCollection-iterate>iterate</a>(<a href=#portcollectioncallback>PortCollectionCallback</a> callback);
+};
+
+callback <dfn id=portcollectioncallback>PortCollectionCallback</dfn> = void (<a href=#messageport>MessagePort</a> port);</pre>
+
+  <dl class=domintro><dt><var title="">portCollection</var> = new <code title=dom-PortCollection><a href=#dom-portcollection>PortCollection</a></code>()</dt>
+
+   <dd>
+
+    <p>Returns a new empty <code><a href=#portcollection>PortCollection</a></code> object.</p>
+
+   </dd>
+
+   <dt><var title="">portCollection</var> . <code title=dom-PortCollection-add><a href=#dom-portcollection-add>add</a></code>(<var title="">port</var>)</dt>
+
+   <dd>
+
+    <p>Adds <var title="">port</var> to the collection, if it isn't already present.</p>
+
+   </dd>
+
+   <dt><var title="">portCollection</var> . <code title=dom-PortCollection-remove><a href=#dom-portcollection-remove>remove</a></code>(<var title="">port</var>)</dt>
+
+   <dd>
+
+    <p>Removes <var title="">port</var> from the collection, if it is present.</p>
+
+   </dd>
+
+   <dt><var title="">portCollection</var> . <code title=dom-PortCollection-clear><a href=#dom-portcollection-clear>clear</a></code>()</dt>
+
+   <dd>
+
+    <p>Removes all ports from the collection.</p>
+
+   </dd>
+
+   <dt><var title="">portCollection</var> . <code title=dom-PortCollection-iterate><a href=#dom-portcollection-iterate>iterate</a></code>(<var title="">callback</var>)</dt>
+
+   <dd>
+
+    <p>Calls <var title="">callback</var> for each port in the collection.</p>
+
+   </dd>
+
+  </dl><div class=impl>
+
+  <p>A <code><a href=#portcollection>PortCollection</a></code> object has an initially empty <dfn id=concept-portcollection-list title=concept-PortCollection-list>list of ports</dfn>. When a <code><a href=#messageport>MessagePort</a></code> object in
+  a <a href=#concept-portcollection-list title=concept-PortCollection-list>list of ports</a> is garbage collected, it must be
+  silently removed from that <a href=#concept-portcollection-list title=concept-PortCollection-list>list of ports</a>. Objects
+  in a <a href=#concept-portcollection-list title=concept-PortCollection-list>list of ports</a> are ordered chronologically by
+  the time at which they were most recently added; the least-recently added <code><a href=#messageport>MessagePort</a></code>
+  object is the first in the list, and the most-recently added <code><a href=#messageport>MessagePort</a></code> is the last
+  in the list.</p>
+
+  <p>The <dfn id=dom-portcollection title=dom-PortCollection><code>PortCollection()</code></dfn> constructor must return
+  a new <code><a href=#portcollection>PortCollection</a></code> object (with an empty <a href=#concept-portcollection-list title=concept-PortCollection-list>list of ports</a>).</p>
+
+  <p>The <dfn id=dom-portcollection-add title=dom-PortCollection-add><code>add()</code></dfn> method must add the
+  <code><a href=#messageport>MessagePort</a></code> given by the argument to the <code><a href=#portcollection>PortCollection</a></code> object's <a href=#concept-portcollection-list title=concept-PortCollection-list>list of ports</a>, unless the <code><a href=#messageport>MessagePort</a></code> is
+  already in the <a href=#concept-portcollection-list title=concept-PortCollection-list>list of ports</a>, in which case the
+  method does nothing. (Calling this method with a port already in the list does not move the port
+  to the end of the list.)</p>
+
+  <p>The <dfn id=dom-portcollection-remove title=dom-PortCollection-remove><code>remove()</code></dfn> method must remove the
+  <code><a href=#messageport>MessagePort</a></code> given by the argument from the <code><a href=#portcollection>PortCollection</a></code> object's <a href=#concept-portcollection-list title=concept-PortCollection-list>list of ports</a>, unless the <code><a href=#messageport>MessagePort</a></code> is
+  not in the <a href=#concept-portcollection-list title=concept-PortCollection-list>list of ports</a>, in which case the
+  method does nothing.</p>
+
+  <p>The <dfn id=dom-portcollection-clear title=dom-PortCollection-clear><code>clear()</code></dfn> method must remove all
+  <code><a href=#messageport>MessagePort</a></code> objects from the <code><a href=#portcollection>PortCollection</a></code> object's <a href=#concept-portcollection-list title=concept-PortCollection-list>list of ports</a>, returning it to the initial empty state.
+  If the <a href=#concept-portcollection-list title=concept-PortCollection-list>list of ports</a> is already empty, the method
+  does nothing.</p>
+
+  <p>The <dfn id=dom-portcollection-iterate title=dom-PortCollection-iterate><code>iterate()</code></dfn> method must invoke its
+  <code><a href=#portcollectioncallback>PortCollectionCallback</a></code> argument once for each <code><a href=#messageport>MessagePort</a></code> object in the
+  object's <a href=#concept-portcollection-list title=concept-PortCollection-list>list of ports</a>, in the order defined
+  above, with each invocation being passed the corresponding <code><a href=#messageport>MessagePort</a></code> object as the
+  callback's sole argument.</p>
+
+  </div>
+
+
+  <h4 id=ports-and-garbage-collection><span class=secno>10.5.5 </span>Ports and garbage collection</h4>
+
   <div class=impl>
 
   <p>When a <code><a href=#messageport>MessagePort</a></code> object <var title="">o</var> is
@@ -86716,23 +86814,25 @@
   <!-- ports in the ports attribute of a MessageEvent that isn't
   dispatched yet are safe because the MessageEvent is safe -->
 
+  <p>There are no strong references from a <code><a href=#portcollection>PortCollection</a></code> object to its
+  <code><a href=#messageport>MessagePort</a></code> objects. (That is in fact the whole point of <code><a href=#portcollection>PortCollection</a></code>
+  objects: they allow for <code><a href=#messageport>MessagePort</a></code> objects to be referenced without preventing them
+  from being garbage collected.)</p>
+
   </div>
 
-  <p class=note>Authors are strongly encouraged to explicitly close
-  <code><a href=#messageport>MessagePort</a></code> objects to disentangle them, so that their
-  resources can be recollected. Creating many <code><a href=#messageport>MessagePort</a></code>
-  objects and discarding them without closing them can lead to high
-  memory usage.</p>
+  <p class=note>Authors are strongly encouraged to explicitly close <code><a href=#messageport>MessagePort</a></code>
+  objects to disentangle them, so that their resources can be recollected. Creating many
+  <code><a href=#messageport>MessagePort</a></code> objects and discarding them without closing them can lead to high
+  transient memory usage since garbage collection is not necessarily performed promptly.</p>
 
 
 
-  </div><!--data-component-->
 
 
 
 
 
-
   <div data-component="Web Storage (editor: Ian Hickson)"><!--TOPIC:Web Storage-->
 
   <h2 id=webstorage><span class=secno>11 </span>Web storage</h2>
@@ -105193,6 +105293,7 @@
    <li><code><a href=#pagetransitionevent>PageTransitionEvent</a></code>
    <li><code><a href=#path>Path</a></code>
    <li><code><a href=#popstateevent>PopStateEvent</a></code>
+   <li><code><a href=#portcollection>PortCollection</a></code>
    <li><code><a href=#propertynodelist>PropertyNodeList</a></code>
    <li><code><a href=#radionodelist>RadioNodeList</a></code>
    <li><code><a href=#sharedworker>SharedWorker</a></code>

Modified: source
===================================================================
--- source	2012-11-02 01:35:37 UTC (rev 7501)
+++ source	2012-11-02 22:32:30 UTC (rev 7502)
@@ -99711,14 +99711,13 @@
 
   </div><!--data-component-->
 
-<!--START dev-html--><!--START w3c-html-->
-<!--END w3c-html--><!--POSTMSG-->
+<!--START dev-html-->
 
 
 
-  <div data-component="Web Messaging (editor: Ian Hickson)"><!--TOPIC:DOM APIs-->
+<!--TOPIC:DOM APIs-->
 
-  <!--START postmsg-->
+<!--START postmsg-->
 
   <h3 id="web-messaging"><dfn id="crossDocumentMessages">Cross-document messaging</dfn></h3>
 
@@ -100820,10 +100819,118 @@
   </div>
 
 
-  <h5>Ports and garbage collection</h5>
+  <h4>Broadcasting to many ports</h4>
 
+  <p>Broadcasting to many ports is in principle relatively simple: keep an array of
+  <code>MessagePort</code> objects to send messages to, and iterate through the array to send a
+  message. However, this has one rather unfortuante effect: it prevents the ports from being garbage
+  collected, even if the other side has gone away.</p>
+
+  <p>To avoid this problem, the <code>PortCollection</code> object can be used. It acts as an opaque
+  array of <code>MessagePort</code> objects, thus allowing the objects to be garbage collected when
+  they stop being relevant, while still allowing scripts to iterate over the
+  <code>MessagePort</code> objects.</p>
+
+  <pre class="idl">[<span title="dom-PortCollection">Constructor</span>] interface <dfn>PortCollection</dfn> {
+  void <span title="dom-PortCollection-add">add</span>(<span>MessagePort</span> port);
+  void <span title="dom-PortCollection-remove">remove</span>(<span>MessagePort</span> port);
+  void <span title="dom-PortCollection-clear">clear</span>();
+  void <span title="dom-PortCollection-iterate">iterate</span>(<span>PortCollectionCallback</span> callback);
+};
+
+callback <dfn>PortCollectionCallback</dfn> = void (<span>MessagePort</span> port);</pre>
+
+  <dl class="domintro">
+
+   <dt><var title="">portCollection</var> = new <code title="dom-PortCollection">PortCollection</code>()</dt>
+
+   <dd>
+
+    <p>Returns a new empty <code>PortCollection</code> object.</p>
+
+   </dd>
+
+   <dt><var title="">portCollection</var> . <code title="dom-PortCollection-add">add</code>(<var title="">port</var>)</dt>
+
+   <dd>
+
+    <p>Adds <var title="">port</var> to the collection, if it isn't already present.</p>
+
+   </dd>
+
+   <dt><var title="">portCollection</var> . <code title="dom-PortCollection-remove">remove</code>(<var title="">port</var>)</dt>
+
+   <dd>
+
+    <p>Removes <var title="">port</var> from the collection, if it is present.</p>
+
+   </dd>
+
+   <dt><var title="">portCollection</var> . <code title="dom-PortCollection-clear">clear</code>()</dt>
+
+   <dd>
+
+    <p>Removes all ports from the collection.</p>
+
+   </dd>
+
+   <dt><var title="">portCollection</var> . <code title="dom-PortCollection-iterate">iterate</code>(<var title="">callback</var>)</dt>
+
+   <dd>
+
+    <p>Calls <var title="">callback</var> for each port in the collection.</p>
+
+   </dd>
+
+  </dl>
+
   <div class="impl">
 
+  <p>A <code>PortCollection</code> object has an initially empty <dfn
+  title="concept-PortCollection-list">list of ports</dfn>. When a <code>MessagePort</code> object in
+  a <span title="concept-PortCollection-list">list of ports</span> is garbage collected, it must be
+  silently removed from that <span title="concept-PortCollection-list">list of ports</span>. Objects
+  in a <span title="concept-PortCollection-list">list of ports</span> are ordered chronologically by
+  the time at which they were most recently added; the least-recently added <code>MessagePort</code>
+  object is the first in the list, and the most-recently added <code>MessagePort</code> is the last
+  in the list.</p>
+
+  <p>The <dfn title="dom-PortCollection"><code>PortCollection()</code></dfn> constructor must return
+  a new <code>PortCollection</code> object (with an empty <span
+  title="concept-PortCollection-list">list of ports</span>).</p>
+
+  <p>The <dfn title="dom-PortCollection-add"><code>add()</code></dfn> method must add the
+  <code>MessagePort</code> given by the argument to the <code>PortCollection</code> object's <span
+  title="concept-PortCollection-list">list of ports</span>, unless the <code>MessagePort</code> is
+  already in the <span title="concept-PortCollection-list">list of ports</span>, in which case the
+  method does nothing. (Calling this method with a port already in the list does not move the port
+  to the end of the list.)</p>
+
+  <p>The <dfn title="dom-PortCollection-remove"><code>remove()</code></dfn> method must remove the
+  <code>MessagePort</code> given by the argument from the <code>PortCollection</code> object's <span
+  title="concept-PortCollection-list">list of ports</span>, unless the <code>MessagePort</code> is
+  not in the <span title="concept-PortCollection-list">list of ports</span>, in which case the
+  method does nothing.</p>
+
+  <p>The <dfn title="dom-PortCollection-clear"><code>clear()</code></dfn> method must remove all
+  <code>MessagePort</code> objects from the <code>PortCollection</code> object's <span
+  title="concept-PortCollection-list">list of ports</span>, returning it to the initial empty state.
+  If the <span title="concept-PortCollection-list">list of ports</span> is already empty, the method
+  does nothing.</p>
+
+  <p>The <dfn title="dom-PortCollection-iterate"><code>iterate()</code></dfn> method must invoke its
+  <code>PortCollectionCallback</code> argument once for each <code>MessagePort</code> object in the
+  object's <span title="concept-PortCollection-list">list of ports</span>, in the order defined
+  above, with each invocation being passed the corresponding <code>MessagePort</code> object as the
+  callback's sole argument.</p>
+
+  </div>
+
+
+  <h4>Ports and garbage collection</h4>
+
+  <div class="impl">
+
   <p>When a <code>MessagePort</code> object <var title="">o</var> is
   entangled, user agents must either act as if <var title="">o</var>'s
   entangled <code>MessagePort</code> object has a strong reference to
@@ -100856,22 +100963,24 @@
   <!-- ports in the ports attribute of a MessageEvent that isn't
   dispatched yet are safe because the MessageEvent is safe -->
 
+  <p>There are no strong references from a <code>PortCollection</code> object to its
+  <code>MessagePort</code> objects. (That is in fact the whole point of <code>PortCollection</code>
+  objects: they allow for <code>MessagePort</code> objects to be referenced without preventing them
+  from being garbage collected.)</p>
+
   </div>
 
-  <p class="note">Authors are strongly encouraged to explicitly close
-  <code>MessagePort</code> objects to disentangle them, so that their
-  resources can be recollected. Creating many <code>MessagePort</code>
-  objects and discarding them without closing them can lead to high
-  memory usage.</p>
+  <p class="note">Authors are strongly encouraged to explicitly close <code>MessagePort</code>
+  objects to disentangle them, so that their resources can be recollected. Creating many
+  <code>MessagePort</code> objects and discarding them without closing them can lead to high
+  transient memory usage since garbage collection is not necessarily performed promptly.</p>
 
 <!--END postmsg-->
 
-  </div><!--data-component-->
 
+
 <!--END dev-html-->
 
-
-
 <!--FIXUP complete -1-->
 
   <div data-component="Web Storage (editor: Ian Hickson)"><!--TOPIC:Web Storage-->




More information about the Commit-Watchers mailing list