Skip to content

Commit fb4ffb4

Browse files
authored
[Concurrency] Add missing runSynchronously to ExecutorJob (#72899)
1 parent 8981f2d commit fb4ffb4

File tree

2 files changed

+93
-0
lines changed

2 files changed

+93
-0
lines changed

stdlib/public/Concurrency/PartialAsyncTask.swift

+87
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,23 @@ public struct UnownedJob: Sendable {
109109
_swiftJobRun(self, executor)
110110
}
111111

112+
/// Run this job isolated to the passed task executor.
113+
///
114+
/// This operation runs the job on the calling thread and *blocks* until the job completes.
115+
/// The intended use of this method is for an executor to determine when and where it
116+
/// wants to run the job and then call this method on it.
117+
///
118+
/// The passed in executor reference is used to establish the executor context for the job,
119+
/// and should be the same executor as the one semantically calling the `runSynchronously` method.
120+
///
121+
/// This operation consumes the job, preventing it accidental use after it has been run.
122+
///
123+
/// Converting a `ExecutorJob` to an ``UnownedJob`` and invoking ``UnownedJob/runSynchronously(_:)` on it multiple times is undefined behavior,
124+
/// as a job can only ever be run once, and must not be accessed after it has been run.
125+
///
126+
/// - Parameter executor: the task executor this job will be run on.
127+
///
128+
/// - SeeAlso: ``runSynchronously(isolatedTo:taskExecutor:)``
112129
@_unavailableInEmbedded
113130
@available(SwiftStdlib 6.0, *)
114131
@_alwaysEmitIntoClient
@@ -117,6 +134,24 @@ public struct UnownedJob: Sendable {
117134
_swiftJobRunOnTaskExecutor(self, executor)
118135
}
119136

137+
/// Run this job isolated to the passed in serial executor, while executing it on the specified task executor.
138+
///
139+
/// This operation runs the job on the calling thread and *blocks* until the job completes.
140+
/// The intended use of this method is for an executor to determine when and where it
141+
/// wants to run the job and then call this method on it.
142+
///
143+
/// The passed in executor reference is used to establish the executor context for the job,
144+
/// and should be the same executor as the one semantically calling the `runSynchronously` method.
145+
///
146+
/// This operation consumes the job, preventing it accidental use after it has been run.
147+
///
148+
/// Converting a `ExecutorJob` to an ``UnownedJob`` and invoking ``UnownedJob/runSynchronously(_:)` on it multiple times is undefined behavior,
149+
/// as a job can only ever be run once, and must not be accessed after it has been run.
150+
///
151+
/// - Parameter serialExecutor: the executor this job will be semantically running on.
152+
/// - Parameter taskExecutor: the task executor this job will be run on.
153+
///
154+
/// - SeeAlso: ``runSynchronously(on:)``
120155
@_unavailableInEmbedded
121156
@available(SwiftStdlib 6.0, *)
122157
@_alwaysEmitIntoClient
@@ -286,6 +321,58 @@ extension ExecutorJob {
286321
__consuming public func runSynchronously(on executor: UnownedSerialExecutor) {
287322
_swiftJobRun(UnownedJob(self), executor)
288323
}
324+
325+
/// Run this job on the passed in task executor.
326+
///
327+
/// This operation runs the job on the calling thread and *blocks* until the job completes.
328+
/// The intended use of this method is for an executor to determine when and where it
329+
/// wants to run the job and then call this method on it.
330+
///
331+
/// The passed in executor reference is used to establish the executor context for the job,
332+
/// and should be the same executor as the one semantically calling the `runSynchronously` method.
333+
///
334+
/// This operation consumes the job, preventing it accidental use after it has been run.
335+
///
336+
/// Converting a `ExecutorJob` to an ``UnownedJob`` and invoking ``UnownedJob/runSynchronously(_:)` on it multiple times is undefined behavior,
337+
/// as a job can only ever be run once, and must not be accessed after it has been run.
338+
///
339+
/// - Parameter executor: the executor this job will be run on.
340+
///
341+
/// - SeeAlso: ``runSynchronously(isolatedTo:taskExecutor:)``
342+
@_unavailableInEmbedded
343+
@available(SwiftStdlib 6.0, *)
344+
@_alwaysEmitIntoClient
345+
@inlinable
346+
__consuming public func runSynchronously(on executor: UnownedTaskExecutor) {
347+
_swiftJobRunOnTaskExecutor(UnownedJob(self), executor)
348+
}
349+
350+
/// Run this job isolated to the passed in serial executor, while executing it on the specified task executor.
351+
///
352+
/// This operation runs the job on the calling thread and *blocks* until the job completes.
353+
/// The intended use of this method is for an executor to determine when and where it
354+
/// wants to run the job and then call this method on it.
355+
///
356+
/// The passed in executor reference is used to establish the executor context for the job,
357+
/// and should be the same executor as the one semantically calling the `runSynchronously` method.
358+
///
359+
/// This operation consumes the job, preventing it accidental use after it has been run.
360+
///
361+
/// Converting a `ExecutorJob` to an ``UnownedJob`` and invoking ``UnownedJob/runSynchronously(_:)` on it multiple times is undefined behavior,
362+
/// as a job can only ever be run once, and must not be accessed after it has been run.
363+
///
364+
/// - Parameter serialExecutor: the executor this job will be semantically running on.
365+
/// - Parameter taskExecutor: the task executor this job will be run on.
366+
///
367+
/// - SeeAlso: ``runSynchronously(on:)``
368+
@_unavailableInEmbedded
369+
@available(SwiftStdlib 6.0, *)
370+
@_alwaysEmitIntoClient
371+
@inlinable
372+
__consuming public func runSynchronously(isolatedTo serialExecutor: UnownedSerialExecutor,
373+
taskExecutor: UnownedTaskExecutor) {
374+
_swiftJobRunOnTaskExecutor(UnownedJob(self), serialExecutor, taskExecutor)
375+
}
289376
}
290377
#endif // !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
291378

test/Concurrency/Runtime/async_task_executor_default_actor_funcs.swift

+6
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ final class NaiveQueueExecutor: TaskExecutor {
2525
}
2626
}
2727

28+
public func apiTest(serialExecutor: any SerialExecutor, _ job: consuming ExecutorJob) {
29+
job.runSynchronously(
30+
isolatedTo: serialExecutor.asUnownedSerialExecutor(),
31+
taskExecutor: self.asUnownedTaskExecutor())
32+
}
33+
2834
}
2935

3036
actor ThreaddyTheDefaultActor {

0 commit comments

Comments
 (0)