aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs')
-rw-r--r--OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs106
1 files changed, 39 insertions, 67 deletions
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs
index 5a77d39..da461e3 100644
--- a/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs
+++ b/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs
@@ -37,46 +37,37 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
37 public class AppDomainManager : iScriptEngineFunctionModule 37 public class AppDomainManager : iScriptEngineFunctionModule
38 { 38 {
39 // 39 //
40 // This class does AppDomain handling and loading/unloading of scripts in it. 40 // This class does AppDomain handling and loading/unloading of
41 // It is instanced in "ScriptEngine" and controlled from "ScriptManager" 41 // scripts in it. It is instanced in "ScriptEngine" and controlled
42 // from "ScriptManager"
42 // 43 //
43 // 1. Create a new AppDomain if old one is full (or doesn't exist) 44 // 1. Create a new AppDomain if old one is full (or doesn't exist)
44 // 2. Load scripts into AppDomain 45 // 2. Load scripts into AppDomain
45 // 3. Unload scripts from AppDomain (stopping them and marking them as inactive) 46 // 3. Unload scripts from AppDomain (stopping them and marking
47 // them as inactive)
46 // 4. Unload AppDomain completely when all scripts in it has stopped 48 // 4. Unload AppDomain completely when all scripts in it has stopped
47 // 49 //
48 50
49 private int maxScriptsPerAppDomain = 1; 51 private int maxScriptsPerAppDomain = 1;
50 52
51 /// <summary> 53 // Internal list of all AppDomains
52 /// Internal list of all AppDomains 54 private List<AppDomainStructure> appDomains =
53 /// </summary> 55 new List<AppDomainStructure>();
54 private List<AppDomainStructure> appDomains = new List<AppDomainStructure>();
55 56
56 /// <summary> 57 // Structure to keep track of data around AppDomain
57 /// Structure to keep track of data around AppDomain
58 /// </summary>
59 private class AppDomainStructure 58 private class AppDomainStructure
60 { 59 {
61 /// <summary> 60 // The AppDomain itself
62 /// The AppDomain itself
63 /// </summary>
64 public AppDomain CurrentAppDomain; 61 public AppDomain CurrentAppDomain;
65 62
66 /// <summary> 63 // Number of scripts loaded into AppDomain
67 /// Number of scripts loaded into AppDomain
68 /// </summary>
69 public int ScriptsLoaded; 64 public int ScriptsLoaded;
70 65
71 /// <summary> 66 // Number of dead scripts
72 /// Number of dead scripts
73 /// </summary>
74 public int ScriptsWaitingUnload; 67 public int ScriptsWaitingUnload;
75 } 68 }
76 69
77 /// <summary> 70 // Current AppDomain
78 /// Current AppDomain
79 /// </summary>
80 private AppDomainStructure currentAD; 71 private AppDomainStructure currentAD;
81 72
82 private object getLock = new object(); // Mutex 73 private object getLock = new object(); // Mutex
@@ -92,20 +83,18 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
92 83
93 public void ReadConfig() 84 public void ReadConfig()
94 { 85 {
95 maxScriptsPerAppDomain = m_scriptEngine.ScriptConfigSource.GetInt("ScriptsPerAppDomain", 1); 86 maxScriptsPerAppDomain = m_scriptEngine.ScriptConfigSource.GetInt(
87 "ScriptsPerAppDomain", 1);
96 } 88 }
97 89
98 /// <summary> 90 // Find a free AppDomain, creating one if necessary
99 /// Find a free AppDomain, creating one if necessary
100 /// </summary>
101 /// <returns>Free AppDomain</returns>
102 private AppDomainStructure GetFreeAppDomain() 91 private AppDomainStructure GetFreeAppDomain()
103 { 92 {
104 // Console.WriteLine("Finding free AppDomain");
105 lock (getLock) 93 lock (getLock)
106 { 94 {
107 // Current full? 95 // Current full?
108 if (currentAD != null && currentAD.ScriptsLoaded >= maxScriptsPerAppDomain) 96 if (currentAD != null &&
97 currentAD.ScriptsLoaded >= maxScriptsPerAppDomain)
109 { 98 {
110 // Add it to AppDomains list and empty current 99 // Add it to AppDomains list and empty current
111 appDomains.Add(currentAD); 100 appDomains.Add(currentAD);
@@ -119,21 +108,18 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
119 currentAD.CurrentAppDomain = PrepareNewAppDomain(); 108 currentAD.CurrentAppDomain = PrepareNewAppDomain();
120 } 109 }
121 110
122 // Console.WriteLine("Scripts loaded in this Appdomain: " + currentAD.ScriptsLoaded);
123 return currentAD; 111 return currentAD;
124 } 112 }
125 } 113 }
126 114
127 private int AppDomainNameCount; 115 private int AppDomainNameCount;
128 116
129 /// <summary> 117 // Create and prepare a new AppDomain for scripts
130 /// Create and prepare a new AppDomain for scripts
131 /// </summary>
132 /// <returns>The new AppDomain</returns>
133 private AppDomain PrepareNewAppDomain() 118 private AppDomain PrepareNewAppDomain()
134 { 119 {
135 // Create and prepare a new AppDomain 120 // Create and prepare a new AppDomain
136 AppDomainNameCount++; 121 AppDomainNameCount++;
122
137 // TODO: Currently security match current appdomain 123 // TODO: Currently security match current appdomain
138 124
139 // Construct and initialize settings for a second AppDomain. 125 // Construct and initialize settings for a second AppDomain.
@@ -143,21 +129,24 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
143 ads.DisallowCodeDownload = true; 129 ads.DisallowCodeDownload = true;
144 ads.LoaderOptimization = LoaderOptimization.MultiDomainHost; 130 ads.LoaderOptimization = LoaderOptimization.MultiDomainHost;
145 ads.ShadowCopyFiles = "false"; // Disable shadowing 131 ads.ShadowCopyFiles = "false"; // Disable shadowing
146 ads.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; 132 ads.ConfigurationFile =
133 AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
147 134
148 135
149 AppDomain AD = AppDomain.CreateDomain("ScriptAppDomain_" + AppDomainNameCount, null, ads); 136 AppDomain AD = AppDomain.CreateDomain("ScriptAppDomain_" +
150 m_scriptEngine.Log.Info("[" + m_scriptEngine.ScriptEngineName + "]: AppDomain Loading: " + 137 AppDomainNameCount, null, ads);
151 AssemblyName.GetAssemblyName("OpenSim.Region.ScriptEngine.Shared.dll").ToString()); 138 m_scriptEngine.Log.Info("[" + m_scriptEngine.ScriptEngineName +
152 AD.Load(AssemblyName.GetAssemblyName("OpenSim.Region.ScriptEngine.Shared.dll")); 139 "]: AppDomain Loading: " +
140 AssemblyName.GetAssemblyName(
141 "OpenSim.Region.ScriptEngine.Shared.dll").ToString());
142 AD.Load(AssemblyName.GetAssemblyName(
143 "OpenSim.Region.ScriptEngine.Shared.dll"));
153 144
154 // Return the new AppDomain 145 // Return the new AppDomain
155 return AD; 146 return AD;
156 } 147 }
157 148
158 /// <summary> 149 // Unload appdomains that are full and have only dead scripts
159 /// Unload appdomains that are full and have only dead scripts
160 /// </summary>
161 private void UnloadAppDomains() 150 private void UnloadAppDomains()
162 { 151 {
163 lock (freeLock) 152 lock (freeLock)
@@ -174,15 +163,9 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
174 { 163 {
175 // Remove from internal list 164 // Remove from internal list
176 appDomains.Remove(ads); 165 appDomains.Remove(ads);
177//#if DEBUG 166
178 //Console.WriteLine("Found empty AppDomain, unloading");
179 //long m = GC.GetTotalMemory(true); // This force a garbage collect that freezes some windows plateforms
180//#endif
181 // Unload 167 // Unload
182 AppDomain.Unload(ads.CurrentAppDomain); 168 AppDomain.Unload(ads.CurrentAppDomain);
183//#if DEBUG
184 //m_scriptEngine.Log.Info("[" + m_scriptEngine.ScriptEngineName + "]: AppDomain unload freed " + (m - GC.GetTotalMemory(true)) + " bytes of memory");
185//#endif
186 } 169 }
187 } 170 }
188 } 171 }
@@ -194,13 +177,10 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
194 // Find next available AppDomain to put it in 177 // Find next available AppDomain to put it in
195 AppDomainStructure FreeAppDomain = GetFreeAppDomain(); 178 AppDomainStructure FreeAppDomain = GetFreeAppDomain();
196 179
197#if DEBUG 180 IScript mbrt = (IScript)
198 m_scriptEngine.Log.Info("[" + m_scriptEngine.ScriptEngineName + "]: Loading into AppDomain: " + FileName); 181 FreeAppDomain.CurrentAppDomain.CreateInstanceFromAndUnwrap(
199#endif 182 FileName, "SecondLife.Script");
200 IScript mbrt = 183
201 (IScript)
202 FreeAppDomain.CurrentAppDomain.CreateInstanceFromAndUnwrap(FileName, "SecondLife.Script");
203 //Console.WriteLine("ScriptEngine AppDomainManager: is proxy={0}", RemotingServices.IsTransparentProxy(mbrt));
204 FreeAppDomain.ScriptsLoaded++; 184 FreeAppDomain.ScriptsLoaded++;
205 ad = FreeAppDomain.CurrentAppDomain; 185 ad = FreeAppDomain.CurrentAppDomain;
206 186
@@ -208,18 +188,11 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
208 } 188 }
209 189
210 190
211 /// <summary> 191 // Increase "dead script" counter for an AppDomain
212 /// Increase "dead script" counter for an AppDomain
213 /// </summary>
214 /// <param name="ad"></param>
215 //[Obsolete("Needs fixing, needs a real purpose in life!!!")]
216 public void StopScript(AppDomain ad) 192 public void StopScript(AppDomain ad)
217 { 193 {
218 lock (freeLock) 194 lock (freeLock)
219 { 195 {
220#if DEBUG
221 m_scriptEngine.Log.Info("[" + m_scriptEngine.ScriptEngineName + "]: Stopping script in AppDomain");
222#endif
223 // Check if it is current AppDomain 196 // Check if it is current AppDomain
224 if (currentAD.CurrentAppDomain == ad) 197 if (currentAD.CurrentAppDomain == ad)
225 { 198 {
@@ -243,9 +216,8 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
243 UnloadAppDomains(); // Outsite lock, has its own GetLock 216 UnloadAppDomains(); // Outsite lock, has its own GetLock
244 } 217 }
245 218
246 /// <summary> 219 // If set to true then threads and stuff should try
247 /// If set to true then threads and stuff should try to make a graceful exit 220 // to make a graceful exit
248 /// </summary>
249 public bool PleaseShutdown 221 public bool PleaseShutdown
250 { 222 {
251 get { return _PleaseShutdown; } 223 get { return _PleaseShutdown; }