Explorar o código

2009-02-17 Gonzalo Paniagua Javier <[email protected]>

	* Socket.cs: instead of clearing the sockets form the output and then
	adding them back, we just remove the ones that have not been signaled.
	Fixes bug #354090 and bug #476138.


svn path=/trunk/mcs/; revision=127234
Gonzalo Paniagua Javier %!s(int64=17) %!d(string=hai) anos
pai
achega
10badb611a

+ 6 - 0
mcs/class/System/System.Net.Sockets/ChangeLog

@@ -1,3 +1,9 @@
+2009-02-17 Gonzalo Paniagua Javier <[email protected]>
+
+	* Socket.cs: instead of clearing the sockets form the output and then
+	adding them back, we just remove the ones that have not been signaled.
+	Fixes bug #354090 and bug #476138.
+
 2009-01-19 Gonzalo Paniagua Javier <[email protected]>
 
 	* Socket.cs: don't throw when there's no ipv6 configuration.

+ 27 - 18
mcs/class/System/System.Net.Sockets/Socket.cs

@@ -684,38 +684,47 @@ namespace System.Net.Sockets
 			if (error != 0)
 				throw new SocketException (error);
 
-			if (checkRead != null)
-				checkRead.Clear ();
-
-			if (checkWrite != null)
-				checkWrite.Clear ();
-
-			if (checkError != null)
-				checkError.Clear ();
-
-			if (sockets == null)
+			if (sockets == null) {
+				if (checkRead != null)
+					checkRead.Clear ();
+				if (checkWrite != null)
+					checkWrite.Clear ();
+				if (checkError != null)
+					checkError.Clear ();
 				return;
+			}
 
 			int mode = 0;
 			int count = sockets.Length;
 			IList currentList = checkRead;
+			int currentIdx = 0;
 			for (int i = 0; i < count; i++) {
+				Socket cur_sock;
 				Socket sock = sockets [i];
 				if (sock == null) { // separator
+					if (currentList != null) {
+						// Remove non-signaled sockets after the current one
+						int to_remove = currentList.Count - currentIdx;
+						for (int k = 0; k < to_remove; k++)
+							currentList.RemoveAt (currentIdx);
+					}
 					currentList = (mode == 0) ? checkWrite : checkError;
+					currentIdx = 0;
 					mode++;
 					continue;
 				}
 
-				if (currentList != null) {
-					if (currentList == checkWrite && !sock.connected) {
-						if ((int) sock.GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error) == 0) {
-							sock.connected = true;
-						}
-					}
-					
-					currentList.Add (sock);
+				if (mode == 1 && currentList == checkWrite && !sock.connected) {
+					if ((int) sock.GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error) == 0)
+						sock.connected = true;
+				}
+
+				// Remove non-signaled sockets before the current one
+				int max = currentList.Count;
+				while ((cur_sock = (Socket) currentList [currentIdx]) != sock) {
+					currentList.RemoveAt (currentIdx);
 				}
+				currentIdx++;
 			}
 		}