HTML Standard Tracker

Filter

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
@@ -99704,28 +99704,27 @@ dictionary <dfn>CloseEventInit</dfn> : <span>EventInit</span> {
 
    </dd>
 
   </dl>
 
 
 <!--END websocket-api-->
 
   </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>
 
   <p>Web browsers, for security and privacy reasons, prevent documents
   in different domains from affecting each other; that is, cross-site
   scripting is disallowed.</p>
 
   <p>While this is an important security feature, it prevents pages
   from different domains from communicating even when those pages are
   not hostile. This section introduces a messaging system that allows
@@ -100813,21 +100812,129 @@ interface <dfn>MessageChannel</dfn> {
 
   <p>The first time a <code>MessagePort</code> object's <code
   title="handler-MessagePort-onmessage">onmessage</code> IDL attribute
   is set, the port's <span>port message queue</span> must be enabled,
   as if the <code title="dom-MessagePort-start">start()</code> method
   had been called.</p>
 
   </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
   <var title="">o</var>, or as if <var title="">o</var>'s owner has a
   strong reference to <var title="">o</var>.</p>
 
   <div class="note">
@@ -100849,35 +100956,37 @@ interface <dfn>MessageChannel</dfn> {
   <code>MessagePort</code> object, or while the
   <code>MessagePort</code> object's <span>port message queue</span> is
   open and there exists a <code title="event-message">message</code>
   event in that queue.</p>
   <!-- we might not need to explicitly say the first part if DOM
   Events is fixed to say that events on a task queue prevent GC -->
 
   <!-- 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-->
 
 
+<!--END dev-html-->
 
 <!--FIXUP complete -1-->
 
   <div data-component="Web Storage (editor: Ian Hickson)"><!--TOPIC:Web Storage-->
 
   <h3 id="webstorage">Web storage</h3>
 
 <!--START storage-->
 
   <h4>Introduction</h4>

|