Prevent pipes from being closed prematurely on OS X and Linux
This change fixes the in-process marshalling of TCP handles on Mac and Linux that is used to support having multiple threads accepting connections from multiple loops. On these two platforms, the ReadStart callback somtimes gets called with a status and pipe_pending_count equal to zero. Now when the status is zero just exit the callback without closing the pipe. This change more closely follows the example at https://nikhilm.github.io/uvbook/processes.html#sending-file-descriptors-over-pipes
This commit is contained in:
parent
8a6495364e
commit
2041e4d08b
|
|
@ -3,15 +3,13 @@
|
|||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.AspNet.Server.Kestrel.Infrastructure;
|
||||
using Microsoft.AspNet.Server.Kestrel.Networking;
|
||||
|
||||
namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||
{
|
||||
public class Connection : ConnectionContext, IConnectionControl
|
||||
{
|
||||
private const int EOF = -4095;
|
||||
private const int ECONNRESET = -4077;
|
||||
|
||||
private static readonly Action<UvStreamHandle, int, Exception, object> _readCallback = ReadCallback;
|
||||
private static readonly Func<UvStreamHandle, int, object, Libuv.uv_buf_t> _allocCallback = AllocCallback;
|
||||
|
||||
|
|
@ -60,7 +58,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
SocketInput.Unpin(status);
|
||||
|
||||
var normalRead = error == null && status > 0;
|
||||
var normalDone = status == 0 || status == ECONNRESET || status == EOF;
|
||||
var normalDone = status == 0 || status == Constants.ECONNRESET || status == Constants.EOF;
|
||||
var errorDone = !(normalDone || normalRead);
|
||||
|
||||
if (normalRead)
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.Server.Kestrel.Networking;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Server.Kestrel.Infrastructure;
|
||||
using Microsoft.AspNet.Server.Kestrel.Networking;
|
||||
|
||||
namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||
{
|
||||
|
|
@ -60,13 +61,26 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
(_1, _2, _3) => buf,
|
||||
(_1, status2, error2, state2) =>
|
||||
{
|
||||
if (status2 == 0)
|
||||
if (status2 < 0)
|
||||
{
|
||||
if (status2 != Constants.EOF)
|
||||
{
|
||||
Exception ex;
|
||||
Thread.Loop.Libuv.Check(status2, out ex);
|
||||
// TODO: Replace Trace.WriteLine with real logging
|
||||
Trace.WriteLine("DispatchPipe.ReadStart " + ex.Message);
|
||||
}
|
||||
|
||||
DispatchPipe.Dispose();
|
||||
Marshal.FreeHGlobal(ptr);
|
||||
return;
|
||||
}
|
||||
|
||||
if (DispatchPipe.PendingCount() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var acceptSocket = CreateAcceptSocket();
|
||||
|
||||
try
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Infrastructure
|
|||
{
|
||||
public const int ListenBacklog = 128;
|
||||
|
||||
public const int EOF = -4095;
|
||||
public const int ECONNRESET = -4077;
|
||||
|
||||
/// <summary>
|
||||
/// Prefix of host name used to specify Unix sockets in the configuration.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -252,6 +252,15 @@ namespace Microsoft.AspNet.Server.Kestrel.Networking
|
|||
Check(_uv_pipe_connect(req, handle, name, cb));
|
||||
}
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
unsafe protected delegate int uv_pipe_pending_count(UvPipeHandle handle);
|
||||
protected uv_pipe_pending_count _uv_pipe_pending_count = default(uv_pipe_pending_count);
|
||||
unsafe public int pipe_pending_count(UvPipeHandle handle)
|
||||
{
|
||||
handle.Validate();
|
||||
return _uv_pipe_pending_count(handle);
|
||||
}
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void uv_alloc_cb(IntPtr server, int suggested_size, out uv_buf_t buf);
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
|
|
|
|||
|
|
@ -32,5 +32,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Networking
|
|||
{
|
||||
_uv.pipe_bind(this, name);
|
||||
}
|
||||
|
||||
public int PendingCount()
|
||||
{
|
||||
return _uv.pipe_pending_count(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue