[whatwg] Sending MessagePorts after they have started
ian at hixie.ch
Mon Dec 15 17:37:54 PST 2008
On Thu, 13 Nov 2008, Jonas Sicking wrote:
> It is currently possible (I think) to send a port through postMessage
> after the port was started. This makes sending ports across processes
> (such as to an iframe or worker living in a different process) pretty
> painful to implement. It also makes it hard to define without causing
> race conditions.
The implementation strategy you describe does indeed seem like it would be
all kinds of pain to set up. However, it isn't the only strategy available
and indeed I think some of the other strategies are more appropriate here.
Some of these other strategies include:
* Using a Unix socket, Windows mailslot, or other communication mechanism
that is buffered, asynchronous, and can be passed between processes.
With such a mechanism, when passing a port from one process or thread
to another, the source thread would just post an event to the
destination thread, and stop reading from the underlying pipe. The
receiving thread would then receive the event, and only when it was
ready to process a message from the pipe would it read from it -- if
the pipe was sent to be sent to another thread first, then it might in
fact never read from the pipe. Meanwhile, the other end of the pipe,
the thread with the other port, need not know any of this, and can be
writing to the pipe without worrying about messages getting lost.
* Shared memory for the ports. Similar to the above strategy, one could
have a block of shared memory for each direction, with in each
direction one side being responsible for adding messages and marking
them new, and the other side being responsible for removing messages
and marking them read.
* Proxying all messages through a single master message controller
thread. Instead of posting messages straight to the destination thread,
each cross-thread or cross-process pair of ports would have its
end-points registered with a single controlling thread or process.
Messages would then be sent to that thread/process, which would keep
them buffered while a port was being bounced around, and would only
actually send messages to the final destination when it was ready.
> There are alternative implementation strategies. The simplest one is
> probably to never tell the other end when a port is moved, instead set
> up a permanent proxy and forward all message through the full chain of
> processes that the ports have passed through. Another strategy is to
> require that each message is acknowledged and resend messages if a port
> end was retangled before the message got processed.
Yes, if IPC absolutely _must_ be done over cross-thread IPC without any
sort of separate message channel to represent the pairs of ports, these
are other options.
> It's also hard to specify this without race conditions since you have to
> deal with the situation that a port has been retangled after a message
> was queued for it to fire against the port.
Good point. Fixed.
I also dropped MessagePort.onclose which had all kinds of weird race
conditions. Currently the only way to know if a port is not entangled is
to change its |active| attribute.
> To fix all this I propose that if a port has been started, we don't
> allow it to be passed to postMessage. If that is done an exception is
This seems like it unnecessarily limits the power of message channels.
What if you want to receive a message, and then defer to another thread if
the message you receive is one asking for a particularly time-consuming
process, but not if it is something simple?
Ian Hickson U+1047E )\._.,--....,'``. fL
http://ln.hixie.ch/ U+263A /, _.. \ _\ ;`._ ,.
Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
More information about the whatwg