diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs')
-rw-r--r-- | OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs | 394 |
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 @@ | |||
1 | using System; | 1 | using System; |
2 | using System.Collections.Generic; | 2 | using System.Collections.Generic; |
3 | using System.Text; | 3 | using System.Text; |
4 | using System.Reflection; | 4 | using System.Reflection; |
5 | using System.Threading; | 5 | using System.Threading; |
6 | using System.Runtime.Remoting; | 6 | using System.Runtime.Remoting; |
7 | using System.IO; | 7 | using System.IO; |
8 | using OpenSim.Region.Environment.Scenes; | 8 | using OpenSim.Region.Environment.Scenes; |
9 | using OpenSim.Region.Environment.Scenes.Scripting; | 9 | using OpenSim.Region.Environment.Scenes.Scripting; |
10 | using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL; | 10 | using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL; |
11 | using OpenSim.Region.ScriptEngine.Common; | 11 | using OpenSim.Region.ScriptEngine.Common; |
12 | using libsecondlife; | 12 | using libsecondlife; |
13 | 13 | ||
14 | namespace OpenSim.Region.ScriptEngine.DotNetEngine | 14 | namespace 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 | } |