diff options
author | Tedd Hansen | 2007-08-18 22:33:06 +0000 |
---|---|---|
committer | Tedd Hansen | 2007-08-18 22:33:06 +0000 |
commit | 1ae73931da62409a36b9c448ac35537dfe3745eb (patch) | |
tree | 1677b745ddfebe19d2d91eb05960a76455daf30e /OpenSim/Region/ScriptEngine/DotNetEngine | |
parent | Scripts are working again. Scripts are now loaded into limited AppDomains (no... (diff) | |
download | opensim-SC-1ae73931da62409a36b9c448ac35537dfe3745eb.zip opensim-SC-1ae73931da62409a36b9c448ac35537dfe3745eb.tar.gz opensim-SC-1ae73931da62409a36b9c448ac35537dfe3745eb.tar.bz2 opensim-SC-1ae73931da62409a36b9c448ac35537dfe3745eb.tar.xz |
Added (theoretical) AppDomain cleanup code.
Diffstat (limited to 'OpenSim/Region/ScriptEngine/DotNetEngine')
-rw-r--r-- | OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs | 106 |
1 files changed, 89 insertions, 17 deletions
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs index 7941ea2..f80ebac 100644 --- a/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs | |||
@@ -10,7 +10,10 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
10 | { | 10 | { |
11 | public class AppDomainManager | 11 | public class AppDomainManager |
12 | { | 12 | { |
13 | private int MaxScriptsPerAppDomain = 10; | 13 | private int MaxScriptsPerAppDomain = 1; |
14 | /// <summary> | ||
15 | /// List of all AppDomains | ||
16 | /// </summary> | ||
14 | private List<AppDomainStructure> AppDomains = new List<AppDomainStructure>(); | 17 | private List<AppDomainStructure> AppDomains = new List<AppDomainStructure>(); |
15 | private struct AppDomainStructure | 18 | private struct AppDomainStructure |
16 | { | 19 | { |
@@ -27,8 +30,12 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
27 | /// </summary> | 30 | /// </summary> |
28 | public int ScriptsWaitingUnload; | 31 | public int ScriptsWaitingUnload; |
29 | } | 32 | } |
33 | /// <summary> | ||
34 | /// Current AppDomain | ||
35 | /// </summary> | ||
30 | private AppDomainStructure CurrentAD; | 36 | private AppDomainStructure CurrentAD; |
31 | private object GetLock = new object(); | 37 | private object GetLock = new object(); // Mutex |
38 | private object FreeLock = new object(); // Mutex | ||
32 | 39 | ||
33 | private ScriptEngine m_scriptEngine; | 40 | private ScriptEngine m_scriptEngine; |
34 | public AppDomainManager(ScriptEngine scriptEngine) | 41 | public AppDomainManager(ScriptEngine scriptEngine) |
@@ -36,17 +43,28 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
36 | m_scriptEngine = scriptEngine; | 43 | m_scriptEngine = scriptEngine; |
37 | } | 44 | } |
38 | 45 | ||
46 | /// <summary> | ||
47 | /// Find a free AppDomain, creating one if necessary | ||
48 | /// </summary> | ||
49 | /// <returns>Free AppDomain</returns> | ||
39 | internal AppDomain GetFreeAppDomain() | 50 | internal AppDomain GetFreeAppDomain() |
40 | { | 51 | { |
52 | FreeAppDomains(); | ||
41 | lock(GetLock) { | 53 | lock(GetLock) { |
42 | // No current or current full? | 54 | // Current full? |
43 | if (CurrentAD.CurrentAppDomain == null || CurrentAD.ScriptsLoaded >= MaxScriptsPerAppDomain) | 55 | if (CurrentAD.ScriptsLoaded >= MaxScriptsPerAppDomain) |
56 | { | ||
57 | AppDomains.Add(CurrentAD); | ||
58 | CurrentAD = new AppDomainStructure(); | ||
59 | } | ||
60 | // No current | ||
61 | if (CurrentAD.CurrentAppDomain == null) | ||
44 | { | 62 | { |
45 | // Create a new current AppDomain | 63 | // Create a new current AppDomain |
46 | CurrentAD = new AppDomainStructure(); | 64 | CurrentAD = new AppDomainStructure(); |
47 | CurrentAD.ScriptsWaitingUnload = 0; // to avoid compile warning for not in use | 65 | CurrentAD.ScriptsWaitingUnload = 0; // to avoid compile warning for not in use |
48 | CurrentAD.CurrentAppDomain = PrepareNewAppDomain(); | 66 | CurrentAD.CurrentAppDomain = PrepareNewAppDomain(); |
49 | AppDomains.Add(CurrentAD); | 67 | |
50 | 68 | ||
51 | } | 69 | } |
52 | 70 | ||
@@ -58,6 +76,10 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
58 | } | 76 | } |
59 | 77 | ||
60 | private int AppDomainNameCount; | 78 | private int AppDomainNameCount; |
79 | /// <summary> | ||
80 | /// Create and prepare a new AppDomain for scripts | ||
81 | /// </summary> | ||
82 | /// <returns>The new AppDomain</returns> | ||
61 | private AppDomain PrepareNewAppDomain() | 83 | private AppDomain PrepareNewAppDomain() |
62 | { | 84 | { |
63 | // Create and prepare a new AppDomain | 85 | // Create and prepare a new AppDomain |
@@ -80,20 +102,20 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
80 | AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; | 102 | AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; |
81 | 103 | ||
82 | AppDomain AD = AppDomain.CreateDomain("ScriptAppDomain_" + AppDomainNameCount, null, ads); | 104 | AppDomain AD = AppDomain.CreateDomain("ScriptAppDomain_" + AppDomainNameCount, null, ads); |
83 | foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies()) | 105 | //foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies()) |
84 | { | 106 | //{ |
85 | //Console.WriteLine("Loading: " + a.GetName(true)); | 107 | // //Console.WriteLine("Loading: " + a.GetName(true)); |
86 | try | 108 | // try |
87 | { | 109 | // { |
88 | //AD.Load(a.GetName(true)); | 110 | // //AD.Load(a.GetName(true)); |
89 | 111 | ||
90 | } | 112 | // } |
91 | catch (Exception e) | 113 | // catch (Exception e) |
92 | { | 114 | // { |
93 | //Console.WriteLine("FAILED load"); | 115 | // //Console.WriteLine("FAILED load"); |
94 | } | 116 | // } |
95 | 117 | ||
96 | } | 118 | //} |
97 | 119 | ||
98 | //Console.WriteLine("Assembly file: " + this.GetType().Assembly.CodeBase); | 120 | //Console.WriteLine("Assembly file: " + this.GetType().Assembly.CodeBase); |
99 | //Console.WriteLine("Assembly name: " + this.GetType().ToString()); | 121 | //Console.WriteLine("Assembly name: " + this.GetType().ToString()); |
@@ -106,5 +128,55 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
106 | 128 | ||
107 | } | 129 | } |
108 | 130 | ||
131 | /// <summary> | ||
132 | /// Unload appdomains that are full and have only dead scripts | ||
133 | /// </summary> | ||
134 | private void FreeAppDomains() | ||
135 | { | ||
136 | lock (FreeLock) | ||
137 | { | ||
138 | foreach (AppDomainStructure ads in new System.Collections.ArrayList(AppDomains)) | ||
139 | { | ||
140 | if (ads.CurrentAppDomain != CurrentAD.CurrentAppDomain) | ||
141 | { | ||
142 | // Not current AppDomain | ||
143 | if (ads.ScriptsLoaded == ads.ScriptsWaitingUnload) | ||
144 | { | ||
145 | AppDomains.Remove(ads); | ||
146 | AppDomain.Unload(ads.CurrentAppDomain); | ||
147 | } | ||
148 | } | ||
149 | } // foreach | ||
150 | } // lock | ||
151 | } | ||
152 | |||
153 | /// <summary> | ||
154 | /// Increase "dead script" counter for an AppDomain | ||
155 | /// </summary> | ||
156 | /// <param name="ad"></param> | ||
157 | [Obsolete("Needs optimizing!!!")] | ||
158 | public void StopScriptInAppDomain(AppDomain ad) | ||
159 | { | ||
160 | lock (FreeLock) | ||
161 | { | ||
162 | if (CurrentAD.CurrentAppDomain == ad) | ||
163 | { | ||
164 | CurrentAD.ScriptsWaitingUnload++; | ||
165 | return; | ||
166 | } | ||
167 | |||
168 | foreach (AppDomainStructure ads in new System.Collections.ArrayList(AppDomains)) | ||
169 | { | ||
170 | if (ads.CurrentAppDomain == ad) | ||
171 | { | ||
172 | AppDomainStructure ads2 = ads; | ||
173 | ads2.ScriptsWaitingUnload++; | ||
174 | AppDomains.Remove(ads); | ||
175 | AppDomains.Add(ads2); | ||
176 | return; | ||
177 | } | ||
178 | } // foreach | ||
179 | } // lock | ||
180 | } | ||
109 | } | 181 | } |
110 | } | 182 | } |