[webkit-dev] Passing data structures through postMessage()

Darin Fisher darin at google.com
Fri Sep 11 11:06:22 PDT 2009


I see.  Thanks, yeah... I misremembered how ImageData works :-/-Darin

On Fri, Sep 11, 2009 at 11:03 AM, Drew Wilson <atwilson at google.com> wrote:

> 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/7753f65f/attachment.html>


More information about the webkit-dev mailing list