[webkit-dev] Passing data structures through postMessage()
Drew Wilson
atwilson at google.com
Fri Sep 11 11:03:38 PDT 2009
Note that ImageData is cloned/copied when sent via postMessage(). So you end
up with a copy of the ImageData, obviating the need for locks.
I think (per my private mail to Darin which I'm restating here) that the use
case is doing some kind of raytracing or something in a Worker, posting the
result to a page, then blitting the result back to the canvas via
putImageData().
-atw
On Fri, Sep 11, 2009 at 10:54 AM, Darin Fisher <darin at google.com> wrote:
> On Thu, Sep 10, 2009 at 5:21 PM, Maciej Stachowiak <mjs at apple.com> wrote:
>
>>
>> On Sep 10, 2009, at 3:12 PM, Chris Campbell wrote:
>>
>> Hi All,
>>>
>>> I had it in mind to implement support for passing data structures
>>> through postMessage() using the "structured clone" algorithm laid out
>>> in the HTML5 spec:
>>>
>>> http://dev.w3.org/html5/spec/Overview.html#posting-messages
>>>
>>> http://dev.w3.org/html5/spec/Overview.html#safe-passing-of-structured-data
>>>
>>> I've had some brief discussion with Dave Levin and Drew Wilson on
>>> #chromium IRC about this, and have an approach in mind that follows
>>> and elaborates on their suggestions, but there are still some holes in
>>> it and I'd very much like input from people familiar with this area.
>>>
>>> Currently, there are several postMessage() handlers (in
>>> MessagePort.idl, DOMWindow.idl, DedicatedWorkerContext.idl, and
>>> Worker.idl), and they all take a DOMString for the message parameter.
>>>
>>> The general idea is to change that message parameter from a DOMString
>>> to a new AttributeIterator type that allows walking of any sort of JS
>>> structure/type. AttributeIterator would essentially be an adapter to
>>> translate native V8 or JSC JavaScript objects to an agnostic interface
>>> suitable for walking the structure and serializing it. I'm thinking
>>> it would look something like this:
>>>
>>> interface AttributeIterator {
>>> bool isUndefined();
>>> bool isNull();
>>> bool isFalse();
>>> bool isTrue();
>>> bool isNumber();
>>> String getNumber();
>>> bool isString();
>>>
>>> // ... cover the other types including Date, RegExp, ImageData,
>>> // File, FileData, and FileList ...
>>>
>>> // Retrieve the key for the next property (for Objects and Arrays)
>>> String nextEnumerableProperty();
>>>
>>> AttributeIterator getPropertyValue(key);
>>> }
>>>
>>
>> Some thoughts off the cuff:
>>
>> I think it would be better to write custom code for doing the cloning for
>> each JS engine. For one thing, turning everything into a string is not
>> necessarily the most efficient way to do things. It might be possible to
>> clone the object graph more directly in a threadsafe way. Also, things like
>> File and ImageData fundamentally can't be turned into a string (well
>> ImageData can)
>>
>
> What does it mean to send a File along? Isn't that just a reference to a
> file? A handle of sorts. It seems like that is something that can be
> passed between threads easily enough.
>
> What is the use case for sending ImageData? It seems like it could be to
> allow a worker to modify the pixels of a canvas or it could be to share a
> separate copy of the data (copy-on-write). It may be undesirable to make
> the canvas have to support having its data be modified by a background
> thread / background process.
>
> -Darin
>
>
>
>>
>> Second, to be really agnostic about it, postMessage should take a generic
>> Message object that has some methods that can be used to do the cross-thread
>> clone without building in the assumption that it serializes to a string in
>> the middle.
>>
>> Third, using a stateful iterator for this instead of an interface
>> representing a value is not a great design. Iterators are not good when what
>> you are traversing is in general a graph.
>>
>> Fourth, this doesn't give a way to detect if an object graph is not in
>> fact legal to clone.
>>
>> It's kind of a shame that we have the baggage of multiple JavaScript
>> engines to contend with. Trying to do things in a generic way will make this
>> task needlessly more difficult.
>>
>> You may also want to get input on this from Oliver Hunt, who wrote the JSC
>> JSON parse/stringify code; from past discussions I know has opinions on how
>> cross-thread cloning should work.
>>
>>
>>
>>>
>>> I'm also thinking that depending on compile-time flags, the
>>> contstructor for AttributeIterator would either take a
>>> v8::Handle<v8::Value> or JSC::JSvalue value.
>>>
>>> Then in each implementation of postMessage() the AttributeIterator
>>> instance could be passed to the structured clone serializer, which
>>> would return a string. Thereafter, no changes would be required to
>>> WebCore internals since they already pass strings around... until on
>>> the receiving end we get to MessageEvent.data where we would do the
>>> deserialization in a custom getter.
>>>
>>>
>>> Open questions:
>>>
>>> (1) Is passing an AttributeIterator type into postMessage() really the
>>> best way to go? Drew mentioned that this might incur a bunch of ObjC
>>> binding work on the JSC side...
>>>
>>> (2) Where should AttributeIterator live in the source tree?
>>>
>>> (3) Where should the serialization and deserialization routines live
>>> in the source tree?
>>>
>>> (3) I haven't addressed the specifics of the serialized string format.
>>> Plain JSON is not quite sufficient since it doesn't retain type
>>> information for Date, RegExp, etc.. However, I'm not too worried
>>> about coming up with a suitable format for this.
>>>
>>>
>>> Comments, advice, admonitions welcome! :)
>>>
>>
>> In general I'm not sure this approach is workable. At the very least File,
>> FileData, FileList and ImageData need to be passed as something other than
>> strings. And I think the value of making the object graph traversal code
>> generic while everything else is JS-engine-specific is pretty low. In
>> addition, I do not think the proposed interface is adequate to implement the
>> cloning algorithm.
>>
>> Regards,
>> Maciej
>>
>>
>>
>> _______________________________________________
>> webkit-dev mailing list
>> webkit-dev at lists.webkit.org
>> http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev
>>
>
>
> _______________________________________________
> webkit-dev mailing list
> webkit-dev at lists.webkit.org
> http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.webkit.org/pipermail/webkit-dev/attachments/20090911/0275d473/attachment.html>
More information about the webkit-dev
mailing list