Dispose candidate process of process pool
[platform/core/appfw/launchpad.git] / src / launchpad-process-pool / loader_executor.cc
1 /*
2  * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "launchpad-process-pool/loader_executor.hh"
18
19 #include <errno.h>
20 #include <stdio.h>
21 #include <unistd.h>
22
23 #include <utility>
24
25 #include <parcel.hh>
26
27 #include "launchpad-process-pool/log_private.hh"
28 #include "launchpad-process-pool/signal_manager.hh"
29 #include "lib/common/inc/launchpad_common.h"
30 #include "lib/common/inc/launchpad_types.h"
31
32 namespace launchpad {
33 namespace {
34
35 std::shared_ptr<AppPacket> CreateAppPacketFromArgs(
36     const std::vector<std::string>& args) {
37   tizen_base::Bundle b;
38   b.Add("LOADER_ARGS", args);
39   auto raw = b.ToRaw();
40   std::vector<uint8_t> data(raw.first.get(), raw.first.get() + raw.second);
41   return std::shared_ptr<AppPacket>(new AppPacket(0, 0, std::move(data)));
42 }
43
44 std::vector<std::string> CreateArgsFromAppPacket(const AppPacket* app_packet) {
45   auto& data = app_packet->GetData();
46   std::string raw(data.begin(), data.end());
47   tizen_base::Bundle b(raw);
48   return b.GetStringArray("LOADER_ARGS");
49 }
50
51 }  // namespace
52
53 LoaderExecutor::LoaderExecutor()
54     : Executor(this), process_pool_(new ProcessPool(2, this)) {}
55
56 LoaderExecutor& LoaderExecutor::GetInst() {
57   static LoaderExecutor inst;
58   return inst;
59 }
60
61 pid_t LoaderExecutor::Execute(const LoaderContext* loader_context,
62     int priority) {
63   loader_argv_ = CreateLoaderArgv(loader_context);
64   if (process_pool_->IsPrepared()) {
65     auto app_packet = CreateAppPacketFromArgs(loader_argv_);
66     return process_pool_->Execute(std::move(app_packet));
67   }
68
69   return Executor::Execute(priority);
70 }
71
72 bool LoaderExecutor::HasCandidateProcess() const {
73   return process_pool_->IsPrepared();
74 }
75
76 void LoaderExecutor::DisposeCandidateProcess() {
77   process_pool_->Dispose();
78   process_pool_->SetTimer();
79 }
80
81 void LoaderExecutor::OnExecution() {
82   std::vector<char*> loader_argv(loader_argv_.size() + 1);
83   int loader_argc = loader_argv_.size();
84   for (int i = 0; i < loader_argc; ++i) {
85     loader_argv[i] = const_cast<char*>(loader_argv_[i].c_str());
86     if ((i + 1) != loader_argc)
87       SECURE_LOGD("loader argument %d : %s##", i, loader_argv[i]);
88   }
89
90   SignalManager::GetInst().UnblockSigchld();
91   _close_all_fds();
92   _setup_stdio(basename(loader_argv[LOADER_ARG_PATH]));
93
94   if (execv(loader_argv[LOADER_ARG_PATH], loader_argv.data()) < 0) {
95     char err_buf[1024];
96     fprintf(stderr, "Failed to execute a file. path: %s, errno: %d:%s\n",
97         loader_argv[LOADER_ARG_PATH], errno,
98         strerror_r(errno, err_buf, sizeof(err_buf)));
99     exit(EXIT_FAILURE);
100   }
101 }
102
103 void LoaderExecutor::OnRequestReceived(std::shared_ptr<AppPacket> app_packet) {
104   _W("Request received");
105   loader_argv_ = CreateArgsFromAppPacket(app_packet.get());
106   OnExecution();
107 }
108
109 std::vector<std::string> LoaderExecutor::CreateLoaderArgv(
110     const LoaderContext* loader_context) {
111   std::string dummy(LOADER_ARG_LEN - 1, ' ');
112   std::vector<std::string> argv(LOADER_ARG_DUMMY + 1);
113   argv[LOADER_ARG_DUMMY] = std::move(dummy);
114   argv[LOADER_ARG_PATH] = loader_context->GetLoaderPath();
115   argv[LOADER_ARG_TYPE] = std::to_string(loader_context->GetType());
116   argv[LOADER_ARG_ID] = std::to_string(loader_context->GetLoaderId());
117   argv[LOADER_ARG_HYDRA] = loader_context->IsHydraMode() ? "1" : "0";
118   argv[LOADER_ARG_EXTRA] = loader_context->GetLoaderExtra();
119   return argv;
120 }
121
122 }  // namespace launchpad