-
Notifications
You must be signed in to change notification settings - Fork 236
Force stopping all threads and libevent timers when test completes or Ctrl+C is pressed #335
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
base: master
Are you sure you want to change the base?
Conversation
… Ctrl+C is pressed
| } | ||
|
|
||
| // Break the event loop to stop processing | ||
| event_base_loopbreak(m_base); |
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.
Race condition between force_stop and event loop callbacks
High Severity
client_group::force_stop() frees resources (via shard_connection::force_stop()) while the worker thread's event loop may still be executing callbacks that use those resources. The event_base_loopbreak() is called AFTER resources are freed at lines 752-755, but the worker thread could be inside a callback like handle_timer_event() accessing m_event_timer, m_bev, etc. that are being freed. Since libevent thread-safety isn't enabled (no evthread_use_pthreads() call), this creates a use-after-free race condition.
Additional Locations (1)
| } | ||
| if (active_threads > 0) { | ||
| fprintf(stderr, "[RUN #%u] Waiting for %u threads to finish...\n", run_id, active_threads); | ||
| } |
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.
Duplicated thread waiting loop code
Low Severity
The waiting loop that polls active_threads and prints status messages is duplicated identically in two places: once for Ctrl+C handling and once for test-time completion. This creates maintenance burden since any future bug fix or enhancement would need to be applied to both locations, risking inconsistent behavior if one is missed.
Additional Locations (1)
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.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
| // This is more aggressive than interrupt() - it forcefully cleans up all events | ||
|
|
||
| // Set the stop flag first - this will cause the run() loop to exit | ||
| m_stop_requested.store(true, std::memory_order_relaxed); |
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.
Unused variable m_stop_requested is set but never read
Low Severity
The m_stop_requested atomic variable is declared in client.h, initialized in the constructor, and set to true in force_stop(), but it's never read anywhere. The comment states "this will cause the run() loop to exit" but run() simply calls event_base_dispatch(m_base) without checking this flag. The actual mechanism that stops the loop is event_base_loopbreak() called later. This is dead code that should be removed.


Note
Medium Risk
Touches shutdown/cleanup and libevent timer/bufferevent lifecycle across threads; incorrect teardown ordering could cause leaks, hangs, or use-after-free during stop conditions.
Overview
Ensures benchmarks shut down promptly by adding a new forceful stop path that tears down all libevent resources and pending work instead of waiting for normal completion.
This introduces
force_stop()onclient,client_group, andshard_connectionto delete timers, disable/free bufferevents, and drain pending requests;m_pending_respis made atomic to avoid benign races when polled from the main thread. The main runner now usesforce_stop()on Ctrl+C and when--test-timeelapses, printing how many threads are being stopped and waiting until they report finished; the interrupt message assertion intests_oss_simple_flow.pyis updated accordingly.Written by Cursor Bugbot for commit 871b6bc. This will update automatically on new commits. Configure here.