mirror of
https://github.com/opensim/opensim.git
synced 2026-07-31 05:45:37 +08:00
avoid a old potencial stack overflow
This commit is contained in:
@@ -328,114 +328,116 @@ namespace OpenMetaverse
|
||||
|
||||
private void AsyncBeginReceive()
|
||||
{
|
||||
if (!IsRunningInbound)
|
||||
return;
|
||||
|
||||
UDPPacketBuffer buf = GetNewUDPBuffer(new IPEndPoint(IPAddress.Any, 0)); // we need a fresh one here, for now at least
|
||||
try
|
||||
while(IsRunningInbound)
|
||||
{
|
||||
// kick off an async read
|
||||
m_udpSocket.BeginReceiveFrom(
|
||||
buf.Data,
|
||||
0,
|
||||
buf.Data.Length,
|
||||
SocketFlags.None,
|
||||
ref buf.RemoteEndPoint,
|
||||
AsyncEndReceive,
|
||||
buf);
|
||||
}
|
||||
catch (SocketException e)
|
||||
{
|
||||
if (e.SocketErrorCode == SocketError.ConnectionReset)
|
||||
UDPPacketBuffer buf = GetNewUDPBuffer(new IPEndPoint(IPAddress.Any, 0)); // we need a fresh one here, for now at least
|
||||
try
|
||||
{
|
||||
m_log.Warn("[UDPBASE]: SIO_UDP_CONNRESET was ignored, attempting to salvage the UDP listener on port " + m_udpPort);
|
||||
bool salvaged = false;
|
||||
while (!salvaged)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_udpSocket.BeginReceiveFrom(
|
||||
buf.Data,
|
||||
0,
|
||||
buf.Data.Length,
|
||||
SocketFlags.None,
|
||||
ref buf.RemoteEndPoint,
|
||||
AsyncEndReceive,
|
||||
buf);
|
||||
salvaged = true;
|
||||
}
|
||||
catch (SocketException) { }
|
||||
catch (ObjectDisposedException) { return; }
|
||||
}
|
||||
// kick off an async read
|
||||
IAsyncResult iar = m_udpSocket.BeginReceiveFrom(
|
||||
buf.Data,
|
||||
0,
|
||||
buf.Data.Length,
|
||||
SocketFlags.None,
|
||||
ref buf.RemoteEndPoint,
|
||||
AsyncEndReceive,
|
||||
buf);
|
||||
|
||||
m_log.Warn("[UDPBASE]: Salvaged the UDP listener on port " + m_udpPort);
|
||||
if (!iar.CompletedSynchronously)
|
||||
return;
|
||||
}
|
||||
catch (SocketException e)
|
||||
{
|
||||
if (e.SocketErrorCode == SocketError.ConnectionReset)
|
||||
{
|
||||
m_log.Warn("[UDPBASE]: SIO_UDP_CONNRESET was ignored, attempting to salvage the UDP listener on port " + m_udpPort);
|
||||
{
|
||||
try
|
||||
{
|
||||
IAsyncResult iar = m_udpSocket.BeginReceiveFrom(
|
||||
buf.Data,
|
||||
0,
|
||||
buf.Data.Length,
|
||||
SocketFlags.None,
|
||||
ref buf.RemoteEndPoint,
|
||||
AsyncEndReceive,
|
||||
buf);
|
||||
|
||||
if (!iar.CompletedSynchronously)
|
||||
return;
|
||||
}
|
||||
catch (SocketException) { }
|
||||
catch (ObjectDisposedException) { return; }
|
||||
}
|
||||
m_log.Warn("[UDPBASE]: Salvaged the UDP listener on port " + m_udpPort);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(
|
||||
string.Format("[UDPBASE]: Error processing UDP begin receive {0}. Exception ", UdpReceives), e);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(
|
||||
string.Format("[UDPBASE]: Error processing UDP begin receive {0}. Exception ", UdpReceives), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void AsyncEndReceive(IAsyncResult iar)
|
||||
{
|
||||
// Asynchronous receive operations will complete here through the call
|
||||
// to AsyncBeginReceive
|
||||
if (IsRunningInbound)
|
||||
bool sync = iar.CompletedSynchronously;
|
||||
try
|
||||
{
|
||||
// get the buffer that was created in AsyncBeginReceive
|
||||
// this is the received data
|
||||
UDPPacketBuffer buffer = (UDPPacketBuffer)iar.AsyncState;
|
||||
|
||||
int startTick = Util.EnvironmentTickCount();
|
||||
|
||||
// get the length of data actually read from the socket, store it with the
|
||||
// buffer
|
||||
buffer.DataLength = m_udpSocket.EndReceiveFrom(iar, ref buffer.RemoteEndPoint);
|
||||
|
||||
if(!IsRunningInbound)
|
||||
return;
|
||||
|
||||
UdpReceives++;
|
||||
|
||||
try
|
||||
|
||||
// call the abstract method PacketReceived(), passing the buffer that
|
||||
// has just been filled from the socket read.
|
||||
PacketReceived(buffer);
|
||||
|
||||
// If more than one thread can be calling AsyncEndReceive() at once (e.g. if m_asyncPacketHandler)
|
||||
// then a particular stat may be inaccurate due to a race condition. We won't worry about this
|
||||
// since this should be rare and won't cause a runtime problem.
|
||||
if (m_currentReceiveTimeSamples >= s_receiveTimeSamples)
|
||||
{
|
||||
// get the buffer that was created in AsyncBeginReceive
|
||||
// this is the received data
|
||||
UDPPacketBuffer buffer = (UDPPacketBuffer)iar.AsyncState;
|
||||
AverageReceiveTicksForLastSamplePeriod
|
||||
= (float)m_receiveTicksInCurrentSamplePeriod / s_receiveTimeSamples;
|
||||
|
||||
int startTick = Util.EnvironmentTickCount();
|
||||
|
||||
// get the length of data actually read from the socket, store it with the
|
||||
// buffer
|
||||
buffer.DataLength = m_udpSocket.EndReceiveFrom(iar, ref buffer.RemoteEndPoint);
|
||||
|
||||
// call the abstract method PacketReceived(), passing the buffer that
|
||||
// has just been filled from the socket read.
|
||||
PacketReceived(buffer);
|
||||
|
||||
// If more than one thread can be calling AsyncEndReceive() at once (e.g. if m_asyncPacketHandler)
|
||||
// then a particular stat may be inaccurate due to a race condition. We won't worry about this
|
||||
// since this should be rare and won't cause a runtime problem.
|
||||
if (m_currentReceiveTimeSamples >= s_receiveTimeSamples)
|
||||
{
|
||||
AverageReceiveTicksForLastSamplePeriod
|
||||
= (float)m_receiveTicksInCurrentSamplePeriod / s_receiveTimeSamples;
|
||||
|
||||
m_receiveTicksInCurrentSamplePeriod = 0;
|
||||
m_currentReceiveTimeSamples = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_receiveTicksInCurrentSamplePeriod += Util.EnvironmentTickCountSubtract(startTick);
|
||||
m_currentReceiveTimeSamples++;
|
||||
}
|
||||
m_receiveTicksInCurrentSamplePeriod = 0;
|
||||
m_currentReceiveTimeSamples = 0;
|
||||
}
|
||||
catch (SocketException se)
|
||||
else
|
||||
{
|
||||
m_log.Error(
|
||||
string.Format(
|
||||
"[UDPBASE]: Error processing UDP end receive {0}, socket error code {1}. Exception ",
|
||||
UdpReceives, se.ErrorCode),
|
||||
se);
|
||||
m_receiveTicksInCurrentSamplePeriod += Util.EnvironmentTickCountSubtract(startTick);
|
||||
m_currentReceiveTimeSamples++;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(
|
||||
string.Format("[UDPBASE]: Error processing UDP end receive {0}. Exception ", UdpReceives), e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
}
|
||||
catch (SocketException se)
|
||||
{
|
||||
m_log.Error(
|
||||
string.Format(
|
||||
"[UDPBASE]: Error processing UDP end receive {0}, socket error code {1}. Exception ",
|
||||
UdpReceives, se.ErrorCode),
|
||||
se);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(
|
||||
string.Format("[UDPBASE]: Error processing UDP end receive {0}. Exception ", UdpReceives), e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if(IsRunningInbound && !sync)
|
||||
AsyncBeginReceive();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user