diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine/XEngine/XEngine.cs')
-rw-r--r-- | OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 513 |
1 files changed, 316 insertions, 197 deletions
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 003e735..3ebeb75 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | |||
@@ -30,6 +30,7 @@ using System.IO; | |||
30 | using System.Threading; | 30 | using System.Threading; |
31 | using System.Collections; | 31 | using System.Collections; |
32 | using System.Collections.Generic; | 32 | using System.Collections.Generic; |
33 | using System.Diagnostics; //for [DebuggerNonUserCode] | ||
33 | using System.Security; | 34 | using System.Security; |
34 | using System.Security.Policy; | 35 | using System.Security.Policy; |
35 | using System.Reflection; | 36 | using System.Reflection; |
@@ -103,6 +104,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
103 | private Dictionary<UUID, IScriptInstance> m_Scripts = | 104 | private Dictionary<UUID, IScriptInstance> m_Scripts = |
104 | new Dictionary<UUID, IScriptInstance>(); | 105 | new Dictionary<UUID, IScriptInstance>(); |
105 | 106 | ||
107 | private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim(); | ||
108 | |||
106 | // Maps the asset ID to the assembly | 109 | // Maps the asset ID to the assembly |
107 | 110 | ||
108 | private Dictionary<UUID, string> m_Assemblies = | 111 | private Dictionary<UUID, string> m_Assemblies = |
@@ -125,6 +128,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
125 | IWorkItemResult m_CurrentCompile = null; | 128 | IWorkItemResult m_CurrentCompile = null; |
126 | private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); | 129 | private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); |
127 | 130 | ||
131 | private void lockScriptsForRead(bool locked) | ||
132 | { | ||
133 | if (locked) | ||
134 | { | ||
135 | if (m_scriptsLock.RecursiveReadCount > 0) | ||
136 | { | ||
137 | m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue."); | ||
138 | m_scriptsLock.ExitReadLock(); | ||
139 | } | ||
140 | if (m_scriptsLock.RecursiveWriteCount > 0) | ||
141 | { | ||
142 | m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed."); | ||
143 | m_scriptsLock.ExitWriteLock(); | ||
144 | } | ||
145 | |||
146 | while (!m_scriptsLock.TryEnterReadLock(60000)) | ||
147 | { | ||
148 | m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire READ lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed."); | ||
149 | if (m_scriptsLock.IsWriteLockHeld) | ||
150 | { | ||
151 | m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim(); | ||
152 | } | ||
153 | } | ||
154 | } | ||
155 | else | ||
156 | { | ||
157 | if (m_scriptsLock.RecursiveReadCount > 0) | ||
158 | { | ||
159 | m_scriptsLock.ExitReadLock(); | ||
160 | } | ||
161 | } | ||
162 | } | ||
163 | private void lockScriptsForWrite(bool locked) | ||
164 | { | ||
165 | if (locked) | ||
166 | { | ||
167 | if (m_scriptsLock.RecursiveReadCount > 0) | ||
168 | { | ||
169 | m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue."); | ||
170 | m_scriptsLock.ExitReadLock(); | ||
171 | } | ||
172 | if (m_scriptsLock.RecursiveWriteCount > 0) | ||
173 | { | ||
174 | m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed."); | ||
175 | m_scriptsLock.ExitWriteLock(); | ||
176 | } | ||
177 | |||
178 | while (!m_scriptsLock.TryEnterWriteLock(60000)) | ||
179 | { | ||
180 | m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire WRITE lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed."); | ||
181 | if (m_scriptsLock.IsWriteLockHeld) | ||
182 | { | ||
183 | m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim(); | ||
184 | } | ||
185 | } | ||
186 | } | ||
187 | else | ||
188 | { | ||
189 | if (m_scriptsLock.RecursiveWriteCount > 0) | ||
190 | { | ||
191 | m_scriptsLock.ExitWriteLock(); | ||
192 | } | ||
193 | } | ||
194 | } | ||
195 | |||
128 | public string ScriptEngineName | 196 | public string ScriptEngineName |
129 | { | 197 | { |
130 | get { return "XEngine"; } | 198 | get { return "XEngine"; } |
@@ -276,25 +344,31 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
276 | "Synonym for scripts show command", HandleShowScripts); | 344 | "Synonym for scripts show command", HandleShowScripts); |
277 | 345 | ||
278 | MainConsole.Instance.Commands.AddCommand( | 346 | MainConsole.Instance.Commands.AddCommand( |
279 | "scripts", false, "scripts suspend", "scripts suspend", "Suspends all running scripts", | 347 | "scripts", false, "scripts suspend", "scripts suspend [<script-item-uuid>]", "Suspends all running scripts", |
280 | "Suspends all currently running scripts. This only suspends event delivery, it will not suspend a" | 348 | "Suspends all currently running scripts. This only suspends event delivery, it will not suspend a" |
281 | + " script that is currently processing an event.\n" | 349 | + " script that is currently processing an event.\n" |
282 | + "Suspended scripts will continue to accumulate events but won't process them.", | 350 | + "Suspended scripts will continue to accumulate events but won't process them.\n" |
283 | HandleSuspendScripts); | 351 | + "If a <script-item-uuid> is given then only that script will be suspended. Otherwise, all suitable scripts are suspended.", |
352 | (module, cmdparams) => HandleScriptsAction(cmdparams, HandleSuspendScript)); | ||
284 | 353 | ||
285 | MainConsole.Instance.Commands.AddCommand( | 354 | MainConsole.Instance.Commands.AddCommand( |
286 | "scripts", false, "scripts resume", "scripts resume", "Resumes all suspended scripts", | 355 | "scripts", false, "scripts resume", "scripts resume [<script-item-uuid>]", "Resumes all suspended scripts", |
287 | "Resumes all currently suspended scripts.\n" | 356 | "Resumes all currently suspended scripts.\n" |
288 | + "Resumed scripts will process all events accumulated whilst suspended.", | 357 | + "Resumed scripts will process all events accumulated whilst suspended." |
289 | HandleResumeScripts); | 358 | + "If a <script-item-uuid> is given then only that script will be resumed. Otherwise, all suitable scripts are resumed.", |
359 | (module, cmdparams) => HandleScriptsAction(cmdparams, HandleResumeScript)); | ||
290 | 360 | ||
291 | MainConsole.Instance.Commands.AddCommand( | 361 | MainConsole.Instance.Commands.AddCommand( |
292 | "scripts", false, "scripts stop", "scripts stop", "Stops all running scripts", | 362 | "scripts", false, "scripts stop", "scripts stop [<script-item-uuid>]", "Stops all running scripts", |
293 | HandleStopScripts); | 363 | "Stops all running scripts." |
364 | + "If a <script-item-uuid> is given then only that script will be stopped. Otherwise, all suitable scripts are stopped.", | ||
365 | (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStopScript)); | ||
294 | 366 | ||
295 | MainConsole.Instance.Commands.AddCommand( | 367 | MainConsole.Instance.Commands.AddCommand( |
296 | "scripts", false, "scripts start", "scripts start", "Starts all stopped scripts", | 368 | "scripts", false, "scripts start", "scripts start [<script-item-uuid>]", "Starts all stopped scripts", |
297 | HandleStartScripts); | 369 | "Starts all stopped scripts." |
370 | + "If a <script-item-uuid> is given then only that script will be started. Otherwise, all suitable scripts are started.", | ||
371 | (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStartScript)); | ||
298 | } | 372 | } |
299 | 373 | ||
300 | public void HandleShowScripts(string module, string[] cmdparams) | 374 | public void HandleShowScripts(string module, string[] cmdparams) |
@@ -334,79 +408,101 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
334 | } | 408 | } |
335 | } | 409 | } |
336 | 410 | ||
337 | public void HandleSuspendScripts(string module, string[] cmdparams) | 411 | /// <summary> |
412 | /// Parse the raw item id into a script instance from the command params if it's present. | ||
413 | /// </summary> | ||
414 | /// <param name="cmdparams"></param> | ||
415 | /// <param name="instance"></param> | ||
416 | /// <returns>true if we're okay to proceed, false if not.</returns> | ||
417 | private void HandleScriptsAction(string[] cmdparams, Action<IScriptInstance> action) | ||
338 | { | 418 | { |
339 | lock (m_Scripts) | 419 | lock (m_Scripts) |
340 | { | 420 | { |
341 | foreach (IScriptInstance instance in m_Scripts.Values) | 421 | string rawItemId; |
422 | UUID itemId = UUID.Zero; | ||
423 | |||
424 | if (cmdparams.Length == 2) | ||
342 | { | 425 | { |
343 | if (!instance.Suspended) | 426 | foreach (IScriptInstance instance in m_Scripts.Values) |
344 | { | 427 | action(instance); |
345 | instance.Suspend(); | ||
346 | 428 | ||
347 | SceneObjectPart sop = m_Scene.GetSceneObjectPart(instance.ObjectID); | 429 | return; |
348 | MainConsole.Instance.OutputFormat( | 430 | } |
349 | "Suspended {0}.{1}, item UUID {2}, prim UUID {3} @ {4}", | 431 | |
350 | instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, sop.AbsolutePosition); | 432 | rawItemId = cmdparams[2]; |
433 | |||
434 | if (!UUID.TryParse(rawItemId, out itemId)) | ||
435 | { | ||
436 | MainConsole.Instance.OutputFormat("Error - {0} is not a valid UUID", rawItemId); | ||
437 | return; | ||
438 | } | ||
439 | |||
440 | if (itemId != UUID.Zero) | ||
441 | { | ||
442 | IScriptInstance instance = GetInstance(itemId); | ||
443 | if (instance == null) | ||
444 | { | ||
445 | MainConsole.Instance.OutputFormat("Error - No item found with id {0}", itemId); | ||
446 | return; | ||
447 | } | ||
448 | else | ||
449 | { | ||
450 | action(instance); | ||
451 | return; | ||
351 | } | 452 | } |
352 | } | 453 | } |
353 | } | 454 | } |
354 | } | 455 | } |
355 | 456 | ||
356 | public void HandleResumeScripts(string module, string[] cmdparams) | 457 | private void HandleSuspendScript(IScriptInstance instance) |
357 | { | 458 | { |
358 | lock (m_Scripts) | 459 | if (!instance.Suspended) |
359 | { | 460 | { |
360 | foreach (IScriptInstance instance in m_Scripts.Values) | 461 | instance.Suspend(); |
361 | { | ||
362 | if (instance.Suspended) | ||
363 | { | ||
364 | instance.Resume(); | ||
365 | 462 | ||
366 | SceneObjectPart sop = m_Scene.GetSceneObjectPart(instance.ObjectID); | 463 | SceneObjectPart sop = m_Scene.GetSceneObjectPart(instance.ObjectID); |
367 | MainConsole.Instance.OutputFormat( | 464 | MainConsole.Instance.OutputFormat( |
368 | "Resumed {0}.{1}, item UUID {2}, prim UUID {3} @ {4}", | 465 | "Suspended {0}.{1}, item UUID {2}, prim UUID {3} @ {4}", |
369 | instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, sop.AbsolutePosition); | 466 | instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, sop.AbsolutePosition); |
370 | } | ||
371 | } | ||
372 | } | 467 | } |
373 | } | 468 | } |
374 | 469 | ||
375 | public void HandleStartScripts(string module, string[] cmdparams) | 470 | private void HandleResumeScript(IScriptInstance instance) |
376 | { | 471 | { |
377 | lock (m_Scripts) | 472 | if (instance.Suspended) |
378 | { | 473 | { |
379 | foreach (IScriptInstance instance in m_Scripts.Values) | 474 | instance.Resume(); |
380 | { | ||
381 | if (!instance.Running) | ||
382 | { | ||
383 | instance.Start(); | ||
384 | 475 | ||
385 | SceneObjectPart sop = m_Scene.GetSceneObjectPart(instance.ObjectID); | 476 | SceneObjectPart sop = m_Scene.GetSceneObjectPart(instance.ObjectID); |
386 | MainConsole.Instance.OutputFormat( | 477 | MainConsole.Instance.OutputFormat( |
387 | "Started {0}.{1}, item UUID {2}, prim UUID {3} @ {4}", | 478 | "Resumed {0}.{1}, item UUID {2}, prim UUID {3} @ {4}", |
388 | instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, sop.AbsolutePosition); | 479 | instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, sop.AbsolutePosition); |
389 | } | ||
390 | } | ||
391 | } | 480 | } |
392 | } | 481 | } |
393 | 482 | ||
394 | public void HandleStopScripts(string module, string[] cmdparams) | 483 | private void HandleStartScript(IScriptInstance instance) |
395 | { | 484 | { |
396 | lock (m_Scripts) | 485 | if (!instance.Running) |
397 | { | 486 | { |
398 | foreach (IScriptInstance instance in m_Scripts.Values) | 487 | instance.Start(); |
399 | { | ||
400 | if (instance.Running) | ||
401 | { | ||
402 | instance.Stop(0); | ||
403 | 488 | ||
404 | SceneObjectPart sop = m_Scene.GetSceneObjectPart(instance.ObjectID); | 489 | SceneObjectPart sop = m_Scene.GetSceneObjectPart(instance.ObjectID); |
405 | MainConsole.Instance.OutputFormat( | 490 | MainConsole.Instance.OutputFormat( |
406 | "Stopped {0}.{1}, item UUID {2}, prim UUID {3} @ {4}", | 491 | "Started {0}.{1}, item UUID {2}, prim UUID {3} @ {4}", |
407 | instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, sop.AbsolutePosition); | 492 | instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, sop.AbsolutePosition); |
408 | } | 493 | } |
409 | } | 494 | } |
495 | |||
496 | private void HandleStopScript(IScriptInstance instance) | ||
497 | { | ||
498 | if (instance.Running) | ||
499 | { | ||
500 | instance.Stop(0); | ||
501 | |||
502 | SceneObjectPart sop = m_Scene.GetSceneObjectPart(instance.ObjectID); | ||
503 | MainConsole.Instance.OutputFormat( | ||
504 | "Stopped {0}.{1}, item UUID {2}, prim UUID {3} @ {4}", | ||
505 | instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, sop.AbsolutePosition); | ||
410 | } | 506 | } |
411 | } | 507 | } |
412 | 508 | ||
@@ -414,47 +510,45 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
414 | { | 510 | { |
415 | if (!m_Enabled) | 511 | if (!m_Enabled) |
416 | return; | 512 | return; |
417 | 513 | lockScriptsForRead(true); | |
418 | lock (m_Scripts) | 514 | foreach (IScriptInstance instance in m_Scripts.Values) |
419 | { | 515 | { |
420 | m_log.InfoFormat( | 516 | // Force a final state save |
421 | "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName); | 517 | // |
422 | 518 | if (m_Assemblies.ContainsKey(instance.AssetID)) | |
423 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
424 | { | 519 | { |
425 | // Force a final state save | 520 | string assembly = m_Assemblies[instance.AssetID]; |
426 | // | 521 | instance.SaveState(assembly); |
427 | if (m_Assemblies.ContainsKey(instance.AssetID)) | 522 | } |
428 | { | ||
429 | string assembly = m_Assemblies[instance.AssetID]; | ||
430 | instance.SaveState(assembly); | ||
431 | } | ||
432 | 523 | ||
433 | // Clear the event queue and abort the instance thread | 524 | // Clear the event queue and abort the instance thread |
434 | // | 525 | // |
435 | instance.ClearQueue(); | 526 | instance.ClearQueue(); |
436 | instance.Stop(0); | 527 | instance.Stop(0); |
437 | 528 | ||
438 | // Release events, timer, etc | 529 | // Release events, timer, etc |
439 | // | 530 | // |
440 | instance.DestroyScriptInstance(); | 531 | instance.DestroyScriptInstance(); |
441 | 532 | ||
442 | // Unload scripts and app domains | 533 | // Unload scripts and app domains |
443 | // Must be done explicitly because they have infinite | 534 | // Must be done explicitly because they have infinite |
444 | // lifetime | 535 | // lifetime |
445 | // | 536 | // |
446 | m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); | 537 | m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); |
447 | if (m_DomainScripts[instance.AppDomain].Count == 0) | 538 | if (m_DomainScripts[instance.AppDomain].Count == 0) |
448 | { | 539 | { |
449 | m_DomainScripts.Remove(instance.AppDomain); | 540 | m_DomainScripts.Remove(instance.AppDomain); |
450 | UnloadAppDomain(instance.AppDomain); | 541 | UnloadAppDomain(instance.AppDomain); |
451 | } | ||
452 | } | 542 | } |
453 | m_Scripts.Clear(); | ||
454 | m_PrimObjects.Clear(); | ||
455 | m_Assemblies.Clear(); | ||
456 | m_DomainScripts.Clear(); | ||
457 | } | 543 | } |
544 | lockScriptsForRead(false); | ||
545 | lockScriptsForWrite(true); | ||
546 | m_Scripts.Clear(); | ||
547 | lockScriptsForWrite(false); | ||
548 | m_PrimObjects.Clear(); | ||
549 | m_Assemblies.Clear(); | ||
550 | m_DomainScripts.Clear(); | ||
551 | |||
458 | lock (m_ScriptEngines) | 552 | lock (m_ScriptEngines) |
459 | { | 553 | { |
460 | m_ScriptEngines.Remove(this); | 554 | m_ScriptEngines.Remove(this); |
@@ -519,22 +613,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
519 | 613 | ||
520 | List<IScriptInstance> instances = new List<IScriptInstance>(); | 614 | List<IScriptInstance> instances = new List<IScriptInstance>(); |
521 | 615 | ||
522 | lock (m_Scripts) | 616 | lockScriptsForRead(true); |
523 | { | 617 | foreach (IScriptInstance instance in m_Scripts.Values) |
524 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
525 | instances.Add(instance); | 618 | instances.Add(instance); |
526 | } | 619 | lockScriptsForRead(false); |
527 | 620 | ||
528 | foreach (IScriptInstance i in instances) | 621 | foreach (IScriptInstance i in instances) |
529 | { | 622 | { |
530 | string assembly = String.Empty; | 623 | string assembly = String.Empty; |
531 | 624 | ||
532 | lock (m_Scripts) | 625 | |
533 | { | ||
534 | if (!m_Assemblies.ContainsKey(i.AssetID)) | 626 | if (!m_Assemblies.ContainsKey(i.AssetID)) |
535 | continue; | 627 | continue; |
536 | assembly = m_Assemblies[i.AssetID]; | 628 | assembly = m_Assemblies[i.AssetID]; |
537 | } | 629 | |
538 | 630 | ||
539 | i.SaveState(assembly); | 631 | i.SaveState(assembly); |
540 | } | 632 | } |
@@ -868,92 +960,95 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
868 | } | 960 | } |
869 | 961 | ||
870 | ScriptInstance instance = null; | 962 | ScriptInstance instance = null; |
871 | lock (m_Scripts) | 963 | // Create the object record |
964 | lockScriptsForRead(true); | ||
965 | if ((!m_Scripts.ContainsKey(itemID)) || | ||
966 | (m_Scripts[itemID].AssetID != assetID)) | ||
872 | { | 967 | { |
873 | // Create the object record | 968 | lockScriptsForRead(false); |
874 | 969 | ||
875 | if ((!m_Scripts.ContainsKey(itemID)) || | 970 | UUID appDomain = assetID; |
876 | (m_Scripts[itemID].AssetID != assetID)) | ||
877 | { | ||
878 | UUID appDomain = assetID; | ||
879 | 971 | ||
880 | if (part.ParentGroup.IsAttachment) | 972 | if (part.ParentGroup.IsAttachment) |
881 | appDomain = part.ParentGroup.RootPart.UUID; | 973 | appDomain = part.ParentGroup.RootPart.UUID; |
882 | 974 | ||
883 | if (!m_AppDomains.ContainsKey(appDomain)) | 975 | if (!m_AppDomains.ContainsKey(appDomain)) |
976 | { | ||
977 | try | ||
884 | { | 978 | { |
885 | try | 979 | AppDomainSetup appSetup = new AppDomainSetup(); |
886 | { | 980 | appSetup.PrivateBinPath = Path.Combine( |
887 | AppDomainSetup appSetup = new AppDomainSetup(); | 981 | m_ScriptEnginesPath, |
888 | appSetup.PrivateBinPath = Path.Combine( | 982 | m_Scene.RegionInfo.RegionID.ToString()); |
889 | m_ScriptEnginesPath, | 983 | |
890 | m_Scene.RegionInfo.RegionID.ToString()); | 984 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; |
891 | 985 | Evidence evidence = new Evidence(baseEvidence); | |
892 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; | 986 | |
893 | Evidence evidence = new Evidence(baseEvidence); | 987 | AppDomain sandbox; |
894 | 988 | if (m_AppDomainLoading) | |
895 | AppDomain sandbox; | 989 | sandbox = AppDomain.CreateDomain( |
896 | if (m_AppDomainLoading) | 990 | m_Scene.RegionInfo.RegionID.ToString(), |
897 | sandbox = AppDomain.CreateDomain( | 991 | evidence, appSetup); |
898 | m_Scene.RegionInfo.RegionID.ToString(), | 992 | else |
899 | evidence, appSetup); | 993 | sandbox = AppDomain.CurrentDomain; |
900 | else | 994 | |
901 | sandbox = AppDomain.CurrentDomain; | 995 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); |
902 | 996 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | |
903 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); | 997 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); |
904 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | 998 | //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); |
905 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); | 999 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); |
906 | //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); | 1000 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; |
907 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); | 1001 | //sandbox.SetAppDomainPolicy(sandboxPolicy); |
908 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; | 1002 | |
909 | //sandbox.SetAppDomainPolicy(sandboxPolicy); | 1003 | m_AppDomains[appDomain] = sandbox; |
910 | 1004 | ||
911 | m_AppDomains[appDomain] = sandbox; | 1005 | m_AppDomains[appDomain].AssemblyResolve += |
912 | 1006 | new ResolveEventHandler( | |
913 | m_AppDomains[appDomain].AssemblyResolve += | 1007 | AssemblyResolver.OnAssemblyResolve); |
914 | new ResolveEventHandler( | 1008 | m_DomainScripts[appDomain] = new List<UUID>(); |
915 | AssemblyResolver.OnAssemblyResolve); | 1009 | } |
916 | m_DomainScripts[appDomain] = new List<UUID>(); | 1010 | catch (Exception e) |
917 | } | 1011 | { |
918 | catch (Exception e) | 1012 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); |
1013 | m_ScriptErrorMessage += "Exception creating app domain:\n"; | ||
1014 | m_ScriptFailCount++; | ||
1015 | lock (m_AddingAssemblies) | ||
919 | { | 1016 | { |
920 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); | 1017 | m_AddingAssemblies[assembly]--; |
921 | m_ScriptErrorMessage += "Exception creating app domain:\n"; | ||
922 | m_ScriptFailCount++; | ||
923 | lock (m_AddingAssemblies) | ||
924 | { | ||
925 | m_AddingAssemblies[assembly]--; | ||
926 | } | ||
927 | return false; | ||
928 | } | 1018 | } |
1019 | return false; | ||
929 | } | 1020 | } |
930 | m_DomainScripts[appDomain].Add(itemID); | 1021 | } |
931 | 1022 | m_DomainScripts[appDomain].Add(itemID); | |
932 | instance = new ScriptInstance(this, part, | 1023 | |
933 | itemID, assetID, assembly, | 1024 | instance = new ScriptInstance(this, part, |
934 | m_AppDomains[appDomain], | 1025 | itemID, assetID, assembly, |
935 | part.ParentGroup.RootPart.Name, | 1026 | m_AppDomains[appDomain], |
936 | item.Name, startParam, postOnRez, | 1027 | part.ParentGroup.RootPart.Name, |
937 | stateSource, m_MaxScriptQueue); | 1028 | item.Name, startParam, postOnRez, |
938 | 1029 | stateSource, m_MaxScriptQueue); | |
939 | m_log.DebugFormat( | 1030 | |
940 | "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", | 1031 | m_log.DebugFormat( |
941 | part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, | 1032 | "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", |
1033 | part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, | ||
942 | part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); | 1034 | part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); |
943 | 1035 | ||
944 | if (presence != null) | 1036 | if (presence != null) |
945 | { | 1037 | { |
946 | ShowScriptSaveResponse(item.OwnerID, | 1038 | ShowScriptSaveResponse(item.OwnerID, |
947 | assetID, "Compile successful", true); | 1039 | assetID, "Compile successful", true); |
948 | } | ||
949 | |||
950 | instance.AppDomain = appDomain; | ||
951 | instance.LineMap = linemap; | ||
952 | |||
953 | m_Scripts[itemID] = instance; | ||
954 | } | 1040 | } |
955 | } | ||
956 | 1041 | ||
1042 | instance.AppDomain = appDomain; | ||
1043 | instance.LineMap = linemap; | ||
1044 | lockScriptsForWrite(true); | ||
1045 | m_Scripts[itemID] = instance; | ||
1046 | lockScriptsForWrite(false); | ||
1047 | } | ||
1048 | else | ||
1049 | { | ||
1050 | lockScriptsForRead(false); | ||
1051 | } | ||
957 | lock (m_PrimObjects) | 1052 | lock (m_PrimObjects) |
958 | { | 1053 | { |
959 | if (!m_PrimObjects.ContainsKey(localID)) | 1054 | if (!m_PrimObjects.ContainsKey(localID)) |
@@ -972,9 +1067,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
972 | m_AddingAssemblies[assembly]--; | 1067 | m_AddingAssemblies[assembly]--; |
973 | } | 1068 | } |
974 | 1069 | ||
975 | if (instance != null) | 1070 | if (instance!=null) |
976 | instance.Init(); | 1071 | instance.Init(); |
977 | 1072 | ||
978 | return true; | 1073 | return true; |
979 | } | 1074 | } |
980 | 1075 | ||
@@ -987,20 +1082,31 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
987 | m_CompileDict.Remove(itemID); | 1082 | m_CompileDict.Remove(itemID); |
988 | } | 1083 | } |
989 | 1084 | ||
990 | IScriptInstance instance = null; | 1085 | lockScriptsForRead(true); |
991 | 1086 | // Do we even have it? | |
992 | lock (m_Scripts) | 1087 | if (!m_Scripts.ContainsKey(itemID)) |
993 | { | 1088 | { |
994 | // Do we even have it? | 1089 | // Do we even have it? |
995 | if (!m_Scripts.ContainsKey(itemID)) | 1090 | if (!m_Scripts.ContainsKey(itemID)) |
996 | return; | 1091 | return; |
997 | 1092 | ||
998 | instance = m_Scripts[itemID]; | 1093 | lockScriptsForRead(false); |
1094 | lockScriptsForWrite(true); | ||
999 | m_Scripts.Remove(itemID); | 1095 | m_Scripts.Remove(itemID); |
1096 | lockScriptsForWrite(false); | ||
1097 | |||
1098 | return; | ||
1000 | } | 1099 | } |
1100 | |||
1001 | 1101 | ||
1102 | IScriptInstance instance=m_Scripts[itemID]; | ||
1103 | lockScriptsForRead(false); | ||
1104 | lockScriptsForWrite(true); | ||
1105 | m_Scripts.Remove(itemID); | ||
1106 | lockScriptsForWrite(false); | ||
1002 | instance.ClearQueue(); | 1107 | instance.ClearQueue(); |
1003 | instance.Stop(0); | 1108 | instance.Stop(0); |
1109 | |||
1004 | // bool objectRemoved = false; | 1110 | // bool objectRemoved = false; |
1005 | 1111 | ||
1006 | lock (m_PrimObjects) | 1112 | lock (m_PrimObjects) |
@@ -1036,11 +1142,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1036 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; | 1142 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; |
1037 | if (handlerObjectRemoved != null) | 1143 | if (handlerObjectRemoved != null) |
1038 | { | 1144 | { |
1039 | SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); | 1145 | SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); |
1040 | handlerObjectRemoved(part.UUID); | 1146 | handlerObjectRemoved(part.UUID); |
1041 | } | 1147 | } |
1042 | 1148 | ||
1043 | 1149 | CleanAssemblies(); | |
1150 | |||
1044 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; | 1151 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; |
1045 | if (handlerScriptRemoved != null) | 1152 | if (handlerScriptRemoved != null) |
1046 | handlerScriptRemoved(itemID); | 1153 | handlerScriptRemoved(itemID); |
@@ -1182,7 +1289,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1182 | return false; | 1289 | return false; |
1183 | 1290 | ||
1184 | uuids = m_PrimObjects[localID]; | 1291 | uuids = m_PrimObjects[localID]; |
1185 | } | 1292 | |
1186 | 1293 | ||
1187 | foreach (UUID itemID in uuids) | 1294 | foreach (UUID itemID in uuids) |
1188 | { | 1295 | { |
@@ -1200,6 +1307,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1200 | result = true; | 1307 | result = true; |
1201 | } | 1308 | } |
1202 | } | 1309 | } |
1310 | } | ||
1203 | 1311 | ||
1204 | return result; | 1312 | return result; |
1205 | } | 1313 | } |
@@ -1299,12 +1407,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1299 | private IScriptInstance GetInstance(UUID itemID) | 1407 | private IScriptInstance GetInstance(UUID itemID) |
1300 | { | 1408 | { |
1301 | IScriptInstance instance; | 1409 | IScriptInstance instance; |
1302 | lock (m_Scripts) | 1410 | lockScriptsForRead(true); |
1411 | if (!m_Scripts.ContainsKey(itemID)) | ||
1303 | { | 1412 | { |
1304 | if (!m_Scripts.ContainsKey(itemID)) | 1413 | lockScriptsForRead(false); |
1305 | return null; | 1414 | return null; |
1306 | instance = m_Scripts[itemID]; | ||
1307 | } | 1415 | } |
1416 | instance = m_Scripts[itemID]; | ||
1417 | lockScriptsForRead(false); | ||
1308 | return instance; | 1418 | return instance; |
1309 | } | 1419 | } |
1310 | 1420 | ||
@@ -1328,6 +1438,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1328 | return false; | 1438 | return false; |
1329 | } | 1439 | } |
1330 | 1440 | ||
1441 | [DebuggerNonUserCode] | ||
1331 | public void ApiResetScript(UUID itemID) | 1442 | public void ApiResetScript(UUID itemID) |
1332 | { | 1443 | { |
1333 | IScriptInstance instance = GetInstance(itemID); | 1444 | IScriptInstance instance = GetInstance(itemID); |
@@ -1379,6 +1490,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1379 | return UUID.Zero; | 1490 | return UUID.Zero; |
1380 | } | 1491 | } |
1381 | 1492 | ||
1493 | [DebuggerNonUserCode] | ||
1382 | public void SetState(UUID itemID, string newState) | 1494 | public void SetState(UUID itemID, string newState) |
1383 | { | 1495 | { |
1384 | IScriptInstance instance = GetInstance(itemID); | 1496 | IScriptInstance instance = GetInstance(itemID); |
@@ -1399,11 +1511,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1399 | { | 1511 | { |
1400 | List<IScriptInstance> instances = new List<IScriptInstance>(); | 1512 | List<IScriptInstance> instances = new List<IScriptInstance>(); |
1401 | 1513 | ||
1402 | lock (m_Scripts) | 1514 | lockScriptsForRead(true); |
1403 | { | 1515 | foreach (IScriptInstance instance in m_Scripts.Values) |
1404 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
1405 | instances.Add(instance); | 1516 | instances.Add(instance); |
1406 | } | 1517 | lockScriptsForRead(false); |
1407 | 1518 | ||
1408 | foreach (IScriptInstance i in instances) | 1519 | foreach (IScriptInstance i in instances) |
1409 | { | 1520 | { |
@@ -1770,19 +1881,27 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1770 | public void SuspendScript(UUID itemID) | 1881 | public void SuspendScript(UUID itemID) |
1771 | { | 1882 | { |
1772 | IScriptInstance instance = GetInstance(itemID); | 1883 | IScriptInstance instance = GetInstance(itemID); |
1773 | if (instance == null) | 1884 | if (instance != null) |
1774 | return; | 1885 | instance.Suspend(); |
1775 | |||
1776 | instance.Suspend(); | ||
1777 | } | 1886 | } |
1778 | 1887 | ||
1779 | public void ResumeScript(UUID itemID) | 1888 | public void ResumeScript(UUID itemID) |
1780 | { | 1889 | { |
1781 | IScriptInstance instance = GetInstance(itemID); | 1890 | IScriptInstance instance = GetInstance(itemID); |
1891 | if (instance != null) | ||
1892 | instance.Resume(); | ||
1893 | } | ||
1894 | |||
1895 | public bool HasScript(UUID itemID, out bool running) | ||
1896 | { | ||
1897 | running = true; | ||
1898 | |||
1899 | IScriptInstance instance = GetInstance(itemID); | ||
1782 | if (instance == null) | 1900 | if (instance == null) |
1783 | return; | 1901 | return false; |
1784 | 1902 | ||
1785 | instance.Resume(); | 1903 | running = instance.Running; |
1904 | return true; | ||
1786 | } | 1905 | } |
1787 | } | 1906 | } |
1788 | } | 1907 | } \ No newline at end of file |