From 836be5565abdf455dfe4103f53fddbd882bee000 Mon Sep 17 00:00:00 2001 From: Louis DeJardin Date: Tue, 8 Jul 2014 14:51:13 -0700 Subject: [PATCH] Using weak gchandles from native to managed See #15 --- .../Http/Connection.cs | 2 +- .../KestrelEngine.cs | 2 +- .../Networking/UvMemory.cs | 4 +-- .../Networking/UvStreamHandle.cs | 32 +++++++++++++++---- 4 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/Connection.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/Connection.cs index 32ca223b97..b159b251f1 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Http/Connection.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Http/Connection.cs @@ -95,8 +95,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http else if (normalDone || errorDone) { KestrelTrace.Log.ConnectionReadFin(_connectionId); - SocketInput.RemoteIntakeFin = true; + _socket.ReadStop(); if (errorDone && error != null) { diff --git a/src/Microsoft.AspNet.Server.Kestrel/KestrelEngine.cs b/src/Microsoft.AspNet.Server.Kestrel/KestrelEngine.cs index dec882350c..3e2b01985b 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/KestrelEngine.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/KestrelEngine.cs @@ -79,7 +79,7 @@ namespace Microsoft.AspNet.Server.Kestrel { foreach (var thread in Threads) { - thread.Stop(TimeSpan.FromSeconds(45)); + thread.Stop(TimeSpan.FromSeconds(2.5)); } Threads.Clear(); } diff --git a/src/Microsoft.AspNet.Server.Kestrel/Networking/UvMemory.cs b/src/Microsoft.AspNet.Server.Kestrel/Networking/UvMemory.cs index 6000c82ebb..e43e600ec3 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Networking/UvMemory.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Networking/UvMemory.cs @@ -36,7 +36,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Networking _threadId = Thread.CurrentThread.ManagedThreadId; handle = Marshal.AllocCoTaskMem(size); - *(IntPtr*)handle = GCHandle.ToIntPtr(GCHandle.Alloc(this)); + *(IntPtr*)handle = GCHandle.ToIntPtr(GCHandle.Alloc(this, GCHandleType.Weak)); } protected void CreateHandle(UvLoopHandle loop, int size) @@ -54,7 +54,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Networking { Trace.Assert(closed || !IsClosed, "Handle is closed"); Trace.Assert(!IsInvalid, "Handle is invalid"); - Trace.Assert(_threadId == Thread.CurrentThread.ManagedThreadId, "ThreadId is correct"); + Trace.Assert(_threadId == Thread.CurrentThread.ManagedThreadId, "ThreadId is incorrect"); } unsafe protected static void DestroyHandle(IntPtr memory) diff --git a/src/Microsoft.AspNet.Server.Kestrel/Networking/UvStreamHandle.cs b/src/Microsoft.AspNet.Server.Kestrel/Networking/UvStreamHandle.cs index 9249b53104..ecde6e08e3 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Networking/UvStreamHandle.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Networking/UvStreamHandle.cs @@ -3,6 +3,7 @@ using System; using System.Diagnostics; +using System.Runtime.InteropServices; namespace Microsoft.AspNet.Server.Kestrel.Networking { @@ -12,19 +13,33 @@ namespace Microsoft.AspNet.Server.Kestrel.Networking private readonly static Libuv.uv_alloc_cb _uv_alloc_cb = UvAllocCb; private readonly static Libuv.uv_read_cb _uv_read_cb = UvReadCb; - public Action _connectionCallback; - public object _connectionState; + public Action _listenCallback; + public object _listenState; + private GCHandle _listenVitality; public Func _allocCallback; - public Action _readCallback; public object _readState; + private GCHandle _readVitality; + protected override bool ReleaseHandle() + { + if (_listenVitality.IsAllocated) + { + _listenVitality.Free(); + } + if (_readVitality.IsAllocated) + { + _readVitality.Free(); + } + return base.ReleaseHandle(); + } public void Listen(int backlog, Action callback, object state) { - _connectionCallback = callback; - _connectionState = state; + _listenCallback = callback; + _listenState = state; + _listenVitality = GCHandle.Alloc(this, GCHandleType.Normal); _uv.listen(this, 10, _uv_connection_cb); } @@ -41,11 +56,16 @@ namespace Microsoft.AspNet.Server.Kestrel.Networking _allocCallback = allocCallback; _readCallback = readCallback; _readState = state; + _readVitality = GCHandle.Alloc(this, GCHandleType.Normal); _uv.read_start(this, _uv_alloc_cb, _uv_read_cb); } public void ReadStop() { + _allocCallback = null; + _readCallback = null; + _readState = null; + _readVitality.Free(); _uv.read_stop(this); } @@ -64,7 +84,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Networking try { - stream._connectionCallback(stream, status, error, stream._connectionState); + stream._listenCallback(stream, status, error, stream._listenState); } catch (Exception ex) {