aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.gitignore5
-rw-r--r--Makefile86
-rw-r--r--build.json12
-rw-r--r--src/csharp/.gitignore2
-rwxr-xr-xsrc/csharp/README.md22
-rw-r--r--src/csharp/ext/grpc_csharp_ext.c113
6 files changed, 238 insertions, 2 deletions
diff --git a/.gitignore b/.gitignore
index 6eb55b1202..9c9ae5abd4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,6 +17,11 @@ coverage
# python compiled objects
*.pyc
+#eclipse project files
+.cproject
+.project
+.settings
+
# cache for run_tests.py
.run_tests_cache
diff --git a/Makefile b/Makefile
index 13f5129f93..122bcb4bc8 100644
--- a/Makefile
+++ b/Makefile
@@ -553,13 +553,13 @@ endif
static: static_c static_cxx
-static_c: libs/$(CONFIG)/libgpr.a libs/$(CONFIG)/libgrpc.a libs/$(CONFIG)/libgrpc_unsecure.a
+static_c: libs/$(CONFIG)/libgpr.a libs/$(CONFIG)/libgrpc.a libs/$(CONFIG)/libgrpc_unsecure.a libs/$(CONFIG)/libgrpc_csharp_ext.a
static_cxx: libs/$(CONFIG)/libgrpc++.a
shared: shared_c shared_cxx
-shared_c: libs/$(CONFIG)/libgpr.$(SHARED_EXT) libs/$(CONFIG)/libgrpc.$(SHARED_EXT) libs/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT)
+shared_c: libs/$(CONFIG)/libgpr.$(SHARED_EXT) libs/$(CONFIG)/libgrpc.$(SHARED_EXT) libs/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT) libs/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT)
shared_cxx: libs/$(CONFIG)/libgrpc++.$(SHARED_EXT)
@@ -1020,6 +1020,8 @@ ifeq ($(CONFIG),opt)
$(Q) $(STRIP) libs/$(CONFIG)/libgrpc.a
$(E) "[STRIP] Stripping libgrpc_unsecure.a"
$(Q) $(STRIP) libs/$(CONFIG)/libgrpc_unsecure.a
+ $(E) "[STRIP] Stripping libgrpc_csharp_ext.a"
+ $(Q) $(STRIP) libs/$(CONFIG)/libgrpc_csharp_ext.a
endif
strip-static_cxx: static_cxx
@@ -1036,6 +1038,8 @@ ifeq ($(CONFIG),opt)
$(Q) $(STRIP) libs/$(CONFIG)/libgrpc.$(SHARED_EXT)
$(E) "[STRIP] Stripping libgrpc_unsecure.so"
$(Q) $(STRIP) libs/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT)
+ $(E) "[STRIP] Stripping libgrpc_csharp_ext.so"
+ $(Q) $(STRIP) libs/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT)
endif
strip-shared_cxx: shared_cxx
@@ -1141,6 +1145,8 @@ install-static_c: static_c strip-static_c
$(Q) $(INSTALL) libs/$(CONFIG)/libgrpc.a $(prefix)/lib/libgrpc.a
$(E) "[INSTALL] Installing libgrpc_unsecure.a"
$(Q) $(INSTALL) libs/$(CONFIG)/libgrpc_unsecure.a $(prefix)/lib/libgrpc_unsecure.a
+ $(E) "[INSTALL] Installing libgrpc_csharp_ext.a"
+ $(Q) $(INSTALL) libs/$(CONFIG)/libgrpc_csharp_ext.a $(prefix)/lib/libgrpc_csharp_ext.a
install-static_cxx: static_cxx strip-static_cxx
$(E) "[INSTALL] Installing libgrpc++.a"
@@ -1180,6 +1186,17 @@ ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf libgrpc_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc_unsecure.so
endif
endif
+ifeq ($(SYSTEM),MINGW32)
+ $(E) "[INSTALL] Installing grpc_csharp_ext.$(SHARED_EXT)"
+ $(Q) $(INSTALL) libs/$(CONFIG)/grpc_csharp_ext.$(SHARED_EXT) $(prefix)/lib/grpc_csharp_ext.$(SHARED_EXT)
+ $(Q) $(INSTALL) libs/$(CONFIG)/libgrpc_csharp_ext-imp.a $(prefix)/lib/libgrpc_csharp_ext-imp.a
+else
+ $(E) "[INSTALL] Installing libgrpc_csharp_ext.$(SHARED_EXT)"
+ $(Q) $(INSTALL) libs/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT) $(prefix)/lib/libgrpc_csharp_ext.$(SHARED_EXT)
+ifneq ($(SYSTEM),Darwin)
+ $(Q) ln -sf libgrpc_csharp_ext.$(SHARED_EXT) $(prefix)/lib/libgrpc_csharp_ext.so
+endif
+endif
ifneq ($(SYSTEM),MINGW32)
ifneq ($(SYSTEM),Darwin)
$(Q) ldconfig
@@ -2300,6 +2317,71 @@ objs/$(CONFIG)/examples/tips/publisher.o: gens/examples/tips/label.pb.cc
objs/$(CONFIG)/examples/tips/subscriber.o: gens/examples/tips/label.pb.cc gens/examples/tips/empty.pb.cc gens/examples/tips/pubsub.pb.cc
+LIBGRPC_CSHARP_EXT_SRC = \
+ src/csharp/ext/grpc_csharp_ext.c \
+
+
+LIBGRPC_CSHARP_EXT_OBJS = $(addprefix objs/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_CSHARP_EXT_SRC))))
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure libraries if you don't have OpenSSL with ALPN.
+
+libs/$(CONFIG)/libgrpc_csharp_ext.a: openssl_dep_error
+
+ifeq ($(SYSTEM),MINGW32)
+libs/$(CONFIG)/grpc_csharp_ext.$(SHARED_EXT): openssl_dep_error
+else
+libs/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT): openssl_dep_error
+endif
+
+else
+
+ifneq ($(OPENSSL_DEP),)
+src/csharp/ext/grpc_csharp_ext.c: $(OPENSSL_DEP)
+endif
+
+libs/$(CONFIG)/libgrpc_csharp_ext.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(LIBGRPC_CSHARP_EXT_OBJS)
+ $(E) "[AR] Creating $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) rm -f libs/$(CONFIG)/libgrpc_csharp_ext.a
+ $(Q) $(AR) rcs libs/$(CONFIG)/libgrpc_csharp_ext.a $(LIBGRPC_CSHARP_EXT_OBJS)
+ifeq ($(SYSTEM),Darwin)
+ $(Q) ranlib libs/$(CONFIG)/libgrpc_csharp_ext.a
+endif
+
+
+
+ifeq ($(SYSTEM),MINGW32)
+libs/$(CONFIG)/grpc_csharp_ext.$(SHARED_EXT): $(LIBGRPC_CSHARP_EXT_OBJS) $(ZLIB_DEP)libs/$(CONFIG)/gpr.$(SHARED_EXT)libs/$(CONFIG)/grpc.$(SHARED_EXT) $(OPENSSL_DEP)
+ $(E) "[LD] Linking $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(LD) $(LDFLAGS) -Llibs/$(CONFIG) -shared -Wl,--output-def=libs/$(CONFIG)/grpc_csharp_ext.def -Wl,--out-implib=libs/$(CONFIG)/libgrpc_csharp_ext-imp.a -o libs/$(CONFIG)/grpc_csharp_ext.$(SHARED_EXT) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) $(LDLIBS_SECURE) $(OPENSSL_MERGE_LIBS) -lgpr-imp -lgrpc-imp
+else
+libs/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT): $(LIBGRPC_CSHARP_EXT_OBJS) $(ZLIB_DEP) libs/$(CONFIG)/libgpr.$(SHARED_EXT) libs/$(CONFIG)/libgrpc.$(SHARED_EXT) $(OPENSSL_DEP)
+ $(E) "[LD] Linking $@"
+ $(Q) mkdir -p `dirname $@`
+ifeq ($(SYSTEM),Darwin)
+ $(Q) $(LD) $(LDFLAGS) -Llibs/$(CONFIG) -dynamiclib -o libs/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) $(LDLIBS_SECURE) $(OPENSSL_MERGE_LIBS) -lgpr -lgrpc
+else
+ $(Q) $(LD) $(LDFLAGS) -Llibs/$(CONFIG) -shared -Wl,-soname,libgrpc_csharp_ext.so.0 -o libs/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) $(LDLIBS_SECURE) $(OPENSSL_MERGE_LIBS) -lgpr -lgrpc
+ $(Q) ln -sf libgrpc_csharp_ext.$(SHARED_EXT) libs/$(CONFIG)/libgrpc_csharp_ext.so.0
+ $(Q) ln -sf libgrpc_csharp_ext.$(SHARED_EXT) libs/$(CONFIG)/libgrpc_csharp_ext.so
+endif
+endif
+
+
+endif
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(LIBGRPC_CSHARP_EXT_OBJS:.o=.dep)
+endif
+endif
+
+objs/$(CONFIG)/src/csharp/ext/grpc_csharp_ext.o:
+
+
LIBEND2END_FIXTURE_CHTTP2_FAKE_SECURITY_SRC = \
test/core/end2end/fixtures/chttp2_fake_security.c \
diff --git a/build.json b/build.json
index 1cd8775f47..e7ab14b1f2 100644
--- a/build.json
+++ b/build.json
@@ -441,6 +441,18 @@
"grpc",
"gpr"
]
+ },
+ {
+ "name": "grpc_csharp_ext",
+ "build": "all",
+ "language": "c",
+ "deps": [
+ "gpr",
+ "grpc"
+ ],
+ "src": [
+ "src/csharp/ext/grpc_csharp_ext.c"
+ ]
}
],
"targets": [
diff --git a/src/csharp/.gitignore b/src/csharp/.gitignore
new file mode 100644
index 0000000000..dbf38f34b7
--- /dev/null
+++ b/src/csharp/.gitignore
@@ -0,0 +1,2 @@
+*.userprefs
+test-results
diff --git a/src/csharp/README.md b/src/csharp/README.md
new file mode 100755
index 0000000000..dac5a4550b
--- /dev/null
+++ b/src/csharp/README.md
@@ -0,0 +1,22 @@
+gRPC C#
+=======
+
+A C# implementation of gRPC, Google's RPC library.
+
+EXPERIMENTAL ONLY
+-----------------
+
+**This gRPC C# implementation is work-in-progress and is not expected to work yet.**
+
+- The implementation is a wrapper around gRPC C core library
+- Code only runs under mono currently, because there have been issues building
+ the gRPC C core library under Windows.
+- It is very possible that some parts of the code will be heavily refactored or
+ completely rewritten.
+
+CONTENTS
+--------
+
+- ext:
+ The extension library that wraps C API to be more digestible by C#.
+
diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c
new file mode 100644
index 0000000000..74d11c655b
--- /dev/null
+++ b/src/csharp/ext/grpc_csharp_ext.c
@@ -0,0 +1,113 @@
+#include <grpc/grpc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/slice.h>
+
+#include <string.h>
+
+grpc_byte_buffer *string_to_byte_buffer(const char *buffer, size_t len) {
+ gpr_slice slice = gpr_slice_from_copied_buffer(buffer, len);
+ grpc_byte_buffer *bb = grpc_byte_buffer_create(&slice, 1);
+ gpr_slice_unref(slice);
+ return bb;
+}
+
+void grpc_call_start_write_from_copied_buffer(grpc_call *call,
+ const char *buffer, size_t len,
+ void *tag, gpr_uint32 flags) {
+ grpc_byte_buffer *byte_buffer = string_to_byte_buffer(buffer, len);
+ GPR_ASSERT(grpc_call_start_write_old(call, byte_buffer, tag, flags) ==
+ GRPC_CALL_OK);
+ grpc_byte_buffer_destroy(byte_buffer);
+}
+
+grpc_completion_type grpc_event_type(const grpc_event *event) {
+ return event->type;
+}
+
+grpc_op_error grpc_event_write_accepted(const grpc_event *event) {
+ GPR_ASSERT(event->type == GRPC_WRITE_ACCEPTED);
+ return event->data.invoke_accepted;
+}
+
+grpc_op_error grpc_event_finish_accepted(const grpc_event *event) {
+ GPR_ASSERT(event->type == GRPC_FINISH_ACCEPTED);
+ return event->data.finish_accepted;
+}
+
+grpc_status_code grpc_event_finished_status(const grpc_event *event) {
+ GPR_ASSERT(event->type == GRPC_FINISHED);
+ return event->data.finished.status;
+}
+
+const char *grpc_event_finished_details(const grpc_event *event) {
+ GPR_ASSERT(event->type == GRPC_FINISHED);
+ return event->data.finished.details;
+}
+
+gpr_intptr grpc_event_read_length(const grpc_event *event) {
+ GPR_ASSERT(event->type == GRPC_READ);
+ if (!event->data.read) {
+ return -1;
+ }
+ return grpc_byte_buffer_length(event->data.read);
+}
+
+/*
+ * Copies data from read event to a buffer. Fatal error occurs if
+ * buffer is too small.
+ */
+void grpc_event_read_copy_to_buffer(const grpc_event *event, char *buffer,
+ size_t buffer_len) {
+ grpc_byte_buffer_reader *reader;
+ gpr_slice slice;
+ size_t offset = 0;
+
+ GPR_ASSERT(event->type == GRPC_READ);
+ reader = grpc_byte_buffer_reader_create(event->data.read);
+
+ GPR_ASSERT(event->data.read);
+ while (grpc_byte_buffer_reader_next(reader, &slice)) {
+ size_t len = GPR_SLICE_LENGTH(slice);
+ GPR_ASSERT(offset + len <= buffer_len);
+ memcpy(buffer + offset, GPR_SLICE_START_PTR(slice),
+ GPR_SLICE_LENGTH(slice));
+ offset += len;
+ gpr_slice_unref(slice);
+ }
+ grpc_byte_buffer_reader_destroy(reader);
+}
+
+grpc_call *grpc_event_call(const grpc_event *event) {
+ /* we only allow this for newly incoming server calls. */
+ GPR_ASSERT(event->type == GRPC_SERVER_RPC_NEW);
+ return event->call;
+}
+
+const char *grpc_event_server_rpc_new_method(const grpc_event *event) {
+ GPR_ASSERT(event->type == GRPC_SERVER_RPC_NEW);
+ return event->data.server_rpc_new.method;
+}
+
+grpc_completion_type grpc_completion_queue_next_with_callback(
+ grpc_completion_queue *cq) {
+ grpc_event *ev;
+ grpc_completion_type t;
+ void (*callback)(grpc_event *);
+
+ ev = grpc_completion_queue_next(cq, gpr_inf_future);
+ t = ev->type;
+ if (ev->tag) {
+ /* call the callback in ev->tag */
+ /* C forbids to cast object pointers to function pointers, so
+ * we cast to intptr first.
+ */
+ callback = (void (*)(grpc_event *))(gpr_intptr)ev->tag;
+ (*callback)(ev);
+ }
+ grpc_event_finish(ev);
+
+ /* return completion type to allow some handling for events that have no
+ * tag - such as GRPC_QUEUE_SHUTDOWN
+ */
+ return t;
+}