diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2023-02-12 22:34:18 +0100 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2023-02-12 22:34:18 +0100 |
commit | 49e8a2fb6698de7e2dd248e8f846824dfbaccdb1 (patch) | |
tree | 38f776e146cfc39233d9006abc9c23eb20ffeb9b | |
parent | 34cc5fc03f1bd3aca18506422f66ae30aff89544 (diff) | |
parent | 103cb4bee6bdcfe793bddab6a7adf960af1f3aad (diff) |
Merge pull request #73026 from SirUppyPancakes/sync-context-send
Implement GodotSynchronizationContext.Send
-rw-r--r-- | modules/mono/glue/GodotSharp/GodotSharp/Core/GodotSynchronizationContext.cs | 35 |
1 files changed, 31 insertions, 4 deletions
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<KeyValuePair<SendOrPostCallback, object>> _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<SendOrPostCallback, object>(d, state)); + _queue.Add((d, state)); } /// <summary> @@ -21,7 +48,7 @@ namespace Godot { while (_queue.TryTake(out var workItem)) { - workItem.Key(workItem.Value); + workItem.Callback(workItem.State); } } |