Skip to content

Commit 7dd133f

Browse files
author
Joshua Peterson
authored
Merge pull request #1429 from Unity-Technologies/mono-upgrade-synchronization-context
Restore Mono runtime and class library OS synchronization context changes
2 parents e3979d9 + 2f7052b commit 7dd133f

File tree

7 files changed

+134
-0
lines changed

7 files changed

+134
-0
lines changed

mcs/class/referencesource/mscorlib/system/exception.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,6 +1138,9 @@ internal Exception FixRemotingException ()
11381138

11391139
return this;
11401140
}
1141+
1142+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
1143+
internal static extern void ReportUnhandledException(Exception exception);
11411144
#endif
11421145
}
11431146

mcs/class/referencesource/mscorlib/system/threading/synchronizationcontext.cs

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,11 @@ private static SynchronizationContext GetThreadLocalContext()
297297
context = AndroidPlatform.GetDefaultSyncContext ();
298298
#endif
299299

300+
#if UNITY_AOT
301+
if (context == null)
302+
context = OSSpecificSynchronizationContext.Get();
303+
#endif
304+
300305
return context;
301306
}
302307

@@ -375,4 +380,93 @@ private static int InvokeWaitMethodHelper(SynchronizationContext syncContext, In
375380
}
376381
#endif
377382
}
383+
384+
#if UNITY_AOT
385+
class OSSpecificSynchronizationContext : SynchronizationContext
386+
{
387+
object m_OSSynchronizationContext;
388+
private static readonly ConditionalWeakTable<object, OSSpecificSynchronizationContext> s_ContextCache = new ConditionalWeakTable<object, OSSpecificSynchronizationContext>();
389+
390+
private OSSpecificSynchronizationContext(object osContext)
391+
{
392+
m_OSSynchronizationContext = osContext;
393+
}
394+
395+
public static OSSpecificSynchronizationContext Get()
396+
{
397+
var osContext = GetOSContext();
398+
if (osContext == null)
399+
return null;
400+
401+
return s_ContextCache.GetValue(osContext, _osContext => new OSSpecificSynchronizationContext(_osContext));
402+
}
403+
404+
public override SynchronizationContext CreateCopy()
405+
{
406+
return new OSSpecificSynchronizationContext(m_OSSynchronizationContext);
407+
}
408+
409+
public override void Send(SendOrPostCallback d, object state)
410+
{
411+
throw new NotSupportedException();
412+
}
413+
414+
public override void Post(SendOrPostCallback d, object state)
415+
{
416+
var callback = Marshal.GetFunctionPointerForDelegate((InvocationEntryDelegate)InvocationEntry);
417+
var invocationContext = new InvocationContext(d, state);
418+
var invocationContextHandle = GCHandle.Alloc(invocationContext);
419+
PostInternal(m_OSSynchronizationContext, callback, GCHandle.ToIntPtr(invocationContextHandle));
420+
}
421+
422+
private delegate void InvocationEntryDelegate(IntPtr arg);
423+
424+
[MonoPInvokeCallback(typeof(InvocationEntryDelegate))]
425+
private static void InvocationEntry(IntPtr arg)
426+
{
427+
try
428+
{
429+
var invocationContextHandle = GCHandle.FromIntPtr(arg);
430+
var invocationContext = (InvocationContext)invocationContextHandle.Target;
431+
invocationContextHandle.Free();
432+
invocationContext.Invoke();
433+
}
434+
catch (Exception e)
435+
{
436+
Exception.ReportUnhandledException(e);
437+
}
438+
}
439+
440+
[AttributeUsage (AttributeTargets.Method)]
441+
sealed class MonoPInvokeCallbackAttribute : Attribute
442+
{
443+
public MonoPInvokeCallbackAttribute(Type t)
444+
{
445+
}
446+
}
447+
448+
class InvocationContext
449+
{
450+
private SendOrPostCallback m_Delegate;
451+
private object m_State;
452+
453+
public InvocationContext(SendOrPostCallback d, object state)
454+
{
455+
m_Delegate = d;
456+
m_State = state;
457+
}
458+
459+
public void Invoke()
460+
{
461+
m_Delegate(m_State);
462+
}
463+
}
464+
465+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
466+
private extern static object GetOSContext();
467+
468+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
469+
private extern static void PostInternal(object osSynchronizationContext, IntPtr callback, IntPtr arg);
470+
}
471+
#endif
378472
}

mono/metadata/exception.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1533,3 +1533,10 @@ mono_error_convert_to_exception_handle (MonoError *error)
15331533
return is_ok (error) ? MONO_HANDLE_CAST (MonoException, NULL_HANDLE)
15341534
: MONO_HANDLE_NEW (MonoException, mono_error_convert_to_exception (error));
15351535
}
1536+
1537+
void
1538+
ves_icall_System_Exception_ReportUnhandledException(MonoObject *exc)
1539+
{
1540+
mono_unhandled_exception_internal (exc);
1541+
mono_invoke_unhandled_exception_hook (exc);
1542+
}

mono/metadata/exception.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,9 @@ typedef void (*MonoUnhandledExceptionFunc) (MonoObject *exc, void *user
172172
MONO_API void mono_install_unhandled_exception_hook (MonoUnhandledExceptionFunc func, void *user_data);
173173
void mono_invoke_unhandled_exception_hook (MonoObject *exc);
174174

175+
void
176+
ves_icall_System_Exception_ReportUnhandledException (MonoObject *exc);
177+
175178
MONO_END_DECLS
176179

177180
#endif /* _MONO_METADATA_EXCEPTION_H_ */

mono/metadata/icall-def.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,10 @@ HANDLES(ENV_17, "internalGetEnvironmentVariable_native", ves_icall_System_Enviro
343343
HANDLES(ENV_18, "internalGetGacPath", ves_icall_System_Environment_GetGacPath, MonoString, 0, ())
344344
HANDLES(ENV_19, "internalGetHome", ves_icall_System_Environment_InternalGetHome, MonoString, 0, ())
345345
NOHANDLES(ICALL(ENV_20, "set_ExitCode", mono_environment_exitcode_set))
346+
347+
ICALL_TYPE(EXCEPTION, "System.Exception", EXCEPTION_1)
348+
NOHANDLES(ICALL(EXCEPTION_1, "ReportUnhandledException", ves_icall_System_Exception_ReportUnhandledException))
349+
346350
ICALL_TYPE(GC, "System.GC", GC_10)
347351
NOHANDLES(ICALL(GC_10, "GetAllocatedBytesForCurrentThread", ves_icall_System_GC_GetAllocatedBytesForCurrentThread))
348352
NOHANDLES(ICALL(GC_0, "GetCollectionCount", ves_icall_System_GC_GetCollectionCount))
@@ -1031,6 +1035,10 @@ HANDLES(NATIVEC_3, "OpenEvent_icall", ves_icall_System_Threading_Events_OpenEven
10311035
NOHANDLES(ICALL(NATIVEC_4, "ResetEvent_internal", ves_icall_System_Threading_Events_ResetEvent_internal))
10321036
NOHANDLES(ICALL(NATIVEC_5, "SetEvent_internal", ves_icall_System_Threading_Events_SetEvent_internal))
10331037

1038+
ICALL_TYPE(OSSYNCCONTEXT, "System.Threading.OSSpecificSynchronizationContext", OSSYNCCONTEXT_1)
1039+
NOHANDLES(ICALL(OSSYNCCONTEXT_1, "GetOSContext", ves_icall_System_Threading_OSSpecificSynchronizationContext_GetOSContext))
1040+
NOHANDLES(ICALL(OSSYNCCONTEXT_2, "PostInternal", ves_icall_System_Threading_OSSpecificSynchronizationContext_PostInternal))
1041+
10341042
ICALL_TYPE(SEMA, "System.Threading.Semaphore", SEMA_1)
10351043
NOHANDLES(ICALL(SEMA_1, "CreateSemaphore_icall", ves_icall_System_Threading_Semaphore_CreateSemaphore_icall))
10361044
NOHANDLES(ICALL(SEMA_2, "OpenSemaphore_icall", ves_icall_System_Threading_Semaphore_OpenSemaphore_icall))

mono/metadata/icall.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9850,3 +9850,16 @@ ves_icall_System_Net_NetworkInformation_LinuxNetworkChange_CloseNLSocket (gpoint
98509850
#undef ICALL
98519851
#undef NOHANDLES
98529852
#undef MONO_HANDLE_REGISTER_ICALL
9853+
9854+
MonoObjectHandle
9855+
ves_icall_System_Threading_OSSpecificSynchronizationContext_GetOSContext ()
9856+
{
9857+
return NULL_HANDLE;
9858+
}
9859+
9860+
void
9861+
ves_icall_System_Threading_OSSpecificSynchronizationContext_PostInternal (gpointer callback, gpointer arg)
9862+
{
9863+
/* This isn't actually reachable since ves_icall_System_Threading_OSSpecificSynchronizationContext_GetOSContext always returns NULL */
9864+
mono_set_pending_exception (mono_exception_from_name_msg (mono_get_corlib (), "System", "NotImplementedException", "System.Threading.InteropServices.OSSpecificSynchronizationContext.PostInternal internal call is not implemented."));
9865+
}

mono/metadata/threads-types.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,4 +597,10 @@ mono_interlocked_unlock(void) {
597597
}
598598
#endif
599599

600+
MonoObjectHandle
601+
ves_icall_System_Threading_OSSpecificSynchronizationContext_GetOSContext ();
602+
603+
void
604+
ves_icall_System_Threading_OSSpecificSynchronizationContext_PostInternal (gpointer callback, gpointer arg);
605+
600606
#endif /* _MONO_METADATA_THREADS_TYPES_H_ */

0 commit comments

Comments
 (0)