Skip to content

Commit 4ca4028

Browse files
committed
Clarify some wording in SE-0417
This clarifies a bit of the execution semantics. We updated most wording but this example was a bit misleading. The diagrams and details explanations seem to be up to date.
1 parent a90aa9a commit 4ca4028

File tree

1 file changed

+8
-7
lines changed

1 file changed

+8
-7
lines changed

proposals/0417-task-executor-preference.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ func nonisolatedAsyncFunc() async -> Int {
124124
}
125125
```
126126

127-
or, for a specific scope using the `withTaskExecutorPreference` method:
127+
or, for a specific scope using the `withTaskExecutorPreference` method. Notably, the task executor preference is in effect for the entire structured task hierarchy while running in a task or scope where a task executor preference is set. For example, the following snippet illustrates child tasks created inside of a `withTaskExecutorPreference`:
128128

129129
```swift
130130
await withTaskExecutorPreference(executor) {
@@ -135,7 +135,7 @@ await withTaskExecutorPreference(executor) {
135135
await withDiscardingTaskGroup { group in
136136
group.addTask {
137137
// starts and runs on the 'executor'
138-
await nonisolatedAsyncFunc()
138+
await nonisolatedAsyncFunc() // also runs on 'executor'
139139
}
140140
}
141141

@@ -145,20 +145,21 @@ await withTaskExecutorPreference(executor) {
145145
}
146146
```
147147

148-
Notably, the task executor preference is in effect for the entire structured task hierarchy while running in a task or scope where a task executor preference is set. For example, the following snippet illustrates child tasks created inside of a `withTaskExecutorPreference`.
149-
150-
If a task with such executor preference encounters code which is `isolated` to some specific actor, it would adhere to that requirement and hop to it as expected:
148+
If a task with such executor preference encounters code which is `isolated` to some specific actor, the isolation properties of the actor still are upheld, however, unless that actor has a custom executor configured, the source of the thread actually running the actor's functions will be from the preferred executor:
151149

152150
```swift
153151
let capy: Capybara = Capybara()
154152
actor Capybara { func eat() {} }
155153

156154
Task(executorPreference: executor) {
157-
// starts on 'executor', however...
158-
try await capy.eat() // still executes actor isolated code on the actor's executor, as expected
155+
// starts on 'executor'
156+
try await capy.eat() // execution is isolated to the 'capy' actor, however execution happens on the 'executor' TaskExecutor
159157
}
160158
```
161159

160+
In a way, one should think of the `SerialExecutor` of the actor and `TaskExecutor` both being tracked and providing different semantics.
161+
The `SerialExecutor` guarntees mutual exclusion, and the `TaskExecutor` provides a source of threads.
162+
162163
## Detailed design
163164

164165
### Setting task executor preference

0 commit comments

Comments
 (0)