[Tizen] Ensure join of font thread 50/294750/1 accepted/tizen/7.0/unified/20230627.014858
authorBowon Ryu <bowon.ryu@samsung.com>
Thu, 22 Jun 2023 10:59:02 +0000 (19:59 +0900)
committerBowon Ryu <bowon.ryu@samsung.com>
Mon, 26 Jun 2023 02:24:13 +0000 (11:24 +0900)
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 <bowon.ryu@samsung.com>
dali/devel-api/text-abstraction/font-client.cpp
dali/devel-api/text-abstraction/font-client.h
dali/internal/adaptor/common/application-impl.cpp
dali/internal/text/text-abstraction/font-client-impl.cpp
dali/internal/text/text-abstraction/font-client-impl.h
dali/internal/text/text-abstraction/plugin/font-client-plugin-cache-handler.cpp

index 9b3c4758fe5a96dc96d2aa18779502102d0b7f37..f40d08644b9e9c82c63e37bade3e374eb07217aa 100644 (file)
@@ -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
index 4123c25fc0997486a8dd6622b025b98e39484453..50303d4c580e3a9473e669cd36e725ede68805fb 100644 (file)
@@ -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
index e7d2687eff4e40c4ff27b4f26dcc5e6601027320..0a8e122de6e0e520af1a54e4bf835402c39d0775 100644 (file)
@@ -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()
index a9fb2f24c7f7a9890fb9557b890ca089fcb95b12..70f2fb7f71a4a746657d1d034a81f13bcec5e778 100644 (file)
@@ -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<std::mutex> 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<std::mutex> 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)
index 9f69794a9c9b357a4f103a585e9341c1b2008e36..809d8f02ed430aa0ea925551254b3dde802a8fc1 100644 (file)
@@ -87,6 +87,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()
    */
index c248787766e9e734942245c8e3ad4c619061c7fc..2509c8d6a5349c01d11e055db72f0e5b45ee8834 100644 (file)
@@ -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<long>(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<long>(dataSize), fontPath.c_str());
     return true;
   }