configmgr/source/components.cxx |   54 +++++++++++++++++++++++++++++++---------
 1 file changed, 42 insertions(+), 12 deletions(-)

New commits:
commit e8358d0a0f7c2c4b1ccf800fe9ec8a7f2bf7066a
Author:     Stephan Bergmann <[email protected]>
AuthorDate: Thu Jul 25 07:59:58 2024 +0200
Commit:     Stephan Bergmann <[email protected]>
CommitDate: Thu Jul 25 09:51:52 2024 +0200

    Keep around a single configmgr::Components::WriteThread instance
    
    ...instead of joining and later re-spawning one.  This helps with the 
current
    Emscripten setup (see 5b1df7709d75c6dd993da5a272e7e37e55a70174 "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 <[email protected]>
    Tested-by: Jenkins

diff --git a/configmgr/source/components.cxx b/configmgr/source/components.cxx
index d2b709e9c337..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>
@@ -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 {
+    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(
@@ -284,6 +313,7 @@ void Components::writeModifications() {
                 &writeThread_, *this, modificationFileUrl_, data_);
             writeThread_->launch();
         }
+        writeThread_->trigger();
         break;
     case ModificationTarget::Dconf:
 #if ENABLE_DCONF

Reply via email to