Remove race condition from socket input that could stall reads
- Without the _sync lock, if new data was produced as ConsumingComplete was called, the next "await SocketInput" might never complete despite not all data being examined. - If more data is produced afterward, the stall would be prevented, but this isn't always the case such as during the end of the request.
This commit is contained in:
parent
850632a091
commit
84a68208d0
|
|
@ -28,6 +28,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
|
|||
private MemoryPoolBlock _pinned;
|
||||
|
||||
private int _consumingState;
|
||||
private object _sync = new object();
|
||||
|
||||
public SocketInput(MemoryPool memory, IThreadPool threadPool)
|
||||
{
|
||||
|
|
@ -57,6 +58,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
|
|||
}
|
||||
|
||||
public void IncomingData(byte[] buffer, int offset, int count)
|
||||
{
|
||||
lock (_sync)
|
||||
{
|
||||
if (count > 0)
|
||||
{
|
||||
|
|
@ -82,8 +85,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
|
|||
|
||||
Complete();
|
||||
}
|
||||
}
|
||||
|
||||
public void IncomingComplete(int count, Exception error)
|
||||
{
|
||||
lock (_sync)
|
||||
{
|
||||
if (_pinned != null)
|
||||
{
|
||||
|
|
@ -117,6 +123,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
|
|||
|
||||
Complete();
|
||||
}
|
||||
}
|
||||
|
||||
public void IncomingDeferred()
|
||||
{
|
||||
|
|
@ -161,6 +168,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
|
|||
public void ConsumingComplete(
|
||||
MemoryPoolIterator consumed,
|
||||
MemoryPoolIterator examined)
|
||||
{
|
||||
lock (_sync)
|
||||
{
|
||||
MemoryPoolBlock returnStart = null;
|
||||
MemoryPoolBlock returnEnd = null;
|
||||
|
|
@ -198,6 +207,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
|
|||
throw new InvalidOperationException("No ongoing consuming operation to complete.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void CompleteAwaiting()
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue