libmain/progress-bar: do not start the update thread when not on a TTY

The progress bar normally maintains the invariant that the update thread is
only running when the progress bar is active. This was violated when it is
already created in inactive state, which happens when stderr is not a TTY. The
update thread is superfluous and would cause std::terminate if the logger were
to be destroyed.

Change-Id: I6ed3e26cdba00e5ac316078fea272d3a1aa0d112
This commit is contained in:
alois31 2024-06-24 20:37:28 +02:00
parent 206a5dbb8f
commit 75284a5263
Signed by untrusted user: alois31
GPG key ID: E0F59EA5E5216914

View file

@ -44,17 +44,20 @@ static std::string_view storePathToName(std::string_view path)
ProgressBar::ProgressBar(bool isTTY) ProgressBar::ProgressBar(bool isTTY)
: isTTY(isTTY) : isTTY(isTTY)
{ {
state_.lock()->active = isTTY; if ((state_.lock()->active = isTTY)) {
updateThread = std::thread([&]() { // Only start the update thread when the logger is set to active.
auto state(state_.lock()); // Otherwise, the destructor will std::terminate trying to destroy a joinable thread.
auto nextWakeup = A_LONG_TIME; updateThread = std::thread([&]() {
while (state->active) { auto state(state_.lock());
if (!state->haveUpdate) auto nextWakeup = A_LONG_TIME;
state.wait_for(updateCV, nextWakeup); while (state->active) {
nextWakeup = draw(*state, {}); if (!state->haveUpdate)
state.wait_for(quitCV, std::chrono::milliseconds(50)); state.wait_for(updateCV, nextWakeup);
} nextWakeup = draw(*state, {});
}); state.wait_for(quitCV, std::chrono::milliseconds(50));
}
});
}
} }
ProgressBar::~ProgressBar() ProgressBar::~ProgressBar()