aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AppDomainManager.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AppDomainManager.cs')
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AppDomainManager.cs476
1 files changed, 238 insertions, 238 deletions
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AppDomainManager.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AppDomainManager.cs
index df00d4e..68ad88d 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AppDomainManager.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AppDomainManager.cs
@@ -1,239 +1,239 @@
1/* 1/*
2* Copyright (c) Contributors, http://opensimulator.org/ 2* Copyright (c) Contributors, http://opensimulator.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders. 3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4* 4*
5* Redistribution and use in source and binary forms, with or without 5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met: 6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright 7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer. 8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright 9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the 10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution. 11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the 12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products 13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission. 14* derived from this software without specific prior written permission.
15* 15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY 16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26* 26*
27*/ 27*/
28 28
29 29
30using System; 30using System;
31using System.Collections; 31using System.Collections;
32using System.Collections.Generic; 32using System.Collections.Generic;
33using System.Reflection; 33using System.Reflection;
34using OpenSim.Region.ScriptEngine.Common; 34using OpenSim.Region.ScriptEngine.Common;
35 35
36namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase 36namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
37{ 37{
38 public class AppDomainManager 38 public class AppDomainManager
39 { 39 {
40 40
41 // 41 //
42 // This class does AppDomain handling and loading/unloading of scripts in it. 42 // This class does AppDomain handling and loading/unloading of scripts in it.
43 // It is instanced in "ScriptEngine" and controlled from "ScriptManager" 43 // It is instanced in "ScriptEngine" and controlled from "ScriptManager"
44 // 44 //
45 // 1. Create a new AppDomain if old one is full (or doesn't exist) 45 // 1. Create a new AppDomain if old one is full (or doesn't exist)
46 // 2. Load scripts into AppDomain 46 // 2. Load scripts into AppDomain
47 // 3. Unload scripts from AppDomain (stopping them and marking them as inactive) 47 // 3. Unload scripts from AppDomain (stopping them and marking them as inactive)
48 // 4. Unload AppDomain completely when all scripts in it has stopped 48 // 4. Unload AppDomain completely when all scripts in it has stopped
49 // 49 //
50 50
51 51
52 private int maxScriptsPerAppDomain = 1; 52 private int maxScriptsPerAppDomain = 1;
53 53
54 /// <summary> 54 /// <summary>
55 /// Internal list of all AppDomains 55 /// Internal list of all AppDomains
56 /// </summary> 56 /// </summary>
57 private List<AppDomainStructure> appDomains = new List<AppDomainStructure>(); 57 private List<AppDomainStructure> appDomains = new List<AppDomainStructure>();
58 58
59 /// <summary> 59 /// <summary>
60 /// Structure to keep track of data around AppDomain 60 /// Structure to keep track of data around AppDomain
61 /// </summary> 61 /// </summary>
62 private class AppDomainStructure 62 private class AppDomainStructure
63 { 63 {
64 /// <summary> 64 /// <summary>
65 /// The AppDomain itself 65 /// The AppDomain itself
66 /// </summary> 66 /// </summary>
67 public AppDomain CurrentAppDomain; 67 public AppDomain CurrentAppDomain;
68 68
69 /// <summary> 69 /// <summary>
70 /// Number of scripts loaded into AppDomain 70 /// Number of scripts loaded into AppDomain
71 /// </summary> 71 /// </summary>
72 public int ScriptsLoaded; 72 public int ScriptsLoaded;
73 73
74 /// <summary> 74 /// <summary>
75 /// Number of dead scripts 75 /// Number of dead scripts
76 /// </summary> 76 /// </summary>
77 public int ScriptsWaitingUnload; 77 public int ScriptsWaitingUnload;
78 } 78 }
79 79
80 /// <summary> 80 /// <summary>
81 /// Current AppDomain 81 /// Current AppDomain
82 /// </summary> 82 /// </summary>
83 private AppDomainStructure currentAD; 83 private AppDomainStructure currentAD;
84 84
85 private object getLock = new object(); // Mutex 85 private object getLock = new object(); // Mutex
86 private object freeLock = new object(); // Mutex 86 private object freeLock = new object(); // Mutex
87 87
88 //private ScriptEngine m_scriptEngine; 88 //private ScriptEngine m_scriptEngine;
89 //public AppDomainManager(ScriptEngine scriptEngine) 89 //public AppDomainManager(ScriptEngine scriptEngine)
90 public AppDomainManager() 90 public AppDomainManager()
91 { 91 {
92 //m_scriptEngine = scriptEngine; 92 //m_scriptEngine = scriptEngine;
93 } 93 }
94 94
95 /// <summary> 95 /// <summary>
96 /// Find a free AppDomain, creating one if necessary 96 /// Find a free AppDomain, creating one if necessary
97 /// </summary> 97 /// </summary>
98 /// <returns>Free AppDomain</returns> 98 /// <returns>Free AppDomain</returns>
99 private AppDomainStructure GetFreeAppDomain() 99 private AppDomainStructure GetFreeAppDomain()
100 { 100 {
101 Console.WriteLine("Finding free AppDomain"); 101 Console.WriteLine("Finding free AppDomain");
102 lock (getLock) 102 lock (getLock)
103 { 103 {
104 // Current full? 104 // Current full?
105 if (currentAD != null && currentAD.ScriptsLoaded >= maxScriptsPerAppDomain) 105 if (currentAD != null && currentAD.ScriptsLoaded >= maxScriptsPerAppDomain)
106 { 106 {
107 // Add it to AppDomains list and empty current 107 // Add it to AppDomains list and empty current
108 appDomains.Add(currentAD); 108 appDomains.Add(currentAD);
109 currentAD = null; 109 currentAD = null;
110 } 110 }
111 // No current 111 // No current
112 if (currentAD == null) 112 if (currentAD == null)
113 { 113 {
114 // Create a new current AppDomain 114 // Create a new current AppDomain
115 currentAD = new AppDomainStructure(); 115 currentAD = new AppDomainStructure();
116 currentAD.CurrentAppDomain = PrepareNewAppDomain(); 116 currentAD.CurrentAppDomain = PrepareNewAppDomain();
117 } 117 }
118 118
119 Console.WriteLine("Scripts loaded in this Appdomain: " + currentAD.ScriptsLoaded); 119 Console.WriteLine("Scripts loaded in this Appdomain: " + currentAD.ScriptsLoaded);
120 return currentAD; 120 return currentAD;
121 } // lock 121 } // lock
122 } 122 }
123 123
124 private int AppDomainNameCount; 124 private int AppDomainNameCount;
125 125
126 /// <summary> 126 /// <summary>
127 /// Create and prepare a new AppDomain for scripts 127 /// Create and prepare a new AppDomain for scripts
128 /// </summary> 128 /// </summary>
129 /// <returns>The new AppDomain</returns> 129 /// <returns>The new AppDomain</returns>
130 private AppDomain PrepareNewAppDomain() 130 private AppDomain PrepareNewAppDomain()
131 { 131 {
132 // Create and prepare a new AppDomain 132 // Create and prepare a new AppDomain
133 AppDomainNameCount++; 133 AppDomainNameCount++;
134 // TODO: Currently security match current appdomain 134 // TODO: Currently security match current appdomain
135 135
136 // Construct and initialize settings for a second AppDomain. 136 // Construct and initialize settings for a second AppDomain.
137 AppDomainSetup ads = new AppDomainSetup(); 137 AppDomainSetup ads = new AppDomainSetup();
138 ads.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory; 138 ads.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
139 ads.DisallowBindingRedirects = false; 139 ads.DisallowBindingRedirects = false;
140 ads.DisallowCodeDownload = true; 140 ads.DisallowCodeDownload = true;
141 ads.LoaderOptimization = LoaderOptimization.MultiDomain; // Sounds good ;) 141 ads.LoaderOptimization = LoaderOptimization.MultiDomain; // Sounds good ;)
142 ads.ShadowCopyFiles = "true"; // Enabled shadowing 142 ads.ShadowCopyFiles = "true"; // Enabled shadowing
143 ads.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; 143 ads.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
144 144
145 AppDomain AD = AppDomain.CreateDomain("ScriptAppDomain_" + AppDomainNameCount, null, ads); 145 AppDomain AD = AppDomain.CreateDomain("ScriptAppDomain_" + AppDomainNameCount, null, ads);
146 Console.WriteLine("Loading: " + 146 Console.WriteLine("Loading: " +
147 AssemblyName.GetAssemblyName("OpenSim.Region.ScriptEngine.Common.dll").ToString()); 147 AssemblyName.GetAssemblyName("OpenSim.Region.ScriptEngine.Common.dll").ToString());
148 AD.Load(AssemblyName.GetAssemblyName("OpenSim.Region.ScriptEngine.Common.dll")); 148 AD.Load(AssemblyName.GetAssemblyName("OpenSim.Region.ScriptEngine.Common.dll"));
149 149
150 // Return the new AppDomain 150 // Return the new AppDomain
151 return AD; 151 return AD;
152 } 152 }
153 153
154 /// <summary> 154 /// <summary>
155 /// Unload appdomains that are full and have only dead scripts 155 /// Unload appdomains that are full and have only dead scripts
156 /// </summary> 156 /// </summary>
157 private void UnloadAppDomains() 157 private void UnloadAppDomains()
158 { 158 {
159 lock (freeLock) 159 lock (freeLock)
160 { 160 {
161 // Go through all 161 // Go through all
162 foreach (AppDomainStructure ads in new ArrayList(appDomains)) 162 foreach (AppDomainStructure ads in new ArrayList(appDomains))
163 { 163 {
164 // Don't process current AppDomain 164 // Don't process current AppDomain
165 if (ads.CurrentAppDomain != currentAD.CurrentAppDomain) 165 if (ads.CurrentAppDomain != currentAD.CurrentAppDomain)
166 { 166 {
167 // Not current AppDomain 167 // Not current AppDomain
168 // Is number of unloaded bigger or equal to number of loaded? 168 // Is number of unloaded bigger or equal to number of loaded?
169 if (ads.ScriptsLoaded <= ads.ScriptsWaitingUnload) 169 if (ads.ScriptsLoaded <= ads.ScriptsWaitingUnload)
170 { 170 {
171 Console.WriteLine("Found empty AppDomain, unloading"); 171 Console.WriteLine("Found empty AppDomain, unloading");
172 // Remove from internal list 172 // Remove from internal list
173 appDomains.Remove(ads); 173 appDomains.Remove(ads);
174#if DEBUG 174#if DEBUG
175 long m = GC.GetTotalMemory(true); 175 long m = GC.GetTotalMemory(true);
176#endif 176#endif
177 // Unload 177 // Unload
178 AppDomain.Unload(ads.CurrentAppDomain); 178 AppDomain.Unload(ads.CurrentAppDomain);
179#if DEBUG 179#if DEBUG
180 Console.WriteLine("AppDomain unload freed " + (m - GC.GetTotalMemory(true)) + 180 Console.WriteLine("AppDomain unload freed " + (m - GC.GetTotalMemory(true)) +
181 " bytes of memory"); 181 " bytes of memory");
182#endif 182#endif
183 } 183 }
184 } 184 }
185 } // foreach 185 } // foreach
186 } // lock 186 } // lock
187 } 187 }
188 188
189 189
190 public IScript LoadScript(string FileName) 190 public IScript LoadScript(string FileName)
191 { 191 {
192 // Find next available AppDomain to put it in 192 // Find next available AppDomain to put it in
193 AppDomainStructure FreeAppDomain = GetFreeAppDomain(); 193 AppDomainStructure FreeAppDomain = GetFreeAppDomain();
194 194
195 Console.WriteLine("Loading into AppDomain: " + FileName); 195 Console.WriteLine("Loading into AppDomain: " + FileName);
196 IScript mbrt = 196 IScript mbrt =
197 (IScript) 197 (IScript)
198 FreeAppDomain.CurrentAppDomain.CreateInstanceFromAndUnwrap(FileName, "SecondLife.Script"); 198 FreeAppDomain.CurrentAppDomain.CreateInstanceFromAndUnwrap(FileName, "SecondLife.Script");
199 //Console.WriteLine("ScriptEngine AppDomainManager: is proxy={0}", RemotingServices.IsTransparentProxy(mbrt)); 199 //Console.WriteLine("ScriptEngine AppDomainManager: is proxy={0}", RemotingServices.IsTransparentProxy(mbrt));
200 FreeAppDomain.ScriptsLoaded++; 200 FreeAppDomain.ScriptsLoaded++;
201 201
202 return mbrt; 202 return mbrt;
203 } 203 }
204 204
205 205
206 /// <summary> 206 /// <summary>
207 /// Increase "dead script" counter for an AppDomain 207 /// Increase "dead script" counter for an AppDomain
208 /// </summary> 208 /// </summary>
209 /// <param name="ad"></param> 209 /// <param name="ad"></param>
210 //[Obsolete("Needs fixing, needs a real purpose in life!!!")] 210 //[Obsolete("Needs fixing, needs a real purpose in life!!!")]
211 public void StopScript(AppDomain ad) 211 public void StopScript(AppDomain ad)
212 { 212 {
213 lock (freeLock) 213 lock (freeLock)
214 { 214 {
215 Console.WriteLine("Stopping script in AppDomain"); 215 Console.WriteLine("Stopping script in AppDomain");
216 // Check if it is current AppDomain 216 // Check if it is current AppDomain
217 if (currentAD.CurrentAppDomain == ad) 217 if (currentAD.CurrentAppDomain == ad)
218 { 218 {
219 // Yes - increase 219 // Yes - increase
220 currentAD.ScriptsWaitingUnload++; 220 currentAD.ScriptsWaitingUnload++;
221 return; 221 return;
222 } 222 }
223 223
224 // Lopp through all AppDomains 224 // Lopp through all AppDomains
225 foreach (AppDomainStructure ads in new ArrayList(appDomains)) 225 foreach (AppDomainStructure ads in new ArrayList(appDomains))
226 { 226 {
227 if (ads.CurrentAppDomain == ad) 227 if (ads.CurrentAppDomain == ad)
228 { 228 {
229 // Found it 229 // Found it
230 ads.ScriptsWaitingUnload++; 230 ads.ScriptsWaitingUnload++;
231 break; 231 break;
232 } 232 }
233 } // foreach 233 } // foreach
234 } // lock 234 } // lock
235 235
236 UnloadAppDomains(); // Outsite lock, has its own GetLock 236 UnloadAppDomains(); // Outsite lock, has its own GetLock
237 } 237 }
238 } 238 }
239} \ No newline at end of file 239} \ No newline at end of file