diff options
-rw-r--r-- | desktop/source/lib/init.cxx | 6 | ||||
-rw-r--r-- | include/rtl/alloc.h | 42 | ||||
-rw-r--r-- | sal/inc/rtllifecycle.h | 4 | ||||
-rw-r--r-- | sal/qa/rtl/alloc/rtl_alloc.cxx | 4 | ||||
-rw-r--r-- | sal/rtl/alloc_cache.cxx | 10 | ||||
-rw-r--r-- | sal/rtl/strimp.cxx | 53 |
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 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: */ |