- From: Glenn Maynard <glenn@zewt.org>
- Date: Tue, 13 Dec 2011 16:11:19 -0500
- To: Charles Pritchard <chuck@jumis.com>
- Cc: Dmitry Lomov <dslomov@chromium.org>, Rick Waldron <waldron.rick@gmail.com>, Webapps WG <public-webapps@w3.org>
- Message-ID: <CABirCh_UJf0AJPOTHONzWSezXGc6tcT5zk3XzXNixn_dNkCocg@mail.gmail.com>
On Tue, Dec 13, 2011 at 3:30 PM, Charles Pritchard <chuck@jumis.com> wrote: > On 12/13/11 11:11 AM, Dmitry Lomov wrote: > >> worker.postMessage({p:port, ab:arrayBuffer}, [post, arrayBuffer]) >> work. Therefore this extension to postMessage semantics is both >> backwards-compatible and consistent. On the receiving side, the 'ports' >> property of event object will still contain only the message ports from the >> transfer list, so that behavior is preserved as well. >> > > What's the behavior if an array buffer or port is not on the > transferrables list? > For example: worker.postMessage({p:port, ab:arrayBuffer}) > If a port is in the first argument but not listed in transfer, DATA_CLONE_ERR will be thrown by the structured clone algorithm when it encounters the MessagePort in step 3 of the internal structured clone algorithm. This doesn't happen when the port is listed for transfer, because the MessagePort will already be in *memory* when step 1 encounters it ("If input is the source object..."). What matters to users here is that structured clone itself is always a const operation; it never modifies its arguments. If you say postMessage({obj: opaqueObject}), where opaqueObject is provided by a third-party library, you never have to worry that postMessage (or IndexedDB, or History, etc.) might modify the object and break the library. It can only modify things that you explicitly list in transfer. This helps future API expansion as well: transfer support can be added to more objects in the future, without breaking existing code by causing unexpected new side-effects. (ArrayBuffers will simply be copied by default, since they support structured clone.) > The clone example you posted makes sense: > > worker.postMessage({p:port, ab:arrayBuffer}, [post, arrayBuffer]) > > If transferrables is supported, it'll ensure the vars are neutered and > referenced appropriately, and if they aren't supported, it'll still pass a > copy of array buffer through the message data. > Pre-Transferable implementations will throw here, since they only allow MessagePort in MessagePortArray. If you want to use transfer while falling back to copies for old browsers, you'll need to jump a few extra hoops (eg. filter objects that aren't instances of Transferable yourself). -- Glenn Maynard
Received on Tuesday, 13 December 2011 21:11:56 UTC