@@ -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}
0 commit comments