static uint32_t PeriodicTask_TimerRunner(uint32_t interval, void * param) { TaskHandle handle = (TaskHandle) param; if(!handle->valid) return 0; if(handle->enabled) handle->function(handle->param); return 1; }
void BackgroundProcessingPool::threadFunction() { setThreadName("BackgrProcPool"); MemoryTracker memory_tracker; memory_tracker.setMetric(CurrentMetrics::MemoryTrackingInBackgroundProcessingPool); current_memory_tracker = &memory_tracker; std::mt19937 rng(reinterpret_cast<intptr_t>(&rng)); std::this_thread::sleep_for(std::chrono::duration<double>(std::uniform_real_distribution<double>(0, sleep_seconds_random_part)(rng))); while (!shutdown) { bool done_work = false; TaskHandle task; try { Poco::Timestamp min_time; { std::unique_lock<std::mutex> lock(tasks_mutex); if (!tasks.empty()) { for (const auto & time_handle : tasks) { if (!time_handle.second->removed) { min_time = time_handle.first; task = time_handle.second; break; } } } } if (shutdown) break; if (!task) { std::unique_lock<std::mutex> lock(tasks_mutex); wake_event.wait_for(lock, std::chrono::duration<double>(sleep_seconds + std::uniform_real_distribution<double>(0, sleep_seconds_random_part)(rng))); continue; } /// No tasks ready for execution. Poco::Timestamp current_time; if (min_time > current_time) { std::unique_lock<std::mutex> lock(tasks_mutex); wake_event.wait_for(lock, std::chrono::microseconds( min_time - current_time + std::uniform_int_distribution<uint64_t>(0, sleep_seconds_random_part * 1000000)(rng))); } Poco::ScopedReadRWLock rlock(task->rwlock); if (task->removed) continue; { CurrentMetrics::Increment metric_increment{CurrentMetrics::BackgroundPoolTask}; done_work = task->function(); } } catch (...) { tryLogCurrentException(__PRETTY_FUNCTION__); } if (shutdown) break; /// If task has done work, it could be executed again immediately. /// If not, add delay before next run. Poco::Timestamp next_time_to_execute = Poco::Timestamp() + (done_work ? 0 : sleep_seconds * 1000000); { std::unique_lock<std::mutex> lock(tasks_mutex); if (task->removed) continue; tasks.erase(task->iterator); task->iterator = tasks.emplace(next_time_to_execute, task); } } current_memory_tracker = nullptr; }