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:
parent
b1c6cf8d6b
commit
29bf0ee9bb
@ -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;
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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) \
|
||||||
|
Loading…
Reference in New Issue
Block a user