[socket] Reduce handle manipulations in native (#5378)
authorLudovic Henry <ludovic@xamarin.com>
Thu, 31 Aug 2017 17:21:29 +0000 (13:21 -0400)
committerGitHub <noreply@github.com>
Thu, 31 Aug 2017 17:21:29 +0000 (13:21 -0400)
configure.ac
mcs/class/System/System.Net.Sockets/Socket.cs
mono/metadata/icall-def.h
mono/metadata/w32socket-internals.h
mono/metadata/w32socket.c
mono/metadata/w32socket.h

index ba174a27c1afea4d0f9a898c4e9fc80df8576b39..2c5e83eb768c35d4926a5bd84e6461187b1dee40 100644 (file)
@@ -40,7 +40,7 @@ MONO_VERSION_BUILD=`echo $VERSION | cut -d . -f 3`
 # This can be reset to 0 when Mono's version number is bumped
 # since it's part of the corlib version (the prefix '1' in the full
 # version number is to ensure the number isn't treated as octal in C)
-MONO_CORLIB_COUNTER=0
+MONO_CORLIB_COUNTER=1
 MONO_CORLIB_VERSION=`printf "1%02d%02d%02d%03d" $MONO_VERSION_MAJOR $MONO_VERSION_MINOR 0 $MONO_CORLIB_COUNTER`
 
 AC_DEFINE_UNQUOTED(MONO_CORLIB_VERSION,$MONO_CORLIB_VERSION,[Version of the corlib-runtime interface])
index ae92b8d730bb51f7ad2493ae02351ccd90cbfb36..4a889e4dd2709692107c9acee71d19ca0b670551 100644 (file)
@@ -1290,7 +1290,12 @@ namespace System.Net.Sockets
                        ThrowIfBufferOutOfRange (buffer, offset, size);
 
                        int nativeError;
-                       int ret = Receive_internal (m_Handle, buffer, offset, size, socketFlags, out nativeError, is_blocking);
+                       int ret;
+                       unsafe {
+                               fixed (byte* pbuffer = buffer) {
+                                       ret = Receive_internal (m_Handle, &pbuffer[offset], size, socketFlags, out nativeError, is_blocking);
+                               }
+                       }
 
                        errorCode = (SocketError) nativeError;
                        if (errorCode != SocketError.Success && errorCode != SocketError.WouldBlock && errorCode != SocketError.InProgress) {
@@ -1315,25 +1320,27 @@ namespace System.Net.Sockets
                        int nativeError;
                        int ret;
 
-                       /* Only example I can find of sending a byte array reference directly into an internal
-                        * call is in System.Runtime.Remoting/System.Runtime.Remoting.Channels.Ipc.Win32/NamedPipeSocket.cs,
-                        * so taking a lead from that... */
-                       WSABUF[] bufarray = new WSABUF[numsegments];
                        GCHandle[] gch = new GCHandle[numsegments];
+                       try {
+                               unsafe {
+                                       fixed (WSABUF* bufarray = new WSABUF[numsegments]) {
+                                               for (int i = 0; i < numsegments; i++) {
+                                                       ArraySegment<byte> segment = buffers[i];
 
-                       for (int i = 0; i < numsegments; i++) {
-                               ArraySegment<byte> segment = buffers[i];
+                                                       if (segment.Offset < 0 || segment.Count < 0 || segment.Count > segment.Array.Length - segment.Offset)
+                                                               throw new ArgumentOutOfRangeException ("segment");
 
-                               if (segment.Offset < 0 || segment.Count < 0 || segment.Count > segment.Array.Length - segment.Offset)
-                                       throw new ArgumentOutOfRangeException ("segment");
+                                                       try {} finally {
+                                                               gch[i] = GCHandle.Alloc (segment.Array, GCHandleType.Pinned);
+                                                       }
 
-                               gch[i] = GCHandle.Alloc (segment.Array, GCHandleType.Pinned);
-                               bufarray[i].len = segment.Count;
-                               bufarray[i].buf = Marshal.UnsafeAddrOfPinnedArrayElement (segment.Array, segment.Offset);
-                       }
+                                                       bufarray[i].len = segment.Count;
+                                                       bufarray[i].buf = Marshal.UnsafeAddrOfPinnedArrayElement (segment.Array, segment.Offset);
+                                               }
 
-                       try {
-                               ret = Receive_internal (m_Handle, bufarray, socketFlags, out nativeError, is_blocking);
+                                               ret = Receive_internal (m_Handle, bufarray, numsegments, socketFlags, out nativeError, is_blocking);
+                                       }
+                               }
                        } finally {
                                for (int i = 0; i < numsegments; i++) {
                                        if (gch[i].IsAllocated)
@@ -1422,7 +1429,11 @@ namespace System.Net.Sockets
                        int total = 0;
 
                        try {
-                               total = Receive_internal (sockares.socket.m_Handle, sockares.Buffer, sockares.Offset, sockares.Size, sockares.SockFlags, out sockares.error, sockares.socket.is_blocking);
+                               unsafe {
+                                       fixed (byte* pbuffer = sockares.Buffer) {
+                                               total = Receive_internal (sockares.socket.m_Handle, &pbuffer[sockares.Offset], sockares.Size, sockares.SockFlags, out sockares.error, sockares.socket.is_blocking);
+                                       }
+                               }
                        } catch (Exception e) {
                                sockares.Complete (e);
                                return;
@@ -1488,31 +1499,31 @@ namespace System.Net.Sockets
                        return sockares.Total;
                }
 
-               static int Receive_internal (SafeSocketHandle safeHandle, WSABUF[] bufarray, SocketFlags flags, out int error, bool blocking)
+               static unsafe int Receive_internal (SafeSocketHandle safeHandle, WSABUF* bufarray, int count, SocketFlags flags, out int error, bool blocking)
                {
                        try {
                                safeHandle.RegisterForBlockingSyscall ();
-                               return Receive_internal (safeHandle.DangerousGetHandle (), bufarray, flags, out error, blocking);
+                               return Receive_internal (safeHandle.DangerousGetHandle (), bufarray, count, flags, out error, blocking);
                        } finally {
                                safeHandle.UnRegisterForBlockingSyscall ();
                        }
                }
 
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               extern static int Receive_internal (IntPtr sock, WSABUF[] bufarray, SocketFlags flags, out int error, bool blocking);
+               extern static unsafe int Receive_internal (IntPtr sock, WSABUF* bufarray, int count, SocketFlags flags, out int error, bool blocking);
 
-               static int Receive_internal (SafeSocketHandle safeHandle, byte[] buffer, int offset, int count, SocketFlags flags, out int error, bool blocking)
+               static unsafe int Receive_internal (SafeSocketHandle safeHandle, byte* buffer, int count, SocketFlags flags, out int error, bool blocking)
                {
                        try {
                                safeHandle.RegisterForBlockingSyscall ();
-                               return Receive_internal (safeHandle.DangerousGetHandle (), buffer, offset, count, flags, out error, blocking);
+                               return Receive_internal (safeHandle.DangerousGetHandle (), buffer, count, flags, out error, blocking);
                        } finally {
                                safeHandle.UnRegisterForBlockingSyscall ();
                        }
                }
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               extern static int Receive_internal(IntPtr sock, byte[] buffer, int offset, int count, SocketFlags flags, out int error, bool blocking);
+               extern static unsafe int Receive_internal(IntPtr sock, byte* buffer, int count, SocketFlags flags, out int error, bool blocking);
 
 #endregion
 
@@ -1541,7 +1552,12 @@ namespace System.Net.Sockets
                        SocketAddress sockaddr = remoteEP.Serialize();
 
                        int nativeError;
-                       int cnt = ReceiveFrom_internal (m_Handle, buffer, offset, size, socketFlags, ref sockaddr, out nativeError, is_blocking);
+                       int cnt;
+                       unsafe {
+                               fixed (byte* pbuffer = buffer) {
+                                       cnt = ReceiveFrom_internal (m_Handle, &pbuffer[offset], size, socketFlags, ref sockaddr, out nativeError, is_blocking);
+                               }
+                       }
 
                        errorCode = (SocketError) nativeError;
                        if (errorCode != SocketError.Success) {
@@ -1672,18 +1688,18 @@ namespace System.Net.Sockets
 
 
 
-               static int ReceiveFrom_internal (SafeSocketHandle safeHandle, byte[] buffer, int offset, int count, SocketFlags flags, ref SocketAddress sockaddr, out int error, bool blocking)
+               static unsafe int ReceiveFrom_internal (SafeSocketHandle safeHandle, byte* buffer, int count, SocketFlags flags, ref SocketAddress sockaddr, out int error, bool blocking)
                {
                        try {
                                safeHandle.RegisterForBlockingSyscall ();
-                               return ReceiveFrom_internal (safeHandle.DangerousGetHandle (), buffer, offset, count, flags, ref sockaddr, out error, blocking);
+                               return ReceiveFrom_internal (safeHandle.DangerousGetHandle (), buffer, count, flags, ref sockaddr, out error, blocking);
                        } 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, bool blocking);
+               extern static unsafe int ReceiveFrom_internal(IntPtr sock, byte* buffer, int count, SocketFlags flags, ref SocketAddress sockaddr, out int error, bool blocking);
 
 #endregion
 
@@ -1757,8 +1773,12 @@ namespace System.Net.Sockets
                        int nativeError;
                        int sent = 0;
                        do {
-                               sent += Send_internal (
-m_Handle, buffer, offset + sent, size - sent, socketFlags, out nativeError, is_blocking);
+                               unsafe {
+                                       fixed (byte *pbuffer = buffer) {
+                                               sent += Send_internal (m_Handle, &pbuffer[offset + sent], size - sent, socketFlags, out nativeError, is_blocking);
+                                       }
+                               }
+
                                errorCode = (SocketError)nativeError;
                                if (errorCode != SocketError.Success && errorCode != SocketError.WouldBlock && errorCode != SocketError.InProgress) {
                                        is_connected = false;
@@ -1786,28 +1806,32 @@ m_Handle, buffer, offset + sent, size - sent, socketFlags, out nativeError, is_b
                        int nativeError;
                        int ret;
 
-                       WSABUF[] bufarray = new WSABUF[numsegments];
                        GCHandle[] gch = new GCHandle[numsegments];
+                       try {
+                               unsafe {
+                                       fixed (WSABUF* bufarray = new WSABUF[numsegments]) {
+                                               for(int i = 0; i < numsegments; i++) {
+                                                       ArraySegment<byte> segment = buffers[i];
 
-                       for(int i = 0; i < numsegments; i++) {
-                               ArraySegment<byte> segment = buffers[i];
+                                                       if (segment.Offset < 0 || segment.Count < 0 || segment.Count > segment.Array.Length - segment.Offset)
+                                                               throw new ArgumentOutOfRangeException ("segment");
 
-                               if (segment.Offset < 0 || segment.Count < 0 || segment.Count > segment.Array.Length - segment.Offset)
-                                       throw new ArgumentOutOfRangeException ("segment");
+                                                       try {} finally {
+                                                               gch[i] = GCHandle.Alloc (segment.Array, GCHandleType.Pinned);
+                                                       }
 
-                               gch[i] = GCHandle.Alloc (segment.Array, GCHandleType.Pinned);
-                               bufarray[i].len = segment.Count;
-                               bufarray[i].buf = Marshal.UnsafeAddrOfPinnedArrayElement (segment.Array, segment.Offset);
-                       }
+                                                       bufarray[i].len = segment.Count;
+                                                       bufarray[i].buf = Marshal.UnsafeAddrOfPinnedArrayElement (segment.Array, segment.Offset);
+                                               }
 
-                       try {
-                               ret = Send_internal (m_Handle, bufarray, socketFlags, out nativeError, is_blocking);
-                       } finally {
-                               for(int i = 0; i < numsegments; i++) {
-                                       if (gch[i].IsAllocated) {
-                                               gch[i].Free ();
+                                               ret = Send_internal (m_Handle, bufarray, numsegments, socketFlags, out nativeError, is_blocking);
                                        }
                                }
+                       } finally {
+                               for (int i = 0; i < numsegments; i++) {
+                                       if (gch[i].IsAllocated)
+                                               gch[i].Free();
+                               }
                        }
 
                        errorCode = (SocketError)nativeError;
@@ -1890,7 +1914,11 @@ m_Handle, buffer, offset + sent, size - sent, socketFlags, out nativeError, is_b
                        int total = 0;
 
                        try {
-                               total = Socket.Send_internal (sockares.socket.m_Handle, sockares.Buffer, sockares.Offset, sockares.Size, sockares.SockFlags, out sockares.error, false);
+                               unsafe {
+                                       fixed (byte *pbuffer = sockares.Buffer) {
+                                               total = Socket.Send_internal (sockares.socket.m_Handle, &pbuffer[sockares.Offset], sockares.Size, sockares.SockFlags, out sockares.error, false);
+                                       }
+                               }
                        } catch (Exception e) {
                                sockares.Complete (e);
                                return;
@@ -1978,31 +2006,31 @@ m_Handle, buffer, offset + sent, size - sent, socketFlags, out nativeError, is_b
                        return sockares.Total;
                }
 
-               static int Send_internal (SafeSocketHandle safeHandle, WSABUF[] bufarray, SocketFlags flags, out int error, bool blocking)
+               static unsafe int Send_internal (SafeSocketHandle safeHandle, WSABUF* bufarray, int count, SocketFlags flags, out int error, bool blocking)
                {
                        try {
                                safeHandle.RegisterForBlockingSyscall ();
-                               return Send_internal (safeHandle.DangerousGetHandle (), bufarray, flags, out error, blocking);
+                               return Send_internal (safeHandle.DangerousGetHandle (), bufarray, count, flags, out error, blocking);
                        } finally {
                                safeHandle.UnRegisterForBlockingSyscall ();
                        }
                }
 
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               extern static int Send_internal (IntPtr sock, WSABUF[] bufarray, SocketFlags flags, out int error, bool blocking);
+               extern static unsafe int Send_internal (IntPtr sock, WSABUF* bufarray, int count, SocketFlags flags, out int error, bool blocking);
 
-               static int Send_internal (SafeSocketHandle safeHandle, byte[] buf, int offset, int count, SocketFlags flags, out int error, bool blocking)
+               static unsafe int Send_internal (SafeSocketHandle safeHandle, byte* buffer, int count, SocketFlags flags, out int error, bool blocking)
                {
                        try {
                                safeHandle.RegisterForBlockingSyscall ();
-                               return Send_internal (safeHandle.DangerousGetHandle (), buf, offset, count, flags, out error, blocking);
+                               return Send_internal (safeHandle.DangerousGetHandle (), buffer, count, flags, out error, blocking);
                        } finally {
                                safeHandle.UnRegisterForBlockingSyscall ();
                        }
                }
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               extern static int Send_internal(IntPtr sock, byte[] buf, int offset, int count, SocketFlags flags, out int error, bool blocking);
+               extern static unsafe int Send_internal(IntPtr sock, byte* buffer, int count, SocketFlags flags, out int error, bool blocking);
 
 #endregion
 
@@ -2018,7 +2046,12 @@ m_Handle, buffer, offset + sent, size - sent, socketFlags, out nativeError, is_b
                                throw new ArgumentNullException("remoteEP");
 
                        int error;
-                       int ret = SendTo_internal (m_Handle, buffer, offset, size, socketFlags, remoteEP.Serialize (), out error, is_blocking);
+                       int ret;
+                       unsafe {
+                               fixed (byte *pbuffer = buffer) {
+                                       ret = SendTo_internal (m_Handle, &pbuffer[offset], size, socketFlags, remoteEP.Serialize (), out error, is_blocking);
+                               }
+                       }
 
                        SocketError err = (SocketError) error;
                        if (err != 0) {
@@ -2134,18 +2167,18 @@ m_Handle, buffer, offset + sent, size - sent, socketFlags, out nativeError, is_b
                        return sockares.Total;
                }
 
-               static int SendTo_internal (SafeSocketHandle safeHandle, byte[] buffer, int offset, int count, SocketFlags flags, SocketAddress sa, out int error, bool blocking)
+               static unsafe int SendTo_internal (SafeSocketHandle safeHandle, byte* buffer, int count, SocketFlags flags, SocketAddress sa, out int error, bool blocking)
                {
                        try {
                                safeHandle.RegisterForBlockingSyscall ();
-                               return SendTo_internal (safeHandle.DangerousGetHandle (), buffer, offset, count, flags, sa, out error, blocking);
+                               return SendTo_internal (safeHandle.DangerousGetHandle (), buffer, count, flags, sa, out error, blocking);
                        } finally {
                                safeHandle.UnRegisterForBlockingSyscall ();
                        }
                }
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               extern static int SendTo_internal (IntPtr sock, byte[] buffer, int offset, int count, SocketFlags flags, SocketAddress sa, out int error, bool blocking);
+               extern static unsafe int SendTo_internal (IntPtr sock, byte* buffer, int count, SocketFlags flags, SocketAddress sa, out int error, bool blocking);
 
 #endregion
 
index ecd050a26e0469e29f4d71f42dce3c75fe5bdc7f..28615d8c1a986bb9eacb71051805387e20e365f0 100644 (file)
@@ -467,15 +467,15 @@ HANDLES(ICALL(SOCK_21, "IOControl_internal(intptr,int,byte[],byte[],int&)", ves_
 HANDLES(ICALL(SOCK_9, "Listen_internal(intptr,int,int&)", ves_icall_System_Net_Sockets_Socket_Listen_internal))
 HANDLES(ICALL(SOCK_10, "LocalEndPoint_internal(intptr,int,int&)", ves_icall_System_Net_Sockets_Socket_LocalEndPoint_internal))
 HANDLES(ICALL(SOCK_11, "Poll_internal", ves_icall_System_Net_Sockets_Socket_Poll_internal))
-HANDLES(ICALL(SOCK_13, "ReceiveFrom_internal(intptr,byte[],int,int,System.Net.Sockets.SocketFlags,System.Net.SocketAddress&,int&,bool)", ves_icall_System_Net_Sockets_Socket_ReceiveFrom_internal))
-HANDLES(ICALL(SOCK_11a, "Receive_internal(intptr,System.Net.Sockets.Socket/WSABUF[],System.Net.Sockets.SocketFlags,int&,bool)", ves_icall_System_Net_Sockets_Socket_Receive_array_internal))
-HANDLES(ICALL(SOCK_12, "Receive_internal(intptr,byte[],int,int,System.Net.Sockets.SocketFlags,int&,bool)", ves_icall_System_Net_Sockets_Socket_Receive_internal))
+HANDLES(ICALL(SOCK_13, "ReceiveFrom_internal(intptr,byte*,int,System.Net.Sockets.SocketFlags,System.Net.SocketAddress&,int&,bool)", ves_icall_System_Net_Sockets_Socket_ReceiveFrom_internal))
+HANDLES(ICALL(SOCK_11a, "Receive_internal(intptr,System.Net.Sockets.Socket/WSABUF*,int,System.Net.Sockets.SocketFlags,int&,bool)", ves_icall_System_Net_Sockets_Socket_Receive_array_internal))
+HANDLES(ICALL(SOCK_12, "Receive_internal(intptr,byte*,int,System.Net.Sockets.SocketFlags,int&,bool)", ves_icall_System_Net_Sockets_Socket_Receive_internal))
 HANDLES(ICALL(SOCK_14, "RemoteEndPoint_internal(intptr,int,int&)", ves_icall_System_Net_Sockets_Socket_RemoteEndPoint_internal))
 HANDLES(ICALL(SOCK_15, "Select_internal(System.Net.Sockets.Socket[]&,int,int&)", ves_icall_System_Net_Sockets_Socket_Select_internal))
 HANDLES(ICALL(SOCK_15a, "SendFile_internal(intptr,string,byte[],byte[],System.Net.Sockets.TransmitFileOptions,int&,bool)", ves_icall_System_Net_Sockets_Socket_SendFile_internal))
-HANDLES(ICALL(SOCK_16, "SendTo_internal(intptr,byte[],int,int,System.Net.Sockets.SocketFlags,System.Net.SocketAddress,int&,bool)", ves_icall_System_Net_Sockets_Socket_SendTo_internal))
-HANDLES(ICALL(SOCK_16a, "Send_internal(intptr,System.Net.Sockets.Socket/WSABUF[],System.Net.Sockets.SocketFlags,int&,bool)", ves_icall_System_Net_Sockets_Socket_Send_array_internal))
-HANDLES(ICALL(SOCK_17, "Send_internal(intptr,byte[],int,int,System.Net.Sockets.SocketFlags,int&,bool)", ves_icall_System_Net_Sockets_Socket_Send_internal))
+HANDLES(ICALL(SOCK_16, "SendTo_internal(intptr,byte*,int,System.Net.Sockets.SocketFlags,System.Net.SocketAddress,int&,bool)", ves_icall_System_Net_Sockets_Socket_SendTo_internal))
+HANDLES(ICALL(SOCK_16a, "Send_internal(intptr,System.Net.Sockets.Socket/WSABUF*,int,System.Net.Sockets.SocketFlags,int&,bool)", ves_icall_System_Net_Sockets_Socket_Send_array_internal))
+HANDLES(ICALL(SOCK_17, "Send_internal(intptr,byte*,int,System.Net.Sockets.SocketFlags,int&,bool)", ves_icall_System_Net_Sockets_Socket_Send_internal))
 HANDLES(ICALL(SOCK_18, "SetSocketOption_internal(intptr,System.Net.Sockets.SocketOptionLevel,System.Net.Sockets.SocketOptionName,object,byte[],int,int&)", ves_icall_System_Net_Sockets_Socket_SetSocketOption_internal))
 HANDLES(ICALL(SOCK_19, "Shutdown_internal(intptr,System.Net.Sockets.SocketShutdown,int&)", ves_icall_System_Net_Sockets_Socket_Shutdown_internal))
 HANDLES(ICALL(SOCK_20, "Socket_internal(System.Net.Sockets.AddressFamily,System.Net.Sockets.SocketType,System.Net.Sockets.ProtocolType,int&)", ves_icall_System_Net_Sockets_Socket_Socket_internal))
index cf9fb28e466950607f2eee6c681d9ce86c009f40..62e2eb154c9c4e28c62a81e23787d7703c10f134 100644 (file)
 #define TF_DISCONNECT 0x01
 #define TF_REUSE_SOCKET 0x02
 
-typedef struct {
-       guint32 len;
-       gpointer buf;
-} WSABUF, *LPWSABUF;
-
 typedef struct {
        gpointer Head;
        guint32 HeadLength;
index 9c0053455829860be455830da6f617c57ffb73c4..43df41bfdc717181022977d5bbc39853e43bdb87 100644 (file)
@@ -1429,21 +1429,15 @@ ves_icall_System_Net_Sockets_Socket_Duplicate_internal (gpointer handle, gint32
 }
 
 gint32
-ves_icall_System_Net_Sockets_Socket_Receive_internal (gsize sock, MonoArrayHandle buffer, gint32 offset, gint32 count, gint32 flags, gint32 *werror, gboolean blocking, MonoError *error)
+ves_icall_System_Net_Sockets_Socket_Receive_internal (gsize sock, gchar *buffer, gint32 count, gint32 flags, gint32 *werror, gboolean blocking, MonoError *error)
 {
        int ret;
-       gint32 alen;
        int recvflags = 0;
        gboolean interrupted;
-       MonoInternalThread* curthread G_GNUC_UNUSED = mono_thread_internal_current ();
        
        error_init (error);
        *werror = 0;
        
-       alen = mono_array_handle_length (buffer);
-       if (offset > alen - count)
-               return 0;
-       
        recvflags = convert_socketflags (flags);
        if (recvflags == -1) {
                *werror = WSAEOPNOTSUPP;
@@ -1454,12 +1448,7 @@ ves_icall_System_Net_Sockets_Socket_Receive_internal (gsize sock, MonoArrayHandl
        if (interrupted)
                return 0;
 
-       uint32_t gchandle;
-       gchar *buf = MONO_ARRAY_HANDLE_PIN (buffer, gchar, offset, &gchandle);
-
-       ret = mono_w32socket_recv (sock, buf, count, recvflags, blocking);
-
-       mono_gchandle_free (gchandle);
+       ret = mono_w32socket_recv (sock, buffer, count, recvflags, blocking);
        
        if (ret == SOCKET_ERROR)
                *werror = mono_w32socket_get_last_error ();
@@ -1475,9 +1464,9 @@ ves_icall_System_Net_Sockets_Socket_Receive_internal (gsize sock, MonoArrayHandl
 }
 
 gint32
-ves_icall_System_Net_Sockets_Socket_Receive_array_internal (gsize sock, MonoArrayHandle buffers, gint32 flags, gint32 *werror, gboolean blocking, MonoError *error)
+ves_icall_System_Net_Sockets_Socket_Receive_array_internal (gsize sock, WSABUF *buffers, gint32 count, gint32 flags, gint32 *werror, gboolean blocking, MonoError *error)
 {
-       int ret, count;
+       int ret;
        gboolean interrupted;
        guint32 recv;
        guint32 recvflags = 0;
@@ -1485,8 +1474,6 @@ ves_icall_System_Net_Sockets_Socket_Receive_array_internal (gsize sock, MonoArra
        error_init (error);
        *werror = 0;
        
-       count = mono_array_handle_length (buffers);
-       
        recvflags = convert_socketflags (flags);
        if (recvflags == -1) {
                *werror = WSAEOPNOTSUPP;
@@ -1499,12 +1486,7 @@ ves_icall_System_Net_Sockets_Socket_Receive_array_internal (gsize sock, MonoArra
                return 0;
        }
 
-       uint32_t gchandle;
-       WSABUF *wsabufs = MONO_ARRAY_HANDLE_PIN (buffers, WSABUF, 0, &gchandle);
-
-       ret = mono_w32socket_recvbuffers (sock, wsabufs, count, &recv, &recvflags, NULL, NULL, blocking);
-
-       mono_gchandle_free (gchandle);
+       ret = mono_w32socket_recvbuffers (sock, buffers, count, &recv, &recvflags, NULL, NULL, blocking);
 
        if (ret == SOCKET_ERROR)
                *werror = mono_w32socket_get_last_error ();
@@ -1520,11 +1502,9 @@ ves_icall_System_Net_Sockets_Socket_Receive_array_internal (gsize sock, MonoArra
 }
 
 gint32
-ves_icall_System_Net_Sockets_Socket_ReceiveFrom_internal (gsize sock, MonoArrayHandle buffer, gint32 offset, gint32 count, gint32 flags, MonoObjectHandle sockaddr, gint32 *werror, gboolean blocking, MonoError *error)
+ves_icall_System_Net_Sockets_Socket_ReceiveFrom_internal (gsize sock, gchar *buffer, gint32 count, gint32 flags, MonoObjectHandle sockaddr, gint32 *werror, gboolean blocking, MonoError *error)
 {
        int ret;
-       gchar *buf;
-       gint32 alen;
        int recvflags = 0;
        struct sockaddr *sa;
        socklen_t sa_size;
@@ -1532,10 +1512,6 @@ ves_icall_System_Net_Sockets_Socket_ReceiveFrom_internal (gsize sock, MonoArrayH
        
        error_init (error);
        *werror = 0;
-       
-       alen = mono_array_handle_length (buffer);
-       if (offset > alen - count)
-               return 0;
 
        sa = create_sockaddr_from_handle (sockaddr, &sa_size, werror, error);
        if (*werror != 0)
@@ -1556,12 +1532,7 @@ ves_icall_System_Net_Sockets_Socket_ReceiveFrom_internal (gsize sock, MonoArrayH
                return 0;
        }
 
-       uint32_t gchandle;
-       buf = MONO_ARRAY_HANDLE_PIN (buffer, gchar, offset, &gchandle);
-
-       ret = mono_w32socket_recvfrom (sock, buf, count, recvflags, sa, &sa_size, blocking);
-
-       mono_gchandle_free (gchandle);
+       ret = mono_w32socket_recvfrom (sock, buffer, count, recvflags, sa, &sa_size, blocking);
 
        if (ret == SOCKET_ERROR)
                *werror = mono_w32socket_get_last_error ();
@@ -1596,22 +1567,15 @@ ves_icall_System_Net_Sockets_Socket_ReceiveFrom_internal (gsize sock, MonoArrayH
 }
 
 gint32
-ves_icall_System_Net_Sockets_Socket_Send_internal (gsize sock, MonoArrayHandle buffer, gint32 offset, gint32 count, gint32 flags, gint32 *werror, gboolean blocking, MonoError *error)
+ves_icall_System_Net_Sockets_Socket_Send_internal (gsize sock, gchar *buffer, gint32 count, gint32 flags, gint32 *werror, gboolean blocking, MonoError *error)
 {
        int ret;
-       gint32 alen;
        int sendflags = 0;
        gboolean interrupted;
        
        error_init (error);
        *werror = 0;
        
-       alen = mono_array_handle_length (buffer);
-       if (offset > alen - count)
-               return 0;
-
-       LOGDEBUG (g_message("%s: alen: %d", __func__, alen));
-       
        LOGDEBUG (g_message("%s: Sending %d bytes", __func__, count));
 
        sendflags = convert_socketflags (flags);
@@ -1626,12 +1590,7 @@ ves_icall_System_Net_Sockets_Socket_Send_internal (gsize sock, MonoArrayHandle b
                return 0;
        }
 
-       uint32_t gchandle;
-       gchar *buf = MONO_ARRAY_HANDLE_PIN (buffer, gchar, offset, &gchandle);
-
-       ret = mono_w32socket_send (sock, buf, count, sendflags, blocking);
-
-       mono_gchandle_free (gchandle);
+       ret = mono_w32socket_send (sock, buffer, count, sendflags, blocking);
 
        if (ret == SOCKET_ERROR)
                *werror = mono_w32socket_get_last_error ();
@@ -1647,9 +1606,9 @@ ves_icall_System_Net_Sockets_Socket_Send_internal (gsize sock, MonoArrayHandle b
 }
 
 gint32
-ves_icall_System_Net_Sockets_Socket_Send_array_internal (gsize sock, MonoArrayHandle buffers, gint32 flags, gint32 *werror, gboolean blocking, MonoError *error)
+ves_icall_System_Net_Sockets_Socket_Send_array_internal (gsize sock, WSABUF *buffers, gint32 count, gint32 flags, gint32 *werror, gboolean blocking, MonoError *error)
 {
-       int ret, count;
+       int ret;
        guint32 sent;
        guint32 sendflags = 0;
        gboolean interrupted;
@@ -1657,8 +1616,6 @@ ves_icall_System_Net_Sockets_Socket_Send_array_internal (gsize sock, MonoArrayHa
        error_init (error);
        *werror = 0;
        
-       count = mono_array_handle_length (buffers);
-       
        sendflags = convert_socketflags (flags);
        if (sendflags == -1) {
                *werror = WSAEOPNOTSUPP;
@@ -1671,12 +1628,7 @@ ves_icall_System_Net_Sockets_Socket_Send_array_internal (gsize sock, MonoArrayHa
                return 0;
        }
 
-       uint32_t gchandle;
-       WSABUF *wsabufs = MONO_ARRAY_HANDLE_PIN (buffers, WSABUF, 0, &gchandle);
-
-       ret = mono_w32socket_sendbuffers (sock, wsabufs, count, &sent, sendflags, NULL, NULL, blocking);
-
-       mono_gchandle_free (gchandle);
+       ret = mono_w32socket_sendbuffers (sock, buffers, count, &sent, sendflags, NULL, NULL, blocking);
 
        if (ret == SOCKET_ERROR)
                *werror = mono_w32socket_get_last_error ();
@@ -1692,29 +1644,21 @@ ves_icall_System_Net_Sockets_Socket_Send_array_internal (gsize sock, MonoArrayHa
 }
 
 gint32
-ves_icall_System_Net_Sockets_Socket_SendTo_internal (gsize sock, MonoArrayHandle buffer, gint32 offset, gint32 count, gint32 flags, MonoObjectHandle sockaddr, gint32 *werror, gboolean blocking, MonoError *error)
+ves_icall_System_Net_Sockets_Socket_SendTo_internal (gsize sock, gchar *buffer, gint32 count, gint32 flags, MonoObjectHandle sockaddr, gint32 *werror, gboolean blocking, MonoError *error)
 {
        int ret;
-       gint32 alen;
        int sendflags = 0;
        struct sockaddr *sa;
        socklen_t sa_size;
        gboolean interrupted;
        
        *werror = 0;
-       
-       alen = mono_array_handle_length (buffer);
-       if (offset > alen - count) {
-               return 0;
-       }
 
        sa = create_sockaddr_from_handle (sockaddr, &sa_size, werror, error);
        if (*werror != 0)
                return 0;
        return_val_if_nok (error, 0);
        
-       LOGDEBUG (g_message ("%s: alen: %d", __func__, alen));
-       
        LOGDEBUG (g_message("%s: Sending %d bytes", __func__, count));
 
        sendflags = convert_socketflags (flags);
@@ -1731,12 +1675,7 @@ ves_icall_System_Net_Sockets_Socket_SendTo_internal (gsize sock, MonoArrayHandle
                return 0;
        }
 
-       uint32_t gchandle;
-       gchar *buf = MONO_ARRAY_HANDLE_PIN (buffer, gchar, offset, &gchandle);
-
-       ret = mono_w32socket_sendto (sock, buf, count, sendflags, sa, sa_size, blocking);
-
-       mono_gchandle_free (gchandle);
+       ret = mono_w32socket_sendto (sock, buffer, count, sendflags, sa, sa_size, blocking);
 
        if (ret == SOCKET_ERROR)
                *werror = mono_w32socket_get_last_error ();
index 9fcd2341d7825e05b7aeb5065ce87acc0d2f94d0..5d5aa4adc53b472f35e448cf21e01bacc80e1829 100644 (file)
 
 #ifndef HOST_WIN32
 typedef gint SOCKET;
+
+typedef struct {
+       guint32 len;
+       gpointer buf;
+} WSABUF, *LPWSABUF;
 #endif
 
 /* This is a copy of System.Net.Sockets.SocketType */
@@ -204,32 +209,28 @@ void
 ves_icall_System_Net_Sockets_Socket_Connect_internal (gsize sock, MonoObjectHandle sockaddr, gint32 *werror, gboolean blocking, MonoError *error);
 
 gint32
-ves_icall_System_Net_Sockets_Socket_Receive_internal (gsize sock, MonoArrayHandle buffer, gint32 offset, gint32 count,
+ves_icall_System_Net_Sockets_Socket_Receive_internal (gsize sock, gchar *buffer, gint32 count,
                                                      gint32 flags, gint32 *werror, gboolean blocking, MonoError *error);
 
 gint32
-ves_icall_System_Net_Sockets_Socket_Receive_array_internal (gsize sock, MonoArrayHandle buffers, gint32 flags,
+ves_icall_System_Net_Sockets_Socket_Receive_array_internal (gsize sock, WSABUF *buffers, gint32 count, gint32 flags,
                                                            gint32 *werror, gboolean blocking, MonoError *error);
 
-/* gint32 */
-/* ves_icall_System_Net_Sockets_Socket_ReceiveFrom_internal (gsize sock, MonoArray *buffer, gint32 offset, gint32 count, */
-/*                                                       gint32 flags, MonoObject **sockaddr, gint32 *werror, gboolean blocking); */
-
 gint32
-ves_icall_System_Net_Sockets_Socket_ReceiveFrom_internal (gsize sock, MonoArrayHandle buffer, gint32 offset, gint32 count,
+ves_icall_System_Net_Sockets_Socket_ReceiveFrom_internal (gsize sock, gchar *buffer, gint32 count,
                                                          gint32 flags, MonoObjectHandle sockaddr, gint32 *werror, gboolean blocking, MonoError *error);
 
 
 gint32
-ves_icall_System_Net_Sockets_Socket_Send_internal (gsize sock, MonoArrayHandle buffer, gint32 offset, gint32 count,
+ves_icall_System_Net_Sockets_Socket_Send_internal (gsize sock, gchar *buffer, gint32 count,
                                                   gint32 flags, gint32 *werror, gboolean blocking, MonoError *error);
 
 gint32
-ves_icall_System_Net_Sockets_Socket_Send_array_internal (gsize sock, MonoArrayHandle buffers, gint32 flags,
+ves_icall_System_Net_Sockets_Socket_Send_array_internal (gsize sock, WSABUF *buffers, gint32 count, gint32 flags,
                                                         gint32 *werror, gboolean blocking, MonoError *error);
 
 gint32
-ves_icall_System_Net_Sockets_Socket_SendTo_internal (gsize sock, MonoArrayHandle buffer, gint32 offset, gint32 count,
+ves_icall_System_Net_Sockets_Socket_SendTo_internal (gsize sock, gchar *buffer, gint32 count,
                                                     gint32 flags, MonoObjectHandle sockaddr, gint32 *werror,
                                                     gboolean blocking, MonoError *error);