From a226dc0bb4f010c248568eb67b0b8e5b768358f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Laban?= Date: Sat, 18 Jan 2020 19:42:37 -0500 Subject: [PATCH] Remove deprecated way of scheduling work on the main thread (#9) --- .../Internal/WasmScheduler.cs | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/System.Reactive.Wasm/Internal/WasmScheduler.cs b/src/System.Reactive.Wasm/Internal/WasmScheduler.cs index 2bc2bf8..74ca11f 100644 --- a/src/System.Reactive.Wasm/Internal/WasmScheduler.cs +++ b/src/System.Reactive.Wasm/Internal/WasmScheduler.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Reactive.Disposables; +using System.Reflection; using System.Runtime.CompilerServices; namespace System.Reactive.Concurrency @@ -126,30 +127,30 @@ public override IDisposable Schedule(TState state, TimeSpan dueTime, Fun // Import from https://github.com/mono/mono/blob/0a8126c2094d2d0800a462d4d0c790d4db421477/mcs/class/corlib/System.Threading/Timer.cs#L39 internal static class WasmRuntime { - private static Dictionary _callbacks; - private static int _nextId; + private static readonly ScheduleTimeoutDelegate _scheduleTimeout; - internal static void ScheduleTimeout(int timeout, Action action) + static WasmRuntime() { - if (_callbacks == null) + // Note that the assembly name must be provided here for mono-wasm AOT to work properly, as + // there is no stack walking available to determine the resolution context. + if (Type.GetType("System.Threading.WasmRuntime, mscorlib") is Type wasmRuntime + && wasmRuntime.GetMethod(nameof(ScheduleTimeout), Reflection.BindingFlags.NonPublic | Reflection.BindingFlags.Static) is MethodInfo scheduleTimeout) { - _callbacks = new Dictionary(); + _scheduleTimeout = (ScheduleTimeoutDelegate)scheduleTimeout.CreateDelegate(typeof(ScheduleTimeoutDelegate)); + } + else + { +#pragma warning disable CA1065 // Do not raise exceptions in unexpected locations. Removed for performance reasons. + throw new NotSupportedException("The currently running version of the runtime does not support this version of the WebAssembly scheduler."); +#pragma warning restore CA1065 // Do not raise exceptions in unexpected locations } - - int id = ++_nextId; - _callbacks[id] = action; - SetTimeout(timeout, id); } - [MethodImpl(MethodImplOptions.InternalCall)] - private static extern void SetTimeout(int timeout, int id); + private delegate void ScheduleTimeoutDelegate(int timeout, Action action); - // XXX Keep this in sync with mini-wasm.c:mono_set_timeout_exec - private static void TimeoutCallback(int id) + internal static void ScheduleTimeout(int timeout, Action action) { - Action cb = _callbacks[id]; - _callbacks.Remove(id); - cb(); + _scheduleTimeout.Invoke(timeout, action); } } }