Skip to content

Unable to cancel NamedPipeClientStream reads on MacOS #101539

@codecat

Description

@codecat

Description

I am unable to cancel reads on NamedPipeClientStream on MacOS, as it seems to deadlock when closing the reader.

Reproduction Steps

The following code reproduces the problem on MacOS, but works fine on both Windows and Linux:

using System.IO.Pipes;

new Thread(() => {
	using var host = new NamedPipeServerStream(
		"cstest_pipes",
		PipeDirection.InOut,
		NamedPipeServerStream.MaxAllowedServerInstances,
		PipeTransmissionMode.Byte,
		PipeOptions.Asynchronous
	);

	Console.WriteLine("Host: Waiting for connection..");
	host.WaitForConnection();

	Console.WriteLine("Host: Connected :)");

	while (true) {
		Thread.Sleep(1000);
	}
}).Start();

using var client = new NamedPipeClientStream(".", "cstest_pipes", PipeDirection.InOut, PipeOptions.Asynchronous);

Console.WriteLine("Client: Connecting..");
client.Connect(TimeSpan.FromSeconds(1));

Console.WriteLine($"Client: Connected: {client.IsConnected}");

var cts = new CancellationTokenSource();
var ct = cts.Token;

using var reader = new BinaryReader(client);
using var readerReg = ct.Register(reader.Close);

new Task(async () => {
	Console.WriteLine("Client: Cancelling in 500ms..");
	await Task.Delay(TimeSpan.FromMilliseconds(500));

	Console.WriteLine("Client: Cancelling..");
	cts.Cancel();

	Console.WriteLine("Client: Cancelled :)");
}).Start();

while (!ct.IsCancellationRequested) {
	Console.WriteLine("Client: Reading byte..");
	try {
		var b = reader.ReadByte();
		Console.WriteLine($"Client: Byte received: 0x{b:02x}");
	} catch (Exception) {
		Console.WriteLine("Client: Exception caught while reading byte");
		break;
	}
}

Console.WriteLine("Client: Disconnected :)");

Expected behavior

On stream close, I expect any existing reads to be cancelled and throw an exception. In other words, I expect the output of the above program to be something like this:

Client: Connecting..
Host: Waiting for connection..
Client: Connected: True
Client: Reading byte..
Host: Connected :)
Client: Cancelling in 500ms..
Client: Cancelling..
Client: Exception caught while reading byte
Client: Cancelled :)
Client: Disconnected :)

Actual behavior

In this case, a deadlock occurs between the stream closing and the stream being read from. In the example code above, the output of the program locks up here:

Host: Waiting for connection..
Client: Connected: True
Client: Reading byte..
Host: Connected :)
Client: Cancelling in 500ms..
Client: Cancelling..

Regression?

No response

Known Workarounds

No response

Configuration

Tested with SDK 9.0.100-preview.3.24204.13 (it happens on 8.0.203 as well)
MacOS Sonoma 14.4.1, arm64

Other information

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions