From 28e1fceb5020f3224a54b017c2a58c41ba04cc1a Mon Sep 17 00:00:00 2001 From: David Rajchenbach-Teller Date: Wed, 1 Oct 2014 05:28:00 +0200 Subject: [PATCH] Bug 1069577 - Transfering values with a PromiseWorker. r=froydnj --- .../promiseworker/PromiseWorker.jsm | 10 ++++++++-- .../tests/xpcshell/test_Promise.js | 20 +++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/toolkit/components/promiseworker/PromiseWorker.jsm b/toolkit/components/promiseworker/PromiseWorker.jsm index fb46ab450194..efe8a908c8c9 100644 --- a/toolkit/components/promiseworker/PromiseWorker.jsm +++ b/toolkit/components/promiseworker/PromiseWorker.jsm @@ -250,21 +250,27 @@ this.BasePromiseWorker.prototype = { * duration of the off main thread execution for this call. * @param {*=} closure An object holding references that should not be * garbage-collected before the message treatment is complete. + * @param {Array=} transfers An array of objects that should be transfered + * to the worker instead of being copied. If any of the objects is a Promise, + * it is resolved before posting the message. * * @return {promise} */ - post: function(fun, args, closure) { + post: function(fun, args, closure, transfers) { return Task.spawn(function* postMessage() { // Normalize in case any of the arguments is a promise if (args) { args = yield Promise.resolve(Promise.all(args)); } + if (transfers) { + transfers = yield Promise.resolve(Promise.all(transfers)); + } let id = ++this._id; let message = {fun: fun, args: args, id: id}; this.log("Posting message", message); try { - this._worker.postMessage(message); + this._worker.postMessage(message, ...[transfers]); } catch (ex if typeof ex == "number") { this.log("Could not post message", message, "due to xpcom error", ex); // handle raw xpcom errors (see eg bug 961317) diff --git a/toolkit/components/promiseworker/tests/xpcshell/test_Promise.js b/toolkit/components/promiseworker/tests/xpcshell/test_Promise.js index b5718826a4ae..e5d758fb54d1 100644 --- a/toolkit/components/promiseworker/tests/xpcshell/test_Promise.js +++ b/toolkit/components/promiseworker/tests/xpcshell/test_Promise.js @@ -60,6 +60,26 @@ add_task(function* test_rejected_promise_args() { } }); +add_task(function* test_transfer_args() { + let array = new Uint8Array(4); + for (let i = 0; i < 4; ++i) { + array[i] = i; + } + Assert.equal(array.buffer.byteLength, 4, "The buffer is not neutered yet"); + + let result = (yield worker.post("bounce", [array.buffer], [], [array.buffer]))[0]; + + // Check that the buffer has been sent + Assert.equal(array.buffer.byteLength, 0, "The buffer has been neutered"); + + // Check that the result is correct + Assert.equal(result.byteLength, 4, "The result has the right size"); + let array2 = new Uint8Array(result); + for (let i = 0; i < 4; ++i) { + Assert.equal(array2[i], i); + } +}); + function run_test() { run_next_test(); }