From eb8f860bd6428ad3dda40f819ff2a7d3389f7c79 Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Sat, 26 Dec 2015 15:07:00 +0000 Subject: [PATCH 1/2] Avoid generic boxing in Post --- .../Infrastructure/KestrelThread.cs | 47 +++++++++++++++++-- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/KestrelThread.cs b/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/KestrelThread.cs index de603b4458..4974ba7a9f 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/KestrelThread.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/KestrelThread.cs @@ -9,6 +9,7 @@ using System.Threading.Tasks; using Microsoft.AspNet.Hosting; using Microsoft.AspNet.Server.Kestrel.Infrastructure; using Microsoft.AspNet.Server.Kestrel.Networking; +using Microsoft.AspNet.Server.Kestrel.Http; using Microsoft.Extensions.Logging; namespace Microsoft.AspNet.Server.Kestrel @@ -24,6 +25,11 @@ namespace Microsoft.AspNet.Server.Kestrel private const int _maxLoops = 8; private static Action _threadCallbackAdapter = (callback, state) => ((Action)callback).Invoke((KestrelThread)state); + private static Action _socketCallbackAdapter = (callback, state) => ((Action)callback).Invoke((SocketOutput)state); + private static Action _tcsCallbackAdapter = (callback, state) => ((Action>)callback).Invoke((TaskCompletionSource)state); + private static Action _listenerPrimaryCallbackAdapter = (callback, state) => ((Action)callback).Invoke((ListenerPrimary)state); + private static Action _listenerSecondaryCallbackAdapter = (callback, state) => ((Action)callback).Invoke((ListenerSecondary)state); + private KestrelEngine _engine; private readonly IApplicationLifetime _appLifetime; private Thread _thread; @@ -144,13 +150,13 @@ namespace Microsoft.AspNet.Server.Kestrel _post.Send(); } - public void Post(Action callback, T state) + public void Post(Action callback, SocketOutput state) { lock (_workSync) { _workAdding.Enqueue(new Work { - CallbackAdapter = (callback2, state2) => ((Action)callback2).Invoke((T)state2), + CallbackAdapter = _socketCallbackAdapter, Callback = callback, State = state }); @@ -158,14 +164,28 @@ namespace Microsoft.AspNet.Server.Kestrel _post.Send(); } - public Task PostAsync(Action callback, T state) + public void Post(Action> callback, TaskCompletionSource state) + { + lock (_workSync) + { + _workAdding.Enqueue(new Work + { + CallbackAdapter = _tcsCallbackAdapter, + Callback = callback, + State = state + }); + } + _post.Send(); + } + + public Task PostAsync(Action callback, ListenerPrimary state) { var tcs = new TaskCompletionSource(); lock (_workSync) { _workAdding.Enqueue(new Work { - CallbackAdapter = (state1, state2) => ((Action)state1).Invoke((T)state2), + CallbackAdapter = _listenerPrimaryCallbackAdapter, Callback = callback, State = state, Completion = tcs @@ -175,7 +195,24 @@ namespace Microsoft.AspNet.Server.Kestrel return tcs.Task; } - public void Send(Action callback, T state) + public Task PostAsync(Action callback, ListenerSecondary state) + { + var tcs = new TaskCompletionSource(); + lock (_workSync) + { + _workAdding.Enqueue(new Work + { + CallbackAdapter = _listenerSecondaryCallbackAdapter, + Callback = callback, + State = state, + Completion = tcs + }); + } + _post.Send(); + return tcs.Task; + } + + public void Send(Action callback, ListenerSecondary state) { if (_loop.ThreadId == Thread.CurrentThread.ManagedThreadId) { From 982ab99b45c044952d3e060642fb56d12dbe994b Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Mon, 28 Dec 2015 23:02:41 +0000 Subject: [PATCH 2/2] Make callback adapters readonly --- .../Infrastructure/KestrelThread.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/KestrelThread.cs b/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/KestrelThread.cs index 4974ba7a9f..4769d62d6e 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/KestrelThread.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/KestrelThread.cs @@ -24,11 +24,11 @@ namespace Microsoft.AspNet.Server.Kestrel // otherwise it needs to wait till the next pass of the libuv loop private const int _maxLoops = 8; - private static Action _threadCallbackAdapter = (callback, state) => ((Action)callback).Invoke((KestrelThread)state); - private static Action _socketCallbackAdapter = (callback, state) => ((Action)callback).Invoke((SocketOutput)state); - private static Action _tcsCallbackAdapter = (callback, state) => ((Action>)callback).Invoke((TaskCompletionSource)state); - private static Action _listenerPrimaryCallbackAdapter = (callback, state) => ((Action)callback).Invoke((ListenerPrimary)state); - private static Action _listenerSecondaryCallbackAdapter = (callback, state) => ((Action)callback).Invoke((ListenerSecondary)state); + private static readonly Action _threadCallbackAdapter = (callback, state) => ((Action)callback).Invoke((KestrelThread)state); + private static readonly Action _socketCallbackAdapter = (callback, state) => ((Action)callback).Invoke((SocketOutput)state); + private static readonly Action _tcsCallbackAdapter = (callback, state) => ((Action>)callback).Invoke((TaskCompletionSource)state); + private static readonly Action _listenerPrimaryCallbackAdapter = (callback, state) => ((Action)callback).Invoke((ListenerPrimary)state); + private static readonly Action _listenerSecondaryCallbackAdapter = (callback, state) => ((Action)callback).Invoke((ListenerSecondary)state); private KestrelEngine _engine; private readonly IApplicationLifetime _appLifetime;