aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs72
1 files changed, 64 insertions, 8 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
index 7035e38..48c5b37 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
@@ -78,6 +78,36 @@ namespace OpenMetaverse
78 public bool IsRunningOutbound { get; private set; } 78 public bool IsRunningOutbound { get; private set; }
79 79
80 /// <summary> 80 /// <summary>
81 /// Number of UDP receives.
82 /// </summary>
83 public int UdpReceives { get; private set; }
84
85 /// <summary>
86 /// Number of UDP sends
87 /// </summary>
88 public int UdpSends { get; private set; }
89
90 /// <summary>
91 /// Number of receives over which to establish a receive time average.
92 /// </summary>
93 private readonly static int s_receiveTimeSamples = 500;
94
95 /// <summary>
96 /// Current number of samples taken to establish a receive time average.
97 /// </summary>
98 private int m_currentReceiveTimeSamples;
99
100 /// <summary>
101 /// Cumulative receive time for the sample so far.
102 /// </summary>
103 private int m_receiveTicksInCurrentSamplePeriod;
104
105 /// <summary>
106 /// The average time taken for each require receive in the last sample.
107 /// </summary>
108 public float AverageReceiveTicksForLastSamplePeriod { get; private set; }
109
110 /// <summary>
81 /// Default constructor 111 /// Default constructor
82 /// </summary> 112 /// </summary>
83 /// <param name="bindAddress">Local IP address to bind the server to</param> 113 /// <param name="bindAddress">Local IP address to bind the server to</param>
@@ -111,6 +141,8 @@ namespace OpenMetaverse
111 141
112 if (!IsRunningInbound) 142 if (!IsRunningInbound)
113 { 143 {
144 m_log.DebugFormat("[UDPBASE]: Starting inbound UDP loop");
145
114 const int SIO_UDP_CONNRESET = -1744830452; 146 const int SIO_UDP_CONNRESET = -1744830452;
115 147
116 IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort); 148 IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort);
@@ -151,6 +183,8 @@ namespace OpenMetaverse
151 /// </summary> 183 /// </summary>
152 public void StartOutbound() 184 public void StartOutbound()
153 { 185 {
186 m_log.DebugFormat("[UDPBASE]: Starting outbound UDP loop");
187
154 IsRunningOutbound = true; 188 IsRunningOutbound = true;
155 } 189 }
156 190
@@ -158,10 +192,8 @@ namespace OpenMetaverse
158 { 192 {
159 if (IsRunningInbound) 193 if (IsRunningInbound)
160 { 194 {
161 // wait indefinitely for a writer lock. Once this is called, the .NET runtime 195 m_log.DebugFormat("[UDPBASE]: Stopping inbound UDP loop");
162 // will deny any more reader locks, in effect blocking all other send/receive 196
163 // threads. Once we have the lock, we set IsRunningInbound = false to inform the other
164 // threads that the socket is closed.
165 IsRunningInbound = false; 197 IsRunningInbound = false;
166 m_udpSocket.Close(); 198 m_udpSocket.Close();
167 } 199 }
@@ -169,6 +201,8 @@ namespace OpenMetaverse
169 201
170 public void StopOutbound() 202 public void StopOutbound()
171 { 203 {
204 m_log.DebugFormat("[UDPBASE]: Stopping outbound UDP loop");
205
172 IsRunningOutbound = false; 206 IsRunningOutbound = false;
173 } 207 }
174 208
@@ -267,6 +301,8 @@ namespace OpenMetaverse
267 // to AsyncBeginReceive 301 // to AsyncBeginReceive
268 if (IsRunningInbound) 302 if (IsRunningInbound)
269 { 303 {
304 UdpReceives++;
305
270 // Asynchronous mode will start another receive before the 306 // Asynchronous mode will start another receive before the
271 // callback for this packet is even fired. Very parallel :-) 307 // callback for this packet is even fired. Very parallel :-)
272 if (m_asyncPacketHandling) 308 if (m_asyncPacketHandling)
@@ -278,6 +314,8 @@ namespace OpenMetaverse
278 314
279 try 315 try
280 { 316 {
317 int startTick = Util.EnvironmentTickCount();
318
281 // get the length of data actually read from the socket, store it with the 319 // get the length of data actually read from the socket, store it with the
282 // buffer 320 // buffer
283 buffer.DataLength = m_udpSocket.EndReceiveFrom(iar, ref buffer.RemoteEndPoint); 321 buffer.DataLength = m_udpSocket.EndReceiveFrom(iar, ref buffer.RemoteEndPoint);
@@ -285,6 +323,23 @@ namespace OpenMetaverse
285 // call the abstract method PacketReceived(), passing the buffer that 323 // call the abstract method PacketReceived(), passing the buffer that
286 // has just been filled from the socket read. 324 // has just been filled from the socket read.
287 PacketReceived(buffer); 325 PacketReceived(buffer);
326
327 // If more than one thread can be calling AsyncEndReceive() at once (e.g. if m_asyncPacketHandler)
328 // then a particular stat may be inaccurate due to a race condition. We won't worry about this
329 // since this should be rare and won't cause a runtime problem.
330 if (m_currentReceiveTimeSamples >= s_receiveTimeSamples)
331 {
332 AverageReceiveTicksForLastSamplePeriod
333 = (float)m_receiveTicksInCurrentSamplePeriod / s_receiveTimeSamples;
334
335 m_receiveTicksInCurrentSamplePeriod = 0;
336 m_currentReceiveTimeSamples = 0;
337 }
338 else
339 {
340 m_receiveTicksInCurrentSamplePeriod += Util.EnvironmentTickCountSubtract(startTick);
341 m_currentReceiveTimeSamples++;
342 }
288 } 343 }
289 catch (SocketException) { } 344 catch (SocketException) { }
290 catch (ObjectDisposedException) { } 345 catch (ObjectDisposedException) { }
@@ -298,14 +353,13 @@ namespace OpenMetaverse
298 if (!m_asyncPacketHandling) 353 if (!m_asyncPacketHandling)
299 AsyncBeginReceive(); 354 AsyncBeginReceive();
300 } 355 }
301
302 } 356 }
303 } 357 }
304 358
305 public void AsyncBeginSend(UDPPacketBuffer buf) 359 public void AsyncBeginSend(UDPPacketBuffer buf)
306 { 360 {
307 if (IsRunningOutbound) 361// if (IsRunningOutbound)
308 { 362// {
309 try 363 try
310 { 364 {
311 m_udpSocket.BeginSendTo( 365 m_udpSocket.BeginSendTo(
@@ -319,7 +373,7 @@ namespace OpenMetaverse
319 } 373 }
320 catch (SocketException) { } 374 catch (SocketException) { }
321 catch (ObjectDisposedException) { } 375 catch (ObjectDisposedException) { }
322 } 376// }
323 } 377 }
324 378
325 void AsyncEndSend(IAsyncResult result) 379 void AsyncEndSend(IAsyncResult result)
@@ -328,6 +382,8 @@ namespace OpenMetaverse
328 { 382 {
329// UDPPacketBuffer buf = (UDPPacketBuffer)result.AsyncState; 383// UDPPacketBuffer buf = (UDPPacketBuffer)result.AsyncState;
330 m_udpSocket.EndSendTo(result); 384 m_udpSocket.EndSendTo(result);
385
386 UdpSends++;
331 } 387 }
332 catch (SocketException) { } 388 catch (SocketException) { }
333 catch (ObjectDisposedException) { } 389 catch (ObjectDisposedException) { }