diff options
author | UbitUmarov | 2018-01-22 17:09:38 +0000 |
---|---|---|
committer | UbitUmarov | 2018-01-22 17:09:38 +0000 |
commit | d38161f83d08e8f36905faaec30fcb9bbce9a319 (patch) | |
tree | 124cba5c7363aebf02965fc0702133c4e81f6874 | |
parent | give BlockingCollection more chances (diff) | |
download | opensim-SC-d38161f83d08e8f36905faaec30fcb9bbce9a319.zip opensim-SC-d38161f83d08e8f36905faaec30fcb9bbce9a319.tar.gz opensim-SC-d38161f83d08e8f36905faaec30fcb9bbce9a319.tar.bz2 opensim-SC-d38161f83d08e8f36905faaec30fcb9bbce9a319.tar.xz |
retire our BlockingQueue replaced by BlockingCollection and cross fingers
5 files changed, 33 insertions, 174 deletions
diff --git a/OpenSim/Framework/BlockingQueue.cs b/OpenSim/Framework/BlockingQueue.cs deleted file mode 100644 index 2461049..0000000 --- a/OpenSim/Framework/BlockingQueue.cs +++ /dev/null | |||
@@ -1,148 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System.Collections.Generic; | ||
29 | using System.Threading; | ||
30 | |||
31 | namespace OpenSim.Framework | ||
32 | { | ||
33 | public class BlockingQueue<T> | ||
34 | { | ||
35 | private readonly Queue<T> m_pqueue = new Queue<T>(); | ||
36 | private readonly Queue<T> m_queue = new Queue<T>(); | ||
37 | private readonly object m_queueSync = new object(); | ||
38 | |||
39 | public void PriorityEnqueue(T value) | ||
40 | { | ||
41 | lock (m_queueSync) | ||
42 | { | ||
43 | m_pqueue.Enqueue(value); | ||
44 | Monitor.Pulse(m_queueSync); | ||
45 | } | ||
46 | } | ||
47 | |||
48 | public void Enqueue(T value) | ||
49 | { | ||
50 | lock (m_queueSync) | ||
51 | { | ||
52 | m_queue.Enqueue(value); | ||
53 | Monitor.Pulse(m_queueSync); | ||
54 | } | ||
55 | } | ||
56 | |||
57 | public T Dequeue() | ||
58 | { | ||
59 | lock (m_queueSync) | ||
60 | { | ||
61 | while (m_queue.Count < 1 && m_pqueue.Count < 1) | ||
62 | { | ||
63 | Monitor.Wait(m_queueSync); | ||
64 | } | ||
65 | |||
66 | if (m_pqueue.Count > 0) | ||
67 | return m_pqueue.Dequeue(); | ||
68 | |||
69 | if (m_queue.Count > 0) | ||
70 | return m_queue.Dequeue(); | ||
71 | return default(T); | ||
72 | } | ||
73 | } | ||
74 | |||
75 | public T Dequeue(int msTimeout) | ||
76 | { | ||
77 | lock (m_queueSync) | ||
78 | { | ||
79 | if (m_queue.Count < 1 && m_pqueue.Count < 1) | ||
80 | { | ||
81 | if(!Monitor.Wait(m_queueSync, msTimeout)) | ||
82 | return default(T); | ||
83 | } | ||
84 | |||
85 | if (m_pqueue.Count > 0) | ||
86 | return m_pqueue.Dequeue(); | ||
87 | if (m_queue.Count > 0) | ||
88 | return m_queue.Dequeue(); | ||
89 | return default(T); | ||
90 | } | ||
91 | } | ||
92 | |||
93 | /// <summary> | ||
94 | /// Indicate whether this queue contains the given item. | ||
95 | /// </summary> | ||
96 | /// <remarks> | ||
97 | /// This method is not thread-safe. Do not rely on the result without consistent external locking. | ||
98 | /// </remarks> | ||
99 | public bool Contains(T item) | ||
100 | { | ||
101 | lock (m_queueSync) | ||
102 | { | ||
103 | if (m_queue.Count < 1 && m_pqueue.Count < 1) | ||
104 | return false; | ||
105 | |||
106 | if (m_pqueue.Contains(item)) | ||
107 | return true; | ||
108 | return m_queue.Contains(item); | ||
109 | } | ||
110 | } | ||
111 | |||
112 | /// <summary> | ||
113 | /// Return a count of the number of requests on this queue. | ||
114 | /// </summary> | ||
115 | public int Count() | ||
116 | { | ||
117 | lock (m_queueSync) | ||
118 | return m_queue.Count + m_pqueue.Count; | ||
119 | } | ||
120 | |||
121 | /// <summary> | ||
122 | /// Return the array of items on this queue. | ||
123 | /// </summary> | ||
124 | /// <remarks> | ||
125 | /// This method is not thread-safe. Do not rely on the result without consistent external locking. | ||
126 | /// </remarks> | ||
127 | public T[] GetQueueArray() | ||
128 | { | ||
129 | lock (m_queueSync) | ||
130 | { | ||
131 | if (m_queue.Count < 1 && m_pqueue.Count < 1) | ||
132 | return new T[0]; | ||
133 | |||
134 | return m_queue.ToArray(); | ||
135 | } | ||
136 | } | ||
137 | |||
138 | public void Clear() | ||
139 | { | ||
140 | lock (m_queueSync) | ||
141 | { | ||
142 | m_pqueue.Clear(); | ||
143 | m_queue.Clear(); | ||
144 | Monitor.Pulse(m_queueSync); | ||
145 | } | ||
146 | } | ||
147 | } | ||
148 | } | ||
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 72b6116..58094d3 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | |||
@@ -27,6 +27,7 @@ | |||
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Collections.Concurrent; | ||
30 | using System.Diagnostics; | 31 | using System.Diagnostics; |
31 | using System.IO; | 32 | using System.IO; |
32 | using System.Net; | 33 | using System.Net; |
@@ -285,7 +286,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
285 | /// <summary>Incoming packets that are awaiting handling</summary> | 286 | /// <summary>Incoming packets that are awaiting handling</summary> |
286 | //protected OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>(); | 287 | //protected OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>(); |
287 | 288 | ||
288 | protected OpenSim.Framework.BlockingQueue<IncomingPacket> packetInbox = new OpenSim.Framework.BlockingQueue<IncomingPacket>(); | 289 | protected BlockingCollection<IncomingPacket> packetInbox = new BlockingCollection<IncomingPacket>(); |
289 | 290 | ||
290 | /// <summary>Bandwidth throttle for this UDP server</summary> | 291 | /// <summary>Bandwidth throttle for this UDP server</summary> |
291 | public TokenBucket Throttle { get; protected set; } | 292 | public TokenBucket Throttle { get; protected set; } |
@@ -712,7 +713,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
712 | scene.Name, | 713 | scene.Name, |
713 | StatType.Pull, | 714 | StatType.Pull, |
714 | MeasuresOfInterest.AverageChangeOverTime, | 715 | MeasuresOfInterest.AverageChangeOverTime, |
715 | stat => stat.Value = packetInbox.Count(), | 716 | stat => stat.Value = packetInbox.Count, |
716 | StatVerbosity.Debug)); | 717 | StatVerbosity.Debug)); |
717 | 718 | ||
718 | // XXX: These stats are also pool stats but we register them separately since they are currently not | 719 | // XXX: These stats are also pool stats but we register them separately since they are currently not |
@@ -1546,10 +1547,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1546 | 1547 | ||
1547 | // if (incomingPacket.Packet.Type == PacketType.AgentUpdate || | 1548 | // if (incomingPacket.Packet.Type == PacketType.AgentUpdate || |
1548 | // incomingPacket.Packet.Type == PacketType.ChatFromViewer) | 1549 | // incomingPacket.Packet.Type == PacketType.ChatFromViewer) |
1549 | if (incomingPacket.Packet.Type == PacketType.ChatFromViewer) | 1550 | // if (incomingPacket.Packet.Type == PacketType.ChatFromViewer) |
1550 | packetInbox.PriorityEnqueue(incomingPacket); | 1551 | // packetInbox.PriorityEnqueue(incomingPacket); |
1551 | else | 1552 | // else |
1552 | packetInbox.Enqueue(incomingPacket); | 1553 | // packetInbox.Enqueue(incomingPacket); |
1554 | packetInbox.Add(incomingPacket); | ||
1553 | 1555 | ||
1554 | } | 1556 | } |
1555 | 1557 | ||
@@ -2018,7 +2020,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2018 | Scene.ThreadAlive(1); | 2020 | Scene.ThreadAlive(1); |
2019 | try | 2021 | try |
2020 | { | 2022 | { |
2021 | incomingPacket = packetInbox.Dequeue(250); | 2023 | packetInbox.TryTake(out incomingPacket, 250); |
2022 | 2024 | ||
2023 | if (incomingPacket != null && IsRunningInbound) | 2025 | if (incomingPacket != null && IsRunningInbound) |
2024 | { | 2026 | { |
@@ -2040,9 +2042,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2040 | Watchdog.UpdateThread(); | 2042 | Watchdog.UpdateThread(); |
2041 | } | 2043 | } |
2042 | 2044 | ||
2043 | if (packetInbox.Count() > 0) | 2045 | if (packetInbox.Count > 0) |
2044 | m_log.Warn("[LLUDPSERVER]: IncomingPacketHandler is shutting down, dropping " + packetInbox.Count() + " packets"); | 2046 | m_log.Warn("[LLUDPSERVER]: IncomingPacketHandler is shutting down, dropping " + packetInbox.Count + " packets"); |
2045 | packetInbox.Clear(); | 2047 | packetInbox.Dispose(); |
2046 | 2048 | ||
2047 | Watchdog.RemoveThread(); | 2049 | Watchdog.RemoveThread(); |
2048 | } | 2050 | } |
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index 3c45b68..0ca76e4 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs | |||
@@ -26,7 +26,7 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections.Concurrent; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.IO; | 31 | using System.IO; |
32 | using System.Linq; | 32 | using System.Linq; |
@@ -668,7 +668,7 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
668 | public UUID user; | 668 | public UUID user; |
669 | } | 669 | } |
670 | 670 | ||
671 | private OpenSim.Framework.BlockingQueue<EstateAccessDeltaRequest> deltaRequests = new OpenSim.Framework.BlockingQueue<EstateAccessDeltaRequest>(); | 671 | private BlockingCollection<EstateAccessDeltaRequest> deltaRequests = new BlockingCollection<EstateAccessDeltaRequest>(); |
672 | 672 | ||
673 | private void handleEstateAccessDeltaRequest(IClientAPI _remote_client, UUID _invoice, int _estateAccessType, UUID _user) | 673 | private void handleEstateAccessDeltaRequest(IClientAPI _remote_client, UUID _invoice, int _estateAccessType, UUID _user) |
674 | { | 674 | { |
@@ -683,7 +683,7 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
683 | newreq.estateAccessType = _estateAccessType; | 683 | newreq.estateAccessType = _estateAccessType; |
684 | newreq.user = _user; | 684 | newreq.user = _user; |
685 | 685 | ||
686 | deltaRequests.Enqueue(newreq); | 686 | deltaRequests.Add(newreq); |
687 | 687 | ||
688 | lock(deltareqLock) | 688 | lock(deltareqLock) |
689 | { | 689 | { |
@@ -713,9 +713,11 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
713 | bool sentGroupsFull = false; | 713 | bool sentGroupsFull = false; |
714 | bool sentManagersFull = false; | 714 | bool sentManagersFull = false; |
715 | 715 | ||
716 | EstateAccessDeltaRequest req; | ||
716 | while(Scene.IsRunning) | 717 | while(Scene.IsRunning) |
717 | { | 718 | { |
718 | EstateAccessDeltaRequest req = deltaRequests.Dequeue(500); | 719 | req = null; |
720 | deltaRequests.TryTake(out req, 500); | ||
719 | 721 | ||
720 | if(!Scene.IsRunning) | 722 | if(!Scene.IsRunning) |
721 | break; | 723 | break; |
@@ -757,7 +759,7 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
757 | changed.Clear(); | 759 | changed.Clear(); |
758 | lock(deltareqLock) | 760 | lock(deltareqLock) |
759 | { | 761 | { |
760 | if(deltaRequests.Count() != 0) | 762 | if(deltaRequests.Count != 0) |
761 | continue; | 763 | continue; |
762 | runnigDeltaExec = false; | 764 | runnigDeltaExec = false; |
763 | return; | 765 | return; |
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index 03a4d34..b5a6912 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs | |||
@@ -27,6 +27,7 @@ | |||
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections; |
30 | using System.Collections.Concurrent; | ||
30 | using System.Collections.Generic; | 31 | using System.Collections.Generic; |
31 | using System.Drawing; | 32 | using System.Drawing; |
32 | using System.Drawing.Imaging; | 33 | using System.Drawing.Imaging; |
@@ -67,7 +68,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
67 | private static readonly string DEFAULT_WORLD_MAP_EXPORT_PATH = "exportmap.jpg"; | 68 | private static readonly string DEFAULT_WORLD_MAP_EXPORT_PATH = "exportmap.jpg"; |
68 | private static readonly UUID STOP_UUID = UUID.Random(); | 69 | private static readonly UUID STOP_UUID = UUID.Random(); |
69 | 70 | ||
70 | private OpenSim.Framework.BlockingQueue<MapRequestState> requests = new OpenSim.Framework.BlockingQueue<MapRequestState>(); | 71 | private BlockingCollection<MapRequestState> requests = new BlockingCollection<MapRequestState>(); |
71 | 72 | ||
72 | private ManualResetEvent m_mapBlockRequestEvent = new ManualResetEvent(false); | 73 | private ManualResetEvent m_mapBlockRequestEvent = new ManualResetEvent(false); |
73 | private Dictionary<UUID, Queue<MapBlockRequestData>> m_mapBlockRequests = new Dictionary<UUID, Queue<MapBlockRequestData>>(); | 74 | private Dictionary<UUID, Queue<MapBlockRequestData>> m_mapBlockRequests = new Dictionary<UUID, Queue<MapBlockRequestData>>(); |
@@ -422,7 +423,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
422 | st.itemtype = 0; | 423 | st.itemtype = 0; |
423 | st.regionhandle = 0; | 424 | st.regionhandle = 0; |
424 | 425 | ||
425 | requests.Enqueue(st); | 426 | requests.Add(st); |
426 | 427 | ||
427 | MapBlockRequestData req = new MapBlockRequestData(); | 428 | MapBlockRequestData req = new MapBlockRequestData(); |
428 | 429 | ||
@@ -719,7 +720,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
719 | av = null; | 720 | av = null; |
720 | st = null; | 721 | st = null; |
721 | 722 | ||
722 | st = requests.Dequeue(4500); | 723 | requests.TryTake(out st, 4500); |
723 | Watchdog.UpdateThread(); | 724 | Watchdog.UpdateThread(); |
724 | 725 | ||
725 | if (st == null || st.agentID == UUID.Zero) | 726 | if (st == null || st.agentID == UUID.Zero) |
@@ -795,8 +796,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
795 | else | 796 | else |
796 | { | 797 | { |
797 | // request still beeing processed, enqueue it back | 798 | // request still beeing processed, enqueue it back |
798 | requests.Enqueue(st); | 799 | requests.Add(st); |
799 | if (requests.Count() < 3) | 800 | if (requests.Count < 3) |
800 | Thread.Sleep(100); | 801 | Thread.Sleep(100); |
801 | } | 802 | } |
802 | } | 803 | } |
@@ -839,7 +840,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
839 | st.itemtype = itemtype; | 840 | st.itemtype = itemtype; |
840 | st.regionhandle = regionhandle; | 841 | st.regionhandle = regionhandle; |
841 | 842 | ||
842 | requests.Enqueue(st); | 843 | requests.Add(st); |
843 | } | 844 | } |
844 | 845 | ||
845 | uint[] itemTypesForcedSend = new uint[] { 6, 1, 7, 10 }; // green dots, infohub, land sells | 846 | uint[] itemTypesForcedSend = new uint[] { 6, 1, 7, 10 }; // green dots, infohub, land sells |
diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODEMeshWorker.cs b/OpenSim/Region/PhysicsModules/ubOde/ODEMeshWorker.cs index f4e2b1f..bdfbe3d 100644 --- a/OpenSim/Region/PhysicsModules/ubOde/ODEMeshWorker.cs +++ b/OpenSim/Region/PhysicsModules/ubOde/ODEMeshWorker.cs | |||
@@ -3,6 +3,7 @@ | |||
3 | */ | 3 | */ |
4 | 4 | ||
5 | using System; | 5 | using System; |
6 | using System.Collections.Concurrent; | ||
6 | using System.Threading; | 7 | using System.Threading; |
7 | using OpenSim.Framework; | 8 | using OpenSim.Framework; |
8 | using OpenSim.Region.PhysicsModules.SharedBase; | 9 | using OpenSim.Region.PhysicsModules.SharedBase; |
@@ -73,7 +74,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
73 | public float MeshSculptphysicalLOD = 32; | 74 | public float MeshSculptphysicalLOD = 32; |
74 | public float MinSizeToMeshmerize = 0.1f; | 75 | public float MinSizeToMeshmerize = 0.1f; |
75 | 76 | ||
76 | private OpenSim.Framework.BlockingQueue<ODEPhysRepData> workQueue = new OpenSim.Framework.BlockingQueue<ODEPhysRepData>(); | 77 | private BlockingCollection<ODEPhysRepData> workQueue = new BlockingCollection<ODEPhysRepData>(); |
77 | private bool m_running; | 78 | private bool m_running; |
78 | 79 | ||
79 | private Thread m_thread; | 80 | private Thread m_thread; |
@@ -100,10 +101,11 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
100 | private void DoWork() | 101 | private void DoWork() |
101 | { | 102 | { |
102 | m_mesher.ExpireFileCache(); | 103 | m_mesher.ExpireFileCache(); |
104 | ODEPhysRepData nextRep; | ||
103 | 105 | ||
104 | while(m_running) | 106 | while(m_running) |
105 | { | 107 | { |
106 | ODEPhysRepData nextRep = workQueue.Dequeue(); | 108 | workQueue.TryTake(out nextRep, -1); |
107 | if(!m_running) | 109 | if(!m_running) |
108 | return; | 110 | return; |
109 | if (nextRep == null) | 111 | if (nextRep == null) |
@@ -132,7 +134,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
132 | try | 134 | try |
133 | { | 135 | { |
134 | m_thread.Abort(); | 136 | m_thread.Abort(); |
135 | workQueue.Clear(); | 137 | // workQueue.Dispose(); |
136 | } | 138 | } |
137 | catch | 139 | catch |
138 | { | 140 | { |
@@ -189,7 +191,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
189 | repData.meshState = MeshState.loadingAsset; | 191 | repData.meshState = MeshState.loadingAsset; |
190 | 192 | ||
191 | repData.comand = meshWorkerCmnds.getmesh; | 193 | repData.comand = meshWorkerCmnds.getmesh; |
192 | workQueue.Enqueue(repData); | 194 | workQueue.Add(repData); |
193 | } | 195 | } |
194 | } | 196 | } |
195 | 197 | ||
@@ -235,7 +237,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
235 | if (needsMeshing(repData)) // no need for pbs now? | 237 | if (needsMeshing(repData)) // no need for pbs now? |
236 | { | 238 | { |
237 | repData.comand = meshWorkerCmnds.changefull; | 239 | repData.comand = meshWorkerCmnds.changefull; |
238 | workQueue.Enqueue(repData); | 240 | workQueue.Add(repData); |
239 | } | 241 | } |
240 | } | 242 | } |
241 | else | 243 | else |