This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 13799 - Should Transferables be transfered even when postMessage fails?
Summary: Should Transferables be transfered even when postMessage fails?
Status: RESOLVED FIXED
Alias: None
Product: WebAppsWG
Classification: Unclassified
Component: Web Messaging (editor: Ian Hickson) (show other bugs)
Version: unspecified
Hardware: PC Windows NT
: P2 normal
Target Milestone: ---
Assignee: Ian 'Hixie' Hickson
QA Contact: public-webapps-bugzilla
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-08-16 23:48 UTC by Travis Leithead [MSFT]
Modified: 2011-10-20 01:41 UTC (History)
5 users (show)

See Also:


Attachments

Description Travis Leithead [MSFT] 2011-08-16 23:48:43 UTC
Currently, in the algorithm for postMessage, step 4.2 (which occurs before the structured clone takes place) it says:

4.If the method was invoked with a third argument transfer, run these substeps:
  2. If the transfer argument is present, then for each object in transfer in turn, obtain a new object by transferring the object to the Window object on which the method was invoked, and add a mapping from the old object to the new transferred object to transfer map. If the objects are MessagePort objects, also append the new transferred object to the new ports array.

Under these conditions, it implies that in the event of a postMessage DATA_CLONE_ERR, the transfer-of-ownership will already have taken place, making the objects useless (to exception-handling code).

This seems bad to lose the transferred items in this way.

If this is the intent, please add a note making this explicit.

Otherwise, please adjust the algorithm to perform the transfer at the last-possible moment such that the transfer of ownership only occurs after any possible exceptions have been thrown.
Comment 1 Jonas Sicking (Not reading bugmail) 2011-08-16 23:55:16 UTC
I agree. Usecase would be to optimistically send an object, and if that fails, send a sub-part of it or some such.
Comment 2 Kenneth Russell 2011-09-13 01:26:55 UTC
Given the way transferral interacts with structured clone, it seems that what would be needed to implement this change would be:

1) During the building of the transfer map in these algorithms:

http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#posting-messages
http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#message-ports

only create a placeholder object into the transfer map, but do not actually effect the transfer.

2) Perform the structured clone of the object graph.

3) Actually perform the transfer operation from the source objects into the placeholders.

Personally I'd like to see a change like this. It's currently tricky to specify a situation where other objects refer to those being transferred and need a little "cleanup" after the structured clone completes. The current typed array editor's draft attempts to do this, but I don't know whether I specified it correctly. See https://www.khronos.org/registry/typedarray/specs/latest/ .
Comment 3 Ian 'Hixie' Hickson 2011-10-19 00:49:33 UTC
EDITOR'S RESPONSE: This is an Editor's Response to your comment. If you are satisfied with this response, please change the state of this bug to CLOSED. If you have additional information and would like the editor to reconsider, please reopen this bug. If you would like to escalate the issue to the full HTML Working Group, please add the TrackerRequest keyword to this bug, and suggest title and text for the tracker issue; or you may create a tracker issue yourself, if you are able to do so. For more details, see this document:
   http://dev.w3.org/html5/decision-policy/decision-policy.html

Status: Accepted
Change Description: see diff given below
Rationale: Concurred with reporter's comments.

kbr: I don't understand why you need to do anything to ArrayBufferViews when transferring ArrayBuffers. Just have the ArrayBufferView's byteOffset, byteLength, etc, properties return 0 when the underlying ArrayBuffer has been neutered. (Also, don't forget to actually say that the old ArrayBuffer is neutered — see the HTML spec for MessagePort to see what I mean.) Similarly, in the "Interactions with the Structured Cloning Algorithm" you don't need to have any special case for ArrayBuffer, that's already handled (because it's Transferable), and the code for ArrayBufferView just needs to say that it recurses to the ArrayBuffer (which won't do anything straight away since the new objects are placeholders at this point now) and then creates a new object with the same values, or something like that. Since the actual transfer happens after the cloning, the values don't get zeroed out until after the clone happens — and if you define the ArrayBufferView interface's attributes as returning zero if the buffer is neutered, independent of the cloning algorithm, then you don't have to worry about that happening during cloning either. Ping me if this isn't clear.
Comment 4 contributor 2011-10-19 00:50:00 UTC
Checked in as WHATWG revision r6697.
Check-in comment: Update postMessage() to do the transfers after the cloning so that if cloning fails, the transferables don't get killed.
http://html5.org/tools/web-apps-tracker?from=6696&to=6697
Comment 5 Kenneth Russell 2011-10-20 01:41:24 UTC
> kbr: I don't understand why you need to do anything to ArrayBufferViews when
> transferring ArrayBuffers. Just have the ArrayBufferView's byteOffset,
> byteLength, etc, properties return 0 when the underlying ArrayBuffer has been
> neutered. (Also, don't forget to actually say that the old ArrayBuffer is
> neutered — see the HTML spec for MessagePort to see what I mean.) Similarly,
> in the "Interactions with the Structured Cloning Algorithm" you don't need to
> have any special case for ArrayBuffer, that's already handled (because it's
> Transferable), and the code for ArrayBufferView just needs to say that it
> recurses to the ArrayBuffer (which won't do anything straight away since the
> new objects are placeholders at this point now) and then creates a new object
> with the same values, or something like that. Since the actual transfer happens
> after the cloning, the values don't get zeroed out until after the clone
> happens — and if you define the ArrayBufferView interface's attributes as
> returning zero if the buffer is neutered, independent of the cloning algorithm,
> then you don't have to worry about that happening during cloning either. Ping
> me if this isn't clear.

Thanks, this is clear. The typed array spec at https://www.khronos.org/registry/typedarray/specs/latest/ has been updated to use the neutering concept. It significantly simplifies the specification of the cloning and transferring operations.