suspendTimeouts_content.js (2739B)
1 "use strict"; 2 3 // To make it easier to follow, this code is arranged so that the functions are 4 // arranged in the order they are called. 5 6 const worker = new Worker("suspendTimeouts_worker.js"); 7 worker.onerror = error => { 8 const message = `error from worker: ${error.filename}:${error.lineno}: ${error.message}`; 9 throw new Error(message); 10 }; 11 12 // Create a message channel. Send one end to the worker, and return the other to 13 // the mochitest. 14 /* exported create_channel */ 15 function create_channel() { 16 const { port1, port2 } = new MessageChannel(); 17 info(`sending port to worker`); 18 worker.postMessage({ mochitestPort: port1 }, [port1]); 19 return port2; 20 } 21 22 // Provoke the worker into sending us a message, and then refuse to receive said 23 // message, causing it to be delayed for later delivery. 24 // 25 // The worker will also post a message to the MessagePort we sent it earlier. 26 // That message should not be delayed, as it is handled by the mochitest window, 27 // not the content window. Its receipt signals that the test can assume that the 28 // runnable for step 2) is in the main thread's event queue, so the test can 29 // prepare for step 3). 30 /* exported start_worker */ 31 function start_worker() { 32 worker.onmessage = handle_echo; 33 34 // This should prevent worker.onmessage from being called, until 35 // resumeTimeouts is called. 36 // 37 // This function is provided by test_suspendTimeouts.js. 38 // eslint-disable-next-line no-undef 39 suspendTimeouts(); 40 41 // The worker should echo this message back to us and to the mochitest. 42 worker.postMessage("HALLOOOOOO"); // suitable message for echoing 43 info(`posted message to worker`); 44 } 45 46 var resumeTimeouts_has_returned = false; 47 48 // Resume timeouts. After this call, the worker's message should not be 49 // delivered to our onmessage handler until control returns to the event loop. 50 /* exported resume_timeouts */ 51 function resume_timeouts() { 52 // This function is provided by test_suspendTimeouts.js. 53 // eslint-disable-next-line no-undef 54 resumeTimeouts(); // onmessage handlers should not run from this call. 55 56 resumeTimeouts_has_returned = true; 57 58 // When this JavaScript invocation returns to the main thread's event loop, 59 // only then should onmessage handlers be invoked. 60 } 61 62 // The buggy code calls this handler from the resumeTimeouts call, before the 63 // main thread returns to the event loop. The correct code calls this only once 64 // the JavaScript invocation that called resumeTimeouts has run to completion. 65 function handle_echo() { 66 ok( 67 resumeTimeouts_has_returned, 68 "worker message delivered from main event loop" 69 ); 70 71 // Finish the mochitest. 72 // This function is set and defined by test_suspendTimeouts.js 73 // eslint-disable-next-line no-undef 74 finish(); 75 }