Skip to content

Commit

Permalink
Fix hanging of NamedPipeClientStream when connecting with infinite ti…
Browse files Browse the repository at this point in the history
…meout (#66877)

* Add new test for named pipe client stream.

The test includes the situation when the NamedPipeClientStream
doesn't response to the cancellation token.

* Handle case with infinite timeout properly.
  • Loading branch information
cranberry-clockworks authored Apr 12, 2022
1 parent a4503d6 commit a3941d0
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ private void ConnectInternal(int timeout, CancellationToken cancellationToken, i
cancellationToken.ThrowIfCancellationRequested();

// Determine how long we should wait in this connection attempt
int waitTime = timeout - elapsed;
int waitTime = timeout == Timeout.Infinite ? CancellationCheckInterval : timeout - elapsed;
if (cancellationToken.CanBeCanceled && waitTime > CancellationCheckInterval)
{
waitTime = CancellationCheckInterval;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,31 @@ public async Task ClientConnectAsync_With_Cancellation_Throws_Timeout_When_Pipe_
}
}

[Fact]
[PlatformSpecific(TestPlatforms.Windows)] // Unix implementation doesn't rely on a timeout and cancellation token when connecting
public async Task ClientConnectAsync_Cancel_With_InfiniteTimeout()
{
string pipeName = PipeStreamConformanceTests.GetUniquePipeName();

using (var cts = new CancellationTokenSource())
using (var server = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1))
using (var firstClient = new NamedPipeClientStream(pipeName))
using (var secondClient = new NamedPipeClientStream(pipeName))
{
var firstConnectionTasks = new Task[]
{
firstClient.ConnectAsync(),
server.WaitForConnectionAsync()
};

Assert.True(Task.WaitAll(firstConnectionTasks, 1000));

cts.CancelAfter(100);

await Assert.ThrowsAsync<OperationCanceledException>(() => secondClient.ConnectAsync(cts.Token)).WaitAsync(1000);
}
}

public static IEnumerable<object[]> GetCancellationTokens =>
new []
{
Expand Down

0 comments on commit a3941d0

Please sign in to comment.