@@ -162,6 +162,39 @@ extension MainActor {
162162 try assumeIsolated ( operation, file: file, line: line)
163163 }
164164}
165+
166+ #if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) || os(visionOS)
167+ @_extern ( c, " pthread_main_np " )
168+ @usableFromInline
169+ internal func pthread_main_np( ) -> CInt
170+
171+ @available ( SwiftStdlib 5 . 1 , * )
172+ @_alwaysEmitIntoClient
173+ @_silgen_name ( " swift_task_deinitOnExecutorMainActorBackDeploy " )
174+ public func _deinitOnExecutorMainActorBackDeploy(
175+ _ object: __owned AnyObject,
176+ _ work: @convention ( thin) ( __owned AnyObject) -> Void ,
177+ _ executor: Builtin . Executor ,
178+ _ flags: Builtin . Word ) {
179+ if #available( macOS 15 . 4 , iOS 18 . 4 , watchOS 11 . 4 , tvOS 18 . 4 , visionOS 2 . 4 , * ) {
180+ // On new-enough platforms, use the runtime functionality, which allocates
181+ // the task more efficiently.
182+ _deinitOnExecutor ( object, work, executor, flags)
183+ } else if pthread_main_np ( ) == 1 {
184+ // Using "main thread" as a proxy for "main actor", immediately destroy
185+ // the object.
186+ work ( consume object)
187+ } else {
188+ // Steal the local object so that the reference count stays at 1 even when
189+ // the object is captured.
190+ var stolenObject : AnyObject ? = consume object
191+ Task . detached { @MainActor in
192+ work ( stolenObject. take ( ) !)
193+ }
194+ }
195+ }
196+ #endif
197+
165198#endif // !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
166199
167200#endif // !$Embedded
0 commit comments