browser_resources_target_resources_race.js (2497B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 /** 7 * Test initial target resources are correctly retrieved even when several calls 8 * to watchResources are made simultaneously. 9 * 10 * This checks a race condition which occurred when calling watchResources 11 * simultaneously. This made the "second" call to watchResources miss existing 12 * resources (in case those are emitted from the target instead of the watcher). 13 * See Bug 1663896. 14 */ 15 add_task(async function () { 16 // Disable the preloaded process as it creates processes intermittently 17 // which forces the emission of RDP requests we aren't correctly waiting for. 18 await pushPref("dom.ipc.processPrelaunch.enabled", false); 19 20 const { client, resourceCommand, targetCommand } = 21 await initMultiProcessResourceCommand(); 22 23 const expectedPlatformMessage = "expectedMessage"; 24 25 info("Log a message *before* calling ResourceCommand.watchResources"); 26 Services.console.logStringMessage(expectedPlatformMessage); 27 28 info("Call watchResources from 2 separate call sites consecutively"); 29 30 // Empty onAvailable callback for CSS MESSAGES, we only want to check that 31 // the second resource we watch correctly provides existing resources. 32 const onCssMessageAvailable = () => {}; 33 34 // First call to watchResources. 35 // We do not await on `watchPromise1` here, in order to simulate simultaneous 36 // calls to watchResources (which could come from 2 separate modules in a real 37 // scenario). 38 const initialWatchPromise = resourceCommand.watchResources( 39 [resourceCommand.TYPES.CSS_MESSAGE], 40 { 41 onAvailable: onCssMessageAvailable, 42 } 43 ); 44 45 // `waitForNextResource` will trigger another call to `watchResources`. 46 const { onResource: onMessageReceived } = 47 await resourceCommand.waitForNextResource( 48 resourceCommand.TYPES.PLATFORM_MESSAGE, 49 { 50 ignoreExistingResources: false, 51 predicate: r => r.message === expectedPlatformMessage, 52 } 53 ); 54 55 info("Waiting for the expected message to be received"); 56 await onMessageReceived; 57 ok(true, "All the expected messages were received"); 58 59 info("Wait for the other watchResources promise to finish"); 60 await initialWatchPromise; 61 62 // Unwatch all resources. 63 resourceCommand.unwatchResources([resourceCommand.TYPES.CSS_MESSAGE], { 64 onAvailable: onCssMessageAvailable, 65 }); 66 67 Services.console.reset(); 68 targetCommand.destroy(); 69 await client.close(); 70 });