Keep around a single configmgr::Components::WriteThread instance

...instead of joining and later re-spawning one.  This helps with the current
Emscripten setup (see 5b1df7709d "Document the
Emscripten threads issue"), and probably doesn't matter much either way on other
platforms (so just get it in unconditionally).  (Renaming the delay_ member
variable to delayOrTerminate_, to make its overall role more clear.)

(I ran into this when trying to turn the Emscripten build from starting up with
a Writer document to starting up with the start center, and then manually
opening a new Writer document.  The resulting different usage scheme happened to
exhaust our current -sPTHREAD_POOL_SIZE=4 pool quickly, so this is one of
multiple commits to address that.)

Change-Id: I1bd28604b4640d2afad982bfd82b1acee8200e26
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170993
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
This commit is contained in:
Stephan Bergmann 2024-07-25 07:59:58 +02:00
parent 4a608aa02d
commit e8358d0a0f

View file

@ -21,6 +21,8 @@
#include <cassert>
#include <chrono>
#include <condition_variable>
#include <mutex>
#include <utility>
#include <vector>
#include <set>
@ -153,7 +155,16 @@ public:
rtl::Reference< WriteThread > * reference, Components & components,
OUString url, Data const & data);
void flush() { delay_.set(); }
void trigger() {
std::scoped_lock l(triggerMutex_);
triggered_ = true;
triggerCondition_.notify_all();
}
void flush() {
delayOrTerminate_.set();
trigger();
}
private:
virtual ~WriteThread() override {}
@ -164,7 +175,10 @@ private:
Components & components_;
OUString url_;
Data const & data_;
osl::Condition delay_;
osl::Condition delayOrTerminate_;
std::mutex triggerMutex_;
std::condition_variable triggerCondition_;
bool triggered_;
std::shared_ptr<osl::Mutex> lock_;
};
@ -173,26 +187,41 @@ Components::WriteThread::WriteThread(
OUString url, Data const & data):
Thread("configmgrWriter"), reference_(reference), components_(components),
url_(std::move(url)), data_(data),
triggered_(false),
lock_( lock() )
{
assert(reference != nullptr);
}
void Components::WriteThread::execute() {
delay_.wait(std::chrono::seconds(1)); // must not throw; result_error is harmless and ignored
osl::MutexGuard g(*lock_); // must not throw
try {
try {
writeModFile(components_, url_, data_);
} catch (css::uno::RuntimeException &) {
// Ignore write errors, instead of aborting:
TOOLS_WARN_EXCEPTION("configmgr", "error writing modifications");
for (;;) {
{
std::unique_lock l(triggerMutex_);
while (!triggered_) {
triggerCondition_.wait(l);
}
triggered_ = false;
}
delayOrTerminate_.wait(std::chrono::seconds(1));
// must not throw; result_error is harmless and ignored
osl::MutexGuard g(*lock_); // must not throw
try {
try {
writeModFile(components_, url_, data_);
} catch (css::uno::RuntimeException &) {
// Ignore write errors, instead of aborting:
TOOLS_WARN_EXCEPTION("configmgr", "error writing modifications");
}
} catch (...) {
reference_->clear();
throw;
}
if (!delayOrTerminate_.check()) {
continue;
}
} catch (...) {
reference_->clear();
throw;
break;
}
reference_->clear();
}
Components & Components::getSingleton(
@ -284,6 +313,7 @@ void Components::writeModifications() {
&writeThread_, *this, modificationFileUrl_, data_);
writeThread_->launch();
}
writeThread_->trigger();
break;
case ModificationTarget::Dconf:
#if ENABLE_DCONF