ListenerSecondary - reduce closure allocation

This commit is contained in:
Ben Adams 2015-11-01 14:10:59 +00:00
parent facf3ad0da
commit 34c1a671f0
1 changed files with 102 additions and 83 deletions

View File

@ -17,6 +17,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
/// </summary> /// </summary>
public abstract class ListenerSecondary : ListenerContext, IDisposable public abstract class ListenerSecondary : ListenerContext, IDisposable
{ {
private string _pipeName;
protected ListenerSecondary(ServiceContext serviceContext) : base(serviceContext) protected ListenerSecondary(ServiceContext serviceContext) : base(serviceContext)
{ {
} }
@ -29,14 +31,25 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
KestrelThread thread, KestrelThread thread,
RequestDelegate application) RequestDelegate application)
{ {
_pipeName = pipeName;
ServerAddress = address; ServerAddress = address;
Thread = thread; Thread = thread;
Application = application; Application = application;
DispatchPipe = new UvPipeHandle(Log); DispatchPipe = new UvPipeHandle(Log);
var tcs = new TaskCompletionSource<int>(); var tcs = new TaskCompletionSource<int>(this);
Thread.Post(_ => Thread.Post(tcs2 => StartCallback(tcs2), tcs);
return tcs.Task;
}
private static void StartCallback(TaskCompletionSource<int> tcs)
{
var listener = (ListenerSecondary)tcs.Task.AsyncState;
listener.StartedCallback(tcs);
}
private void StartedCallback(TaskCompletionSource<int> tcs)
{ {
try try
{ {
@ -45,8 +58,23 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
connect.Init(Thread.Loop); connect.Init(Thread.Loop);
connect.Connect( connect.Connect(
DispatchPipe, DispatchPipe,
pipeName, _pipeName,
(connect2, status, error, state) => (connect2, status, error, state) => ConnectCallback(connect2, status, error, (TaskCompletionSource<int>)state),
tcs);
}
catch (Exception ex)
{
DispatchPipe.Dispose();
tcs.SetException(ex);
}
}
private static void ConnectCallback(UvConnectRequest connect, int status, Exception error, TaskCompletionSource<int> tcs)
{
var listener = (ListenerSecondary)tcs.Task.AsyncState;
listener.ConnectedCallback(connect, status, error, tcs);
}
private void ConnectedCallback(UvConnectRequest connect, int status, Exception error, TaskCompletionSource<int> tcs)
{ {
connect.Dispose(); connect.Dispose();
if (error != null) if (error != null)
@ -61,15 +89,26 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
var buf = Thread.Loop.Libuv.buf_init(ptr, 4); var buf = Thread.Loop.Libuv.buf_init(ptr, 4);
DispatchPipe.ReadStart( DispatchPipe.ReadStart(
(_1, _2, _3) => buf, (handle, status2, state) => buf,
(_1, status2, state2) => (handle, status2, state) => ((ListenerSecondary)state).ReadStartCallback(handle, status2, ptr), this);
tcs.SetResult(0);
}
catch (Exception ex)
{ {
if (status2 < 0) DispatchPipe.Dispose();
tcs.SetException(ex);
}
}
private void ReadStartCallback(UvStreamHandle handle, int status, IntPtr ptr)
{ {
if (status2 != Constants.EOF) if (status < 0)
{
if (status != Constants.EOF)
{ {
Exception ex; Exception ex;
Thread.Loop.Libuv.Check(status2, out ex); Thread.Loop.Libuv.Check(status, out ex);
Log.LogError("DispatchPipe.ReadStart", ex); Log.LogError("DispatchPipe.ReadStart", ex);
} }
@ -98,26 +137,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
var connection = new Connection(this, acceptSocket); var connection = new Connection(this, acceptSocket);
connection.Start(); connection.Start();
},
null);
tcs.SetResult(0);
}
catch (Exception ex)
{
DispatchPipe.Dispose();
tcs.SetException(ex);
}
},
null);
}
catch (Exception ex)
{
DispatchPipe.Dispose();
tcs.SetException(ex);
}
}, null);
return tcs.Task;
} }
/// <summary> /// <summary>
@ -133,7 +152,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
// the exception that stopped the event loop will never be surfaced. // the exception that stopped the event loop will never be surfaced.
if (Thread.FatalError == null) if (Thread.FatalError == null)
{ {
Thread.Send(_ => DispatchPipe.Dispose(), null); Thread.Send(listener => ((ListenerSecondary)listener).DispatchPipe.Dispose(), this);
} }
} }
} }