Skip to content

Use condition_variable for interruptible thread sleep in updateLoop#147

Open
jslauthor wants to merge 1 commit intoCountly:masterfrom
hypernuclear:fix/interruptible-stop
Open

Use condition_variable for interruptible thread sleep in updateLoop#147
jslauthor wants to merge 1 commit intoCountly:masterfrom
hypernuclear:fix/interruptible-stop

Conversation

@jslauthor
Copy link

Summary

  • Replace std::this_thread::sleep_for() in updateLoop() with std::condition_variable::wait_for()
  • Add stop_cv.notify_one() in _deleteThread() to wake the sleeping thread immediately

This makes stop() return instantly instead of blocking for up to the full update interval (e.g. 30 seconds). Currently, _deleteThread() sets stop_thread = true and calls thread->join(), but the thread is stuck inside an uninterruptible sleep_for() and won't check the flag until the sleep finishes.

This causes GUI applications to hang for up to 30 seconds on quit when the SDK's static singleton destructor calls stop().

Changes

include/countly.hpp

  • Added #include <condition_variable>
  • Added std::condition_variable stop_cv member

src/countly.cpp

  • updateLoop(): Replaced sleep_for with stop_cv.wait_for() using stop_thread as predicate
  • _deleteThread(): Added stop_cv.notify_one() after setting stop_thread = true

Test plan

  • Verified stop() returns instantly instead of blocking
  • Verified update interval behavior is unchanged during normal operation (same sleep duration unless notified)
  • No changes to public API

Replace std::this_thread::sleep_for() in updateLoop() with
std::condition_variable::wait_for() so that _deleteThread() can
wake the background thread immediately via notify_one().

This makes stop() return instantly instead of blocking for up to
the full update interval (e.g. 30 seconds in production builds).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@jslauthor
Copy link
Author

Sorry, accidentally created this. Will open again if needed!

@jslauthor jslauthor closed this Mar 17, 2026
@jslauthor jslauthor reopened this Mar 17, 2026
@jslauthor
Copy link
Author

Okay, I do need it. 😅 This lets us cancel any pending requests so the app can close cleanly. Let me know if you'd like any changes!

@arifBurakDemiray
Copy link
Member

Hello @jslauthor 🙌

Thanks a lot for your contribution! We’ll review it carefully and get back to you soon. 🙇

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR improves shutdown responsiveness of the SDK’s background updateLoop() by making its sleep interruptible, so stop() doesn’t block for up to the full update interval.

Changes:

  • Replace std::this_thread::sleep_for() with std::condition_variable::wait_for() in Countly::updateLoop() to allow early wakeups on stop.
  • Add stop_cv.notify_one() in Countly::_deleteThread() after setting the stop flag.
  • Add a std::condition_variable stop_cv member and required header include.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/countly.cpp Uses stop_cv.wait_for() in updateLoop() and notifies the condition variable during _deleteThread() to wake the worker thread promptly.
include/countly.hpp Adds <condition_variable> include and a stop_cv member to support interruptible waits.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +1198 to +1201
std::unique_lock<std::mutex> lk(*mutex);
stop_cv.wait_for(lk, std::chrono::milliseconds(wait_milliseconds), [this] {
return stop_thread;
});
if (stop_thread) {
stop_thread = false;
running = false;
return;
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