Merge sigint_checker_t generalizations from #7060

This makes it possible to expand the signals checked by the type. I can't merge
the sigttin fixes for #7060 yet because they introduce new breakage, but this
will make merging any future fix easier.
This commit is contained in:
Mahmoud Al-Qudsi 2020-06-20 11:23:36 -05:00
parent dd1a26588a
commit f2d5f95396
4 changed files with 14 additions and 11 deletions

View File

@ -64,7 +64,7 @@ static bool any_jobs_finished(size_t jobs_len, const parser_t &parser) {
}
static int wait_for_backgrounds(parser_t &parser, bool any_flag) {
sigint_checker_t sigint;
sigchecker_t sigint(topic_t::sighupint);
size_t jobs_len = parser.jobs().size();
while ((!any_flag && !all_jobs_finished(parser)) ||
(any_flag && !any_jobs_finished(jobs_len, parser))) {
@ -106,7 +106,7 @@ static bool any_specified_jobs_finished(const parser_t &parser, const std::vecto
static int wait_for_backgrounds_specified(parser_t &parser, const std::vector<job_id_t> &ids,
bool any_flag) {
sigint_checker_t sigint;
sigchecker_t sigint(topic_t::sighupint);
while ((!any_flag && !all_specified_jobs_finished(parser, ids)) ||
(any_flag && !any_specified_jobs_finished(parser, ids))) {
if (sigint.check()) {

View File

@ -1953,7 +1953,7 @@ extern "C" {
[[gnu::noinline]] void debug_thread_error(void) {
// Wait for a SIGINT. We can't use sigsuspend() because the signal may be delivered on another
// thread.
sigint_checker_t sigint;
sigchecker_t sigint(topic_t::sighupint);
sigint.wait();
}
}

View File

@ -395,22 +395,23 @@ void signal_unblock_all() {
sigprocmask(SIG_SETMASK, &iset, nullptr);
}
sigint_checker_t::sigint_checker_t() {
sigchecker_t::sigchecker_t(topic_t signal) {
topic_ = signal;
// Call check() to update our generation.
check();
}
bool sigint_checker_t::check() {
bool sigchecker_t::check() {
auto &tm = topic_monitor_t::principal();
generation_t gen = tm.generation_for_topic(topic_t::sighupint);
generation_t gen = tm.generation_for_topic(topic_);
bool changed = this->gen_ != gen;
this->gen_ = gen;
return changed;
}
void sigint_checker_t::wait() const {
void sigchecker_t::wait() const {
auto &tm = topic_monitor_t::principal();
generation_list_t gens{};
gens[topic_t::sighupint] = this->gen_;
tm.check(&gens, {topic_t::sighupint}, true /* wait */);
gens[topic_] = this->gen_;
tm.check(&gens, {topic_}, true /* wait */);
}

View File

@ -33,12 +33,14 @@ void signal_unblock_all();
/// Returns signals with non-default handlers.
void get_signals_with_handlers(sigset_t *set);
enum class topic_t : uint8_t;
/// A sigint_detector_t can be used to check if a SIGINT (or SIGHUP) has been delivered.
class sigint_checker_t {
class sigchecker_t {
topic_t topic_;
uint64_t gen_{0};
public:
sigint_checker_t();
sigchecker_t(topic_t signal);
/// Check if a sigint has been delivered since the last call to check(), or since the detector
/// was created.