[Mono-bugs] [Bug 33745][Wis] New - Socket.Poll appears to be incorrect
bugzilla-daemon@rocky.ximian.com
bugzilla-daemon@rocky.ximian.com
12 Nov 2002 16:20:41 -0000
Please do not reply to this email- if you want to comment on the bug, go to the
URL shown below and enter your comments there.
Changed by tim@timcoleman.com.
http://bugzilla.ximian.com/show_bug.cgi?id=33745
--- shadow/33745 Tue Nov 12 11:20:41 2002
+++ shadow/33745.tmp.23194 Tue Nov 12 11:20:41 2002
@@ -0,0 +1,120 @@
+Bug#: 33745
+Product: Mono/Class Libraries
+Version: unspecified
+OS: GNU/Linux [Other]
+OS Details: Debian unstable
+Status: NEW
+Resolution:
+Severity:
+Priority: Wishlist
+Component: System
+AssignedTo: mono-bugs@ximian.com
+ReportedBy: tim@timcoleman.com
+QAContact: mono-bugs@ximian.com
+TargetMilestone: ---
+URL:
+Cc:
+Summary: Socket.Poll appears to be incorrect
+
+Please fill in this template when reporting a bug, unless you know what
+you are doing.
+Description of Problem:
+As part of my development for System.Data.SqlClient, I have implemented a
+connection timeout. This is done by calling Socket.BeginConnect (), and
+then polling the socket in a callback. Once the Socket.Poll with select
+mode SelectMode.SelectWrite returns true, then it calls Socket.EndConnect
+() and sets a ManualResetEvent, triggering the initial thread to continue.
+
+If the ManualResetEvent does not get set, then WaitOne returns false and
+an exception is thrown.
+
+Steps to reproduce the problem:
+Here is a code sample:
+
+using System;
+using System.Net;
+using System.Net.Sockets;
+using System.Threading;
+
+class Test {
+ public static void Main ()
+ {
+ SocketTester tester = new SocketTester ("localhost",
+31337);
+ }
+}
+
+class SocketTester {
+
+ Socket socket;
+ int timeout;
+ ManualResetEvent connected = new ManualResetEvent (false);
+
+ public SocketTester (string host, int port)
+ : this (host, port, 15)
+ {
+ }
+
+ public SocketTester (string host, int port, int timeout)
+ {
+ this.timeout = timeout;
+
+ socket = new Socket (AddressFamily.InterNetwork,
+SocketType.Stream, ProtocolType.Tcp);
+ IPHostEntry hostEntry = Dns.Resolve (host);
+ IPEndPoint endPoint = new IPEndPoint
+(hostEntry.AddressList [0], port);
+ connected.Reset ();
+ IAsyncResult asyncResult = socket.BeginConnect (endPoint,
+new AsyncCallback (ConnectCallback), socket);
+ if (!connected.WaitOne (new TimeSpan (0, 0, timeout),
+true))
+ throw new Exception ("Timeout exceeded. Could not
+open socket.");
+ socket.Close ();
+ Console.WriteLine ("Connection succeeded.");
+ }
+
+ private void ConnectCallback (IAsyncResult ar)
+ {
+ Socket s = (Socket) ar.AsyncState;
+ if (Poll (s, timeout, SelectMode.SelectWrite)) {
+ socket.EndConnect (ar);
+ connected.Set ();
+ }
+ }
+
+ private bool Poll (Socket s, int seconds, SelectMode selectMode)
+ {
+ long uSeconds = seconds * 1000000;
+ bool bState = false;
+ while (uSeconds > (long) Int32.MaxValue) {
+ bState = s.Poll (Int32.MaxValue, selectMode);
+ if (bState)
+ return true;
+ uSeconds -= Int32.MaxValue;
+ }
+ return s.Poll ((int) uSeconds, selectMode);
+ }
+}
+
+Actual Results:
+*Immediately* throws two exceptions:
+The main thread throws the System.Exception () indicating a timeout.
+The other thread throws a SocketException (): "Connection refused."
+
+Expected Results:
+The timeout specified, 15 seconds, should expire, and then the WaitOne
+will return false. This should cause the System.Exception () indicating a
+timeout. The SocketException should not be thrown. The SocketException
+appears to be called from within EndConnect, which is only called if
+Socket.Poll returns true, which should not happen.
+
+On Windows, Socket.Poll will not return true, and the event will timeout.
+
+How often does this happen?
+Every time.
+
+Additional Information:
+This only occurs on Linux, not on Windows. Seems to be a problem with
+Socket.Poll.