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 <llsan@microsoft.com>2022-06-14 02:56:25 +0300
committerLluis Sanchez <llsan@microsoft.com>2022-09-13 20:38:42 +0300
commit86b644dd323c725888d09cb53423fe430fc684a9 (patch)
tree60d547c42a106c53dcfd71bbcb1e5019836cc148
parent8b5552652a0d6d8816053fd9c4cae5c697e55dec (diff)
More thread safety
-rw-r--r--Mono.Addins/Mono.Addins/Addin.cs33
-rw-r--r--Mono.Addins/Mono.Addins/AddinEngine.cs12
-rw-r--r--Mono.Addins/Mono.Addins/AddinInfo.cs37
-rw-r--r--Mono.Addins/Mono.Addins/AddinRegistry.cs43
-rw-r--r--Mono.Addins/Mono.Addins/ExtensionContextTransaction.cs2
-rw-r--r--Mono.Addins/Mono.Addins/ExtensionNode.cs10
-rw-r--r--Mono.Addins/Mono.Addins/ExtensionTree.cs2
-rw-r--r--Mono.Addins/Mono.Addins/InstanceExtensionNode.cs9
-rw-r--r--Mono.Addins/Mono.Addins/RuntimeAddin.cs45
-rw-r--r--Mono.Addins/Mono.Addins/TreeNode.cs4
10 files changed, 99 insertions, 98 deletions
diff --git a/Mono.Addins/Mono.Addins/Addin.cs b/Mono.Addins/Mono.Addins/Addin.cs
index 47f9917..792eb84 100644
--- a/Mono.Addins/Mono.Addins/Addin.cs
+++ b/Mono.Addins/Mono.Addins/Addin.cs
@@ -136,14 +136,16 @@ namespace Mono.Addins
internal AddinInfo AddinInfo {
get {
- if (addin == null) {
+ var addinInfo = addin;
+
+ if (addinInfo == null) {
try {
- addin = AddinInfo.ReadFromDescription (Description);
+ addinInfo = addin = AddinInfo.ReadFromDescription (Description);
} catch (Exception ex) {
throw new InvalidOperationException ("Could not read add-in file: " + database.GetDescriptionPath (domain, id), ex);
}
}
- return addin;
+ return addinInfo;
}
}
@@ -235,17 +237,16 @@ namespace Mono.Addins
/// </summary>
public AddinDescription Description {
get {
- if (desc != null) {
- AddinDescription d = desc.Target as AddinDescription;
- if (d != null)
- return d;
+ var addinDescription = (AddinDescription) desc?.Target;
+ if (addinDescription != null) {
+ return addinDescription;
}
var configFile = database.GetDescriptionPath (domain, id);
- AddinDescription m;
- database.ReadAddinDescription (new ConsoleProgressStatus (true), configFile, out m);
- if (m == null) {
+ database.ReadAddinDescription (new ConsoleProgressStatus (true), configFile, out addinDescription);
+
+ if (addinDescription == null) {
try {
if (File.Exists (configFile)) {
// The file is corrupted. Remove it.
@@ -257,14 +258,14 @@ namespace Mono.Addins
throw new InvalidOperationException ("Could not read add-in description");
}
if (addin == null) {
- addin = AddinInfo.ReadFromDescription (m);
- sourceFile = m.AddinFile;
+ addin = AddinInfo.ReadFromDescription (addinDescription);
+ sourceFile = addinDescription.AddinFile;
}
- SetIsUserAddin (m);
+ SetIsUserAddin (addinDescription);
if (!isUserAddin.Value)
- m.Flags |= AddinFlags.CantUninstall;
- desc = new WeakReference (m);
- return m;
+ addinDescription.Flags |= AddinFlags.CantUninstall;
+ desc = new WeakReference (addinDescription);
+ return addinDescription;
}
}
diff --git a/Mono.Addins/Mono.Addins/AddinEngine.cs b/Mono.Addins/Mono.Addins/AddinEngine.cs
index d6adb62..1e0a615 100644
--- a/Mono.Addins/Mono.Addins/AddinEngine.cs
+++ b/Mono.Addins/Mono.Addins/AddinEngine.cs
@@ -247,7 +247,7 @@ namespace Mono.Addins
if (string.IsNullOrEmpty (configDir))
registry = AddinRegistry.GetGlobalRegistry (this, startupDirectory);
else
- registry = new AddinRegistry (this, configDir, startupDirectory, addinsDir, databaseDir);
+ registry = new AddinRegistry (this, configDir, startupDirectory, addinsDir, databaseDir, null);
if ((asmFile != null && registry.CreateHostAddinsFile (asmFile)) || registry.UnknownDomain)
registry.Update (new ConsoleProgressStatus (false));
@@ -590,20 +590,18 @@ namespace Mono.Addins
bool InsertAddin (ExtensionContextTransaction transaction, IProgressStatus statusMonitor, Addin iad)
{
try {
- RuntimeAddin runtimeAddin = new RuntimeAddin (this);
+ RuntimeAddin runtimeAddin = new RuntimeAddin (this, iad);
+ AddinDescription description = iad.Description;
RegisterAssemblyResolvePaths (transaction, runtimeAddin, iad.Description.MainModule);
-
- // Read the config file and load the add-in assemblies
- AddinDescription description = runtimeAddin.Load (iad);
-
+
// Register the add-in
loadedAddins = loadedAddins.SetItem(Addin.GetIdName (runtimeAddin.Id), runtimeAddin);
if (!AddinDatabase.RunningSetupProcess) {
// Load the extension points and other addin data
- RegisterNodeSets (iad.Id, description.ExtensionNodeSets);
+ RegisterNodeSets (transaction, iad.Id, description.ExtensionNodeSets);
foreach (ConditionTypeDescription cond in description.ConditionTypes)
RegisterCondition (transaction, cond.Id, runtimeAddin, cond.TypeName);
diff --git a/Mono.Addins/Mono.Addins/AddinInfo.cs b/Mono.Addins/Mono.Addins/AddinInfo.cs
index b1125f7..eb8f127 100644
--- a/Mono.Addins/Mono.Addins/AddinInfo.cs
+++ b/Mono.Addins/Mono.Addins/AddinInfo.cs
@@ -32,6 +32,8 @@ using System.Collections;
using System.Xml;
using System.Xml.Serialization;
using Mono.Addins.Description;
+using System.Collections.Immutable;
+using System.Linq;
namespace Mono.Addins
{
@@ -49,14 +51,14 @@ namespace Mono.Addins
string category = "";
bool defaultEnabled = true;
bool isroot;
- DependencyCollection dependencies;
- DependencyCollection optionalDependencies;
+ ImmutableArray<Dependency> dependencies;
+ ImmutableArray<Dependency> optionalDependencies;
AddinPropertyCollection properties;
private AddinInfo ()
{
- dependencies = new DependencyCollection ();
- optionalDependencies = new DependencyCollection ();
+ dependencies = ImmutableArray<Dependency>.Empty;
+ optionalDependencies = ImmutableArray<Dependency>.Empty;
}
public string Id {
@@ -65,17 +67,14 @@ namespace Mono.Addins
public string LocalId {
get { return id; }
- set { id = value; }
}
public string Namespace {
get { return namspace; }
- set { namspace = value; }
}
public bool IsRoot {
get { return isroot; }
- set { isroot = value; }
}
public string Name {
@@ -90,17 +89,14 @@ namespace Mono.Addins
sid = sid.Substring (2);
return Addin.GetFullId (namspace, sid, null);
}
- set { name = value; }
}
public string Version {
get { return version; }
- set { version = value; }
}
public string BaseVersion {
get { return baseVersion; }
- set { baseVersion = value; }
}
public string Author {
@@ -110,7 +106,6 @@ namespace Mono.Addins
return s;
return author;
}
- set { author = value; }
}
public string Copyright {
@@ -120,7 +115,6 @@ namespace Mono.Addins
return s;
return copyright;
}
- set { copyright = value; }
}
public string Url {
@@ -130,7 +124,6 @@ namespace Mono.Addins
return s;
return url;
}
- set { url = value; }
}
public string Description {
@@ -140,7 +133,6 @@ namespace Mono.Addins
return s;
return description;
}
- set { description = value; }
}
public string Category {
@@ -150,19 +142,17 @@ namespace Mono.Addins
return s;
return category;
}
- set { category = value; }
}
public bool EnabledByDefault {
get { return defaultEnabled; }
- set { defaultEnabled = value; }
}
- public DependencyCollection Dependencies {
+ public ImmutableArray<Dependency> Dependencies {
get { return dependencies; }
}
- public DependencyCollection OptionalDependencies {
+ public ImmutableArray<Dependency> OptionalDependencies {
get { return optionalDependencies; }
}
@@ -185,14 +175,9 @@ namespace Mono.Addins
info.baseVersion = description.CompatVersion;
info.isroot = description.IsRoot;
info.defaultEnabled = description.EnabledByDefault;
-
- foreach (Dependency dep in description.MainModule.Dependencies)
- info.Dependencies.Add (dep);
-
- foreach (ModuleDescription mod in description.OptionalModules) {
- foreach (Dependency dep in mod.Dependencies)
- info.OptionalDependencies.Add (dep);
- }
+
+ info.dependencies = ImmutableArray<Dependency>.Empty.AddRange (description.MainModule.Dependencies);
+ info.optionalDependencies = ImmutableArray<Dependency>.Empty.AddRange (description.OptionalModules.SelectMany(module => module.Dependencies));
info.properties = description.Properties;
return info;
diff --git a/Mono.Addins/Mono.Addins/AddinRegistry.cs b/Mono.Addins/Mono.Addins/AddinRegistry.cs
index 0e1ef2a..94e8123 100644
--- a/Mono.Addins/Mono.Addins/AddinRegistry.cs
+++ b/Mono.Addins/Mono.Addins/AddinRegistry.cs
@@ -67,13 +67,13 @@ namespace Mono.Addins
/// </remarks>
public class AddinRegistry: IDisposable
{
- AddinDatabase database;
- StringCollection addinDirs;
- string basePath;
+ readonly AddinDatabase database;
+ readonly string [] addinDirs;
+ readonly string basePath;
+ readonly string startupDirectory;
+ readonly string addinsDir;
+ readonly string databaseDir;
string currentDomain;
- string startupDirectory;
- string addinsDir;
- string databaseDir;
/// <summary>
/// Initializes a new instance.
@@ -92,7 +92,7 @@ namespace Mono.Addins
/// of the Environment.SpecialFolder enumeration can be used (always between square
/// brackets)
/// </remarks>
- public AddinRegistry (string registryPath): this (null, registryPath, null, null, null)
+ public AddinRegistry (string registryPath): this (null, registryPath, null, null, null, null)
{
}
@@ -116,7 +116,7 @@ namespace Mono.Addins
/// of the Environment.SpecialFolder enumeration can be used (always between square
/// brackets)
/// </remarks>
- public AddinRegistry (string registryPath, string startupDirectory): this (null, registryPath, startupDirectory, null, null)
+ public AddinRegistry (string registryPath, string startupDirectory): this (null, registryPath, startupDirectory, null, null, null)
{
}
@@ -145,7 +145,7 @@ namespace Mono.Addins
/// of the Environment.SpecialFolder enumeration can be used (always between square
/// brackets)
/// </remarks>
- public AddinRegistry (string registryPath, string startupDirectory, string addinsDir): this (null, registryPath, startupDirectory, addinsDir, null)
+ public AddinRegistry (string registryPath, string startupDirectory, string addinsDir): this (null, registryPath, startupDirectory, addinsDir, null, null)
{
}
@@ -179,11 +179,11 @@ namespace Mono.Addins
/// of the Environment.SpecialFolder enumeration can be used (always between square
/// brackets)
/// </remarks>
- public AddinRegistry (string registryPath, string startupDirectory, string addinsDir, string databaseDir): this (null, registryPath, startupDirectory, addinsDir, databaseDir)
+ public AddinRegistry (string registryPath, string startupDirectory, string addinsDir, string databaseDir): this (null, registryPath, startupDirectory, addinsDir, databaseDir, null)
{
}
- internal AddinRegistry (AddinEngine engine, string registryPath, string startupDirectory, string addinsDir, string databaseDir)
+ internal AddinRegistry (AddinEngine engine, string registryPath, string startupDirectory, string addinsDir, string databaseDir, string additionalGlobalAddinDirectory)
{
basePath = Path.GetFullPath (Util.NormalizePath (registryPath));
@@ -208,8 +208,10 @@ namespace Mono.Addins
// Look for add-ins in the hosts directory and in the default
// addins directory
- addinDirs = new StringCollection ();
- addinDirs.Add (DefaultAddinsFolder);
+ if (additionalGlobalAddinDirectory != null)
+ addinDirs = new [] { DefaultAddinsFolder, additionalGlobalAddinDirectory };
+ else
+ addinDirs = new [] { DefaultAddinsFolder };
// Initialize the database after all paths have been set
database = new AddinDatabase (engine, this);
@@ -239,15 +241,15 @@ namespace Mono.Addins
internal static AddinRegistry GetGlobalRegistry (AddinEngine engine, string startupDirectory)
{
- AddinRegistry reg = new AddinRegistry (engine, GlobalRegistryPath, startupDirectory, null, null);
string baseDir;
if (Util.IsWindows)
baseDir = Environment.GetFolderPath (Environment.SpecialFolder.CommonProgramFiles);
else
baseDir = "/etc";
-
- reg.GlobalAddinDirectories.Add (Path.Combine (baseDir, "mono.addins"));
- return reg;
+
+ var globalDir = Path.Combine (baseDir, "mono.addins");
+
+ return new AddinRegistry (engine, GlobalRegistryPath, startupDirectory, null, null, globalDir);
}
internal bool UnknownDomain {
@@ -743,10 +745,15 @@ namespace Mono.Addins
get { return databaseDir; }
}
- internal StringCollection GlobalAddinDirectories {
+ internal IEnumerable<string> GlobalAddinDirectories {
get { return addinDirs; }
}
+ internal void RegisterGlobalAddinDirectory (string dir)
+ {
+
+ }
+
internal string StartupDirectory {
get {
return startupDirectory;
diff --git a/Mono.Addins/Mono.Addins/ExtensionContextTransaction.cs b/Mono.Addins/Mono.Addins/ExtensionContextTransaction.cs
index 7ca7eed..f961d8c 100644
--- a/Mono.Addins/Mono.Addins/ExtensionContextTransaction.cs
+++ b/Mono.Addins/Mono.Addins/ExtensionContextTransaction.cs
@@ -185,7 +185,7 @@ namespace Mono.Addins
public void ReportAddinLoad (RuntimeAddin addin)
{
if (addinLoadEvents == null)
- addinLoadEvents = new List<string> ();
+ addinLoadEvents = new List<RuntimeAddin> ();
addinLoadEvents.Add (addin);
}
diff --git a/Mono.Addins/Mono.Addins/ExtensionNode.cs b/Mono.Addins/Mono.Addins/ExtensionNode.cs
index 5452dcd..dc490bc 100644
--- a/Mono.Addins/Mono.Addins/ExtensionNode.cs
+++ b/Mono.Addins/Mono.Addins/ExtensionNode.cs
@@ -61,7 +61,7 @@ namespace Mono.Addins
ModuleDescription module;
AddinEngine addinEngine;
event ExtensionNodeEventHandler extensionNodeChanged;
- object localLock = new object ();
+ internal readonly object localLock = new object ();
/// <summary>
/// Identifier of the node.
@@ -121,11 +121,19 @@ namespace Mono.Addins
internal void SetTreeNode (TreeNode node)
{
+ // treeNode can only be set once (it's set during the node initialization)
+ if (treeNode != null)
+ throw new InvalidOperationException ();
+
treeNode = node;
}
internal void SetData (AddinEngine addinEngine, string plugid, ExtensionNodeType nodeType, ModuleDescription module)
{
+ // SetData can only be called once (it's set during the node initialization)
+ if (addinEngine != null)
+ throw new InvalidOperationException ();
+
this.addinEngine = addinEngine;
this.addinId = plugid;
this.nodeType = nodeType;
diff --git a/Mono.Addins/Mono.Addins/ExtensionTree.cs b/Mono.Addins/Mono.Addins/ExtensionTree.cs
index 3b571a4..b8da472 100644
--- a/Mono.Addins/Mono.Addins/ExtensionTree.cs
+++ b/Mono.Addins/Mono.Addins/ExtensionTree.cs
@@ -41,7 +41,7 @@ namespace Mono.Addins
{
int internalId;
internal const string AutoIdPrefix = "__nid_";
- ExtensionContext context;
+ readonly ExtensionContext context;
public ExtensionTree (AddinEngine addinEngine, ExtensionContext context): base (addinEngine, "")
{
diff --git a/Mono.Addins/Mono.Addins/InstanceExtensionNode.cs b/Mono.Addins/Mono.Addins/InstanceExtensionNode.cs
index 3d6640d..e49632e 100644
--- a/Mono.Addins/Mono.Addins/InstanceExtensionNode.cs
+++ b/Mono.Addins/Mono.Addins/InstanceExtensionNode.cs
@@ -69,8 +69,13 @@ namespace Mono.Addins
/// </remarks>
public object GetInstance ()
{
- if (cachedInstance == null)
- cachedInstance = CreateInstance ();
+ if (cachedInstance == null) {
+ lock (localLock) {
+ // Use locking here to avoid creating more than one instance per ExtensionNode
+ if (cachedInstance != null)
+ cachedInstance = CreateInstance ();
+ }
+ }
return cachedInstance;
}
diff --git a/Mono.Addins/Mono.Addins/RuntimeAddin.cs b/Mono.Addins/Mono.Addins/RuntimeAddin.cs
index 54d1749..d5a03ac 100644
--- a/Mono.Addins/Mono.Addins/RuntimeAddin.cs
+++ b/Mono.Addins/Mono.Addins/RuntimeAddin.cs
@@ -49,27 +49,37 @@ namespace Mono.Addins
/// </summary>
public class RuntimeAddin
{
- string id;
- string baseDirectory;
+ readonly string id;
+ readonly string baseDirectory;
+ readonly Addin ainfo;
+ readonly RuntimeAddin parentAddin;
+ readonly AddinEngine addinEngine;
+ readonly ModuleDescription module;
+
string privatePath;
- Addin ainfo;
- RuntimeAddin parentAddin;
Dictionary<string, Assembly> loadedAssemblies = new Dictionary<string, Assembly>();
bool fullyLoadedAssemblies;
-
- RuntimeAddin[] depAddins;
- ResourceManager[] resourceManagers;
+
+ RuntimeAddin [] depAddins;
+ ResourceManager [] resourceManagers;
AddinLocalizer localizer;
- ModuleDescription module;
- AddinEngine addinEngine;
ExtensionNodeDescription localizerDescription;
- internal RuntimeAddin (AddinEngine addinEngine)
+ internal RuntimeAddin (AddinEngine addinEngine, Addin iad)
{
this.addinEngine = addinEngine;
+
+ ainfo = iad;
+
+ AddinDescription description = iad.Description;
+ id = description.AddinId;
+ baseDirectory = description.BasePath;
+ module = description.MainModule;
+ module.RuntimeAddin = this;
+ localizerDescription = description.Localizer;
}
-
+
internal RuntimeAddin (AddinEngine addinEngine, RuntimeAddin parentAddin, ModuleDescription module)
{
this.addinEngine = addinEngine;
@@ -619,19 +629,6 @@ namespace Mono.Addins
return addin;
}
- internal AddinDescription Load (Addin iad)
- {
- ainfo = iad;
-
- AddinDescription description = iad.Description;
- id = description.AddinId;
- baseDirectory = description.BasePath;
- module = description.MainModule;
- module.RuntimeAddin = this;
- localizerDescription = description.Localizer;
- return description;
- }
-
AddinLocalizer LoadLocalizer ()
{
if (localizerDescription != null) {
diff --git a/Mono.Addins/Mono.Addins/TreeNode.cs b/Mono.Addins/Mono.Addins/TreeNode.cs
index 827545c..8cccdab 100644
--- a/Mono.Addins/Mono.Addins/TreeNode.cs
+++ b/Mono.Addins/Mono.Addins/TreeNode.cs
@@ -42,12 +42,12 @@ namespace Mono.Addins
ImmutableArray<TreeNode> children;
ExtensionNode extensionNode;
bool childrenLoaded;
- string id;
+ readonly string id;
TreeNode parent;
ExtensionNodeSet nodeTypes;
ExtensionPoint extensionPoint;
BaseCondition condition;
- protected AddinEngine addinEngine;
+ protected readonly AddinEngine addinEngine;
public TreeNode (AddinEngine addinEngine, string id)
{