]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-8932 - Add in process loading via LoadEmbeddedPlugins
authorMichael Giagnocavo <mgg@giagnocavo.net>
Mon, 14 Mar 2016 00:29:03 +0000 (18:29 -0600)
committerMichael Giagnocavo <mgg@giagnocavo.net>
Mon, 14 Mar 2016 00:29:03 +0000 (18:29 -0600)
src/mod/languages/mod_managed/managed/Loader.cs
src/mod/languages/mod_managed/managed/PluginManager.cs

index e3803ae427ac7b37ae77893585f25070c8d1dbfd..e81157d1b65818aa1b7933490f75959de7f190b2 100644 (file)
@@ -141,7 +141,9 @@ namespace FreeSWITCH {
         \r
         static void watcher_Changed(object sender, FileSystemEventArgs e) {\r
             Action<string> queueFile = fileName => {\r
-                var currentPi = pluginInfos.FirstOrDefault(p => string.Compare(fileName, p.FileName, StringComparison.OrdinalIgnoreCase) == 0);\r
+                var currentPi = pluginInfos\r
+                    .Where(x => !string.IsNullOrEmpty(x.FileName))\r
+                    .FirstOrDefault(p => string.Compare(fileName, p.FileName, StringComparison.OrdinalIgnoreCase) == 0);\r
                 if (currentPi != null) {\r
                     var noReload = currentPi.Manager.ApiExecutors.Any(x => (x.PluginOptions & PluginOptions.NoAutoReload) == PluginOptions.NoAutoReload) ||\r
                                    currentPi.Manager.AppExecutors.Any(x => (x.PluginOptions & PluginOptions.NoAutoReload) == PluginOptions.NoAutoReload);\r
@@ -259,7 +261,7 @@ namespace FreeSWITCH {
             System.Threading.Interlocked.Increment(ref appDomainCount);\r
             setup.ApplicationName = Path.GetFileName(fileName) + "_" + appDomainCount;\r
             var domain = AppDomain.CreateDomain(setup.ApplicationName, null, setup);\r
-                \r
+\r
             PluginManager pm;\r
             try {\r
                 pm = (PluginManager)domain.CreateInstanceAndUnwrap(pmType.Assembly.FullName, pmType.FullName, null);\r
@@ -276,9 +278,17 @@ namespace FreeSWITCH {
                 return;\r
             }\r
 \r
+            addPlugin(fileName, domain, pm);\r
+        }\r
+\r
+        static void addPlugin(string fileName, AppDomain domain, PluginManager pm) {\r
             // Update dictionaries atomically\r
             lock (loaderLock) {\r
-                unloadFile(fileName);\r
+                if (!string.IsNullOrEmpty(fileName)) {\r
+                    if (domain == null) throw new ApplicationException("File based plugins must specify an AppDomain.");\r
+                    unloadFile(fileName);\r
+                }\r
+                if (domain == null) domain = AppDomain.CurrentDomain;\r
 \r
                 var pi = new PluginInfo { FileName = fileName, Domain = domain, Manager = pm };\r
                 pluginInfos.Add(pi);\r
@@ -298,6 +308,11 @@ namespace FreeSWITCH {
             }\r
         }\r
 \r
+        public static void LoadEmbeddedPlugins(Assembly asm) {\r
+            var pm = new EmbeddedPluginManager(asm);\r
+            addPlugin(null, null, pm);\r
+        }\r
+\r
         static void unloadFile(string fileName) {\r
             List<PluginInfo> pisToRemove;\r
             lock (loaderLock) {\r
index f9bcf7f5b5aa8fd83327cad75e366a48b315451e..c5900e19b6cd2ba95667e8e8d8344155e8235081 100644 (file)
@@ -250,7 +250,7 @@ namespace FreeSWITCH {
             }\r
         }\r
 \r
-        public void BlockUntilUnloadIsSafe() {\r
+        public virtual void BlockUntilUnloadIsSafe() {\r
             if (isUnloading) throw new InvalidOperationException("PluginManager is already unloading.");\r
             isUnloading = true;\r
             unloadCount = ApiExecutors.Count + AppExecutors.Count;\r
@@ -310,4 +310,36 @@ namespace FreeSWITCH {
 \r
     }\r
 \r
+    internal class EmbeddedPluginManager : PluginManager {\r
+        \r
+        // This is for cases where FreeSWITCH is "embedded", that is a .NET app hosts the FS core lib itself.\r
+        // In such a case, there may be plugins defined in the main process that need to share address space\r
+        // and be loaded from the main assembly. This class plus changes in Loader.cs (null filenames=embedded)\r
+        // work together to allow such plugins to work. These plugins cannot be reloaded. \r
+\r
+        Assembly asm;\r
+        public EmbeddedPluginManager(Assembly asm) {\r
+            this.asm = asm;\r
+            var allTypes = asm.GetExportedTypes();\r
+            var opts = GetOptions(allTypes);\r
+            AddApiPlugins(allTypes, opts);\r
+            AddAppPlugins(allTypes, opts);\r
+        }\r
+\r
+        protected override bool LoadInternal(string fileName) {\r
+            throw new NotImplementedException("EmbeddedPluginManager should not have Load[Internal] called.");\r
+        }\r
+\r
+        public override void BlockUntilUnloadIsSafe() {\r
+            throw new NotImplementedException("EmbeddedPluginManager should never be unloaded.");\r
+        }\r
+\r
+    }\r
+\r
+    public static class EmbeddedLoader {\r
+        public static void LoadEmbeddedPlugins(Assembly asm) {\r
+            Loader.LoadEmbeddedPlugins(asm);\r
+        }\r
+    }\r
+\r
 }\r