-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve NamedPipeClientStream.Connect edge cases handling #65553
Conversation
…nd the sys-call will quit immediately
Tagging subscribers to this area: @dotnet/area-system-io Issue DetailsBased on my understanding of the two following quotes from the docs: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew
https://docs.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-waitnamedpipew
There is no point of calling The C++ example also calls Based on
I've extended the condition to not fail on fixes #65434
|
FWIW I've tried to create a nice unit test based on repro provided in #65434 but I've failed (it would not be reliable). So I've used repro provided by @vonzshik to test the fix. Here is what I had: static async Task Repro(CancellationToken cancellationToken)
{
const int ClientCount = 10;
const int ServerCount = 3;
int timeout = (int)TimeSpan.FromSeconds(0.03).TotalMilliseconds;
Barrier barrier = new Barrier(ClientCount + ServerCount);
var clientTasks = Enumerable.Range(0, ClientCount).Select(i => Task.Run(async () =>
{
await using var client = new NamedPipeClientStream("foo");
try
{
Task connect = client.ConnectAsync(timeout, cancellationToken);
while (connect.Status != TaskStatus.Running) ;
barrier.SignalAndWait();
await connect;
}
catch (TimeoutException)
{
return;
}
await client.WriteAsync(new byte[1], cancellationToken);
}, cancellationToken)).ToArray();
var serverTasks = Enumerable.Range(0, ServerCount).Select(i => Task.Run(async () =>
{
barrier.SignalAndWait(); // wait until clients start to connect
await using var server = new NamedPipeServerStream("foo", PipeDirection.InOut, ServerCount);
await server.WaitForConnectionAsync(cancellationToken);
await server.ReadAsync(new byte[1], cancellationToken);
}, cancellationToken)).ToArray();
await Task.WhenAll(clientTasks);
await Task.WhenAll(serverTasks);
} |
@stephentoub @jozkee PTAL |
src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.Windows.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.Windows.cs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. Test?
Co-authored-by: Stephen Toub <stoub@microsoft.com>
|
* don't try to call WaitNamedPipeW if we know that no instances exist and the sys-call will quit immediately * remove code duplication Co-authored-by: Stephen Toub <stoub@microsoft.com>
Based on my understanding of the two following quotes from the docs:
https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew
https://docs.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-waitnamedpipew
There is no point of calling
WaitNamedPipe
right afterCreateFileW
failed withERROR_FILE_NOT_FOUND
(we are going to get the same error, unless the pipe was created in the meantime). Imo it's better to returnfalse
and let the re-try logic retry in a moment.The C++ example also calls
WaitNamedPipe
only whenCreateFileW
failed withERROR_PIPE_BUSY
.Based on
I've extended the condition to not fail on
ERROR_FILE_NOT_FOUND
as suggested by @vonzshik in #65434fixes #65434