-
Notifications
You must be signed in to change notification settings - Fork 29.8k
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
[async_wrap] call destroy hooks on uv_timer_t #13369
Conversation
93436c1
to
87ae33b
Compare
}); | ||
}); | ||
|
||
process.on('exit', () => assert.strictEqual(destroyTcpWrapCallCount, 2)); |
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.
Just fyi, the test from #13353 might be better because it uses AsyncResource
to trigger the destroy call, so it doesn’t rely on .close()
specifics.
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.
Ah thanks. And I can remove the setTimeout()
at the bottom of the test.
if (ret.IsEmpty()) { | ||
ClearFatalExceptionHandlers(env); | ||
FatalException(env->isolate(), try_catch); | ||
do { |
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.
will this not call the destroy
hook synchronously if emitDestroy
was called from within the destroy
hook? We don't want that because destroy
hooks should never be called synchronously.
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.
@AndreasMadsen It would act like a nextTick()
. The current execution scope would complete before the destroy hook was called.
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.
Yeah, that came to me a few hours after I wrote that. Thanks!
87ae33b
to
fe1e23e
Compare
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.
Great, thank you a lot!
@addaleax Thanks for pointing to the other test. Also forgot to include your test for |
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.
LGTM, thanks for taking care of this.
fe1e23e
to
a127045
Compare
a127045
to
5e4aaee
Compare
Calling the destroy callbacks in a uv_idle_t causes a timing issue where if a handle or request is closed then the class isn't deleted until uv_close() callbacks are called (which happens after the poll phase). This results in some destroy callbacks not being called just before the application exits. So instead switch the destroy callbacks to be called in a uv_timer_t with the timeout set to zero. When uv_run() is called with UV_RUN_ONCE the final operation of the event loop is to process all remaining timers. By setting the timeout to zero it results in the destroy callbacks being processed after uv_close() but before uv_run() returned. Processing the destroyed ids that were previously missed. Also, process the destroy_ids_list() in a do {} while() loop that makes sure the vector is empty before returning. Which also makes running clear() unnecessary. Fixes: nodejs#13262 PR-URL: nodejs#13369 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Andreas Madsen <amwebdk@gmail.com>
Verify that the destroy callback for a TCP server is called before exit if it is closed in another destroy callback. Fixes: nodejs#13262 PR-URL: nodejs#13369 Reviewed-By: Trevor Norris <trev.norris@gmail.com> Reviewed-By: Andreas Madsen <amwebdk@gmail.com>
5e4aaee
to
78b1358
Compare
Calling the destroy callbacks in a uv_idle_t causes a timing issue where if a handle or request is closed then the class isn't deleted until uv_close() callbacks are called (which happens after the poll phase). This results in some destroy callbacks not being called just before the application exits. So instead switch the destroy callbacks to be called in a uv_timer_t with the timeout set to zero. When uv_run() is called with UV_RUN_ONCE the final operation of the event loop is to process all remaining timers. By setting the timeout to zero it results in the destroy callbacks being processed after uv_close() but before uv_run() returned. Processing the destroyed ids that were previously missed. Also, process the destroy_ids_list() in a do {} while() loop that makes sure the vector is empty before returning. Which also makes running clear() unnecessary. Fixes: #13262 PR-URL: #13369 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Andreas Madsen <amwebdk@gmail.com>
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
async_wrap
Summary
Calling the destroy callbacks in a
uv_idle_t
causes a timing issue whereif a handle or request is closed then the class isn't deleted until
uv_close()
callbacks are called (which happens after the poll phase).This results in some destroy callbacks not being called just before the
application exits. So instead switch the destroy callbacks to be called
in a
uv_timer_t
with the timeout set to zero.When
uv_run()
is called withUV_RUN_ONCE
the final operation of theevent loop is to process all remaining timers. By setting the timeout to
zero it results in the destroy callbacks being processed after
uv_close()
but beforeuv_run()
returned. Processing the destroyed idsthat were previously missed.
Also, process the
destroy_ids_list()
in ado {} while()
loop that makessure the vector is empty before returning. Which also makes running
clear()
unnecessary.Fixes: #13262
@addaleax Hope you don't mind that I added the relevant test you included in #13286 (left you as the committer, but altered the commit message)
CI: https://ci.nodejs.org/job/node-test-commit/10272/