#include <mono/metadata/metadata-internals.h>
#include <mono/metadata/mono-mlist.h>
#include <mono/metadata/threadpool.h>
+#include <mono/metadata/threadpool-internals.h>
#include <mono/metadata/threads-types.h>
#include <mono/utils/mono-logger-internal.h>
#include <mono/metadata/gc-internal.h>
runtime_invoke (o, NULL, &exc, NULL);
- if (exc) {
- /* fixme: do something useful */
- }
+ if (exc)
+ mono_internal_thread_unhandled_exception (exc);
mono_domain_set_internal (caller_domain);
}
void mono_thread_pool_remove_socket (int sock) MONO_INTERNAL;
gboolean mono_thread_pool_is_queue_array (MonoArray *o) MONO_INTERNAL;
+void mono_internal_thread_unhandled_exception (MonoObject* exc) MONO_INTERNAL;
#endif
exc = mono_async_invoke (tp, ar);
if (tp_item_end_func)
tp_item_end_func (tp_item_user_data);
- if (exc && mono_runtime_unhandled_exception_policy_get () == MONO_UNHANDLED_POLICY_CURRENT) {
- gboolean unloaded;
- MonoClass *klass;
-
- klass = exc->vtable->klass;
- unloaded = is_appdomainunloaded_exception (exc->vtable->domain, klass);
- if (!unloaded && klass != mono_defaults.threadabortexception_class) {
- mono_unhandled_exception (exc);
- if (mono_environment_exitcode_get () == 1)
- exit (255);
- }
- if (klass == mono_defaults.threadabortexception_class)
- mono_thread_internal_reset_abort (thread);
- }
+ if (exc)
+ mono_internal_thread_unhandled_exception (exc);
if (is_socket && tp->is_io) {
MonoSocketAsyncResult *state = (MonoSocketAsyncResult *) data;
tp_item_user_data = user_data;
}
+void
+mono_internal_thread_unhandled_exception (MonoObject* exc)
+{
+ if (mono_runtime_unhandled_exception_policy_get () == MONO_UNHANDLED_POLICY_CURRENT) {
+ gboolean unloaded;
+ MonoClass *klass;
+
+ klass = exc->vtable->klass;
+ unloaded = is_appdomainunloaded_exception (exc->vtable->domain, klass);
+ if (!unloaded && klass != mono_defaults.threadabortexception_class) {
+ mono_unhandled_exception (exc);
+ if (mono_environment_exitcode_get () == 1)
+ exit (255);
+ }
+ if (klass == mono_defaults.threadabortexception_class)
+ mono_thread_internal_reset_abort (mono_thread_internal_current ());
+ }
+}
finalizer-abort.cs \
finalizer-exception.cs \
finalizer-exit.cs \
+ finalizer-thread.cs \
main-exit.cs \
main-returns-abort-resetabort.cs \
main-returns-background-abort-resetabort.cs \
-
-using System;
-using System.Collections;
+using System;
using System.Threading;
-public class foo {
- public static LocalDataStoreSlot dataslot = Thread.AllocateDataSlot();
- public static int final_count=0;
+public class FinalizerException {
+ ~FinalizerException () {
+ throw new Exception ();
+ }
- ~foo() {
- // Demonstrate that this is still the same thread
- string ID=(string)Thread.GetData(dataslot);
- if(ID==null) {
- Console.WriteLine("Set ID: foo");
- Thread.SetData(dataslot, "foo");
- }
+ public static int Main () {
+ AppDomain.CurrentDomain.UnhandledException += (sender, args) => {
+ Console.WriteLine ("caught");
+ Environment.Exit (0);
+ };
- // Don't run forever
- if(final_count++>10) {
- Environment.Exit(0);
- }
+ new FinalizerException ();
- Console.WriteLine("finalizer thread ID: {0}", (string)Thread.GetData(dataslot));
- throw new SystemException("wibble");
- }
+ GC.Collect ();
+ GC.WaitForPendingFinalizers ();
- public static int Main() {
- ArrayList list = new ArrayList ();
- Thread.SetData(dataslot, "ID is wibble");
- Environment.ExitCode = 2;
- while(true) {
- foo instance = new foo();
- list.Add (new WeakReference(instance));
- Thread.Sleep (0);
- }
- return 1;
- }
-}
+ Thread.Sleep (Timeout.Infinite); // infinite wait so we don't race against the unhandled exception callback
+ return 2;
+ }
+}
--- /dev/null
+
+using System;
+using System.Collections;
+using System.Threading;
+
+public class foo {
+ public static LocalDataStoreSlot dataslot = Thread.AllocateDataSlot();
+ public static int final_count=0;
+
+ ~foo() {
+ // Demonstrate that this is still the same thread
+ string ID=(string)Thread.GetData(dataslot);
+ if(ID==null) {
+ Console.WriteLine("Set ID: foo");
+ Thread.SetData(dataslot, "foo");
+ }
+
+ // Don't run forever
+ if(final_count++>10) {
+ Environment.Exit(0);
+ }
+
+ Console.WriteLine("finalizer thread ID: {0}", (string)Thread.GetData(dataslot));
+
+ if ((string)Thread.GetData(dataslot) != "foo")
+ throw new Exception ();
+ }
+
+ public static int Main() {
+ ArrayList list = new ArrayList ();
+ Thread.SetData(dataslot, "ID is wibble");
+ Environment.ExitCode = 2;
+ while(true) {
+ foo instance = new foo();
+ list.Add (new WeakReference(instance));
+ Thread.Sleep (0);
+ }
+ return 1;
+ }
+}
+