diff options
Diffstat (limited to 'configmgr')
-rw-r--r-- | configmgr/source/components.cxx | 84 |
1 files changed, 43 insertions, 41 deletions
diff --git a/configmgr/source/components.cxx b/configmgr/source/components.cxx index 8afaaff3bae8..4790cdd4bd3c 100644 --- a/configmgr/source/components.cxx +++ b/configmgr/source/components.cxx @@ -21,6 +21,8 @@ #include <cassert> #include <chrono> +#include <condition_variable> +#include <mutex> #include <utility> #include <vector> #include <set> @@ -51,7 +53,6 @@ #include <sal/types.h> #include <salhelper/thread.hxx> #include <comphelper/diagnose_ex.hxx> -#include <comphelper/backupfilehelper.hxx> #include <o3tl/string_view.hxx> #include "additions.hxx" @@ -154,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 {} @@ -165,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_; }; @@ -174,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 { + 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 { - writeModFile(components_, url_, data_); - } catch (css::uno::RuntimeException &) { - // Ignore write errors, instead of aborting: - TOOLS_WARN_EXCEPTION("configmgr", "error writing modifications"); + 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( @@ -285,6 +313,7 @@ void Components::writeModifications() { &writeThread_, *this, modificationFileUrl_, data_); writeThread_->launch(); } + writeThread_->trigger(); break; case ModificationTarget::Dconf: #if ENABLE_DCONF @@ -607,34 +636,7 @@ Components::Components( Components::~Components() { - // get flag if _exit was already called which is a sign to not secure user config. - // this is used for win only currently where calling _exit() unfortunately still - // calls destructors (what is not wanted). May be needed for other systems, too - // (unknown yet) but can do no harm - const bool bExitWasCalled(comphelper::BackupFileHelper::getExitWasCalled()); - -#ifndef _WIN32 - // we can add a SAL_WARN here for other systems where the destructor gets called after - // an _exit() call. Still safe - the getExitWasCalled() is used, but a hint that _exit - // behaves different on a system - SAL_WARN_IF(bExitWasCalled, "configmgr", "Components::~Components() called after _exit() call"); -#endif - - if (bExitWasCalled) - { - // do not write, re-join threads - osl::MutexGuard g(*lock_); - - if (writeThread_.is()) - { - writeThread_->join(); - } - } - else - { - // write changes - flushModifications(); - } + flushModifications(); for (auto const& rootElem : roots_) { |