1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
"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({ data }) {
ok(
resumeTimeouts_has_returned,
"worker message delivered from main event loop"
);
// Finish the mochitest.
finish();
}
|