HTML Standard Tracker

Diff (omit for latest revision)
Filter

Short URL: http://html5.org/r/7502

File a bug

SVNBugCommentTime (UTC)
7502[Gecko] [Internet Explorer] [Opera] [Webkit] Provide a way for authors to broadcast to many ports without memory leaks.2012-11-02 22:32
Index: source
===================================================================
--- source	(revision 7501)
+++ source	(revision 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-->

|