Merge pull request #11272 from jtattermusch/csharp_microbenchmarks

C# add microbenchmarks project
pull/10057/merge
Jan Tattermusch 8 years ago committed by GitHub
commit 60e9dac236
  1. 7
      src/csharp/.editorconfig
  2. 11
      src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
  3. 10
      src/csharp/Grpc.Core/Internal/CompletionRegistry.cs
  4. 4
      src/csharp/Grpc.Core/Internal/NativeMethods.cs
  5. 6
      src/csharp/Grpc.Core/Properties/AssemblyInfo.cs
  6. 2
      src/csharp/Grpc.Microbenchmarks/.gitignore
  7. 28
      src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj
  8. 55
      src/csharp/Grpc.Microbenchmarks/Program.cs
  9. 106
      src/csharp/Grpc.Microbenchmarks/SendMessageBenchmark.cs
  10. 79
      src/csharp/Grpc.Microbenchmarks/ThreadedBenchmark.cs
  11. 8
      src/csharp/Grpc.sln
  12. 86
      src/csharp/ext/grpc_csharp_ext.c

@ -0,0 +1,7 @@
root = true
[**]
end_of_line = LF
indent_style = space
indent_size = 4
insert_final_newline = true
tab_width = 4

@ -218,5 +218,16 @@ namespace Grpc.Core.Internal
{
return buffered ? 0 : GRPC_WRITE_BUFFER_HINT;
}
/// <summary>
/// Only for testing.
/// </summary>
public static CallSafeHandle CreateFake(IntPtr ptr, CompletionQueueSafeHandle cq)
{
var call = new CallSafeHandle();
call.SetHandle(ptr);
call.Initialize(cq);
return call;
}
}
}

@ -52,6 +52,7 @@ namespace Grpc.Core.Internal
readonly GrpcEnvironment environment;
readonly ConcurrentDictionary<IntPtr, OpCompletionDelegate> dict = new ConcurrentDictionary<IntPtr, OpCompletionDelegate>(new IntPtrComparer());
IntPtr lastRegisteredKey; // only for testing
public CompletionRegistry(GrpcEnvironment environment)
{
@ -62,6 +63,7 @@ namespace Grpc.Core.Internal
{
environment.DebugStats.PendingBatchCompletions.Increment();
GrpcPreconditions.CheckState(dict.TryAdd(key, callback));
this.lastRegisteredKey = key;
}
public void RegisterBatchCompletion(BatchContextSafeHandle ctx, BatchCompletionDelegate callback)
@ -84,6 +86,14 @@ namespace Grpc.Core.Internal
return value;
}
/// <summary>
/// For testing purposes only.
/// </summary>
public IntPtr LastRegisteredKey
{
get { return this.lastRegisteredKey; }
}
private static void HandleBatchCompletion(bool success, BatchContextSafeHandle ctx, BatchCompletionDelegate callback)
{
try

@ -164,6 +164,8 @@ namespace Grpc.Core.Internal
public readonly Delegates.grpcsharp_test_callback_delegate grpcsharp_test_callback;
public readonly Delegates.grpcsharp_test_nop_delegate grpcsharp_test_nop;
public readonly Delegates.grpcsharp_test_override_method_delegate grpcsharp_test_override_method;
#endregion
public NativeMethods(UnmanagedLibrary library)
@ -278,6 +280,7 @@ namespace Grpc.Core.Internal
this.grpcsharp_test_callback = GetMethodDelegate<Delegates.grpcsharp_test_callback_delegate>(library);
this.grpcsharp_test_nop = GetMethodDelegate<Delegates.grpcsharp_test_nop_delegate>(library);
this.grpcsharp_test_override_method = GetMethodDelegate<Delegates.grpcsharp_test_override_method_delegate>(library);
}
/// <summary>
@ -434,6 +437,7 @@ namespace Grpc.Core.Internal
public delegate CallError grpcsharp_test_callback_delegate([MarshalAs(UnmanagedType.FunctionPtr)] OpCompletionDelegate callback);
public delegate IntPtr grpcsharp_test_nop_delegate(IntPtr ptr);
public delegate void grpcsharp_test_override_method_delegate(string methodName, string variant);
}
}
}

@ -59,8 +59,14 @@ using System.Runtime.CompilerServices;
"0442bb8e12768722de0b0cb1b15e955b32a11352740ee59f2c94c48edc8e177d1052536b8ac651bce11ce5da3a" +
"27fc95aff3dc604a6971417453f9483c7b5e836756d5b271bf8f2403fe186e31956148c03d804487cf642f8cc0" +
"71394ee9672dfe5b55ea0f95dfd5a7f77d22c962ccf51320d3")]
[assembly: InternalsVisibleTo("Grpc.Microbenchmarks,PublicKey=" +
"00240000048000009400000006020000002400005253413100040000010001002f5797a92c6fcde81bd4098f43" +
"0442bb8e12768722de0b0cb1b15e955b32a11352740ee59f2c94c48edc8e177d1052536b8ac651bce11ce5da3a" +
"27fc95aff3dc604a6971417453f9483c7b5e836756d5b271bf8f2403fe186e31956148c03d804487cf642f8cc0" +
"71394ee9672dfe5b55ea0f95dfd5a7f77d22c962ccf51320d3")]
#else
[assembly: InternalsVisibleTo("Grpc.Core.Tests")]
[assembly: InternalsVisibleTo("Grpc.Core.Testing")]
[assembly: InternalsVisibleTo("Grpc.IntegrationTesting")]
[assembly: InternalsVisibleTo("Grpc.Microbenchmarks")]
#endif

@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\Grpc.Core\Version.csproj.include" />
<Import Project="..\Grpc.Core\Common.csproj.include" />
<PropertyGroup>
<TargetFrameworks>net45;netcoreapp1.0</TargetFrameworks>
<AssemblyName>Grpc.Microbenchmarks</AssemblyName>
<OutputType>Exe</OutputType>
<PackageId>Grpc.Microbenchmarks</PackageId>
<PackageTargetFallback Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">$(PackageTargetFallback);portable-net45</PackageTargetFallback>
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">1.0.4</RuntimeFrameworkVersion>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="../Grpc.Core/Grpc.Core.csproj" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
<Reference Include="System" />
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\Grpc.Core\Version.cs" />
</ItemGroup>
</Project>

@ -0,0 +1,55 @@
#region Copyright notice and license
// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using System;
using Grpc.Core;
using Grpc.Core.Internal;
using Grpc.Core.Logging;
namespace Grpc.Microbenchmarks
{
class Program
{
public static void Main(string[] args)
{
GrpcEnvironment.SetLogger(new TextWriterLogger(Console.Error));
var benchmark = new SendMessageBenchmark();
benchmark.Init();
foreach (int threadCount in new int[] {1, 1, 2, 4, 8, 12})
{
benchmark.Run(threadCount, 4 * 1000 * 1000, 0);
}
benchmark.Cleanup();
}
}
}

@ -0,0 +1,106 @@
#region Copyright notice and license
// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using System;
using System.Threading;
using Grpc.Core;
using Grpc.Core.Internal;
using System.Collections.Generic;
using System.Diagnostics;
namespace Grpc.Microbenchmarks
{
public class SendMessageBenchmark
{
static readonly NativeMethods Native = NativeMethods.Get();
GrpcEnvironment environment;
public void Init()
{
Native.grpcsharp_test_override_method("grpcsharp_call_start_batch", "nop");
environment = GrpcEnvironment.AddRef();
}
public void Cleanup()
{
GrpcEnvironment.ReleaseAsync().Wait();
// TODO(jtattermusch): track GC stats
}
public void Run(int threadCount, int iterations, int payloadSize)
{
Console.WriteLine(string.Format("SendMessageBenchmark: threads={0}, iterations={1}, payloadSize={2}", threadCount, iterations, payloadSize));
var threadedBenchmark = new ThreadedBenchmark(threadCount, () => ThreadBody(iterations, payloadSize));
threadedBenchmark.Run();
}
private void ThreadBody(int iterations, int payloadSize)
{
// TODO(jtattermusch): parametrize by number of pending completions.
// TODO(jtattermusch): parametrize by cached/non-cached BatchContextSafeHandle
var completionRegistry = new CompletionRegistry(environment);
var cq = CompletionQueueSafeHandle.CreateAsync(completionRegistry);
var call = CreateFakeCall(cq);
var sendCompletionHandler = new SendCompletionHandler((success) => { });
var payload = new byte[payloadSize];
var writeFlags = default(WriteFlags);
var stopwatch = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
{
call.StartSendMessage(sendCompletionHandler, payload, writeFlags, false);
var callback = completionRegistry.Extract(completionRegistry.LastRegisteredKey);
callback(true);
}
stopwatch.Stop();
Console.WriteLine("Elapsed millis: " + stopwatch.ElapsedMilliseconds);
cq.Dispose();
}
private static CallSafeHandle CreateFakeCall(CompletionQueueSafeHandle cq)
{
var call = CallSafeHandle.CreateFake(new IntPtr(0xdead), cq);
bool success = false;
while (!success)
{
// avoid calling destroy on a nonexistent grpc_call pointer
call.DangerousAddRef(ref success);
}
return call;
}
}
}

@ -0,0 +1,79 @@
#region Copyright notice and license
// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using System;
using System.Threading;
using Grpc.Core;
using Grpc.Core.Internal;
using System.Collections.Generic;
using System.Diagnostics;
namespace Grpc.Microbenchmarks
{
public class ThreadedBenchmark
{
List<ThreadStart> runners;
public ThreadedBenchmark(IEnumerable<ThreadStart> runners)
{
this.runners = new List<ThreadStart>(runners);
}
public ThreadedBenchmark(int threadCount, Action threadBody)
{
this.runners = new List<ThreadStart>();
for (int i = 0; i < threadCount; i++)
{
this.runners.Add(new ThreadStart(() => threadBody()));
}
}
public void Run()
{
Console.WriteLine("Running threads.");
var threads = new List<Thread>();
for (int i = 0; i < runners.Count; i++)
{
var thread = new Thread(runners[i]);
thread.Start();
threads.Add(thread);
}
foreach (var thread in threads)
{
thread.Join();
}
Console.WriteLine("All threads finished.");
}
}
}

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26228.4
VisualStudioVersion = 15.0.26430.4
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.Core", "Grpc.Core\Grpc.Core.csproj", "{BD878CB3-BDB4-46AB-84EF-C3B4729F56BC}"
EndProject
@ -37,6 +37,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.Reflection", "Grpc.Ref
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.Reflection.Tests", "Grpc.Reflection.Tests\Grpc.Reflection.Tests.csproj", "{335AD0A2-F2CC-4C2E-853C-26174206BEE7}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.Microbenchmarks", "Grpc.Microbenchmarks\Grpc.Microbenchmarks.csproj", "{84C17746-4727-4290-8E8B-A380793DAE1E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -111,6 +113,10 @@ Global
{335AD0A2-F2CC-4C2E-853C-26174206BEE7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{335AD0A2-F2CC-4C2E-853C-26174206BEE7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{335AD0A2-F2CC-4C2E-853C-26174206BEE7}.Release|Any CPU.Build.0 = Release|Any CPU
{84C17746-4727-4290-8E8B-A380793DAE1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{84C17746-4727-4290-8E8B-A380793DAE1E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{84C17746-4727-4290-8E8B-A380793DAE1E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{84C17746-4727-4290-8E8B-A380793DAE1E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

@ -529,6 +529,38 @@ GPR_EXPORT void GPR_CALLTYPE grpcsharp_call_destroy(grpc_call *call) {
grpc_call_unref(call);
}
typedef grpc_call_error (*grpcsharp_call_start_batch_func)(grpc_call *call,
const grpc_op *ops,
size_t nops,
void *tag,
void *reserved);
/* Only for testing */
static grpc_call_error grpcsharp_call_start_batch_nop(grpc_call *call,
const grpc_op *ops,
size_t nops, void *tag,
void *reserved) {
return GRPC_CALL_OK;
}
static grpc_call_error grpcsharp_call_start_batch_default(grpc_call *call,
const grpc_op *ops,
size_t nops,
void *tag,
void *reserved) {
return grpc_call_start_batch(call, ops, nops, tag, reserved);
}
static grpcsharp_call_start_batch_func g_call_start_batch_func =
grpcsharp_call_start_batch_default;
static grpc_call_error grpcsharp_call_start_batch(grpc_call *call,
const grpc_op *ops,
size_t nops, void *tag,
void *reserved) {
return g_call_start_batch_func(call, ops, nops, tag, reserved);
}
GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_start_unary(
grpc_call *call, grpcsharp_batch_context *ctx, const char *send_buffer,
size_t send_buffer_len, uint32_t write_flags,
@ -576,8 +608,8 @@ GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_start_unary(
ops[5].flags = 0;
ops[5].reserved = NULL;
return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx,
NULL);
return grpcsharp_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]),
ctx, NULL);
}
GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_start_client_streaming(
@ -616,8 +648,8 @@ GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_start_client_streaming(
ops[3].flags = 0;
ops[3].reserved = NULL;
return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx,
NULL);
return grpcsharp_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]),
ctx, NULL);
}
GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_start_server_streaming(
@ -656,8 +688,8 @@ GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_start_server_streaming(
ops[3].flags = 0;
ops[3].reserved = NULL;
return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx,
NULL);
return grpcsharp_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]),
ctx, NULL);
}
GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_start_duplex_streaming(
@ -685,8 +717,8 @@ GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_start_duplex_streaming(
ops[1].flags = 0;
ops[1].reserved = NULL;
return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx,
NULL);
return grpcsharp_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]),
ctx, NULL);
}
GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_recv_initial_metadata(
@ -699,8 +731,8 @@ GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_recv_initial_metadata(
ops[0].flags = 0;
ops[0].reserved = NULL;
return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx,
NULL);
return grpcsharp_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]),
ctx, NULL);
}
GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_send_message(
@ -720,7 +752,7 @@ GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_send_message(
ops[1].flags = 0;
ops[1].reserved = NULL;
return grpc_call_start_batch(call, ops, nops, ctx, NULL);
return grpcsharp_call_start_batch(call, ops, nops, ctx, NULL);
}
GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_send_close_from_client(
@ -731,8 +763,8 @@ GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_send_close_from_client(
ops[0].flags = 0;
ops[0].reserved = NULL;
return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx,
NULL);
return grpcsharp_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]),
ctx, NULL);
}
GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_send_status_from_server(
@ -773,7 +805,7 @@ GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_send_status_from_server(
ops[nops].reserved = NULL;
nops++;
}
return grpc_call_start_batch(call, ops, nops, ctx, NULL);
return grpcsharp_call_start_batch(call, ops, nops, ctx, NULL);
}
GPR_EXPORT grpc_call_error GPR_CALLTYPE
@ -784,8 +816,8 @@ grpcsharp_call_recv_message(grpc_call *call, grpcsharp_batch_context *ctx) {
ops[0].data.recv_message.recv_message = &(ctx->recv_message);
ops[0].flags = 0;
ops[0].reserved = NULL;
return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx,
NULL);
return grpcsharp_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]),
ctx, NULL);
}
GPR_EXPORT grpc_call_error GPR_CALLTYPE
@ -798,8 +830,8 @@ grpcsharp_call_start_serverside(grpc_call *call, grpcsharp_batch_context *ctx) {
ops[0].flags = 0;
ops[0].reserved = NULL;
return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx,
NULL);
return grpcsharp_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]),
ctx, NULL);
}
GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_send_initial_metadata(
@ -817,8 +849,8 @@ GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_send_initial_metadata(
ops[0].flags = 0;
ops[0].reserved = NULL;
return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx,
NULL);
return grpcsharp_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]),
ctx, NULL);
}
GPR_EXPORT grpc_call_error GPR_CALLTYPE
@ -1092,3 +1124,17 @@ GPR_EXPORT void *GPR_CALLTYPE grpcsharp_test_nop(void *ptr) { return ptr; }
GPR_EXPORT int32_t GPR_CALLTYPE grpcsharp_sizeof_grpc_event(void) {
return sizeof(grpc_event);
}
/* Override a method for testing */
GPR_EXPORT void GPR_CALLTYPE
grpcsharp_test_override_method(const char *method_name, const char *variant) {
if (strcmp("grpcsharp_call_start_batch", method_name) == 0) {
if (strcmp("nop", variant) == 0) {
g_call_start_batch_func = grpcsharp_call_start_batch_nop;
} else {
GPR_ASSERT(0);
}
} else {
GPR_ASSERT(0);
}
}

Loading…
Cancel
Save