From e65e1824cc944f98f028be94fcdb9eaa0ad5bec3 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Sat, 18 Mar 2023 22:19:23 +0000 Subject: [PATCH] Make `FileSystem` and conforming types as `Sendable` --- Sources/TSCBasic/FileSystem.swift | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/Sources/TSCBasic/FileSystem.swift b/Sources/TSCBasic/FileSystem.swift index 741aa93e..8f0cc22b 100644 --- a/Sources/TSCBasic/FileSystem.swift +++ b/Sources/TSCBasic/FileSystem.swift @@ -146,7 +146,7 @@ public enum FileMode: Sendable { /// substitute a virtual file system or redirect file system operations. /// /// - Note: All of these APIs are synchronous and can block. -public protocol FileSystem: AnyObject { +public protocol FileSystem: AnyObject, Sendable { /// Check whether the given path exists and is accessible. func exists(_ path: AbsolutePath, followSymlink: Bool) -> Bool @@ -548,8 +548,6 @@ private class LocalFileSystem: FileSystem { } } -// FIXME: This class does not yet support concurrent mutation safely. -// /// Concrete FileSystem implementation which simulates an empty disk. public class InMemoryFileSystem: FileSystem { @@ -1008,6 +1006,9 @@ public class InMemoryFileSystem: FileSystem { } } +// Internal state of `InMemoryFileSystem` is protected with a lock in all of its `public` methods. +extension InMemoryFileSystem: @unchecked Sendable {} + /// A rerooted view on an existing FileSystem. /// /// This is a simple wrapper which creates a new FileSystem view into a subtree @@ -1159,9 +1160,16 @@ public class RerootedFileSystemView: FileSystem { } } +// `RerootedFileSystemView` doesn't hold any internal state and can be considered `Sendable` since +// `underlyingFileSystem` is required to be `Sendable`. +extension RerootedFileSystemView: @unchecked Sendable {} + /// Public access to the local FS proxy. public var localFileSystem: FileSystem = LocalFileSystem() +// `LocalFileSystem` doesn't hold any internal state and all of its underlying operations are blocking. +extension LocalFileSystem: @unchecked Sendable {} + extension FileSystem { /// Print the filesystem tree of the given path. ///