From bf6edf83466fa625f013ca55e6e4c73f74c2e470 Mon Sep 17 00:00:00 2001 From: Leonard Souza Date: Tue, 17 Mar 2026 15:57:21 -0700 Subject: [PATCH] Use condition_variable for interruptible thread sleep 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 --- include/countly.hpp | 2 ++ src/countly.cpp | 19 +++++++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/include/countly.hpp b/include/countly.hpp index fa985e3..bcfb52c 100644 --- a/include/countly.hpp +++ b/include/countly.hpp @@ -5,6 +5,7 @@ #include "countly/countly_configuration.hpp" #include +#include #include #include #include @@ -349,6 +350,7 @@ class Countly : public cly::CountlyDelegates { bool enable_automatic_session = false; bool stop_thread = false; bool running = false; + std::condition_variable stop_cv; // Wakes updateLoop immediately on stop size_t wait_milliseconds = COUNTLY_KEEPALIVE_INTERVAL; size_t max_events = COUNTLY_MAX_EVENTS_DEFAULT; diff --git a/src/countly.cpp b/src/countly.cpp index 42552d6..af38aae 100644 --- a/src/countly.cpp +++ b/src/countly.cpp @@ -479,6 +479,7 @@ void Countly::_deleteThread() { mutex->lock(); stop_thread = true; mutex->unlock(); + stop_cv.notify_one(); if (thread && thread->joinable()) { try { thread->join(); @@ -1193,15 +1194,17 @@ void Countly::updateLoop() { running = true; mutex->unlock(); while (true) { - mutex->lock(); - if (stop_thread) { - stop_thread = false; - mutex->unlock(); - break; + { + std::unique_lock 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; + } } - size_t last_wait_milliseconds = wait_milliseconds; - mutex->unlock(); - std::this_thread::sleep_for(std::chrono::milliseconds(last_wait_milliseconds)); if (enable_automatic_session == true && configuration->manualSessionControl == false) { updateSession(); } else if (configuration->manualSessionControl == true) {