-
Notifications
You must be signed in to change notification settings - Fork 692
Description
NIOLock is particularly scary, but NIOLockedValueBox has some limitations too that need to be tidied up.
The following functions are dangerous:
swift-nio/Sources/NIOConcurrencyHelpers/NIOLock.swift
Lines 232 to 254 in 9ff5fdd
extension NIOLock { | |
/// Acquire the lock for the duration of the given block. | |
/// | |
/// This convenience method should be preferred to `lock` and `unlock` in | |
/// most situations, as it ensures that the lock will be released regardless | |
/// of how `body` exits. | |
/// | |
/// - Parameter body: The block to execute while holding the lock. | |
/// - Returns: The value returned by the block. | |
@inlinable | |
public func withLock<T>(_ body: () throws -> T) rethrows -> T { | |
self.lock() | |
defer { | |
self.unlock() | |
} | |
return try body() | |
} | |
@inlinable | |
public func withLockVoid(_ body: () throws -> Void) rethrows { | |
try self.withLock(body) | |
} | |
} |
Here, withLock
needs to take its closure sending
and the return value needs to be sending
too. In Swift 5, these both need to be Sendable
, with an unchecked version available.
swift-nio/Sources/NIOConcurrencyHelpers/NIOLockedValueBox.swift
Lines 35 to 39 in 9ff5fdd
/// Access the `Value`, allowing mutation of it. | |
@inlinable | |
public func withLockedValue<T>(_ mutate: (inout Value) throws -> T) rethrows -> T { | |
try self._storage.withLockedValue(mutate) | |
} |
Here, withLockedValue
needs again to take its closure sending
. Optionally, we could relax its Sendable
requirement, and also return the value sending
, but given our need to remain compatible with Swift 5 we should probably leave it stricter for now. In Swift 5, the closure probably needs to be @Sendable
.