Following up on this issue:<div><br></div><div><span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; border-collapse: collapse; ">Currently, the checks specified for MessagePort.postMessage() are different from the checks done in window.postMessage() (as described in section 7.2.4 "Posting messages with message ports").<div>
<br></div><div>In particular, step 4 of section 7.2.4 says:</div><div><br></div><div><span style="font-family: sans-serif; font-size: medium; ">If any of the entries in <var title="">ports</var> are null, <b>if any of the entries in </b><var title=""><b>ports</b></var><b> are not entangled </b><code style="font-size: inherit; font-family: monospace; font-variant: normal; color: rgb(255, 69, 0); "><a href="#1232afb852169a6e_1232af4ce8d86de7_messageport" style="color: inherit; background-repeat: initial; background-color: transparent; "><b>MessagePort</b></a></code><b> objects</b>, or if any <code style="font-size: inherit; font-family: monospace; font-variant: normal; color: rgb(255, 69, 0); "><a href="#1232afb852169a6e_1232af4ce8d86de7_messageport" style="color: inherit; background-repeat: initial; background-color: transparent; ">MessagePort</a></code> object is listed in <var title="">ports</var> more than once, then throw an <code style="font-size: inherit; font-family: monospace; font-variant: normal; color: rgb(255, 69, 0); "><a href="http://infrastructure.html#invalid_state_err" target="_blank" style="color: inherit; background-repeat: initial; background-color: transparent; ">INVALID_STATE_ERR</a></code> exception.</span></div>
<div><br></div><div>The spec for MessagePort.postMessage() does not throw an exception if any of the entries in ports are not entangled (per this thread). We should probably update the spec for window.postMessage() to define the same behavior there as well.</div>
<div><br></div><div>Also, as written, the spec now incorrectly lets us send a cloned port multiple times. So code like this would not generate an error:</div><div><br></div><div>var channel = new MessageChannel();</div><div>
otherWindow.postMessage("message1", channel.port1);</div><div>otherWindow.postMessage("message2", channel.port1);   // Sent the same port again</div><div><br></div><div>The current WebKit behavior is to throw an INVALID_STATE_ERR in this case, while still allowing closed ports to be sent, which I believe is the intended behavior based on previous discussions. If this is correct, we should update the spec to prohibit resending cloned ports.</div>
<div><br></div><div>-atw</div></span><br><div class="gmail_quote">On Thu, Jun 4, 2009 at 10:30 AM, Drew Wilson <span dir="ltr"><<a href="mailto:atwilson@google.com">atwilson@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Hi all,<div><br></div><div>I'd like to propose a change to the spec for postMessage(). Currently the spec reads:</div><div><br></div><div><span style="font-family:-webkit-sans-serif;font-size:16px;color:rgb(0, 128, 0);line-height:21px">Throws an <code style="font-size:inherit;font-family:monospace;font-variant:normal;color:rgb(255, 69, 0)"><a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/infrastructure.html#invalid_state_err" style="color:inherit;background-repeat:initial;background-color:transparent" target="_blank">INVALID_STATE_ERR</a></code> if the <var title="">ports</var> array is not null and it contains either null entries, duplicate ports, or ports that are not entangled.</span></div>

<div><br></div><div>I'd like to suggest that we allow sending ports that are not entangled (i.e. ports that have been closed) - the rationale is two-fold:</div><div><br></div><div>1) We removed MessagePort.active because it exposes details about garbage collection (i.e. an application could determine whether the other side of a MessagePort was collected or not based on testing the "active" attribute of a port). Throwing an exception in postMessage() is the same thing - it provides details about whether the other end of the port has been collected.</div>

<div><br></div><div>2) Imagine the following scenario: Window W has two workers, A and B. Worker A wants to send a set of messages to Worker B by queuing those messages on a MessagePort, then asking Window W to forward that port to Worker B:</div>

<div><br></div><div>Window W code:</div><div><br></div><div>  workerA.onmessage(evt) {</div><div>    if (evt.data == "forward") {</div><div>        // Currently this would throw an exception if the passed port is closed/unentangled.</div>

<div>        workerB.postMessage("messageFromA", evt.ports);</div><div>    }</div><div>  }</div><div><br></div><div>Worker A code:</div><div><br></div><div>function sendMessagesToB() {</div><div>    var channel = new MessageChannel();</div>

<div>    channel.port1.postMessage("message 1");</div><div>    channel.port1.postMessage("message 2");</div><div>    channel.port1.postMessage("message 3");</div><div>    // Send port to worker B via Window W</div>

<div>    postMessage("forward", [channel.port2]);</div><div>}</div><div><br></div><div>Now Worker A is done with its port - it wants to close the port. But it can't safely do so until it knows that Window W has forwarded the port to Worker B, so it needs to build in some kind of "ack" mechanism to know when it's safe to close the port. Even worse, what if Worker A wants to shut down - it can't safely shut down until it knows that its message has been delivered, because the port would get closed when the owner closes.</div>

<div><br></div><div>Since the port still acts as a task source even when it is closed, there seems to be no reason not to allow passing unentangled ports around - it's a reasonable way to represent a set of messages. And if you think about it, there's no reason why this is allowed:</div>

<div><br></div><div>postMessage("msg", port)</div><div>port.close()</div><div><br></div><div>while this is prohibited:</div><div><br></div><div>port.close();</div><div>postMessage("msg", port);</div><div>

<br></div><div>Given that in both cases the port will almost certainly be closed before the message is delivered to the target.</div><div><br></div><div>-atw</div><div><br></div><div><br></div><div><br></div>
</blockquote></div><br></div>