+ Implement blocking interrupts by sigprocmask

+ Never wait for longer than 1 second to avoid missing an interrupt
This commit is contained in:
mainzelm 2002-02-13 14:42:50 +00:00
parent 1f9c6a102c
commit 47d41db14e
1 changed files with 25 additions and 11 deletions

View File

@ -17,9 +17,10 @@
#include "../scsh/signals1.h" #include "../scsh/signals1.h"
/* turning interrupts and I/O readiness into events */ /* turning interrupts and I/O readiness into events */
sigset_t full_sigset;
#define block_interrupts() #define block_interrupts(){sigprocmask (SIG_BLOCK, &full_sigset, 0);}
#define allow_interrupts() #define allow_interrupts(){sigprocmask (SIG_UNBLOCK, &full_sigset, 0);}
static void when_keyboard_interrupt(); static void when_keyboard_interrupt();
@ -31,7 +32,7 @@ static void when_scsh_interrupt();
/* JMG: for scsh */ /* JMG: for scsh */
static long interrupt_count[32]; static long interrupt_count[32];
static int s48_os_signal_pending(void); static int s48_os_signal_pending(void);
static int s48_os_signal_happend(void); static bool s48_os_signal_happend(void);
bool s48_setcatcher(int signum, void (*catcher)(int)); bool s48_setcatcher(int signum, void (*catcher)(int));
@ -53,7 +54,8 @@ s48_sysdep_init(void)
for (i = 0; i < max_sig; i++) for (i = 0; i < max_sig; i++)
interrupt_count[i] = 0; interrupt_count[i] = 0;
sigfillset (&full_sigset);
/* JMG: for scsh */ /* JMG: for scsh */
s48_setcatcher(SIGCHLD, when_scsh_interrupt); s48_setcatcher(SIGCHLD, when_scsh_interrupt);
s48_setcatcher(SIGCONT, when_scsh_interrupt); s48_setcatcher(SIGCONT, when_scsh_interrupt);
@ -341,11 +343,11 @@ s48_get_next_event(long *ready_fd, long *status)
/* fprintf(stderr, "[alarm]\n"); */ /* fprintf(stderr, "[alarm]\n"); */
return (ALARM_EVENT); return (ALARM_EVENT);
} }
block_interrupts();
/* JMG: scsh should handle this */ /* JMG: scsh should handle this */
if (s48_os_signal_pending()) if (s48_os_signal_pending())
return (OS_SIGNAL_EVENT); return (OS_SIGNAL_EVENT);
block_interrupts();
if ((keyboard_interrupt_count == 0) if ((keyboard_interrupt_count == 0)
&& (alarm_time == -1 || s48_current_time < alarm_time) && (alarm_time == -1 || s48_current_time < alarm_time)
&& (poll_time == -1 || s48_current_time < poll_time)) && (poll_time == -1 || s48_current_time < poll_time))
@ -616,8 +618,10 @@ queue_ready_ports(bool wait, long seconds, long ticks)
} }
tvp = &tv; tvp = &tv;
if (wait) if (wait)
if (seconds == -1) if (seconds == -1){
tvp = NULL; tv.tv_sec = 1;
tv.tv_usec = 0;
}
else { else {
tv.tv_sec = seconds; tv.tv_sec = seconds;
tv.tv_usec = ticks * (1000000 / TICKS_PER_SECOND); tv.tv_usec = ticks * (1000000 / TICKS_PER_SECOND);
@ -625,6 +629,9 @@ queue_ready_ports(bool wait, long seconds, long ticks)
else else
timerclear(&tv); timerclear(&tv);
while(TRUE) { while(TRUE) {
if ((keyboard_interrupt_count > 0) || s48_os_signal_happend ())
return NO_ERRORS;
/* time gap */
left = select(limfd, &reads, &writes, &alls, tvp); left = select(limfd, &reads, &writes, &alls, tvp);
if (left > 0) { if (left > 0) {
fdpp = &pending.first; fdpp = &pending.first;
@ -641,6 +648,12 @@ queue_ready_ports(bool wait, long seconds, long ticks)
poll_time = -1; poll_time = -1;
return NO_ERRORS; return NO_ERRORS;
} }
else if (left == 0 && seconds == -1)
return NO_ERRORS;
else if (left == 0 && seconds > 0){
tv.tv_sec = --seconds;
tv.tv_usec = 0;
}
else if (left == 0) else if (left == 0)
return NO_ERRORS; return NO_ERRORS;
else if (errno == EINTR) { else if (errno == EINTR) {
@ -684,12 +697,13 @@ static void when_scsh_interrupt(int signo)
* reenabled when the handler returns (or if done by hand). * reenabled when the handler returns (or if done by hand).
*/ */
/* needs no be called with interrupts blocked */
int int
s48_os_signal_pending(void) { s48_os_signal_pending(void) {
int i; int i;
for (i = 0; i < max_sig; i++){ for (i = 0; i < max_sig; i++){
if (interrupt_count[i] > 0){ if (interrupt_count[i] > 0){
block_interrupts();
--interrupt_count[i]; --interrupt_count[i];
allow_interrupts(); allow_interrupts();
s48_set_os_signal(S48_UNSAFE_ENTER_FIXNUM(i), s48_set_os_signal(S48_UNSAFE_ENTER_FIXNUM(i),
@ -700,14 +714,14 @@ s48_os_signal_pending(void) {
return FALSE; return FALSE;
} }
int bool
s48_os_signal_happend(void) { s48_os_signal_happend(void) {
int i; int i;
for (i = 0; i < max_sig; i++){ for (i = 0; i < max_sig; i++){
if (interrupt_count[i] > 0){ if (interrupt_count[i] > 0){
return 1; return TRUE;
} }
} }
return 0; return FALSE;
} }