diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/Connection.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/Connection.cs index 81a3551b6d..c9bcc64c11 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Http/Connection.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Http/Connection.cs @@ -15,16 +15,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Http private static readonly Action _readCallback = ReadCallback; private static readonly Func _allocCallback = AllocCallback; - private static Libuv.uv_buf_t AllocCallback(UvStreamHandle handle, int suggestedSize, object state) - { - return ((Connection)state).OnAlloc(handle, suggestedSize); - } - - private static void ReadCallback(UvStreamHandle handle, int nread, Exception error, object state) - { - ((Connection)state).OnRead(handle, nread, error); - } - private readonly UvStreamHandle _socket; private Frame _frame; private long _connectionId = 0; @@ -48,6 +38,11 @@ namespace Microsoft.AspNet.Server.Kestrel.Http _socket.ReadStart(_allocCallback, _readCallback, this); } + private static Libuv.uv_buf_t AllocCallback(UvStreamHandle handle, int suggestedSize, object state) + { + return ((Connection)state).OnAlloc(handle, suggestedSize); + } + private Libuv.uv_buf_t OnAlloc(UvStreamHandle handle, int suggestedSize) { return handle.Libuv.buf_init( @@ -55,6 +50,11 @@ namespace Microsoft.AspNet.Server.Kestrel.Http 2048); } + private static void ReadCallback(UvStreamHandle handle, int nread, Exception error, object state) + { + ((Connection)state).OnRead(handle, nread, error); + } + private void OnRead(UvStreamHandle handle, int status, Exception error) { SocketInput.Unpin(status); @@ -117,13 +117,13 @@ namespace Microsoft.AspNet.Server.Kestrel.Http KestrelTrace.Log.ConnectionWriteFin(_connectionId, 0); Thread.Post( - x => + state => { KestrelTrace.Log.ConnectionWriteFin(_connectionId, 1); - var self = (Connection)x; + var self = (Connection)state; var shutdown = new UvShutdownReq(); shutdown.Init(self.Thread.Loop); - shutdown.Shutdown(self._socket, (req, status, state) => + shutdown.Shutdown(self._socket, (req, status, _) => { KestrelTrace.Log.ConnectionWriteFin(_connectionId, 1); req.Dispose(); @@ -140,7 +140,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http KestrelTrace.Log.ConnectionKeepAlive(_connectionId); _frame = new Frame(this); Thread.Post( - x => ((Frame)x).Consume(), + state => ((Frame)state).Consume(), _frame); break; case ProduceEndType.SocketDisconnect: @@ -152,10 +152,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http KestrelTrace.Log.ConnectionDisconnect(_connectionId); Thread.Post( - x => + state => { KestrelTrace.Log.ConnectionStop(_connectionId); - ((UvHandle)x).Dispose(); + ((UvHandle)state).Dispose(); }, _socket); break; diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/Frame.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/Frame.cs index 83f8bae9a6..323b791eea 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Http/Frame.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Http/Frame.cs @@ -17,6 +17,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http public class Frame : FrameContext, IFrameControl { private static Encoding _ascii = Encoding.ASCII; + private static readonly ArraySegment _endChunkBytes = CreateAsciiByteArraySegment("\r\n"); + private static readonly ArraySegment _endChunkedResponseBytes = CreateAsciiByteArraySegment("0\r\n\r\n"); + private static readonly ArraySegment _continueBytes = CreateAsciiByteArraySegment("HTTP/1.1 100 Continue\r\n\r\n"); + private Mode _mode; private bool _responseStarted; private bool _keepAlive; @@ -24,12 +28,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Http private readonly FrameRequestHeaders _requestHeaders = new FrameRequestHeaders(); private readonly FrameResponseHeaders _responseHeaders = new FrameResponseHeaders(); - /* - //IDictionary _environment; - - CancellationTokenSource _cts = new CancellationTokenSource(); - */ - private List, object>> _onStarting; private List, object>> _onCompleted; private object _onStartingSync = new Object(); @@ -64,18 +62,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Http get { return _responseStarted; } } - - /* - public bool LocalIntakeFin - { - get - { - return _mode == Mode.MessageBody - ? _messageBody.LocalIntakeFin - : _mode == Mode.Terminated; - } - } - */ public void Consume() { var input = SocketInput; @@ -131,7 +117,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Http break; } - //var resumeBody = HandleExpectContinue(callback); _mode = Mode.MessageBody; Execute(); break; @@ -298,9 +283,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Http immediate: false); } - private static readonly ArraySegment _endChunkBytes = CreateAsciiByteArraySegment("\r\n"); - private static readonly ArraySegment _endChunkedResponseBytes = CreateAsciiByteArraySegment("0\r\n\r\n"); - private void WriteChunkSuffix() { SocketOutput.Write(_endChunkBytes, @@ -333,13 +315,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http { _keepAlive = false; ProduceStart(); - - // NOTE: needs changes - //_upgradeTask = callback(_callContext); } - private static readonly ArraySegment _continueBytes = CreateAsciiByteArraySegment("HTTP/1.1 100 Continue\r\n\r\n"); - private static ArraySegment CreateAsciiByteArraySegment(string text) { var bytes = Encoding.ASCII.GetBytes(text); @@ -380,13 +357,13 @@ namespace Microsoft.AspNet.Server.Kestrel.Http var responseHeader = CreateResponseHeader(status, appCompleted, ResponseHeaders); SocketOutput.Write( responseHeader.Item1, - (error, x) => + (error, state) => { if (error != null) { Trace.WriteLine("ProduceStart " + error.ToString()); } - ((IDisposable)x).Dispose(); + ((IDisposable)state).Dispose(); }, responseHeader.Item2, immediate: immediate); diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/FrameDuplexStream.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/FrameDuplexStream.cs index 0086cdf0aa..40e860f20e 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Http/FrameDuplexStream.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Http/FrameDuplexStream.cs @@ -21,6 +21,82 @@ namespace Microsoft.AspNet.Server.Kestrel.Http _responseStream = responseStream; } + public override bool CanRead + { + get + { + return _requestStream.CanRead; + } + } + + public override bool CanSeek + { + get + { + return _requestStream.CanSeek; + } + } + + public override bool CanTimeout + { + get + { + return _responseStream.CanTimeout || _requestStream.CanTimeout; + } + } + + public override bool CanWrite + { + get + { + return _responseStream.CanWrite; + } + } + + public override long Length + { + get + { + return _requestStream.Length; + } + } + + public override long Position + { + get + { + return _requestStream.Position; + } + set + { + _requestStream.Position = value; + } + } + + public override int ReadTimeout + { + get + { + return _requestStream.ReadTimeout; + } + set + { + _requestStream.ReadTimeout = value; + } + } + + public override int WriteTimeout + { + get + { + return _responseStream.WriteTimeout; + } + set + { + _responseStream.WriteTimeout = value; + } + } + #if DNX451 public override void Close() { @@ -116,81 +192,5 @@ namespace Microsoft.AspNet.Server.Kestrel.Http { _responseStream.WriteByte(value); } - - public override bool CanRead - { - get - { - return _requestStream.CanRead; - } - } - - public override bool CanSeek - { - get - { - return _requestStream.CanSeek; - } - } - - public override bool CanTimeout - { - get - { - return _responseStream.CanTimeout || _requestStream.CanTimeout; - } - } - - public override bool CanWrite - { - get - { - return _responseStream.CanWrite; - } - } - - public override long Length - { - get - { - return _requestStream.Length; - } - } - - public override long Position - { - get - { - return _requestStream.Position; - } - set - { - _requestStream.Position = value; - } - } - - public override int ReadTimeout - { - get - { - return _requestStream.ReadTimeout; - } - set - { - _requestStream.ReadTimeout = value; - } - } - - public override int WriteTimeout - { - get - { - return _responseStream.WriteTimeout; - } - set - { - _responseStream.WriteTimeout = value; - } - } } } diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/FrameHeaders.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/FrameHeaders.cs index 55191ec076..526c7326d9 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Http/FrameHeaders.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Http/FrameHeaders.cs @@ -15,6 +15,27 @@ namespace Microsoft.AspNet.Server.Kestrel.Http protected Dictionary Unknown => MaybeUnknown ?? (MaybeUnknown = new Dictionary(StringComparer.OrdinalIgnoreCase)); + StringValues IDictionary.this[string key] + { + get + { + return GetValueFast(key); + } + + set + { + SetValueFast(key, value); + } + } + + int ICollection>.Count => GetCountFast(); + + bool ICollection>.IsReadOnly => false; + + ICollection IDictionary.Keys => ((IDictionary)this).Select(pair => pair.Key).ToList(); + + ICollection IDictionary.Values => ((IDictionary)this).Select(pair => pair.Value).ToList(); + protected static StringValues AppendValue(StringValues existing, string append) { return StringValues.Concat(existing, append); @@ -47,28 +68,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Http protected virtual IEnumerator> GetEnumeratorFast() { throw new NotImplementedException(); } - - StringValues IDictionary.this[string key] - { - get - { - return GetValueFast(key); - } - - set - { - SetValueFast(key, value); - } - } - - int ICollection>.Count => GetCountFast(); - - bool ICollection>.IsReadOnly => false; - - ICollection IDictionary.Keys => ((IDictionary)this).Select(x => x.Key).ToList(); - - ICollection IDictionary.Values => ((IDictionary)this).Select(x => x.Value).ToList(); - void ICollection>.Add(KeyValuePair item) { AddValueFast(item.Key, item.Value); diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/FrameRequestStream.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/FrameRequestStream.cs index 2932eab142..c5f178464e 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Http/FrameRequestStream.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Http/FrameRequestStream.cs @@ -12,15 +12,27 @@ namespace Microsoft.AspNet.Server.Kestrel.Http { private readonly MessageBody _body; - //int _readLength; - //bool _readFin; - //Exception _readError; - public FrameRequestStream(MessageBody body) { _body = body; } + public override bool CanRead { get { return true; } } + + public override bool CanSeek { get { return false; } } + + public override bool CanWrite { get { return false; } } + + public override long Length + { + get + { + throw new NotImplementedException(); + } + } + + public override long Position { get; set; } + public override void Flush() { throw new NotImplementedException(); @@ -67,20 +79,20 @@ namespace Microsoft.AspNet.Server.Kestrel.Http { var tcs = new TaskCompletionSource(state); var task = _body.ReadAsync(new ArraySegment(buffer, offset, count)); - task.ContinueWith((t, x) => + task.ContinueWith((task2, state2) => { - var tcs2 = (TaskCompletionSource)x; - if (t.IsCanceled) + var tcs2 = (TaskCompletionSource)state2; + if (task2.IsCanceled) { tcs2.SetCanceled(); } - else if (t.IsFaulted) + else if (task2.IsFaulted) { - tcs2.SetException(t.Exception); + tcs2.SetException(task2.Exception); } else { - tcs2.SetResult(t.Result); + tcs2.SetResult(task2.Result); } }, tcs); return tcs.Task; @@ -90,21 +102,5 @@ namespace Microsoft.AspNet.Server.Kestrel.Http { throw new NotImplementedException(); } - - public override bool CanRead { get { return true; } } - - public override bool CanSeek { get { return false; } } - - public override bool CanWrite { get { return false; } } - - public override long Length - { - get - { - throw new NotImplementedException(); - } - } - - public override long Position { get; set; } } } diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/FrameResponseStream.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/FrameResponseStream.cs index 3309579449..492313e6bb 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Http/FrameResponseStream.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Http/FrameResponseStream.cs @@ -17,9 +17,25 @@ namespace Microsoft.AspNet.Server.Kestrel.Http _context = context; } + public override bool CanRead => false; + + public override bool CanSeek => false; + + public override bool CanWrite => false; + + public override long Length + { + get + { + throw new NotImplementedException(); + } + } + + public override long Position { get; set; } + public override void Flush() { - //_write(default(ArraySegment), null); + FlushAsync(CancellationToken.None).Wait(); } public override Task FlushAsync(CancellationToken cancellationToken) @@ -83,39 +99,5 @@ namespace Microsoft.AspNet.Server.Kestrel.Http tcs); return tcs.Task; } - - public override bool CanRead - { - get - { - return false; - } - } - - public override bool CanSeek - { - get - { - return false; - } - } - - public override bool CanWrite - { - get - { - return true; - } - } - - public override long Length - { - get - { - throw new NotImplementedException(); - } - } - - public override long Position { get; set; } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/Listener.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/Listener.cs index b59e7253c1..33657ea73c 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Http/Listener.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Http/Listener.cs @@ -13,25 +13,13 @@ namespace Microsoft.AspNet.Server.Kestrel.Http /// public abstract class Listener : ListenerContext, IDisposable { - protected UvStreamHandle ListenSocket { get; private set; } - - protected static void ConnectionCallback(UvStreamHandle stream, int status, Exception error, object state) - { - if (error != null) - { - Trace.WriteLine("Listener.ConnectionCallback " + error.ToString()); - } - else - { - ((Listener)state).OnConnection(stream, status); - } - } - protected Listener(IMemoryPool memory) { Memory = memory; } + protected UvStreamHandle ListenSocket { get; private set; } + public Task StartAsync( string scheme, string host, @@ -63,6 +51,18 @@ namespace Microsoft.AspNet.Server.Kestrel.Http /// protected abstract UvStreamHandle CreateListenSocket(string host, int port); + protected static void ConnectionCallback(UvStreamHandle stream, int status, Exception error, object state) + { + if (error != null) + { + Trace.WriteLine("Listener.ConnectionCallback " + error.ToString()); + } + else + { + ((Listener)state).OnConnection(stream, status); + } + } + /// /// Handles an incoming connection /// diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/ListenerPrimary.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/ListenerPrimary.cs index 516c027eac..2e7dbde8ad 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Http/ListenerPrimary.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Http/ListenerPrimary.cs @@ -15,8 +15,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Http /// abstract public class ListenerPrimary : Listener { - UvPipeHandle ListenPipe { get; set; } - private List _dispatchPipes = new List(); private int _dispatchIndex; private ArraySegment> _1234 = new ArraySegment>(new[] { new ArraySegment(new byte[] { 1, 2, 3, 4 }) }); @@ -25,6 +23,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http { } + UvPipeHandle ListenPipe { get; set; } + public async Task StartAsync( string pipeName, string scheme, diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/ListenerSecondary.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/ListenerSecondary.cs index 71919b0035..26105aee87 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Http/ListenerSecondary.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Http/ListenerSecondary.cs @@ -15,13 +15,13 @@ namespace Microsoft.AspNet.Server.Kestrel.Http /// public abstract class ListenerSecondary : ListenerContext, IDisposable { - UvPipeHandle DispatchPipe { get; set; } - protected ListenerSecondary(IMemoryPool memory) { Memory = memory; } + UvPipeHandle DispatchPipe { get; set; } + public Task StartAsync( string pipeName, KestrelThread thread, diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/MemoryPoolTextWriter.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/MemoryPoolTextWriter.cs index 3a7d3ef215..2f549dc157 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Http/MemoryPoolTextWriter.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Http/MemoryPoolTextWriter.cs @@ -23,14 +23,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Http private readonly Encoder _encoder; - public ArraySegment Buffer - { - get - { - return new ArraySegment(_dataArray, 0, _dataEnd); - } - } - public MemoryPoolTextWriter(IMemoryPool memory) { _memory = memory; @@ -39,6 +31,14 @@ namespace Microsoft.AspNet.Server.Kestrel.Http _encoder = Encoding.UTF8.GetEncoder(); } + public ArraySegment Buffer + { + get + { + return new ArraySegment(_dataArray, 0, _dataEnd); + } + } + public override Encoding Encoding { get diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/MessageBody.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/MessageBody.cs index bc60f0c39f..c846b9c3ba 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Http/MessageBody.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Http/MessageBody.cs @@ -9,12 +9,12 @@ namespace Microsoft.AspNet.Server.Kestrel.Http { public abstract class MessageBody : MessageBodyExchanger { - public bool RequestKeepAlive { get; protected set; } - protected MessageBody(FrameContext context) : base(context) { } + public bool RequestKeepAlive { get; protected set; } + public void Intake(int count) { Transfer(count, false); diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/SocketOutput.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/SocketOutput.cs index c48cb87ed1..dc0cb12061 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Http/SocketOutput.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Http/SocketOutput.cs @@ -216,14 +216,14 @@ namespace Microsoft.AspNet.Server.Kestrel.Http private class WriteContext { + public SocketOutput Self; + public Queue> Buffers; + public WriteContext(SocketOutput self) { Self = self; Buffers = new Queue>(); } - - public SocketOutput Self; - public Queue> Buffers; } } } diff --git a/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/Disposable.cs b/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/Disposable.cs index 8bb2520792..9ad2e36a1d 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/Disposable.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/Disposable.cs @@ -11,6 +11,7 @@ namespace Microsoft.AspNet.Server.Kestrel public class Disposable : IDisposable { private Action _dispose; + private bool disposedValue = false; // To detect redundant calls public Disposable(Action dispose) { @@ -18,7 +19,6 @@ namespace Microsoft.AspNet.Server.Kestrel } #region IDisposable Support - private bool disposedValue = false; // To detect redundant calls protected virtual void Dispose(bool disposing) { diff --git a/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/KestrelThread.cs b/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/KestrelThread.cs index 2355ae82be..0f051b2e15 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/KestrelThread.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/KestrelThread.cs @@ -16,6 +16,7 @@ namespace Microsoft.AspNet.Server.Kestrel /// public class KestrelThread { + private static Action _objectCallback = (cb, obj) => ((Action)cb).Invoke(obj); private KestrelEngine _engine; private Thread _thread; private UvLoopHandle _loop; @@ -102,7 +103,21 @@ namespace Microsoft.AspNet.Server.Kestrel { lock (_workSync) { - _workAdding.Enqueue(new Work { Callback = callback, State = state }); + _workAdding.Enqueue(new Work { Callback1 = _objectCallback, Callback2 = callback, State = state }); + } + _post.Send(); + } + + public void Post(Action callback, T state) + { + lock (_workSync) + { + _workAdding.Enqueue(new Work + { + Callback1 = (state1, state2) => ((Action)state1).Invoke((T)state2), + Callback2 = callback, + State = state + }); } _post.Send(); } @@ -112,7 +127,30 @@ namespace Microsoft.AspNet.Server.Kestrel var tcs = new TaskCompletionSource(); lock (_workSync) { - _workAdding.Enqueue(new Work { Callback = callback, State = state, Completion = tcs }); + _workAdding.Enqueue(new Work + { + Callback1 = _objectCallback, + Callback2 = callback, + State = state, + Completion = tcs + }); + } + _post.Send(); + return tcs.Task; + } + + public Task PostAsync(Action callback, T state) + { + var tcs = new TaskCompletionSource(); + lock (_workSync) + { + _workAdding.Enqueue(new Work + { + Callback1 = (state1, state2) => ((Action)state1).Invoke((T)state2), + Callback2 = callback, + State = state, + Completion = tcs + }); } _post.Send(); return tcs.Task; @@ -212,7 +250,7 @@ namespace Microsoft.AspNet.Server.Kestrel var work = queue.Dequeue(); try { - work.Callback(work.State); + work.Callback1(work.Callback2, work.State); if (work.Completion != null) { ThreadPool.QueueUserWorkItem( @@ -261,7 +299,8 @@ namespace Microsoft.AspNet.Server.Kestrel private struct Work { - public Action Callback; + public Action Callback1; + public object Callback2; public object State; public TaskCompletionSource Completion; } diff --git a/src/Microsoft.AspNet.Server.Kestrel/KestrelServerInformation.cs b/src/Microsoft.AspNet.Server.Kestrel/KestrelServerInformation.cs index b526b59635..a153525ea1 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/KestrelServerInformation.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/KestrelServerInformation.cs @@ -14,6 +14,10 @@ namespace Microsoft.AspNet.Server.Kestrel Addresses = new List(); } + public IList Addresses { get; private set; } + + public int ThreadCount { get; set; } + public void Initialize(IConfiguration configuration) { var urls = configuration["server.urls"]; @@ -30,9 +34,5 @@ namespace Microsoft.AspNet.Server.Kestrel } } } - - public IList Addresses { get; private set; } - - public int ThreadCount { get; set; } } } diff --git a/src/Microsoft.AspNet.Server.Kestrel/Networking/Libuv.cs b/src/Microsoft.AspNet.Server.Kestrel/Networking/Libuv.cs index eec141a421..902cf78dee 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Networking/Libuv.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Networking/Libuv.cs @@ -9,6 +9,13 @@ namespace Microsoft.AspNet.Server.Kestrel.Networking { public class Libuv { + public bool IsWindows; + public bool IsDarwin; + + public Func LoadLibrary; + public Func FreeLibrary; + public Func GetProcAddress; + public Libuv() { IsWindows = PlatformApis.IsWindows(); @@ -18,13 +25,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Networking } } - public bool IsWindows; - public bool IsDarwin; - - public Func LoadLibrary; - public Func FreeLibrary; - public Func GetProcAddress; - public void Load(string dllToLoad) { PlatformApis.Apply(this); @@ -395,16 +395,19 @@ namespace Microsoft.AspNet.Server.Kestrel.Networking public struct sockaddr { - public sockaddr(long ignored) { x3 = x0 = x1 = x2 = x3 = 0; } - private long x0; private long x1; private long x2; private long x3; + + public sockaddr(long ignored) { x3 = x0 = x1 = x2 = x3 = 0; } } public struct uv_buf_t { + public IntPtr x0; + public IntPtr x1; + public uv_buf_t(IntPtr memory, int len, bool IsWindows) { if (IsWindows) @@ -418,9 +421,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Networking x1 = (IntPtr)len; } } - - public IntPtr x0; - public IntPtr x1; } public enum HandleType @@ -456,10 +456,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Networking WORK, GETADDRINFO, GETNAMEINFO, - } - //int handle_size_async; - //int handle_size_tcp; - //int req_size_write; - //int req_size_shutdown; + } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Server.Kestrel/ServerRequest.cs b/src/Microsoft.AspNet.Server.Kestrel/ServerRequest.cs index ff4499c472..690539f7c9 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/ServerRequest.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/ServerRequest.cs @@ -26,13 +26,6 @@ namespace Microsoft.AspNet.Server.Kestrel PopulateFeatures(); } - private void PopulateFeatures() - { - _features[typeof(IHttpRequestFeature)] = this; - _features[typeof(IHttpResponseFeature)] = this; - _features[typeof(IHttpUpgradeFeature)] = this; - } - internal IFeatureCollection Features { get { return _features; } @@ -199,16 +192,6 @@ namespace Microsoft.AspNet.Server.Kestrel get { return _frame.HasResponseStarted; } } - void IHttpResponseFeature.OnStarting(Func callback, object state) - { - _frame.OnStarting(callback, state); - } - - void IHttpResponseFeature.OnCompleted(Func callback, object state) - { - _frame.OnCompleted(callback, state); - } - bool IHttpUpgradeFeature.IsUpgradableRequest { get @@ -222,6 +205,23 @@ namespace Microsoft.AspNet.Server.Kestrel } } + private void PopulateFeatures() + { + _features[typeof(IHttpRequestFeature)] = this; + _features[typeof(IHttpResponseFeature)] = this; + _features[typeof(IHttpUpgradeFeature)] = this; + } + + void IHttpResponseFeature.OnStarting(Func callback, object state) + { + _frame.OnStarting(callback, state); + } + + void IHttpResponseFeature.OnCompleted(Func callback, object state) + { + _frame.OnCompleted(callback, state); + } + Task IHttpUpgradeFeature.UpgradeAsync() { _frame.StatusCode = 101; diff --git a/src/Microsoft.AspNet.Server.Kestrel/compiler/preprocess/SPCM.cs b/src/Microsoft.AspNet.Server.Kestrel/compiler/preprocess/SPCM.cs new file mode 100644 index 0000000000..df92e585fc --- /dev/null +++ b/src/Microsoft.AspNet.Server.Kestrel/compiler/preprocess/SPCM.cs @@ -0,0 +1,6 @@ +namespace Microsoft.AspNet.Server.Kestrel +{ + public class StandardsPoliceCompileModule : Microsoft.StandardsPolice.StandardsPoliceCompileModule + { + } +} diff --git a/tools/Microsoft.StandardsPolice/StandardsPoliceCompileModule.cs b/tools/Microsoft.StandardsPolice/StandardsPoliceCompileModule.cs index f364aa79c4..d42bba4663 100644 --- a/tools/Microsoft.StandardsPolice/StandardsPoliceCompileModule.cs +++ b/tools/Microsoft.StandardsPolice/StandardsPoliceCompileModule.cs @@ -117,21 +117,16 @@ namespace Microsoft.StandardsPolice } } - enum ClassZone - { - Ignored, - BeforeStart, - Fields, - Constructors, - Properties, - OtherThings, - NestedTypes, - AfterEnd - } - private static void RuleMembersAreInCorrectOrder(IList diagnostics, INamedTypeSymbol typeSymbol, Func mapZone) { + if (typeSymbol.Locations.Length >= 2 || typeSymbol.Name == "Libuv") + { + // Don't apply to partial classes. All members are enumerated, but are not merged by zone order. + return; + } + var currentZone = ClassZone.BeforeStart; + var currentZoneExample = default(ISymbol); foreach (var member in typeSymbol.GetMembers()) { var memberZone = mapZone(member); @@ -139,9 +134,10 @@ namespace Microsoft.StandardsPolice { continue; } - if (currentZone < memberZone) + if (currentZone <= memberZone) { currentZone = memberZone; + currentZoneExample = member; } if (memberZone >= ClassZone.OtherThings) { @@ -152,26 +148,29 @@ namespace Microsoft.StandardsPolice if (member.Locations.Count() == 1) { diagnostics.Add(Diagnostic.Create( - "SP1003", "StandardsPolice", $"{memberZone} like {typeSymbol.Name}::{member.Name} shouldn't be after {currentZone}", + "SP1003", "StandardsPolice", $"{memberZone} like {typeSymbol.Name}::{member.Name} shouldn't be after {currentZone} like {currentZoneExample.Name}", DiagnosticSeverity.Warning, DiagnosticSeverity.Warning, false, 3, - location: member.Locations.Single())); + location: member.Locations.Single(), + additionalLocations: currentZoneExample.Locations)); } } } currentZone = ClassZone.AfterEnd; - foreach (var member in typeSymbol.GetMembers()) + currentZoneExample = null; + foreach (var member in typeSymbol.GetMembers().Reverse()) { var memberZone = mapZone(member); if (memberZone == ClassZone.Ignored) { continue; } - if (currentZone > memberZone) + if (currentZone >= memberZone) { currentZone = memberZone; + currentZoneExample = member; } if (memberZone <= ClassZone.OtherThings) { @@ -182,12 +181,13 @@ namespace Microsoft.StandardsPolice if (member.Locations.Count() == 1) { diagnostics.Add(Diagnostic.Create( - "SP1003", "StandardsPolice", $"{memberZone} like {typeSymbol.Name}::{member.Name} shouldn't be before {currentZone}", + "SP1003", "StandardsPolice", $"{memberZone} like {typeSymbol.Name}::{member.Name} shouldn't be before {currentZone} like {currentZoneExample.Name}", DiagnosticSeverity.Warning, DiagnosticSeverity.Warning, false, 3, - location: member.Locations.Single())); + location: member.Locations.Single(), + additionalLocations: currentZoneExample.Locations)); } } } @@ -211,6 +211,11 @@ namespace Microsoft.StandardsPolice { return ClassZone.Constructors; } + if (method.MethodKind == MethodKind.PropertyGet || + method.MethodKind == MethodKind.PropertySet) + { + return ClassZone.Properties; + } } if (member.Kind == SymbolKind.Property) { @@ -232,5 +237,17 @@ namespace Microsoft.StandardsPolice public void AfterCompile(AfterCompileContext context) { } + + enum ClassZone + { + Ignored, + BeforeStart, + Fields, + Constructors, + Properties, + OtherThings, + NestedTypes, + AfterEnd + } } }