2 * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "launchpad-process-pool/launchpad.hh"
19 #include <bundle_internal.h>
22 #include <security-manager.h>
23 #include <sys/prctl.h>
24 #include <systemd/sd-daemon.h>
30 #include <app_info.hh>
31 #include <aul_keys.hh>
32 #include <cpu_boost_controller.hh>
33 #include <exception.hh>
34 #include <executor.hh>
36 #include <sched_priority.hh>
38 #include <user_tracer.hh>
41 #include "launchpad-process-pool/config.hh"
42 #include "launchpad-process-pool/dbus.hh"
43 #include "launchpad-process-pool/debug.hh"
44 #include "launchpad-process-pool/launcher_info.hh"
45 #include "launchpad-process-pool/launchpad_args.hh"
46 #include "launchpad-process-pool/loader_manager.hh"
47 #include "launchpad-process-pool/loader_executor.hh"
48 #include "launchpad-process-pool/log.hh"
49 #include "launchpad-process-pool/log_private.hh"
50 #include "launchpad-process-pool/memory_monitor.hh"
51 #include "launchpad-process-pool/signal_manager.hh"
52 #include "launchpad-process-pool/tracer.hh"
53 #include "launchpad-process-pool/util.hh"
54 #include "launchpad-process-pool/worker.hh"
59 constexpr const char kRunAulDaemonsPath[] = "/run/aul/daemons/";
60 constexpr const char kLaunchpadProcessPoolSock[] =
61 ".launchpad-process-pool-sock";
62 constexpr const char kInfoDirectoryPath[] = "/usr/share/aul";
63 const int kReceivedBufferSize = 131071;
64 const int kMaxPendingConnection = 128;
65 const uid_t kRegularUidMin = 5000;
67 class CleanupInfo : public launchpad::Worker::Job {
69 CleanupInfo(std::string appid, pid_t pid)
70 : appid_(std::move(appid)), pid_(pid) {}
73 _W("security_manager_cleanup_app() ++");
74 security_manager_cleanup_app(appid_.c_str(), getuid(), pid_);
75 _W("security_manager_cleanup_app() --");
83 int GetLaunchpadFdFromSystemd() {
84 const std::string path = kRunAulDaemonsPath + std::to_string(getuid()) +
85 "/" + std::string(kLaunchpadProcessPoolSock);
86 int fds = sd_listen_fds(0);
87 for (int fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + fds; ++fd) {
88 if (sd_is_socket_unix(fd, SOCK_STREAM, 1, path.c_str(), 0) > 0)
92 _W("There is no socket stream");
96 int GetLaunchpadFdFromEnvironment() {
97 auto* value = getenv("LAUNCHPAD_LISTEN_FD");
98 if (value == nullptr || !isdigit(value[0])) {
99 _E("Failed to get launchpad fd");
107 ServerSocket* GetLaunchpadSocket() {
108 int fd = GetLaunchpadFdFromSystemd();
110 fd = GetLaunchpadFdFromEnvironment();
113 return new ServerSocket(fd);
115 auto* socket = new ServerSocket();
116 const std::string endpoint = kRunAulDaemonsPath + std::to_string(getuid()) +
117 "/" + kLaunchpadProcessPoolSock;
118 socket->Bind(endpoint);
119 socket->SetReceiveBufferSize(kReceivedBufferSize);
120 socket->Listen(kMaxPendingConnection);
124 void PrintAppInfo(const AppInfo* app_info) {
125 SECURE_LOGD("appid: %s", app_info->GetAppId().c_str());
126 SECURE_LOGD("app_path: %s", app_info->GetAppPath().c_str());
127 SECURE_LOGD("comp_type: %s", app_info->GetCompType().c_str());
128 SECURE_LOGD("internal pool: %s", app_info->GetInternalPool().c_str());
129 SECURE_LOGD("hwacc: %s", app_info->GetHwacc().c_str());
130 SECURE_LOGD("app_type: %s", app_info->GetAppType().c_str());
131 SECURE_LOGD("pkg_type: %s", app_info->GetPkgType().c_str());
134 int CheckCallerPermission(pid_t caller_pid) {
135 std::string attr_current = Procfs::GetAttrCurrent(caller_pid);
136 if (attr_current.empty())
139 if (attr_current.compare("User") == 0 ||
140 attr_current.compare("System") == 0 ||
141 attr_current.compare("System::Privileged") == 0)
147 int GetLoaderIdFromBundle(const tizen_base::Bundle& b) {
148 auto loader_id = b.GetString(kAulLoaderId);
149 if (loader_id.empty())
152 _W("Requested loader id: %s", loader_id.c_str());
153 return std::stoi(loader_id);
158 Launchpad::Launchpad(int argc, char** argv)
161 loop_(g_main_loop_new(nullptr, FALSE)) {
162 LaunchpadArgs::GetInst().Set(argc_, argv_);
164 { PadCmd::Visibility,
165 std::bind(&Launchpad::HandleVisibilityRequest, this,
166 std::placeholders::_1) },
168 std::bind(&Launchpad::HandleAddLoaderRequest, this,
169 std::placeholders::_1) },
170 { PadCmd::RemoveLoader,
171 std::bind(&Launchpad::HandleRemoveLoaderRequest, this,
172 std::placeholders::_1) },
173 { PadCmd::MakeDefaultSlots,
174 std::bind(&Launchpad::HandleMakeDefaultSlotsRequest, this,
175 std::placeholders::_1) },
176 { PadCmd::PrepareAppDefinedLoader,
177 std::bind(&Launchpad::HandlePrepareAppDefinedLoaderRequest, this,
178 std::placeholders::_1) },
180 std::bind(&Launchpad::HandleDemandRequest, this,
181 std::placeholders::_1) },
183 std::bind(&Launchpad::HandlePingRequest, this,
184 std::placeholders::_1) },
185 { PadCmd::UpdateAppType,
186 std::bind(&Launchpad::HandleUpdateAppTypeRequest, this,
187 std::placeholders::_1) },
189 std::bind(&Launchpad::HandleConnectRequest, this,
190 std::placeholders::_1) },
192 std::bind(&Launchpad::HandleLaunchRequest, this,
193 std::placeholders::_1) },
194 { PadCmd::KillLoader,
195 std::bind(&Launchpad::HandleKillLoaderRequest, this,
196 std::placeholders::_1) },
197 { PadCmd::RestartLoader,
198 std::bind(&Launchpad::HandleRestartLoaderRequest, this,
199 std::placeholders::_1) },
200 { PadCmd::DisposeLoader,
201 std::bind(&Launchpad::HandleDisposeLoaderRequest, this,
202 std::placeholders::_1) },
205 CPUBoostController::Level level;
206 int ret = CPUBoostController::GetBoostLevel(getpid(), &level);
208 CPUBoostController::Clear(getpid());
211 level == CPUBoostController::Level::None ||
212 level == CPUBoostController::Level::Weak) {
213 CPUBoostController::DoBoost(getpid(), CPUBoostController::Level::Strong,
217 g_timeout_add(1000, [](gpointer data) {
218 CPUBoostController::Clear(getpid());
219 return G_SOURCE_REMOVE;
221 mode_ = Config::GetInst().GetLaunchMode().GetMode();
224 Launchpad::~Launchpad() {
225 if (loop_ != nullptr)
226 g_main_loop_unref(loop_);
229 int Launchpad::Run() {
235 #ifdef TIZEN_FEATURE_PRIORITY_CHANGE
239 std::string(__FUNCTION__) + "(" + std::to_string(__LINE__) +
240 "): g_main_loop_run()");
241 g_main_loop_run(loop_);
246 void Launchpad::Quit() {
247 g_main_loop_quit(loop_);
250 bool Launchpad::OnCreate() {
251 UserTracer user_tracer(
252 std::string(__FUNCTION__) + "(" + std::to_string(__LINE__) + ")");
253 launchpad::SignalManager::GetInst().SetEventListener(this);
256 app_executor_.reset(new AppExecutor());
257 socket_.reset(GetLaunchpadSocket());
259 new IOChannel(socket_->GetFd(), IOChannel::IOCondition::IO_IN, this));
260 channel_->SetCloseOnDestroy(false);
261 } catch (const Exception& e) {
262 _E("Exception occurs. error: %s", e.what());
266 cleaner_.reset(new Worker("cleaner+"));
269 LoaderManager::GetInst().AddDefaultLoaderContexts();
270 LoaderManager::GetInst().SetEventListener(this);
271 launchpad::Debug::GetInst().Init();
273 Util::SendCmdToAmd(AmdCmd::LaunchpadLaunchSignal);
274 lang_config_.reset(new LanguageConfig());
275 region_format_config_.reset(new RegionFormatConfig());
281 void Launchpad::OnTerminate() {
283 region_format_config_.reset();
284 lang_config_.reset();
287 Util::SendCmdToAmd(AmdCmd::LaunchpadDeadSignal);
288 Debug::GetInst().Dispose();
292 LoaderManager::GetInst().Dispose();
295 SignalManager::GetInst().Dispose();
298 void Launchpad::HandleVisibilityRequest(std::shared_ptr<Request> request) {
299 LoaderManager::GetInst().ActivateLoaderContexts(LoaderMethod::Visibility);
300 request->SendResult(0);
301 _W("[PAD_CMD_VISIBILITY]");
304 void Launchpad::HandleAddLoaderRequest(std::shared_ptr<Request> request) {
305 auto context = LoaderManager::GetInst().AddLoaderContext(
306 request->GetBundle());
307 if (context == nullptr) {
308 request->SendResult(-1);
309 _W("[PAD_CMD_ADD_LOADER] Can not add loader context");
313 request->SendResult(context->GetLoaderId());
314 _W("[PAD_CMD_ADD_LOADER]");
317 void Launchpad::HandleRemoveLoaderRequest(std::shared_ptr<Request> request) {
318 auto& b = request->GetBundle();
319 auto loader_id_str = b.GetString(kAulLoaderId);
320 if (loader_id_str.empty()) {
321 _E("Failed to get loader id");
322 request->SendResult(-1);
326 LoaderManager::GetInst().RemoveLoaderContext(LoaderType::Dynamic,
327 std::stoi(loader_id_str));
328 request->SendResult(0);
329 _W("[PAD_CMD_REMOVE_LOADER]");
332 void Launchpad::HandleMakeDefaultSlotsRequest(
333 std::shared_ptr<Request> request) {
334 LoaderManager::GetInst().AddDefaultLoaderContexts();
335 _W("[PAD_CMD_MAKE_DEFAULT_SLOTS]");
338 void Launchpad::HandlePrepareAppDefinedLoaderRequest(
339 std::shared_ptr<Request> request) {
340 auto& b = request->GetBundle();
341 auto loader_name = b.GetString(kAulLoaderName);
342 if (loader_name.empty()) {
343 _E("Failed to get loader name");
344 request->SendResult(-EINVAL);
348 auto context = LoaderManager::GetInst().PrepareAppDefinedLoaderContext(
349 loader_name, request->GetCallerPid());
350 if (context == nullptr) {
351 request->SendResult(-EINVAL);
355 request->SendResult(context->GetLoaderId());
356 _W("[PAD_CMD_PREPARE_APP_DEFINED_LOADER] result: %d", context->GetLoaderId());
359 void Launchpad::HandleDemandRequest(std::shared_ptr<Request> request) {
360 LoaderManager::GetInst().ActivateLoaderContexts(LoaderMethod::Demand);
361 request->SendResult(0);
362 _W("[PAD_CMD_DEMAND]");
365 void Launchpad::HandlePingRequest(std::shared_ptr<Request> request) {
366 request->SendResult(getpid());
367 _W("[PAD_CMD_PING]");
370 void Launchpad::HandleUpdateAppTypeRequest(std::shared_ptr<Request> request) {
371 auto& b = request->GetBundle();
372 auto app_type = b.GetString(kAulAppType);
373 if (app_type.empty()) {
374 _E("Failed to get app type");
378 auto installed = b.GetString(kAulIsInstalled);
379 _I("type: %s, installed: %s", app_type.c_str(), installed.c_str());
380 bool app_installed = (installed == "true") ? true : false;
381 LoaderManager::GetInst().UpdateAppInstallationStatus(app_type, app_installed);
382 _W("[PAD_CMD_UPDATE_APP_TYPE]");
385 void Launchpad::HandleConnectRequest(std::shared_ptr<Request> request) {
386 client_socket_.reset(
387 new ClientSocket(request->GetClientSocket()->RemoveFd()));
388 _W("[PAD_CMD_CONNECT] client fd: %d", client_socket_->GetFd());
391 bool Launchpad::CanUseLoaderContext(
392 const std::shared_ptr<LoaderContext>& context) {
393 if (context->IsPrepared())
396 if (mode_ == Config::LaunchMode::Mode::PreviousOperation)
399 if (mode_ == Config::LaunchMode::Mode::DefaultOperation) {
400 if (context->IsHydraMode())
403 return context->GetPid() > 0 && context->RefCount() == 0;
406 // Config::LaunchMode::Mode::AlwaysLoader
407 // Config::LaunchMode::Mode::AlwaysLoaderWithoutCPUChecker
408 // Config::LaunchMode::Mode::AlwaysLoaderWithLowPriority
409 if (context->GetPid() > 0)
412 return context->IsLaunchable();
415 Launchpad::LaunchResult Launchpad::LaunchRequestPrepare(
416 std::shared_ptr<Request> request) {
417 auto* app_info = AppInfo::Create(request->GetBundle());
418 if (app_info == nullptr) {
419 _E("Failed to create AppInfo");
420 return LaunchResult::Fail;
423 request->SetAppInfo(std::unique_ptr<AppInfo>(app_info));
424 if (app_info->GetAppPath().empty()) {
425 _E("AppPath is empty");
426 return LaunchResult::Fail;
429 PrintAppInfo(app_info);
431 auto& loader_manager = LoaderManager::GetInst();
432 auto& comp_type = app_info->GetCompType();
433 if (comp_type == "svcapp") {
434 request->SetLoaderId(GetLoaderIdFromBundle(request->GetBundle()));
435 if (request->GetLoaderId() > PadLoaderId::DynamicBase) {
436 auto context = loader_manager.FindLoaderContext(LoaderType::Dynamic,
437 request->GetLoaderId());
438 if (context != nullptr && CanUseLoaderContext(context))
439 request->SetAvailableLoaderContext(std::move(context));
441 request->SetLoaderId(PadLoaderId::Direct);
443 } else if (comp_type == "widget" && app_info->GetAppType() == "webapp") {
444 request->SetLoaderId(PadLoaderId::Direct);
446 request->SetLoaderId(GetLoaderIdFromBundle(request->GetBundle()));
447 if (request->GetLoaderId() <= PadLoaderId::Static) {
448 auto context = loader_manager.FindAvailableLoaderContext(
449 app_info->GetHwacc(), app_info->GetAppType(),
450 app_info->GetLoaderName());
451 if (context != nullptr) {
452 request->SetLoaderContext(context);
453 if (CanUseLoaderContext(context)) {
454 request->SetAvailableLoaderContext(std::move(context));
456 auto alt_context = loader_manager.FindAlternativeLoaderContext(
457 static_cast<LoaderType>(context->GetType()));
458 if (alt_context != nullptr && CanUseLoaderContext(alt_context))
459 request->SetAvailableLoaderContext(std::move(alt_context));
463 auto context = loader_manager.FindLoaderContext(LoaderType::Dynamic,
464 request->GetLoaderId());
465 if (context != nullptr && CanUseLoaderContext(context))
466 request->SetAvailableLoaderContext(std::move(context));
470 return LaunchResult::Success;
473 Launchpad::LaunchResult Launchpad::ForkProcessing(
474 std::shared_ptr<Request> request) {
475 if (request->GetBundle().GetType(kAulSdk) != BUNDLE_TYPE_NONE) {
476 if (Debug::GetInst().Load())
477 app_executor_->DisposeCandidateProcess();
480 _W("appid: %s", request->GetAppInfo()->GetAppId().c_str());
481 request->SetPid(app_executor_->Execute(request->GetAppInfo()));
482 if (request->GetPid() == -1) {
483 _E("Failed to create a child process. appid: %s",
484 request->GetAppInfo()->GetAppId().c_str());
487 request->SendResult(request->GetPid());
488 _W("appid: %s, pid: %d",
489 request->GetAppInfo()->GetAppId().c_str(), request->GetPid());
490 LoaderManager::GetInst().HandleDirectLaunch(
491 std::move(request->GetLoaderContext()));
492 if (request->GetPid() == -1)
493 return LaunchResult::Fail;
495 return LaunchResult::Success;
498 Launchpad::LaunchResult Launchpad::LaunchRequestPend(
499 std::shared_ptr<Request> request) {
500 auto loader_context = request->GetAvailableLoaderContext();
501 if (loader_context->IsPrepared()) {
502 if (mode_ == Config::LaunchMode::Mode::AlwaysLoaderWithLowPriority)
503 SchedPriority::Set(loader_context->GetPid(), 0);
505 return LaunchResult::Continue;
508 _W("Loader context is not prepared");
509 loader_context->Ref();
510 if (loader_context->GetPid() <= 0)
511 loader_context->Prepare();
513 if (loader_context->GetPid() > 0) {
514 CPUBoostController::DoBoost(loader_context->GetPid(),
515 CPUBoostController::Level::Strong, 10000);
516 _W("Send result: %d", loader_context->GetPid());
517 request->SetPid(loader_context->GetPid());
518 request->SendResult(loader_context->GetPid());
521 pending_requests_.push_back(std::move(request));
522 return LaunchResult::Pending;
525 Launchpad::LaunchResult Launchpad::LaunchRequestDo(
526 std::shared_ptr<Request> request) {
527 auto loader_context = request->GetAvailableLoaderContext();
528 if (request->GetLoaderId() == PadLoaderId::Direct ||
529 loader_context == nullptr ||
530 launchpad::Debug::GetInst().CheckAsanApp(
531 request->GetAppInfo()->GetAppId())) {
532 return ForkProcessing(request);
535 if (LaunchRequestPend(request) == LaunchResult::Pending)
536 return LaunchResult::Pending;
538 auto* app_info = request->GetAppInfo();
539 _W("Launch %d type process. appid: %s",
540 static_cast<int>(loader_context->GetType()),
541 app_info->GetAppId().c_str());
542 request->SetPid(loader_context->Deploy(app_info));
544 if ((mode_ == Config::LaunchMode::Mode::AlwaysLoaderWithoutCPUChecker) ||
545 (mode_ == Config::LaunchMode::Mode::AlwaysLoaderWithLowPriority) ||
546 (mode_ == Config::LaunchMode::Mode::AlwaysLoader &&
547 loader_context->RefCount() > 0))
548 loader_context->Prepare();
550 return LaunchResult::Success;
553 void Launchpad::LaunchRequestComplete(std::shared_ptr<Request> request) {
554 MemoryMonitor::GetInst().Reset();
555 request->SendResult(request->GetPid());
557 if (request->GetPid() > 0) {
558 auto* app_info = request->GetAppInfo();
559 launchpad::DBus::SendAppLaunchSignal(request->GetPid(),
560 app_info->GetAppId().c_str());
561 pid_map_[request->GetPid()] = app_info->GetAppId();
562 launchpad::Log::Print("[LAUNCH]", "pid(%7d) | appid(%s)",
563 request->GetPid(), app_info->GetAppId().c_str());
567 void Launchpad::HandleLaunchRequest(std::shared_ptr<Request> request) {
568 Tracer tracer("LAUNCHPAD:LAUNCH");
569 if (LaunchRequestPrepare(request) == LaunchResult::Fail) {
570 request->SendResult(-1);
574 if (LaunchRequestDo(request) == LaunchResult::Pending)
577 LaunchRequestComplete(request);
578 _W("[PAD_CMD_LAUNCH] appid: %s, result: %d",
579 request->GetAppInfo()->GetAppId().c_str(), request->GetPid());
582 void Launchpad::HandleKillLoaderRequest(std::shared_ptr<Request> request) {
583 auto& b = request->GetBundle();
584 auto loader_name = b.GetString(kAulLoaderName);
585 auto loader_context =
586 LoaderManager::GetInst().FindLoaderContextFromName(loader_name);
587 if (loader_context == nullptr) {
588 _E("Failed to find loader context. loader_name(%s)", loader_name.c_str());
592 if (loader_context->RefCount() == 0)
593 loader_context->Dispose();
595 _W("[PAD_CMD_KILL_LOADER] loader_name: %s", loader_name.c_str());
598 void Launchpad::HandleRestartLoaderRequest(std::shared_ptr<Request> request) {
599 auto& b = request->GetBundle();
600 auto loader_name = b.GetString(kAulLoaderName);
601 auto loader_context =
602 LoaderManager::GetInst().FindLoaderContextFromName(loader_name);
603 if (loader_context == nullptr) {
604 _E("Failed to find loader context. loader_name(%s)", loader_name.c_str());
608 if (loader_context->RefCount() == 0)
609 loader_context->Dispose();
611 if (loader_context->GetPid() < 1)
612 loader_context->Prepare();
614 _W("[PAD_CMD_RESTART_LOADER] loader_name: %s, pid: %d",
615 loader_name.c_str(), loader_context->GetPid());
618 void Launchpad::HandleDisposeLoaderRequest(std::shared_ptr<Request> request) {
619 pid_t caller_pid = request->GetCallerPid();
620 auto loader_context =
621 LoaderManager::GetInst().FindLoaderContextFromPid(caller_pid);
622 if (loader_context == nullptr) {
623 _E("Failed to find loader context. pid(%d)", caller_pid);
627 loader_context->Dispose();
628 _W("[PAD_CMD_DISPOSE_LOADER] loader_name: %s, pid: %d",
629 loader_context->GetLoaderName().c_str(), caller_pid);
632 void Launchpad::OnIOEventReceived(int fd, int condition) {
633 auto client_socket = socket_->Accept();
634 if (!client_socket) {
635 _E("Failed to accept the client request");
640 auto request = std::make_shared<Request>(std::move(client_socket));
641 _W("cmd(%d), caller(%d)", request->GetCmd(), request->GetCallerPid());
642 if (request->GetCallerUid() >= kRegularUidMin) {
643 if (CheckCallerPermission(request->GetCallerPid()) < 0) {
644 _E("Permission denied. pid(%d)", request->GetCallerPid());
645 request->SendResult(-EPERM);
650 auto found = handlers_.find(request->GetCmd());
651 if (found == handlers_.end()) {
652 _E("Unknown command: %d", request->GetCmd());
653 request->SendResult(-EINVAL);
657 auto method_handler = found->second;
658 method_handler(std::move(request));
659 } catch (const Exception& e) {
660 _E("Exception occurs. error(%s)", e.what());
664 void Launchpad::OnSigchldReceived(pid_t pid) {
665 auto found = pid_map_.find(pid);
666 if (found != pid_map_.end()) {
667 auto appid = found->second;
668 cleaner_->Add(std::make_shared<CleanupInfo>(std::move(appid), pid));
669 pid_map_.erase(found);
672 auto iter = pending_requests_.begin();
673 while (iter != pending_requests_.end()) {
674 auto request = *iter;
675 auto context = request->GetAvailableLoaderContext();
676 if (context != nullptr && request->GetPid() == pid) {
678 auto* app_info = request->GetAppInfo();
679 launchpad::DBus::SendAppLaunchSignal(request->GetPid(),
680 app_info->GetAppId().c_str());
681 pending_requests_.erase(iter);
688 launchpad::Log::Print("[SIGCHLD]", "pid(%7d)", pid);
689 LoaderManager::GetInst().HandleSigchld(pid);
692 void Launchpad::OnLoaderPrepared(LoaderContext* loader_context) {
693 _W("Loader is prepared. name(%s), pid(%d)",
694 loader_context->GetLoaderName().c_str(), loader_context->GetPid());
695 if (loader_context->RefCount() == 0)
698 auto iter = pending_requests_.begin();
699 while (iter != pending_requests_.end()) {
700 auto request = *iter;
701 auto context = request->GetAvailableLoaderContext();
702 if (context != nullptr && context.get() == loader_context) {
703 loader_context->Unref();
704 pending_requests_.erase(iter);
705 LaunchRequestDo(request);
706 LaunchRequestComplete(request);
714 void Launchpad::OnLoaderLaunched(LoaderContext* loader_context) {
715 _W("Loader is launched. name(%s), pid(%d)",
716 loader_context->GetLoaderName().c_str(), loader_context->GetPid());
717 if (loader_context->RefCount() == 0) {
718 if (mode_ == Config::LaunchMode::Mode::AlwaysLoaderWithLowPriority)
719 SchedPriority::Set(loader_context->GetPid(), 19);
724 for (auto& request : pending_requests_) {
725 auto context = request->GetAvailableLoaderContext();
726 if (context != nullptr && context.get() == loader_context) {
727 request->SendResult(loader_context->GetPid());
733 } // namespace launchpad
735 int main(int argc, char** argv) {
736 launchpad::UserTracer tracer(
737 std::string(__FUNCTION__) + "(" + std::to_string(__LINE__) + ")");
738 prctl(PR_SET_CHILD_SUBREAPER, 1, 0, 0, 0);
739 launchpad::Launchpad launchpad(argc, argv);
740 return launchpad.Run();