Skip to content

Commit

Permalink
Work around assumeIsolated now requiring Sendable values
Browse files Browse the repository at this point in the history
  • Loading branch information
tgoyne committed Jun 18, 2024
1 parent 9e935a6 commit 5944cb0
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 28 deletions.
4 changes: 1 addition & 3 deletions RealmSwift/Aliases.swift
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,8 @@ extension ObjectBase {
let token = RLMObjectNotificationToken()
token.observe(self, keyPaths: keyPaths) { object, names, oldValues, newValues, error in
assert(error == nil)
assumeOnActorExecutor(actor) { actor in
block(actor, .init(object: object as? T, names: names,
actor.invokeIsolated(block, .init(object: object as? T, names: names,
oldValues: oldValues, newValues: newValues))
}
}
await withTaskCancellationHandler(operation: token.registrationComplete,
onCancel: { token.invalidate() })
Expand Down
4 changes: 1 addition & 3 deletions RealmSwift/Impl/RealmCollectionImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,7 @@ extension RealmCollectionImpl {
) async -> NotificationToken {
await with(self, on: actor) { actor, collection in
collection.observe(keyPaths: keyPaths, on: nil) { change in
assumeOnActorExecutor(actor) { actor in
block(actor, change)
}
actor.invokeIsolated(block, change)
}
} ?? NotificationToken()
}
Expand Down
4 changes: 1 addition & 3 deletions RealmSwift/Map.swift
Original file line number Diff line number Diff line change
Expand Up @@ -607,9 +607,7 @@ public final class Map<Key: _MapKey, Value: RealmCollectionValue>: RLMSwiftColle
) async -> NotificationToken {
await with(self, on: actor) { actor, collection in
collection.observe(keyPaths: keyPaths, on: nil) { change in
assumeOnActorExecutor(actor) { actor in
block(actor, change)
}
actor.invokeIsolated(block, change)
}
} ?? NotificationToken()
}
Expand Down
4 changes: 1 addition & 3 deletions RealmSwift/Projection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -536,9 +536,7 @@ extension ProjectionObservable {
) async -> NotificationToken {
await with(self, on: actor) { actor, obj in
obj.observe(keyPaths: keyPaths, on: nil) { (change: ObjectChange<Self>) in
assumeOnActorExecutor(actor) { actor in
block(actor, change)
}
actor.invokeIsolated(block, change)
}
} ?? NotificationToken()
}
Expand Down
4 changes: 1 addition & 3 deletions RealmSwift/SectionedResults.swift
Original file line number Diff line number Diff line change
Expand Up @@ -206,9 +206,7 @@ public extension RealmSectionedResult {
) async -> NotificationToken {
await with(self, on: actor) { actor, collection in
collection.observe(keyPaths: keyPaths, on: nil) { change in
assumeOnActorExecutor(actor) { actor in
block(actor, change)
}
actor.invokeIsolated(block, change)
}
} ?? NotificationToken()
}
Expand Down
39 changes: 26 additions & 13 deletions RealmSwift/Util.swift
Original file line number Diff line number Diff line change
Expand Up @@ -160,30 +160,43 @@ internal func logRuntimeIssue(_ message: StaticString) {
}
}

@available(macOS 10.15, tvOS 13.0, iOS 13.0, watchOS 6.0, *)
@_unavailableFromAsync
internal func assumeOnMainActorExecutor<T>(_ operation: @MainActor () throws -> T,
file: StaticString = #fileID, line: UInt = #line
) rethrows -> T {
internal func assumeOnMainActorExecutor(_ operation: @MainActor () throws -> Void,
file: StaticString = #fileID, line: UInt = #line
) rethrows {
#if compiler(>=5.10)
// This is backdeployable in Xcode 15.3+, but not 15.1
try MainActor.assumeIsolated(operation)
#else
if #available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *) {
return try MainActor.assumeIsolated(operation)
}

precondition(Thread.isMainThread, file: file, line: line)
return try withoutActuallyEscaping(operation) { fn in
try unsafeBitCast(fn, to: (() throws -> T).self)()
try unsafeBitCast(fn, to: (() throws -> ()).self)()
}
#endif
}

@_unavailableFromAsync
@available(macOS 10.15, tvOS 13.0, iOS 13.0, watchOS 6.0, *)
internal func assumeOnActorExecutor<A: Actor, T>(_ actor: A,
_ operation: (isolated A) throws -> T
) rethrows -> T {
if #available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *) {
return try actor.assumeIsolated(operation)
}
extension Actor {
@_unavailableFromAsync
internal func invokeIsolated<Ret, Arg>(_ operation: (isolated Self, Arg) throws -> Ret, _ arg: Arg,
file: StaticString = #fileID, line: UInt = #line
) rethrows -> Ret {
#if compiler(>=5.10)
// This is backdeployable in Xcode 15.3+, but not 15.1
preconditionIsolated(file: file, line: line)
#else
if #available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *) {
preconditionIsolated(file: file, line: line)
}
#endif

return try withoutActuallyEscaping(operation) { fn in
try unsafeBitCast(fn, to: ((A) throws -> T).self)(actor)
return try withoutActuallyEscaping(operation) { fn in
try unsafeBitCast(fn, to: ((Self, Arg) throws -> Ret).self)(self, arg)
}
}
}

0 comments on commit 5944cb0

Please sign in to comment.