[Libreoffice-commits] core.git: desktop/source include/rtl sal/inc sal/qa sal/rtl

Ashod Nakashian ashod.nakashian at collabora.co.uk
Thu Dec 28 18:10:27 UTC 2017


 desktop/source/lib/init.cxx    |    6 +++-
 include/rtl/alloc.h            |   42 +++++++++++++++++++++++++++++---
 sal/inc/rtllifecycle.h         |    4 +++
 sal/qa/rtl/alloc/rtl_alloc.cxx |    4 +--
 sal/rtl/alloc_cache.cxx        |   10 +++++++
 sal/rtl/strimp.cxx             |   53 ++++++++++++++++++++++++++++-------------
 6 files changed, 95 insertions(+), 24 deletions(-)

New commits:
commit 271a663d2f098f3f665cab6da2e13b265a7eab93
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Mon Dec 25 15:02:41 2017 -0500

    rtl: support start/stop threads around pre-init
    
    This is necessary to avoid having extra threads
    while forking. After forking, the second stage
    of pre-init is started and so we start the stopped
    rtl threads.
    
    The comment for rtl_alloc_preInit_phase_t has
    more details.
    
    Change-Id: I1a3f7be74d4b04d0b2fc4a72b02124c2faa3c047
    Reviewed-on: https://gerrit.libreoffice.org/47060
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index f87caa5b0787..f8aebcfc8606 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -3552,7 +3552,9 @@ static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char
         return 1;
 
     if (eStage == PRE_INIT)
-        rtl_alloc_preInit(true);
+        rtl_alloc_preInit(rtlAllocPreInitStart);
+    else if (eStage == SECOND_INIT)
+        rtl_alloc_preInit(rtlAllocPreInitEnd);
 
     if (eStage != SECOND_INIT)
         comphelper::LibreOfficeKit::setActive();
@@ -3707,7 +3709,7 @@ static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char
     }
 
     if (eStage == PRE_INIT)
-        rtl_alloc_preInit(false);
+        rtl_alloc_preInit(rtlAllocPostInit);
 
     return bInitialized;
 }
diff --git a/include/rtl/alloc.h b/include/rtl/alloc.h
index cb4f09cbb67c..83babccb9e70 100644
--- a/include/rtl/alloc.h
+++ b/include/rtl/alloc.h
@@ -289,15 +289,49 @@ SAL_DLLPUBLIC void SAL_CALL rtl_cache_free (
 #ifdef LIBO_INTERNAL_ONLY
 
 /** @cond INTERNAL */
+/** rtl_alloc_preInit_phase_t
+ *
+ * This is used to control the pre-init logic
+ * in rtl_alloc_preInit. The reason for this is
+ * to first initialize all caching and other memory
+ * logic from WSD (the Online demaon) at startup.
+ * All these pages will then be forked over when
+ * spawning per-document instances. This is done
+ * by calling rtl_alloc_preInit with rtlAllocPreInitStart.
+ *
+ * However before forking we need to wind down
+ * all threads, which is required by design.
+ * This is done by calling rtl_alloc_preInit
+ * with rtlAllocPreInitEnd.
+ *
+ * And of course the stopped threads need restarting
+ * after forking to ensure correct cleanup of the
+ * caches and other memory allocations. This is done
+ * by calling rtl_alloc_preInit with rtlAllocPostInit.
+ *
+ * @since LibreOffice 6.1
+ */
+typedef enum
+{
+    // Start phase I of pre-init.
+    rtlAllocPreInitStart,
+    // Finish phase I of pre-init (before forking).
+    rtlAllocPreInitEnd,
+    // Post pre-init and after forking.
+    rtlAllocPostInit
+
+} rtl_alloc_preInit_phase_t;
+
+/** @cond INTERNAL */
 /** rtl_alloc_preInit
  *
  * This function, is called at the beginning and again
  * at the end of LibreOfficeKit pre-initialization to enable
  * various optimizations.
  *
- * Its function is to annotate a section @start = true to
- * end (@start = false) via. two calls. Inside this section
- * string allocators are replaced with ones which cause the
+ * Its function is to annotate a section @phase = rtlAllocPreInitStart
+ * to end (@phase = rtlAllocPreInitEnd) via. two calls. Inside this
+ * section string allocators are replaced with ones which cause the
  * strings to be staticized at the end of the section.
  *
  * This brings a number of constraints - in particular no
@@ -317,7 +351,7 @@ SAL_DLLPUBLIC void SAL_CALL rtl_cache_free (
  * @since LibreOffice 6.1
  */
 SAL_DLLPUBLIC void SAL_CALL rtl_alloc_preInit (
-    sal_Bool start
+    rtl_alloc_preInit_phase_t phase
 ) SAL_THROW_EXTERN_C();
 /** @endcond */
 
diff --git a/sal/inc/rtllifecycle.h b/sal/inc/rtllifecycle.h
index 82e38dee6372..528f4cc48a2f 100644
--- a/sal/inc/rtllifecycle.h
+++ b/sal/inc/rtllifecycle.h
@@ -26,6 +26,10 @@ void rtl_cache_fini(void);
 
 void ensureCacheSingleton(void);
 
+void rtl_cache_stop_threads(void);
+
+void rtl_cache_start_threads(void);
+
 void rtl_memory_init(void);
 
 void rtl_memory_fini(void);
diff --git a/sal/qa/rtl/alloc/rtl_alloc.cxx b/sal/qa/rtl/alloc/rtl_alloc.cxx
index 0e9b7c0f47a8..37c7b41eb338 100644
--- a/sal/qa/rtl/alloc/rtl_alloc.cxx
+++ b/sal/qa/rtl/alloc/rtl_alloc.cxx
@@ -158,7 +158,7 @@ public:
         const char *sample = "Hello World";
         std::vector<OUString> aStrings;
 
-        rtl_alloc_preInit(true);
+        rtl_alloc_preInit(rtlAllocPreInitStart);
 
         OUString aFoo("foo");
 
@@ -183,7 +183,7 @@ public:
         }
 
         // should static-ize all the strings.
-        rtl_alloc_preInit(false);
+        rtl_alloc_preInit(rtlAllocPreInitEnd);
 
         for (size_t i = 0; i < aStrings.size(); ++i)
             CPPUNIT_ASSERT_MESSAGE( "static after.", (aStrings[i].pData->refCount & SAL_STRING_STATIC_FLAG) );
diff --git a/sal/rtl/alloc_cache.cxx b/sal/rtl/alloc_cache.cxx
index 468bbdcdbf04..5ad8690e3152 100644
--- a/sal/rtl/alloc_cache.cxx
+++ b/sal/rtl/alloc_cache.cxx
@@ -1353,6 +1353,16 @@ rtl_cache_wsupdate_all(void * arg)
 #endif
 }
 
+void rtl_cache_stop_threads(void)
+{
+    rtl_cache_wsupdate_fini();
+}
+
+void rtl_cache_start_threads(void)
+{
+    rtl_cache_wsupdate_init();
+}
+
 void rtl_cache_init()
 {
     {
diff --git a/sal/rtl/strimp.cxx b/sal/rtl/strimp.cxx
index ed0d333639d2..d520d2412b6e 100644
--- a/sal/rtl/strimp.cxx
+++ b/sal/rtl/strimp.cxx
@@ -21,6 +21,7 @@
 #include <assert.h>
 #include <rtl/alloc.h>
 #include <rtl/ustring.h>
+#include <rtllifecycle.h>
 
 #include "strimp.hxx"
 #include "alloc_impl.hxx"
@@ -93,25 +94,45 @@ static void mark_static(void *addr, sal_Size /* size */, void *)
     str->refCount |= SAL_STRING_STATIC_FLAG;
 }
 
-void SAL_CALL rtl_alloc_preInit (sal_Bool start) SAL_THROW_EXTERN_C()
+void SAL_CALL rtl_alloc_preInit (rtl_alloc_preInit_phase_t phase) SAL_THROW_EXTERN_C()
 {
-    if (start)
+    switch (phase)
     {
-        rtl_allocateString = pre_allocateStringFn;
-        rtl_freeString = pre_freeStringFn;
-        pre_arena = rtl_arena_create("pre-init strings", 4, 0,
-                                     nullptr, rtl_arena_alloc,
-                                     rtl_arena_free, 0);
-    }
-    else // back to normal
-    {
-        rtl_arena_foreach(pre_arena, mark_static, nullptr);
-        rtl_allocateString = rtl_allocateMemory;
-        rtl_freeString = rtl_freeMemory;
-
-        // TODO: also re-initialize main allocator as well.
+        case rtlAllocPreInitStart:
+        {
+            rtl_allocateString = pre_allocateStringFn;
+            rtl_freeString = pre_freeStringFn;
+            pre_arena = rtl_arena_create("pre-init strings", 4, 0,
+                                         nullptr, rtl_arena_alloc,
+                                         rtl_arena_free, 0);
+
+            // To be consistent (and to ensure the rtl_cache threads are started).
+            ensureCacheSingleton();
+        }
+        break;
+
+        case rtlAllocPreInitEnd:
+        // back to normal
+        {
+            rtl_arena_foreach(pre_arena, mark_static, nullptr);
+            rtl_allocateString = rtl_allocateMemory;
+            rtl_freeString = rtl_freeMemory;
+
+            // Stop the rtl cache thread to have no extra threads while forking.
+            rtl_cache_stop_threads();
+
+            // TODO: also re-initialize main allocator as well.
+        }
+        break;
+
+        case rtlAllocPostInit:
+        {
+            // We have forked and need to restart threads and anything
+            // that must start after forking.
+            rtl_cache_start_threads();
+        }
+        break;
     }
 }
 
-
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list