diff options
author | Lluis Sanchez <lluis@xamarin.com> | 2022-10-27 13:26:14 +0300 |
---|---|---|
committer | Lluis Sanchez <lluis@xamarin.com> | 2022-10-27 13:26:14 +0300 |
commit | f86d50b03bf48a3b1bcb87eb9a26487c0ceaef04 (patch) | |
tree | ba98f50b0091f1d33bcb6a10e8deed43c4038ed2 | |
parent | 9eaab025099bc82c0fc31379afa95786aa7fcdfa (diff) |
Fix NRE when unloading an add-in
When removing many nodes in a transaction it may happen that a parent
is removed before its children, since the list of nodes to remove is
in a hashset, so there is no defined order. Added a null check to avoid
a crash when that happens.
-rw-r--r-- | Mono.Addins/Mono.Addins/ExtensionContextTransaction.cs | 4 | ||||
-rw-r--r-- | Test/FileContentExtension/FileContentExtension.addin.xml | 27 | ||||
-rw-r--r-- | Test/UnitTests/SimpleApp.addin.xml | 4 | ||||
-rw-r--r-- | Test/UnitTests/TestMultithreading.cs | 8 |
4 files changed, 42 insertions, 1 deletions
diff --git a/Mono.Addins/Mono.Addins/ExtensionContextTransaction.cs b/Mono.Addins/Mono.Addins/ExtensionContextTransaction.cs index ba2a245..99cba20 100644 --- a/Mono.Addins/Mono.Addins/ExtensionContextTransaction.cs +++ b/Mono.Addins/Mono.Addins/ExtensionContextTransaction.cs @@ -165,7 +165,9 @@ namespace Mono.Addins { foreach (var node in childrenChanged) { - if (node.NotifyChildrenChanged()) + // It may happen that a node is removed while updating its parent. In this case the parent + // will be set to null, and then there is no need to notify changes + if (node.Parent != null && node.NotifyChildrenChanged()) NotifyExtensionsChangedEvent(node.GetPath()); } } diff --git a/Test/FileContentExtension/FileContentExtension.addin.xml b/Test/FileContentExtension/FileContentExtension.addin.xml index b3f1144..6675368 100644 --- a/Test/FileContentExtension/FileContentExtension.addin.xml +++ b/Test/FileContentExtension/FileContentExtension.addin.xml @@ -65,6 +65,33 @@ <Node id="n4" type="test" /> </Extension> + <Extension path="/SimpleApp/ItemTree"> + <ItemSet label="i1"> + <Item /> + <ItemSet label="i2"> + <Item /> + <ItemSet label="i1"> + <Item /> + <ItemSet label="i2"> + <Item /> + <ItemSet label="i1"> + <Item /> + <ItemSet label="i2"> + <Item /> + <ItemSet label="i1"> + <Item /> + <ItemSet label="i2"> + <Item /> + </ItemSet> + </ItemSet> + </ItemSet> + </ItemSet> + </ItemSet> + </ItemSet> + </ItemSet> + </ItemSet> + </Extension> + <Module> <Dependencies> <Addin id="SystemInfoExtension" version="0.1.0" /> diff --git a/Test/UnitTests/SimpleApp.addin.xml b/Test/UnitTests/SimpleApp.addin.xml index 7cf285c..86524f4 100644 --- a/Test/UnitTests/SimpleApp.addin.xml +++ b/Test/UnitTests/SimpleApp.addin.xml @@ -48,6 +48,10 @@ <ExtensionNode type="UnitTests.ItemSetNode" /> </ExtensionPoint> + <ExtensionPoint path = "/SimpleApp/ItemTree"> + <ExtensionNode type="UnitTests.ItemSetNode" /> + </ExtensionPoint> + <ExtensionPoint path = "/SimpleApp/NodeWithChildren"> <ExtensionNode name="Node"> <ExtensionNode name="Child" /> diff --git a/Test/UnitTests/TestMultithreading.cs b/Test/UnitTests/TestMultithreading.cs index 646cdef..64a560a 100644 --- a/Test/UnitTests/TestMultithreading.cs +++ b/Test/UnitTests/TestMultithreading.cs @@ -7,6 +7,7 @@ using SimpleApp; using System.Threading; using System.Diagnostics; using System.Linq; +using System.Collections.Generic; namespace UnitTests { @@ -62,6 +63,7 @@ namespace UnitTests testData.StartThreads ((index, data) => { while (!data.Stopped) { + LoadAll(AddinManager.GetExtensionNodes<ItemSetNode>("/SimpleApp/ItemTree")); var writers = AddinManager.GetExtensionObjects<IWriter> ("/SimpleApp/Writers"); testData.Counters [index] = writers.Length; } @@ -87,6 +89,12 @@ namespace UnitTests } } + void LoadAll(IEnumerable<ExtensionNode> nodes) + { + foreach (var n in nodes.OfType<ItemSetNode>()) + LoadAll(n.GetChildNodes()); + } + [Test] public void EventsMultithread() { |