From 5379671cd1be9926937c07b87f86200b7e4dac48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tautvydas=20=C5=BDilys?= Date: Fri, 19 Apr 2019 15:43:54 -0700 Subject: [PATCH 1/4] Fallback to runtime implemented OS specific synchronization context if none is set. --- .../threading/synchronizationcontext.cs | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/mcs/class/referencesource/mscorlib/system/threading/synchronizationcontext.cs b/mcs/class/referencesource/mscorlib/system/threading/synchronizationcontext.cs index 3e092bb3e31b..94c84bbde9d0 100644 --- a/mcs/class/referencesource/mscorlib/system/threading/synchronizationcontext.cs +++ b/mcs/class/referencesource/mscorlib/system/threading/synchronizationcontext.cs @@ -297,6 +297,11 @@ private static SynchronizationContext GetThreadLocalContext() context = AndroidPlatform.GetDefaultSyncContext (); #endif +#if UNITY_AOT + if (context == null) + context = OSSpecificSynchronizationContext.Get(); +#endif + return context; } @@ -375,4 +380,86 @@ private static int InvokeWaitMethodHelper(SynchronizationContext syncContext, In } #endif } + +#if UNITY_AOT + class OSSpecificSynchronizationContext : SynchronizationContext + { + object m_OSSynchronizationContext; + private static readonly ConditionalWeakTable s_ContextCache = new ConditionalWeakTable(); + + private OSSpecificSynchronizationContext(object osContext) + { + m_OSSynchronizationContext = osContext; + } + + public static OSSpecificSynchronizationContext Get() + { + var osContext = GetOSContext(); + if (osContext == null) + return null; + + return s_ContextCache.GetValue(osContext, _osContext => new OSSpecificSynchronizationContext(_osContext)); + } + + public override SynchronizationContext CreateCopy() + { + return new OSSpecificSynchronizationContext(m_OSSynchronizationContext); + } + + public override void Send(SendOrPostCallback d, object state) + { + throw new NotSupportedException(); + } + + public override void Post(SendOrPostCallback d, object state) + { + var callback = Marshal.GetFunctionPointerForDelegate((InvocationEntryDelegate)InvocationEntry); + var invocationContext = new InvocationContext(d, state); + var invocationContextHandle = GCHandle.Alloc(invocationContext); + PostInternal(m_OSSynchronizationContext, callback, GCHandle.ToIntPtr(invocationContextHandle)); + } + + private delegate void InvocationEntryDelegate(IntPtr arg); + + [MonoPInvokeCallback(typeof(InvocationEntryDelegate))] + private static void InvocationEntry(IntPtr arg) + { + var invocationContextHandle = GCHandle.FromIntPtr(arg); + var invocationContext = (InvocationContext)invocationContextHandle.Target; + invocationContextHandle.Free(); + invocationContext.Invoke(); + } + + [AttributeUsage (AttributeTargets.Method)] + sealed class MonoPInvokeCallbackAttribute : Attribute + { + public MonoPInvokeCallbackAttribute(Type t) + { + } + } + + class InvocationContext + { + private SendOrPostCallback m_Delegate; + private object m_State; + + public InvocationContext(SendOrPostCallback d, object state) + { + m_Delegate = d; + m_State = state; + } + + public void Invoke() + { + m_Delegate(m_State); + } + } + + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private extern static object GetOSContext(); + + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private extern static void PostInternal(object osSynchronizationContext, IntPtr callback, IntPtr arg); + } +#endif } From 02c0f70d4f3b6e5f54f509cfc774d6a9e8e5a509 Mon Sep 17 00:00:00 2001 From: Josh Peterson Date: Mon, 19 Apr 2021 13:11:20 -0400 Subject: [PATCH 2/4] "Implement" OSSpecificSynchronizationContext icalls. --- mono/metadata/icall-def.h | 4 ++++ mono/metadata/icall.c | 13 +++++++++++++ mono/metadata/threads-types.h | 6 ++++++ 3 files changed, 23 insertions(+) diff --git a/mono/metadata/icall-def.h b/mono/metadata/icall-def.h index c07299a85d12..85aa97619ef7 100644 --- a/mono/metadata/icall-def.h +++ b/mono/metadata/icall-def.h @@ -1031,6 +1031,10 @@ HANDLES(NATIVEC_3, "OpenEvent_icall", ves_icall_System_Threading_Events_OpenEven NOHANDLES(ICALL(NATIVEC_4, "ResetEvent_internal", ves_icall_System_Threading_Events_ResetEvent_internal)) NOHANDLES(ICALL(NATIVEC_5, "SetEvent_internal", ves_icall_System_Threading_Events_SetEvent_internal)) +ICALL_TYPE(OSSYNCCONTEXT, "System.Threading.OSSpecificSynchronizationContext", OSSYNCCONTEXT_1) +HANDLES(ICALL(OSSYNCCONTEXT_1, "GetOSContext", ves_icall_System_Threading_OSSpecificSynchronizationContext_GetOSContext)) +ICALL(OSSYNCCONTEXT_2, "PostInternal", ves_icall_System_Threading_OSSpecificSynchronizationContext_PostInternal) + ICALL_TYPE(SEMA, "System.Threading.Semaphore", SEMA_1) NOHANDLES(ICALL(SEMA_1, "CreateSemaphore_icall", ves_icall_System_Threading_Semaphore_CreateSemaphore_icall)) NOHANDLES(ICALL(SEMA_2, "OpenSemaphore_icall", ves_icall_System_Threading_Semaphore_OpenSemaphore_icall)) diff --git a/mono/metadata/icall.c b/mono/metadata/icall.c index b87d9dd4d524..03d935417ac2 100644 --- a/mono/metadata/icall.c +++ b/mono/metadata/icall.c @@ -9850,3 +9850,16 @@ ves_icall_System_Net_NetworkInformation_LinuxNetworkChange_CloseNLSocket (gpoint #undef ICALL #undef NOHANDLES #undef MONO_HANDLE_REGISTER_ICALL + +MonoObjectHandle +ves_icall_System_Threading_OSSpecificSynchronizationContext_GetOSContext () +{ + return NULL_HANDLE; +} + +void +ves_icall_System_Threading_OSSpecificSynchronizationContext_PostInternal (gpointer callback, gpointer arg) +{ + /* This isn't actually reachable since ves_icall_System_Threading_OSSpecificSynchronizationContext_GetOSContext always returns NULL */ + mono_set_pending_exception (mono_get_exception_not_implemented ("System.Threading.InteropServices.OSSpecificSynchronizationContext.PostInternal internal call is not implemented.")); +} diff --git a/mono/metadata/threads-types.h b/mono/metadata/threads-types.h index 4ad22c04e394..4939f9a82aae 100644 --- a/mono/metadata/threads-types.h +++ b/mono/metadata/threads-types.h @@ -597,4 +597,10 @@ mono_interlocked_unlock(void) { } #endif +MonoObjectHandle +ves_icall_System_Threading_OSSpecificSynchronizationContext_GetOSContext (); + +void +ves_icall_System_Threading_OSSpecificSynchronizationContext_PostInternal (gpointer callback, gpointer arg); + #endif /* _MONO_METADATA_THREADS_TYPES_H_ */ From e4495a62590dbf2451c6f854619f302a4acaa97f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tautvydas=20=C5=BDilys?= Date: Mon, 22 Apr 2019 15:29:53 -0700 Subject: [PATCH 3/4] Expose an icall to report unhandled exceptions in mscorlib. --- .../referencesource/mscorlib/system/exception.cs | 3 +++ .../system/threading/synchronizationcontext.cs | 15 +++++++++++---- mono/metadata/exception.c | 7 +++++++ mono/metadata/exception.h | 3 +++ mono/metadata/icall-def.h | 3 +++ 5 files changed, 27 insertions(+), 4 deletions(-) diff --git a/mcs/class/referencesource/mscorlib/system/exception.cs b/mcs/class/referencesource/mscorlib/system/exception.cs index 89c57758e963..19a9e6c6c95a 100644 --- a/mcs/class/referencesource/mscorlib/system/exception.cs +++ b/mcs/class/referencesource/mscorlib/system/exception.cs @@ -1138,6 +1138,9 @@ internal Exception FixRemotingException () return this; } + + [MethodImplAttribute(MethodImplOptions.InternalCall)] + internal static extern void ReportUnhandledException(Exception exception); #endif } diff --git a/mcs/class/referencesource/mscorlib/system/threading/synchronizationcontext.cs b/mcs/class/referencesource/mscorlib/system/threading/synchronizationcontext.cs index 94c84bbde9d0..2df1364d2aa9 100644 --- a/mcs/class/referencesource/mscorlib/system/threading/synchronizationcontext.cs +++ b/mcs/class/referencesource/mscorlib/system/threading/synchronizationcontext.cs @@ -424,10 +424,17 @@ public override void Post(SendOrPostCallback d, object state) [MonoPInvokeCallback(typeof(InvocationEntryDelegate))] private static void InvocationEntry(IntPtr arg) { - var invocationContextHandle = GCHandle.FromIntPtr(arg); - var invocationContext = (InvocationContext)invocationContextHandle.Target; - invocationContextHandle.Free(); - invocationContext.Invoke(); + try + { + var invocationContextHandle = GCHandle.FromIntPtr(arg); + var invocationContext = (InvocationContext)invocationContextHandle.Target; + invocationContextHandle.Free(); + invocationContext.Invoke(); + } + catch (Exception e) + { + Exception.ReportUnhandledException(e); + } } [AttributeUsage (AttributeTargets.Method)] diff --git a/mono/metadata/exception.c b/mono/metadata/exception.c index db668d23f658..1f9fe652978c 100644 --- a/mono/metadata/exception.c +++ b/mono/metadata/exception.c @@ -1533,3 +1533,10 @@ mono_error_convert_to_exception_handle (MonoError *error) return is_ok (error) ? MONO_HANDLE_CAST (MonoException, NULL_HANDLE) : MONO_HANDLE_NEW (MonoException, mono_error_convert_to_exception (error)); } + +void +ves_icall_System_Exception_ReportUnhandledException(MonoObject *exc) +{ + mono_unhandled_exception (exc); + mono_invoke_unhandled_exception_hook (exc); +} \ No newline at end of file diff --git a/mono/metadata/exception.h b/mono/metadata/exception.h index 155c23c7e774..bd012adeb6e7 100644 --- a/mono/metadata/exception.h +++ b/mono/metadata/exception.h @@ -172,6 +172,9 @@ typedef void (*MonoUnhandledExceptionFunc) (MonoObject *exc, void *user MONO_API void mono_install_unhandled_exception_hook (MonoUnhandledExceptionFunc func, void *user_data); void mono_invoke_unhandled_exception_hook (MonoObject *exc); +void +ves_icall_System_Exception_ReportUnhandledException (MonoObject *exc); + MONO_END_DECLS #endif /* _MONO_METADATA_EXCEPTION_H_ */ diff --git a/mono/metadata/icall-def.h b/mono/metadata/icall-def.h index 85aa97619ef7..4268026eb1cb 100644 --- a/mono/metadata/icall-def.h +++ b/mono/metadata/icall-def.h @@ -357,6 +357,9 @@ HANDLES(GC_7, "_SuppressFinalize", ves_icall_System_GC_SuppressFinalize, void, 1 HANDLES(GC_9, "get_ephemeron_tombstone", ves_icall_System_GC_get_ephemeron_tombstone, MonoObject, 0, ()) HANDLES(GC_8, "register_ephemeron_array", ves_icall_System_GC_register_ephemeron_array, void, 1, (MonoObject)) +ICALL_TYPE(EXCEPTION, "System.Exception", EXCEPTION_1) +HANDLES(ICALL(EXCEPTION_1, "ReportUnhandledException", ves_icall_System_Exception_ReportUnhandledException)) + ICALL_TYPE(CALDATA, "System.Globalization.CalendarData", CALDATA_1) HANDLES(CALDATA_1, "fill_calendar_data", ves_icall_System_Globalization_CalendarData_fill_calendar_data, MonoBoolean, 3, (MonoCalendarData, MonoString, gint32)) From 2f7052b49838401daf5e45edcae1629f29633226 Mon Sep 17 00:00:00 2001 From: Josh Peterson Date: Tue, 20 Apr 2021 10:34:20 -0400 Subject: [PATCH 4/4] Use the proper icall syntax for new Mono --- mono/metadata/exception.c | 2 +- mono/metadata/icall-def.h | 11 ++++++----- mono/metadata/icall.c | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/mono/metadata/exception.c b/mono/metadata/exception.c index 1f9fe652978c..b514e7ac3102 100644 --- a/mono/metadata/exception.c +++ b/mono/metadata/exception.c @@ -1537,6 +1537,6 @@ mono_error_convert_to_exception_handle (MonoError *error) void ves_icall_System_Exception_ReportUnhandledException(MonoObject *exc) { - mono_unhandled_exception (exc); + mono_unhandled_exception_internal (exc); mono_invoke_unhandled_exception_hook (exc); } \ No newline at end of file diff --git a/mono/metadata/icall-def.h b/mono/metadata/icall-def.h index 4268026eb1cb..db60b2e16274 100644 --- a/mono/metadata/icall-def.h +++ b/mono/metadata/icall-def.h @@ -343,6 +343,10 @@ HANDLES(ENV_17, "internalGetEnvironmentVariable_native", ves_icall_System_Enviro HANDLES(ENV_18, "internalGetGacPath", ves_icall_System_Environment_GetGacPath, MonoString, 0, ()) HANDLES(ENV_19, "internalGetHome", ves_icall_System_Environment_InternalGetHome, MonoString, 0, ()) NOHANDLES(ICALL(ENV_20, "set_ExitCode", mono_environment_exitcode_set)) + +ICALL_TYPE(EXCEPTION, "System.Exception", EXCEPTION_1) +NOHANDLES(ICALL(EXCEPTION_1, "ReportUnhandledException", ves_icall_System_Exception_ReportUnhandledException)) + ICALL_TYPE(GC, "System.GC", GC_10) NOHANDLES(ICALL(GC_10, "GetAllocatedBytesForCurrentThread", ves_icall_System_GC_GetAllocatedBytesForCurrentThread)) NOHANDLES(ICALL(GC_0, "GetCollectionCount", ves_icall_System_GC_GetCollectionCount)) @@ -357,9 +361,6 @@ HANDLES(GC_7, "_SuppressFinalize", ves_icall_System_GC_SuppressFinalize, void, 1 HANDLES(GC_9, "get_ephemeron_tombstone", ves_icall_System_GC_get_ephemeron_tombstone, MonoObject, 0, ()) HANDLES(GC_8, "register_ephemeron_array", ves_icall_System_GC_register_ephemeron_array, void, 1, (MonoObject)) -ICALL_TYPE(EXCEPTION, "System.Exception", EXCEPTION_1) -HANDLES(ICALL(EXCEPTION_1, "ReportUnhandledException", ves_icall_System_Exception_ReportUnhandledException)) - ICALL_TYPE(CALDATA, "System.Globalization.CalendarData", CALDATA_1) HANDLES(CALDATA_1, "fill_calendar_data", ves_icall_System_Globalization_CalendarData_fill_calendar_data, MonoBoolean, 3, (MonoCalendarData, MonoString, gint32)) @@ -1035,8 +1036,8 @@ NOHANDLES(ICALL(NATIVEC_4, "ResetEvent_internal", ves_icall_System_Threading_Ev NOHANDLES(ICALL(NATIVEC_5, "SetEvent_internal", ves_icall_System_Threading_Events_SetEvent_internal)) ICALL_TYPE(OSSYNCCONTEXT, "System.Threading.OSSpecificSynchronizationContext", OSSYNCCONTEXT_1) -HANDLES(ICALL(OSSYNCCONTEXT_1, "GetOSContext", ves_icall_System_Threading_OSSpecificSynchronizationContext_GetOSContext)) -ICALL(OSSYNCCONTEXT_2, "PostInternal", ves_icall_System_Threading_OSSpecificSynchronizationContext_PostInternal) +NOHANDLES(ICALL(OSSYNCCONTEXT_1, "GetOSContext", ves_icall_System_Threading_OSSpecificSynchronizationContext_GetOSContext)) +NOHANDLES(ICALL(OSSYNCCONTEXT_2, "PostInternal", ves_icall_System_Threading_OSSpecificSynchronizationContext_PostInternal)) ICALL_TYPE(SEMA, "System.Threading.Semaphore", SEMA_1) NOHANDLES(ICALL(SEMA_1, "CreateSemaphore_icall", ves_icall_System_Threading_Semaphore_CreateSemaphore_icall)) diff --git a/mono/metadata/icall.c b/mono/metadata/icall.c index 03d935417ac2..1a647c9520db 100644 --- a/mono/metadata/icall.c +++ b/mono/metadata/icall.c @@ -9861,5 +9861,5 @@ void ves_icall_System_Threading_OSSpecificSynchronizationContext_PostInternal (gpointer callback, gpointer arg) { /* This isn't actually reachable since ves_icall_System_Threading_OSSpecificSynchronizationContext_GetOSContext always returns NULL */ - mono_set_pending_exception (mono_get_exception_not_implemented ("System.Threading.InteropServices.OSSpecificSynchronizationContext.PostInternal internal call is not implemented.")); + mono_set_pending_exception (mono_exception_from_name_msg (mono_get_corlib (), "System", "NotImplementedException", "System.Threading.InteropServices.OSSpecificSynchronizationContext.PostInternal internal call is not implemented.")); }