Skip to content

Commit 841fda5

Browse files
committed
Add asyncMainDrainQueue hook
The swift_task_asyncMainDrainQueue function acts as the entrypoint into driving the main queues, ultimately running the whole program and acting as the backing driver of the main actor. Making the function hookable means that custom concurrency runtimes can implement their own async entrypoints, allowing async top-level code and async-main to "just work".
1 parent ec7a926 commit 841fda5

File tree

3 files changed

+44
-15
lines changed

3 files changed

+44
-15
lines changed

include/swift/Runtime/Concurrency.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,19 @@ SWIFT_EXPORT_FROM(swift_Concurrency)
770770
SWIFT_CC(swift) void (*swift_task_enqueueMainExecutor_hook)(
771771
Job *job, swift_task_enqueueMainExecutor_original original);
772772

773+
/// A hook to override the entrypoint to the main runloop used to drive the
774+
/// concurrency runtime and drain the main queue. This function must not return.
775+
/// Note: If the hook is wrapping the original function and the `compatOverride`
776+
/// is passed in, the `original` function pointer must be passed into the
777+
/// compatibility override function as the original function.
778+
typedef SWIFT_CC(swift) void (*swift_task_asyncMainDrainQueue_original)();
779+
typedef SWIFT_CC(swift) void (*swift_task_asyncMainDrainQueue_override)(
780+
swift_task_asyncMainDrainQueue_original original);
781+
SWIFT_EXPORT_FROM(swift_Concurrency)
782+
SWIFT_CC(swift) void (*swift_task_asyncMainDrainQueue_hook)(
783+
swift_task_asyncMainDrainQueue_original original,
784+
swift_task_asyncMainDrainQueue_override compatOverride);
785+
773786
/// Initialize the runtime storage for a default actor.
774787
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
775788
void swift_defaultActor_initialize(DefaultActor *actor);

stdlib/public/CompatibilityOverride/CompatibilityOverrideConcurrency.def

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,9 @@
7777
# define OVERRIDE_TASK_GROUP OVERRIDE
7878
# define OVERRIDE_TASK_LOCAL OVERRIDE
7979
# define OVERRIDE_TASK_STATUS OVERRIDE
80-
#ifndef OVERRIDE_TASK_NORETURN
81-
# define OVERRIDE_TASK_NORETURN(name, attrs, ccAttrs, namespace, typedArgs, \
82-
namedArgs) \
80+
#ifndef HOOKED_OVERRIDE_TASK_NORETURN
81+
# define HOOKED_OVERRIDE_TASK_NORETURN(name, attrs, ccAttrs, namespace, \
82+
typedArgs, namedArgs) \
8383
OVERRIDE(name, void, attrs, ccAttrs, namespace, typedArgs, namedArgs)
8484
#endif
8585
#else
@@ -101,8 +101,8 @@
101101
# ifndef OVERRIDE_TASK_STATUS
102102
# define OVERRIDE_TASK_STATUS(...)
103103
# endif
104-
# ifndef OVERRIDE_TASK_NORETURN
105-
# define OVERRIDE_TASK_NORETURN(...)
104+
# ifndef HOOKED_OVERRIDE_TASK_NORETURN
105+
# define HOOKED_OVERRIDE_TASK_NORETURN(...)
106106
# endif
107107
#endif
108108

@@ -189,9 +189,10 @@ OVERRIDE_TASK(task_createNullaryContinuationJob, NullaryContinuationJob *,
189189
(size_t priority,
190190
AsyncTask *continuation), (priority, continuation))
191191

192-
OVERRIDE_TASK_NORETURN(task_asyncMainDrainQueue,
193-
SWIFT_EXPORT_FROM(swift_Concurrency), SWIFT_CC(swift), swift::,
194-
, )
192+
HOOKED_OVERRIDE_TASK_NORETURN(task_asyncMainDrainQueue,
193+
SWIFT_EXPORT_FROM(swift_Concurrency), SWIFT_CC(swift),
194+
swift::, ,)
195+
195196

196197
OVERRIDE_TASK(task_suspend, AsyncTask *,
197198
SWIFT_EXPORT_FROM(swift_Concurrency), SWIFT_CC(swift),
@@ -388,4 +389,4 @@ OVERRIDE_TASK_STATUS(task_escalate, JobPriority,
388389
#undef OVERRIDE_TASK_GROUP
389390
#undef OVERRIDE_TASK_LOCAL
390391
#undef OVERRIDE_TASK_STATUS
391-
#undef OVERRIDE_TASK_NORETURN
392+
#undef HOOKED_OVERRIDE_TASK_NORETURN

stdlib/public/Concurrency/Task.cpp

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1589,20 +1589,31 @@ static void swift_task_asyncMainDrainQueueImpl() {
15891589
#endif
15901590
}
15911591

1592+
SWIFT_CC(swift)
1593+
void (*swift::swift_task_asyncMainDrainQueue_hook)(
1594+
swift_task_asyncMainDrainQueue_original original,
1595+
swift_task_asyncMainDrainQueue_override compatOverride) = nullptr;
1596+
15921597
#define OVERRIDE_TASK COMPATIBILITY_OVERRIDE
15931598

15941599
#ifdef SWIFT_STDLIB_SUPPORT_BACK_DEPLOYMENT
15951600
/// The original COMPATIBILITY_OVERRIDE defined in CompatibilityOverride.h
15961601
/// returns the result of the impl function and override function. This results
15971602
/// in a warning emitted for noreturn functions. Overriding the override macro
15981603
/// to not return.
1599-
#define OVERRIDE_TASK_NORETURN(name, attrs, ccAttrs, namespace, typedArgs, \
1600-
namedArgs) \
1604+
#define HOOKED_OVERRIDE_TASK_NORETURN(name, attrs, ccAttrs, namespace, \
1605+
typedArgs, namedArgs) \
16011606
attrs ccAttrs void namespace swift_##name COMPATIBILITY_PAREN(typedArgs) { \
16021607
static Override_##name Override; \
16031608
static swift_once_t Predicate; \
16041609
swift_once( \
16051610
&Predicate, [](void *) { Override = getOverride_##name(); }, nullptr); \
1611+
if (swift_##name##_hook) { \
1612+
swift_##name##_hook(COMPATIBILITY_UNPAREN_WITH_COMMA(namedArgs) \
1613+
swift_##name##Impl, \
1614+
Override); \
1615+
abort(); \
1616+
} \
16061617
if (Override != nullptr) \
16071618
Override(COMPATIBILITY_UNPAREN_WITH_COMMA(namedArgs) \
16081619
swift_##name##Impl); \
@@ -1612,11 +1623,15 @@ static void swift_task_asyncMainDrainQueueImpl() {
16121623
#else // ifndef SWIFT_STDLIB_SUPPORT_BACK_DEPLOYMENT
16131624
// Call directly through to the original implementation when we don't support
16141625
// overrides.
1615-
#define OVERRIDE_TASK_NORETURN(name, attrs, ccAttrs, namespace, typedArgs, \
1616-
namedArgs) \
1626+
#define HOOKED_OVERRIDE_TASK_NORETURN(name, attrs, ccAttrs, namespace, \
1627+
typedArgs, namedArgs) \
16171628
attrs ccAttrs void namespace swift_##name COMPATIBILITY_PAREN(typedArgs) { \
1618-
swift_##name##Impl COMPATIBILITY_PAREN(namedArgs); \
1619-
}
1629+
if (swift_##name##_hook) { \
1630+
swift_##name##_hook(swift_##name##Impl, nullptr); \
1631+
abort(); \
1632+
} \
1633+
swift_##name##Impl COMPATIBILITY_PAREN(namedArgs); \
1634+
}
16201635
#endif // #else SWIFT_STDLIB_SUPPORT_BACK_DEPLOYMENT
16211636

16221637
#include COMPATIBILITY_OVERRIDE_INCLUDE_PATH

0 commit comments

Comments
 (0)