Merge branch 'master' of github.com:google/grpc into docker

pull/514/head
Donna Dionne 10 years ago
commit 0963425a94
  1. 36
      INSTALL
  2. 580
      Makefile
  3. 8
      include/grpc/support/port_platform.h
  4. 6
      src/core/surface/call.c
  5. 12
      src/csharp/GrpcCore/GrpcEnvironment.cs
  6. 104
      src/csharp/GrpcCore/Internal/CallSafeHandle.cs
  7. 12
      src/csharp/GrpcCore/Internal/ChannelSafeHandle.cs
  8. 34
      src/csharp/GrpcCore/Internal/CompletionQueueSafeHandle.cs
  9. 84
      src/csharp/GrpcCore/Internal/Event.cs
  10. 46
      src/csharp/GrpcCore/Internal/ServerSafeHandle.cs
  11. 38
      src/csharp/GrpcCore/Internal/Timespec.cs
  12. 31
      src/csharp/GrpcCoreTests/TimespecTest.cs
  13. 271
      src/csharp/ext/grpc_csharp_ext.c
  14. 171
      templates/Makefile.template
  15. 2
      templates/vsprojects/vs2013/grpc_csharp_ext_shared.vcxproj.template
  16. 10
      test/build/protobuf.cc
  17. 2
      test/core/end2end/gen_build_json.py
  18. 137
      test/core/end2end/tests/empty_batch.c
  19. 24
      tools/run_tests/tests.json
  20. 2
      vsprojects/vs2013/grpc_csharp_ext_shared.vcxproj
  21. 2
      vsprojects/vs2013/grpc_shared.vcxproj
  22. 3
      vsprojects/vs2013/grpc_shared.vcxproj.filters

@ -14,10 +14,14 @@ A typical unix installation won't require any more steps than running:
$ make $ make
# make install # make install
You don't need anything else than GNU Make and gcc. Under a Debian or You don't need anything else than GNU Make, gcc and autotools. Under a Debian
Ubuntu system, this should boil down to the following package: or Ubuntu system, this should boil down to the following packages:
# apt-get install build-essential python-all-dev python-virtualenv # apt-get install build-essential autoconf libtool
Building the python wrapper requires the following:
# apt-get install python-all-dev python-virtualenv
******************************* *******************************
@ -68,33 +72,23 @@ Compiling and running grpc plain-C tests dont't require any more dependency.
Compiling and running grpc C++ tests depend on protobuf 3.0.0, gtest and Compiling and running grpc C++ tests depend on protobuf 3.0.0, gtest and
gflags. Although gflags and protobuf are provided in third_party, you will gflags. Although gflags is provided in third_party, you will need to manually
need to manually install these dependencies on your system to run these tests. install that dependency on your system to run these tests.
Under a Debian or Ubuntu system, you can install the gtests and gflags packages Under a Debian or Ubuntu system, you can install the gtests and gflags packages
using apt-get: using apt-get:
# apt-get install libgflags-dev libgtest-dev # apt-get install libgflags-dev libgtest-dev
However, protobuf 3.0.0 isn't in a debian package yet: you'll need to compile However, protobuf 3.0.0 isn't in a debian package yet, but the Makefile will
and install it from the sources in the third_party. Note that if you already automatically try and compile the one present in third_party if you cloned the
have the protobuf and protoc packages installed on your system, they will most repository recursively, and that it detects your system is lacking it.
likely interfere, and you'll need to uninstall them first.
Compiling and installing protobuf 3.0.0 requires a few more dependencies in Compiling and installing protobuf 3.0.0 requires a few more dependencies in
itself, notably the autoconf suite, curl, and unzip. If you have apt-get, you itself, notably the autoconf suite. If you have apt-get, you can install
can install these dependencies this way: these dependencies this way:
# apt-get install unzip curl autoconf libtool
Then, you can build and install protobuf 3.0.0: # apt-get install autoconf libtool
$ cd third_party/protobuf
$ ./autogen.sh
$ ./configure
$ make
# make install
# ldconfig
A word on OpenSSL A word on OpenSSL

File diff suppressed because one or more lines are too long

@ -70,6 +70,7 @@
#define GPR_POSIX_TIME 1 #define GPR_POSIX_TIME 1
#define GPR_GETPID_IN_UNISTD_H 1 #define GPR_GETPID_IN_UNISTD_H 1
#elif defined(__linux__) #elif defined(__linux__)
#include <features.h>
#define GPR_CPU_LINUX 1 #define GPR_CPU_LINUX 1
#define GPR_GCC_ATOMIC 1 #define GPR_GCC_ATOMIC 1
#define GPR_LINUX 1 #define GPR_LINUX 1
@ -78,7 +79,14 @@
#define GPR_LINUX_EVENTFD 1 #define GPR_LINUX_EVENTFD 1
#define GPR_POSIX_SOCKET 1 #define GPR_POSIX_SOCKET 1
#define GPR_POSIX_SOCKETADDR 1 #define GPR_POSIX_SOCKETADDR 1
#ifdef __GLIBC_PREREQ
#if __GLIBC_PREREQ(2, 17)
#define GPR_LINUX_ENV 1 #define GPR_LINUX_ENV 1
#endif
#endif
#ifndef GPR_LINUX_ENV
#define GPR_POSIX_ENV 1
#endif
#define GPR_POSIX_FILE 1 #define GPR_POSIX_FILE 1
#define GPR_POSIX_STRING 1 #define GPR_POSIX_STRING 1
#define GPR_POSIX_SYNC 1 #define GPR_POSIX_SYNC 1

@ -991,6 +991,12 @@ grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops,
const grpc_op *op; const grpc_op *op;
grpc_ioreq *req; 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 */ /* rewrite batch ops into ioreq ops */
for (in = 0, out = 0; in < nops; in++) { for (in = 0, out = 0; in < nops; in++) {
op = &ops[in]; op = &ops[in];

@ -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);
} }

@ -149,8 +149,6 @@ else
LIBS = rt m z pthread LIBS = rt m z pthread
LDFLAGS += -pthread LDFLAGS += -pthread
endif endif
LIBSXX = protobuf
LIBS_PROTOC = protoc protobuf
ifneq ($(wildcard /usr/src/gtest/src/gtest-all.cc),) ifneq ($(wildcard /usr/src/gtest/src/gtest-all.cc),)
GTEST_LIB = /usr/src/gtest/src/gtest-all.cc -I/usr/src/gtest GTEST_LIB = /usr/src/gtest/src/gtest-all.cc -I/usr/src/gtest
@ -174,7 +172,6 @@ CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS)
LDFLAGS += $(ARCH_FLAGS) LDFLAGS += $(ARCH_FLAGS)
LDLIBS += $(addprefix -l, $(LIBS)) LDLIBS += $(addprefix -l, $(LIBS))
LDLIBSXX += $(addprefix -l, $(LIBSXX)) LDLIBSXX += $(addprefix -l, $(LIBSXX))
HOST_LDLIBS_PROTOC += $(addprefix -l, $(LIBS_PROTOC))
HOST_CPPFLAGS = $(CPPFLAGS) HOST_CPPFLAGS = $(CPPFLAGS)
HOST_CFLAGS = $(CFLAGS) HOST_CFLAGS = $(CFLAGS)
@ -205,6 +202,8 @@ endif
OPENSSL_ALPN_CHECK_CMD = $(CC) $(CFLAGS) $(CPPFLAGS) -o /dev/null test/build/openssl-alpn.c -lssl -lcrypto -ldl $(LDFLAGS) OPENSSL_ALPN_CHECK_CMD = $(CC) $(CFLAGS) $(CPPFLAGS) -o /dev/null test/build/openssl-alpn.c -lssl -lcrypto -ldl $(LDFLAGS)
ZLIB_CHECK_CMD = $(CC) $(CFLAGS) $(CPPFLAGS) -o /dev/null test/build/zlib.c -lz $(LDFLAGS) ZLIB_CHECK_CMD = $(CC) $(CFLAGS) $(CPPFLAGS) -o /dev/null test/build/zlib.c -lz $(LDFLAGS)
PERFTOOLS_CHECK_CMD = $(CC) $(CFLAGS) $(CPPFLAGS) -o /dev/null test/build/perftools.c -lprofiler $(LDFLAGS) PERFTOOLS_CHECK_CMD = $(CC) $(CFLAGS) $(CPPFLAGS) -o /dev/null test/build/perftools.c -lprofiler $(LDFLAGS)
PROTOBUF_CHECK_CMD = $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o /dev/null test/build/protobuf.cc -lprotobuf $(LDFLAGS)
PROTOC_CHECK_CMD = protoc --version | grep -q libprotoc.3
ifndef REQUIRE_CUSTOM_LIBRARIES_$(CONFIG) ifndef REQUIRE_CUSTOM_LIBRARIES_$(CONFIG)
HAS_SYSTEM_PERFTOOLS = $(shell $(PERFTOOLS_CHECK_CMD) 2> /dev/null && echo true || echo false) HAS_SYSTEM_PERFTOOLS = $(shell $(PERFTOOLS_CHECK_CMD) 2> /dev/null && echo true || echo false)
@ -217,12 +216,16 @@ endif
ifndef REQUIRE_CUSTOM_LIBRARIES_$(CONFIG) ifndef REQUIRE_CUSTOM_LIBRARIES_$(CONFIG)
HAS_SYSTEM_OPENSSL_ALPN = $(shell $(OPENSSL_ALPN_CHECK_CMD) 2> /dev/null && echo true || echo false) HAS_SYSTEM_OPENSSL_ALPN = $(shell $(OPENSSL_ALPN_CHECK_CMD) 2> /dev/null && echo true || echo false)
HAS_SYSTEM_ZLIB = $(shell $(ZLIB_CHECK_CMD) 2> /dev/null && echo true || echo false) HAS_SYSTEM_ZLIB = $(shell $(ZLIB_CHECK_CMD) 2> /dev/null && echo true || echo false)
HAS_SYSTEM_PROTOBUF = $(shell $(PROTOBUF_CHECK_CMD) 2> /dev/null && echo true || echo false)
else else
# override system libraries if the config requires a custom compiled library # override system libraries if the config requires a custom compiled library
HAS_SYSTEM_OPENSSL_ALPN = false HAS_SYSTEM_OPENSSL_ALPN = false
HAS_SYSTEM_ZLIB = false HAS_SYSTEM_ZLIB = false
HAS_SYSTEM_PROTOBUF = false
endif endif
HAS_VALID_PROTOC = $(shell $(PROTOC_CHECK_CMD) 2> /dev/null && echo true || echo false)
ifeq ($(wildcard third_party/openssl/ssl/ssl.h),) ifeq ($(wildcard third_party/openssl/ssl/ssl.h),)
HAS_EMBEDDED_OPENSSL_ALPN = false HAS_EMBEDDED_OPENSSL_ALPN = false
else else
@ -235,11 +238,20 @@ else
HAS_EMBEDDED_ZLIB = true HAS_EMBEDDED_ZLIB = true
endif endif
ifeq ($(wildcard third_party/protobuf/src/google/protobuf/descriptor.pb.h),)
HAS_EMBEDDED_PROTOBUF = false
ifneq ($(HAS_VALID_PROTOC),true)
NO_PROTOC = true
endif
else
HAS_EMBEDDED_PROTOBUF = true
endif
ifeq ($(HAS_SYSTEM_ZLIB),false) ifeq ($(HAS_SYSTEM_ZLIB),false)
ifeq ($(HAS_EMBEDDED_ZLIB),true) ifeq ($(HAS_EMBEDDED_ZLIB),true)
ZLIB_DEP = libs/$(CONFIG)/zlib/libz.a ZLIB_DEP = libs/$(CONFIG)/zlib/libz.a
CPPFLAGS += -Ithird_party/zlib CPPFLAGS += -Ithird_party/zlib
LDFLAGS += -Lthird_party/zlib LDFLAGS += -Llibs/$(CONFIG)/zlib
else else
DEP_MISSING += zlib DEP_MISSING += zlib
endif endif
@ -261,6 +273,24 @@ endif
LDLIBS_SECURE += $(addprefix -l, $(LIBS_SECURE)) LDLIBS_SECURE += $(addprefix -l, $(LIBS_SECURE))
ifeq ($(HAS_SYSTEM_PROTOBUF),false)
ifeq ($(HAS_EMBEDDED_PROTOBUF),true)
PROTOBUF_DEP = libs/$(CONFIG)/protobuf/libprotobuf.a
CPPFLAGS += -Ithird_party/protobuf/src
LDFLAGS += -Llibs/$(CONFIG)/protobuf
PROTOC = bins/$(CONFIG)/protobuf/protoc
else
NO_PROTOBUF = true
endif
else
endif
LIBS_PROTOBUF = protobuf
LIBS_PROTOC = protoc protobuf
LDLIBS_PROTOBUF += $(addprefix -l, $(LIBS_PROTOBUF))
HOST_LDLIBS_PROTOC += $(addprefix -l, $(LIBS_PROTOC))
ifeq ($(MAKECMDGOALS),clean) ifeq ($(MAKECMDGOALS),clean)
NO_DEPS = true NO_DEPS = true
endif endif
@ -316,6 +346,10 @@ endif
openssl_dep_error: openssl_dep_message git_update stop openssl_dep_error: openssl_dep_message git_update stop
protobuf_dep_error: protobuf_dep_message git_update stop
protoc_dep_error: protoc_dep_message git_update stop
openssl_dep_message: openssl_dep_message:
@echo @echo
@echo "DEPENDENCY ERROR" @echo "DEPENDENCY ERROR"
@ -330,6 +364,34 @@ openssl_dep_message:
@echo " make run_dep_checks" @echo " make run_dep_checks"
@echo @echo
protobuf_dep_message:
@echo
@echo "DEPENDENCY ERROR"
@echo
@echo "The target you are trying to run requires protobuf 3.0.0+"
@echo "Your system doesn't have it, and neither does the third_party directory."
@echo
@echo "Please consult INSTALL to get more information."
@echo
@echo "If you need information about why these tests failed, run:"
@echo
@echo " make run_dep_checks"
@echo
protoc_dep_message:
@echo
@echo "DEPENDENCY ERROR"
@echo
@echo "The target you are trying to run requires protobuf-compiler 3.0.0+"
@echo "Your system doesn't have it, and neither does the third_party directory."
@echo
@echo "Please consult INSTALL to get more information."
@echo
@echo "If you need information about why these tests failed, run:"
@echo
@echo " make run_dep_checks"
@echo
stop: stop:
@false @false
@ -340,6 +402,9 @@ ${tgt.name}: bins/$(CONFIG)/${tgt.name}
run_dep_checks: run_dep_checks:
$(OPENSSL_ALPN_CHECK_CMD) || true $(OPENSSL_ALPN_CHECK_CMD) || true
$(ZLIB_CHECK_CMD) || true $(ZLIB_CHECK_CMD) || true
$(PERFTOOLS_CHECK_CMD) || true
$(PROTOBUF_CHECK_CMD) || true
$(PROTOC_CHECK_CMD) || true
libs/$(CONFIG)/zlib/libz.a: libs/$(CONFIG)/zlib/libz.a:
$(E) "[MAKE] Building zlib" $(E) "[MAKE] Building zlib"
@ -361,6 +426,21 @@ endif
$(Q)mkdir -p libs/$(CONFIG)/openssl $(Q)mkdir -p libs/$(CONFIG)/openssl
$(Q)cp third_party/openssl/libssl.a third_party/openssl/libcrypto.a libs/$(CONFIG)/openssl $(Q)cp third_party/openssl/libssl.a third_party/openssl/libcrypto.a libs/$(CONFIG)/openssl
third_party/protobuf/configure:
$(E) "[AUTOGEN] Preparing protobuf"
$(Q)(cd third_party/protobuf ; autoreconf -f -i -Wall,no-obsolete)
libs/$(CONFIG)/protobuf/libprotobuf.a: third_party/protobuf/configure
$(E) "[MAKE] Building protobuf"
$(Q)(cd third_party/protobuf ; CC="$(CC)" CXX="$(CXX)" LDFLAGS="$(LDFLAGS_$(CONFIG)) -g" CXXFLAGS="-DLANG_CXX11 -std=c++11" CPPFLAGS="$(CPPFLAGS_$(CONFIG)) -g" ./configure --disable-shared --enable-static)
$(Q)$(MAKE) -C third_party/protobuf clean
$(Q)$(MAKE) -C third_party/protobuf
$(Q)mkdir -p libs/$(CONFIG)/protobuf
$(Q)mkdir -p bins/$(CONFIG)/protobuf
$(Q)cp third_party/protobuf/src/.libs/libprotoc.a libs/$(CONFIG)/protobuf
$(Q)cp third_party/protobuf/src/.libs/libprotobuf.a libs/$(CONFIG)/protobuf
$(Q)cp third_party/protobuf/src/protoc bins/$(CONFIG)/protobuf
static: static_c static_cxx static: static_c static_cxx
static_c: \ static_c: \
@ -531,10 +611,14 @@ ifeq ($(CONFIG),opt)
endif endif
% for p in protos: % for p in protos:
gens/${p}.pb.cc: ${p}.proto $(PROTOC_PLUGINS) ifeq ($(NO_PROTOC),true)
gens/${p}.pb.cc: protoc_dep_error
else
gens/${p}.pb.cc: ${p}.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[PROTOC] Generating protobuf CC file from $<" $(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
$(Q) $(PROTOC) --cpp_out=gens --grpc_out=gens --plugin=protoc-gen-grpc=bins/$(CONFIG)/cpp_plugin $< $(Q) $(PROTOC) --cpp_out=gens --grpc_out=gens --plugin=protoc-gen-grpc=bins/$(CONFIG)/cpp_plugin $<
endif
% endfor % endfor
@ -704,17 +788,60 @@ endif
else else
% if lib.language == 'c++':
ifeq ($(NO_PROTOBUF),true)
# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay.
libs/$(CONFIG)/lib${lib.name}.a: protobuf_dep_error
% if lib.build == "all":
ifeq ($(SYSTEM),MINGW32)
libs/$(CONFIG)/${lib.name}.$(SHARED_EXT): protobuf_dep_error
else
libs/$(CONFIG)/lib${lib.name}.$(SHARED_EXT): protobuf_dep_error
endif
% endif
else
% endif
ifneq ($(OPENSSL_DEP),) ifneq ($(OPENSSL_DEP),)
# This is to ensure the embedded OpenSSL is built beforehand, properly
# installing headers to their final destination on the drive. We need this
# otherwise parallel compilation will fail if a source is compiled first.
% for src in lib.src: % for src in lib.src:
${src}: $(OPENSSL_DEP) ${src}: $(OPENSSL_DEP)
% endfor % endfor
endif endif
libs/$(CONFIG)/lib${lib.name}.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(LIB${lib.name.upper()}_OBJS) libs/$(CONFIG)/lib${lib.name}.a: $(ZLIB_DEP) $(OPENSSL_DEP)\
## The else here corresponds to the if secure earlier. ## The else here corresponds to the if secure earlier.
% else: % else:
libs/$(CONFIG)/lib${lib.name}.a: $(ZLIB_DEP) $(LIB${lib.name.upper()}_OBJS) % if lib.language == 'c++':
ifeq ($(NO_PROTOBUF),true)
# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay.
libs/$(CONFIG)/lib${lib.name}.a: protobuf_dep_error
% if lib.build == "all":
ifeq ($(SYSTEM),MINGW32)
libs/$(CONFIG)/${lib.name}.$(SHARED_EXT): protobuf_dep_error
else
libs/$(CONFIG)/lib${lib.name}.$(SHARED_EXT): protobuf_dep_error
endif
% endif
else
% endif
libs/$(CONFIG)/lib${lib.name}.a: $(ZLIB_DEP)\
% endif
% if lib.language == 'c++':
$(PROTOBUF_DEP)\
% endif % endif
$(LIB${lib.name.upper()}_OBJS)
$(E) "[AR] Creating $@" $(E) "[AR] Creating $@"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
$(Q) rm -f libs/$(CONFIG)/lib${lib.name}.a $(Q) rm -f libs/$(CONFIG)/lib${lib.name}.a
@ -780,10 +907,15 @@ else
endif endif
endif endif
% endif % endif
% if lib.get('secure', True):
## If the lib was secure, we have to close the Makefile's if that tested ## If the lib was secure, we have to close the Makefile's if that tested
## the presence of an ALPN-capable OpenSSL. ## the presence of an ALPN-capable OpenSSL.
% if lib.get('secure', True):
endif
% endif
% if lib.language == 'c++':
## If the lib was C++, we have to close the Makefile's if that tested
## the presence of protobuf 3.0.0+
endif endif
% endif % endif
@ -840,7 +972,20 @@ else
## That simplifies the codegen a bit, but prevents a fully defined Makefile. ## That simplifies the codegen a bit, but prevents a fully defined Makefile.
## I can live with that. ## I can live with that.
## ##
% if tgt.build == 'protoc':
ifeq ($(NO_PROTOBUF),true)
# You can't build the protoc plugins if you don't have protobuf 3.0.0+.
bins/$(CONFIG)/${tgt.name}: protobuf_dep_error
else
bins/$(CONFIG)/${tgt.name}: $(PROTOBUF_DEP) $(${tgt.name.upper()}_OBJS)\
% else:
bins/$(CONFIG)/${tgt.name}: $(${tgt.name.upper()}_OBJS)\ bins/$(CONFIG)/${tgt.name}: $(${tgt.name.upper()}_OBJS)\
% endif
% for dep in tgt.deps: % for dep in tgt.deps:
libs/$(CONFIG)/lib${dep}.a\ libs/$(CONFIG)/lib${dep}.a\
% endfor % endfor
@ -870,9 +1015,9 @@ bins/$(CONFIG)/${tgt.name}: $(${tgt.name.upper()}_OBJS)\
% endfor % endfor
% if tgt.language == "c++": % if tgt.language == "c++":
% if tgt.build == 'protoc': % if tgt.build == 'protoc':
$(HOST_LDLIBSXX)\ $(HOST_LDLIBSXX) $(HOST_LDLIBS_PROTOC)\
% else: % else:
$(LDLIBSXX)\ $(LDLIBSXX) $(LDLIBS_PROTOBUF)\
% endif % endif
% endif % endif
% if tgt.build == 'protoc': % if tgt.build == 'protoc':
@ -886,6 +1031,10 @@ bins/$(CONFIG)/${tgt.name}: $(${tgt.name.upper()}_OBJS)\
$(LDLIBS_SECURE)\ $(LDLIBS_SECURE)\
% endif % endif
-o bins/$(CONFIG)/${tgt.name} -o bins/$(CONFIG)/${tgt.name}
% if tgt.build == 'protoc':
endif
% endif
% if tgt.get('secure', True): % if tgt.get('secure', True):
endif endif

@ -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'])}

@ -0,0 +1,10 @@
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor.pb.h>
bool protobuf_test(const google::protobuf::MethodDescriptor *method) {
return method->client_streaming() || method->server_streaming();
}
int main() {
return 0;
}

@ -25,6 +25,7 @@ END2END_TESTS = [
'disappearing_server', 'disappearing_server',
'early_server_shutdown_finishes_inflight_calls', 'early_server_shutdown_finishes_inflight_calls',
'early_server_shutdown_finishes_tags', 'early_server_shutdown_finishes_tags',
'empty_batch',
'graceful_server_shutdown', 'graceful_server_shutdown',
'invoke_large_request', 'invoke_large_request',
'max_concurrent_streams', 'max_concurrent_streams',
@ -123,4 +124,3 @@ def main():
if __name__ == '__main__': if __name__ == '__main__':
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);
}

@ -333,6 +333,10 @@
"language": "c", "language": "c",
"name": "chttp2_fake_security_early_server_shutdown_finishes_tags_test" "name": "chttp2_fake_security_early_server_shutdown_finishes_tags_test"
}, },
{
"language": "c",
"name": "chttp2_fake_security_empty_batch_test"
},
{ {
"language": "c", "language": "c",
"name": "chttp2_fake_security_graceful_server_shutdown_test" "name": "chttp2_fake_security_graceful_server_shutdown_test"
@ -521,6 +525,10 @@
"language": "c", "language": "c",
"name": "chttp2_fullstack_early_server_shutdown_finishes_tags_test" "name": "chttp2_fullstack_early_server_shutdown_finishes_tags_test"
}, },
{
"language": "c",
"name": "chttp2_fullstack_empty_batch_test"
},
{ {
"language": "c", "language": "c",
"name": "chttp2_fullstack_graceful_server_shutdown_test" "name": "chttp2_fullstack_graceful_server_shutdown_test"
@ -709,6 +717,10 @@
"language": "c", "language": "c",
"name": "chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test" "name": "chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test"
}, },
{
"language": "c",
"name": "chttp2_simple_ssl_fullstack_empty_batch_test"
},
{ {
"language": "c", "language": "c",
"name": "chttp2_simple_ssl_fullstack_graceful_server_shutdown_test" "name": "chttp2_simple_ssl_fullstack_graceful_server_shutdown_test"
@ -897,6 +909,10 @@
"language": "c", "language": "c",
"name": "chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test" "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", "language": "c",
"name": "chttp2_simple_ssl_with_oauth2_fullstack_graceful_server_shutdown_test" "name": "chttp2_simple_ssl_with_oauth2_fullstack_graceful_server_shutdown_test"
@ -1085,6 +1101,10 @@
"language": "c", "language": "c",
"name": "chttp2_socket_pair_early_server_shutdown_finishes_tags_test" "name": "chttp2_socket_pair_early_server_shutdown_finishes_tags_test"
}, },
{
"language": "c",
"name": "chttp2_socket_pair_empty_batch_test"
},
{ {
"language": "c", "language": "c",
"name": "chttp2_socket_pair_graceful_server_shutdown_test" "name": "chttp2_socket_pair_graceful_server_shutdown_test"
@ -1273,6 +1293,10 @@
"language": "c", "language": "c",
"name": "chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test" "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", "language": "c",
"name": "chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_test" "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="$(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'">

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

@ -130,6 +130,9 @@
<ClCompile Include="..\..\src\core\iomgr\pollset_multipoller_with_poll_posix.c"> <ClCompile Include="..\..\src\core\iomgr\pollset_multipoller_with_poll_posix.c">
<Filter>src\core\iomgr</Filter> <Filter>src\core\iomgr</Filter>
</ClCompile> </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"> <ClCompile Include="..\..\src\core\iomgr\pollset_posix.c">
<Filter>src\core\iomgr</Filter> <Filter>src\core\iomgr</Filter>
</ClCompile> </ClCompile>

Loading…
Cancel
Save