Do not run OCaml code inside signal handlers

master
Stephen Dolan 2020-06-24 16:21:30 +01:00
parent e678885007
commit 32feddc1fc
6 changed files with 4 additions and 41 deletions

View File

@ -253,15 +253,6 @@ static void caml_thread_leave_blocking_section(void)
caml_thread_restore_runtime_state();
}
static int caml_thread_try_leave_blocking_section(void)
{
/* Disable immediate processing of signals (PR#3659).
try_leave_blocking_section always fails, forcing the signal to be
recorded and processed at the next leave_blocking_section or
polling. */
return 0;
}
/* Hooks for I/O locking */
static void caml_io_mutex_free(struct channel *chan)
@ -496,7 +487,6 @@ CAMLprim value caml_thread_initialize(value unit) /* ML */
caml_scan_roots_hook = caml_thread_scan_roots;
caml_enter_blocking_section_hook = caml_thread_enter_blocking_section;
caml_leave_blocking_section_hook = caml_thread_leave_blocking_section;
caml_try_leave_blocking_section_hook = caml_thread_try_leave_blocking_section;
#ifdef NATIVE_CODE
caml_termination_hook = st_thread_exit;
#endif

View File

@ -264,7 +264,6 @@
#define something_to_do caml_something_to_do
#define enter_blocking_section_hook caml_enter_blocking_section_hook
#define leave_blocking_section_hook caml_leave_blocking_section_hook
#define try_leave_blocking_section_hook caml_try_leave_blocking_section_hook
#define enter_blocking_section caml_enter_blocking_section
#define leave_blocking_section caml_leave_blocking_section
#define convert_signal_number caml_convert_signal_number

View File

@ -86,7 +86,6 @@ void caml_setup_stack_overflow_detection(void);
CAMLextern void (*caml_enter_blocking_section_hook)(void);
CAMLextern void (*caml_leave_blocking_section_hook)(void);
CAMLextern int (*caml_try_leave_blocking_section_hook)(void);
#ifdef POSIX_SIGNALS
CAMLextern int (*caml_sigmask_hook)(int, const sigset_t *, sigset_t *);
#endif

View File

@ -136,33 +136,18 @@ CAMLno_tsan void caml_record_signal(int signal_number)
/* Management of blocking sections. */
static intnat volatile caml_async_signal_mode = 0;
static void caml_enter_blocking_section_default(void)
{
CAMLassert (caml_async_signal_mode == 0);
caml_async_signal_mode = 1;
}
static void caml_leave_blocking_section_default(void)
{
CAMLassert (caml_async_signal_mode == 1);
caml_async_signal_mode = 0;
}
static int caml_try_leave_blocking_section_default(void)
{
intnat res;
Read_and_clear(res, caml_async_signal_mode);
return res;
}
CAMLexport void (*caml_enter_blocking_section_hook)(void) =
caml_enter_blocking_section_default;
CAMLexport void (*caml_leave_blocking_section_hook)(void) =
caml_leave_blocking_section_default;
CAMLexport int (*caml_try_leave_blocking_section_hook)(void) =
caml_try_leave_blocking_section_default;
CAMLno_tsan /* The read of [caml_something_to_do] is not synchronized. */
CAMLexport void caml_enter_blocking_section(void)

View File

@ -46,12 +46,7 @@ static void handle_signal(int signal_number)
signal(signal_number, handle_signal);
#endif
if (signal_number < 0 || signal_number >= NSIG) return;
if (caml_try_leave_blocking_section_hook()) {
caml_raise_if_exception(caml_execute_signal_exn(signal_number, 1));
caml_enter_blocking_section_hook();
}else{
caml_record_signal(signal_number);
}
caml_record_signal(signal_number);
errno = saved_errno;
}

View File

@ -99,19 +99,14 @@ DECLARE_SIGNAL_HANDLER(handle_signal)
signal(sig, handle_signal);
#endif
if (sig < 0 || sig >= NSIG) return;
if (caml_try_leave_blocking_section_hook ()) {
caml_raise_if_exception(caml_execute_signal_exn(sig, 1));
caml_enter_blocking_section_hook();
} else {
caml_record_signal(sig);
caml_record_signal(sig);
/* Some ports cache [Caml_state->young_limit] in a register.
Use the signal context to modify that register too, but only if
we are inside OCaml code (not inside C code). */
#if defined(CONTEXT_PC) && defined(CONTEXT_YOUNG_LIMIT)
if (caml_find_code_fragment_by_pc((char *) CONTEXT_PC) != NULL)
CONTEXT_YOUNG_LIMIT = (context_reg) Caml_state->young_limit;
if (caml_find_code_fragment_by_pc((char *) CONTEXT_PC) != NULL)
CONTEXT_YOUNG_LIMIT = (context_reg) Caml_state->young_limit;
#endif
}
errno = saved_errno;
}