Fix Sub Thread of AppCoreEflBase 28/270828/2
authorHwankyu Jhun <h.jhun@samsung.com>
Thu, 10 Feb 2022 01:21:38 +0000 (10:21 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Thu, 10 Feb 2022 01:32:16 +0000 (10:32 +0900)
This patch is to fix a crash issue of unit tests. Sometimes, the sub
thread of AppCoreEflBase for loading voice elm library runs after the
test instance is destroyed. In this case, the thread cannot find the
DlMock. Because, the mockup is already destroyed.

Change-Id: I7280a90cf1d6b203dd868d2b82456bde3d7f7b9c
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
tizen-cpp/app-core-efl-cpp/app_core_efl_base.cc
tizen-cpp/app-core-efl-cpp/app_core_efl_base.hh

index b69ee53..6fa4a74 100644 (file)
 
 namespace tizen_cpp {
 
-namespace {
-
-std::unique_ptr<VoiceElm> __vc_elm;
-
-}  // namespace
+class AppCoreEflBase::Impl {
+ public:
+  Impl(AppCoreEflBase* parent);
+  ~Impl();
+
+  void Init(int argc, char** argv);
+  void Finish();
+  void LoopRun();
+  void LoopExit();
+  void TrimMemory();
+
+ private:
+  friend class AppCoreEflBase;
+  AppCoreEflBase* parent_;
+
+  std::thread thread_;
+  std::unique_ptr<VoiceElm> vc_elm_;
+  guint source_id_ = 0;
+};
+
+AppCoreEflBase::Impl::Impl(AppCoreEflBase* parent) : parent_(parent) {}
+
+AppCoreEflBase::Impl::~Impl() {
+  if (thread_.joinable())
+    thread_.join();
+
+  if (source_id_ != 0)
+    g_source_remove(source_id_);
+}
 
-void AppCoreEflBase::OnLoopInit(int argc, char** argv) {
+void AppCoreEflBase::Impl::Init(int argc, char** argv) {
   elm_init(argc, argv);
-  unsigned int hint = GetHint();
+  unsigned int hint = parent_->GetHint();
   if ((hint & HINT_HW_ACC_CONTROL) && !getenv("AUL_HWACC")) {
     const char* hwacc = getenv("HWACC");
     if (hwacc == nullptr) {
@@ -53,32 +77,35 @@ void AppCoreEflBase::OnLoopInit(int argc, char** argv) {
   }
 
   if (VoiceElm::IsVtAutoMode()) {
-    std::thread([]{
-          int retry_count = 3;
-          do {
-            if (__vc_elm.get() == nullptr)
-              __vc_elm.reset(VoiceElm::Load());
-
-            if (__vc_elm.get() != nullptr) {
-              g_idle_add([](gpointer data) {
-                    if (__vc_elm.get() != nullptr)
-                      __vc_elm->Init();
-                    return G_SOURCE_REMOVE;
-                  }, nullptr);
-              break;
-            }
-          } while (retry_count--);
-        }).detach();
+    thread_ = std::thread([&] {
+        int retry_count = 3;
+        do {
+          if (vc_elm_.get() == nullptr)
+              vc_elm_.reset(VoiceElm::Load());
+
+          if (vc_elm_.get() != nullptr) {
+            source_id_ = g_idle_add([](gpointer user_data) {
+                  auto* impl = static_cast<AppCoreEflBase::Impl*>(user_data);
+                  if (impl->vc_elm_.get() != nullptr)
+                    impl->vc_elm_->Init();
+
+                  impl->source_id_ = 0;
+                  return G_SOURCE_REMOVE;
+                }, this);
+            break;
+          }
+        } while (retry_count--);
+    });
   }
 }
 
-void AppCoreEflBase::OnLoopFinish() {
-  if (__vc_elm != nullptr)
-    __vc_elm.reset();
+void AppCoreEflBase::Impl::Finish() {
+  if (thread_.joinable())
+    thread_.join();
 
   elm_shutdown();
 
-  /* Check loader case */
+  // Check loader case
   const char* env = getenv("AUL_LOADER_INIT");
   if (env && env[0] == '1') {
     setenv("AUL_LOADER_INIT", "0", 1);
@@ -86,17 +113,44 @@ void AppCoreEflBase::OnLoopFinish() {
   }
 }
 
-void AppCoreEflBase::OnLoopRun() {
+void AppCoreEflBase::Impl::LoopRun() {
   elm_run();
 }
 
-void AppCoreEflBase::OnLoopExit() {
+void AppCoreEflBase::Impl::LoopExit() {
   elm_exit();
 }
 
+void AppCoreEflBase::Impl::TrimMemory() {
+  elm_cache_all_flush();
+}
+
+AppCoreEflBase::AppCoreEflBase(unsigned int hint)
+    : AppCoreUiBase(hint),
+      impl_(new Impl(this)) {
+}
+
+AppCoreEflBase::~AppCoreEflBase() = default;
+
+void AppCoreEflBase::OnLoopInit(int argc, char** argv) {
+  impl_->Init(argc, argv);
+}
+
+void AppCoreEflBase::OnLoopFinish() {
+  impl_->Finish();
+}
+
+void AppCoreEflBase::OnLoopRun() {
+  impl_->LoopRun();
+}
+
+void AppCoreEflBase::OnLoopExit() {
+  impl_->LoopExit();
+}
+
 int AppCoreEflBase::OnTrimMemory() {
   _D("Trim memory");
-  elm_cache_all_flush();
+  impl_->TrimMemory();
   return AppCoreUiBase::OnTrimMemory();
 }
 
index 497fd43..3ac987f 100644 (file)
@@ -19,6 +19,8 @@
 
 #include <app_core_ui_base.hh>
 
+#include <memory>
+
 #undef EXPORT_API
 #define EXPORT_API __attribute__((visibility("default")))
 
@@ -26,13 +28,18 @@ namespace tizen_cpp {
 
 class EXPORT_API AppCoreEflBase : public AppCoreUiBase {
  public:
-  explicit AppCoreEflBase(unsigned int hint) : AppCoreUiBase(hint) {}
+  explicit AppCoreEflBase(unsigned int hint);
+  virtual ~AppCoreEflBase();
 
   void OnLoopInit(int argc, char** argv) override;
   void OnLoopFinish() override;
   void OnLoopRun() override;
   void OnLoopExit() override;
   int OnTrimMemory() override;
+
+ private:
+  class Impl;
+  std::unique_ptr<Impl> impl_;
 };
 
 }  // namespace tizen_cpp