diff options
-rw-r--r-- | asmrun/signals.c | 31 | ||||
-rw-r--r-- | byterun/signals.c | 16 | ||||
-rw-r--r-- | byterun/signals.h | 1 | ||||
-rw-r--r-- | byterun/win32.c | 19 |
4 files changed, 36 insertions, 31 deletions
diff --git a/asmrun/signals.c b/asmrun/signals.c index 82c23e0cf..e8a194344 100644 --- a/asmrun/signals.c +++ b/asmrun/signals.c @@ -126,6 +126,22 @@ void caml_execute_signal(int signal_number, int in_signal_handler) if (Is_exception_result(res)) caml_raise(Extract_exception(res)); } +/* Record the delivery of a signal and play with the allocation limit + so that the next allocation will trigger a garbage collection. */ + +void caml_record_signal(int signal_number) +{ + caml_pending_signals[signal_number] = 1; + caml_young_limit = caml_young_end; + /* Some ports cache [caml_young_limit] in a register. + Use the signal context to modify that register too, but only if + we are inside Caml code (not inside C code). */ +#if defined(CONTEXT_PC) && defined(CONTEXT_YOUNG_LIMIT) + if (In_code_area(CONTEXT_PC)) + CONTEXT_YOUNG_LIMIT = (context_reg) caml_young_limit; +#endif +} + /* This routine is the common entry point for garbage collection and signal handling. It can trigger a callback to Caml code. With system threads, this callback can cause a context switch. @@ -193,23 +209,10 @@ DECLARE_SIGNAL_HANDLER(handle_signal) #endif if (sig < 0 || sig >= NSIG) return; if (caml_try_leave_blocking_section_hook ()) { - /* We are interrupting a C function blocked on I/O. - Callback the Caml code immediately. */ caml_execute_signal(sig, 1); caml_enter_blocking_section_hook(); } else { - /* We can't execute the signal code immediately. - Instead, we remember the signal and play with the allocation limit - so that the next allocation will trigger a garbage collection. */ - caml_pending_signals[sig] = 1; - caml_young_limit = caml_young_end; - /* Some ports cache [caml_young_limit] in a register. - Use the signal context to modify that register too, but only if - we are inside Caml code (not inside C code). */ -#if defined(CONTEXT_PC) && defined(CONTEXT_YOUNG_LIMIT) - if (In_code_area(CONTEXT_PC)) - CONTEXT_YOUNG_LIMIT = (context_reg) caml_young_limit; -#endif + caml_record_signal(sig); } } diff --git a/byterun/signals.c b/byterun/signals.c index a4851e7c8..a02f6b859 100644 --- a/byterun/signals.c +++ b/byterun/signals.c @@ -94,6 +94,8 @@ CAMLexport int (*caml_try_leave_blocking_section_hook)(void) = CAMLexport int caml_rev_convert_signal_number(int signo); +/* Execute a signal handler immediately */ + void caml_execute_signal(int signal_number, int in_signal_handler) { value res; @@ -121,6 +123,15 @@ void caml_execute_signal(int signal_number, int in_signal_handler) if (Is_exception_result(res)) caml_raise(Extract_exception(res)); } +/* Record the delivery of a signal, and arrange so that caml_process_event + is called as soon as possible. */ + +void caml_record_signal(int signal_number) +{ + caml_pending_signals[signal_number] = 1; + caml_something_to_do = 1; +} + static void handle_signal(int signal_number) { #if !defined(POSIX_SIGNALS) && !defined(BSD_SIGNALS) @@ -131,9 +142,8 @@ static void handle_signal(int signal_number) caml_execute_signal(signal_number, 1); caml_enter_blocking_section_hook(); }else{ - caml_pending_signals[signal_number] = 1; - caml_something_to_do = 1; - } + caml_record_signal(signal_number); + } } void caml_urge_major_slice (void) diff --git a/byterun/signals.h b/byterun/signals.h index d77917ef8..e1b5df190 100644 --- a/byterun/signals.h +++ b/byterun/signals.h @@ -37,6 +37,7 @@ void caml_urge_major_slice (void); CAMLextern int caml_convert_signal_number (int); CAMLextern int caml_rev_convert_signal_number (int); void caml_execute_signal(int signal_number, int in_signal_handler); +void caml_record_signal(int signal_number); void caml_process_event(void); CAMLextern void (*caml_enter_blocking_section_hook)(void); diff --git a/byterun/win32.c b/byterun/win32.c index 2188c77e1..229a07d63 100644 --- a/byterun/win32.c +++ b/byterun/win32.c @@ -161,7 +161,6 @@ static volatile sighandler ctrl_handler_action = SIG_DFL; static BOOL WINAPI ctrl_handler(DWORD event) { int saved_mode; - sighandler action; /* Only ctrl-C and ctrl-Break are handled */ if (event != CTRL_C_EVENT && event != CTRL_BREAK_EVENT) return FALSE; @@ -170,17 +169,10 @@ static BOOL WINAPI ctrl_handler(DWORD event) /* Ignore behavior is to do nothing, which we get by claiming that we have handled the event */ if (ctrl_handler_action == SIG_IGN) return TRUE; - /* Reset handler to default action for consistency with signal() */ - action = ctrl_handler_action; - ctrl_handler_action = SIG_DFL; - /* Call user-provided signal handler. Win32 doesn't like it when - we do a longjmp() at this point (it looks like we're running in - a different thread than the main program!). So, pretend we are not in - async signal mode, so that the handler simply records the signal. */ - saved_mode = caml_async_signal_mode; - caml_async_signal_mode = 0; - action(SIGINT); - caml_async_signal_mode = saved_mode; + /* Win32 doesn't like it when we do a longjmp() at this point + (it looks like we're running in a different thread than + the main program!). So, just record the signal. */ + caml_record_signal(SIGINT); /* We have handled the event */ return TRUE; } @@ -385,8 +377,7 @@ void caml_signal_thread(void * lpParam) if (!ret || numread != 1) caml_sys_exit(Val_int(2)); switch (iobuf[0]) { case 'C': - caml_pending_signal = SIGINT; - caml_something_to_do = 1; + caml_record_signal(SIGINT); break; case 'T': raise(SIGTERM); |