Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Conversation

@teo-tsirpanis
Copy link

Fixes issue dotnet/runtime#57472

Main pr dotnet/runtime#57479

Also backported to 5.0 in dotnet/runtime#57562 and 3.1 in #43102. This PR will pave the way for backporting it to the System.Memory OOB package for .NET Framework.

Customer Impact

A customer has encountered dotnet/runtime#57472 while on .NET Framework and reported it in dotnet/runtime#67295, necessiating backporting it once again. As an example provided in that issue, this memory manager:

private sealed class BasicMemoryManager : MemoryManager<byte>
{
    private readonly byte[] _buffer;
    public BasicMemoryManager(int size = 1024) => _buffer = new byte[size];

    protected override bool TryGetArray(out ArraySegment<byte> segment)
    {
        segment = new ArraySegment<byte>(_buffer);
        return true;
    }
    public override Span<byte> GetSpan() => _buffer;

    public override MemoryHandle Pin(int elementIndex = 0) => throw new NotSupportedException();
    public override void Unpin() => throw new NotSupportedException();
    protected override void Dispose(bool disposing) { }
}

will fail two of the following tests:

[Theory]
[InlineData(0, 32)]
[InlineData(0, 29)]
[InlineData(32, 32)] // fail: length 0
[InlineData(32, 29)] // fail: length -3
public void OffsetTest(int offset, int length)
{
    var mgr = new BasicMemoryManager(1024);
    var slice = mgr.Memory.Slice(offset, length);
    Assert.Equal(length, slice.Length);

    var ros = new ReadOnlySequence<byte>(slice);
    Assert.True(ros.IsSingleSegment);
    Assert.Equal(length, ros.Length);
}

Testing

Failing test has been added in this PR.

Risk

Low, as the change is very simple and obvious when you look at ReadOnlySequence<T> ctor that accepts ReadOnlyMemory<T> (notice line 133 versus lines 140 and 148):

if (MemoryMarshal.TryGetMemoryManager(memory, out MemoryManager<T> manager, out int index, out int length))
{
_sequenceStart = new SequencePosition(manager, ReadOnlySequence.MemoryManagerToSequenceStart(index));
_sequenceEnd = new SequencePosition(manager, ReadOnlySequence.MemoryManagerToSequenceEnd(length));
}
else if (MemoryMarshal.TryGetArray(memory, out ArraySegment<T> segment))
{
T[] array = segment.Array;
int start = segment.Offset;
_sequenceStart = new SequencePosition(array, ReadOnlySequence.ArrayToSequenceStart(start));
_sequenceEnd = new SequencePosition(array, ReadOnlySequence.ArrayToSequenceEnd(start + segment.Count));
}
else if (typeof(T) == typeof(char))
{
if (!MemoryMarshal.TryGetString(((ReadOnlyMemory<char>)(object)memory), out string text, out int start, out length))
ThrowHelper.ThrowInvalidOperationException();
_sequenceStart = new SequencePosition(text, ReadOnlySequence.StringToSequenceStart(start));
_sequenceEnd = new SequencePosition(text, ReadOnlySequence.StringToSequenceEnd(start + length));
}

Moreover, the changed code gets triggered only when creating a ReadOnlySequence from a ReadOnlyMemory backed by a MemoryManager. All other use cases (including creating from an array or from a ReadOnlyMemory backed by an array or a string) are unaffected. And the changes are identical to those in the other backports.

Regression

This is not a regression.

@ericstj
Copy link
Member

ericstj commented Apr 13, 2022

@dotnet/area-system-memory can someone please review this and be assigned as owner to take to tactics?

Copy link
Member

@jozkee jozkee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No backporting conflicts and test classes in 2.1 seem similar as the ones in 3.1, which already contains the fix.

@jozkee jozkee added the Servicing-consider Issue for next servicing release review label Apr 14, 2022
@jozkee jozkee added this to the 2.1.x milestone Apr 14, 2022
@danmoseley
Copy link
Member

cc @Pilchie - for ASP.NET..

@leecow leecow added Servicing-approved Approved for servicing release and removed Servicing-consider Issue for next servicing release review labels Apr 19, 2022
@jozkee jozkee closed this Apr 25, 2022
@jozkee jozkee reopened this Apr 25, 2022
@jozkee
Copy link
Member

jozkee commented Apr 25, 2022

@dotnet/area-infrastructure-libraries all Linux legs are being cancelled with this message:

##[warning]An image label with the label ubuntu-16.04 does not exist.
,##[error]The remote provider was unable to process the request.
Started: Just now
Duration: 44s

Is that concerning?

@ViktorHofer
Copy link
Member

ViktorHofer commented Apr 27, 2022

@danmoseley @ericstj looks like the release/2.1 branch isn't buildable and testable anymore based on Helix and docker EOL changes. Personally I didn't know that we still do servicing updates for 2.1 in the open.

@jozkee
Copy link
Member

jozkee commented May 2, 2022

Ping @ericstj @danmoseley

@ericstj
Copy link
Member

ericstj commented May 3, 2022

Chatted offline -- we believe we can merge this once it's ready. I think this still needs package authoring. Here's a recent example of a 2.1 fix that shipped a package: 24e09fe

@teo-tsirpanis
Copy link
Author

Done @ericstj.

@jozkee
Copy link
Member

jozkee commented May 3, 2022

@teo-tsirpanis @dotnet/area-infrastructure-libraries don't we need to include System.Memory in src/packages.builds?
https://github.com/dotnet/corefx/pull/43017/files#diff-43676c2abb12b62b72c9d923c709c340a45fafccf2a7b7daf84549b0ee2b0f54R26-R29

@ericstj does this still require local validation i.e: building 2.1 locally on Linux?

@teo-tsirpanis
Copy link
Author

Oops I forgot it, will fix it soon.

@teo-tsirpanis
Copy link
Author

Done @jozkee.

@carlossanlop carlossanlop added the * NO MERGE * The PR is not ready for merge yet (see discussion for detailed reasons) label May 3, 2022
@carlossanlop
Copy link

@jozkee @ericstj If we are taking this, it needs to be merged directly into the 2.1 internal branch, not here. @jozkee I'll give you instructions offline.

@carlossanlop
Copy link

Talked to @mmitche about this. We can take the change in the public repo, we will manually take care of any internal flows.

@carlossanlop carlossanlop removed the * NO MERGE * The PR is not ready for merge yet (see discussion for detailed reasons) label May 4, 2022
@carlossanlop carlossanlop merged commit 8b6f401 into dotnet:release/2.1 May 4, 2022
@teo-tsirpanis teo-tsirpanis deleted the backport57472 branch May 4, 2022 16:10
Copy link
Member

@ViktorHofer ViktorHofer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Infra changes LGTM

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-System.Memory Servicing-approved Approved for servicing release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants