From 21b0296d9edb62b9f5bad79edb2d0d47a4f453d5 Mon Sep 17 00:00:00 2001 From: Bowon Ryu Date: Thu, 22 Jun 2023 19:59:02 +0900 Subject: [PATCH] [Tizen] Ensure join of font thread In certain cases where the font thread is not joined, such as when there is no UI or when the font client is not used. this patch ensures the join of the font thread by invoking the join method in the destructor. Change-Id: I8ffcf21ab9dcc1b1e4de54e50adb23d0796b996e Signed-off-by: Bowon Ryu --- dali/devel-api/text-abstraction/font-client.cpp | 5 ++ dali/devel-api/text-abstraction/font-client.h | 5 ++ dali/internal/adaptor/common/application-impl.cpp | 3 + .../text/text-abstraction/font-client-impl.cpp | 68 ++++++++++++++++------ .../text/text-abstraction/font-client-impl.h | 5 ++ .../plugin/font-client-plugin-cache-handler.cpp | 2 +- 6 files changed, 68 insertions(+), 20 deletions(-) diff --git a/dali/devel-api/text-abstraction/font-client.cpp b/dali/devel-api/text-abstraction/font-client.cpp index 9b3c475..f40d086 100644 --- a/dali/devel-api/text-abstraction/font-client.cpp +++ b/dali/devel-api/text-abstraction/font-client.cpp @@ -869,6 +869,11 @@ void FontClientFontPreLoad(const FontPathList& fontPathList, const FontPathList& Internal::FontClient::PreLoad(fontPathList, memoryFontPathList, useThread, syncCreation); } +void FontClientJoinFontThreads() +{ + Internal::FontClient::JoinFontThreads(); +} + } // namespace TextAbstraction } // namespace Dali diff --git a/dali/devel-api/text-abstraction/font-client.h b/dali/devel-api/text-abstraction/font-client.h index 4123c25..50303d4 100644 --- a/dali/devel-api/text-abstraction/font-client.h +++ b/dali/devel-api/text-abstraction/font-client.h @@ -682,6 +682,11 @@ DALI_ADAPTOR_API void FontClientPreCache(const FontFamilyList& fallbackFamilyLis */ DALI_ADAPTOR_API void FontClientFontPreLoad(const FontPathList& fontPathList, const FontPathList& memoryFontPathList, bool useThread, bool syncCreation); +/** + * @brief Joins font threads, waiting for their execution to complete. + */ +DALI_ADAPTOR_API void FontClientJoinFontThreads(); + } // namespace TextAbstraction } // namespace Dali diff --git a/dali/internal/adaptor/common/application-impl.cpp b/dali/internal/adaptor/common/application-impl.cpp index e7d2687..0a8e122 100644 --- a/dali/internal/adaptor/common/application-impl.cpp +++ b/dali/internal/adaptor/common/application-impl.cpp @@ -309,6 +309,9 @@ void Application::OnInit() DALI_TRACE_END(gTraceFilter, "DALI_APP_EMIT_INIT_SIGNAL"); mAdaptor->NotifySceneCreated(); + + // Ensure the join of Font thread at this point + Dali::TextAbstraction::FontClientJoinFontThreads(); } void Application::OnTerminate() diff --git a/dali/internal/text/text-abstraction/font-client-impl.cpp b/dali/internal/text/text-abstraction/font-client-impl.cpp index a9fb2f2..70f2fb7 100644 --- a/dali/internal/text/text-abstraction/font-client-impl.cpp +++ b/dali/internal/text/text-abstraction/font-client-impl.cpp @@ -57,9 +57,32 @@ namespace TextAbstraction { namespace Internal { +class FontThread +{ +/* + * There are cases in the candidate process where the font thread is + * no UI or when the font client is not used. + * In such cases, we can ensure the join of the font thread + * by calling the join method in the destructor of this class. + */ +public: + FontThread() + { + } + ~FontThread() + { + if(mThread.joinable()) + { + mThread.join(); + } + } + std::thread mThread; +}; + Dali::TextAbstraction::FontClient FontClient::gPreCreatedFontClient(NULL); -std::thread gPreCacheThread; -std::thread gPreLoadThread; + +FontThread gPreCacheThread; +FontThread gPreLoadThread; std::mutex gMutex; std::condition_variable gPreCacheCond; std::condition_variable gPreLoadCond; @@ -101,17 +124,8 @@ Dali::TextAbstraction::FontClient FontClient::Get() } else // create and register the object { - if(gPreCacheThread.joinable()) - { - gPreCacheThread.join(); - FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "FontClient PreCache thread join\n"); - } - - if(gPreLoadThread.joinable()) - { - gPreLoadThread.join(); - FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "FontClient PreLoad thread join\n"); - } + // Check the joinable status of PreCahe and PreLoad thread, and join them + JoinFontThreads(); if(gPreCreatedFontClient) { @@ -205,9 +219,10 @@ void FontClient::PreCache(const FontFamilyList& fallbackFamilyList, const FontFa return; } - if(gPreCacheThread.joinable()) + if(gPreCacheThread.mThread.joinable()) { FONT_LOG_MESSAGE(Dali::Integration::Log::ERROR, "FontClient pre-cache thread already running.\n"); + return; } if(!gPreCreatedFontClient) @@ -232,13 +247,13 @@ void FontClient::PreCache(const FontFamilyList& fallbackFamilyList, const FontFa gPreCacheThreadReady = false; std::unique_lock lock(gMutex); FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "BEGIN: DALI_TEXT_PRECACHE_THREAD_SYNC_CREATION\n"); - gPreCacheThread = std::thread(PreCacheRun, fallbackFamilyList, extraFamilyList, localeFamily, syncCreation); + gPreCacheThread.mThread = std::thread(PreCacheRun, fallbackFamilyList, extraFamilyList, localeFamily, syncCreation); gPreCacheCond.wait_for(lock, timeout, []{return gPreCacheThreadReady;}); FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "END: DALI_TEXT_PRECACHE_THREAD_SYNC_CREATION\n"); } else { - gPreCacheThread = std::thread(PreCacheRun, fallbackFamilyList, extraFamilyList, localeFamily, syncCreation); + gPreCacheThread.mThread = std::thread(PreCacheRun, fallbackFamilyList, extraFamilyList, localeFamily, syncCreation); } } else @@ -255,7 +270,7 @@ void FontClient::PreLoad(const FontPathList& fontPathList, const FontPathList& m return; } - if(gPreLoadThread.joinable()) + if(gPreLoadThread.mThread.joinable()) { FONT_LOG_MESSAGE(Dali::Integration::Log::ERROR, "FontClient font pre-load thread already running.\n"); return; @@ -282,13 +297,13 @@ void FontClient::PreLoad(const FontPathList& fontPathList, const FontPathList& m gPreLoadThreadReady = false; std::unique_lock lock(gMutex); FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "BEGIN: DALI_TEXT_FONT_PRELOAD_THREAD_SYNC_CREATION\n"); - gPreLoadThread = std::thread(PreLoadRun, fontPathList, memoryFontPathList, syncCreation); + gPreLoadThread.mThread = std::thread(PreLoadRun, fontPathList, memoryFontPathList, syncCreation); gPreLoadCond.wait_for(lock, timeout, []{return gPreLoadThreadReady;}); FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "END: DALI_TEXT_FONT_PRELOAD_THREAD_SYNC_CREATION\n"); } else { - gPreLoadThread = std::thread(PreLoadRun, fontPathList, memoryFontPathList, syncCreation); + gPreLoadThread.mThread = std::thread(PreLoadRun, fontPathList, memoryFontPathList, syncCreation); } } else @@ -297,6 +312,21 @@ void FontClient::PreLoad(const FontPathList& fontPathList, const FontPathList& m } } +void FontClient::JoinFontThreads() +{ + if(gPreCacheThread.mThread.joinable()) + { + gPreCacheThread.mThread.join(); + FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "FontClient PreCache thread join\n"); + } + + if(gPreLoadThread.mThread.joinable()) + { + gPreLoadThread.mThread.join(); + FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "FontClient PreLoad thread join\n"); + } +} + void FontClient::ClearCache() { if(mPlugin) diff --git a/dali/internal/text/text-abstraction/font-client-impl.h b/dali/internal/text/text-abstraction/font-client-impl.h index 9f69794..809d8f0 100644 --- a/dali/internal/text/text-abstraction/font-client-impl.h +++ b/dali/internal/text/text-abstraction/font-client-impl.h @@ -88,6 +88,11 @@ public: // API for Dali::TextAbstraction::FontClient used. static void PreLoadRun(const FontPathList& fontPathList, const FontPathList& memoryFontPathList, bool syncCreation); /** + * @brief Joins font threads, waiting for their execution to complete. + */ + static void JoinFontThreads(); + + /** * @copydoc Dali::TextAbstraction::FontClient::ClearCache() */ void ClearCache(); diff --git a/dali/internal/text/text-abstraction/plugin/font-client-plugin-cache-handler.cpp b/dali/internal/text/text-abstraction/plugin/font-client-plugin-cache-handler.cpp index c248787..2509c8d 100644 --- a/dali/internal/text/text-abstraction/plugin/font-client-plugin-cache-handler.cpp +++ b/dali/internal/text/text-abstraction/plugin/font-client-plugin-cache-handler.cpp @@ -604,7 +604,7 @@ bool FontClient::Plugin::CacheHandler::LoadFontDataFromFile(const std::string& f { if(Dali::FileLoader::ReadFile(fontPath, dataSize, fontDataBuffer, Dali::FileLoader::BINARY)) { - FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "PreLoad font file buffer : %lu, size : %ld, path : %s\n", fontDataBuffer.Size(), static_cast(dataSize), fontPath.c_str()); + FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "PreLoad font file buffer : %zu, size : %ld, path : %s\n", fontDataBuffer.Size(), static_cast(dataSize), fontPath.c_str()); return true; } -- 2.7.4