summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXavier Leroy <xavier.leroy@inria.fr>2005-10-12 12:33:47 +0000
committerXavier Leroy <xavier.leroy@inria.fr>2005-10-12 12:33:47 +0000
commitb7e2234b9a520c59ff889c55bc81b356bdc9ba36 (patch)
treed536398ea4c709456c39343326e769a2561e51bc
parent0353fedc2d2514ca0a46637bbb079cb78c9e4ee5 (diff)
Suite nettoyage signaux (pour Win32)
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@7115 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
-rw-r--r--asmrun/signals.c31
-rw-r--r--byterun/signals.c16
-rw-r--r--byterun/signals.h1
-rw-r--r--byterun/win32.c19
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);