Skip to content

Commit f6e1bf0

Browse files
committed
(squashed) revert generated P/Invoke layer
1 parent 8adff2c commit f6e1bf0

File tree

67 files changed

+2531
-1050
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+2531
-1050
lines changed

src/Servers/HttpSys/perf/Microbenchmarks/RequestHeaderBenchmarks.cs

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
using System.Text;
77
using BenchmarkDotNet.Attributes;
88
using Microsoft.AspNetCore.HttpSys.Internal;
9-
using Windows.Win32.Foundation;
10-
using Windows.Win32.Networking.HttpServer;
119
using RequestHeaders = Microsoft.AspNetCore.HttpSys.Internal.RequestHeaders;
1210

1311
[SimpleJob, MemoryDiagnoser]
@@ -56,7 +54,7 @@ private unsafe RequestHeaders CreateRequestHeader(int unknowHeaderCount)
5654
var nativeContext = new NativeRequestContext(MemoryPool<byte>.Shared, null, 0, false);
5755
var nativeMemory = new Span<byte>(nativeContext.NativeRequest, (int)nativeContext.Size + 8);
5856

59-
var requestStructure = new HTTP_REQUEST_V1();
57+
var requestStructure = new HttpApiTypes.HTTP_REQUEST();
6058
var remainingMemory = SetUnknownHeaders(nativeMemory, ref requestStructure, GenerateUnknownHeaders(unknowHeaderCount));
6159
SetHostHeader(remainingMemory, ref requestStructure);
6260
MemoryMarshal.Write(nativeMemory, in requestStructure);
@@ -66,64 +64,64 @@ private unsafe RequestHeaders CreateRequestHeader(int unknowHeaderCount)
6664
return requestHeaders;
6765
}
6866

69-
private unsafe Span<byte> SetHostHeader(Span<byte> nativeMemory, ref HTTP_REQUEST_V1 requestStructure)
67+
private unsafe Span<byte> SetHostHeader(Span<byte> nativeMemory, ref HttpApiTypes.HTTP_REQUEST requestStructure)
7068
{
7169
// Writing localhost to Host header
72-
var dataDestination = nativeMemory[Marshal.SizeOf<HTTP_REQUEST_V1>()..];
73-
var length = Encoding.ASCII.GetBytes("localhost:5001", dataDestination);
70+
var dataDestination = nativeMemory.Slice(Marshal.SizeOf<HttpApiTypes.HTTP_REQUEST>());
71+
int length = Encoding.ASCII.GetBytes("localhost:5001", dataDestination);
7472
fixed (byte* address = &MemoryMarshal.GetReference(dataDestination))
7573
{
76-
requestStructure.Headers.KnownHeaders._28.pRawValue = (PCSTR)address;
77-
requestStructure.Headers.KnownHeaders._28.RawValueLength = (ushort)length;
74+
requestStructure.Headers.KnownHeaders_29.pRawValue = address;
75+
requestStructure.Headers.KnownHeaders_29.RawValueLength = (ushort)length;
7876
}
7977
return dataDestination;
8078
}
8179

8280
/// <summary>
8381
/// Writes an array HTTP_UNKNOWN_HEADER and an array of header key-value pairs to nativeMemory. Pointers in the HTTP_UNKNOWN_HEADER structure points to the corresponding key-value pair.
8482
/// </summary>
85-
private unsafe Span<byte> SetUnknownHeaders(Span<byte> nativeMemory, ref HTTP_REQUEST_V1 requestStructure, IReadOnlyCollection<(string Key, string Value)> headerNames)
83+
private unsafe Span<byte> SetUnknownHeaders(Span<byte> nativeMemory, ref HttpApiTypes.HTTP_REQUEST requestStructure, IReadOnlyCollection<(string Key, string Value)> headerNames)
8684
{
87-
var unknownHeaderStructureDestination = nativeMemory[Marshal.SizeOf<HTTP_REQUEST_V1>()..];
85+
var unknownHeaderStructureDestination = nativeMemory.Slice(Marshal.SizeOf<HttpApiTypes.HTTP_REQUEST>());
8886
fixed (byte* address = &MemoryMarshal.GetReference(unknownHeaderStructureDestination))
8987
{
90-
requestStructure.Headers.pUnknownHeaders = (HTTP_UNKNOWN_HEADER*)address;
88+
requestStructure.Headers.pUnknownHeaders = (HttpApiTypes.HTTP_UNKNOWN_HEADER*)address;
9189
}
9290
requestStructure.Headers.UnknownHeaderCount += (ushort)headerNames.Count;
9391

94-
var unknownHeadersSize = Marshal.SizeOf<HTTP_UNKNOWN_HEADER>();
95-
var dataDestination = unknownHeaderStructureDestination[(unknownHeadersSize * headerNames.Count)..];
96-
foreach (var (headerKey, headerValue) in headerNames)
92+
var unknownHeadersSize = Marshal.SizeOf<HttpApiTypes.HTTP_UNKNOWN_HEADER>();
93+
var dataDestination = unknownHeaderStructureDestination.Slice(unknownHeadersSize * headerNames.Count);
94+
foreach (var headerName in headerNames)
9795
{
98-
var unknownHeaderStructure = new HTTP_UNKNOWN_HEADER();
99-
var nameLength = Encoding.ASCII.GetBytes(headerKey, dataDestination);
96+
var unknownHeaderStructure = new HttpApiTypes.HTTP_UNKNOWN_HEADER();
97+
int nameLength = Encoding.ASCII.GetBytes(headerName.Key, dataDestination);
10098
fixed (byte* address = &MemoryMarshal.GetReference(dataDestination))
10199
{
102-
unknownHeaderStructure.pName = (PCSTR)address;
100+
unknownHeaderStructure.pName = address;
103101
unknownHeaderStructure.NameLength = (ushort)nameLength;
104102
}
105-
dataDestination = dataDestination[nameLength..];
103+
dataDestination = dataDestination.Slice(nameLength);
106104

107-
if (!string.IsNullOrEmpty(headerValue))
105+
if (!string.IsNullOrEmpty(headerName.Value))
108106
{
109-
var valueLength = Encoding.ASCII.GetBytes(headerValue, dataDestination);
107+
int valueLength = Encoding.ASCII.GetBytes(headerName.Value, dataDestination);
110108
fixed (byte* address = &MemoryMarshal.GetReference(dataDestination))
111109
{
112-
unknownHeaderStructure.pRawValue = (PCSTR)address;
110+
unknownHeaderStructure.pRawValue = address;
113111
unknownHeaderStructure.RawValueLength = (ushort)valueLength;
114112
}
115-
dataDestination = dataDestination[nameLength..];
113+
dataDestination = dataDestination.Slice(nameLength);
116114
}
117115
MemoryMarshal.Write(unknownHeaderStructureDestination, in unknownHeaderStructure);
118-
unknownHeaderStructureDestination = unknownHeaderStructureDestination[unknownHeadersSize..];
116+
unknownHeaderStructureDestination = unknownHeaderStructureDestination.Slice(unknownHeadersSize);
119117
}
120118
return dataDestination;
121119
}
122120

123-
private static List<(string, string)> GenerateUnknownHeaders(int count)
121+
private IReadOnlyCollection<(string, string)> GenerateUnknownHeaders(int count)
124122
{
125123
var result = new List<(string, string)>();
126-
for (var i = 0; i < count; i++)
124+
for (int i = 0; i < count; i++)
127125
{
128126
result.Add(($"X-Custom-{i}", $"Value-{i}"));
129127
}
Lines changed: 67 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,94 @@
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;
5+
using System.Net;
46
using System.Net.Http;
57
using System.Net.WebSockets;
68
using System.Text;
9+
using System.Threading;
10+
using System.Threading.Tasks;
711

8-
namespace TestClient;
9-
10-
public class Program
12+
namespace TestClient
1113
{
12-
private const string Address =
13-
"http://localhost:5000/public/1kb.txt";
14-
// "https://localhost:9090/public/1kb.txt";
15-
16-
public static void Main(string[] args)
14+
public class Program
1715
{
18-
Console.WriteLine("Ready");
19-
Console.ReadKey();
16+
private const string Address =
17+
"http://localhost:5000/public/1kb.txt";
18+
// "https://localhost:9090/public/1kb.txt";
2019

21-
var handler = new HttpClientHandler();
22-
handler.MaxConnectionsPerServer = 500;
23-
handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
24-
// handler.UseDefaultCredentials = true;
25-
HttpClient client = new HttpClient(handler);
20+
public static void Main(string[] args)
21+
{
22+
Console.WriteLine("Ready");
23+
Console.ReadKey();
2624

27-
RunParallelRequests(client);
25+
var handler = new HttpClientHandler();
26+
handler.MaxConnectionsPerServer = 500;
27+
handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
28+
// handler.UseDefaultCredentials = true;
29+
HttpClient client = new HttpClient(handler);
2830

29-
// RunManualRequests(client);
31+
RunParallelRequests(client);
3032

31-
// RunWebSocketClient().Wait();
33+
// RunManualRequests(client);
3234

33-
Console.WriteLine("Done");
34-
// Console.ReadKey();
35-
}
35+
// RunWebSocketClient().Wait();
3636

37-
private static void RunManualRequests(HttpClient client)
38-
{
39-
while (true)
40-
{
41-
Console.WriteLine("Press any key to send request");
42-
Console.ReadKey();
43-
var result = client.GetAsync(Address).Result;
44-
Console.WriteLine(result);
37+
Console.WriteLine("Done");
38+
// Console.ReadKey();
4539
}
46-
}
4740

48-
private static void RunParallelRequests(HttpClient client)
49-
{
50-
int completionCount = 0;
51-
int iterations = 100000;
52-
for (int i = 0; i < iterations; i++)
41+
private static void RunManualRequests(HttpClient client)
5342
{
54-
client.GetAsync(Address)
55-
.ContinueWith(t => Interlocked.Increment(ref completionCount));
43+
while (true)
44+
{
45+
Console.WriteLine("Press any key to send request");
46+
Console.ReadKey();
47+
var result = client.GetAsync(Address).Result;
48+
Console.WriteLine(result);
49+
}
5650
}
5751

58-
while (completionCount < iterations)
52+
private static void RunParallelRequests(HttpClient client)
5953
{
60-
Thread.Sleep(10);
54+
int completionCount = 0;
55+
int iterations = 100000;
56+
for (int i = 0; i < iterations; i++)
57+
{
58+
client.GetAsync(Address)
59+
.ContinueWith(t => Interlocked.Increment(ref completionCount));
60+
}
61+
62+
while (completionCount < iterations)
63+
{
64+
Thread.Sleep(10);
65+
}
6166
}
62-
}
63-
64-
public static async Task RunWebSocketClient()
65-
{
66-
ClientWebSocket websocket = new ClientWebSocket();
67-
68-
string url = "ws://localhost:5000/";
69-
Console.WriteLine("Connecting to: " + url);
70-
await websocket.ConnectAsync(new Uri(url), CancellationToken.None);
7167

72-
string message = "Hello World";
73-
Console.WriteLine("Sending message: " + message);
74-
byte[] messageBytes = Encoding.UTF8.GetBytes(message);
75-
await websocket.SendAsync(new ArraySegment<byte>(messageBytes), WebSocketMessageType.Text, true, CancellationToken.None);
76-
77-
byte[] incomingData = new byte[1024];
78-
WebSocketReceiveResult result = await websocket.ReceiveAsync(new ArraySegment<byte>(incomingData), CancellationToken.None);
79-
80-
if (result.CloseStatus.HasValue)
81-
{
82-
Console.WriteLine("Closed; Status: " + result.CloseStatus + ", " + result.CloseStatusDescription);
83-
}
84-
else
68+
public static async Task RunWebSocketClient()
8569
{
86-
Console.WriteLine("Received message: " + Encoding.UTF8.GetString(incomingData, 0, result.Count));
70+
ClientWebSocket websocket = new ClientWebSocket();
71+
72+
string url = "ws://localhost:5000/";
73+
Console.WriteLine("Connecting to: " + url);
74+
await websocket.ConnectAsync(new Uri(url), CancellationToken.None);
75+
76+
string message = "Hello World";
77+
Console.WriteLine("Sending message: " + message);
78+
byte[] messageBytes = Encoding.UTF8.GetBytes(message);
79+
await websocket.SendAsync(new ArraySegment<byte>(messageBytes), WebSocketMessageType.Text, true, CancellationToken.None);
80+
81+
byte[] incomingData = new byte[1024];
82+
WebSocketReceiveResult result = await websocket.ReceiveAsync(new ArraySegment<byte>(incomingData), CancellationToken.None);
83+
84+
if (result.CloseStatus.HasValue)
85+
{
86+
Console.WriteLine("Closed; Status: " + result.CloseStatus + ", " + result.CloseStatusDescription);
87+
}
88+
else
89+
{
90+
Console.WriteLine("Received message: " + Encoding.UTF8.GetString(incomingData, 0, result.Count));
91+
}
8792
}
8893
}
8994
}

src/Servers/HttpSys/src/AsyncAcceptContext.cs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Diagnostics;
55
using System.Threading.Tasks.Sources;
66
using Microsoft.Extensions.Logging;
7+
using Microsoft.AspNetCore.HttpSys.Internal;
78

89
namespace Microsoft.AspNetCore.Server.HttpSys;
910

@@ -45,9 +46,9 @@ internal ValueTask<RequestContext> AcceptAsync()
4546

4647
AllocateNativeRequest();
4748

48-
var statusCode = QueueBeginGetContext();
49-
if (statusCode != ErrorCodes.ERROR_SUCCESS &&
50-
statusCode != ErrorCodes.ERROR_IO_PENDING)
49+
uint statusCode = QueueBeginGetContext();
50+
if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS &&
51+
statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_IO_PENDING)
5152
{
5253
// some other bad error, possible(?) return values are:
5354
// ERROR_INVALID_HANDLE, ERROR_INSUFFICIENT_BUFFER, ERROR_OPERATION_ABORTED
@@ -62,16 +63,16 @@ private void IOCompleted(uint errorCode, uint numBytes, bool managed)
6263
try
6364
{
6465
ObserveCompletion(managed); // expectation tracking
65-
if (errorCode != ErrorCodes.ERROR_SUCCESS &&
66-
errorCode != ErrorCodes.ERROR_MORE_DATA)
66+
if (errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS &&
67+
errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_MORE_DATA)
6768
{
6869
// (keep all the error handling in one place)
6970
throw new HttpSysException((int)errorCode);
7071
}
7172

7273
Debug.Assert(_requestContext != null);
7374

74-
if (errorCode == ErrorCodes.ERROR_SUCCESS)
75+
if (errorCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS)
7576
{
7677
var requestContext = _requestContext;
7778
// It's important that we clear the request context before we set the result
@@ -93,10 +94,10 @@ private void IOCompleted(uint errorCode, uint numBytes, bool managed)
9394
AllocateNativeRequest(numBytes, _requestContext.RequestId);
9495

9596
// We need to issue a new request, either because auth failed, or because our buffer was too small the first time.
96-
var statusCode = QueueBeginGetContext();
97+
uint statusCode = QueueBeginGetContext();
9798

98-
if (statusCode != ErrorCodes.ERROR_SUCCESS &&
99-
statusCode != ErrorCodes.ERROR_IO_PENDING)
99+
if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS &&
100+
statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_IO_PENDING)
100101
{
101102
// some other bad error, possible(?) return values are:
102103
// ERROR_INVALID_HANDLE, ERROR_INSUFFICIENT_BUFFER, ERROR_OPERATION_ABORTED
@@ -179,15 +180,15 @@ private uint QueueBeginGetContext()
179180
_requestContext.RequestId,
180181
// Small perf impact by not using HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY
181182
// if the request sends header+body in a single TCP packet
182-
0u,
183+
(uint)HttpApiTypes.HTTP_FLAGS.NONE,
183184
_requestContext.NativeRequest,
184185
_requestContext.Size,
185186
&bytesTransferred,
186187
_overlapped);
187188

188189
switch (statusCode)
189190
{
190-
case (ErrorCodes.ERROR_CONNECTION_INVALID or ErrorCodes.ERROR_INVALID_PARAMETER) when _requestContext.RequestId != 0:
191+
case (UnsafeNclNativeMethods.ErrorCodes.ERROR_CONNECTION_INVALID or UnsafeNclNativeMethods.ErrorCodes.ERROR_INVALID_PARAMETER) when _requestContext.RequestId != 0:
191192
// ERROR_CONNECTION_INVALID:
192193
// The client reset the connection between the time we got the MORE_DATA error and when we called HttpReceiveHttpRequest
193194
// with the new buffer. We can clear the request id and move on to the next request.
@@ -201,23 +202,23 @@ private uint QueueBeginGetContext()
201202
_requestContext.RequestId = 0;
202203
retry = true;
203204
break;
204-
case ErrorCodes.ERROR_MORE_DATA:
205+
case UnsafeNclNativeMethods.ErrorCodes.ERROR_MORE_DATA:
205206
// the buffer was not big enough to fit the headers, we need
206207
// to read the RequestId returned, allocate a new buffer of the required size
207208
// (uint)backingBuffer.Length - AlignmentPadding
208209
CancelExpectCompletion(); // we'll "expect" again when we retry
209210
AllocateNativeRequest(bytesTransferred);
210211
retry = true;
211212
break;
212-
case ErrorCodes.ERROR_SUCCESS:
213+
case UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS:
213214
if (HttpSysListener.SkipIOCPCallbackOnSuccess)
214215
{
215216
// IO operation completed synchronously - callback won't be called to signal completion.
216217
IOCompleted(statusCode, bytesTransferred, true); // marks completion
217218
}
218219
// else: callback fired by IOCP (at some point), which marks completion
219220
break;
220-
case ErrorCodes.ERROR_IO_PENDING:
221+
case UnsafeNclNativeMethods.ErrorCodes.ERROR_IO_PENDING:
221222
break; // no change to state - callback will occur at some point
222223
default:
223224
// fault code, not expecting an IOCP callback

0 commit comments

Comments
 (0)