http server receiver: go back to simpler and lighter Beginread/endread. async/await is still just a slower wrapper around it, with more unpredictable side effects

This commit is contained in:
UbitUmarov
2021-01-05 22:14:51 +00:00
parent 582ce9e380
commit fa26f37a17

View File

@@ -207,8 +207,15 @@ namespace OSHttpServer
/// </remarks>
public virtual void Start()
{
Task tk = new Task(() => ReceiveLoop());
tk.Start();
try
{
m_stream.BeginRead(m_ReceiveBuffer, 0, m_ReceiveBuffer.Length, OnReceive, null);
}
catch (IOException err)
{
LogWriter.Write(this, LogPrio.Debug, err.ToString());
}
//Task.Run(async () => await ReceiveLoop()).ConfigureAwait(false);
}
/// <summary>
@@ -341,7 +348,105 @@ namespace OSHttpServer
}
}
private async void ReceiveLoop()
private void OnReceive(IAsyncResult ar)
{
try
{
int bytesRead = 0;
if (m_stream == null)
return;
try
{
bytesRead = m_stream.EndRead(ar);
}
catch (NullReferenceException)
{
Disconnect(SocketError.ConnectionReset);
return;
}
if (bytesRead == 0)
{
Disconnect(SocketError.Success);
return;
}
if (m_isClosing)
return;
m_ReceiveBytesLeft += bytesRead;
int offset = m_parser.Parse(m_ReceiveBuffer, 0, m_ReceiveBytesLeft);
if (m_stream == null)
return; // "Connection: Close" in effect.
while (offset != 0)
{
int nextBytesleft = m_ReceiveBytesLeft - offset;
if (nextBytesleft <= 0)
break;
int nextOffset = m_parser.Parse(m_ReceiveBuffer, offset, nextBytesleft);
if (m_stream == null)
return; // "Connection: Close" in effect.
if (nextOffset == 0)
break;
offset = nextOffset;
}
// copy unused bytes to the beginning of the array
if (offset > 0 && m_ReceiveBytesLeft > offset)
Buffer.BlockCopy(m_ReceiveBuffer, offset, m_ReceiveBuffer, 0, m_ReceiveBytesLeft - offset);
m_ReceiveBytesLeft -= offset;
if (StreamPassedOff)
return; //?
m_stream.BeginRead(m_ReceiveBuffer, m_ReceiveBytesLeft, m_ReceiveBuffer.Length - m_ReceiveBytesLeft, OnReceive, null);
}
catch (BadRequestException err)
{
LogWriter.Write(this, LogPrio.Warning, "Bad request, responding with it. Error: " + err);
try
{
Respond("HTTP/1.1", HttpStatusCode.BadRequest, err.Message);
}
catch (Exception err2)
{
LogWriter.Write(this, LogPrio.Fatal, "Failed to reply to a bad request. " + err2);
}
//Disconnect(SocketError.NoRecovery);
Disconnect(SocketError.Success); // try to flush
}
catch (IOException err)
{
LogWriter.Write(this, LogPrio.Debug, "Failed to end receive: " + err.Message);
if (err.InnerException is SocketException)
Disconnect((SocketError)((SocketException)err.InnerException).ErrorCode);
else
Disconnect(SocketError.ConnectionReset);
}
catch (ObjectDisposedException err)
{
LogWriter.Write(this, LogPrio.Debug, "Failed to end receive : " + err.Message);
Disconnect(SocketError.NotSocket);
}
catch (NullReferenceException err)
{
LogWriter.Write(this, LogPrio.Debug, "Failed to end receive : NullRef: " + err.Message);
Disconnect(SocketError.NoRecovery);
}
catch (Exception err)
{
LogWriter.Write(this, LogPrio.Debug, "Failed to end receive: " + err.Message);
Disconnect(SocketError.NoRecovery);
}
}
/*
private async Task ReceiveLoop()
{
m_ReceiveBytesLeft = 0;
try
@@ -432,6 +537,7 @@ namespace OSHttpServer
Disconnect(SocketError.NoRecovery);
}
}
*/
private void OnRequestCompleted(object source, EventArgs args)
{