I understand that transferring objects to a Web Worker causes the main thread to lose ownership. I am wondering if there is any way for it to regain ownership. This Plunker (code below) demonstrates the issue I am having.
main.js
var worker = new Worker("worker.js");
var z = new Int16Array(10);
worker.onmessage = function(e) {
console.log(e.data); // [0, 1, ... 10]
console.log(z); // [], ownership not regained here
}
console.log(z); // [0, 0, ... 0], original value here
worker.postMessage(z, [z.buffer]);
console.log(z); // [], ownership lost here
worker.js
self.onmessage = function(e) {
var data = e.data; // transferred "z" from main.js
for (var i = 0; i < 10; i++) {
data[i] = i;
}
// I thought this would return ownership back to the main thread
self.postMessage(data, [data.buffer]);
}
Essentially, the end goal is to change the value of z
in the main thread from within the worker thread, without having to copy the results in the main thread after the message is received. However, it seems that the ownership of z
is retained by the worker. Am I misunderstanding something? Is there a way to accomplish this?
Any suggestions are greatly appreciated.
No, it doesn't work like that. The Int16Array
is just an interface wrapping over ArrayBuffer
, which is where the real binary data are stored. When you transfer the ownership, the Int16Array
is invalidated (set to 0 length). In your worker, new Int16Array
is created and assigned to the old ArrayBuffer
. I crated this image for you:
ArrayBuffer
) is serialized to Structured clone, array buffer is transferedInt16Array
object has no longer a buffer and therefore is invalidInt16Array
instance, this instance receives transferred ArrayBufferObviously, interpreter cannot have an idea that you returned the ArrayBuffer
back, so the typed array remains invalid forever.