check the *actual* length to allow more stack usage *and* allow smaller pool rentals

pull/19511/head
Marc Gravell 5 years ago
parent 74be06c80f
commit cb813e1ffc
  1. 2
      src/csharp/Grpc.Core/Grpc.Core.csproj
  2. 10
      src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
  3. 10
      src/csharp/Grpc.Core/Internal/MarshalUtils.cs

@ -100,6 +100,8 @@
<ItemGroup>
<PackageReference Include="System.Interactive.Async" Version="3.2.0" />
<!-- System.Buffers *may* come in transitively, but: we can *always* use ArrayPool -->
<PackageReference Include="System.Buffers" Version="4.5.0" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">

@ -135,8 +135,16 @@ namespace Grpc.Core.Internal
{
var ctx = completionQueue.CompletionRegistry.RegisterBatchCompletion(CompletionHandler_ISendStatusFromServerCompletionCallback, callback);
var optionalPayloadLength = optionalPayload != null ? new UIntPtr((ulong)optionalPayload.Length) : UIntPtr.Zero;
int maxBytes = MarshalUtils.GetMaxBytesUTF8(status.Detail);
const int MaxStackAllocBytes = 256;
int maxBytes = MarshalUtils.GetMaxByteCountUTF8(status.Detail);
if (maxBytes > MaxStackAllocBytes)
{
// pay the extra to get the *actual* size; this could mean that
// it ends up fitting on the stack after all, but even if not
// it will mean that we ask for a *much* smaller buffer
maxBytes = MarshalUtils.GetByteCountUTF8(status.Detail);
}
if (maxBytes <= MaxStackAllocBytes)
{ // for small status, we can encode on the stack without touching arrays

@ -66,9 +66,17 @@ namespace Grpc.Core.Internal
/// <summary>
/// Returns the maximum number of bytes required to encode a given string.
/// </summary>
public static int GetMaxBytesUTF8(string str)
public static int GetMaxByteCountUTF8(string str)
{
return EncodingUTF8.GetMaxByteCount(str.Length);
}
/// <summary>
/// Returns the actual number of bytes required to encode a given string.
/// </summary>
public static int GetByteCountUTF8(string str)
{
return EncodingUTF8.GetByteCount(str);
}
}
}

Loading…
Cancel
Save