Skip to content

Fix race condition in Python viewers set_X methods #2613

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

Closed

Conversation

aftersomemath
Copy link
Contributor

The set_figures, set_texts, and set_images methods introduced by 37d7591 and #2503 have a race condition as was discussed in the review of #2503.

This PR fixes that race condition. It was particularly easy to trigger when setting/clearing images, since those take more time than figures and text.

The fix uses atomics to synchronize the staging of overlay data in an almost non-blocking way. The set_images method also now uses smart pointers to manage the image buffers.

@yuvaltassa yuvaltassa requested a review from nimrod-gileadi May 9, 2025 11:16
@yuvaltassa
Copy link
Collaborator

I think if you rebase the CI failures will disappear since ubuntu 20.04 has since been removed

@aftersomemath
Copy link
Contributor Author

Done, let's see what happens.

@@ -2632,18 +2632,42 @@ void Simulate::Render() {
}

// user figures
if (this->newfigurerequest.load() == 1) {
this->user_figures_.clear();
for (const auto& [viewport, figure] : this->user_figures_new_) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can this loop be replaced with user_figures_ = user_figures_new_?

Or better:

user_figures_.clear();
std::swap(user_figures_, user_figures_new_);

Which performs no copies (just swaps the underlying pointers).

Same for the other loops.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

for (auto& [font, gridpos, text1, text2] : this->user_texts_) {
ShowOverlayText(this, rect, font, gridpos, text1, text2);
}

// user images
if (this->newimagerequest.load() == 1) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Make sure that if you use shared_ptr, user_images_new_ gets cleared so that the images aren't held in memory unnecessarily. I think if you use std::swap you could switch to unique_ptr.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It was cleared on the python bindings side, but using std::swap means user_images_new_ does not need to be cleared anymore.

@yuvaltassa
Copy link
Collaborator

@aftersomemath, can you remove trailing whitespaces in simulate.cc ?

@aftersomemath
Copy link
Contributor Author

Done, sorry about that.

copybara-service bot pushed a commit that referenced this pull request Jun 3, 2025
--
c9acc0a by Levi Burner <[email protected]>:

Fix race condition in Python viewers set_X methods

--
b89ab8f by Levi Burner <[email protected]>:

use std::swap to replace some copying

--
02625be by Levi Burner <[email protected]>:

fix whitespace

COPYBARA_INTEGRATE_REVIEW=#2613 from aftersomemath:simulate-set-race 02625be
PiperOrigin-RevId: 766646168
Change-Id: I1e1dc16afbfb1e69fb958d54bd1075cc9aed3569
@yuvaltassa
Copy link
Collaborator

Merged in 3eb31f5

@yuvaltassa yuvaltassa closed this Jun 12, 2025
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.

3 participants