mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2026-01-18 07:12:26 -08:00
The interrupt servicing thread must explicitely include the interrupt signal among the ones it captures. Otherwise it will never be interrupted itself.
This commit is contained in:
parent
29d472ea59
commit
f50ffce152
3 changed files with 22 additions and 3 deletions
|
|
@ -20,6 +20,9 @@ ECL 10.1.1:
|
|||
- The output values of a process or thread are now collected in the process
|
||||
object and returned by PROCESS-JOIN.
|
||||
|
||||
- The interrupt servicing thread must explicitely include the interrupt signal
|
||||
among the ones it captures. Otherwise it will never be interrupted itself.
|
||||
|
||||
;;; Local Variables: ***
|
||||
;;; mode:text ***
|
||||
;;; fill-column:79 ***
|
||||
|
|
|
|||
|
|
@ -121,8 +121,8 @@ thread_cleanup(void *aux)
|
|||
* mp_process_kill().
|
||||
*/
|
||||
cl_object process = (cl_object)aux;
|
||||
process->process.active = 0;
|
||||
mp_giveup_lock(process->process.exit_lock);
|
||||
process->process.active = 0;
|
||||
THREAD_OP_LOCK();
|
||||
cl_core.processes = ecl_remove_eq(process, cl_core.processes);
|
||||
THREAD_OP_UNLOCK();
|
||||
|
|
|
|||
|
|
@ -789,7 +789,7 @@ ecl_interrupt_process(cl_object process, cl_object function)
|
|||
cl_object lock;
|
||||
int ok;
|
||||
function = si_coerce_to_function(function);
|
||||
lock = mp_get_lock(1, cl_core.signal_queue_lock);
|
||||
lock = mp_get_lock_wait(cl_core.signal_queue_lock);
|
||||
queue_signal(process->process.env, function);
|
||||
ok = do_interrupt_thread(process);
|
||||
mp_giveup_lock(lock);
|
||||
|
|
@ -901,17 +901,32 @@ asynchronous_signal_servicing_thread()
|
|||
sigset_t handled_set;
|
||||
cl_object signal_code;
|
||||
int signo;
|
||||
int interrupt_signal = 0;
|
||||
if (ecl_get_option(ECL_OPT_TRAP_INTERRUPT_SIGNAL)) {
|
||||
interrupt_signal = ecl_get_option(ECL_OPT_THREAD_INTERRUPT_SIGNAL);
|
||||
}
|
||||
/*
|
||||
* We wait here for all signals that are blocked in all other
|
||||
* threads. It would be desirable to be able to wait for _all_
|
||||
* signals, but this can not be done for SIGFPE, SIGSEGV, etc
|
||||
* signals, but this can not be done for SIGFPE, SIGSEGV, etc.
|
||||
*/
|
||||
pthread_sigmask(SIG_SETMASK, NULL, &handled_set);
|
||||
/*
|
||||
* Under OS X we also have to explicitely add the signal we
|
||||
* use to communicate process interrupts. For some unknown
|
||||
* reason those signals may get lost.
|
||||
*/
|
||||
if (interrupt_signal) {
|
||||
sigaddset(&handled_set, interrupt_signal);
|
||||
pthread_sigmask(SIG_SETMASK, &handled_set, NULL);
|
||||
}
|
||||
CL_CATCH_ALL_BEGIN(ecl_process_env()) {
|
||||
for (;;) {
|
||||
/* Waiting may fail! */
|
||||
int status = sigwait(&handled_set, &signo);
|
||||
if (status == 0) {
|
||||
if (interrupt_signal == signo)
|
||||
goto RETURN;
|
||||
signal_code = call_handler(lisp_signal_handler, signo,
|
||||
NULL, NULL);
|
||||
if (!Null(signal_code)) {
|
||||
|
|
@ -922,6 +937,7 @@ asynchronous_signal_servicing_thread()
|
|||
}
|
||||
}
|
||||
} CL_CATCH_ALL_END;
|
||||
RETURN:
|
||||
@(return)
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue