Skip to content

Instantly share code, notes, and snippets.

@samsonjs
Created July 8, 2024 15:54
Show Gist options
  • Save samsonjs/e25b6ad7939e4e6b11a2cdb6943fae2f to your computer and use it in GitHub Desktop.
Save samsonjs/e25b6ad7939e4e6b11a2cdb6943fae2f to your computer and use it in GitHub Desktop.
Attempting to send non-Sendable AVFoundation types in a safe way
public import AVFoundation
struct UniqueRef<Value>: ~Copyable, @unchecked Sendable {
private let lock = NSLock()
private var unsafeValue: Value?
init(value: sending Value) {
self.unsafeValue = value
}
mutating func take() -> sending Value? {
lock.withLock {
defer { unsafeValue = nil }
return unsafeValue
}
}
}
public struct Settings: ~Copyable, Sendable {
private var uniqueMix: UniqueRef<AVAudioMix>?
public init(mix: sending AVAudioMix?) {
self.uniqueMix = mix.map(UniqueRef.init)
}
mutating func takeMix() -> sending AVAudioMix? {
uniqueMix?.take()
}
}
public final class ExampleExportSession: Sendable {
func export(settings: consuming sending Settings) async throws {
let writer = ExampleWriter(mix: settings.takeMix())
try await writer.write()
}
}
actor ExampleWriter {
let mix: AVAudioMix?
init(mix: sending AVAudioMix?) {
self.mix = mix
}
func write() async throws {}
}
@samsonjs
Copy link
Author

samsonjs commented Jul 9, 2024

CleanShot 2024-07-08 at 20 23 54@2x

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment