You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
On Linux, disposing a socket on a given thread does not interrupt poll/select on another thread.
To reproduce, compile & run the following code and press enter when prompted:
// Comment this define to test using Socket.Select(...)
#define POLL
using System;using System.Net;using System.Net.Sockets;using System.Threading.Tasks;classProgram{staticvoidMain(){varendPoint=new IPEndPoint(IPAddress.Loopback,8080);varlistener=new TcpListener(endPoint);
listener.Start();varclient=new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp){NoDelay=true};
client.Connect(endPoint);varlistenerTask= Task.Factory.StartNew(s =>{varsocket=(Socket)s;#if POLLif(socket.Poll(-1, SelectMode.SelectRead)){if(!socket.Connected){ Console.WriteLine("Connection closed.");}}#elsevarreadSockets=new System.Collections.Generic.List<Socket>{socket}; Socket.Select(readSockets,null,null,-1);if(!socket.Connected){ Console.WriteLine("Connection closed.");}#endif}, client, TaskCreationOptions.LongRunning);
Console.WriteLine("Press enter to dispose the socket.");
Console.ReadLine();
Console.WriteLine("Disposing socket...");
client.Dispose();
Console.WriteLine("Socket disposed.");if(!listenerTask.Wait(5000))
Console.WriteLine("Socket did not break out of Select call within 5 seconds.");
Console.WriteLine("Done.");}}
Have you tried the equivalent in C? Generally closing a socket while it's in use by synchronous operations is considered undefined behavior by the Berkeley sockets specification. On Windows it may work most of the time, but it's also possible to lead to crashes and other corruption. On Linux, it often results in hangs.
@wfurt has been looking into ways to make this better when used from managed code, but it would only be working around the inherent limitations of the underlying APIs / OSes, rather than it being a bug in managed code.
dotnet/corefx#26898 should resolve this and you can call shutdown() as workaround. As @stephentoub mentioned, we are trying to bend OS behavior where blocking IO operation behaves different on Linux/MacOS.
On Linux, disposing a socket on a given thread does not interrupt poll/select on another thread.
To reproduce, compile & run the following code and press enter when prompted:
Expected result:
The following output is written to stdout:
This is the result you get on the desktop CLR, and .NET Core on Windows.
Actual result:
Info
.NET Core version: 2.1.302
OS: Ubuntu 14.04
The text was updated successfully, but these errors were encountered: