|
|
|
@ -1,5 +1,6 @@
|
|
|
|
|
#include "runner.hpp"
|
|
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
#include <array>
|
|
|
|
|
#include <cerrno>
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
@ -75,6 +76,12 @@ run_result runner::run_blocking(const program &program) {
|
|
|
|
|
close(out_pipe[1]);
|
|
|
|
|
close(err_pipe[1]);
|
|
|
|
|
|
|
|
|
|
// Register the job as active
|
|
|
|
|
{
|
|
|
|
|
std::lock_guard<std::mutex> guard(active_jobs_mutex);
|
|
|
|
|
active_jobs.push_back(active_job{program.name, pid});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t len = program.code.size();
|
|
|
|
|
size_t window = 0;
|
|
|
|
|
const char *data = program.code.data();
|
|
|
|
@ -128,12 +135,11 @@ run_result runner::run_blocking(const program &program) {
|
|
|
|
|
if (pfds[i].fd == out_pipe[0]) {
|
|
|
|
|
out.append(buffer.data(), bytes_read);
|
|
|
|
|
} else if (pfds[i].fd == timerfd) {
|
|
|
|
|
if (backend == runner_backend::Docker) {
|
|
|
|
|
const char *const kill_args[] = {"docker", "kill", program.name.c_str(), nullptr};
|
|
|
|
|
pid_t kill_pid;
|
|
|
|
|
ensure(posix_spawnp(&kill_pid, kill_args[0], nullptr, nullptr, const_cast<char *const *>(kill_args), nullptr));
|
|
|
|
|
} else {
|
|
|
|
|
ensure(kill(pid, SIGINT));
|
|
|
|
|
std::lock_guard<std::mutex> guard(active_jobs_mutex);
|
|
|
|
|
auto it = std::find_if(active_jobs.begin(), active_jobs.end(), [pid](const active_job &job) { return job.pid == pid; });
|
|
|
|
|
if (it != active_jobs.end()) {
|
|
|
|
|
exit(*it);
|
|
|
|
|
active_jobs.erase(it);
|
|
|
|
|
}
|
|
|
|
|
killed = true;
|
|
|
|
|
} else {
|
|
|
|
@ -154,7 +160,34 @@ run_result runner::run_blocking(const program &program) {
|
|
|
|
|
close(err_pipe[0]);
|
|
|
|
|
close(timerfd);
|
|
|
|
|
|
|
|
|
|
// Remove the job from the active list
|
|
|
|
|
{
|
|
|
|
|
std::lock_guard<std::mutex> guard(active_jobs_mutex);
|
|
|
|
|
auto it = std::find_if(active_jobs.begin(), active_jobs.end(), [pid](const active_job &job) { return job.pid == pid; });
|
|
|
|
|
if (it != active_jobs.end()) {
|
|
|
|
|
active_jobs.erase(it);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
posix_spawn_file_actions_destroy(&actions);
|
|
|
|
|
return run_result{out, err, killed ? 124 : exit_code};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void runner::exit_active_jobs() {
|
|
|
|
|
std::lock_guard<std::mutex> guard(active_jobs_mutex);
|
|
|
|
|
for (const auto &job : active_jobs) {
|
|
|
|
|
exit(job);
|
|
|
|
|
}
|
|
|
|
|
active_jobs.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void runner::exit(const active_job &job) {
|
|
|
|
|
if (backend == runner_backend::Docker) {
|
|
|
|
|
const char *const kill_args[] = {"docker", "kill", job.job_id.c_str(), nullptr};
|
|
|
|
|
pid_t kill_pid;
|
|
|
|
|
ensure(posix_spawnp(&kill_pid, kill_args[0], nullptr, nullptr, const_cast<char *const *>(kill_args), nullptr));
|
|
|
|
|
} else {
|
|
|
|
|
ensure(kill(job.pid, SIGINT));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|