Changeset 521 in Corrade


Ignore:
Timestamp:
Apr 20, 2017, 11:37:25 PM (6 months ago)
Author:
office
Message:
  • Use slim locks for all operations.
  • Add places result constant.
Location:
wasOpenMetaverse
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • wasOpenMetaverse/Caches/AgentCache.cs

    r487 r521  
    99using OpenMetaverse;
    1010using wasSharp.Collections.Specialized;
     11using wasSharp.Collections.Generic;
    1112
    1213namespace wasOpenMetaverse.Caches
     
    1415    public class AgentCache : ObservableHashSet<Cache.Agent>
    1516    {
    16         public Dictionary<UUID, Cache.Agent> nameCache = new Dictionary<UUID, Cache.Agent>();
     17        public SerializableDictionary<UUID, Cache.Agent> nameCache = new SerializableDictionary<UUID, Cache.Agent>();
    1718
    1819        public MultiKeyDictionary<string, string, Cache.Agent> nameHandleCache =
     
    3233        }
    3334
    34         public Cache.Agent this[UUID UUID]
     35        public Cache.Agent this[UUID @UUID]
    3536        {
    3637            get
    3738            {
    3839                Cache.Agent agent;
    39                 nameCache.TryGetValue(UUID, out agent);
     40                nameCache.TryGetValue(@UUID, out agent);
    4041                return agent;
    4142            }
    4243        }
    4344
    44         public Cache.Agent this[string firstname, string lastname, UUID UUID]
     45        public Cache.Agent this[string firstname, string lastname, UUID @UUID]
    4546        {
    4647            get
    4748            {
    4849                Cache.Agent agent;
    49                 nameUUIDHandleCache.TryGetValue(firstname, lastname, UUID, out agent);
     50                nameUUIDHandleCache.TryGetValue(firstname, lastname, @UUID, out agent);
    5051                return agent;
    5152            }
     
    103104            enumerable.Except(AsEnumerable()).AsParallel().ForAll(agent =>
    104105            {
    105                 nameCache.Remove(agent.UUID);
    106                 nameHandleCache.Remove(agent.FirstName, agent.LastName);
    107                 nameUUIDHandleCache.Remove(agent.FirstName, agent.LastName, agent.UUID);
     106                if (nameCache.ContainsKey(agent.UUID))
     107                    nameCache.Remove(agent.UUID);
     108                nameCache.Add(agent.UUID, agent);
     109
     110                if (nameHandleCache.ContainsKey(agent.FirstName, agent.LastName))
     111                    nameHandleCache.Remove(agent.FirstName, agent.LastName);
     112                nameHandleCache.Add(agent.FirstName, agent.LastName, agent);
     113
     114                if (nameUUIDHandleCache.ContainsKey(agent.FirstName, agent.LastName, agent.UUID))
     115                    nameUUIDHandleCache.Remove(agent.FirstName, agent.LastName, agent.UUID);
     116
     117                nameUUIDHandleCache.Add(agent.FirstName, agent.LastName, agent.UUID, agent);
    108118            });
    109119
     
    116126        }
    117127
    118         public bool Contains(UUID UUID)
     128        public bool Contains(UUID @UUID)
    119129        {
    120             return nameCache.ContainsKey(UUID);
     130            return nameCache.ContainsKey(@UUID);
    121131        }
    122132    }
  • wasOpenMetaverse/Caches/GroupCache.cs

    r518 r521  
    100100            enumerable.Except(AsEnumerable()).AsParallel().ForAll(group =>
    101101            {
    102                 nameCache.Remove(group.UUID);
    103                 nameUUIDHandleCache.Remove(group.Name, group.UUID);
    104                 groupCache.Remove(group.Name);
     102                if (nameCache.ContainsKey(group.UUID))
     103                    nameCache.Remove(group.UUID);
     104                nameCache.Add(group.UUID, group);
     105                if (nameUUIDHandleCache.ContainsKey(group.Name, group.UUID))
     106                    nameUUIDHandleCache.Remove(group.Name, group.UUID);
     107                nameUUIDHandleCache.Add(group.Name, group.UUID, group);
     108                if (groupCache.ContainsKey(group.Name))
     109                    groupCache.Remove(group.Name);
     110                groupCache.Add(group.Name, group);
    105111            });
    106112
  • wasOpenMetaverse/Caches/RegionCache.cs

    r487 r521  
    138138            enumerable.Except(AsEnumerable()).AsParallel().ForAll(region =>
    139139            {
    140                 nameCache.Remove(region.Name);
    141                 handleCache.Remove(region.Handle);
    142                 UUIDCache.Remove(region.UUID);
    143                 nameHandleCache.Remove(region.Name);
    144                 UUIDHandleCache.Remove(region.UUID);
     140                if (nameCache.ContainsKey(region.Name))
     141                    nameCache.Remove(region.Name);
     142                nameCache.Add(region.Name, region);
     143
     144                if (handleCache.ContainsKey(region.Handle))
     145                    handleCache.Remove(region.Handle);
     146                handleCache.Add(region.Handle, region);
     147
     148                if (UUIDCache.ContainsKey(region.UUID))
     149                    UUIDCache.Remove(region.UUID);
     150                UUIDCache.Add(region.UUID, region);
     151
     152                if (nameHandleCache.ContainsKey(region.Name, region.Handle))
     153                    nameHandleCache.Remove(region.Name, region.Handle);
     154                nameHandleCache.Add(region.Name, region.Handle, region);
     155
     156                if (UUIDHandleCache.ContainsKey(region.UUID, region.Handle))
     157                    UUIDHandleCache.Remove(region.UUID, region.Handle);
     158                UUIDHandleCache.Add(region.UUID, region.Handle, region);
    145159            });
    146160
  • wasOpenMetaverse/Constants.cs

    r518 r521  
    105105                public const uint SEARCH_RESULTS_COUNT = 100;
    106106            }
     107
     108            public struct PLACES
     109            {
     110                public const uint SEARCH_RESULTS_COUNT = 100;
     111            }
    107112        }
    108113
  • wasOpenMetaverse/Inventory.cs

    r519 r521  
    7272            if (!(realItem is InventoryAttachment) && !(realItem is InventoryObject)) return;
    7373            var attachmentPoint = AttachmentPoint.Default;
    74             lock (Locks.ClientInstanceAppearanceLock)
    75             {
    76                 var objectAttachedEvent = new ManualResetEvent(false);
    77                 EventHandler<PrimEventArgs> ObjectUpdateEventHandler = (sender, args) =>
    78                 {
    79                     Primitive prim;
    80                     lock (Locks.ClientInstanceNetworkLock)
    81                     {
    82                         if (
    83                             !Client.Network.CurrentSim.ObjectsPrimitives.TryGetValue(args.Prim.LocalID,
    84                                 out prim))
    85                             return;
    86                     }
    87 
    88                     if (Client.Self.LocalID.Equals(0) || prim.NameValues == null)
    89                         return;
    90 
    91                     if (!prim.NameValues.AsParallel()
    92                         .Where(o => string.Equals(o.Name, "AttachItemID"))
    93                         .Any(o => string.Equals(o.Value.ToString().Trim(), realItem.UUID.ToString(),
    94                             StringComparison.OrdinalIgnoreCase))) return;
    95 
    96                     attachmentPoint = (AttachmentPoint)(((prim.PrimData.State & 0xF0) >> 4) |
    97                                                          ((prim.PrimData.State & ~0xF0) << 4));
    98 
    99                     objectAttachedEvent.Set();
    100                 };
    101 
    102                 lock (Locks.ClientInstanceObjectsLock)
    103                 {
    104                     Client.Objects.ObjectUpdate += ObjectUpdateEventHandler;
    105                     Client.Appearance.Attach(realItem, point, replace);
    106                     objectAttachedEvent.WaitOne((int)millisecondsTimeout, false);
    107                     Client.Objects.ObjectUpdate -= ObjectUpdateEventHandler;
    108                 }
    109             }
     74            Locks.ClientInstanceAppearanceLock.EnterWriteLock();
     75            var objectAttachedEvent = new ManualResetEvent(false);
     76            EventHandler<PrimEventArgs> ObjectUpdateEventHandler = (sender, args) =>
     77            {
     78                Primitive prim;
     79                Locks.ClientInstanceNetworkLock.EnterReadLock();
     80                if (!Client.Network.CurrentSim.ObjectsPrimitives.TryGetValue(args.Prim.LocalID, out prim))
     81                {
     82                    Locks.ClientInstanceNetworkLock.ExitReadLock();
     83                    return;
     84                }
     85                Locks.ClientInstanceNetworkLock.ExitReadLock();
     86
     87                if (Client.Self.LocalID.Equals(0) || prim.NameValues == null)
     88                    return;
     89
     90                if (!prim.NameValues.AsParallel()
     91                    .Where(o => string.Equals(o.Name, "AttachItemID"))
     92                    .Any(o => string.Equals(o.Value.ToString().Trim(), realItem.UUID.ToString(),
     93                        StringComparison.OrdinalIgnoreCase))) return;
     94
     95                attachmentPoint = (AttachmentPoint)(((prim.PrimData.State & 0xF0) >> 4) |
     96                                                     ((prim.PrimData.State & ~0xF0) << 4));
     97
     98                objectAttachedEvent.Set();
     99            };
     100
     101            Locks.ClientInstanceObjectsLock.EnterWriteLock();
     102            Client.Objects.ObjectUpdate += ObjectUpdateEventHandler;
     103            Client.Appearance.Attach(realItem, point, replace);
     104            objectAttachedEvent.WaitOne((int)millisecondsTimeout, false);
     105            Client.Objects.ObjectUpdate -= ObjectUpdateEventHandler;
     106            Locks.ClientInstanceObjectsLock.ExitWriteLock();
     107            Locks.ClientInstanceAppearanceLock.ExitWriteLock();
    110108            if (realItem is InventoryAttachment)
    111109            {
     
    128126            RemoveLink(Client, realItem, CurrentOutfitFolder, millisecondsTimeout);
    129127            var attachmentPoint = AttachmentPoint.Default;
    130             lock (Locks.ClientInstanceAppearanceLock)
    131             {
    132                 var objectDetachedEvent = new ManualResetEvent(false);
    133                 EventHandler<KillObjectEventArgs> KillObjectEventHandler = (sender, args) =>
    134                 {
    135                     Primitive prim;
    136                     lock (Locks.ClientInstanceNetworkLock)
    137                     {
    138                         if (
    139                             !Client.Network.CurrentSim.ObjectsPrimitives.TryGetValue(args.ObjectLocalID,
    140                                 out prim))
    141                             return;
    142                     }
    143 
    144                     if (Client.Self.LocalID.Equals(0) || prim.NameValues == null)
    145                         return;
    146 
    147                     if (!prim.NameValues.AsParallel()
    148                         .Where(o => string.Equals(o.Name, "AttachItemID"))
    149                         .Any(o => string.Equals(o.Value.ToString().Trim(), realItem.UUID.ToString(),
    150                             StringComparison.OrdinalIgnoreCase))) return;
    151 
    152                     attachmentPoint = (AttachmentPoint)(((prim.PrimData.State & 0xF0) >> 4) |
    153                                                          ((prim.PrimData.State & ~0xF0) << 4));
    154 
    155                     objectDetachedEvent.Set();
    156                 };
    157 
    158                 lock (Locks.ClientInstanceObjectsLock)
    159                 {
    160                     Client.Objects.KillObject += KillObjectEventHandler;
    161                     Client.Appearance.Detach(realItem);
    162                     objectDetachedEvent.WaitOne((int)millisecondsTimeout, false);
    163                     Client.Objects.KillObject -= KillObjectEventHandler;
    164                 }
    165             }
     128            Locks.ClientInstanceAppearanceLock.EnterWriteLock();
     129            var objectDetachedEvent = new ManualResetEvent(false);
     130            EventHandler<KillObjectEventArgs> KillObjectEventHandler = (sender, args) =>
     131            {
     132                Primitive prim;
     133                Locks.ClientInstanceNetworkLock.EnterReadLock();
     134                if (!Client.Network.CurrentSim.ObjectsPrimitives.TryGetValue(args.ObjectLocalID, out prim))
     135                {
     136                    Locks.ClientInstanceNetworkLock.ExitReadLock();
     137                    return;
     138                }
     139                Locks.ClientInstanceNetworkLock.ExitReadLock();
     140
     141                if (Client.Self.LocalID.Equals(0) || prim.NameValues == null)
     142                    return;
     143
     144                if (!prim.NameValues.AsParallel()
     145                    .Where(o => string.Equals(o.Name, "AttachItemID"))
     146                    .Any(o => string.Equals(o.Value.ToString().Trim(), realItem.UUID.ToString(),
     147                        StringComparison.OrdinalIgnoreCase))) return;
     148
     149                attachmentPoint = (AttachmentPoint)(((prim.PrimData.State & 0xF0) >> 4) |
     150                                                     ((prim.PrimData.State & ~0xF0) << 4));
     151
     152                objectDetachedEvent.Set();
     153            };
     154
     155            Locks.ClientInstanceObjectsLock.EnterWriteLock();
     156            Client.Objects.KillObject += KillObjectEventHandler;
     157            Client.Appearance.Detach(realItem);
     158            objectDetachedEvent.WaitOne((int)millisecondsTimeout, false);
     159            Client.Objects.KillObject -= KillObjectEventHandler;
     160            Locks.ClientInstanceObjectsLock.ExitWriteLock();
     161            Locks.ClientInstanceAppearanceLock.ExitWriteLock();
    166162            if (realItem is InventoryAttachment)
    167163            {
     
    181177            var realItem = ResolveItemLink(Client, item);
    182178            if (!(realItem is InventoryWearable)) return;
    183             lock (Locks.ClientInstanceAppearanceLock)
    184             {
    185                 Client.Appearance.AddToOutfit(realItem, replace);
    186             }
     179            Locks.ClientInstanceAppearanceLock.EnterWriteLock();
     180            Client.Appearance.AddToOutfit(realItem, replace);
     181            Locks.ClientInstanceAppearanceLock.ExitWriteLock();
    187182            AddLink(Client, realItem, CurrentOutfitFolder, millisecondsTimeout);
    188183            UpdateInventoryRecursive(Client, CurrentOutfitFolder, millisecondsTimeout, true);
     
    194189            var realItem = ResolveItemLink(Client, item);
    195190            if (!(realItem is InventoryWearable)) return;
    196             lock (Locks.ClientInstanceAppearanceLock)
    197             {
    198                 Client.Appearance.RemoveFromOutfit(realItem);
    199             }
     191            Locks.ClientInstanceAppearanceLock.EnterWriteLock();
     192            Client.Appearance.RemoveFromOutfit(realItem);
     193            Locks.ClientInstanceAppearanceLock.ExitWriteLock();
    200194            RemoveLink(Client, realItem, CurrentOutfitFolder, millisecondsTimeout);
    201195            UpdateInventoryRecursive(Client, CurrentOutfitFolder, millisecondsTimeout, true);
     
    289283            uint dataTimeout)
    290284        {
    291             var selectedPrimitives = new HashSet<Primitive>();
    292             lock (Locks.ClientInstanceNetworkLock)
    293             {
    294                 selectedPrimitives.UnionWith(Client.Network.Simulators.AsParallel()
     285            Locks.ClientInstanceNetworkLock.EnterReadLock();
     286            var selectedPrimitives = new HashSet<Primitive>(Client.Network.Simulators.AsParallel()
    295287                    .Select(o => o.ObjectsPrimitives)
    296288                    .Select(o => o.Copy().Values)
    297289                    .SelectMany(o => o)
    298290                    .Where(o => o.ParentID.Equals(Client.Self.LocalID)));
    299             }
     291            Locks.ClientInstanceNetworkLock.ExitReadLock();
    300292
    301293            if (!selectedPrimitives.Any() || !Services.UpdatePrimitives(Client, ref selectedPrimitives, dataTimeout))
     
    824816            uint millisecondsTimeout, bool force = false)
    825817        {
    826             lock (Locks.ClientInstanceNetworkLock)
    827             {
    828                 // Wait for CAPs.
    829                 if (!Client.Network.CurrentSim.Caps.IsEventQueueRunning)
    830                 {
    831                     var EventQueueRunningEvent = new AutoResetEvent(false);
    832                     EventHandler<EventQueueRunningEventArgs> handler = (sender, e) => { EventQueueRunningEvent.Set(); };
    833                     Client.Network.EventQueueRunning += handler;
    834                     EventQueueRunningEvent.WaitOne((int)millisecondsTimeout, false);
    835                     Client.Network.EventQueueRunning -= handler;
    836                 }
    837             }
    838 
    839             Locks.ClientInstanceInventoryLock.EnterReadLock();
     818            Locks.ClientInstanceNetworkLock.EnterReadLock();
     819            // Wait for CAPs.
     820            if (!Client.Network.CurrentSim.Caps.IsEventQueueRunning)
     821            {
     822                var EventQueueRunningEvent = new AutoResetEvent(false);
     823                EventHandler<EventQueueRunningEventArgs> handler = (sender, e) => { EventQueueRunningEvent.Set(); };
     824                Client.Network.EventQueueRunning += handler;
     825                EventQueueRunningEvent.WaitOne((int)millisecondsTimeout, false);
     826                Client.Network.EventQueueRunning -= handler;
     827            }
     828            Locks.ClientInstanceNetworkLock.ExitReadLock();
     829
     830            Locks.ClientInstanceInventoryLock.EnterWriteLock();
    840831            directUpdateInventoryRecursive(Client, Client.Inventory.Store.GetNodeFor(root.UUID), millisecondsTimeout,
    841832                    force);
    842             Locks.ClientInstanceInventoryLock.ExitReadLock();
     833            Locks.ClientInstanceInventoryLock.ExitWriteLock();
    843834        }
    844835
     
    856847            uint millisecondsTimeout, bool force = false)
    857848        {
    858             lock (Locks.ClientInstanceNetworkLock)
    859             {
    860                 // Wait for CAPs.
    861                 if (!Client.Network.CurrentSim.Caps.IsEventQueueRunning)
    862                 {
    863                     var EventQueueRunningEvent = new AutoResetEvent(false);
    864                     EventHandler<EventQueueRunningEventArgs> handler = (sender, e) => { EventQueueRunningEvent.Set(); };
    865                     Client.Network.EventQueueRunning += handler;
    866                     EventQueueRunningEvent.WaitOne((int)millisecondsTimeout, false);
    867                     Client.Network.EventQueueRunning -= handler;
    868                 }
    869             }
    870 
    871             Locks.ClientInstanceInventoryLock.EnterReadLock();
     849            Locks.ClientInstanceNetworkLock.EnterReadLock();
     850            // Wait for CAPs.
     851            if (!Client.Network.CurrentSim.Caps.IsEventQueueRunning)
     852            {
     853                var EventQueueRunningEvent = new AutoResetEvent(false);
     854                EventHandler<EventQueueRunningEventArgs> handler = (sender, e) => { EventQueueRunningEvent.Set(); };
     855                Client.Network.EventQueueRunning += handler;
     856                EventQueueRunningEvent.WaitOne((int)millisecondsTimeout, false);
     857                Client.Network.EventQueueRunning -= handler;
     858            }
     859            Locks.ClientInstanceNetworkLock.ExitReadLock();
     860
     861            Locks.ClientInstanceInventoryLock.EnterWriteLock();
    872862            directUpdateInventoryRecursive(Client, root, millisecondsTimeout, force);
    873             Locks.ClientInstanceInventoryLock.ExitReadLock();
     863            Locks.ClientInstanceInventoryLock.ExitWriteLock();
    874864        }
    875865
  • wasOpenMetaverse/Locks.cs

    r519 r521  
    1313        public static readonly ReaderWriterLockSlim ClientInstanceGroupsLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
    1414        public static readonly ReaderWriterLockSlim ClientInstanceInventoryLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
    15 
    16         //public static readonly object ClientInstanceInventoryLock = new object();
    17         public static readonly object ClientInstanceAvatarsLock = new object();
    18 
    19         public static readonly object ClientInstanceSelfLock = new object();
    20         public static readonly object ClientInstanceConfigurationLock = new object();
    21         public static readonly object ClientInstanceParcelsLock = new object();
    22         public static readonly object ClientInstanceNetworkLock = new object();
    23         public static readonly object ClientInstanceGridLock = new object();
    24         public static readonly object ClientInstanceDirectoryLock = new object();
    25         public static readonly object ClientInstanceEstateLock = new object();
    26         public static readonly object ClientInstanceObjectsLock = new object();
    27         public static readonly object ClientInstanceFriendsLock = new object();
    28         public static readonly object ClientInstanceAssetsLock = new object();
    29         public static readonly object ClientInstanceAppearanceLock = new object();
    30         public static readonly object ClientInstanceSoundLock = new object();
     15        public static readonly ReaderWriterLockSlim ClientInstanceAvatarsLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
     16        public static readonly ReaderWriterLockSlim ClientInstanceSelfLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
     17        public static readonly ReaderWriterLockSlim ClientInstanceConfigurationLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
     18        public static readonly ReaderWriterLockSlim ClientInstanceParcelsLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
     19        public static readonly ReaderWriterLockSlim ClientInstanceNetworkLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
     20        public static readonly ReaderWriterLockSlim ClientInstanceGridLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
     21        public static readonly ReaderWriterLockSlim ClientInstanceDirectoryLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
     22        public static readonly ReaderWriterLockSlim ClientInstanceEstateLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
     23        public static readonly ReaderWriterLockSlim ClientInstanceObjectsLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
     24        public static readonly ReaderWriterLockSlim ClientInstanceFriendsLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
     25        public static readonly ReaderWriterLockSlim ClientInstanceAssetsLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
     26        public static readonly ReaderWriterLockSlim ClientInstanceAppearanceLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
     27        public static readonly ReaderWriterLockSlim ClientInstanceSoundLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
    3128    }
    3229}
  • wasOpenMetaverse/Mesh.cs

    r487 r521  
    4646                {
    4747                    case true:
    48                         lock (Locks.ClientInstanceAssetsLock)
     48                        Locks.ClientInstanceAssetsLock.EnterReadLock();
     49                        var ImageDownloadedEvent = new ManualResetEvent(false);
     50                        Client.Assets.RequestImage(primitive.Sculpt.SculptTexture, (state, args) =>
    4951                        {
    50                             var ImageDownloadedEvent = new ManualResetEvent(false);
    51                             Client.Assets.RequestImage(primitive.Sculpt.SculptTexture, (state, args) =>
    52                             {
    53                                 if (!state.Equals(TextureRequestState.Finished)) return;
    54                                 assetData = args.AssetData;
    55                                 ImageDownloadedEvent.Set();
    56                             });
    57                             if (!ImageDownloadedEvent.WaitOne((int) millisecondsTimeout, false))
    58                                 return false;
     52                            if (!state.Equals(TextureRequestState.Finished)) return;
     53                            assetData = args.AssetData;
     54                            ImageDownloadedEvent.Set();
     55                        });
     56                        if (!ImageDownloadedEvent.WaitOne((int)millisecondsTimeout, false))
     57                        {
     58                            Locks.ClientInstanceAssetsLock.ExitReadLock();
     59                            return false;
    5960                        }
     61                        Locks.ClientInstanceAssetsLock.ExitReadLock();
    6062                        Client.Assets.Cache.SaveAssetToCache(primitive.Sculpt.SculptTexture, assetData);
    6163                        break;
     64
    6265                    default:
    6366                        assetData = Client.Assets.Cache.GetCachedAssetBytes(primitive.Sculpt.SculptTexture);
     
    7073                    case true:
    7174                        return false;
     75
    7276                    default:
    7377                        if ((managedImage.Channels & ManagedImage.ImageChannels.Alpha) != 0)
     
    7882                        break;
    7983                }
    80                 facetedMesh = mesher.GenerateFacetedSculptMesh(primitive, (Bitmap) image, DetailLevel.Highest);
     84                facetedMesh = mesher.GenerateFacetedSculptMesh(primitive, (Bitmap)image, DetailLevel.Highest);
    8185                return true;
    8286            }
    8387            FacetedMesh localFacetedMesh = null;
    8488            var MeshDownloadedEvent = new ManualResetEvent(false);
    85             lock (Locks.ClientInstanceAssetsLock)
    86             {
    87                 Client.Assets.RequestMesh(primitive.Sculpt.SculptTexture, (success, meshAsset) =>
     89            Locks.ClientInstanceAssetsLock.EnterReadLock();
     90            Client.Assets.RequestMesh(primitive.Sculpt.SculptTexture, (success, meshAsset) =>
    8891                {
    8992                    FacetedMesh.TryDecodeFromAsset(primitive, meshAsset, DetailLevel.Highest, out localFacetedMesh);
     
    9194                });
    9295
    93                 if (!MeshDownloadedEvent.WaitOne((int) millisecondsTimeout, false))
    94                     return false;
    95             }
     96            if (!MeshDownloadedEvent.WaitOne((int)millisecondsTimeout, false))
     97            {
     98                Locks.ClientInstanceAssetsLock.ExitReadLock();
     99                return false;
     100            }
     101            Locks.ClientInstanceAssetsLock.ExitReadLock();
    96102
    97103            switch (localFacetedMesh != null)
     
    100106                    facetedMesh = localFacetedMesh;
    101107                    return true;
     108
    102109                default:
    103110                    return false;
     
    184191                acc.Attributes.Append(Doc.CreateAttribute("source")).InnerText = string.Format("#{0}-{1}", src_id,
    185192                    "array");
    186                 acc.Attributes.Append(Doc.CreateAttribute("count")).InnerText = (vals.Count/param.Length).ToString();
     193                acc.Attributes.Append(Doc.CreateAttribute("count")).InnerText = (vals.Count / param.Length).ToString();
    187194                acc.Attributes.Append(Doc.CreateAttribute("stride")).InnerText = param.Length.ToString();
    188195
     
    284291                                pBuilder.Append(index);
    285292                                pBuilder.Append(" ");
    286                                 if (i%3 == 0)
     293                                if (i % 3 == 0)
    287294                                {
    288295                                    vcountBuilder.Append("3 ");
     
    319326
    320327                // Transpose the quaternion (don't ask me why)
    321                 q.X = q.X*-1f;
    322                 q.Y = q.Y*-1f;
    323                 q.Z = q.Z*-1f;
     328                q.X = q.X * -1f;
     329                q.Y = q.Y * -1f;
     330                q.Z = q.Z * -1f;
    324331
    325332                var x2 = q.X + q.X;
    326333                var y2 = q.Y + q.Y;
    327334                var z2 = q.Z + q.Z;
    328                 var xx = q.X*x2;
    329                 var xy = q.X*y2;
    330                 var xz = q.X*z2;
    331                 var yy = q.Y*y2;
    332                 var yz = q.Y*z2;
    333                 var zz = q.Z*z2;
    334                 var wx = q.W*x2;
    335                 var wy = q.W*y2;
    336                 var wz = q.W*z2;
    337 
    338                 mat[0] = (1.0f - (yy + zz))*scale.X;
    339                 mat[1] = (xy - wz)*scale.X;
    340                 mat[2] = (xz + wy)*scale.X;
     335                var xx = q.X * x2;
     336                var xy = q.X * y2;
     337                var xz = q.X * z2;
     338                var yy = q.Y * y2;
     339                var yz = q.Y * z2;
     340                var zz = q.Z * z2;
     341                var wx = q.W * x2;
     342                var wy = q.W * y2;
     343                var wz = q.W * z2;
     344
     345                mat[0] = (1.0f - (yy + zz)) * scale.X;
     346                mat[1] = (xy - wz) * scale.X;
     347                mat[2] = (xz + wy) * scale.X;
    341348                mat[3] = 0.0f;
    342349
    343                 mat[4] = (xy + wz)*scale.Y;
    344                 mat[5] = (1.0f - (xx + zz))*scale.Y;
    345                 mat[6] = (yz - wx)*scale.Y;
     350                mat[4] = (xy + wz) * scale.Y;
     351                mat[5] = (1.0f - (xx + zz)) * scale.Y;
     352                mat[6] = (yz - wx) * scale.Y;
    346353                mat[7] = 0.0f;
    347354
    348                 mat[8] = (xz - wy)*scale.Z;
    349                 mat[9] = (yz + wx)*scale.Z;
    350                 mat[10] = (1.0f - (xx + yy))*scale.Z;
     355                mat[8] = (xz - wy) * scale.Z;
     356                mat[9] = (yz + wx) * scale.Z;
     357                mat[10] = (1.0f - (xx + yy)) * scale.Z;
    351358                mat[11] = 0.0f;
    352359
     
    495502                    for (var j = 0; j < 4; j++)
    496503                    {
    497                         matrixVal += srt[j*4 + i].ToString(Utils.EnUsCulture) + " ";
     504                        matrixVal += srt[j * 4 + i].ToString(Utils.EnUsCulture) + " ";
    498505                    }
    499506                }
  • wasOpenMetaverse/Properties/AssemblyInfo.cs

    r518 r521  
    2727// [assembly: AssemblyVersion("1.0.*")]
    2828
    29 [assembly: AssemblyVersion("1.27.*")]
     29[assembly: AssemblyVersion("1.28.*")]
  • wasOpenMetaverse/Reflection.cs

    r516 r521  
    392392
    393393                // OpenMetaverse particular flags.
     394
     395                // LL permissions.
     396                if (data is Permissions)
     397                    wasSharpNET.Reflection.wasSetInfoValue(info, ref structure, Inventory.wasStringToPermissions(d.Value));
     398
    394399                if (data is ParcelFlags)
    395400                {
  • wasOpenMetaverse/Resolvers.cs

    r519 r521  
    3737                return false;
    3838            var groupUUID = UUID.Zero;
     39            var requestUUID = UUID.Zero;
    3940            EventHandler<DirGroupsReplyEventArgs> DirGroupsReplyDelegate = (sender, args) =>
    4041            {
     42                if (!args.QueryID.Equals(requestUUID))
     43                    return;
     44
    4145                alarm.Alarm(dataTimeout);
    4246                var groupSearchData =
    4347                    args.MatchedGroups.AsParallel()
    4448                        .FirstOrDefault(o => o.GroupName.Equals(GroupName, StringComparison.OrdinalIgnoreCase));
    45                 switch (!groupSearchData.Equals(default(DirectoryManager.GroupSearchData)))
     49                if (!groupSearchData.Equals(default(DirectoryManager.GroupSearchData)))
    4650                {
    47                     case true:
    48                         groupUUID = groupSearchData.GroupID;
    49                         alarm.Signal.Set();
    50                         break;
     51                    groupUUID = groupSearchData.GroupID;
     52                    alarm.Signal.Set();
    5153                }
    5254            };
    5355            Client.Directory.DirGroupsReply += DirGroupsReplyDelegate;
    54             Client.Directory.StartGroupSearch(GroupName, 0);
     56            requestUUID = Client.Directory.StartGroupSearch(GroupName, 0, DirectoryManager.DirFindFlags.Groups);
    5557            if (!alarm.Signal.WaitOne((int)millisecondsTimeout, false))
    5658            {
     
    8789                return true;
    8890            }
    89             bool succeeded;
    90             lock (Locks.ClientInstanceDirectoryLock)
    91             {
    92                 succeeded = directGroupNameToUUID(Client, GroupName, millisecondsTimeout, dataTimeout, alarm,
    93                     ref GroupUUID);
    94             }
     91            var succeeded = directGroupNameToUUID(Client, GroupName, millisecondsTimeout, dataTimeout, alarm,
     92                ref GroupUUID);
    9593            if (succeeded)
    9694            {
     
    124122                return false;
    125123            var agentUUID = UUID.Zero;
     124            var requestUUID = UUID.Zero;
    126125            EventHandler<DirPeopleReplyEventArgs> DirPeopleReplyDelegate = (sender, args) =>
    127126            {
     127                if (!args.QueryID.Equals(requestUUID))
     128                    return;
     129
    128130                alarm.Alarm(dataTimeout);
    129131                var agentSearchData =
     
    132134                            o.FirstName.Equals(FirstName, StringComparison.OrdinalIgnoreCase) &&
    133135                            o.LastName.Equals(LastName, StringComparison.OrdinalIgnoreCase));
    134                 switch (!agentSearchData.Equals(default(DirectoryManager.AgentSearchData)))
     136                if (!agentSearchData.Equals(default(DirectoryManager.AgentSearchData)))
    135137                {
    136                     case true:
    137                         agentUUID = agentSearchData.AgentID;
    138                         alarm.Signal.Set();
    139                         break;
     138                    agentUUID = agentSearchData.AgentID;
     139                    alarm.Signal.Set();
    140140                }
    141141            };
    142142            Client.Directory.DirPeopleReply += DirPeopleReplyDelegate;
    143             Client.Directory.StartPeopleSearch(
     143            requestUUID = Client.Directory.StartPeopleSearch(
    144144                string.Format(Utils.EnUsCulture, "{0} {1}", FirstName, LastName), 0);
    145145            if (!alarm.Signal.WaitOne((int)millisecondsTimeout, false))
     
    180180                return true;
    181181            }
    182             bool succeeded;
    183             lock (Locks.ClientInstanceDirectoryLock)
    184             {
    185                 succeeded = directAgentNameToUUID(Client, FirstName, LastName, millisecondsTimeout, dataTimeout, alarm,
     182            var succeeded = directAgentNameToUUID(Client, FirstName, LastName, millisecondsTimeout, dataTimeout, alarm,
    186183                    ref AgentUUID);
    187             }
    188184            if (succeeded)
    189185            {
     
    248244                return true;
    249245            }
     246            Locks.ClientInstanceGroupsLock.EnterWriteLock();
    250247            bool succeeded = directGroupUUIDToName(Client, GroupUUID, millisecondsTimeout, ref GroupName);
     248            Locks.ClientInstanceGroupsLock.ExitWriteLock();
    251249            if (succeeded)
    252250            {
     
    312310                return true;
    313311            }
    314             bool succeeded;
    315             lock (Locks.ClientInstanceAvatarsLock)
    316             {
    317                 succeeded = directAgentUUIDToName(Client, AgentUUID, millisecondsTimeout, ref AgentName);
    318             }
     312            Locks.ClientInstanceAvatarsLock.EnterWriteLock();
     313            var succeeded = directAgentUUIDToName(Client, AgentUUID, millisecondsTimeout, ref AgentName);
     314            Locks.ClientInstanceAvatarsLock.ExitWriteLock();
    319315            if (succeeded)
    320316            {
     
    483479                {
    484480                    ulong updateHandle = 0;
    485                     // Use fail locks.
    486                     var resolved = false;
    487                     if (Monitor.TryEnter(Locks.ClientInstanceGridLock, 1000))
    488                     {
    489                         try
    490                         {
    491                             resolved = directRegionNameToHandle(Client, name, millisecondsTimeout, ref updateHandle);
    492                         }
    493                         finally
    494                         {
    495                             Monitor.Exit(Locks.ClientInstanceGridLock);
    496                         }
    497                     }
     481                    Locks.ClientInstanceGridLock.EnterReadLock();
     482                    var resolved = directRegionNameToHandle(Client, name, millisecondsTimeout, ref updateHandle);
     483                    Locks.ClientInstanceGridLock.ExitReadLock();
    498484
    499485                    if (!resolved || region.Handle.Equals(updateHandle)) return;
     
    504490            }
    505491
    506             bool succeeded;
    507             lock (Locks.ClientInstanceGridLock)
    508             {
    509                 succeeded = directRegionNameToHandle(Client, name, millisecondsTimeout, ref regionHandle);
    510             }
     492            Locks.ClientInstanceGridLock.EnterReadLock();
     493            var succeeded = directRegionNameToHandle(Client, name, millisecondsTimeout, ref regionHandle);
     494            Locks.ClientInstanceGridLock.ExitReadLock();
    511495            if (succeeded)
    512496            {
     
    575559                {
    576560                    ulong updateHandle = 0;
    577                     // Use fail locks.
    578                     var resolved = false;
    579                     if (Monitor.TryEnter(Locks.ClientInstanceGridLock, 1000))
    580                     {
    581                         try
    582                         {
    583                             resolved = directRegionUUIDToHandle(Client, regionUUID, millisecondsTimeout,
    584                                 ref updateHandle);
    585                         }
    586                         finally
    587                         {
    588                             Monitor.Exit(Locks.ClientInstanceGridLock);
    589                         }
    590                     }
     561                    Locks.ClientInstanceGridLock.EnterReadLock();
     562                    var resolved = directRegionUUIDToHandle(Client, regionUUID, millisecondsTimeout,
     563                        ref updateHandle);
     564                    Locks.ClientInstanceGridLock.ExitReadLock();
    591565
    592566                    if (!resolved || region.Handle.Equals(updateHandle)) return;
     
    597571            }
    598572
    599             bool succeeded;
    600             lock (Locks.ClientInstanceGridLock)
    601             {
    602                 succeeded = directRegionUUIDToHandle(Client, regionUUID, millisecondsTimeout, ref regionHandle);
    603             }
     573            Locks.ClientInstanceGridLock.EnterReadLock();
     574            var succeeded = directRegionUUIDToHandle(Client, regionUUID, millisecondsTimeout, ref regionHandle);
     575            Locks.ClientInstanceGridLock.ExitReadLock();
    604576            if (succeeded)
    605577            {
  • wasOpenMetaverse/Services.cs

    r519 r521  
    1010using System.Threading;
    1111using OpenMetaverse;
    12 using wasSharp;
    1312using wasSharp.Timers;
    1413using Parallel = System.Threading.Tasks.Parallel;
     
    3332            EventHandler<MoneyBalanceReplyEventArgs> MoneyBalanceEventHandler =
    3433                (sender, args) => MoneyBalanceEvent.Set();
     34            Locks.ClientInstanceSelfLock.EnterReadLock();
    3535            Client.Self.MoneyBalanceReply += MoneyBalanceEventHandler;
    3636            Client.Self.RequestBalance();
    3737            if (!MoneyBalanceEvent.WaitOne((int)millisecondsTimeout, false))
    3838            {
     39                Locks.ClientInstanceSelfLock.ExitReadLock();
    3940                Client.Self.MoneyBalanceReply -= MoneyBalanceEventHandler;
    4041                return false;
    4142            }
    4243            Client.Self.MoneyBalanceReply -= MoneyBalanceEventHandler;
     44            Locks.ClientInstanceSelfLock.ExitReadLock();
    4345            return true;
    4446        }
     
    5961            EventHandler<EventArgs> MuteListUpdatedEventHandler =
    6062                (sender, args) => MuteListUpdatedEvent.Set();
    61             lock (Locks.ClientInstanceSelfLock)
    62             {
    63                 Client.Self.MuteListUpdated += MuteListUpdatedEventHandler;
    64                 Client.Self.RequestMuteList();
    65                 MuteListUpdatedEvent.WaitOne((int)millisecondsTimeout, false);
    66                 Client.Self.MuteListUpdated -= MuteListUpdatedEventHandler;
    67             }
     63
     64            Locks.ClientInstanceSelfLock.EnterReadLock();
     65            Client.Self.MuteListUpdated += MuteListUpdatedEventHandler;
     66            Client.Self.RequestMuteList();
     67            MuteListUpdatedEvent.WaitOne((int)millisecondsTimeout, false);
     68            Client.Self.MuteListUpdated -= MuteListUpdatedEventHandler;
     69            Locks.ClientInstanceSelfLock.ExitReadLock();
     70
    6871            mutes = Client.Self.MuteList.Copy().Values;
    6972
     
    8083        public static bool GetMutes(GridClient Client, uint millisecondsTimeout, ref IEnumerable<MuteEntry> mutes)
    8184        {
    82             bool succeeded;
    8385            if (Cache.MuteCache.Any())
    8486            {
     
    8789            }
    8890
    89             lock (Locks.ClientInstanceSelfLock)
    90             {
    91                 succeeded = directGetMutes(Client, millisecondsTimeout, ref mutes);
    92             }
     91            Locks.ClientInstanceSelfLock.EnterReadLock();
     92            var succeeded = directGetMutes(Client, millisecondsTimeout, ref mutes);
     93            Locks.ClientInstanceSelfLock.ExitReadLock();
    9394
    9495            if (succeeded)
     
    180181        public static bool GetCurrentGroups(GridClient Client, uint millisecondsTimeout, ref IEnumerable<UUID> groups)
    181182        {
    182             bool succeeded;
    183183            if (Cache.CurrentGroupsCache.Any())
    184184            {
     
    187187            }
    188188
    189             succeeded = directGetCurrentGroups(Client, millisecondsTimeout, ref groups);
     189            Locks.ClientInstanceGroupsLock.EnterReadLock();
     190            var succeeded = directGetCurrentGroups(Client, millisecondsTimeout, ref groups);
     191            Locks.ClientInstanceGroupsLock.ExitReadLock();
    190192
    191193            if (succeeded)
     
    224226                }
    225227            };
    226             lock (Locks.ClientInstanceAvatarsLock)
    227             {
    228                 Client.Avatars.AvatarGroupsReply += AvatarGroupsReplyEventHandler;
    229                 Client.Avatars.RequestAvatarProperties(agentUUID);
    230                 if (!alarm.Signal.WaitOne((int)millisecondsTimeout, false))
    231                 {
    232                     Client.Avatars.AvatarGroupsReply -= AvatarGroupsReplyEventHandler;
    233                     return false;
    234                 }
     228            Locks.ClientInstanceAvatarsLock.EnterReadLock();
     229            Client.Avatars.AvatarGroupsReply += AvatarGroupsReplyEventHandler;
     230            Client.Avatars.RequestAvatarProperties(agentUUID);
     231            if (!alarm.Signal.WaitOne((int)millisecondsTimeout, false))
     232            {
    235233                Client.Avatars.AvatarGroupsReply -= AvatarGroupsReplyEventHandler;
    236             }
     234                Locks.ClientInstanceAvatarsLock.ExitReadLock();
     235                return false;
     236            }
     237            Client.Avatars.AvatarGroupsReply -= AvatarGroupsReplyEventHandler;
     238            Locks.ClientInstanceAvatarsLock.ExitReadLock();
    237239            return
    238240                avatarGroups.AsParallel()
     
    260262                    GroupChatJoinedEvent.Set();
    261263                };
    262             lock (Locks.ClientInstanceSelfLock)
    263             {
    264                 Client.Self.GroupChatJoined += GroupChatJoinedEventHandler;
    265                 Client.Self.RequestJoinGroupChat(groupUUID);
    266                 if (!GroupChatJoinedEvent.WaitOne((int)millisecondsTimeout, false))
    267                 {
    268                     Client.Self.GroupChatJoined -= GroupChatJoinedEventHandler;
    269                     return false;
    270                 }
     264            Locks.ClientInstanceSelfLock.EnterWriteLock();
     265            Client.Self.GroupChatJoined += GroupChatJoinedEventHandler;
     266            Client.Self.RequestJoinGroupChat(groupUUID);
     267            if (!GroupChatJoinedEvent.WaitOne((int)millisecondsTimeout, false))
     268            {
    271269                Client.Self.GroupChatJoined -= GroupChatJoinedEventHandler;
    272             }
     270                Locks.ClientInstanceSelfLock.ExitWriteLock();
     271                return false;
     272            }
     273            Client.Self.GroupChatJoined -= GroupChatJoinedEventHandler;
     274            Locks.ClientInstanceSelfLock.ExitWriteLock();
    273275            return succeeded;
    274276        }
     
    276278        public static bool UpdateParcelAccessList(GridClient Client, Simulator simulator, int parcelLocalID, AccessList accessListType, List<ParcelManager.ParcelAccessEntry> accessList)
    277279        {
    278             lock (Locks.ClientInstanceNetworkLock)
    279             {
    280                 Client.Network.SendPacket(new ParcelAccessListUpdatePacket
    281                 {
    282                     List = accessList.AsParallel().Select(o => new ParcelAccessListUpdatePacket.ListBlock
    283                     {
    284                         ID = o.AgentID,
    285                         Flags = (uint)o.Flags
    286                     }).ToArray(),
    287                     AgentData = new ParcelAccessListUpdatePacket.AgentDataBlock
    288                     {
    289                         AgentID = Client.Self.AgentID,
    290                         SessionID = Client.Self.SessionID
    291                     },
    292                     Data = new ParcelAccessListUpdatePacket.DataBlock
    293                     {
    294                         Flags = (uint)accessListType,
    295                         LocalID = parcelLocalID,
    296                         TransactionID = UUID.Random(),
    297                         SequenceID = 1,
    298                         Sections = (int)Math.Ceiling(accessList.Count / 48f)
    299                     },
    300                     Type = PacketType.ParcelAccessListUpdate
    301                 }, simulator);
    302             }
     280            Locks.ClientInstanceNetworkLock.EnterWriteLock();
     281            Client.Network.SendPacket(new ParcelAccessListUpdatePacket
     282            {
     283                List = accessList.AsParallel().Select(o => new ParcelAccessListUpdatePacket.ListBlock
     284                {
     285                    ID = o.AgentID,
     286                    Flags = (uint)o.Flags
     287                }).ToArray(),
     288                AgentData = new ParcelAccessListUpdatePacket.AgentDataBlock
     289                {
     290                    AgentID = Client.Self.AgentID,
     291                    SessionID = Client.Self.SessionID
     292                },
     293                Data = new ParcelAccessListUpdatePacket.DataBlock
     294                {
     295                    Flags = (uint)accessListType,
     296                    LocalID = parcelLocalID,
     297                    TransactionID = UUID.Random(),
     298                    SequenceID = 1,
     299                    Sections = (int)Math.Ceiling(accessList.Count / 48f)
     300                },
     301                Type = PacketType.ParcelAccessListUpdate
     302            }, simulator);
     303            Locks.ClientInstanceNetworkLock.ExitWriteLock();
    303304
    304305            return true;
     
    320321        {
    321322            var groupMembersReceivedEvent = new ManualResetEvent(false);
    322             var groupMembers = new HashSet<UUID>();
    323323            var requestUUID = UUID.Zero;
     324            bool isInGroup = false;
    324325            EventHandler<GroupMembersReplyEventArgs> HandleGroupMembersReplyDelegate = (sender, args) =>
    325326            {
    326327                if (!args.RequestID.Equals(requestUUID) || !groupUUID.Equals(args.GroupID))
    327328                    return;
    328                 groupMembers.UnionWith(args.Members.Values.Select(o => o.ID));
     329                isInGroup = args.Members.ContainsKey(agentUUID);
    329330                groupMembersReceivedEvent.Set();
    330331            };
     
    337338            }
    338339            Client.Groups.GroupMembersReply -= HandleGroupMembersReplyDelegate;
    339             return groupMembers.Contains(agentUUID);
     340            return isInGroup;
    340341        }
    341342
     
    362363                GroupProfileEvent.Set();
    363364            };
     365            Locks.ClientInstanceGroupsLock.EnterReadLock();
    364366            Client.Groups.GroupProfile += GroupProfileDelegate;
    365367            Client.Groups.RequestGroupProfile(groupUUID);
     
    367369            {
    368370                Client.Groups.GroupProfile -= GroupProfileDelegate;
     371                Locks.ClientInstanceGroupsLock.ExitReadLock();
    369372                return false;
    370373            }
    371374            Client.Groups.GroupProfile -= GroupProfileDelegate;
     375            Locks.ClientInstanceGroupsLock.ExitReadLock();
    372376            group = localGroup;
    373377            return true;
     
    388392        public static bool GetParcelAtPosition(GridClient Client, Simulator simulator, Vector3 position,
    389393            uint millisecondsTimeout,
     394            uint dataTimeout,
    390395            ref Parcel parcel)
    391396        {
     
    393398            EventHandler<SimParcelsDownloadedEventArgs> SimParcelsDownloadedDelegate =
    394399                (sender, args) => RequestAllSimParcelsEvent.Set();
    395             lock (Locks.ClientInstanceParcelsLock)
    396             {
    397                 Client.Parcels.SimParcelsDownloaded += SimParcelsDownloadedDelegate;
    398                 switch (!simulator.IsParcelMapFull())
    399                 {
    400                     case true:
    401                         Client.Parcels.RequestAllSimParcels(simulator);
    402                         break;
    403 
    404                     default:
    405                         RequestAllSimParcelsEvent.Set();
    406                         break;
    407                 }
    408                 if (!RequestAllSimParcelsEvent.WaitOne((int)millisecondsTimeout, false))
    409                 {
    410                     Client.Parcels.SimParcelsDownloaded -= SimParcelsDownloadedDelegate;
    411                     return false;
    412                 }
     400            Locks.ClientInstanceParcelsLock.EnterReadLock();
     401            Client.Parcels.SimParcelsDownloaded += SimParcelsDownloadedDelegate;
     402            switch (!simulator.IsParcelMapFull())
     403            {
     404                case true:
     405                    Client.Parcels.RequestAllSimParcels(simulator, true, (int)dataTimeout);
     406                    break;
     407
     408                default:
     409                    RequestAllSimParcelsEvent.Set();
     410                    break;
     411            }
     412            if (!RequestAllSimParcelsEvent.WaitOne((int)millisecondsTimeout, false))
     413            {
    413414                Client.Parcels.SimParcelsDownloaded -= SimParcelsDownloadedDelegate;
    414             }
     415                Locks.ClientInstanceParcelsLock.ExitReadLock();
     416                return false;
     417            }
     418            Client.Parcels.SimParcelsDownloaded -= SimParcelsDownloadedDelegate;
     419            Locks.ClientInstanceParcelsLock.ExitReadLock();
    415420            var localParcel = simulator.Parcels.Copy().Values
    416421                .AsParallel()
     
    454459                }
    455460            };
    456             lock (Locks.ClientInstanceParcelsLock)
    457             {
    458                 Client.Parcels.ParcelInfoReply += ParcelInfoEventHandler;
    459                 Client.Parcels.RequestParcelInfo(parcelUUID);
    460                 if (!ParcelInfoEvent.WaitOne((int)millisecondsTimeout, false))
    461                 {
    462                     Client.Parcels.ParcelInfoReply -= ParcelInfoEventHandler;
    463                     return false;
    464                 }
     461            Locks.ClientInstanceParcelsLock.EnterReadLock();
     462            Client.Parcels.ParcelInfoReply += ParcelInfoEventHandler;
     463            Client.Parcels.RequestParcelInfo(parcelUUID);
     464            if (!ParcelInfoEvent.WaitOne((int)millisecondsTimeout, false))
     465            {
    465466                Client.Parcels.ParcelInfoReply -= ParcelInfoEventHandler;
    466             }
     467                Locks.ClientInstanceParcelsLock.ExitReadLock();
     468                return false;
     469            }
     470            Client.Parcels.ParcelInfoReply -= ParcelInfoEventHandler;
     471            Locks.ClientInstanceParcelsLock.ExitReadLock();
    467472            if (localParcelInfo.Equals(default(ParcelInfo)))
    468473            {
     
    484489        public static HashSet<Primitive> GetPrimitives(GridClient Client, float range)
    485490        {
    486             lock (Locks.ClientInstanceNetworkLock)
    487             {
    488                 var objectsPrimitives = Client.Network.Simulators.AsParallel()
    489                     .SelectMany(o => o?.ObjectsPrimitives?.Copy()?.Values)
    490                     .ToDictionary(o => o.LocalID, p => p);
    491                 var objectsAvatars = Client.Network.Simulators.AsParallel()
    492                     .SelectMany(o => o?.ObjectsAvatars?.Copy()?.Values)
    493                     .ToDictionary(o => o.LocalID, p => p);
    494                 return new HashSet<Primitive>(Client.Network.Simulators.AsParallel()
    495                     .Select(o => new { s = o, a = o?.ObjectsPrimitives?.Copy()?.Values })
    496                     .SelectMany(o => o.a.AsParallel().Where(p =>
    497                     {
    498                         // find the parent of the primitive
    499                         var parent = p;
    500                         Primitive ancestorPrimitive;
    501                         if (objectsPrimitives.TryGetValue(parent.ParentID, out ancestorPrimitive))
    502                         {
    503                             parent = ancestorPrimitive;
    504                         }
    505                         Avatar ancestorAvatar;
    506                         if (objectsAvatars.TryGetValue(parent.ParentID, out ancestorAvatar))
    507                         {
    508                             parent = ancestorAvatar;
    509                         }
    510                         return Vector3d.Distance(Helpers.GlobalPosition(o.s, parent.Position),
    511                             Helpers.GlobalPosition(Client.Network.CurrentSim, Client.Self.SimPosition)) <= range;
    512                     })));
    513             }
     491            Locks.ClientInstanceNetworkLock.EnterReadLock();
     492            var objectsPrimitives = Client.Network.Simulators.AsParallel()
     493                .SelectMany(o => o?.ObjectsPrimitives?.Copy()?.Values)
     494                .ToDictionary(o => o.LocalID, p => p);
     495            var objectsAvatars = Client.Network.Simulators.AsParallel()
     496                .SelectMany(o => o?.ObjectsAvatars?.Copy()?.Values)
     497                .ToDictionary(o => o.LocalID, p => p);
     498            var result = new HashSet<Primitive>(Client.Network.Simulators.AsParallel()
     499                .Select(o => new { s = o, a = o?.ObjectsPrimitives?.Copy()?.Values })
     500                .SelectMany(o => o.a.AsParallel().Where(p =>
     501                {
     502                    // find the parent of the primitive
     503                    var parent = p;
     504                    Primitive ancestorPrimitive;
     505                    if (objectsPrimitives.TryGetValue(parent.ParentID, out ancestorPrimitive))
     506                    {
     507                        parent = ancestorPrimitive;
     508                    }
     509                    Avatar ancestorAvatar;
     510                    if (objectsAvatars.TryGetValue(parent.ParentID, out ancestorAvatar))
     511                    {
     512                        parent = ancestorAvatar;
     513                    }
     514                    return Vector3d.Distance(Helpers.GlobalPosition(o.s, parent.Position),
     515                        Helpers.GlobalPosition(Client.Network.CurrentSim, Client.Self.SimPosition)) <= range;
     516                })));
     517            Locks.ClientInstanceNetworkLock.ExitReadLock();
     518            return result;
    514519        }
    515520
     
    525530        public static HashSet<Primitive> GetObjects(GridClient Client, float range)
    526531        {
    527             lock (Locks.ClientInstanceNetworkLock)
    528             {
    529                 var objectsAvatars = Client.Network.Simulators.AsParallel()
    530                     .SelectMany(o => o?.ObjectsAvatars?.Copy()?.Values)
    531                     .ToDictionary(o => o.LocalID, p => p);
    532                 return new HashSet<Primitive>(Client.Network.Simulators.AsParallel()
    533                     .Select(o => new { s = o, a = o.ObjectsPrimitives.Copy().Values })
    534                     .SelectMany(o => o.a.AsParallel().Where(p =>
    535                     {
    536                         // find the parent of the primitive
    537                         var parent = p;
    538                         Avatar ancestorAvatar;
    539                         if (objectsAvatars.TryGetValue(parent.ParentID, out ancestorAvatar))
    540                         {
    541                             parent = ancestorAvatar;
    542                         }
    543                         return (p.ParentID.Equals(0) || objectsAvatars.ContainsKey(p.ParentID)) &&
    544                                Vector3d.Distance(Helpers.GlobalPosition(o.s, parent.Position),
    545                                    Helpers.GlobalPosition(Client.Network.CurrentSim, Client.Self.SimPosition)) <= range;
    546                     })));
    547             }
     532            Locks.ClientInstanceNetworkLock.EnterReadLock();
     533            var objectsAvatars = Client.Network.Simulators.AsParallel()
     534                .SelectMany(o => o?.ObjectsAvatars?.Copy()?.Values)
     535                .ToDictionary(o => o.LocalID, p => p);
     536            var result = new HashSet<Primitive>(Client.Network.Simulators.AsParallel()
     537                .Select(o => new { s = o, a = o.ObjectsPrimitives.Copy().Values })
     538                .SelectMany(o => o.a.AsParallel().Where(p =>
     539                {
     540                    // find the parent of the primitive
     541                    var parent = p;
     542                    Avatar ancestorAvatar;
     543                    if (objectsAvatars.TryGetValue(parent.ParentID, out ancestorAvatar))
     544                    {
     545                        parent = ancestorAvatar;
     546                    }
     547                    return (p.ParentID.Equals(0) || objectsAvatars.ContainsKey(p.ParentID)) &&
     548                           Vector3d.Distance(Helpers.GlobalPosition(o.s, parent.Position),
     549                               Helpers.GlobalPosition(Client.Network.CurrentSim, Client.Self.SimPosition)) <= range;
     550                })));
     551            Locks.ClientInstanceNetworkLock.ExitReadLock();
     552            return result;
    548553        }
    549554
     
    558563        public static HashSet<Avatar> GetAvatars(GridClient Client, float range)
    559564        {
    560             lock (Locks.ClientInstanceNetworkLock)
    561             {
    562                 var objectsPrimitives = Client.Network.Simulators.AsParallel()
    563                     .SelectMany(o => o?.ObjectsPrimitives?.Copy()?.Values)
    564                     .ToDictionary(o => o.LocalID, p => p);
    565                 var objectsAvatars = Client.Network.Simulators.AsParallel()
    566                     .SelectMany(o => o?.ObjectsAvatars?.Copy()?.Values)
    567                     .ToDictionary(o => o.LocalID, p => p);
    568                 return new HashSet<Avatar>(Client.Network.Simulators.AsParallel()
    569                     .Select(o => new { s = o, a = o?.ObjectsAvatars?.Copy()?.Values })
    570                     .SelectMany(o => o.a.AsParallel().Where(p =>
    571                     {
    572                         // find the parent of the primitive
    573                         Primitive parent = p;
    574                         Primitive ancestorPrimitive;
    575                         if (objectsPrimitives.TryGetValue(parent.ParentID, out ancestorPrimitive))
    576                         {
    577                             parent = ancestorPrimitive;
    578                         }
    579                         Avatar ancestorAvatar;
    580                         if (objectsAvatars.TryGetValue(parent.ParentID, out ancestorAvatar))
    581                         {
    582                             parent = ancestorAvatar;
    583                         }
    584                         return Vector3d.Distance(Helpers.GlobalPosition(o.s, parent.Position),
    585                             Helpers.GlobalPosition(Client.Network.CurrentSim, Client.Self.SimPosition)) <= range;
    586                     })));
    587             }
     565            Locks.ClientInstanceNetworkLock.EnterReadLock();
     566            var objectsPrimitives = Client.Network.Simulators.AsParallel()
     567                .SelectMany(o => o?.ObjectsPrimitives?.Copy()?.Values)
     568                .ToDictionary(o => o.LocalID, p => p);
     569            var objectsAvatars = Client.Network.Simulators.AsParallel()
     570                .SelectMany(o => o?.ObjectsAvatars?.Copy()?.Values)
     571                .ToDictionary(o => o.LocalID, p => p);
     572            var result = new HashSet<Avatar>(Client.Network.Simulators.AsParallel()
     573                .Select(o => new { s = o, a = o?.ObjectsAvatars?.Copy()?.Values })
     574                .SelectMany(o => o.a.AsParallel().Where(p =>
     575                {
     576                    // find the parent of the primitive
     577                    Primitive parent = p;
     578                    Primitive ancestorPrimitive;
     579                    if (objectsPrimitives.TryGetValue(parent.ParentID, out ancestorPrimitive))
     580                    {
     581                        parent = ancestorPrimitive;
     582                    }
     583                    Avatar ancestorAvatar;
     584                    if (objectsAvatars.TryGetValue(parent.ParentID, out ancestorAvatar))
     585                    {
     586                        parent = ancestorAvatar;
     587                    }
     588                    return Vector3d.Distance(Helpers.GlobalPosition(o.s, parent.Position),
     589                        Helpers.GlobalPosition(Client.Network.CurrentSim, Client.Self.SimPosition)) <= range;
     590                })));
     591            Locks.ClientInstanceNetworkLock.ExitReadLock();
     592            return result;
    588593        }
    589594
     
    607612            Parallel.ForEach(regionHandles, o =>
    608613            {
    609                 lock (Locks.ClientInstanceObjectsLock)
    610                 {
    611                     Client.Objects.ObjectProperties += ObjectPropertiesEventHandler;
    612                     ObjectPropertiesEvent.Reset();
    613                     lock (Locks.ClientInstanceNetworkLock)
    614                     {
    615                         Client.Objects.SelectObjects(
    616                             Client.Network.Simulators.AsParallel().FirstOrDefault(p => p.Handle.Equals(o)),
    617                             localPrimitives.Where(p => p.RegionHandle.Equals(o))
    618                                 .Select(p => p.LocalID)
    619                                 .ToArray(), true);
    620                     }
    621                     ObjectPropertiesEvent.WaitOne((int)dataTimeout, false);
    622                     Client.Objects.ObjectProperties -= ObjectPropertiesEventHandler;
    623                 }
     614                Locks.ClientInstanceObjectsLock.EnterWriteLock();
     615                Client.Objects.ObjectProperties += ObjectPropertiesEventHandler;
     616                ObjectPropertiesEvent.Reset();
     617                Locks.ClientInstanceNetworkLock.EnterReadLock();
     618                Client.Objects.SelectObjects(
     619                    Client.Network.Simulators.AsParallel().FirstOrDefault(p => p.Handle.Equals(o)),
     620                    localPrimitives.Where(p => p.RegionHandle.Equals(o))
     621                        .Select(p => p.LocalID)
     622                        .ToArray(), true);
     623                Locks.ClientInstanceNetworkLock.ExitReadLock();
     624                ObjectPropertiesEvent.WaitOne((int)dataTimeout, false);
     625                Client.Objects.ObjectProperties -= ObjectPropertiesEventHandler;
     626                Locks.ClientInstanceObjectsLock.ExitWriteLock();
    624627            });
    625628            primitives = new HashSet<Primitive>(localPrimitives.Where(o => o.Properties != null));
     
    644647            var localPrimitive = primitive;
    645648            var regionHandle = localPrimitive.RegionHandle;
    646             lock (Locks.ClientInstanceObjectsLock)
    647             {
    648                 Client.Objects.ObjectProperties += ObjectPropertiesEventHandler;
    649                 ObjectPropertiesEvent.Reset();
    650                 Client.Objects.SelectObject(
    651                     Client.Network.Simulators.AsParallel().FirstOrDefault(p => p.Handle.Equals(regionHandle)),
    652                     localPrimitive.LocalID, true);
    653                 ObjectPropertiesEvent.WaitOne((int)dataTimeout, false);
    654                 Client.Objects.ObjectProperties -= ObjectPropertiesEventHandler;
    655             }
     649            Locks.ClientInstanceObjectsLock.EnterWriteLock();
     650            Client.Objects.ObjectProperties += ObjectPropertiesEventHandler;
     651            ObjectPropertiesEvent.Reset();
     652            Locks.ClientInstanceNetworkLock.EnterReadLock();
     653            Client.Objects.SelectObject(
     654                Client.Network.Simulators.AsParallel().FirstOrDefault(p => p.Handle.Equals(regionHandle)),
     655                localPrimitive.LocalID, true);
     656            Locks.ClientInstanceNetworkLock.ExitReadLock();
     657            ObjectPropertiesEvent.WaitOne((int)dataTimeout, false);
     658            Client.Objects.ObjectProperties -= ObjectPropertiesEventHandler;
     659            Locks.ClientInstanceObjectsLock.ExitWriteLock();
    656660            primitive = localPrimitive;
    657661            return true;
     
    721725                    }
    722726                };
    723             lock (Locks.ClientInstanceAvatarsLock)
    724             {
    725                 Parallel.ForEach(scansAvatars, o =>
     727            Locks.ClientInstanceAvatarsLock.EnterReadLock();
     728            Parallel.ForEach(scansAvatars, o =>
    726729                {
    727730                    Client.Avatars.AvatarInterestsReply += AvatarInterestsReplyEventHandler;
     
    745748                    Client.Avatars.AvatarClassifiedReply -= AvatarClassifiedReplyEventHandler;
    746749                });
    747             }
     750            Locks.ClientInstanceAvatarsLock.ExitReadLock();
    748751            if (
    749752                avatarUpdates.Values.AsParallel()
     
    964967            var AssetReceivedEvent = new ManualResetEvent(false);
    965968            byte[] localAssetData = null;
    966             lock (Locks.ClientInstanceAssetsLock)
    967             {
    968                 Client.Assets.RequestImage(assetUUID, (state, asset) =>
    969                 {
    970                     if (!asset.AssetID.Equals(assetUUID))
    971                         return;
    972                     if (!state.Equals(TextureRequestState.Finished))
    973                         return;
    974                     localAssetData = asset.AssetData;
    975                     AssetReceivedEvent.Set();
    976                 });
    977             }
     969
     970            Locks.ClientInstanceAssetsLock.EnterReadLock();
     971            Client.Assets.RequestImage(assetUUID, (state, asset) =>
     972            {
     973                if (!asset.AssetID.Equals(assetUUID))
     974                    return;
     975                if (!state.Equals(TextureRequestState.Finished))
     976                    return;
     977                localAssetData = asset.AssetData;
     978                AssetReceivedEvent.Set();
     979            });
     980            Locks.ClientInstanceAssetsLock.ExitReadLock();
    978981
    979982            assetData = localAssetData;
     
    994997        public static bool DownloadTexture(GridClient Client, UUID assetUUID, out byte[] assetData, uint dataTimeout)
    995998        {
    996             lock (Locks.ClientInstanceAssetsLock)
    997             {
    998                 if (Client.Assets.Cache.HasAsset(assetUUID))
    999                 {
    1000                     assetData = Client.Assets.Cache.GetCachedAssetBytes(assetUUID);
    1001                     return true;
    1002                 }
    1003             }
     999            Locks.ClientInstanceAssetsLock.EnterReadLock();
     1000            if (Client.Assets.Cache.HasAsset(assetUUID))
     1001            {
     1002                assetData = Client.Assets.Cache.GetCachedAssetBytes(assetUUID);
     1003                Locks.ClientInstanceAssetsLock.ExitReadLock();
     1004                return true;
     1005            }
     1006            Locks.ClientInstanceAssetsLock.ExitReadLock();
    10041007            var succeeded = directDownloadTexture(Client, assetUUID, out assetData, dataTimeout);
    10051008            if (succeeded)
    10061009            {
    1007                 lock (Locks.ClientInstanceAssetsLock)
    1008                 {
    1009                     Client.Assets.Cache.SaveAssetToCache(assetUUID, assetData);
    1010                 }
     1010                Locks.ClientInstanceAssetsLock.EnterWriteLock();
     1011                Client.Assets.Cache.SaveAssetToCache(assetUUID, assetData);
     1012                Locks.ClientInstanceAssetsLock.ExitWriteLock();
    10111013            }
    10121014            return succeeded;
Note: See TracChangeset for help on using the changeset viewer.