-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Fix asyncMainDrainQueue noreturn warning #61692
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@swift-ci please test |
macOS:
Linux:
Windows:
|
b931348
to
d635a2d
Compare
@swift-ci please test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, thanks!
Linux:
Windows:
|
The async main drain queue function is noreturn, but was emitting a warning due to the override compatibility returning the result of the overridden function in the wrapper override function. To work around this, I've added the `OVERRIDE_TASK_NORETURN` macro, which provides an override point for noreturn functions in the concurrency library that doesn't return the result from the wrapped function, avoiding the warning. In the event that the function is not set, the macro is set to the normal `OVERRIDE` with the return type set to `void`.
d635a2d
to
ec7a926
Compare
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".
This patch tests that the hook actually works. Not going to lie, the test is pretty disgusting. The function we're testing is a noreturn function, which introduces some interesting challenges when we need to return to finish the test. I need to somehow exit the function without killing the process, but also without returning. If I just use a loop properly, the test will hang for the age of the universe. If I don't and return from the hook, the test will abort or crash. I tried removing the abort after the hook in the hook override macro to see if we could sneak past the compiler, and no, that explodes on the return pointer. So, here's the workaround. C++11 threads don't seem to have a way to kill themselves, but you can use `pthread_exit` or `pthread_kill` to either kill yourself or kill another thread. So the override function sets the `Ran` to true, and then exits (which is noreturn, so we haven't broken that contract), killing itself and allowing us to join without returning from the inferior. The main thread immediately waits for the original thread to die. Since it blocks, we avoid the possible race on setting the state of `Ran` in the override hook and where it gets checked in the test. If that becomes an issue, we could probably just wrap the `Ran` bool in an atomic and call it a day. Anyway, it's well past my bedtime and I'm playing with threads. This can only end in a creative disaster. :D
@swift-ci please test |
@mikeash I had some fun writing that test. Turns out it's pretty tricky testing a |
I don't think I have any better ideas. You could get out of it by throwing an exception, but I don't think that qualifies as "better." |
macOS failure: Not my fault this time. |
@swift-ci please test macOS |
macOS failure should be fixed by: #64029 |
@swift-ci please test macOS |
The async main drain queue function is noreturn, but was emitting a warning due to the override compatibility returning the result of the overridden function in the wrapper override function. To work around this, I've added the
OVERRIDE_TASK_NORETURN
macro, which provides an override point for noreturn functions in the concurrency library that doesn't return the result from the wrapped function, avoiding the warning. In the event that the function is not set, the macro is set to the normalOVERRIDE
with the return type set tovoid
.rdar://85521851