test_nested_eventloop.html (2608B)
1 <!DOCTYPE HTML> 2 <html> 3 <!-- 4 https://bugzilla.mozilla.org/show_bug.cgi?id=650295 5 --> 6 <head> 7 <meta charset="utf-8"> 8 <title>Test for Bug 650295 -- Spin the event loop from inside a callback</title> 9 <script src="/tests/SimpleTest/SimpleTest.js"></script> 10 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> 11 <script type="application/javascript" src="head.js"></script> 12 </head> 13 <body> 14 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=650295">Mozilla Bug 650295</a> 15 <p id="display"></p> 16 <div id="content" style="display: none"> 17 18 </div> 19 <pre id="test"> 20 <script type="text/javascript"> 21 SimpleTest.waitForExplicitFinish(); 22 23 /* 24 * SpecialPowers.spinEventLoop can be used to spin the event loop, causing 25 * queued SpeechEvents (such as those created by calls to start(), stop() 26 * or abort()) to be processed immediately. 27 * When this is done from inside DOM event handlers, it is possible to 28 * cause reentrancy in our C++ code, which we should be able to withstand. 29 */ 30 function abortAndSpinEventLoop(evt, sr) { 31 sr.abort(); 32 SpecialPowers.spinEventLoop(window); 33 } 34 function doneFunc() { 35 // Trigger gc now and wait some time to make sure this test gets the blame 36 // for any assertions caused by spinning the event loop. 37 // 38 // NB - The assertions should be gone, but this looks too scary to touch 39 // during batch cleanup. 40 var count = 0, GC_COUNT = 4; 41 42 function triggerGCOrFinish() { 43 SpecialPowers.gc(); 44 count++; 45 46 if (count == GC_COUNT) { 47 SimpleTest.finish(); 48 } 49 } 50 51 for (var i = 0; i < GC_COUNT; i++) { 52 setTimeout(triggerGCOrFinish, 0); 53 } 54 } 55 56 /* 57 * We start by performing a normal start, then abort from the audiostart 58 * callback and force the EVENT_ABORT to be processed while still inside 59 * the event handler. This causes the recording to stop, which raises 60 * the audioend and (later on) end events. 61 * Then, we abort (once again spinning the event loop) from the audioend 62 * handler, attempting to cause a re-entry into the abort code. This second 63 * call should be ignored, and we get the end callback and finish. 64 */ 65 66 performTest({ 67 eventsToRequest: [], 68 expectedEvents: { 69 "audiostart": abortAndSpinEventLoop, 70 "audioend": abortAndSpinEventLoop, 71 "end": null 72 }, 73 doneFunc, 74 prefs: [["media.webspeech.test.fake_fsm_events", true], 75 ["media.webspeech.test.fake_recognition_service", true], 76 ["media.webspeech.recognition.timeout", 100000]] 77 }); 78 79 </script> 80 </pre> 81 </body> 82 </html>