diff --git a/stdlib/public/Concurrency/Executor.swift b/stdlib/public/Concurrency/Executor.swift index 0b1dbc3644cd2..ff642319e29a6 100644 --- a/stdlib/public/Concurrency/Executor.swift +++ b/stdlib/public/Concurrency/Executor.swift @@ -382,11 +382,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 f4b8f6da3cde6..9838ad068b749 100644 --- a/stdlib/public/Concurrency/ExecutorBridge.cpp +++ b/stdlib/public/Concurrency/ExecutorBridge.cpp @@ -18,6 +18,7 @@ #include "Error.h" #include "ExecutorBridge.h" +#include "TaskPrivate.h" using namespace swift; @@ -73,6 +74,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 d160d424acc44..7eb570c73ef74 100644 --- a/stdlib/public/Concurrency/ExecutorBridge.swift +++ b/stdlib/public/Concurrency/ExecutorBridge.swift @@ -130,3 +130,8 @@ internal func _dispatchAssertMainQueue() @_silgen_name("swift_createDefaultExecutorsOnce") func _createDefaultExecutorsOnce() + +@_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 8fcf079de8c89..46a16bcb6cb5f 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 }