From 0ade4ecfa70257192e5317d360a29c64b8cbb301 Mon Sep 17 00:00:00 2001 From: "Dirk-Jan C. Binnema" Date: Mon, 22 Nov 2021 21:52:01 +0200 Subject: [PATCH] indexer: fix race condition It was possible for the worker to stop before the work was even started; and then we might wait forever for the queue to become empty. --- lib/index/mu-indexer.cc | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/index/mu-indexer.cc b/lib/index/mu-indexer.cc index 38ae1f3a..d373040c 100644 --- a/lib/index/mu-indexer.cc +++ b/lib/index/mu-indexer.cc @@ -198,13 +198,14 @@ Indexer::Private::worker() g_debug("started worker"); - while (state_ == IndexState::Scanning || !fq_.empty()) { + while (state_ == IndexState::Scanning) { + if (!fq_.pop(item, 250ms)) continue; try { std::unique_lock lock{lock_}; - store_.add_message(item, true /*use-transaction*/); + store_.add_message(item, true /*use-transaction*/); ++progress_.updated; } catch (const Mu::Error& er) { @@ -261,9 +262,12 @@ Indexer::Private::start(const Indexer::Config& conf) conf_.scan ? "yes" : "no", conf_.cleanup ? "yes" : "no"); - workers_.emplace_back(std::thread([this] { worker(); })); - state_.change_to(IndexState::Scanning); + { + /* kick off the first worker, which will spawn more if needed. */ + std::lock_guard wlock{wlock_}; + workers_.emplace_back(std::thread([this] { worker(); })); + } scanner_worker_ = std::thread([this] { progress_ = {};