Skip to content

Commit d84a1af

Browse files
fivedotschromium-wpt-export-bot
authored andcommitted
Switch to refcounted locks, add shared locks for writable streams
This CL changes the scope of the WriteLockManager, making it responsible for the creation of locks, instead of owning access handle and file writer receivers. This simplifies error handling and avoids unnecessary IO operations when taking a lock is not possible. This new locks are refcounted, when there are no more references to them, their destructor releases the lock on the URL. Creating access handles requires an exclusive lock, which prevent any other lock from being taken on the URL. Creating writable streams requires a shared lock, which prevent the taking of exclusive locks, but allow the taking of shared ones. Bug: 1218431 Change-Id: I9c21b901ed0f5f331682c8a6b75db5e28674e5a3 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3100189 Commit-Queue: Emanuel Krivoy <[email protected]> Reviewed-by: Austin Sullivan <[email protected]> Cr-Commit-Position: refs/heads/main@{#918766}
1 parent 27eeda0 commit d84a1af

2 files changed

+88
-36
lines changed

file-system-access/sandboxed_FileSystemFileHandle-sync-access-handle-lock.https.tentative.worker.js

Lines changed: 0 additions & 36 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
importScripts('/resources/testharness.js');
2+
importScripts('resources/sandboxed-fs-test-helpers.js');
3+
4+
'use strict';
5+
6+
directory_test(async (t, root_dir) => {
7+
const fileHandle = await root_dir.getFileHandle('OPFS.test', {create: true});
8+
9+
const syncHandle1 = await fileHandle.createSyncAccessHandle();
10+
await promise_rejects_dom(
11+
t, 'InvalidStateError', fileHandle.createSyncAccessHandle());
12+
13+
await syncHandle1.close();
14+
const syncHandle2 = await fileHandle.createSyncAccessHandle();
15+
await syncHandle2.close();
16+
}, 'There can only be one open access handle at any given time');
17+
18+
directory_test(async (t, root_dir) => {
19+
const fooFileHandle = await root_dir.getFileHandle('foo.test', {create: true});
20+
const barFileHandle = await root_dir.getFileHandle('bar.test', {create: true});
21+
22+
const fooSyncHandle = await fooFileHandle.createSyncAccessHandle();
23+
t.add_cleanup(() => fooSyncHandle.close());
24+
25+
const barSyncHandle1 = await barFileHandle.createSyncAccessHandle();
26+
await promise_rejects_dom(
27+
t, 'InvalidStateError', barFileHandle.createSyncAccessHandle());
28+
29+
await barSyncHandle1.close();
30+
const barSyncHandle2 = await barFileHandle.createSyncAccessHandle();
31+
await barSyncHandle2.close();
32+
}, 'An access handle from one file does not interfere with the creation of an' +
33+
' access handle on another file');
34+
35+
directory_test(async (t, root_dir) => {
36+
const fooFileHandle = await root_dir.getFileHandle('foo.test', {create: true});
37+
const barFileHandle = await root_dir.getFileHandle('bar.test', {create: true});
38+
39+
const fooWritable = await fooFileHandle.createWritable();
40+
t.add_cleanup(() => fooWritable.close());
41+
42+
const barSyncHandle = await barFileHandle.createSyncAccessHandle();
43+
t.add_cleanup(() => barSyncHandle.close());
44+
}, 'A writable stream from one file does not interfere with the creation of an' +
45+
' access handle on another file');
46+
47+
directory_test(async (t, root_dir) => {
48+
const fooFileHandle = await root_dir.getFileHandle('foo.test', {create: true});
49+
const barFileHandle = await root_dir.getFileHandle('bar.test', {create: true});
50+
51+
const fooSyncHandle = await fooFileHandle.createSyncAccessHandle();
52+
t.add_cleanup(() => fooSyncHandle.close());
53+
54+
const barWritable = await barFileHandle.createWritable();
55+
t.add_cleanup(() => barWritable.close());
56+
}, 'An access handle from one file does not interfere with the creation of a' +
57+
' writable stream on another file');
58+
59+
directory_test(async (t, root_dir) => {
60+
const fileHandle = await root_dir.getFileHandle('OPFS.test', {create: true});
61+
62+
const syncHandle = await fileHandle.createSyncAccessHandle();
63+
await promise_rejects_dom(
64+
t, 'InvalidStateError', fileHandle.createWritable());
65+
66+
await syncHandle.close();
67+
const writable = await fileHandle.createWritable();
68+
await writable.close();
69+
}, 'Writable streams cannot be created if there is an open access handle');
70+
71+
directory_test(async (t, root_dir) => {
72+
const fileHandle = await root_dir.getFileHandle('OPFS.test', {create: true});
73+
74+
const writable1 = await fileHandle.createWritable();
75+
const writable2 = await fileHandle.createWritable();
76+
await promise_rejects_dom(
77+
t, 'InvalidStateError', fileHandle.createSyncAccessHandle());
78+
79+
await writable1.close();
80+
await promise_rejects_dom(
81+
t, 'InvalidStateError', fileHandle.createSyncAccessHandle());
82+
83+
await writable2.close();
84+
const syncHandle = await fileHandle.createSyncAccessHandle();
85+
await syncHandle.close();
86+
}, 'Access handles cannot be created if there are open Writable streams');
87+
88+
done();

0 commit comments

Comments
 (0)