Handle SIGCHLD event for process-pool
authorHwankyu Jhun <h.jhun@samsung.com>
Wed, 20 Dec 2023 02:23:18 +0000 (11:23 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Wed, 20 Dec 2023 03:57:14 +0000 (12:57 +0900)
If the process pool is terminated, the launchpad should remove
the process information. And, if sending the request to the process pool
is failed, the launchpad must create a new process to execute an application.

Change-Id: I1d5096394593fe3db92fbd125f468bd9b73c498f
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
src/launchpad-process-pool/app_executor.cc
src/launchpad-process-pool/app_executor.hh
src/launchpad-process-pool/launchpad.cc
src/launchpad-process-pool/loader_executor.cc
src/launchpad-process-pool/loader_executor.hh
src/launchpad-process-pool/loader_manager.cc
src/launchpad-process-pool/process_pool.cc
src/launchpad-process-pool/process_pool.hh

index 06dda58c675fa75c37c5c4ee355745ae7f64cf13..afb2e94e20e536547dd8c7e8a64689000a2aeaf5 100644 (file)
@@ -99,7 +99,9 @@ pid_t AppExecutor::Execute(const AppInfo* app_info) {
   if (process_pool_->IsPrepared()) {
     tizen_base::Parcel parcel;
     parcel.WriteParcelable(*app_info);
-    return process_pool_->Execute(parcel);
+    pid_t pid = process_pool_->Execute(parcel);
+    if (pid > 0)
+      return pid;
   }
 
   app_info_ = app_info;
@@ -111,6 +113,10 @@ void AppExecutor::DisposeCandidateProcess() {
   process_pool_->SetTimer();
 }
 
+void AppExecutor::HandleSigchld(pid_t pid) {
+  process_pool_->HandleSigchld(pid);
+}
+
 void AppExecutor::OnExecution() {
   UserTracer::Print(std::to_string(getpid()) + "|after calling fork(). " +
       app_info_->GetAppId());
index 94b23fad7358cd8fa403577084437ab99ee0a3bb..7fd168e9346bc1fc620bb567fcafc80c237c4ae2 100644 (file)
@@ -40,6 +40,7 @@ class AppExecutor : public Executor::Delegator,
 
   pid_t Execute(const AppInfo* app_info);
   void DisposeCandidateProcess();
+  void HandleSigchld(pid_t pid);
 
  private:
   void OnExecution() override;
index 1562f1560afa08825c29121b3cba6c02443dc9a8..c12f04a4631f80464dca6e6203151fdf46c02de3 100644 (file)
@@ -687,6 +687,7 @@ void Launchpad::OnSigchldReceived(pid_t pid) {
 
   launchpad::Log::Print("[SIGCHLD]", "pid(%7d)", pid);
   LoaderManager::GetInst().HandleSigchld(pid);
+  app_executor_->HandleSigchld(pid);
 }
 
 void Launchpad::OnLoaderPrepared(LoaderContext* loader_context) {
index be307ec0ff8a3293b0350264a307f97c2fc58b7a..1a23a670499b814dacba33719db73438bf55c9aa 100644 (file)
@@ -70,7 +70,9 @@ pid_t LoaderExecutor::Execute(const LoaderContext* loader_context,
     b.Add("LOADER_ARGS", loader_argv_);
     b.Add("LOADER_PRIORITY", std::to_string(priority));
     auto parcel = CreateParcelFromBundle(&b);
-    return process_pool_->Execute(parcel);
+    pid_t pid = process_pool_->Execute(parcel);
+    if (pid > 0)
+      return pid;
   }
 
   return Executor::Execute(priority);
@@ -85,6 +87,10 @@ void LoaderExecutor::DisposeCandidateProcess() {
   process_pool_->SetTimer();
 }
 
+void LoaderExecutor::HandleSigchld(pid_t pid) {
+  process_pool_->HandleSigchld(pid);
+}
+
 void LoaderExecutor::OnExecution() {
   std::vector<char*> loader_argv(loader_argv_.size() + 1);
   int loader_argc = loader_argv_.size();
index 110ffef3f19ed206b87fed70b9350dd09d559577..9a7c7080f1583ee39f403174c326ba8bf7809649 100644 (file)
@@ -17,6 +17,8 @@
 #ifndef LAUNCHPAD_PROCESS_POOL_LOADER_EXECUTOR_HH_
 #define LAUNCHPAD_PROCESS_POOL_LOADER_EXECUTOR_HH_
 
+#include <sys/types.h>
+
 #include <memory>
 #include <string>
 #include <vector>
@@ -41,6 +43,7 @@ class LoaderExecutor : public Executor::Delegator,
   pid_t Execute(const LoaderContext* loader_context, int priority);
   bool HasCandidateProcess() const;
   void DisposeCandidateProcess();
+  void HandleSigchld(pid_t pid);
 
  private:
   LoaderExecutor();
index 4ddee1c926f6cd579a666bad14e02571add9360d..472d556879d2789cd93865e2d1ae414bce38cb7d 100644 (file)
@@ -93,6 +93,7 @@ void LoaderManager::HandleSigchld(pid_t pid) {
   }
 
   RemoveLoaderContextsByCallerPid(pid);
+  LoaderExecutor::GetInst().HandleSigchld(pid);
 }
 
 void LoaderManager::AddDefaultLoaderContexts() {
index 82456cc9798b3c8093d1eda56380833a4f9393a3..81a5c05b17d70d9d61cc5ca9d38f629d1b7c27ea 100644 (file)
@@ -102,22 +102,38 @@ pid_t ProcessPool::Execute(const tizen_base::Parcel& parcel) {
     return -1;
 
   auto process = std::move(queue_.front());
-  queue_.pop();
-  process->Send(parcel);
+  queue_.erase(queue_.begin());
+  if (process->Send(parcel) < 0)
+    return -1;
+
   return process->GetPid();
 }
 
 void ProcessPool::Dispose() {
-  while (!queue_.empty()) {
-    auto process = std::move(queue_.front());
-    queue_.pop();
+  for (auto& process : queue_) {
     process->Kill();
     _D("Kill process(%d)", process->GetPid());
   }
-
+  queue_.clear();
   UnsetTimer();
 }
 
+void ProcessPool::HandleSigchld(pid_t pid) {
+  auto iter = queue_.begin();
+  while (iter != queue_.end()) {
+    if ((*iter)->GetPid() == pid) {
+      iter = queue_.erase(iter);
+      break;
+    }
+
+    iter++;
+  }
+
+  int current_process_count = static_cast<int>(queue_.size());
+  if (current_process_count != num_processes_)
+    SetTimer();
+}
+
 ProcessPool::Process::Process(pid_t pid, int fd)
     : pid_(pid), socket_(new Socket(fd)) {
 }
@@ -186,7 +202,7 @@ void ProcessPool::PrepareProcess() {
     }
 
     close(pipe_fd_[0]);
-    queue_.push(std::make_shared<Process>(pid, pipe_fd_[1]));
+    queue_.push_back(std::make_shared<Process>(pid, pipe_fd_[1]));
   }
 }
 
index d38e327271b2a693d70e31c8ac9f574cb2f56534..7d159c2c3e255ddf7347d6acfd8e2d2c54a9f31f 100644 (file)
@@ -20,7 +20,6 @@
 #include <glib.h>
 #include <sys/types.h>
 
-#include <queue>
 #include <memory>
 #include <string>
 #include <vector>
@@ -48,6 +47,7 @@ class ProcessPool : public Executor::Delegator,
   bool IsPrepared() const;
   pid_t Execute(const tizen_base::Parcel& parcel);
   void Dispose();
+  void HandleSigchld(pid_t pid);
   void SetTimer();
 
  private:
@@ -75,7 +75,7 @@ class ProcessPool : public Executor::Delegator,
   int num_processes_;
   IEvent* event_listener_;
   int pipe_fd_[2] = { -1, -1 };
-  std::queue<std::shared_ptr<Process>> queue_;
+  std::vector<std::shared_ptr<Process>> queue_;
   guint timer_ = 0;
 };