-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Fix destruction of suspended generators in suspended fibers during shutdown #15158
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
2119053
to
c4fd31a
Compare
Zend/zend_generators.c
Outdated
@@ -722,6 +774,13 @@ ZEND_API void zend_generator_resume(zend_generator *orig_generator) /* {{{ */ | |||
return; | |||
} | |||
|
|||
if (EG(active_fiber)) { | |||
orig_generator->flags |= ZEND_GENERATOR_IN_FIBER; | |||
if (generator != orig_generator) { |
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.
Redundant condition (a few lines deeper as well).
…utdown The generator destructor is a no-op when the generator is running in a fiber, because unwinding the fiber will resume the generator. Normally the destructor is never called in this case, but this can happen during shutdown. We detect that a generator is running in a fiber with the ZEND_GENERATOR_IN_FIBER flag. This change fixes two cases in which this mechanism was broken: - The flag was not added when resuming a 'yield from $nonGenerator', as this is handled in a separate code path - When a generator that is running in a fiber has multiple children (aka multiple generators yielding from it), all of them could be considered to also run in a fiber (only one actually is), and could leak if not destroyed before shutdown.
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.
It looks right to me, visiting all generators only once sounds good to me.
Maybe call ZEND_GENERATOR_VISITED ZEND_GENERATOR_DTOR_VISITED
instead.
* PHP-8.2: [ci skip] NEWS Fix destruction of generator running in fibers during shutdown (#15158)
* PHP-8.3: [ci skip] NEWS [ci skip] NEWS Fix destruction of generator running in fibers during shutdown (#15158)
Fixes #15108.
In #10462 we ensured that generators running in a fiber are not destroyed before the fiber:
This was extended to support
yield from
in 00be6e1 and b9bca2d (I can not find the related PR anymore).Here I fix two additional cases not handled by #10462:
The
ZEND_GENERATOR_IN_FIBER
flag was not added when resuming ayield from $nonGenerator
. I fix that by adding the flag earlier.When a generator that is running in a fiber has multiple children (aka multiple generators yielding from it), all of them could be considered to also run in a fiber (only one actually is), and could leak if not destroyed before shutdown.
Unfortunately the second one requires traversing the child tree (at most once) during dtor if the root is marked
ZEND_GENERATOR_IN_FIBER
.