Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Henry <ludovic@xamarin.com>2017-08-31 20:21:29 +0300
committerGitHub <noreply@github.com>2017-08-31 20:21:29 +0300
commit078463fa1fb2ed7ffefa503812bcb91fab628aa4 (patch)
treeb1921823dc1c5bdd14bc4769d8da9c5818e99395 /mcs/class/System
parent118a5c70ed6deb963573f8f69e4c910efe952c87 (diff)
[socket] Reduce handle manipulations in native (#5378)
Diffstat (limited to 'mcs/class/System')
-rw-r--r--mcs/class/System/System.Net.Sockets/Socket.cs141
1 files changed, 87 insertions, 54 deletions
diff --git a/mcs/class/System/System.Net.Sockets/Socket.cs b/mcs/class/System/System.Net.Sockets/Socket.cs
index ae92b8d730b..4a889e4dd27 100644
--- a/mcs/class/System/System.Net.Sockets/Socket.cs
+++ b/mcs/class/System/System.Net.Sockets/Socket.cs
@@ -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