http://bugzilla.novell.com/show_bug.cgi?id=541492
User [email protected] added comment http://bugzilla.novell.com/show_bug.cgi?id=541492#c3 --- Comment #3 from Oskar Berggren <[email protected]> 2009-11-03 09:21:24 MST --- The behavior comes from Socket, and should affect everything using a Socket in this way (disposing while in Accept()). Code that exhibits this is part of a bigger project, and doesn't fail all the time (but often). From what I can see, any simple multi threaded application that uses TcpListener.AcceptSocket() and wishes to stop the listener from a different thread may exhibit this behavior. As would any similar app using Socket directly. I described the problem in more detail on the mailing list (2009-09-23), but received no reply at the time: http://www.mail-archive.com/[email protected]/msg22093.html I reproduce the contents of the mail here: I have a TcpListener and a thread that blocks in AcceptSocket(), corresponding to Socket.Accept(). Another thread now calls Stop() on the listener, which causes the socket to be disposed. I believe the intention is that the thread blocking on Accept() should now get a SocketException with errorcode = interrupted. This is based on reading the code, and this does happen sometimes. However, sometimes, quite often, I get this ThreadAbortException instead: System.Threading.ThreadAbortException: Thread was being aborted at System.Net.Sockets.SocketException..ctor (Int32 error) [0x00007] in /home/oskar/mono24/mono-2.4.2.3/mono-2.4.2.3/mcs/class/System/System.Net.Sockets/SocketException.cs:54 at System.Net.Sockets.Socket.Accept () [0x000b8] in /home/oskar/mono24/mono-2.4.2.3/mono-2.4.2.3/mcs/class/System/System.Net.Sockets/Socket.cs:1434 at System.Net.Sockets.TcpListener.AcceptSocket () [0x00016] in /home/oskar/mono24/mono-2.4.2.3/mono-2.4.2.3/mcs/class/System/System.Net.Sockets/TcpListener.cs:193 at XXXX.TriggerServer.Run_impl () [0x0003b] in MYCODE BTW, Socket.cs:1434 above seems bogus... There is no call to SocketException..ctor on that line. Closest one, and only one in Accept(), is on line 1426. Looking at the code in Socket.Accept() it is built to handle a ThreadAbortException by preventing the abort and generating a SocketException instead. But this does not seem to work reliably! Is it possible there is a race condition here? That is: Can Close_internal() in fact cause Accept_internal() to return (with an error code) before Dispose() calls Abort() on blocking_thread? This is an excerpt from public Socket Accept(): blocking_thread = Thread.CurrentThread; try { sock = Accept_internal(socket, out error, blocking); } catch (ThreadAbortException) { if (disposed) { #if !NET_2_1 Thread.ResetAbort (); #endif error = (int) SocketError.Interrupted; } } finally { blocking_thread = null; } if (error != 0) throw new SocketException (error); And this is the Dispose(): protected virtual void Dispose (bool explicitDisposing) { if (disposed) return; disposed = true; connected = false; if ((int) socket != -1) { int error; closed = true; IntPtr x = socket; socket = (IntPtr) (-1); Close_internal (x, out error); if (blocking_thread != null) { blocking_thread.Abort (); blocking_thread = null; } if (error != 0) throw new SocketException (error); } } -- Configure bugmail: http://bugzilla.novell.com/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- You are the QA contact for the bug. You are the assignee for the bug. _______________________________________________ mono-bugs maillist - [email protected] http://lists.ximian.com/mailman/listinfo/mono-bugs
