Don't allocate Exceptions unnecessarily
- Allocate Exceptions in the ReadStart callbacks if necessary instead of in UvStreamHandle. - This also fixes a bug in ListenerSecondary where it should have previously been looking at the error code instead of the read count. #237
This commit is contained in:
parent
8e818e3549
commit
c809beec18
|
|
@ -13,7 +13,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
{
|
||||
public class Connection : ConnectionContext, IConnectionControl
|
||||
{
|
||||
private static readonly Action<UvStreamHandle, int, int, Exception, object> _readCallback = ReadCallback;
|
||||
private static readonly Action<UvStreamHandle, int, object> _readCallback = ReadCallback;
|
||||
private static readonly Func<UvStreamHandle, int, object, Libuv.uv_buf_t> _allocCallback = AllocCallback;
|
||||
|
||||
private static long _lastConnectionId;
|
||||
|
|
@ -113,28 +113,34 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
result.Data.Count);
|
||||
}
|
||||
|
||||
private static void ReadCallback(UvStreamHandle handle, int readCount, int errorCode, Exception error, object state)
|
||||
private static void ReadCallback(UvStreamHandle handle, int status, object state)
|
||||
{
|
||||
((Connection)state).OnRead(handle, readCount, errorCode, error);
|
||||
((Connection)state).OnRead(handle, status);
|
||||
}
|
||||
|
||||
private void OnRead(UvStreamHandle handle, int readCount, int errorCode, Exception error)
|
||||
private void OnRead(UvStreamHandle handle, int status)
|
||||
{
|
||||
var normalRead = readCount != 0 && errorCode == 0;
|
||||
var normalDone = readCount == 0 && (errorCode == 0 || errorCode == Constants.ECONNRESET || errorCode == Constants.EOF);
|
||||
var normalRead = status > 0;
|
||||
var normalDone = status == 0 || status == Constants.ECONNRESET || status == Constants.EOF;
|
||||
var errorDone = !(normalDone || normalRead);
|
||||
var readCount = normalRead ? status : 0;
|
||||
|
||||
if (normalRead)
|
||||
{
|
||||
Log.ConnectionRead(_connectionId, readCount);
|
||||
}
|
||||
else if (normalDone || errorDone)
|
||||
else
|
||||
{
|
||||
_socket.ReadStop();
|
||||
Log.ConnectionReadFin(_connectionId);
|
||||
}
|
||||
|
||||
_rawSocketInput.IncomingComplete(readCount, errorDone ? error : null);
|
||||
Exception error = null;
|
||||
if (errorDone)
|
||||
{
|
||||
handle.Libuv.Check(status, out error);
|
||||
}
|
||||
_rawSocketInput.IncomingComplete(readCount, error);
|
||||
}
|
||||
|
||||
void IConnectionControl.Pause()
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
|
||||
DispatchPipe.ReadStart(
|
||||
(_1, _2, _3) => buf,
|
||||
(_1, status2, errCode, error2, state2) =>
|
||||
(_1, status2, state2) =>
|
||||
{
|
||||
if (status2 < 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Infrastructure
|
|||
|
||||
void ConnectionStop(long connectionId);
|
||||
|
||||
void ConnectionRead(long connectionId, int status);
|
||||
void ConnectionRead(long connectionId, int count);
|
||||
|
||||
void ConnectionPause(long connectionId);
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Networking
|
|||
private GCHandle _listenVitality;
|
||||
|
||||
public Func<UvStreamHandle, int, object, Libuv.uv_buf_t> _allocCallback;
|
||||
public Action<UvStreamHandle, int, int, Exception, object> _readCallback;
|
||||
public Action<UvStreamHandle, int, object> _readCallback;
|
||||
public object _readState;
|
||||
private GCHandle _readVitality;
|
||||
|
||||
|
|
@ -72,13 +72,14 @@ namespace Microsoft.AspNet.Server.Kestrel.Networking
|
|||
|
||||
public void ReadStart(
|
||||
Func<UvStreamHandle, int, object, Libuv.uv_buf_t> allocCallback,
|
||||
Action<UvStreamHandle, int, int, Exception, object> readCallback,
|
||||
Action<UvStreamHandle, int, object> readCallback,
|
||||
object state)
|
||||
{
|
||||
if (_readVitality.IsAllocated)
|
||||
{
|
||||
throw new InvalidOperationException("TODO: ReadStop must be called before ReadStart may be called again");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_allocCallback = allocCallback;
|
||||
|
|
@ -118,7 +119,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Networking
|
|||
return _uv.try_write(this, new[] { buf }, 1);
|
||||
}
|
||||
|
||||
|
||||
private static void UvConnectionCb(IntPtr handle, int status)
|
||||
{
|
||||
var stream = FromIntPtr<UvStreamHandle>(handle);
|
||||
|
|
@ -137,7 +137,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Networking
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private static void UvAllocCb(IntPtr handle, int suggested_size, out Libuv.uv_buf_t buf)
|
||||
{
|
||||
var stream = FromIntPtr<UvStreamHandle>(handle);
|
||||
|
|
@ -153,22 +152,13 @@ namespace Microsoft.AspNet.Server.Kestrel.Networking
|
|||
}
|
||||
}
|
||||
|
||||
private static void UvReadCb(IntPtr handle, int nread, ref Libuv.uv_buf_t buf)
|
||||
private static void UvReadCb(IntPtr handle, int status, ref Libuv.uv_buf_t buf)
|
||||
{
|
||||
var stream = FromIntPtr<UvStreamHandle>(handle);
|
||||
|
||||
try
|
||||
{
|
||||
if (nread < 0)
|
||||
{
|
||||
Exception error;
|
||||
stream._uv.Check(nread, out error);
|
||||
stream._readCallback(stream, 0, nread, error, stream._readState);
|
||||
}
|
||||
else
|
||||
{
|
||||
stream._readCallback(stream, nread, 0, null, stream._readState);
|
||||
}
|
||||
stream._readCallback(stream, status, stream._readState);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
|||
connect.Dispose();
|
||||
clientConnectionPipe.ReadStart(
|
||||
(_3, cb, _4) => buf,
|
||||
(_3, status2, errCode, error2, _4) =>
|
||||
(_3, status2, _4) =>
|
||||
{
|
||||
if (status2 == 0)
|
||||
{
|
||||
|
|
@ -213,7 +213,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
|||
|
||||
clientConnectionPipe.ReadStart(
|
||||
(_3, cb, _4) => buf,
|
||||
(_3, status2, errCode2, error2, _4) =>
|
||||
(_3, status2, _4) =>
|
||||
{
|
||||
if (status2 == 0)
|
||||
{
|
||||
|
|
@ -226,7 +226,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
|||
var buf2 = loop2.Libuv.buf_init(Marshal.AllocHGlobal(64), 64);
|
||||
clientConnectionTcp.ReadStart(
|
||||
(_5, cb, _6) => buf2,
|
||||
(_5, status3, errCode3, error3, _6) =>
|
||||
(_5, status3, _6) =>
|
||||
{
|
||||
if (status3 == 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -129,7 +129,6 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
|||
[Fact]
|
||||
public async Task SocketCanRead()
|
||||
{
|
||||
int bytesRead = 0;
|
||||
var loop = new UvLoopHandle(_logger);
|
||||
loop.Init(_uv);
|
||||
var tcp = new UvTcpHandle(_logger);
|
||||
|
|
@ -145,10 +144,9 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
|||
var data = Marshal.AllocCoTaskMem(500);
|
||||
tcp2.ReadStart(
|
||||
(a, b, c) => _uv.buf_init(data, 500),
|
||||
(__, nread, errCode, error2, state2) =>
|
||||
(__, nread, state2) =>
|
||||
{
|
||||
bytesRead += nread;
|
||||
if (nread == 0)
|
||||
if (nread <= 0)
|
||||
{
|
||||
tcp2.Dispose();
|
||||
}
|
||||
|
|
@ -186,7 +184,6 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
|||
[Fact]
|
||||
public async Task SocketCanReadAndWrite()
|
||||
{
|
||||
int bytesRead = 0;
|
||||
var loop = new UvLoopHandle(_logger);
|
||||
loop.Init(_uv);
|
||||
var tcp = new UvTcpHandle(_logger);
|
||||
|
|
@ -202,10 +199,9 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
|||
var data = Marshal.AllocCoTaskMem(500);
|
||||
tcp2.ReadStart(
|
||||
(a, b, c) => tcp2.Libuv.buf_init(data, 500),
|
||||
(__, nread, errCode, error2, state2) =>
|
||||
(__, nread, state2) =>
|
||||
{
|
||||
bytesRead += nread;
|
||||
if (nread == 0)
|
||||
if (nread <= 0)
|
||||
{
|
||||
tcp2.Dispose();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue