diff options
author | Melanie Thielker | 2008-07-22 17:58:42 +0000 |
---|---|---|
committer | Melanie Thielker | 2008-07-22 17:58:42 +0000 |
commit | f112cebde2c1bc06108839acac82bc8addd7c506 (patch) | |
tree | 7f1e7fabf2fec74171d5982f09d847b47e20d7ca /OpenSim/Region/ClientStack/LindenUDP/LLPacketTracker.cs | |
parent | * refactor: move new inventory service call by user server to OGS1 with all t... (diff) | |
download | opensim-SC-f112cebde2c1bc06108839acac82bc8addd7c506.zip opensim-SC-f112cebde2c1bc06108839acac82bc8addd7c506.tar.gz opensim-SC-f112cebde2c1bc06108839acac82bc8addd7c506.tar.bz2 opensim-SC-f112cebde2c1bc06108839acac82bc8addd7c506.tar.xz |
Refactor the packet scheduling out of ClientView. Add intelligent
resending, timeouts, packet discarding. Add notification event for
packet discarding. Add priority scheduling for packet queues.
Add outgoing duplicate detection facility. Correct packet sequencing.
Make provisions for automatic server side throttle adjustments (comes
in next installment)
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP/LLPacketTracker.cs')
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLPacketTracker.cs | 263 |
1 files changed, 0 insertions, 263 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLPacketTracker.cs b/OpenSim/Region/ClientStack/LindenUDP/LLPacketTracker.cs deleted file mode 100644 index 690fadb..0000000 --- a/OpenSim/Region/ClientStack/LindenUDP/LLPacketTracker.cs +++ /dev/null | |||
@@ -1,263 +0,0 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | using System.Text; | ||
4 | using System.Threading; | ||
5 | using libsecondlife; | ||
6 | using libsecondlife.Packets; | ||
7 | using OpenSim.Framework; | ||
8 | |||
9 | namespace OpenSim.Region.ClientStack.LindenUDP | ||
10 | { | ||
11 | |||
12 | public class LLPacketTracker | ||
13 | { | ||
14 | public delegate void PacketAcked(uint sequenceNumber); | ||
15 | public event PacketAcked OnPacketAcked; | ||
16 | |||
17 | protected List<uint> m_beenAcked = new List<uint>(); | ||
18 | |||
19 | protected TerrainPacketTracker[,] m_sentTerrainPackets = new TerrainPacketTracker[16, 16]; | ||
20 | protected Dictionary<LLUUID, PrimPacketTracker> m_sendPrimPackets = new Dictionary<LLUUID, PrimPacketTracker>(); | ||
21 | |||
22 | protected LLClientView m_parentClient; | ||
23 | |||
24 | public LLPacketTracker(LLClientView parent) | ||
25 | { | ||
26 | m_parentClient = parent; | ||
27 | OnPacketAcked += TerrainPacketAcked; | ||
28 | //OnPacketAcked += PrimPacketAcked; | ||
29 | } | ||
30 | |||
31 | public void PacketAck(uint sequenceNumber) | ||
32 | { | ||
33 | lock (m_beenAcked) | ||
34 | { | ||
35 | m_beenAcked.Add(sequenceNumber); | ||
36 | } | ||
37 | } | ||
38 | |||
39 | public void TrackTerrainPacket(uint sequenceNumber, int patchX, int patchY) | ||
40 | { | ||
41 | TrackTerrainPacket(sequenceNumber, patchX, patchY, false, null); | ||
42 | } | ||
43 | |||
44 | public void TrackTerrainPacket(uint sequenceNumber, int patchX, int patchY, bool keepResending, LayerDataPacket packet) | ||
45 | { | ||
46 | TerrainPacketTracker tracker = new TerrainPacketTracker(); | ||
47 | tracker.X = patchX; | ||
48 | tracker.Y = patchY; | ||
49 | tracker.SeqNumber = sequenceNumber; | ||
50 | tracker.TimeSent = DateTime.Now; | ||
51 | tracker.KeepResending = keepResending; | ||
52 | tracker.Packet = packet; | ||
53 | lock (m_sentTerrainPackets) | ||
54 | { | ||
55 | m_sentTerrainPackets[patchX, patchY] = tracker; | ||
56 | } | ||
57 | } | ||
58 | |||
59 | public void TrackPrimPacket(uint sequenceNumber, LLUUID primID) | ||
60 | { | ||
61 | PrimPacketTracker tracker = new PrimPacketTracker(); | ||
62 | tracker.PrimID = primID; | ||
63 | tracker.TimeSent = DateTime.Now; | ||
64 | tracker.SeqNumber = sequenceNumber; | ||
65 | lock (m_sendPrimPackets) | ||
66 | { | ||
67 | m_sendPrimPackets[primID] = tracker; | ||
68 | } | ||
69 | } | ||
70 | |||
71 | public void TerrainPacketCheck() | ||
72 | { | ||
73 | DateTime now = DateTime.Now; | ||
74 | List<TerrainPacketTracker> resendList = new List<TerrainPacketTracker>(); | ||
75 | lock (m_sentTerrainPackets) | ||
76 | { | ||
77 | for (int y = 0; y < 16; y++) | ||
78 | { | ||
79 | for (int x = 0; x < 16; x++) | ||
80 | { | ||
81 | if (m_sentTerrainPackets[x, y] != null) | ||
82 | { | ||
83 | TerrainPacketTracker tracker = m_sentTerrainPackets[x, y]; | ||
84 | if ((now - tracker.TimeSent) > TimeSpan.FromMinutes(1)) | ||
85 | { | ||
86 | tracker.TimeSent = now; | ||
87 | m_sentTerrainPackets[x, y] = null; | ||
88 | resendList.Add(tracker); | ||
89 | } | ||
90 | } | ||
91 | } | ||
92 | } | ||
93 | } | ||
94 | |||
95 | foreach (TerrainPacketTracker tracker in resendList) | ||
96 | { | ||
97 | if (!tracker.KeepResending) | ||
98 | { | ||
99 | m_parentClient.TriggerTerrainUnackedEvent(tracker.X, tracker.Y); | ||
100 | } | ||
101 | else | ||
102 | { | ||
103 | if (tracker.Packet != null) | ||
104 | { | ||
105 | tracker.Packet.Header.Resent = true; | ||
106 | m_parentClient.OutPacket(tracker.Packet, ThrottleOutPacketType.Resend); | ||
107 | tracker.TimeSent = DateTime.Now; | ||
108 | lock (m_sentTerrainPackets) | ||
109 | { | ||
110 | if (m_sentTerrainPackets[tracker.X, tracker.Y] == null) | ||
111 | { | ||
112 | m_sentTerrainPackets[tracker.X, tracker.Y] = tracker; | ||
113 | } | ||
114 | } | ||
115 | } | ||
116 | } | ||
117 | } | ||
118 | } | ||
119 | |||
120 | public void PrimPacketCheck() | ||
121 | { | ||
122 | DateTime now = DateTime.Now; | ||
123 | List<PrimPacketTracker> resendList = new List<PrimPacketTracker>(); | ||
124 | List<PrimPacketTracker> ackedList = new List<PrimPacketTracker>(); | ||
125 | |||
126 | lock (m_sendPrimPackets) | ||
127 | { | ||
128 | foreach (PrimPacketTracker tracker in m_sendPrimPackets.Values) | ||
129 | { | ||
130 | if (tracker.Acked) | ||
131 | { | ||
132 | ackedList.Add(tracker); | ||
133 | } | ||
134 | else if (((now - tracker.TimeSent) > TimeSpan.FromMinutes(1)) && (!tracker.Acked)) | ||
135 | { | ||
136 | resendList.Add(tracker); | ||
137 | } | ||
138 | } | ||
139 | } | ||
140 | |||
141 | foreach (PrimPacketTracker tracker in resendList) | ||
142 | { | ||
143 | lock (m_sendPrimPackets) | ||
144 | { | ||
145 | m_sendPrimPackets.Remove(tracker.PrimID); | ||
146 | } | ||
147 | //call event | ||
148 | Console.WriteLine("Prim packet not acked, " + tracker.PrimID.ToString()); | ||
149 | } | ||
150 | |||
151 | |||
152 | RemovePrimTrackers(ackedList); | ||
153 | } | ||
154 | |||
155 | public void PrimTrackerCleanup() | ||
156 | { | ||
157 | List<PrimPacketTracker> ackedList = new List<PrimPacketTracker>(); | ||
158 | |||
159 | lock (m_sendPrimPackets) | ||
160 | { | ||
161 | foreach (PrimPacketTracker tracker in m_sendPrimPackets.Values) | ||
162 | { | ||
163 | if (tracker.Acked) | ||
164 | { | ||
165 | ackedList.Add(tracker); | ||
166 | } | ||
167 | } | ||
168 | } | ||
169 | Thread.Sleep(15); //give a little bit of time for other code to access list before we lock it again | ||
170 | |||
171 | RemovePrimTrackers(ackedList); | ||
172 | } | ||
173 | |||
174 | protected void RemovePrimTrackers(List<PrimPacketTracker> ackedList) | ||
175 | { | ||
176 | lock (m_sendPrimPackets) | ||
177 | { | ||
178 | foreach (PrimPacketTracker tracker in ackedList) | ||
179 | { | ||
180 | m_sendPrimPackets.Remove(tracker.PrimID); | ||
181 | } | ||
182 | } | ||
183 | } | ||
184 | |||
185 | protected void TerrainPacketAcked(uint sequence) | ||
186 | { | ||
187 | lock (m_sentTerrainPackets) | ||
188 | { | ||
189 | for (int y = 0; y < 16; y++) | ||
190 | { | ||
191 | for (int x = 0; x < 16; x++) | ||
192 | { | ||
193 | if (m_sentTerrainPackets[x, y] != null) | ||
194 | { | ||
195 | if (m_sentTerrainPackets[x, y].SeqNumber == sequence) | ||
196 | { | ||
197 | m_sentTerrainPackets[x, y] = null; | ||
198 | return; | ||
199 | } | ||
200 | } | ||
201 | } | ||
202 | } | ||
203 | } | ||
204 | } | ||
205 | |||
206 | protected void PrimPacketAcked(uint sequence) | ||
207 | { | ||
208 | lock (m_sendPrimPackets) | ||
209 | { | ||
210 | foreach (PrimPacketTracker tracker in m_sendPrimPackets.Values) | ||
211 | { | ||
212 | if (tracker.SeqNumber == sequence) | ||
213 | { | ||
214 | tracker.Acked = true; | ||
215 | break; | ||
216 | } | ||
217 | } | ||
218 | } | ||
219 | } | ||
220 | |||
221 | public void Process() | ||
222 | { | ||
223 | List<uint> ackedPackets = null; | ||
224 | lock (m_beenAcked) | ||
225 | { | ||
226 | ackedPackets = new List<uint>(m_beenAcked); | ||
227 | m_beenAcked.Clear(); | ||
228 | } | ||
229 | |||
230 | if (ackedPackets != null) | ||
231 | { | ||
232 | foreach (uint packetId in ackedPackets) | ||
233 | { | ||
234 | if (OnPacketAcked != null) | ||
235 | { | ||
236 | OnPacketAcked(packetId); | ||
237 | } | ||
238 | } | ||
239 | } | ||
240 | |||
241 | // ackedPackets.Clear(); | ||
242 | ackedPackets = null; | ||
243 | } | ||
244 | |||
245 | public class TerrainPacketTracker | ||
246 | { | ||
247 | public uint SeqNumber = 0; | ||
248 | public int X; | ||
249 | public int Y; | ||
250 | public DateTime TimeSent; | ||
251 | public LayerDataPacket Packet; | ||
252 | public bool KeepResending; | ||
253 | } | ||
254 | |||
255 | public class PrimPacketTracker | ||
256 | { | ||
257 | public uint SeqNumber = 0; | ||
258 | public DateTime TimeSent; | ||
259 | public LLUUID PrimID; | ||
260 | public bool Acked = false; | ||
261 | } | ||
262 | } | ||
263 | } | ||