1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-12-04 14:46:47 -05:00

[dos,js] Try to add own timer ISR

The goal is to check if js scripts do not execute too long under DOS.
It may be buggy.
This commit is contained in:
Witold Filipczyk 2022-06-12 22:14:49 +02:00
parent b1c6cf8d6b
commit 29bf0ee9bb
3 changed files with 51 additions and 16 deletions

View File

@ -44,7 +44,7 @@ js_heartbeat_callback(JSRuntime *rt, void *opaque)
/* Callback for SIGVTALRM. Go through all heartbeats, decrease each /* Callback for SIGVTALRM. Go through all heartbeats, decrease each
* one's TTL, and call JS_RequestInterruptCallback if a heartbeat's TTL * one's TTL, and call JS_RequestInterruptCallback if a heartbeat's TTL
* goes to 0. */ * goes to 0. */
static void void
check_heartbeats(void *data) check_heartbeats(void *data)
{ {
struct heartbeat *hb; struct heartbeat *hb;
@ -67,9 +67,7 @@ check_heartbeats(void *data)
} }
} }
} }
#ifdef CONFIG_OS_DOS #ifndef CONFIG_OS_DOS
install_signal_handler(SIGALRM, check_heartbeats, NULL, 1);
#else
install_signal_handler(SIGVTALRM, check_heartbeats, NULL, 1); install_signal_handler(SIGVTALRM, check_heartbeats, NULL, 1);
#endif #endif
} }
@ -95,25 +93,18 @@ add_heartbeat(struct ecmascript_interpreter *interpreter)
hb->interpreter = interpreter; hb->interpreter = interpreter;
add_to_list(heartbeats, hb); add_to_list(heartbeats, hb);
#ifndef CONFIG_OS_DOS
/* Update the heartbeat timer. */ /* Update the heartbeat timer. */
if (list_is_singleton(*hb)) { if (list_is_singleton(*hb)) {
heartbeat_timer.it_value.tv_sec = 1; heartbeat_timer.it_value.tv_sec = 1;
#ifdef CONFIG_OS_DOS
setitimer(ITIMER_REAL, &heartbeat_timer, NULL);
#else
setitimer(ITIMER_VIRTUAL, &heartbeat_timer, NULL); setitimer(ITIMER_VIRTUAL, &heartbeat_timer, NULL);
#endif
} }
/* We install the handler every call to add_heartbeat instead of only on /* We install the handler every call to add_heartbeat instead of only on
* module initialisation because other code may set other handlers for * module initialisation because other code may set other handlers for
* the signal. */ * the signal. */
#ifdef CONFIG_OS_DOS
install_signal_handler(SIGALRM, check_heartbeats, NULL, 1);
#else
install_signal_handler(SIGVTALRM, check_heartbeats, NULL, 1); install_signal_handler(SIGVTALRM, check_heartbeats, NULL, 1);
#endif #endif
return hb; return hb;
} }
@ -124,15 +115,13 @@ done_heartbeat(struct heartbeat *hb)
if (!hb) return; /* add_heartbeat returned NULL */ if (!hb) return; /* add_heartbeat returned NULL */
assert(hb->interpreter); assert(hb->interpreter);
#ifndef CONFIG_OS_DOS
/* Stop the heartbeat timer if this heartbeat is the only one. */ /* Stop the heartbeat timer if this heartbeat is the only one. */
if (list_is_singleton(*hb)) { if (list_is_singleton(*hb)) {
heartbeat_timer.it_value.tv_sec = 0; heartbeat_timer.it_value.tv_sec = 0;
#ifdef CONFIG_OS_DOS
setitimer(ITIMER_REAL, &heartbeat_timer, NULL);
#else
setitimer(ITIMER_VIRTUAL, &heartbeat_timer, NULL); setitimer(ITIMER_VIRTUAL, &heartbeat_timer, NULL);
#endif
} }
#endif
del_from_list(hb); del_from_list(hb);
hb->interpreter->heartbeat = NULL; hb->interpreter->heartbeat = NULL;

View File

@ -15,6 +15,7 @@ struct heartbeat {
}; };
struct heartbeat *add_heartbeat(struct ecmascript_interpreter *interpreter); struct heartbeat *add_heartbeat(struct ecmascript_interpreter *interpreter);
void check_heartbeats(void *data);
void done_heartbeat(struct heartbeat *hb); void done_heartbeat(struct heartbeat *hb);
int js_heartbeat_callback(JSRuntime *rt, void *opaque); int js_heartbeat_callback(JSRuntime *rt, void *opaque);

View File

@ -24,6 +24,9 @@
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#include <values.h> #include <values.h>
#ifdef CONFIG_ECMASCRIPT
#include "ecmascript/quickjs/heartbeat.h"
#endif
#include "intl/libintl.h" #include "intl/libintl.h"
#include "main/main.h" #include "main/main.h"
#include "main/select.h" #include "main/select.h"
@ -1010,6 +1013,33 @@ void os_seed_random(unsigned char **pool, int *pool_size)
*pool_size = RANDOM_POOL_SIZE; *pool_size = RANDOM_POOL_SIZE;
} }
_go32_dpmi_seginfo OldISR, NewISR;
#define TIMER 8
//Simple Example of chaining interrupt handlers
//Adopted from Matthew Mastracci's code
#include <pc.h>
#include <dpmi.h>
#include <go32.h>
//macros by Shawn Hargreaves from the Allegro library for locking
//functions and variables.
#define LOCK_VARIABLE(x) _go32_dpmi_lock_data((void *)&x,(long)sizeof(x));
#define LOCK_FUNCTION(x) _go32_dpmi_lock_code(x,(long)sizeof(x));
static void
TickHandler(void)
{
#ifdef CONFIG_ECMASCRIPT
static int internal = 0;
if (internal++ >= 19) {
internal = 0;
check_heartbeats(NULL);
}
#endif
}
void init_osdep(void) void init_osdep(void)
{ {
int s, rs; int s, rs;
@ -1040,12 +1070,27 @@ void init_osdep(void)
sigemptyset(&sa.sa_mask); sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART; sa.sa_flags = SA_RESTART;
EINTRLOOP(rs, sigaction(SIGINT, &sa, NULL)); EINTRLOOP(rs, sigaction(SIGINT, &sa, NULL));
LOCK_FUNCTION(TickHandler);
LOCK_FUNCTION(check_heartbeats);
//load the address of the old timer ISR into the OldISR structure
_go32_dpmi_get_protected_mode_interrupt_vector(TIMER, &OldISR);
//point NewISR to the proper selector:offset for handler
//function
NewISR.pm_offset = (int)TickHandler;
NewISR.pm_selector = _go32_my_cs();
//chain the new ISR onto the old one so that first the old
//timer ISR
//will be called, then the new timer ISR
_go32_dpmi_chain_protected_mode_interrupt_vector(TIMER, &NewISR);
} }
void terminate_osdep(void) void terminate_osdep(void)
{ {
if (screen_backbuffer) if (screen_backbuffer)
mem_free(screen_backbuffer); mem_free(screen_backbuffer);
_go32_dpmi_set_protected_mode_interrupt_vector(TIMER, &OldISR);
} }
#define LINKS_BIN_SEARCH(entries, eq, ab, key, result) \ #define LINKS_BIN_SEARCH(entries, eq, ab, key, result) \