Skip to content

Commit 201dd2f

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 f56615c commit 201dd2f

File tree

1 file changed

+66
-24
lines changed

1 file changed

+66
-24
lines changed

index.bs

+66-24
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">lock count</dfn> (a number representing the number of 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,23 @@ 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">lock count</dfn> (a number representing the number of 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" id=file-entry-lock-take>take a lock</dfn> 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/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/lock count=].
139+
1. Let |ancestorLockStatus| be the result of [=file system entry/checking for an ancestor lock=] on |entry|.
140+
1. If |ancestorLockStatus| is "`taken`":
141+
1. Return "`failure`".
142+
1. If |entry| is a [=directory entry=]:
143+
1. Let |descendantLockStatus| be the result of [=file system entry/checking for a descendant lock=] on |entry|.
144+
1. If |descendantLockStatus| is "`taken`":
145+
1. Return "`failure`".
143146
1. If |lock| is not "`open`":
144147
1. If |value| is "`exclusive`" or |lock| is "`taken-exclusive`":
145148
1. Return "`failure`".
@@ -157,12 +160,47 @@ Note: These steps have to be run on the [=file system queue=].
157160
</div>
158161

159162
<div algorithm>
160-
To <dfn for="file entry/lock">release</dfn> a [=file entry/lock=] on a given
161-
[=/file entry=] |file|:
163+
To <dfn for="file system entry">check for an ancestor lock</dfn> on a given
164+
[=/file system entry=] |entry|:
165+
166+
1. Let |parent| be the |entry|'s [=file system entry/parent=].
167+
1. If |parent| is null:
168+
1. Return "`open`".
169+
1. Let |lock| be the |parent|'s [=file system entry/lock=].
170+
1. If |lock| is not "`open`":
171+
1. Return "`taken`".
172+
1. Let |ancestorLockStatus| be the result of [=file system entry/checking for an ancestor lock=] on |parent|.
173+
1. Return |ancestorLockStatus|.
174+
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">check for a descendant lock</dfn> on a given
181+
[=directory entry=] |directory|:
182+
183+
1. [=set/For each=] |child| of |directory|'s [=directory entry/children=]:
184+
1. Let |lock| be the |child|'s [=file system entry/lock=].
185+
1. If |lock| is not "`open`":
186+
1. Return "`taken`".
187+
1. If |child| is a [=directory entry=]:
188+
1. Let |descendantLockStatus| be the result of [=file system entry/checking for a descendant lock=] on |child|.
189+
1. If |descendantLockStatus| is "`taken`":
190+
1. Return "`taken`".
191+
1. Return "`open`".
192+
193+
Note: These steps have to be run on the [=file system queue=].
194+
195+
</div>
196+
197+
<div algorithm>
198+
To <dfn for="file system entry/lock">release</dfn> a [=file system entry/lock=] on a given
199+
[=/file system entry=] |entry|:
162200

163-
1. Let |lock| be the |file|'s associated [=file entry/lock=].
201+
1. Let |lock| be the |entry|'s associated [=file system entry/lock=].
164202
1. [=Assert=]: |lock| is not "`open`".
165-
1. Let |count| be the |file|'s [=file entry/lock count=].
203+
1. Let |count| be the |entry|'s [=file system entry/lock count=].
166204
1. [=Assert=]: |count| is greater than 0.
167205
1. Decrease |count| by 1.
168206
1. If |count| is 0, set |lock| to "`open`".
@@ -174,6 +212,10 @@ Note: These steps have to be run on the [=file system queue=].
174212
Note: Locks help prevent concurrent modifications to a file. A {{FileSystemWritableFileStream}}
175213
requires a shared lock, while a {{FileSystemSyncAccessHandle}} requires an exclusive one.
176214

215+
A <dfn export id=file>file entry</dfn> additionally consists of
216+
<dfn for="file entry" export>binary data</dfn> (a [=byte sequence=]) and a
217+
<dfn for="file entry">modification timestamp</dfn> (a number representing the number of milliseconds since the <a spec=FileAPI>Unix Epoch</a>).
218+
177219
A <dfn export id=directory>directory entry</dfn> additionally consists of a [=/set=] of
178220
<dfn for="directory entry">children</dfn>, which are themselves [=/file system entries=].
179221
Each member is either a [=/file entry=] or a [=/directory entry=].
@@ -536,7 +578,7 @@ The <dfn method for=FileSystemFileHandle>getFile()</dfn> method steps are:
536578
the temporary file starts out empty,
537579
otherwise the existing file is first copied to this temporary file.
538580

539-
Creating a {{FileSystemWritableFileStream}} [=file entry/take a lock|takes a shared lock=] on the
581+
Creating a {{FileSystemWritableFileStream}} [=file system entry/take a lock|takes a shared lock=] on the
540582
[=file entry=] [=locate an entry|locatable=] with |fileHandle|'s [=FileSystemHandle/locator=].
541583
This prevents the creation of {{FileSystemSyncAccessHandle|FileSystemSyncAccessHandles}}
542584
for the entry, until the stream is closed.
@@ -573,7 +615,7 @@ The <dfn method for=FileSystemFileHandle>createWritable(|options|)</dfn> method
573615
|result| with a "{{NotFoundError}}" {{DOMException}} and abort these steps.
574616
1. [=Assert=]: |entry| is a [=file entry=].
575617

576-
1. Let |lockResult| be the result of [=file entry/take a lock|taking a lock=]
618+
1. Let |lockResult| be the result of [=file system entry/take a lock|taking a lock=]
577619
with "`shared`" on |entry|.
578620

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

604-
Creating a {{FileSystemSyncAccessHandle}} [=file entry/take a lock|takes an exclusive lock=] on the
646+
Creating a {{FileSystemSyncAccessHandle}} [=file system entry/take a lock|takes an exclusive lock=] on the
605647
[=file entry=] [=locate an entry|locatable=] with |fileHandle|'s [=FileSystemHandle/locator=].
606648
This prevents the creation of further {{FileSystemSyncAccessHandle|FileSystemSyncAccessHandles}}
607649
or {{FileSystemWritableFileStream|FileSystemWritableFileStreams}}
@@ -643,7 +685,7 @@ The <dfn method for=FileSystemFileHandle>createSyncAccessHandle()</dfn> method s
643685
|result| with a "{{NotFoundError}}" {{DOMException}} and abort these steps.
644686
1. [=Assert=]: |entry| is a [=file entry=].
645687

646-
1. Let |lockResult| be the result of [=file entry/take a lock|taking a lock=]
688+
1. Let |lockResult| be the result of [=file system entry/take a lock|taking a lock=]
647689
with "`exclusive`" on |entry|.
648690

649691
1. [=Queue a storage task=] with |global| to run these steps:
@@ -1179,15 +1221,15 @@ given a [=file entry=] |file| in a [=/Realm=] |realm|:
11791221
file on disk being written to.
11801222

11811223
1. [=Enqueue the following steps=] to the [=file system queue=]:
1182-
1. [=file entry/lock/release|Release the lock=] on
1224+
1. [=file system entry/lock/release|Release the lock=] on
11831225
|stream|'s [=FileSystemWritableFileStream/[[file]]=].
11841226
1. [=Queue a storage task=] with |file|'s [=relevant global object=]
11851227
to [=/resolve=] |closeResult| with `undefined`.
11861228

11871229
1. Return |closeResult|.
11881230
1. Let |abortAlgorithm| be these steps:
11891231
1. [=enqueue steps|Enqueue this step=] to the [=file system queue=]:
1190-
1. [=file entry/lock/release|Release the lock=] on
1232+
1. [=file system entry/lock/release|Release the lock=] on
11911233
|stream|'s [=FileSystemWritableFileStream/[[file]]=].
11921234
1. Let |highWaterMark| be 1.
11931235
1. Let |sizeAlgorithm| be an algorithm that returns `1`.
@@ -1647,7 +1689,7 @@ The <dfn method for=FileSystemSyncAccessHandle>flush()</dfn> method steps are:
16471689
: |handle| . {{FileSystemSyncAccessHandle/close()}}
16481690
:: Closes the access handle or no-ops if the access handle is already closed.
16491691
This disables any further operations on it and
1650-
[=file entry/lock/release|releases the lock=] on the
1692+
[=file system entry/lock/release|releases the lock=] on the
16511693
[=FileSystemSyncAccessHandle/[[file]]=] associated with |handle|.
16521694
</div>
16531695

@@ -1659,7 +1701,7 @@ The <dfn method for=FileSystemSyncAccessHandle>close()</dfn> method steps are:
16591701
1. Set |lockReleased| to false.
16601702
1. Let |file| be [=this=]'s [=FileSystemSyncAccessHandle/[[file]]=].
16611703
1. [=Enqueue the following steps=] to the [=file system queue=]:
1662-
1. [=file entry/lock/release|Release the lock=] on |file|.
1704+
1. [=file system entry/lock/release|Release the lock=] on |file|.
16631705
1. Set |lockReleased| to true.
16641706
1. [=Pause=] until |lockReleased| is true.
16651707

0 commit comments

Comments
 (0)