aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorMelanie Thielker2008-09-18 18:50:39 +0000
committerMelanie Thielker2008-09-18 18:50:39 +0000
commit903fbd1f06b990141a90b539a2dbe77ab6be830e (patch)
tree9e33425216bd3a5631cf561d279ba503565c1e05 /OpenSim
parent* Updates the SQLite region database to support the same properties that the ... (diff)
downloadopensim-SC-903fbd1f06b990141a90b539a2dbe77ab6be830e.zip
opensim-SC-903fbd1f06b990141a90b539a2dbe77ab6be830e.tar.gz
opensim-SC-903fbd1f06b990141a90b539a2dbe77ab6be830e.tar.bz2
opensim-SC-903fbd1f06b990141a90b539a2dbe77ab6be830e.tar.xz
XEngine: fix collisions, add event coalescing for collision events.
Fix a nasty concurrency issue that could cause a high event frequency to start more than one thread pool job for a single script.
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODEPrim.cs10
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs244
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/EventManager.cs25
3 files changed, 154 insertions, 125 deletions
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
index 21e514b..79c4041 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
@@ -2294,14 +2294,12 @@ namespace OpenSim.Region.Physics.OdePlugin
2294 if (CollisionEventsThisFrame == null) 2294 if (CollisionEventsThisFrame == null)
2295 return; 2295 return;
2296 2296
2297 //if (CollisionEventsThisFrame.m_objCollisionList == null) 2297 base.SendCollisionUpdate(CollisionEventsThisFrame);
2298 // return;
2299 2298
2300 if (CollisionEventsThisFrame.m_objCollisionList.Count > 0) 2299 if(CollisionEventsThisFrame.m_objCollisionList.Count == 0)
2301 { 2300 CollisionEventsThisFrame = null;
2302 base.SendCollisionUpdate(CollisionEventsThisFrame); 2301 else
2303 CollisionEventsThisFrame = new CollisionEventUpdate(); 2302 CollisionEventsThisFrame = new CollisionEventUpdate();
2304 }
2305 } 2303 }
2306 2304
2307 public override bool SubscribedEvents() 2305 public override bool SubscribedEvents()
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 71bdd6e..506f0f5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -79,6 +79,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
79 private bool m_ShuttingDown = false; 79 private bool m_ShuttingDown = false;
80 private int m_ControlEventsInQueue = 0; 80 private int m_ControlEventsInQueue = 0;
81 private int m_LastControlLevel = 0; 81 private int m_LastControlLevel = 0;
82 private bool m_CollisionInQueue = false;
82 83
83 private Dictionary<string,IScriptApi> m_Apis = new Dictionary<string,IScriptApi>(); 84 private Dictionary<string,IScriptApi> m_Apis = new Dictionary<string,IScriptApi>();
84 85
@@ -495,6 +496,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
495 m_ControlEventsInQueue++; 496 m_ControlEventsInQueue++;
496 } 497 }
497 498
499 if (data.EventName == "collision")
500 {
501 if (m_CollisionInQueue)
502 return;
503 if (data.DetectParams == null)
504 return;
505
506 m_CollisionInQueue = true;
507 }
508
498 m_EventQueue.Enqueue(data); 509 m_EventQueue.Enqueue(data);
499 510
500 if (m_CurrentResult == null) 511 if (m_CurrentResult == null)
@@ -510,146 +521,159 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
510 /// <returns></returns> 521 /// <returns></returns>
511 public object EventProcessor() 522 public object EventProcessor()
512 { 523 {
513 EventParams data = null; 524 lock(m_Script)
514
515 lock (m_EventQueue)
516 { 525 {
517 data = (EventParams) m_EventQueue.Dequeue(); 526 EventParams data = null;
518 if (data == null) // Shouldn't happen 527
519 { 528 lock (m_EventQueue)
520 m_CurrentResult = null;
521 return 0;
522 }
523 if (data.EventName == "timer")
524 m_TimerQueued = false;
525 if (data.EventName == "control")
526 { 529 {
527 if (m_ControlEventsInQueue > 0) 530 data = (EventParams) m_EventQueue.Dequeue();
528 m_ControlEventsInQueue--; 531 if (data == null) // Shouldn't happen
532 {
533 if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown))
534 {
535 m_CurrentResult = m_Engine.QueueEventHandler(this);
536 }
537 else
538 {
539 m_CurrentResult = null;
540 }
541 return 0;
542 }
543
544 if (data.EventName == "timer")
545 m_TimerQueued = false;
546 if (data.EventName == "control")
547 {
548 if (m_ControlEventsInQueue > 0)
549 m_ControlEventsInQueue--;
550 }
551 if (data.EventName == "collision")
552 m_CollisionInQueue = false;
529 } 553 }
530 } 554
531 555 //m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this);
532 //m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this);
533 556
534 m_DetectParams = data.DetectParams; 557 m_DetectParams = data.DetectParams;
535 558
536 if (data.EventName == "state") // Hardcoded state change 559 if (data.EventName == "state") // Hardcoded state change
537 {
538// m_Engine.Log.DebugFormat("[Script] Script {0}.{1} state set to {2}",
539// m_PrimName, m_ScriptName, data.Params[0].ToString());
540 m_State=data.Params[0].ToString();
541 AsyncCommandManager async = (AsyncCommandManager)m_Engine.AsyncCommands;
542 async.RemoveScript(
543 m_LocalID, m_ItemID);
544
545 SceneObjectPart part = m_Engine.World.GetSceneObjectPart(
546 m_LocalID);
547 if (part != null)
548 { 560 {
549 part.SetScriptEvents(m_ItemID, 561 // m_Engine.Log.DebugFormat("[Script] Script {0}.{1} state set to {2}",
550 (int)m_Script.GetStateEventFlags(State)); 562 // m_PrimName, m_ScriptName, data.Params[0].ToString());
563 m_State=data.Params[0].ToString();
564 AsyncCommandManager async = (AsyncCommandManager)m_Engine.AsyncCommands;
565 async.RemoveScript(
566 m_LocalID, m_ItemID);
567
568 SceneObjectPart part = m_Engine.World.GetSceneObjectPart(
569 m_LocalID);
570 if (part != null)
571 {
572 part.SetScriptEvents(m_ItemID,
573 (int)m_Script.GetStateEventFlags(State));
574 }
551 } 575 }
552 } 576 else
553 else
554 {
555 SceneObjectPart part = m_Engine.World.GetSceneObjectPart(
556 m_LocalID);
557// m_Engine.Log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}",
558// m_PrimName, m_ScriptName, data.EventName, m_State);
559
560 try
561 { 577 {
562 m_CurrentEvent = data.EventName; 578 SceneObjectPart part = m_Engine.World.GetSceneObjectPart(
563 m_EventStart = DateTime.Now; 579 m_LocalID);
564 m_InEvent = true; 580 // m_Engine.Log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}",
581 // m_PrimName, m_ScriptName, data.EventName, m_State);
565 582
566 m_Script.ExecuteEvent(State, data.EventName, data.Params); 583 try
584 {
585 m_CurrentEvent = data.EventName;
586 m_EventStart = DateTime.Now;
587 m_InEvent = true;
567 588
568 m_InEvent = false; 589 m_Script.ExecuteEvent(State, data.EventName, data.Params);
569 m_CurrentEvent = String.Empty;
570 590
571 if (m_SaveState) 591 m_InEvent = false;
572 { 592 m_CurrentEvent = String.Empty;
573 // This will be the very first event we deliver
574 // (state_entry) in defualt state
575 //
576 593
577 SaveState(m_Assembly); 594 if (m_SaveState)
595 {
596 // This will be the very first event we deliver
597 // (state_entry) in defualt state
598 //
578 599
579 m_SaveState = false; 600 SaveState(m_Assembly);
580 }
581 }
582 catch (Exception e)
583 {
584 m_InEvent = false;
585 m_CurrentEvent = String.Empty;
586 601
587 if (!(e is TargetInvocationException) || (!(e.InnerException is EventAbortException) && (!(e.InnerException is SelfDeleteException)))) 602 m_SaveState = false;
603 }
604 }
605 catch (Exception e)
588 { 606 {
589 if (e is System.Threading.ThreadAbortException) 607 m_InEvent = false;
608 m_CurrentEvent = String.Empty;
609
610 if (!(e is TargetInvocationException) || (!(e.InnerException is EventAbortException) && (!(e.InnerException is SelfDeleteException))))
590 { 611 {
591 lock (m_EventQueue) 612 if (e is System.Threading.ThreadAbortException)
592 { 613 {
593 if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) 614 lock (m_EventQueue)
594 { 615 {
595 m_CurrentResult=m_Engine.QueueEventHandler(this); 616 if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown))
617 {
618 m_CurrentResult=m_Engine.QueueEventHandler(this);
619 }
620 else
621 {
622 m_CurrentResult = null;
623 }
596 } 624 }
597 else
598 {
599 m_CurrentResult = null;
600 }
601 }
602 625
603 m_DetectParams = null; 626 m_DetectParams = null;
604 627
605 return 0; 628 return 0;
606 } 629 }
607 630
608 try 631 try
609 { 632 {
610 // DISPLAY ERROR INWORLD 633 // DISPLAY ERROR INWORLD
611 string text = "Runtime error:\n" + e.InnerException.ToString(); 634 string text = "Runtime error:\n" + e.InnerException.ToString();
612 if (text.Length > 1000) 635 if (text.Length > 1000)
613 text = text.Substring(0, 1000); 636 text = text.Substring(0, 1000);
614 m_Engine.World.SimChat(Utils.StringToBytes(text), 637 m_Engine.World.SimChat(Utils.StringToBytes(text),
615 ChatTypeEnum.DebugChannel, 2147483647, 638 ChatTypeEnum.DebugChannel, 2147483647,
616 part.AbsolutePosition, 639 part.AbsolutePosition,
617 part.Name, part.UUID, false); 640 part.Name, part.UUID, false);
641 }
642 catch (Exception e2) // LEGIT: User Scripting
643 {
644 m_Engine.Log.Error("[Script]: "+
645 "Error displaying error in-world: " +
646 e2.ToString());
647 m_Engine.Log.Error("[Script]: " +
648 "Errormessage: Error compiling script:\r\n" +
649 e.ToString());
650 }
618 } 651 }
619 catch (Exception e2) // LEGIT: User Scripting 652 else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException))
620 { 653 {
621 m_Engine.Log.Error("[Script]: "+ 654 m_InSelfDelete = true;
622 "Error displaying error in-world: " + 655 if (part != null && part.ParentGroup != null)
623 e2.ToString()); 656 m_Engine.World.DeleteSceneObject(part.ParentGroup);
624 m_Engine.Log.Error("[Script]: " +
625 "Errormessage: Error compiling script:\r\n" +
626 e.ToString());
627 } 657 }
628 } 658 }
629 else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException))
630 {
631 m_InSelfDelete = true;
632 if (part != null && part.ParentGroup != null)
633 m_Engine.World.DeleteSceneObject(part.ParentGroup);
634 }
635 } 659 }
636 }
637 660
638 lock (m_EventQueue) 661 lock (m_EventQueue)
639 {
640 if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown))
641 {
642 m_CurrentResult = m_Engine.QueueEventHandler(this);
643 }
644 else
645 { 662 {
646 m_CurrentResult = null; 663 if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown))
664 {
665 m_CurrentResult = m_Engine.QueueEventHandler(this);
666 }
667 else
668 {
669 m_CurrentResult = null;
670 }
647 } 671 }
648 }
649 672
650 m_DetectParams = null; 673 m_DetectParams = null;
651 674
652 return 0; 675 return 0;
676 }
653 } 677 }
654 678
655 public int EventTime() 679 public int EventTime()
@@ -730,6 +754,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
730 754
731 public DetectParams GetDetectParams(int idx) 755 public DetectParams GetDetectParams(int idx)
732 { 756 {
757 if (m_DetectParams == null)
758 return null;
733 if (idx < 0 || idx >= m_DetectParams.Length) 759 if (idx < 0 || idx >= m_DetectParams.Length)
734 return null; 760 return null;
735 761
@@ -738,6 +764,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
738 764
739 public UUID GetDetectID(int idx) 765 public UUID GetDetectID(int idx)
740 { 766 {
767 if (m_DetectParams == null)
768 return UUID.Zero;
741 if (idx < 0 || idx >= m_DetectParams.Length) 769 if (idx < 0 || idx >= m_DetectParams.Length)
742 return UUID.Zero; 770 return UUID.Zero;
743 771
diff --git a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs
index 22abd79..9ed2fbb 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs
@@ -198,10 +198,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine
198 det.Add(d); 198 det.Add(d);
199 } 199 }
200 200
201 myScriptEngine.PostObjectEvent(localID, new EventParams( 201 if (det.Count > 0)
202 "collision_start", 202 myScriptEngine.PostObjectEvent(localID, new EventParams(
203 new Object[] { new LSL_Types.LSLInteger(1) }, 203 "collision_start",
204 det.ToArray())); 204 new Object[] { new LSL_Types.LSLInteger(det.Count) },
205 det.ToArray()));
205 } 206 }
206 207
207 public void collision(uint localID, ColliderArgs col) 208 public void collision(uint localID, ColliderArgs col)
@@ -217,9 +218,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
217 det.Add(d); 218 det.Add(d);
218 } 219 }
219 220
220 myScriptEngine.PostObjectEvent(localID, new EventParams( 221 if (det.Count > 0)
221 "collision", new Object[] { new LSL_Types.LSLInteger(1) }, 222 myScriptEngine.PostObjectEvent(localID, new EventParams(
222 det.ToArray())); 223 "collision", new Object[] { new LSL_Types.LSLInteger(det.Count) },
224 det.ToArray()));
223 } 225 }
224 226
225 public void collision_end(uint localID, ColliderArgs col) 227 public void collision_end(uint localID, ColliderArgs col)
@@ -235,10 +237,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine
235 det.Add(d); 237 det.Add(d);
236 } 238 }
237 239
238 myScriptEngine.PostObjectEvent(localID, new EventParams( 240 if (det.Count > 0)
239 "collision_end", 241 myScriptEngine.PostObjectEvent(localID, new EventParams(
240 new Object[] { new LSL_Types.LSLInteger(1) }, 242 "collision_end",
241 det.ToArray())); 243 new Object[] { new LSL_Types.LSLInteger(det.Count) },
244 det.ToArray()));
242 } 245 }
243 246
244 public void land_collision_start(uint localID, UUID itemID) 247 public void land_collision_start(uint localID, UUID itemID)