Merge github.com:grpc/grpc into c++api

pull/501/head
Craig Tiller 10 years ago
commit 869a8700f8
  1. 222
      Makefile
  2. 6
      src/core/surface/call.c
  3. 12
      src/csharp/GrpcCore/GrpcEnvironment.cs
  4. 104
      src/csharp/GrpcCore/Internal/CallSafeHandle.cs
  5. 12
      src/csharp/GrpcCore/Internal/ChannelSafeHandle.cs
  6. 34
      src/csharp/GrpcCore/Internal/CompletionQueueSafeHandle.cs
  7. 84
      src/csharp/GrpcCore/Internal/Event.cs
  8. 46
      src/csharp/GrpcCore/Internal/ServerSafeHandle.cs
  9. 38
      src/csharp/GrpcCore/Internal/Timespec.cs
  10. 31
      src/csharp/GrpcCoreTests/TimespecTest.cs
  11. 271
      src/csharp/ext/grpc_csharp_ext.c
  12. 2
      templates/vsprojects/vs2013/grpc_csharp_ext_shared.vcxproj.template
  13. 2
      test/core/end2end/gen_build_json.py
  14. 137
      test/core/end2end/tests/empty_batch.c
  15. 24
      tools/run_tests/tests.json
  16. 2
      vsprojects/vs2013/grpc_csharp_ext_shared.vcxproj
  17. 2
      vsprojects/vs2013/grpc_shared.vcxproj
  18. 3
      vsprojects/vs2013/grpc_shared.vcxproj.filters

File diff suppressed because one or more lines are too long

@ -995,6 +995,12 @@ grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops,
const grpc_op *op;
grpc_ioreq *req;
if (nops == 0) {
grpc_cq_begin_op(call->cq, call, GRPC_OP_COMPLETE);
grpc_cq_end_op_complete(call->cq, tag, call, do_nothing, NULL, GRPC_OP_OK);
return GRPC_CALL_OK;
}
/* rewrite batch ops into ioreq ops */
for (in = 0, out = 0; in < nops; in++) {
op = &ops[in];

@ -13,11 +13,11 @@ namespace Google.GRPC.Core
{
const int THREAD_POOL_SIZE = 1;
[DllImport("grpc.dll")]
static extern void grpc_init();
[DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_init();
[DllImport("grpc.dll")]
static extern void grpc_shutdown();
[DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_shutdown();
static object staticLock = new object();
static bool initCalled = false;
@ -61,7 +61,7 @@ namespace Google.GRPC.Core
/// </summary>
private static void GrpcInit()
{
grpc_init();
grpcsharp_init();
threadPool.Start();
// TODO: use proper logging here
Console.WriteLine("GRPC initialized.");
@ -73,7 +73,7 @@ namespace Google.GRPC.Core
private static void GrpcShutdown()
{
threadPool.Stop();
grpc_shutdown();
grpcsharp_shutdown();
// TODO: use proper logging here
Console.WriteLine("GRPC shutdown.");

@ -15,67 +15,67 @@ namespace Google.GRPC.Core.Internal
{
const UInt32 GRPC_WRITE_BUFFER_HINT = 1;
[DllImport("grpc.dll")]
static extern CallSafeHandle grpc_channel_create_call_old(ChannelSafeHandle channel, string method, string host, Timespec deadline);
[DllImport("grpc_csharp_ext.dll")]
static extern CallSafeHandle grpcsharp_channel_create_call_old(ChannelSafeHandle channel, string method, string host, Timespec deadline);
[DllImport("grpc.dll")]
static extern GRPCCallError grpc_call_add_metadata(CallSafeHandle call, IntPtr metadata, UInt32 flags);
[DllImport("grpc_csharp_ext.dll")]
static extern GRPCCallError grpcsharp_call_add_metadata(CallSafeHandle call, IntPtr metadata, UInt32 flags);
[DllImport("grpc.dll")]
static extern GRPCCallError grpc_call_invoke_old(CallSafeHandle call, CompletionQueueSafeHandle cq, IntPtr metadataReadTag, IntPtr finishedTag, UInt32 flags);
[DllImport("grpc_csharp_ext.dll")]
static extern GRPCCallError grpcsharp_call_invoke_old(CallSafeHandle call, CompletionQueueSafeHandle cq, IntPtr metadataReadTag, IntPtr finishedTag, UInt32 flags);
[DllImport("grpc.dll", EntryPoint = "grpc_call_invoke_old")]
static extern GRPCCallError grpc_call_invoke_old_CALLBACK(CallSafeHandle call, CompletionQueueSafeHandle cq,
[DllImport("grpc_csharp_ext.dll", EntryPoint = "grpcsharp_call_invoke_old")]
static extern GRPCCallError grpcsharp_call_invoke_old_CALLBACK(CallSafeHandle call, CompletionQueueSafeHandle cq,
[MarshalAs(UnmanagedType.FunctionPtr)] EventCallbackDelegate metadataReadCallback,
[MarshalAs(UnmanagedType.FunctionPtr)] EventCallbackDelegate finishedCallback,
UInt32 flags);
[DllImport("grpc.dll")]
static extern GRPCCallError grpc_call_server_accept_old(CallSafeHandle call, CompletionQueueSafeHandle completionQueue, IntPtr finishedTag);
[DllImport("grpc_csharp_ext.dll")]
static extern GRPCCallError grpcsharp_call_server_accept_old(CallSafeHandle call, CompletionQueueSafeHandle completionQueue, IntPtr finishedTag);
[DllImport("grpc.dll", EntryPoint = "grpc_call_server_accept_old")]
static extern GRPCCallError grpc_call_server_accept_old_CALLBACK(CallSafeHandle call, CompletionQueueSafeHandle completionQueue, [MarshalAs(UnmanagedType.FunctionPtr)] EventCallbackDelegate finishedCallback);
[DllImport("grpc_csharp_ext.dll", EntryPoint = "grpcsharp_call_server_accept_old")]
static extern GRPCCallError grpcsharp_call_server_accept_old_CALLBACK(CallSafeHandle call, CompletionQueueSafeHandle completionQueue, [MarshalAs(UnmanagedType.FunctionPtr)] EventCallbackDelegate finishedCallback);
[DllImport("grpc.dll")]
static extern GRPCCallError grpc_call_server_end_initial_metadata_old(CallSafeHandle call, UInt32 flags);
[DllImport("grpc_csharp_ext.dll")]
static extern GRPCCallError grpcsharp_call_server_end_initial_metadata_old(CallSafeHandle call, UInt32 flags);
[DllImport("grpc.dll")]
static extern GRPCCallError grpc_call_cancel(CallSafeHandle call);
[DllImport("grpc_csharp_ext.dll")]
static extern GRPCCallError grpcsharp_call_cancel(CallSafeHandle call);
[DllImport("grpc.dll")]
static extern GRPCCallError grpc_call_cancel_with_status(CallSafeHandle call, StatusCode status, string description);
[DllImport("grpc_csharp_ext.dll")]
static extern GRPCCallError grpcsharp_call_cancel_with_status(CallSafeHandle call, StatusCode status, string description);
[DllImport("grpc.dll")]
static extern GRPCCallError grpc_call_start_write_status_old(CallSafeHandle call, StatusCode statusCode, string statusMessage, IntPtr tag);
[DllImport("grpc_csharp_ext.dll")]
static extern GRPCCallError grpcsharp_call_start_write_status_old(CallSafeHandle call, StatusCode statusCode, string statusMessage, IntPtr tag);
[DllImport("grpc.dll", EntryPoint = "grpc_call_start_write_status_old")]
static extern GRPCCallError grpc_call_start_write_status_old_CALLBACK(CallSafeHandle call, StatusCode statusCode, string statusMessage, [MarshalAs(UnmanagedType.FunctionPtr)] EventCallbackDelegate callback);
[DllImport("grpc_csharp_ext.dll", EntryPoint = "grpcsharp_call_start_write_status_old")]
static extern GRPCCallError grpcsharp_call_start_write_status_old_CALLBACK(CallSafeHandle call, StatusCode statusCode, string statusMessage, [MarshalAs(UnmanagedType.FunctionPtr)] EventCallbackDelegate callback);
[DllImport("grpc.dll")]
static extern GRPCCallError grpc_call_writes_done_old(CallSafeHandle call, IntPtr tag);
[DllImport("grpc_csharp_ext.dll")]
static extern GRPCCallError grpcsharp_call_writes_done_old(CallSafeHandle call, IntPtr tag);
[DllImport("grpc.dll", EntryPoint = "grpc_call_writes_done_old")]
static extern GRPCCallError grpc_call_writes_done_old_CALLBACK(CallSafeHandle call, [MarshalAs(UnmanagedType.FunctionPtr)] EventCallbackDelegate callback);
[DllImport("grpc_csharp_ext.dll", EntryPoint = "grpcsharp_call_writes_done_old")]
static extern GRPCCallError grpcsharp_call_writes_done_old_CALLBACK(CallSafeHandle call, [MarshalAs(UnmanagedType.FunctionPtr)] EventCallbackDelegate callback);
[DllImport("grpc.dll")]
static extern GRPCCallError grpc_call_start_read_old(CallSafeHandle call, IntPtr tag);
[DllImport("grpc_csharp_ext.dll")]
static extern GRPCCallError grpcsharp_call_start_read_old(CallSafeHandle call, IntPtr tag);
[DllImport("grpc.dll", EntryPoint = "grpc_call_start_read_old")]
static extern GRPCCallError grpc_call_start_read_old_CALLBACK(CallSafeHandle call, [MarshalAs(UnmanagedType.FunctionPtr)] EventCallbackDelegate callback);
[DllImport("grpc_csharp_ext.dll", EntryPoint = "grpcsharp_call_start_read_old")]
static extern GRPCCallError grpcsharp_call_start_read_old_CALLBACK(CallSafeHandle call, [MarshalAs(UnmanagedType.FunctionPtr)] EventCallbackDelegate callback);
[DllImport("grpc_csharp_ext.dll")]
static extern void grpc_call_start_write_from_copied_buffer(CallSafeHandle call,
static extern void grpcsharp_call_start_write_from_copied_buffer(CallSafeHandle call,
byte[] buffer, UIntPtr length,
IntPtr tag, UInt32 flags);
[DllImport("grpc_csharp_ext.dll", EntryPoint = "grpc_call_start_write_from_copied_buffer")]
static extern void grpc_call_start_write_from_copied_buffer_CALLBACK(CallSafeHandle call,
[DllImport("grpc_csharp_ext.dll", EntryPoint = "grpcsharp_call_start_write_from_copied_buffer")]
static extern void grpcsharp_call_start_write_from_copied_buffer_CALLBACK(CallSafeHandle call,
byte[] buffer, UIntPtr length,
[MarshalAs(UnmanagedType.FunctionPtr)] EventCallbackDelegate callback,
UInt32 flags);
[DllImport("grpc.dll")]
static extern void grpc_call_destroy(IntPtr call);
[DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_call_destroy(IntPtr call);
private CallSafeHandle()
{
@ -86,87 +86,87 @@ namespace Google.GRPC.Core.Internal
/// </summary>
public static CallSafeHandle Create(ChannelSafeHandle channel, string method, string host, Timespec deadline)
{
return grpc_channel_create_call_old(channel, method, host, deadline);
return grpcsharp_channel_create_call_old(channel, method, host, deadline);
}
public void Invoke(CompletionQueueSafeHandle cq, IntPtr metadataReadTag, IntPtr finishedTag, bool buffered)
{
AssertCallOk(grpc_call_invoke_old(this, cq, metadataReadTag, finishedTag, GetFlags(buffered)));
AssertCallOk(grpcsharp_call_invoke_old(this, cq, metadataReadTag, finishedTag, GetFlags(buffered)));
}
public void Invoke(CompletionQueueSafeHandle cq, bool buffered, EventCallbackDelegate metadataReadCallback, EventCallbackDelegate finishedCallback)
{
AssertCallOk(grpc_call_invoke_old_CALLBACK(this, cq, metadataReadCallback, finishedCallback, GetFlags(buffered)));
AssertCallOk(grpcsharp_call_invoke_old_CALLBACK(this, cq, metadataReadCallback, finishedCallback, GetFlags(buffered)));
}
public void ServerAccept(CompletionQueueSafeHandle cq, IntPtr finishedTag)
{
AssertCallOk(grpc_call_server_accept_old(this, cq, finishedTag));
AssertCallOk(grpcsharp_call_server_accept_old(this, cq, finishedTag));
}
public void ServerAccept(CompletionQueueSafeHandle cq, EventCallbackDelegate callback)
{
AssertCallOk(grpc_call_server_accept_old_CALLBACK(this, cq, callback));
AssertCallOk(grpcsharp_call_server_accept_old_CALLBACK(this, cq, callback));
}
public void ServerEndInitialMetadata(UInt32 flags)
{
AssertCallOk(grpc_call_server_end_initial_metadata_old(this, flags));
AssertCallOk(grpcsharp_call_server_end_initial_metadata_old(this, flags));
}
public void StartWrite(byte[] payload, IntPtr tag, bool buffered)
{
grpc_call_start_write_from_copied_buffer(this, payload, new UIntPtr((ulong) payload.Length), tag, GetFlags(buffered));
grpcsharp_call_start_write_from_copied_buffer(this, payload, new UIntPtr((ulong) payload.Length), tag, GetFlags(buffered));
}
public void StartWrite(byte[] payload, bool buffered, EventCallbackDelegate callback)
{
grpc_call_start_write_from_copied_buffer_CALLBACK(this, payload, new UIntPtr((ulong) payload.Length), callback, GetFlags(buffered));
grpcsharp_call_start_write_from_copied_buffer_CALLBACK(this, payload, new UIntPtr((ulong) payload.Length), callback, GetFlags(buffered));
}
public void StartWriteStatus(Status status, IntPtr tag)
{
AssertCallOk(grpc_call_start_write_status_old(this, status.StatusCode, status.Detail, tag));
AssertCallOk(grpcsharp_call_start_write_status_old(this, status.StatusCode, status.Detail, tag));
}
public void StartWriteStatus(Status status, EventCallbackDelegate callback)
{
AssertCallOk(grpc_call_start_write_status_old_CALLBACK(this, status.StatusCode, status.Detail, callback));
AssertCallOk(grpcsharp_call_start_write_status_old_CALLBACK(this, status.StatusCode, status.Detail, callback));
}
public void WritesDone(IntPtr tag)
{
AssertCallOk(grpc_call_writes_done_old(this, tag));
AssertCallOk(grpcsharp_call_writes_done_old(this, tag));
}
public void WritesDone(EventCallbackDelegate callback)
{
AssertCallOk(grpc_call_writes_done_old_CALLBACK(this, callback));
AssertCallOk(grpcsharp_call_writes_done_old_CALLBACK(this, callback));
}
public void StartRead(IntPtr tag)
{
AssertCallOk(grpc_call_start_read_old(this, tag));
AssertCallOk(grpcsharp_call_start_read_old(this, tag));
}
public void StartRead(EventCallbackDelegate callback)
{
AssertCallOk(grpc_call_start_read_old_CALLBACK(this, callback));
AssertCallOk(grpcsharp_call_start_read_old_CALLBACK(this, callback));
}
public void Cancel()
{
AssertCallOk(grpc_call_cancel(this));
AssertCallOk(grpcsharp_call_cancel(this));
}
public void CancelWithStatus(Status status)
{
AssertCallOk(grpc_call_cancel_with_status(this, status.StatusCode, status.Detail));
AssertCallOk(grpcsharp_call_cancel_with_status(this, status.StatusCode, status.Detail));
}
protected override bool ReleaseHandle()
{
grpc_call_destroy(handle);
grpcsharp_call_destroy(handle);
return true;
}

@ -10,11 +10,11 @@ namespace Google.GRPC.Core.Internal
/// </summary>
internal class ChannelSafeHandle : SafeHandleZeroIsInvalid
{
[DllImport("grpc.dll")]
static extern ChannelSafeHandle grpc_channel_create(string target, IntPtr channelArgs);
[DllImport("grpc_csharp_ext.dll")]
static extern ChannelSafeHandle grpcsharp_channel_create(string target, IntPtr channelArgs);
[DllImport("grpc.dll")]
static extern void grpc_channel_destroy(IntPtr channel);
[DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_channel_destroy(IntPtr channel);
private ChannelSafeHandle()
{
@ -22,12 +22,12 @@ namespace Google.GRPC.Core.Internal
public static ChannelSafeHandle Create(string target, IntPtr channelArgs)
{
return grpc_channel_create(target, channelArgs);
return grpcsharp_channel_create(target, channelArgs);
}
protected override bool ReleaseHandle()
{
grpc_channel_destroy(handle);
grpcsharp_channel_destroy(handle);
return true;
}
}

@ -9,23 +9,23 @@ namespace Google.GRPC.Core.Internal
/// </summary>
internal class CompletionQueueSafeHandle : SafeHandleZeroIsInvalid
{
[DllImport("grpc.dll")]
static extern CompletionQueueSafeHandle grpc_completion_queue_create();
[DllImport("grpc_csharp_ext.dll")]
static extern CompletionQueueSafeHandle grpcsharp_completion_queue_create();
[DllImport("grpc.dll")]
static extern EventSafeHandle grpc_completion_queue_pluck(CompletionQueueSafeHandle cq, IntPtr tag, Timespec deadline);
[DllImport("grpc_csharp_ext.dll")]
static extern EventSafeHandle grpcsharp_completion_queue_pluck(CompletionQueueSafeHandle cq, IntPtr tag, Timespec deadline);
[DllImport("grpc.dll")]
static extern EventSafeHandle grpc_completion_queue_next(CompletionQueueSafeHandle cq, Timespec deadline);
[DllImport("grpc_csharp_ext.dll")]
static extern EventSafeHandle grpcsharp_completion_queue_next(CompletionQueueSafeHandle cq, Timespec deadline);
[DllImport("grpc.dll")]
static extern void grpc_completion_queue_shutdown(CompletionQueueSafeHandle cq);
[DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_completion_queue_shutdown(CompletionQueueSafeHandle cq);
[DllImport("grpc_csharp_ext.dll")]
static extern GRPCCompletionType grpc_completion_queue_next_with_callback(CompletionQueueSafeHandle cq);
static extern GRPCCompletionType grpcsharp_completion_queue_next_with_callback(CompletionQueueSafeHandle cq);
[DllImport("grpc.dll")]
static extern void grpc_completion_queue_destroy(IntPtr cq);
[DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_completion_queue_destroy(IntPtr cq);
private CompletionQueueSafeHandle()
{
@ -33,32 +33,32 @@ namespace Google.GRPC.Core.Internal
public static CompletionQueueSafeHandle Create()
{
return grpc_completion_queue_create();
return grpcsharp_completion_queue_create();
}
public EventSafeHandle Next(Timespec deadline)
{
return grpc_completion_queue_next(this, deadline);
return grpcsharp_completion_queue_next(this, deadline);
}
public GRPCCompletionType NextWithCallback()
{
return grpc_completion_queue_next_with_callback(this);
return grpcsharp_completion_queue_next_with_callback(this);
}
public EventSafeHandle Pluck(IntPtr tag, Timespec deadline)
{
return grpc_completion_queue_pluck(this, tag, deadline);
return grpcsharp_completion_queue_pluck(this, tag, deadline);
}
public void Shutdown()
{
grpc_completion_queue_shutdown(this);
grpcsharp_completion_queue_shutdown(this);
}
protected override bool ReleaseHandle()
{
grpc_completion_queue_destroy(handle);
grpcsharp_completion_queue_destroy(handle);
return true;
}
}

@ -9,84 +9,84 @@ namespace Google.GRPC.Core.Internal
/// </summary>
internal class EventSafeHandle : SafeHandleZeroIsInvalid
{
[DllImport("grpc.dll")]
static extern void grpc_event_finish(IntPtr ev);
[DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_event_finish(IntPtr ev);
[DllImport("grpc_csharp_ext.dll")]
static extern GRPCCompletionType grpc_event_type(EventSafeHandle ev);
static extern GRPCCompletionType grpcsharp_event_type(EventSafeHandle ev);
[DllImport("grpc_csharp_ext.dll")]
static extern CallSafeHandle grpc_event_call(EventSafeHandle ev);
static extern CallSafeHandle grpcsharp_event_call(EventSafeHandle ev);
[DllImport("grpc_csharp_ext.dll")]
static extern GRPCOpError grpc_event_write_accepted(EventSafeHandle ev);
static extern GRPCOpError grpcsharp_event_write_accepted(EventSafeHandle ev);
[DllImport("grpc_csharp_ext.dll")]
static extern GRPCOpError grpc_event_finish_accepted(EventSafeHandle ev);
static extern GRPCOpError grpcsharp_event_finish_accepted(EventSafeHandle ev);
[DllImport("grpc_csharp_ext.dll")]
static extern StatusCode grpc_event_finished_status(EventSafeHandle ev);
static extern StatusCode grpcsharp_event_finished_status(EventSafeHandle ev);
[DllImport("grpc_csharp_ext.dll")]
static extern IntPtr grpc_event_finished_details(EventSafeHandle ev); // returns const char*
static extern IntPtr grpcsharp_event_finished_details(EventSafeHandle ev); // returns const char*
[DllImport("grpc_csharp_ext.dll")]
static extern IntPtr grpc_event_read_length(EventSafeHandle ev);
static extern IntPtr grpcsharp_event_read_length(EventSafeHandle ev);
[DllImport("grpc_csharp_ext.dll")]
static extern void grpc_event_read_copy_to_buffer(EventSafeHandle ev, byte[] buffer, UIntPtr bufferLen);
static extern void grpcsharp_event_read_copy_to_buffer(EventSafeHandle ev, byte[] buffer, UIntPtr bufferLen);
[DllImport("grpc_csharp_ext.dll")]
static extern IntPtr grpc_event_server_rpc_new_method(EventSafeHandle ev); // returns const char*
static extern IntPtr grpcsharp_event_server_rpc_new_method(EventSafeHandle ev); // returns const char*
public GRPCCompletionType GetCompletionType()
{
return grpc_event_type(this);
return grpcsharp_event_type(this);
}
public GRPCOpError GetWriteAccepted()
{
return grpc_event_write_accepted(this);
return grpcsharp_event_write_accepted(this);
}
public GRPCOpError GetFinishAccepted()
{
return grpc_event_finish_accepted(this);
return grpcsharp_event_finish_accepted(this);
}
public Status GetFinished()
{
// TODO: can the native method return string directly?
string details = Marshal.PtrToStringAnsi(grpc_event_finished_details(this));
return new Status(grpc_event_finished_status(this), details);
string details = Marshal.PtrToStringAnsi(grpcsharp_event_finished_details(this));
return new Status(grpcsharp_event_finished_status(this), details);
}
public byte[] GetReadData()
{
IntPtr len = grpc_event_read_length(this);
IntPtr len = grpcsharp_event_read_length(this);
if (len == new IntPtr(-1))
{
return null;
}
byte[] data = new byte[(int) len];
grpc_event_read_copy_to_buffer(this, data, new UIntPtr((ulong)data.Length));
grpcsharp_event_read_copy_to_buffer(this, data, new UIntPtr((ulong)data.Length));
return data;
}
public CallSafeHandle GetCall() {
return grpc_event_call(this);
return grpcsharp_event_call(this);
}
public string GetServerRpcNewMethod() {
// TODO: can the native method return string directly?
return Marshal.PtrToStringAnsi(grpc_event_server_rpc_new_method(this));
return Marshal.PtrToStringAnsi(grpcsharp_event_server_rpc_new_method(this));
}
//TODO: client_metadata_read event type
protected override bool ReleaseHandle()
{
grpc_event_finish(handle);
grpcsharp_event_finish(handle);
return true;
}
}
@ -98,35 +98,35 @@ namespace Google.GRPC.Core.Internal
/// </summary>
internal class EventSafeHandleNotOwned : SafeHandleZeroIsInvalid
{
[DllImport("grpc.dll")]
static extern void grpc_event_finish(IntPtr ev);
[DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_event_finish(IntPtr ev);
[DllImport("grpc_csharp_ext.dll")]
static extern GRPCCompletionType grpc_event_type(EventSafeHandleNotOwned ev);
static extern GRPCCompletionType grpcsharp_event_type(EventSafeHandleNotOwned ev);
[DllImport("grpc_csharp_ext.dll")]
static extern CallSafeHandle grpc_event_call(EventSafeHandleNotOwned ev);
static extern CallSafeHandle grpcsharp_event_call(EventSafeHandleNotOwned ev);
[DllImport("grpc_csharp_ext.dll")]
static extern GRPCOpError grpc_event_write_accepted(EventSafeHandleNotOwned ev);
static extern GRPCOpError grpcsharp_event_write_accepted(EventSafeHandleNotOwned ev);
[DllImport("grpc_csharp_ext.dll")]
static extern GRPCOpError grpc_event_finish_accepted(EventSafeHandleNotOwned ev);
static extern GRPCOpError grpcsharp_event_finish_accepted(EventSafeHandleNotOwned ev);
[DllImport("grpc_csharp_ext.dll")]
static extern StatusCode grpc_event_finished_status(EventSafeHandleNotOwned ev);
static extern StatusCode grpcsharp_event_finished_status(EventSafeHandleNotOwned ev);
[DllImport("grpc_csharp_ext.dll")]
static extern IntPtr grpc_event_finished_details(EventSafeHandleNotOwned ev); // returns const char*
static extern IntPtr grpcsharp_event_finished_details(EventSafeHandleNotOwned ev); // returns const char*
[DllImport("grpc_csharp_ext.dll")]
static extern IntPtr grpc_event_read_length(EventSafeHandleNotOwned ev);
static extern IntPtr grpcsharp_event_read_length(EventSafeHandleNotOwned ev);
[DllImport("grpc_csharp_ext.dll")]
static extern void grpc_event_read_copy_to_buffer(EventSafeHandleNotOwned ev, byte[] buffer, UIntPtr bufferLen);
static extern void grpcsharp_event_read_copy_to_buffer(EventSafeHandleNotOwned ev, byte[] buffer, UIntPtr bufferLen);
[DllImport("grpc_csharp_ext.dll")]
static extern IntPtr grpc_event_server_rpc_new_method(EventSafeHandleNotOwned ev); // returns const char*
static extern IntPtr grpcsharp_event_server_rpc_new_method(EventSafeHandleNotOwned ev); // returns const char*
public EventSafeHandleNotOwned() : base(false)
{
@ -139,52 +139,52 @@ namespace Google.GRPC.Core.Internal
public GRPCCompletionType GetCompletionType()
{
return grpc_event_type(this);
return grpcsharp_event_type(this);
}
public GRPCOpError GetWriteAccepted()
{
return grpc_event_write_accepted(this);
return grpcsharp_event_write_accepted(this);
}
public GRPCOpError GetFinishAccepted()
{
return grpc_event_finish_accepted(this);
return grpcsharp_event_finish_accepted(this);
}
public Status GetFinished()
{
// TODO: can the native method return string directly?
string details = Marshal.PtrToStringAnsi(grpc_event_finished_details(this));
return new Status(grpc_event_finished_status(this), details);
string details = Marshal.PtrToStringAnsi(grpcsharp_event_finished_details(this));
return new Status(grpcsharp_event_finished_status(this), details);
}
public byte[] GetReadData()
{
IntPtr len = grpc_event_read_length(this);
IntPtr len = grpcsharp_event_read_length(this);
if (len == new IntPtr(-1))
{
return null;
}
byte[] data = new byte[(int) len];
grpc_event_read_copy_to_buffer(this, data, new UIntPtr((ulong)data.Length));
grpcsharp_event_read_copy_to_buffer(this, data, new UIntPtr((ulong)data.Length));
return data;
}
public CallSafeHandle GetCall() {
return grpc_event_call(this);
return grpcsharp_event_call(this);
}
public string GetServerRpcNewMethod() {
// TODO: can the native method return string directly?
return Marshal.PtrToStringAnsi(grpc_event_server_rpc_new_method(this));
return Marshal.PtrToStringAnsi(grpcsharp_event_server_rpc_new_method(this));
}
//TODO: client_metadata_read event type
protected override bool ReleaseHandle()
{
grpc_event_finish(handle);
grpcsharp_event_finish(handle);
return true;
}
}

@ -10,31 +10,31 @@ namespace Google.GRPC.Core.Internal
/// </summary>
internal sealed class ServerSafeHandle : SafeHandleZeroIsInvalid
{
[DllImport("grpc.dll", EntryPoint = "grpc_server_request_call_old")]
static extern GRPCCallError grpc_server_request_call_old_CALLBACK(ServerSafeHandle server, [MarshalAs(UnmanagedType.FunctionPtr)] EventCallbackDelegate callback);
[DllImport("grpc_csharp_ext.dll", EntryPoint = "grpcsharp_server_request_call_old")]
static extern GRPCCallError grpcsharp_server_request_call_old_CALLBACK(ServerSafeHandle server, [MarshalAs(UnmanagedType.FunctionPtr)] EventCallbackDelegate callback);
[DllImport("grpc.dll")]
static extern ServerSafeHandle grpc_server_create(CompletionQueueSafeHandle cq, IntPtr args);
[DllImport("grpc_csharp_ext.dll")]
static extern ServerSafeHandle grpcsharp_server_create(CompletionQueueSafeHandle cq, IntPtr args);
// TODO: check int representation size
[DllImport("grpc.dll")]
static extern int grpc_server_add_http2_port(ServerSafeHandle server, string addr);
[DllImport("grpc_csharp_ext.dll")]
static extern int grpcsharp_server_add_http2_port(ServerSafeHandle server, string addr);
// TODO: check int representation size
[DllImport("grpc.dll")]
static extern int grpc_server_add_secure_http2_port(ServerSafeHandle server, string addr);
[DllImport("grpc_csharp_ext.dll")]
static extern int grpcsharp_server_add_secure_http2_port(ServerSafeHandle server, string addr);
[DllImport("grpc.dll")]
static extern void grpc_server_start(ServerSafeHandle server);
[DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_server_start(ServerSafeHandle server);
[DllImport("grpc.dll")]
static extern void grpc_server_shutdown(ServerSafeHandle server);
[DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_server_shutdown(ServerSafeHandle server);
[DllImport("grpc.dll", EntryPoint = "grpc_server_shutdown_and_notify")]
static extern void grpc_server_shutdown_and_notify_CALLBACK(ServerSafeHandle server, [MarshalAs(UnmanagedType.FunctionPtr)] EventCallbackDelegate callback);
[DllImport("grpc_csharp_ext.dll", EntryPoint = "grpcsharp_server_shutdown_and_notify")]
static extern void grpcsharp_server_shutdown_and_notify_CALLBACK(ServerSafeHandle server, [MarshalAs(UnmanagedType.FunctionPtr)] EventCallbackDelegate callback);
[DllImport("grpc.dll")]
static extern void grpc_server_destroy(IntPtr server);
[DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_server_destroy(IntPtr server);
private ServerSafeHandle()
{
@ -43,38 +43,38 @@ namespace Google.GRPC.Core.Internal
public static ServerSafeHandle NewServer(CompletionQueueSafeHandle cq, IntPtr args)
{
// TODO: also grpc_secure_server_create...
return grpc_server_create(cq, args);
return grpcsharp_server_create(cq, args);
}
public int AddPort(string addr)
{
// TODO: also grpc_server_add_secure_http2_port...
return grpc_server_add_http2_port(this, addr);
return grpcsharp_server_add_http2_port(this, addr);
}
public void Start()
{
grpc_server_start(this);
grpcsharp_server_start(this);
}
public void Shutdown()
{
grpc_server_shutdown(this);
grpcsharp_server_shutdown(this);
}
public void ShutdownAndNotify(EventCallbackDelegate callback)
{
grpc_server_shutdown_and_notify_CALLBACK(this, callback);
grpcsharp_server_shutdown_and_notify_CALLBACK(this, callback);
}
public GRPCCallError RequestCall(EventCallbackDelegate callback)
{
return grpc_server_request_call_old_CALLBACK(this, callback);
return grpcsharp_server_request_call_old_CALLBACK(this, callback);
}
protected override bool ReleaseHandle()
{
grpc_server_destroy(handle);
grpcsharp_server_destroy(handle);
return true;
}
}

@ -13,13 +13,20 @@ namespace Google.GRPC.Core.Internal
const int nanosPerSecond = 1000 * 1000 * 1000;
const int nanosPerTick = 100;
[DllImport("gpr.dll")]
static extern Timespec gpr_now();
[DllImport("grpc_csharp_ext.dll")]
static extern Timespec gprsharp_now();
// TODO: this only works on 64bit linux, can we autoselect the right size of ints?
// perhaps using IntPtr would work.
public System.Int64 tv_sec;
public System.Int64 tv_nsec;
[DllImport("grpc_csharp_ext.dll")]
static extern Timespec gprsharp_inf_future();
[DllImport("grpc_csharp_ext.dll")]
static extern int gprsharp_sizeof_timespec();
// TODO: revisit this.
// NOTE: on linux 64bit sizeof(gpr_timespec) = 16, on windows 32bit sizeof(gpr_timespec) = 8
// so IntPtr seems to have the right size to work on both.
public System.IntPtr tv_sec;
public System.IntPtr tv_nsec;
/// <summary>
/// Timespec a long time in the future.
@ -28,8 +35,7 @@ namespace Google.GRPC.Core.Internal
{
get
{
// TODO: set correct value based on the length of the struct
return new Timespec { tv_sec = Int32.MaxValue, tv_nsec = 0 };
return gprsharp_inf_future();
}
}
@ -37,7 +43,15 @@ namespace Google.GRPC.Core.Internal
{
get
{
return gpr_now();
return gprsharp_now();
}
}
internal static int NativeSize
{
get
{
return gprsharp_sizeof_timespec();
}
}
@ -54,12 +68,12 @@ namespace Google.GRPC.Core.Internal
}
public Timespec Add(TimeSpan timeSpan) {
long nanos = tv_nsec + (timeSpan.Ticks % TimeSpan.TicksPerSecond) * nanosPerTick;
long nanos = tv_nsec.ToInt64() + (timeSpan.Ticks % TimeSpan.TicksPerSecond) * nanosPerTick;
long overflow_sec = (nanos > nanosPerSecond) ? 1 : 0;
Timespec result;
result.tv_nsec = nanos % nanosPerSecond;
result.tv_sec = tv_sec + (timeSpan.Ticks / TimeSpan.TicksPerSecond) + overflow_sec;
result.tv_nsec = new IntPtr(nanos % nanosPerSecond);
result.tv_sec = new IntPtr(tv_sec.ToInt64() + (timeSpan.Ticks / TimeSpan.TicksPerSecond) + overflow_sec);
return result;
}
}

@ -1,5 +1,6 @@
using System;
using NUnit.Framework;
using System.Runtime.InteropServices;
using Google.GRPC.Core.Internal;
namespace Google.GRPC.Core.Internal.Tests
@ -12,31 +13,43 @@ namespace Google.GRPC.Core.Internal.Tests
var timespec = Timespec.Now;
}
[Test]
public void InfFuture()
{
var timespec = Timespec.InfFuture;
}
[Test]
public void TimespecSizeIsNativeSize()
{
Assert.AreEqual(Timespec.NativeSize, Marshal.SizeOf(typeof(Timespec)));
}
[Test]
public void Add()
{
var t = new Timespec { tv_sec = 12345, tv_nsec = 123456789 };
var t = new Timespec { tv_sec = new IntPtr(12345), tv_nsec = new IntPtr(123456789) };
var result = t.Add(TimeSpan.FromTicks(TimeSpan.TicksPerSecond * 10));
Assert.AreEqual(result.tv_sec, 12355);
Assert.AreEqual(result.tv_nsec, 123456789);
Assert.AreEqual(result.tv_sec, new IntPtr(12355));
Assert.AreEqual(result.tv_nsec, new IntPtr(123456789));
}
[Test]
public void Add_Nanos()
{
var t = new Timespec { tv_sec = 12345, tv_nsec = 123456789 };
var t = new Timespec { tv_sec = new IntPtr(12345), tv_nsec = new IntPtr(123456789) };
var result = t.Add(TimeSpan.FromTicks(10));
Assert.AreEqual(result.tv_sec, 12345);
Assert.AreEqual(result.tv_nsec, 123456789 + 1000);
Assert.AreEqual(result.tv_sec, new IntPtr(12345));
Assert.AreEqual(result.tv_nsec, new IntPtr(123456789 + 1000));
}
[Test]
public void Add_NanosOverflow()
{
var t = new Timespec { tv_sec = 12345, tv_nsec = 999999999 };
var t = new Timespec { tv_sec = new IntPtr(12345), tv_nsec = new IntPtr(999999999) };
var result = t.Add(TimeSpan.FromTicks(TimeSpan.TicksPerSecond * 10 + 10));
Assert.AreEqual(result.tv_sec, 12356);
Assert.AreEqual(result.tv_nsec, 999);
Assert.AreEqual(result.tv_sec, new IntPtr(12356));
Assert.AreEqual(result.tv_nsec, new IntPtr(999));
}
}
}

@ -1,9 +1,23 @@
#include <grpc/support/port_platform.h>
#include <grpc/grpc.h>
#include <grpc/support/log.h>
#include <grpc/support/slice.h>
#include <string.h>
#ifdef GPR_WIN32
#define GPR_EXPORT __declspec(dllexport)
#define GPR_CALLTYPE __stdcall
#endif
#ifndef GPR_EXPORT
#define GPR_EXPORT
#endif
#ifndef GPR_CALLTYPE
#define GPR_CALLTYPE
#endif
grpc_byte_buffer *string_to_byte_buffer(const char *buffer, size_t len) {
gpr_slice slice = gpr_slice_from_copied_buffer(buffer, len);
grpc_byte_buffer *bb = grpc_byte_buffer_create(&slice, 1);
@ -11,40 +25,119 @@ grpc_byte_buffer *string_to_byte_buffer(const char *buffer, size_t len) {
return bb;
}
void grpc_call_start_write_from_copied_buffer(grpc_call *call,
const char *buffer, size_t len,
void *tag, gpr_uint32 flags) {
grpc_byte_buffer *byte_buffer = string_to_byte_buffer(buffer, len);
GPR_ASSERT(grpc_call_start_write_old(call, byte_buffer, tag, flags) ==
GRPC_CALL_OK);
grpc_byte_buffer_destroy(byte_buffer);
/* Init & shutdown */
GPR_EXPORT void GPR_CALLTYPE grpcsharp_init(void) { grpc_init(); }
GPR_EXPORT void GPR_CALLTYPE grpcsharp_shutdown(void) { grpc_shutdown(); }
/* Completion queue */
GPR_EXPORT grpc_completion_queue *GPR_CALLTYPE
grpcsharp_completion_queue_create(void) {
return grpc_completion_queue_create();
}
GPR_EXPORT grpc_event *GPR_CALLTYPE
grpcsharp_completion_queue_next(grpc_completion_queue *cq,
gpr_timespec deadline) {
return grpc_completion_queue_next(cq, deadline);
}
grpc_completion_type grpc_event_type(const grpc_event *event) {
GPR_EXPORT grpc_event *GPR_CALLTYPE
grpcsharp_completion_queue_pluck(grpc_completion_queue *cq, void *tag,
gpr_timespec deadline) {
return grpc_completion_queue_pluck(cq, tag, deadline);
}
GPR_EXPORT void GPR_CALLTYPE
grpcsharp_completion_queue_shutdown(grpc_completion_queue *cq) {
grpc_completion_queue_shutdown(cq);
}
GPR_EXPORT void GPR_CALLTYPE
grpcsharp_completion_queue_destroy(grpc_completion_queue *cq) {
grpc_completion_queue_destroy(cq);
}
GPR_EXPORT grpc_completion_type GPR_CALLTYPE
grpcsharp_completion_queue_next_with_callback(grpc_completion_queue *cq) {
grpc_event *ev;
grpc_completion_type t;
void(GPR_CALLTYPE * callback)(grpc_event *);
ev = grpc_completion_queue_next(cq, gpr_inf_future);
t = ev->type;
if (ev->tag) {
/* call the callback in ev->tag */
/* C forbids to cast object pointers to function pointers, so
* we cast to intptr first.
*/
callback = (void(GPR_CALLTYPE *)(grpc_event *))(gpr_intptr)ev->tag;
(*callback)(ev);
}
grpc_event_finish(ev);
/* return completion type to allow some handling for events that have no
* tag - such as GRPC_QUEUE_SHUTDOWN
*/
return t;
}
/* Channel */
GPR_EXPORT grpc_channel *GPR_CALLTYPE
grpcsharp_channel_create(const char *target, const grpc_channel_args *args) {
return grpc_channel_create(target, args);
}
GPR_EXPORT void GPR_CALLTYPE grpcsharp_channel_destroy(grpc_channel *channel) {
grpc_channel_destroy(channel);
}
GPR_EXPORT grpc_call *GPR_CALLTYPE
grpcsharp_channel_create_call_old(grpc_channel *channel, const char *method,
const char *host, gpr_timespec deadline) {
return grpc_channel_create_call_old(channel, method, host, deadline);
}
/* Event */
GPR_EXPORT void GPR_CALLTYPE grpcsharp_event_finish(grpc_event *event) {
grpc_event_finish(event);
}
GPR_EXPORT grpc_completion_type GPR_CALLTYPE
grpcsharp_event_type(const grpc_event *event) {
return event->type;
}
grpc_op_error grpc_event_write_accepted(const grpc_event *event) {
GPR_EXPORT grpc_op_error GPR_CALLTYPE
grpcsharp_event_write_accepted(const grpc_event *event) {
GPR_ASSERT(event->type == GRPC_WRITE_ACCEPTED);
return event->data.invoke_accepted;
}
grpc_op_error grpc_event_finish_accepted(const grpc_event *event) {
GPR_EXPORT grpc_op_error GPR_CALLTYPE
grpcsharp_event_finish_accepted(const grpc_event *event) {
GPR_ASSERT(event->type == GRPC_FINISH_ACCEPTED);
return event->data.finish_accepted;
}
grpc_status_code grpc_event_finished_status(const grpc_event *event) {
GPR_EXPORT grpc_status_code GPR_CALLTYPE
grpcsharp_event_finished_status(const grpc_event *event) {
GPR_ASSERT(event->type == GRPC_FINISHED);
return event->data.finished.status;
}
const char *grpc_event_finished_details(const grpc_event *event) {
GPR_EXPORT const char *GPR_CALLTYPE
grpcsharp_event_finished_details(const grpc_event *event) {
GPR_ASSERT(event->type == GRPC_FINISHED);
return event->data.finished.details;
}
gpr_intptr grpc_event_read_length(const grpc_event *event) {
GPR_EXPORT gpr_intptr GPR_CALLTYPE
grpcsharp_event_read_length(const grpc_event *event) {
GPR_ASSERT(event->type == GRPC_READ);
if (!event->data.read) {
return -1;
@ -56,7 +149,8 @@ gpr_intptr grpc_event_read_length(const grpc_event *event) {
* Copies data from read event to a buffer. Fatal error occurs if
* buffer is too small.
*/
void grpc_event_read_copy_to_buffer(const grpc_event *event, char *buffer,
GPR_EXPORT void GPR_CALLTYPE
grpcsharp_event_read_copy_to_buffer(const grpc_event *event, char *buffer,
size_t buffer_len) {
grpc_byte_buffer_reader *reader;
gpr_slice slice;
@ -77,37 +171,142 @@ void grpc_event_read_copy_to_buffer(const grpc_event *event, char *buffer,
grpc_byte_buffer_reader_destroy(reader);
}
grpc_call *grpc_event_call(const grpc_event *event) {
GPR_EXPORT grpc_call *GPR_CALLTYPE
grpcsharp_event_call(const grpc_event *event) {
/* we only allow this for newly incoming server calls. */
GPR_ASSERT(event->type == GRPC_SERVER_RPC_NEW);
return event->call;
}
const char *grpc_event_server_rpc_new_method(const grpc_event *event) {
GPR_EXPORT const char *GPR_CALLTYPE
grpcsharp_event_server_rpc_new_method(const grpc_event *event) {
GPR_ASSERT(event->type == GRPC_SERVER_RPC_NEW);
return event->data.server_rpc_new.method;
}
grpc_completion_type grpc_completion_queue_next_with_callback(
grpc_completion_queue *cq) {
grpc_event *ev;
grpc_completion_type t;
void (*callback)(grpc_event *);
/* Timespec */
ev = grpc_completion_queue_next(cq, gpr_inf_future);
t = ev->type;
if (ev->tag) {
/* call the callback in ev->tag */
/* C forbids to cast object pointers to function pointers, so
* we cast to intptr first.
*/
callback = (void (*)(grpc_event *))(gpr_intptr)ev->tag;
(*callback)(ev);
}
grpc_event_finish(ev);
GPR_EXPORT gpr_timespec GPR_CALLTYPE gprsharp_now(void) { return gpr_now(); }
/* return completion type to allow some handling for events that have no
* tag - such as GRPC_QUEUE_SHUTDOWN
*/
return t;
GPR_EXPORT gpr_timespec GPR_CALLTYPE gprsharp_inf_future(void) {
return gpr_inf_future;
}
GPR_EXPORT gpr_int32 GPR_CALLTYPE gprsharp_sizeof_timespec(void) {
return sizeof(gpr_timespec);
}
/* Call */
GPR_EXPORT grpc_call_error GPR_CALLTYPE
grpcsharp_call_add_metadata_old(grpc_call *call, grpc_metadata *metadata,
gpr_uint32 flags) {
return grpc_call_add_metadata_old(call, metadata, flags);
}
GPR_EXPORT grpc_call_error GPR_CALLTYPE
grpcsharp_call_invoke_old(grpc_call *call, grpc_completion_queue *cq,
void *metadata_read_tag, void *finished_tag,
gpr_uint32 flags) {
return grpc_call_invoke_old(call, cq, metadata_read_tag, finished_tag, flags);
}
GPR_EXPORT grpc_call_error GPR_CALLTYPE
grpcsharp_call_server_accept_old(grpc_call *call, grpc_completion_queue *cq,
void *finished_tag) {
return grpc_call_server_accept_old(call, cq, finished_tag);
}
GPR_EXPORT grpc_call_error GPR_CALLTYPE
grpcsharp_call_server_end_initial_metadata_old(grpc_call *call,
gpr_uint32 flags) {
return grpc_call_server_end_initial_metadata_old(call, flags);
}
GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_cancel(grpc_call *call) {
return grpc_call_cancel(call);
}
GPR_EXPORT grpc_call_error GPR_CALLTYPE
grpcsharp_call_cancel_with_status(grpc_call *call, grpc_status_code status,
const char *description) {
return grpc_call_cancel_with_status(call, status, description);
}
GPR_EXPORT grpc_call_error GPR_CALLTYPE
grpcsharp_call_start_write_old(grpc_call *call, grpc_byte_buffer *byte_buffer,
void *tag, gpr_uint32 flags) {
return grpc_call_start_write_old(call, byte_buffer, tag, flags);
}
GPR_EXPORT grpc_call_error GPR_CALLTYPE
grpcsharp_call_start_write_status_old(grpc_call *call,
grpc_status_code status_code,
const char *status_message, void *tag) {
return grpc_call_start_write_status_old(call, status_code, status_message,
tag);
}
GPR_EXPORT grpc_call_error GPR_CALLTYPE
grpcsharp_call_writes_done_old(grpc_call *call, void *tag) {
return grpc_call_writes_done_old(call, tag);
}
GPR_EXPORT grpc_call_error GPR_CALLTYPE
grpcsharp_call_start_read_old(grpc_call *call, void *tag) {
return grpc_call_start_read_old(call, tag);
}
GPR_EXPORT void GPR_CALLTYPE grpcsharp_call_destroy(grpc_call *call) {
grpc_call_destroy(call);
}
GPR_EXPORT void GPR_CALLTYPE
grpcsharp_call_start_write_from_copied_buffer(grpc_call *call,
const char *buffer, size_t len,
void *tag, gpr_uint32 flags) {
grpc_byte_buffer *byte_buffer = string_to_byte_buffer(buffer, len);
GPR_ASSERT(grpc_call_start_write_old(call, byte_buffer, tag, flags) ==
GRPC_CALL_OK);
grpc_byte_buffer_destroy(byte_buffer);
}
/* Server */
GPR_EXPORT grpc_call_error GPR_CALLTYPE
grpcsharp_server_request_call_old(grpc_server *server, void *tag_new) {
return grpc_server_request_call_old(server, tag_new);
}
GPR_EXPORT grpc_server *GPR_CALLTYPE
grpcsharp_server_create(grpc_completion_queue *cq,
const grpc_channel_args *args) {
return grpc_server_create(cq, args);
}
GPR_EXPORT int GPR_CALLTYPE
grpcsharp_server_add_http2_port(grpc_server *server, const char *addr) {
return grpc_server_add_http2_port(server, addr);
}
GPR_EXPORT int GPR_CALLTYPE
grpcsharp_server_add_secure_http2_port(grpc_server *server, const char *addr) {
return grpc_server_add_secure_http2_port(server, addr);
}
GPR_EXPORT void GPR_CALLTYPE grpcsharp_server_start(grpc_server *server) {
grpc_server_start(server);
}
GPR_EXPORT void GPR_CALLTYPE grpcsharp_server_shutdown(grpc_server *server) {
grpc_server_shutdown(server);
}
GPR_EXPORT void GPR_CALLTYPE
grpcsharp_server_shutdown_and_notify(grpc_server *server, void *tag) {
grpc_server_shutdown_and_notify(server, tag);
}
GPR_EXPORT void GPR_CALLTYPE grpcsharp_server_destroy(grpc_server *server) {
grpc_server_destroy(server);
}

@ -1,2 +1,2 @@
<%namespace file="vcxproj_defs.include" import="gen_project"/>\
${gen_project('grpc_csharp_ext', libs, targets, configuration_type = 'DynamicLibrary', project_guid = '{C26D04A8-37C6-44C7-B458-906C9FCE928C}', additional_props = ['winsock'])}
${gen_project('grpc_csharp_ext', libs, targets, configuration_type = 'DynamicLibrary', project_guid = '{C26D04A8-37C6-44C7-B458-906C9FCE928C}', additional_props = ['winsock', 'ssl'])}

@ -25,6 +25,7 @@ END2END_TESTS = [
'disappearing_server',
'early_server_shutdown_finishes_inflight_calls',
'early_server_shutdown_finishes_tags',
'empty_batch',
'graceful_server_shutdown',
'invoke_large_request',
'max_concurrent_streams',
@ -123,4 +124,3 @@ def main():
if __name__ == '__main__':
main()

@ -0,0 +1,137 @@
/*
*
* 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.
*
*/
#include "test/core/end2end/end2end_tests.h"
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "src/core/support/string.h"
#include <grpc/byte_buffer.h>
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/time.h>
#include <grpc/support/useful.h>
#include "test/core/end2end/cq_verifier.h"
enum { TIMEOUT = 200000 };
static void *tag(gpr_intptr t) { return (void *)t; }
static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
const char *test_name,
grpc_channel_args *client_args,
grpc_channel_args *server_args) {
grpc_end2end_test_fixture f;
gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
f = config.create_fixture(client_args, server_args);
config.init_client(&f, client_args);
config.init_server(&f, server_args);
return f;
}
static gpr_timespec n_seconds_time(int n) {
return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
}
static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
static void drain_cq(grpc_completion_queue *cq) {
grpc_event *ev;
grpc_completion_type type;
do {
ev = grpc_completion_queue_next(cq, five_seconds_time());
GPR_ASSERT(ev);
type = ev->type;
grpc_event_finish(ev);
} while (type != GRPC_QUEUE_SHUTDOWN);
}
static void shutdown_server(grpc_end2end_test_fixture *f) {
if (!f->server) return;
grpc_server_shutdown(f->server);
grpc_server_destroy(f->server);
f->server = NULL;
}
static void shutdown_client(grpc_end2end_test_fixture *f) {
if (!f->client) return;
grpc_channel_destroy(f->client);
f->client = NULL;
}
static void end_test(grpc_end2end_test_fixture *f) {
shutdown_server(f);
shutdown_client(f);
grpc_completion_queue_shutdown(f->server_cq);
drain_cq(f->server_cq);
grpc_completion_queue_destroy(f->server_cq);
grpc_completion_queue_shutdown(f->client_cq);
drain_cq(f->client_cq);
grpc_completion_queue_destroy(f->client_cq);
}
static void empty_batch_body(grpc_end2end_test_fixture f) {
grpc_call *c;
gpr_timespec deadline = five_seconds_time();
cq_verifier *v_client = cq_verifier_create(f.client_cq);
grpc_op *op = NULL;
c = grpc_channel_create_call(f.client, f.client_cq, "/foo",
"foo.test.google.com", deadline);
GPR_ASSERT(c);
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(c, op, 0, tag(1)));
cq_expect_completion(v_client, tag(1), GRPC_OP_OK);
cq_verify(v_client);
grpc_call_destroy(c);
cq_verifier_destroy(v_client);
}
static void test_invoke_empty_body(grpc_end2end_test_config config) {
grpc_end2end_test_fixture f;
f = begin_test(config, __FUNCTION__, NULL, NULL);
empty_batch_body(f);
end_test(&f);
config.tear_down_data(&f);
}
void grpc_end2end_tests(grpc_end2end_test_config config) {
test_invoke_empty_body(config);
}

@ -329,6 +329,10 @@
"language": "c",
"name": "chttp2_fake_security_early_server_shutdown_finishes_tags_test"
},
{
"language": "c",
"name": "chttp2_fake_security_empty_batch_test"
},
{
"language": "c",
"name": "chttp2_fake_security_graceful_server_shutdown_test"
@ -517,6 +521,10 @@
"language": "c",
"name": "chttp2_fullstack_early_server_shutdown_finishes_tags_test"
},
{
"language": "c",
"name": "chttp2_fullstack_empty_batch_test"
},
{
"language": "c",
"name": "chttp2_fullstack_graceful_server_shutdown_test"
@ -705,6 +713,10 @@
"language": "c",
"name": "chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test"
},
{
"language": "c",
"name": "chttp2_simple_ssl_fullstack_empty_batch_test"
},
{
"language": "c",
"name": "chttp2_simple_ssl_fullstack_graceful_server_shutdown_test"
@ -893,6 +905,10 @@
"language": "c",
"name": "chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test"
},
{
"language": "c",
"name": "chttp2_simple_ssl_with_oauth2_fullstack_empty_batch_test"
},
{
"language": "c",
"name": "chttp2_simple_ssl_with_oauth2_fullstack_graceful_server_shutdown_test"
@ -1081,6 +1097,10 @@
"language": "c",
"name": "chttp2_socket_pair_early_server_shutdown_finishes_tags_test"
},
{
"language": "c",
"name": "chttp2_socket_pair_empty_batch_test"
},
{
"language": "c",
"name": "chttp2_socket_pair_graceful_server_shutdown_test"
@ -1269,6 +1289,10 @@
"language": "c",
"name": "chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test"
},
{
"language": "c",
"name": "chttp2_socket_pair_one_byte_at_a_time_empty_batch_test"
},
{
"language": "c",
"name": "chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_test"

@ -36,11 +36,13 @@
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="global.props" />
<Import Project="winsock.props" />
<Import Project="ssl.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="global.props" />
<Import Project="winsock.props" />
<Import Project="ssl.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

@ -279,6 +279,8 @@
</ClCompile>
<ClCompile Include="..\..\src\core\iomgr\pollset_multipoller_with_poll_posix.c">
</ClCompile>
<ClCompile Include="..\..\src\core\iomgr\pollset_multipoller_with_epoll.c">
</ClCompile>
<ClCompile Include="..\..\src\core\iomgr\pollset_posix.c">
</ClCompile>
<ClCompile Include="..\..\src\core\iomgr\pollset_windows.c">

@ -133,6 +133,9 @@
<ClCompile Include="..\..\src\core\iomgr\pollset_multipoller_with_poll_posix.c">
<Filter>src\core\iomgr</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\iomgr\pollset_multipoller_with_epoll.c">
<Filter>src\core\iomgr</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\iomgr\pollset_posix.c">
<Filter>src\core\iomgr</Filter>
</ClCompile>

Loading…
Cancel
Save