Skip to content

Commit cd5084a

Browse files
committed
Merge in 'release/7.0-rc1' changes
2 parents 60dae83 + 84b8f80 commit cd5084a

File tree

5 files changed

+48
-18
lines changed

5 files changed

+48
-18
lines changed

src/Servers/Kestrel/Transport.Quic/test/QuicConnectionContextTests.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,8 @@ public async Task StreamPool_StreamAbortedOnClient_NotPooled()
421421
public async Task StreamPool_StreamAbortedOnClientAndServer_NotPooled()
422422
{
423423
// Arrange
424+
using var httpEventSource = new HttpEventSourceListener(LoggerFactory);
425+
424426
await using var connectionListener = await QuicTestHelpers.CreateConnectionListenerFactory(LoggerFactory);
425427

426428
var options = QuicTestHelpers.CreateClientConnectionOptions(connectionListener.EndPoint);

src/Servers/Kestrel/Transport.Sockets/src/Internal/SocketConnection.cs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ internal sealed partial class SocketConnection : TransportConnection
3333

3434
internal SocketConnection(Socket socket,
3535
MemoryPool<byte> memoryPool,
36-
PipeScheduler transportScheduler,
36+
PipeScheduler socketScheduler,
3737
ILogger logger,
3838
SocketSenderPool socketSenderPool,
3939
PipeOptions inputOptions,
@@ -55,12 +55,7 @@ internal SocketConnection(Socket socket,
5555

5656
ConnectionClosed = _connectionClosedTokenSource.Token;
5757

58-
// On *nix platforms, Sockets already dispatches to the ThreadPool.
59-
// Yes, the IOQueues are still used for the PipeSchedulers. This is intentional.
60-
// https://github.com/aspnet/KestrelHttpServer/issues/2573
61-
var awaiterScheduler = OperatingSystem.IsWindows() ? transportScheduler : PipeScheduler.Inline;
62-
63-
_receiver = new SocketReceiver(awaiterScheduler);
58+
_receiver = new SocketReceiver(socketScheduler);
6459

6560
var pair = DuplexPipe.CreateConnectionPair(inputOptions, outputOptions);
6661

src/Servers/Kestrel/Transport.Sockets/src/SocketConnectionContextFactory.cs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,13 @@ public SocketConnectionContextFactory(SocketConnectionFactoryOptions options, IL
5656
{
5757
var memoryPool = _options.MemoryPoolFactory();
5858
var transportScheduler = options.UnsafePreferInlineScheduling ? PipeScheduler.Inline : new IOQueue();
59-
// https://github.com/aspnet/KestrelHttpServer/issues/2573
60-
var awaiterScheduler = OperatingSystem.IsWindows() ? transportScheduler : PipeScheduler.Inline;
6159

6260
_settings[i] = new QueueSettings()
6361
{
6462
Scheduler = transportScheduler,
6563
InputOptions = new PipeOptions(memoryPool, applicationScheduler, transportScheduler, maxReadBufferSize, maxReadBufferSize / 2, useSynchronizationContext: false),
6664
OutputOptions = new PipeOptions(memoryPool, transportScheduler, applicationScheduler, maxWriteBufferSize, maxWriteBufferSize / 2, useSynchronizationContext: false),
67-
SocketSenderPool = new SocketSenderPool(awaiterScheduler),
65+
SocketSenderPool = new SocketSenderPool(transportScheduler),
6866
MemoryPool = memoryPool,
6967
};
7068
}
@@ -73,16 +71,14 @@ public SocketConnectionContextFactory(SocketConnectionFactoryOptions options, IL
7371
{
7472
var memoryPool = _options.MemoryPoolFactory();
7573
var transportScheduler = options.UnsafePreferInlineScheduling ? PipeScheduler.Inline : PipeScheduler.ThreadPool;
76-
// https://github.com/aspnet/KestrelHttpServer/issues/2573
77-
var awaiterScheduler = OperatingSystem.IsWindows() ? transportScheduler : PipeScheduler.Inline;
7874
_settings = new QueueSettings[]
7975
{
8076
new QueueSettings()
8177
{
8278
Scheduler = transportScheduler,
8379
InputOptions = new PipeOptions(memoryPool, applicationScheduler, transportScheduler, maxReadBufferSize, maxReadBufferSize / 2, useSynchronizationContext: false),
8480
OutputOptions = new PipeOptions(memoryPool, transportScheduler, applicationScheduler, maxWriteBufferSize, maxWriteBufferSize / 2, useSynchronizationContext: false),
85-
SocketSenderPool = new SocketSenderPool(awaiterScheduler),
81+
SocketSenderPool = new SocketSenderPool(PipeScheduler.Inline),
8682
MemoryPool = memoryPool,
8783
}
8884
};
@@ -101,7 +97,7 @@ public ConnectionContext Create(Socket socket)
10197

10298
var connection = new SocketConnection(socket,
10399
setting.MemoryPool,
104-
setting.Scheduler,
100+
PipeScheduler.Inline,
105101
_logger,
106102
setting.SocketSenderPool,
107103
setting.InputOptions,
Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,37 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
using System.Net;
5+
using System.Net.Sockets;
46
using Microsoft.Extensions.Logging;
57

68
namespace Microsoft.AspNetCore.Testing;
79

810
public static class ServerRetryHelper
911
{
12+
private const int RetryCount = 10;
13+
1014
/// <summary>
1115
/// Retry a func. Useful when a test needs an explicit port and you want to avoid port conflicts.
1216
/// </summary>
1317
public static async Task BindPortsWithRetry(Func<int, Task> retryFunc, ILogger logger)
1418
{
19+
var ports = GetFreePorts(RetryCount);
20+
1521
var retryCount = 0;
1622
while (true)
1723
{
18-
// Approx dynamic port range on Windows and Linux.
19-
var randomPort = Random.Shared.Next(35000, 60000);
2024

2125
try
2226
{
23-
await retryFunc(randomPort);
27+
await retryFunc(ports[retryCount]);
2428
break;
2529
}
2630
catch (Exception ex)
2731
{
2832
retryCount++;
2933

30-
if (retryCount >= 5)
34+
if (retryCount >= RetryCount)
3135
{
3236
throw;
3337
}
@@ -38,4 +42,35 @@ public static async Task BindPortsWithRetry(Func<int, Task> retryFunc, ILogger l
3842
}
3943
}
4044
}
45+
46+
private static int[] GetFreePorts(int count)
47+
{
48+
var sockets = new List<Socket>();
49+
50+
for (var i = 0; i < count; i++)
51+
{
52+
// Find a port that's free by binding port 0.
53+
// Note that this port should be free when the test runs, but:
54+
// - Something else could steal it before the test uses it.
55+
// - UDP port with the same number could be in use.
56+
// For that reason, some retries should be available.
57+
var ipEndPoint = new IPEndPoint(IPAddress.Loopback, 0);
58+
var listenSocket = new Socket(ipEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
59+
60+
listenSocket.Bind(ipEndPoint);
61+
62+
sockets.Add(listenSocket);
63+
}
64+
65+
// Ports are calculated upfront. Rebinding with port 0 could result the same port
66+
// being returned for each retry.
67+
var ports = sockets.Select(s => (IPEndPoint)s.LocalEndPoint).Select(ep => ep.Port).ToArray();
68+
69+
foreach (var socket in sockets)
70+
{
71+
socket.Dispose();
72+
}
73+
74+
return ports;
75+
}
4176
}

src/Servers/Kestrel/test/Interop.FunctionalTests/Http3/Http3RequestTests.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,8 @@ public async Task GET_ServerStreaming_ClientReadsPartialResponse(HttpProtocols p
228228
public async Task POST_ClientSendsOnlyHeaders_RequestReceivedOnServer(HttpProtocols protocol)
229229
{
230230
// Arrange
231+
using var httpEventSource = new HttpEventSourceListener(LoggerFactory);
232+
231233
var builder = CreateHostBuilder(context =>
232234
{
233235
return Task.CompletedTask;

0 commit comments

Comments
 (0)