Ensure libuv handles get disposed properly after binding errors

This commit is contained in:
Stephen Halter 2016-07-22 12:26:13 -07:00
parent 0e7967a7fc
commit 27f8c8dca2
7 changed files with 59 additions and 22 deletions

View File

@ -3,6 +3,7 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Server.Kestrel.Internal.Infrastructure;
using Microsoft.AspNetCore.Server.Kestrel.Internal.Networking;
using Microsoft.Extensions.Logging;
@ -38,6 +39,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http
{
var listener = ((Listener)tcs2.Task.AsyncState);
listener.ListenSocket = listener.CreateListenSocket();
ListenSocket.Listen(Constants.ListenBacklog, ConnectionCallback, this);
tcs2.SetResult(0);
}
catch (Exception ex)
@ -54,7 +56,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http
/// </summary>
protected abstract UvStreamHandle CreateListenSocket();
protected static void ConnectionCallback(UvStreamHandle stream, int status, Exception error, object state)
private static void ConnectionCallback(UvStreamHandle stream, int status, Exception error, object state)
{
var listener = (Listener)state;

View File

@ -70,10 +70,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http
}
var dispatchPipe = new UvPipeHandle(Log);
dispatchPipe.Init(Thread.Loop, Thread.QueueCloseHandle, true);
try
{
dispatchPipe.Init(Thread.Loop, Thread.QueueCloseHandle, true);
pipe.Accept(dispatchPipe);
}
catch (UvException ex)

View File

@ -1,7 +1,6 @@
// 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.AspNetCore.Server.Kestrel.Internal.Infrastructure;
using Microsoft.AspNetCore.Server.Kestrel.Internal.Networking;
using Microsoft.Extensions.Logging;
@ -22,9 +21,18 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http
protected override UvStreamHandle CreateListenSocket()
{
var socket = new UvPipeHandle(Log);
socket.Init(Thread.Loop, Thread.QueueCloseHandle, false);
socket.Bind(ServerAddress.UnixPipePath);
socket.Listen(Constants.ListenBacklog, (stream, status, error, state) => ConnectionCallback(stream, status, error, state), this);
try
{
socket.Init(Thread.Loop, Thread.QueueCloseHandle, false);
socket.Bind(ServerAddress.UnixPipePath);
}
catch
{
socket.Dispose();
throw;
}
return socket;
}

View File

@ -22,9 +22,18 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http
protected override UvStreamHandle CreateListenSocket()
{
var socket = new UvPipeHandle(Log);
socket.Init(Thread.Loop, Thread.QueueCloseHandle, false);
socket.Bind(ServerAddress.UnixPipePath);
socket.Listen(Constants.ListenBacklog, (stream, status, error, state) => ConnectionCallback(stream, status, error, state), this);
try
{
socket.Init(Thread.Loop, Thread.QueueCloseHandle, false);
socket.Bind(ServerAddress.UnixPipePath);
}
catch
{
socket.Dispose();
throw;
}
return socket;
}

View File

@ -583,7 +583,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http
_writeReq = Self._writeReqPool.Allocate();
_writeReq.Write(Self._socket, _lockedStart, _lockedEnd, _bufferCount, (_writeReq, status, error, state) =>
_writeReq.Write(Self._socket, _lockedStart, _lockedEnd, _bufferCount, (req, status, error, state) =>
{
var writeContext = (WriteContext)state;
writeContext.PoolWriteReq(writeContext._writeReq);

View File

@ -1,6 +1,7 @@
// 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 System;
using Microsoft.AspNetCore.Server.Kestrel.Internal.Infrastructure;
using Microsoft.AspNetCore.Server.Kestrel.Internal.Networking;
using Microsoft.Extensions.Logging;
@ -22,14 +23,22 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http
protected override UvStreamHandle CreateListenSocket()
{
var socket = new UvTcpHandle(Log);
socket.Init(Thread.Loop, Thread.QueueCloseHandle);
socket.NoDelay(ServerOptions.NoDelay);
socket.Bind(ServerAddress);
// If requested port was "0", replace with assigned dynamic port.
ServerAddress.Port = socket.GetSockIPEndPoint().Port;
try
{
socket.Init(Thread.Loop, Thread.QueueCloseHandle);
socket.NoDelay(ServerOptions.NoDelay);
socket.Bind(ServerAddress);
// If requested port was "0", replace with assigned dynamic port.
ServerAddress.Port = socket.GetSockIPEndPoint().Port;
}
catch
{
socket.Dispose();
throw;
}
socket.Listen(Constants.ListenBacklog, (stream, status, error, state) => ConnectionCallback(stream, status, error, state), this);
return socket;
}

View File

@ -1,6 +1,7 @@
// 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 System;
using Microsoft.AspNetCore.Server.Kestrel.Internal.Infrastructure;
using Microsoft.AspNetCore.Server.Kestrel.Internal.Networking;
using Microsoft.Extensions.Logging;
@ -22,14 +23,22 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http
protected override UvStreamHandle CreateListenSocket()
{
var socket = new UvTcpHandle(Log);
socket.Init(Thread.Loop, Thread.QueueCloseHandle);
socket.NoDelay(ServerOptions.NoDelay);
socket.Bind(ServerAddress);
// If requested port was "0", replace with assigned dynamic port.
ServerAddress.Port = socket.GetSockIPEndPoint().Port;
try
{
socket.Init(Thread.Loop, Thread.QueueCloseHandle);
socket.NoDelay(ServerOptions.NoDelay);
socket.Bind(ServerAddress);
// If requested port was "0", replace with assigned dynamic port.
ServerAddress.Port = socket.GetSockIPEndPoint().Port;
}
catch
{
socket.Dispose();
throw;
}
socket.Listen(Constants.ListenBacklog, (stream, status, error, state) => ConnectionCallback(stream, status, error, state), this);
return socket;
}