From 5000ae3de50d1a99383b2643594d27a5c8cbcca1 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/3] 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 4c5290eb74a0..029464a42ec1 100644 --- a/mcs/class/referencesource/mscorlib/system/threading/synchronizationcontext.cs +++ b/mcs/class/referencesource/mscorlib/system/threading/synchronizationcontext.cs @@ -293,6 +293,11 @@ private static SynchronizationContext GetThreadLocalContext() context = AndroidPlatform.GetDefaultSyncContext (); #endif +#if UNITY_AOT + if (context == null) + context = OSSpecificSynchronizationContext.Get(); +#endif + return context; } @@ -371,4 +376,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 b022c9b34bc15f5c2883455699937082460f3849 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tautvydas=20=C5=BDilys?= Date: Fri, 19 Apr 2019 17:39:49 -0700 Subject: [PATCH 2/3] "Implement" OSSpecificSynchronizationContext icalls. --- mono/metadata/icall-def.h | 4 ++++ mono/metadata/icall.c | 12 ++++++++++++ mono/metadata/threads-types.h | 6 ++++++ 3 files changed, 22 insertions(+) diff --git a/mono/metadata/icall-def.h b/mono/metadata/icall-def.h index 4e6d11f6a542..e324a20260f8 100644 --- a/mono/metadata/icall-def.h +++ b/mono/metadata/icall-def.h @@ -935,6 +935,10 @@ HANDLES(ICALL(NATIVEC_3, "OpenEvent_internal(string,System.Security.AccessContro ICALL(NATIVEC_4, "ResetEvent_internal", ves_icall_System_Threading_Events_ResetEvent_internal) 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) ICALL(SEMA_1, "CreateSemaphore_internal(int,int,string,int&)", ves_icall_System_Threading_Semaphore_CreateSemaphore_internal) ICALL(SEMA_2, "OpenSemaphore_internal(string,System.Security.AccessControl.SemaphoreRights,int&)", ves_icall_System_Threading_Semaphore_OpenSemaphore_internal) diff --git a/mono/metadata/icall.c b/mono/metadata/icall.c index befabf51c486..8bedfdb678e0 100644 --- a/mono/metadata/icall.c +++ b/mono/metadata/icall.c @@ -8751,3 +8751,15 @@ mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignatu return mono_register_jit_icall_full (func, name, sig, no_wrapper, NULL); } +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 4189f7a75094..2fcf55787083 100644 --- a/mono/metadata/threads-types.h +++ b/mono/metadata/threads-types.h @@ -267,4 +267,10 @@ mono_thread_internal_describe (MonoInternalThread *internal, GString *str); gboolean mono_thread_internal_is_current (MonoInternalThread *internal); +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 4b9c1a272332f16d3d208ca219dc6e7eb7fc84b8 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/3] 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 a539756ee162..81e472443d7d 100644 --- a/mcs/class/referencesource/mscorlib/system/exception.cs +++ b/mcs/class/referencesource/mscorlib/system/exception.cs @@ -1114,6 +1114,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 029464a42ec1..9e43efdd2811 100644 --- a/mcs/class/referencesource/mscorlib/system/threading/synchronizationcontext.cs +++ b/mcs/class/referencesource/mscorlib/system/threading/synchronizationcontext.cs @@ -420,10 +420,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 61fde6541757..9ee13f95a145 100644 --- a/mono/metadata/exception.c +++ b/mono/metadata/exception.c @@ -1183,3 +1183,10 @@ mono_exception_from_name_four_strings_checked (MonoImage *image, const char *nam return create_exception_four_strings (klass, a1, a2, a3, a4, 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 6575694c7c50..f53a2c8f4597 100644 --- a/mono/metadata/exception.h +++ b/mono/metadata/exception.h @@ -161,6 +161,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 e324a20260f8..8efe62c3f347 100644 --- a/mono/metadata/icall-def.h +++ b/mono/metadata/icall-def.h @@ -293,6 +293,9 @@ HANDLES(ICALL(ENV_18, "internalGetGacPath", ves_icall_System_Environment_GetGacP HANDLES(ICALL(ENV_19, "internalGetHome", ves_icall_System_Environment_InternalGetHome)) ICALL(ENV_20, "set_ExitCode", mono_environment_exitcode_set) +ICALL_TYPE(EXCEPTION, "System.Exception", EXCEPTION_1) +HANDLES(ICALL(EXCEPTION_1, "ReportUnhandledException", ves_icall_System_Exception_ReportUnhandledException)) + ICALL_TYPE(GC, "System.GC", GC_0) ICALL(GC_0, "GetCollectionCount", mono_gc_collection_count) ICALL(GC_0a, "GetGeneration", mono_gc_get_generation)