Bug 830694 - Taking advantage of zero-copy transfer between workers;r=froydnj

This commit is contained in:
David Rajchenbach-Teller 2013-01-16 13:30:28 +01:00
parent 8f10e8a89e
commit 84d3a15daf
2 changed files with 42 additions and 33 deletions

View File

@ -240,37 +240,13 @@ File.prototype = {
* @resolves {Uint8Array} An array containing the bytes read.
*/
read: function read(nbytes) {
// FIXME: Once bug 720949 has landed, we might be able to simplify
// the implementation of |readAll|
let self = this;
let promise;
if (nbytes != null) {
promise = Promise.resolve(nbytes);
} else {
promise = this.stat();
promise = promise.then(function withStat(stat) {
return stat.size;
let promise = Scheduler.post("File_prototype_read",
[this._fdmsg,
nbytes]);
return promise.then(
function onSuccess(data) {
return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
});
}
let array;
let size;
promise = promise.then(
function withSize(aSize) {
size = aSize;
array = new Uint8Array(size);
return self.readTo(array);
}
);
promise = promise.then(
function afterReadTo(bytes) {
if (bytes == size) {
return array;
} else {
return array.subarray(0, bytes);
}
}
);
return promise;
},
/**
@ -475,8 +451,12 @@ File.makeDir = function makeDir(path, options) {
* read from the file.
*/
File.read = function read(path, bytes) {
return Scheduler.post("read",
let promise = Scheduler.post("read",
[Type.path.toMsg(path), bytes], path);
return promise.then(
function onSuccess(data) {
return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
});
};
/**

View File

@ -62,7 +62,12 @@ if (this.Components) {
if (DEBUG) {
LOG("Sending positive reply", JSON.stringify(result), "id is", id);
}
self.postMessage({ok: result, id:id});
if (result instanceof Transfer) {
// Take advantage of zero-copy transfers
self.postMessage({ok: result.data, id: id}, result.transfers);
} else {
self.postMessage({ok: result, id:id});
}
} else if (exn == StopIteration) {
// StopIteration cannot be serialized automatically
if (DEBUG) {
@ -173,6 +178,21 @@ if (this.Components) {
let File = exports.OS.File;
/**
* A constructor used to transfer data to the caller
* without copy.
*
* @param {*} data The data to return to the caller.
* @param {Array} transfers An array of Transferable
* values that should be moved instead of being copied.
*
* @constructor
*/
let Transfer = function Transfer(data, transfers) {
this.data = data;
this.transfers = transfers;
};
/**
* The agent.
*
@ -214,7 +234,8 @@ if (this.Components) {
return OpenedFiles.add(file);
},
read: function read(path, bytes) {
return File.read(Type.path.fromMsg(path), bytes);
let data = File.read(Type.path.fromMsg(path), bytes);
return new Transfer({buffer: data.buffer, byteOffset: data.byteOffset, byteLength: data.byteLength}, [data.buffer]);
},
exists: function exists(path) {
return File.exists(Type.path.fromMsg(path));
@ -249,6 +270,14 @@ if (this.Components) {
return exports.OS.File.Info.toMsg(this.stat());
});
},
File_prototype_read: function read(fd, nbytes, options) {
return withFile(fd,
function do_read() {
let data = this.read(nbytes, options);
return new Transfer({buffer: data.buffer, byteOffset: data.byteOffset, byteLength: data.byteLength}, [data.buffer]);
}
);
},
File_prototype_readTo: function readTo(fd, buffer, options) {
return withFile(fd,
function do_readTo() {