private Int32 MonoDataSocketReceiveWhatsAvaiable(Byte[] buffer, Int32 offset, Int32 size)
{
this.StartTimeoutTimer();
try
{
IAsyncResult lAsyncResult = this.BeginMonoSslRead(buffer, offset, size);
Int32 lBytesRead;
// Manual timeout management
// Timeout is increased to avoid racing conditions loops
Int32 lTimeout = this.Timeout * 1000 + MONO_TIMEOUT_SHIFT_PERIOD;
while (true)
{
Int32 lCurrentTimeout = Math.Min(MONO_TIMEOUT_POLL_PERIOD, lTimeout);
lTimeout -= lCurrentTimeout;
if (lAsyncResult.AsyncWaitHandle.WaitOne(lCurrentTimeout))
{
lBytesRead = this.EndMonoSslRead(lAsyncResult);
break;
}
if (!this.Connected)
{
throw new SocketException();
}
if (lTimeout == 0)
{
// We got a timeout here
this.DataSocketClose();
throw new SocketException();
}
}
// Say 'Hi!' to Mono bugs
if (lBytesRead < 0)
{
throw new SocketException();
}
return lBytesRead;
}
catch (IOException)
{
throw new SocketException();
}
finally
{
this.StopTimeoutTimer();
}
}