@@ -288,6 +288,9 @@ public protocol FileSystem: Sendable {
288288
289289 /// Execute the given block while holding the lock.
290290 func withLock< T> ( on path: AbsolutePath , type: FileLock . LockType , _ body: ( ) throws -> T ) throws -> T
291+
292+ /// Execute the given block while holding the lock.
293+ func withLock< T> ( on path: AbsolutePath , type: FileLock . LockType , _ body: ( ) async throws -> T ) async throws -> T
291294}
292295
293296/// Convenience implementations (default arguments aren't permitted in protocol
@@ -336,6 +339,10 @@ public extension FileSystem {
336339 throw FileSystemError ( . unsupported, path)
337340 }
338341
342+ func withLock< T> ( on path: AbsolutePath , type: FileLock . LockType , _ body: ( ) async throws -> T ) async throws -> T {
343+ throw FileSystemError ( . unsupported, path)
344+ }
345+
339346 func hasQuarantineAttribute( _ path: AbsolutePath ) -> Bool { false }
340347
341348 func hasAttribute( _ name: FileSystemAttribute , _ path: AbsolutePath ) -> Bool { false }
@@ -601,12 +608,20 @@ private struct LocalFileSystem: FileSystem {
601608 func withLock< T> ( on path: AbsolutePath , type: FileLock . LockType = . exclusive, _ body: ( ) throws -> T ) throws -> T {
602609 try FileLock . withLock ( fileToLock: path, type: type, body: body)
603610 }
611+
612+ func withLock< T> (
613+ on path: AbsolutePath ,
614+ type: FileLock . LockType = . exclusive,
615+ _ body: ( ) async throws -> T
616+ ) async throws -> T {
617+ try await FileLock . withLock ( fileToLock: path, type: type, body: body)
618+ }
604619}
605620
606621/// Concrete FileSystem implementation which simulates an empty disk.
607622public final class InMemoryFileSystem : FileSystem {
608623 /// Private internal representation of a file system node.
609- /// Not threadsafe .
624+ /// Not thread-safe .
610625 private class Node {
611626 /// The actual node data.
612627 let contents : NodeContents
@@ -622,7 +637,7 @@ public final class InMemoryFileSystem: FileSystem {
622637 }
623638
624639 /// Private internal representation the contents of a file system node.
625- /// Not threadsafe .
640+ /// Not thread-safe .
626641 private enum NodeContents {
627642 case file( ByteString )
628643 case directory( DirectoryContents )
@@ -642,7 +657,7 @@ public final class InMemoryFileSystem: FileSystem {
642657 }
643658
644659 /// Private internal representation the contents of a directory.
645- /// Not threadsafe .
660+ /// Not thread-safe .
646661 private final class DirectoryContents {
647662 var entries : [ String : Node ]
648663
@@ -697,7 +712,7 @@ public final class InMemoryFileSystem: FileSystem {
697712 }
698713
699714 /// Private function to look up the node corresponding to a path.
700- /// Not threadsafe .
715+ /// Not thread-safe .
701716 private func getNode( _ path: AbsolutePath , followSymlink: Bool = true ) throws -> Node ? {
702717 func getNodeInternal( _ path: AbsolutePath ) throws -> Node ? {
703718 // If this is the root node, return it.
@@ -841,7 +856,7 @@ public final class InMemoryFileSystem: FileSystem {
841856 }
842857 }
843858
844- /// Not threadsafe .
859+ /// Not thread-safe .
845860 private func _createDirectory( _ path: AbsolutePath , recursive: Bool ) throws {
846861 // Ignore if client passes root.
847862 guard !path. isRoot else {
@@ -989,7 +1004,7 @@ public final class InMemoryFileSystem: FileSystem {
9891004 }
9901005
9911006 /// Private implementation of core copying function.
992- /// Not threadsafe .
1007+ /// Not thread-safe .
9931008 private func _copy( from sourcePath: AbsolutePath , to destinationPath: AbsolutePath ) throws {
9941009 // Get the source node.
9951010 guard let source = try getNode ( sourcePath) else {
0 commit comments