Resolved merge conflicts with master

pull/6920/head
murgatroid99 9 years ago
commit b2edc6c99a
  1. 16
      BUILD
  2. 47
      Makefile
  3. 2
      binding.gyp
  4. 23
      build.yaml
  5. 2
      config.m4
  6. 31
      doc/compression.md
  7. 2
      examples/csharp/helloworld/.nuget/packages.config
  8. 10
      examples/csharp/helloworld/Greeter/Greeter.csproj
  9. 10
      examples/csharp/helloworld/Greeter/Helloworld.cs
  10. 64
      examples/csharp/helloworld/Greeter/HelloworldGrpc.cs
  11. 6
      examples/csharp/helloworld/Greeter/packages.config
  12. 10
      examples/csharp/helloworld/GreeterClient/GreeterClient.csproj
  13. 2
      examples/csharp/helloworld/GreeterClient/Program.cs
  14. 6
      examples/csharp/helloworld/GreeterClient/packages.config
  15. 10
      examples/csharp/helloworld/GreeterServer/GreeterServer.csproj
  16. 6
      examples/csharp/helloworld/GreeterServer/packages.config
  17. 2
      examples/csharp/helloworld/generate_protos.bat
  18. 2
      examples/csharp/route_guide/.nuget/packages.config
  19. 16
      examples/csharp/route_guide/RouteGuide/RouteGuide.cs
  20. 10
      examples/csharp/route_guide/RouteGuide/RouteGuide.csproj
  21. 161
      examples/csharp/route_guide/RouteGuide/RouteGuideGrpc.cs
  22. 6
      examples/csharp/route_guide/RouteGuide/packages.config
  23. 2
      examples/csharp/route_guide/RouteGuideClient/Program.cs
  24. 10
      examples/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj
  25. 6
      examples/csharp/route_guide/RouteGuideClient/packages.config
  26. 10
      examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj
  27. 6
      examples/csharp/route_guide/RouteGuideServer/packages.config
  28. 2
      examples/csharp/route_guide/generate_protos.bat
  29. 108
      examples/objective-c/route_guide/Misc/Base.lproj/Main.storyboard
  30. 98
      examples/objective-c/route_guide/ViewControllers.m
  31. 6
      gRPC.podspec
  32. 1
      grpc.def
  33. 4
      grpc.gemspec
  34. 13
      include/grpc++/impl/codegen/async_stream.h
  35. 15
      include/grpc++/impl/codegen/completion_queue.h
  36. 11
      include/grpc++/impl/codegen/sync_stream.h
  37. 8
      include/grpc/grpc_posix.h
  38. 2
      include/grpc/impl/codegen/grpc_types.h
  39. 1
      include/grpc/impl/codegen/port_platform.h
  40. 2
      package.json
  41. 8
      package.xml
  42. 6
      setup.py
  43. 27
      src/compiler/csharp_generator.cc
  44. 7
      src/core/ext/client_config/channel_connectivity.c
  45. 3
      src/core/ext/transport/chttp2/server/insecure/server_chttp2.c
  46. 3
      src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c
  47. 8
      src/core/ext/transport/chttp2/transport/chttp2_transport.c
  48. 1812
      src/core/lib/iomgr/ev_epoll_linux.c
  49. 47
      src/core/lib/iomgr/ev_epoll_linux.h
  50. 15
      src/core/lib/iomgr/ev_posix.c
  51. 3
      src/core/lib/iomgr/ev_posix.h
  52. 121
      src/core/lib/iomgr/network_status_tracker.c
  53. 41
      src/core/lib/iomgr/network_status_tracker.h
  54. 22
      src/core/lib/iomgr/socket_utils_common_posix.c
  55. 3
      src/core/lib/iomgr/socket_utils_posix.h
  56. 8
      src/core/lib/iomgr/tcp_posix.c
  57. 3
      src/core/lib/iomgr/tcp_server.h
  58. 123
      src/core/lib/iomgr/tcp_server_posix.c
  59. 1
      src/core/lib/iomgr/tcp_server_windows.c
  60. 5
      src/core/lib/iomgr/tcp_windows.c
  61. 4
      src/core/lib/iomgr/udp_server.c
  62. 8
      src/core/lib/profiling/basic_timers.c
  63. 7
      src/core/lib/security/credentials/composite/composite_credentials.c
  64. 2
      src/core/lib/security/credentials/credentials.c
  65. 9
      src/core/lib/security/credentials/credentials.h
  66. 4
      src/core/lib/security/credentials/fake/fake_credentials.c
  67. 2
      src/core/lib/security/credentials/iam/iam_credentials.c
  68. 13
      src/core/lib/security/credentials/jwt/jwt_credentials.c
  69. 10
      src/core/lib/security/credentials/oauth2/oauth2_credentials.c
  70. 7
      src/core/lib/security/credentials/plugin/plugin_credentials.c
  71. 10
      src/core/lib/security/transport/client_auth_filter.c
  72. 16
      src/core/lib/surface/channel.c
  73. 12
      src/core/lib/surface/completion_queue.c
  74. 2
      src/core/lib/surface/version.c
  75. 4
      src/core/lib/transport/transport_op_string.c
  76. 4
      src/csharp/Grpc.Auth/project.json
  77. 13
      src/csharp/Grpc.Core/Grpc.Core.nuspec
  78. 23
      src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs
  79. 4
      src/csharp/Grpc.Core/VersionInfo.cs
  80. 2
      src/csharp/Grpc.Core/project.json
  81. 2
      src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs
  82. 15
      src/csharp/Grpc.Examples/MathGrpc.cs
  83. 2
      src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs
  84. 15
      src/csharp/Grpc.HealthCheck/HealthGrpc.cs
  85. 4
      src/csharp/Grpc.HealthCheck/project.json
  86. 6
      src/csharp/Grpc.IntegrationTesting/ClientRunners.cs
  87. 2
      src/csharp/Grpc.IntegrationTesting/GeneratedServiceBaseTest.cs
  88. 4
      src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs
  89. 4
      src/csharp/Grpc.IntegrationTesting/MetadataCredentialsTest.cs
  90. 15
      src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
  91. 30
      src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
  92. 2
      src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs
  93. 2
      src/csharp/Grpc.IntegrationTesting/StressTestClient.cs
  94. 45
      src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
  95. 2
      src/csharp/build_packages.bat
  96. 127
      src/node/ext/node_grpc.cc
  97. 43
      src/node/index.js
  98. 21
      src/node/src/common.js
  99. 4
      src/node/src/credentials.js
  100. 4
      src/node/src/server.js
  101. Some files were not shown because too many files have changed in this diff Show More

16
BUILD

@ -177,6 +177,7 @@ cc_library(
"src/core/lib/iomgr/endpoint.h",
"src/core/lib/iomgr/endpoint_pair.h",
"src/core/lib/iomgr/error.h",
"src/core/lib/iomgr/ev_epoll_linux.h",
"src/core/lib/iomgr/ev_poll_and_epoll_posix.h",
"src/core/lib/iomgr/ev_poll_posix.h",
"src/core/lib/iomgr/ev_posix.h",
@ -187,6 +188,7 @@ cc_library(
"src/core/lib/iomgr/iomgr_internal.h",
"src/core/lib/iomgr/iomgr_posix.h",
"src/core/lib/iomgr/load_file.h",
"src/core/lib/iomgr/network_status_tracker.h",
"src/core/lib/iomgr/polling_entity.h",
"src/core/lib/iomgr/pollset.h",
"src/core/lib/iomgr/pollset_set.h",
@ -327,6 +329,7 @@ cc_library(
"src/core/lib/iomgr/endpoint_pair_posix.c",
"src/core/lib/iomgr/endpoint_pair_windows.c",
"src/core/lib/iomgr/error.c",
"src/core/lib/iomgr/ev_epoll_linux.c",
"src/core/lib/iomgr/ev_poll_and_epoll_posix.c",
"src/core/lib/iomgr/ev_poll_posix.c",
"src/core/lib/iomgr/ev_posix.c",
@ -337,6 +340,7 @@ cc_library(
"src/core/lib/iomgr/iomgr_posix.c",
"src/core/lib/iomgr/iomgr_windows.c",
"src/core/lib/iomgr/load_file.c",
"src/core/lib/iomgr/network_status_tracker.c",
"src/core/lib/iomgr/polling_entity.c",
"src/core/lib/iomgr/pollset_set_windows.c",
"src/core/lib/iomgr/pollset_windows.c",
@ -560,6 +564,7 @@ cc_library(
"src/core/lib/iomgr/endpoint.h",
"src/core/lib/iomgr/endpoint_pair.h",
"src/core/lib/iomgr/error.h",
"src/core/lib/iomgr/ev_epoll_linux.h",
"src/core/lib/iomgr/ev_poll_and_epoll_posix.h",
"src/core/lib/iomgr/ev_poll_posix.h",
"src/core/lib/iomgr/ev_posix.h",
@ -570,6 +575,7 @@ cc_library(
"src/core/lib/iomgr/iomgr_internal.h",
"src/core/lib/iomgr/iomgr_posix.h",
"src/core/lib/iomgr/load_file.h",
"src/core/lib/iomgr/network_status_tracker.h",
"src/core/lib/iomgr/polling_entity.h",
"src/core/lib/iomgr/pollset.h",
"src/core/lib/iomgr/pollset_set.h",
@ -700,6 +706,7 @@ cc_library(
"src/core/lib/iomgr/endpoint_pair_posix.c",
"src/core/lib/iomgr/endpoint_pair_windows.c",
"src/core/lib/iomgr/error.c",
"src/core/lib/iomgr/ev_epoll_linux.c",
"src/core/lib/iomgr/ev_poll_and_epoll_posix.c",
"src/core/lib/iomgr/ev_poll_posix.c",
"src/core/lib/iomgr/ev_posix.c",
@ -710,6 +717,7 @@ cc_library(
"src/core/lib/iomgr/iomgr_posix.c",
"src/core/lib/iomgr/iomgr_windows.c",
"src/core/lib/iomgr/load_file.c",
"src/core/lib/iomgr/network_status_tracker.c",
"src/core/lib/iomgr/polling_entity.c",
"src/core/lib/iomgr/pollset_set_windows.c",
"src/core/lib/iomgr/pollset_windows.c",
@ -908,6 +916,7 @@ cc_library(
"src/core/lib/iomgr/endpoint.h",
"src/core/lib/iomgr/endpoint_pair.h",
"src/core/lib/iomgr/error.h",
"src/core/lib/iomgr/ev_epoll_linux.h",
"src/core/lib/iomgr/ev_poll_and_epoll_posix.h",
"src/core/lib/iomgr/ev_poll_posix.h",
"src/core/lib/iomgr/ev_posix.h",
@ -918,6 +927,7 @@ cc_library(
"src/core/lib/iomgr/iomgr_internal.h",
"src/core/lib/iomgr/iomgr_posix.h",
"src/core/lib/iomgr/load_file.h",
"src/core/lib/iomgr/network_status_tracker.h",
"src/core/lib/iomgr/polling_entity.h",
"src/core/lib/iomgr/pollset.h",
"src/core/lib/iomgr/pollset_set.h",
@ -1035,6 +1045,7 @@ cc_library(
"src/core/lib/iomgr/endpoint_pair_posix.c",
"src/core/lib/iomgr/endpoint_pair_windows.c",
"src/core/lib/iomgr/error.c",
"src/core/lib/iomgr/ev_epoll_linux.c",
"src/core/lib/iomgr/ev_poll_and_epoll_posix.c",
"src/core/lib/iomgr/ev_poll_posix.c",
"src/core/lib/iomgr/ev_posix.c",
@ -1045,6 +1056,7 @@ cc_library(
"src/core/lib/iomgr/iomgr_posix.c",
"src/core/lib/iomgr/iomgr_windows.c",
"src/core/lib/iomgr/load_file.c",
"src/core/lib/iomgr/network_status_tracker.c",
"src/core/lib/iomgr/polling_entity.c",
"src/core/lib/iomgr/pollset_set_windows.c",
"src/core/lib/iomgr/pollset_windows.c",
@ -1792,6 +1804,7 @@ objc_library(
"src/core/lib/iomgr/endpoint_pair_posix.c",
"src/core/lib/iomgr/endpoint_pair_windows.c",
"src/core/lib/iomgr/error.c",
"src/core/lib/iomgr/ev_epoll_linux.c",
"src/core/lib/iomgr/ev_poll_and_epoll_posix.c",
"src/core/lib/iomgr/ev_poll_posix.c",
"src/core/lib/iomgr/ev_posix.c",
@ -1802,6 +1815,7 @@ objc_library(
"src/core/lib/iomgr/iomgr_posix.c",
"src/core/lib/iomgr/iomgr_windows.c",
"src/core/lib/iomgr/load_file.c",
"src/core/lib/iomgr/network_status_tracker.c",
"src/core/lib/iomgr/polling_entity.c",
"src/core/lib/iomgr/pollset_set_windows.c",
"src/core/lib/iomgr/pollset_windows.c",
@ -2004,6 +2018,7 @@ objc_library(
"src/core/lib/iomgr/endpoint.h",
"src/core/lib/iomgr/endpoint_pair.h",
"src/core/lib/iomgr/error.h",
"src/core/lib/iomgr/ev_epoll_linux.h",
"src/core/lib/iomgr/ev_poll_and_epoll_posix.h",
"src/core/lib/iomgr/ev_poll_posix.h",
"src/core/lib/iomgr/ev_posix.h",
@ -2014,6 +2029,7 @@ objc_library(
"src/core/lib/iomgr/iomgr_internal.h",
"src/core/lib/iomgr/iomgr_posix.h",
"src/core/lib/iomgr/load_file.h",
"src/core/lib/iomgr/network_status_tracker.h",
"src/core/lib/iomgr/polling_entity.h",
"src/core/lib/iomgr/pollset.h",
"src/core/lib/iomgr/pollset_set.h",

@ -200,6 +200,7 @@ LD_tsan = clang
LDXX_tsan = clang++
CPPFLAGS_tsan = -O0 -fsanitize=thread -fno-omit-frame-pointer -Wno-unused-command-line-argument -DGPR_NO_DIRECT_SYSCALLS
LDFLAGS_tsan = -fsanitize=thread
DEFINES_tsan = GRPC_TSAN
DEFINES_tsan += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=5
VALID_CONFIG_stapprof = 1
@ -414,7 +415,7 @@ E = @echo
Q = @
endif
VERSION = 0.15.0-dev
VERSION = 0.16.0-dev
CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES))
CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS)
@ -904,6 +905,7 @@ dns_resolver_connectivity_test: $(BINDIR)/$(CONFIG)/dns_resolver_connectivity_te
dns_resolver_test: $(BINDIR)/$(CONFIG)/dns_resolver_test
dualstack_socket_test: $(BINDIR)/$(CONFIG)/dualstack_socket_test
endpoint_pair_test: $(BINDIR)/$(CONFIG)/endpoint_pair_test
ev_epoll_linux_test: $(BINDIR)/$(CONFIG)/ev_epoll_linux_test
fd_conservation_posix_test: $(BINDIR)/$(CONFIG)/fd_conservation_posix_test
fd_posix_test: $(BINDIR)/$(CONFIG)/fd_posix_test
fling_client: $(BINDIR)/$(CONFIG)/fling_client
@ -1248,6 +1250,7 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/dns_resolver_test \
$(BINDIR)/$(CONFIG)/dualstack_socket_test \
$(BINDIR)/$(CONFIG)/endpoint_pair_test \
$(BINDIR)/$(CONFIG)/ev_epoll_linux_test \
$(BINDIR)/$(CONFIG)/fd_conservation_posix_test \
$(BINDIR)/$(CONFIG)/fd_posix_test \
$(BINDIR)/$(CONFIG)/fling_client \
@ -1568,6 +1571,8 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/dualstack_socket_test || ( echo test dualstack_socket_test failed ; exit 1 )
$(E) "[RUN] Testing endpoint_pair_test"
$(Q) $(BINDIR)/$(CONFIG)/endpoint_pair_test || ( echo test endpoint_pair_test failed ; exit 1 )
$(E) "[RUN] Testing ev_epoll_linux_test"
$(Q) $(BINDIR)/$(CONFIG)/ev_epoll_linux_test || ( echo test ev_epoll_linux_test failed ; exit 1 )
$(E) "[RUN] Testing fd_conservation_posix_test"
$(Q) $(BINDIR)/$(CONFIG)/fd_conservation_posix_test || ( echo test fd_conservation_posix_test failed ; exit 1 )
$(E) "[RUN] Testing fd_posix_test"
@ -2564,6 +2569,7 @@ LIBGRPC_SRC = \
src/core/lib/iomgr/endpoint_pair_posix.c \
src/core/lib/iomgr/endpoint_pair_windows.c \
src/core/lib/iomgr/error.c \
src/core/lib/iomgr/ev_epoll_linux.c \
src/core/lib/iomgr/ev_poll_and_epoll_posix.c \
src/core/lib/iomgr/ev_poll_posix.c \
src/core/lib/iomgr/ev_posix.c \
@ -2574,6 +2580,7 @@ LIBGRPC_SRC = \
src/core/lib/iomgr/iomgr_posix.c \
src/core/lib/iomgr/iomgr_windows.c \
src/core/lib/iomgr/load_file.c \
src/core/lib/iomgr/network_status_tracker.c \
src/core/lib/iomgr/polling_entity.c \
src/core/lib/iomgr/pollset_set_windows.c \
src/core/lib/iomgr/pollset_windows.c \
@ -2834,6 +2841,7 @@ LIBGRPC_CRONET_SRC = \
src/core/lib/iomgr/endpoint_pair_posix.c \
src/core/lib/iomgr/endpoint_pair_windows.c \
src/core/lib/iomgr/error.c \
src/core/lib/iomgr/ev_epoll_linux.c \
src/core/lib/iomgr/ev_poll_and_epoll_posix.c \
src/core/lib/iomgr/ev_poll_posix.c \
src/core/lib/iomgr/ev_posix.c \
@ -2844,6 +2852,7 @@ LIBGRPC_CRONET_SRC = \
src/core/lib/iomgr/iomgr_posix.c \
src/core/lib/iomgr/iomgr_windows.c \
src/core/lib/iomgr/load_file.c \
src/core/lib/iomgr/network_status_tracker.c \
src/core/lib/iomgr/polling_entity.c \
src/core/lib/iomgr/pollset_set_windows.c \
src/core/lib/iomgr/pollset_windows.c \
@ -3173,6 +3182,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/lib/iomgr/endpoint_pair_posix.c \
src/core/lib/iomgr/endpoint_pair_windows.c \
src/core/lib/iomgr/error.c \
src/core/lib/iomgr/ev_epoll_linux.c \
src/core/lib/iomgr/ev_poll_and_epoll_posix.c \
src/core/lib/iomgr/ev_poll_posix.c \
src/core/lib/iomgr/ev_posix.c \
@ -3183,6 +3193,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/lib/iomgr/iomgr_posix.c \
src/core/lib/iomgr/iomgr_windows.c \
src/core/lib/iomgr/load_file.c \
src/core/lib/iomgr/network_status_tracker.c \
src/core/lib/iomgr/polling_entity.c \
src/core/lib/iomgr/pollset_set_windows.c \
src/core/lib/iomgr/pollset_windows.c \
@ -6376,6 +6387,7 @@ LIBEND2END_TESTS_SRC = \
test/core/end2end/tests/max_concurrent_streams.c \
test/core/end2end/tests/max_message_length.c \
test/core/end2end/tests/negative_deadline.c \
test/core/end2end/tests/network_status_change.c \
test/core/end2end/tests/no_op.c \
test/core/end2end/tests/payload.c \
test/core/end2end/tests/ping.c \
@ -6453,6 +6465,7 @@ LIBEND2END_NOSEC_TESTS_SRC = \
test/core/end2end/tests/max_concurrent_streams.c \
test/core/end2end/tests/max_message_length.c \
test/core/end2end/tests/negative_deadline.c \
test/core/end2end/tests/network_status_change.c \
test/core/end2end/tests/no_op.c \
test/core/end2end/tests/payload.c \
test/core/end2end/tests/ping.c \
@ -7135,6 +7148,38 @@ endif
endif
EV_EPOLL_LINUX_TEST_SRC = \
test/core/iomgr/ev_epoll_linux_test.c \
EV_EPOLL_LINUX_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(EV_EPOLL_LINUX_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/ev_epoll_linux_test: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/ev_epoll_linux_test: $(EV_EPOLL_LINUX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(EV_EPOLL_LINUX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/ev_epoll_linux_test
endif
$(OBJDIR)/$(CONFIG)/test/core/iomgr/ev_epoll_linux_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_ev_epoll_linux_test: $(EV_EPOLL_LINUX_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(EV_EPOLL_LINUX_TEST_OBJS:.o=.dep)
endif
endif
FD_CONSERVATION_POSIX_TEST_SRC = \
test/core/iomgr/fd_conservation_posix_test.c \

@ -581,6 +581,7 @@
'src/core/lib/iomgr/endpoint_pair_posix.c',
'src/core/lib/iomgr/endpoint_pair_windows.c',
'src/core/lib/iomgr/error.c',
'src/core/lib/iomgr/ev_epoll_linux.c',
'src/core/lib/iomgr/ev_poll_and_epoll_posix.c',
'src/core/lib/iomgr/ev_poll_posix.c',
'src/core/lib/iomgr/ev_posix.c',
@ -591,6 +592,7 @@
'src/core/lib/iomgr/iomgr_posix.c',
'src/core/lib/iomgr/iomgr_windows.c',
'src/core/lib/iomgr/load_file.c',
'src/core/lib/iomgr/network_status_tracker.c',
'src/core/lib/iomgr/polling_entity.c',
'src/core/lib/iomgr/pollset_set_windows.c',
'src/core/lib/iomgr/pollset_windows.c',

@ -7,7 +7,7 @@ settings:
'#3': Use "-preN" suffixes to identify pre-release versions
'#4': Per-language overrides are possible with (eg) ruby_version tag here
'#5': See the expand_version.py for all the quirks here
version: 0.15.0-dev
version: 0.16.0-dev
filegroups:
- name: census
public_headers:
@ -173,6 +173,7 @@ filegroups:
- src/core/lib/iomgr/endpoint.h
- src/core/lib/iomgr/endpoint_pair.h
- src/core/lib/iomgr/error.h
- src/core/lib/iomgr/ev_epoll_linux.h
- src/core/lib/iomgr/ev_poll_and_epoll_posix.h
- src/core/lib/iomgr/ev_poll_posix.h
- src/core/lib/iomgr/ev_posix.h
@ -183,6 +184,7 @@ filegroups:
- src/core/lib/iomgr/iomgr_internal.h
- src/core/lib/iomgr/iomgr_posix.h
- src/core/lib/iomgr/load_file.h
- src/core/lib/iomgr/network_status_tracker.h
- src/core/lib/iomgr/polling_entity.h
- src/core/lib/iomgr/pollset.h
- src/core/lib/iomgr/pollset_set.h
@ -250,6 +252,7 @@ filegroups:
- src/core/lib/iomgr/endpoint_pair_posix.c
- src/core/lib/iomgr/endpoint_pair_windows.c
- src/core/lib/iomgr/error.c
- src/core/lib/iomgr/ev_epoll_linux.c
- src/core/lib/iomgr/ev_poll_and_epoll_posix.c
- src/core/lib/iomgr/ev_poll_posix.c
- src/core/lib/iomgr/ev_posix.c
@ -260,6 +263,7 @@ filegroups:
- src/core/lib/iomgr/iomgr_posix.c
- src/core/lib/iomgr/iomgr_windows.c
- src/core/lib/iomgr/load_file.c
- src/core/lib/iomgr/network_status_tracker.c
- src/core/lib/iomgr/polling_entity.c
- src/core/lib/iomgr/pollset_set_windows.c
- src/core/lib/iomgr/pollset_windows.c
@ -1393,6 +1397,18 @@ targets:
- grpc
- gpr_test_util
- gpr
- name: ev_epoll_linux_test
build: test
language: c
src:
- test/core/iomgr/ev_epoll_linux_test.c
deps:
- grpc_test_util
- grpc
- gpr_test_util
- gpr
platforms:
- linux
- name: fd_conservation_posix_test
build: test
language: c
@ -1600,7 +1616,7 @@ targets:
- gpr_test_util
- gpr
- name: gpr_sync_test
cpu_cost: 3
cpu_cost: 10
build: test
language: c
src:
@ -1609,7 +1625,7 @@ targets:
- gpr_test_util
- gpr
- name: gpr_thd_test
cpu_cost: 1
cpu_cost: 10
build: test
language: c
src:
@ -3268,6 +3284,7 @@ configs:
CPPFLAGS: -O0 -fsanitize=thread -fno-omit-frame-pointer -Wno-unused-command-line-argument
-DGPR_NO_DIRECT_SYSCALLS
CXX: clang++
DEFINES: GRPC_TSAN
LD: clang
LDFLAGS: -fsanitize=thread
LDXX: clang++

@ -100,6 +100,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/iomgr/endpoint_pair_posix.c \
src/core/lib/iomgr/endpoint_pair_windows.c \
src/core/lib/iomgr/error.c \
src/core/lib/iomgr/ev_epoll_linux.c \
src/core/lib/iomgr/ev_poll_and_epoll_posix.c \
src/core/lib/iomgr/ev_poll_posix.c \
src/core/lib/iomgr/ev_posix.c \
@ -110,6 +111,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/iomgr/iomgr_posix.c \
src/core/lib/iomgr/iomgr_windows.c \
src/core/lib/iomgr/load_file.c \
src/core/lib/iomgr/network_status_tracker.c \
src/core/lib/iomgr/polling_entity.c \
src/core/lib/iomgr/pollset_set_windows.c \
src/core/lib/iomgr/pollset_windows.c \

@ -42,13 +42,13 @@ and RPC settings (for example, if compression would result in small or negative
gains).
When a message from a client compressed with an unsupported algorithm is
processed by a server, it WILL result in an INVALID\_ARGUMENT error on the
processed by a server, it WILL result in an `UNIMPLEMENTED` error status on the
server. The server will then include in its response a `grpc-accept-encoding`
header specifying the algorithms it does accept. If an INTERNAL error is
returned from the server despite having used one of the algorithms from the
`grpc-accept-encoding` header, the cause MUST NOT be related to compression.
Data sent from a server compressed with an algorithm not supported by the client
WILL result in an INTERNAL error on the client side.
header specifying the algorithms it does accept. If an `UNIMPLEMENTED` error
status is returned from the server despite having used one of the algorithms
from the `grpc-accept-encoding` header, the cause MUST NOT be related to
compression. Data sent from a server compressed with an algorithm not supported
by the client WILL result in an `INTERNAL` error status on the client side.
Note that a peer MAY choose to not disclose all the encodings it supports.
However, if it receives a message compressed in an undisclosed but supported
@ -99,13 +99,20 @@ compressed.
channel compression configuration MUST be used.
1. When a compression method (including no compression) is specified for an
outgoing message, the message MUST be compressed accordingly.
1. A message compressed in a way not supported by its endpoint MUST fail with
INVALID\_ARGUMENT status, its associated description indicating the unsupported
condition as well as the supported ones. The returned `grpc-accept-encoding`
header MUST NOT contain the compression method (encoding) used.
1. A message compressed by a client in a way not supported by its server MUST
fail with status `UNIMPLEMENTED`, its associated description indicating the
unsupported condition as well as the supported ones. The returned
`grpc-accept-encoding` header MUST NOT contain the compression method
(encoding) used.
1. A message compressed by a server in a way not supported by its client MUST
fail with status `INTERNAL`, its associated description indicating the
unsupported condition as well as the supported ones. The returned
`grpc-accept-encoding` header MUST NOT contain the compression method
(encoding) used.
1. An ill-constructed message with its [Compressed-Flag
bit](PROTOCOL-HTTP2.md#compressed-flag)
set but lacking a
"[grpc-encoding](PROTOCOL-HTTP2.md#message-encoding)"
entry different from _identity_ in its metadata MUST fail with INTERNAL status,
its associated description indicating the invalid Compressed-Flag condition.
entry different from _identity_ in its metadata MUST fail with `INTERNAL`
status, its associated description indicating the invalid Compressed-Flag
condition.

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Grpc.Tools" version="0.14.0" />
<package id="Grpc.Tools" version="0.15.0" />
</packages>

@ -10,7 +10,7 @@
<RootNamespace>Greeter</RootNamespace>
<AssemblyName>Greeter</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<NuGetPackageImportStamp>745ac60f</NuGetPackageImportStamp>
<NuGetPackageImportStamp>2669b4f2</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -33,11 +33,11 @@
<ItemGroup>
<Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Google.Protobuf.3.0.0-beta2\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
<HintPath>..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
</Reference>
<Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Grpc.Core.0.14.0\lib\net45\Grpc.Core.dll</HintPath>
<HintPath>..\packages\Grpc.Core.0.15.0\lib\net45\Grpc.Core.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
@ -61,11 +61,11 @@
<None Include="packages.config" />
</ItemGroup>
<ItemGroup />
<Import Project="..\packages\Grpc.Core.0.14.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.0.14.0\build\net45\Grpc.Core.targets')" />
<Import Project="..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Grpc.Core.0.14.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.0.14.0\build\net45\Grpc.Core.targets'))" />
<Error Condition="!Exists('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets'))" />
</Target>
</Project>

@ -31,9 +31,9 @@ namespace Helloworld {
"cm90bzM="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
new pbr::GeneratedCodeInfo(typeof(global::Helloworld.HelloRequest), global::Helloworld.HelloRequest.Parser, new[]{ "Name" }, null, null, null),
new pbr::GeneratedCodeInfo(typeof(global::Helloworld.HelloReply), global::Helloworld.HelloReply.Parser, new[]{ "Message" }, null, null, null)
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
new pbr::GeneratedClrTypeInfo(typeof(global::Helloworld.HelloRequest), global::Helloworld.HelloRequest.Parser, new[]{ "Name" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Helloworld.HelloReply), global::Helloworld.HelloReply.Parser, new[]{ "Message" }, null, null, null)
}));
}
#endregion
@ -76,7 +76,7 @@ namespace Helloworld {
public string Name {
get { return name_; }
set {
name_ = pb::Preconditions.CheckNotNull(value, "value");
name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@ -182,7 +182,7 @@ namespace Helloworld {
public string Message {
get { return message_; }
set {
message_ = pb::Preconditions.CheckNotNull(value, "value");
message_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}

@ -61,38 +61,6 @@ namespace Helloworld {
get { return global::Helloworld.HelloworldReflection.Descriptor.Services[0]; }
}
/// <summary>Client for Greeter</summary>
[System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
public interface IGreeterClient
{
/// <summary>
/// Sends a greeting
/// </summary>
global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// Sends a greeting
/// </summary>
global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, CallOptions options);
/// <summary>
/// Sends a greeting
/// </summary>
AsyncUnaryCall<global::Helloworld.HelloReply> SayHelloAsync(global::Helloworld.HelloRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// Sends a greeting
/// </summary>
AsyncUnaryCall<global::Helloworld.HelloReply> SayHelloAsync(global::Helloworld.HelloRequest request, CallOptions options);
}
/// <summary>Interface of server-side implementations of Greeter</summary>
[System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")]
public interface IGreeter
{
/// <summary>
/// Sends a greeting
/// </summary>
global::System.Threading.Tasks.Task<global::Helloworld.HelloReply> SayHello(global::Helloworld.HelloRequest request, ServerCallContext context);
}
/// <summary>Base class for server-side implementations of Greeter</summary>
public abstract class GreeterBase
{
@ -107,21 +75,24 @@ namespace Helloworld {
}
/// <summary>Client for Greeter</summary>
#pragma warning disable 0618
public class GreeterClient : ClientBase<GreeterClient>, IGreeterClient
#pragma warning restore 0618
public class GreeterClient : ClientBase<GreeterClient>
{
/// <summary>Creates a new client for Greeter</summary>
/// <param name="channel">The channel to use to make remote calls.</param>
public GreeterClient(Channel channel) : base(channel)
{
}
/// <summary>Creates a new client for Greeter that uses a custom <c>CallInvoker</c>.</summary>
/// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
public GreeterClient(CallInvoker callInvoker) : base(callInvoker)
{
}
///<summary>Protected parameterless constructor to allow creation of test doubles.</summary>
/// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
protected GreeterClient() : base()
{
}
///<summary>Protected constructor to allow creation of configured clients.</summary>
/// <summary>Protected constructor to allow creation of configured clients.</summary>
/// <param name="configuration">The client configuration.</param>
protected GreeterClient(ClientBaseConfiguration configuration) : base(configuration)
{
}
@ -160,27 +131,10 @@ namespace Helloworld {
}
}
/// <summary>Creates a new client for Greeter</summary>
public static GreeterClient NewClient(Channel channel)
{
return new GreeterClient(channel);
}
/// <summary>Creates service definition that can be registered with a server</summary>
#pragma warning disable 0618
public static ServerServiceDefinition BindService(IGreeter serviceImpl)
#pragma warning restore 0618
{
return ServerServiceDefinition.CreateBuilder(__ServiceName)
.AddMethod(__Method_SayHello, serviceImpl.SayHello).Build();
}
/// <summary>Creates service definition that can be registered with a server</summary>
#pragma warning disable 0618
public static ServerServiceDefinition BindService(GreeterBase serviceImpl)
#pragma warning restore 0618
{
return ServerServiceDefinition.CreateBuilder(__ServiceName)
return ServerServiceDefinition.CreateBuilder()
.AddMethod(__Method_SayHello, serviceImpl.SayHello).Build();
}

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Google.Protobuf" version="3.0.0-beta2" targetFramework="net45" />
<package id="Grpc" version="0.14.0" targetFramework="net45" />
<package id="Grpc.Core" version="0.14.0" targetFramework="net45" />
<package id="Google.Protobuf" version="3.0.0-beta3" targetFramework="net45" />
<package id="Grpc" version="0.15.0" targetFramework="net45" />
<package id="Grpc.Core" version="0.15.0" targetFramework="net45" />
<package id="Ix-Async" version="1.2.5" targetFramework="net45" />
</packages>

@ -10,7 +10,7 @@
<RootNamespace>GreeterClient</RootNamespace>
<AssemblyName>GreeterClient</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<NuGetPackageImportStamp>63b59176</NuGetPackageImportStamp>
<NuGetPackageImportStamp>5e942a7d</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -33,11 +33,11 @@
<ItemGroup>
<Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Google.Protobuf.3.0.0-beta2\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
<HintPath>..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
</Reference>
<Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Grpc.Core.0.14.0\lib\net45\Grpc.Core.dll</HintPath>
<HintPath>..\packages\Grpc.Core.0.15.0\lib\net45\Grpc.Core.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
@ -59,11 +59,11 @@
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="..\packages\Grpc.Core.0.14.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.0.14.0\build\net45\Grpc.Core.targets')" />
<Import Project="..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Grpc.Core.0.14.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.0.14.0\build\net45\Grpc.Core.targets'))" />
<Error Condition="!Exists('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets'))" />
</Target>
</Project>

@ -39,7 +39,7 @@ namespace GreeterClient
{
Channel channel = new Channel("127.0.0.1:50051", ChannelCredentials.Insecure);
var client = Greeter.NewClient(channel);
var client = new Greeter.GreeterClient(channel);
String user = "you";
var reply = client.SayHello(new HelloRequest { Name = user });

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Google.Protobuf" version="3.0.0-beta2" targetFramework="net45" />
<package id="Grpc" version="0.14.0" targetFramework="net45" />
<package id="Grpc.Core" version="0.14.0" targetFramework="net45" />
<package id="Google.Protobuf" version="3.0.0-beta3" targetFramework="net45" />
<package id="Grpc" version="0.15.0" targetFramework="net45" />
<package id="Grpc.Core" version="0.15.0" targetFramework="net45" />
<package id="Ix-Async" version="1.2.5" targetFramework="net45" />
</packages>

@ -10,7 +10,7 @@
<RootNamespace>GreeterServer</RootNamespace>
<AssemblyName>GreeterServer</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<NuGetPackageImportStamp>25ac2e80</NuGetPackageImportStamp>
<NuGetPackageImportStamp>9c7b2963</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -33,11 +33,11 @@
<ItemGroup>
<Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Google.Protobuf.3.0.0-beta2\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
<HintPath>..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
</Reference>
<Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Grpc.Core.0.14.0\lib\net45\Grpc.Core.dll</HintPath>
<HintPath>..\packages\Grpc.Core.0.15.0\lib\net45\Grpc.Core.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
@ -59,11 +59,11 @@
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="..\packages\Grpc.Core.0.14.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.0.14.0\build\net45\Grpc.Core.targets')" />
<Import Project="..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Grpc.Core.0.14.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.0.14.0\build\net45\Grpc.Core.targets'))" />
<Error Condition="!Exists('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets'))" />
</Target>
</Project>

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Google.Protobuf" version="3.0.0-beta2" targetFramework="net45" />
<package id="Grpc" version="0.14.0" targetFramework="net45" />
<package id="Grpc.Core" version="0.14.0" targetFramework="net45" />
<package id="Google.Protobuf" version="3.0.0-beta3" targetFramework="net45" />
<package id="Grpc" version="0.15.0" targetFramework="net45" />
<package id="Grpc.Core" version="0.15.0" targetFramework="net45" />
<package id="Ix-Async" version="1.2.5" targetFramework="net45" />
</packages>

@ -34,7 +34,7 @@ setlocal
@rem enter this directory
cd /d %~dp0
set TOOLS_PATH=packages\Grpc.Tools.0.14.0\tools\windows_x86
set TOOLS_PATH=packages\Grpc.Tools.0.15.0\tools\windows_x86
%TOOLS_PATH%\protoc.exe -I../../protos --csharp_out Greeter ../../protos/helloworld.proto --grpc_out Greeter --plugin=protoc-gen-grpc=%TOOLS_PATH%\grpc_csharp_plugin.exe

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Grpc.Tools" version="0.14.0" />
<package id="Grpc.Tools" version="0.15.0" />
</packages>

@ -41,12 +41,12 @@ namespace Routeguide {
"ZUIPUm91dGVHdWlkZVByb3RvUAGiAgNSVEdiBnByb3RvMw=="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
new pbr::GeneratedCodeInfo(typeof(global::Routeguide.Point), global::Routeguide.Point.Parser, new[]{ "Latitude", "Longitude" }, null, null, null),
new pbr::GeneratedCodeInfo(typeof(global::Routeguide.Rectangle), global::Routeguide.Rectangle.Parser, new[]{ "Lo", "Hi" }, null, null, null),
new pbr::GeneratedCodeInfo(typeof(global::Routeguide.Feature), global::Routeguide.Feature.Parser, new[]{ "Name", "Location" }, null, null, null),
new pbr::GeneratedCodeInfo(typeof(global::Routeguide.RouteNote), global::Routeguide.RouteNote.Parser, new[]{ "Location", "Message" }, null, null, null),
new pbr::GeneratedCodeInfo(typeof(global::Routeguide.RouteSummary), global::Routeguide.RouteSummary.Parser, new[]{ "PointCount", "FeatureCount", "Distance", "ElapsedTime" }, null, null, null)
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
new pbr::GeneratedClrTypeInfo(typeof(global::Routeguide.Point), global::Routeguide.Point.Parser, new[]{ "Latitude", "Longitude" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Routeguide.Rectangle), global::Routeguide.Rectangle.Parser, new[]{ "Lo", "Hi" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Routeguide.Feature), global::Routeguide.Feature.Parser, new[]{ "Name", "Location" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Routeguide.RouteNote), global::Routeguide.RouteNote.Parser, new[]{ "Location", "Message" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Routeguide.RouteSummary), global::Routeguide.RouteSummary.Parser, new[]{ "PointCount", "FeatureCount", "Distance", "ElapsedTime" }, null, null, null)
}));
}
#endregion
@ -383,7 +383,7 @@ namespace Routeguide {
public string Name {
get { return name_; }
set {
name_ = pb::Preconditions.CheckNotNull(value, "value");
name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@ -541,7 +541,7 @@ namespace Routeguide {
public string Message {
get { return message_; }
set {
message_ = pb::Preconditions.CheckNotNull(value, "value");
message_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}

@ -11,7 +11,7 @@
<AssemblyName>RouteGuide</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<NuGetPackageImportStamp>0a9fcb7a</NuGetPackageImportStamp>
<NuGetPackageImportStamp>de2137f9</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -33,11 +33,11 @@
<ItemGroup>
<Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Google.Protobuf.3.0.0-beta2\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
<HintPath>..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
</Reference>
<Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Grpc.Core.0.14.0\lib\net45\Grpc.Core.dll</HintPath>
<HintPath>..\packages\Grpc.Core.0.15.0\lib\net45\Grpc.Core.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@ -74,12 +74,12 @@
</None>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Grpc.Core.0.14.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.0.14.0\build\net45\Grpc.Core.targets')" />
<Import Project="..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Grpc.Core.0.14.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.0.14.0\build\net45\Grpc.Core.targets'))" />
<Error Condition="!Exists('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

@ -85,132 +85,6 @@ namespace Routeguide {
get { return global::Routeguide.RouteGuideReflection.Descriptor.Services[0]; }
}
/// <summary>Client for RouteGuide</summary>
[System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
public interface IRouteGuideClient
{
/// <summary>
/// A simple RPC.
///
/// Obtains the feature at a given position.
///
/// A feature with an empty name is returned if there's no feature at the given
/// position.
/// </summary>
global::Routeguide.Feature GetFeature(global::Routeguide.Point request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// A simple RPC.
///
/// Obtains the feature at a given position.
///
/// A feature with an empty name is returned if there's no feature at the given
/// position.
/// </summary>
global::Routeguide.Feature GetFeature(global::Routeguide.Point request, CallOptions options);
/// <summary>
/// A simple RPC.
///
/// Obtains the feature at a given position.
///
/// A feature with an empty name is returned if there's no feature at the given
/// position.
/// </summary>
AsyncUnaryCall<global::Routeguide.Feature> GetFeatureAsync(global::Routeguide.Point request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// A simple RPC.
///
/// Obtains the feature at a given position.
///
/// A feature with an empty name is returned if there's no feature at the given
/// position.
/// </summary>
AsyncUnaryCall<global::Routeguide.Feature> GetFeatureAsync(global::Routeguide.Point request, CallOptions options);
/// <summary>
/// A server-to-client streaming RPC.
///
/// Obtains the Features available within the given Rectangle. Results are
/// streamed rather than returned at once (e.g. in a response message with a
/// repeated field), as the rectangle may cover a large area and contain a
/// huge number of features.
/// </summary>
AsyncServerStreamingCall<global::Routeguide.Feature> ListFeatures(global::Routeguide.Rectangle request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// A server-to-client streaming RPC.
///
/// Obtains the Features available within the given Rectangle. Results are
/// streamed rather than returned at once (e.g. in a response message with a
/// repeated field), as the rectangle may cover a large area and contain a
/// huge number of features.
/// </summary>
AsyncServerStreamingCall<global::Routeguide.Feature> ListFeatures(global::Routeguide.Rectangle request, CallOptions options);
/// <summary>
/// A client-to-server streaming RPC.
///
/// Accepts a stream of Points on a route being traversed, returning a
/// RouteSummary when traversal is completed.
/// </summary>
AsyncClientStreamingCall<global::Routeguide.Point, global::Routeguide.RouteSummary> RecordRoute(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// A client-to-server streaming RPC.
///
/// Accepts a stream of Points on a route being traversed, returning a
/// RouteSummary when traversal is completed.
/// </summary>
AsyncClientStreamingCall<global::Routeguide.Point, global::Routeguide.RouteSummary> RecordRoute(CallOptions options);
/// <summary>
/// A Bidirectional streaming RPC.
///
/// Accepts a stream of RouteNotes sent while a route is being traversed,
/// while receiving other RouteNotes (e.g. from other users).
/// </summary>
AsyncDuplexStreamingCall<global::Routeguide.RouteNote, global::Routeguide.RouteNote> RouteChat(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// A Bidirectional streaming RPC.
///
/// Accepts a stream of RouteNotes sent while a route is being traversed,
/// while receiving other RouteNotes (e.g. from other users).
/// </summary>
AsyncDuplexStreamingCall<global::Routeguide.RouteNote, global::Routeguide.RouteNote> RouteChat(CallOptions options);
}
/// <summary>Interface of server-side implementations of RouteGuide</summary>
[System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")]
public interface IRouteGuide
{
/// <summary>
/// A simple RPC.
///
/// Obtains the feature at a given position.
///
/// A feature with an empty name is returned if there's no feature at the given
/// position.
/// </summary>
global::System.Threading.Tasks.Task<global::Routeguide.Feature> GetFeature(global::Routeguide.Point request, ServerCallContext context);
/// <summary>
/// A server-to-client streaming RPC.
///
/// Obtains the Features available within the given Rectangle. Results are
/// streamed rather than returned at once (e.g. in a response message with a
/// repeated field), as the rectangle may cover a large area and contain a
/// huge number of features.
/// </summary>
global::System.Threading.Tasks.Task ListFeatures(global::Routeguide.Rectangle request, IServerStreamWriter<global::Routeguide.Feature> responseStream, ServerCallContext context);
/// <summary>
/// A client-to-server streaming RPC.
///
/// Accepts a stream of Points on a route being traversed, returning a
/// RouteSummary when traversal is completed.
/// </summary>
global::System.Threading.Tasks.Task<global::Routeguide.RouteSummary> RecordRoute(IAsyncStreamReader<global::Routeguide.Point> requestStream, ServerCallContext context);
/// <summary>
/// A Bidirectional streaming RPC.
///
/// Accepts a stream of RouteNotes sent while a route is being traversed,
/// while receiving other RouteNotes (e.g. from other users).
/// </summary>
global::System.Threading.Tasks.Task RouteChat(IAsyncStreamReader<global::Routeguide.RouteNote> requestStream, IServerStreamWriter<global::Routeguide.RouteNote> responseStream, ServerCallContext context);
}
/// <summary>Base class for server-side implementations of RouteGuide</summary>
public abstract class RouteGuideBase
{
@ -265,21 +139,24 @@ namespace Routeguide {
}
/// <summary>Client for RouteGuide</summary>
#pragma warning disable 0618
public class RouteGuideClient : ClientBase<RouteGuideClient>, IRouteGuideClient
#pragma warning restore 0618
public class RouteGuideClient : ClientBase<RouteGuideClient>
{
/// <summary>Creates a new client for RouteGuide</summary>
/// <param name="channel">The channel to use to make remote calls.</param>
public RouteGuideClient(Channel channel) : base(channel)
{
}
/// <summary>Creates a new client for RouteGuide that uses a custom <c>CallInvoker</c>.</summary>
/// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
public RouteGuideClient(CallInvoker callInvoker) : base(callInvoker)
{
}
///<summary>Protected parameterless constructor to allow creation of test doubles.</summary>
/// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
protected RouteGuideClient() : base()
{
}
///<summary>Protected constructor to allow creation of configured clients.</summary>
/// <summary>Protected constructor to allow creation of configured clients.</summary>
/// <param name="configuration">The client configuration.</param>
protected RouteGuideClient(ClientBaseConfiguration configuration) : base(configuration)
{
}
@ -402,30 +279,10 @@ namespace Routeguide {
}
}
/// <summary>Creates a new client for RouteGuide</summary>
public static RouteGuideClient NewClient(Channel channel)
{
return new RouteGuideClient(channel);
}
/// <summary>Creates service definition that can be registered with a server</summary>
#pragma warning disable 0618
public static ServerServiceDefinition BindService(IRouteGuide serviceImpl)
#pragma warning restore 0618
{
return ServerServiceDefinition.CreateBuilder(__ServiceName)
.AddMethod(__Method_GetFeature, serviceImpl.GetFeature)
.AddMethod(__Method_ListFeatures, serviceImpl.ListFeatures)
.AddMethod(__Method_RecordRoute, serviceImpl.RecordRoute)
.AddMethod(__Method_RouteChat, serviceImpl.RouteChat).Build();
}
/// <summary>Creates service definition that can be registered with a server</summary>
#pragma warning disable 0618
public static ServerServiceDefinition BindService(RouteGuideBase serviceImpl)
#pragma warning restore 0618
{
return ServerServiceDefinition.CreateBuilder(__ServiceName)
return ServerServiceDefinition.CreateBuilder()
.AddMethod(__Method_GetFeature, serviceImpl.GetFeature)
.AddMethod(__Method_ListFeatures, serviceImpl.ListFeatures)
.AddMethod(__Method_RecordRoute, serviceImpl.RecordRoute)

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Google.Protobuf" version="3.0.0-beta2" targetFramework="net45" />
<package id="Grpc" version="0.14.0" targetFramework="net45" />
<package id="Grpc.Core" version="0.14.0" targetFramework="net45" />
<package id="Google.Protobuf" version="3.0.0-beta3" targetFramework="net45" />
<package id="Grpc" version="0.15.0" targetFramework="net45" />
<package id="Grpc.Core" version="0.15.0" targetFramework="net45" />
<package id="Ix-Async" version="1.2.5" targetFramework="net45" />
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
</packages>

@ -231,7 +231,7 @@ namespace Routeguide
static void Main(string[] args)
{
var channel = new Channel("127.0.0.1:50052", ChannelCredentials.Insecure);
var client = new RouteGuideClient(RouteGuide.NewClient(channel));
var client = new RouteGuideClient(new RouteGuide.RouteGuideClient(channel));
// Looking for a valid feature
client.GetFeature(409146138, -746188906);

@ -11,7 +11,7 @@
<AssemblyName>RouteGuideClient</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<NuGetPackageImportStamp>8ef088f0</NuGetPackageImportStamp>
<NuGetPackageImportStamp>b880049a</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@ -35,11 +35,11 @@
<ItemGroup>
<Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Google.Protobuf.3.0.0-beta2\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
<HintPath>..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
</Reference>
<Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Grpc.Core.0.14.0\lib\net45\Grpc.Core.dll</HintPath>
<HintPath>..\packages\Grpc.Core.0.15.0\lib\net45\Grpc.Core.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@ -71,12 +71,12 @@
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Grpc.Core.0.14.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.0.14.0\build\net45\Grpc.Core.targets')" />
<Import Project="..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Grpc.Core.0.14.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.0.14.0\build\net45\Grpc.Core.targets'))" />
<Error Condition="!Exists('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Google.Protobuf" version="3.0.0-beta2" targetFramework="net45" />
<package id="Grpc" version="0.14.0" targetFramework="net45" />
<package id="Grpc.Core" version="0.14.0" targetFramework="net45" />
<package id="Google.Protobuf" version="3.0.0-beta3" targetFramework="net45" />
<package id="Grpc" version="0.15.0" targetFramework="net45" />
<package id="Grpc.Core" version="0.15.0" targetFramework="net45" />
<package id="Ix-Async" version="1.2.5" targetFramework="net45" />
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
</packages>

@ -11,7 +11,7 @@
<AssemblyName>RouteGuideServer</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<NuGetPackageImportStamp>d5246467</NuGetPackageImportStamp>
<NuGetPackageImportStamp>946ecc79</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@ -35,11 +35,11 @@
<ItemGroup>
<Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Google.Protobuf.3.0.0-beta2\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
<HintPath>..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
</Reference>
<Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Grpc.Core.0.14.0\lib\net45\Grpc.Core.dll</HintPath>
<HintPath>..\packages\Grpc.Core.0.15.0\lib\net45\Grpc.Core.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@ -72,12 +72,12 @@
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Grpc.Core.0.14.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.0.14.0\build\net45\Grpc.Core.targets')" />
<Import Project="..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Grpc.Core.0.14.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.0.14.0\build\net45\Grpc.Core.targets'))" />
<Error Condition="!Exists('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Google.Protobuf" version="3.0.0-beta2" targetFramework="net45" />
<package id="Grpc" version="0.14.0" targetFramework="net45" />
<package id="Grpc.Core" version="0.14.0" targetFramework="net45" />
<package id="Google.Protobuf" version="3.0.0-beta3" targetFramework="net45" />
<package id="Grpc" version="0.15.0" targetFramework="net45" />
<package id="Grpc.Core" version="0.15.0" targetFramework="net45" />
<package id="Ix-Async" version="1.2.5" targetFramework="net45" />
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
</packages>

@ -34,7 +34,7 @@ setlocal
@rem enter this directory
cd /d %~dp0
set TOOLS_PATH=packages\Grpc.Tools.0.14.0\tools\windows_x86
set TOOLS_PATH=packages\Grpc.Tools.0.15.0\tools\windows_x86
%TOOLS_PATH%\protoc.exe -I../../protos --csharp_out RouteGuide ../../protos/route_guide.proto --grpc_out RouteGuide --plugin=protoc-gen-grpc=%TOOLS_PATH%\grpc_csharp_plugin.exe

@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="7702" systemVersion="14D131" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="49e-Tb-3d3">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10116" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="49e-Tb-3d3">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7701"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
</dependencies>
<scenes>
<!--Get Feature-->
@ -16,33 +17,35 @@
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" text="Get Feature Demo" textAlignment="center" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="KQZ-1w-vlD">
<rect key="frame" x="150" y="279" width="299" height="42"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<fontDescription key="fontDescription" name="Helvetica" family="Helvetica" pointSize="36"/>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" misplaced="YES" text="Execution log:" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="au7-AW-5ov">
<rect key="frame" x="16" y="0.0" width="257" height="61"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="See ViewControllers.m and this app's log in XCode" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="A5M-7J-77L">
<rect key="frame" x="136" y="329" width="329" height="17"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="2ga-Gd-X9q">
<rect key="frame" x="20" y="82" width="560" height="437"/>
<accessibility key="accessibilityConfiguration">
<accessibilityTraits key="traits" link="YES"/>
</accessibility>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="centerX" secondItem="KQZ-1w-vlD" secondAttribute="centerX" id="6BV-lF-sBN"/>
<constraint firstItem="A5M-7J-77L" firstAttribute="top" secondItem="KQZ-1w-vlD" secondAttribute="bottom" constant="8" symbolic="YES" id="cfb-er-3JN"/>
<constraint firstItem="A5M-7J-77L" firstAttribute="centerX" secondItem="KQZ-1w-vlD" secondAttribute="centerX" id="e1l-AV-tCB"/>
<constraint firstAttribute="centerY" secondItem="KQZ-1w-vlD" secondAttribute="centerY" id="exm-UA-ej4"/>
<constraint firstItem="au7-AW-5ov" firstAttribute="centerX" secondItem="tsR-hK-woN" secondAttribute="centerX" constant="20" id="JAX-zf-Z1I"/>
</constraints>
</view>
<tabBarItem key="tabBarItem" title="Get Feature" image="first" id="acW-dT-cKf"/>
<connections>
<outlet property="outputLabel" destination="2ga-Gd-X9q" id="yXF-xa-kbD"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="W5J-7L-Pyd" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="718" y="-660"/>
<point key="canvasLocation" x="733" y="-653"/>
</scene>
<!--List Features-->
<scene sceneID="wg7-f3-ORb">
@ -56,29 +59,35 @@
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" text="List Features Demo" textAlignment="center" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="zEq-FU-wV5">
<rect key="frame" x="143" y="279" width="315" height="42"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<fontDescription key="fontDescription" name="Helvetica" family="Helvetica" pointSize="36"/>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="8mE-gq-NQc">
<rect key="frame" x="20" y="114" width="560" height="437"/>
<accessibility key="accessibilityConfiguration">
<accessibilityTraits key="traits" link="YES"/>
</accessibility>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="See ViewControllers.m and this app's log in XCode" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="NDk-cv-Gan">
<rect key="frame" x="136" y="329" width="329" height="17"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" misplaced="YES" text="Execution log:" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="DbB-M0-xs2">
<rect key="frame" x="50" y="12" width="257" height="61"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<accessibility key="accessibilityConfiguration">
<accessibilityTraits key="traits" staticText="YES"/>
</accessibility>
<constraints>
<constraint firstItem="NDk-cv-Gan" firstAttribute="top" secondItem="zEq-FU-wV5" secondAttribute="bottom" constant="8" symbolic="YES" id="Day-4N-Vmt"/>
<constraint firstItem="NDk-cv-Gan" firstAttribute="centerX" secondItem="zEq-FU-wV5" secondAttribute="centerX" id="JgO-Fn-dHn"/>
<constraint firstAttribute="centerX" secondItem="zEq-FU-wV5" secondAttribute="centerX" id="qqM-NS-xev"/>
<constraint firstAttribute="centerY" secondItem="zEq-FU-wV5" secondAttribute="centerY" id="qzY-Ky-pLD"/>
<constraint firstItem="DbB-M0-xs2" firstAttribute="centerX" secondItem="QS5-Rx-YEW" secondAttribute="centerX" constant="20" id="UDo-WG-7i3"/>
<constraint firstItem="DbB-M0-xs2" firstAttribute="centerX" secondItem="QS5-Rx-YEW" secondAttribute="centerX" constant="20" id="W7v-LC-HjP"/>
</constraints>
</view>
<tabBarItem key="tabBarItem" title="List Features" image="second" id="cPa-gy-q4n"/>
<connections>
<outlet property="outputLabel" destination="8mE-gq-NQc" id="6rw-Kd-21X"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="4Nw-L8-lE0" sceneMemberID="firstResponder"/>
</objects>
@ -117,29 +126,32 @@
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" text="Record Route Demo" textAlignment="center" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="Nqv-Vr-o8P">
<rect key="frame" x="136" y="279" width="329" height="42"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<fontDescription key="fontDescription" name="Helvetica" family="Helvetica" pointSize="36"/>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" misplaced="YES" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9wL-iS-tp8">
<rect key="frame" x="20" y="114" width="560" height="437"/>
<accessibility key="accessibilityConfiguration">
<accessibilityTraits key="traits" link="YES"/>
</accessibility>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="See ViewControllers.m and this app's log in XCode" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="xjS-0N-tLe">
<rect key="frame" x="136" y="329" width="329" height="17"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" misplaced="YES" text="Execution log:" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5qv-tY-qxl">
<rect key="frame" x="30" y="10" width="257" height="61"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="centerX" secondItem="Nqv-Vr-o8P" secondAttribute="centerX" id="1wf-uc-57y"/>
<constraint firstItem="xjS-0N-tLe" firstAttribute="centerX" secondItem="Nqv-Vr-o8P" secondAttribute="centerX" id="Gnh-rN-EQ3"/>
<constraint firstItem="xjS-0N-tLe" firstAttribute="top" secondItem="Nqv-Vr-o8P" secondAttribute="bottom" constant="8" symbolic="YES" id="Xhj-u3-th9"/>
<constraint firstAttribute="centerY" secondItem="Nqv-Vr-o8P" secondAttribute="centerY" id="xqU-v8-Bb3"/>
<constraint firstItem="9wL-iS-tp8" firstAttribute="centerX" secondItem="Wvj-mg-YnO" secondAttribute="centerX" constant="20" id="7TX-Jm-662"/>
<constraint firstItem="5qv-tY-qxl" firstAttribute="centerX" secondItem="Wvj-mg-YnO" secondAttribute="centerX" id="mRS-9u-c2a"/>
</constraints>
</view>
<tabBarItem key="tabBarItem" title="Record Route" image="first" id="PLK-Jm-UyM"/>
<connections>
<outlet property="outputLabel" destination="9wL-iS-tp8" id="xhd-zm-66g"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="9RW-dt-a4q" sceneMemberID="firstResponder"/>
</objects>
@ -157,29 +169,31 @@
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" text="Route Chat Demo" textAlignment="center" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="zUL-Bo-wJt">
<rect key="frame" x="156" y="279" width="289" height="42"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<fontDescription key="fontDescription" name="Helvetica" family="Helvetica" pointSize="36"/>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" misplaced="YES" text="Execution log:" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="BxD-G9-xhU">
<rect key="frame" x="20" y="10" width="257" height="61"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="See ViewControllers.m and this app's log in XCode" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="CgS-1q-Od9">
<rect key="frame" x="136" y="329" width="329" height="17"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="131-U2-Ogk">
<rect key="frame" x="20" y="114" width="560" height="437"/>
<accessibility key="accessibilityConfiguration">
<accessibilityTraits key="traits" link="YES"/>
</accessibility>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="centerY" secondItem="zUL-Bo-wJt" secondAttribute="centerY" id="5hM-q1-ZjM"/>
<constraint firstItem="CgS-1q-Od9" firstAttribute="top" secondItem="zUL-Bo-wJt" secondAttribute="bottom" constant="8" symbolic="YES" id="AqI-Ra-a5O"/>
<constraint firstItem="CgS-1q-Od9" firstAttribute="centerX" secondItem="zUL-Bo-wJt" secondAttribute="centerX" id="K8f-KI-bc6"/>
<constraint firstAttribute="centerX" secondItem="zUL-Bo-wJt" secondAttribute="centerX" id="n8b-x8-Yze"/>
<constraint firstItem="BxD-G9-xhU" firstAttribute="centerX" secondItem="c9d-af-OMP" secondAttribute="centerX" id="wSw-7t-wxX"/>
</constraints>
</view>
<tabBarItem key="tabBarItem" title="Route Chat" image="second" id="p2G-IC-yAR"/>
<connections>
<outlet property="outputLabel" destination="131-U2-Ogk" id="fNw-M5-x1D"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="yUz-se-Cfi" sceneMemberID="firstResponder"/>
</objects>

@ -80,20 +80,30 @@ static NSString * const kHostAddress = @"localhost:50051";
* Run the getFeature demo. Calls getFeature with a point known to have a feature and a point known
* not to have a feature.
*/
@interface GetFeatureViewController : UIViewController {
RTGRouteGuide *service;
}
@interface GetFeatureViewController : UIViewController
@property (weak, nonatomic) IBOutlet UILabel *outputLabel;
@end
@implementation GetFeatureViewController
@implementation GetFeatureViewController {
RTGRouteGuide *_service;
}
- (void)execRequest {
void (^handler)(RTGFeature *response, NSError *error) = ^(RTGFeature *response, NSError *error) {
// TODO(makdharma): Remove boilerplate by consolidating into one log function.
if (response.name.length) {
NSString *str =[NSString stringWithFormat:@"%@\nFound feature called %@ at %@.", self.outputLabel.text, response.location, response.name];
self.outputLabel.text = str;
NSLog(@"Found feature called %@ at %@.", response.name, response.location);
} else if (response) {
NSString *str =[NSString stringWithFormat:@"%@\nFound no features at %@", self.outputLabel.text,response.location];
self.outputLabel.text = str;
NSLog(@"Found no features at %@", response.location);
} else {
NSString *str =[NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error];
self.outputLabel.text = str;
NSLog(@"RPC error: %@", error);
}
};
@ -102,8 +112,8 @@ static NSString * const kHostAddress = @"localhost:50051";
point.latitude = 409146138;
point.longitude = -746188906;
[service getFeatureWithRequest:point handler:handler];
[service getFeatureWithRequest:[RTGPoint message] handler:handler];
[_service getFeatureWithRequest:point handler:handler];
[_service getFeatureWithRequest:[RTGPoint message] handler:handler];
}
- (void)viewDidLoad {
@ -112,10 +122,13 @@ static NSString * const kHostAddress = @"localhost:50051";
// This only needs to be done once per host, before creating service objects for that host.
[GRPCCall useInsecureConnectionsForHost:kHostAddress];
service = [[RTGRouteGuide alloc] initWithHost:kHostAddress];
_service = [[RTGRouteGuide alloc] initWithHost:kHostAddress];
}
- (void)viewDidAppear:(BOOL)animated {
self.outputLabel.text = @"RPC log:";
self.outputLabel.numberOfLines = 0;
self.outputLabel.font = [UIFont fontWithName:@"Helvetica Neue" size:8.0];
[self execRequest];
}
@ -128,13 +141,15 @@ static NSString * const kHostAddress = @"localhost:50051";
* Run the listFeatures demo. Calls listFeatures with a rectangle containing all of the features in
* the pre-generated database. Prints each response as it comes in.
*/
@interface ListFeaturesViewController : UIViewController {
RTGRouteGuide *service;
}
@interface ListFeaturesViewController : UIViewController
@property (weak, nonatomic) IBOutlet UILabel *outputLabel;
@end
@implementation ListFeaturesViewController
@implementation ListFeaturesViewController {
RTGRouteGuide *_service;
}
- (void)execRequest {
RTGRectangle *rectangle = [RTGRectangle message];
@ -144,11 +159,15 @@ static NSString * const kHostAddress = @"localhost:50051";
rectangle.hi.longitude = -745E6;
NSLog(@"Looking for features between %@ and %@", rectangle.lo, rectangle.hi);
[service listFeaturesWithRequest:rectangle
[_service listFeaturesWithRequest:rectangle
eventHandler:^(BOOL done, RTGFeature *response, NSError *error) {
if (response) {
NSString *str =[NSString stringWithFormat:@"%@\nFound feature at %@ called %@.", self.outputLabel.text, response.location, response.name];
self.outputLabel.text = str;
NSLog(@"Found feature at %@ called %@.", response.location, response.name);
} else if (error) {
NSString *str =[NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error];
self.outputLabel.text = str;
NSLog(@"RPC error: %@", error);
}
}];
@ -157,10 +176,13 @@ static NSString * const kHostAddress = @"localhost:50051";
- (void)viewDidLoad {
[super viewDidLoad];
service = [[RTGRouteGuide alloc] initWithHost:kHostAddress];
_service = [[RTGRouteGuide alloc] initWithHost:kHostAddress];
}
- (void)viewDidAppear:(BOOL)animated {
self.outputLabel.text = @"RPC log:";
self.outputLabel.numberOfLines = 0;
self.outputLabel.font = [UIFont fontWithName:@"Helvetica Neue" size:8.0];
[self execRequest];
}
@ -174,13 +196,15 @@ static NSString * const kHostAddress = @"localhost:50051";
* database with a variable delay in between. Prints the statistics when they are sent from the
* server.
*/
@interface RecordRouteViewController : UIViewController {
RTGRouteGuide *service;
}
@interface RecordRouteViewController : UIViewController
@property (weak, nonatomic) IBOutlet UILabel *outputLabel;
@end
@implementation RecordRouteViewController
@implementation RecordRouteViewController {
RTGRouteGuide *_service;
}
- (void)execRequest {
NSString *dataBasePath = [NSBundle.mainBundle pathForResource:@"route_guide_db"
@ -192,18 +216,28 @@ static NSString * const kHostAddress = @"localhost:50051";
RTGPoint *location = [RTGPoint message];
location.longitude = [((NSNumber *) feature[@"location"][@"longitude"]) intValue];
location.latitude = [((NSNumber *) feature[@"location"][@"latitude"]) intValue];
NSString *str =[NSString stringWithFormat:@"%@\nVisiting point %@", self.outputLabel.text, location];
self.outputLabel.text = str;
NSLog(@"Visiting point %@", location);
return location;
}];
[service recordRouteWithRequestsWriter:locations
[_service recordRouteWithRequestsWriter:locations
handler:^(RTGRouteSummary *response, NSError *error) {
if (response) {
NSString *str =[NSString stringWithFormat:
@"%@\nFinished trip with %i points\nPassed %i features\n"
"Travelled %i meters\nIt took %i seconds",
self.outputLabel.text, response.pointCount, response.featureCount,
response.distance, response.elapsedTime];
self.outputLabel.text = str;
NSLog(@"Finished trip with %i points", response.pointCount);
NSLog(@"Passed %i features", response.featureCount);
NSLog(@"Travelled %i meters", response.distance);
NSLog(@"It took %i seconds", response.elapsedTime);
} else {
NSString *str =[NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error];
self.outputLabel.text = str;
NSLog(@"RPC error: %@", error);
}
}];
@ -212,10 +246,13 @@ static NSString * const kHostAddress = @"localhost:50051";
- (void)viewDidLoad {
[super viewDidLoad];
service = [[RTGRouteGuide alloc] initWithHost:kHostAddress];
_service = [[RTGRouteGuide alloc] initWithHost:kHostAddress];
}
- (void)viewDidAppear:(BOOL)animated {
self.outputLabel.text = @"RPC log:";
self.outputLabel.numberOfLines = 0;
self.outputLabel.font = [UIFont fontWithName:@"Helvetica Neue" size:8.0];
[self execRequest];
}
@ -228,13 +265,15 @@ static NSString * const kHostAddress = @"localhost:50051";
* Run the routeChat demo. Send some chat messages, and print any chat messages that are sent from
* the server.
*/
@interface RouteChatViewController : UIViewController {
RTGRouteGuide *service;
}
@interface RouteChatViewController : UIViewController
@property (weak, nonatomic) IBOutlet UILabel *outputLabel;
@end
@implementation RouteChatViewController
@implementation RouteChatViewController {
RTGRouteGuide *_service;
}
- (void)execRequest {
NSArray *notes = @[[RTGRouteNote noteWithMessage:@"First message" latitude:0 longitude:0],
@ -246,11 +285,16 @@ static NSString * const kHostAddress = @"localhost:50051";
return note;
}];
[service routeChatWithRequestsWriter:notesWriter
[_service routeChatWithRequestsWriter:notesWriter
eventHandler:^(BOOL done, RTGRouteNote *note, NSError *error) {
if (note) {
NSString *str =[NSString stringWithFormat:@"%@\nGot message %@ at %@",
self.outputLabel.text, note.message, note.location];
self.outputLabel.text = str;
NSLog(@"Got message %@ at %@", note.message, note.location);
} else if (error) {
NSString *str =[NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error];
self.outputLabel.text = str;
NSLog(@"RPC error: %@", error);
}
if (done) {
@ -262,10 +306,14 @@ static NSString * const kHostAddress = @"localhost:50051";
- (void)viewDidLoad {
[super viewDidLoad];
service = [[RTGRouteGuide alloc] initWithHost:kHostAddress];
_service = [[RTGRouteGuide alloc] initWithHost:kHostAddress];
}
- (void)viewDidAppear:(BOOL)animated {
// TODO(makarandd): Set these properties through UI builder
self.outputLabel.text = @"RPC log:";
self.outputLabel.numberOfLines = 0;
self.outputLabel.font = [UIFont fontWithName:@"Helvetica Neue" size:8.0];
[self execRequest];
}

@ -180,6 +180,7 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/endpoint.h',
'src/core/lib/iomgr/endpoint_pair.h',
'src/core/lib/iomgr/error.h',
'src/core/lib/iomgr/ev_epoll_linux.h',
'src/core/lib/iomgr/ev_poll_and_epoll_posix.h',
'src/core/lib/iomgr/ev_poll_posix.h',
'src/core/lib/iomgr/ev_posix.h',
@ -190,6 +191,7 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/iomgr_internal.h',
'src/core/lib/iomgr/iomgr_posix.h',
'src/core/lib/iomgr/load_file.h',
'src/core/lib/iomgr/network_status_tracker.h',
'src/core/lib/iomgr/polling_entity.h',
'src/core/lib/iomgr/pollset.h',
'src/core/lib/iomgr/pollset_set.h',
@ -364,6 +366,7 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/endpoint_pair_posix.c',
'src/core/lib/iomgr/endpoint_pair_windows.c',
'src/core/lib/iomgr/error.c',
'src/core/lib/iomgr/ev_epoll_linux.c',
'src/core/lib/iomgr/ev_poll_and_epoll_posix.c',
'src/core/lib/iomgr/ev_poll_posix.c',
'src/core/lib/iomgr/ev_posix.c',
@ -374,6 +377,7 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/iomgr_posix.c',
'src/core/lib/iomgr/iomgr_windows.c',
'src/core/lib/iomgr/load_file.c',
'src/core/lib/iomgr/network_status_tracker.c',
'src/core/lib/iomgr/polling_entity.c',
'src/core/lib/iomgr/pollset_set_windows.c',
'src/core/lib/iomgr/pollset_windows.c',
@ -559,6 +563,7 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/endpoint.h',
'src/core/lib/iomgr/endpoint_pair.h',
'src/core/lib/iomgr/error.h',
'src/core/lib/iomgr/ev_epoll_linux.h',
'src/core/lib/iomgr/ev_poll_and_epoll_posix.h',
'src/core/lib/iomgr/ev_poll_posix.h',
'src/core/lib/iomgr/ev_posix.h',
@ -569,6 +574,7 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/iomgr_internal.h',
'src/core/lib/iomgr/iomgr_posix.h',
'src/core/lib/iomgr/load_file.h',
'src/core/lib/iomgr/network_status_tracker.h',
'src/core/lib/iomgr/polling_entity.h',
'src/core/lib/iomgr/pollset.h',
'src/core/lib/iomgr/pollset_set.h',

@ -90,6 +90,7 @@ EXPORTS
grpc_call_error_to_string
grpc_insecure_channel_create_from_fd
grpc_server_add_insecure_channel_from_fd
grpc_use_signal
grpc_auth_property_iterator_next
grpc_auth_context_property_iterator
grpc_auth_context_peer_identity

@ -189,6 +189,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/iomgr/endpoint.h )
s.files += %w( src/core/lib/iomgr/endpoint_pair.h )
s.files += %w( src/core/lib/iomgr/error.h )
s.files += %w( src/core/lib/iomgr/ev_epoll_linux.h )
s.files += %w( src/core/lib/iomgr/ev_poll_and_epoll_posix.h )
s.files += %w( src/core/lib/iomgr/ev_poll_posix.h )
s.files += %w( src/core/lib/iomgr/ev_posix.h )
@ -199,6 +200,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/iomgr/iomgr_internal.h )
s.files += %w( src/core/lib/iomgr/iomgr_posix.h )
s.files += %w( src/core/lib/iomgr/load_file.h )
s.files += %w( src/core/lib/iomgr/network_status_tracker.h )
s.files += %w( src/core/lib/iomgr/polling_entity.h )
s.files += %w( src/core/lib/iomgr/pollset.h )
s.files += %w( src/core/lib/iomgr/pollset_set.h )
@ -343,6 +345,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/iomgr/endpoint_pair_posix.c )
s.files += %w( src/core/lib/iomgr/endpoint_pair_windows.c )
s.files += %w( src/core/lib/iomgr/error.c )
s.files += %w( src/core/lib/iomgr/ev_epoll_linux.c )
s.files += %w( src/core/lib/iomgr/ev_poll_and_epoll_posix.c )
s.files += %w( src/core/lib/iomgr/ev_poll_posix.c )
s.files += %w( src/core/lib/iomgr/ev_posix.c )
@ -353,6 +356,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/iomgr/iomgr_posix.c )
s.files += %w( src/core/lib/iomgr/iomgr_windows.c )
s.files += %w( src/core/lib/iomgr/load_file.c )
s.files += %w( src/core/lib/iomgr/network_status_tracker.c )
s.files += %w( src/core/lib/iomgr/polling_entity.c )
s.files += %w( src/core/lib/iomgr/pollset_set_windows.c )
s.files += %w( src/core/lib/iomgr/pollset_windows.c )

@ -52,11 +52,14 @@ class ClientAsyncStreamingInterface {
/// Request notification of the reading of the initial metadata. Completion
/// will be notified by \a tag on the associated completion queue.
/// This call is optional, but if it is used, it cannot be used concurrently
/// with or after the \a Read method.
///
/// \param[in] tag Tag identifying this request.
virtual void ReadInitialMetadata(void* tag) = 0;
/// Request notification completion.
/// Indicate that the stream is to be finished and request notification
/// Should not be used concurrently with other operations
///
/// \param[out] status To be updated with the operation status.
/// \param[in] tag Tag identifying this request.
@ -71,6 +74,11 @@ class AsyncReaderInterface {
/// Read a message of type \a R into \a msg. Completion will be notified by \a
/// tag on the associated completion queue.
/// This is thread-safe with respect to \a Write or \a WritesDone methods. It
/// should not be called concurrently with other streaming APIs
/// on the same stream. It is not meaningful to call it concurrently
/// with another \a Read on the same stream since reads on the same stream
/// are delivered in order.
///
/// \param[out] msg Where to eventually store the read message.
/// \param[in] tag The tag identifying the operation.
@ -88,6 +96,7 @@ class AsyncWriterInterface {
/// Only one write may be outstanding at any given time. This means that
/// after calling Write, one must wait to receive \a tag from the completion
/// queue BEFORE calling Write again.
/// This is thread-safe with respect to \a Read
///
/// \param[in] msg The message to be written.
/// \param[in] tag The tag identifying the operation.
@ -158,6 +167,7 @@ class ClientAsyncWriterInterface : public ClientAsyncStreamingInterface,
public AsyncWriterInterface<W> {
public:
/// Signal the client is done with the writes.
/// Thread-safe with respect to \a Read
///
/// \param[in] tag The tag identifying the operation.
virtual void WritesDone(void* tag) = 0;
@ -229,6 +239,7 @@ class ClientAsyncReaderWriterInterface : public ClientAsyncStreamingInterface,
public AsyncReaderInterface<R> {
public:
/// Signal the client is done with the writes.
/// Thread-safe with respect to \a Read
///
/// \param[in] tag The tag identifying the operation.
virtual void WritesDone(void* tag) = 0;

@ -31,8 +31,19 @@
*
*/
/// A completion queue implements a concurrent producer-consumer queue, with two
/// main methods, \a Next and \a AsyncNext.
/// A completion queue implements a concurrent producer-consumer queue, with
/// two main API-exposed methods: \a Next and \a AsyncNext. These
/// methods are the essential component of the gRPC C++ asynchronous API.
/// There is also a \a Shutdown method to indicate that a given completion queue
/// will no longer have regular events. This must be called before the
/// completion queue is destroyed.
/// All completion queue APIs are thread-safe and may be used concurrently with
/// any other completion queue API invocation; it is acceptable to have
/// multiple threads calling \a Next or \a AsyncNext on the same or different
/// completion queues, or to call these methods concurrently with a \a Shutdown
/// elsewhere.
/// \remark{All other API calls on completion queue should be completed before
/// a completion queue destructor is called.}
#ifndef GRPCXX_IMPL_CODEGEN_COMPLETION_QUEUE_H
#define GRPCXX_IMPL_CODEGEN_COMPLETION_QUEUE_H

@ -71,6 +71,9 @@ class ReaderInterface {
virtual ~ReaderInterface() {}
/// Blocking read a message and parse to \a msg. Returns \a true on success.
/// This is thread-safe with respect to \a Write or \WritesDone methods on
/// the same stream. It should not be called concurrently with another \a
/// Read on the same stream as the order of delivery will not be defined.
///
/// \param[out] msg The read message.
///
@ -87,6 +90,7 @@ class WriterInterface {
virtual ~WriterInterface() {}
/// Blocking write \a msg to the stream with options.
/// This is thread-safe with respect to \a Read
///
/// \param msg The message to be written to the stream.
/// \param options Options affecting the write operation.
@ -95,6 +99,7 @@ class WriterInterface {
virtual bool Write(const W& msg, const WriteOptions& options) = 0;
/// Blocking write \a msg to the stream with default options.
/// This is thread-safe with respect to \a Read
///
/// \param msg The message to be written to the stream.
///
@ -174,7 +179,8 @@ class ClientWriterInterface : public ClientStreamingInterface,
public WriterInterface<W> {
public:
/// Half close writing from the client.
/// Block until writes are completed.
/// Block until currently-pending writes are completed.
/// Thread safe with respect to \a Read operations only
///
/// \return Whether the writes were successful.
virtual bool WritesDone() = 0;
@ -257,7 +263,8 @@ class ClientReaderWriterInterface : public ClientStreamingInterface,
/// the metadata will be available in ClientContext after the first read.
virtual void WaitForInitialMetadata() = 0;
/// Block until writes are completed.
/// Block until currently-pending writes are completed.
/// Thread-safe with respect to \a Read
///
/// \return Whether the writes were successful.
virtual bool WritesDone() = 0;

@ -63,6 +63,14 @@ GRPCAPI void grpc_server_add_insecure_channel_from_fd(grpc_server *server,
grpc_completion_queue *cq,
int fd);
/** GRPC Core POSIX library may internally use signals to optimize some work.
The library uses (SIGRTMIN + 2) signal by default. Use this API to instruct
the library to use a different signal i.e 'signum' instead.
Note:
- To prevent GRPC library from using any signals, pass a 'signum' of -1
- This API is optional but if called, it MUST be called before grpc_init() */
GRPCAPI void grpc_use_signal(int signum);
#ifdef __cplusplus
}
#endif

@ -156,6 +156,8 @@ typedef struct {
#define GRPC_SSL_TARGET_NAME_OVERRIDE_ARG "grpc.ssl_target_name_override"
/* Maximum metadata size */
#define GRPC_ARG_MAX_METADATA_SIZE "grpc.max_metadata_size"
/** If non-zero, allow the use of SO_REUSEPORT if it's available (default 1) */
#define GRPC_ARG_ALLOW_REUSEPORT "grpc.so_reuseport"
/** Result of a grpc call. If the caller satisfies the prerequisites of a
particular operation, the grpc_call_error returned will be GRPC_CALL_OK.

@ -207,6 +207,7 @@
#ifdef __GLIBC_PREREQ
#if __GLIBC_PREREQ(2, 9)
#define GPR_LINUX_EVENTFD 1
#define GPR_LINUX_EPOLL 1
#endif
#if __GLIBC_PREREQ(2, 10)
#define GPR_LINUX_SOCKETUTILS 1

@ -1,6 +1,6 @@
{
"name": "grpc",
"version": "0.15.0-dev",
"version": "0.16.0-dev",
"author": "Google Inc.",
"description": "gRPC Library for Node",
"homepage": "http://www.grpc.io/",

@ -13,8 +13,8 @@
<date>2016-05-19</date>
<time>16:06:07</time>
<version>
<release>0.15.0</release>
<api>0.15.0</api>
<release>0.16.0</release>
<api>0.16.0</api>
</version>
<stability>
<release>beta</release>
@ -196,6 +196,7 @@
<file baseinstalldir="/" name="src/core/lib/iomgr/endpoint.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/endpoint_pair.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/error.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/ev_epoll_linux.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/ev_poll_and_epoll_posix.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/ev_poll_posix.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/ev_posix.h" role="src" />
@ -206,6 +207,7 @@
<file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_internal.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_posix.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/load_file.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/network_status_tracker.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/polling_entity.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/pollset.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/pollset_set.h" role="src" />
@ -350,6 +352,7 @@
<file baseinstalldir="/" name="src/core/lib/iomgr/endpoint_pair_posix.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/endpoint_pair_windows.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/error.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/ev_epoll_linux.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/ev_poll_and_epoll_posix.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/ev_poll_posix.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/ev_posix.c" role="src" />
@ -360,6 +363,7 @@
<file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_posix.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_windows.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/load_file.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/network_status_tracker.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/polling_entity.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/pollset_set_windows.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/pollset_windows.c" role="src" />

@ -31,6 +31,7 @@
import os
import os.path
import shlex
import shutil
import sys
import sysconfig
@ -99,8 +100,9 @@ if not "win32" in sys.platform:
DEFINE_MACROS = (('OPENSSL_NO_ASM', 1), ('_WIN32_WINNT', 0x600), ('GPR_BACKWARDS_COMPATIBILITY_MODE', 1),)
LDFLAGS = ()
CFLAGS = ()
LDFLAGS = shlex.split(os.environ.get('GRPC_PYTHON_LDFLAGS', ''))
CFLAGS = shlex.split(os.environ.get('GRPC_PYTHON_CFLAGS', ''))
if "linux" in sys.platform:
LDFLAGS += ('-Wl,-wrap,memcpy',)
if "linux" in sys.platform or "darwin" in sys.platform:

@ -333,22 +333,28 @@ void GenerateClientStub(Printer* out, const ServiceDescriptor *service) {
out->Indent();
// constructors
out->Print("/// <summary>Creates a new client for $servicename$</summary>\n"
"/// <param name=\"channel\">The channel to use to make remote calls.</param>\n",
"servicename", GetServiceClassName(service));
out->Print("public $name$(Channel channel) : base(channel)\n",
"name", GetClientClassName(service));
out->Print("{\n");
out->Print("}\n");
out->Print("/// <summary>Creates a new client for $servicename$ that uses a custom <c>CallInvoker</c>.</summary>\n"
"/// <param name=\"callInvoker\">The callInvoker to use to make remote calls.</param>\n",
"servicename", GetServiceClassName(service));
out->Print("public $name$(CallInvoker callInvoker) : base(callInvoker)\n",
"name", GetClientClassName(service));
out->Print("{\n");
out->Print("}\n");
out->Print("///<summary>Protected parameterless constructor to allow creation"
out->Print("/// <summary>Protected parameterless constructor to allow creation"
" of test doubles.</summary>\n");
out->Print("protected $name$() : base()\n",
"name", GetClientClassName(service));
out->Print("{\n");
out->Print("}\n");
out->Print("///<summary>Protected constructor to allow creation of configured"
" clients.</summary>\n");
out->Print("/// <summary>Protected constructor to allow creation of configured clients.</summary>\n"
"/// <param name=\"configuration\">The client configuration.</param>\n");
out->Print("protected $name$(ClientBaseConfiguration configuration)"
" : base(configuration)\n",
"name", GetClientClassName(service));
@ -485,20 +491,6 @@ void GenerateBindServiceMethod(Printer* out, const ServiceDescriptor *service) {
out->Print("\n");
}
void GenerateNewStubMethods(Printer* out, const ServiceDescriptor *service) {
out->Print("/// <summary>Creates a new client for $servicename$</summary>\n",
"servicename", GetServiceClassName(service));
out->Print("public static $classname$ NewClient(Channel channel)\n",
"classname", GetClientClassName(service));
out->Print("{\n");
out->Indent();
out->Print("return new $classname$(channel);\n", "classname",
GetClientClassName(service));
out->Outdent();
out->Print("}\n");
out->Print("\n");
}
void GenerateService(Printer* out, const ServiceDescriptor *service,
bool generate_client, bool generate_server,
bool internal_access) {
@ -524,7 +516,6 @@ void GenerateService(Printer* out, const ServiceDescriptor *service,
}
if (generate_client) {
GenerateClientStub(out, service);
GenerateNewStubMethods(out, service);
}
if (generate_server) {
GenerateBindServiceMethod(out, service);

@ -189,10 +189,11 @@ void grpc_channel_watch_connectivity_state(
GRPC_API_TRACE(
"grpc_channel_watch_connectivity_state("
"channel=%p, last_observed_state=%d, "
"deadline=gpr_timespec { tv_sec: %lld, tv_nsec: %d, clock_type: %d }, "
"deadline=gpr_timespec { tv_sec: %" PRId64
", tv_nsec: %d, clock_type: %d }, "
"cq=%p, tag=%p)",
7, (channel, (int)last_observed_state, (long long)deadline.tv_sec,
(int)deadline.tv_nsec, (int)deadline.clock_type, cq, tag));
7, (channel, (int)last_observed_state, deadline.tv_sec, deadline.tv_nsec,
(int)deadline.clock_type, cq, tag));
grpc_cq_begin_op(cq, tag);

@ -97,7 +97,8 @@ int grpc_server_add_insecure_http2_port(grpc_server *server, const char *addr) {
goto error;
}
err = grpc_tcp_server_create(NULL, &tcp);
err =
grpc_tcp_server_create(NULL, grpc_server_get_channel_args(server), &tcp);
if (err != GRPC_ERROR_NONE) {
goto error;
}

@ -216,7 +216,8 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr,
state = gpr_malloc(sizeof(*state));
memset(state, 0, sizeof(*state));
grpc_closure_init(&state->destroy_closure, destroy_done, state);
err = grpc_tcp_server_create(&state->destroy_closure, &tcp);
err = grpc_tcp_server_create(&state->destroy_closure,
grpc_server_get_channel_args(server), &tcp);
if (err != GRPC_ERROR_NONE) {
goto error;
}

@ -1557,17 +1557,15 @@ static void close_from_api(grpc_exec_ctx *exec_ctx,
gpr_slice_buffer_add(&transport_global->qbuf,
gpr_slice_ref(*optional_message));
}
gpr_slice_buffer_add(
&transport_global->qbuf,
grpc_chttp2_rst_stream_create(stream_global->id, GRPC_CHTTP2_NO_ERROR,
&stream_global->stats.outgoing));
if (optional_message) {
gpr_slice_ref(*optional_message);
}
}
if (optional_message) {
gpr_slice_ref(*optional_message);
}
grpc_chttp2_fake_status(exec_ctx, transport_global, stream_global, status,
optional_message);
grpc_error *err = GRPC_ERROR_CREATE("Stream closed");

File diff suppressed because it is too large Load Diff

@ -0,0 +1,47 @@
/*
*
* 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.
*
*/
#ifndef GRPC_CORE_LIB_IOMGR_EV_EPOLL_LINUX_H
#define GRPC_CORE_LIB_IOMGR_EV_EPOLL_LINUX_H
#include "src/core/lib/iomgr/ev_posix.h"
const grpc_event_engine_vtable *grpc_init_epoll_linux(void);
#ifdef GPR_LINUX_EPOLL
void *grpc_fd_get_polling_island(grpc_fd *fd);
void *grpc_pollset_get_polling_island(grpc_pollset *ps);
bool grpc_are_polling_islands_equal(void *p, void *q);
#endif /* defined(GPR_LINUX_EPOLL) */
#endif /* GRPC_CORE_LIB_IOMGR_EV_EPOLL_LINUX_H */

@ -44,6 +44,7 @@
#include <grpc/support/string_util.h>
#include <grpc/support/useful.h>
#include "src/core/lib/iomgr/ev_epoll_linux.h"
#include "src/core/lib/iomgr/ev_poll_and_epoll_posix.h"
#include "src/core/lib/iomgr/ev_poll_posix.h"
#include "src/core/lib/support/env.h"
@ -53,6 +54,7 @@
grpc_poll_function_type grpc_poll_function = poll;
static const grpc_event_engine_vtable *g_event_engine;
static const char *g_poll_strategy_name = NULL;
typedef const grpc_event_engine_vtable *(*event_engine_factory_fn)(void);
@ -62,7 +64,9 @@ typedef struct {
} event_engine_factory;
static const event_engine_factory g_factories[] = {
{"poll", grpc_init_poll_posix}, {"legacy", grpc_init_poll_and_epoll_posix},
{"epoll", grpc_init_epoll_linux},
{"poll", grpc_init_poll_posix},
{"legacy", grpc_init_poll_and_epoll_posix},
};
static void add(const char *beg, const char *end, char ***ss, size_t *ns) {
@ -98,6 +102,7 @@ static void try_engine(const char *engine) {
for (size_t i = 0; i < GPR_ARRAY_SIZE(g_factories); i++) {
if (is(engine, g_factories[i].name)) {
if ((g_event_engine = g_factories[i].factory())) {
g_poll_strategy_name = g_factories[i].name;
gpr_log(GPR_DEBUG, "Using polling engine: %s", g_factories[i].name);
return;
}
@ -105,6 +110,9 @@ static void try_engine(const char *engine) {
}
}
/* Call this only after calling grpc_event_engine_init() */
const char *grpc_get_poll_strategy_name() { return g_poll_strategy_name; }
void grpc_event_engine_init(void) {
char *s = gpr_getenv("GRPC_POLL_STRATEGY");
if (s == NULL) {
@ -167,11 +175,6 @@ void grpc_fd_notify_on_write(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
g_event_engine->fd_notify_on_write(exec_ctx, fd, closure);
}
grpc_pollset *grpc_fd_get_read_notifier_pollset(grpc_exec_ctx *exec_ctx,
grpc_fd *fd) {
return g_event_engine->fd_get_read_notifier_pollset(exec_ctx, fd);
}
size_t grpc_pollset_size(void) { return g_event_engine->pollset_size; }
void grpc_pollset_init(grpc_pollset *pollset, gpr_mu **mu) {

@ -99,6 +99,9 @@ typedef struct grpc_event_engine_vtable {
void grpc_event_engine_init(void);
void grpc_event_engine_shutdown(void);
/* Return the name of the poll strategy */
const char *grpc_get_poll_strategy_name();
/* Create a wrapped file descriptor.
Requires fd is a non-blocking file descriptor.
This takes ownership of closing fd. */

@ -0,0 +1,121 @@
/*
*
* 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 <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "src/core/lib/iomgr/endpoint.h"
typedef struct endpoint_ll_node {
grpc_endpoint *ep;
struct endpoint_ll_node *next;
} endpoint_ll_node;
static endpoint_ll_node *head = NULL;
static gpr_mu g_endpoint_mutex;
static bool g_init_done = false;
void grpc_initialize_network_status_monitor() {
g_init_done = true;
gpr_mu_init(&g_endpoint_mutex);
// TODO(makarandd): Install callback with OS to monitor network status.
}
void grpc_destroy_network_status_monitor() {
for (endpoint_ll_node *curr = head; curr != NULL;) {
endpoint_ll_node *next = curr->next;
gpr_free(curr);
curr = next;
}
gpr_mu_destroy(&g_endpoint_mutex);
}
void grpc_network_status_register_endpoint(grpc_endpoint *ep) {
if (!g_init_done) {
grpc_initialize_network_status_monitor();
}
gpr_mu_lock(&g_endpoint_mutex);
if (head == NULL) {
head = (endpoint_ll_node *)gpr_malloc(sizeof(endpoint_ll_node));
head->ep = ep;
head->next = NULL;
} else {
endpoint_ll_node *prev_head = head;
head = (endpoint_ll_node *)gpr_malloc(sizeof(endpoint_ll_node));
head->ep = ep;
head->next = prev_head;
}
gpr_mu_unlock(&g_endpoint_mutex);
}
void grpc_network_status_unregister_endpoint(grpc_endpoint *ep) {
gpr_mu_lock(&g_endpoint_mutex);
GPR_ASSERT(head);
bool found = false;
endpoint_ll_node *prev = head;
// if we're unregistering the head, just move head to the next
if (ep == head->ep) {
head = head->next;
gpr_free(prev);
found = true;
} else {
for (endpoint_ll_node *curr = head->next; curr != NULL; curr = curr->next) {
if (ep == curr->ep) {
prev->next = curr->next;
gpr_free(curr);
found = true;
break;
}
prev = curr;
}
}
gpr_mu_unlock(&g_endpoint_mutex);
GPR_ASSERT(found);
}
// Walk the linked-list from head and execute shutdown. It is possible that
// other threads might be in the process of shutdown as well, but that has
// no side effect since endpoint shutdown is idempotent.
void grpc_network_status_shutdown_all_endpoints() {
gpr_mu_lock(&g_endpoint_mutex);
if (head == NULL) {
gpr_mu_unlock(&g_endpoint_mutex);
return;
}
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
for (endpoint_ll_node *curr = head; curr != NULL; curr = curr->next) {
curr->ep->vtable->shutdown(&exec_ctx, curr->ep);
}
gpr_mu_unlock(&g_endpoint_mutex);
grpc_exec_ctx_finish(&exec_ctx);
}

@ -0,0 +1,41 @@
/*
*
* Copyright 2016, 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.
*
*/
#ifndef GRPC_CORE_LIB_IOMGR_NETWORK_STATUS_TRACKER_H
#define GRPC_CORE_LIB_IOMGR_NETWORK_STATUS_TRACKER_H
#include "src/core/lib/iomgr/endpoint.h"
void grpc_network_status_register_endpoint(grpc_endpoint *ep);
void grpc_network_status_unregister_endpoint(grpc_endpoint *ep);
void grpc_network_status_shutdown_all_endpoints();
#endif /* GRPC_CORE_LIB_IOMGR_NETWORK_STATUS_TRACKER_H */

@ -169,6 +169,28 @@ grpc_error *grpc_set_socket_reuse_addr(int fd, int reuse) {
return GRPC_ERROR_NONE;
}
/* set a socket to reuse old addresses */
grpc_error *grpc_set_socket_reuse_port(int fd, int reuse) {
#ifndef SO_REUSEPORT
return GRPC_ERROR_CREATE("SO_REUSEPORT unavailable on compiling system");
#else
int val = (reuse != 0);
int newval;
socklen_t intlen = sizeof(newval);
if (0 != setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val))) {
return GRPC_OS_ERROR(errno, "setsockopt(SO_REUSEPORT)");
}
if (0 != getsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &newval, &intlen)) {
return GRPC_OS_ERROR(errno, "getsockopt(SO_REUSEPORT)");
}
if ((newval != 0) != val) {
return GRPC_ERROR_CREATE("Failed to set SO_REUSEPORT");
}
return GRPC_ERROR_NONE;
#endif
}
/* disable nagle */
grpc_error *grpc_set_socket_low_latency(int fd, int low_latency) {
int val = (low_latency != 0);

@ -55,6 +55,9 @@ grpc_error *grpc_set_socket_reuse_addr(int fd, int reuse);
/* disable nagle */
grpc_error *grpc_set_socket_low_latency(int fd, int low_latency);
/* set SO_REUSEPORT */
grpc_error *grpc_set_socket_reuse_port(int fd, int reuse);
/* Returns true if this system can create AF_INET6 sockets bound to ::1.
The value is probed once, and cached for the life of the process.

@ -35,6 +35,7 @@
#ifdef GPR_POSIX_SOCKET
#include "src/core/lib/iomgr/network_status_tracker.h"
#include "src/core/lib/iomgr/tcp_posix.h"
#include <errno.h>
@ -152,6 +153,7 @@ static void tcp_ref(grpc_tcp *tcp) { gpr_ref(&tcp->refcount); }
#endif
static void tcp_destroy(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep) {
grpc_network_status_unregister_endpoint(ep);
grpc_tcp *tcp = (grpc_tcp *)ep;
TCP_UNREF(exec_ctx, tcp, "destroy");
}
@ -160,7 +162,7 @@ static void call_read_cb(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp,
grpc_error *error) {
grpc_closure *cb = tcp->read_cb;
if (false && grpc_tcp_trace) {
if (grpc_tcp_trace) {
size_t i;
const char *str = grpc_error_string(error);
gpr_log(GPR_DEBUG, "read: error=%s", str);
@ -394,7 +396,7 @@ static void tcp_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
grpc_tcp *tcp = (grpc_tcp *)ep;
grpc_error *error = GRPC_ERROR_NONE;
if (false && grpc_tcp_trace) {
if (grpc_tcp_trace) {
size_t i;
for (i = 0; i < buf->count; i++) {
@ -474,6 +476,8 @@ grpc_endpoint *grpc_tcp_create(grpc_fd *em_fd, size_t slice_size,
tcp->write_closure.cb = tcp_handle_write;
tcp->write_closure.cb_arg = tcp;
gpr_slice_buffer_init(&tcp->last_read_buffer);
/* Tell network status tracker about new endpoint */
grpc_network_status_register_endpoint(&tcp->base);
return &tcp->base;
}

@ -34,6 +34,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_TCP_SERVER_H
#define GRPC_CORE_LIB_IOMGR_TCP_SERVER_H
#include <grpc/grpc.h>
#include "src/core/lib/iomgr/closure.h"
#include "src/core/lib/iomgr/endpoint.h"
@ -59,6 +61,7 @@ typedef void (*grpc_tcp_server_cb)(grpc_exec_ctx *exec_ctx, void *arg,
If shutdown_complete is not NULL, it will be used by
grpc_tcp_server_unref() when the ref count reaches zero. */
grpc_error *grpc_tcp_server_create(grpc_closure *shutdown_complete,
const grpc_channel_args *args,
grpc_tcp_server **server);
/* Start listening to bound ports */

@ -112,8 +112,10 @@ struct grpc_tcp_server {
/* destroyed port count: how many ports are completely destroyed */
size_t destroyed_ports;
/* is this server shutting down? (boolean) */
int shutdown;
/* is this server shutting down? */
bool shutdown;
/* use SO_REUSEPORT */
bool so_reuseport;
/* linked list of server ports */
grpc_tcp_listener *head;
@ -135,14 +137,42 @@ struct grpc_tcp_server {
size_t next_pollset_to_assign;
};
static gpr_once check_init = GPR_ONCE_INIT;
static bool has_so_reuseport;
static void init(void) {
int s = socket(AF_INET, SOCK_STREAM, 0);
if (s >= 0) {
has_so_reuseport = GRPC_LOG_IF_ERROR("check for SO_REUSEPORT",
grpc_set_socket_reuse_port(s, 1));
close(s);
}
}
grpc_error *grpc_tcp_server_create(grpc_closure *shutdown_complete,
const grpc_channel_args *args,
grpc_tcp_server **server) {
gpr_once_init(&check_init, init);
grpc_tcp_server *s = gpr_malloc(sizeof(grpc_tcp_server));
s->so_reuseport = has_so_reuseport;
for (size_t i = 0; i < (args == NULL ? 0 : args->num_args); i++) {
if (0 == strcmp(GRPC_ARG_ALLOW_REUSEPORT, args->args[i].key)) {
if (args->args[i].type == GRPC_ARG_INTEGER) {
s->so_reuseport =
has_so_reuseport && (args->args[i].value.integer != 0);
} else {
gpr_free(s);
return GRPC_ERROR_CREATE(GRPC_ARG_ALLOW_REUSEPORT
" must be an integer");
}
}
}
gpr_ref_init(&s->refs, 1);
gpr_mu_init(&s->mu);
s->active_ports = 0;
s->destroyed_ports = 0;
s->shutdown = 0;
s->shutdown = false;
s->shutdown_starting.head = NULL;
s->shutdown_starting.tail = NULL;
s->shutdown_complete = shutdown_complete;
@ -218,7 +248,7 @@ static void tcp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
gpr_mu_lock(&s->mu);
GPR_ASSERT(!s->shutdown);
s->shutdown = 1;
s->shutdown = true;
/* shutdown all fd's */
if (s->active_ports) {
@ -268,13 +298,19 @@ static int get_max_accept_queue_size(void) {
/* Prepare a recently-created socket for listening. */
static grpc_error *prepare_socket(int fd, const struct sockaddr *addr,
size_t addr_len, int *port) {
size_t addr_len, bool so_reuseport,
int *port) {
struct sockaddr_storage sockname_temp;
socklen_t sockname_len;
grpc_error *err = GRPC_ERROR_NONE;
GPR_ASSERT(fd >= 0);
if (so_reuseport) {
err = grpc_set_socket_reuse_port(fd, 1);
if (err != GRPC_ERROR_NONE) goto error;
}
err = grpc_set_socket_nonblocking(fd, 1);
if (err != GRPC_ERROR_NONE) goto error;
err = grpc_set_socket_cloexec(fd, 1);
@ -407,7 +443,7 @@ static grpc_error *add_socket_to_server(grpc_tcp_server *s, int fd,
char *addr_str;
char *name;
grpc_error *err = prepare_socket(fd, addr, addr_len, &port);
grpc_error *err = prepare_socket(fd, addr, addr_len, s->so_reuseport, &port);
if (err == GRPC_ERROR_NONE) {
GPR_ASSERT(port > 0);
grpc_sockaddr_to_string(&addr_str, (struct sockaddr *)&addr, 1);
@ -443,6 +479,52 @@ static grpc_error *add_socket_to_server(grpc_tcp_server *s, int fd,
return err;
}
static grpc_error *clone_port(grpc_tcp_listener *listener, unsigned count) {
grpc_tcp_listener *sp = NULL;
char *addr_str;
char *name;
grpc_error *err;
for (grpc_tcp_listener *l = listener->next; l && l->is_sibling; l = l->next) {
l->fd_index += count;
}
for (unsigned i = 0; i < count; i++) {
int fd, port;
grpc_dualstack_mode dsmode;
err = grpc_create_dualstack_socket(&listener->addr.sockaddr, SOCK_STREAM, 0,
&dsmode, &fd);
if (err != GRPC_ERROR_NONE) return err;
err = prepare_socket(fd, &listener->addr.sockaddr, listener->addr_len, true,
&port);
if (err != GRPC_ERROR_NONE) return err;
listener->server->nports++;
grpc_sockaddr_to_string(&addr_str, &listener->addr.sockaddr, 1);
gpr_asprintf(&name, "tcp-server-listener:%s/clone-%d", addr_str, i);
sp = gpr_malloc(sizeof(grpc_tcp_listener));
sp->next = listener->next;
listener->next = sp;
sp->server = listener->server;
sp->fd = fd;
sp->emfd = grpc_fd_create(fd, name);
memcpy(sp->addr.untyped, listener->addr.untyped, listener->addr_len);
sp->addr_len = listener->addr_len;
sp->port = port;
sp->port_index = listener->port_index;
sp->fd_index = listener->fd_index + count - i;
sp->is_sibling = 1;
sp->sibling = listener->is_sibling ? listener->sibling : listener;
GPR_ASSERT(sp->emfd);
while (listener->server->tail->next != NULL) {
listener->server->tail = listener->server->tail->next;
}
gpr_free(addr_str);
gpr_free(name);
}
return GRPC_ERROR_NONE;
}
grpc_error *grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
size_t addr_len, int *out_port) {
grpc_tcp_listener *sp;
@ -599,14 +681,29 @@ void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s,
s->on_accept_cb_arg = on_accept_cb_arg;
s->pollsets = pollsets;
s->pollset_count = pollset_count;
for (sp = s->head; sp; sp = sp->next) {
for (i = 0; i < pollset_count; i++) {
grpc_pollset_add_fd(exec_ctx, pollsets[i], sp->emfd);
sp = s->head;
while (sp != NULL) {
if (s->so_reuseport && pollset_count > 1) {
GPR_ASSERT(GRPC_LOG_IF_ERROR(
"clone_port", clone_port(sp, (unsigned)(pollset_count - 1))));
for (i = 0; i < pollset_count; i++) {
grpc_pollset_add_fd(exec_ctx, pollsets[i], sp->emfd);
sp->read_closure.cb = on_read;
sp->read_closure.cb_arg = sp;
grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure);
s->active_ports++;
sp = sp->next;
}
} else {
for (i = 0; i < pollset_count; i++) {
grpc_pollset_add_fd(exec_ctx, pollsets[i], sp->emfd);
}
sp->read_closure.cb = on_read;
sp->read_closure.cb_arg = sp;
grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure);
s->active_ports++;
sp = sp->next;
}
sp->read_closure.cb = on_read;
sp->read_closure.cb_arg = sp;
grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure);
s->active_ports++;
}
gpr_mu_unlock(&s->mu);
}

@ -103,6 +103,7 @@ struct grpc_tcp_server {
/* Public function. Allocates the proper data structures to hold a
grpc_tcp_server. */
grpc_error *grpc_tcp_server_create(grpc_closure *shutdown_complete,
const grpc_channel_args *args,
grpc_tcp_server **server) {
grpc_tcp_server *s = gpr_malloc(sizeof(grpc_tcp_server));
gpr_ref_init(&s->refs, 1);

@ -37,6 +37,7 @@
#include <limits.h>
#include "src/core/lib/iomgr/network_status_tracker.h"
#include "src/core/lib/iomgr/sockaddr_windows.h"
#include <grpc/support/alloc.h>
@ -378,6 +379,7 @@ static void win_shutdown(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep) {
}
static void win_destroy(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep) {
grpc_network_status_unregister_endpoint(ep);
grpc_tcp *tcp = (grpc_tcp *)ep;
TCP_UNREF(tcp, "destroy");
}
@ -401,6 +403,9 @@ grpc_endpoint *grpc_tcp_create(grpc_winsocket *socket, char *peer_string) {
grpc_closure_init(&tcp->on_read, on_read, tcp);
grpc_closure_init(&tcp->on_write, on_write, tcp);
tcp->peer_string = gpr_strdup(peer_string);
/* Tell network status tracking code about the new endpoint */
grpc_network_status_register_endpoint(&tcp->base);
return &tcp->base;
}

@ -243,13 +243,13 @@ static int prepare_socket(int fd, const struct sockaddr *addr,
if (!grpc_set_socket_sndbuf(fd, buffer_size_bytes)) {
gpr_log(GPR_ERROR, "Failed to set send buffer size to %d bytes",
buf_size_bytes);
buffer_size_bytes);
goto error;
}
if (!grpc_set_socket_rcvbuf(fd, buffer_size_bytes)) {
gpr_log(GPR_ERROR, "Failed to set receive buffer size to %d bytes",
buf_size_bytes);
buffer_size_bytes);
goto error;
}

@ -141,11 +141,11 @@ static void write_log(gpr_timer_log *log) {
entry->tm = gpr_time_0(entry->tm.clock_type);
}
fprintf(output_file,
"{\"t\": %lld.%09d, \"thd\": \"%d\", \"type\": \"%c\", \"tag\": "
"{\"t\": %" PRId64
".%09d, \"thd\": \"%d\", \"type\": \"%c\", \"tag\": "
"\"%s\", \"file\": \"%s\", \"line\": %d, \"imp\": %d}\n",
(long long)entry->tm.tv_sec, (int)entry->tm.tv_nsec, entry->thd,
entry->type, entry->tagstr, entry->file, entry->line,
entry->important);
entry->tm.tv_sec, entry->tm.tv_nsec, entry->thd, entry->type,
entry->tagstr, entry->file, entry->line, entry->important);
}
}

@ -72,11 +72,12 @@ static void composite_call_md_context_destroy(
static void composite_call_metadata_cb(grpc_exec_ctx *exec_ctx, void *user_data,
grpc_credentials_md *md_elems,
size_t num_md,
grpc_credentials_status status) {
grpc_credentials_status status,
const char *error_details) {
grpc_composite_call_credentials_metadata_context *ctx =
(grpc_composite_call_credentials_metadata_context *)user_data;
if (status != GRPC_CREDENTIALS_OK) {
ctx->cb(exec_ctx, ctx->user_data, NULL, 0, status);
ctx->cb(exec_ctx, ctx->user_data, NULL, 0, status, error_details);
return;
}
@ -101,7 +102,7 @@ static void composite_call_metadata_cb(grpc_exec_ctx *exec_ctx, void *user_data,
/* We're done!. */
ctx->cb(exec_ctx, ctx->user_data, ctx->md_elems->entries,
ctx->md_elems->num_entries, GRPC_CREDENTIALS_OK);
ctx->md_elems->num_entries, GRPC_CREDENTIALS_OK, NULL);
composite_call_md_context_destroy(ctx);
}

@ -117,7 +117,7 @@ void grpc_call_credentials_get_request_metadata(
grpc_credentials_metadata_cb cb, void *user_data) {
if (creds == NULL || creds->vtable->get_request_metadata == NULL) {
if (cb != NULL) {
cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_OK);
cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_OK, NULL);
}
return;
}

@ -156,11 +156,10 @@ void grpc_credentials_md_store_unref(grpc_credentials_md_store *store);
/* --- grpc_call_credentials. --- */
typedef void (*grpc_credentials_metadata_cb)(grpc_exec_ctx *exec_ctx,
void *user_data,
grpc_credentials_md *md_elems,
size_t num_md,
grpc_credentials_status status);
/* error_details must be NULL if status is GRPC_CREDENTIALS_OK. */
typedef void (*grpc_credentials_metadata_cb)(
grpc_exec_ctx *exec_ctx, void *user_data, grpc_credentials_md *md_elems,
size_t num_md, grpc_credentials_status status, const char *error_details);
typedef struct {
void (*destruct)(grpc_call_credentials *c);

@ -100,7 +100,7 @@ static void on_simulated_token_fetch_done(grpc_exec_ctx *exec_ctx,
(grpc_credentials_metadata_request *)user_data;
grpc_md_only_test_credentials *c = (grpc_md_only_test_credentials *)r->creds;
r->cb(exec_ctx, r->user_data, c->md_store->entries, c->md_store->num_entries,
GRPC_CREDENTIALS_OK);
GRPC_CREDENTIALS_OK, NULL);
grpc_credentials_metadata_request_destroy(r);
}
@ -117,7 +117,7 @@ static void md_only_test_get_request_metadata(
grpc_closure_create(on_simulated_token_fetch_done, cb_arg),
GRPC_ERROR_NONE);
} else {
cb(exec_ctx, user_data, c->md_store->entries, 1, GRPC_CREDENTIALS_OK);
cb(exec_ctx, user_data, c->md_store->entries, 1, GRPC_CREDENTIALS_OK, NULL);
}
}

@ -55,7 +55,7 @@ static void iam_get_request_metadata(grpc_exec_ctx *exec_ctx,
void *user_data) {
grpc_google_iam_credentials *c = (grpc_google_iam_credentials *)creds;
cb(exec_ctx, user_data, c->iam_md->entries, c->iam_md->num_entries,
GRPC_CREDENTIALS_OK);
GRPC_CREDENTIALS_OK, NULL);
}
static grpc_call_credentials_vtable iam_vtable = {iam_destruct,

@ -113,10 +113,11 @@ static void jwt_get_request_metadata(grpc_exec_ctx *exec_ctx,
if (jwt_md != NULL) {
cb(exec_ctx, user_data, jwt_md->entries, jwt_md->num_entries,
GRPC_CREDENTIALS_OK);
GRPC_CREDENTIALS_OK, NULL);
grpc_credentials_md_store_unref(jwt_md);
} else {
cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_ERROR);
cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_ERROR,
"Could not generate JWT.");
}
}
@ -149,11 +150,11 @@ grpc_call_credentials *grpc_service_account_jwt_access_credentials_create(
"grpc_service_account_jwt_access_credentials_create("
"json_key=%s, "
"token_lifetime="
"gpr_timespec { tv_sec: %lld, tv_nsec: %d, clock_type: %d }, "
"gpr_timespec { tv_sec: %" PRId64
", tv_nsec: %d, clock_type: %d }, "
"reserved=%p)",
5,
(json_key, (long long)token_lifetime.tv_sec, (int)token_lifetime.tv_nsec,
(int)token_lifetime.clock_type, reserved));
5, (json_key, token_lifetime.tv_sec, token_lifetime.tv_nsec,
(int)token_lifetime.clock_type, reserved));
GPR_ASSERT(reserved == NULL);
return grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
grpc_auth_json_key_create_from_string(json_key), token_lifetime);

@ -235,10 +235,11 @@ static void on_oauth2_token_fetcher_http_response(grpc_exec_ctx *exec_ctx,
c->token_expiration =
gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), token_lifetime);
r->cb(exec_ctx, r->user_data, c->access_token_md->entries,
c->access_token_md->num_entries, status);
c->access_token_md->num_entries, GRPC_CREDENTIALS_OK, NULL);
} else {
c->token_expiration = gpr_inf_past(GPR_CLOCK_REALTIME);
r->cb(exec_ctx, r->user_data, NULL, 0, status);
r->cb(exec_ctx, r->user_data, NULL, 0, status,
"Error occured when fetching oauth2 token.");
}
gpr_mu_unlock(&c->mu);
grpc_credentials_metadata_request_destroy(r);
@ -266,7 +267,7 @@ static void oauth2_token_fetcher_get_request_metadata(
}
if (cached_access_token_md != NULL) {
cb(exec_ctx, user_data, cached_access_token_md->entries,
cached_access_token_md->num_entries, GRPC_CREDENTIALS_OK);
cached_access_token_md->num_entries, GRPC_CREDENTIALS_OK, NULL);
grpc_credentials_md_store_unref(cached_access_token_md);
} else {
c->fetch_func(
@ -404,7 +405,8 @@ static void access_token_get_request_metadata(
grpc_polling_entity *pollent, grpc_auth_metadata_context context,
grpc_credentials_metadata_cb cb, void *user_data) {
grpc_access_token_credentials *c = (grpc_access_token_credentials *)creds;
cb(exec_ctx, user_data, c->access_token_md->entries, 1, GRPC_CREDENTIALS_OK);
cb(exec_ctx, user_data, c->access_token_md->entries, 1, GRPC_CREDENTIALS_OK,
NULL);
}
static grpc_call_credentials_vtable access_token_vtable = {

@ -67,7 +67,8 @@ static void plugin_md_request_metadata_ready(void *request,
gpr_log(GPR_ERROR, "Getting metadata from plugin failed with error: %s",
error_details);
}
r->cb(&exec_ctx, r->user_data, NULL, 0, GRPC_CREDENTIALS_ERROR);
r->cb(&exec_ctx, r->user_data, NULL, 0, GRPC_CREDENTIALS_ERROR,
error_details);
} else {
size_t i;
grpc_credentials_md *md_array = NULL;
@ -79,7 +80,7 @@ static void plugin_md_request_metadata_ready(void *request,
gpr_slice_from_copied_buffer(md[i].value, md[i].value_length);
}
}
r->cb(&exec_ctx, r->user_data, md_array, num_md, GRPC_CREDENTIALS_OK);
r->cb(&exec_ctx, r->user_data, md_array, num_md, GRPC_CREDENTIALS_OK, NULL);
if (md_array != NULL) {
for (i = 0; i < num_md; i++) {
gpr_slice_unref(md_array[i].key);
@ -107,7 +108,7 @@ static void plugin_get_request_metadata(grpc_exec_ctx *exec_ctx,
c->plugin.get_metadata(c->plugin.state, context,
plugin_md_request_metadata_ready, request);
} else {
cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_OK);
cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_OK, NULL);
}
}

@ -91,14 +91,16 @@ static void bubble_up_error(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
grpc_status_code status, const char *error_msg) {
call_data *calld = elem->call_data;
gpr_log(GPR_ERROR, "Client side authentication failure: %s", error_msg);
grpc_transport_stream_op_add_cancellation(&calld->op, status);
gpr_slice error_slice = gpr_slice_from_copied_string(error_msg);
grpc_transport_stream_op_add_close(&calld->op, status, &error_slice);
grpc_call_next_op(exec_ctx, elem, &calld->op);
}
static void on_credentials_metadata(grpc_exec_ctx *exec_ctx, void *user_data,
grpc_credentials_md *md_elems,
size_t num_md,
grpc_credentials_status status) {
grpc_credentials_status status,
const char *error_details) {
grpc_call_element *elem = (grpc_call_element *)user_data;
call_data *calld = elem->call_data;
grpc_transport_stream_op *op = &calld->op;
@ -107,7 +109,9 @@ static void on_credentials_metadata(grpc_exec_ctx *exec_ctx, void *user_data,
reset_auth_metadata_context(&calld->auth_md_context);
if (status != GRPC_CREDENTIALS_OK) {
bubble_up_error(exec_ctx, elem, GRPC_STATUS_UNAUTHENTICATED,
"Credentials failed to get metadata.");
(error_details != NULL && strlen(error_details) > 0)
? error_details
: "Credentials failed to get metadata.");
return;
}
GPR_ASSERT(num_md <= MAX_CREDENTIALS_METADATA_COUNT);

@ -223,11 +223,12 @@ grpc_call *grpc_channel_create_call(grpc_channel *channel,
"grpc_channel_create_call("
"channel=%p, parent_call=%p, propagation_mask=%x, cq=%p, method=%s, "
"host=%s, "
"deadline=gpr_timespec { tv_sec: %lld, tv_nsec: %d, clock_type: %d }, "
"deadline=gpr_timespec { tv_sec: %" PRId64
", tv_nsec: %d, clock_type: %d }, "
"reserved=%p)",
10, (channel, parent_call, (unsigned)propagation_mask, cq, method, host,
(long long)deadline.tv_sec, (int)deadline.tv_nsec,
(int)deadline.clock_type, reserved));
10,
(channel, parent_call, (unsigned)propagation_mask, cq, method, host,
deadline.tv_sec, deadline.tv_nsec, (int)deadline.clock_type, reserved));
GPR_ASSERT(!reserved);
return grpc_channel_create_call_internal(
channel, parent_call, propagation_mask, cq, NULL,
@ -282,11 +283,12 @@ grpc_call *grpc_channel_create_registered_call(
"grpc_channel_create_registered_call("
"channel=%p, parent_call=%p, propagation_mask=%x, completion_queue=%p, "
"registered_call_handle=%p, "
"deadline=gpr_timespec { tv_sec: %lld, tv_nsec: %d, clock_type: %d }, "
"deadline=gpr_timespec { tv_sec: %" PRId64
", tv_nsec: %d, clock_type: %d }, "
"reserved=%p)",
9, (channel, parent_call, (unsigned)propagation_mask, completion_queue,
registered_call_handle, (long long)deadline.tv_sec,
(int)deadline.tv_nsec, (int)deadline.clock_type, reserved));
registered_call_handle, deadline.tv_sec, deadline.tv_nsec,
(int)deadline.clock_type, reserved));
GPR_ASSERT(!reserved);
return grpc_channel_create_call_internal(
channel, parent_call, propagation_mask, completion_queue, NULL,

@ -326,10 +326,11 @@ grpc_event grpc_completion_queue_next(grpc_completion_queue *cc,
GRPC_API_TRACE(
"grpc_completion_queue_next("
"cc=%p, "
"deadline=gpr_timespec { tv_sec: %lld, tv_nsec: %d, clock_type: %d }, "
"deadline=gpr_timespec { tv_sec: %" PRId64
", tv_nsec: %d, clock_type: %d }, "
"reserved=%p)",
5, (cc, (long long)deadline.tv_sec, (int)deadline.tv_nsec,
(int)deadline.clock_type, reserved));
5, (cc, deadline.tv_sec, deadline.tv_nsec, (int)deadline.clock_type,
reserved));
GPR_ASSERT(!reserved);
deadline = gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC);
@ -439,9 +440,10 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag,
GRPC_API_TRACE(
"grpc_completion_queue_pluck("
"cc=%p, tag=%p, "
"deadline=gpr_timespec { tv_sec: %lld, tv_nsec: %d, clock_type: %d }, "
"deadline=gpr_timespec { tv_sec: %" PRId64
", tv_nsec: %d, clock_type: %d }, "
"reserved=%p)",
6, (cc, tag, (long long)deadline.tv_sec, (int)deadline.tv_nsec,
6, (cc, tag, deadline.tv_sec, deadline.tv_nsec,
(int)deadline.clock_type, reserved));
}
GPR_ASSERT(!reserved);

@ -36,4 +36,4 @@
#include <grpc/grpc.h>
const char *grpc_version_string(void) { return "0.15.0-dev"; }
const char *grpc_version_string(void) { return "0.16.0-dev"; }

@ -63,8 +63,8 @@ static void put_metadata_list(gpr_strvec *b, grpc_metadata_batch md) {
}
if (gpr_time_cmp(md.deadline, gpr_inf_future(md.deadline.clock_type)) != 0) {
char *tmp;
gpr_asprintf(&tmp, " deadline=%lld.%09d", (long long)md.deadline.tv_sec,
(int)md.deadline.tv_nsec);
gpr_asprintf(&tmp, " deadline=%" PRId64 ".%09d", md.deadline.tv_sec,
md.deadline.tv_nsec);
gpr_strvec_add(b, tmp);
}
}

@ -1,5 +1,5 @@
{
"version": "0.15.0-dev",
"version": "0.16.0-dev",
"title": "gRPC C# Auth",
"authors": [ "Google Inc." ],
"copyright": "Copyright 2015, Google Inc.",
@ -13,7 +13,7 @@
"tags": [ "gRPC RPC Protocol HTTP/2 Auth OAuth2" ],
},
"dependencies": {
"Grpc.Core": "0.15.0-dev",
"Grpc.Core": "0.16.0-dev",
"Google.Apis.Auth": "1.11.1"
},
"frameworks": {

@ -24,11 +24,12 @@
<file src="bin/ReleaseSigned/Grpc.Core.xml" target="lib/net45" />
<file src="**\*.cs" target="src" />
<file src="Grpc.Core.targets" target="\build\net45\Grpc.Core.targets" />
<file src="../nativelibs/windows_x86/grpc_csharp_ext.dll" target="/build/native/bin/windows_x86/grpc_csharp_ext.dll" />
<file src="../nativelibs/windows_x64/grpc_csharp_ext.dll" target="/build/native/bin/windows_x64/grpc_csharp_ext.dll" />
<file src="../nativelibs/linux_x86/libgrpc_csharp_ext.so" target="/build/native/bin/linux_x86/libgrpc_csharp_ext.so" />
<file src="../nativelibs/linux_x64/libgrpc_csharp_ext.so" target="/build/native/bin/linux_x64/libgrpc_csharp_ext.so" />
<file src="../nativelibs/macosx_x86/libgrpc_csharp_ext.dylib" target="/build/native/bin/macosx_x86/libgrpc_csharp_ext.dylib" />
<file src="../nativelibs/macosx_x64/libgrpc_csharp_ext.dylib" target="/build/native/bin/macosx_x64/libgrpc_csharp_ext.dylib" />
<!-- without backslashes in the the source path, nuget won't copy the files -->
<file src="..\nativelibs\windows_x86\grpc_csharp_ext.dll" target="/build/native/bin/windows_x86/grpc_csharp_ext.dll" />
<file src="..\nativelibs\windows_x64\grpc_csharp_ext.dll" target="/build/native/bin/windows_x64/grpc_csharp_ext.dll" />
<file src="..\nativelibs\linux_x86\libgrpc_csharp_ext.so" target="/build/native/bin/linux_x86/libgrpc_csharp_ext.so" />
<file src="..\nativelibs\linux_x64\libgrpc_csharp_ext.so" target="/build/native/bin/linux_x64/libgrpc_csharp_ext.so" />
<file src="..\nativelibs\macosx_x86\libgrpc_csharp_ext.dylib" target="/build/native/bin/macosx_x86/libgrpc_csharp_ext.dylib" />
<file src="..\nativelibs\macosx_x64\libgrpc_csharp_ext.dylib" target="/build/native/bin/macosx_x64/libgrpc_csharp_ext.dylib" />
</files>
</package>

@ -54,7 +54,10 @@ namespace Grpc.Core.Internal
public void RegisterCompletionQueue(CompletionQueueSafeHandle cq)
{
Native.grpcsharp_server_register_completion_queue(this, cq);
using (cq.NewScope())
{
Native.grpcsharp_server_register_completion_queue(this, cq);
}
}
public int AddInsecurePort(string addr)
@ -74,16 +77,22 @@ namespace Grpc.Core.Internal
public void ShutdownAndNotify(BatchCompletionDelegate callback, CompletionQueueSafeHandle completionQueue)
{
var ctx = BatchContextSafeHandle.Create();
completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, callback);
Native.grpcsharp_server_shutdown_and_notify_callback(this, completionQueue, ctx);
using (completionQueue.NewScope())
{
var ctx = BatchContextSafeHandle.Create();
completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, callback);
Native.grpcsharp_server_shutdown_and_notify_callback(this, completionQueue, ctx);
}
}
public void RequestCall(BatchCompletionDelegate callback, CompletionQueueSafeHandle completionQueue)
{
var ctx = BatchContextSafeHandle.Create();
completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, callback);
Native.grpcsharp_server_request_call(this, completionQueue, ctx).CheckOk();
using (completionQueue.NewScope())
{
var ctx = BatchContextSafeHandle.Create();
completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, callback);
Native.grpcsharp_server_request_call(this, completionQueue, ctx).CheckOk();
}
}
protected override bool ReleaseHandle()

@ -48,11 +48,11 @@ namespace Grpc.Core
/// <summary>
/// Current <c>AssemblyFileVersion</c> of gRPC C# assemblies
/// </summary>
public const string CurrentAssemblyFileVersion = "0.15.0.0";
public const string CurrentAssemblyFileVersion = "0.16.0.0";
/// <summary>
/// Current version of gRPC C#
/// </summary>
public const string CurrentVersion = "0.15.0-dev";
public const string CurrentVersion = "0.16.0-dev";
}
}

@ -1,5 +1,5 @@
{
"version": "0.15.0-dev",
"version": "0.16.0-dev",
"title": "gRPC C# Core",
"authors": [ "Google Inc." ],
"copyright": "Copyright 2015, Google Inc.",

@ -62,7 +62,7 @@ namespace Math.Tests
};
server.Start();
channel = new Channel(Host, server.Ports.Single().BoundPort, ChannelCredentials.Insecure);
client = Math.NewClient(channel);
client = new Math.MathClient(channel);
}
[TestFixtureTearDown]

@ -128,17 +128,22 @@ namespace Math {
/// <summary>Client for Math</summary>
public class MathClient : ClientBase<MathClient>
{
/// <summary>Creates a new client for Math</summary>
/// <param name="channel">The channel to use to make remote calls.</param>
public MathClient(Channel channel) : base(channel)
{
}
/// <summary>Creates a new client for Math that uses a custom <c>CallInvoker</c>.</summary>
/// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
public MathClient(CallInvoker callInvoker) : base(callInvoker)
{
}
///<summary>Protected parameterless constructor to allow creation of test doubles.</summary>
/// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
protected MathClient() : base()
{
}
///<summary>Protected constructor to allow creation of configured clients.</summary>
/// <summary>Protected constructor to allow creation of configured clients.</summary>
/// <param name="configuration">The client configuration.</param>
protected MathClient(ClientBaseConfiguration configuration) : base(configuration)
{
}
@ -235,12 +240,6 @@ namespace Math {
}
}
/// <summary>Creates a new client for Math</summary>
public static MathClient NewClient(Channel channel)
{
return new MathClient(channel);
}
/// <summary>Creates service definition that can be registered with a server</summary>
public static ServerServiceDefinition BindService(MathBase serviceImpl)
{

@ -65,7 +65,7 @@ namespace Grpc.HealthCheck.Tests
server.Start();
channel = new Channel(Host, server.Ports.Single().BoundPort, ChannelCredentials.Insecure);
client = Grpc.Health.V1.Health.NewClient(channel);
client = new Grpc.Health.V1.Health.HealthClient(channel);
}
[TestFixtureTearDown]

@ -71,17 +71,22 @@ namespace Grpc.Health.V1 {
/// <summary>Client for Health</summary>
public class HealthClient : ClientBase<HealthClient>
{
/// <summary>Creates a new client for Health</summary>
/// <param name="channel">The channel to use to make remote calls.</param>
public HealthClient(Channel channel) : base(channel)
{
}
/// <summary>Creates a new client for Health that uses a custom <c>CallInvoker</c>.</summary>
/// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
public HealthClient(CallInvoker callInvoker) : base(callInvoker)
{
}
///<summary>Protected parameterless constructor to allow creation of test doubles.</summary>
/// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
protected HealthClient() : base()
{
}
///<summary>Protected constructor to allow creation of configured clients.</summary>
/// <summary>Protected constructor to allow creation of configured clients.</summary>
/// <param name="configuration">The client configuration.</param>
protected HealthClient(ClientBaseConfiguration configuration) : base(configuration)
{
}
@ -108,12 +113,6 @@ namespace Grpc.Health.V1 {
}
}
/// <summary>Creates a new client for Health</summary>
public static HealthClient NewClient(Channel channel)
{
return new HealthClient(channel);
}
/// <summary>Creates service definition that can be registered with a server</summary>
public static ServerServiceDefinition BindService(HealthBase serviceImpl)
{

@ -1,5 +1,5 @@
{
"version": "0.15.0-dev",
"version": "0.16.0-dev",
"title": "gRPC C# Healthchecking",
"authors": [ "Google Inc." ],
"copyright": "Copyright 2015, Google Inc.",
@ -13,7 +13,7 @@
"tags": [ "gRPC health check" ]
},
"dependencies": {
"Grpc.Core": "0.15.0-dev",
"Grpc.Core": "0.16.0-dev",
"Google.Protobuf": "3.0.0-beta3"
},
"frameworks": {

@ -211,7 +211,7 @@ namespace Grpc.IntegrationTesting
bool profilerReset = false;
var client = BenchmarkService.NewClient(channel);
var client = new BenchmarkService.BenchmarkServiceClient(channel);
var request = CreateSimpleRequest();
var stopwatch = new Stopwatch();
@ -237,7 +237,7 @@ namespace Grpc.IntegrationTesting
private async Task RunUnaryAsync(Channel channel, IInterarrivalTimer timer)
{
var client = BenchmarkService.NewClient(channel);
var client = new BenchmarkService.BenchmarkServiceClient(channel);
var request = CreateSimpleRequest();
var stopwatch = new Stopwatch();
@ -256,7 +256,7 @@ namespace Grpc.IntegrationTesting
private async Task RunStreamingPingPongAsync(Channel channel, IInterarrivalTimer timer)
{
var client = BenchmarkService.NewClient(channel);
var client = new BenchmarkService.BenchmarkServiceClient(channel);
var request = CreateSimpleRequest();
var stopwatch = new Stopwatch();

@ -61,7 +61,7 @@ namespace Grpc.IntegrationTesting
};
server.Start();
channel = new Channel(Host, server.Ports.Single().BoundPort, ChannelCredentials.Insecure);
client = TestService.NewClient(channel);
client = new TestService.TestServiceClient(channel);
}
[TearDown]

@ -69,7 +69,7 @@ namespace Grpc.IntegrationTesting
};
int port = server.Ports.Single().BoundPort;
channel = new Channel(Host, port, TestCredentials.CreateSslCredentials(), options);
client = TestService.NewClient(channel);
client = new TestService.TestServiceClient(channel);
}
[TestFixtureTearDown]
@ -148,7 +148,7 @@ namespace Grpc.IntegrationTesting
[Test]
public void UnimplementedMethod()
{
InteropClient.RunUnimplementedMethod(UnimplementedService.NewClient(channel));
InteropClient.RunUnimplementedMethod(new UnimplementedService.UnimplementedServiceClient(channel));
}
}
}

@ -88,7 +88,7 @@ namespace Grpc.IntegrationTesting
var channelCredentials = ChannelCredentials.Create(TestCredentials.CreateSslCredentials(),
CallCredentials.FromInterceptor(asyncAuthInterceptor));
channel = new Channel(Host, server.Ports.Single().BoundPort, channelCredentials, options);
client = TestService.NewClient(channel);
client = new TestService.TestServiceClient(channel);
client.UnaryCall(new SimpleRequest { });
}
@ -97,7 +97,7 @@ namespace Grpc.IntegrationTesting
public void MetadataCredentials_PerCall()
{
channel = new Channel(Host, server.Ports.Single().BoundPort, TestCredentials.CreateSslCredentials(), options);
client = TestService.NewClient(channel);
client = new TestService.TestServiceClient(channel);
var callCredentials = CallCredentials.FromInterceptor(asyncAuthInterceptor);
client.UnaryCall(new SimpleRequest { }, new CallOptions(credentials: callCredentials));

@ -97,17 +97,22 @@ namespace Grpc.Testing {
/// <summary>Client for MetricsService</summary>
public class MetricsServiceClient : ClientBase<MetricsServiceClient>
{
/// <summary>Creates a new client for MetricsService</summary>
/// <param name="channel">The channel to use to make remote calls.</param>
public MetricsServiceClient(Channel channel) : base(channel)
{
}
/// <summary>Creates a new client for MetricsService that uses a custom <c>CallInvoker</c>.</summary>
/// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
public MetricsServiceClient(CallInvoker callInvoker) : base(callInvoker)
{
}
///<summary>Protected parameterless constructor to allow creation of test doubles.</summary>
/// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
protected MetricsServiceClient() : base()
{
}
///<summary>Protected constructor to allow creation of configured clients.</summary>
/// <summary>Protected constructor to allow creation of configured clients.</summary>
/// <param name="configuration">The client configuration.</param>
protected MetricsServiceClient(ClientBaseConfiguration configuration) : base(configuration)
{
}
@ -162,12 +167,6 @@ namespace Grpc.Testing {
}
}
/// <summary>Creates a new client for MetricsService</summary>
public static MetricsServiceClient NewClient(Channel channel)
{
return new MetricsServiceClient(channel);
}
/// <summary>Creates service definition that can be registered with a server</summary>
public static ServerServiceDefinition BindService(MetricsServiceBase serviceImpl)
{

@ -93,17 +93,22 @@ namespace Grpc.Testing {
/// <summary>Client for BenchmarkService</summary>
public class BenchmarkServiceClient : ClientBase<BenchmarkServiceClient>
{
/// <summary>Creates a new client for BenchmarkService</summary>
/// <param name="channel">The channel to use to make remote calls.</param>
public BenchmarkServiceClient(Channel channel) : base(channel)
{
}
/// <summary>Creates a new client for BenchmarkService that uses a custom <c>CallInvoker</c>.</summary>
/// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
public BenchmarkServiceClient(CallInvoker callInvoker) : base(callInvoker)
{
}
///<summary>Protected parameterless constructor to allow creation of test doubles.</summary>
/// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
protected BenchmarkServiceClient() : base()
{
}
///<summary>Protected constructor to allow creation of configured clients.</summary>
/// <summary>Protected constructor to allow creation of configured clients.</summary>
/// <param name="configuration">The client configuration.</param>
protected BenchmarkServiceClient(ClientBaseConfiguration configuration) : base(configuration)
{
}
@ -162,12 +167,6 @@ namespace Grpc.Testing {
}
}
/// <summary>Creates a new client for BenchmarkService</summary>
public static BenchmarkServiceClient NewClient(Channel channel)
{
return new BenchmarkServiceClient(channel);
}
/// <summary>Creates service definition that can be registered with a server</summary>
public static ServerServiceDefinition BindService(BenchmarkServiceBase serviceImpl)
{
@ -273,17 +272,22 @@ namespace Grpc.Testing {
/// <summary>Client for WorkerService</summary>
public class WorkerServiceClient : ClientBase<WorkerServiceClient>
{
/// <summary>Creates a new client for WorkerService</summary>
/// <param name="channel">The channel to use to make remote calls.</param>
public WorkerServiceClient(Channel channel) : base(channel)
{
}
/// <summary>Creates a new client for WorkerService that uses a custom <c>CallInvoker</c>.</summary>
/// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
public WorkerServiceClient(CallInvoker callInvoker) : base(callInvoker)
{
}
///<summary>Protected parameterless constructor to allow creation of test doubles.</summary>
/// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
protected WorkerServiceClient() : base()
{
}
///<summary>Protected constructor to allow creation of configured clients.</summary>
/// <summary>Protected constructor to allow creation of configured clients.</summary>
/// <param name="configuration">The client configuration.</param>
protected WorkerServiceClient(ClientBaseConfiguration configuration) : base(configuration)
{
}
@ -398,12 +402,6 @@ namespace Grpc.Testing {
}
}
/// <summary>Creates a new client for WorkerService</summary>
public static WorkerServiceClient NewClient(Channel channel)
{
return new WorkerServiceClient(channel);
}
/// <summary>Creates service definition that can be registered with a server</summary>
public static ServerServiceDefinition BindService(WorkerServiceBase serviceImpl)
{

@ -79,7 +79,7 @@ namespace Grpc.IntegrationTesting
};
channel = new Channel(Host, server.Ports.Single().BoundPort, clientCredentials, options);
client = TestService.NewClient(channel);
client = new TestService.TestServiceClient(channel);
}
[TestFixtureTearDown]

@ -148,7 +148,7 @@ namespace Grpc.IntegrationTesting
channels.Add(channel);
for (int j = 0; j < options.NumStubsPerChannel; j++)
{
var client = TestService.NewClient(channel);
var client = new TestService.TestServiceClient(channel);
var task = Task.Factory.StartNew(() => RunBodyAsync(client).GetAwaiter().GetResult(),
TaskCreationOptions.LongRunning);
tasks.Add(task);

@ -168,17 +168,22 @@ namespace Grpc.Testing {
/// <summary>Client for TestService</summary>
public class TestServiceClient : ClientBase<TestServiceClient>
{
/// <summary>Creates a new client for TestService</summary>
/// <param name="channel">The channel to use to make remote calls.</param>
public TestServiceClient(Channel channel) : base(channel)
{
}
/// <summary>Creates a new client for TestService that uses a custom <c>CallInvoker</c>.</summary>
/// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
public TestServiceClient(CallInvoker callInvoker) : base(callInvoker)
{
}
///<summary>Protected parameterless constructor to allow creation of test doubles.</summary>
/// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
protected TestServiceClient() : base()
{
}
///<summary>Protected constructor to allow creation of configured clients.</summary>
/// <summary>Protected constructor to allow creation of configured clients.</summary>
/// <param name="configuration">The client configuration.</param>
protected TestServiceClient(ClientBaseConfiguration configuration) : base(configuration)
{
}
@ -315,12 +320,6 @@ namespace Grpc.Testing {
}
}
/// <summary>Creates a new client for TestService</summary>
public static TestServiceClient NewClient(Channel channel)
{
return new TestServiceClient(channel);
}
/// <summary>Creates service definition that can be registered with a server</summary>
public static ServerServiceDefinition BindService(TestServiceBase serviceImpl)
{
@ -373,17 +372,22 @@ namespace Grpc.Testing {
/// <summary>Client for UnimplementedService</summary>
public class UnimplementedServiceClient : ClientBase<UnimplementedServiceClient>
{
/// <summary>Creates a new client for UnimplementedService</summary>
/// <param name="channel">The channel to use to make remote calls.</param>
public UnimplementedServiceClient(Channel channel) : base(channel)
{
}
/// <summary>Creates a new client for UnimplementedService that uses a custom <c>CallInvoker</c>.</summary>
/// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
public UnimplementedServiceClient(CallInvoker callInvoker) : base(callInvoker)
{
}
///<summary>Protected parameterless constructor to allow creation of test doubles.</summary>
/// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
protected UnimplementedServiceClient() : base()
{
}
///<summary>Protected constructor to allow creation of configured clients.</summary>
/// <summary>Protected constructor to allow creation of configured clients.</summary>
/// <param name="configuration">The client configuration.</param>
protected UnimplementedServiceClient(ClientBaseConfiguration configuration) : base(configuration)
{
}
@ -422,12 +426,6 @@ namespace Grpc.Testing {
}
}
/// <summary>Creates a new client for UnimplementedService</summary>
public static UnimplementedServiceClient NewClient(Channel channel)
{
return new UnimplementedServiceClient(channel);
}
/// <summary>Creates service definition that can be registered with a server</summary>
public static ServerServiceDefinition BindService(UnimplementedServiceBase serviceImpl)
{
@ -485,17 +483,22 @@ namespace Grpc.Testing {
/// <summary>Client for ReconnectService</summary>
public class ReconnectServiceClient : ClientBase<ReconnectServiceClient>
{
/// <summary>Creates a new client for ReconnectService</summary>
/// <param name="channel">The channel to use to make remote calls.</param>
public ReconnectServiceClient(Channel channel) : base(channel)
{
}
/// <summary>Creates a new client for ReconnectService that uses a custom <c>CallInvoker</c>.</summary>
/// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
public ReconnectServiceClient(CallInvoker callInvoker) : base(callInvoker)
{
}
///<summary>Protected parameterless constructor to allow creation of test doubles.</summary>
/// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
protected ReconnectServiceClient() : base()
{
}
///<summary>Protected constructor to allow creation of configured clients.</summary>
/// <summary>Protected constructor to allow creation of configured clients.</summary>
/// <param name="configuration">The client configuration.</param>
protected ReconnectServiceClient(ClientBaseConfiguration configuration) : base(configuration)
{
}
@ -538,12 +541,6 @@ namespace Grpc.Testing {
}
}
/// <summary>Creates a new client for ReconnectService</summary>
public static ReconnectServiceClient NewClient(Channel channel)
{
return new ReconnectServiceClient(channel);
}
/// <summary>Creates service definition that can be registered with a server</summary>
public static ServerServiceDefinition BindService(ReconnectServiceBase serviceImpl)
{

@ -30,7 +30,7 @@
@rem Builds gRPC NuGet packages
@rem Current package versions
set VERSION=0.15.0-dev
set VERSION=0.16.0-dev
set PROTOBUF_VERSION=3.0.0-beta3
@rem Packages that depend on prerelease packages (like Google.Protobuf) need to have prerelease suffix as well.

@ -31,12 +31,16 @@
*
*/
#include <list>
#include <node.h>
#include <nan.h>
#include <v8.h>
#include "grpc/grpc.h"
#include "grpc/grpc_security.h"
#include "grpc/support/alloc.h"
#include "grpc/support/log.h"
#include "grpc/support/time.h"
#include "call.h"
#include "call_credentials.h"
@ -45,14 +49,32 @@
#include "server.h"
#include "completion_queue_async_worker.h"
#include "server_credentials.h"
#include "timeval.h"
using v8::FunctionTemplate;
using v8::Local;
using v8::Value;
using v8::Number;
using v8::Object;
using v8::Uint32;
using v8::String;
typedef struct log_args {
gpr_log_func_args core_args;
gpr_timespec timestamp;
} log_args;
typedef struct logger_state {
Nan::Callback *callback;
std::list<log_args *> *pending_args;
uv_mutex_t mutex;
uv_async_t async;
// Indicates that a logger has been set
bool logger_set;
} logger_state;
logger_state grpc_logger_state;
static char *pem_root_certs = NULL;
void InitStatusConstants(Local<Object> exports) {
@ -235,6 +257,18 @@ void InitWriteFlags(Local<Object> exports) {
Nan::Set(write_flags, Nan::New("NO_COMPRESS").ToLocalChecked(), NO_COMPRESS);
}
void InitLogConstants(Local<Object> exports) {
Nan::HandleScope scope;
Local<Object> log_verbosity = Nan::New<Object>();
Nan::Set(exports, Nan::New("logVerbosity").ToLocalChecked(), log_verbosity);
Local<Value> DEBUG(Nan::New<Uint32, uint32_t>(GPR_LOG_SEVERITY_DEBUG));
Nan::Set(log_verbosity, Nan::New("DEBUG").ToLocalChecked(), DEBUG);
Local<Value> INFO(Nan::New<Uint32, uint32_t>(GPR_LOG_SEVERITY_INFO));
Nan::Set(log_verbosity, Nan::New("INFO").ToLocalChecked(), INFO);
Local<Value> LOG_ERROR(Nan::New<Uint32, uint32_t>(GPR_LOG_SEVERITY_ERROR));
Nan::Set(log_verbosity, Nan::New("ERROR").ToLocalChecked(), LOG_ERROR);
}
NAN_METHOD(MetadataKeyIsLegal) {
if (!info[0]->IsString()) {
return Nan::ThrowTypeError(
@ -298,16 +332,101 @@ NAN_METHOD(SetDefaultRootsPem) {
}
}
NAUV_WORK_CB(LogMessagesCallback) {
Nan::HandleScope scope;
std::list<log_args *> args;
uv_mutex_lock(&grpc_logger_state.mutex);
args.splice(args.begin(), *grpc_logger_state.pending_args);
uv_mutex_unlock(&grpc_logger_state.mutex);
/* Call the callback with each log message */
while (!args.empty()) {
log_args *arg = args.front();
args.pop_front();
Local<Value> file = Nan::New(arg->core_args.file).ToLocalChecked();
Local<Value> line = Nan::New<Uint32, uint32_t>(arg->core_args.line);
Local<Value> severity = Nan::New(
gpr_log_severity_string(arg->core_args.severity)).ToLocalChecked();
Local<Value> message = Nan::New(arg->core_args.message).ToLocalChecked();
Local<Value> timestamp = Nan::New<v8::Date>(
grpc::node::TimespecToMilliseconds(arg->timestamp)).ToLocalChecked();
const int argc = 5;
Local<Value> argv[argc] = {file, line, severity, message, timestamp};
grpc_logger_state.callback->Call(argc, argv);
delete[] arg->core_args.message;
delete arg;
}
}
void node_log_func(gpr_log_func_args *args) {
// TODO(mlumish): Use the core's log formatter when it becomes available
log_args *args_copy = new log_args;
size_t message_len = strlen(args->message) + 1;
char *message = new char[message_len];
memcpy(message, args->message, message_len);
memcpy(&args_copy->core_args, args, sizeof(gpr_log_func_args));
args_copy->core_args.message = message;
args_copy->timestamp = gpr_now(GPR_CLOCK_REALTIME);
uv_mutex_lock(&grpc_logger_state.mutex);
grpc_logger_state.pending_args->push_back(args_copy);
uv_mutex_unlock(&grpc_logger_state.mutex);
uv_async_send(&grpc_logger_state.async);
}
void init_logger() {
memset(&grpc_logger_state, 0, sizeof(logger_state));
grpc_logger_state.pending_args = new std::list<log_args *>();
uv_mutex_init(&grpc_logger_state.mutex);
uv_async_init(uv_default_loop(),
&grpc_logger_state.async,
LogMessagesCallback);
uv_unref((uv_handle_t*)&grpc_logger_state.async);
grpc_logger_state.logger_set = false;
gpr_log_verbosity_init();
}
/* This registers a JavaScript logger for messages from the gRPC core. Because
that handler has to be run in the context of the JavaScript event loop, it
will be run asynchronously. To minimize the problems that could cause for
debugging, we leave core to do its default synchronous logging until a
JavaScript logger is set */
NAN_METHOD(SetDefaultLoggerCallback) {
if (!info[0]->IsFunction()) {
return Nan::ThrowTypeError(
"setDefaultLoggerCallback's argument must be a function");
}
if (!grpc_logger_state.logger_set) {
gpr_set_log_function(node_log_func);
grpc_logger_state.logger_set = true;
}
grpc_logger_state.callback = new Nan::Callback(info[0].As<v8::Function>());
}
NAN_METHOD(SetLogVerbosity) {
if (!info[0]->IsUint32()) {
return Nan::ThrowTypeError(
"setLogVerbosity's argument must be a number");
}
gpr_log_severity severity = static_cast<gpr_log_severity>(
Nan::To<uint32_t>(info[0]).FromJust());
gpr_set_log_verbosity(severity);
}
void init(Local<Object> exports) {
Nan::HandleScope scope;
grpc_init();
grpc_set_ssl_roots_override_callback(get_ssl_roots_override);
init_logger();
InitStatusConstants(exports);
InitCallErrorConstants(exports);
InitOpTypeConstants(exports);
InitPropagateConstants(exports);
InitConnectivityStateConstants(exports);
InitWriteFlags(exports);
InitLogConstants(exports);
grpc::node::Call::Init(exports);
grpc::node::CallCredentials::Init(exports);
@ -333,6 +452,14 @@ void init(Local<Object> exports) {
Nan::GetFunction(
Nan::New<FunctionTemplate>(SetDefaultRootsPem)
).ToLocalChecked());
Nan::Set(exports, Nan::New("setDefaultLoggerCallback").ToLocalChecked(),
Nan::GetFunction(
Nan::New<FunctionTemplate>(SetDefaultLoggerCallback)
).ToLocalChecked());
Nan::Set(exports, Nan::New("setLogVerbosity").ToLocalChecked(),
Nan::GetFunction(
Nan::New<FunctionTemplate>(SetLogVerbosity)
).ToLocalChecked());
}
NODE_MODULE(grpc_node, init)

@ -46,6 +46,8 @@ var client = require('./src/client.js');
var server = require('./src/server.js');
var common = require('./src/common.js');
var Metadata = require('./src/metadata.js');
var grpc = require('./src/grpc_extension');
@ -122,6 +124,42 @@ exports.load = function load(filename, format, options) {
return loadObject(builder.ns, options);
};
var log_template = _.template(
'{severity} {timestamp}\t{file}:{line}]\t{message}',
{interpolate: /{([\s\S]+?)}/g});
/**
* Sets the logger function for the gRPC module. For debugging purposes, the C
* core will log synchronously directly to stdout unless this function is
* called. Note: the output format here is intended to be informational, and
* is not guaranteed to stay the same in the future.
* Logs will be directed to logger.error.
* @param {Console} logger A Console-like object.
*/
exports.setLogger = function setLogger(logger) {
common.logger = logger;
grpc.setDefaultLoggerCallback(function(file, line, severity,
message, timestamp) {
logger.error(log_template({
file: path.basename(file),
line: line,
severity: severity,
message: message,
timestamp: timestamp.toISOString()
}));
});
};
/**
* Sets the logger verbosity for gRPC module logging. The options are members
* of the grpc.logVerbosity map.
* @param {Number} verbosity The minimum severity to log
*/
exports.setLogVerbosity = function setLogVerbosity(verbosity) {
common.logVerbosity = verbosity;
grpc.setLogVerbosity(verbosity);
};
/**
* @see module:src/server.Server
*/
@ -152,6 +190,11 @@ exports.callError = grpc.callError;
*/
exports.writeFlags = grpc.writeFlags;
/**
* Log verbosity setting name to code number mapping
*/
exports.logVerbosity = grpc.logVerbosity;
/**
* Credentials factories
*/

@ -157,3 +157,24 @@ exports.getProtobufServiceAttrs = function getProtobufServiceAttrs(service,
}];
}));
};
/**
* The logger object for the gRPC module. Defaults to console.
*/
exports.logger = console;
/**
* The current logging verbosity. 0 corresponds to logging everything
*/
exports.logVerbosity = 0;
/**
* Log a message if the severity is at least as high as the current verbosity
* @param {Number} severity A value of the grpc.logVerbosity map
* @param {String} message The message to log
*/
exports.log = function log(severity, message) {
if (severity >= exports.logVerbosity) {
exports.logger.error(message);
}
};

@ -69,6 +69,8 @@ var ChannelCredentials = grpc.ChannelCredentials;
var Metadata = require('./metadata.js');
var common = require('./common.js');
/**
* Create an SSL Credentials object. If using a client-side certificate, both
* the second and third arguments must be passed.
@ -120,7 +122,7 @@ exports.createFromGoogleCredential = function(google_credential) {
var service_url = auth_context.service_url;
google_credential.getRequestMetadata(service_url, function(err, header) {
if (err) {
console.log('Auth error:', err);
common.log(grpc.logVerbosity.INFO, 'Auth error:' + err);
callback(err);
return;
}

@ -735,8 +735,8 @@ Server.prototype.addService = function(service, implementation) {
}
var impl;
if (implementation[name] === undefined) {
console.warn('Method handler for %s expected but not provided',
attrs.path);
common.log(grpc.logVerbosity.ERROR, 'Method handler for ' +
attrs.path + ' expected but not provided');
impl = defaultHandler[method_type];
} else {
impl = _.bind(implementation[name], implementation);

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save