internal static unsafe long ReadScatterAtOffset(SafeFileHandle handle, IReadOnlyList <Memory <byte> > buffers, long fileOffset) { MemoryHandle[] handles = new MemoryHandle[buffers.Count]; Span <Interop.Sys.IOVector> vectors = buffers.Count <= IovStackThreshold ? stackalloc Interop.Sys.IOVector[IovStackThreshold] : new Interop.Sys.IOVector[buffers.Count]; long result; try { int buffersCount = buffers.Count; for (int i = 0; i < buffersCount; i++) { Memory <byte> buffer = buffers[i]; MemoryHandle memoryHandle = buffer.Pin(); vectors[i] = new Interop.Sys.IOVector { Base = (byte *)memoryHandle.Pointer, Count = (UIntPtr)buffer.Length }; handles[i] = memoryHandle; } fixed(Interop.Sys.IOVector *pinnedVectors = &MemoryMarshal.GetReference(vectors)) { result = Interop.Sys.PReadV(handle, pinnedVectors, buffers.Count, fileOffset); } } finally { foreach (MemoryHandle memoryHandle in handles) { memoryHandle.Dispose(); } } return(FileStreamHelpers.CheckFileCall(result, handle.Path)); }
private static unsafe int Receive(SafeCloseSocket socket, SocketFlags flags, byte[] buffer, int offset, int count, byte[] socketAddress, ref int socketAddressLen, out SocketFlags receivedFlags, out Interop.Error errno) { Debug.Assert(socketAddress != null || socketAddressLen == 0, $"Unexpected values: socketAddress={socketAddress}, socketAddressLen={socketAddressLen}"); long received; int sockAddrLen = 0; if (socketAddress != null) { sockAddrLen = socketAddressLen; } fixed (byte* sockAddr = socketAddress) fixed (byte* b = buffer) { var iov = new Interop.Sys.IOVector { Base = (b == null) ? null : &b[offset], Count = (UIntPtr)count }; var messageHeader = new Interop.Sys.MessageHeader { SocketAddress = sockAddr, SocketAddressLen = sockAddrLen, IOVectors = &iov, IOVectorCount = 1 }; errno = Interop.Sys.ReceiveMessage(socket, &messageHeader, flags, &received); receivedFlags = messageHeader.Flags; sockAddrLen = messageHeader.SocketAddressLen; } if (errno != Interop.Error.SUCCESS) { return -1; } socketAddressLen = sockAddrLen; return checked((int)received); }
private static unsafe int ReceiveMessageFrom(int fd, SocketFlags flags, int available, byte[] buffer, int offset, int count, byte[] socketAddress, ref int socketAddressLen, bool isIPv4, bool isIPv6, out SocketFlags receivedFlags, out IPPacketInformation ipPacketInformation, out Interop.Error errno) { Debug.Assert(socketAddress != null); int cmsgBufferLen = Interop.Sys.GetControlMessageBufferSize(isIPv4, isIPv6); var cmsgBuffer = stackalloc byte[cmsgBufferLen]; int sockAddrLen = socketAddressLen; Interop.Sys.MessageHeader messageHeader; long received; fixed (byte* rawSocketAddress = socketAddress) fixed (byte* b = buffer) { var sockAddr = (byte*)rawSocketAddress; var iov = new Interop.Sys.IOVector { Base = &b[offset], Count = (UIntPtr)count }; messageHeader = new Interop.Sys.MessageHeader { SocketAddress = sockAddr, SocketAddressLen = sockAddrLen, IOVectors = &iov, IOVectorCount = 1, ControlBuffer = cmsgBuffer, ControlBufferLen = cmsgBufferLen }; errno = Interop.Sys.ReceiveMessage(fd, &messageHeader, flags, &received); receivedFlags = messageHeader.Flags; sockAddrLen = messageHeader.SocketAddressLen; } ipPacketInformation = GetIPPacketInformation(&messageHeader, isIPv4, isIPv6); if (errno != Interop.Error.SUCCESS) { return -1; } socketAddressLen = sockAddrLen; return checked((int)received); }
private static unsafe int Receive(int fd, SocketFlags flags, int available, IList<ArraySegment<byte>> buffers, byte[] socketAddress, ref int socketAddressLen, out SocketFlags receivedFlags, out Interop.Error errno) { // Pin buffers and set up iovecs. int maxBuffers = buffers.Count; var handles = new GCHandle[maxBuffers]; var iovecs = new Interop.Sys.IOVector[maxBuffers]; var pinnedSocketAddress = default(GCHandle); byte* sockAddr = null; int sockAddrLen = 0; long received = 0; int toReceive = 0, iovCount = maxBuffers; try { for (int i = 0; i < maxBuffers; i++) { ArraySegment<byte> buffer = buffers[i]; handles[i] = GCHandle.Alloc(buffer.Array, GCHandleType.Pinned); iovecs[i].Base = &((byte*)handles[i].AddrOfPinnedObject())[buffer.Offset]; int space = buffer.Count; toReceive += space; if (toReceive >= available) { iovecs[i].Count = (UIntPtr)(space - (toReceive - available)); toReceive = available; iovCount = i + 1; break; } iovecs[i].Count = (UIntPtr)space; } if (socketAddress != null) { pinnedSocketAddress = GCHandle.Alloc(socketAddress, GCHandleType.Pinned); sockAddr = (byte*)pinnedSocketAddress.AddrOfPinnedObject(); sockAddrLen = socketAddressLen; } // Make the call. fixed (Interop.Sys.IOVector* iov = iovecs) { var messageHeader = new Interop.Sys.MessageHeader { SocketAddress = sockAddr, SocketAddressLen = sockAddrLen, IOVectors = iov, IOVectorCount = iovCount }; errno = Interop.Sys.ReceiveMessage(fd, &messageHeader, flags, &received); receivedFlags = messageHeader.Flags; sockAddrLen = messageHeader.SocketAddressLen; } } finally { // Free GC handles. for (int i = 0; i < iovCount; i++) { if (handles[i].IsAllocated) { handles[i].Free(); } } if (pinnedSocketAddress.IsAllocated) { pinnedSocketAddress.Free(); } } if (errno != Interop.Error.SUCCESS) { return -1; } socketAddressLen = sockAddrLen; return checked((int)received); }
private static unsafe int Send(int fd, SocketFlags flags, IList<ArraySegment<byte>> buffers, ref int bufferIndex, ref int offset, byte[] socketAddress, int socketAddressLen, out Interop.Error errno) { // Pin buffers and set up iovecs. int startIndex = bufferIndex, startOffset = offset; var pinnedSocketAddress = default(GCHandle); byte* sockAddr = null; int sockAddrLen = 0; int maxBuffers = buffers.Count - startIndex; var handles = new GCHandle[maxBuffers]; var iovecs = new Interop.Sys.IOVector[maxBuffers]; int sent; int toSend = 0, iovCount = maxBuffers; try { for (int i = 0; i < maxBuffers; i++, startOffset = 0) { ArraySegment<byte> buffer = buffers[startIndex + i]; Debug.Assert(buffer.Offset + startOffset < buffer.Array.Length); handles[i] = GCHandle.Alloc(buffer.Array, GCHandleType.Pinned); iovecs[i].Base = &((byte*)handles[i].AddrOfPinnedObject())[buffer.Offset + startOffset]; toSend += (buffer.Count - startOffset); iovecs[i].Count = (UIntPtr)(buffer.Count - startOffset); } if (socketAddress != null) { pinnedSocketAddress = GCHandle.Alloc(socketAddress, GCHandleType.Pinned); sockAddr = (byte*)pinnedSocketAddress.AddrOfPinnedObject(); sockAddrLen = socketAddressLen; } // Make the call fixed (Interop.Sys.IOVector* iov = iovecs) { var messageHeader = new Interop.Sys.MessageHeader { SocketAddress = sockAddr, SocketAddressLen = sockAddrLen, IOVectors = iov, IOVectorCount = iovCount }; long bytesSent; errno = Interop.Sys.SendMessage(fd, &messageHeader, flags, &bytesSent); sent = checked((int)bytesSent); } } finally { // Free GC handles. for (int i = 0; i < iovCount; i++) { if (handles[i].IsAllocated) { handles[i].Free(); } } if (pinnedSocketAddress.IsAllocated) { pinnedSocketAddress.Free(); } } if (errno != Interop.Error.SUCCESS) { return -1; } // Update position. int endIndex = bufferIndex, endOffset = offset, unconsumed = sent; for (; endIndex < buffers.Count && unconsumed > 0; endIndex++, endOffset = 0) { int space = buffers[endIndex].Count - endOffset; if (space > unconsumed) { endOffset += unconsumed; break; } unconsumed -= space; } bufferIndex = endIndex; offset = endOffset; return sent; }
private static unsafe int Send(int fd, SocketFlags flags, byte[] buffer, ref int offset, ref int count, byte[] socketAddress, int socketAddressLen, out Interop.Error errno) { var pinnedSocketAddress = default(GCHandle); byte* sockAddr = null; int sockAddrLen = 0; int sent; try { if (socketAddress != null) { pinnedSocketAddress = GCHandle.Alloc(socketAddress, GCHandleType.Pinned); sockAddr = (byte*)pinnedSocketAddress.AddrOfPinnedObject(); sockAddrLen = socketAddressLen; } fixed (byte* b = buffer) { var iov = new Interop.Sys.IOVector { Base = &b[offset], Count = (UIntPtr)count }; var messageHeader = new Interop.Sys.MessageHeader { SocketAddress = sockAddr, SocketAddressLen = sockAddrLen, IOVectors = &iov, IOVectorCount = 1 }; long bytesSent; errno = Interop.Sys.SendMessage(fd, &messageHeader, flags, &bytesSent); sent = checked((int)bytesSent); } } finally { if (pinnedSocketAddress.IsAllocated) { pinnedSocketAddress.Free(); } } if (errno != Interop.Error.SUCCESS) { return -1; } offset += sent; count -= sent; return sent; }
private static unsafe int Receive(int fd, SocketFlags flags, int available, byte[] buffer, int offset, int count, byte[] socketAddress, ref int socketAddressLen, out SocketFlags receivedFlags, out Interop.Error errno) { Debug.Assert(socketAddress != null || socketAddressLen == 0); var pinnedSocketAddress = default(GCHandle); byte* sockAddr = null; int sockAddrLen = 0; long received; try { if (socketAddress != null) { pinnedSocketAddress = GCHandle.Alloc(socketAddress, GCHandleType.Pinned); sockAddr = (byte*)pinnedSocketAddress.AddrOfPinnedObject(); sockAddrLen = socketAddressLen; } fixed (byte* b = buffer) { var iov = new Interop.Sys.IOVector { Base = &b[offset], Count = (UIntPtr)count }; var messageHeader = new Interop.Sys.MessageHeader { SocketAddress = sockAddr, SocketAddressLen = sockAddrLen, IOVectors = &iov, IOVectorCount = 1 }; errno = Interop.Sys.ReceiveMessage(fd, &messageHeader, flags, &received); receivedFlags = messageHeader.Flags; sockAddrLen = messageHeader.SocketAddressLen; } } finally { if (pinnedSocketAddress.IsAllocated) { pinnedSocketAddress.Free(); } } if (errno != Interop.Error.SUCCESS) { return -1; } socketAddressLen = sockAddrLen; return checked((int)received); }
private static unsafe int Send(int fd, SocketFlags flags, byte[] buffer, ref int offset, ref int count, byte[] socketAddress, int socketAddressLen, out Interop.Error errno) { int sent; int sockAddrLen = 0; if (socketAddress != null) { sockAddrLen = socketAddressLen; } fixed (byte* sockAddr = socketAddress) fixed (byte* b = buffer) { var iov = new Interop.Sys.IOVector { Base = &b[offset], Count = (UIntPtr)count }; var messageHeader = new Interop.Sys.MessageHeader { SocketAddress = sockAddr, SocketAddressLen = sockAddrLen, IOVectors = &iov, IOVectorCount = 1 }; long bytesSent; errno = Interop.Sys.SendMessage(fd, &messageHeader, flags, &bytesSent); sent = checked((int)bytesSent); } if (errno != Interop.Error.SUCCESS) { return -1; } offset += sent; count -= sent; return sent; }
internal static unsafe void WriteGatherAtOffset(SafeFileHandle handle, IReadOnlyList <ReadOnlyMemory <byte> > buffers, long fileOffset) { int buffersCount = buffers.Count; if (buffersCount == 0) { return; } var handles = new MemoryHandle[buffersCount]; Span <Interop.Sys.IOVector> vectors = buffersCount <= IovStackThreshold ? stackalloc Interop.Sys.IOVector[IovStackThreshold] : new Interop.Sys.IOVector[buffersCount]; try { int buffersOffset = 0, firstBufferOffset = 0; while (true) { long totalBytesToWrite = 0; for (int i = buffersOffset; i < buffersCount; i++) { ReadOnlyMemory <byte> buffer = buffers[i]; totalBytesToWrite += buffer.Length; MemoryHandle memoryHandle = buffer.Pin(); vectors[i] = new Interop.Sys.IOVector { Base = firstBufferOffset + (byte *)memoryHandle.Pointer, Count = (UIntPtr)buffer.Length }; handles[i] = memoryHandle; firstBufferOffset = 0; } if (totalBytesToWrite == 0) { break; } long bytesWritten; fixed(Interop.Sys.IOVector *pinnedVectors = &MemoryMarshal.GetReference(vectors)) { bytesWritten = Interop.Sys.PWriteV(handle, pinnedVectors, buffersCount, fileOffset); } FileStreamHelpers.CheckFileCall(bytesWritten, handle.Path); if (bytesWritten == totalBytesToWrite) { break; } // The write completed successfully but for fewer bytes than requested. // We need to try again for the remainder. for (int i = 0; i < buffersCount; i++) { int n = buffers[i].Length; if (n <= bytesWritten) { buffersOffset++; bytesWritten -= n; if (bytesWritten == 0) { break; } } else { firstBufferOffset = (int)(bytesWritten - n); break; } } } } finally { foreach (MemoryHandle memoryHandle in handles) { memoryHandle.Dispose(); } } }