Skip to content

Commit a0294b7

Browse files
author
Nathan Memmott
committed
Support locking of directory entries
Moves the locking algorithm from file entry to file system entry. Fixes #137
1 parent bd6ef5a commit a0294b7

File tree

1 file changed

+46
-24
lines changed

1 file changed

+46
-24
lines changed

index.bs

Lines changed: 46 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,9 @@ specifications do not need to bother implementing [=/file system entry=]'s
110110

111111
Issue(101): Make access check algorithms associated with a FileSystemHandle.
112112

113-
Each [=/file system entry=] has an associated <dfn for="file system entry" id=entry-name>name</dfn> (a [=string=]).
113+
Each [=/file system entry=] has an associated <dfn for="file system entry" id=entry-name>name</dfn> (a [=string=]),
114+
a <dfn for="file system entry">lock</dfn> (a string that may exclusively be "`open`", "`taken-exclusive`" or "`taken-shared`")
115+
and a <dfn for="file system entry">shared lock count</dfn> (a number representing the number of shared locks that are taken at a given point in time).
114116

115117
A <dfn>valid file name</dfn> is a [=string=] that is not an empty string, is not equal to "." or "..",
116118
and does not contain '/' or any other character used as path separator on the underlying platform.
@@ -124,22 +126,20 @@ Issue: We should consider having further normative restrictions on file names th
124126
never be allowed using this API, rather than leaving it entirely up to underlying file
125127
systems.
126128

127-
A <dfn export id=file>file entry</dfn> additionally consists of
128-
<dfn for="file entry" export>binary data</dfn> (a [=byte sequence=]), a
129-
<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`")
131-
and a <dfn for="file entry">shared lock count</dfn> (a number representing the number shared locks that are taken at a given point in time).
132-
133129
A user agent has an associated <dfn>file system queue</dfn> which is the
134130
result of [=starting a new parallel queue=]. This queue is to be used for all
135131
file system operations.
136132

137133
<div algorithm>
138-
To <dfn for="file entry/lock">take</dfn> a [=file entry/lock=] with a |value| of
139-
"`exclusive`" or "`shared`" on a given [=file entry=] |file|:
140-
141-
1. Let |lock| be the |file|'s [=file entry/lock=].
142-
1. Let |count| be the |file|'s [=file entry/shared lock count=].
134+
To <dfn for="file system entry" id=file-entry-lock-take>take a lock</dfn> with a |value| of
135+
"`exclusive`" or "`shared`" on a given [=/file system entry=] |entry|:
136+
137+
1. Let |lock| be the |entry|'s [=file system entry/lock=].
138+
1. Let |count| be the |entry|'s [=file system entry/shared lock count=].
139+
1. If |entry| is a [=directory entry=]:
140+
1. Let |descendantLockStatus| be the result of [=file system entry/checking for a descendant lock=] on |entry|.
141+
1. If |descendantLockStatus| is "`taken`":
142+
1. Return "`failure`".
143143
1. If |value| is "`exclusive`":
144144
1. If |lock| is "`open`":
145145
1. Set lock to "`taken-exclusive`".
@@ -159,11 +159,29 @@ Note: These steps have to be run on the [=file system queue=].
159159
</div>
160160

161161
<div algorithm>
162-
To <dfn for="file entry/lock">release</dfn> a [=file entry/lock=] on a given
163-
[=file entry=] |file|:
162+
To <dfn for="file system entry">check for a descendant lock</dfn> on a given
163+
[=directory entry=] |directory|:
164+
165+
1. [=set/For each=] |child| of |directory|'s [=directory entry/children=]:
166+
1. Let |lock| be the |child|'s [=file system entry/lock=].
167+
1. If |lock| is not "`open`":
168+
1. Return "`taken`".
169+
1. If |child| is a [=directory entry=]:
170+
1. Let |descendantLockStatus| be the result of [=file system entry/checking for a descendant lock=] on |child|.
171+
1. If |descendantLockStatus| is "`taken`":
172+
1. Return "`taken`".
173+
1. Return "`open`".
164174

165-
1. Let |lock| be the |file|'s associated [=file entry/lock=].
166-
1. Let |count| be the |file|'s [=file entry/shared lock count=].
175+
Note: These steps have to be run on the [=file system queue=].
176+
177+
</div>
178+
179+
<div algorithm>
180+
To <dfn for="file system entry/lock">release</dfn> a [=file system entry/lock=] on a given
181+
[=/file system entry=] |entry|:
182+
183+
1. Let |lock| be the |entry|'s associated [=file system entry/lock=].
184+
1. Let |count| be the |entry|'s [=file system entry/shared lock count=].
167185
1. If |lock| is "`taken-shared`":
168186
1. Decrease |count| by 1.
169187
1. If |count| is 0, set |lock| to "`open`".
@@ -176,6 +194,10 @@ Note: These steps have to be run on the [=file system queue=].
176194
Note: Locks help prevent concurrent modifications to a file. A {{FileSystemWritableFileStream}}
177195
requires a shared lock, while a {{FileSystemSyncAccessHandle}} requires an exclusive one.
178196

197+
A <dfn export id=file>file entry</dfn> additionally consists of
198+
<dfn for="file entry" export>binary data</dfn> (a [=byte sequence=]) and a
199+
<dfn for="file entry">modification timestamp</dfn> (a number representing the number of milliseconds since the <a spec=FileAPI>Unix Epoch</a>).
200+
179201
A <dfn export id=directory>directory entry</dfn> additionally consists of a [=/set=] of
180202
<dfn for="directory entry">children</dfn>, which are themselves [=/file system entries=].
181203
Each member is either a [=/file entry=] or a [=/directory entry=].
@@ -538,7 +560,7 @@ The <dfn method for=FileSystemFileHandle>getFile()</dfn> method steps are:
538560
the temporary file starts out empty,
539561
otherwise the existing file is first copied to this temporary file.
540562

541-
Creating a {{FileSystemWritableFileStream}} [=file entry/lock/take|takes a shared lock=] on the
563+
Creating a {{FileSystemWritableFileStream}} [=file system entry/take a lock|takes a shared lock=] on the
542564
[=file entry=] [=locate an entry|locatable=] with |fileHandle|'s [=FileSystemHandle/locator=].
543565
This prevents the creation of {{FileSystemSyncAccessHandle|FileSystemSyncAccessHandles}}
544566
for the entry, until the stream is closed.
@@ -575,7 +597,7 @@ The <dfn method for=FileSystemFileHandle>createWritable(|options|)</dfn> method
575597
|result| with a "{{NotFoundError}}" {{DOMException}} and abort these steps.
576598
1. [=Assert=]: |entry| is a [=file entry=].
577599

578-
1. Let |lockResult| be the result of [=file entry/lock/take|taking a lock=]
600+
1. Let |lockResult| be the result of [=file system entry/take a lock|taking a lock=]
579601
with "`shared`" on |entry|.
580602

581603
1. [=Queue a storage task=] with |global| to run these steps:
@@ -603,7 +625,7 @@ The <dfn method for=FileSystemFileHandle>createWritable(|options|)</dfn> method
603625
[=file entry=] [=locate an entry|locatable=] by |fileHandle|'s [=FileSystemHandle/locator=].
604626
To ensure the changes are reflected in this file, the handle can be flushed.
605627

606-
Creating a {{FileSystemSyncAccessHandle}} [=file entry/lock/take|takes an exclusive lock=] on the
628+
Creating a {{FileSystemSyncAccessHandle}} [=file system entry/take a lock|takes an exclusive lock=] on the
607629
[=file entry=] [=locate an entry|locatable=] with |fileHandle|'s [=FileSystemHandle/locator=].
608630
This prevents the creation of further {{FileSystemSyncAccessHandle|FileSystemSyncAccessHandles}}
609631
or {{FileSystemWritableFileStream|FileSystemWritableFileStreams}}
@@ -645,7 +667,7 @@ The <dfn method for=FileSystemFileHandle>createSyncAccessHandle()</dfn> method s
645667
|result| with a "{{NotFoundError}}" {{DOMException}} and abort these steps.
646668
1. [=Assert=]: |entry| is a [=file entry=].
647669

648-
1. Let |lockResult| be the result of [=file entry/lock/take|taking a lock=]
670+
1. Let |lockResult| be the result of [=file system entry/take a lock|taking a lock=]
649671
with "`exclusive`" on |entry|.
650672

651673
1. [=Queue a storage task=] with |global| to run these steps:
@@ -1181,15 +1203,15 @@ given a [=file entry=] |file| in a [=/Realm=] |realm|:
11811203
file on disk being written to.
11821204

11831205
1. [=Enqueue the following steps=] to the [=file system queue=]:
1184-
1. [=file entry/lock/release|Release the lock=] on
1206+
1. [=file system entry/lock/release|Release the lock=] on
11851207
|stream|'s [=FileSystemWritableFileStream/[[file]]=].
11861208
1. [=Queue a storage task=] with |file|'s [=relevant global object=]
11871209
to [=/resolve=] |closeResult| with `undefined`.
11881210

11891211
1. Return |closeResult|.
11901212
1. Let |abortAlgorithm| be these steps:
11911213
1. [=enqueue steps|Enqueue this step=] to the [=file system queue=]:
1192-
1. [=file entry/lock/release|Release the lock=] on
1214+
1. [=file system entry/lock/release|Release the lock=] on
11931215
|stream|'s [=FileSystemWritableFileStream/[[file]]=].
11941216
1. Let |highWaterMark| be 1.
11951217
1. Let |sizeAlgorithm| be an algorithm that returns `1`.
@@ -1649,7 +1671,7 @@ The <dfn method for=FileSystemSyncAccessHandle>flush()</dfn> method steps are:
16491671
: |handle| . {{FileSystemSyncAccessHandle/close()}}
16501672
:: Closes the access handle or no-ops if the access handle is already closed.
16511673
This disables any further operations on it and
1652-
[=file entry/lock/release|releases the lock=] on the
1674+
[=file system entry/lock/release|releases the lock=] on the
16531675
[=FileSystemSyncAccessHandle/[[file]]=] associated with |handle|.
16541676
</div>
16551677

@@ -1661,7 +1683,7 @@ The <dfn method for=FileSystemSyncAccessHandle>close()</dfn> method steps are:
16611683
1. Set |lockReleased| to false.
16621684
1. Let |file| be [=this=]'s [=FileSystemSyncAccessHandle/[[file]]=].
16631685
1. [=Enqueue the following steps=] to the [=file system queue=]:
1664-
1. [=file entry/lock/release|Release the lock=] on |file|.
1686+
1. [=file system entry/lock/release|Release the lock=] on |file|.
16651687
1. Set |lockReleased| to true.
16661688
1. [=Pause=] until |lockReleased| is true.
16671689

0 commit comments

Comments
 (0)