diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs
index 8225f802f3987..94d1cea46d1b0 100644
--- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs
+++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs
@@ -2155,7 +2155,7 @@ public bool Poll(int microSeconds, SelectMode mode)
}
/// Determines the status of the .
- /// The time to wait for a response.
+ /// The time to wait for a response. indicates an infinite timeout.
/// One of the values.
///
/// The status of the based on the polling mode value passed in the parameter.
@@ -2167,7 +2167,7 @@ public bool Poll(int microSeconds, SelectMode mode)
/// does not block and the connection has failed, or if OutOfBandInline is not set and out-of-band data is available.
/// Otherwise, it returns .
///
- /// is less than -1 milliseconds or greater than milliseconds.
+ /// was negative or greater than TimeSpan.FromMicroseconds(int.MaxValue).
/// An error occurred when attempting to access the socket.
/// The has been closed.
public bool Poll(TimeSpan timeout, SelectMode mode) =>
@@ -2217,10 +2217,10 @@ public static void Select(IList? checkRead, IList? checkWrite, IList? checkError
/// An of instances to check for readability.
/// An of instances to check for writability.
/// An of instances to check for errors.
- /// The timeout value. A value equal to -1 microseconds indicates an infinite timeout.
+ /// The timeout value. A value equal to indicates an infinite timeout.
/// The , , or parameter is or empty.
/// The , , or parameter contains too many sockets.
- /// The was less than -1 microseconds or greater than microseconds
+ /// The was negative or greater than TimeSpan.FromMicroseconds(int.MaxValue).
/// An error occurred when attempting to access the socket.
/// One or more sockets was disposed.
public static void Select(IList? checkRead, IList? checkWrite, IList? checkError, TimeSpan timeout) =>
@@ -2228,8 +2228,18 @@ public static void Select(IList? checkRead, IList? checkWrite, IList? checkError
private static int ToTimeoutMicroseconds(TimeSpan timeout)
{
+ if (timeout == Timeout.InfiniteTimeSpan)
+ {
+ return -1;
+ }
+
+ if (timeout < TimeSpan.Zero)
+ {
+ throw new ArgumentOutOfRangeException(nameof(timeout));
+ }
long totalMicroseconds = (long)timeout.TotalMicroseconds;
- if (totalMicroseconds < -1 || totalMicroseconds > int.MaxValue)
+
+ if (totalMicroseconds > int.MaxValue)
{
throw new ArgumentOutOfRangeException(nameof(timeout));
}
diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/ArgumentValidationTests.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/ArgumentValidationTests.cs
index 31da90800351a..f0f7ed672ac04 100644
--- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/ArgumentValidationTests.cs
+++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/ArgumentValidationTests.cs
@@ -371,6 +371,58 @@ public void Select_NullOrEmptyLists_Throws_ArgumentNull_TimeSpan()
Assert.Throws(() => Socket.Select(emptyList, emptyList, emptyList, nonInfinity));
}
+ [Fact]
+ public void SelectPoll_NegativeTimeSpan_Throws()
+ {
+ using (Socket host = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
+ {
+ host.Bind(new IPEndPoint(IPAddress.Loopback, 0));
+ host.Listen(1);
+ Task accept = host.AcceptAsync();
+
+ using (Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
+ {
+ s.Connect(new IPEndPoint(IPAddress.Loopback, ((IPEndPoint)host.LocalEndPoint).Port));
+
+ var list = new List();
+ list.Add(s);
+
+ Assert.Throws(() => Socket.Select(null, list, null, TimeSpan.FromMicroseconds(-1)));
+ Assert.Throws(() => Socket.Select(null, list, null, TimeSpan.FromMicroseconds((double)int.MaxValue + 1)));
+ Assert.Throws(() => Socket.Select(null, list, null, TimeSpan.FromMilliseconds(-1.1)));
+
+ Assert.Throws(() => s.Poll(TimeSpan.FromMicroseconds(-1), SelectMode.SelectWrite));
+ Assert.Throws(() => s.Poll(TimeSpan.FromMicroseconds((double)int.MaxValue + 1), SelectMode.SelectWrite));
+ Assert.Throws(() => s.Poll(TimeSpan.FromMilliseconds(-1.1), SelectMode.SelectWrite));
+ }
+ }
+ }
+
+ [Fact]
+ public void SelectPoll_InfiniteTimeSpan_Ok()
+ {
+ using (Socket host = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
+ {
+ host.Bind(new IPEndPoint(IPAddress.Loopback, 0));
+ host.Listen(1);
+ Task accept = host.AcceptAsync();
+
+ using (Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
+ {
+ s.Connect(new IPEndPoint(IPAddress.Loopback, ((IPEndPoint)host.LocalEndPoint).Port));
+
+ var list = new List();
+ list.Add(s);
+
+ // should be writable
+ Socket.Select(null, list, null, Timeout.InfiniteTimeSpan);
+ Socket.Select(null, list, null, -1);
+ s.Poll(Timeout.InfiniteTimeSpan, SelectMode.SelectWrite);
+ s.Poll(-1, SelectMode.SelectWrite);
+ }
+ }
+ }
+
[Fact]
public void Select_LargeList_Throws_ArgumentOutOfRange()
{