Prevent double-close race condition in ListenHandleTests.CanListenToOpenTcpSocketHandle() (#2666)

This commit is contained in:
Mike Harder 2018-06-14 12:50:03 -07:00 committed by GitHub
parent 13663e1e15
commit 35d9590f3c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 20 additions and 14 deletions

View File

@ -14,16 +14,23 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
[OSSkipCondition(OperatingSystems.Windows, SkipReason = "Listening to open TCP socket and/or pipe handles is not supported on Windows.")] [OSSkipCondition(OperatingSystems.Windows, SkipReason = "Listening to open TCP socket and/or pipe handles is not supported on Windows.")]
public class ListenHandleTests : LoggedTest public class ListenHandleTests : LoggedTest
{ {
// The Socket.Handle will be passed into libuv, which calls close() on the file descriptor when TestServer is disposed. If
// the managed Socket is also disposed or finalized, it will try to call close() again on the file descriptor, which may lead to
// race condition bugs (test hangs) if the file descriptor has been re-used for another resource. In .NET Core, objects
// assigned to static fields should never be disposed or finalized (even at process shutdown).
// https://github.com/aspnet/KestrelHttpServer/issues/2597
private static readonly Socket _canListenToOpenTcpSocketHandleSocket =
new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
[ConditionalFact] [ConditionalFact]
public async Task CanListenToOpenTcpSocketHandle() public async Task CanListenToOpenTcpSocketHandle()
{ {
using (var listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) _canListenToOpenTcpSocketHandleSocket.Bind(new IPEndPoint(IPAddress.Loopback, 0));
{
listenSocket.Bind(new IPEndPoint(IPAddress.Loopback, 0));
using (var server = new TestServer(_ => Task.CompletedTask, new TestServiceContext(LoggerFactory), new ListenOptions((ulong)listenSocket.Handle))) using (var server = new TestServer(_ => Task.CompletedTask, new TestServiceContext(LoggerFactory),
new ListenOptions((ulong)_canListenToOpenTcpSocketHandleSocket.Handle)))
{ {
using (var connection = new TestConnection(((IPEndPoint)listenSocket.LocalEndPoint).Port)) using (var connection = new TestConnection(((IPEndPoint)_canListenToOpenTcpSocketHandleSocket.LocalEndPoint).Port))
{ {
await connection.SendEmptyGet(); await connection.SendEmptyGet();
@ -38,4 +45,3 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
} }
} }
} }
}