Skip to content

libpcp_web: fix libuv teardown; pmfind: defer context release and shutdown order#2557

Open
kurik wants to merge 2 commits intoperformancecopilot:mainfrom
kurik:pmfind
Open

libpcp_web: fix libuv teardown; pmfind: defer context release and shutdown order#2557
kurik wants to merge 2 commits intoperformancecopilot:mainfrom
kurik:pmfind

Conversation

@kurik
Copy link
Copy Markdown
Contributor

@kurik kurik commented Apr 8, 2026

Add pmWebTimerLoopFinalize() to uv_close the global instrumentation timer after pmWebTimerClose and export it in PCP_WEB_1.24. Order pmWebGroupClose so struct webgroups is freed only from uv_close callbacks (timer then async) and clear module->privdata early to avoid double teardown.

In pmfind, defer source_release to the next tick to avoid use-after-free when pmWebGroupDestroy runs from on_done; delete from contexts dict before destroy; track defer_pending and use extra uv_run/uv_stop as needed. Call pmWebGroupClose and pmWebTimerLoopFinalize before uv_loop_close with draining uv_run passes.

This is a followup of the #2555 which fixes unsafe multi-threaded use of timers during request handling.
Later changes fix libuv shutdown rules (do not free memory that still holds closing handles) and pmfind-specific ordering (destroy vs. deref vs. dict, and draining the loop before uv_loop_close). Those are separate failure modes; fixing one does not imply the other is fixed.

…tdown order

Add pmWebTimerLoopFinalize() to uv_close the global instrumentation timer
after pmWebTimerClose and export it in PCP_WEB_1.24. Order pmWebGroupClose so
struct webgroups is freed only from uv_close callbacks (timer then async) and
clear module->privdata early to avoid double teardown.

In pmfind, defer source_release to the next tick to avoid use-after-free when
pmWebGroupDestroy runs from on_done; delete from contexts dict before destroy;
track defer_pending and use extra uv_run/uv_stop as needed. Call pmWebGroupClose
and pmWebTimerLoopFinalize before uv_loop_close with draining uv_run passes.
@kurik
Copy link
Copy Markdown
Contributor Author

kurik commented Apr 8, 2026

Hmmm... Ubuntu 18.04 is using old libuv which does not support uv_handle_get_loop() yet :-(
Will need to find a way around it....

Use handle->loop via pmfind_handle_loop() so pmfind links on distros
whose libuv lacks uv_handle_get_loop (e.g. Ubuntu 18.04).
* Call before uv_loop_close(); run the loop once to process the close cb.
*/
void
pmWebTimerLoopFinalize(void)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just in terms of naming, "pmWebTimerDestroy" might be more consistent with other parts of libpcp_web?

uv_run(loop, UV_RUN_DEFAULT);

uv_close((uv_handle_t *)&timing, NULL);
uv_run(loop, UV_RUN_DEFAULT);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh wow, so many explicit calls to uv_run ... are they all really necessary?

@kurik
Copy link
Copy Markdown
Contributor Author

kurik commented Apr 9, 2026

Thanks @natoscott for the review.
I agree that this patch still needs some work. For some reason, which I still need to investigate, it does not work on older Debian and Ubuntu releases as expected. Unfortunately, I do not have those older distros readily available for testing, so this might take some time.

The issue itself seems to be orthogonal to the fix delivered in #2555; this patch just revealed it.

I will keep working on this and ping you for another review once it is ready.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants