- From: Ian Hickson <ian@hixie.ch>
- Date: Tue, 16 Dec 2008 01:37:54 +0000 (UTC)
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 > thrown. 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? Cheers, -- Ian Hickson U+1047E )\._.,--....,'``. fL http://ln.hixie.ch/ U+263A /, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
Received on Monday, 15 December 2008 17:37:54 UTC