From 103cb4bee6bdcfe793bddab6a7adf960af1f3aad Mon Sep 17 00:00:00 2001 From: Caleb Kemper Date: Sat, 11 Feb 2023 01:30:25 -0700 Subject: Implement GodotSynchronizationContext.Send --- .../GodotSharp/Core/GodotSynchronizationContext.cs | 35 +++++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) (limited to 'modules/mono') diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotSynchronizationContext.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotSynchronizationContext.cs index 027eab30fc..79030c79cc 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotSynchronizationContext.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotSynchronizationContext.cs @@ -1,17 +1,44 @@ using System; using System.Collections.Concurrent; -using System.Collections.Generic; using System.Threading; +using System.Threading.Tasks; namespace Godot { public sealed class GodotSynchronizationContext : SynchronizationContext, IDisposable { - private readonly BlockingCollection> _queue = new(); + private readonly BlockingCollection<(SendOrPostCallback Callback, object State)> _queue = new(); + + public override void Send(SendOrPostCallback d, object state) + { + // Shortcut if we're already on this context + // Also necessary to avoid a deadlock, since Send is blocking + if (Current == this) + { + d(state); + return; + } + + var source = new TaskCompletionSource(); + + _queue.Add((st => + { + try + { + d(st); + } + finally + { + source.SetResult(); + } + }, state)); + + source.Task.Wait(); + } public override void Post(SendOrPostCallback d, object state) { - _queue.Add(new KeyValuePair(d, state)); + _queue.Add((d, state)); } /// @@ -21,7 +48,7 @@ namespace Godot { while (_queue.TryTake(out var workItem)) { - workItem.Key(workItem.Value); + workItem.Callback(workItem.State); } } -- cgit v1.2.3