diff options
| author | J08nY | 2017-10-04 18:41:47 +0200 |
|---|---|---|
| committer | J08nY | 2017-10-04 18:41:47 +0200 |
| commit | caa000e3625241b930fdcda1594bbaf9c9acf642 (patch) | |
| tree | 2eb6ce02a3a172bd2cf4463d45bcbd7954589e31 | |
| parent | 45c08cad912299a8d2043e432bb38e003151526b (diff) | |
| download | ecgen-caa000e3625241b930fdcda1594bbaf9c9acf642.tar.gz ecgen-caa000e3625241b930fdcda1594bbaf9c9acf642.tar.zst ecgen-caa000e3625241b930fdcda1594bbaf9c9acf642.zip | |
| -rw-r--r-- | src/util/timeout.c | 18 | ||||
| -rw-r--r-- | src/util/timeout.h | 41 |
2 files changed, 38 insertions, 21 deletions
diff --git a/src/util/timeout.c b/src/util/timeout.c index 51138fd..c9e20e0 100644 --- a/src/util/timeout.c +++ b/src/util/timeout.c @@ -3,18 +3,26 @@ * Copyright (C) 2017 J08nY */ #include "timeout.h" -#include <signal.h> -__thread jmp_buf exception; +__thread jmp_buf timeout_ptr; +__thread bool timeout_in; +__thread timer_t timeout_timer; -void timeout_handle(int signum) { longjmp(exception, 1); } +void timeout_handle(int signum, siginfo_t *siginfo, void *other) { + sigset_t mask; + sigemptyset(&mask); + sigaddset(&mask, SIGALRM); + sigprocmask(SIG_UNBLOCK, &mask, NULL); + + if (timeout_in) siglongjmp(timeout_ptr, 1); +} bool timeout_init(const config_t *cfg) { struct sigaction new_action; - new_action.sa_handler = timeout_handle; + new_action.sa_sigaction = timeout_handle; sigemptyset(&new_action.sa_mask); - new_action.sa_flags = 0; + new_action.sa_flags = SA_SIGINFO; sigaction(SIGALRM, &new_action, NULL); return true; diff --git a/src/util/timeout.h b/src/util/timeout.h index 7a1ebb2..0226fda 100644 --- a/src/util/timeout.h +++ b/src/util/timeout.h @@ -9,25 +9,34 @@ #include <sys/syscall.h> #include <time.h> #include <unistd.h> +#include "io/output.h" #include "misc/config.h" -extern __thread jmp_buf exception; +extern __thread sigjmp_buf timeout_ptr; +extern __thread bool timeout_in; +extern __thread timer_t timeout_timer; -#define timeout_start(seconds) \ - do { \ - struct sigevent sevp; \ - sevp.sigev_notify = SIGEV_THREAD_ID; \ - sevp.sigev_signo = SIGALRM; \ - sevp._sigev_un._tid = (__pid_t)syscall(SYS_gettid); \ - \ - timer_t timer; \ - timer_create(CLOCK_MONOTONIC, &sevp, &timer); \ - struct itimerspec timer_time = { \ - .it_interval = {.tv_sec = (seconds), .tv_nsec = 0}, \ - .it_value = {.tv_sec = 0, .tv_nsec = 0}}; \ - timer_settime(timer, 0, &timer_time, NULL); \ - setjmp(exception); \ - } while (0); +#define timeout_start(seconds) \ + { \ + struct sigevent sevp; \ + sevp.sigev_notify = SIGEV_THREAD_ID; \ + sevp.sigev_signo = SIGALRM; \ + sevp._sigev_un._tid = (__pid_t)syscall(SYS_gettid); \ + \ + timer_create(CLOCK_MONOTONIC, &sevp, &timeout_timer); \ + struct itimerspec timer_time = { \ + .it_interval = {.tv_sec = 0, .tv_nsec = 0}, \ + .it_value = {.tv_sec = (seconds), .tv_nsec = 0}}; \ + timer_settime(timeout_timer, 0, &timer_time, NULL); \ + timeout_in = true; \ + }; \ + if (sigsetjmp(timeout_ptr, 1) == 1) + +#define timeout_stop() \ + { \ + timeout_in = false; \ + timer_delete(timeout_timer); \ + } /** * @brief |
