summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--desktop/source/lib/init.cxx6
-rw-r--r--include/rtl/alloc.h42
-rw-r--r--sal/inc/rtllifecycle.h4
-rw-r--r--sal/qa/rtl/alloc/rtl_alloc.cxx4
-rw-r--r--sal/rtl/alloc_cache.cxx10
-rw-r--r--sal/rtl/strimp.cxx53
6 files changed, 95 insertions, 24 deletions
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 a739bda8f155..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-intialize 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: */