summaryrefslogtreecommitdiff
path: root/modules/mono
diff options
context:
space:
mode:
authorRémi Verschelde <rverschelde@gmail.com>2023-02-12 22:34:18 +0100
committerRémi Verschelde <rverschelde@gmail.com>2023-02-12 22:34:18 +0100
commit49e8a2fb6698de7e2dd248e8f846824dfbaccdb1 (patch)
tree38f776e146cfc39233d9006abc9c23eb20ffeb9b /modules/mono
parent34cc5fc03f1bd3aca18506422f66ae30aff89544 (diff)
parent103cb4bee6bdcfe793bddab6a7adf960af1f3aad (diff)
Merge pull request #73026 from SirUppyPancakes/sync-context-send
Implement GodotSynchronizationContext.Send
Diffstat (limited to 'modules/mono')
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/GodotSynchronizationContext.cs35
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);
}
}