Introduce sigint_checker_t and use it in wait

Allow a simpler way to check for sigint via sigint_checker_t.
Adopt it in builtin_wait, instead of hooking into the reader.
This commit is contained in:
ridiculousfish 2019-05-25 19:05:24 -07:00
parent f8ba0ac5bf
commit ea3ad0c099
3 changed files with 31 additions and 4 deletions

View file

@ -7,7 +7,7 @@
#include "common.h"
#include "parser.h"
#include "proc.h"
#include "reader.h"
#include "signal.h"
#include "wgetopt.h"
#include "wutil.h"
@ -66,11 +66,11 @@ 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;
size_t jobs_len = parser.jobs().size();
while ((!any_flag && !all_jobs_finished(parser)) ||
(any_flag && !any_jobs_finished(jobs_len, parser))) {
if (reader_test_interrupted()) {
if (sigint.check()) {
return 128 + SIGINT;
}
proc_wait_any(parser);
@ -108,9 +108,10 @@ static bool any_specified_jobs_finished(const std::vector<job_id_t> &ids) {
static int wait_for_backgrounds_specified(parser_t &parser, const std::vector<job_id_t> &ids,
bool any_flag) {
sigint_checker_t sigint;
while ((!any_flag && !all_specified_jobs_finished(ids)) ||
(any_flag && !any_specified_jobs_finished(ids))) {
if (reader_test_interrupted()) {
if (sigint.check()) {
return 128 + SIGINT;
}
proc_wait_any(parser);

View file

@ -15,6 +15,7 @@
#include "parser.h"
#include "proc.h"
#include "reader.h"
#include "signal.h"
#include "topic_monitor.h"
#include "wutil.h" // IWYU pragma: keep
@ -417,3 +418,16 @@ void signal_unblock_all() {
sigemptyset(&iset);
sigprocmask(SIG_SETMASK, &iset, NULL);
}
sigint_checker_t::sigint_checker_t() {
// Call check() to update our generation.
check();
}
bool sigint_checker_t::check() {
auto &tm = topic_monitor_t::principal();
generation_t gen = tm.generation_for_topic(topic_t::sighupint);
bool changed = this->gen_ != gen;
this->gen_ = gen;
return changed;
}

View file

@ -32,4 +32,16 @@ void signal_unblock_all();
/// Returns signals with non-default handlers.
void get_signals_with_handlers(sigset_t *set);
/// A sigint_detector_t can be used to check if a SIGINT (or SIGHUP) has been delivered.
class sigint_checker_t {
uint64_t gen_{0};
public:
sigint_checker_t();
/// Check if a sigint has been delivered since the last call to check(), or since the detector
/// was created.
bool check();
};
#endif