diff options
author | Justin Clark-Casey (justincc) | 2010-08-26 00:08:53 +0100 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2010-08-26 00:08:53 +0100 |
commit | 8031f8ec09df4f654c86a9c7bc498664f7b9d9dc (patch) | |
tree | d6a6da4d448b9bc11ff8d1078b9be089b9872151 /OpenSim/Region/ScriptEngine/Shared/Api | |
parent | minor: remove mono compiler warning (diff) | |
download | opensim-SC-8031f8ec09df4f654c86a9c7bc498664f7b9d9dc.zip opensim-SC-8031f8ec09df4f654c86a9c7bc498664f7b9d9dc.tar.gz opensim-SC-8031f8ec09df4f654c86a9c7bc498664f7b9d9dc.tar.bz2 opensim-SC-8031f8ec09df4f654c86a9c7bc498664f7b9d9dc.tar.xz |
Improve consistency of locking for SOG.m_parts in order to avoid race conditions in linking and unlinking
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared/Api')
-rw-r--r-- | OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 100 |
1 files changed, 61 insertions, 39 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 21604d0..af42dae 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -235,7 +235,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
235 | { | 235 | { |
236 | case ScriptBaseClass.LINK_SET: | 236 | case ScriptBaseClass.LINK_SET: |
237 | if (m_host.ParentGroup != null) | 237 | if (m_host.ParentGroup != null) |
238 | return new List<SceneObjectPart>(m_host.ParentGroup.Children.Values); | 238 | { |
239 | lock (m_host.ParentGroup.Children) | ||
240 | return new List<SceneObjectPart>(m_host.ParentGroup.Children.Values); | ||
241 | } | ||
239 | return ret; | 242 | return ret; |
240 | 243 | ||
241 | case ScriptBaseClass.LINK_ROOT: | 244 | case ScriptBaseClass.LINK_ROOT: |
@@ -250,7 +253,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
250 | case ScriptBaseClass.LINK_ALL_OTHERS: | 253 | case ScriptBaseClass.LINK_ALL_OTHERS: |
251 | if (m_host.ParentGroup == null) | 254 | if (m_host.ParentGroup == null) |
252 | return new List<SceneObjectPart>(); | 255 | return new List<SceneObjectPart>(); |
253 | ret = new List<SceneObjectPart>(m_host.ParentGroup.Children.Values); | 256 | |
257 | lock (m_host.ParentGroup.Children) | ||
258 | ret = new List<SceneObjectPart>(m_host.ParentGroup.Children.Values); | ||
259 | |||
254 | if (ret.Contains(m_host)) | 260 | if (ret.Contains(m_host)) |
255 | ret.Remove(m_host); | 261 | ret.Remove(m_host); |
256 | return ret; | 262 | return ret; |
@@ -258,7 +264,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
258 | case ScriptBaseClass.LINK_ALL_CHILDREN: | 264 | case ScriptBaseClass.LINK_ALL_CHILDREN: |
259 | if (m_host.ParentGroup == null) | 265 | if (m_host.ParentGroup == null) |
260 | return new List<SceneObjectPart>(); | 266 | return new List<SceneObjectPart>(); |
261 | ret = new List<SceneObjectPart>(m_host.ParentGroup.Children.Values); | 267 | |
268 | lock (m_host.ParentGroup.Children) | ||
269 | ret = new List<SceneObjectPart>(m_host.ParentGroup.Children.Values); | ||
270 | |||
262 | if (ret.Contains(m_host.ParentGroup.RootPart)) | 271 | if (ret.Contains(m_host.ParentGroup.RootPart)) |
263 | ret.Remove(m_host.ParentGroup.RootPart); | 272 | ret.Remove(m_host.ParentGroup.RootPart); |
264 | return ret; | 273 | return ret; |
@@ -1178,12 +1187,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1178 | if (group == null) | 1187 | if (group == null) |
1179 | return; | 1188 | return; |
1180 | bool allow = true; | 1189 | bool allow = true; |
1181 | foreach (SceneObjectPart part in group.Children.Values) | 1190 | |
1191 | lock (group.Children) | ||
1182 | { | 1192 | { |
1183 | if (part.Scale.X > World.m_maxPhys || part.Scale.Y > World.m_maxPhys || part.Scale.Z > World.m_maxPhys) | 1193 | foreach (SceneObjectPart part in group.Children.Values) |
1184 | { | 1194 | { |
1185 | allow = false; | 1195 | if (part.Scale.X > World.m_maxPhys || part.Scale.Y > World.m_maxPhys || part.Scale.Z > World.m_maxPhys) |
1186 | break; | 1196 | { |
1197 | allow = false; | ||
1198 | break; | ||
1199 | } | ||
1187 | } | 1200 | } |
1188 | } | 1201 | } |
1189 | 1202 | ||
@@ -3492,7 +3505,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3492 | { | 3505 | { |
3493 | m_host.AddScriptLPS(1); | 3506 | m_host.AddScriptLPS(1); |
3494 | 3507 | ||
3495 | if (m_host.ParentGroup.Children.Count > 1) | 3508 | if (m_host.ParentGroup.PrimCount > 1) |
3496 | { | 3509 | { |
3497 | return m_host.LinkNum; | 3510 | return m_host.LinkNum; |
3498 | } | 3511 | } |
@@ -3604,15 +3617,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3604 | case ScriptBaseClass.LINK_ALL_OTHERS: | 3617 | case ScriptBaseClass.LINK_ALL_OTHERS: |
3605 | case ScriptBaseClass.LINK_ALL_CHILDREN: | 3618 | case ScriptBaseClass.LINK_ALL_CHILDREN: |
3606 | case ScriptBaseClass.LINK_THIS: | 3619 | case ScriptBaseClass.LINK_THIS: |
3607 | foreach (SceneObjectPart part in parentPrim.Children.Values) | 3620 | lock (parentPrim.Children) |
3608 | { | 3621 | { |
3609 | if (part.UUID != m_host.UUID) | 3622 | foreach (SceneObjectPart part in parentPrim.Children.Values) |
3610 | { | 3623 | { |
3611 | childPrim = part; | 3624 | if (part.UUID != m_host.UUID) |
3612 | break; | 3625 | { |
3626 | childPrim = part; | ||
3627 | break; | ||
3628 | } | ||
3613 | } | 3629 | } |
3630 | break; | ||
3614 | } | 3631 | } |
3615 | break; | ||
3616 | default: | 3632 | default: |
3617 | childPrim = parentPrim.GetLinkNumPart(linknum); | 3633 | childPrim = parentPrim.GetLinkNumPart(linknum); |
3618 | if (childPrim.UUID == m_host.UUID) | 3634 | if (childPrim.UUID == m_host.UUID) |
@@ -3623,27 +3639,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3623 | if (linknum == ScriptBaseClass.LINK_ROOT) | 3639 | if (linknum == ScriptBaseClass.LINK_ROOT) |
3624 | { | 3640 | { |
3625 | // Restructuring Multiple Prims. | 3641 | // Restructuring Multiple Prims. |
3626 | List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values); | 3642 | lock (parentPrim.Children) |
3627 | parts.Remove(parentPrim.RootPart); | ||
3628 | foreach (SceneObjectPart part in parts) | ||
3629 | { | ||
3630 | parentPrim.DelinkFromGroup(part.LocalId, true); | ||
3631 | } | ||
3632 | parentPrim.HasGroupChanged = true; | ||
3633 | parentPrim.ScheduleGroupForFullUpdate(); | ||
3634 | parentPrim.TriggerScriptChangedEvent(Changed.LINK); | ||
3635 | |||
3636 | if (parts.Count > 0) | ||
3637 | { | 3643 | { |
3638 | SceneObjectPart newRoot = parts[0]; | 3644 | List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values); |
3639 | parts.Remove(newRoot); | 3645 | parts.Remove(parentPrim.RootPart); |
3640 | foreach (SceneObjectPart part in parts) | 3646 | foreach (SceneObjectPart part in parts) |
3641 | { | 3647 | { |
3642 | part.UpdateFlag = 0; | 3648 | parentPrim.DelinkFromGroup(part.LocalId, true); |
3643 | newRoot.ParentGroup.LinkToGroup(part.ParentGroup); | 3649 | } |
3650 | parentPrim.HasGroupChanged = true; | ||
3651 | parentPrim.ScheduleGroupForFullUpdate(); | ||
3652 | parentPrim.TriggerScriptChangedEvent(Changed.LINK); | ||
3653 | |||
3654 | if (parts.Count > 0) | ||
3655 | { | ||
3656 | SceneObjectPart newRoot = parts[0]; | ||
3657 | parts.Remove(newRoot); | ||
3658 | foreach (SceneObjectPart part in parts) | ||
3659 | { | ||
3660 | part.UpdateFlag = 0; | ||
3661 | newRoot.ParentGroup.LinkToGroup(part.ParentGroup); | ||
3662 | } | ||
3663 | newRoot.ParentGroup.HasGroupChanged = true; | ||
3664 | newRoot.ParentGroup.ScheduleGroupForFullUpdate(); | ||
3644 | } | 3665 | } |
3645 | newRoot.ParentGroup.HasGroupChanged = true; | ||
3646 | newRoot.ParentGroup.ScheduleGroupForFullUpdate(); | ||
3647 | } | 3666 | } |
3648 | } | 3667 | } |
3649 | else | 3668 | else |
@@ -3665,16 +3684,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3665 | if (parentPrim.RootPart.AttachmentPoint != 0) | 3684 | if (parentPrim.RootPart.AttachmentPoint != 0) |
3666 | return; // Fail silently if attached | 3685 | return; // Fail silently if attached |
3667 | 3686 | ||
3668 | List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values); | 3687 | lock (parentPrim.Children) |
3669 | parts.Remove(parentPrim.RootPart); | ||
3670 | |||
3671 | foreach (SceneObjectPart part in parts) | ||
3672 | { | 3688 | { |
3673 | parentPrim.DelinkFromGroup(part.LocalId, true); | 3689 | List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values); |
3674 | parentPrim.TriggerScriptChangedEvent(Changed.LINK); | 3690 | parts.Remove(parentPrim.RootPart); |
3691 | |||
3692 | foreach (SceneObjectPart part in parts) | ||
3693 | { | ||
3694 | parentPrim.DelinkFromGroup(part.LocalId, true); | ||
3695 | parentPrim.TriggerScriptChangedEvent(Changed.LINK); | ||
3696 | } | ||
3697 | parentPrim.HasGroupChanged = true; | ||
3698 | parentPrim.ScheduleGroupForFullUpdate(); | ||
3675 | } | 3699 | } |
3676 | parentPrim.HasGroupChanged = true; | ||
3677 | parentPrim.ScheduleGroupForFullUpdate(); | ||
3678 | } | 3700 | } |
3679 | 3701 | ||
3680 | public LSL_String llGetLinkKey(int linknum) | 3702 | public LSL_String llGetLinkKey(int linknum) |
@@ -4200,7 +4222,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4200 | { | 4222 | { |
4201 | partItemID = item.ItemID; | 4223 | partItemID = item.ItemID; |
4202 | int linkNumber = m_host.LinkNum; | 4224 | int linkNumber = m_host.LinkNum; |
4203 | if (m_host.ParentGroup.Children.Count == 1) | 4225 | if (m_host.ParentGroup.PrimCount == 1) |
4204 | linkNumber = 0; | 4226 | linkNumber = 0; |
4205 | 4227 | ||
4206 | object[] resobj = new object[] | 4228 | object[] resobj = new object[] |