Skip to content

Conversation

@ktoso
Copy link
Contributor

@ktoso ktoso commented Apr 11, 2025

The problem is that even with the #isolation parameter the non-Sendable
async closure operation still would potentially hop off the caller
isolation. We introduced this change because the plan was the
non-Sendable closure would run on the isolated parameter's isolation,
but that's not actually the case: an "re-enqueue" can still happens in those cases.

Instead, we can use the nonisolated(nonsending) on the function and closure,
in order to guarantee there is no hop between those at all, and
developers can trust that adding this cancellation handler will not
cause any unexpected isolation changes and hops.

The API was always documented to not hop as we execute the operation,
so this brings the correct and expected behavior.

This corrects the following APIs:

  • withCheckedContinuation
  • withUnsafeContinuation
  • withCheckedThrowingContinuation
  • withUnsafeThrowingContinuation
  • withTaskGroup
  • withThrowingTaskGroup
  • withDiscardingTaskGroup
  • withThrowingDiscardingTaskGroup
  • TaskLocal.withValue

as well as task group's next() and related ones...

This gets down the "re-enqueue" count of those methods by far, and makes all these more reliable and predictable.

resolves rdar://140110775
resolves rdar://162192512

@ktoso ktoso requested a review from a team as a code owner April 11, 2025 07:24
@ktoso ktoso force-pushed the wip-improve-withTaskCancellationHandler-with-caller-execution branch 2 times, most recently from de601db to 1303d99 Compare April 11, 2025 07:28
@ktoso
Copy link
Contributor Author

ktoso commented Apr 12, 2025

This is blocked by incorrect behavior of the caller execution on a closure rdar://149107104

@ktoso ktoso added the concurrency Feature: umbrella label for concurrency language features label Apr 17, 2025
@ktoso ktoso force-pushed the wip-improve-withTaskCancellationHandler-with-caller-execution branch 2 times, most recently from a583630 to 9ea3293 Compare April 30, 2025 02:13
@ktoso
Copy link
Contributor Author

ktoso commented Apr 30, 2025

Now blocked on rdar://150017382

@ktoso
Copy link
Contributor Author

ktoso commented May 15, 2025

@swift-ci please smoke test

@gottesmm
Copy link
Contributor

@swift-ci smoke test

1 similar comment
@gottesmm
Copy link
Contributor

gottesmm commented Jul 7, 2025

@swift-ci smoke test

@ktoso
Copy link
Contributor Author

ktoso commented Jul 8, 2025

Good news, this was now unblocked by #82858

@ktoso ktoso force-pushed the wip-improve-withTaskCancellationHandler-with-caller-execution branch 3 times, most recently from 25a963e to be2b2ad Compare July 8, 2025 09:28
@ktoso
Copy link
Contributor Author

ktoso commented Jul 8, 2025

@swift-ci please smoke test

@ktoso
Copy link
Contributor Author

ktoso commented Jul 8, 2025

This is almost unblocked, we need to fix throwing nonisolated nonsending (caller isolated) closures to not lose isolation -- rdar://155313349

And there seems to be a problem with noncopyable types and nonisolated nonsending (caller isolated) closures as well; It shows up in cancellation_handler_only_once.swift:20 as a error: copy of noncopyable typed value. -- rdar://155316655

Giving it a run to see if anything else

@ktoso
Copy link
Contributor Author

ktoso commented Jul 8, 2025

@swift-ci please smoke test

@ktoso
Copy link
Contributor Author

ktoso commented Jul 11, 2025

By now this is unlikely to make it into 6.2.0

@ktoso ktoso force-pushed the wip-improve-withTaskCancellationHandler-with-caller-execution branch from 9f1e063 to 0e5a262 Compare October 14, 2025 09:23
@ktoso ktoso requested a review from phausler as a code owner October 14, 2025 09:23
@ktoso ktoso changed the title [Concurrency] improve cancellation handler to not hop and use caller execution context [Concurrency] Correct enqueue behavior in with... functions by adopting nonisolated(nonsending) Oct 14, 2025
@ktoso
Copy link
Contributor Author

ktoso commented Oct 15, 2025

@swift-ci please smoke test

@ktoso
Copy link
Contributor Author

ktoso commented Oct 15, 2025

Fixing all the ABI tests to follow.

@ktoso ktoso force-pushed the wip-improve-withTaskCancellationHandler-with-caller-execution branch from fcdc60b to 01e0397 Compare October 15, 2025 15:17
@ktoso ktoso force-pushed the wip-improve-withTaskCancellationHandler-with-caller-execution branch from 01e0397 to 9a2d287 Compare October 15, 2025 15:17
@ktoso
Copy link
Contributor Author

ktoso commented Oct 15, 2025

@swift-ci please smoke test

ktoso added a commit to ktoso/swift that referenced this pull request Oct 16, 2025
This is the minimal set of changes from
swiftlang#80753 to specifically address
the with...Continuation APIs re-enqueueing tasks when they need not have
to.

Resolves rdar://162192512

resolves
@ktoso
Copy link
Contributor Author

ktoso commented Oct 16, 2025

@gottesmm will investigate the optimizer approach to solving this instead; seems we're missing the optimization in debug mode

ktoso added a commit to ktoso/swift that referenced this pull request Oct 21, 2025
This is the minimal set of changes from
swiftlang#80753 to specifically address
the with...Continuation APIs re-enqueueing tasks when they need not have
to.

In the specific case of the continuation APIs we move to adopt the
`nonisolated(nonsending)` feature, however there will be a follow-up
here to improve how we handle enqueues with a Serial Executor that is
also a Task Executor at the same time

Resolves rdar://162192512
ktoso added a commit to ktoso/swift that referenced this pull request Oct 21, 2025
This is the minimal set of changes from
swiftlang#80753 to specifically address
the with...Continuation APIs re-enqueueing tasks when they need not have
to.

In the specific case of the continuation APIs we move to adopt the
`nonisolated(nonsending)` feature, however there will be a follow-up
here to improve how we handle enqueues with a Serial Executor that is
also a Task Executor at the same time

Resolves rdar://162192512
ktoso added a commit to ktoso/swift that referenced this pull request Oct 22, 2025
This is the minimal set of changes from
swiftlang#80753 to specifically address
the with...Continuation APIs re-enqueueing tasks when they need not have
to.

In the specific case of the continuation APIs we move to adopt the
`nonisolated(nonsending)` feature, however there will be a follow-up
here to improve how we handle enqueues with a Serial Executor that is
also a Task Executor at the same time

Resolves rdar://162192512
ktoso added a commit to ktoso/swift that referenced this pull request Oct 29, 2025
This is the minimal set of changes from
swiftlang#80753 to specifically address
the with...Continuation APIs re-enqueueing tasks when they need not have
to.

In the specific case of the continuation APIs we move to adopt the
`nonisolated(nonsending)` feature, however there will be a follow-up
here to improve how we handle enqueues with a Serial Executor that is
also a Task Executor at the same time

Resolves rdar://162192512
@ktoso ktoso force-pushed the wip-improve-withTaskCancellationHandler-with-caller-execution branch from 9a2d287 to 3ceae73 Compare December 15, 2025 07:17
@ktoso
Copy link
Contributor Author

ktoso commented Dec 15, 2025

@swift-ci please smoke test

Copy link
Contributor

@jamieQ jamieQ left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some further unsolicited feedback/questions for your consideration :)

func globalTestFunc(isolation: isolated (any Actor)? = #isolation) async {
isolation!.assertIsolated("wat in \(#function)!")
await withTaskCancellationHandler {
isolation!.assertIsolated("wat in \(#function)!")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might be good to test that this works without a capture of the isolated parameter too, to ensure it's relying on the nonisolated(nonsending)-ness of the closure, and not the isolated capture logic.

@ktoso ktoso force-pushed the wip-improve-withTaskCancellationHandler-with-caller-execution branch 3 times, most recently from eda5dc2 to aa0fb44 Compare December 16, 2025 13:30
This drastically lessens the number of unexpected task enqueues and hops
that these APIs cause, and therefore improves performance and even
correctness in a few cases (like the withContinuation APIs)
@ktoso ktoso force-pushed the wip-improve-withTaskCancellationHandler-with-caller-execution branch from aa0fb44 to 13e6b40 Compare December 16, 2025 23:15
@ktoso
Copy link
Contributor Author

ktoso commented Dec 16, 2025

@swift-ci please smoke test

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

Labels

concurrency Feature: umbrella label for concurrency language features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants