-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
fix broken Select with error list on macOS #104915
Conversation
Tagging subscribers to this area: @dotnet/ncl |
@@ -19,6 +19,8 @@ internal static partial class SocketPal | |||
public static readonly int MaximumAddressSize = Interop.Sys.GetMaximumAddressSize(); | |||
private static readonly bool SupportsDualModeIPv4PacketInfo = GetPlatformSupportsDualModeIPv4PacketInfo(); | |||
|
|||
private static readonly bool PollNeedsErrorListFixup = OperatingSystem.IsMacOS() || OperatingSystem.IsIOS() || OperatingSystem.IsTvOS(); |
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.
I assume there's nothing we can query for in the PAL layer and it really is just us knowing that these OSes behave differently?
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.
If there is update we can check Darwin kernel version. But I'm not aware of anything so far.
src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Unix.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Unix.cs
Outdated
Show resolved
Hide resolved
// To fix that we will search read list and if macthing descriptor exiost we will add events flags | ||
// instead of adding new entry to error list. | ||
int readIndex = 0; | ||
while (readIndex < readCount) |
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.
Is this turning a linear operation into an N^2 operation?
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.
yes. This is where the assumption comes in that this is used from small number of sockets where it does not matter as much .... and the cost is only on platforms that are currently broken. (and use read and error list together)
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.
@GrabYourPitchforks, any concerns?
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.
I put up different implementation that avoids the N^2 problem. Please take another look @stephentoub
src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Unix.cs
Show resolved
Hide resolved
src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Unix.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Unix.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Unix.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Unix.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Unix.cs
Outdated
Show resolved
Hide resolved
for (int i = 0 ; i < readFdsCount; i++) | ||
{ | ||
fd = *(readFds + i); | ||
*(readFds + i) = __DARWIN_FD_ISSET(fd, readSetPtr); |
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.
What does __DARWIN_FD_ISSET return? Is it returning fd if it's set and otherwise 0?
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.
this is basically same as FD_ISSET
but working on set larger than FD_SETSIZE. man page says
FD_ISSET(fd, &fdset) is non-zero if fd is a member of fdset, zero otherwise.
in practice this seems to be int with one bit set depending on the position in it bit array.
Co-authored-by: Stephen Toub <stoub@microsoft.com>
Span<int> readFDs = checkRead?.Count > 20 ? new int[checkRead.Count] : stackalloc int[checkRead?.Count ?? 0]; | ||
Span<int> writeFDs = checkWrite?.Count > 20 ? new int[checkWrite.Count] : stackalloc int[checkWrite?.Count ?? 0]; | ||
Span<int> errorFDs = checkError?.Count > 20 ? new int[checkError.Count] : stackalloc int[checkError?.Count ?? 0]; |
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.
Where does the "20" come from? Pull it out into a named constant?
src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Unix.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Sockets/tests/FunctionalTests/SelectTest.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Sockets/tests/FunctionalTests/SelectTest.cs
Outdated
Show resolved
Hide resolved
Co-authored-by: Stephen Toub <stoub@microsoft.com>
as I discover on #920, we can make the
Select
work if we useinstead of
e.g on OSX like platforms we walk the lists to avoid socks duplication between read and error list.
It does add some expense but the
Select
should not be used for massive amount of sockets anyway and the fix makes the simple cases consistent with other platforms. Right now it just hangs and that is unpleasant.fixes #920