Move call to CopyFrom in SocketOutput.WriteAsync inside lock to make writes atomic

This commit is contained in:
Stephen Halter 2016-01-07 15:28:35 -08:00
parent 63e39a257e
commit e90b61e6c5
1 changed files with 20 additions and 15 deletions

View File

@ -83,19 +83,19 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
bool socketShutdownSend = false, bool socketShutdownSend = false,
bool socketDisconnect = false) bool socketDisconnect = false)
{ {
if (buffer.Count > 0)
{
var tail = ProducingStart();
tail.CopyFrom(buffer);
// We do our own accounting below
ProducingCompleteNoPreComplete(tail);
}
TaskCompletionSource<object> tcs = null; TaskCompletionSource<object> tcs = null;
var scheduleWrite = false; var scheduleWrite = false;
lock (_contextLock) lock (_contextLock)
{ {
if (buffer.Count > 0)
{
var tail = ProducingStart();
tail.CopyFrom(buffer);
// We do our own accounting below
ProducingCompleteNoPreComplete(tail);
}
if (_nextWriteContext == null) if (_nextWriteContext == null)
{ {
if (_writeContextPool.Count > 0) if (_writeContextPool.Count > 0)
@ -253,9 +253,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
// This is called on the libuv event loop // This is called on the libuv event loop
private void WriteAllPending() private void WriteAllPending()
{ {
WriteContext writingContext; WriteContext writingContext = null;
lock (_contextLock) if (Monitor.TryEnter(_contextLock))
{ {
_writePending = false; _writePending = false;
@ -264,13 +264,18 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
writingContext = _nextWriteContext; writingContext = _nextWriteContext;
_nextWriteContext = null; _nextWriteContext = null;
} }
else
{ Monitor.Exit(_contextLock);
return; }
} else
{
ScheduleWrite();
} }
writingContext.DoWriteIfNeeded(); if (writingContext != null)
{
writingContext.DoWriteIfNeeded();
}
} }
// This is called on the libuv event loop // This is called on the libuv event loop