Merge pull request #505 from jtattermusch/csharp_single_dll

Make grcp_sharp_ext the only dll needed to run gRPC C#.

Great news! LGTM
pull/509/head
Tim Emiola 10 years ago
commit 9b09d19484
  1. 12
      src/csharp/GrpcCore/GrpcEnvironment.cs
  2. 104
      src/csharp/GrpcCore/Internal/CallSafeHandle.cs
  3. 12
      src/csharp/GrpcCore/Internal/ChannelSafeHandle.cs
  4. 34
      src/csharp/GrpcCore/Internal/CompletionQueueSafeHandle.cs
  5. 84
      src/csharp/GrpcCore/Internal/Event.cs
  6. 46
      src/csharp/GrpcCore/Internal/ServerSafeHandle.cs
  7. 38
      src/csharp/GrpcCore/Internal/Timespec.cs
  8. 31
      src/csharp/GrpcCoreTests/TimespecTest.cs
  9. 271
      src/csharp/ext/grpc_csharp_ext.c
  10. 2
      templates/vsprojects/vs2013/grpc_csharp_ext_shared.vcxproj.template
  11. 2
      vsprojects/vs2013/grpc_csharp_ext_shared.vcxproj

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

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

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

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

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

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

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

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

@ -1,9 +1,23 @@
#include <grpc/support/port_platform.h>
#include <grpc/grpc.h> #include <grpc/grpc.h>
#include <grpc/support/log.h> #include <grpc/support/log.h>
#include <grpc/support/slice.h> #include <grpc/support/slice.h>
#include <string.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) { grpc_byte_buffer *string_to_byte_buffer(const char *buffer, size_t len) {
gpr_slice slice = gpr_slice_from_copied_buffer(buffer, len); gpr_slice slice = gpr_slice_from_copied_buffer(buffer, len);
grpc_byte_buffer *bb = grpc_byte_buffer_create(&slice, 1); 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; return bb;
} }
void grpc_call_start_write_from_copied_buffer(grpc_call *call, /* Init & shutdown */
const char *buffer, size_t len,
void *tag, gpr_uint32 flags) { GPR_EXPORT void GPR_CALLTYPE grpcsharp_init(void) { grpc_init(); }
grpc_byte_buffer *byte_buffer = string_to_byte_buffer(buffer, len);
GPR_ASSERT(grpc_call_start_write_old(call, byte_buffer, tag, flags) == GPR_EXPORT void GPR_CALLTYPE grpcsharp_shutdown(void) { grpc_shutdown(); }
GRPC_CALL_OK);
grpc_byte_buffer_destroy(byte_buffer); /* 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; 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); GPR_ASSERT(event->type == GRPC_WRITE_ACCEPTED);
return event->data.invoke_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); GPR_ASSERT(event->type == GRPC_FINISH_ACCEPTED);
return event->data.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); GPR_ASSERT(event->type == GRPC_FINISHED);
return event->data.finished.status; 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); GPR_ASSERT(event->type == GRPC_FINISHED);
return event->data.finished.details; 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); GPR_ASSERT(event->type == GRPC_READ);
if (!event->data.read) { if (!event->data.read) {
return -1; 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 * Copies data from read event to a buffer. Fatal error occurs if
* buffer is too small. * 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) { size_t buffer_len) {
grpc_byte_buffer_reader *reader; grpc_byte_buffer_reader *reader;
gpr_slice slice; 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_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. */ /* we only allow this for newly incoming server calls. */
GPR_ASSERT(event->type == GRPC_SERVER_RPC_NEW); GPR_ASSERT(event->type == GRPC_SERVER_RPC_NEW);
return event->call; 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); GPR_ASSERT(event->type == GRPC_SERVER_RPC_NEW);
return event->data.server_rpc_new.method; return event->data.server_rpc_new.method;
} }
grpc_completion_type grpc_completion_queue_next_with_callback( /* Timespec */
grpc_completion_queue *cq) {
grpc_event *ev;
grpc_completion_type t;
void (*callback)(grpc_event *);
ev = grpc_completion_queue_next(cq, gpr_inf_future); GPR_EXPORT gpr_timespec GPR_CALLTYPE gprsharp_now(void) { return gpr_now(); }
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);
/* return completion type to allow some handling for events that have no GPR_EXPORT gpr_timespec GPR_CALLTYPE gprsharp_inf_future(void) {
* tag - such as GRPC_QUEUE_SHUTDOWN return gpr_inf_future;
*/ }
return t;
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"/>\ <%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'])}

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

Loading…
Cancel
Save