+ 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"
|
#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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue