blob: 43f7bbfc4e69e475073cd69fbf531a51cf0580e7 [file] [log] [blame]
<!DOCTYPE html>
<meta charset=utf-8>
<title>Web Locks API: Lock held with Promise that is GC'd (Chromium-specific, relies on gc/internals)</title>
<link rel=help href="https://github.com/inexorabletash/web-locks">
<script src="/js-test-resources/gc.js"></script>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
'use strict';
// For uncaught rejections.
setup({allow_uncaught_exception: true});
// Wait for a promise in a subsequent task (not just microtask in same task).
function task(t) {
return new Promise(resolve => {
t.step_timeout(resolve, 0);
});
}
promise_test(async t => {
let res = `${self.location.pathname}-${t.name}`;
let observe_lock, observe_promise;
// Acquire the lock, and keep it alive via a promise that never resolves.
let resolve, acquired = new Promise(r => { resolve = r; });
navigator.locks.request(res, lock => {
resolve();
// Neither |lock| nor |promise| are retained.
const promise = new Promise(() => {});
observe_lock = internals.observeGC(lock);
observe_promise = internals.observeGC(promise);
return promise;
});
await acquired;
// Drain the microtask queue and trigger a GC.
await task(t);
asyncGC(async function () {
assert_true(observe_lock.wasCollected, 'Lock should be collected');
assert_true(observe_promise.wasCollected, 'Promise should be collected');
// Now try and request the lock.
let lock = 'should be overwritten';
await navigator.locks.request(res, {ifAvailable: true}, l => {
lock = l;
});
assert_equals(lock, null, 'Lock acquisition should have failed');
});
}, 'GC of waiting promise does not cause lock to be released');
</script>