+ Implement blocking interrupts by sigprocmask
+ Never wait for longer than 1 second to avoid missing an interrupt
This commit is contained in:
parent
1f9c6a102c
commit
47d41db14e
|
@ -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,6 +54,7 @@ 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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue