From ea8a3f08e12bbcf4c92cf63ed4d160d6a5197b15 Mon Sep 17 00:00:00 2001 From: Nathan Memmott Date: Thu, 6 Jul 2023 13:50:07 -0700 Subject: [PATCH] Support locking of directory entries Moves the locking algorithm from file entry to file system entry. Fixes #137 --- index.bs | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/index.bs b/index.bs index 85afe86..c473795 100644 --- a/index.bs +++ b/index.bs @@ -109,7 +109,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 shared lock count (a number representing the number shared 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. @@ -123,22 +125,16 @@ 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 shared lock count (a number representing the number shared locks that are taken at a given point in time). - -A user agent has an associated file system queue which is the +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 sytem operations.
-To take a [=file entry/lock=] with a |value| of -"`exclusive`" or "`shared`" on a given [=file entry=] |file|: +To take a [=file system entry/lock=] with a |value| of +"`exclusive`" or "`shared`" on a given [=/file system entry=] |entry|: -1. Let |lock| be the |file|'s [=file entry/lock=]. -1. Let |count| be the |file|'s [=file entry/shared lock count=]. +1. Let |lock| be the |entry|'s [=file system entry/lock=]. +1. Let |count| be the |entry|'s [=file system entry/shared lock count=]. 1. If |value| is "`exclusive`": 1. If |lock| is "`open`": 1. Set lock to "`taken-exclusive`". @@ -158,11 +154,11 @@ 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 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 |count| be the |file|'s [=file entry/shared lock count=]. +1. Let |lock| be the |entry|'s associated [=file system entry/lock=]. +1. Let |count| be the |entry|'s [=file system entry/shared lock count=]. 1. If |lock| is "`taken-shared`": 1. Decrease |count| by 1. 1. If |count| is 0, set |lock| to "`open`". @@ -175,6 +171,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=]. @@ -537,7 +537,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/lock/take|takes a shared lock=] on the + Creating a {{FileSystemWritableFileStream}} [=file system entry/lock/take|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. @@ -574,7 +574,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/lock/take|taking a lock=] + 1. Let |lockResult| be the result of [=file system entry/lock/take|taking a lock=] with "`shared`" on |entry|. 1. [=Queue a storage task=] with |global| to run these steps: @@ -602,7 +602,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/lock/take|takes an exclusive lock=] on the + Creating a {{FileSystemSyncAccessHandle}} [=file system entry/lock/take|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}} @@ -644,7 +644,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/lock/take|taking a lock=] + 1. Let |lockResult| be the result of [=file system entry/lock/take|taking a lock=] with "`exclusive`" on |entry|. 1. [=Queue a storage task=] with |global| to run these steps: @@ -1180,7 +1180,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`. @@ -1188,7 +1188,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`. @@ -1648,7 +1648,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|.
@@ -1660,7 +1660,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.