Consider thread loop synchronization 32/307532/2
authorHwankyu Jhun <h.jhun@samsung.com>
Tue, 12 Mar 2024 01:04:18 +0000 (10:04 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Tue, 12 Mar 2024 01:06:31 +0000 (10:06 +0900)
Even though the tizen_core_task_run() function is called, the
tizen_core_task_is_running() can return 'false'.
To make running thread loop synchronously, using condition variable is needed.

Change-Id: Iccefb111cdde8f6121d479547c457e89c75b3569
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
tizen_base/task.cc
tizen_base/task.h

index d09b8585b46c74f5c20a40a1811989de25701cbc..0dd22c1e5469580cad3e711ae9c08c60ed013186 100644 (file)
@@ -195,11 +195,13 @@ std::shared_ptr<Context> Task::GetContext() const {
 }
 
 void Task::Quit() {
+  std::unique_lock<std::mutex> lock(loop_mutex_);
   if (g_main_loop_is_running(loop_))
     g_main_loop_quit(loop_);
 }
 
 void Task::Run() {
+  std::unique_lock<std::mutex> lock(loop_mutex_);
   if (use_thread_) {
     thread_ = std::thread([&]() -> void {
       tid_ = gettid();
@@ -207,14 +209,17 @@ void Task::Run() {
       tid_ = -1;
       cpu_boosting_level_ = TIZEN_CORE_CPU_BOOSTING_LEVEL_NONE;
     });
+    cond_var_.wait(lock, [this]() { return g_main_loop_is_running(loop_); });
   } else {
     tid_ = getpid();
+    lock.unlock();
     g_main_loop_run(loop_);
     tid_ = -1;
   }
 }
 
 bool Task::IsRunning() const {
+  std::unique_lock<std::mutex> lock(loop_mutex_);
   return g_main_loop_is_running(loop_);
 }
 
@@ -328,7 +333,24 @@ bool Task::ClearCpuBoosting() {
 }
 
 void Task::ThreadLoop() {
-  g_main_context_push_thread_default(context_->GetHandle());
+  {
+    std::unique_lock<std::mutex> lock(loop_mutex_);
+    GSource* source = g_idle_source_new();
+    g_source_set_callback(
+        source, [](gpointer user_data) {
+          auto* task = static_cast<Task*>(user_data);
+          std::unique_lock<std::mutex> lock(task->loop_mutex_);
+          task->cond_var_.notify_one();
+          return G_SOURCE_REMOVE;
+        }, this,
+        nullptr);
+    g_source_set_priority(source, G_PRIORITY_HIGH);
+    g_source_attach(source, context_->GetHandle());
+    g_source_unref(source);
+
+    g_main_context_push_thread_default(context_->GetHandle());
+  }
+
   g_main_loop_run(loop_);
   g_main_context_pop_thread_default(context_->GetHandle());
 }
index 8c8683046ff16730fbca9e1684d1d4c795338e1b..7145c0fdd33dcbc58dd875cfdeee1eda6eaab584 100644 (file)
@@ -91,6 +91,8 @@ class EXPORT_API Task : public ILoop,
   bool use_thread_;
   std::shared_ptr<Context> context_;
   std::thread thread_;
+  std::condition_variable cond_var_;
+  mutable std::mutex loop_mutex_;
   GMainLoop* loop_ = nullptr;
   std::list<std::shared_ptr<ISource>> event_sources_;
   mutable std::recursive_mutex mutex_;