Skip to content

Commit

Permalink
Merge remote-tracking branch 'brzzdev/lock-isolated-non-sendable' int…
Browse files Browse the repository at this point in the history
…o lock-isolated-non-sendable
  • Loading branch information
brzzdev committed Oct 31, 2023
2 parents 6db610b + 91d49e3 commit 6d509c3
Showing 1 changed file with 18 additions and 13 deletions.
31 changes: 18 additions & 13 deletions Sources/ConcurrencyExtras/LockIsolated.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Foundation

/// A generic wrapper for isolating a mutable value with a lock.
/// A generic wrapper for isolating a mutable or non-Sendable value with a lock.
///
/// To asynchronously isolate a value on an actor, see ``ActorIsolated``. If you trust the
/// sendability of the underlying value, consider using ``UncheckedSendable``, instead.
Expand All @@ -12,9 +12,23 @@ public final class LockIsolated<Value>: @unchecked Sendable {
/// Initializes lock-isolated state around a value.
///
/// - Parameter value: A value to isolate with a lock.
public init(_ value: @autoclosure @Sendable () throws -> Value) rethrows {
public init(_ value: @Sendable () throws -> Value) rethrows {
self._value = try value()
}

/// Initializes lock-isolated state around a value.
///
/// - Parameter value: A value to isolate with a lock.
public init(_ value: Value) {
self._value = value
}

/// The lock-isolated value.
public var value: Value {
self.lock.sync {
self._value
}
}

public subscript<Subject: Sendable>(dynamicMember keyPath: KeyPath<Value, Subject>) -> Subject {
self.lock.sync {
Expand All @@ -28,7 +42,7 @@ public final class LockIsolated<Value>: @unchecked Sendable {
///
/// ```swift
/// // Isolate an integer for concurrent read/write access:
/// var count = LockIsolated(0)
/// let count = LockIsolated(0)
///
/// func increment() {
/// // Safely increment it:
Expand All @@ -52,7 +66,7 @@ public final class LockIsolated<Value>: @unchecked Sendable {
///
/// ```swift
/// // Isolate an integer for concurrent read/write access:
/// var count = LockIsolated(0)
/// let count = LockIsolated(0)
///
/// func reset() {
/// // Reset it:
Expand Down Expand Up @@ -84,15 +98,6 @@ public final class LockIsolated<Value>: @unchecked Sendable {
}
}

extension LockIsolated where Value: Sendable {
/// The lock-isolated value.
public var value: Value {
self.lock.sync {
self._value
}
}
}

extension LockIsolated: Equatable where Value: Equatable {
public static func == (lhs: LockIsolated, rhs: LockIsolated) -> Bool {
lhs.withValue { lhsValue in rhs.withValue { rhsValue in lhsValue == rhsValue } }
Expand Down

0 comments on commit 6d509c3

Please sign in to comment.