aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs
blob: 1e20547c5e03a96b4c6da7e21c1647c1ce69be1d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Threading;
using System.Runtime.Remoting;
using System.IO;

namespace OpenSim.Region.ScriptEngine.DotNetEngine
{
    public class AppDomainManager
    {
        private int MaxScriptsPerAppDomain = 10;
        private List<AppDomainStructure> AppDomains = new List<AppDomainStructure>();
        private struct AppDomainStructure
        {
            /// <summary>
            /// The AppDomain itself
            /// </summary>
            public AppDomain CurrentAppDomain;
            /// <summary>
            /// Number of scripts loaded into AppDomain
            /// </summary>
            public int ScriptsLoaded;
            /// <summary>
            /// Number of dead scripts
            /// </summary>
            public int ScriptsWaitingUnload;
        }
        private AppDomainStructure CurrentAD;
        private object GetLock = new object();

                private ScriptEngine m_scriptEngine;
        public AppDomainManager(ScriptEngine scriptEngine)
        {
            m_scriptEngine = scriptEngine;
        }

        internal AppDomain GetFreeAppDomain()
        {
            lock(GetLock) {
                // No current or current full?
                if (CurrentAD.CurrentAppDomain == null || CurrentAD.ScriptsLoaded >= MaxScriptsPerAppDomain)
                {
                    // Create a new current AppDomain
                    CurrentAD = new AppDomainStructure();
                    CurrentAD.ScriptsWaitingUnload = 0; // to avoid compile warning for not in use
                    CurrentAD.CurrentAppDomain = PrepareNewAppDomain();
                    AppDomains.Add(CurrentAD);

                }

                // Increase number of scripts loaded
                CurrentAD.ScriptsLoaded++;
                // Return AppDomain
                return CurrentAD.CurrentAppDomain;
            } // lock
        }

        private int AppDomainNameCount;
        private AppDomain PrepareNewAppDomain()
        {
            // Create and prepare a new AppDomain
            AppDomainNameCount++;
            // TODO: Currently security and configuration match current appdomain

            // Construct and initialize settings for a second AppDomain.
            AppDomainSetup ads = new AppDomainSetup();
            ads.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
                //Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ScriptEngines");
            //ads.ApplicationName = "DotNetScriptEngine";
            //ads.DynamicBase = ads.ApplicationBase;
            
            Console.WriteLine("AppDomain BaseDirectory: " + ads.ApplicationBase);
            ads.DisallowBindingRedirects = false;
            ads.DisallowCodeDownload = true;
            ads.ShadowCopyFiles = "true";
            
            ads.ConfigurationFile =
                AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;

            AppDomain AD = AppDomain.CreateDomain("ScriptAppDomain_" + AppDomainNameCount, null, ads);
            foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies())
            {
                //Console.WriteLine("Loading: " + a.GetName(true));
                try
                {
                    AD.Load(a.GetName(true));
                    
                }
                catch (Exception e)
                {
                    //Console.WriteLine("FAILED load");
                }
                
            }

            Console.WriteLine("Assembly file: " + this.GetType().Assembly.CodeBase);
            Console.WriteLine("Assembly name: " + this.GetType().ToString());
            //AD.CreateInstanceFrom(this.GetType().Assembly.CodeBase, "OpenSim.Region.ScriptEngine.DotNetEngine.ScriptEngine");

            //AD.Load(this.GetType().Assembly.CodeBase);

            Console.WriteLine("Done preparing new appdomain.");
            return AD;

        }

        public class NOOP : MarshalByRefType
        {
            public NOOP() {
            }
        }
    }
}