Skip to content
This repository has been archived by the owner on Aug 2, 2023. It is now read-only.

Remove TryGetPointer from RioTcpConnection #1375

Merged
merged 4 commits into from
Mar 28, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Buffers;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO.Pipelines.Networking.Windows.RIO.Internal.Winsock;
using System.Runtime.InteropServices;
using System.Threading;
using System.IO.Pipelines.Networking.Windows.RIO.Internal.Winsock;

namespace System.IO.Pipelines.Networking.Windows.RIO.Internal
{
Expand Down Expand Up @@ -92,7 +92,7 @@ public void RemoveConnection(long key)
}
}

public IntPtr GetBufferId(IntPtr address, out long startAddress)
private IntPtr GetBufferId(IntPtr address, out long startAddress)
{
var id = IntPtr.Zero;
startAddress = 0;
Expand All @@ -116,6 +116,25 @@ public IntPtr GetBufferId(IntPtr address, out long startAddress)
return id;
}

public unsafe RioBufferSegment GetSegmentFromMemory(Buffer<byte> memory)
{
// It's ok to unpin the handle here because the memory is from the pool
// we created, which is already pinned.
var pin = memory.Pin();
var spanPtr = (IntPtr)pin.PinnedPointer;
pin.Free();

long startAddress;
long spanAddress = spanPtr.ToInt64();
var bufferId = GetBufferId(spanPtr, out startAddress);

checked
{
var offset = (uint)(spanAddress - startAddress);
return new RioBufferSegment(bufferId, offset, (uint)memory.Length);
}
}

private void OnSlabAllocated(MemoryPoolSlab slab)
{
lock (_bufferIdMappings)
Expand Down
30 changes: 5 additions & 25 deletions src/System.IO.Pipelines.Networking.Windows.RIO/RioTcpConnection.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Buffers;
using System.Threading;
using System.Threading.Tasks;
using System.IO.Pipelines.Networking.Windows.RIO.Internal;
using System.IO.Pipelines.Networking.Windows.RIO.Internal.Winsock;
using System.Threading;
using System.Threading.Tasks;

namespace System.IO.Pipelines.Networking.Windows.RIO
{
Expand Down Expand Up @@ -64,7 +63,7 @@ internal RioTcpConnection(IntPtr socket, long connectionId, IntPtr requestQueue,
private void ProcessReceives()
{
_buffer = _input.Writer.Alloc(2048);
var receiveBufferSeg = GetSegmentFromMemory(_buffer.Buffer);
var receiveBufferSeg = _rioThread.GetSegmentFromMemory(_buffer.Buffer);

if (!_rio.RioReceive(_requestQueue, ref receiveBufferSeg, 1, RioReceiveFlags.None, 0))
{
Expand Down Expand Up @@ -120,7 +119,7 @@ private Task SendAsync(Buffer<byte> memory, bool endOfMessage)

var flushSends = endOfMessage || MaxOutstandingSendsReached;

Send(GetSegmentFromMemory(memory), flushSends);
Send(_rioThread.GetSegmentFromMemory(memory), flushSends);

if (flushSends && !endOfMessage)
{
Expand All @@ -136,7 +135,7 @@ private async Task SendAsyncAwaited(Buffer<byte> memory, bool endOfMessage)

var flushSends = endOfMessage || MaxOutstandingSendsReached;

Send(GetSegmentFromMemory(memory), flushSends);
Send(_rioThread.GetSegmentFromMemory(memory), flushSends);

if (flushSends && !endOfMessage)
{
Expand Down Expand Up @@ -219,25 +218,6 @@ public void ReceiveEndComplete()
_buffer.FlushAsync();
}

private unsafe RioBufferSegment GetSegmentFromMemory(Buffer<byte> memory)
{
void* pointer;
if (!memory.TryGetPointer(out pointer))
{
throw new InvalidOperationException("Memory needs to be pinned");
}
var spanPtr = (IntPtr)pointer;
long startAddress;
long spanAddress = spanPtr.ToInt64();
var bufferId = _rioThread.GetBufferId(spanPtr, out startAddress);

checked
{
var offset = (uint)(spanAddress - startAddress);
return new RioBufferSegment(bufferId, offset, (uint)memory.Length);
}
}

private static void ThrowError(ErrorType type)
{
var errorNo = RioImports.WSAGetLastError();
Expand Down