75 lines
2.7 KiB
JavaScript
75 lines
2.7 KiB
JavaScript
"use strict";
|
|
|
|
// To make it easier to follow, this code is arranged so that the functions are
|
|
// arranged in the order they are called.
|
|
|
|
const worker = new Worker("suspendTimeouts_worker.js");
|
|
worker.onerror = error => {
|
|
const message = `error from worker: ${error.filename}:${error.lineno}: ${error.message}`;
|
|
throw new Error(message);
|
|
};
|
|
|
|
// Create a message channel. Send one end to the worker, and return the other to
|
|
// the mochitest.
|
|
/* exported create_channel */
|
|
function create_channel() {
|
|
const { port1, port2 } = new MessageChannel();
|
|
info(`sending port to worker`);
|
|
worker.postMessage({ mochitestPort: port1 }, [port1]);
|
|
return port2;
|
|
}
|
|
|
|
// Provoke the worker into sending us a message, and then refuse to receive said
|
|
// message, causing it to be delayed for later delivery.
|
|
//
|
|
// The worker will also post a message to the MessagePort we sent it earlier.
|
|
// That message should not be delayed, as it is handled by the mochitest window,
|
|
// not the content window. Its receipt signals that the test can assume that the
|
|
// runnable for step 2) is in the main thread's event queue, so the test can
|
|
// prepare for step 3).
|
|
/* exported start_worker */
|
|
function start_worker() {
|
|
worker.onmessage = handle_echo;
|
|
|
|
// This should prevent worker.onmessage from being called, until
|
|
// resumeTimeouts is called.
|
|
//
|
|
// This function is provided by test_suspendTimeouts.js.
|
|
// eslint-disable-next-line no-undef
|
|
suspendTimeouts();
|
|
|
|
// The worker should echo this message back to us and to the mochitest.
|
|
worker.postMessage("HALLOOOOOO"); // suitable message for echoing
|
|
info(`posted message to worker`);
|
|
}
|
|
|
|
var resumeTimeouts_has_returned = false;
|
|
|
|
// Resume timeouts. After this call, the worker's message should not be
|
|
// delivered to our onmessage handler until control returns to the event loop.
|
|
/* exported resume_timeouts */
|
|
function resume_timeouts() {
|
|
// This function is provided by test_suspendTimeouts.js.
|
|
// eslint-disable-next-line no-undef
|
|
resumeTimeouts(); // onmessage handlers should not run from this call.
|
|
|
|
resumeTimeouts_has_returned = true;
|
|
|
|
// When this JavaScript invocation returns to the main thread's event loop,
|
|
// only then should onmessage handlers be invoked.
|
|
}
|
|
|
|
// The buggy code calls this handler from the resumeTimeouts call, before the
|
|
// main thread returns to the event loop. The correct code calls this only once
|
|
// the JavaScript invocation that called resumeTimeouts has run to completion.
|
|
function handle_echo() {
|
|
ok(
|
|
resumeTimeouts_has_returned,
|
|
"worker message delivered from main event loop"
|
|
);
|
|
|
|
// Finish the mochitest.
|
|
// This function is set and defined by test_suspendTimeouts.js
|
|
// eslint-disable-next-line no-undef
|
|
finish();
|
|
}
|