aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs394
1 files changed, 197 insertions, 197 deletions
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs
index 96670f1..b0b4662 100644
--- a/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs
+++ b/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs
@@ -1,197 +1,197 @@
1using System; 1using System;
2using System.Collections.Generic; 2using System.Collections.Generic;
3using System.Text; 3using System.Text;
4using System.Reflection; 4using System.Reflection;
5using System.Threading; 5using System.Threading;
6using System.Runtime.Remoting; 6using System.Runtime.Remoting;
7using System.IO; 7using System.IO;
8using OpenSim.Region.Environment.Scenes; 8using OpenSim.Region.Environment.Scenes;
9using OpenSim.Region.Environment.Scenes.Scripting; 9using OpenSim.Region.Environment.Scenes.Scripting;
10using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL; 10using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL;
11using OpenSim.Region.ScriptEngine.Common; 11using OpenSim.Region.ScriptEngine.Common;
12using libsecondlife; 12using libsecondlife;
13 13
14namespace OpenSim.Region.ScriptEngine.DotNetEngine 14namespace OpenSim.Region.ScriptEngine.DotNetEngine
15{ 15{
16 public class AppDomainManager 16 public class AppDomainManager
17 { 17 {
18 private int maxScriptsPerAppDomain = 1; 18 private int maxScriptsPerAppDomain = 1;
19 /// <summary> 19 /// <summary>
20 /// Internal list of all AppDomains 20 /// Internal list of all AppDomains
21 /// </summary> 21 /// </summary>
22 private List<AppDomainStructure> appDomains = new List<AppDomainStructure>(); 22 private List<AppDomainStructure> appDomains = new List<AppDomainStructure>();
23 /// <summary> 23 /// <summary>
24 /// Structure to keep track of data around AppDomain 24 /// Structure to keep track of data around AppDomain
25 /// </summary> 25 /// </summary>
26 private class AppDomainStructure 26 private class AppDomainStructure
27 { 27 {
28 /// <summary> 28 /// <summary>
29 /// The AppDomain itself 29 /// The AppDomain itself
30 /// </summary> 30 /// </summary>
31 public AppDomain CurrentAppDomain; 31 public AppDomain CurrentAppDomain;
32 /// <summary> 32 /// <summary>
33 /// Number of scripts loaded into AppDomain 33 /// Number of scripts loaded into AppDomain
34 /// </summary> 34 /// </summary>
35 public int ScriptsLoaded; 35 public int ScriptsLoaded;
36 /// <summary> 36 /// <summary>
37 /// Number of dead scripts 37 /// Number of dead scripts
38 /// </summary> 38 /// </summary>
39 public int ScriptsWaitingUnload; 39 public int ScriptsWaitingUnload;
40 } 40 }
41 /// <summary> 41 /// <summary>
42 /// Current AppDomain 42 /// Current AppDomain
43 /// </summary> 43 /// </summary>
44 private AppDomainStructure currentAD; 44 private AppDomainStructure currentAD;
45 private object getLock = new object(); // Mutex 45 private object getLock = new object(); // Mutex
46 private object freeLock = new object(); // Mutex 46 private object freeLock = new object(); // Mutex
47 47
48 //private ScriptEngine m_scriptEngine; 48 //private ScriptEngine m_scriptEngine;
49 //public AppDomainManager(ScriptEngine scriptEngine) 49 //public AppDomainManager(ScriptEngine scriptEngine)
50 public AppDomainManager() 50 public AppDomainManager()
51 { 51 {
52 //m_scriptEngine = scriptEngine; 52 //m_scriptEngine = scriptEngine;
53 } 53 }
54 54
55 /// <summary> 55 /// <summary>
56 /// Find a free AppDomain, creating one if necessary 56 /// Find a free AppDomain, creating one if necessary
57 /// </summary> 57 /// </summary>
58 /// <returns>Free AppDomain</returns> 58 /// <returns>Free AppDomain</returns>
59 private AppDomainStructure GetFreeAppDomain() 59 private AppDomainStructure GetFreeAppDomain()
60 { 60 {
61 Console.WriteLine("Finding free AppDomain"); 61 Console.WriteLine("Finding free AppDomain");
62 lock (getLock) 62 lock (getLock)
63 { 63 {
64 // Current full? 64 // Current full?
65 if (currentAD != null && currentAD.ScriptsLoaded >= maxScriptsPerAppDomain) 65 if (currentAD != null && currentAD.ScriptsLoaded >= maxScriptsPerAppDomain)
66 { 66 {
67 // Add it to AppDomains list and empty current 67 // Add it to AppDomains list and empty current
68 appDomains.Add(currentAD); 68 appDomains.Add(currentAD);
69 currentAD = null; 69 currentAD = null;
70 } 70 }
71 // No current 71 // No current
72 if (currentAD == null) 72 if (currentAD == null)
73 { 73 {
74 // Create a new current AppDomain 74 // Create a new current AppDomain
75 currentAD = new AppDomainStructure(); 75 currentAD = new AppDomainStructure();
76 currentAD.CurrentAppDomain = PrepareNewAppDomain(); 76 currentAD.CurrentAppDomain = PrepareNewAppDomain();
77 } 77 }
78 78
79 Console.WriteLine("Scripts loaded in this Appdomain: " + currentAD.ScriptsLoaded); 79 Console.WriteLine("Scripts loaded in this Appdomain: " + currentAD.ScriptsLoaded);
80 return currentAD; 80 return currentAD;
81 } // lock 81 } // lock
82 } 82 }
83 83
84 private int AppDomainNameCount; 84 private int AppDomainNameCount;
85 /// <summary> 85 /// <summary>
86 /// Create and prepare a new AppDomain for scripts 86 /// Create and prepare a new AppDomain for scripts
87 /// </summary> 87 /// </summary>
88 /// <returns>The new AppDomain</returns> 88 /// <returns>The new AppDomain</returns>
89 private AppDomain PrepareNewAppDomain() 89 private AppDomain PrepareNewAppDomain()
90 { 90 {
91 // Create and prepare a new AppDomain 91 // Create and prepare a new AppDomain
92 AppDomainNameCount++; 92 AppDomainNameCount++;
93 // TODO: Currently security match current appdomain 93 // TODO: Currently security match current appdomain
94 94
95 // Construct and initialize settings for a second AppDomain. 95 // Construct and initialize settings for a second AppDomain.
96 AppDomainSetup ads = new AppDomainSetup(); 96 AppDomainSetup ads = new AppDomainSetup();
97 ads.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory; 97 ads.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
98 ads.DisallowBindingRedirects = false; 98 ads.DisallowBindingRedirects = false;
99 ads.DisallowCodeDownload = true; 99 ads.DisallowCodeDownload = true;
100 ads.ShadowCopyFiles = "true"; // Enabled shadowing 100 ads.ShadowCopyFiles = "true"; // Enabled shadowing
101 ads.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; 101 ads.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
102 102
103 AppDomain AD = AppDomain.CreateDomain("ScriptAppDomain_" + AppDomainNameCount, null, ads); 103 AppDomain AD = AppDomain.CreateDomain("ScriptAppDomain_" + AppDomainNameCount, null, ads);
104 104
105 // Return the new AppDomain 105 // Return the new AppDomain
106 return AD; 106 return AD;
107 107
108 } 108 }
109 109
110 /// <summary> 110 /// <summary>
111 /// Unload appdomains that are full and have only dead scripts 111 /// Unload appdomains that are full and have only dead scripts
112 /// </summary> 112 /// </summary>
113 private void UnloadAppDomains() 113 private void UnloadAppDomains()
114 { 114 {
115 lock (freeLock) 115 lock (freeLock)
116 { 116 {
117 // Go through all 117 // Go through all
118 foreach (AppDomainStructure ads in new System.Collections.ArrayList(appDomains)) 118 foreach (AppDomainStructure ads in new System.Collections.ArrayList(appDomains))
119 { 119 {
120 // Don't process current AppDomain 120 // Don't process current AppDomain
121 if (ads.CurrentAppDomain != currentAD.CurrentAppDomain) 121 if (ads.CurrentAppDomain != currentAD.CurrentAppDomain)
122 { 122 {
123 // Not current AppDomain 123 // Not current AppDomain
124 // Is number of unloaded bigger or equal to number of loaded? 124 // Is number of unloaded bigger or equal to number of loaded?
125 if (ads.ScriptsLoaded <= ads.ScriptsWaitingUnload) 125 if (ads.ScriptsLoaded <= ads.ScriptsWaitingUnload)
126 { 126 {
127 Console.WriteLine("Found empty AppDomain, unloading"); 127 Console.WriteLine("Found empty AppDomain, unloading");
128 // Remove from internal list 128 // Remove from internal list
129 appDomains.Remove(ads); 129 appDomains.Remove(ads);
130#if DEBUG 130#if DEBUG
131 long m = GC.GetTotalMemory(true); 131 long m = GC.GetTotalMemory(true);
132#endif 132#endif
133 // Unload 133 // Unload
134 AppDomain.Unload(ads.CurrentAppDomain); 134 AppDomain.Unload(ads.CurrentAppDomain);
135#if DEBUG 135#if DEBUG
136 Console.WriteLine("AppDomain unload freed " + (m - GC.GetTotalMemory(true)) + " bytes of memory"); 136 Console.WriteLine("AppDomain unload freed " + (m - GC.GetTotalMemory(true)) + " bytes of memory");
137#endif 137#endif
138 } 138 }
139 } 139 }
140 } // foreach 140 } // foreach
141 } // lock 141 } // lock
142 } 142 }
143 143
144 144
145 145
146 public OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL.LSL_BaseClass LoadScript(string FileName) 146 public OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL.LSL_BaseClass LoadScript(string FileName)
147 { 147 {
148 // Find next available AppDomain to put it in 148 // Find next available AppDomain to put it in
149 AppDomainStructure FreeAppDomain = GetFreeAppDomain(); 149 AppDomainStructure FreeAppDomain = GetFreeAppDomain();
150 150
151 Console.WriteLine("Loading into AppDomain: " + FileName); 151 Console.WriteLine("Loading into AppDomain: " + FileName);
152 LSL_BaseClass mbrt = (LSL_BaseClass)FreeAppDomain.CurrentAppDomain.CreateInstanceFromAndUnwrap(FileName, "SecondLife.Script"); 152 LSL_BaseClass mbrt = (LSL_BaseClass)FreeAppDomain.CurrentAppDomain.CreateInstanceFromAndUnwrap(FileName, "SecondLife.Script");
153 //Console.WriteLine("ScriptEngine AppDomainManager: is proxy={0}", RemotingServices.IsTransparentProxy(mbrt)); 153 //Console.WriteLine("ScriptEngine AppDomainManager: is proxy={0}", RemotingServices.IsTransparentProxy(mbrt));
154 FreeAppDomain.ScriptsLoaded++; 154 FreeAppDomain.ScriptsLoaded++;
155 155
156 return mbrt; 156 return mbrt;
157 } 157 }
158 158
159 159
160 /// <summary> 160 /// <summary>
161 /// Increase "dead script" counter for an AppDomain 161 /// Increase "dead script" counter for an AppDomain
162 /// </summary> 162 /// </summary>
163 /// <param name="ad"></param> 163 /// <param name="ad"></param>
164 //[Obsolete("Needs fixing, needs a real purpose in life!!!")] 164 //[Obsolete("Needs fixing, needs a real purpose in life!!!")]
165 public void StopScript(AppDomain ad) 165 public void StopScript(AppDomain ad)
166 { 166 {
167 lock (freeLock) 167 lock (freeLock)
168 { 168 {
169 Console.WriteLine("Stopping script in AppDomain"); 169 Console.WriteLine("Stopping script in AppDomain");
170 // Check if it is current AppDomain 170 // Check if it is current AppDomain
171 if (currentAD.CurrentAppDomain == ad) 171 if (currentAD.CurrentAppDomain == ad)
172 { 172 {
173 // Yes - increase 173 // Yes - increase
174 currentAD.ScriptsWaitingUnload++; 174 currentAD.ScriptsWaitingUnload++;
175 return; 175 return;
176 } 176 }
177 177
178 // Lopp through all AppDomains 178 // Lopp through all AppDomains
179 foreach (AppDomainStructure ads in new System.Collections.ArrayList(appDomains)) 179 foreach (AppDomainStructure ads in new System.Collections.ArrayList(appDomains))
180 { 180 {
181 if (ads.CurrentAppDomain == ad) 181 if (ads.CurrentAppDomain == ad)
182 { 182 {
183 // Found it 183 // Found it
184 ads.ScriptsWaitingUnload++; 184 ads.ScriptsWaitingUnload++;
185 break; 185 break;
186 } 186 }
187 } // foreach 187 } // foreach
188 } // lock 188 } // lock
189 189
190 UnloadAppDomains(); // Outsite lock, has its own GetLock 190 UnloadAppDomains(); // Outsite lock, has its own GetLock
191 191
192 192
193 } 193 }
194 194
195 195
196 } 196 }
197} 197}