-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
007bd1d
commit a0b53e3
Showing
5 changed files
with
150 additions
and
67 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
public final class AsyncRecursiveLock { | ||
@TaskLocal private static var lockCount = 0 | ||
|
||
private let internalLock = AsyncLock() | ||
|
||
public init() { | ||
} | ||
|
||
public func lock(isolation: isolated (any Actor)? = #isolation) async { | ||
// precondition(lockCount >= 0) | ||
// | ||
// lockCount += 1 | ||
// | ||
// if lockCount == 1 { | ||
// await internalLock.lock() | ||
// } | ||
} | ||
// | ||
public func unlock() { | ||
// lockCount -= 1 | ||
// | ||
// precondition(lockCount >= 0) | ||
// | ||
// if lockCount == 0 { | ||
// internalLock.unlock() | ||
// } | ||
} | ||
// | ||
// public func withLock<T>( | ||
// isolation: isolated (any Actor)? = #isolation, | ||
// _ block: () async throws -> sending T | ||
// ) async rethrows -> sending T { | ||
// await lock() | ||
// // bug | ||
//// defer { unlock() } | ||
// | ||
// do { | ||
// let value = try await block() | ||
// | ||
// unlock() | ||
// | ||
// return value | ||
// } catch { | ||
// unlock() | ||
// | ||
// throw error | ||
// } | ||
// } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import Testing | ||
import Lock | ||
|
||
actor RecursiveReentrantActor { | ||
var value = 42 | ||
let lock = AsyncRecursiveLock() | ||
|
||
func doThing() async { | ||
await lock.lock() | ||
Check failure on line 9 in Tests/LockTests/RecursiveLockTests.swift GitHub Actions / Test (platform=macOS,variant=Mac Catalyst)
Check failure on line 9 in Tests/LockTests/RecursiveLockTests.swift GitHub Actions / Test (platform=tvOS Simulator,name=Apple TV)
|
||
defer { lock.unlock() } | ||
|
||
try! #require(self.value == 42) | ||
self.value = 0 | ||
try! await Task.sleep(nanoseconds: 1_000_000) | ||
try! #require(self.value == 0) | ||
self.value = 42 | ||
} | ||
} | ||
|
||
struct RecursiveLockTests { | ||
@Test | ||
func lockUnlock() async { | ||
let lock = AsyncRecursiveLock() | ||
|
||
await lock.lock() | ||
lock.unlock() | ||
} | ||
|
||
// @Test | ||
// func serializes() async { | ||
// let actor = RecursiveReentrantActor() | ||
// var tasks = [Task<Void, Never>]() | ||
// | ||
// for _ in 0..<1000 { | ||
// let task = Task { | ||
// await actor.doThing() | ||
// } | ||
// | ||
// tasks.append(task) | ||
// } | ||
// | ||
// for task in tasks { | ||
// await task.value | ||
// } | ||
// } | ||
|
||
// @Test | ||
// func recursion() async { | ||
// let lock = AsyncLock() | ||
// | ||
// await lock.withLock { | ||
// await lock.lock() | ||
// await lock.withLock { | ||
// } | ||
// await lock.unlock() | ||
// } | ||
// } | ||
} |