diff --git a/stdlib/public/Concurrency/Executor.swift b/stdlib/public/Concurrency/Executor.swift index af6991eda55e4..f2f405e15f9e5 100644 --- a/stdlib/public/Concurrency/Executor.swift +++ b/stdlib/public/Concurrency/Executor.swift @@ -340,11 +340,26 @@ extension SerialExecutor { #endif } + #if SWIFT_CONCURRENCY_USES_DISPATCH + @available(SwiftStdlib 6.2, *) + private var _dispatchQueue: OpaquePointer? { + return _getDispatchQueueForExecutor(self.asUnownedSerialExecutor()) + } + #endif + @available(SwiftStdlib 6.2, *) internal func _isSameExecutor(_ rhs: some SerialExecutor) -> Bool { if rhs === self { return true } + #if SWIFT_CONCURRENCY_USES_DISPATCH + if let rhsQueue = rhs._dispatchQueue { + if let ourQueue = _dispatchQueue, ourQueue == rhsQueue { + return true + } + return false + } + #endif if let rhs = rhs as? Self { return isSameExclusiveExecutionContext(other: rhs) } diff --git a/stdlib/public/Concurrency/ExecutorBridge.cpp b/stdlib/public/Concurrency/ExecutorBridge.cpp index 6debd5659beb8..195698c4dd23a 100644 --- a/stdlib/public/Concurrency/ExecutorBridge.cpp +++ b/stdlib/public/Concurrency/ExecutorBridge.cpp @@ -16,6 +16,7 @@ #include "Error.h" #include "ExecutorBridge.h" +#include "TaskPrivate.h" using namespace swift; @@ -136,6 +137,15 @@ extern "C" SWIFT_CC(swift) void swift_dispatchAssertMainQueue() { dispatch_assert_queue(dispatch_get_main_queue()); } -#endif // SWIFT_CONCURRENCY_ENABLE_DISPATCH + +extern "C" SWIFT_CC(swift) +void *swift_getDispatchQueueForExecutor(SerialExecutorRef executor) { + if (executor.getRawImplementation() == (uintptr_t)_swift_task_getDispatchQueueSerialExecutorWitnessTable()) { + return executor.getIdentity(); + } + return nullptr; +} + +#endif // SWIFT_CONCURRENCY_USES_DISPATCH #pragma clang diagnostic pop diff --git a/stdlib/public/Concurrency/ExecutorBridge.swift b/stdlib/public/Concurrency/ExecutorBridge.swift index 9301de71d43e3..e9f8e4caeac0a 100644 --- a/stdlib/public/Concurrency/ExecutorBridge.swift +++ b/stdlib/public/Concurrency/ExecutorBridge.swift @@ -119,3 +119,8 @@ internal func _dispatchEnqueueWithDeadline(_ global: CBool, @available(SwiftStdlib 6.2, *) @_silgen_name("swift_dispatchAssertMainQueue") internal func _dispatchAssertMainQueue() + +@_silgen_name("swift_getDispatchQueueForExecutor") +internal func _getDispatchQueueForExecutor( + _ executor: UnownedSerialExecutor +) -> OpaquePointer? diff --git a/stdlib/public/Concurrency/Task.cpp b/stdlib/public/Concurrency/Task.cpp index 62e679d5e1eb9..262d02092a640 100644 --- a/stdlib/public/Concurrency/Task.cpp +++ b/stdlib/public/Concurrency/Task.cpp @@ -382,6 +382,11 @@ static SerialExecutorRef executorForEnqueuedJob(Job *job) { return swift_task_getMainExecutor(); } + if (auto identity = reinterpret_cast(jobQueue)) { + return SerialExecutorRef::forOrdinary( + identity, _swift_task_getDispatchQueueSerialExecutorWitnessTable()); + } + return SerialExecutorRef::generic(); #endif }