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;
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());
pid_t Execute(const AppInfo* app_info);
void DisposeCandidateProcess();
+ void HandleSigchld(pid_t pid);
private:
void OnExecution() override;
launchpad::Log::Print("[SIGCHLD]", "pid(%7d)", pid);
LoaderManager::GetInst().HandleSigchld(pid);
+ app_executor_->HandleSigchld(pid);
}
void Launchpad::OnLoaderPrepared(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);
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();
#ifndef LAUNCHPAD_PROCESS_POOL_LOADER_EXECUTOR_HH_
#define LAUNCHPAD_PROCESS_POOL_LOADER_EXECUTOR_HH_
+#include <sys/types.h>
+
#include <memory>
#include <string>
#include <vector>
pid_t Execute(const LoaderContext* loader_context, int priority);
bool HasCandidateProcess() const;
void DisposeCandidateProcess();
+ void HandleSigchld(pid_t pid);
private:
LoaderExecutor();
}
RemoveLoaderContextsByCallerPid(pid);
+ LoaderExecutor::GetInst().HandleSigchld(pid);
}
void LoaderManager::AddDefaultLoaderContexts() {
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)) {
}
}
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]));
}
}
#include <glib.h>
#include <sys/types.h>
-#include <queue>
#include <memory>
#include <string>
#include <vector>
bool IsPrepared() const;
pid_t Execute(const tizen_base::Parcel& parcel);
void Dispose();
+ void HandleSigchld(pid_t pid);
void SetTimer();
private:
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;
};