Skip to content

Commit 5a51e99

Browse files
authored
Add Read/Write Async test (#98432)
1 parent eaa6f01 commit 5a51e99

File tree

1 file changed

+93
-1
lines changed

1 file changed

+93
-1
lines changed

src/libraries/System.Threading.ThreadPool/tests/ThreadPoolTests.cs

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
using System.Diagnostics.Tracing;
77
using System.IO;
88
using System.Linq;
9+
using System.Net.Sockets;
10+
using System.Net;
911
using System.Reflection;
1012
using System.Threading.Tasks;
1113
using System.Threading.Tests;
@@ -1160,6 +1162,95 @@ public void ThreadPoolMinMaxThreadsEventTest()
11601162
}).Dispose();
11611163
}
11621164

1165+
private sealed class RuntimeEventListener : EventListener
1166+
{
1167+
private const string ClrProviderName = "Microsoft-Windows-DotNETRuntime";
1168+
private const EventKeywords ThreadingKeyword = (EventKeywords)0x10000;
1169+
1170+
public volatile int tpIOEnqueue = 0;
1171+
public volatile int tpIODequeue = 0;
1172+
public ManualResetEvent tpWaitIOEnqueueEvent = new ManualResetEvent(false);
1173+
public ManualResetEvent tpWaitIODequeueEvent = new ManualResetEvent(false);
1174+
1175+
protected override void OnEventSourceCreated(EventSource eventSource)
1176+
{
1177+
if (eventSource.Name.Equals(ClrProviderName))
1178+
{
1179+
EnableEvents(eventSource, EventLevel.Verbose, ThreadingKeyword);
1180+
}
1181+
1182+
base.OnEventSourceCreated(eventSource);
1183+
}
1184+
1185+
protected override void OnEventWritten(EventWrittenEventArgs eventData)
1186+
{
1187+
if (eventData.EventName.Equals("ThreadPoolIOEnqueue"))
1188+
{
1189+
Interlocked.Increment(ref tpIOEnqueue);
1190+
tpWaitIOEnqueueEvent.Set();
1191+
}
1192+
else if (eventData.EventName.Equals("ThreadPoolIODequeue"))
1193+
{
1194+
Interlocked.Increment(ref tpIODequeue);
1195+
tpWaitIODequeueEvent.Set();
1196+
}
1197+
}
1198+
}
1199+
1200+
[ConditionalFact(nameof(IsThreadingAndRemoteExecutorSupported), nameof(UseWindowsThreadPool))]
1201+
public void ReadWriteAsyncTest()
1202+
{
1203+
RemoteExecutor.Invoke(async () =>
1204+
{
1205+
using (RuntimeEventListener eventListener = new RuntimeEventListener())
1206+
{
1207+
TaskCompletionSource<int> portTcs = new TaskCompletionSource<int>();
1208+
TaskCompletionSource<bool> readAsyncReadyTcs = new TaskCompletionSource<bool>();
1209+
1210+
async Task StartListenerAsync()
1211+
{
1212+
using TcpListener listener = new TcpListener(IPAddress.Loopback, 0);
1213+
listener.Start();
1214+
int port = ((IPEndPoint)listener.LocalEndpoint).Port;
1215+
portTcs.SetResult(port);
1216+
using TcpClient client = await listener.AcceptTcpClientAsync();
1217+
using (NetworkStream stream = client.GetStream())
1218+
{
1219+
byte[] buffer = new byte[1];
1220+
Task readAsyncTask = stream.ReadAsync(buffer, 0, buffer.Length);
1221+
readAsyncReadyTcs.SetResult(true);
1222+
await readAsyncTask;
1223+
}
1224+
listener.Stop();
1225+
}
1226+
1227+
async Task StartClientAsync()
1228+
{
1229+
int port = await portTcs.Task;
1230+
using (TcpClient client = new TcpClient(new IPEndPoint(IPAddress.Loopback, 0)))
1231+
{
1232+
await client.ConnectAsync(IPAddress.Loopback, port);
1233+
using (NetworkStream stream = client.GetStream())
1234+
{
1235+
bool readAsyncReady = await readAsyncReadyTcs.Task;
1236+
byte[] data = new byte[1];
1237+
await stream.WriteAsync(data, 0, data.Length);
1238+
}
1239+
}
1240+
}
1241+
1242+
Task listenerTask = StartListenerAsync();
1243+
Task clientTask = StartClientAsync();
1244+
await Task.WhenAll(listenerTask, clientTask);
1245+
ManualResetEvent[] waitEvents = [eventListener.tpWaitIOEnqueueEvent, eventListener.tpWaitIODequeueEvent];
1246+
1247+
Assert.True(WaitHandle.WaitAll(waitEvents, TimeSpan.FromSeconds(15))); // Assert that there wasn't a timeout
1248+
Assert.True(eventListener.tpIOEnqueue > 0);
1249+
Assert.True(eventListener.tpIODequeue > 0);
1250+
}
1251+
}).Dispose();
1252+
}
1253+
11631254
public static bool IsThreadingAndRemoteExecutorSupported =>
11641255
PlatformDetection.IsThreadingSupported && RemoteExecutor.IsSupported;
11651256

@@ -1169,6 +1260,7 @@ private static bool GetUseWindowsThreadPool()
11691260
return useWindowsThreadPool;
11701261
}
11711262

1172-
private static bool UsePortableThreadPool { get; } = !GetUseWindowsThreadPool();
1263+
private static bool UseWindowsThreadPool { get; } = GetUseWindowsThreadPool();
1264+
private static bool UsePortableThreadPool { get; } = !UseWindowsThreadPool;
11731265
}
11741266
}

0 commit comments

Comments
 (0)