Skip to content

Commit bc3475c

Browse files
author
Nathan Memmott
committed
Add new SAH and WFS locking modes
Adds new locking modes for sync access handles and writable file streams. Updates "file entry/take a lock" and "file entry/lock/release" to support these new modes.
1 parent b03688d commit bc3475c

File tree

1 file changed

+64
-25
lines changed

1 file changed

+64
-25
lines changed

index.bs

Lines changed: 64 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -127,31 +127,27 @@ systems.
127127
A <dfn export id=file>file entry</dfn> additionally consists of
128128
<dfn for="file entry" export>binary data</dfn> (a [=byte sequence=]), a
129129
<dfn for="file entry">modification timestamp</dfn> (a number representing the number of milliseconds since the <a spec=FileAPI>Unix Epoch</a>),
130-
a <dfn for="file entry">lock</dfn> (a string that may exclusively be "`open`", "`taken-exclusive`" or "`taken-shared`")
130+
a <dfn for="file entry">lock</dfn> (a [=string=] or null)
131131
and a <dfn for="file entry">shared lock count</dfn> (a number representing the number of shared locks that are taken at a given point in time).
132132

133133
A user agent has an associated <dfn>file system queue</dfn> which is the
134134
result of [=starting a new parallel queue=]. This queue is to be used for all
135135
file system operations.
136136

137137
<div algorithm>
138-
To <dfn for="file entry" id=file-entry-lock-take>take a lock</dfn> with a |value| of
139-
"`exclusive`" or "`shared`" on a given [=file entry=] |file|:
138+
To <dfn for="file entry" id=file-entry-lock-take>take a lock</dfn> with a |lockType| (a [=string=])
139+
on a given [=file entry=] |file|:
140140

141141
1. Let |lock| be the |file|'s [=file entry/lock=].
142142
1. Let |count| be the |file|'s [=file entry/shared lock count=].
143-
1. If |value| is "`exclusive`":
144-
1. If |lock| is "`open`":
145-
1. Set lock to "`taken-exclusive`".
146-
1. Return "`success`".
147-
1. If |value| is "`shared`":
148-
1. If |lock| is "`open`":
149-
1. Set |lock| to "`taken-shared`".
150-
1. Set |count| to 1.
151-
1. Return "`success`".
152-
1. Otherwise, if |lock| is "`taken-shared`":
153-
1. Increase |count| by 1.
154-
1. Return "`success`".
143+
1. If |lock| is null:
144+
1. Set |lock| to |lockType|.
145+
1. Set |count| to 1.
146+
1. Return "`success`".
147+
1. If |lock| is not "`exclusive`":
148+
1. If |lock| equals |lockType|:
149+
1. Increase |count| by 1.
150+
1. Return "`success`".
155151
1. Return "`failure`".
156152

157153
Note: These steps have to be run on the [=file system queue=].
@@ -164,10 +160,9 @@ To <dfn for="file entry/lock">release</dfn> a [=file entry/lock=] on a given
164160

165161
1. Let |lock| be the |file|'s associated [=file entry/lock=].
166162
1. Let |count| be the |file|'s [=file entry/shared lock count=].
167-
1. If |lock| is "`taken-shared`":
168-
1. Decrease |count| by 1.
169-
1. If |count| is 0, set |lock| to "`open`".
170-
1. Otherwise, set |lock| to "`open`".
163+
1. [=Assert=]: |count| greater than 0.
164+
1. Decrease |count| by 1.
165+
1. If |count| is 0, set |lock| to null.
171166

172167
Note: These steps have to be run on the [=file system queue=].
173168

@@ -420,16 +415,32 @@ The <dfn method for=FileSystemHandle>isSameEntry(|other|)</dfn> method steps are
420415
## The {{FileSystemFileHandle}} interface ## {#api-filesystemfilehandle}
421416

422417
<xmp class=idl>
418+
enum FileSystemWritableFileStreamMode {
419+
"exclusive",
420+
"siloed",
421+
};
422+
423423
dictionary FileSystemCreateWritableOptions {
424424
boolean keepExistingData = false;
425+
FileSystemWritableFileStreamMode mode = "siloed";
426+
};
427+
428+
enum FileSystemSyncAccessHandleMode {
429+
"readwrite",
430+
"read-only",
431+
"readwrite-unsafe",
432+
};
433+
434+
dictionary FileSystemCreateSyncAccessHandleOptions {
435+
FileSystemSyncAccessHandleMode mode = "readwrite";
425436
};
426437

427438
[Exposed=(Window,Worker), SecureContext, Serializable]
428439
interface FileSystemFileHandle : FileSystemHandle {
429440
Promise<File> getFile();
430441
Promise<FileSystemWritableFileStream> createWritable(optional FileSystemCreateWritableOptions options = {});
431442
[Exposed=DedicatedWorker]
432-
Promise<FileSystemSyncAccessHandle> createSyncAccessHandle();
443+
Promise<FileSystemSyncAccessHandle> createSyncAccessHandle(optional FileSystemCreateSyncAccessHandleOptions options = {});
433444
};
434445
</xmp>
435446

@@ -575,8 +586,14 @@ The <dfn method for=FileSystemFileHandle>createWritable(|options|)</dfn> method
575586
|result| with a "{{NotFoundError}}" {{DOMException}} and abort these steps.
576587
1. [=Assert=]: |entry| is a [=file entry=].
577588

589+
1. Let |lockType| be a [=string=].
590+
1. Let |mode| be |options|["{{FileSystemCreateWritableOptions/mode}}"].
591+
1. If |mode| is "`exclusive`":
592+
1. Set |lockType| to "`exclusive`".
593+
1. Otherwise, if |mode| is "`siloed`":
594+
1. Set |lockType| to "`writableSiloed`".
578595
1. Let |lockResult| be the result of [=file entry/take a lock|taking a lock=]
579-
with "`shared`" on |entry|.
596+
with |lockType| on |entry|.
580597

581598
1. [=Queue a storage task=] with |global| to run these steps:
582599
1. If |lockResult| is "`failure`", [=/reject=] |result| with a
@@ -617,7 +634,7 @@ The <dfn method for=FileSystemFileHandle>createWritable(|options|)</dfn> method
617634
</div>
618635

619636
<div algorithm>
620-
The <dfn method for=FileSystemFileHandle>createSyncAccessHandle()</dfn> method steps are:
637+
The <dfn method for=FileSystemFileHandle>createSyncAccessHandle(|options|)</dfn> method steps are:
621638

622639
1. Let |result| be [=a new promise=].
623640
1. Let |locator| be [=this=]'s [=FileSystemHandle/locator=].
@@ -645,15 +662,27 @@ The <dfn method for=FileSystemFileHandle>createSyncAccessHandle()</dfn> method s
645662
|result| with a "{{NotFoundError}}" {{DOMException}} and abort these steps.
646663
1. [=Assert=]: |entry| is a [=file entry=].
647664

665+
1. Let |lockType| be a [=string=].
666+
1. Let |writePermission| be a [=string=].
667+
1. Let |mode| be |options|["{{FileSystemCreateSyncAccessHandleOptions/mode}}"].
668+
1. If |mode| is "`readwrite`":
669+
1. Set |lockType| to "`exclusive`".
670+
1. Set |writePermission| to "`writable`".
671+
1. Otherwise, if |mode| is "`read-only`":
672+
1. Set |lockType| to "`syncAccessHandleReadOnly`".
673+
1. Set |writePermission| to "`notWritable`".
674+
1. Otherwise, if |mode| is "`readwrite-unsafe`":
675+
1. Set |lockType| to "`syncAccessHandleReadWriteUnsafe`".
676+
1. Set |writePermission| to "`writable`".
648677
1. Let |lockResult| be the result of [=file entry/take a lock|taking a lock=]
649-
with "`exclusive`" on |entry|.
678+
with |lockType| on |entry|.
650679

651680
1. [=Queue a storage task=] with |global| to run these steps:
652681
1. If |lockResult| is "`failure`", [=/reject=] |result| with a
653682
"{{NoModificationAllowedError}}" {{DOMException}} and abort these steps.
654683

655684
1. Let |handle| be the result of <a>creating a new `FileSystemSyncAccessHandle`</a>
656-
for |entry| in |realm|.
685+
with |entry| and |writePermission| in |realm|.
657686
1. [=/Resolve=] |result| with |handle|.
658687

659688
1. Return |result|.
@@ -1440,6 +1469,9 @@ A {{FileSystemSyncAccessHandle}} has an associated <dfn for=FileSystemSyncAccess
14401469
A {{FileSystemSyncAccessHandle}} has an associated <dfn for=FileSystemSyncAccessHandle>\[[state]]</dfn>,
14411470
a string that may exclusively be "`open`" or "`closed`".
14421471

1472+
A {{FileSystemSyncAccessHandle}} has an associated <dfn for=FileSystemSyncAccessHandle>\[[writePermission]]</dfn>,
1473+
a string that may exclusively be "`writable`" or "`notWritable`".
1474+
14431475
A {{FileSystemSyncAccessHandle}} is an object that is capable of reading from/writing to,
14441476
as well as obtaining and changing the size of, a single file.
14451477

@@ -1451,11 +1483,12 @@ A {{FileSystemSyncAccessHandle}} has a <dfn for="FileSystemSyncAccessHandle">fil
14511483
<div algorithm>
14521484
To
14531485
<dfn local-lt="creating a new FileSystemSyncAccessHandle">create a new `FileSystemSyncAccessHandle`</dfn>
1454-
given a [=file entry=] |file| in a [=/Realm=] |realm|:
1486+
given a [=file entry=] |file| and a |writePermission| of "`writable`" or "`notWritable`" in a [=/Realm=] |realm|:
14551487

14561488
1. Let |handle| be a [=new=] {{FileSystemSyncAccessHandle}} in |realm|.
14571489
1. Set |handle|'s [=FileSystemSyncAccessHandle/[[file]]=] to |file|.
14581490
1. Set |handle|'s [=FileSystemSyncAccessHandle/[[state]]=] to "`open`".
1491+
1. Set |handle|'s [=FileSystemSyncAccessHandle/[[writePermission]]=] to |writePermission|.
14591492
1. Return |handle|.
14601493

14611494
</div>
@@ -1518,6 +1551,8 @@ The <dfn method for=FileSystemSyncAccessHandle>write(|buffer|, {{FileSystemReadW
15181551

15191552
1. If [=this=]'s [=[[state]]=] is "`closed`",
15201553
[=throw=] an "{{InvalidStateError}}" {{DOMException}}.
1554+
1. If [=this=]'s [=[[writePermission]]=]' is "`notWritable`",
1555+
[=throw=] a "{{NoModificationAllowedError}}" {{DOMException}}.
15211556
1. Let |writePosition| be |options|["{{FileSystemReadWriteOptions/at}}"] if
15221557
|options|["{{FileSystemReadWriteOptions/at}}"] [=map/exists=]; otherwise
15231558
[=this=]'s [=FileSystemSyncAccessHandle/file position cursor=].
@@ -1578,6 +1613,8 @@ The <dfn method for=FileSystemSyncAccessHandle>truncate(|newSize|)</dfn> method
15781613

15791614
1. If [=this=]'s [=[[state]]=] is "`closed`",
15801615
[=throw=] an "{{InvalidStateError}}" {{DOMException}}.
1616+
1. If [=this=]'s [=[[writePermission]]=]' is "`notWritable`",
1617+
[=throw=] a "{{NoModificationAllowedError}}" {{DOMException}}.
15811618
1. Let |fileContents| be a copy of [=this=]'s
15821619
[=FileSystemSyncAccessHandle/[[file]]=]'s [=file entry/binary data=].
15831620
1. Let |oldSize| be the [=byte sequence/length=] of [=this=]'s
@@ -1634,6 +1671,8 @@ The <dfn method for=FileSystemSyncAccessHandle>flush()</dfn> method steps are:
16341671

16351672
1. If [=this=]'s [=[[state]]=] is "`closed`",
16361673
[=throw=] an "{{InvalidStateError}}" {{DOMException}}.
1674+
1. If [=this=]'s [=[[writePermission]]=]' is "`notWritable`",
1675+
[=throw=] a "{{NoModificationAllowedError}}" {{DOMException}}.
16371676
1. Attempt to transfer all cached modifications of the file's content to the
16381677
file system's underlying storage device.
16391678

0 commit comments

Comments
 (0)