Skip to content
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

Fix sleep_for for max duration #2601

Merged

Conversation

taminob
Copy link
Contributor

@taminob taminob commented Oct 22, 2023

As mentioned in the issue, the bug is caused by the standard library expecting for std::condition_variable::sleep_for a duration which does not cause an overflow when added to the current time.

This PR fixes the issue by using sleep_until to emulate sleep_for since sleep_for is defined as identical to adding the current time and then using sleep_until by the standard.

Additionally, this PR re-applies #2586 which was reverted in #2599 because of this bug.

I also tried to write a test to catch this kind of error for SleeperThread, but I wasn't able to check for this kind of failure.
The standard does not specify the behavior if a too big duration is passed.
I ended up writing a few basic other tests for the class and restructured the build system to allow for easier addition to the tests by providing all sources of waybar as a static library which is now simply linked against main.cpp for the executable.

Resolves #2598

@taminob taminob marked this pull request as draft October 22, 2023 23:25
@taminob taminob force-pushed the bugfix/2598/fix-max-duration-sleep-for-bug branch 2 times, most recently from 74b27fb to c5b1703 Compare October 23, 2023 13:05
@alebastr
Copy link
Contributor

alebastr commented Oct 23, 2023 via email

@taminob
Copy link
Contributor Author

taminob commented Oct 23, 2023

That is not entirely true. std::condition_variable::wait_for at least in GCC libstdc++ on GNU libc defaults to pthread_cond_clockwait with monotonic clock (std::chrono::clock_steady), protecting it from system clock adjustments. The code here passes std::chrono::system_clock to wait_until and thus the sleep duration will be affected by the system clock changes.

Good point, thanks for the correction.
You're completely right, it is actually equivalent to return wait_until(lock, chrono::steady_clock::now() + rel_time, std::move(pred));.

Tomorrow, I'll also split this PR up into the testing/build system changes (since it's not really related to the change anyway) and the fix + re-applied PR.

The standard library has the implicit requirement that for
std::condition_variable::sleep_for() the duration must not cause an
overflow if added to the current time.
This commit will reduce the duration accordingly to fit into the
duration type.
In the previous fix for a passed max duration, the assumption was made
that at maximum one second will pass between the duration assignment and
the std::condition_variable::sleep_for() call.
This implementation makes the behavior more predictable by using
sleep_until() instead to emulate the sleep_for() behavior.
This reverts commit 2d33c20 and
reapplies various patches for memory leaks.
The reason for the revert was a bug for a maximum duration interval
which caused sleep_for() to cause unpredictable behavior.
Using pascal case for the class name keeps it more consistent with the
majority of the other class names.
@taminob taminob force-pushed the bugfix/2598/fix-max-duration-sleep-for-bug branch from c5b1703 to 68dfd6a Compare October 24, 2023 15:53
@taminob taminob marked this pull request as ready for review October 24, 2023 16:47
@Alexays Alexays merged commit 1618ee7 into Alexays:master Oct 26, 2023
7 of 8 checks passed
@Alexays
Copy link
Owner

Alexays commented Oct 26, 2023

Thanks :)

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.

Waybar doesn't start and can't quit it, need to force kill
3 participants