Handle SIGCHLD event for process-pool 89/303089/4
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:15:03 +0000 (12:15 +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 06dda58..afb2e94 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 94b23fa..7fd168e 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 1562f15..c12f04a 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 be307ec..1a23a67 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 110ffef..9a7c708 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 4ddee1c..472d556 100644 (file)
@@ -93,6 +93,7 @@ void LoaderManager::HandleSigchld(pid_t pid) {
   }
 
   RemoveLoaderContextsByCallerPid(pid);
+  LoaderExecutor::GetInst().HandleSigchld(pid);
 }
 
 void LoaderManager::AddDefaultLoaderContexts() {
index 82456cc..81a5c05 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 d38e327..7d159c2 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;
 };