Skip to content

Commit 3818207

Browse files
committed
[Concurrency] Fix _unsafeInheritExecutor usage in withTaskCancellationHandler
1 parent dd8a21e commit 3818207

File tree

4 files changed

+58
-4
lines changed

4 files changed

+58
-4
lines changed

stdlib/public/Concurrency/TaskCancellation.swift

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,26 @@ import Swift
6767
/// as resuming a continuation, may acquire these same internal locks.
6868
/// Therefore, if a cancellation handler must acquire a lock, other code should
6969
/// not cancel tasks or resume continuations while holding that lock.
70-
@_unsafeInheritExecutor // the operation runs on the same executor as we start out with
7170
@available(SwiftStdlib 5.1, *)
72-
@backDeployed(before: SwiftStdlib 5.8)
71+
@backDeployed(before: SwiftStdlib 6.0)
7372
public func withTaskCancellationHandler<T>(
73+
operation: () async throws -> T,
74+
onCancel handler: @Sendable () -> Void,
75+
isolation: isolated (any Actor)? = #isolation
76+
) async rethrows -> T {
77+
// unconditionally add the cancellation record to the task.
78+
// if the task was already cancelled, it will be executed right away.
79+
let record = _taskAddCancellationHandler(handler: handler)
80+
defer { _taskRemoveCancellationHandler(record: record) }
81+
82+
return try await operation()
83+
}
84+
85+
@_unsafeInheritExecutor // ABI compatibility with Swift 5.1
86+
@available(SwiftStdlib 5.1, *)
87+
@usableFromInline
88+
@_silgen_name("$ss27withTaskCancellationHandler9operation8onCancelxxyYaKXE_yyYbXEtYaKlF")
89+
internal func __abi_withTaskCancellationHandler<T>(
7490
operation: () async throws -> T,
7591
onCancel handler: @Sendable () -> Void
7692
) async rethrows -> T {
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// RUN: %empty-directory(%t)
2+
3+
// RUN: %target-swift-frontend -emit-module -emit-module-path %t/other_global_actor_inference.swiftmodule -module-name other_global_actor_inference -strict-concurrency=complete %S/Inputs/other_global_actor_inference.swift -enable-experimental-feature GlobalActorIsolatedTypesUsability
4+
// RUN: %target-swift-frontend -I %t -disable-availability-checking %s -emit-sil -o /dev/null -verify -verify-additional-prefix minimal-targeted- -enable-experimental-feature GlobalActorIsolatedTypesUsability
5+
// RUN: %target-swift-frontend -I %t -disable-availability-checking %s -emit-sil -o /dev/null -verify -strict-concurrency=targeted -verify-additional-prefix minimal-targeted- -enable-experimental-feature GlobalActorIsolatedTypesUsability
6+
// RUN: %target-swift-frontend -I %t -disable-availability-checking %s -emit-sil -o /dev/null -verify -strict-concurrency=complete -verify-additional-prefix complete-tns- -enable-experimental-feature GlobalActorIsolatedTypesUsability
7+
// RUN: %target-swift-frontend -I %t -disable-availability-checking %s -emit-sil -o /dev/null -verify -strict-concurrency=complete -enable-upcoming-feature RegionBasedIsolation -verify-additional-prefix complete-tns- -enable-experimental-feature GlobalActorIsolatedTypesUsability
8+
9+
// REQUIRES: concurrency
10+
// REQUIRES: asserts
11+
12+
actor Container {
13+
var num: Int = 0 // expected-note{{mutation of this property is only permitted within the actor}}
14+
func test() async {
15+
16+
// no warnings:
17+
await withTaskCancellationHandler {
18+
num += 1
19+
} onCancel: {
20+
// nothing
21+
}
22+
}
23+
24+
func errors() async {
25+
await withTaskCancellationHandler {
26+
num += 1 // no error, this runs synchronously on caller context
27+
} onCancel: {
28+
// this should error because cancellation is invoked concurrently
29+
num += 10 // expected-error{{actor-isolated property 'num' can not be mutated from a Sendable closure}}
30+
}
31+
}
32+
}

test/abi/macOS/arm64/concurrency.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,8 +316,11 @@ Added: _$sScf13checkIsolatedyyFTj
316316
// method descriptor for Swift.SerialExecutor.checkIsolated() -> ()
317317
Added: _$sScf13checkIsolatedyyFTq
318318

319-
// #isolated adoption in TaskLocal.withValue
319+
// #isolated adoption in multiple APIs
320320
// Swift.TaskLocal.withValueImpl<A>(_: __owned A, operation: () async throws -> A1, isolation: isolated Swift.Actor?, file: Swift.String, line: Swift.UInt) async throws -> A1
321+
// withTaskCancellationHandler gains #isolated
322+
Added: _$ss27withTaskCancellationHandler9operation8onCancel9isolationxxyYaKXE_yyYbXEScA_pSgYitYaKlF
323+
Added: _$ss27withTaskCancellationHandler9operation8onCancel9isolationxxyYaKXE_yyYbXEScA_pSgYitYaKlFTu
321324
Added: _$ss9TaskLocalC13withValueImpl_9operation9isolation4file4lineqd__xn_qd__yYaKXEScA_pSgYiSSSutYaKlF
322325
Added: _$ss9TaskLocalC13withValueImpl_9operation9isolation4file4lineqd__xn_qd__yYaKXEScA_pSgYiSSSutYaKlFTu
323326
// Swift.TaskLocal.withValue<A>(_: A, operation: () async throws -> A1, isolation: isolated Swift.Actor?, file: Swift.String, line: Swift.UInt) async throws -> A1

test/abi/macOS/x86_64/concurrency.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,10 @@ Added: _$sScf13checkIsolatedyyFTj
316316
// method descriptor for Swift.SerialExecutor.checkIsolated() -> ()
317317
Added: _$sScf13checkIsolatedyyFTq
318318

319-
// #isolated adoption in TaskLocal.withValue
319+
// #isolated adoption in multiple APis
320+
// withTaskCancellationHandler gains #isolated
321+
Added: _$ss27withTaskCancellationHandler9operation8onCancel9isolationxxyYaKXE_yyYbXEScA_pSgYitYaKlF
322+
Added: _$ss27withTaskCancellationHandler9operation8onCancel9isolationxxyYaKXE_yyYbXEScA_pSgYitYaKlFTu
320323
// Swift.TaskLocal.withValueImpl<A>(_: __owned A, operation: () async throws -> A1, isolation: isolated Swift.Actor?, file: Swift.String, line: Swift.UInt) async throws -> A1
321324
Added: _$ss9TaskLocalC13withValueImpl_9operation9isolation4file4lineqd__xn_qd__yYaKXEScA_pSgYiSSSutYaKlF
322325
Added: _$ss9TaskLocalC13withValueImpl_9operation9isolation4file4lineqd__xn_qd__yYaKXEScA_pSgYiSSSutYaKlFTu

0 commit comments

Comments
 (0)