diff --git a/src/Engine/ProtoCore/Lang/CallSite.cs b/src/Engine/ProtoCore/Lang/CallSite.cs index 6e10b316ecf..548c53e1701 100644 --- a/src/Engine/ProtoCore/Lang/CallSite.cs +++ b/src/Engine/ProtoCore/Lang/CallSite.cs @@ -17,6 +17,8 @@ using ProtoCore.Runtime; using WarningID = ProtoCore.Runtime.WarningID; using System.Collections.ObjectModel; +using DynamoServices; +using Validity = ProtoCore.Utils.Validity; namespace ProtoCore { @@ -1894,11 +1896,7 @@ private StackValue ExecWithZeroRI(List functionEndPoint, Conte if (traceD != null) { //There was data associated with the previous execution, push this into the TLS - - Dictionary dataDict = new Dictionary(); - dataDict.Add(TRACE_KEY, traceD); - - TraceUtils.SetObjectToTLS(dataDict); + TraceUtils.SetTraceData(TRACE_KEY, traceD); } else { @@ -1912,16 +1910,17 @@ private StackValue ExecWithZeroRI(List functionEndPoint, Conte if (ret.IsNull) { //wipe the trace cache - TraceUtils.ClearTLSKey(TRACE_KEY); + TraceUtils.ClearAllKnownTLSKeys(); } - - //TLS -> TraceCache - Dictionary traceRet = TraceUtils.GetObjectFromTLS(); - - if (traceRet.ContainsKey(TRACE_KEY)) + else { - var val = traceRet[TRACE_KEY]; - newTraceData.Data = val; + //TLS -> TraceCache + var traceRet = TraceUtils.GetTraceData(TRACE_KEY); + + if (traceRet != null) + { + newTraceData.Data = traceRet; + } } // An explicit call requires return coercion at the return instruction diff --git a/src/Engine/ProtoCore/Lang/TraceUtils.cs b/src/Engine/ProtoCore/Lang/TraceUtils.cs deleted file mode 100644 index 2a95a4802d5..00000000000 --- a/src/Engine/ProtoCore/Lang/TraceUtils.cs +++ /dev/null @@ -1,98 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Runtime.Serialization; -using System.Text; -using System.Threading; - -namespace ProtoCore.Lang -{ - public static class TraceUtils - { - - -// ReSharper disable InconsistentNaming -//Luke: This is deliberately inconsistent, it is not supposed to be in widespread use, to work around a defiency -//in the TLS implementation. -//TODO(Luke): Replace this with an attribute lookup - internal const string __TEMP_REVIT_TRACE_ID = "{0459D869-0C72-447F-96D8-08A7FB92214B}-REVIT"; -// ReSharper restore InconsistentNaming - - - /// - /// Returns a list of the keys bound to trace elements - /// This should be extracted from the attribute on the methods - /// - /// - public static List TEMP_GetTraceKeys() - { - //TODO:Luke Extract this from RequiresTraceAttribute - - return new List() { __TEMP_REVIT_TRACE_ID }; - } - - /// - /// Returns a map of TraceID -> Objects - /// - /// - public static Dictionary GetObjectFromTLS() - { - Dictionary objs = new Dictionary(); - - foreach (String key in TEMP_GetTraceKeys()) - { - objs.Add(key, - (ISerializable)Thread.GetData(Thread.GetNamedDataSlot(key))); - } - - return objs; - } - - /// - /// Set the data associated with trace - /// - /// - public static void SetObjectToTLS(Dictionary objs) - { - foreach (String k in objs.Keys) - { - if (objs[k] == null) - Thread.FreeNamedDataSlot(k); - - Thread.SetData(Thread.GetNamedDataSlot(k), objs[k]); - - } - } - - /// - /// Clear a specific key - /// - /// - public static void ClearTLSKey(string key) - { - Dictionary objs = new Dictionary(); - objs.Add(key, null); - SetObjectToTLS(objs); - - } - - - /// - /// Clear the named slots for all the know keys - /// - public static void ClearAllKnownTLSKeys() - { - Dictionary objs = new Dictionary(); - - foreach (String key in TEMP_GetTraceKeys()) - { - objs.Add(key, null); - } - - SetObjectToTLS(objs); - - } - - } -} diff --git a/src/Engine/ProtoCore/ProtoCore.csproj b/src/Engine/ProtoCore/ProtoCore.csproj index 0ef04096754..dff3da1242b 100644 --- a/src/Engine/ProtoCore/ProtoCore.csproj +++ b/src/Engine/ProtoCore/ProtoCore.csproj @@ -149,7 +149,6 @@ - diff --git a/src/NodeServices/Properties/AssemblyInfo.cs b/src/NodeServices/Properties/AssemblyInfo.cs index 80e21db01fa..1ddd3cefca7 100644 --- a/src/NodeServices/Properties/AssemblyInfo.cs +++ b/src/NodeServices/Properties/AssemblyInfo.cs @@ -17,4 +17,6 @@ [assembly: InternalsVisibleTo("TestServices")] [assembly: InternalsVisibleTo("ProtoTestFx")] [assembly: InternalsVisibleTo("DynamoCoreTests")] -[assembly: InternalsVisibleTo("DynamoWPFCLI")] \ No newline at end of file +[assembly: InternalsVisibleTo("DynamoWPFCLI")] +[assembly: InternalsVisibleTo("ProtoTest")] +[assembly: InternalsVisibleTo("IntegrationTests")] \ No newline at end of file diff --git a/src/NodeServices/TraceSupport.cs b/src/NodeServices/TraceSupport.cs index 02a69ca8761..e01db73025a 100644 --- a/src/NodeServices/TraceSupport.cs +++ b/src/NodeServices/TraceSupport.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Runtime.Serialization; using System.Threading; @@ -17,6 +18,56 @@ public class RegisterForTraceAttribute : Attribute /// public static class TraceUtils { + // ReSharper disable InconsistentNaming + //Luke: This is deliberately inconsistent, it is not supposed to be in widespread use, to work around a defiency + //in the TLS implementation. + //TODO(Luke): Replace this with an attribute lookup + internal const string __TEMP_REVIT_TRACE_ID = "{0459D869-0C72-447F-96D8-08A7FB92214B}-REVIT"; + // ReSharper restore InconsistentNaming + + [ThreadStatic] private static Dictionary _localStorageSlot; //= new Dictionary(); + + internal static Dictionary LocalStorageSlot + { + get + { + return _localStorageSlot ?? (_localStorageSlot = new Dictionary()); + } + set + { + _localStorageSlot = value; + } + } + + /// + /// Returns a list of the keys bound to trace elements + /// This should be extracted from the attribute on the methods + /// + /// + internal static List TEMP_GetTraceKeys() + { + //TODO:Luke Extract this from RequiresTraceAttribute + + return new List() { __TEMP_REVIT_TRACE_ID }; + } + + /// + /// Clear a specific key + /// + /// + internal static void ClearTLSKey(string key) + { + LocalStorageSlot.Remove(key); + } + + /// + /// Clear the named slots for all the know keys + /// + internal static void ClearAllKnownTLSKeys() + { + LocalStorageSlot.Clear(); + } + /// /// Returns the data that is bound to a particular key /// @@ -24,18 +75,15 @@ public static class TraceUtils /// public static ISerializable GetTraceData(string key) { - Object data = Thread.GetData(Thread.GetNamedDataSlot(key)); - - //Null is ok - if (data == null) + ISerializable data; + if (!LocalStorageSlot.TryGetValue(key, out data)) + { return null; - - var ret = data as ISerializable; - if (ret != null) - return ret; - - //Data, that was not serializable is not - throw new InvalidOperationException("Data in Named slot was not serializable"); + } + else + { + return data; + } } /// @@ -45,7 +93,14 @@ public static ISerializable GetTraceData(string key) /// public static void SetTraceData(string key, ISerializable value) { - Thread.SetData(Thread.GetNamedDataSlot(key), value); + if (LocalStorageSlot.ContainsKey(key)) + { + LocalStorageSlot[key] = value; + } + else + { + LocalStorageSlot.Add(key, value); + } } } } diff --git a/test/Engine/ProtoTest/TD/TraceUtilsTests.cs b/test/Engine/ProtoTest/TD/TraceUtilsTests.cs index 1549a3685e9..fff22aaf7b2 100644 --- a/test/Engine/ProtoTest/TD/TraceUtilsTests.cs +++ b/test/Engine/ProtoTest/TD/TraceUtilsTests.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Runtime.Serialization; using System.Text; +using DynamoServices; using NUnit.Framework; using ProtoCore.Lang; @@ -38,7 +39,7 @@ public static void SetGetTest() { - List keys = TraceUtils.TEMP_GetTraceKeys(); + var key = TraceUtils.TEMP_GetTraceKeys()[0]; SerializableString testStr1 = new SerializableString("{0955D962-2936-4FB2-AAB3-635C6FF6E0AD}"); @@ -46,16 +47,12 @@ public static void SetGetTest() SerializableString testStr2 = new SerializableString("{2D7FE0ED-56F3-47A4-9BAA-8DF570170D97}"); - - Dictionary data = new Dictionary(); - data.Add(keys[0], testStr1); - - TraceUtils.SetObjectToTLS(data); + TraceUtils.SetTraceData(key, testStr1); //Set complete, readback test - Dictionary readback = TraceUtils.GetObjectFromTLS(); - Assert.IsTrue(((SerializableString)readback[keys[0]]).Payload == testStr1.Payload); + ISerializable readback = TraceUtils.GetTraceData(key); + Assert.IsTrue(readback == testStr1); } @@ -64,7 +61,7 @@ public static void SetGetTest() public static void OverwriteTest() { - List keys = TraceUtils.TEMP_GetTraceKeys(); + var key = TraceUtils.TEMP_GetTraceKeys()[0]; SerializableString testStr1 = new SerializableString("{0955D962-2936-4FB2-AAB3-635C6FF6E0AD}"); @@ -72,29 +69,21 @@ public static void OverwriteTest() SerializableString testStr2 = new SerializableString("{2D7FE0ED-56F3-47A4-9BAA-8DF570170D97}"); - - var data = new Dictionary(); - data.Add(keys[0], testStr1); - - var data2 = new Dictionary(); - data2.Add(keys[0], testStr2); - - - TraceUtils.SetObjectToTLS(data); + TraceUtils.SetTraceData(key, testStr1); //Set complete, readback test - var readback = TraceUtils.GetObjectFromTLS(); - Assert.IsTrue(((SerializableString)readback[keys[0]]).Payload == testStr1.Payload); + ISerializable readback = TraceUtils.GetTraceData(key); + Assert.IsTrue(readback == testStr1); - TraceUtils.SetObjectToTLS(data2); + TraceUtils.SetTraceData(key, testStr2); //Set complete, readback test - readback = TraceUtils.GetObjectFromTLS(); - Assert.IsTrue(((SerializableString)readback[keys[0]]).Payload == testStr2.Payload); + readback = TraceUtils.GetTraceData(key); + Assert.IsTrue(readback == testStr2); } @@ -103,32 +92,24 @@ public static void OverwriteTest() public static void OverwriteNullTest() { - List keys = TraceUtils.TEMP_GetTraceKeys(); + var key = TraceUtils.TEMP_GetTraceKeys()[0]; SerializableString testStr1 = new SerializableString("{0955D962-2936-4FB2-AAB3-635C6FF6E0AD}"); - - Dictionary data = new Dictionary(); - data.Add(keys[0], testStr1); - - - TraceUtils.SetObjectToTLS(data); + TraceUtils.SetTraceData(key, testStr1); //Set complete, readback test - var readback = TraceUtils.GetObjectFromTLS(); - Assert.IsTrue(((SerializableString)readback[keys[0]]).Payload == testStr1.Payload); - - - data[keys[0]] = null; + ISerializable readback = TraceUtils.GetTraceData(key); + Assert.IsTrue(readback == testStr1); - TraceUtils.SetObjectToTLS(data); + TraceUtils.SetTraceData(key, null); //Set complete, readback test - readback = TraceUtils.GetObjectFromTLS(); - Assert.IsTrue((ISerializable)readback[keys[0]] == null); + readback = TraceUtils.GetTraceData(key); + Assert.IsTrue(readback == null); } diff --git a/test/System/IntegrationTests/CallsiteRegen.cs b/test/System/IntegrationTests/CallsiteRegen.cs index 184d73f0490..656ad6d6750 100644 --- a/test/System/IntegrationTests/CallsiteRegen.cs +++ b/test/System/IntegrationTests/CallsiteRegen.cs @@ -9,6 +9,7 @@ using ProtoCore.DSASM.Mirror; using ProtoScript.Runners; using ProtoTestFx.TD; +using DynamoServices; namespace IntegrationTests { @@ -35,7 +36,7 @@ public void Setup() [TearDown] public static void TLSCleanup() { - Thread.FreeNamedDataSlot(__TEMP_REVIT_TRACE_ID); + TraceUtils.ClearAllKnownTLSKeys(); } diff --git a/test/System/IntegrationTests/IncrementingTraceTests.cs b/test/System/IntegrationTests/IncrementingTraceTests.cs index 8767f2ef1e0..f83bbb85ee6 100644 --- a/test/System/IntegrationTests/IncrementingTraceTests.cs +++ b/test/System/IntegrationTests/IncrementingTraceTests.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Text; using System.Threading; +using DynamoServices; using FFITarget; using NUnit.Framework; using ProtoCore.AST.AssociativeAST; @@ -39,8 +40,8 @@ public void TestFixup() public static void TLSCleanup() { - Thread.FreeNamedDataSlot(__TEMP_REVIT_TRACE_ID); - + TraceUtils.ClearAllKnownTLSKeys(); + } [Test] diff --git a/test/System/IntegrationTests/MinimalTraceTests.cs b/test/System/IntegrationTests/MinimalTraceTests.cs index 527e2b3dec1..ae39ec1040e 100644 --- a/test/System/IntegrationTests/MinimalTraceTests.cs +++ b/test/System/IntegrationTests/MinimalTraceTests.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Text; using System.Threading; +using DynamoServices; using FFITarget; using NUnit.Framework; using ProtoCore.DSASM.Mirror; @@ -25,7 +26,7 @@ public void Setup() [TearDown] public static void TLSCleanup() { - Thread.FreeNamedDataSlot(__TEMP_REVIT_TRACE_ID); + TraceUtils.ClearAllKnownTLSKeys(); } [Test] diff --git a/test/System/IntegrationTests/TestWrapperCleanup.cs b/test/System/IntegrationTests/TestWrapperCleanup.cs index 6f0d565722c..ee1fa878ddb 100644 --- a/test/System/IntegrationTests/TestWrapperCleanup.cs +++ b/test/System/IntegrationTests/TestWrapperCleanup.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Text; using System.Threading; +using DynamoServices; using FFITarget; using NUnit.Framework; using ProtoTestFx.TD; @@ -24,7 +25,7 @@ public void Setup() [TearDown] public static void TLSCleanup() { - Thread.FreeNamedDataSlot(__TEMP_REVIT_TRACE_ID); + TraceUtils.ClearAllKnownTLSKeys(); WrappersTest.Reset(); }