Przeglądaj źródła

[Socket] Move ReceiveFrom related methods to their region

Ludovic Henry 10 lat temu
rodzic
commit
5ed347d0e5

+ 185 - 194
mcs/class/System/System.Net.Sockets/Socket.cs

@@ -1755,49 +1755,205 @@ namespace System.Net.Sockets
 
 #endregion
 
-		void CheckRange (byte[] buffer, int offset, int size)
+#region ReceiveFrom
+
+		public int ReceiveFrom (byte [] buffer, ref EndPoint remoteEP)
 		{
-			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");
+			ThrowIfDisposedAndClosed ();
+			ThrowIfBufferNull (buffer);
+			ThrowIfBufferOutOfRange (buffer, 0, buffer.Length);
+
+			if (remoteEP == null)
+				throw new ArgumentNullException ("remoteEP");
+
+			return ReceiveFrom_nochecks (buffer, 0, buffer.Length, SocketFlags.None, ref remoteEP);
 		}
 
-		public IAsyncResult BeginReceiveFrom(byte[] buffer, int offset,
-						     int size,
-						     SocketFlags socket_flags,
-						     ref EndPoint remote_end,
-						     AsyncCallback callback,
-						     object state) {
-			if (is_disposed && is_closed)
-				throw new ObjectDisposedException (GetType ().ToString ());
+		public int ReceiveFrom (byte [] buffer, SocketFlags flags, ref EndPoint remoteEP)
+		{
+			ThrowIfDisposedAndClosed ();
+			ThrowIfBufferNull (buffer);
+			ThrowIfBufferOutOfRange (buffer, 0, buffer.Length);
 
-			if (buffer == null)
-				throw new ArgumentNullException ("buffer");
+			if (remoteEP == null)
+				throw new ArgumentNullException ("remoteEP");
+
+			return ReceiveFrom_nochecks (buffer, 0, buffer.Length, flags, ref remoteEP);
+		}
+
+		public int ReceiveFrom (byte [] buffer, int size, SocketFlags flags, ref EndPoint remoteEP)
+		{
+			ThrowIfDisposedAndClosed ();
+			ThrowIfBufferNull (buffer);
+			ThrowIfBufferOutOfRange (buffer, 0, size);
+
+			if (remoteEP == null)
+				throw new ArgumentNullException ("remoteEP");
+
+			return ReceiveFrom_nochecks (buffer, 0, size, flags, ref remoteEP);
+		}
+
+		public int ReceiveFrom (byte [] buffer, int offset, int size, SocketFlags flags, ref EndPoint remoteEP)
+		{
+			ThrowIfDisposedAndClosed ();
+			ThrowIfBufferNull (buffer);
+			ThrowIfBufferOutOfRange (buffer, offset, size);
+
+			if (remoteEP == null)
+				throw new ArgumentNullException ("remoteEP");
+
+			return ReceiveFrom_nochecks (buffer, offset, size, flags, ref remoteEP);
+		}
+
+		public bool ReceiveFromAsync (SocketAsyncEventArgs e)
+		{
+			ThrowIfDisposedAndClosed ();
+
+			// We do not support recv into multiple buffers yet
+			if (e.BufferList != null)
+				throw new NotSupportedException ("Mono doesn't support using BufferList at this point.");
+			if (e.RemoteEndPoint == null)
+				throw new ArgumentNullException ("remoteEP", "Value cannot be null.");
+
+			e.curSocket = this;
+			e.Worker.Init (this, e, SocketOperation.ReceiveFrom);
+
+			SocketAsyncResult sockares = e.Worker.result;
+			sockares.Buffer = e.Buffer;
+			sockares.Offset = e.Offset;
+			sockares.Size = e.Count;
+			sockares.EndPoint = e.RemoteEndPoint;
+			sockares.SockFlags = e.SocketFlags;
+
+			int count;
+			lock (readQ) {
+				readQ.Enqueue (e.Worker);
+				count = readQ.Count;
+			}
+
+			if (count == 1)
+				socket_pool_queue (SocketAsyncWorker.Dispatcher, sockares);
+
+			return true;
+		}
+
+		public IAsyncResult BeginReceiveFrom (byte[] buffer, int offset, int size, SocketFlags socket_flags, ref EndPoint remote_end, AsyncCallback callback, object state)
+		{
+			ThrowIfDisposedAndClosed ();
+			ThrowIfBufferNull (buffer);
+			ThrowIfBufferOutOfRange (buffer, offset, size);
 
 			if (remote_end == null)
 				throw new ArgumentNullException ("remote_end");
 
-			CheckRange (buffer, offset, size);
+			SocketAsyncResult sockares = new SocketAsyncResult (this, state, callback, SocketOperation.ReceiveFrom) {
+				Buffer = buffer,
+				Offset = offset,
+				Size = size,
+				SockFlags = socket_flags,
+				EndPoint = remote_end,
+			};
 
-			SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.ReceiveFrom);
-			req.Buffer = buffer;
-			req.Offset = offset;
-			req.Size = size;
-			req.SockFlags = socket_flags;
-			req.EndPoint = remote_end;
 			int count;
 			lock (readQ) {
-				readQ.Enqueue (req.Worker);
+				readQ.Enqueue (sockares.Worker);
 				count = readQ.Count;
 			}
+
 			if (count == 1)
-				socket_pool_queue (SocketAsyncWorker.Dispatcher, req);
-			return req;
+				socket_pool_queue (SocketAsyncWorker.Dispatcher, sockares);
+
+			return sockares;
+		}
+
+		public int EndReceiveFrom(IAsyncResult result, ref EndPoint end_point)
+		{
+			ThrowIfDisposedAndClosed ();
+
+			if (end_point == null)
+				throw new ArgumentNullException ("remote_end");
+
+			SocketAsyncResult sockares = ValidateEndIAsyncResult (result, "EndReceiveFrom", "result");
+
+			if (!sockares.IsCompleted)
+				sockares.AsyncWaitHandle.WaitOne();
+
+			sockares.CheckIfThrowDelayedException();
+
+			end_point = sockares.EndPoint;
+
+			return sockares.Total;
+		}
+
+		internal int ReceiveFrom_nochecks (byte [] buf, int offset, int size, SocketFlags flags, ref EndPoint remote_end)
+		{
+			int error;
+			return ReceiveFrom_nochecks_exc (buf, offset, size, flags, ref remote_end, true, out error);
+		}
+
+		internal int ReceiveFrom_nochecks_exc (byte [] buf, int offset, int size, SocketFlags flags, ref EndPoint remote_end, bool throwOnError, out int error)
+		{
+			SocketAddress sockaddr = remote_end.Serialize();
+
+			int cnt = ReceiveFrom_internal (safe_handle, buf, offset, size, flags, ref sockaddr, out error);
+
+			SocketError err = (SocketError) error;
+			if (err != 0) {
+				if (err != SocketError.WouldBlock && err != SocketError.InProgress) {
+					is_connected = false;
+				} else if (err == SocketError.WouldBlock && is_blocking) { // This might happen when ReceiveTimeout is set
+					if (throwOnError)	
+						throw new SocketException ((int) SocketError.TimedOut, TIMEOUT_EXCEPTION_MSG);
+					error = (int) SocketError.TimedOut;
+					return 0;
+				}
+
+				if (throwOnError)
+					throw new SocketException (error);
+
+				return 0;
+			}
+
+			is_connected = true;
+			is_bound = true;
+
+			/* If sockaddr is null then we're a connection oriented protocol and should ignore the
+			 * remote_end parameter (see MSDN documentation for Socket.ReceiveFrom(...) ) */
+			if (sockaddr != null) {
+				/* Stupidly, EndPoint.Create() is an instance method */
+				remote_end = remote_end.Create (sockaddr);
+			}
+
+			seed_endpoint = remote_end;
+
+			return cnt;
+		}
+
+		static int ReceiveFrom_internal (SafeSocketHandle safeHandle, byte[] buffer, int offset, int count, SocketFlags flags, ref SocketAddress sockaddr, out int error)
+		{
+			try {
+				safeHandle.RegisterForBlockingSyscall ();
+				return ReceiveFrom_internal (safeHandle.DangerousGetHandle (), buffer, offset, count, flags, ref sockaddr, out error);
+			} finally {
+				safeHandle.UnRegisterForBlockingSyscall ();
+			}
+		}
+
+		[MethodImplAttribute(MethodImplOptions.InternalCall)]
+		extern static int ReceiveFrom_internal(IntPtr sock, byte[] buffer, int offset, int count, SocketFlags flags, ref SocketAddress sockaddr, out int error);
+
+#endregion
+
+		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");
 		}
 
 		[MonoTODO]
@@ -2297,171 +2453,6 @@ namespace System.Net.Sockets
 			return result;
 		}
 
-
-		public bool ReceiveFromAsync (SocketAsyncEventArgs e)
-		{
-			if (is_disposed && is_closed)
-				throw new ObjectDisposedException (GetType ().ToString ());
-
-			// We do not support recv into multiple buffers yet
-			if (e.BufferList != null)
-				throw new NotSupportedException ("Mono doesn't support using BufferList at this point.");
-			if (e.RemoteEndPoint == null)
-				throw new ArgumentNullException ("remoteEP", "Value cannot be null.");
-
-			e.curSocket = this;
-			e.Worker.Init (this, e, SocketOperation.ReceiveFrom);
-			SocketAsyncResult res = e.Worker.result;
-			res.Buffer = e.Buffer;
-			res.Offset = e.Offset;
-			res.Size = e.Count;
-			res.EndPoint = e.RemoteEndPoint;
-			res.SockFlags = e.SocketFlags;
-			int count;
-			lock (readQ) {
-				readQ.Enqueue (e.Worker);
-				count = readQ.Count;
-			}
-			if (count == 1)
-				socket_pool_queue (SocketAsyncWorker.Dispatcher, res);
-			return true;
-		}
-
-		public int ReceiveFrom (byte [] buffer, ref EndPoint remoteEP)
-		{
-			if (is_disposed && is_closed)
-				throw new ObjectDisposedException (GetType ().ToString ());
-
-			if (buffer == null)
-				throw new ArgumentNullException ("buffer");
-
-			if (remoteEP == null)
-				throw new ArgumentNullException ("remoteEP");
-
-			return ReceiveFrom_nochecks (buffer, 0, buffer.Length, SocketFlags.None, ref remoteEP);
-		}
-
-		public int ReceiveFrom (byte [] buffer, SocketFlags flags, ref EndPoint remoteEP)
-		{
-			if (is_disposed && is_closed)
-				throw new ObjectDisposedException (GetType ().ToString ());
-
-			if (buffer == null)
-				throw new ArgumentNullException ("buffer");
-
-			if (remoteEP == null)
-				throw new ArgumentNullException ("remoteEP");
-
-			return ReceiveFrom_nochecks (buffer, 0, buffer.Length, flags, ref remoteEP);
-		}
-
-		public int ReceiveFrom (byte [] buffer, int size, SocketFlags flags,
-					ref EndPoint remoteEP)
-		{
-			if (is_disposed && is_closed)
-				throw new ObjectDisposedException (GetType ().ToString ());
-
-			if (buffer == null)
-				throw new ArgumentNullException ("buffer");
-
-			if (remoteEP == null)
-				throw new ArgumentNullException ("remoteEP");
-
-			if (size < 0 || size > buffer.Length)
-				throw new ArgumentOutOfRangeException ("size");
-
-			return ReceiveFrom_nochecks (buffer, 0, size, flags, ref remoteEP);
-		}
-
-		[MethodImplAttribute(MethodImplOptions.InternalCall)]
-		private extern static int RecvFrom_internal(IntPtr sock,
-							    byte[] buffer,
-							    int offset,
-							    int count,
-							    SocketFlags flags,
-							    ref SocketAddress sockaddr,
-							    out int error);
-
-		private static int RecvFrom_internal (SafeSocketHandle safeHandle,
-							    byte[] buffer,
-							    int offset,
-							    int count,
-							    SocketFlags flags,
-							    ref SocketAddress sockaddr,
-							    out int error)
-		{
-			try {
-				safeHandle.RegisterForBlockingSyscall ();
-				return RecvFrom_internal (safeHandle.DangerousGetHandle (), buffer, offset, count, flags, ref sockaddr, out error);
-			} finally {
-				safeHandle.UnRegisterForBlockingSyscall ();
-			}
-		}
-
-		public int ReceiveFrom (byte [] buffer, int offset, int size, SocketFlags flags,
-					ref EndPoint remoteEP)
-		{
-			if (is_disposed && is_closed)
-				throw new ObjectDisposedException (GetType ().ToString ());
-
-			if (buffer == null)
-				throw new ArgumentNullException ("buffer");
-
-			if (remoteEP == null)
-				throw new ArgumentNullException ("remoteEP");
-
-			CheckRange (buffer, offset, size);
-
-			return ReceiveFrom_nochecks (buffer, offset, size, flags, ref remoteEP);
-		}
-
-		internal int ReceiveFrom_nochecks (byte [] buf, int offset, int size, SocketFlags flags,
-						   ref EndPoint remote_end)
-		{
-			int error;
-			return ReceiveFrom_nochecks_exc (buf, offset, size, flags, ref remote_end, true, out error);
-		}
-
-		internal int ReceiveFrom_nochecks_exc (byte [] buf, int offset, int size, SocketFlags flags,
-						   ref EndPoint remote_end, bool throwOnError, out int error)
-		{
-			SocketAddress sockaddr = remote_end.Serialize();
-			int cnt = RecvFrom_internal (safe_handle, buf, offset, size, flags, ref sockaddr, out error);
-			SocketError err = (SocketError) error;
-			if (err != 0) {
-				if (err != SocketError.WouldBlock && err != SocketError.InProgress)
-					is_connected = false;
-				else if (err == SocketError.WouldBlock && is_blocking) { // This might happen when ReceiveTimeout is set
-					if (throwOnError)	
-						throw new SocketException ((int) SocketError.TimedOut, TIMEOUT_EXCEPTION_MSG);
-					error = (int) SocketError.TimedOut;
-					return 0;
-				}
-
-				if (throwOnError)
-					throw new SocketException (error);
-				return 0;
-			}
-
-			is_connected = true;
-			is_bound = true;
-
-			// If sockaddr is null then we're a connection
-			// oriented protocol and should ignore the
-			// remote_end parameter (see MSDN
-			// documentation for Socket.ReceiveFrom(...) )
-			
-			if ( sockaddr != null ) {
-				// Stupidly, EndPoint.Create() is an
-				// instance method
-				remote_end = remote_end.Create (sockaddr);
-			}
-			
-			seed_endpoint = remote_end;
-			
-			return cnt;
-		}
-
 		[MonoTODO ("Not implemented")]
 		public bool ReceiveMessageFromAsync (SocketAsyncEventArgs e)
 		{

+ 0 - 27
mcs/class/System/System.Net.Sockets/Socket_2_1.cs

@@ -460,33 +460,6 @@ namespace System.Net.Sockets {
 			return(req.Total);
 		}
 
-		// Used by Udpclient
-		public
-		int EndReceiveFrom(IAsyncResult result, ref EndPoint end_point)
-		{
-			if (is_disposed && is_closed)
-				throw new ObjectDisposedException (GetType ().ToString ());
-
-			if (result == null)
-				throw new ArgumentNullException ("result");
-
-			if (end_point == null)
-				throw new ArgumentNullException ("remote_end");
-
-			SocketAsyncResult req = result as SocketAsyncResult;
-			if (req == null)
-				throw new ArgumentException ("Invalid IAsyncResult", "result");
-
-			if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
-				throw InvalidAsyncOp ("EndReceiveFrom");
-			if (!result.IsCompleted)
-				result.AsyncWaitHandle.WaitOne();
-
- 			req.CheckIfThrowDelayedException();
-			end_point = req.EndPoint;
-			return req.Total;
-		}
-
 		[MethodImplAttribute(MethodImplOptions.InternalCall)]
 		internal static extern void socket_pool_queue (SocketAsyncCallback d, SocketAsyncResult r);
 	}

+ 3 - 3
mcs/class/System/Test/System.Net.Sockets/SocketTest.cs

@@ -3156,7 +3156,7 @@ namespace MonoTests.System.Net.Sockets
 
 			EndPoint remoteEP = new IPEndPoint (IPAddress.Loopback, 8001);
 			try {
-				s.ReceiveFrom ((Byte []) null, -1, (SocketFlags) 666,
+				s.ReceiveFrom ((Byte []) null, 0, (SocketFlags) 666,
 					ref remoteEP);
 				Assert.Fail ("#1");
 			} catch (ArgumentNullException ex) {
@@ -3178,7 +3178,7 @@ namespace MonoTests.System.Net.Sockets
 			byte [] buffer = new byte [5];
 			EndPoint remoteEP = null;
 			try {
-				s.ReceiveFrom (buffer, -1, (SocketFlags) 666, ref remoteEP);
+				s.ReceiveFrom (buffer, buffer.Length, (SocketFlags) 666, ref remoteEP);
 				Assert.Fail ("#1");
 			} catch (ArgumentNullException ex) {
 				Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
@@ -3322,7 +3322,7 @@ namespace MonoTests.System.Net.Sockets
 			EndPoint remoteEP = null;
 
 			try {
-				s.ReceiveFrom (buffer, -1, -1, (SocketFlags) 666, ref remoteEP);
+				s.ReceiveFrom (buffer, 0, buffer.Length, (SocketFlags) 666, ref remoteEP);
 				Assert.Fail ("#1");
 			} catch (ArgumentNullException ex) {
 				Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");

+ 1 - 1
mono/metadata/icall-def.h

@@ -429,9 +429,9 @@ ICALL(SOCK_8, "GetSocketOption_obj_internal(intptr,System.Net.Sockets.SocketOpti
 ICALL(SOCK_9, "Listen_internal(intptr,int,int&)", ves_icall_System_Net_Sockets_Socket_Listen_internal)
 ICALL(SOCK_10, "LocalEndPoint_internal(intptr,int,int&)", ves_icall_System_Net_Sockets_Socket_LocalEndPoint_internal)
 ICALL(SOCK_11, "Poll_internal", ves_icall_System_Net_Sockets_Socket_Poll_internal)
+ICALL(SOCK_13, "ReceiveFrom_internal(intptr,byte[],int,int,System.Net.Sockets.SocketFlags,System.Net.SocketAddress&,int&)", ves_icall_System_Net_Sockets_Socket_ReceiveFrom_internal)
 ICALL(SOCK_11a, "Receive_internal(intptr,System.Net.Sockets.Socket/WSABUF[],System.Net.Sockets.SocketFlags,int&)", ves_icall_System_Net_Sockets_Socket_Receive_array_internal)
 ICALL(SOCK_12, "Receive_internal(intptr,byte[],int,int,System.Net.Sockets.SocketFlags,int&)", ves_icall_System_Net_Sockets_Socket_Receive_internal)
-ICALL(SOCK_13, "RecvFrom_internal(intptr,byte[],int,int,System.Net.Sockets.SocketFlags,System.Net.SocketAddress&,int&)", ves_icall_System_Net_Sockets_Socket_RecvFrom_internal)
 ICALL(SOCK_14, "RemoteEndPoint_internal(intptr,int,int&)", ves_icall_System_Net_Sockets_Socket_RemoteEndPoint_internal)
 ICALL(SOCK_15, "Select_internal(System.Net.Sockets.Socket[]&,int,int&)", ves_icall_System_Net_Sockets_Socket_Select_internal)
 ICALL(SOCK_15a, "SendFile(intptr,string,byte[],byte[],System.Net.Sockets.TransmitFileOptions)", ves_icall_System_Net_Sockets_Socket_SendFile)

+ 1 - 1
mono/metadata/socket-io.c

@@ -1406,7 +1406,7 @@ gint32 ves_icall_System_Net_Sockets_Socket_Receive_array_internal(SOCKET sock, M
 	return(recv);
 }
 
-gint32 ves_icall_System_Net_Sockets_Socket_RecvFrom_internal(SOCKET sock, MonoArray *buffer, gint32 offset, gint32 count, gint32 flags, MonoObject **sockaddr, gint32 *error)
+gint32 ves_icall_System_Net_Sockets_Socket_ReceiveFrom_internal(SOCKET sock, MonoArray *buffer, gint32 offset, gint32 count, gint32 flags, MonoObject **sockaddr, gint32 *error)
 {
 	int ret;
 	guchar *buf;

+ 1 - 1
mono/metadata/socket-io.h

@@ -204,7 +204,7 @@ extern void ves_icall_System_Net_Sockets_Socket_Bind_internal(SOCKET sock, MonoO
 extern void ves_icall_System_Net_Sockets_Socket_Connect_internal(SOCKET sock, MonoObject *sockaddr, gint32 *error);
 extern gint32 ves_icall_System_Net_Sockets_Socket_Receive_internal(SOCKET sock, MonoArray *buffer, gint32 offset, gint32 count, gint32 flags, gint32 *error);
 extern gint32 ves_icall_System_Net_Sockets_Socket_Receive_array_internal(SOCKET sock, MonoArray *buffers, gint32 flags, gint32 *error);
-extern gint32 ves_icall_System_Net_Sockets_Socket_RecvFrom_internal(SOCKET sock, MonoArray *buffer, gint32 offset, gint32 count, gint32 flags, MonoObject **sockaddr, gint32 *error);
+extern gint32 ves_icall_System_Net_Sockets_Socket_ReceiveFrom_internal(SOCKET sock, MonoArray *buffer, gint32 offset, gint32 count, gint32 flags, MonoObject **sockaddr, gint32 *error);
 extern gint32 ves_icall_System_Net_Sockets_Socket_Send_internal(SOCKET sock, MonoArray *buffer, gint32 offset, gint32 count, gint32 flags, gint32 *error);
 extern gint32 ves_icall_System_Net_Sockets_Socket_Send_array_internal(SOCKET sock, MonoArray *buffers, gint32 flags, gint32 *error);
 extern gint32 ves_icall_System_Net_Sockets_Socket_SendTo_internal(SOCKET sock, MonoArray *buffer, gint32 offset, gint32 count, gint32 flags, MonoObject *sockaddr, gint32 *error);