[Mono-devel-list] Re: [Mono-patches] r44192 - trunk/mcs/class/System/System.Net.Sockets
Dick Porter
dick at ximian.com
Mon May 9 04:07:59 EDT 2005
On Sat, 2005-05-07 at 02:22 -0400, Gonzalo Paniagua wrote:
> Modified:
> trunk/mcs/class/System/System.Net.Sockets/ChangeLog
> trunk/mcs/class/System/System.Net.Sockets/Socket.cs
> Log:
> 2005-05-07 Gonzalo Paniagua Javier <gonzalo at ximian.com>
>
> * Socket.cs: see bug #74842, which is fixed with this patch for details
> and test cases on the blocking behavior of accept() when close() is
> called from another thread. The solution applied is to Abort the thread
> that is blocking in Accept_internal() when someone calls Close (), then
> reset the abort state if the socket is disposed and return the same
> error as MS (10004 - interrupted).
>
> Modified: trunk/mcs/class/System/System.Net.Sockets/Socket.cs
> ===================================================================
> --- trunk/mcs/class/System/System.Net.Sockets/Socket.cs 2005-05-07 05:22:49 UTC (rev 44191)
> +++ trunk/mcs/class/System/System.Net.Sockets/Socket.cs 2005-05-07 06:22:46 UTC (rev 44192)
> @@ -777,13 +777,25 @@
> [MethodImplAttribute(MethodImplOptions.InternalCall)]
> private extern static IntPtr Accept_internal(IntPtr sock,
> out int error);
> -
> +
> + Thread accept_thread;
> public Socket Accept() {
> if (disposed && closed)
> throw new ObjectDisposedException (GetType ().ToString ());
>
> - int error;
> - IntPtr sock=Accept_internal(socket, out error);
> + int error = 0;
> + IntPtr sock = (IntPtr) (-1);
> + accept_thread = Thread.CurrentThread;
> + try {
> + sock = Accept_internal(socket, out error);
> + } catch (ThreadAbortException the) {
> + if (disposed) {
> + Thread.ResetAbort ();
> + error = 10004;
> + }
> + } finally {
> + accept_thread = null;
> + }
>
> if (error != 0) {
> throw new SocketException (error);
> @@ -1715,6 +1727,10 @@
> IntPtr x = socket;
> socket = (IntPtr) (-1);
> Close_internal (x, out error);
> + if (accept_thread != null) {
> + accept_thread.Abort ();
> + accept_thread = null;
> + }
>
Isn't it possible for the accept_thread to be aborted while it is in the
finally block? Or Close()d multiple times while accept_thread != null?
Given how fragile thread aborting is, even without this race condition
this might get ugly. I can't think of a better solution offhand
though...
- Dick
More information about the Mono-devel-list
mailing list