Queue os-signal events.

This commit is contained in:
mainzelm 2002-06-10 08:46:08 +00:00
parent 8d0a620457
commit bbfd094bbd
6 changed files with 53 additions and 38 deletions

View File

@ -23,7 +23,7 @@ extern char s48_Spending_eventsPS;
extern char s48_Spending_interruptPS; extern char s48_Spending_interruptPS;
extern void s48_disable_interruptsB(void); extern void s48_disable_interruptsB(void);
extern void s48_enable_interruptsB(void); extern void s48_enable_interruptsB(void);
extern void s48_set_os_signal(s48_value type, s48_value argument); extern void s48_set_os_signals(s48_value list);
/* imported and exported bindings */ /* imported and exported bindings */
extern void s48_define_exported_binding(char *, s48_value); extern void s48_define_exported_binding(char *, s48_value);

View File

@ -30,7 +30,10 @@ static void when_sigpipe_interrupt();
/* JMG:*/ /* JMG:*/
static void when_scsh_interrupt(); static void when_scsh_interrupt();
/* JMG: for scsh */ /* JMG: for scsh */
static long interrupt_count[32]; #define INTERRUPT_QUEUE_LENGTH 32
static int interrupt_queue [INTERRUPT_QUEUE_LENGTH];
static int next_interrupt = 0;
static int s48_os_signal_pending(void); static int s48_os_signal_pending(void);
static bool s48_os_signal_happend(void); static bool s48_os_signal_happend(void);
@ -51,8 +54,6 @@ s48_sysdep_init(void)
errno); errno);
exit(1); exit(1);
} }
for (i = 0; i < max_sig; i++)
interrupt_count[i] = 0;
sigfillset (&full_sigset); sigfillset (&full_sigset);
@ -671,11 +672,25 @@ queue_ready_ports(bool wait, long seconds, long ticks)
} }
} }
/*
* Adds `signum' to the queue of received signals.
*/
static void
queue_interrupt(int signum)
{
if (next_interrupt == INTERRUPT_QUEUE_LENGTH){
perror("Interrupt queue overflow -- report to Scheme 48 maintainers.");
exit(-1);
}
interrupt_queue[next_interrupt] = signum;
next_interrupt++;
}
/* JMG: for scsh */ /* JMG: for scsh */
static void when_scsh_interrupt(int signo) static void when_scsh_interrupt(int signo)
{ {
interrupt_count[sig2int[signo]] +=1; queue_interrupt(sig2int[signo]);
NOTE_EVENT; NOTE_EVENT;
return; return;
} }
@ -703,31 +718,34 @@ 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 */ /*
* Returns TRUE if there is a signal to be delivered up to Scheme.
* Needs no be called with interrupts blocked.
*/
int int
s48_os_signal_pending(void) { s48_os_signal_pending(void) {
int i; int i;
s48_value interrupt_list = S48_NULL;
block_interrupts();
for (i = 0; i < max_sig; i++){ if (next_interrupt == 0) {
if (interrupt_count[i] > 0){
--interrupt_count[i];
allow_interrupts(); allow_interrupts();
s48_set_os_signal(S48_UNSAFE_ENTER_FIXNUM(i), return FALSE; }
S48_UNSAFE_ENTER_FIXNUM(0)); else {
return TRUE; /* turn the queue into a scheme list and preserve the order */
} for (i = next_interrupt; i > 0 ; i--)
} interrupt_list = s48_cons (s48_enter_fixnum (interrupt_queue [i - 1]),
return FALSE; interrupt_list);
s48_set_os_signals(interrupt_list);
next_interrupt = 0;
allow_interrupts();
return TRUE; }
} }
bool bool
s48_os_signal_happend(void) { s48_os_signal_happend(void) {
int i; return (next_interrupt != 0);
for (i = 0; i < max_sig; i++){
if (interrupt_count[i] > 0){
return TRUE;
}
}
return FALSE;
} }

View File

@ -66,7 +66,7 @@
(define (initialize-sigevents!) (define (initialize-sigevents!)
(set! sigevent-thread-queue (make-thread-queue)) (set! sigevent-thread-queue (make-thread-queue))
(set-interrupt-handler! (enum interrupt os-signal) (set-interrupt-handler! (enum interrupt os-signal)
(lambda (type arg enabled-interrupts) (lambda (type enabled-interrupts)
; type is already set in the unix signal handler ; type is already set in the unix signal handler
(register-interrupt type))) (register-interrupt type)))
(set-interrupt-handler! (enum interrupt keyboard) (set-interrupt-handler! (enum interrupt keyboard)

View File

@ -446,7 +446,7 @@
current-thread current-thread
disable-interrupts! disable-interrupts!
enable-interrupts! enable-interrupts!
s48-set-os-signal s48-set-os-signals
s48-*callback-return-stack-block* s48-*callback-return-stack-block*
)) ))
@ -479,7 +479,7 @@
s48-*pending-interrupt?* s48-*pending-interrupt?*
s48-disable-interrupts! s48-disable-interrupts!
s48-enable-interrupts! s48-enable-interrupts!
s48-set-os-signal s48-set-os-signals
s48-define-exported-binding s48-define-exported-binding
s48-get-imported-binding s48-get-imported-binding

View File

@ -81,8 +81,7 @@
(set! *interrupt-template* (s48-trace-value *interrupt-template*)) (set! *interrupt-template* (s48-trace-value *interrupt-template*))
(set! *interrupted-template* (s48-trace-value *interrupted-template*)) (set! *interrupted-template* (s48-trace-value *interrupted-template*))
(set! *finalize-these* (s48-trace-value *finalize-these*)) (set! *finalize-these* (s48-trace-value *finalize-these*))
(set! *os-signal-type* (s48-trace-value *os-signal-type*)) (set! *os-signal-list* (s48-trace-value *os-signal-list*))
(set! *os-signal-argument* (s48-trace-value *os-signal-argument*))
(trace-finalizer-alist!) (trace-finalizer-alist!)
; These could be moved to the appropriate modules. ; These could be moved to the appropriate modules.

View File

@ -67,24 +67,22 @@
(push (enter-fixnum *enabled-interrupts*)) (push (enter-fixnum *enabled-interrupts*))
3)) 3))
((eq? pending-interrupt (enum interrupt os-signal)) ((eq? pending-interrupt (enum interrupt os-signal))
(push *os-signal-type*) (push (vm-car *os-signal-list*))
(push *os-signal-argument*) (set! *os-signal-list* (vm-cdr *os-signal-list*))
(set! *os-signal-type* false) (if (not (vm-eq? *os-signal-list* null))
(set! *os-signal-argument* false) (note-interrupt! (enum interrupt os-signal)))
(push (enter-fixnum *enabled-interrupts*)) (push (enter-fixnum *enabled-interrupts*))
3) 2)
(else (else
(push (enter-fixnum *enabled-interrupts*)) (push (enter-fixnum *enabled-interrupts*))
1))) 1)))
; Called from outside when an os-signal event is returned. ; Called from outside when an os-signal event is returned.
(define (s48-set-os-signal type argument) (define (s48-set-os-signals signal-list)
(set! *os-signal-type* type) (set! *os-signal-list* (vm-append! *os-signal-list* signal-list)))
(set! *os-signal-argument* argument))
(define *os-signal-type* false) (define *os-signal-list* null)
(define *os-signal-argument* false)
; Return from a call to an interrupt handler. ; Return from a call to an interrupt handler.