From 96880dc3e7fb9a87aa6c18c0e08595af70103d30 Mon Sep 17 00:00:00 2001 From: Paolo Molaro Date: Tue, 12 Oct 2010 17:08:42 +0200 Subject: [PATCH] Fixed the console sigint deadlock, by queuing execution in the finalizer thread. * console-io.h, console-null.c, console-unix.c, console-win32.c, gc.c: instead of executing tons of managed code in signal context, we wake up the finalizer thread and any complex console-specific code will be handled there. This can cause a (usually small) delay, but it's much better than deadlocking. --- mono/metadata/console-io.h | 1 + mono/metadata/console-null.c | 6 ++++++ mono/metadata/console-unix.c | 16 +++++++++++++++- mono/metadata/console-win32.c | 6 ++++++ mono/metadata/gc.c | 3 +++ 5 files changed, 31 insertions(+), 1 deletion(-) diff --git a/mono/metadata/console-io.h b/mono/metadata/console-io.h index 46bfe44aaef..a7ef7686b68 100644 --- a/mono/metadata/console-io.h +++ b/mono/metadata/console-io.h @@ -19,6 +19,7 @@ G_BEGIN_DECLS void mono_console_init (void) MONO_INTERNAL; +void mono_console_handle_async_ops (void) MONO_INTERNAL; MonoBoolean ves_icall_System_ConsoleDriver_Isatty (HANDLE handle) MONO_INTERNAL; gint32 ves_icall_System_ConsoleDriver_InternalKeyAvailable (gint32 timeout) MONO_INTERNAL; MonoBoolean ves_icall_System_ConsoleDriver_SetEcho (MonoBoolean echo) MONO_INTERNAL; diff --git a/mono/metadata/console-null.c b/mono/metadata/console-null.c index a50b2a37d20..a2e1486c084 100644 --- a/mono/metadata/console-null.c +++ b/mono/metadata/console-null.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -20,6 +21,11 @@ mono_console_init (void) { } +void +mono_console_handle_async_ops (void) +{ +} + MonoBoolean ves_icall_System_ConsoleDriver_Isatty (HANDLE handle) { diff --git a/mono/metadata/console-unix.c b/mono/metadata/console-unix.c index a6c86d12718..aae513f1a02 100644 --- a/mono/metadata/console-unix.c +++ b/mono/metadata/console-unix.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -231,6 +232,7 @@ do_console_cancel_event (void) MonoMethod *im; MonoVTable *vtable; + /* FIXME: this should likely iterate all the domains, instead */ if (!domain->domain) return; @@ -258,6 +260,17 @@ do_console_cancel_event (void) mono_thread_pool_add ((MonoObject *) load_value, msg, NULL, NULL); } +static int need_cancel = FALSE; +/* this is executed from the finalizer thread */ +void +mono_console_handle_async_ops (void) +{ + if (need_cancel) { + need_cancel = FALSE; + do_console_cancel_event (); + } +} + static gboolean in_sigint; static void sigint_handler (int signo) @@ -270,7 +283,8 @@ sigint_handler (int signo) in_sigint = TRUE; save_errno = errno; - do_console_cancel_event (); + need_cancel = TRUE; + mono_gc_finalize_notify (); errno = save_errno; in_sigint = FALSE; } diff --git a/mono/metadata/console-win32.c b/mono/metadata/console-win32.c index 56180991796..6b940f3edfb 100644 --- a/mono/metadata/console-win32.c +++ b/mono/metadata/console-win32.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -35,6 +36,11 @@ mono_console_init (void) { } +void +mono_console_handle_async_ops (void) +{ +} + MonoBoolean ves_icall_System_ConsoleDriver_Isatty (HANDLE handle) { diff --git a/mono/metadata/gc.c b/mono/metadata/gc.c index 718fdbf05e7..83064485e73 100644 --- a/mono/metadata/gc.c +++ b/mono/metadata/gc.c @@ -27,6 +27,7 @@ #include #include /* for mono_delegate_free_ftnptr () */ #include +#include #include #ifndef HOST_WIN32 @@ -1043,6 +1044,8 @@ finalizer_thread (gpointer unused) WaitForSingleObjectEx (finalizer_event, INFINITE, FALSE); #endif + mono_console_handle_async_ops (); + #ifndef DISABLE_ATTACH mono_attach_maybe_start (); #endif -- 2.25.1