-
Notifications
You must be signed in to change notification settings - Fork 32
Is it appropriate to "transfer" SABs? #98
Comments
The alternative would be to use cloning? If you squint you could maybe see It's true that when formalizing the clone and transfer semantics in https://html.spec.whatwg.org/multipage/infrastructure.html#safe-passing-of-structured-data [[Detached]] being a slot of transferable objects was seen as a primitive so @dherman might be right on the money here. |
I tend to agree that the primary semantic of transferring is that the original object is no longer usable. |
Looking at our code a little more, the original design might have been influenced by how easy it is to implement, since the pointer to the shared memory (a SharedArrayRawBuffer in our code) is put into the transfer map in the same way as a pointer to an ArrayBuffer's buffer memory would be, the only difference is that the SAB is not detached on the sending side. From that point of view, thinking of passing a SAB as a transfer is highly appropriate, and detaching is a separate operation that is not implied by transfering. (Just observing, not judging.) |
On the observation front:
|
Yes, there's just no way you can really require non-copying in the absence of observable concurrent side effects or certain leaky abstractions (eg revealing memory addresses might make it hard to copy but probably not impossible). (For new listeners the issue at hand is browsers with process separation; if an ArrayBuffer is transfered from one agent to another but the agents are in two separate processes, the implementation will most likely wish to copy the memory and not implement cross-process shared memory.) |
NaCl is in a separate process, so it copies things over, JS just does It seems like something similar applies to SAB if transfer implies original users can't access the SAB anymore: all users have to call in before this can be completed. |
I would think that two agents, separated by a boundary over which they cannot coherently share mapped pages, would therefore be in two separate agent clusters. Indeed, I thought the main motivation for defining agent clusters is to surface this implementation issue when coherent mapped sharing is impossible. Note that on most operating systems, processes can coherently share mapped pages. So process separation itself should not necessarily force agent cluster separation. OTOH, two agents running in two separate machines without coherent shared memory (ironically, let's say, in a cluster) would necessarily be in two different agent clusters. This issue has also shown up within a "machine" in some historic multicore designs, like the Transputer or the IBM Cell processor. As the number of cores on a chip explodes, we should not expect coherent sharing to scale. |
When I raised the issue of detaching SABs in the hope of safely terminating agents without terminating the whole agent cluster, at #55 (comment) @lukewagner said:
Does this hazard apply with just as much force to detachment-on-transfer? (I would expect it does) |
Before this discussion veers off course irretrievably, let me try to rein it in: The only thing I want resolved in this bug is whether, when a SAB is sent from one agent to another in an HTML embedding, one needs to write In particular, this discussion has nothing to do with agent clusters, or whether something can or cannot be copied or anything like that, and I apologize for nibbling at @annevk's bait in this regard. I can only blame myself. Please open new bugs for all other questions, or followup in existing bugs. EDIT: corrected embarrassing typo. |
To try to close this loop. I think |
I tend to agree with @domenic. @lars-t-hansen made an argument in #98 (comment) based on code, but presumably the code for |
And I think I agree with both @annevk and @domenic. @binji, do you have any opinions about this? Personally I'm happy to defer to the folk who are closer to HTML than me, but good if we are all known to agree before we jump. (This is outside the ES spec proper in any case but me or Anne will need to shepherd it through the appropriate channels.) |
Well, as @lars-t-hansen mentioned, the code is nicer if the SAB is in the transfer list. The behaviors are very similar, when an ArrayBuffer (shared or otherwise) is not in the transfer list, the data is copied, so that code doesn't have to change. When it is in the transfer list, in both cases only the pointer is copied. The only difference is whether the original is detached or not. I took a look at the way it's done for blobs, and it is similar. They just store a list of blob indexes and blob handles, then extract that. The difference is that we'll want to share the logic for transferring ArrayBuffers and sharing SharedArrayBuffers. This isn't an issue with blobs, since they can't be transferred. Not a big deal, but the code will be a little nastier, I suspect. I guess that's another question: if we make this change, I assume SharedArrayBuffers will not be allowed to be transferred since they can't be detached. Is that right? This also means that if you did want to send a copy of a SAB (for some reason), you'd have to copy the data to an ArrayBuffer, send it, then copy the new ArrayBuffer to a new SAB. Probably not too much of a problem, as it's hard to imagine why you'd want to copy a SAB in the first place. |
If copying became desired, we could add cloning support to SAB, no? And yeah, you cannot transfer objects that cannot be detached at the moment. |
@annevk I don't think so, because by deciding that |
I meant with a new API. Same as we would have to do for blobs. |
The buffer no longer goes in the transfer list, see Issue #98.
This matter was resolved a while back: the SAB should not be in the transfer list, and a DataCloneError should be thrown if it is. The change has been recorded in the canonical DOM companion spec, https://tc39.github.io/ecmascript_sharedmem/dom_shmem.html#postMessage. |
@domenic @annevk
This came up in a discussion with @dherman: Is it appropriate for SABs to be sent from one agent to another with the structured clone transfer mechanism (as we have now) or without it? It turns out he and I have different intuitions about what is entailed by "transfer". To me it it entails "don't deep copy". To Dave it entails "detach the buffer, don't share it". Clearly, for ArrayBuffer both intuitions hold.
I don't know precisely how we came to this point where a SAB must be in the transfer list. Judging from our Mercurial log I inherited the mechanism with the prototype code I took over from @sstangl, and given my intuition about structured clone I always thought it was a reasonable choice. I don't know if there's any deeper background, eg, a design that comes from PNaCl for example.
Another justification that comes up from time to time is that having to add a SAB to the transfer map makes it easier to guarantee that a SAB is never shared accidentally. I happen to think that's a benefit, but not if it runs counter to some generally agreed-upon aspect of transfering. (Nobody's raised any flags before now.)
The text was updated successfully, but these errors were encountered: