Add a new option to the loader configuration 94/289294/3
authorHwankyu Jhun <h.jhun@samsung.com>
Mon, 6 Mar 2023 04:01:23 +0000 (04:01 +0000)
committerHwankyu Jhun <h.jhun@samsung.com>
Mon, 6 Mar 2023 05:42:29 +0000 (05:42 +0000)
The "CONDITION_PATH_EXISTS" option is added to the loader configuration.
The option is for the "ON_BOOT_TIMEOUT" option. If the path does not exist,
the launchpad does not prepare the candidate process. And, the launchpad
adds a timer to wait until the path exists. The interval of the timer is 100 ms.

Change-Id: I626b25ef8448079bd7fba90f76e7815a2934574b
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
src/launchpad-process-pool/launchpad.cc
src/launchpad-process-pool/loader_info.cc
src/launchpad-process-pool/loader_info.hh
src/launchpad-process-pool/slot_info.h
tests/launchpad-process-pool-unittest/src/test_launchpad.cc

index 71a67df..9a7b293 100644 (file)
@@ -132,6 +132,7 @@ typedef struct {
   int on_boot_timeout;
   guint on_boot_timer;
   int sched_priority;
+  std::vector<std::string> condition_path_exists;
 } candidate_process_context_t;
 
 typedef struct {
@@ -1830,6 +1831,19 @@ static gboolean __on_boot_timeout_cb(gpointer user_data) {
     _E("Candidate process is already running. %d:%s:%d", context->type,
        context->loader_name, context->pid);
   } else {
+    auto iter = context->condition_path_exists.begin();
+    while (iter != context->condition_path_exists.end()) {
+      auto& path = *iter;
+      if (access(path.c_str(), F_OK) != 0) {
+        _D("%s does not exist", path.c_str());
+        context->on_boot_timer = g_timeout_add(100, __on_boot_timeout_cb,
+            context);
+        return G_SOURCE_REMOVE;
+      }
+
+      iter = context->condition_path_exists.erase(iter);
+    }
+
     __prepare_candidate_process(context->type, context->loader_id);
     context->touched = true;
   }
@@ -2585,14 +2599,13 @@ static void __destroy_slot(candidate_process_context_t* cpc) {
   if (cpc->loader_name)
     free(cpc->loader_name);
 
-  free(cpc);
+  delete cpc;
 }
 
 static candidate_process_context_t* __create_slot(slot_info_t* info) {
   candidate_process_context_t* cpc;
 
-  cpc = static_cast<candidate_process_context_t*>(
-      calloc(1, sizeof(candidate_process_context_t)));
+  cpc = new candidate_process_context_t();
   if (cpc == nullptr) {
     _E("Out of memory");
     return nullptr;
@@ -2647,11 +2660,16 @@ static candidate_process_context_t* __create_slot(slot_info_t* info) {
   cpc->live_timer = 0;
   cpc->is_hydra = info->is_hydra;
   cpc->app_check = info->app_check;
+  cpc->client_channel = nullptr;
+  cpc->channel = nullptr;
+  cpc->hydra_channel = nullptr;
   cpc->score = WIN_SCORE;
   cpc->pss = 0;
   cpc->cpu_check_count = 0;
   cpc->on_boot_timeout = info->on_boot_timeout;
+  cpc->on_boot_timer = 0;
   cpc->sched_priority = info->sched_priority;
+  cpc->condition_path_exists = info->condition_path_exists;
 
   if ((cpc->deactivation_method & static_cast<int>(launchpad::LoaderMethod::OutOfMemory)) && __is_low_memory())
     cpc->state = CANDIDATE_PROCESS_STATE_PAUSED;
@@ -2946,7 +2964,6 @@ static void __add_slot_from_info(const launchpad::LoaderInfoPtr& info) {
       0,
   };
 
-  // TODO(changyu.choi): slot_info will be implemented to refer to loader_info
   slot_info_t slot_info = {
     .type = LAUNCHPAD_LOADER_TYPE_USER + user_slot_offset,
     .loader_name = info->GetName().c_str(),
@@ -2957,7 +2974,8 @@ static void __add_slot_from_info(const launchpad::LoaderInfoPtr& info) {
     .is_hydra = info->IsHydraEnabled(),
     .app_check = info->IsNeededAppCheck(),
     .on_boot_timeout = info->GetOnbootTimeout(),
-    .sched_priority = info->GetSchedPriority()
+    .sched_priority = info->GetSchedPriority(),
+    .condition_path_exists = info->GetConditionPathExists()
   };
 
   if (info->GetExe() == "null") {
index 28e2934..465c8a1 100644 (file)
@@ -54,6 +54,7 @@ constexpr const char kTagHydra[] = "HYDRA";
 constexpr const char kTagAppCheck[] = "APP_CHECK";
 constexpr const char kTagOnBootTimeout[] = "ON_BOOT_TIMEOUT";
 constexpr const char kTagSchedPriority[] = "SCHED_PRIORITY";
+constexpr const char kTagConditionPathExists[] = "CONDITION_PATH_EXISTS";
 
 constexpr const char kValOn[] = "ON";
 constexpr const char kValOff[] = "OFF";
@@ -144,6 +145,16 @@ void LoaderInfoInflator::ParseAppTypes(const LoaderInfoPtr& info,
   } while (std::getline(ss, line));
 }
 
+void LoaderInfoInflator::ParseConditionPathExists(const LoaderInfoPtr& info,
+    const std::string& tok_start, std::istringstream& stream) {
+  std::string line = tok_start;
+  do {
+    auto tokens = Split(line, " |\t\r\n");
+    for (auto& token : tokens)
+      info->condition_path_exists_.push_back(std::move(token));
+  } while (std::getline(stream, line));
+}
+
 void LoaderInfoInflator::Parse(std::vector<LoaderInfoPtr>& loader_info_list,
                                const fs::path& path) {
   std::ifstream fp;
@@ -234,6 +245,8 @@ void LoaderInfoInflator::Parse(std::vector<LoaderInfoPtr>& loader_info_list,
       info->on_boot_timeout_ = std::stoi(tok2);
     } else if (kTagSchedPriority == key) {
       info->sched_priority_ = std::min(std::max(std::stoi(tok2), -20), 19);
+    } else if (key == kTagConditionPathExists) {
+      ParseConditionPathExists(info, tok2, ss);
     }
   }
 
@@ -330,6 +343,10 @@ void LoaderInfo::SetAppExists(bool exists) {
   app_exists_ = exists;
 }
 
+const std::vector<std::string>& LoaderInfo::GetConditionPathExists() const {
+  return condition_path_exists_;
+}
+
 std::vector<LoaderInfoPtr> LoaderInfoInflator::Inflate(
     const std::string_view path) {
   fs::path p(path);
index 105aecb..af12572 100644 (file)
@@ -74,6 +74,7 @@ class LoaderInfo {
   tizen_base::Bundle& GetExtra();
   void SetType(LoaderType type);
   void SetAppExists(bool exsits);
+  const std::vector<std::string>& GetConditionPathExists() const;
 
  private:
   LoaderType type_ = LoaderType::Unsupported;
@@ -98,6 +99,7 @@ class LoaderInfo {
   bool app_check_ = true;
   int on_boot_timeout_ = 0;
   int sched_priority_ = 0;
+  std::vector<std::string> condition_path_exists_;
 
   friend class LoaderInfoManager;
   friend class LoaderInfoInflator;
@@ -124,6 +126,8 @@ class LoaderInfoInflator {
   void ParseAppTypes(const LoaderInfoPtr& info,
                      std::string& tok_start,
                      std::istringstream& ss);
+  void ParseConditionPathExists(const LoaderInfoPtr& info,
+      const std::string& tok_start, std::istringstream& stream);
 };
 
 class LoaderInfoManager {
index 58de327..9597fa1 100644 (file)
@@ -19,6 +19,9 @@
 
 #include <stdbool.h>
 
+#include <string>
+#include <vector>
+
 typedef struct slot_info_s {
        int type;
        int loader_id;
@@ -39,6 +42,7 @@ typedef struct slot_info_s {
        bool app_check;
        int on_boot_timeout;
        int sched_priority;
+       std::vector<std::string> condition_path_exists;
 } slot_info_t;
 
 #endif /* __SLOT_INFO_H__ */
index d332ebb..10086da 100644 (file)
@@ -82,6 +82,8 @@ EXTRA_ARRAY_VAL               /test/libcapi-media-camera.so.0
 EXTRA_ARRAY_VAL                /test/ecore_evas/engines/extn/v-1.25/module.so
 ALTERNATIVE_LOADER     common-loader1
 EXTRA   threads   7
+ON_BOOT_TIMEOUT   10000
+CONDITION_PATH_EXISTS   /run/.wm_ready
 )__test";
 
 }  // namespace
@@ -177,9 +179,9 @@ TEST_F(LaunchpadTest, LoaderInfoTest) {
   EXPECT_EQ(info->GetAppTypes()[0], "capp");
   EXPECT_EQ(info->GetAppTypes()[1], "c++app");
   EXPECT_EQ(info->GetHwAcc(), "ON");
-  EXPECT_EQ(info->GetDetectionMethod(), LoaderMethod::Timeout |
-                                            LoaderMethod::Visibility |
-                                            LoaderMethod::Install);
+  EXPECT_EQ(info->GetDetectionMethod(),
+      (LoaderMethod::Timeout | LoaderMethod::Visibility |
+       LoaderMethod::Install));
   EXPECT_EQ(info->GetTimeoutVal(), 5000);
   auto& b = info->GetExtra();
   EXPECT_EQ(b.GetString("loader_type"), "hw-loader");
@@ -195,4 +197,7 @@ TEST_F(LaunchpadTest, LoaderInfoTest) {
   EXPECT_EQ(arr[6], "/test/libcapi-media-player.so.0");
   EXPECT_EQ(arr[7], "/test/libcapi-media-camera.so.0");
   EXPECT_EQ(arr[8], "/test/ecore_evas/engines/extn/v-1.25/module.so");
+
+  EXPECT_EQ(info->GetOnbootTimeout(), 10000);
+  EXPECT_EQ(info->GetConditionPathExists()[0], "/run/.wm_ready");
 }