Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono-addins.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLluis Sanchez <lluis@xamarin.com>2022-10-27 13:26:14 +0300
committerLluis Sanchez <lluis@xamarin.com>2022-10-27 13:26:14 +0300
commitf86d50b03bf48a3b1bcb87eb9a26487c0ceaef04 (patch)
treeba98f50b0091f1d33bcb6a10e8deed43c4038ed2
parent9eaab025099bc82c0fc31379afa95786aa7fcdfa (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.cs4
-rw-r--r--Test/FileContentExtension/FileContentExtension.addin.xml27
-rw-r--r--Test/UnitTests/SimpleApp.addin.xml4
-rw-r--r--Test/UnitTests/TestMultithreading.cs8
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()
{