+ 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"
/* turning interrupts and I/O readiness into events */
sigset_t full_sigset;
#define block_interrupts()
#define allow_interrupts()
#define block_interrupts(){sigprocmask (SIG_BLOCK, &full_sigset, 0);}
#define allow_interrupts(){sigprocmask (SIG_UNBLOCK, &full_sigset, 0);}
static void when_keyboard_interrupt();
@ -31,7 +32,7 @@ static void when_scsh_interrupt();
/* JMG: for scsh */
static long interrupt_count[32];
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));
@ -53,7 +54,8 @@ s48_sysdep_init(void)
for (i = 0; i < max_sig; i++)
interrupt_count[i] = 0;
sigfillset (&full_sigset);
/* JMG: for scsh */
s48_setcatcher(SIGCHLD, 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"); */
return (ALARM_EVENT);
}
block_interrupts();
/* JMG: scsh should handle this */
if (s48_os_signal_pending())
return (OS_SIGNAL_EVENT);
block_interrupts();
if ((keyboard_interrupt_count == 0)
&& (alarm_time == -1 || s48_current_time < alarm_time)
&& (poll_time == -1 || s48_current_time < poll_time))
@ -616,8 +618,10 @@ queue_ready_ports(bool wait, long seconds, long ticks)
}
tvp = &tv;
if (wait)
if (seconds == -1)
tvp = NULL;
if (seconds == -1){
tv.tv_sec = 1;
tv.tv_usec = 0;
}
else {
tv.tv_sec = seconds;
tv.tv_usec = ticks * (1000000 / TICKS_PER_SECOND);
@ -625,6 +629,9 @@ queue_ready_ports(bool wait, long seconds, long ticks)
else
timerclear(&tv);
while(TRUE) {
if ((keyboard_interrupt_count > 0) || s48_os_signal_happend ())
return NO_ERRORS;
/* time gap */
left = select(limfd, &reads, &writes, &alls, tvp);
if (left > 0) {
fdpp = &pending.first;
@ -641,6 +648,12 @@ queue_ready_ports(bool wait, long seconds, long ticks)
poll_time = -1;
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)
return NO_ERRORS;
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).
*/
/* needs no be called with interrupts blocked */
int
s48_os_signal_pending(void) {
int i;
for (i = 0; i < max_sig; i++){
if (interrupt_count[i] > 0){
block_interrupts();
--interrupt_count[i];
allow_interrupts();
s48_set_os_signal(S48_UNSAFE_ENTER_FIXNUM(i),
@ -700,14 +714,14 @@ s48_os_signal_pending(void) {
return FALSE;
}
int
bool
s48_os_signal_happend(void) {
int i;
for (i = 0; i < max_sig; i++){
if (interrupt_count[i] > 0){
return 1;
return TRUE;
}
}
return 0;
return FALSE;
}