fix(OnceFlag): add isSet and check before waiting (#6316)

This commit is contained in:
nerix
2025-07-03 23:22:15 +02:00
committed by GitHub
parent 2568d8a6ea
commit 70bdeb79c3
4 changed files with 39 additions and 1 deletions
+1 -1
View File
@@ -68,7 +68,7 @@
- Dev: Refactored `Button` and friends. (#6102, #6255, #6266, #6302, #6268) - Dev: Refactored `Button` and friends. (#6102, #6255, #6266, #6302, #6268)
- Dev: Made Settings & Account button on Linux/macOS SVGs. (#6267) - Dev: Made Settings & Account button on Linux/macOS SVGs. (#6267)
- Dev: Emoji style / set is now stored lowercase (and matched case-insensitively). Changing emoji style from this point on and then running an old version might mean you will use the Twitter emoji style by default. (#6300) - Dev: Emoji style / set is now stored lowercase (and matched case-insensitively). Changing emoji style from this point on and then running an old version might mean you will use the Twitter emoji style by default. (#6300)
- Dev: `OnceFlag`'s internal flag is now atomic. (#6237) - Dev: Refactored `OnceFlag`. (#6237, #6316)
- Dev: Bumped clang-format requirement to 19. (#6236) - Dev: Bumped clang-format requirement to 19. (#6236)
## 2.5.3 ## 2.5.3
+14
View File
@@ -16,6 +16,10 @@ void OnceFlag::set()
bool OnceFlag::waitFor(std::chrono::milliseconds ms) bool OnceFlag::waitFor(std::chrono::milliseconds ms)
{ {
std::unique_lock lock(this->mutex); std::unique_lock lock(this->mutex);
if (this->flag.load(std::memory_order::relaxed))
{
return true;
}
return this->condvar.wait_for(lock, ms, [this] { return this->condvar.wait_for(lock, ms, [this] {
return this->flag.load(std::memory_order::relaxed); return this->flag.load(std::memory_order::relaxed);
}); });
@@ -24,9 +28,19 @@ bool OnceFlag::waitFor(std::chrono::milliseconds ms)
void OnceFlag::wait() void OnceFlag::wait()
{ {
std::unique_lock lock(this->mutex); std::unique_lock lock(this->mutex);
if (this->flag.load(std::memory_order::relaxed))
{
return;
}
this->condvar.wait(lock, [this] { this->condvar.wait(lock, [this] {
return this->flag.load(std::memory_order::relaxed); return this->flag.load(std::memory_order::relaxed);
}); });
} }
bool OnceFlag::isSet()
{
std::unique_lock lock(this->mutex);
return this->flag.load(std::memory_order::relaxed);
}
} // namespace chatterino } // namespace chatterino
+3
View File
@@ -31,6 +31,9 @@ public:
/// The calling thread will be suspended during the wait. /// The calling thread will be suspended during the wait.
void wait(); void wait();
/// Is the flag currently set?
bool isSet();
private: private:
std::mutex mutex; std::mutex mutex;
std::condition_variable condvar; std::condition_variable condvar;
+21
View File
@@ -79,10 +79,31 @@ TEST(OnceFlag, waitForTimeout)
}); });
startedFlag.wait(); startedFlag.wait();
ASSERT_TRUE(startedFlag.isSet());
startedAckFlag.set(); startedAckFlag.set();
ASSERT_TRUE(startedAckFlag.isSet());
ASSERT_FALSE(stoppedFlag.waitFor(std::chrono::milliseconds{25})); ASSERT_FALSE(stoppedFlag.waitFor(std::chrono::milliseconds{25}));
stoppedFlag.wait(); stoppedFlag.wait();
ASSERT_TRUE(stoppedFlag.isSet());
t.join(); t.join();
} }
TEST(OnceFlag, alreadySet)
{
OnceFlag flag;
flag.set();
ASSERT_TRUE(flag.isSet());
auto start = std::chrono::system_clock::now();
flag.wait();
auto stop = std::chrono::system_clock::now();
ASSERT_LT(stop - start, std::chrono::milliseconds{10});
start = std::chrono::system_clock::now();
ASSERT_TRUE(flag.waitFor(std::chrono::milliseconds{0}));
stop = std::chrono::system_clock::now();
ASSERT_LT(stop - start, std::chrono::milliseconds{10});
}