Merge pull request #409 from Alkarex/patch-1
[mono.git] / mcs / class / System / System.Net.Sockets / Socket.cs
index ea25e8c5c16bcf52876cbc88373a06a446765ee6..763bc3462f422e907943bb3439a3aa1fb0478b2c 100644 (file)
@@ -55,6 +55,7 @@ namespace System.Net.Sockets
        {
                private bool islistening;
                private bool useoverlappedIO;
+               private const int SOCKET_CLOSED = 10004;
 
                static void AddSockets (List<Socket> sockets, IList list, string name)
                {
@@ -543,21 +544,19 @@ namespace System.Net.Sockets
 
                        int error = 0;
                        IntPtr sock = (IntPtr) (-1);
-                       blocking_thread = Thread.CurrentThread;
                        try {
+                               RegisterForBlockingSyscall ();
                                sock = Accept_internal(socket, out error, blocking);
-                       } catch (ThreadAbortException) {
-                               if (disposed) {
-                                       Thread.ResetAbort ();
-                                       error = (int) SocketError.Interrupted;
-                               }
                        } finally {
-                               blocking_thread = null;
+                               UnRegisterForBlockingSyscall ();
+                       }
+
+                       if (error != 0) {
+                               if (closed)
+                                       error = SOCKET_CLOSED;
+                               throw new SocketException(error);
                        }
 
-                       if (error != 0)
-                               throw new SocketException (error);
-                       
                        Socket accepted = new Socket(this.AddressFamily, this.SocketType,
                                this.ProtocolType, sock);
 
@@ -573,21 +572,19 @@ namespace System.Net.Sockets
                        
                        int error = 0;
                        IntPtr sock = (IntPtr)(-1);
-                       blocking_thread = Thread.CurrentThread;
                        
                        try {
+                               RegisterForBlockingSyscall ();
                                sock = Accept_internal (socket, out error, blocking);
-                       } catch (ThreadAbortException) {
-                               if (disposed) {
-                                       Thread.ResetAbort ();
-                                       error = (int)SocketError.Interrupted;
-                               }
                        } finally {
-                               blocking_thread = null;
+                               UnRegisterForBlockingSyscall ();
                        }
                        
-                       if (error != 0)
+                       if (error != 0) {
+                               if (closed)
+                                       error = SOCKET_CLOSED;
                                throw new SocketException (error);
+                       }
                        
                        acceptSocket.address_family = this.AddressFamily;
                        acceptSocket.socket_type = this.SocketType;
@@ -747,6 +744,21 @@ namespace System.Net.Sockets
                        socket_pool_queue (Worker.Dispatcher, req);
                        return(req);
                }
+
+               void CheckRange (byte[] buffer, int offset, int size)
+               {
+                       if (offset < 0)
+                               throw new ArgumentOutOfRangeException ("offset", "offset must be >= 0");
+                               
+                       if (offset > buffer.Length)
+                               throw new ArgumentOutOfRangeException ("offset", "offset must be <= buffer.Length");
+
+                       if (size < 0)                          
+                               throw new ArgumentOutOfRangeException ("size", "size must be >= 0");
+                               
+                       if (size > buffer.Length - offset)
+                               throw new ArgumentOutOfRangeException ("size", "size must be <= buffer.Length - offset");
+               }
                
                public IAsyncResult BeginReceive(byte[] buffer, int offset,
                                                 int size,
@@ -760,11 +772,7 @@ namespace System.Net.Sockets
                        if (buffer == null)
                                throw new ArgumentNullException ("buffer");
 
-                       if (offset < 0 || offset > buffer.Length)
-                               throw new ArgumentOutOfRangeException ("offset");
-
-                       if (size < 0 || offset + size > buffer.Length)
-                               throw new ArgumentOutOfRangeException ("size");
+                       CheckRange (buffer, offset, size);
 
                        SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Receive);
                        req.Buffer = buffer;
@@ -852,14 +860,7 @@ namespace System.Net.Sockets
                        if (remote_end == null)
                                throw new ArgumentNullException ("remote_end");
 
-                       if (offset < 0)
-                               throw new ArgumentOutOfRangeException ("offset", "offset must be >= 0");
-
-                       if (size < 0)
-                               throw new ArgumentOutOfRangeException ("size", "size must be >= 0");
-
-                       if (offset + size > buffer.Length)
-                               throw new ArgumentOutOfRangeException ("offset, size", "offset + size exceeds the buffer length");
+                       CheckRange (buffer, offset, size);
 
                        SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.ReceiveFrom);
                        req.Buffer = buffer;
@@ -892,11 +893,7 @@ namespace System.Net.Sockets
                        if (remoteEP == null)
                                throw new ArgumentNullException ("remoteEP");
 
-                       if (offset < 0 || offset > buffer.Length)
-                               throw new ArgumentOutOfRangeException ("offset");
-
-                       if (size < 0 || offset + size > buffer.Length)
-                               throw new ArgumentOutOfRangeException ("size");
+                       CheckRange (buffer, offset, size);
 
                        throw new NotImplementedException ();
                }
@@ -910,14 +907,7 @@ namespace System.Net.Sockets
                        if (buffer == null)
                                throw new ArgumentNullException ("buffer");
 
-                       if (offset < 0)
-                               throw new ArgumentOutOfRangeException ("offset", "offset must be >= 0");
-
-                       if (size < 0)
-                               throw new ArgumentOutOfRangeException ("size", "size must be >= 0");
-
-                       if (offset + size > buffer.Length)
-                               throw new ArgumentOutOfRangeException ("offset, size", "offset + size exceeds the buffer length");
+                       CheckRange (buffer, offset, size);
 
                        if (!connected)
                                throw new SocketException ((int)SocketError.NotConnected);
@@ -1083,14 +1073,7 @@ namespace System.Net.Sockets
                        if (buffer == null)
                                throw new ArgumentNullException ("buffer");
 
-                       if (offset < 0)
-                               throw new ArgumentOutOfRangeException ("offset", "offset must be >= 0");
-
-                       if (size < 0)
-                               throw new ArgumentOutOfRangeException ("size", "size must be >= 0");
-
-                       if (offset + size > buffer.Length)
-                               throw new ArgumentOutOfRangeException ("offset, size", "offset + size exceeds the buffer length");
+                       CheckRange (buffer, offset, size);
 
                        SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.SendTo);
                        req.Buffer = buffer;
@@ -1563,8 +1546,7 @@ namespace System.Net.Sockets
                        if (buffer == null)
                                throw new ArgumentNullException ("buffer");
 
-                       if (size < 0 || size > buffer.Length)
-                               throw new ArgumentOutOfRangeException ("size");
+                       CheckRange (buffer, 0, size);
 
                        SocketError error;
 
@@ -1587,11 +1569,7 @@ namespace System.Net.Sockets
                        if (buffer == null)
                                throw new ArgumentNullException ("buffer");
 
-                       if (offset < 0 || offset > buffer.Length)
-                               throw new ArgumentOutOfRangeException ("offset");
-
-                       if (size < 0 || offset + size > buffer.Length)
-                               throw new ArgumentOutOfRangeException ("size");
+                       CheckRange (buffer, offset, size);
                        
                        SocketError error;
 
@@ -1614,11 +1592,7 @@ namespace System.Net.Sockets
                        if (buffer == null)
                                throw new ArgumentNullException ("buffer");
 
-                       if (offset < 0 || offset > buffer.Length)
-                               throw new ArgumentOutOfRangeException ("offset");
-
-                       if (size < 0 || offset + size > buffer.Length)
-                               throw new ArgumentOutOfRangeException ("size");
+                       CheckRange (buffer, offset, size);
                        
                        return Receive_nochecks (buffer, offset, size, flags, out error);
                }
@@ -1643,10 +1617,9 @@ namespace System.Net.Sockets
                        res.Size = e.Count;
                        res.EndPoint = e.RemoteEndPoint;
                        res.SockFlags = e.SocketFlags;
-                       Worker worker = new Worker (e);
                        int count;
                        lock (readQ) {
-                               readQ.Enqueue (worker);
+                               readQ.Enqueue (e.Worker);
                                count = readQ.Count;
                        }
                        if (count == 1)
@@ -1722,11 +1695,7 @@ namespace System.Net.Sockets
                        if (remoteEP == null)
                                throw new ArgumentNullException ("remoteEP");
 
-                       if (offset < 0 || offset > buffer.Length)
-                               throw new ArgumentOutOfRangeException ("offset");
-
-                       if (size < 0 || offset + size > buffer.Length)
-                               throw new ArgumentOutOfRangeException ("size");
+                       CheckRange (buffer, offset, size);
 
                        return ReceiveFrom_nochecks (buffer, offset, size, flags, ref remoteEP);
                }
@@ -1804,11 +1773,7 @@ namespace System.Net.Sockets
                        if (remoteEP == null)
                                throw new ArgumentNullException ("remoteEP");
 
-                       if (offset < 0 || offset > buffer.Length)
-                               throw new ArgumentOutOfRangeException ("offset");
-
-                       if (size < 0 || offset + size > buffer.Length)
-                               throw new ArgumentOutOfRangeException ("size");
+                       CheckRange (buffer, offset, size);
 
                        /* FIXME: figure out how we get hold of the
                         * IPPacketInformation
@@ -1871,8 +1836,7 @@ namespace System.Net.Sockets
                        if (buf == null)
                                throw new ArgumentNullException ("buf");
 
-                       if (size < 0 || size > buf.Length)
-                               throw new ArgumentOutOfRangeException ("size");
+                       CheckRange (buf, 0, size);
 
                        SocketError error;
 
@@ -1892,11 +1856,7 @@ namespace System.Net.Sockets
                        if (buf == null)
                                throw new ArgumentNullException ("buffer");
 
-                       if (offset < 0 || offset > buf.Length)
-                               throw new ArgumentOutOfRangeException ("offset");
-
-                       if (size < 0 || offset + size > buf.Length)
-                               throw new ArgumentOutOfRangeException ("size");
+                       CheckRange (buf, offset, size);
 
                        SocketError error;
 
@@ -1916,11 +1876,7 @@ namespace System.Net.Sockets
                        if (buf == null)
                                throw new ArgumentNullException ("buffer");
 
-                       if (offset < 0 || offset > buf.Length)
-                               throw new ArgumentOutOfRangeException ("offset");
-
-                       if (size < 0 || offset + size > buf.Length)
-                               throw new ArgumentOutOfRangeException ("size");
+                       CheckRange (buf, offset, size);
 
                        return Send_nochecks (buf, offset, size, flags, out error);
                }
@@ -1981,10 +1937,9 @@ namespace System.Net.Sockets
                        res.Size = e.Count;
                        res.SockFlags = e.SocketFlags;
                        res.EndPoint = e.RemoteEndPoint;
-                       Worker worker = new Worker (e);
                        int count;
                        lock (writeQ) {
-                               writeQ.Enqueue (worker);
+                               writeQ.Enqueue (e.Worker);
                                count = writeQ.Count;
                        }
                        if (count == 1)
@@ -2032,8 +1987,7 @@ namespace System.Net.Sockets
                        if (remote_end == null)
                                throw new ArgumentNullException ("remote_end");
 
-                       if (size < 0 || size > buffer.Length)
-                               throw new ArgumentOutOfRangeException ("size");
+                       CheckRange (buffer, 0, size);
 
                        return SendTo_nochecks (buffer, 0, size, flags, remote_end);
                }
@@ -2059,11 +2013,7 @@ namespace System.Net.Sockets
                        if (remote_end == null)
                                throw new ArgumentNullException("remote_end");
 
-                       if (offset < 0 || offset > buffer.Length)
-                               throw new ArgumentOutOfRangeException ("offset");
-
-                       if (size < 0 || offset + size > buffer.Length)
-                               throw new ArgumentOutOfRangeException ("size");
+                       CheckRange (buffer, offset, size);
 
                        return SendTo_nochecks (buffer, offset, size, flags, remote_end);
                }