77 lines
2.1 KiB
C
77 lines
2.1 KiB
C
#include "../twn_timer.h"
|
|
#include "twn_engine_context_c.h"
|
|
|
|
#include <SDL_messagebox.h>
|
|
|
|
#include <signal.h>
|
|
#include <stdint.h>
|
|
#include <time.h>
|
|
#include <unistd.h>
|
|
#include <stdbool.h>
|
|
|
|
|
|
static timer_t timerid;
|
|
static struct sigaction sa;
|
|
static struct sigevent sev;
|
|
|
|
static bool created;
|
|
static uint64_t used_milliseconds_to_expire;
|
|
|
|
#define SANITY_TIMER_MESSAGE_FMT "Game tick exeeded its allocated time (%lu milliseconds), application is closing"
|
|
|
|
/* stop application */
|
|
static void sanity_timer_handler(int sig, siginfo_t *si, void *uc) {
|
|
(void)uc; (void)sig; (void)si;
|
|
size_t text_str_len = snprintf(NULL, 0, SANITY_TIMER_MESSAGE_FMT, used_milliseconds_to_expire) + 1;
|
|
char *text_str = SDL_malloc(text_str_len);
|
|
snprintf(text_str, text_str_len, SANITY_TIMER_MESSAGE_FMT, used_milliseconds_to_expire);
|
|
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "sanity timer", text_str, ctx.window);
|
|
SDL_free(text_str);
|
|
raise(SIGKILL);
|
|
}
|
|
|
|
|
|
bool start_sanity_timer(uint64_t milliseconds_to_expire) {
|
|
if (!created) {
|
|
sa.sa_flags = SA_SIGINFO;
|
|
sa.sa_sigaction = sanity_timer_handler;
|
|
sigemptyset(&sa.sa_mask);
|
|
if (sigaction(SIGRTMIN, &sa, NULL) == -1)
|
|
goto ERR_SIGACTION;
|
|
|
|
sev.sigev_notify = SIGEV_SIGNAL;
|
|
sev.sigev_signo = SIGRTMIN;
|
|
sev.sigev_value.sival_ptr = &timerid;
|
|
if (timer_create(CLOCK_MONOTONIC, &sev, &timerid) == -1)
|
|
goto ERR_TIMERCREATE;
|
|
|
|
created = true;
|
|
|
|
ERR_TIMERCREATE:
|
|
// ERR_SIGPROCMASK:
|
|
ERR_SIGACTION:
|
|
return false;
|
|
}
|
|
|
|
struct itimerspec its = {0};
|
|
its.it_value.tv_sec = milliseconds_to_expire / 1000;
|
|
its.it_value.tv_nsec = (milliseconds_to_expire * 1000000 % 1000000000);
|
|
if (timer_settime(timerid, 0, &its, NULL) == -1)
|
|
return false;
|
|
|
|
used_milliseconds_to_expire = milliseconds_to_expire;
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool end_sanity_timer(void) {
|
|
struct itimerspec its = {0};
|
|
its.it_value.tv_sec = 0;
|
|
its.it_value.tv_nsec = 0;
|
|
if (timer_settime(timerid, 0, &its, NULL) == -1)
|
|
return false;
|
|
|
|
return false;
|
|
}
|