* bug fix: interrupt handlers are now per-process to match
pthread semantics, RUN-PROGRAM and SB-SPROF do not die
with 'no handler for signal XX in interrupt_handle_now(..)'
anymore
Hannu Koivisto)
** bug fix: binding specials is thread safe (thanks to
Hannu Koivisto)
Hannu Koivisto)
** bug fix: binding specials is thread safe (thanks to
Hannu Koivisto)
+ ** bug fix: interrupt handlers are now per-process, RUN-PROGRAM
+ and SB-SPROF do not die with 'no handler for signal XX in
+ interrupt_handle_now(..)' anymore
* fixed some bugs revealed by Paul Dietz' test suite:
** ENSURE-GENERIC-FUNCTION should take a method class object for
the :method-class keyword argument.
* fixed some bugs revealed by Paul Dietz' test suite:
** ENSURE-GENERIC-FUNCTION should take a method class object for
the :method-class keyword argument.
unsigned long control_stack_size, binding_stack_size;
sigset_t tmp, old;
struct thread *th=arch_os_get_current_thread();
unsigned long control_stack_size, binding_stack_size;
sigset_t tmp, old;
struct thread *th=arch_os_get_current_thread();
- struct interrupt_data *data=th->interrupt_data;
-
#ifdef PRINTNOISE
printf("[Collecting garbage ... \n");
#ifdef PRINTNOISE
printf("[Collecting garbage ... \n");
printf("Scavenging interrupt handlers (%d bytes) ...\n",
(int)sizeof(interrupt_handlers));
#endif
printf("Scavenging interrupt handlers (%d bytes) ...\n",
(int)sizeof(interrupt_handlers));
#endif
- scavenge((lispobj *) data->interrupt_handlers,
- sizeof(data->interrupt_handlers) / sizeof(lispobj));
+ scavenge((lispobj *) interrupt_handlers,
+ sizeof(interrupt_handlers) / sizeof(lispobj));
/* _size quantities are in units of sizeof(lispobj) - i.e. 4 */
control_stack_size =
/* _size quantities are in units of sizeof(lispobj) - i.e. 4 */
control_stack_size =
/* Scavenge the Lisp functions of the interrupt handlers, taking
* care to avoid SIG_DFL and SIG_IGN. */
/* Scavenge the Lisp functions of the interrupt handlers, taking
* care to avoid SIG_DFL and SIG_IGN. */
- for_each_thread(th) {
- struct interrupt_data *data=th->interrupt_data;
- for (i = 0; i < NSIG; i++) {
- union interrupt_handler handler = data->interrupt_handlers[i];
- if (!ARE_SAME_HANDLER(handler.c, SIG_IGN) &&
- !ARE_SAME_HANDLER(handler.c, SIG_DFL)) {
- scavenge((lispobj *)(data->interrupt_handlers + i), 1);
- }
+ for (i = 0; i < NSIG; i++) {
+ union interrupt_handler handler = interrupt_handlers[i];
+ if (!ARE_SAME_HANDLER(handler.c, SIG_IGN) &&
+ !ARE_SAME_HANDLER(handler.c, SIG_DFL)) {
+ scavenge((lispobj *)(interrupt_handlers + i), 1);
}
}
/* Scavenge the function list for INTERRUPT-THREAD. */
}
}
/* Scavenge the function list for INTERRUPT-THREAD. */
* becomes 'yes'.) */
boolean internal_errors_enabled = 0;
* becomes 'yes'.) */
boolean internal_errors_enabled = 0;
-struct interrupt_data * global_interrupt_data;
+static void (*interrupt_low_level_handlers[NSIG]) (int, siginfo_t*, void*);
+union interrupt_handler interrupt_handlers[NSIG];
/* At the toplevel repl we routinely call this function. The signal
* mask ought to be clear anyway most of the time, but may be non-zero
/* At the toplevel repl we routinely call this function. The signal
* mask ought to be clear anyway most of the time, but may be non-zero
interrupt_handle_now(int signal, siginfo_t *info, void *void_context)
{
os_context_t *context = (os_context_t*)void_context;
interrupt_handle_now(int signal, siginfo_t *info, void *void_context)
{
os_context_t *context = (os_context_t*)void_context;
- struct thread *thread=arch_os_get_current_thread();
#if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64)
boolean were_in_lisp;
#endif
#if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64)
boolean were_in_lisp;
#endif
delivered we appear to have a null FPU control word. */
os_restore_fp_control(context);
#endif
delivered we appear to have a null FPU control word. */
os_restore_fp_control(context);
#endif
- handler = thread->interrupt_data->interrupt_handlers[signal];
+ handler = interrupt_handlers[signal];
if (ARE_SAME_HANDLER(handler.c, SIG_IGN)) {
return;
if (ARE_SAME_HANDLER(handler.c, SIG_IGN)) {
return;
* because we're not in pseudoatomic and allocation shouldn't
* be interrupted. In which case it's no longer an issue as
* all our allocation from C now goes through a PA wrapper,
* because we're not in pseudoatomic and allocation shouldn't
* be interrupted. In which case it's no longer an issue as
* all our allocation from C now goes through a PA wrapper,
- * but still, doesn't hurt */
+ * but still, doesn't hurt.
+ *
+ * Yeah, but non-gencgc platforms that don't really wrap
+ * allocation in PA. MG - 2005-08-29 */
lispobj info_sap,context_sap = alloc_sap(context);
info_sap = alloc_sap(info);
lispobj info_sap,context_sap = alloc_sap(context);
info_sap = alloc_sap(info);
low_level_interrupt_handle_now(int signal, siginfo_t *info, void *void_context)
{
os_context_t *context = (os_context_t*)void_context;
low_level_interrupt_handle_now(int signal, siginfo_t *info, void *void_context)
{
os_context_t *context = (os_context_t*)void_context;
- struct thread *thread=arch_os_get_current_thread();
- struct interrupt_data *data=thread->interrupt_data;
#ifdef LISP_FEATURE_LINUX
os_restore_fp_control(context);
#endif
check_blockables_blocked_or_lose();
check_interrupts_enabled_or_lose(context);
#ifdef LISP_FEATURE_LINUX
os_restore_fp_control(context);
#endif
check_blockables_blocked_or_lose();
check_interrupts_enabled_or_lose(context);
- (*data->interrupt_low_level_handlers[signal])
- (signal, info, void_context);
+ interrupt_low_level_handlers[signal](signal, info, void_context);
#ifdef LISP_FEATURE_DARWIN
/* Work around G5 bug */
DARWIN_FIX_CONTEXT(context);
#ifdef LISP_FEATURE_DARWIN
/* Work around G5 bug */
DARWIN_FIX_CONTEXT(context);
void*))
{
struct sigaction sa;
void*))
{
struct sigaction sa;
- struct thread *th=arch_os_get_current_thread();
- /* It may be before the initial thread is started. */
- struct interrupt_data *data=
- th ? th->interrupt_data : global_interrupt_data;
if (0 > signal || signal >= NSIG) {
lose("bad signal number %d", signal);
if (0 > signal || signal >= NSIG) {
lose("bad signal number %d", signal);
#endif
sigaction(signal, &sa, NULL);
#endif
sigaction(signal, &sa, NULL);
- data->interrupt_low_level_handlers[signal] =
+ interrupt_low_level_handlers[signal] =
(ARE_SAME_HANDLER(handler, SIG_DFL) ? 0 : handler);
}
(ARE_SAME_HANDLER(handler, SIG_DFL) ? 0 : handler);
}
struct sigaction sa;
sigset_t old, new;
union interrupt_handler oldhandler;
struct sigaction sa;
sigset_t old, new;
union interrupt_handler oldhandler;
- struct thread *th=arch_os_get_current_thread();
- /* It may be before the initial thread is started. */
- struct interrupt_data *data=
- th ? th->interrupt_data : global_interrupt_data;
FSHOW((stderr, "/entering POSIX install_handler(%d, ..)\n", signal));
FSHOW((stderr, "/entering POSIX install_handler(%d, ..)\n", signal));
sigaddset(&new, signal);
thread_sigmask(SIG_BLOCK, &new, &old);
sigaddset(&new, signal);
thread_sigmask(SIG_BLOCK, &new, &old);
- FSHOW((stderr, "/data->interrupt_low_level_handlers[signal]=%x\n",
- (unsigned int)data->interrupt_low_level_handlers[signal]));
- if (data->interrupt_low_level_handlers[signal]==0) {
+ FSHOW((stderr, "/interrupt_low_level_handlers[signal]=%x\n",
+ (unsigned int)interrupt_low_level_handlers[signal]));
+ if (interrupt_low_level_handlers[signal]==0) {
if (ARE_SAME_HANDLER(handler, SIG_DFL) ||
ARE_SAME_HANDLER(handler, SIG_IGN)) {
sa.sa_sigaction = handler;
if (ARE_SAME_HANDLER(handler, SIG_DFL) ||
ARE_SAME_HANDLER(handler, SIG_IGN)) {
sa.sa_sigaction = handler;
sigaction(signal, &sa, NULL);
}
sigaction(signal, &sa, NULL);
}
- oldhandler = data->interrupt_handlers[signal];
- data->interrupt_handlers[signal].c = handler;
+ oldhandler = interrupt_handlers[signal];
+ interrupt_handlers[signal].c = handler;
thread_sigmask(SIG_SETMASK, &old, 0);
thread_sigmask(SIG_SETMASK, &old, 0);
sigaddset_deferrable(&deferrable_sigset);
sigaddset_blockable(&blockable_sigset);
sigaddset_deferrable(&deferrable_sigset);
sigaddset_blockable(&blockable_sigset);
- global_interrupt_data=calloc(sizeof(struct interrupt_data), 1);
-
/* Set up high level handler information. */
for (i = 0; i < NSIG; i++) {
/* Set up high level handler information. */
for (i = 0; i < NSIG; i++) {
- global_interrupt_data->interrupt_handlers[i].c =
+ interrupt_handlers[i].c =
/* (The cast here blasts away the distinction between
* SA_SIGACTION-style three-argument handlers and
* signal(..)-style one-argument handlers, which is OK
/* (The cast here blasts away the distinction between
* SA_SIGACTION-style three-argument handlers and
* signal(..)-style one-argument handlers, which is OK
void (*c)(int, siginfo_t*, void*);
};
void (*c)(int, siginfo_t*, void*);
};
-struct interrupt_data {
- void (*interrupt_low_level_handlers[NSIG]) (int, siginfo_t*, void*) ;
- union interrupt_handler interrupt_handlers[NSIG];
+extern union interrupt_handler interrupt_handlers[NSIG];
/* signal information for pending signal. pending_signal=0 when there
* is no pending signal. */
void (*pending_handler) (int, siginfo_t*, void*) ;
/* signal information for pending signal. pending_signal=0 when there
* is no pending signal. */
void (*pending_handler) (int, siginfo_t*, void*) ;
printf(" handlers");
fflush(stdout);
#endif
printf(" handlers");
fflush(stdout);
#endif
- pscav((lispobj *) all_threads->interrupt_data->interrupt_handlers,
- sizeof(all_threads->interrupt_data->interrupt_handlers)
- / sizeof(lispobj),
+ pscav((lispobj *) interrupt_handlers,
+ sizeof(interrupt_handlers) / sizeof(lispobj),
free_thread_struct(th);
return 0;
}
free_thread_struct(th);
return 0;
}
- if(all_threads)
- memcpy(th->interrupt_data,
- arch_os_get_current_thread()->interrupt_data,
- sizeof (struct interrupt_data));
- else
- memcpy(th->interrupt_data,global_interrupt_data,
- sizeof (struct interrupt_data));
-
+ th->interrupt_data->pending_handler = 0;
th->no_tls_value_marker=initial_function;
return th;
}
th->no_tls_value_marker=initial_function;
return th;
}
(assert (null (symbol-value-in-thread 'sb-thread:*current-thread*
thread))))
(assert (null (symbol-value-in-thread 'sb-thread:*current-thread*
thread))))
+;; interrupt handlers are per-thread with pthreads, make sure the
+;; handler installed in one thread is global
+(sb-thread:make-thread
+ (lambda ()
+ (sb-ext:run-program "sleep" '("1") :search t :wait nil)))
+
#| ;; a cll post from eric marsden
| (defun crash ()
| (setq *debugger-hook*
#| ;; a cll post from eric marsden
| (defun crash ()
| (setq *debugger-hook*
| (mp:make-process #'roomy)
| (mp:make-process #'roomy)))
|#
| (mp:make-process #'roomy)
| (mp:make-process #'roomy)))
|#
-
-;; give the other thread time to die before we leave, otherwise the
-;; overall exit status is 0, not 104
-(sleep 2)
-
;;; checkins which aren't released. (And occasionally for internal
;;; versions, especially for internal versions off the main CVS
;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
;;; checkins which aren't released. (And occasionally for internal
;;; versions, especially for internal versions off the main CVS
;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)