diff options
author | Lluis Sanchez <lluis@xamarin.com> | 2013-07-03 17:47:14 +0400 |
---|---|---|
committer | Lluis Sanchez <lluis@xamarin.com> | 2013-07-03 17:47:14 +0400 |
commit | a5428fb07e23cb439447e19ee26c17c44c740931 (patch) | |
tree | ae994d065530009e6ef52161f4ae92d7bd38b16e | |
parent | 26d48b684b9cacb4058ee91333dd388e5c857ded (diff) |
Fix deadlock when loading add-in rootsthreadsafe
Don't try to load add-ins in the assembly load handler, since it may lead to
app domain creation and cause a deadlock in the runtime.
-rwxr-xr-x | Mono.Addins/Mono.Addins/AddinEngine.cs | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/Mono.Addins/Mono.Addins/AddinEngine.cs b/Mono.Addins/Mono.Addins/AddinEngine.cs index fdad615..e7e5f13 100755 --- a/Mono.Addins/Mono.Addins/AddinEngine.cs +++ b/Mono.Addins/Mono.Addins/AddinEngine.cs @@ -318,6 +318,7 @@ namespace Mono.Addins internal RuntimeAddin GetAddinForAssembly (Assembly asm) { + ValidateAddinRoots (); RuntimeAddin ad; loadedAssemblies.TryGetValue (asm, out ad); return ad; @@ -385,11 +386,13 @@ namespace Mono.Addins public bool IsAddinLoaded (string id) { CheckInitialized (); + ValidateAddinRoots (); return loadedAddins.ContainsKey (Addin.GetIdName (id)); } internal RuntimeAddin GetAddin (string id) { + ValidateAddinRoots (); RuntimeAddin a; loadedAddins.TryGetValue (Addin.GetIdName (id), out a); return a; @@ -688,12 +691,34 @@ namespace Mono.Addins void OnAssemblyLoaded (object s, AssemblyLoadEventArgs a) { - if (a != null) - CheckHostAssembly (a.LoadedAssembly); + if (a != null) { + lock (pendingRootChecks) { + pendingRootChecks.Add (a.LoadedAssembly); + } + } } - + + List<Assembly> pendingRootChecks = new List<Assembly> (); + + internal void ValidateAddinRoots () + { + List<Assembly> copy = null; + lock (pendingRootChecks) { + if (pendingRootChecks.Count > 0) { + copy = new List<Assembly> (pendingRootChecks); + pendingRootChecks.Clear (); + } + } + if (copy != null) { + foreach (Assembly asm in copy) + CheckHostAssembly (asm); + } + } + internal void ActivateRoots () { + lock (pendingRootChecks) + pendingRootChecks.Clear (); foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies ()) CheckHostAssembly (asm); } |