From 8cced4c1d7bece877a12cf69d0f1448a5b352c01 Mon Sep 17 00:00:00 2001 From: Kaz Wolfe Date: Mon, 25 Aug 2025 13:31:05 -0700 Subject: [PATCH] fix: use channel threadlocal instead of a ThreadStatic --- Dalamud/Plugin/Ipc/Internal/CallGateChannel.cs | 18 ++++++++++++++++++ .../Plugin/Ipc/Internal/CallGatePubSubBase.cs | 11 ++++------- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/Dalamud/Plugin/Ipc/Internal/CallGateChannel.cs b/Dalamud/Plugin/Ipc/Internal/CallGateChannel.cs index 698f0917e..e177abab7 100644 --- a/Dalamud/Plugin/Ipc/Internal/CallGateChannel.cs +++ b/Dalamud/Plugin/Ipc/Internal/CallGateChannel.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using System.Reflection; +using System.Threading; using Dalamud.Plugin.Internal.Types; using Dalamud.Plugin.Ipc.Exceptions; @@ -17,6 +18,8 @@ namespace Dalamud.Plugin.Ipc.Internal; /// internal class CallGateChannel { + private readonly ThreadLocal ipcExecutionContext = new(); + /// /// The actual storage. /// @@ -146,6 +149,21 @@ internal class CallGateChannel return (TRet)result; } + internal void SetInvocationContext(IpcContext ipcContext) + { + this.ipcExecutionContext.Value = ipcContext; + } + + internal IpcContext? GetInvocationContext() + { + return this.ipcExecutionContext.IsValueCreated ? this.ipcExecutionContext.Value : null; + } + + internal void ClearInvocationContext() + { + this.ipcExecutionContext.Value = null; + } + private void CheckAndConvertArgs(object?[]? args, MethodInfo methodInfo) { var paramTypes = methodInfo.GetParameters() diff --git a/Dalamud/Plugin/Ipc/Internal/CallGatePubSubBase.cs b/Dalamud/Plugin/Ipc/Internal/CallGatePubSubBase.cs index 24cb5ca11..521824b7b 100644 --- a/Dalamud/Plugin/Ipc/Internal/CallGatePubSubBase.cs +++ b/Dalamud/Plugin/Ipc/Internal/CallGatePubSubBase.cs @@ -14,9 +14,6 @@ namespace Dalamud.Plugin.Ipc.Internal; /// internal abstract class CallGatePubSubBase { - [ThreadStatic] - private static IpcContext? ipcExecutionContext; - /// /// Initializes a new instance of the class. /// @@ -77,7 +74,7 @@ internal abstract class CallGatePubSubBase /// Returns a potential IPC context. public IpcContext? GetContext() { - return ipcExecutionContext; + return this.Channel.GetInvocationContext(); } /// @@ -172,11 +169,11 @@ internal abstract class CallGatePubSubBase private IDisposable BuildContext() { - ipcExecutionContext = new IpcContext + this.Channel.SetInvocationContext(new IpcContext { SourcePlugin = this.OwningPlugin != null ? new ExposedPlugin(this.OwningPlugin) : null, - }; + }); - return Disposable.Create(() => { ipcExecutionContext = null; }); + return Disposable.Create(() => { this.Channel.ClearInvocationContext(); }); } }