<!DOCTYPE html>
<html>
<body>
<p>Test sharing SharedArrayBuffers between dedicated workers.</p>
<div id="result"></div>
<script type="text/javascript">
function log(message)
{
document.getElementById("result").innerHTML += message + "</br>";
}
var testCases = [
"testSendSharedArrayBuffer",
"testSendInt8Array",
"testSendUint8Array",
"testSendUint8ClampedArray",
"testSendInt16Array",
"testSendUint16Array",
"testSendInt32Array",
"testSendUint32Array",
"testSendFloat32Array",
"testSendFloat64Array",
"testSendSharedArrayBufferTwice",
"testTransferArrayBufferAndSharedArrayBuffer",
"testSharedArrayBufferInTransferListViaMessagePort",
];
var testIndex = 0;
function runNextTest()
{
if (testIndex < testCases.length) {
testIndex++;
try {
window[testCases[testIndex - 1]]();
} catch (ex) {
log("FAIL: unexpected exception " + ex);
runNextTest();
}
} else {
log("DONE");
if (window.testRunner)
testRunner.notifyDone();
}
}
function testSendSharedArrayBuffer()
{
runSendTest("SharedArrayBuffer");
}
function testSendInt8Array()
{
runSendTest("Int8Array");
}
function testSendUint8Array()
{
runSendTest("Uint8Array");
}
function testSendUint8ClampedArray()
{
runSendTest("Uint8ClampedArray");
}
function testSendInt16Array()
{
runSendTest("Int16Array");
}
function testSendUint16Array()
{
runSendTest("Uint16Array");
}
function testSendInt32Array()
{
runSendTest("Int32Array");
}
function testSendUint32Array()
{
runSendTest("Uint32Array");
}
function testSendFloat32Array()
{
runSendTest("Float32Array");
}
function testSendFloat64Array()
{
runSendTest("Float64Array");
}
function initializeTypedArray(ta, length) {
var i;
for (i = 0; i < length; ++i)
ta[i] = i;
}
function runSendTest(name)
{
var length = 8;
var type = window[name];
var sab;
var ta;
var msg;
log("Running " + name + " test case");
if (name == 'SharedArrayBuffer') {
sab = new SharedArrayBuffer(length);
ta = new Uint8Array(sab);
msg = {name: name, data: sab, length: length};
} else {
sab = new SharedArrayBuffer(length * type.BYTES_PER_ELEMENT);
ta = new type(sab);
msg = {name: name, data: ta, length: length};
}
initializeTypedArray(ta, length);
// Don't allow passing a SharedArrayBuffer in the transfer list.
try {
worker.postMessage(msg, [sab]);
log("FAIL: Passing SharedArrayBuffer in the transfer list did not throw.");
} catch (e) {
log("PASS: Passing SharedArrayBuffer in the transfer list threw.");
}
// Without Atomics, we can't safely test modifying the contents of the
// SharedArrayBuffer. All we can test for now is that the SharedArrayBuffer
// is not neutered when transferred to a Worker.
worker.postMessage(msg);
if (sab.length === 0)
log("FAIL: SharedArrayBuffer was neutered during transfer.");
else
log("PASS: SharedArrayBuffer not neutered during transfer.");
// Ensure the data wasn't changed.
for (i = 0; i < length; ++i) {
if (ta[i] != i) {
log("FAIL: Original data changed during transfer. Expected " + i +
" got " + ta[i]);
break;
}
}
if (i == length)
log("PASS: Original data not changed during transfer.");
}
function testTransferArrayBufferAndSharedArrayBuffer() {
var ab = new ArrayBuffer(4);
var sab = new SharedArrayBuffer(16);
var msg = {
name : 'ArrayBufferAndSharedArrayBuffer',
ab: ab,
abLength: ab.byteLength,
sab: sab,
sabLength: sab.byteLength,
};
log("Running TransferArrayBufferAndSharedArrayBuffer test case");
initializeTypedArray(new Uint8Array(ab), ab.byteLength);
initializeTypedArray(new Uint8Array(sab), sab.byteLength);
worker.postMessage(msg, [ab]);
if (ab.byteLength === 0)
log("PASS: ArrayBuffer was neutered during transfer.");
else
log("FAIL: ArrayBuffer was not neutered during transfer.");
}
function testSendSharedArrayBufferTwice() {
var sab = new SharedArrayBuffer(16);
var msg = {
name : 'SharedArrayBufferTwice',
sab: sab,
sabLength: sab.byteLength,
sab2: sab,
sab2Length: sab.byteLength,
};
log("Running SendSharedArrayBufferTwice test case");
initializeTypedArray(new Uint8Array(sab), sab.byteLength);
worker.postMessage(msg);
}
function testSharedArrayBufferInTransferListViaMessagePort() {
var ab1 = new ArrayBuffer(4);
var ab2 = new ArrayBuffer(4);
var sab1 = new SharedArrayBuffer(16);
var sab2 = new SharedArrayBuffer(16);
var msg = {
name : 'SharedArrayBufferInTransferListViaMessagePort',
ab1: ab1,
ab2: ab2,
sab1: sab1,
sab2: sab2,
};
var channel = new MessageChannel();
channel.port2.onmessage = function() {
log("FAIL: Message should not be sent.");
};
log("Running SharedArrayBufferInTransferListViaMessagePort test case");
try {
channel.port1.postMessage(msg, [ab1, sab1, ab2, sab2]);
log("FAIL: Passing SharedArrayBuffer in the transfer list did not throw.");
} catch (e) {
log("PASS: Passing SharedArrayBuffer in the transfer list threw.");
}
if (ab1.byteLength === 0)
log("FAIL: ArrayBuffer 'ab1' was neutered.");
else
log("PASS: ArrayBuffer 'ab1' was not neutered.");
if (ab2.byteLength === 0)
log("FAIL: ArrayBuffer 'ab2' was neutered.");
else
log("PASS: ArrayBuffer 'ab2' was not neutered.");
runNextTest();
}
if (window.testRunner) {
testRunner.dumpAsText();
testRunner.waitUntilDone();
}
if (window.SharedArrayBuffer) {
var worker = new Worker('resources/worker-sharedarraybuffer-transfer.js');
runNextTest();
worker.onmessage = function(e) {
if (e.data != 'DONE') {
// The worker sent a pass/fail message.
log(e.data);
} else {
runNextTest();
}
};
} else {
log("SharedArrayBuffers are not enabled -- skipping test.");
testRunner.notifyDone();
}
</script>
</body>
</html>