# Suspension guarantees when isolation does not change

**URL:** <https://forums.swift.org/t/suspension-guarantees-when-isolation-does-not-change/73606>\
**Category:** Using Swift\
**Tags:** concurrency\
**Created:** [July 31, 2024, 8:29pm UTC](https://forums.swift.org/t/suspension-guarantees-when-isolation-does-not-change/73606 "2024-07-31T20:29:48Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![mattie](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/mattie/32/13267_2.png) [@mattie](https://forums.swift.org/u/mattie)\
**Post date:** [July 31, 2024, 8:29pm UTC](https://forums.swift.org/t/suspension-guarantees-when-isolation-does-not-change/73606/1 "2024-07-31T20:29:48Z")

</div>

I have a question about suspension. SE-0420 says this:

> Avoiding extra suspensions from actor-isolated code can also be semantically important because code from other tasks can interleave on the actor during suspensions, potentially changing the values stored in isolated storage; this is guaranteed not to happen at the moments of call and return between functions with the same isolation.

Does this mean the transition from points A to B in this example is guaranteed to be synchronous? Is that true in all cases when the isolation does not change?

```swift
actor MyActor {
  func funcA() async {
    // point A
    await funcB()
  }
    
  func funcB() async {
    // point B
  }
}

```

---

<div class="post-metadata">

**Author:** ![ktoso](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ktoso/32/44526_2.png) [@ktoso](https://forums.swift.org/u/ktoso)\
**Post date:** [July 31, 2024, 9:21pm UTC](https://forums.swift.org/t/suspension-guarantees-when-isolation-does-not-change/73606/2 "2024-07-31T21:21:11Z")

</div>

Yeah, this is something you can rely on because of the "`await` is only marking potential suspension points" and this code actually has nothing that'd force a suspension...

Since you're "on" the actor already, and not "giving it up", the `funcB` call should not have a way to fail "getting on the actor".

At least today this is guaranteed and code does rely on it frequently.

---

<div class="post-metadata">

**Author:** ![ksluder](https://avatars.discourse-cdn.com/v4/letter/k/eada6e/32.png) [@ksluder](https://forums.swift.org/u/ksluder)\
**Post date:** [July 31, 2024, 9:26pm UTC](https://forums.swift.org/t/suspension-guarantees-when-isolation-does-not-change/73606/3 "2024-07-31T21:26:45Z")

</div>

Should the compiler diagnose a warning about an unnecessary `await` here, to reinforce the guarantee that an actor-isolated function that calls another function that is isolated to the same actor will not suspend?

---

<div class="post-metadata">

**Author:** ![Jumhyn](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jumhyn/32/3891_2.png) [@Jumhyn](https://forums.swift.org/u/Jumhyn)\
**Post date:** [July 31, 2024, 9:32pm UTC](https://forums.swift.org/t/suspension-guarantees-when-isolation-does-not-change/73606/4 "2024-07-31T21:32:32Z")

</div>

`funcB` here is declared `async` so I think it's appropriate to require `await`. With detailed knowledge of the behavior of `funcB` one might be able to 'know' that `funcB` won't _actually_ suspend, but `funcB` has declared its intent that it should be treated _as though it's going to suspend_. (And indeed, under Swift's current rules the `await` is _not_ unnecessary—it is an error to omit the `await` here.)

---

<div class="post-metadata">

**Author:** ![ksluder](https://avatars.discourse-cdn.com/v4/letter/k/eada6e/32.png) [@ksluder](https://forums.swift.org/u/ksluder)\
**Post date:** [July 31, 2024, 9:33pm UTC](https://forums.swift.org/t/suspension-guarantees-when-isolation-does-not-change/73606/5 "2024-07-31T21:33:45Z")

</div>

> [@Jumhyn](#):
>
> `funcB` here is declared `async` so I think it's appropriate to require `await`.

Ah, yes. I had a feeling I was missing something.

---

<div class="post-metadata">

**Author:** ![mattie](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/mattie/32/13267_2.png) [@mattie](https://forums.swift.org/u/mattie)\
**Post date:** [July 31, 2024, 10:04pm UTC](https://forums.swift.org/t/suspension-guarantees-when-isolation-does-not-change/73606/6 "2024-07-31T22:04:51Z")

</div>

> [@ktoso](#):
>
> At least today this is guaranteed and code does rely on it frequently.

This sentence is giving me pause. I also want to rely on this, but it kinda sounds like one day this might change.

I just want to be really clear because this is a pretty powerful assumption, and should it no longer be synchronous, my code would completely break.

> [@Jumhyn](#):
>
> `funcB` here is declared `async` so I think it's appropriate to require `await`

In my example, `funcB` does nothing. So, I see why the question was being asked.

But, a non-contrived example could peform out-of-isolation operations that would then necessitate suspension. Given this, isn't the `await` is absolutely necessary given these function signatures?

---

<div class="post-metadata">

**Author:** ![ktoso](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ktoso/32/44526_2.png) [@ktoso](https://forums.swift.org/u/ktoso)\
**Post date:** [July 31, 2024, 10:07pm UTC](https://forums.swift.org/t/suspension-guarantees-when-isolation-does-not-change/73606/7 "2024-07-31T22:07:16Z")

</div>

> [@mattie](#):
>
> I just want to be really clear because this is a pretty powerful assumption, and should it no longer be synchronous, my code would completely break.

It's more about "well you COULD–accidentally or on purpose–make `funcB` suspend for real and then you'd get interleaving potential".

---

<div class="post-metadata">

**Author:** ![mattie](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/mattie/32/13267_2.png) [@mattie](https://forums.swift.org/u/mattie)\
**Post date:** [July 31, 2024, 10:09pm UTC](https://forums.swift.org/t/suspension-guarantees-when-isolation-does-not-change/73606/8 "2024-07-31T22:09:54Z")

</div>

My question is about the mechnics of the function call itself. Even if `funcB` does cause a suspension, the transition from point A to point B should remain synchronous, shouldn't it?

---

<div class="post-metadata">

**Author:** ![ktoso](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ktoso/32/44526_2.png) [@ktoso](https://forums.swift.org/u/ktoso)\
**Post date:** [July 31, 2024, 10:10pm UTC](https://forums.swift.org/t/suspension-guarantees-when-isolation-does-not-change/73606/9 "2024-07-31T22:10:17Z")

</div>

It should, yeah.

---

<div class="post-metadata">

**Author:** ![mattie](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/mattie/32/13267_2.png) [@mattie](https://forums.swift.org/u/mattie)\
**Post date:** [July 31, 2024, 10:16pm UTC](https://forums.swift.org/t/suspension-guarantees-when-isolation-does-not-change/73606/10 "2024-07-31T22:16:16Z")

</div>

What I want to say is something like:

A async function call that does not change isolation is guaranteed to transfer control into the callee synchronously. But, the callee could then itself make an async call that results in suspension.

Does this sound right?

---

<div class="post-metadata">

**Author:** ![ktoso](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ktoso/32/44526_2.png) [@ktoso](https://forums.swift.org/u/ktoso)\
**Post date:** [July 31, 2024, 10:20pm UTC](https://forums.swift.org/t/suspension-guarantees-when-isolation-does-not-change/73606/11 "2024-07-31T22:20:17Z")

</div>

At least today that's true, yes. I don't expect this to change tbh.

---

<div class="post-metadata">

**Author:** ![John\_McCall](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/john_mccall/32/1351_2.png) [@John\_McCall](https://forums.swift.org/u/John_McCall)\
**Post date:** [July 31, 2024, 10:48pm UTC](https://forums.swift.org/t/suspension-guarantees-when-isolation-does-not-change/73606/12 "2024-07-31T22:48:23Z")

</div>

It is intended to be a guarantee that async function calls between functions with the same isolation will not suspend just as part of performing the call or returning from the call. The only gap I know of in that guarantee involves calls through Objective-C async (i.e. completion-handler-based) interfaces.

---

<div class="post-metadata">

**Author:** ![mattie](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/mattie/32/13267_2.png) [@mattie](https://forums.swift.org/u/mattie)\
**Post date:** [August 1, 2024, 11:45am UTC](https://forums.swift.org/t/suspension-guarantees-when-isolation-does-not-change/73606/13 "2024-08-01T11:45:11Z")

</div>

Answers the question perfectly. Thank you so much!
