#include <dds/proc.hpp> | #include <dds/proc.hpp> | ||||
#include <dds/util/algo.hpp> | #include <dds/util/algo.hpp> | ||||
#include <dds/util/signal.hpp> | |||||
#include <spdlog/spdlog.h> | #include <spdlog/spdlog.h> | ||||
lk.unlock(); | lk.unlock(); | ||||
try { | try { | ||||
compilation.compile(tc); | compilation.compile(tc); | ||||
cancellation_point(); | |||||
} catch (...) { | } catch (...) { | ||||
lk.lock(); | lk.lock(); | ||||
exceptions.push_back(std::current_exception()); | exceptions.push_back(std::current_exception()); |
return 1; | return 1; | ||||
} | } | ||||
dds::install_signal_handlers(); | |||||
try { | try { | ||||
if (build.cmd) { | if (build.cmd) { | ||||
return build.run(); | return build.run(); |
#ifndef _WIN32 | #ifndef _WIN32 | ||||
#include "./proc.hpp" | #include "./proc.hpp" | ||||
#include <dds/util/signal.hpp> | |||||
#include <spdlog/fmt/fmt.h> | #include <spdlog/fmt/fmt.h> | ||||
#include <poll.h> | #include <poll.h> | ||||
while (true) { | while (true) { | ||||
rc = ::poll(&stdio_fd, 1, -1); | rc = ::poll(&stdio_fd, 1, -1); | ||||
if (rc && errno == EINTR) { | |||||
errno = 0; | |||||
continue; | |||||
} | |||||
check_rc(rc > 0, "Failed in poll()"); | check_rc(rc > 0, "Failed in poll()"); | ||||
std::string buffer; | std::string buffer; | ||||
buffer.resize(1024); | buffer.resize(1024); | ||||
} else if (WIFSIGNALED(status)) { | } else if (WIFSIGNALED(status)) { | ||||
res.signal = WTERMSIG(status); | res.signal = WTERMSIG(status); | ||||
} | } | ||||
cancellation_point(); | |||||
return res; | return res; | ||||
} | } | ||||
#include "./signal.hpp" | |||||
#include <csignal> | |||||
namespace { | |||||
std::sig_atomic_t got_signal = 0; | |||||
void handle_signal(int sig) { got_signal = sig; } | |||||
} // namespace | |||||
using namespace dds; | |||||
void dds::notify_cancel() noexcept { got_signal = SIGINT; } | |||||
void dds::install_signal_handlers() noexcept { | |||||
std::signal(SIGINT, handle_signal); | |||||
std::signal(SIGTERM, handle_signal); | |||||
} | |||||
bool dds::is_cancelled() noexcept { return got_signal != 0; } | |||||
void dds::cancellation_point() { | |||||
if (is_cancelled()) { | |||||
throw user_cancelled(); | |||||
} | |||||
} |
#pragma once | |||||
#include <stdexcept> | |||||
namespace dds { | |||||
class user_cancelled : public std::exception {}; | |||||
void install_signal_handlers() noexcept; | |||||
void notify_cancel() noexcept; | |||||
void reset_cancelled() noexcept; | |||||
bool is_cancelled() noexcept; | |||||
void cancellation_point(); | |||||
} // namespace dds |