diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine/XEngine/XEngine.cs')
-rwxr-xr-x[-rw-r--r--] | OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 236 |
1 files changed, 152 insertions, 84 deletions
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 6df36f7..05124fc 100644..100755 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | |||
@@ -78,7 +78,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
78 | /// A parameter to allow us to notify the log if at least one script has a compilation that is not compatible | 78 | /// A parameter to allow us to notify the log if at least one script has a compilation that is not compatible |
79 | /// with ScriptStopStrategy. | 79 | /// with ScriptStopStrategy. |
80 | /// </summary> | 80 | /// </summary> |
81 | public bool HaveNotifiedLogOfScriptStopMistmatch { get; private set; } | 81 | public bool HaveNotifiedLogOfScriptStopMismatch { get; private set; } |
82 | 82 | ||
83 | private SmartThreadPool m_ThreadPool; | 83 | private SmartThreadPool m_ThreadPool; |
84 | private int m_MaxScriptQueue; | 84 | private int m_MaxScriptQueue; |
@@ -110,6 +110,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
110 | private int m_ScriptFailCount; // Number of script fails since compile queue was last empty | 110 | private int m_ScriptFailCount; // Number of script fails since compile queue was last empty |
111 | private string m_ScriptErrorMessage; | 111 | private string m_ScriptErrorMessage; |
112 | private bool m_AppDomainLoading; | 112 | private bool m_AppDomainLoading; |
113 | private bool m_CompactMemOnLoad; | ||
113 | private Dictionary<UUID,ArrayList> m_ScriptErrors = | 114 | private Dictionary<UUID,ArrayList> m_ScriptErrors = |
114 | new Dictionary<UUID,ArrayList>(); | 115 | new Dictionary<UUID,ArrayList>(); |
115 | 116 | ||
@@ -130,9 +131,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
130 | /// It appears that if a script thread is aborted whilst it is holding ReaderWriterLockSlim (possibly the write | 131 | /// It appears that if a script thread is aborted whilst it is holding ReaderWriterLockSlim (possibly the write |
131 | /// lock) then the lock is not properly released. This causes mono 2.6, 2.10 and possibly | 132 | /// lock) then the lock is not properly released. This causes mono 2.6, 2.10 and possibly |
132 | /// later to crash, sometimes with symptoms such as a leap to 100% script usage and a vm thead dump showing | 133 | /// later to crash, sometimes with symptoms such as a leap to 100% script usage and a vm thead dump showing |
133 | /// all threads waiting on release of ReaderWriterLockSlim write thread which none of the threads listed | 134 | /// all threads waiting on release of ReaderWriterLockSlim write thread which none of the threads listed |
134 | /// actually hold. | 135 | /// actually hold. |
135 | /// | 136 | /// |
136 | /// Pausing for event completion reduces the risk of this happening. However, it may be that aborting threads | 137 | /// Pausing for event completion reduces the risk of this happening. However, it may be that aborting threads |
137 | /// is not a mono issue per se but rather a risky activity in itself in an AppDomain that is not immediately | 138 | /// is not a mono issue per se but rather a risky activity in itself in an AppDomain that is not immediately |
138 | /// shutting down. | 139 | /// shutting down. |
@@ -181,7 +182,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
181 | 182 | ||
182 | private ScriptCompileQueue m_CompileQueue = new ScriptCompileQueue(); | 183 | private ScriptCompileQueue m_CompileQueue = new ScriptCompileQueue(); |
183 | IWorkItemResult m_CurrentCompile = null; | 184 | IWorkItemResult m_CurrentCompile = null; |
184 | private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); | 185 | private Dictionary<UUID, ScriptCompileInfo> m_CompileDict = new Dictionary<UUID, ScriptCompileInfo>(); |
185 | 186 | ||
186 | private ScriptEngineConsoleCommands m_consoleCommands; | 187 | private ScriptEngineConsoleCommands m_consoleCommands; |
187 | 188 | ||
@@ -235,6 +236,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
235 | get { return m_ConfigSource; } | 236 | get { return m_ConfigSource; } |
236 | } | 237 | } |
237 | 238 | ||
239 | private class ScriptCompileInfo | ||
240 | { | ||
241 | public List<EventParams> eventList = new List<EventParams>(); | ||
242 | } | ||
243 | |||
238 | /// <summary> | 244 | /// <summary> |
239 | /// Event fired after the script engine has finished removing a script. | 245 | /// Event fired after the script engine has finished removing a script. |
240 | /// </summary> | 246 | /// </summary> |
@@ -301,15 +307,15 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
301 | m_MaxScriptQueue = m_ScriptConfig.GetInt("MaxScriptEventQueue",300); | 307 | m_MaxScriptQueue = m_ScriptConfig.GetInt("MaxScriptEventQueue",300); |
302 | m_StackSize = m_ScriptConfig.GetInt("ThreadStackSize", 262144); | 308 | m_StackSize = m_ScriptConfig.GetInt("ThreadStackSize", 262144); |
303 | m_SleepTime = m_ScriptConfig.GetInt("MaintenanceInterval", 10) * 1000; | 309 | m_SleepTime = m_ScriptConfig.GetInt("MaintenanceInterval", 10) * 1000; |
304 | m_AppDomainLoading = m_ScriptConfig.GetBoolean("AppDomainLoading", true); | 310 | m_AppDomainLoading = m_ScriptConfig.GetBoolean("AppDomainLoading", false); |
305 | 311 | m_CompactMemOnLoad = m_ScriptConfig.GetBoolean("CompactMemOnLoad", false); | |
306 | m_EventLimit = m_ScriptConfig.GetInt("EventLimit", 30); | 312 | m_EventLimit = m_ScriptConfig.GetInt("EventLimit", 30); |
307 | m_KillTimedOutScripts = m_ScriptConfig.GetBoolean("KillTimedOutScripts", false); | 313 | m_KillTimedOutScripts = m_ScriptConfig.GetBoolean("KillTimedOutScripts", false); |
308 | m_SaveTime = m_ScriptConfig.GetInt("SaveInterval", 120) * 1000; | 314 | m_SaveTime = m_ScriptConfig.GetInt("SaveInterval", 120) * 1000; |
309 | m_WaitForEventCompletionOnScriptStop | 315 | m_WaitForEventCompletionOnScriptStop |
310 | = m_ScriptConfig.GetInt("WaitForEventCompletionOnScriptStop", m_WaitForEventCompletionOnScriptStop); | 316 | = m_ScriptConfig.GetInt("WaitForEventCompletionOnScriptStop", m_WaitForEventCompletionOnScriptStop); |
311 | 317 | ||
312 | m_ScriptEnginesPath = "../caches/" + m_ScriptConfig.GetString("ScriptEnginesPath", "ScriptEngines"); | 318 | m_ScriptEnginesPath = m_ScriptConfig.GetString("ScriptEnginesPath", "ScriptEngines"); |
313 | 319 | ||
314 | m_Prio = ThreadPriority.BelowNormal; | 320 | m_Prio = ThreadPriority.BelowNormal; |
315 | switch (priority) | 321 | switch (priority) |
@@ -506,7 +512,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
506 | { | 512 | { |
507 | string rawItemId; | 513 | string rawItemId; |
508 | UUID itemId = UUID.Zero; | 514 | UUID itemId = UUID.Zero; |
509 | 515 | ||
510 | if (cmdparams.Length == 2) | 516 | if (cmdparams.Length == 2) |
511 | { | 517 | { |
512 | IEnumerable<IScriptInstance> scripts = m_Scripts.Values; | 518 | IEnumerable<IScriptInstance> scripts = m_Scripts.Values; |
@@ -519,17 +525,17 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
519 | 525 | ||
520 | return; | 526 | return; |
521 | } | 527 | } |
522 | 528 | ||
523 | for (int i = 2; i < cmdparams.Length; i++) | 529 | for (int i = 2; i < cmdparams.Length; i++) |
524 | { | 530 | { |
525 | rawItemId = cmdparams[i]; | 531 | rawItemId = cmdparams[i]; |
526 | 532 | ||
527 | if (!UUID.TryParse(rawItemId, out itemId)) | 533 | if (!UUID.TryParse(rawItemId, out itemId)) |
528 | { | 534 | { |
529 | MainConsole.Instance.OutputFormat("ERROR: {0} is not a valid UUID", rawItemId); | 535 | MainConsole.Instance.OutputFormat("ERROR: {0} is not a valid UUID", rawItemId); |
530 | continue; | 536 | continue; |
531 | } | 537 | } |
532 | 538 | ||
533 | if (itemId != UUID.Zero) | 539 | if (itemId != UUID.Zero) |
534 | { | 540 | { |
535 | IScriptInstance instance = GetInstance(itemId); | 541 | IScriptInstance instance = GetInstance(itemId); |
@@ -815,12 +821,15 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
815 | { | 821 | { |
816 | if (!m_Enabled) | 822 | if (!m_Enabled) |
817 | return; | 823 | return; |
818 | 824 | ||
819 | lock (m_ScriptEngines) | 825 | lock (m_ScriptEngines) |
820 | { | 826 | { |
821 | if (m_ScriptEngines.Contains(this)) | 827 | if (m_ScriptEngines.Contains(this)) |
822 | m_ScriptEngines.Remove(this); | 828 | m_ScriptEngines.Remove(this); |
823 | } | 829 | } |
830 | |||
831 | lock(m_Scripts) | ||
832 | m_ThreadPool.Shutdown(); | ||
824 | } | 833 | } |
825 | 834 | ||
826 | public object DoBackup(object o) | 835 | public object DoBackup(object o) |
@@ -977,14 +986,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
977 | SceneObjectPart part = | 986 | SceneObjectPart part = |
978 | m_Scene.GetSceneObjectPart( | 987 | m_Scene.GetSceneObjectPart( |
979 | localID); | 988 | localID); |
980 | 989 | ||
981 | TaskInventoryItem item = | 990 | TaskInventoryItem item = |
982 | part.Inventory.GetInventoryItem(itemID); | 991 | part.Inventory.GetInventoryItem(itemID); |
983 | 992 | ||
984 | ScenePresence presence = | 993 | ScenePresence presence = |
985 | m_Scene.GetScenePresence( | 994 | m_Scene.GetScenePresence( |
986 | item.OwnerID); | 995 | item.OwnerID); |
987 | 996 | ||
988 | if (presence != null) | 997 | if (presence != null) |
989 | { | 998 | { |
990 | presence.ControllingClient.SendAgentAlertMessage( | 999 | presence.ControllingClient.SendAgentAlertMessage( |
@@ -1008,7 +1017,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1008 | { | 1017 | { |
1009 | lock (m_CompileDict) | 1018 | lock (m_CompileDict) |
1010 | { | 1019 | { |
1011 | m_CompileDict[itemID] = 0; | 1020 | // m_log.DebugFormat("[XENGINE]: Set compile dict for {0}", itemID); |
1021 | m_CompileDict[itemID] = new ScriptCompileInfo(); | ||
1012 | } | 1022 | } |
1013 | 1023 | ||
1014 | DoOnRezScript(parms); | 1024 | DoOnRezScript(parms); |
@@ -1016,7 +1026,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1016 | else | 1026 | else |
1017 | { | 1027 | { |
1018 | lock (m_CompileDict) | 1028 | lock (m_CompileDict) |
1019 | m_CompileDict[itemID] = 0; | 1029 | m_CompileDict[itemID] = new ScriptCompileInfo(); |
1030 | // m_log.DebugFormat("[XENGINE]: Set compile dict for {0} delayed", itemID); | ||
1020 | 1031 | ||
1021 | // This must occur after the m_CompileDict so that an existing compile thread cannot hit the check | 1032 | // This must occur after the m_CompileDict so that an existing compile thread cannot hit the check |
1022 | // in DoOnRezScript() before m_CompileDict has been updated. | 1033 | // in DoOnRezScript() before m_CompileDict has been updated. |
@@ -1024,18 +1035,15 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1024 | 1035 | ||
1025 | // m_log.DebugFormat("[XEngine]: Added script {0} to compile queue", itemID); | 1036 | // m_log.DebugFormat("[XEngine]: Added script {0} to compile queue", itemID); |
1026 | 1037 | ||
1027 | if (m_CurrentCompile == null) | 1038 | // NOTE: Although we use a lockless queue, the lock here |
1039 | // is required. It ensures that there are never two | ||
1040 | // compile threads running, which, due to a race | ||
1041 | // conndition, might otherwise happen | ||
1042 | // | ||
1043 | lock (m_CompileQueue) | ||
1028 | { | 1044 | { |
1029 | // NOTE: Although we use a lockless queue, the lock here | 1045 | if (m_CurrentCompile == null) |
1030 | // is required. It ensures that there are never two | 1046 | m_CurrentCompile = m_ThreadPool.QueueWorkItem(DoOnRezScriptQueue, null); |
1031 | // compile threads running, which, due to a race | ||
1032 | // conndition, might otherwise happen | ||
1033 | // | ||
1034 | lock (m_CompileQueue) | ||
1035 | { | ||
1036 | if (m_CurrentCompile == null) | ||
1037 | m_CurrentCompile = m_ThreadPool.QueueWorkItem(DoOnRezScriptQueue, null); | ||
1038 | } | ||
1039 | } | 1047 | } |
1040 | } | 1048 | } |
1041 | } | 1049 | } |
@@ -1071,12 +1079,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1071 | "[XEngine]: Started {0} scripts in {1}", scriptsStarted, m_Scene.Name); | 1079 | "[XEngine]: Started {0} scripts in {1}", scriptsStarted, m_Scene.Name); |
1072 | } | 1080 | } |
1073 | } | 1081 | } |
1082 | catch (System.Threading.ThreadAbortException) { } | ||
1074 | catch (Exception e) | 1083 | catch (Exception e) |
1075 | { | 1084 | { |
1076 | m_log.Error( | 1085 | m_log.Error( |
1077 | string.Format( | 1086 | string.Format( |
1078 | "[XEngine]: Failure in DoOnRezScriptQueue() for item {0} in {1}. Continuing. Exception ", | 1087 | "[XEngine]: Failure in DoOnRezScriptQueue() for item {0} in {1}. Continuing. Exception ", |
1079 | o[1], m_Scene.Name), | 1088 | o[1], m_Scene.Name), |
1080 | e); | 1089 | e); |
1081 | } | 1090 | } |
1082 | } | 1091 | } |
@@ -1093,7 +1102,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1093 | } | 1102 | } |
1094 | finally | 1103 | finally |
1095 | { | 1104 | { |
1096 | // FIXME: On failure we must trigger this even if the compile queue is not actually empty so that the | 1105 | // FIXME: On failure we must trigger this even if the compile queue is not actually empty so that the |
1097 | // RegionReadyModule is not forever waiting. This event really needs a different name. | 1106 | // RegionReadyModule is not forever waiting. This event really needs a different name. |
1098 | m_Scene.EventManager.TriggerEmptyScriptCompileQueue(m_ScriptFailCount, | 1107 | m_Scene.EventManager.TriggerEmptyScriptCompileQueue(m_ScriptFailCount, |
1099 | m_ScriptErrorMessage); | 1108 | m_ScriptErrorMessage); |
@@ -1110,8 +1119,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1110 | { | 1119 | { |
1111 | m_CurrentCompile = null; | 1120 | m_CurrentCompile = null; |
1112 | 1121 | ||
1113 | // This is to avoid a situation where the m_CompileQueue while loop above could complete but | 1122 | // This is to avoid a situation where the m_CompileQueue while loop above could complete but |
1114 | // OnRezScript() place a new script on the queue and check m_CurrentCompile = null before we hit | 1123 | // OnRezScript() place a new script on the queue and check m_CurrentCompile = null before we hit |
1115 | // this section. | 1124 | // this section. |
1116 | if (m_CompileQueue.Count > 0) | 1125 | if (m_CompileQueue.Count > 0) |
1117 | m_CurrentCompile = m_ThreadPool.QueueWorkItem(DoOnRezScriptQueue, null); | 1126 | m_CurrentCompile = m_ThreadPool.QueueWorkItem(DoOnRezScriptQueue, null); |
@@ -1137,7 +1146,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1137 | { | 1146 | { |
1138 | if (!m_CompileDict.ContainsKey(itemID)) | 1147 | if (!m_CompileDict.ContainsKey(itemID)) |
1139 | return false; | 1148 | return false; |
1140 | m_CompileDict.Remove(itemID); | ||
1141 | } | 1149 | } |
1142 | 1150 | ||
1143 | // Get the asset ID of the script, so we can check if we | 1151 | // Get the asset ID of the script, so we can check if we |
@@ -1152,6 +1160,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1152 | m_log.ErrorFormat("[Script]: SceneObjectPart with localID {0} unavailable. Script NOT started.", localID); | 1160 | m_log.ErrorFormat("[Script]: SceneObjectPart with localID {0} unavailable. Script NOT started.", localID); |
1153 | m_ScriptErrorMessage += "SceneObjectPart unavailable. Script NOT started.\n"; | 1161 | m_ScriptErrorMessage += "SceneObjectPart unavailable. Script NOT started.\n"; |
1154 | m_ScriptFailCount++; | 1162 | m_ScriptFailCount++; |
1163 | lock (m_CompileDict) | ||
1164 | m_CompileDict.Remove(itemID); | ||
1155 | return false; | 1165 | return false; |
1156 | } | 1166 | } |
1157 | 1167 | ||
@@ -1160,6 +1170,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1160 | { | 1170 | { |
1161 | m_ScriptErrorMessage += "Can't find script inventory item.\n"; | 1171 | m_ScriptErrorMessage += "Can't find script inventory item.\n"; |
1162 | m_ScriptFailCount++; | 1172 | m_ScriptFailCount++; |
1173 | lock (m_CompileDict) | ||
1174 | m_CompileDict.Remove(itemID); | ||
1163 | return false; | 1175 | return false; |
1164 | } | 1176 | } |
1165 | 1177 | ||
@@ -1188,7 +1200,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1188 | m_Compiler.PerformScriptCompile(script, assetID.ToString(), item.OwnerID, out assemblyPath, out linemap); | 1200 | m_Compiler.PerformScriptCompile(script, assetID.ToString(), item.OwnerID, out assemblyPath, out linemap); |
1189 | 1201 | ||
1190 | // m_log.DebugFormat( | 1202 | // m_log.DebugFormat( |
1191 | // "[XENGINE]: Found assembly path {0} onrez {1} in {2}", | 1203 | // "[XENGINE]: Found assembly path {0} onrez {1} in {2}", |
1192 | // assemblyPath, item.ItemID, World.Name); | 1204 | // assemblyPath, item.ItemID, World.Name); |
1193 | 1205 | ||
1194 | if (!m_AddingAssemblies.ContainsKey(assemblyPath)) { | 1206 | if (!m_AddingAssemblies.ContainsKey(assemblyPath)) { |
@@ -1241,7 +1253,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1241 | catch (Exception e) | 1253 | catch (Exception e) |
1242 | { | 1254 | { |
1243 | // m_log.ErrorFormat( | 1255 | // m_log.ErrorFormat( |
1244 | // "[XEngine]: Exception when rezzing script with item ID {0}, {1}{2}", | 1256 | // "[XEngine]: Exception when rezzing script with item ID {0}, {1}{2}", |
1245 | // itemID, e.Message, e.StackTrace); | 1257 | // itemID, e.Message, e.StackTrace); |
1246 | 1258 | ||
1247 | // try | 1259 | // try |
@@ -1277,10 +1289,17 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1277 | // e.Message.ToString()); | 1289 | // e.Message.ToString()); |
1278 | // } | 1290 | // } |
1279 | 1291 | ||
1292 | lock (m_CompileDict) | ||
1293 | m_CompileDict.Remove(itemID); | ||
1280 | return false; | 1294 | return false; |
1281 | } | 1295 | } |
1282 | } | 1296 | } |
1283 | 1297 | ||
1298 | // optionaly do not load a assembly on top of a lot of to release memory | ||
1299 | // only if logins disable since causes a lot of rubber banding | ||
1300 | if(m_CompactMemOnLoad && !m_Scene.LoginsEnabled) | ||
1301 | GC.Collect(2); | ||
1302 | |||
1284 | ScriptInstance instance = null; | 1303 | ScriptInstance instance = null; |
1285 | lock (m_Scripts) | 1304 | lock (m_Scripts) |
1286 | { | 1305 | { |
@@ -1288,26 +1307,27 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1288 | if ((!m_Scripts.ContainsKey(itemID)) || | 1307 | if ((!m_Scripts.ContainsKey(itemID)) || |
1289 | (m_Scripts[itemID].AssetID != assetID)) | 1308 | (m_Scripts[itemID].AssetID != assetID)) |
1290 | { | 1309 | { |
1291 | UUID appDomain = assetID; | 1310 | // UUID appDomain = assetID; |
1292 | 1311 | ||
1293 | if (part.ParentGroup.IsAttachment) | 1312 | // if (part.ParentGroup.IsAttachment) |
1294 | appDomain = part.ParentGroup.RootPart.UUID; | 1313 | // appDomain = part.ParentGroup.RootPart.UUID; |
1314 | UUID appDomain = part.ParentGroup.RootPart.UUID; | ||
1295 | 1315 | ||
1296 | if (!m_AppDomains.ContainsKey(appDomain)) | 1316 | if (!m_AppDomains.ContainsKey(appDomain)) |
1297 | { | 1317 | { |
1298 | try | 1318 | try |
1299 | { | 1319 | { |
1300 | AppDomainSetup appSetup = new AppDomainSetup(); | 1320 | AppDomain sandbox; |
1301 | appSetup.PrivateBinPath = Path.Combine( | 1321 | if (m_AppDomainLoading) |
1322 | { | ||
1323 | AppDomainSetup appSetup = new AppDomainSetup(); | ||
1324 | appSetup.PrivateBinPath = Path.Combine( | ||
1302 | m_ScriptEnginesPath, | 1325 | m_ScriptEnginesPath, |
1303 | m_Scene.RegionInfo.RegionID.ToString()); | 1326 | m_Scene.RegionInfo.RegionID.ToString()); |
1304 | 1327 | ||
1305 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; | 1328 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; |
1306 | Evidence evidence = new Evidence(baseEvidence); | 1329 | Evidence evidence = new Evidence(baseEvidence); |
1307 | 1330 | ||
1308 | AppDomain sandbox; | ||
1309 | if (m_AppDomainLoading) | ||
1310 | { | ||
1311 | sandbox = AppDomain.CreateDomain( | 1331 | sandbox = AppDomain.CreateDomain( |
1312 | m_Scene.RegionInfo.RegionID.ToString(), | 1332 | m_Scene.RegionInfo.RegionID.ToString(), |
1313 | evidence, appSetup); | 1333 | evidence, appSetup); |
@@ -1319,7 +1339,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1319 | { | 1339 | { |
1320 | sandbox = AppDomain.CurrentDomain; | 1340 | sandbox = AppDomain.CurrentDomain; |
1321 | } | 1341 | } |
1322 | 1342 | ||
1323 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); | 1343 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); |
1324 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | 1344 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); |
1325 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); | 1345 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); |
@@ -1327,7 +1347,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1327 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); | 1347 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); |
1328 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; | 1348 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; |
1329 | //sandbox.SetAppDomainPolicy(sandboxPolicy); | 1349 | //sandbox.SetAppDomainPolicy(sandboxPolicy); |
1330 | 1350 | ||
1331 | m_AppDomains[appDomain] = sandbox; | 1351 | m_AppDomains[appDomain] = sandbox; |
1332 | 1352 | ||
1333 | m_DomainScripts[appDomain] = new List<UUID>(); | 1353 | m_DomainScripts[appDomain] = new List<UUID>(); |
@@ -1337,10 +1357,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1337 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); | 1357 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); |
1338 | m_ScriptErrorMessage += "Exception creating app domain:\n"; | 1358 | m_ScriptErrorMessage += "Exception creating app domain:\n"; |
1339 | m_ScriptFailCount++; | 1359 | m_ScriptFailCount++; |
1340 | lock (m_AddingAssemblies) | 1360 | lock (m_AddingAssemblies) |
1341 | { | 1361 | { |
1342 | m_AddingAssemblies[assemblyPath]--; | 1362 | m_AddingAssemblies[assemblyPath]--; |
1343 | } | 1363 | } |
1364 | lock (m_CompileDict) | ||
1365 | m_CompileDict.Remove(itemID); | ||
1344 | return false; | 1366 | return false; |
1345 | } | 1367 | } |
1346 | } | 1368 | } |
@@ -1360,14 +1382,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1360 | { | 1382 | { |
1361 | coopSleepHandle = new XEngineEventWaitHandle(false, EventResetMode.AutoReset); | 1383 | coopSleepHandle = new XEngineEventWaitHandle(false, EventResetMode.AutoReset); |
1362 | 1384 | ||
1363 | scriptObj | 1385 | scriptObj |
1364 | = (IScript)m_AppDomains[appDomain].CreateInstanceAndUnwrap( | 1386 | = (IScript)m_AppDomains[appDomain].CreateInstanceAndUnwrap( |
1365 | assemblyName.FullName, | 1387 | assemblyName.FullName, |
1366 | "SecondLife.XEngineScript", | 1388 | "SecondLife.XEngineScript", |
1367 | false, | 1389 | false, |
1368 | BindingFlags.Default, | 1390 | BindingFlags.Default, |
1369 | null, | 1391 | null, |
1370 | new object[] { coopSleepHandle }, | 1392 | new object[] { coopSleepHandle }, |
1371 | null, | 1393 | null, |
1372 | null); | 1394 | null); |
1373 | 1395 | ||
@@ -1379,7 +1401,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1379 | 1401 | ||
1380 | try | 1402 | try |
1381 | { | 1403 | { |
1382 | scriptObj | 1404 | scriptObj |
1383 | = (IScript)m_AppDomains[appDomain].CreateInstanceAndUnwrap( | 1405 | = (IScript)m_AppDomains[appDomain].CreateInstanceAndUnwrap( |
1384 | assemblyName.FullName, | 1406 | assemblyName.FullName, |
1385 | "SecondLife.Script", | 1407 | "SecondLife.Script", |
@@ -1394,10 +1416,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1394 | { | 1416 | { |
1395 | m_log.Error( | 1417 | m_log.Error( |
1396 | string.Format( | 1418 | string.Format( |
1397 | "[XENGINE]: Could not load previous SecondLife.Script from assembly {0} in {1}. Not starting. Exception ", | 1419 | "[XENGINE]: Could not load previous SecondLife.Script from assembly {0} in {1}. Not starting. Exception ", |
1398 | assemblyName.FullName, World.Name), | 1420 | assemblyName.FullName, World.Name), |
1399 | e2); | 1421 | e2); |
1400 | 1422 | ||
1423 | lock (m_CompileDict) | ||
1424 | m_CompileDict.Remove(itemID); | ||
1401 | return false; | 1425 | return false; |
1402 | } | 1426 | } |
1403 | 1427 | ||
@@ -1408,7 +1432,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1408 | { | 1432 | { |
1409 | try | 1433 | try |
1410 | { | 1434 | { |
1411 | scriptObj | 1435 | scriptObj |
1412 | = (IScript)m_AppDomains[appDomain].CreateInstanceAndUnwrap( | 1436 | = (IScript)m_AppDomains[appDomain].CreateInstanceAndUnwrap( |
1413 | assemblyName.FullName, | 1437 | assemblyName.FullName, |
1414 | "SecondLife.Script", | 1438 | "SecondLife.Script", |
@@ -1428,7 +1452,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1428 | 1452 | ||
1429 | try | 1453 | try |
1430 | { | 1454 | { |
1431 | scriptObj | 1455 | scriptObj |
1432 | = (IScript)m_AppDomains[appDomain].CreateInstanceAndUnwrap( | 1456 | = (IScript)m_AppDomains[appDomain].CreateInstanceAndUnwrap( |
1433 | assemblyName.FullName, | 1457 | assemblyName.FullName, |
1434 | "SecondLife.XEngineScript", | 1458 | "SecondLife.XEngineScript", |
@@ -1443,10 +1467,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1443 | { | 1467 | { |
1444 | m_log.Error( | 1468 | m_log.Error( |
1445 | string.Format( | 1469 | string.Format( |
1446 | "[XENGINE]: Could not load previous SecondLife.XEngineScript from assembly {0} in {1}. Not starting. Exception ", | 1470 | "[XENGINE]: Could not load previous SecondLife.XEngineScript from assembly {0} in {1}. Not starting. Exception ", |
1447 | assemblyName.FullName, World.Name), | 1471 | assemblyName.FullName, World.Name), |
1448 | e2); | 1472 | e2); |
1449 | 1473 | ||
1474 | lock (m_CompileDict) | ||
1475 | m_CompileDict.Remove(itemID); | ||
1450 | return false; | 1476 | return false; |
1451 | } | 1477 | } |
1452 | 1478 | ||
@@ -1454,7 +1480,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1454 | } | 1480 | } |
1455 | } | 1481 | } |
1456 | 1482 | ||
1457 | if (m_coopTermination != coopTerminationForThisScript && !HaveNotifiedLogOfScriptStopMistmatch) | 1483 | if (m_coopTermination != coopTerminationForThisScript && !HaveNotifiedLogOfScriptStopMismatch) |
1458 | { | 1484 | { |
1459 | // Notify the log that there is at least one script compile that doesn't match the | 1485 | // Notify the log that there is at least one script compile that doesn't match the |
1460 | // ScriptStopStrategy. Operator has to manually delete old DLLs - we can't do this on Windows | 1486 | // ScriptStopStrategy. Operator has to manually delete old DLLs - we can't do this on Windows |
@@ -1464,7 +1490,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1464 | + "\nContinuing with script compiled strategy but to remove this message please set [XEngine] DeleteScriptsOnStartup = true for one simulator session to remove old script DLLs (script state will not be lost).", | 1490 | + "\nContinuing with script compiled strategy but to remove this message please set [XEngine] DeleteScriptsOnStartup = true for one simulator session to remove old script DLLs (script state will not be lost).", |
1465 | World.Name, coopTerminationForThisScript ? "co-op" : "abort", m_coopTermination ? "co-op" : "abort"); | 1491 | World.Name, coopTerminationForThisScript ? "co-op" : "abort", m_coopTermination ? "co-op" : "abort"); |
1466 | 1492 | ||
1467 | HaveNotifiedLogOfScriptStopMistmatch = true; | 1493 | HaveNotifiedLogOfScriptStopMismatch = true; |
1468 | } | 1494 | } |
1469 | 1495 | ||
1470 | instance = new ScriptInstance(this, part, | 1496 | instance = new ScriptInstance(this, part, |
@@ -1472,11 +1498,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1472 | startParam, postOnRez, | 1498 | startParam, postOnRez, |
1473 | m_MaxScriptQueue); | 1499 | m_MaxScriptQueue); |
1474 | 1500 | ||
1475 | if ( | 1501 | if(!instance.Load(scriptObj, coopSleepHandle, assemblyPath, |
1476 | !instance.Load( | ||
1477 | scriptObj, coopSleepHandle, assemblyPath, | ||
1478 | Path.Combine(ScriptEnginePath, World.RegionInfo.RegionID.ToString()), stateSource, coopTerminationForThisScript)) | 1502 | Path.Combine(ScriptEnginePath, World.RegionInfo.RegionID.ToString()), stateSource, coopTerminationForThisScript)) |
1479 | return false; | 1503 | { |
1504 | lock (m_CompileDict) | ||
1505 | m_CompileDict.Remove(itemID); | ||
1506 | return false; | ||
1507 | } | ||
1480 | 1508 | ||
1481 | // if (DebugLevel >= 1) | 1509 | // if (DebugLevel >= 1) |
1482 | // m_log.DebugFormat( | 1510 | // m_log.DebugFormat( |
@@ -1506,16 +1534,26 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1506 | m_PrimObjects[localID].Add(itemID); | 1534 | m_PrimObjects[localID].Add(itemID); |
1507 | } | 1535 | } |
1508 | 1536 | ||
1509 | if (!m_Assemblies.ContainsKey(assetID)) | ||
1510 | m_Assemblies[assetID] = assemblyPath; | ||
1511 | 1537 | ||
1512 | lock (m_AddingAssemblies) | 1538 | lock (m_AddingAssemblies) |
1513 | { | 1539 | { |
1540 | if (!m_Assemblies.ContainsKey(assetID)) | ||
1541 | m_Assemblies[assetID] = assemblyPath; | ||
1542 | |||
1514 | m_AddingAssemblies[assemblyPath]--; | 1543 | m_AddingAssemblies[assemblyPath]--; |
1515 | } | 1544 | } |
1516 | 1545 | ||
1517 | if (instance != null) | 1546 | if (instance != null) |
1547 | { | ||
1518 | instance.Init(); | 1548 | instance.Init(); |
1549 | lock (m_CompileDict) | ||
1550 | { | ||
1551 | foreach (EventParams pp in m_CompileDict[itemID].eventList) | ||
1552 | instance.PostEvent(pp); | ||
1553 | } | ||
1554 | } | ||
1555 | lock (m_CompileDict) | ||
1556 | m_CompileDict.Remove(itemID); | ||
1519 | 1557 | ||
1520 | bool runIt; | 1558 | bool runIt; |
1521 | if (m_runFlags.TryGetValue(itemID, out runIt)) | 1559 | if (m_runFlags.TryGetValue(itemID, out runIt)) |
@@ -1567,7 +1605,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1567 | } | 1605 | } |
1568 | 1606 | ||
1569 | if (instance.StatePersistedHere) | 1607 | if (instance.StatePersistedHere) |
1570 | instance.RemoveState(); | 1608 | instance.RemoveState(); |
1571 | 1609 | ||
1572 | instance.DestroyScriptInstance(); | 1610 | instance.DestroyScriptInstance(); |
1573 | 1611 | ||
@@ -1619,20 +1657,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1619 | // Do not remove assembly files if another instance of the script | 1657 | // Do not remove assembly files if another instance of the script |
1620 | // is currently initialising | 1658 | // is currently initialising |
1621 | if (!m_AddingAssemblies.ContainsKey(m_Assemblies[assetID]) | 1659 | if (!m_AddingAssemblies.ContainsKey(m_Assemblies[assetID]) |
1622 | || m_AddingAssemblies[m_Assemblies[assetID]] == 0) | 1660 | || m_AddingAssemblies[m_Assemblies[assetID]] == 0) |
1623 | { | 1661 | { |
1624 | // m_log.DebugFormat("[XEngine] Removing unreferenced assembly {0}", m_Assemblies[assetID]); | 1662 | // m_log.DebugFormat("[XEngine] Removing unreferenced assembly {0}", m_Assemblies[assetID]); |
1625 | try | 1663 | try |
1626 | { | 1664 | { |
1627 | if (File.Exists(m_Assemblies[assetID])) | 1665 | if (File.Exists(m_Assemblies[assetID])) |
1628 | File.Delete(m_Assemblies[assetID]); | 1666 | File.Delete(m_Assemblies[assetID]); |
1629 | 1667 | ||
1630 | if (File.Exists(m_Assemblies[assetID]+".text")) | 1668 | if (File.Exists(m_Assemblies[assetID]+".text")) |
1631 | File.Delete(m_Assemblies[assetID]+".text"); | 1669 | File.Delete(m_Assemblies[assetID]+".text"); |
1632 | 1670 | ||
1633 | if (File.Exists(m_Assemblies[assetID]+".mdb")) | 1671 | if (File.Exists(m_Assemblies[assetID]+".mdb")) |
1634 | File.Delete(m_Assemblies[assetID]+".mdb"); | 1672 | File.Delete(m_Assemblies[assetID]+".mdb"); |
1635 | 1673 | ||
1636 | if (File.Exists(m_Assemblies[assetID]+".map")) | 1674 | if (File.Exists(m_Assemblies[assetID]+".map")) |
1637 | File.Delete(m_Assemblies[assetID]+".map"); | 1675 | File.Delete(m_Assemblies[assetID]+".map"); |
1638 | } | 1676 | } |
@@ -1689,7 +1727,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1689 | new WorkItemCallback(this.ProcessEventHandler), | 1727 | new WorkItemCallback(this.ProcessEventHandler), |
1690 | parms)); | 1728 | parms)); |
1691 | } | 1729 | } |
1692 | 1730 | ||
1693 | /// <summary> | 1731 | /// <summary> |
1694 | /// Process a previously posted script event. | 1732 | /// Process a previously posted script event. |
1695 | /// </summary> | 1733 | /// </summary> |
@@ -1700,7 +1738,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1700 | Culture.SetCurrentCulture(); | 1738 | Culture.SetCurrentCulture(); |
1701 | 1739 | ||
1702 | IScriptInstance instance = (ScriptInstance) parms; | 1740 | IScriptInstance instance = (ScriptInstance) parms; |
1703 | 1741 | ||
1704 | // m_log.DebugFormat("[XEngine]: Processing event for {0}", instance); | 1742 | // m_log.DebugFormat("[XEngine]: Processing event for {0}", instance); |
1705 | 1743 | ||
1706 | return instance.EventProcessor(); | 1744 | return instance.EventProcessor(); |
@@ -1733,15 +1771,26 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1733 | instance = m_Scripts[itemID]; | 1771 | instance = m_Scripts[itemID]; |
1734 | } | 1772 | } |
1735 | catch { /* ignore race conditions */ } | 1773 | catch { /* ignore race conditions */ } |
1736 | 1774 | ||
1737 | if (instance != null) | 1775 | if (instance != null) |
1738 | { | 1776 | { |
1739 | instance.PostEvent(p); | 1777 | instance.PostEvent(p); |
1740 | result = true; | 1778 | result = true; |
1741 | } | 1779 | } |
1780 | else | ||
1781 | { | ||
1782 | lock (m_CompileDict) | ||
1783 | { | ||
1784 | if (m_CompileDict.ContainsKey(itemID)) | ||
1785 | { | ||
1786 | m_CompileDict[itemID].eventList.Add(p); | ||
1787 | result = true; | ||
1788 | } | ||
1789 | } | ||
1790 | } | ||
1742 | } | 1791 | } |
1743 | } | 1792 | } |
1744 | 1793 | ||
1745 | return result; | 1794 | return result; |
1746 | } | 1795 | } |
1747 | 1796 | ||
@@ -1760,6 +1809,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1760 | instance.PostEvent(p); | 1809 | instance.PostEvent(p); |
1761 | return true; | 1810 | return true; |
1762 | } | 1811 | } |
1812 | lock (m_CompileDict) | ||
1813 | { | ||
1814 | if (m_CompileDict.ContainsKey(itemID)) | ||
1815 | { | ||
1816 | m_CompileDict[itemID].eventList.Add(p); | ||
1817 | return true; | ||
1818 | } | ||
1819 | } | ||
1763 | return false; | 1820 | return false; |
1764 | } | 1821 | } |
1765 | 1822 | ||
@@ -1817,7 +1874,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1817 | if (!(sender is System.AppDomain)) | 1874 | if (!(sender is System.AppDomain)) |
1818 | return null; | 1875 | return null; |
1819 | 1876 | ||
1820 | string[] pathList = new string[] {"caches", m_ScriptEnginesPath, | 1877 | string[] pathList = new string[] {"bin", m_ScriptEnginesPath, |
1821 | Path.Combine(m_ScriptEnginesPath, | 1878 | Path.Combine(m_ScriptEnginesPath, |
1822 | m_Scene.RegionInfo.RegionID.ToString())}; | 1879 | m_Scene.RegionInfo.RegionID.ToString())}; |
1823 | 1880 | ||
@@ -1851,15 +1908,23 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1851 | return instance; | 1908 | return instance; |
1852 | } | 1909 | } |
1853 | 1910 | ||
1854 | public void SetScriptState(UUID itemID, bool running) | 1911 | public void SetScriptState(UUID itemID, bool running, bool self) |
1855 | { | 1912 | { |
1856 | IScriptInstance instance = GetInstance(itemID); | 1913 | IScriptInstance instance = GetInstance(itemID); |
1857 | if (instance != null) | 1914 | if (instance != null) |
1858 | { | 1915 | { |
1859 | if (running) | 1916 | if (running) |
1860 | instance.Start(); | 1917 | instance.Start(); |
1861 | else | 1918 | else |
1862 | instance.Stop(100); | 1919 | { |
1920 | if(self) | ||
1921 | { | ||
1922 | instance.Running = false; | ||
1923 | throw new EventAbortException(); | ||
1924 | } | ||
1925 | else | ||
1926 | instance.Stop(100); | ||
1927 | } | ||
1863 | } | 1928 | } |
1864 | } | 1929 | } |
1865 | 1930 | ||
@@ -2033,6 +2098,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
2033 | string xml = instance.GetXMLState(); | 2098 | string xml = instance.GetXMLState(); |
2034 | 2099 | ||
2035 | XmlDocument sdoc = new XmlDocument(); | 2100 | XmlDocument sdoc = new XmlDocument(); |
2101 | sdoc.XmlResolver=null; | ||
2036 | bool loadedState = true; | 2102 | bool loadedState = true; |
2037 | try | 2103 | try |
2038 | { | 2104 | { |
@@ -2084,10 +2150,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
2084 | string fn = Path.GetFileName(assemName); | 2150 | string fn = Path.GetFileName(assemName); |
2085 | 2151 | ||
2086 | string assem = String.Empty; | 2152 | string assem = String.Empty; |
2153 | string assemNameText = assemName + ".text"; | ||
2087 | 2154 | ||
2088 | if (File.Exists(assemName + ".text")) | 2155 | if (File.Exists(assemNameText)) |
2089 | { | 2156 | { |
2090 | FileInfo tfi = new FileInfo(assemName + ".text"); | 2157 | FileInfo tfi = new FileInfo(assemNameText); |
2091 | 2158 | ||
2092 | if (tfi != null) | 2159 | if (tfi != null) |
2093 | { | 2160 | { |
@@ -2095,7 +2162,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
2095 | 2162 | ||
2096 | try | 2163 | try |
2097 | { | 2164 | { |
2098 | using (FileStream tfs = File.Open(assemName + ".text", | 2165 | using (FileStream tfs = File.Open(assemNameText, |
2099 | FileMode.Open, FileAccess.Read)) | 2166 | FileMode.Open, FileAccess.Read)) |
2100 | { | 2167 | { |
2101 | tfs.Read(tdata, 0, tdata.Length); | 2168 | tfs.Read(tdata, 0, tdata.Length); |
@@ -2187,6 +2254,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
2187 | return false; | 2254 | return false; |
2188 | 2255 | ||
2189 | XmlDocument doc = new XmlDocument(); | 2256 | XmlDocument doc = new XmlDocument(); |
2257 | doc.XmlResolver=null; | ||
2190 | 2258 | ||
2191 | try | 2259 | try |
2192 | { | 2260 | { |