diff --git a/index.bs b/index.bs index 6ea488a..6c31515 100644 --- a/index.bs +++ b/index.bs @@ -110,7 +110,9 @@ specifications do not need to bother implementing [=/file system entry=]'s Issue(101): Make access check algorithms associated with a FileSystemHandle. -Each [=/file system entry=] has an associated name (a [=string=]). +Each [=/file system entry=] has an associated name (a [=string=]), +a lock (a string that may exclusively be "`open`", "`taken-exclusive`" or "`taken-shared`") +and a lock count (a number representing the number of locks that are taken at a given point in time). A valid file name is a [=string=] that is not an empty string, is not equal to "." or "..", 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 never be allowed using this API, rather than leaving it entirely up to underlying file systems. -A file entry additionally consists of -binary data (a [=byte sequence=]), a -modification timestamp (a number representing the number of milliseconds since the Unix Epoch), -a lock (a string that may exclusively be "`open`", "`taken-exclusive`" or "`taken-shared`") -and a lock count (a number representing the number of locks that are taken at a given point in time). - A user agent has an associated file system queue which is the result of [=starting a new parallel queue=]. This queue is to be used for all file system operations.
-To take a lock with a |value| of -"`exclusive`" or "`shared`" on a given [=file entry=] |file|: - -1. Let |lock| be the |file|'s [=file entry/lock=]. -1. Let |count| be the |file|'s [=file entry/lock count=]. +To take a lock with a |value| of +"`exclusive`" or "`shared`" on a given [=/file system entry=] |entry|: + +1. Let |lock| be the |entry|'s [=file system entry/lock=]. +1. Let |count| be the |entry|'s [=file system entry/lock count=]. +1. Let |ancestorLockStatus| be the result of [=file system entry/checking for an ancestor lock=] on |entry|. +1. If |ancestorLockStatus| is "`taken`": + 1. Return "`failure`". +1. If |entry| is a [=directory entry=]: + 1. Let |descendantLockStatus| be the result of [=file system entry/checking for a descendant lock=] on |entry|. + 1. If |descendantLockStatus| is "`taken`": + 1. Return "`failure`". 1. If |lock| is not "`open`": 1. If |value| is "`exclusive`" or |lock| is "`taken-exclusive`": 1. Return "`failure`". @@ -157,12 +160,47 @@ Note: These steps have to be run on the [=file system queue=].
-To release a [=file entry/lock=] on a given -[=/file entry=] |file|: +To check for an ancestor lock on a given +[=/file system entry=] |entry|: + +1. Let |parent| be the |entry|'s [=file system entry/parent=]. +1. If |parent| is null: + 1. Return "`open`". +1. Let |lock| be the |parent|'s [=file system entry/lock=]. +1. If |lock| is not "`open`": + 1. Return "`taken`". +1. Let |ancestorLockStatus| be the result of [=file system entry/checking for an ancestor lock=] on |parent|. +1. Return |ancestorLockStatus|. + +Note: These steps have to be run on the [=file system queue=]. + +
+ +
+To check for a descendant lock on a given +[=directory entry=] |directory|: + +1. [=set/For each=] |child| of |directory|'s [=directory entry/children=]: + 1. Let |lock| be the |child|'s [=file system entry/lock=]. + 1. If |lock| is not "`open`": + 1. Return "`taken`". + 1. If |child| is a [=directory entry=]: + 1. Let |descendantLockStatus| be the result of [=file system entry/checking for a descendant lock=] on |child|. + 1. If |descendantLockStatus| is "`taken`": + 1. Return "`taken`". +1. Return "`open`". + +Note: These steps have to be run on the [=file system queue=]. + +
+ +
+To release a [=file system entry/lock=] on a given +[=/file system entry=] |entry|: -1. Let |lock| be the |file|'s associated [=file entry/lock=]. +1. Let |lock| be the |entry|'s associated [=file system entry/lock=]. 1. [=Assert=]: |lock| is not "`open`". -1. Let |count| be the |file|'s [=file entry/lock count=]. +1. Let |count| be the |entry|'s [=file system entry/lock count=]. 1. [=Assert=]: |count| is greater than 0. 1. Decrease |count| by 1. 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=]. Note: Locks help prevent concurrent modifications to a file. A {{FileSystemWritableFileStream}} requires a shared lock, while a {{FileSystemSyncAccessHandle}} requires an exclusive one. +A file entry additionally consists of +binary data (a [=byte sequence=]) and a +modification timestamp (a number representing the number of milliseconds since the Unix Epoch). + A directory entry additionally consists of a [=/set=] of children, which are themselves [=/file system entries=]. Each member is either a [=/file entry=] or a [=/directory entry=]. @@ -536,7 +578,7 @@ The getFile() method steps are: the temporary file starts out empty, otherwise the existing file is first copied to this temporary file. - Creating a {{FileSystemWritableFileStream}} [=file entry/take a lock|takes a shared lock=] on the + Creating a {{FileSystemWritableFileStream}} [=file system entry/take a lock|takes a shared lock=] on the [=file entry=] [=locate an entry|locatable=] with |fileHandle|'s [=FileSystemHandle/locator=]. This prevents the creation of {{FileSystemSyncAccessHandle|FileSystemSyncAccessHandles}} for the entry, until the stream is closed. @@ -573,7 +615,7 @@ The createWritable(|options|) method |result| with a "{{NotFoundError}}" {{DOMException}} and abort these steps. 1. [=Assert=]: |entry| is a [=file entry=]. - 1. Let |lockResult| be the result of [=file entry/take a lock|taking a lock=] + 1. Let |lockResult| be the result of [=file system entry/take a lock|taking a lock=] with "`shared`" on |entry|. 1. [=Queue a storage task=] with |global| to run these steps: @@ -601,7 +643,7 @@ The createWritable(|options|) method [=file entry=] [=locate an entry|locatable=] by |fileHandle|'s [=FileSystemHandle/locator=]. To ensure the changes are reflected in this file, the handle can be flushed. - Creating a {{FileSystemSyncAccessHandle}} [=file entry/take a lock|takes an exclusive lock=] on the + Creating a {{FileSystemSyncAccessHandle}} [=file system entry/take a lock|takes an exclusive lock=] on the [=file entry=] [=locate an entry|locatable=] with |fileHandle|'s [=FileSystemHandle/locator=]. This prevents the creation of further {{FileSystemSyncAccessHandle|FileSystemSyncAccessHandles}} or {{FileSystemWritableFileStream|FileSystemWritableFileStreams}} @@ -643,7 +685,7 @@ The createSyncAccessHandle() method s |result| with a "{{NotFoundError}}" {{DOMException}} and abort these steps. 1. [=Assert=]: |entry| is a [=file entry=]. - 1. Let |lockResult| be the result of [=file entry/take a lock|taking a lock=] + 1. Let |lockResult| be the result of [=file system entry/take a lock|taking a lock=] with "`exclusive`" on |entry|. 1. [=Queue a storage task=] with |global| to run these steps: @@ -1179,7 +1221,7 @@ given a [=file entry=] |file| in a [=/Realm=] |realm|: file on disk being written to. 1. [=Enqueue the following steps=] to the [=file system queue=]: - 1. [=file entry/lock/release|Release the lock=] on + 1. [=file system entry/lock/release|Release the lock=] on |stream|'s [=FileSystemWritableFileStream/[[file]]=]. 1. [=Queue a storage task=] with |file|'s [=relevant global object=] to [=/resolve=] |closeResult| with `undefined`. @@ -1187,7 +1229,7 @@ given a [=file entry=] |file| in a [=/Realm=] |realm|: 1. Return |closeResult|. 1. Let |abortAlgorithm| be these steps: 1. [=enqueue steps|Enqueue this step=] to the [=file system queue=]: - 1. [=file entry/lock/release|Release the lock=] on + 1. [=file system entry/lock/release|Release the lock=] on |stream|'s [=FileSystemWritableFileStream/[[file]]=]. 1. Let |highWaterMark| be 1. 1. Let |sizeAlgorithm| be an algorithm that returns `1`. @@ -1647,7 +1689,7 @@ The flush() method steps are: : |handle| . {{FileSystemSyncAccessHandle/close()}} :: Closes the access handle or no-ops if the access handle is already closed. This disables any further operations on it and - [=file entry/lock/release|releases the lock=] on the + [=file system entry/lock/release|releases the lock=] on the [=FileSystemSyncAccessHandle/[[file]]=] associated with |handle|.
@@ -1659,7 +1701,7 @@ The close() method steps are: 1. Set |lockReleased| to false. 1. Let |file| be [=this=]'s [=FileSystemSyncAccessHandle/[[file]]=]. 1. [=Enqueue the following steps=] to the [=file system queue=]: - 1. [=file entry/lock/release|Release the lock=] on |file|. + 1. [=file system entry/lock/release|Release the lock=] on |file|. 1. Set |lockReleased| to true. 1. [=Pause=] until |lockReleased| is true.