Permalink
Browse files

Fixed the console sigint deadlock, by queuing execution in the finali…

…zer 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.
  • Loading branch information...
1 parent d3985be commit 96880dc3e7fb9a87aa6c18c0e08595af70103d30 @illupus illupus committed Oct 12, 2010
@@ -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;
@@ -11,6 +11,7 @@
#include <mono/metadata/object-internals.h>
#include <mono/metadata/class-internals.h>
#include <mono/metadata/domain-internals.h>
+#include <mono/metadata/gc-internal.h>
#include <mono/metadata/console-io.h>
#include <mono/metadata/exception.h>
@@ -20,6 +21,11 @@ mono_console_init (void)
{
}
+void
+mono_console_handle_async_ops (void)
+{
+}
+
MonoBoolean
ves_icall_System_ConsoleDriver_Isatty (HANDLE handle)
{
@@ -28,6 +28,7 @@
#include <mono/metadata/object-internals.h>
#include <mono/metadata/class-internals.h>
#include <mono/metadata/domain-internals.h>
+#include <mono/metadata/gc-internal.h>
#include <mono/metadata/metadata.h>
#include <mono/metadata/threadpool.h>
@@ -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;
}
@@ -24,6 +24,7 @@
#include <mono/metadata/object-internals.h>
#include <mono/metadata/class-internals.h>
#include <mono/metadata/domain-internals.h>
+#include <mono/metadata/gc-internal.h>
#include <mono/metadata/metadata.h>
#include <mono/metadata/threadpool.h>
@@ -35,6 +36,11 @@ mono_console_init (void)
{
}
+void
+mono_console_handle_async_ops (void)
+{
+}
+
MonoBoolean
ves_icall_System_ConsoleDriver_Isatty (HANDLE handle)
{
View
@@ -27,6 +27,7 @@
#include <mono/metadata/gc-internal.h>
#include <mono/metadata/marshal.h> /* for mono_delegate_free_ftnptr () */
#include <mono/metadata/attach.h>
+#include <mono/metadata/console-io.h>
#include <mono/utils/mono-semaphore.h>
#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

0 comments on commit 96880dc

Please sign in to comment.