Add priority for united service configurefile
authorSukhyungKang <shine.kang@samsung.com>
Fri, 4 Apr 2025 00:25:58 +0000 (09:25 +0900)
committerSukhyungKang <shine.kang@samsung.com>
Thu, 10 Apr 2025 06:25:05 +0000 (15:25 +0900)
Signed-off-by: SukhyungKang <shine.kang@samsung.com>
src/service.cc
src/service.hh
src/service_context.cc
src/service_context.hh
src/service_info.cc
src/service_info.hh
src/service_loader.cc
src/service_loader.hh

index 5351531f9b1dd91395f5fb9d3925b6c8d317546c..21ffa56147b44ec64b0855aee9573c2e6261f0f4 100644 (file)
@@ -111,6 +111,7 @@ void Service::Run() {
         service->OnCreate();
         service->state_ = Service::State::Running;
         ServiceManager::GetInst().NotifyServiceStateChanged(service);
+        service->cond_var_.notify_one();
         return false;
       }, this, &source);
 
@@ -122,6 +123,15 @@ void Service::Run() {
   running_ = true;
 }
 
+void Service::WaitRun() {
+  _E("@@ wait run : %s", name_.c_str());
+  std::unique_lock<std::mutex> lock(mutex_);
+
+  cond_var_.wait(lock, [this]() { return state_ == State::Running; });
+
+  _E("@@ wait end : %s", name_.c_str());
+}
+
 void Service::Quit() {
   if (!running_) return;
 
index 354ad592e084efe2c5dae75f0179d0de4d3eb365..d1a15c9e66157a51e1077daef105e967fd7f6b55 100644 (file)
@@ -42,6 +42,7 @@ class Service : public std::enable_shared_from_this<Service> {
 
   void Run();
   void Quit();
+  void WaitRun();
 
   const std::string& GetName() const;
   State GetState() const;
index 8864417ba15ebf52ff04aa9be3282fd9cbc94640..cfd5f4b23514ac3d18fe379c890065b3a98c94e5 100644 (file)
@@ -38,6 +38,10 @@ ServiceContext::ServiceContext(std::shared_ptr<ServiceInfo> info)
 ServiceContext::~ServiceContext() { Shutdown(); }
 
 bool ServiceContext::Init() {
+  return true;
+}
+
+bool ServiceContext::Run() {
   if (!Load()) return false;
 
   auto* init_func = reinterpret_cast<void* (*)(const char*)>(
@@ -84,6 +88,8 @@ std::shared_ptr<ServiceInfo> ServiceContext::GetServiceInfo() const {
 
 const std::string& ServiceContext::GetName() const { return info_->GetName(); }
 
+const unsigned int ServiceContext::GetPriority() const { return info_->GetPriority(); }
+
 bool ServiceContext::Load() {
   if (handle_) return true;
 
index 54939a9ace98195e2561fd0be6540e4bf4f53f00..00ca8f827ee724a044b9e7219a70411bf3a05756 100644 (file)
@@ -31,10 +31,12 @@ class ServiceContext {
   ~ServiceContext();
 
   bool Init();
+  bool Run();
   void Shutdown();
   std::shared_ptr<Service> GetService() const;
   std::shared_ptr<ServiceInfo> GetServiceInfo() const;
   const std::string& GetName() const;
+  const unsigned int GetPriority() const;
 
  private:
   bool Load();
index 0c17c59a1347e54cc35aee273eabc83019d696af..abd9108c31508e8d152db9d2e686e5323831a0db 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <utility>
 
+#include "exception.hh"
 #include "log_private.hh"
 
 namespace {
@@ -28,6 +29,7 @@ static const std::string kName = kTagUnitedService + ":name";
 static const std::string kMode = kTagUnitedService + ":mode";
 static const std::string kType = kTagUnitedService + ":type";
 static const std::string kPath = kTagUnitedService + ":path";
+static const std::string kPriority = kTagUnitedService + ":priority";
 
 }  // namespace
 
@@ -46,6 +48,17 @@ ServiceInfo::ServiceInfo(std::string conf_name,
   _D("Type=%s", type_.c_str());
   path_ = dictionary->Get(kPath);
   _D("Path=%s", path_.c_str());
+
+  try {
+    priority_ = stoul(dictionary->Get(kPriority));
+    _D("Priority=%d", priority_);
+
+    if (priority_ < 1 || priority_ > 99)
+      priority_ = 0;
+  } catch (const Exception& e) {
+    _E("Failed to get priority : %s", e.what());
+    priority_ = 0;
+  }
 }
 
 ServiceInfo::~ServiceInfo() {}
@@ -62,4 +75,6 @@ const std::string& ServiceInfo::GetType() const { return type_; }
 
 const std::string& ServiceInfo::GetPath() const { return path_; }
 
+const unsigned int ServiceInfo::GetPriority() const { return priority_; }
+
 }  // namespace tizen_base
index 3a6baa8b821b385d9731cdf76565376211057ad6..d91225405768790b37f545e700fc9876fc1e5524 100644 (file)
@@ -35,6 +35,7 @@ class ServiceInfo {
   const std::string& GetMode() const;
   const std::string& GetType() const;
   const std::string& GetPath() const;
+  const unsigned int GetPriority() const;
 
  private:
   std::string conf_name_;
@@ -43,6 +44,7 @@ class ServiceInfo {
   std::string mode_;
   std::string type_;
   std::string path_;
+  unsigned int priority_;
 };
 
 }  // namespace tizen_base
index 95f00077963204a0ef9e891ce2cc6085f6f5ee94..86a64e4dea51aafa1f2986c853449ec057f91095 100644 (file)
@@ -19,6 +19,7 @@
 #include <tizen_core.h>
 #include <tizen_core_channel.h>
 
+#include <algorithm>
 #include <filesystem>
 #include <utility>
 
@@ -31,6 +32,31 @@ namespace {
 constexpr const char kPathUnitedService[] = "/usr/share/united-service/";
 constexpr const char kConf[] = "/conf/";
 
+bool compare_context(const std::shared_ptr<tizen_base::ServiceContext>& context1,
+    const std::shared_ptr<tizen_base::ServiceContext>& context2) {
+  return context1->GetPriority() > context2->GetPriority();
+}
+
+void PrintState(const std::shared_ptr<tizen_base::ServiceContext>& context) {
+  switch(context->GetService()->GetState()) {
+    case tizen_base::Service::State::Initialized:
+      _W("%s : state Initialized", context->GetService()->GetName().c_str());
+      break;
+    case tizen_base::Service::State::Created:
+      _W("%s : state Created", context->GetService()->GetName().c_str());
+        break;
+    case tizen_base::Service::State::Running:
+      _W("%s : state Running", context->GetService()->GetName().c_str());
+        break;
+    case tizen_base::Service::State::Destroyed:
+      _W("%s : state Destroyed", context->GetService()->GetName().c_str());
+        break;
+    default:
+      _W("invalid state");
+      break;
+  }
+}
+
 }  // namespace
 
 namespace tizen_base {
@@ -109,11 +135,54 @@ void ServiceLoader::LoadServices() {
         auto info =
             std::make_shared<ServiceInfo>(file.string(), std::move(dictionary));
         auto context = std::make_shared<ServiceContext>(std::move(info));
-        context->Init();
+        // context->Init();
         contexts_.push_back(std::move(context));
       }
     }
   }
+
+  if (!contexts_.empty())
+    std::sort(contexts_.begin(), contexts_.end(), compare_context);
+}
+
+void ServiceLoader::RunServices() {
+  unsigned int previous_priority = 0;
+  std::shared_ptr<ServiceContext> previous_service = nullptr;
+
+  for (auto& context : contexts_) {
+    if (context->GetServiceInfo()->GetMode().compare("on-demand") == 0) {
+      _W("%s is on-demand mode. it's skipped to run", context->GetName().c_str());
+      continue;
+    }
+
+    if (previous_priority == 0)
+      previous_priority = context->GetPriority();
+
+    if (previous_priority == context->GetPriority()) {
+      _E("@@ Priority : %d, pre-priority : %d,  name : %s", context->GetPriority(), previous_priority, context->GetName().c_str());
+      context->Run();
+
+      PrintState(context);
+
+      previous_service = context;
+    } else {
+      _E("@@ Priority : %d, pre-priority : %d,  name : %s", context->GetPriority(), previous_priority, context->GetName().c_str());
+      previous_service->GetService()->WaitRun();
+
+      _E("@@ Previous state");
+      PrintState(previous_service);
+
+      context->Run();
+
+      _E("@@ Current state");
+      PrintState(context);
+
+      previous_service = context;
+      previous_priority = context->GetPriority();
+    }
+  }
+
+  // throw new std::runtime_error("Failed to Run service");
 }
 
 int ServiceLoader::Run() {
@@ -148,6 +217,8 @@ void ServiceLoader::SendMessage(const tizen_base::Bundle& envelope) {
 void ServiceLoader::OnCreate() {
   try {
     LoadServices();
+
+    RunServices();
   } catch (const fs::filesystem_error& e) {
     _E("Exception occurs. error: %s(%d)", e.what(), e.code().value());
   } catch (const Exception& e) {
index a4bc63df5b4103d67a1bc6536f0b09863ea1ed92..4dab542c62b14ace26e9eee4db1098841d2e314b 100644 (file)
@@ -20,6 +20,7 @@
 #include <memory>
 #include <string>
 
+#include "service.hh"
 #include "service_context.hh"
 #include "service_info.hh"
 
@@ -43,6 +44,7 @@ class ServiceLoader {
   bool Init();
   void Shutdown();
   void LoadServices();
+  void RunServices();
   static void ChannelReceiveCb(tizen_core_channel_object_h object,
                                void* user_data);