aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/XEngine/XEngine.cs')
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs513
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;
30using System.Threading; 30using System.Threading;
31using System.Collections; 31using System.Collections;
32using System.Collections.Generic; 32using System.Collections.Generic;
33using System.Diagnostics; //for [DebuggerNonUserCode]
33using System.Security; 34using System.Security;
34using System.Security.Policy; 35using System.Security.Policy;
35using System.Reflection; 36using 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