Merge branch 'master' into async_thread_stress_test

pull/4828/head
Vijay Pai 9 years ago
commit ce7929c877
  1. 10
      .gitignore
  2. 619
      BUILD
  3. 2406
      Makefile
  4. 51
      Rakefile
  5. 191
      binding.gyp
  6. 652
      build.yaml
  7. 35
      doc/statuscodes.md
  8. 4
      examples/cpp/helloworld/Makefile
  9. 4
      examples/cpp/helloworld/greeter_async_server.cc
  10. 208
      gRPC.podspec
  11. 261
      grpc.def
  12. 586
      grpc.gemspec
  13. 11
      include/grpc++/alarm.h
  14. 81
      include/grpc++/channel.h
  15. 299
      include/grpc++/client_context.h
  16. 175
      include/grpc++/completion_queue.h
  17. 5
      include/grpc++/generic/async_generic_service.h
  18. 7
      include/grpc++/generic/generic_stub.h
  19. 547
      include/grpc++/impl/call.h
  20. 39
      include/grpc++/impl/client_unary_call.h
  21. 462
      include/grpc++/impl/codegen/async_stream.h
  22. 156
      include/grpc++/impl/codegen/async_unary_call.h
  23. 578
      include/grpc++/impl/codegen/call.h
  24. 51
      include/grpc++/impl/codegen/call_hook.h
  25. 123
      include/grpc++/impl/codegen/channel_interface.h
  26. 354
      include/grpc++/impl/codegen/client_context.h
  27. 75
      include/grpc++/impl/codegen/client_unary_call.h
  28. 202
      include/grpc++/impl/codegen/completion_queue.h
  29. 52
      include/grpc++/impl/codegen/completion_queue_tag.h
  30. 116
      include/grpc++/impl/codegen/config.h
  31. 72
      include/grpc++/impl/codegen/config_protobuf.h
  32. 67
      include/grpc++/impl/codegen/grpc_library.h
  33. 203
      include/grpc++/impl/codegen/method_handler_impl.h
  34. 76
      include/grpc++/impl/codegen/proto_utils.h
  35. 73
      include/grpc++/impl/codegen/rpc_method.h
  36. 92
      include/grpc++/impl/codegen/rpc_service_method.h
  37. 110
      include/grpc++/impl/codegen/security/auth_context.h
  38. 68
      include/grpc++/impl/codegen/serialization_traits.h
  39. 201
      include/grpc++/impl/codegen/server_context.h
  40. 254
      include/grpc++/impl/codegen/server_interface.h
  41. 161
      include/grpc++/impl/codegen/service_type.h
  42. 76
      include/grpc++/impl/codegen/status.h
  43. 152
      include/grpc++/impl/codegen/status_code_enum.h
  44. 123
      include/grpc++/impl/codegen/string_ref.h
  45. 43
      include/grpc++/impl/codegen/stub_options.h
  46. 45
      include/grpc++/impl/codegen/sync.h
  47. 49
      include/grpc++/impl/codegen/sync_cxx11.h
  48. 105
      include/grpc++/impl/codegen/sync_no_cxx11.h
  49. 415
      include/grpc++/impl/codegen/sync_stream.h
  50. 111
      include/grpc++/impl/codegen/time.h
  51. 26
      include/grpc++/impl/grpc_library.h
  52. 39
      include/grpc++/impl/method_handler_impl.h
  53. 41
      include/grpc++/impl/proto_utils.h
  54. 38
      include/grpc++/impl/rpc_method.h
  55. 232
      include/grpc++/impl/rpc_service_method.h
  56. 33
      include/grpc++/impl/serialization_traits.h
  57. 88
      include/grpc++/impl/service_type.h
  58. 10
      include/grpc++/impl/sync.h
  59. 14
      include/grpc++/impl/sync_cxx11.h
  60. 70
      include/grpc++/impl/sync_no_cxx11.h
  61. 75
      include/grpc++/security/auth_context.h
  62. 15
      include/grpc++/security/credentials.h
  63. 174
      include/grpc++/server.h
  64. 37
      include/grpc++/server_builder.h
  65. 162
      include/grpc++/server_context.h
  66. 426
      include/grpc++/support/async_stream.h
  67. 120
      include/grpc++/support/async_unary_call.h
  68. 81
      include/grpc++/support/config.h
  69. 37
      include/grpc++/support/config_protobuf.h
  70. 41
      include/grpc++/support/status.h
  71. 117
      include/grpc++/support/status_code_enum.h
  72. 88
      include/grpc++/support/string_ref.h
  73. 8
      include/grpc++/support/stub_options.h
  74. 380
      include/grpc++/support/sync_stream.h
  75. 76
      include/grpc++/support/time.h
  76. 85
      include/grpc/byte_buffer.h
  77. 99
      include/grpc/census.h
  78. 52
      include/grpc/compression.h
  79. 520
      include/grpc/grpc.h
  80. 122
      include/grpc/grpc_security.h
  81. 2
      include/grpc/grpc_zookeeper.h
  82. 74
      include/grpc/impl/codegen/alloc.h
  83. 92
      include/grpc/impl/codegen/atm.h
  84. 72
      include/grpc/impl/codegen/atm_gcc_atomic.h
  85. 87
      include/grpc/impl/codegen/atm_gcc_sync.h
  86. 125
      include/grpc/impl/codegen/atm_win32.h
  87. 121
      include/grpc/impl/codegen/byte_buffer.h
  88. 73
      include/grpc/impl/codegen/compression_types.h
  89. 59
      include/grpc/impl/codegen/connectivity_state.h
  90. 373
      include/grpc/impl/codegen/grpc_types.h
  91. 110
      include/grpc/impl/codegen/log.h
  92. 349
      include/grpc/impl/codegen/port_platform.h
  93. 67
      include/grpc/impl/codegen/propagation_bits.h
  94. 182
      include/grpc/impl/codegen/slice.h
  95. 105
      include/grpc/impl/codegen/slice_buffer.h
  96. 163
      include/grpc/impl/codegen/status.h
  97. 315
      include/grpc/impl/codegen/sync.h
  98. 55
      include/grpc/impl/codegen/sync_generic.h
  99. 47
      include/grpc/impl/codegen/sync_posix.h
  100. 49
      include/grpc/impl/codegen/sync_win32.h
  101. Some files were not shown because too many files have changed in this diff Show More

10
.gitignore vendored

@ -5,6 +5,7 @@ libs
objs
# Python items
python_build/
.coverage*
.eggs
.tox
@ -12,6 +13,10 @@ htmlcov/
dist/
*.egg
# Node installation output
node_modules/
src/node/extension_binary/
# gcov coverage data
reports
coverage
@ -40,6 +45,9 @@ coverage
# Makefile's cache
cache.mk
# Ruby's local gem information
Gemfile.lock
# Temporary test reports
report.xml
latency_trace.txt
@ -56,7 +64,7 @@ out
.ycm_extra_conf.py
# XCode
build/
^build/
*.pbxuser
!default.pbxuser
*.mode1v3

619
BUILD

@ -41,100 +41,6 @@ package(default_visibility = ["//visibility:public"])
cc_library(
name = "gpr",
srcs = [
"src/core/profiling/timers.h",
"src/core/support/block_annotate.h",
"src/core/support/env.h",
"src/core/support/file.h",
"src/core/support/murmur_hash.h",
"src/core/support/stack_lockfree.h",
"src/core/support/string.h",
"src/core/support/string_win32.h",
"src/core/support/thd_internal.h",
"src/core/support/time_precise.h",
"src/core/profiling/basic_timers.c",
"src/core/profiling/stap_timers.c",
"src/core/support/alloc.c",
"src/core/support/avl.c",
"src/core/support/cmdline.c",
"src/core/support/cpu_iphone.c",
"src/core/support/cpu_linux.c",
"src/core/support/cpu_posix.c",
"src/core/support/cpu_windows.c",
"src/core/support/env_linux.c",
"src/core/support/env_posix.c",
"src/core/support/env_win32.c",
"src/core/support/file.c",
"src/core/support/file_posix.c",
"src/core/support/file_win32.c",
"src/core/support/histogram.c",
"src/core/support/host_port.c",
"src/core/support/log.c",
"src/core/support/log_android.c",
"src/core/support/log_linux.c",
"src/core/support/log_posix.c",
"src/core/support/log_win32.c",
"src/core/support/murmur_hash.c",
"src/core/support/slice.c",
"src/core/support/slice_buffer.c",
"src/core/support/stack_lockfree.c",
"src/core/support/string.c",
"src/core/support/string_posix.c",
"src/core/support/string_win32.c",
"src/core/support/subprocess_posix.c",
"src/core/support/sync.c",
"src/core/support/sync_posix.c",
"src/core/support/sync_win32.c",
"src/core/support/thd.c",
"src/core/support/thd_posix.c",
"src/core/support/thd_win32.c",
"src/core/support/time.c",
"src/core/support/time_posix.c",
"src/core/support/time_precise.c",
"src/core/support/time_win32.c",
"src/core/support/tls_pthread.c",
],
hdrs = [
"include/grpc/support/alloc.h",
"include/grpc/support/atm.h",
"include/grpc/support/atm_gcc_atomic.h",
"include/grpc/support/atm_gcc_sync.h",
"include/grpc/support/atm_win32.h",
"include/grpc/support/avl.h",
"include/grpc/support/cmdline.h",
"include/grpc/support/cpu.h",
"include/grpc/support/histogram.h",
"include/grpc/support/host_port.h",
"include/grpc/support/log.h",
"include/grpc/support/log_win32.h",
"include/grpc/support/port_platform.h",
"include/grpc/support/slice.h",
"include/grpc/support/slice_buffer.h",
"include/grpc/support/string_util.h",
"include/grpc/support/subprocess.h",
"include/grpc/support/sync.h",
"include/grpc/support/sync_generic.h",
"include/grpc/support/sync_posix.h",
"include/grpc/support/sync_win32.h",
"include/grpc/support/thd.h",
"include/grpc/support/time.h",
"include/grpc/support/tls.h",
"include/grpc/support/tls_gcc.h",
"include/grpc/support/tls_msvc.h",
"include/grpc/support/tls_pthread.h",
"include/grpc/support/useful.h",
],
includes = [
"include",
".",
],
deps = [
],
)
cc_library(
name = "grpc",
srcs = [
@ -265,6 +171,16 @@ cc_library(
"src/core/transport/static_metadata.h",
"src/core/transport/transport.h",
"src/core/transport/transport_impl.h",
"src/core/profiling/timers.h",
"src/core/support/block_annotate.h",
"src/core/support/env.h",
"src/core/support/file.h",
"src/core/support/murmur_hash.h",
"src/core/support/stack_lockfree.h",
"src/core/support/string.h",
"src/core/support/string_win32.h",
"src/core/support/thd_internal.h",
"src/core/support/time_precise.h",
"src/core/census/aggregation.h",
"src/core/census/context.h",
"src/core/census/rpc_metric_id.h",
@ -367,6 +283,7 @@ cc_library(
"src/core/json/json_reader.c",
"src/core/json/json_string.c",
"src/core/json/json_writer.c",
"src/core/surface/alarm.c",
"src/core/surface/api_trace.c",
"src/core/surface/byte_buffer.c",
"src/core/surface/byte_buffer_reader.c",
@ -415,9 +332,53 @@ cc_library(
"src/core/transport/static_metadata.c",
"src/core/transport/transport.c",
"src/core/transport/transport_op_string.c",
"src/core/profiling/basic_timers.c",
"src/core/profiling/stap_timers.c",
"src/core/support/alloc.c",
"src/core/support/avl.c",
"src/core/support/cmdline.c",
"src/core/support/cpu_iphone.c",
"src/core/support/cpu_linux.c",
"src/core/support/cpu_posix.c",
"src/core/support/cpu_windows.c",
"src/core/support/env_linux.c",
"src/core/support/env_posix.c",
"src/core/support/env_win32.c",
"src/core/support/file.c",
"src/core/support/file_posix.c",
"src/core/support/file_win32.c",
"src/core/support/histogram.c",
"src/core/support/host_port.c",
"src/core/support/log.c",
"src/core/support/log_android.c",
"src/core/support/log_linux.c",
"src/core/support/log_posix.c",
"src/core/support/log_win32.c",
"src/core/support/murmur_hash.c",
"src/core/support/slice.c",
"src/core/support/slice_buffer.c",
"src/core/support/stack_lockfree.c",
"src/core/support/string.c",
"src/core/support/string_posix.c",
"src/core/support/string_win32.c",
"src/core/support/subprocess_posix.c",
"src/core/support/subprocess_windows.c",
"src/core/support/sync.c",
"src/core/support/sync_posix.c",
"src/core/support/sync_win32.c",
"src/core/support/thd.c",
"src/core/support/thd_posix.c",
"src/core/support/thd_win32.c",
"src/core/support/time.c",
"src/core/support/time_posix.c",
"src/core/support/time_precise.c",
"src/core/support/time_win32.c",
"src/core/support/tls_pthread.c",
"src/core/support/wrap_memcpy.c",
"src/core/census/context.c",
"src/core/census/initialize.c",
"src/core/census/operation.c",
"src/core/census/placeholders.c",
"src/core/census/tag_set.c",
"src/core/census/tracing.c",
],
@ -428,6 +389,54 @@ cc_library(
"include/grpc/compression.h",
"include/grpc/grpc.h",
"include/grpc/status.h",
"include/grpc/support/alloc.h",
"include/grpc/support/atm.h",
"include/grpc/support/atm_gcc_atomic.h",
"include/grpc/support/atm_gcc_sync.h",
"include/grpc/support/atm_win32.h",
"include/grpc/support/avl.h",
"include/grpc/support/cmdline.h",
"include/grpc/support/cpu.h",
"include/grpc/support/histogram.h",
"include/grpc/support/host_port.h",
"include/grpc/support/log.h",
"include/grpc/support/log_win32.h",
"include/grpc/support/port_platform.h",
"include/grpc/support/slice.h",
"include/grpc/support/slice_buffer.h",
"include/grpc/support/string_util.h",
"include/grpc/support/subprocess.h",
"include/grpc/support/sync.h",
"include/grpc/support/sync_generic.h",
"include/grpc/support/sync_posix.h",
"include/grpc/support/sync_win32.h",
"include/grpc/support/thd.h",
"include/grpc/support/time.h",
"include/grpc/support/tls.h",
"include/grpc/support/tls_gcc.h",
"include/grpc/support/tls_msvc.h",
"include/grpc/support/tls_pthread.h",
"include/grpc/support/useful.h",
"include/grpc/impl/codegen/alloc.h",
"include/grpc/impl/codegen/atm.h",
"include/grpc/impl/codegen/atm_gcc_atomic.h",
"include/grpc/impl/codegen/atm_gcc_sync.h",
"include/grpc/impl/codegen/atm_win32.h",
"include/grpc/impl/codegen/byte_buffer.h",
"include/grpc/impl/codegen/compression_types.h",
"include/grpc/impl/codegen/connectivity_state.h",
"include/grpc/impl/codegen/grpc_types.h",
"include/grpc/impl/codegen/log.h",
"include/grpc/impl/codegen/port_platform.h",
"include/grpc/impl/codegen/propagation_bits.h",
"include/grpc/impl/codegen/slice.h",
"include/grpc/impl/codegen/slice_buffer.h",
"include/grpc/impl/codegen/status.h",
"include/grpc/impl/codegen/sync.h",
"include/grpc/impl/codegen/sync_generic.h",
"include/grpc/impl/codegen/sync_posix.h",
"include/grpc/impl/codegen/sync_win32.h",
"include/grpc/impl/codegen/time.h",
"include/grpc/census.h",
],
includes = [
@ -437,7 +446,6 @@ cc_library(
deps = [
"//external:libssl",
"//external:zlib",
":gpr",
],
copts = [
"-std=gnu99",
@ -448,6 +456,16 @@ cc_library(
cc_library(
name = "grpc_unsecure",
srcs = [
"src/core/profiling/timers.h",
"src/core/support/block_annotate.h",
"src/core/support/env.h",
"src/core/support/file.h",
"src/core/support/murmur_hash.h",
"src/core/support/stack_lockfree.h",
"src/core/support/string.h",
"src/core/support/string_win32.h",
"src/core/support/thd_internal.h",
"src/core/support/time_precise.h",
"src/core/census/grpc_filter.h",
"src/core/channel/channel_args.h",
"src/core/channel/channel_stack.h",
@ -565,6 +583,49 @@ cc_library(
"src/core/census/context.h",
"src/core/census/rpc_metric_id.h",
"src/core/surface/init_unsecure.c",
"src/core/profiling/basic_timers.c",
"src/core/profiling/stap_timers.c",
"src/core/support/alloc.c",
"src/core/support/avl.c",
"src/core/support/cmdline.c",
"src/core/support/cpu_iphone.c",
"src/core/support/cpu_linux.c",
"src/core/support/cpu_posix.c",
"src/core/support/cpu_windows.c",
"src/core/support/env_linux.c",
"src/core/support/env_posix.c",
"src/core/support/env_win32.c",
"src/core/support/file.c",
"src/core/support/file_posix.c",
"src/core/support/file_win32.c",
"src/core/support/histogram.c",
"src/core/support/host_port.c",
"src/core/support/log.c",
"src/core/support/log_android.c",
"src/core/support/log_linux.c",
"src/core/support/log_posix.c",
"src/core/support/log_win32.c",
"src/core/support/murmur_hash.c",
"src/core/support/slice.c",
"src/core/support/slice_buffer.c",
"src/core/support/stack_lockfree.c",
"src/core/support/string.c",
"src/core/support/string_posix.c",
"src/core/support/string_win32.c",
"src/core/support/subprocess_posix.c",
"src/core/support/subprocess_windows.c",
"src/core/support/sync.c",
"src/core/support/sync_posix.c",
"src/core/support/sync_win32.c",
"src/core/support/thd.c",
"src/core/support/thd_posix.c",
"src/core/support/thd_win32.c",
"src/core/support/time.c",
"src/core/support/time_posix.c",
"src/core/support/time_precise.c",
"src/core/support/time_win32.c",
"src/core/support/tls_pthread.c",
"src/core/support/wrap_memcpy.c",
"src/core/census/grpc_context.c",
"src/core/census/grpc_filter.c",
"src/core/channel/channel_args.c",
@ -643,6 +704,7 @@ cc_library(
"src/core/json/json_reader.c",
"src/core/json/json_string.c",
"src/core/json/json_writer.c",
"src/core/surface/alarm.c",
"src/core/surface/api_trace.c",
"src/core/surface/byte_buffer.c",
"src/core/surface/byte_buffer_reader.c",
@ -694,10 +756,59 @@ cc_library(
"src/core/census/context.c",
"src/core/census/initialize.c",
"src/core/census/operation.c",
"src/core/census/placeholders.c",
"src/core/census/tag_set.c",
"src/core/census/tracing.c",
],
hdrs = [
"include/grpc/support/alloc.h",
"include/grpc/support/atm.h",
"include/grpc/support/atm_gcc_atomic.h",
"include/grpc/support/atm_gcc_sync.h",
"include/grpc/support/atm_win32.h",
"include/grpc/support/avl.h",
"include/grpc/support/cmdline.h",
"include/grpc/support/cpu.h",
"include/grpc/support/histogram.h",
"include/grpc/support/host_port.h",
"include/grpc/support/log.h",
"include/grpc/support/log_win32.h",
"include/grpc/support/port_platform.h",
"include/grpc/support/slice.h",
"include/grpc/support/slice_buffer.h",
"include/grpc/support/string_util.h",
"include/grpc/support/subprocess.h",
"include/grpc/support/sync.h",
"include/grpc/support/sync_generic.h",
"include/grpc/support/sync_posix.h",
"include/grpc/support/sync_win32.h",
"include/grpc/support/thd.h",
"include/grpc/support/time.h",
"include/grpc/support/tls.h",
"include/grpc/support/tls_gcc.h",
"include/grpc/support/tls_msvc.h",
"include/grpc/support/tls_pthread.h",
"include/grpc/support/useful.h",
"include/grpc/impl/codegen/alloc.h",
"include/grpc/impl/codegen/atm.h",
"include/grpc/impl/codegen/atm_gcc_atomic.h",
"include/grpc/impl/codegen/atm_gcc_sync.h",
"include/grpc/impl/codegen/atm_win32.h",
"include/grpc/impl/codegen/byte_buffer.h",
"include/grpc/impl/codegen/compression_types.h",
"include/grpc/impl/codegen/connectivity_state.h",
"include/grpc/impl/codegen/grpc_types.h",
"include/grpc/impl/codegen/log.h",
"include/grpc/impl/codegen/port_platform.h",
"include/grpc/impl/codegen/propagation_bits.h",
"include/grpc/impl/codegen/slice.h",
"include/grpc/impl/codegen/slice_buffer.h",
"include/grpc/impl/codegen/status.h",
"include/grpc/impl/codegen/sync.h",
"include/grpc/impl/codegen/sync_generic.h",
"include/grpc/impl/codegen/sync_posix.h",
"include/grpc/impl/codegen/sync_win32.h",
"include/grpc/impl/codegen/time.h",
"include/grpc/byte_buffer.h",
"include/grpc/byte_buffer_reader.h",
"include/grpc/compression.h",
@ -710,7 +821,6 @@ cc_library(
".",
],
deps = [
":gpr",
],
copts = [
"-std=gnu99",
@ -732,7 +842,6 @@ cc_library(
".",
],
deps = [
":gpr",
":grpc",
],
)
@ -781,6 +890,7 @@ cc_library(
"src/cpp/util/status.cc",
"src/cpp/util/string_ref.cc",
"src/cpp/util/time.cc",
"src/cpp/codegen/grpc_library.cc",
],
hdrs = [
"include/grpc++/channel.h",
@ -793,6 +903,7 @@ cc_library(
"include/grpc++/impl/call.h",
"include/grpc++/impl/client_unary_call.h",
"include/grpc++/impl/grpc_library.h",
"include/grpc++/impl/method_handler_impl.h",
"include/grpc++/impl/proto_utils.h",
"include/grpc++/impl/rpc_method.h",
"include/grpc++/impl/rpc_service_method.h",
@ -825,6 +936,36 @@ cc_library(
"include/grpc++/support/stub_options.h",
"include/grpc++/support/sync_stream.h",
"include/grpc++/support/time.h",
"include/grpc++/impl/codegen/async_stream.h",
"include/grpc++/impl/codegen/async_unary_call.h",
"include/grpc++/impl/codegen/call.h",
"include/grpc++/impl/codegen/call_hook.h",
"include/grpc++/impl/codegen/channel_interface.h",
"include/grpc++/impl/codegen/client_context.h",
"include/grpc++/impl/codegen/client_unary_call.h",
"include/grpc++/impl/codegen/completion_queue.h",
"include/grpc++/impl/codegen/completion_queue_tag.h",
"include/grpc++/impl/codegen/config.h",
"include/grpc++/impl/codegen/config_protobuf.h",
"include/grpc++/impl/codegen/grpc_library.h",
"include/grpc++/impl/codegen/method_handler_impl.h",
"include/grpc++/impl/codegen/proto_utils.h",
"include/grpc++/impl/codegen/rpc_method.h",
"include/grpc++/impl/codegen/rpc_service_method.h",
"include/grpc++/impl/codegen/security/auth_context.h",
"include/grpc++/impl/codegen/serialization_traits.h",
"include/grpc++/impl/codegen/server_context.h",
"include/grpc++/impl/codegen/server_interface.h",
"include/grpc++/impl/codegen/service_type.h",
"include/grpc++/impl/codegen/status.h",
"include/grpc++/impl/codegen/status_code_enum.h",
"include/grpc++/impl/codegen/string_ref.h",
"include/grpc++/impl/codegen/stub_options.h",
"include/grpc++/impl/codegen/sync.h",
"include/grpc++/impl/codegen/sync_cxx11.h",
"include/grpc++/impl/codegen/sync_no_cxx11.h",
"include/grpc++/impl/codegen/sync_stream.h",
"include/grpc++/impl/codegen/time.h",
],
includes = [
"include",
@ -833,7 +974,6 @@ cc_library(
deps = [
"//external:libssl",
"//external:protobuf_clib",
":gpr",
":grpc",
],
)
@ -874,6 +1014,7 @@ cc_library(
"src/cpp/util/status.cc",
"src/cpp/util/string_ref.cc",
"src/cpp/util/time.cc",
"src/cpp/codegen/grpc_library.cc",
],
hdrs = [
"include/grpc++/channel.h",
@ -886,6 +1027,7 @@ cc_library(
"include/grpc++/impl/call.h",
"include/grpc++/impl/client_unary_call.h",
"include/grpc++/impl/grpc_library.h",
"include/grpc++/impl/method_handler_impl.h",
"include/grpc++/impl/proto_utils.h",
"include/grpc++/impl/rpc_method.h",
"include/grpc++/impl/rpc_service_method.h",
@ -918,6 +1060,36 @@ cc_library(
"include/grpc++/support/stub_options.h",
"include/grpc++/support/sync_stream.h",
"include/grpc++/support/time.h",
"include/grpc++/impl/codegen/async_stream.h",
"include/grpc++/impl/codegen/async_unary_call.h",
"include/grpc++/impl/codegen/call.h",
"include/grpc++/impl/codegen/call_hook.h",
"include/grpc++/impl/codegen/channel_interface.h",
"include/grpc++/impl/codegen/client_context.h",
"include/grpc++/impl/codegen/client_unary_call.h",
"include/grpc++/impl/codegen/completion_queue.h",
"include/grpc++/impl/codegen/completion_queue_tag.h",
"include/grpc++/impl/codegen/config.h",
"include/grpc++/impl/codegen/config_protobuf.h",
"include/grpc++/impl/codegen/grpc_library.h",
"include/grpc++/impl/codegen/method_handler_impl.h",
"include/grpc++/impl/codegen/proto_utils.h",
"include/grpc++/impl/codegen/rpc_method.h",
"include/grpc++/impl/codegen/rpc_service_method.h",
"include/grpc++/impl/codegen/security/auth_context.h",
"include/grpc++/impl/codegen/serialization_traits.h",
"include/grpc++/impl/codegen/server_context.h",
"include/grpc++/impl/codegen/server_interface.h",
"include/grpc++/impl/codegen/service_type.h",
"include/grpc++/impl/codegen/status.h",
"include/grpc++/impl/codegen/status_code_enum.h",
"include/grpc++/impl/codegen/string_ref.h",
"include/grpc++/impl/codegen/stub_options.h",
"include/grpc++/impl/codegen/sync.h",
"include/grpc++/impl/codegen/sync_cxx11.h",
"include/grpc++/impl/codegen/sync_no_cxx11.h",
"include/grpc++/impl/codegen/sync_stream.h",
"include/grpc++/impl/codegen/time.h",
],
includes = [
"include",
@ -925,7 +1097,6 @@ cc_library(
],
deps = [
"//external:protobuf_clib",
":gpr",
":grpc_unsecure",
],
)
@ -954,8 +1125,59 @@ cc_library(
"src/compiler/objective_c_generator.cc",
"src/compiler/python_generator.cc",
"src/compiler/ruby_generator.cc",
"src/cpp/codegen/grpc_library.cc",
],
hdrs = [
"include/grpc++/impl/codegen/async_stream.h",
"include/grpc++/impl/codegen/async_unary_call.h",
"include/grpc++/impl/codegen/call.h",
"include/grpc++/impl/codegen/call_hook.h",
"include/grpc++/impl/codegen/channel_interface.h",
"include/grpc++/impl/codegen/client_context.h",
"include/grpc++/impl/codegen/client_unary_call.h",
"include/grpc++/impl/codegen/completion_queue.h",
"include/grpc++/impl/codegen/completion_queue_tag.h",
"include/grpc++/impl/codegen/config.h",
"include/grpc++/impl/codegen/config_protobuf.h",
"include/grpc++/impl/codegen/grpc_library.h",
"include/grpc++/impl/codegen/method_handler_impl.h",
"include/grpc++/impl/codegen/proto_utils.h",
"include/grpc++/impl/codegen/rpc_method.h",
"include/grpc++/impl/codegen/rpc_service_method.h",
"include/grpc++/impl/codegen/security/auth_context.h",
"include/grpc++/impl/codegen/serialization_traits.h",
"include/grpc++/impl/codegen/server_context.h",
"include/grpc++/impl/codegen/server_interface.h",
"include/grpc++/impl/codegen/service_type.h",
"include/grpc++/impl/codegen/status.h",
"include/grpc++/impl/codegen/status_code_enum.h",
"include/grpc++/impl/codegen/string_ref.h",
"include/grpc++/impl/codegen/stub_options.h",
"include/grpc++/impl/codegen/sync.h",
"include/grpc++/impl/codegen/sync_cxx11.h",
"include/grpc++/impl/codegen/sync_no_cxx11.h",
"include/grpc++/impl/codegen/sync_stream.h",
"include/grpc++/impl/codegen/time.h",
"include/grpc/impl/codegen/alloc.h",
"include/grpc/impl/codegen/atm.h",
"include/grpc/impl/codegen/atm_gcc_atomic.h",
"include/grpc/impl/codegen/atm_gcc_sync.h",
"include/grpc/impl/codegen/atm_win32.h",
"include/grpc/impl/codegen/byte_buffer.h",
"include/grpc/impl/codegen/compression_types.h",
"include/grpc/impl/codegen/connectivity_state.h",
"include/grpc/impl/codegen/grpc_types.h",
"include/grpc/impl/codegen/log.h",
"include/grpc/impl/codegen/port_platform.h",
"include/grpc/impl/codegen/propagation_bits.h",
"include/grpc/impl/codegen/slice.h",
"include/grpc/impl/codegen/slice_buffer.h",
"include/grpc/impl/codegen/status.h",
"include/grpc/impl/codegen/sync.h",
"include/grpc/impl/codegen/sync_generic.h",
"include/grpc/impl/codegen/sync_posix.h",
"include/grpc/impl/codegen/sync_win32.h",
"include/grpc/impl/codegen/time.h",
],
includes = [
"include",
@ -980,106 +1202,11 @@ cc_library(
],
deps = [
":grpc",
":gpr",
],
)
objc_library(
name = "gpr_objc",
srcs = [
"src/core/profiling/basic_timers.c",
"src/core/profiling/stap_timers.c",
"src/core/support/alloc.c",
"src/core/support/avl.c",
"src/core/support/cmdline.c",
"src/core/support/cpu_iphone.c",
"src/core/support/cpu_linux.c",
"src/core/support/cpu_posix.c",
"src/core/support/cpu_windows.c",
"src/core/support/env_linux.c",
"src/core/support/env_posix.c",
"src/core/support/env_win32.c",
"src/core/support/file.c",
"src/core/support/file_posix.c",
"src/core/support/file_win32.c",
"src/core/support/histogram.c",
"src/core/support/host_port.c",
"src/core/support/log.c",
"src/core/support/log_android.c",
"src/core/support/log_linux.c",
"src/core/support/log_posix.c",
"src/core/support/log_win32.c",
"src/core/support/murmur_hash.c",
"src/core/support/slice.c",
"src/core/support/slice_buffer.c",
"src/core/support/stack_lockfree.c",
"src/core/support/string.c",
"src/core/support/string_posix.c",
"src/core/support/string_win32.c",
"src/core/support/subprocess_posix.c",
"src/core/support/sync.c",
"src/core/support/sync_posix.c",
"src/core/support/sync_win32.c",
"src/core/support/thd.c",
"src/core/support/thd_posix.c",
"src/core/support/thd_win32.c",
"src/core/support/time.c",
"src/core/support/time_posix.c",
"src/core/support/time_precise.c",
"src/core/support/time_win32.c",
"src/core/support/tls_pthread.c",
],
hdrs = [
"include/grpc/support/alloc.h",
"include/grpc/support/atm.h",
"include/grpc/support/atm_gcc_atomic.h",
"include/grpc/support/atm_gcc_sync.h",
"include/grpc/support/atm_win32.h",
"include/grpc/support/avl.h",
"include/grpc/support/cmdline.h",
"include/grpc/support/cpu.h",
"include/grpc/support/histogram.h",
"include/grpc/support/host_port.h",
"include/grpc/support/log.h",
"include/grpc/support/log_win32.h",
"include/grpc/support/port_platform.h",
"include/grpc/support/slice.h",
"include/grpc/support/slice_buffer.h",
"include/grpc/support/string_util.h",
"include/grpc/support/subprocess.h",
"include/grpc/support/sync.h",
"include/grpc/support/sync_generic.h",
"include/grpc/support/sync_posix.h",
"include/grpc/support/sync_win32.h",
"include/grpc/support/thd.h",
"include/grpc/support/time.h",
"include/grpc/support/tls.h",
"include/grpc/support/tls_gcc.h",
"include/grpc/support/tls_msvc.h",
"include/grpc/support/tls_pthread.h",
"include/grpc/support/useful.h",
"src/core/profiling/timers.h",
"src/core/support/block_annotate.h",
"src/core/support/env.h",
"src/core/support/file.h",
"src/core/support/murmur_hash.h",
"src/core/support/stack_lockfree.h",
"src/core/support/string.h",
"src/core/support/string_win32.h",
"src/core/support/thd_internal.h",
"src/core/support/time_precise.h",
],
includes = [
"include",
".",
],
deps = [
],
)
objc_library(
name = "grpc_objc",
srcs = [
@ -1182,6 +1309,7 @@ objc_library(
"src/core/json/json_reader.c",
"src/core/json/json_string.c",
"src/core/json/json_writer.c",
"src/core/surface/alarm.c",
"src/core/surface/api_trace.c",
"src/core/surface/byte_buffer.c",
"src/core/surface/byte_buffer_reader.c",
@ -1230,9 +1358,53 @@ objc_library(
"src/core/transport/static_metadata.c",
"src/core/transport/transport.c",
"src/core/transport/transport_op_string.c",
"src/core/profiling/basic_timers.c",
"src/core/profiling/stap_timers.c",
"src/core/support/alloc.c",
"src/core/support/avl.c",
"src/core/support/cmdline.c",
"src/core/support/cpu_iphone.c",
"src/core/support/cpu_linux.c",
"src/core/support/cpu_posix.c",
"src/core/support/cpu_windows.c",
"src/core/support/env_linux.c",
"src/core/support/env_posix.c",
"src/core/support/env_win32.c",
"src/core/support/file.c",
"src/core/support/file_posix.c",
"src/core/support/file_win32.c",
"src/core/support/histogram.c",
"src/core/support/host_port.c",
"src/core/support/log.c",
"src/core/support/log_android.c",
"src/core/support/log_linux.c",
"src/core/support/log_posix.c",
"src/core/support/log_win32.c",
"src/core/support/murmur_hash.c",
"src/core/support/slice.c",
"src/core/support/slice_buffer.c",
"src/core/support/stack_lockfree.c",
"src/core/support/string.c",
"src/core/support/string_posix.c",
"src/core/support/string_win32.c",
"src/core/support/subprocess_posix.c",
"src/core/support/subprocess_windows.c",
"src/core/support/sync.c",
"src/core/support/sync_posix.c",
"src/core/support/sync_win32.c",
"src/core/support/thd.c",
"src/core/support/thd_posix.c",
"src/core/support/thd_win32.c",
"src/core/support/time.c",
"src/core/support/time_posix.c",
"src/core/support/time_precise.c",
"src/core/support/time_win32.c",
"src/core/support/tls_pthread.c",
"src/core/support/wrap_memcpy.c",
"src/core/census/context.c",
"src/core/census/initialize.c",
"src/core/census/operation.c",
"src/core/census/placeholders.c",
"src/core/census/tag_set.c",
"src/core/census/tracing.c",
],
@ -1243,6 +1415,54 @@ objc_library(
"include/grpc/compression.h",
"include/grpc/grpc.h",
"include/grpc/status.h",
"include/grpc/support/alloc.h",
"include/grpc/support/atm.h",
"include/grpc/support/atm_gcc_atomic.h",
"include/grpc/support/atm_gcc_sync.h",
"include/grpc/support/atm_win32.h",
"include/grpc/support/avl.h",
"include/grpc/support/cmdline.h",
"include/grpc/support/cpu.h",
"include/grpc/support/histogram.h",
"include/grpc/support/host_port.h",
"include/grpc/support/log.h",
"include/grpc/support/log_win32.h",
"include/grpc/support/port_platform.h",
"include/grpc/support/slice.h",
"include/grpc/support/slice_buffer.h",
"include/grpc/support/string_util.h",
"include/grpc/support/subprocess.h",
"include/grpc/support/sync.h",
"include/grpc/support/sync_generic.h",
"include/grpc/support/sync_posix.h",
"include/grpc/support/sync_win32.h",
"include/grpc/support/thd.h",
"include/grpc/support/time.h",
"include/grpc/support/tls.h",
"include/grpc/support/tls_gcc.h",
"include/grpc/support/tls_msvc.h",
"include/grpc/support/tls_pthread.h",
"include/grpc/support/useful.h",
"include/grpc/impl/codegen/alloc.h",
"include/grpc/impl/codegen/atm.h",
"include/grpc/impl/codegen/atm_gcc_atomic.h",
"include/grpc/impl/codegen/atm_gcc_sync.h",
"include/grpc/impl/codegen/atm_win32.h",
"include/grpc/impl/codegen/byte_buffer.h",
"include/grpc/impl/codegen/compression_types.h",
"include/grpc/impl/codegen/connectivity_state.h",
"include/grpc/impl/codegen/grpc_types.h",
"include/grpc/impl/codegen/log.h",
"include/grpc/impl/codegen/port_platform.h",
"include/grpc/impl/codegen/propagation_bits.h",
"include/grpc/impl/codegen/slice.h",
"include/grpc/impl/codegen/slice_buffer.h",
"include/grpc/impl/codegen/status.h",
"include/grpc/impl/codegen/sync.h",
"include/grpc/impl/codegen/sync_generic.h",
"include/grpc/impl/codegen/sync_posix.h",
"include/grpc/impl/codegen/sync_win32.h",
"include/grpc/impl/codegen/time.h",
"include/grpc/census.h",
"src/core/security/auth_filters.h",
"src/core/security/base64.h",
@ -1371,6 +1591,16 @@ objc_library(
"src/core/transport/static_metadata.h",
"src/core/transport/transport.h",
"src/core/transport/transport_impl.h",
"src/core/profiling/timers.h",
"src/core/support/block_annotate.h",
"src/core/support/env.h",
"src/core/support/file.h",
"src/core/support/murmur_hash.h",
"src/core/support/stack_lockfree.h",
"src/core/support/string.h",
"src/core/support/string_win32.h",
"src/core/support/thd_internal.h",
"src/core/support/time_precise.h",
"src/core/census/aggregation.h",
"src/core/census/context.h",
"src/core/census/rpc_metric_id.h",
@ -1380,7 +1610,6 @@ objc_library(
".",
],
deps = [
":gpr_objc",
"//external:libssl_objc",
],
sdk_dylibs = ["libz"],

2406
Makefile

File diff suppressed because it is too large Load Diff

@ -4,17 +4,33 @@ require 'rspec/core/rake_task'
require 'rubocop/rake_task'
require 'bundler/gem_tasks'
load 'tools/distrib/docker_for_windows.rb'
# Add rubocop style checking tasks
RuboCop::RakeTask.new(:rubocop) do |task|
task.options = ['-c', 'src/ruby/.rubocop.yml']
task.patterns = ['src/ruby/{lib,spec}/**/*.rb']
end
spec = Gem::Specification.load('grpc.gemspec')
Gem::PackageTask.new(spec) do |pkg|
end
# Add the extension compiler task
Rake::ExtensionTask.new 'grpc' do |ext|
Rake::ExtensionTask.new('grpc_c', spec) do |ext|
ext.source_pattern = '**/*.{c,h}'
ext.ext_dir = File.join('src', 'ruby', 'ext', 'grpc')
ext.lib_dir = File.join('src', 'ruby', 'lib', 'grpc')
ext.cross_compile = true
ext.cross_platform = ['x86-mingw32', 'x64-mingw32']
ext.cross_compiling do |spec|
spec.files = %w( etc/roots.pem grpc_c.32.ruby grpc_c.64.ruby )
spec.files += Dir.glob('src/ruby/bin/**/*')
spec.files += Dir.glob('src/ruby/ext/**/*')
spec.files += Dir.glob('src/ruby/lib/**/*')
spec.files += Dir.glob('src/ruby/pb/**/*')
end
end
# Define the test suites
@ -51,6 +67,37 @@ namespace :suite do
end
end
desc 'Build the Windows gRPC DLLs for Ruby'
task 'dlls' do
grpc_config = ENV['GRPC_CONFIG'] || 'opt'
verbose = ENV['V'] || '0'
env = 'CPPFLAGS="-D_WIN32_WINNT=0x600 -DUNICODE -D_UNICODE" '
env += 'LDFLAGS=-static '
env += 'SYSTEM=MINGW32 '
env += 'EMBED_ZLIB=true '
env += 'BUILDDIR=/tmp '
env += "V=#{verbose} "
out = '/tmp/libs/opt/grpc-0.dll'
w64 = { cross: 'x86_64-w64-mingw32', out: 'grpc_c.64.ruby' }
w32 = { cross: 'i686-w64-mingw32', out: 'grpc_c.32.ruby' }
[ w64, w32 ].each do |opt|
env_comp = "CC=#{opt[:cross]}-gcc "
env_comp += "LD=#{opt[:cross]}-gcc "
docker_for_windows "#{env} #{env_comp} make -j #{out} && #{opt[:cross]}-strip -x -S #{out} && cp #{out} #{opt[:out]}"
end
end
desc 'Build the gem file under rake_compiler_dock'
task 'gem:windows' do
verbose = ENV['V'] || '0'
docker_for_windows "bundle && rake cross native gem RUBY_CC_VERSION=2.3.0:2.2.2:2.1.6:2.0.0 V=#{verbose}"
end
# Define dependencies between the suites.
task 'suite:wrapper' => [:compile, :rubocop]
task 'suite:idiomatic' => 'suite:wrapper'
@ -58,6 +105,8 @@ task 'suite:bidi' => 'suite:wrapper'
task 'suite:server' => 'suite:wrapper'
task 'suite:pb' => 'suite:server'
task 'gem:windows' => 'dlls'
desc 'Compiles the gRPC extension then runs all the tests'
task all: ['suite:idiomatic', 'suite:bidi', 'suite:pb', 'suite:server']
task default: :all

@ -37,29 +37,45 @@
# Some of this file is built with the help of
# https://n8.io/converting-a-c-library-to-gyp/
{
'variables': {
'config': '<!(echo $CONFIG)'
},
# TODO: Finish windows support
'target_defaults': {
# Empirically, Node only exports ALPN symbols if its major version is >0.
# io.js always reports versions >0 and always exports ALPN symbols.
# Therefore, Node's major version will be truthy if and only if it
# supports ALPN. The output of "node -v" is v[major].[minor].[patch],
# like "v4.1.1" in a recent version. We use cut to split by period and
# take the first field (resulting in "v[major]"), then use cut again
# to take all but the first character, removing the "v".
'defines': [
'TSI_OPENSSL_ALPN_SUPPORT=<!(node --version | cut -d. -f1 | cut -c2-)'
],
'include_dirs': [
'.',
'include'
],
'conditions': [
['OS == "win"', {
"include_dirs": [ "third_party/boringssl/include" ]
}, {
"include_dirs": [ "third_party/boringssl/include" ],
"defines": [
'_WIN32_WINNT=0x0600',
'WIN32_LEAN_AND_MEAN',
'_HAS_EXCEPTIONS=0',
'UNICODE',
'_UNICODE',
'NOMINMAX',
'OPENSSL_NO_ASM'
],
"msvs_settings": {
'VCCLCompilerTool': {
'RuntimeLibrary': 1, # static debug
}
},
"libraries": [
"ws2_32"
]
}, { # OS != "win"
# Empirically, Node only exports ALPN symbols if its major version is >0.
# io.js always reports versions >0 and always exports ALPN symbols.
# Therefore, Node's major version will be truthy if and only if it
# supports ALPN. The output of "node -v" is v[major].[minor].[patch],
# like "v4.1.1" in a recent version. We use cut to split by period and
# take the first field (resulting in "v[major]"), then use cut again
# to take all but the first character, removing the "v".
'defines': [
'TSI_OPENSSL_ALPN_SUPPORT=<!(node --version | cut -d. -f1 | cut -c2-)'
],
'variables': {
'config': '<!(echo $CONFIG)'
},
'include_dirs': [
'<(node_root_dir)/deps/openssl/openssl/include',
'<(node_root_dir)/deps/zlib'
@ -93,6 +109,29 @@
'conditions': [
['OS == "win"', {
'targets': [
{
# IMPORTANT WINDOWS BUILD INFORMATION
# This library does not build on Windows without modifying the Node
# development packages that node-gyp downloads in order to build.
# Due to https://github.com/nodejs/node/issues/4932, the headers for
# BoringSSL conflict with the OpenSSL headers included by default
# when including the Node headers. The remedy for this is to remove
# the OpenSSL headers, from the downloaded Node development package,
# which is typically located in `.node-gyp` in your home directory.
'target_name': 'WINDOWS_BUILD_WARNING',
'actions': [
{
'action_name': 'WINDOWS_BUILD_WARNING',
'inputs': [
'package.json'
],
'outputs': [
'ignore_this_part'
],
'action': ['echo', 'IMPORTANT: Due to https://github.com/nodejs/node/issues/4932, to build this library on Windows, you must first remove <(node_root_dir)/include/node/openssl/']
}
]
},
# Only want to compile BoringSSL and zlib under Windows
{
'cflags': [
@ -400,8 +439,7 @@
'third_party/boringssl/ssl/t1_enc.c',
'third_party/boringssl/ssl/t1_lib.c',
'third_party/boringssl/ssl/tls_record.c',
],
"include_dirs": [ "third_party/boringssl/include" ]
]
},
{
'cflags': [
@ -430,75 +468,12 @@
'third_party/zlib/trees.c',
'third_party/zlib/uncompr.c',
'third_party/zlib/zutil.c',
],
"include_dirs": [ "third_party/boringssl/include" ]
]
},
]
}]
],
'targets': [
{
'cflags': [
'-std=c99',
'-Wall',
'-Werror'
],
'target_name': 'gpr',
'product_prefix': 'lib',
'type': 'static_library',
'dependencies': [
],
'sources': [
'src/core/profiling/basic_timers.c',
'src/core/profiling/stap_timers.c',
'src/core/support/alloc.c',
'src/core/support/avl.c',
'src/core/support/cmdline.c',
'src/core/support/cpu_iphone.c',
'src/core/support/cpu_linux.c',
'src/core/support/cpu_posix.c',
'src/core/support/cpu_windows.c',
'src/core/support/env_linux.c',
'src/core/support/env_posix.c',
'src/core/support/env_win32.c',
'src/core/support/file.c',
'src/core/support/file_posix.c',
'src/core/support/file_win32.c',
'src/core/support/histogram.c',
'src/core/support/host_port.c',
'src/core/support/log.c',
'src/core/support/log_android.c',
'src/core/support/log_linux.c',
'src/core/support/log_posix.c',
'src/core/support/log_win32.c',
'src/core/support/murmur_hash.c',
'src/core/support/slice.c',
'src/core/support/slice_buffer.c',
'src/core/support/stack_lockfree.c',
'src/core/support/string.c',
'src/core/support/string_posix.c',
'src/core/support/string_win32.c',
'src/core/support/subprocess_posix.c',
'src/core/support/sync.c',
'src/core/support/sync_posix.c',
'src/core/support/sync_win32.c',
'src/core/support/thd.c',
'src/core/support/thd_posix.c',
'src/core/support/thd_win32.c',
'src/core/support/time.c',
'src/core/support/time_posix.c',
'src/core/support/time_precise.c',
'src/core/support/time_win32.c',
'src/core/support/tls_pthread.c',
],
"conditions": [
['OS == "mac"', {
'xcode_settings': {
'MACOSX_DEPLOYMENT_TARGET': '10.9'
}
}]
]
},
{
'cflags': [
'-std=c99',
@ -509,7 +484,6 @@
'product_prefix': 'lib',
'type': 'static_library',
'dependencies': [
'gpr',
],
'sources': [
'src/core/httpcli/httpcli_security_connector.c',
@ -611,6 +585,7 @@
'src/core/json/json_reader.c',
'src/core/json/json_string.c',
'src/core/json/json_writer.c',
'src/core/surface/alarm.c',
'src/core/surface/api_trace.c',
'src/core/surface/byte_buffer.c',
'src/core/surface/byte_buffer_reader.c',
@ -659,9 +634,53 @@
'src/core/transport/static_metadata.c',
'src/core/transport/transport.c',
'src/core/transport/transport_op_string.c',
'src/core/profiling/basic_timers.c',
'src/core/profiling/stap_timers.c',
'src/core/support/alloc.c',
'src/core/support/avl.c',
'src/core/support/cmdline.c',
'src/core/support/cpu_iphone.c',
'src/core/support/cpu_linux.c',
'src/core/support/cpu_posix.c',
'src/core/support/cpu_windows.c',
'src/core/support/env_linux.c',
'src/core/support/env_posix.c',
'src/core/support/env_win32.c',
'src/core/support/file.c',
'src/core/support/file_posix.c',
'src/core/support/file_win32.c',
'src/core/support/histogram.c',
'src/core/support/host_port.c',
'src/core/support/log.c',
'src/core/support/log_android.c',
'src/core/support/log_linux.c',
'src/core/support/log_posix.c',
'src/core/support/log_win32.c',
'src/core/support/murmur_hash.c',
'src/core/support/slice.c',
'src/core/support/slice_buffer.c',
'src/core/support/stack_lockfree.c',
'src/core/support/string.c',
'src/core/support/string_posix.c',
'src/core/support/string_win32.c',
'src/core/support/subprocess_posix.c',
'src/core/support/subprocess_windows.c',
'src/core/support/sync.c',
'src/core/support/sync_posix.c',
'src/core/support/sync_win32.c',
'src/core/support/thd.c',
'src/core/support/thd_posix.c',
'src/core/support/thd_win32.c',
'src/core/support/time.c',
'src/core/support/time_posix.c',
'src/core/support/time_precise.c',
'src/core/support/time_win32.c',
'src/core/support/tls_pthread.c',
'src/core/support/wrap_memcpy.c',
'src/core/census/context.c',
'src/core/census/initialize.c',
'src/core/census/operation.c',
'src/core/census/placeholders.c',
'src/core/census/tag_set.c',
'src/core/census/tracing.c',
],
@ -703,6 +722,11 @@
"boringssl",
"z",
]
}],
['OS=="linux"', {
'ldflags': [
'-Wl,-wrap,memcpy'
]
}]
],
"target_name": "grpc_node",
@ -720,7 +744,6 @@
],
"dependencies": [
"grpc",
"gpr",
]
},
{

File diff suppressed because it is too large Load Diff

@ -0,0 +1,35 @@
# Status codes and their use in gRPC
gRPC uses a set of well defined status codes as part of the RPC API. All RPCs started at a client return a `status` object composed of an integer `code` and a string `message`. The server-side can choose the status it returns for a given RPC.
The gRPC client and server-side implementations may also generate and return `status` on their own when errors happen.
Only a subset of the pre-defined status codes are generated by the gRPC libraries. The following table lists these codes and summarizes the situations in which they are generated, either by the client or the server-side library implementation.
| Case | Code | Generated at Client or Server |
| ------------- |:-------------| :-----:|
| Client Application cancelled the request | CANCELLED | Both |
| Deadline expires before server returns status | DEADLINE_EXCEEDED | Both |
| Method not found at server | UNIMPLEMENTED | Server|
| Server shutting down | UNAVAILABLE | Server|
| Server side application throws an exception (or does something other than returning a Status code to terminate an RPC) | UNKNOWN | Server|
| No response received before Deadline expires. This may occur either when the client is unable to send the request to the server or when the server fails to respond in time. | DEADLINE_EXCEEDED | Both|
| Some data transmitted (e.g., request metadata written to TCP connection) before connection breaks | UNAVAILABLE | Client |
| Could not decompress, but compression algorithm supported (Client -> Server) | INTERNAL | Server |
| Could not decompress, but compression algorithm supported (Server -> Client) | INTERNAL | Client |
| Compression mechanism used by client not supported at server | UNIMPLEMENTED | Server |
| Server temporarily out of resources (e.g., Flow-control resource limits reached) | RESOURCE_EXHAUSTED | Server|
| Flow-control protocol violation | INTERNAL | Both |
| Error parsing returned status | UNKNOWN | Client |
| Incorrect Auth metadata ( Credentials failed to get metadata, Incompatible credentials set on channel and call, Invalid host set in `:authority` metadata, etc.) | UNAUTHENTICATED | Both |
| Error parsing response proto | INTERNAL | Client|
| Error parsing request proto | INTERNAL | Server|
The following status codes are never generated by the library:
- INVALID_ARGUMENT
- NOT_FOUND
- ALREADY_EXISTS
- FAILED_PRECONDITION
- ABORTED
- OUT_OF_RANGE
- DATA_LOSS

@ -1,5 +1,5 @@
#
# Copyright 2015, Google Inc.
# Copyright 2015-2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@ -55,9 +55,11 @@ greeter_async_client: helloworld.pb.o helloworld.grpc.pb.o greeter_async_client.
greeter_async_server: helloworld.pb.o helloworld.grpc.pb.o greeter_async_server.o
$(CXX) $^ $(LDFLAGS) -o $@
.PRECIOUS: %.grpc.pb.cc
%.grpc.pb.cc: %.proto
$(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $<
.PRECIOUS: %.pb.cc
%.pb.cc: %.proto
$(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $<

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -67,7 +67,7 @@ class ServerImpl final {
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
// Register "service_" as the instance through which we'll communicate with
// clients. In this case it corresponds to an *asynchronous* service.
builder.RegisterAsyncService(&service_);
builder.RegisterService(&service_);
// Get hold of the completion queue used for the asynchronous communication
// with the gRPC runtime.
cq_ = builder.AddCompletionQueue();

@ -63,86 +63,7 @@ Pod::Spec.new do |s|
# Core cross-platform gRPC library, written in C.
s.subspec 'C-Core' do |ss|
ss.source_files = 'src/core/profiling/timers.h',
'src/core/support/block_annotate.h',
'src/core/support/env.h',
'src/core/support/file.h',
'src/core/support/murmur_hash.h',
'src/core/support/stack_lockfree.h',
'src/core/support/string.h',
'src/core/support/string_win32.h',
'src/core/support/thd_internal.h',
'src/core/support/time_precise.h',
'include/grpc/support/alloc.h',
'include/grpc/support/atm.h',
'include/grpc/support/atm_gcc_atomic.h',
'include/grpc/support/atm_gcc_sync.h',
'include/grpc/support/atm_win32.h',
'include/grpc/support/avl.h',
'include/grpc/support/cmdline.h',
'include/grpc/support/cpu.h',
'include/grpc/support/histogram.h',
'include/grpc/support/host_port.h',
'include/grpc/support/log.h',
'include/grpc/support/log_win32.h',
'include/grpc/support/port_platform.h',
'include/grpc/support/slice.h',
'include/grpc/support/slice_buffer.h',
'include/grpc/support/string_util.h',
'include/grpc/support/subprocess.h',
'include/grpc/support/sync.h',
'include/grpc/support/sync_generic.h',
'include/grpc/support/sync_posix.h',
'include/grpc/support/sync_win32.h',
'include/grpc/support/thd.h',
'include/grpc/support/time.h',
'include/grpc/support/tls.h',
'include/grpc/support/tls_gcc.h',
'include/grpc/support/tls_msvc.h',
'include/grpc/support/tls_pthread.h',
'include/grpc/support/useful.h',
'src/core/profiling/basic_timers.c',
'src/core/profiling/stap_timers.c',
'src/core/support/alloc.c',
'src/core/support/avl.c',
'src/core/support/cmdline.c',
'src/core/support/cpu_iphone.c',
'src/core/support/cpu_linux.c',
'src/core/support/cpu_posix.c',
'src/core/support/cpu_windows.c',
'src/core/support/env_linux.c',
'src/core/support/env_posix.c',
'src/core/support/env_win32.c',
'src/core/support/file.c',
'src/core/support/file_posix.c',
'src/core/support/file_win32.c',
'src/core/support/histogram.c',
'src/core/support/host_port.c',
'src/core/support/log.c',
'src/core/support/log_android.c',
'src/core/support/log_linux.c',
'src/core/support/log_posix.c',
'src/core/support/log_win32.c',
'src/core/support/murmur_hash.c',
'src/core/support/slice.c',
'src/core/support/slice_buffer.c',
'src/core/support/stack_lockfree.c',
'src/core/support/string.c',
'src/core/support/string_posix.c',
'src/core/support/string_win32.c',
'src/core/support/subprocess_posix.c',
'src/core/support/sync.c',
'src/core/support/sync_posix.c',
'src/core/support/sync_win32.c',
'src/core/support/thd.c',
'src/core/support/thd_posix.c',
'src/core/support/thd_win32.c',
'src/core/support/time.c',
'src/core/support/time_posix.c',
'src/core/support/time_precise.c',
'src/core/support/time_win32.c',
'src/core/support/tls_pthread.c',
'src/core/security/auth_filters.h',
ss.source_files = 'src/core/security/auth_filters.h',
'src/core/security/base64.h',
'src/core/security/credentials.h',
'src/core/security/handshake.h',
@ -269,6 +190,16 @@ Pod::Spec.new do |s|
'src/core/transport/static_metadata.h',
'src/core/transport/transport.h',
'src/core/transport/transport_impl.h',
'src/core/profiling/timers.h',
'src/core/support/block_annotate.h',
'src/core/support/env.h',
'src/core/support/file.h',
'src/core/support/murmur_hash.h',
'src/core/support/stack_lockfree.h',
'src/core/support/string.h',
'src/core/support/string_win32.h',
'src/core/support/thd_internal.h',
'src/core/support/time_precise.h',
'src/core/census/aggregation.h',
'src/core/census/context.h',
'src/core/census/rpc_metric_id.h',
@ -278,6 +209,54 @@ Pod::Spec.new do |s|
'include/grpc/compression.h',
'include/grpc/grpc.h',
'include/grpc/status.h',
'include/grpc/support/alloc.h',
'include/grpc/support/atm.h',
'include/grpc/support/atm_gcc_atomic.h',
'include/grpc/support/atm_gcc_sync.h',
'include/grpc/support/atm_win32.h',
'include/grpc/support/avl.h',
'include/grpc/support/cmdline.h',
'include/grpc/support/cpu.h',
'include/grpc/support/histogram.h',
'include/grpc/support/host_port.h',
'include/grpc/support/log.h',
'include/grpc/support/log_win32.h',
'include/grpc/support/port_platform.h',
'include/grpc/support/slice.h',
'include/grpc/support/slice_buffer.h',
'include/grpc/support/string_util.h',
'include/grpc/support/subprocess.h',
'include/grpc/support/sync.h',
'include/grpc/support/sync_generic.h',
'include/grpc/support/sync_posix.h',
'include/grpc/support/sync_win32.h',
'include/grpc/support/thd.h',
'include/grpc/support/time.h',
'include/grpc/support/tls.h',
'include/grpc/support/tls_gcc.h',
'include/grpc/support/tls_msvc.h',
'include/grpc/support/tls_pthread.h',
'include/grpc/support/useful.h',
'include/grpc/impl/codegen/alloc.h',
'include/grpc/impl/codegen/atm.h',
'include/grpc/impl/codegen/atm_gcc_atomic.h',
'include/grpc/impl/codegen/atm_gcc_sync.h',
'include/grpc/impl/codegen/atm_win32.h',
'include/grpc/impl/codegen/byte_buffer.h',
'include/grpc/impl/codegen/compression_types.h',
'include/grpc/impl/codegen/connectivity_state.h',
'include/grpc/impl/codegen/grpc_types.h',
'include/grpc/impl/codegen/log.h',
'include/grpc/impl/codegen/port_platform.h',
'include/grpc/impl/codegen/propagation_bits.h',
'include/grpc/impl/codegen/slice.h',
'include/grpc/impl/codegen/slice_buffer.h',
'include/grpc/impl/codegen/status.h',
'include/grpc/impl/codegen/sync.h',
'include/grpc/impl/codegen/sync_generic.h',
'include/grpc/impl/codegen/sync_posix.h',
'include/grpc/impl/codegen/sync_win32.h',
'include/grpc/impl/codegen/time.h',
'include/grpc/census.h',
'src/core/httpcli/httpcli_security_connector.c',
'src/core/security/base64.c',
@ -378,6 +357,7 @@ Pod::Spec.new do |s|
'src/core/json/json_reader.c',
'src/core/json/json_string.c',
'src/core/json/json_writer.c',
'src/core/surface/alarm.c',
'src/core/surface/api_trace.c',
'src/core/surface/byte_buffer.c',
'src/core/surface/byte_buffer_reader.c',
@ -426,23 +406,57 @@ Pod::Spec.new do |s|
'src/core/transport/static_metadata.c',
'src/core/transport/transport.c',
'src/core/transport/transport_op_string.c',
'src/core/profiling/basic_timers.c',
'src/core/profiling/stap_timers.c',
'src/core/support/alloc.c',
'src/core/support/avl.c',
'src/core/support/cmdline.c',
'src/core/support/cpu_iphone.c',
'src/core/support/cpu_linux.c',
'src/core/support/cpu_posix.c',
'src/core/support/cpu_windows.c',
'src/core/support/env_linux.c',
'src/core/support/env_posix.c',
'src/core/support/env_win32.c',
'src/core/support/file.c',
'src/core/support/file_posix.c',
'src/core/support/file_win32.c',
'src/core/support/histogram.c',
'src/core/support/host_port.c',
'src/core/support/log.c',
'src/core/support/log_android.c',
'src/core/support/log_linux.c',
'src/core/support/log_posix.c',
'src/core/support/log_win32.c',
'src/core/support/murmur_hash.c',
'src/core/support/slice.c',
'src/core/support/slice_buffer.c',
'src/core/support/stack_lockfree.c',
'src/core/support/string.c',
'src/core/support/string_posix.c',
'src/core/support/string_win32.c',
'src/core/support/subprocess_posix.c',
'src/core/support/subprocess_windows.c',
'src/core/support/sync.c',
'src/core/support/sync_posix.c',
'src/core/support/sync_win32.c',
'src/core/support/thd.c',
'src/core/support/thd_posix.c',
'src/core/support/thd_win32.c',
'src/core/support/time.c',
'src/core/support/time_posix.c',
'src/core/support/time_precise.c',
'src/core/support/time_win32.c',
'src/core/support/tls_pthread.c',
'src/core/support/wrap_memcpy.c',
'src/core/census/context.c',
'src/core/census/initialize.c',
'src/core/census/operation.c',
'src/core/census/placeholders.c',
'src/core/census/tag_set.c',
'src/core/census/tracing.c'
ss.private_header_files = 'src/core/profiling/timers.h',
'src/core/support/block_annotate.h',
'src/core/support/env.h',
'src/core/support/file.h',
'src/core/support/murmur_hash.h',
'src/core/support/stack_lockfree.h',
'src/core/support/string.h',
'src/core/support/string_win32.h',
'src/core/support/thd_internal.h',
'src/core/support/time_precise.h',
'src/core/security/auth_filters.h',
ss.private_header_files = 'src/core/security/auth_filters.h',
'src/core/security/base64.h',
'src/core/security/credentials.h',
'src/core/security/handshake.h',
@ -569,6 +583,16 @@ Pod::Spec.new do |s|
'src/core/transport/static_metadata.h',
'src/core/transport/transport.h',
'src/core/transport/transport_impl.h',
'src/core/profiling/timers.h',
'src/core/support/block_annotate.h',
'src/core/support/env.h',
'src/core/support/file.h',
'src/core/support/murmur_hash.h',
'src/core/support/stack_lockfree.h',
'src/core/support/string.h',
'src/core/support/string_win32.h',
'src/core/support/thd_internal.h',
'src/core/support/time_precise.h',
'src/core/census/aggregation.h',
'src/core/census/context.h',
'src/core/census/rpc_metric_id.h'
@ -585,7 +609,7 @@ Pod::Spec.new do |s|
ss.requires_arc = false
ss.libraries = 'z'
ss.dependency 'BoringSSL', '~> 1.0'
ss.dependency 'BoringSSL', '~> 2.0'
# ss.compiler_flags = '-GCC_WARN_INHIBIT_ALL_WARNINGS', '-w'
end

@ -0,0 +1,261 @@
EXPORTS
census_initialize
census_shutdown
census_supported
census_enabled
census_context_serialize
census_trace_mask
census_set_trace_mask
census_start_rpc_op_timestamp
census_start_client_rpc_op
census_set_rpc_client_peer
census_start_server_rpc_op
census_start_op
census_end_op
census_trace_print
census_trace_scan_start
census_get_trace_record
census_trace_scan_end
census_tag_set_create
census_tag_set_destroy
census_tag_set_get_create_status
census_tag_set_initialize_iterator
census_tag_set_next_tag
census_tag_set_get_tag_by_key
census_tag_set_encode
census_tag_set_decode
census_context_tag_set
census_record_values
census_view_create
census_view_delete
census_view_metric
census_view_naggregations
census_view_tags
census_view_aggregrations
census_view_get_data
census_view_reset
grpc_compression_algorithm_parse
grpc_compression_algorithm_name
grpc_compression_algorithm_for_level
grpc_compression_options_init
grpc_compression_options_enable_algorithm
grpc_compression_options_disable_algorithm
grpc_compression_options_is_algorithm_enabled
grpc_metadata_array_init
grpc_metadata_array_destroy
grpc_call_details_init
grpc_call_details_destroy
grpc_register_plugin
grpc_init
grpc_shutdown
grpc_version_string
grpc_completion_queue_create
grpc_completion_queue_next
grpc_completion_queue_pluck
grpc_completion_queue_shutdown
grpc_completion_queue_destroy
grpc_alarm_create
grpc_alarm_cancel
grpc_alarm_destroy
grpc_channel_check_connectivity_state
grpc_channel_watch_connectivity_state
grpc_channel_create_call
grpc_channel_ping
grpc_channel_register_call
grpc_channel_create_registered_call
grpc_call_start_batch
grpc_call_get_peer
grpc_census_call_set_context
grpc_census_call_get_context
grpc_channel_get_target
grpc_insecure_channel_create
grpc_lame_client_channel_create
grpc_channel_destroy
grpc_call_cancel
grpc_call_cancel_with_status
grpc_call_destroy
grpc_server_request_call
grpc_server_register_method
grpc_server_request_registered_call
grpc_server_create
grpc_server_register_completion_queue
grpc_server_add_insecure_http2_port
grpc_server_start
grpc_server_shutdown_and_notify
grpc_server_cancel_all_calls
grpc_server_destroy
grpc_tracer_set_enabled
grpc_header_key_is_legal
grpc_header_nonbin_value_is_legal
grpc_is_binary_header
grpc_auth_property_iterator_next
grpc_auth_context_property_iterator
grpc_auth_context_peer_identity
grpc_auth_context_find_properties_by_name
grpc_auth_context_peer_identity_property_name
grpc_auth_context_peer_is_authenticated
grpc_call_auth_context
grpc_auth_context_release
grpc_auth_context_add_property
grpc_auth_context_add_cstring_property
grpc_auth_context_set_peer_identity_property_name
grpc_channel_credentials_release
grpc_google_default_credentials_create
grpc_ssl_credentials_create
grpc_call_credentials_release
grpc_composite_channel_credentials_create
grpc_composite_call_credentials_create
grpc_google_compute_engine_credentials_create
grpc_max_auth_token_lifetime
grpc_service_account_jwt_access_credentials_create
grpc_google_refresh_token_credentials_create
grpc_access_token_credentials_create
grpc_google_iam_credentials_create
grpc_metadata_credentials_create_from_plugin
grpc_secure_channel_create
grpc_server_credentials_release
grpc_ssl_server_credentials_create
grpc_server_add_secure_http2_port
grpc_call_set_credentials
grpc_server_credentials_set_auth_metadata_processor
gpr_malloc
gpr_free
gpr_realloc
gpr_malloc_aligned
gpr_free_aligned
gpr_set_allocation_functions
gpr_get_allocation_functions
grpc_raw_byte_buffer_create
grpc_raw_compressed_byte_buffer_create
grpc_byte_buffer_copy
grpc_byte_buffer_length
grpc_byte_buffer_destroy
grpc_byte_buffer_reader_init
grpc_byte_buffer_reader_destroy
grpc_byte_buffer_reader_next
grpc_byte_buffer_reader_readall
grpc_raw_byte_buffer_from_reader
gpr_log
gpr_log_message
gpr_set_log_function
gpr_slice_ref
gpr_slice_unref
gpr_slice_new
gpr_slice_new_with_len
gpr_slice_malloc
gpr_slice_from_copied_string
gpr_slice_from_copied_buffer
gpr_slice_from_static_string
gpr_slice_sub
gpr_slice_sub_no_ref
gpr_slice_split_tail
gpr_slice_split_head
gpr_empty_slice
gpr_slice_cmp
gpr_slice_str_cmp
gpr_slice_buffer_init
gpr_slice_buffer_destroy
gpr_slice_buffer_add
gpr_slice_buffer_add_indexed
gpr_slice_buffer_addn
gpr_slice_buffer_tiny_add
gpr_slice_buffer_pop
gpr_slice_buffer_reset_and_unref
gpr_slice_buffer_swap
gpr_slice_buffer_move_into
gpr_slice_buffer_trim_end
gpr_slice_buffer_move_first
gpr_slice_buffer_take_first
gpr_mu_init
gpr_mu_destroy
gpr_mu_lock
gpr_mu_unlock
gpr_mu_trylock
gpr_cv_init
gpr_cv_destroy
gpr_cv_wait
gpr_cv_signal
gpr_cv_broadcast
gpr_once_init
gpr_event_init
gpr_event_set
gpr_event_get
gpr_event_wait
gpr_ref_init
gpr_ref
gpr_refn
gpr_unref
gpr_stats_init
gpr_stats_inc
gpr_stats_read
gpr_time_0
gpr_inf_future
gpr_inf_past
gpr_time_init
gpr_now
gpr_convert_clock_type
gpr_time_cmp
gpr_time_max
gpr_time_min
gpr_time_add
gpr_time_sub
gpr_time_from_micros
gpr_time_from_nanos
gpr_time_from_millis
gpr_time_from_seconds
gpr_time_from_minutes
gpr_time_from_hours
gpr_time_to_millis
gpr_time_similar
gpr_sleep_until
gpr_timespec_to_micros
gpr_avl_create
gpr_avl_ref
gpr_avl_unref
gpr_avl_add
gpr_avl_remove
gpr_avl_get
gpr_cmdline_create
gpr_cmdline_add_int
gpr_cmdline_add_flag
gpr_cmdline_add_string
gpr_cmdline_on_extra_arg
gpr_cmdline_set_survive_failure
gpr_cmdline_parse
gpr_cmdline_destroy
gpr_cmdline_usage_string
gpr_cpu_num_cores
gpr_cpu_current_cpu
gpr_histogram_create
gpr_histogram_destroy
gpr_histogram_add
gpr_histogram_merge
gpr_histogram_percentile
gpr_histogram_mean
gpr_histogram_stddev
gpr_histogram_variance
gpr_histogram_maximum
gpr_histogram_minimum
gpr_histogram_count
gpr_histogram_sum
gpr_histogram_sum_of_squares
gpr_histogram_get_contents
gpr_histogram_merge_contents
gpr_join_host_port
gpr_split_host_port
gpr_format_message
gpr_strdup
gpr_asprintf
gpr_subprocess_binary_extension
gpr_subprocess_create
gpr_subprocess_destroy
gpr_subprocess_join
gpr_subprocess_interrupt
gpr_thd_new
gpr_thd_options_default
gpr_thd_options_set_detached
gpr_thd_options_set_joinable
gpr_thd_options_is_detached
gpr_thd_options_is_joinable
gpr_thd_currentid
gpr_thd_join

@ -16,7 +16,7 @@ Gem::Specification.new do |s|
s.required_ruby_version = '>= 2.0.0'
s.requirements << 'libgrpc ~> 0.11.0 needs to be installed'
s.files = %w( Rakefile Makefile )
s.files = %w( Makefile )
s.files += %w( etc/roots.pem )
s.files += Dir.glob('src/ruby/bin/**/*')
s.files += Dir.glob('src/ruby/ext/**/*')
@ -33,19 +33,26 @@ Gem::Specification.new do |s|
s.platform = Gem::Platform::RUBY
s.add_dependency 'google-protobuf', '~> 3.0.0alpha.1.1'
s.add_dependency 'googleauth', '~> 0.5.1'
s.add_dependency 'googleauth', '~> 0.5.1'
s.add_development_dependency 'bundler', '~> 1.9'
s.add_development_dependency 'logging', '~> 2.0'
s.add_development_dependency 'simplecov', '~> 0.9'
s.add_development_dependency 'rake', '~> 10.4'
s.add_development_dependency 'rake-compiler', '~> 0.9'
s.add_development_dependency 'rspec', '~> 3.2'
s.add_development_dependency 'rubocop', '~> 0.30.0'
s.add_development_dependency 'signet', '~>0.7.0'
s.add_development_dependency 'bundler', '~> 1.9'
s.add_development_dependency 'logging', '~> 2.0'
s.add_development_dependency 'simplecov', '~> 0.9'
s.add_development_dependency 'rake', '~> 10.4'
s.add_development_dependency 'rake-compiler', '~> 0.9'
s.add_development_dependency 'rake-compiler-dock', '~> 0.5'
s.add_development_dependency 'rspec', '~> 3.2'
s.add_development_dependency 'rubocop', '~> 0.30.0'
s.add_development_dependency 'signet', '~> 0.7.0'
s.extensions = %w(src/ruby/ext/grpc/extconf.rb)
s.files += %w( include/grpc/grpc_security.h )
s.files += %w( include/grpc/byte_buffer.h )
s.files += %w( include/grpc/byte_buffer_reader.h )
s.files += %w( include/grpc/compression.h )
s.files += %w( include/grpc/grpc.h )
s.files += %w( include/grpc/status.h )
s.files += %w( include/grpc/support/alloc.h )
s.files += %w( include/grpc/support/atm.h )
s.files += %w( include/grpc/support/atm_gcc_atomic.h )
@ -74,63 +81,26 @@ Gem::Specification.new do |s|
s.files += %w( include/grpc/support/tls_msvc.h )
s.files += %w( include/grpc/support/tls_pthread.h )
s.files += %w( include/grpc/support/useful.h )
s.files += %w( src/core/profiling/timers.h )
s.files += %w( src/core/support/block_annotate.h )
s.files += %w( src/core/support/env.h )
s.files += %w( src/core/support/file.h )
s.files += %w( src/core/support/murmur_hash.h )
s.files += %w( src/core/support/stack_lockfree.h )
s.files += %w( src/core/support/string.h )
s.files += %w( src/core/support/string_win32.h )
s.files += %w( src/core/support/thd_internal.h )
s.files += %w( src/core/support/time_precise.h )
s.files += %w( src/core/profiling/basic_timers.c )
s.files += %w( src/core/profiling/stap_timers.c )
s.files += %w( src/core/support/alloc.c )
s.files += %w( src/core/support/avl.c )
s.files += %w( src/core/support/cmdline.c )
s.files += %w( src/core/support/cpu_iphone.c )
s.files += %w( src/core/support/cpu_linux.c )
s.files += %w( src/core/support/cpu_posix.c )
s.files += %w( src/core/support/cpu_windows.c )
s.files += %w( src/core/support/env_linux.c )
s.files += %w( src/core/support/env_posix.c )
s.files += %w( src/core/support/env_win32.c )
s.files += %w( src/core/support/file.c )
s.files += %w( src/core/support/file_posix.c )
s.files += %w( src/core/support/file_win32.c )
s.files += %w( src/core/support/histogram.c )
s.files += %w( src/core/support/host_port.c )
s.files += %w( src/core/support/log.c )
s.files += %w( src/core/support/log_android.c )
s.files += %w( src/core/support/log_linux.c )
s.files += %w( src/core/support/log_posix.c )
s.files += %w( src/core/support/log_win32.c )
s.files += %w( src/core/support/murmur_hash.c )
s.files += %w( src/core/support/slice.c )
s.files += %w( src/core/support/slice_buffer.c )
s.files += %w( src/core/support/stack_lockfree.c )
s.files += %w( src/core/support/string.c )
s.files += %w( src/core/support/string_posix.c )
s.files += %w( src/core/support/string_win32.c )
s.files += %w( src/core/support/subprocess_posix.c )
s.files += %w( src/core/support/sync.c )
s.files += %w( src/core/support/sync_posix.c )
s.files += %w( src/core/support/sync_win32.c )
s.files += %w( src/core/support/thd.c )
s.files += %w( src/core/support/thd_posix.c )
s.files += %w( src/core/support/thd_win32.c )
s.files += %w( src/core/support/time.c )
s.files += %w( src/core/support/time_posix.c )
s.files += %w( src/core/support/time_precise.c )
s.files += %w( src/core/support/time_win32.c )
s.files += %w( src/core/support/tls_pthread.c )
s.files += %w( include/grpc/grpc_security.h )
s.files += %w( include/grpc/byte_buffer.h )
s.files += %w( include/grpc/byte_buffer_reader.h )
s.files += %w( include/grpc/compression.h )
s.files += %w( include/grpc/grpc.h )
s.files += %w( include/grpc/status.h )
s.files += %w( include/grpc/impl/codegen/alloc.h )
s.files += %w( include/grpc/impl/codegen/atm.h )
s.files += %w( include/grpc/impl/codegen/atm_gcc_atomic.h )
s.files += %w( include/grpc/impl/codegen/atm_gcc_sync.h )
s.files += %w( include/grpc/impl/codegen/atm_win32.h )
s.files += %w( include/grpc/impl/codegen/byte_buffer.h )
s.files += %w( include/grpc/impl/codegen/compression_types.h )
s.files += %w( include/grpc/impl/codegen/connectivity_state.h )
s.files += %w( include/grpc/impl/codegen/grpc_types.h )
s.files += %w( include/grpc/impl/codegen/log.h )
s.files += %w( include/grpc/impl/codegen/port_platform.h )
s.files += %w( include/grpc/impl/codegen/propagation_bits.h )
s.files += %w( include/grpc/impl/codegen/slice.h )
s.files += %w( include/grpc/impl/codegen/slice_buffer.h )
s.files += %w( include/grpc/impl/codegen/status.h )
s.files += %w( include/grpc/impl/codegen/sync.h )
s.files += %w( include/grpc/impl/codegen/sync_generic.h )
s.files += %w( include/grpc/impl/codegen/sync_posix.h )
s.files += %w( include/grpc/impl/codegen/sync_win32.h )
s.files += %w( include/grpc/impl/codegen/time.h )
s.files += %w( include/grpc/census.h )
s.files += %w( src/core/security/auth_filters.h )
s.files += %w( src/core/security/base64.h )
@ -259,6 +229,16 @@ Gem::Specification.new do |s|
s.files += %w( src/core/transport/static_metadata.h )
s.files += %w( src/core/transport/transport.h )
s.files += %w( src/core/transport/transport_impl.h )
s.files += %w( src/core/profiling/timers.h )
s.files += %w( src/core/support/block_annotate.h )
s.files += %w( src/core/support/env.h )
s.files += %w( src/core/support/file.h )
s.files += %w( src/core/support/murmur_hash.h )
s.files += %w( src/core/support/stack_lockfree.h )
s.files += %w( src/core/support/string.h )
s.files += %w( src/core/support/string_win32.h )
s.files += %w( src/core/support/thd_internal.h )
s.files += %w( src/core/support/time_precise.h )
s.files += %w( src/core/census/aggregation.h )
s.files += %w( src/core/census/context.h )
s.files += %w( src/core/census/rpc_metric_id.h )
@ -361,6 +341,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/json/json_reader.c )
s.files += %w( src/core/json/json_string.c )
s.files += %w( src/core/json/json_writer.c )
s.files += %w( src/core/surface/alarm.c )
s.files += %w( src/core/surface/api_trace.c )
s.files += %w( src/core/surface/byte_buffer.c )
s.files += %w( src/core/surface/byte_buffer_reader.c )
@ -409,9 +390,480 @@ Gem::Specification.new do |s|
s.files += %w( src/core/transport/static_metadata.c )
s.files += %w( src/core/transport/transport.c )
s.files += %w( src/core/transport/transport_op_string.c )
s.files += %w( src/core/profiling/basic_timers.c )
s.files += %w( src/core/profiling/stap_timers.c )
s.files += %w( src/core/support/alloc.c )
s.files += %w( src/core/support/avl.c )
s.files += %w( src/core/support/cmdline.c )
s.files += %w( src/core/support/cpu_iphone.c )
s.files += %w( src/core/support/cpu_linux.c )
s.files += %w( src/core/support/cpu_posix.c )
s.files += %w( src/core/support/cpu_windows.c )
s.files += %w( src/core/support/env_linux.c )
s.files += %w( src/core/support/env_posix.c )
s.files += %w( src/core/support/env_win32.c )
s.files += %w( src/core/support/file.c )
s.files += %w( src/core/support/file_posix.c )
s.files += %w( src/core/support/file_win32.c )
s.files += %w( src/core/support/histogram.c )
s.files += %w( src/core/support/host_port.c )
s.files += %w( src/core/support/log.c )
s.files += %w( src/core/support/log_android.c )
s.files += %w( src/core/support/log_linux.c )
s.files += %w( src/core/support/log_posix.c )
s.files += %w( src/core/support/log_win32.c )
s.files += %w( src/core/support/murmur_hash.c )
s.files += %w( src/core/support/slice.c )
s.files += %w( src/core/support/slice_buffer.c )
s.files += %w( src/core/support/stack_lockfree.c )
s.files += %w( src/core/support/string.c )
s.files += %w( src/core/support/string_posix.c )
s.files += %w( src/core/support/string_win32.c )
s.files += %w( src/core/support/subprocess_posix.c )
s.files += %w( src/core/support/subprocess_windows.c )
s.files += %w( src/core/support/sync.c )
s.files += %w( src/core/support/sync_posix.c )
s.files += %w( src/core/support/sync_win32.c )
s.files += %w( src/core/support/thd.c )
s.files += %w( src/core/support/thd_posix.c )
s.files += %w( src/core/support/thd_win32.c )
s.files += %w( src/core/support/time.c )
s.files += %w( src/core/support/time_posix.c )
s.files += %w( src/core/support/time_precise.c )
s.files += %w( src/core/support/time_win32.c )
s.files += %w( src/core/support/tls_pthread.c )
s.files += %w( src/core/support/wrap_memcpy.c )
s.files += %w( src/core/census/context.c )
s.files += %w( src/core/census/initialize.c )
s.files += %w( src/core/census/operation.c )
s.files += %w( src/core/census/placeholders.c )
s.files += %w( src/core/census/tag_set.c )
s.files += %w( src/core/census/tracing.c )
s.files += %w( third_party/boringssl/crypto/aes/internal.h )
s.files += %w( third_party/boringssl/crypto/asn1/asn1_locl.h )
s.files += %w( third_party/boringssl/crypto/bio/internal.h )
s.files += %w( third_party/boringssl/crypto/bn/internal.h )
s.files += %w( third_party/boringssl/crypto/bn/rsaz_exp.h )
s.files += %w( third_party/boringssl/crypto/bytestring/internal.h )
s.files += %w( third_party/boringssl/crypto/cipher/internal.h )
s.files += %w( third_party/boringssl/crypto/conf/conf_def.h )
s.files += %w( third_party/boringssl/crypto/conf/internal.h )
s.files += %w( third_party/boringssl/crypto/des/internal.h )
s.files += %w( third_party/boringssl/crypto/dh/internal.h )
s.files += %w( third_party/boringssl/crypto/digest/internal.h )
s.files += %w( third_party/boringssl/crypto/digest/md32_common.h )
s.files += %w( third_party/boringssl/crypto/directory.h )
s.files += %w( third_party/boringssl/crypto/dsa/internal.h )
s.files += %w( third_party/boringssl/crypto/ec/internal.h )
s.files += %w( third_party/boringssl/crypto/ec/p256-x86_64-table.h )
s.files += %w( third_party/boringssl/crypto/evp/internal.h )
s.files += %w( third_party/boringssl/crypto/internal.h )
s.files += %w( third_party/boringssl/crypto/modes/internal.h )
s.files += %w( third_party/boringssl/crypto/obj/obj_dat.h )
s.files += %w( third_party/boringssl/crypto/obj/obj_xref.h )
s.files += %w( third_party/boringssl/crypto/pkcs8/internal.h )
s.files += %w( third_party/boringssl/crypto/rand/internal.h )
s.files += %w( third_party/boringssl/crypto/rsa/internal.h )
s.files += %w( third_party/boringssl/crypto/test/scoped_types.h )
s.files += %w( third_party/boringssl/crypto/test/test_util.h )
s.files += %w( third_party/boringssl/crypto/x509/charmap.h )
s.files += %w( third_party/boringssl/crypto/x509/vpm_int.h )
s.files += %w( third_party/boringssl/crypto/x509v3/ext_dat.h )
s.files += %w( third_party/boringssl/crypto/x509v3/pcy_int.h )
s.files += %w( third_party/boringssl/include/openssl/aead.h )
s.files += %w( third_party/boringssl/include/openssl/aes.h )
s.files += %w( third_party/boringssl/include/openssl/arm_arch.h )
s.files += %w( third_party/boringssl/include/openssl/asn1.h )
s.files += %w( third_party/boringssl/include/openssl/asn1_mac.h )
s.files += %w( third_party/boringssl/include/openssl/asn1t.h )
s.files += %w( third_party/boringssl/include/openssl/base.h )
s.files += %w( third_party/boringssl/include/openssl/base64.h )
s.files += %w( third_party/boringssl/include/openssl/bio.h )
s.files += %w( third_party/boringssl/include/openssl/blowfish.h )
s.files += %w( third_party/boringssl/include/openssl/bn.h )
s.files += %w( third_party/boringssl/include/openssl/buf.h )
s.files += %w( third_party/boringssl/include/openssl/buffer.h )
s.files += %w( third_party/boringssl/include/openssl/bytestring.h )
s.files += %w( third_party/boringssl/include/openssl/cast.h )
s.files += %w( third_party/boringssl/include/openssl/chacha.h )
s.files += %w( third_party/boringssl/include/openssl/cipher.h )
s.files += %w( third_party/boringssl/include/openssl/cmac.h )
s.files += %w( third_party/boringssl/include/openssl/conf.h )
s.files += %w( third_party/boringssl/include/openssl/cpu.h )
s.files += %w( third_party/boringssl/include/openssl/crypto.h )
s.files += %w( third_party/boringssl/include/openssl/curve25519.h )
s.files += %w( third_party/boringssl/include/openssl/des.h )
s.files += %w( third_party/boringssl/include/openssl/dh.h )
s.files += %w( third_party/boringssl/include/openssl/digest.h )
s.files += %w( third_party/boringssl/include/openssl/dsa.h )
s.files += %w( third_party/boringssl/include/openssl/dtls1.h )
s.files += %w( third_party/boringssl/include/openssl/ec.h )
s.files += %w( third_party/boringssl/include/openssl/ec_key.h )
s.files += %w( third_party/boringssl/include/openssl/ecdh.h )
s.files += %w( third_party/boringssl/include/openssl/ecdsa.h )
s.files += %w( third_party/boringssl/include/openssl/engine.h )
s.files += %w( third_party/boringssl/include/openssl/err.h )
s.files += %w( third_party/boringssl/include/openssl/evp.h )
s.files += %w( third_party/boringssl/include/openssl/ex_data.h )
s.files += %w( third_party/boringssl/include/openssl/hkdf.h )
s.files += %w( third_party/boringssl/include/openssl/hmac.h )
s.files += %w( third_party/boringssl/include/openssl/lhash.h )
s.files += %w( third_party/boringssl/include/openssl/lhash_macros.h )
s.files += %w( third_party/boringssl/include/openssl/md4.h )
s.files += %w( third_party/boringssl/include/openssl/md5.h )
s.files += %w( third_party/boringssl/include/openssl/mem.h )
s.files += %w( third_party/boringssl/include/openssl/obj.h )
s.files += %w( third_party/boringssl/include/openssl/obj_mac.h )
s.files += %w( third_party/boringssl/include/openssl/objects.h )
s.files += %w( third_party/boringssl/include/openssl/opensslfeatures.h )
s.files += %w( third_party/boringssl/include/openssl/opensslv.h )
s.files += %w( third_party/boringssl/include/openssl/ossl_typ.h )
s.files += %w( third_party/boringssl/include/openssl/pem.h )
s.files += %w( third_party/boringssl/include/openssl/pkcs12.h )
s.files += %w( third_party/boringssl/include/openssl/pkcs7.h )
s.files += %w( third_party/boringssl/include/openssl/pkcs8.h )
s.files += %w( third_party/boringssl/include/openssl/poly1305.h )
s.files += %w( third_party/boringssl/include/openssl/pqueue.h )
s.files += %w( third_party/boringssl/include/openssl/rand.h )
s.files += %w( third_party/boringssl/include/openssl/rc4.h )
s.files += %w( third_party/boringssl/include/openssl/rsa.h )
s.files += %w( third_party/boringssl/include/openssl/safestack.h )
s.files += %w( third_party/boringssl/include/openssl/sha.h )
s.files += %w( third_party/boringssl/include/openssl/srtp.h )
s.files += %w( third_party/boringssl/include/openssl/ssl.h )
s.files += %w( third_party/boringssl/include/openssl/ssl3.h )
s.files += %w( third_party/boringssl/include/openssl/stack.h )
s.files += %w( third_party/boringssl/include/openssl/stack_macros.h )
s.files += %w( third_party/boringssl/include/openssl/thread.h )
s.files += %w( third_party/boringssl/include/openssl/time_support.h )
s.files += %w( third_party/boringssl/include/openssl/tls1.h )
s.files += %w( third_party/boringssl/include/openssl/type_check.h )
s.files += %w( third_party/boringssl/include/openssl/x509.h )
s.files += %w( third_party/boringssl/include/openssl/x509_vfy.h )
s.files += %w( third_party/boringssl/include/openssl/x509v3.h )
s.files += %w( third_party/boringssl/ssl/internal.h )
s.files += %w( third_party/boringssl/ssl/test/async_bio.h )
s.files += %w( third_party/boringssl/ssl/test/packeted_bio.h )
s.files += %w( third_party/boringssl/ssl/test/scoped_types.h )
s.files += %w( third_party/boringssl/ssl/test/test_config.h )
s.files += %w( src/boringssl/err_data.c )
s.files += %w( third_party/boringssl/crypto/aes/aes.c )
s.files += %w( third_party/boringssl/crypto/aes/mode_wrappers.c )
s.files += %w( third_party/boringssl/crypto/asn1/a_bitstr.c )
s.files += %w( third_party/boringssl/crypto/asn1/a_bool.c )
s.files += %w( third_party/boringssl/crypto/asn1/a_bytes.c )
s.files += %w( third_party/boringssl/crypto/asn1/a_d2i_fp.c )
s.files += %w( third_party/boringssl/crypto/asn1/a_dup.c )
s.files += %w( third_party/boringssl/crypto/asn1/a_enum.c )
s.files += %w( third_party/boringssl/crypto/asn1/a_gentm.c )
s.files += %w( third_party/boringssl/crypto/asn1/a_i2d_fp.c )
s.files += %w( third_party/boringssl/crypto/asn1/a_int.c )
s.files += %w( third_party/boringssl/crypto/asn1/a_mbstr.c )
s.files += %w( third_party/boringssl/crypto/asn1/a_object.c )
s.files += %w( third_party/boringssl/crypto/asn1/a_octet.c )
s.files += %w( third_party/boringssl/crypto/asn1/a_print.c )
s.files += %w( third_party/boringssl/crypto/asn1/a_strnid.c )
s.files += %w( third_party/boringssl/crypto/asn1/a_time.c )
s.files += %w( third_party/boringssl/crypto/asn1/a_type.c )
s.files += %w( third_party/boringssl/crypto/asn1/a_utctm.c )
s.files += %w( third_party/boringssl/crypto/asn1/a_utf8.c )
s.files += %w( third_party/boringssl/crypto/asn1/asn1_lib.c )
s.files += %w( third_party/boringssl/crypto/asn1/asn1_par.c )
s.files += %w( third_party/boringssl/crypto/asn1/asn_pack.c )
s.files += %w( third_party/boringssl/crypto/asn1/bio_asn1.c )
s.files += %w( third_party/boringssl/crypto/asn1/bio_ndef.c )
s.files += %w( third_party/boringssl/crypto/asn1/f_enum.c )
s.files += %w( third_party/boringssl/crypto/asn1/f_int.c )
s.files += %w( third_party/boringssl/crypto/asn1/f_string.c )
s.files += %w( third_party/boringssl/crypto/asn1/t_bitst.c )
s.files += %w( third_party/boringssl/crypto/asn1/t_pkey.c )
s.files += %w( third_party/boringssl/crypto/asn1/tasn_dec.c )
s.files += %w( third_party/boringssl/crypto/asn1/tasn_enc.c )
s.files += %w( third_party/boringssl/crypto/asn1/tasn_fre.c )
s.files += %w( third_party/boringssl/crypto/asn1/tasn_new.c )
s.files += %w( third_party/boringssl/crypto/asn1/tasn_prn.c )
s.files += %w( third_party/boringssl/crypto/asn1/tasn_typ.c )
s.files += %w( third_party/boringssl/crypto/asn1/tasn_utl.c )
s.files += %w( third_party/boringssl/crypto/asn1/x_bignum.c )
s.files += %w( third_party/boringssl/crypto/asn1/x_long.c )
s.files += %w( third_party/boringssl/crypto/base64/base64.c )
s.files += %w( third_party/boringssl/crypto/bio/bio.c )
s.files += %w( third_party/boringssl/crypto/bio/bio_mem.c )
s.files += %w( third_party/boringssl/crypto/bio/buffer.c )
s.files += %w( third_party/boringssl/crypto/bio/connect.c )
s.files += %w( third_party/boringssl/crypto/bio/fd.c )
s.files += %w( third_party/boringssl/crypto/bio/file.c )
s.files += %w( third_party/boringssl/crypto/bio/hexdump.c )
s.files += %w( third_party/boringssl/crypto/bio/pair.c )
s.files += %w( third_party/boringssl/crypto/bio/printf.c )
s.files += %w( third_party/boringssl/crypto/bio/socket.c )
s.files += %w( third_party/boringssl/crypto/bio/socket_helper.c )
s.files += %w( third_party/boringssl/crypto/bn/add.c )
s.files += %w( third_party/boringssl/crypto/bn/asm/x86_64-gcc.c )
s.files += %w( third_party/boringssl/crypto/bn/bn.c )
s.files += %w( third_party/boringssl/crypto/bn/bn_asn1.c )
s.files += %w( third_party/boringssl/crypto/bn/cmp.c )
s.files += %w( third_party/boringssl/crypto/bn/convert.c )
s.files += %w( third_party/boringssl/crypto/bn/ctx.c )
s.files += %w( third_party/boringssl/crypto/bn/div.c )
s.files += %w( third_party/boringssl/crypto/bn/exponentiation.c )
s.files += %w( third_party/boringssl/crypto/bn/gcd.c )
s.files += %w( third_party/boringssl/crypto/bn/generic.c )
s.files += %w( third_party/boringssl/crypto/bn/kronecker.c )
s.files += %w( third_party/boringssl/crypto/bn/montgomery.c )
s.files += %w( third_party/boringssl/crypto/bn/mul.c )
s.files += %w( third_party/boringssl/crypto/bn/prime.c )
s.files += %w( third_party/boringssl/crypto/bn/random.c )
s.files += %w( third_party/boringssl/crypto/bn/rsaz_exp.c )
s.files += %w( third_party/boringssl/crypto/bn/shift.c )
s.files += %w( third_party/boringssl/crypto/bn/sqrt.c )
s.files += %w( third_party/boringssl/crypto/buf/buf.c )
s.files += %w( third_party/boringssl/crypto/bytestring/ber.c )
s.files += %w( third_party/boringssl/crypto/bytestring/cbb.c )
s.files += %w( third_party/boringssl/crypto/bytestring/cbs.c )
s.files += %w( third_party/boringssl/crypto/chacha/chacha_generic.c )
s.files += %w( third_party/boringssl/crypto/chacha/chacha_vec.c )
s.files += %w( third_party/boringssl/crypto/cipher/aead.c )
s.files += %w( third_party/boringssl/crypto/cipher/cipher.c )
s.files += %w( third_party/boringssl/crypto/cipher/derive_key.c )
s.files += %w( third_party/boringssl/crypto/cipher/e_aes.c )
s.files += %w( third_party/boringssl/crypto/cipher/e_chacha20poly1305.c )
s.files += %w( third_party/boringssl/crypto/cipher/e_des.c )
s.files += %w( third_party/boringssl/crypto/cipher/e_null.c )
s.files += %w( third_party/boringssl/crypto/cipher/e_rc2.c )
s.files += %w( third_party/boringssl/crypto/cipher/e_rc4.c )
s.files += %w( third_party/boringssl/crypto/cipher/e_ssl3.c )
s.files += %w( third_party/boringssl/crypto/cipher/e_tls.c )
s.files += %w( third_party/boringssl/crypto/cipher/tls_cbc.c )
s.files += %w( third_party/boringssl/crypto/cmac/cmac.c )
s.files += %w( third_party/boringssl/crypto/conf/conf.c )
s.files += %w( third_party/boringssl/crypto/cpu-arm.c )
s.files += %w( third_party/boringssl/crypto/cpu-intel.c )
s.files += %w( third_party/boringssl/crypto/crypto.c )
s.files += %w( third_party/boringssl/crypto/curve25519/curve25519.c )
s.files += %w( third_party/boringssl/crypto/des/des.c )
s.files += %w( third_party/boringssl/crypto/dh/check.c )
s.files += %w( third_party/boringssl/crypto/dh/dh.c )
s.files += %w( third_party/boringssl/crypto/dh/dh_asn1.c )
s.files += %w( third_party/boringssl/crypto/dh/params.c )
s.files += %w( third_party/boringssl/crypto/digest/digest.c )
s.files += %w( third_party/boringssl/crypto/digest/digests.c )
s.files += %w( third_party/boringssl/crypto/directory_posix.c )
s.files += %w( third_party/boringssl/crypto/directory_win.c )
s.files += %w( third_party/boringssl/crypto/dsa/dsa.c )
s.files += %w( third_party/boringssl/crypto/dsa/dsa_asn1.c )
s.files += %w( third_party/boringssl/crypto/ec/ec.c )
s.files += %w( third_party/boringssl/crypto/ec/ec_asn1.c )
s.files += %w( third_party/boringssl/crypto/ec/ec_key.c )
s.files += %w( third_party/boringssl/crypto/ec/ec_montgomery.c )
s.files += %w( third_party/boringssl/crypto/ec/oct.c )
s.files += %w( third_party/boringssl/crypto/ec/p224-64.c )
s.files += %w( third_party/boringssl/crypto/ec/p256-64.c )
s.files += %w( third_party/boringssl/crypto/ec/p256-x86_64.c )
s.files += %w( third_party/boringssl/crypto/ec/simple.c )
s.files += %w( third_party/boringssl/crypto/ec/util-64.c )
s.files += %w( third_party/boringssl/crypto/ec/wnaf.c )
s.files += %w( third_party/boringssl/crypto/ecdh/ecdh.c )
s.files += %w( third_party/boringssl/crypto/ecdsa/ecdsa.c )
s.files += %w( third_party/boringssl/crypto/ecdsa/ecdsa_asn1.c )
s.files += %w( third_party/boringssl/crypto/engine/engine.c )
s.files += %w( third_party/boringssl/crypto/err/err.c )
s.files += %w( third_party/boringssl/crypto/evp/algorithm.c )
s.files += %w( third_party/boringssl/crypto/evp/digestsign.c )
s.files += %w( third_party/boringssl/crypto/evp/evp.c )
s.files += %w( third_party/boringssl/crypto/evp/evp_asn1.c )
s.files += %w( third_party/boringssl/crypto/evp/evp_ctx.c )
s.files += %w( third_party/boringssl/crypto/evp/p_dsa_asn1.c )
s.files += %w( third_party/boringssl/crypto/evp/p_ec.c )
s.files += %w( third_party/boringssl/crypto/evp/p_ec_asn1.c )
s.files += %w( third_party/boringssl/crypto/evp/p_rsa.c )
s.files += %w( third_party/boringssl/crypto/evp/p_rsa_asn1.c )
s.files += %w( third_party/boringssl/crypto/evp/pbkdf.c )
s.files += %w( third_party/boringssl/crypto/evp/sign.c )
s.files += %w( third_party/boringssl/crypto/ex_data.c )
s.files += %w( third_party/boringssl/crypto/hkdf/hkdf.c )
s.files += %w( third_party/boringssl/crypto/hmac/hmac.c )
s.files += %w( third_party/boringssl/crypto/lhash/lhash.c )
s.files += %w( third_party/boringssl/crypto/md4/md4.c )
s.files += %w( third_party/boringssl/crypto/md5/md5.c )
s.files += %w( third_party/boringssl/crypto/mem.c )
s.files += %w( third_party/boringssl/crypto/modes/cbc.c )
s.files += %w( third_party/boringssl/crypto/modes/cfb.c )
s.files += %w( third_party/boringssl/crypto/modes/ctr.c )
s.files += %w( third_party/boringssl/crypto/modes/gcm.c )
s.files += %w( third_party/boringssl/crypto/modes/ofb.c )
s.files += %w( third_party/boringssl/crypto/obj/obj.c )
s.files += %w( third_party/boringssl/crypto/obj/obj_xref.c )
s.files += %w( third_party/boringssl/crypto/pem/pem_all.c )
s.files += %w( third_party/boringssl/crypto/pem/pem_info.c )
s.files += %w( third_party/boringssl/crypto/pem/pem_lib.c )
s.files += %w( third_party/boringssl/crypto/pem/pem_oth.c )
s.files += %w( third_party/boringssl/crypto/pem/pem_pk8.c )
s.files += %w( third_party/boringssl/crypto/pem/pem_pkey.c )
s.files += %w( third_party/boringssl/crypto/pem/pem_x509.c )
s.files += %w( third_party/boringssl/crypto/pem/pem_xaux.c )
s.files += %w( third_party/boringssl/crypto/pkcs8/p5_pbe.c )
s.files += %w( third_party/boringssl/crypto/pkcs8/p5_pbev2.c )
s.files += %w( third_party/boringssl/crypto/pkcs8/p8_pkey.c )
s.files += %w( third_party/boringssl/crypto/pkcs8/pkcs8.c )
s.files += %w( third_party/boringssl/crypto/poly1305/poly1305.c )
s.files += %w( third_party/boringssl/crypto/poly1305/poly1305_arm.c )
s.files += %w( third_party/boringssl/crypto/poly1305/poly1305_vec.c )
s.files += %w( third_party/boringssl/crypto/rand/rand.c )
s.files += %w( third_party/boringssl/crypto/rand/urandom.c )
s.files += %w( third_party/boringssl/crypto/rand/windows.c )
s.files += %w( third_party/boringssl/crypto/rc4/rc4.c )
s.files += %w( third_party/boringssl/crypto/refcount_c11.c )
s.files += %w( third_party/boringssl/crypto/refcount_lock.c )
s.files += %w( third_party/boringssl/crypto/rsa/blinding.c )
s.files += %w( third_party/boringssl/crypto/rsa/padding.c )
s.files += %w( third_party/boringssl/crypto/rsa/rsa.c )
s.files += %w( third_party/boringssl/crypto/rsa/rsa_asn1.c )
s.files += %w( third_party/boringssl/crypto/rsa/rsa_impl.c )
s.files += %w( third_party/boringssl/crypto/sha/sha1.c )
s.files += %w( third_party/boringssl/crypto/sha/sha256.c )
s.files += %w( third_party/boringssl/crypto/sha/sha512.c )
s.files += %w( third_party/boringssl/crypto/stack/stack.c )
s.files += %w( third_party/boringssl/crypto/thread.c )
s.files += %w( third_party/boringssl/crypto/thread_none.c )
s.files += %w( third_party/boringssl/crypto/thread_pthread.c )
s.files += %w( third_party/boringssl/crypto/thread_win.c )
s.files += %w( third_party/boringssl/crypto/time_support.c )
s.files += %w( third_party/boringssl/crypto/x509/a_digest.c )
s.files += %w( third_party/boringssl/crypto/x509/a_sign.c )
s.files += %w( third_party/boringssl/crypto/x509/a_strex.c )
s.files += %w( third_party/boringssl/crypto/x509/a_verify.c )
s.files += %w( third_party/boringssl/crypto/x509/asn1_gen.c )
s.files += %w( third_party/boringssl/crypto/x509/by_dir.c )
s.files += %w( third_party/boringssl/crypto/x509/by_file.c )
s.files += %w( third_party/boringssl/crypto/x509/i2d_pr.c )
s.files += %w( third_party/boringssl/crypto/x509/pkcs7.c )
s.files += %w( third_party/boringssl/crypto/x509/t_crl.c )
s.files += %w( third_party/boringssl/crypto/x509/t_req.c )
s.files += %w( third_party/boringssl/crypto/x509/t_x509.c )
s.files += %w( third_party/boringssl/crypto/x509/t_x509a.c )
s.files += %w( third_party/boringssl/crypto/x509/x509.c )
s.files += %w( third_party/boringssl/crypto/x509/x509_att.c )
s.files += %w( third_party/boringssl/crypto/x509/x509_cmp.c )
s.files += %w( third_party/boringssl/crypto/x509/x509_d2.c )
s.files += %w( third_party/boringssl/crypto/x509/x509_def.c )
s.files += %w( third_party/boringssl/crypto/x509/x509_ext.c )
s.files += %w( third_party/boringssl/crypto/x509/x509_lu.c )
s.files += %w( third_party/boringssl/crypto/x509/x509_obj.c )
s.files += %w( third_party/boringssl/crypto/x509/x509_r2x.c )
s.files += %w( third_party/boringssl/crypto/x509/x509_req.c )
s.files += %w( third_party/boringssl/crypto/x509/x509_set.c )
s.files += %w( third_party/boringssl/crypto/x509/x509_trs.c )
s.files += %w( third_party/boringssl/crypto/x509/x509_txt.c )
s.files += %w( third_party/boringssl/crypto/x509/x509_v3.c )
s.files += %w( third_party/boringssl/crypto/x509/x509_vfy.c )
s.files += %w( third_party/boringssl/crypto/x509/x509_vpm.c )
s.files += %w( third_party/boringssl/crypto/x509/x509cset.c )
s.files += %w( third_party/boringssl/crypto/x509/x509name.c )
s.files += %w( third_party/boringssl/crypto/x509/x509rset.c )
s.files += %w( third_party/boringssl/crypto/x509/x509spki.c )
s.files += %w( third_party/boringssl/crypto/x509/x509type.c )
s.files += %w( third_party/boringssl/crypto/x509/x_algor.c )
s.files += %w( third_party/boringssl/crypto/x509/x_all.c )
s.files += %w( third_party/boringssl/crypto/x509/x_attrib.c )
s.files += %w( third_party/boringssl/crypto/x509/x_crl.c )
s.files += %w( third_party/boringssl/crypto/x509/x_exten.c )
s.files += %w( third_party/boringssl/crypto/x509/x_info.c )
s.files += %w( third_party/boringssl/crypto/x509/x_name.c )
s.files += %w( third_party/boringssl/crypto/x509/x_pkey.c )
s.files += %w( third_party/boringssl/crypto/x509/x_pubkey.c )
s.files += %w( third_party/boringssl/crypto/x509/x_req.c )
s.files += %w( third_party/boringssl/crypto/x509/x_sig.c )
s.files += %w( third_party/boringssl/crypto/x509/x_spki.c )
s.files += %w( third_party/boringssl/crypto/x509/x_val.c )
s.files += %w( third_party/boringssl/crypto/x509/x_x509.c )
s.files += %w( third_party/boringssl/crypto/x509/x_x509a.c )
s.files += %w( third_party/boringssl/crypto/x509v3/pcy_cache.c )
s.files += %w( third_party/boringssl/crypto/x509v3/pcy_data.c )
s.files += %w( third_party/boringssl/crypto/x509v3/pcy_lib.c )
s.files += %w( third_party/boringssl/crypto/x509v3/pcy_map.c )
s.files += %w( third_party/boringssl/crypto/x509v3/pcy_node.c )
s.files += %w( third_party/boringssl/crypto/x509v3/pcy_tree.c )
s.files += %w( third_party/boringssl/crypto/x509v3/v3_akey.c )
s.files += %w( third_party/boringssl/crypto/x509v3/v3_akeya.c )
s.files += %w( third_party/boringssl/crypto/x509v3/v3_alt.c )
s.files += %w( third_party/boringssl/crypto/x509v3/v3_bcons.c )
s.files += %w( third_party/boringssl/crypto/x509v3/v3_bitst.c )
s.files += %w( third_party/boringssl/crypto/x509v3/v3_conf.c )
s.files += %w( third_party/boringssl/crypto/x509v3/v3_cpols.c )
s.files += %w( third_party/boringssl/crypto/x509v3/v3_crld.c )
s.files += %w( third_party/boringssl/crypto/x509v3/v3_enum.c )
s.files += %w( third_party/boringssl/crypto/x509v3/v3_extku.c )
s.files += %w( third_party/boringssl/crypto/x509v3/v3_genn.c )
s.files += %w( third_party/boringssl/crypto/x509v3/v3_ia5.c )
s.files += %w( third_party/boringssl/crypto/x509v3/v3_info.c )
s.files += %w( third_party/boringssl/crypto/x509v3/v3_int.c )
s.files += %w( third_party/boringssl/crypto/x509v3/v3_lib.c )
s.files += %w( third_party/boringssl/crypto/x509v3/v3_ncons.c )
s.files += %w( third_party/boringssl/crypto/x509v3/v3_pci.c )
s.files += %w( third_party/boringssl/crypto/x509v3/v3_pcia.c )
s.files += %w( third_party/boringssl/crypto/x509v3/v3_pcons.c )
s.files += %w( third_party/boringssl/crypto/x509v3/v3_pku.c )
s.files += %w( third_party/boringssl/crypto/x509v3/v3_pmaps.c )
s.files += %w( third_party/boringssl/crypto/x509v3/v3_prn.c )
s.files += %w( third_party/boringssl/crypto/x509v3/v3_purp.c )
s.files += %w( third_party/boringssl/crypto/x509v3/v3_skey.c )
s.files += %w( third_party/boringssl/crypto/x509v3/v3_sxnet.c )
s.files += %w( third_party/boringssl/crypto/x509v3/v3_utl.c )
s.files += %w( third_party/boringssl/ssl/custom_extensions.c )
s.files += %w( third_party/boringssl/ssl/d1_both.c )
s.files += %w( third_party/boringssl/ssl/d1_clnt.c )
s.files += %w( third_party/boringssl/ssl/d1_lib.c )
s.files += %w( third_party/boringssl/ssl/d1_meth.c )
s.files += %w( third_party/boringssl/ssl/d1_pkt.c )
s.files += %w( third_party/boringssl/ssl/d1_srtp.c )
s.files += %w( third_party/boringssl/ssl/d1_srvr.c )
s.files += %w( third_party/boringssl/ssl/dtls_record.c )
s.files += %w( third_party/boringssl/ssl/pqueue/pqueue.c )
s.files += %w( third_party/boringssl/ssl/s3_both.c )
s.files += %w( third_party/boringssl/ssl/s3_clnt.c )
s.files += %w( third_party/boringssl/ssl/s3_enc.c )
s.files += %w( third_party/boringssl/ssl/s3_lib.c )
s.files += %w( third_party/boringssl/ssl/s3_meth.c )
s.files += %w( third_party/boringssl/ssl/s3_pkt.c )
s.files += %w( third_party/boringssl/ssl/s3_srvr.c )
s.files += %w( third_party/boringssl/ssl/ssl_aead_ctx.c )
s.files += %w( third_party/boringssl/ssl/ssl_asn1.c )
s.files += %w( third_party/boringssl/ssl/ssl_buffer.c )
s.files += %w( third_party/boringssl/ssl/ssl_cert.c )
s.files += %w( third_party/boringssl/ssl/ssl_cipher.c )
s.files += %w( third_party/boringssl/ssl/ssl_file.c )
s.files += %w( third_party/boringssl/ssl/ssl_lib.c )
s.files += %w( third_party/boringssl/ssl/ssl_rsa.c )
s.files += %w( third_party/boringssl/ssl/ssl_session.c )
s.files += %w( third_party/boringssl/ssl/ssl_stat.c )
s.files += %w( third_party/boringssl/ssl/t1_enc.c )
s.files += %w( third_party/boringssl/ssl/t1_lib.c )
s.files += %w( third_party/boringssl/ssl/tls_record.c )
s.files += %w( third_party/zlib/crc32.h )
s.files += %w( third_party/zlib/deflate.h )
s.files += %w( third_party/zlib/gzguts.h )
s.files += %w( third_party/zlib/inffast.h )
s.files += %w( third_party/zlib/inffixed.h )
s.files += %w( third_party/zlib/inflate.h )
s.files += %w( third_party/zlib/inftrees.h )
s.files += %w( third_party/zlib/trees.h )
s.files += %w( third_party/zlib/zconf.h )
s.files += %w( third_party/zlib/zlib.h )
s.files += %w( third_party/zlib/zutil.h )
s.files += %w( third_party/zlib/adler32.c )
s.files += %w( third_party/zlib/compress.c )
s.files += %w( third_party/zlib/crc32.c )
s.files += %w( third_party/zlib/deflate.c )
s.files += %w( third_party/zlib/gzclose.c )
s.files += %w( third_party/zlib/gzlib.c )
s.files += %w( third_party/zlib/gzread.c )
s.files += %w( third_party/zlib/gzwrite.c )
s.files += %w( third_party/zlib/infback.c )
s.files += %w( third_party/zlib/inffast.c )
s.files += %w( third_party/zlib/inflate.c )
s.files += %w( third_party/zlib/inftrees.c )
s.files += %w( third_party/zlib/trees.c )
s.files += %w( third_party/zlib/uncompr.c )
s.files += %w( third_party/zlib/zutil.c )
end

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -36,14 +36,15 @@
#ifndef GRPCXX_ALARM_H
#define GRPCXX_ALARM_H
#include <grpc++/completion_queue.h>
#include <grpc++/impl/grpc_library.h>
#include <grpc++/support/time.h>
#include <grpc++/impl/codegen/grpc_library.h>
#include <grpc++/impl/codegen/time.h>
namespace grpc {
class CompletionQueue;
/// A thin wrapper around \a grpc_alarm (see / \a / src/core/surface/alarm.h).
class Alarm : public GrpcLibrary {
class Alarm : private GrpcLibrary {
public:
/// Create a completion queue alarm instance associated to \a cq.
///

@ -36,99 +36,48 @@
#include <memory>
#include <grpc/grpc.h>
#include <grpc++/impl/call.h>
#include <grpc++/impl/grpc_library.h>
#include <grpc++/support/config.h>
#include <grpc++/impl/codegen/channel_interface.h>
#include <grpc++/impl/codegen/config.h>
#include <grpc++/impl/codegen/grpc_library.h>
#include <grpc/grpc.h>
struct grpc_channel;
namespace grpc {
class CallOpSetInterface;
class ChannelArguments;
class CompletionQueue;
class ChannelCredentials;
class SecureChannelCredentials;
template <class R>
class ClientReader;
template <class W>
class ClientWriter;
template <class W, class R>
class ClientReaderWriter;
template <class R>
class ClientAsyncReader;
template <class W>
class ClientAsyncWriter;
template <class W, class R>
class ClientAsyncReaderWriter;
template <class R>
class ClientAsyncResponseReader;
/// Channels represent a connection to an endpoint. Created by \a CreateChannel.
class Channel GRPC_FINAL : public GrpcLibrary,
class Channel GRPC_FINAL : public ChannelInterface,
public CallHook,
public std::enable_shared_from_this<Channel> {
public std::enable_shared_from_this<Channel>,
private GrpcLibrary {
public:
~Channel();
/// Get the current channel state. If the channel is in IDLE and
/// \a try_to_connect is set to true, try to connect.
grpc_connectivity_state GetState(bool try_to_connect);
/// Return the \a tag on \a cq when the channel state is changed or \a
/// deadline expires. \a GetState needs to called to get the current state.
template <typename T>
void NotifyOnStateChange(grpc_connectivity_state last_observed, T deadline,
CompletionQueue* cq, void* tag) {
TimePoint<T> deadline_tp(deadline);
NotifyOnStateChangeImpl(last_observed, deadline_tp.raw_time(), cq, tag);
}
/// Blocking wait for channel state change or \a deadline expiration.
/// \a GetState needs to called to get the current state.
template <typename T>
bool WaitForStateChange(grpc_connectivity_state last_observed, T deadline) {
TimePoint<T> deadline_tp(deadline);
return WaitForStateChangeImpl(last_observed, deadline_tp.raw_time());
}
grpc_connectivity_state GetState(bool try_to_connect) GRPC_OVERRIDE;
private:
template <class R>
friend class ::grpc::ClientReader;
template <class W>
friend class ::grpc::ClientWriter;
template <class W, class R>
friend class ::grpc::ClientReaderWriter;
template <class R>
friend class ::grpc::ClientAsyncReader;
template <class W>
friend class ::grpc::ClientAsyncWriter;
template <class W, class R>
friend class ::grpc::ClientAsyncReaderWriter;
template <class R>
friend class ::grpc::ClientAsyncResponseReader;
template <class InputMessage, class OutputMessage>
friend Status BlockingUnaryCall(Channel* channel, const RpcMethod& method,
friend Status BlockingUnaryCall(ChannelInterface* channel,
const RpcMethod& method,
ClientContext* context,
const InputMessage& request,
OutputMessage* result);
friend class ::grpc::RpcMethod;
friend std::shared_ptr<Channel> CreateChannelInternal(
const grpc::string& host, grpc_channel* c_channel);
Channel(const grpc::string& host, grpc_channel* c_channel);
Call CreateCall(const RpcMethod& method, ClientContext* context,
CompletionQueue* cq);
void PerformOpsOnCall(CallOpSetInterface* ops, Call* call);
void* RegisterMethod(const char* method);
CompletionQueue* cq) GRPC_OVERRIDE;
void PerformOpsOnCall(CallOpSetInterface* ops, Call* call) GRPC_OVERRIDE;
void* RegisterMethod(const char* method) GRPC_OVERRIDE;
void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed,
gpr_timespec deadline, CompletionQueue* cq,
void* tag);
void* tag) GRPC_OVERRIDE;
bool WaitForStateChangeImpl(grpc_connectivity_state last_observed,
gpr_timespec deadline);
gpr_timespec deadline) GRPC_OVERRIDE;
const grpc::string host_;
grpc_channel* const c_channel_; // owned

@ -49,303 +49,6 @@
#ifndef GRPCXX_CLIENT_CONTEXT_H
#define GRPCXX_CLIENT_CONTEXT_H
#include <map>
#include <memory>
#include <string>
#include <grpc++/impl/sync.h>
#include <grpc++/security/auth_context.h>
#include <grpc++/support/config.h>
#include <grpc++/support/status.h>
#include <grpc++/support/string_ref.h>
#include <grpc++/support/time.h>
#include <grpc/compression.h>
#include <grpc/grpc.h>
#include <grpc/support/log.h>
#include <grpc/support/time.h>
struct census_context;
namespace grpc {
class Channel;
class CompletionQueue;
class CallCredentials;
class RpcMethod;
template <class R>
class ClientReader;
template <class W>
class ClientWriter;
template <class W, class R>
class ClientReaderWriter;
template <class R>
class ClientAsyncReader;
template <class W>
class ClientAsyncWriter;
template <class W, class R>
class ClientAsyncReaderWriter;
template <class R>
class ClientAsyncResponseReader;
class ServerContext;
/// Options for \a ClientContext::FromServerContext specifying which traits from
/// the \a ServerContext to propagate (copy) from it into a new \a
/// ClientContext.
///
/// \see ClientContext::FromServerContext
class PropagationOptions {
public:
PropagationOptions() : propagate_(GRPC_PROPAGATE_DEFAULTS) {}
PropagationOptions& enable_deadline_propagation() {
propagate_ |= GRPC_PROPAGATE_DEADLINE;
return *this;
}
PropagationOptions& disable_deadline_propagation() {
propagate_ &= ~GRPC_PROPAGATE_DEADLINE;
return *this;
}
PropagationOptions& enable_census_stats_propagation() {
propagate_ |= GRPC_PROPAGATE_CENSUS_STATS_CONTEXT;
return *this;
}
PropagationOptions& disable_census_stats_propagation() {
propagate_ &= ~GRPC_PROPAGATE_CENSUS_STATS_CONTEXT;
return *this;
}
PropagationOptions& enable_census_tracing_propagation() {
propagate_ |= GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT;
return *this;
}
PropagationOptions& disable_census_tracing_propagation() {
propagate_ &= ~GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT;
return *this;
}
PropagationOptions& enable_cancellation_propagation() {
propagate_ |= GRPC_PROPAGATE_CANCELLATION;
return *this;
}
PropagationOptions& disable_cancellation_propagation() {
propagate_ &= ~GRPC_PROPAGATE_CANCELLATION;
return *this;
}
uint32_t c_bitmask() const { return propagate_; }
private:
uint32_t propagate_;
};
namespace testing {
class InteropClientContextInspector;
} // namespace testing
class ClientContext {
public:
ClientContext();
~ClientContext();
/// Create a new \a ClientContext as a child of an incoming server call,
/// according to \a options (\see PropagationOptions).
///
/// \param server_context The source server context to use as the basis for
/// constructing the client context.
/// \param options The options controlling what to copy from the \a
/// server_context.
///
/// \return A newly constructed \a ClientContext instance based on \a
/// server_context, with traits propagated (copied) according to \a options.
static std::unique_ptr<ClientContext> FromServerContext(
const ServerContext& server_context,
PropagationOptions options = PropagationOptions());
/// Add the (\a meta_key, \a meta_value) pair to the metadata associated with
/// a client call. These are made available at the server side by the \a
/// grpc::ServerContext::client_metadata() method.
///
/// \warning This method should only be called before invoking the rpc.
///
/// \param meta_key The metadata key. If \a meta_value is binary data, it must
/// end in "-bin".
/// \param meta_value The metadata value. If its value is binary, it must be
/// base64-encoding (see https://tools.ietf.org/html/rfc4648#section-4) and \a
/// meta_key must end in "-bin".
void AddMetadata(const grpc::string& meta_key,
const grpc::string& meta_value);
/// Return a collection of initial metadata key-value pairs. Note that keys
/// may happen more than once (ie, a \a std::multimap is returned).
///
/// \warning This method should only be called after initial metadata has been
/// received. For streaming calls, see \a
/// ClientReaderInterface::WaitForInitialMetadata().
///
/// \return A multimap of initial metadata key-value pairs from the server.
const std::multimap<grpc::string_ref, grpc::string_ref>&
GetServerInitialMetadata() {
GPR_ASSERT(initial_metadata_received_);
return recv_initial_metadata_;
}
/// Return a collection of trailing metadata key-value pairs. Note that keys
/// may happen more than once (ie, a \a std::multimap is returned).
///
/// \warning This method is only callable once the stream has finished.
///
/// \return A multimap of metadata trailing key-value pairs from the server.
const std::multimap<grpc::string_ref, grpc::string_ref>&
GetServerTrailingMetadata() {
// TODO(yangg) check finished
return trailing_metadata_;
}
/// Set the deadline for the client call.
///
/// \warning This method should only be called before invoking the rpc.
///
/// \param deadline the deadline for the client call. Units are determined by
/// the type used.
template <typename T>
void set_deadline(const T& deadline) {
TimePoint<T> deadline_tp(deadline);
deadline_ = deadline_tp.raw_time();
}
#ifndef GRPC_CXX0X_NO_CHRONO
/// Return the deadline for the client call.
std::chrono::system_clock::time_point deadline() {
return Timespec2Timepoint(deadline_);
}
#endif // !GRPC_CXX0X_NO_CHRONO
/// Return a \a gpr_timespec representation of the client call's deadline.
gpr_timespec raw_deadline() { return deadline_; }
/// Set the per call authority header (see
/// https://tools.ietf.org/html/rfc7540#section-8.1.2.3).
void set_authority(const grpc::string& authority) { authority_ = authority; }
/// Return the authentication context for this client call.
///
/// \see grpc::AuthContext.
std::shared_ptr<const AuthContext> auth_context() const;
/// Set credentials for the client call.
///
/// A credentials object encapsulates all the state needed by a client to
/// authenticate with a server and make various assertions, e.g., about the
/// client’s identity, role, or whether it is authorized to make a particular
/// call.
///
/// \see http://www.grpc.io/docs/guides/auth.html
void set_credentials(const std::shared_ptr<CallCredentials>& creds) {
creds_ = creds;
}
/// Return the compression algorithm to be used by the client call.
grpc_compression_algorithm compression_algorithm() const {
return compression_algorithm_;
}
/// Set \a algorithm to be the compression algorithm used for the client call.
///
/// \param algorith The compression algorithm used for the client call.
void set_compression_algorithm(grpc_compression_algorithm algorithm);
/// Return the peer uri in a string.
///
/// \warning This value is never authenticated or subject to any security
/// related code. It must not be used for any authentication related
/// functionality. Instead, use auth_context.
///
/// \return The call's peer URI.
grpc::string peer() const;
/// Get and set census context.
void set_census_context(struct census_context* ccp) { census_context_ = ccp; }
struct census_context* census_context() const {
return census_context_;
}
/// Send a best-effort out-of-band cancel. The call could be in any stage.
/// e.g. if it is already finished, it may still return success.
///
/// There is no guarantee the call will be cancelled.
void TryCancel();
/// Global Callbacks
///
/// Can be set exactly once per application to install hooks whenever
/// a client context is constructed and destructed.
class GlobalCallbacks {
public:
virtual ~GlobalCallbacks() {}
virtual void DefaultConstructor(ClientContext* context) = 0;
virtual void Destructor(ClientContext* context) = 0;
};
static void SetGlobalCallbacks(GlobalCallbacks* callbacks);
private:
// Disallow copy and assign.
ClientContext(const ClientContext&);
ClientContext& operator=(const ClientContext&);
friend class ::grpc::testing::InteropClientContextInspector;
friend class CallOpClientRecvStatus;
friend class CallOpRecvInitialMetadata;
friend class Channel;
template <class R>
friend class ::grpc::ClientReader;
template <class W>
friend class ::grpc::ClientWriter;
template <class W, class R>
friend class ::grpc::ClientReaderWriter;
template <class R>
friend class ::grpc::ClientAsyncReader;
template <class W>
friend class ::grpc::ClientAsyncWriter;
template <class W, class R>
friend class ::grpc::ClientAsyncReaderWriter;
template <class R>
friend class ::grpc::ClientAsyncResponseReader;
template <class InputMessage, class OutputMessage>
friend Status BlockingUnaryCall(Channel* channel, const RpcMethod& method,
ClientContext* context,
const InputMessage& request,
OutputMessage* result);
grpc_call* call() { return call_; }
void set_call(grpc_call* call, const std::shared_ptr<Channel>& channel);
grpc::string authority() { return authority_; }
bool initial_metadata_received_;
std::shared_ptr<Channel> channel_;
grpc::mutex mu_;
grpc_call* call_;
bool call_canceled_;
gpr_timespec deadline_;
grpc::string authority_;
std::shared_ptr<CallCredentials> creds_;
mutable std::shared_ptr<const AuthContext> auth_context_;
struct census_context* census_context_;
std::multimap<grpc::string, grpc::string> send_initial_metadata_;
std::multimap<grpc::string_ref, grpc::string_ref> recv_initial_metadata_;
std::multimap<grpc::string_ref, grpc::string_ref> trailing_metadata_;
grpc_call* propagate_from_call_;
PropagationOptions propagation_options_;
grpc_compression_algorithm compression_algorithm_;
};
} // namespace grpc
#include <grpc++/impl/codegen/client_context.h>
#endif // GRPCXX_CLIENT_CONTEXT_H

@ -31,182 +31,9 @@
*
*/
/// A completion queue implements a concurrent producer-consumer queue, with two
/// main methods, \a Next and \a AsyncNext.
#ifndef GRPCXX_COMPLETION_QUEUE_H
#define GRPCXX_COMPLETION_QUEUE_H
#include <grpc/support/time.h>
#include <grpc++/impl/grpc_library.h>
#include <grpc++/support/status.h>
#include <grpc++/support/time.h>
struct grpc_completion_queue;
namespace grpc {
template <class R>
class ClientReader;
template <class W>
class ClientWriter;
template <class W, class R>
class ClientReaderWriter;
template <class R>
class ServerReader;
template <class W>
class ServerWriter;
template <class W, class R>
class ServerReaderWriter;
template <class ServiceType, class RequestType, class ResponseType>
class RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
class ClientStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
class ServerStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
class BidiStreamingHandler;
class UnknownMethodHandler;
class Channel;
class ClientContext;
class CompletionQueueTag;
class CompletionQueue;
class RpcMethod;
class Server;
class ServerBuilder;
class ServerContext;
/// A thin wrapper around \a grpc_completion_queue (see / \a
/// src/core/surface/completion_queue.h).
class CompletionQueue : public GrpcLibrary {
public:
/// Default constructor. Implicitly creates a \a grpc_completion_queue
/// instance.
CompletionQueue();
/// Wrap \a take, taking ownership of the instance.
///
/// \param take The completion queue instance to wrap. Ownership is taken.
explicit CompletionQueue(grpc_completion_queue* take);
/// Destructor. Destroys the owned wrapped completion queue / instance.
~CompletionQueue() GRPC_OVERRIDE;
/// Tri-state return for AsyncNext: SHUTDOWN, GOT_EVENT, TIMEOUT.
enum NextStatus {
SHUTDOWN, ///< The completion queue has been shutdown.
GOT_EVENT, ///< Got a new event; \a tag will be filled in with its
///< associated value; \a ok indicating its success.
TIMEOUT ///< deadline was reached.
};
/// Read from the queue, blocking up to \a deadline (or the queue's shutdown).
/// Both \a tag and \a ok are updated upon success (if an event is available
/// within the \a deadline). A \a tag points to an arbitrary location usually
/// employed to uniquely identify an event.
///
/// \param tag[out] Upon sucess, updated to point to the event's tag.
/// \param ok[out] Upon sucess, true if read a regular event, false otherwise.
/// \param deadline[in] How long to block in wait for an event.
///
/// \return The type of event read.
template <typename T>
NextStatus AsyncNext(void** tag, bool* ok, const T& deadline) {
TimePoint<T> deadline_tp(deadline);
return AsyncNextInternal(tag, ok, deadline_tp.raw_time());
}
/// Read from the queue, blocking until an event is available or the queue is
/// shutting down.
///
/// \param tag[out] Updated to point to the read event's tag.
/// \param ok[out] true if read a regular event, false otherwise.
///
/// \return true if read a regular event, false if the queue is shutting down.
bool Next(void** tag, bool* ok) {
return (AsyncNextInternal(tag, ok, gpr_inf_future(GPR_CLOCK_REALTIME)) !=
SHUTDOWN);
}
/// Request the shutdown of the queue.
///
/// \warning This method must be called at some point. Once invoked, \a Next
/// will start to return false and \a AsyncNext will return \a
/// NextStatus::SHUTDOWN. Only once either one of these methods does that
/// (that is, once the queue has been \em drained) can an instance of this
/// class be destroyed.
void Shutdown();
/// Returns a \em raw pointer to the underlying \a grpc_completion_queue
/// instance.
///
/// \warning Remember that the returned instance is owned. No transfer of
/// owership is performed.
grpc_completion_queue* cq() { return cq_; }
private:
// Friend synchronous wrappers so that they can access Pluck(), which is
// a semi-private API geared towards the synchronous implementation.
template <class R>
friend class ::grpc::ClientReader;
template <class W>
friend class ::grpc::ClientWriter;
template <class W, class R>
friend class ::grpc::ClientReaderWriter;
template <class R>
friend class ::grpc::ServerReader;
template <class W>
friend class ::grpc::ServerWriter;
template <class W, class R>
friend class ::grpc::ServerReaderWriter;
template <class ServiceType, class RequestType, class ResponseType>
friend class RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
friend class ClientStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
friend class ServerStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
friend class BidiStreamingHandler;
friend class UnknownMethodHandler;
friend class ::grpc::Server;
friend class ::grpc::ServerContext;
template <class InputMessage, class OutputMessage>
friend Status BlockingUnaryCall(Channel* channel, const RpcMethod& method,
ClientContext* context,
const InputMessage& request,
OutputMessage* result);
NextStatus AsyncNextInternal(void** tag, bool* ok, gpr_timespec deadline);
/// Wraps \a grpc_completion_queue_pluck.
/// \warning Must not be mixed with calls to \a Next.
bool Pluck(CompletionQueueTag* tag);
/// Performs a single polling pluck on \a tag.
void TryPluck(CompletionQueueTag* tag);
grpc_completion_queue* cq_; // owned
};
/// An interface allowing implementors to process and filter event tags.
class CompletionQueueTag {
public:
virtual ~CompletionQueueTag() {}
// Called prior to returning from Next(), return value is the status of the
// operation (return status is the default thing to do). If this function
// returns false, the tag is dropped and not returned from the completion
// queue
virtual bool FinalizeResult(void** tag, bool* status) = 0;
};
/// A specific type of completion queue used by the processing of notifications
/// by servers. Instantiated by \a ServerBuilder.
class ServerCompletionQueue : public CompletionQueue {
private:
friend class ServerBuilder;
ServerCompletionQueue() {}
};
} // namespace grpc
#include <grpc++/impl/codegen/completion_queue.h>
#endif // GRPCXX_COMPLETION_QUEUE_H

@ -51,6 +51,7 @@ class GenericServerContext GRPC_FINAL : public ServerContext {
private:
friend class Server;
friend class ServerInterface;
grpc::string method_;
grpc::string host_;
@ -58,11 +59,7 @@ class GenericServerContext GRPC_FINAL : public ServerContext {
class AsyncGenericService GRPC_FINAL {
public:
// TODO(yangg) Once we can add multiple completion queues to the server
// in c core, add a CompletionQueue* argument to the ctor here.
// TODO(yangg) support methods list.
AsyncGenericService() : server_(nullptr) {}
AsyncGenericService(const grpc::string& methods) : server_(nullptr) {}
void RequestCall(GenericServerContext* ctx,
GenericServerAsyncReaderWriter* reader_writer,

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -47,7 +47,8 @@ typedef ClientAsyncReaderWriter<ByteBuffer, ByteBuffer>
// by name.
class GenericStub GRPC_FINAL {
public:
explicit GenericStub(std::shared_ptr<Channel> channel) : channel_(channel) {}
explicit GenericStub(std::shared_ptr<ChannelInterface> channel)
: channel_(channel) {}
// begin a call to a named method
std::unique_ptr<GenericClientAsyncReaderWriter> Call(
@ -55,7 +56,7 @@ class GenericStub GRPC_FINAL {
void* tag);
private:
std::shared_ptr<Channel> channel_;
std::shared_ptr<ChannelInterface> channel_;
};
} // namespace grpc

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -34,549 +34,6 @@
#ifndef GRPCXX_IMPL_CALL_H
#define GRPCXX_IMPL_CALL_H
#include <functional>
#include <memory>
#include <map>
#include <cstring>
#include <grpc/support/alloc.h>
#include <grpc++/client_context.h>
#include <grpc++/completion_queue.h>
#include <grpc++/impl/serialization_traits.h>
#include <grpc++/support/config.h>
#include <grpc++/support/status.h>
struct grpc_call;
struct grpc_op;
namespace grpc {
class ByteBuffer;
class Call;
void FillMetadataMap(
grpc_metadata_array* arr,
std::multimap<grpc::string_ref, grpc::string_ref>* metadata);
grpc_metadata* FillMetadataArray(
const std::multimap<grpc::string, grpc::string>& metadata);
/// Per-message write options.
class WriteOptions {
public:
WriteOptions() : flags_(0) {}
WriteOptions(const WriteOptions& other) : flags_(other.flags_) {}
/// Clear all flags.
inline void Clear() { flags_ = 0; }
/// Returns raw flags bitset.
inline uint32_t flags() const { return flags_; }
/// Sets flag for the disabling of compression for the next message write.
///
/// \sa GRPC_WRITE_NO_COMPRESS
inline WriteOptions& set_no_compression() {
SetBit(GRPC_WRITE_NO_COMPRESS);
return *this;
}
/// Clears flag for the disabling of compression for the next message write.
///
/// \sa GRPC_WRITE_NO_COMPRESS
inline WriteOptions& clear_no_compression() {
ClearBit(GRPC_WRITE_NO_COMPRESS);
return *this;
}
/// Get value for the flag indicating whether compression for the next
/// message write is forcefully disabled.
///
/// \sa GRPC_WRITE_NO_COMPRESS
inline bool get_no_compression() const {
return GetBit(GRPC_WRITE_NO_COMPRESS);
}
/// Sets flag indicating that the write may be buffered and need not go out on
/// the wire immediately.
///
/// \sa GRPC_WRITE_BUFFER_HINT
inline WriteOptions& set_buffer_hint() {
SetBit(GRPC_WRITE_BUFFER_HINT);
return *this;
}
/// Clears flag indicating that the write may be buffered and need not go out
/// on the wire immediately.
///
/// \sa GRPC_WRITE_BUFFER_HINT
inline WriteOptions& clear_buffer_hint() {
ClearBit(GRPC_WRITE_BUFFER_HINT);
return *this;
}
/// Get value for the flag indicating that the write may be buffered and need
/// not go out on the wire immediately.
///
/// \sa GRPC_WRITE_BUFFER_HINT
inline bool get_buffer_hint() const { return GetBit(GRPC_WRITE_BUFFER_HINT); }
WriteOptions& operator=(const WriteOptions& rhs) {
flags_ = rhs.flags_;
return *this;
}
private:
void SetBit(const uint32_t mask) { flags_ |= mask; }
void ClearBit(const uint32_t mask) { flags_ &= ~mask; }
bool GetBit(const uint32_t mask) const { return (flags_ & mask) != 0; }
uint32_t flags_;
};
/// Default argument for CallOpSet. I is unused by the class, but can be
/// used for generating multiple names for the same thing.
template <int I>
class CallNoOp {
protected:
void AddOp(grpc_op* ops, size_t* nops) {}
void FinishOp(bool* status, int max_message_size) {}
};
class CallOpSendInitialMetadata {
public:
CallOpSendInitialMetadata() : send_(false) {}
void SendInitialMetadata(
const std::multimap<grpc::string, grpc::string>& metadata) {
send_ = true;
initial_metadata_count_ = metadata.size();
initial_metadata_ = FillMetadataArray(metadata);
}
protected:
void AddOp(grpc_op* ops, size_t* nops) {
if (!send_) return;
grpc_op* op = &ops[(*nops)++];
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->flags = 0;
op->reserved = NULL;
op->data.send_initial_metadata.count = initial_metadata_count_;
op->data.send_initial_metadata.metadata = initial_metadata_;
}
void FinishOp(bool* status, int max_message_size) {
if (!send_) return;
gpr_free(initial_metadata_);
send_ = false;
}
bool send_;
size_t initial_metadata_count_;
grpc_metadata* initial_metadata_;
};
class CallOpSendMessage {
public:
CallOpSendMessage() : send_buf_(nullptr), own_buf_(false) {}
/// Send \a message using \a options for the write. The \a options are cleared
/// after use.
template <class M>
Status SendMessage(const M& message,
const WriteOptions& options) GRPC_MUST_USE_RESULT;
template <class M>
Status SendMessage(const M& message) GRPC_MUST_USE_RESULT;
protected:
void AddOp(grpc_op* ops, size_t* nops) {
if (send_buf_ == nullptr) return;
grpc_op* op = &ops[(*nops)++];
op->op = GRPC_OP_SEND_MESSAGE;
op->flags = write_options_.flags();
op->reserved = NULL;
op->data.send_message = send_buf_;
// Flags are per-message: clear them after use.
write_options_.Clear();
}
void FinishOp(bool* status, int max_message_size) {
if (own_buf_) grpc_byte_buffer_destroy(send_buf_);
send_buf_ = nullptr;
}
private:
grpc_byte_buffer* send_buf_;
WriteOptions write_options_;
bool own_buf_;
};
template <class M>
Status CallOpSendMessage::SendMessage(const M& message,
const WriteOptions& options) {
write_options_ = options;
return SerializationTraits<M>::Serialize(message, &send_buf_, &own_buf_);
}
template <class M>
Status CallOpSendMessage::SendMessage(const M& message) {
return SendMessage(message, WriteOptions());
}
template <class R>
class CallOpRecvMessage {
public:
CallOpRecvMessage() : got_message(false), message_(nullptr) {}
void RecvMessage(R* message) { message_ = message; }
bool got_message;
protected:
void AddOp(grpc_op* ops, size_t* nops) {
if (message_ == nullptr) return;
grpc_op* op = &ops[(*nops)++];
op->op = GRPC_OP_RECV_MESSAGE;
op->flags = 0;
op->reserved = NULL;
op->data.recv_message = &recv_buf_;
}
void FinishOp(bool* status, int max_message_size) {
if (message_ == nullptr) return;
if (recv_buf_) {
if (*status) {
got_message = true;
*status = SerializationTraits<R>::Deserialize(recv_buf_, message_,
max_message_size).ok();
} else {
got_message = false;
grpc_byte_buffer_destroy(recv_buf_);
}
} else {
got_message = false;
*status = false;
}
message_ = nullptr;
}
private:
R* message_;
grpc_byte_buffer* recv_buf_;
};
namespace CallOpGenericRecvMessageHelper {
class DeserializeFunc {
public:
virtual Status Deserialize(grpc_byte_buffer* buf, int max_message_size) = 0;
};
template <class R>
class DeserializeFuncType GRPC_FINAL : public DeserializeFunc {
public:
DeserializeFuncType(R* message) : message_(message) {}
Status Deserialize(grpc_byte_buffer* buf,
int max_message_size) GRPC_OVERRIDE {
return SerializationTraits<R>::Deserialize(buf, message_, max_message_size);
}
private:
R* message_; // Not a managed pointer because management is external to this
};
} // namespace CallOpGenericRecvMessageHelper
class CallOpGenericRecvMessage {
public:
CallOpGenericRecvMessage() : got_message(false) {}
template <class R>
void RecvMessage(R* message) {
deserialize_.reset(
new CallOpGenericRecvMessageHelper::DeserializeFuncType<R>(message));
}
bool got_message;
protected:
void AddOp(grpc_op* ops, size_t* nops) {
if (!deserialize_) return;
grpc_op* op = &ops[(*nops)++];
op->op = GRPC_OP_RECV_MESSAGE;
op->flags = 0;
op->reserved = NULL;
op->data.recv_message = &recv_buf_;
}
void FinishOp(bool* status, int max_message_size) {
if (!deserialize_) return;
if (recv_buf_) {
if (*status) {
got_message = true;
*status = deserialize_->Deserialize(recv_buf_, max_message_size).ok();
} else {
got_message = false;
grpc_byte_buffer_destroy(recv_buf_);
}
} else {
got_message = false;
*status = false;
}
deserialize_.reset();
}
private:
std::unique_ptr<CallOpGenericRecvMessageHelper::DeserializeFunc> deserialize_;
grpc_byte_buffer* recv_buf_;
};
class CallOpClientSendClose {
public:
CallOpClientSendClose() : send_(false) {}
void ClientSendClose() { send_ = true; }
protected:
void AddOp(grpc_op* ops, size_t* nops) {
if (!send_) return;
grpc_op* op = &ops[(*nops)++];
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
op->flags = 0;
op->reserved = NULL;
}
void FinishOp(bool* status, int max_message_size) { send_ = false; }
private:
bool send_;
};
class CallOpServerSendStatus {
public:
CallOpServerSendStatus() : send_status_available_(false) {}
void ServerSendStatus(
const std::multimap<grpc::string, grpc::string>& trailing_metadata,
const Status& status) {
trailing_metadata_count_ = trailing_metadata.size();
trailing_metadata_ = FillMetadataArray(trailing_metadata);
send_status_available_ = true;
send_status_code_ = static_cast<grpc_status_code>(status.error_code());
send_status_details_ = status.error_message();
}
protected:
void AddOp(grpc_op* ops, size_t* nops) {
if (!send_status_available_) return;
grpc_op* op = &ops[(*nops)++];
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count =
trailing_metadata_count_;
op->data.send_status_from_server.trailing_metadata = trailing_metadata_;
op->data.send_status_from_server.status = send_status_code_;
op->data.send_status_from_server.status_details =
send_status_details_.empty() ? nullptr : send_status_details_.c_str();
op->flags = 0;
op->reserved = NULL;
}
void FinishOp(bool* status, int max_message_size) {
if (!send_status_available_) return;
gpr_free(trailing_metadata_);
send_status_available_ = false;
}
private:
bool send_status_available_;
grpc_status_code send_status_code_;
grpc::string send_status_details_;
size_t trailing_metadata_count_;
grpc_metadata* trailing_metadata_;
};
class CallOpRecvInitialMetadata {
public:
CallOpRecvInitialMetadata() : recv_initial_metadata_(nullptr) {}
void RecvInitialMetadata(ClientContext* context) {
context->initial_metadata_received_ = true;
recv_initial_metadata_ = &context->recv_initial_metadata_;
}
protected:
void AddOp(grpc_op* ops, size_t* nops) {
if (!recv_initial_metadata_) return;
memset(&recv_initial_metadata_arr_, 0, sizeof(recv_initial_metadata_arr_));
grpc_op* op = &ops[(*nops)++];
op->op = GRPC_OP_RECV_INITIAL_METADATA;
op->data.recv_initial_metadata = &recv_initial_metadata_arr_;
op->flags = 0;
op->reserved = NULL;
}
void FinishOp(bool* status, int max_message_size) {
if (recv_initial_metadata_ == nullptr) return;
FillMetadataMap(&recv_initial_metadata_arr_, recv_initial_metadata_);
recv_initial_metadata_ = nullptr;
}
private:
std::multimap<grpc::string_ref, grpc::string_ref>* recv_initial_metadata_;
grpc_metadata_array recv_initial_metadata_arr_;
};
class CallOpClientRecvStatus {
public:
CallOpClientRecvStatus() : recv_status_(nullptr) {}
void ClientRecvStatus(ClientContext* context, Status* status) {
recv_trailing_metadata_ = &context->trailing_metadata_;
recv_status_ = status;
}
protected:
void AddOp(grpc_op* ops, size_t* nops) {
if (recv_status_ == nullptr) return;
memset(&recv_trailing_metadata_arr_, 0,
sizeof(recv_trailing_metadata_arr_));
status_details_ = nullptr;
status_details_capacity_ = 0;
grpc_op* op = &ops[(*nops)++];
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
op->data.recv_status_on_client.trailing_metadata =
&recv_trailing_metadata_arr_;
op->data.recv_status_on_client.status = &status_code_;
op->data.recv_status_on_client.status_details = &status_details_;
op->data.recv_status_on_client.status_details_capacity =
&status_details_capacity_;
op->flags = 0;
op->reserved = NULL;
}
void FinishOp(bool* status, int max_message_size) {
if (recv_status_ == nullptr) return;
FillMetadataMap(&recv_trailing_metadata_arr_, recv_trailing_metadata_);
*recv_status_ = Status(
static_cast<StatusCode>(status_code_),
status_details_ ? grpc::string(status_details_) : grpc::string());
gpr_free(status_details_);
recv_status_ = nullptr;
}
private:
std::multimap<grpc::string_ref, grpc::string_ref>* recv_trailing_metadata_;
Status* recv_status_;
grpc_metadata_array recv_trailing_metadata_arr_;
grpc_status_code status_code_;
char* status_details_;
size_t status_details_capacity_;
};
/// An abstract collection of call ops, used to generate the
/// grpc_call_op structure to pass down to the lower layers,
/// and as it is-a CompletionQueueTag, also massages the final
/// completion into the correct form for consumption in the C++
/// API.
class CallOpSetInterface : public CompletionQueueTag {
public:
CallOpSetInterface() : max_message_size_(0) {}
/// Fills in grpc_op, starting from ops[*nops] and moving
/// upwards.
virtual void FillOps(grpc_op* ops, size_t* nops) = 0;
void set_max_message_size(int max_message_size) {
max_message_size_ = max_message_size;
}
protected:
int max_message_size_;
};
/// Primary implementaiton of CallOpSetInterface.
/// Since we cannot use variadic templates, we declare slots up to
/// the maximum count of ops we'll need in a set. We leverage the
/// empty base class optimization to slim this class (especially
/// when there are many unused slots used). To avoid duplicate base classes,
/// the template parmeter for CallNoOp is varied by argument position.
template <class Op1 = CallNoOp<1>, class Op2 = CallNoOp<2>,
class Op3 = CallNoOp<3>, class Op4 = CallNoOp<4>,
class Op5 = CallNoOp<5>, class Op6 = CallNoOp<6>>
class CallOpSet : public CallOpSetInterface,
public Op1,
public Op2,
public Op3,
public Op4,
public Op5,
public Op6 {
public:
CallOpSet() : return_tag_(this) {}
void FillOps(grpc_op* ops, size_t* nops) GRPC_OVERRIDE {
this->Op1::AddOp(ops, nops);
this->Op2::AddOp(ops, nops);
this->Op3::AddOp(ops, nops);
this->Op4::AddOp(ops, nops);
this->Op5::AddOp(ops, nops);
this->Op6::AddOp(ops, nops);
}
bool FinalizeResult(void** tag, bool* status) GRPC_OVERRIDE {
this->Op1::FinishOp(status, max_message_size_);
this->Op2::FinishOp(status, max_message_size_);
this->Op3::FinishOp(status, max_message_size_);
this->Op4::FinishOp(status, max_message_size_);
this->Op5::FinishOp(status, max_message_size_);
this->Op6::FinishOp(status, max_message_size_);
*tag = return_tag_;
return true;
}
void set_output_tag(void* return_tag) { return_tag_ = return_tag; }
private:
void* return_tag_;
};
/// A CallOpSet that does not post completions to the completion queue.
///
/// Allows hiding some completions that the C core must generate from
/// C++ users.
template <class Op1 = CallNoOp<1>, class Op2 = CallNoOp<2>,
class Op3 = CallNoOp<3>, class Op4 = CallNoOp<4>,
class Op5 = CallNoOp<5>, class Op6 = CallNoOp<6>>
class SneakyCallOpSet : public CallOpSet<Op1, Op2, Op3, Op4, Op5, Op6> {
public:
bool FinalizeResult(void** tag, bool* status) GRPC_OVERRIDE {
typedef CallOpSet<Op1, Op2, Op3, Op4, Op5, Op6> Base;
return Base::FinalizeResult(tag, status) && false;
}
};
// Channel and Server implement this to allow them to hook performing ops
class CallHook {
public:
virtual ~CallHook() {}
virtual void PerformOpsOnCall(CallOpSetInterface* ops, Call* call) = 0;
};
// Straightforward wrapping of the C call object
class Call GRPC_FINAL {
public:
/* call is owned by the caller */
Call(grpc_call* call, CallHook* call_hook_, CompletionQueue* cq);
Call(grpc_call* call, CallHook* call_hook_, CompletionQueue* cq,
int max_message_size);
void PerformOps(CallOpSetInterface* ops);
grpc_call* call() { return call_; }
CompletionQueue* cq() { return cq_; }
int max_message_size() { return max_message_size_; }
private:
CallHook* call_hook_;
CompletionQueue* cq_;
grpc_call* call_;
int max_message_size_;
};
} // namespace grpc
#include <grpc++/impl/codegen/call.h>
#endif // GRPCXX_IMPL_CALL_H

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -34,41 +34,6 @@
#ifndef GRPCXX_IMPL_CLIENT_UNARY_CALL_H
#define GRPCXX_IMPL_CLIENT_UNARY_CALL_H
#include <grpc++/impl/call.h>
#include <grpc++/support/config.h>
#include <grpc++/support/status.h>
namespace grpc {
class Channel;
class ClientContext;
class CompletionQueue;
class RpcMethod;
// Wrapper that performs a blocking unary call
template <class InputMessage, class OutputMessage>
Status BlockingUnaryCall(Channel* channel, const RpcMethod& method,
ClientContext* context, const InputMessage& request,
OutputMessage* result) {
CompletionQueue cq;
Call call(channel->CreateCall(method, context, &cq));
CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
CallOpRecvInitialMetadata, CallOpRecvMessage<OutputMessage>,
CallOpClientSendClose, CallOpClientRecvStatus> ops;
Status status = ops.SendMessage(request);
if (!status.ok()) {
return status;
}
ops.SendInitialMetadata(context->send_initial_metadata_);
ops.RecvInitialMetadata(context);
ops.RecvMessage(result);
ops.ClientSendClose();
ops.ClientRecvStatus(context, &status);
call.PerformOps(&ops);
GPR_ASSERT((cq.Pluck(&ops) && ops.got_message) || !status.ok());
return status;
}
} // namespace grpc
#include <grpc++/impl/codegen/client_unary_call.h>
#endif // GRPCXX_IMPL_CLIENT_UNARY_CALL_H

@ -0,0 +1,462 @@
/*
*
* Copyright 2015-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 GRPCXX_IMPL_CODEGEN_ASYNC_STREAM_H
#define GRPCXX_IMPL_CODEGEN_ASYNC_STREAM_H
#include <grpc++/impl/codegen/channel_interface.h>
#include <grpc++/impl/codegen/call.h>
#include <grpc++/impl/codegen/service_type.h>
#include <grpc++/impl/codegen/server_context.h>
#include <grpc++/impl/codegen/status.h>
namespace grpc {
class CompletionQueue;
/// Common interface for all client side asynchronous streaming.
class ClientAsyncStreamingInterface {
public:
virtual ~ClientAsyncStreamingInterface() {}
/// Request notification of the reading of the initial metadata. Completion
/// will be notified by \a tag on the associated completion queue.
///
/// \param[in] tag Tag identifying this request.
virtual void ReadInitialMetadata(void* tag) = 0;
/// Request notification completion.
///
/// \param[out] status To be updated with the operation status.
/// \param[in] tag Tag identifying this request.
virtual void Finish(Status* status, void* tag) = 0;
};
/// An interface that yields a sequence of messages of type \a R.
template <class R>
class AsyncReaderInterface {
public:
virtual ~AsyncReaderInterface() {}
/// Read a message of type \a R into \a msg. Completion will be notified by \a
/// tag on the associated completion queue.
///
/// \param[out] msg Where to eventually store the read message.
/// \param[in] tag The tag identifying the operation.
virtual void Read(R* msg, void* tag) = 0;
};
/// An interface that can be fed a sequence of messages of type \a W.
template <class W>
class AsyncWriterInterface {
public:
virtual ~AsyncWriterInterface() {}
/// Request the writing of \a msg with identifying tag \a tag.
///
/// 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.
///
/// \param[in] msg The message to be written.
/// \param[in] tag The tag identifying the operation.
virtual void Write(const W& msg, void* tag) = 0;
};
template <class R>
class ClientAsyncReaderInterface : public ClientAsyncStreamingInterface,
public AsyncReaderInterface<R> {};
template <class R>
class ClientAsyncReader GRPC_FINAL : public ClientAsyncReaderInterface<R> {
public:
/// Create a stream and write the first request out.
template <class W>
ClientAsyncReader(ChannelInterface* channel, CompletionQueue* cq,
const RpcMethod& method, ClientContext* context,
const W& request, void* tag)
: context_(context), call_(channel->CreateCall(method, context, cq)) {
init_ops_.set_output_tag(tag);
init_ops_.SendInitialMetadata(context->send_initial_metadata_);
// TODO(ctiller): don't assert
GPR_ASSERT(init_ops_.SendMessage(request).ok());
init_ops_.ClientSendClose();
call_.PerformOps(&init_ops_);
}
void ReadInitialMetadata(void* tag) GRPC_OVERRIDE {
GPR_ASSERT(!context_->initial_metadata_received_);
meta_ops_.set_output_tag(tag);
meta_ops_.RecvInitialMetadata(context_);
call_.PerformOps(&meta_ops_);
}
void Read(R* msg, void* tag) GRPC_OVERRIDE {
read_ops_.set_output_tag(tag);
if (!context_->initial_metadata_received_) {
read_ops_.RecvInitialMetadata(context_);
}
read_ops_.RecvMessage(msg);
call_.PerformOps(&read_ops_);
}
void Finish(Status* status, void* tag) GRPC_OVERRIDE {
finish_ops_.set_output_tag(tag);
if (!context_->initial_metadata_received_) {
finish_ops_.RecvInitialMetadata(context_);
}
finish_ops_.ClientRecvStatus(context_, status);
call_.PerformOps(&finish_ops_);
}
private:
ClientContext* context_;
Call call_;
CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage, CallOpClientSendClose>
init_ops_;
CallOpSet<CallOpRecvInitialMetadata> meta_ops_;
CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>> read_ops_;
CallOpSet<CallOpRecvInitialMetadata, CallOpClientRecvStatus> finish_ops_;
};
/// Common interface for client side asynchronous writing.
template <class W>
class ClientAsyncWriterInterface : public ClientAsyncStreamingInterface,
public AsyncWriterInterface<W> {
public:
/// Signal the client is done with the writes.
///
/// \param[in] tag The tag identifying the operation.
virtual void WritesDone(void* tag) = 0;
};
template <class W>
class ClientAsyncWriter GRPC_FINAL : public ClientAsyncWriterInterface<W> {
public:
template <class R>
ClientAsyncWriter(ChannelInterface* channel, CompletionQueue* cq,
const RpcMethod& method, ClientContext* context,
R* response, void* tag)
: context_(context), call_(channel->CreateCall(method, context, cq)) {
finish_ops_.RecvMessage(response);
init_ops_.set_output_tag(tag);
init_ops_.SendInitialMetadata(context->send_initial_metadata_);
call_.PerformOps(&init_ops_);
}
void ReadInitialMetadata(void* tag) GRPC_OVERRIDE {
GPR_ASSERT(!context_->initial_metadata_received_);
meta_ops_.set_output_tag(tag);
meta_ops_.RecvInitialMetadata(context_);
call_.PerformOps(&meta_ops_);
}
void Write(const W& msg, void* tag) GRPC_OVERRIDE {
write_ops_.set_output_tag(tag);
// TODO(ctiller): don't assert
GPR_ASSERT(write_ops_.SendMessage(msg).ok());
call_.PerformOps(&write_ops_);
}
void WritesDone(void* tag) GRPC_OVERRIDE {
writes_done_ops_.set_output_tag(tag);
writes_done_ops_.ClientSendClose();
call_.PerformOps(&writes_done_ops_);
}
void Finish(Status* status, void* tag) GRPC_OVERRIDE {
finish_ops_.set_output_tag(tag);
if (!context_->initial_metadata_received_) {
finish_ops_.RecvInitialMetadata(context_);
}
finish_ops_.ClientRecvStatus(context_, status);
call_.PerformOps(&finish_ops_);
}
private:
ClientContext* context_;
Call call_;
CallOpSet<CallOpSendInitialMetadata> init_ops_;
CallOpSet<CallOpRecvInitialMetadata> meta_ops_;
CallOpSet<CallOpSendMessage> write_ops_;
CallOpSet<CallOpClientSendClose> writes_done_ops_;
CallOpSet<CallOpRecvInitialMetadata, CallOpGenericRecvMessage,
CallOpClientRecvStatus> finish_ops_;
};
/// Client-side interface for asynchronous bi-directional streaming.
template <class W, class R>
class ClientAsyncReaderWriterInterface : public ClientAsyncStreamingInterface,
public AsyncWriterInterface<W>,
public AsyncReaderInterface<R> {
public:
/// Signal the client is done with the writes.
///
/// \param[in] tag The tag identifying the operation.
virtual void WritesDone(void* tag) = 0;
};
template <class W, class R>
class ClientAsyncReaderWriter GRPC_FINAL
: public ClientAsyncReaderWriterInterface<W, R> {
public:
ClientAsyncReaderWriter(ChannelInterface* channel, CompletionQueue* cq,
const RpcMethod& method, ClientContext* context,
void* tag)
: context_(context), call_(channel->CreateCall(method, context, cq)) {
init_ops_.set_output_tag(tag);
init_ops_.SendInitialMetadata(context->send_initial_metadata_);
call_.PerformOps(&init_ops_);
}
void ReadInitialMetadata(void* tag) GRPC_OVERRIDE {
GPR_ASSERT(!context_->initial_metadata_received_);
meta_ops_.set_output_tag(tag);
meta_ops_.RecvInitialMetadata(context_);
call_.PerformOps(&meta_ops_);
}
void Read(R* msg, void* tag) GRPC_OVERRIDE {
read_ops_.set_output_tag(tag);
if (!context_->initial_metadata_received_) {
read_ops_.RecvInitialMetadata(context_);
}
read_ops_.RecvMessage(msg);
call_.PerformOps(&read_ops_);
}
void Write(const W& msg, void* tag) GRPC_OVERRIDE {
write_ops_.set_output_tag(tag);
// TODO(ctiller): don't assert
GPR_ASSERT(write_ops_.SendMessage(msg).ok());
call_.PerformOps(&write_ops_);
}
void WritesDone(void* tag) GRPC_OVERRIDE {
writes_done_ops_.set_output_tag(tag);
writes_done_ops_.ClientSendClose();
call_.PerformOps(&writes_done_ops_);
}
void Finish(Status* status, void* tag) GRPC_OVERRIDE {
finish_ops_.set_output_tag(tag);
if (!context_->initial_metadata_received_) {
finish_ops_.RecvInitialMetadata(context_);
}
finish_ops_.ClientRecvStatus(context_, status);
call_.PerformOps(&finish_ops_);
}
private:
ClientContext* context_;
Call call_;
CallOpSet<CallOpSendInitialMetadata> init_ops_;
CallOpSet<CallOpRecvInitialMetadata> meta_ops_;
CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>> read_ops_;
CallOpSet<CallOpSendMessage> write_ops_;
CallOpSet<CallOpClientSendClose> writes_done_ops_;
CallOpSet<CallOpRecvInitialMetadata, CallOpClientRecvStatus> finish_ops_;
};
template <class W, class R>
class ServerAsyncReader GRPC_FINAL : public ServerAsyncStreamingInterface,
public AsyncReaderInterface<R> {
public:
explicit ServerAsyncReader(ServerContext* ctx)
: call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
void SendInitialMetadata(void* tag) GRPC_OVERRIDE {
GPR_ASSERT(!ctx_->sent_initial_metadata_);
meta_ops_.set_output_tag(tag);
meta_ops_.SendInitialMetadata(ctx_->initial_metadata_);
ctx_->sent_initial_metadata_ = true;
call_.PerformOps(&meta_ops_);
}
void Read(R* msg, void* tag) GRPC_OVERRIDE {
read_ops_.set_output_tag(tag);
read_ops_.RecvMessage(msg);
call_.PerformOps(&read_ops_);
}
void Finish(const W& msg, const Status& status, void* tag) {
finish_ops_.set_output_tag(tag);
if (!ctx_->sent_initial_metadata_) {
finish_ops_.SendInitialMetadata(ctx_->initial_metadata_);
ctx_->sent_initial_metadata_ = true;
}
// The response is dropped if the status is not OK.
if (status.ok()) {
finish_ops_.ServerSendStatus(ctx_->trailing_metadata_,
finish_ops_.SendMessage(msg));
} else {
finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
}
call_.PerformOps(&finish_ops_);
}
void FinishWithError(const Status& status, void* tag) {
GPR_ASSERT(!status.ok());
finish_ops_.set_output_tag(tag);
if (!ctx_->sent_initial_metadata_) {
finish_ops_.SendInitialMetadata(ctx_->initial_metadata_);
ctx_->sent_initial_metadata_ = true;
}
finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
call_.PerformOps(&finish_ops_);
}
private:
void BindCall(Call* call) GRPC_OVERRIDE { call_ = *call; }
Call call_;
ServerContext* ctx_;
CallOpSet<CallOpSendInitialMetadata> meta_ops_;
CallOpSet<CallOpRecvMessage<R>> read_ops_;
CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
CallOpServerSendStatus> finish_ops_;
};
template <class W>
class ServerAsyncWriter GRPC_FINAL : public ServerAsyncStreamingInterface,
public AsyncWriterInterface<W> {
public:
explicit ServerAsyncWriter(ServerContext* ctx)
: call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
void SendInitialMetadata(void* tag) GRPC_OVERRIDE {
GPR_ASSERT(!ctx_->sent_initial_metadata_);
meta_ops_.set_output_tag(tag);
meta_ops_.SendInitialMetadata(ctx_->initial_metadata_);
ctx_->sent_initial_metadata_ = true;
call_.PerformOps(&meta_ops_);
}
void Write(const W& msg, void* tag) GRPC_OVERRIDE {
write_ops_.set_output_tag(tag);
if (!ctx_->sent_initial_metadata_) {
write_ops_.SendInitialMetadata(ctx_->initial_metadata_);
ctx_->sent_initial_metadata_ = true;
}
// TODO(ctiller): don't assert
GPR_ASSERT(write_ops_.SendMessage(msg).ok());
call_.PerformOps(&write_ops_);
}
void Finish(const Status& status, void* tag) {
finish_ops_.set_output_tag(tag);
if (!ctx_->sent_initial_metadata_) {
finish_ops_.SendInitialMetadata(ctx_->initial_metadata_);
ctx_->sent_initial_metadata_ = true;
}
finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
call_.PerformOps(&finish_ops_);
}
private:
void BindCall(Call* call) GRPC_OVERRIDE { call_ = *call; }
Call call_;
ServerContext* ctx_;
CallOpSet<CallOpSendInitialMetadata> meta_ops_;
CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage> write_ops_;
CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> finish_ops_;
};
/// Server-side interface for asynchronous bi-directional streaming.
template <class W, class R>
class ServerAsyncReaderWriter GRPC_FINAL : public ServerAsyncStreamingInterface,
public AsyncWriterInterface<W>,
public AsyncReaderInterface<R> {
public:
explicit ServerAsyncReaderWriter(ServerContext* ctx)
: call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
void SendInitialMetadata(void* tag) GRPC_OVERRIDE {
GPR_ASSERT(!ctx_->sent_initial_metadata_);
meta_ops_.set_output_tag(tag);
meta_ops_.SendInitialMetadata(ctx_->initial_metadata_);
ctx_->sent_initial_metadata_ = true;
call_.PerformOps(&meta_ops_);
}
void Read(R* msg, void* tag) GRPC_OVERRIDE {
read_ops_.set_output_tag(tag);
read_ops_.RecvMessage(msg);
call_.PerformOps(&read_ops_);
}
void Write(const W& msg, void* tag) GRPC_OVERRIDE {
write_ops_.set_output_tag(tag);
if (!ctx_->sent_initial_metadata_) {
write_ops_.SendInitialMetadata(ctx_->initial_metadata_);
ctx_->sent_initial_metadata_ = true;
}
// TODO(ctiller): don't assert
GPR_ASSERT(write_ops_.SendMessage(msg).ok());
call_.PerformOps(&write_ops_);
}
void Finish(const Status& status, void* tag) {
finish_ops_.set_output_tag(tag);
if (!ctx_->sent_initial_metadata_) {
finish_ops_.SendInitialMetadata(ctx_->initial_metadata_);
ctx_->sent_initial_metadata_ = true;
}
finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
call_.PerformOps(&finish_ops_);
}
private:
friend class ::grpc::Server;
void BindCall(Call* call) GRPC_OVERRIDE { call_ = *call; }
Call call_;
ServerContext* ctx_;
CallOpSet<CallOpSendInitialMetadata> meta_ops_;
CallOpSet<CallOpRecvMessage<R>> read_ops_;
CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage> write_ops_;
CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> finish_ops_;
};
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_ASYNC_STREAM_H

@ -0,0 +1,156 @@
/*
*
* Copyright 2015-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 GRPCXX_IMPL_CODEGEN_ASYNC_UNARY_CALL_H
#define GRPCXX_IMPL_CODEGEN_ASYNC_UNARY_CALL_H
#include <grpc++/impl/codegen/call.h>
#include <grpc++/impl/codegen/channel_interface.h>
#include <grpc++/impl/codegen/client_context.h>
#include <grpc++/impl/codegen/server_context.h>
#include <grpc++/impl/codegen/service_type.h>
#include <grpc++/impl/codegen/status.h>
#include <grpc/impl/codegen/log.h>
namespace grpc {
class CompletionQueue;
template <class R>
class ClientAsyncResponseReaderInterface {
public:
virtual ~ClientAsyncResponseReaderInterface() {}
virtual void ReadInitialMetadata(void* tag) = 0;
virtual void Finish(R* msg, Status* status, void* tag) = 0;
};
template <class R>
class ClientAsyncResponseReader GRPC_FINAL
: public ClientAsyncResponseReaderInterface<R> {
public:
template <class W>
ClientAsyncResponseReader(ChannelInterface* channel, CompletionQueue* cq,
const RpcMethod& method, ClientContext* context,
const W& request)
: context_(context), call_(channel->CreateCall(method, context, cq)) {
init_buf_.SendInitialMetadata(context->send_initial_metadata_);
// TODO(ctiller): don't assert
GPR_ASSERT(init_buf_.SendMessage(request).ok());
init_buf_.ClientSendClose();
call_.PerformOps(&init_buf_);
}
void ReadInitialMetadata(void* tag) {
GPR_ASSERT(!context_->initial_metadata_received_);
meta_buf_.set_output_tag(tag);
meta_buf_.RecvInitialMetadata(context_);
call_.PerformOps(&meta_buf_);
}
void Finish(R* msg, Status* status, void* tag) {
finish_buf_.set_output_tag(tag);
if (!context_->initial_metadata_received_) {
finish_buf_.RecvInitialMetadata(context_);
}
finish_buf_.RecvMessage(msg);
finish_buf_.ClientRecvStatus(context_, status);
call_.PerformOps(&finish_buf_);
}
private:
ClientContext* context_;
Call call_;
SneakyCallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
CallOpClientSendClose> init_buf_;
CallOpSet<CallOpRecvInitialMetadata> meta_buf_;
CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>,
CallOpClientRecvStatus> finish_buf_;
};
template <class W>
class ServerAsyncResponseWriter GRPC_FINAL
: public ServerAsyncStreamingInterface {
public:
explicit ServerAsyncResponseWriter(ServerContext* ctx)
: call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
void SendInitialMetadata(void* tag) GRPC_OVERRIDE {
GPR_ASSERT(!ctx_->sent_initial_metadata_);
meta_buf_.set_output_tag(tag);
meta_buf_.SendInitialMetadata(ctx_->initial_metadata_);
ctx_->sent_initial_metadata_ = true;
call_.PerformOps(&meta_buf_);
}
void Finish(const W& msg, const Status& status, void* tag) {
finish_buf_.set_output_tag(tag);
if (!ctx_->sent_initial_metadata_) {
finish_buf_.SendInitialMetadata(ctx_->initial_metadata_);
ctx_->sent_initial_metadata_ = true;
}
// The response is dropped if the status is not OK.
if (status.ok()) {
finish_buf_.ServerSendStatus(ctx_->trailing_metadata_,
finish_buf_.SendMessage(msg));
} else {
finish_buf_.ServerSendStatus(ctx_->trailing_metadata_, status);
}
call_.PerformOps(&finish_buf_);
}
void FinishWithError(const Status& status, void* tag) {
GPR_ASSERT(!status.ok());
finish_buf_.set_output_tag(tag);
if (!ctx_->sent_initial_metadata_) {
finish_buf_.SendInitialMetadata(ctx_->initial_metadata_);
ctx_->sent_initial_metadata_ = true;
}
finish_buf_.ServerSendStatus(ctx_->trailing_metadata_, status);
call_.PerformOps(&finish_buf_);
}
private:
void BindCall(Call* call) GRPC_OVERRIDE { call_ = *call; }
Call call_;
ServerContext* ctx_;
CallOpSet<CallOpSendInitialMetadata> meta_buf_;
CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
CallOpServerSendStatus> finish_buf_;
};
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_ASYNC_UNARY_CALL_H

@ -0,0 +1,578 @@
/*
*
* Copyright 2015-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 GRPCXX_IMPL_CODEGEN_CALL_H
#define GRPCXX_IMPL_CODEGEN_CALL_H
#include <functional>
#include <memory>
#include <map>
#include <cstring>
#include <grpc/impl/codegen/alloc.h>
#include <grpc/impl/codegen/grpc_types.h>
#include <grpc++/impl/codegen/client_context.h>
#include <grpc++/impl/codegen/call_hook.h>
#include <grpc++/impl/codegen/completion_queue_tag.h>
#include <grpc++/impl/codegen/serialization_traits.h>
#include <grpc++/impl/codegen/config.h>
#include <grpc++/impl/codegen/status.h>
struct grpc_byte_buffer;
namespace grpc {
class ByteBuffer;
class Call;
class CallHook;
class CompletionQueue;
void FillMetadataMap(
grpc_metadata_array* arr,
std::multimap<grpc::string_ref, grpc::string_ref>* metadata);
grpc_metadata* FillMetadataArray(
const std::multimap<grpc::string, grpc::string>& metadata);
/// Per-message write options.
class WriteOptions {
public:
WriteOptions() : flags_(0) {}
WriteOptions(const WriteOptions& other) : flags_(other.flags_) {}
/// Clear all flags.
inline void Clear() { flags_ = 0; }
/// Returns raw flags bitset.
inline uint32_t flags() const { return flags_; }
/// Sets flag for the disabling of compression for the next message write.
///
/// \sa GRPC_WRITE_NO_COMPRESS
inline WriteOptions& set_no_compression() {
SetBit(GRPC_WRITE_NO_COMPRESS);
return *this;
}
/// Clears flag for the disabling of compression for the next message write.
///
/// \sa GRPC_WRITE_NO_COMPRESS
inline WriteOptions& clear_no_compression() {
ClearBit(GRPC_WRITE_NO_COMPRESS);
return *this;
}
/// Get value for the flag indicating whether compression for the next
/// message write is forcefully disabled.
///
/// \sa GRPC_WRITE_NO_COMPRESS
inline bool get_no_compression() const {
return GetBit(GRPC_WRITE_NO_COMPRESS);
}
/// Sets flag indicating that the write may be buffered and need not go out on
/// the wire immediately.
///
/// \sa GRPC_WRITE_BUFFER_HINT
inline WriteOptions& set_buffer_hint() {
SetBit(GRPC_WRITE_BUFFER_HINT);
return *this;
}
/// Clears flag indicating that the write may be buffered and need not go out
/// on the wire immediately.
///
/// \sa GRPC_WRITE_BUFFER_HINT
inline WriteOptions& clear_buffer_hint() {
ClearBit(GRPC_WRITE_BUFFER_HINT);
return *this;
}
/// Get value for the flag indicating that the write may be buffered and need
/// not go out on the wire immediately.
///
/// \sa GRPC_WRITE_BUFFER_HINT
inline bool get_buffer_hint() const { return GetBit(GRPC_WRITE_BUFFER_HINT); }
WriteOptions& operator=(const WriteOptions& rhs) {
flags_ = rhs.flags_;
return *this;
}
private:
void SetBit(const uint32_t mask) { flags_ |= mask; }
void ClearBit(const uint32_t mask) { flags_ &= ~mask; }
bool GetBit(const uint32_t mask) const { return (flags_ & mask) != 0; }
uint32_t flags_;
};
/// Default argument for CallOpSet. I is unused by the class, but can be
/// used for generating multiple names for the same thing.
template <int I>
class CallNoOp {
protected:
void AddOp(grpc_op* ops, size_t* nops) {}
void FinishOp(bool* status, int max_message_size) {}
};
class CallOpSendInitialMetadata {
public:
CallOpSendInitialMetadata() : send_(false) {}
void SendInitialMetadata(
const std::multimap<grpc::string, grpc::string>& metadata) {
send_ = true;
initial_metadata_count_ = metadata.size();
initial_metadata_ = FillMetadataArray(metadata);
}
protected:
void AddOp(grpc_op* ops, size_t* nops) {
if (!send_) return;
grpc_op* op = &ops[(*nops)++];
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->flags = 0;
op->reserved = NULL;
op->data.send_initial_metadata.count = initial_metadata_count_;
op->data.send_initial_metadata.metadata = initial_metadata_;
}
void FinishOp(bool* status, int max_message_size) {
if (!send_) return;
gpr_free(initial_metadata_);
send_ = false;
}
bool send_;
size_t initial_metadata_count_;
grpc_metadata* initial_metadata_;
};
class CallOpSendMessage {
public:
CallOpSendMessage() : send_buf_(nullptr), own_buf_(false) {}
/// Send \a message using \a options for the write. The \a options are cleared
/// after use.
template <class M>
Status SendMessage(const M& message,
const WriteOptions& options) GRPC_MUST_USE_RESULT;
template <class M>
Status SendMessage(const M& message) GRPC_MUST_USE_RESULT;
protected:
void AddOp(grpc_op* ops, size_t* nops) {
if (send_buf_ == nullptr) return;
grpc_op* op = &ops[(*nops)++];
op->op = GRPC_OP_SEND_MESSAGE;
op->flags = write_options_.flags();
op->reserved = NULL;
op->data.send_message = send_buf_;
// Flags are per-message: clear them after use.
write_options_.Clear();
}
void FinishOp(bool* status, int max_message_size) {
if (own_buf_) grpc_byte_buffer_destroy(send_buf_);
send_buf_ = nullptr;
}
private:
grpc_byte_buffer* send_buf_;
WriteOptions write_options_;
bool own_buf_;
};
template <class M>
Status CallOpSendMessage::SendMessage(const M& message,
const WriteOptions& options) {
write_options_ = options;
return SerializationTraits<M>::Serialize(message, &send_buf_, &own_buf_);
}
template <class M>
Status CallOpSendMessage::SendMessage(const M& message) {
return SendMessage(message, WriteOptions());
}
template <class R>
class CallOpRecvMessage {
public:
CallOpRecvMessage() : got_message(false), message_(nullptr) {}
void RecvMessage(R* message) { message_ = message; }
bool got_message;
protected:
void AddOp(grpc_op* ops, size_t* nops) {
if (message_ == nullptr) return;
grpc_op* op = &ops[(*nops)++];
op->op = GRPC_OP_RECV_MESSAGE;
op->flags = 0;
op->reserved = NULL;
op->data.recv_message = &recv_buf_;
}
void FinishOp(bool* status, int max_message_size) {
if (message_ == nullptr) return;
if (recv_buf_) {
if (*status) {
got_message = true;
*status = SerializationTraits<R>::Deserialize(recv_buf_, message_,
max_message_size).ok();
} else {
got_message = false;
grpc_byte_buffer_destroy(recv_buf_);
}
} else {
got_message = false;
*status = false;
}
message_ = nullptr;
}
private:
R* message_;
grpc_byte_buffer* recv_buf_;
};
namespace CallOpGenericRecvMessageHelper {
class DeserializeFunc {
public:
virtual Status Deserialize(grpc_byte_buffer* buf, int max_message_size) = 0;
};
template <class R>
class DeserializeFuncType GRPC_FINAL : public DeserializeFunc {
public:
DeserializeFuncType(R* message) : message_(message) {}
Status Deserialize(grpc_byte_buffer* buf,
int max_message_size) GRPC_OVERRIDE {
return SerializationTraits<R>::Deserialize(buf, message_, max_message_size);
}
private:
R* message_; // Not a managed pointer because management is external to this
};
} // namespace CallOpGenericRecvMessageHelper
class CallOpGenericRecvMessage {
public:
CallOpGenericRecvMessage() : got_message(false) {}
template <class R>
void RecvMessage(R* message) {
deserialize_.reset(
new CallOpGenericRecvMessageHelper::DeserializeFuncType<R>(message));
}
bool got_message;
protected:
void AddOp(grpc_op* ops, size_t* nops) {
if (!deserialize_) return;
grpc_op* op = &ops[(*nops)++];
op->op = GRPC_OP_RECV_MESSAGE;
op->flags = 0;
op->reserved = NULL;
op->data.recv_message = &recv_buf_;
}
void FinishOp(bool* status, int max_message_size) {
if (!deserialize_) return;
if (recv_buf_) {
if (*status) {
got_message = true;
*status = deserialize_->Deserialize(recv_buf_, max_message_size).ok();
} else {
got_message = false;
grpc_byte_buffer_destroy(recv_buf_);
}
} else {
got_message = false;
*status = false;
}
deserialize_.reset();
}
private:
std::unique_ptr<CallOpGenericRecvMessageHelper::DeserializeFunc> deserialize_;
grpc_byte_buffer* recv_buf_;
};
class CallOpClientSendClose {
public:
CallOpClientSendClose() : send_(false) {}
void ClientSendClose() { send_ = true; }
protected:
void AddOp(grpc_op* ops, size_t* nops) {
if (!send_) return;
grpc_op* op = &ops[(*nops)++];
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
op->flags = 0;
op->reserved = NULL;
}
void FinishOp(bool* status, int max_message_size) { send_ = false; }
private:
bool send_;
};
class CallOpServerSendStatus {
public:
CallOpServerSendStatus() : send_status_available_(false) {}
void ServerSendStatus(
const std::multimap<grpc::string, grpc::string>& trailing_metadata,
const Status& status) {
trailing_metadata_count_ = trailing_metadata.size();
trailing_metadata_ = FillMetadataArray(trailing_metadata);
send_status_available_ = true;
send_status_code_ = static_cast<grpc_status_code>(status.error_code());
send_status_details_ = status.error_message();
}
protected:
void AddOp(grpc_op* ops, size_t* nops) {
if (!send_status_available_) return;
grpc_op* op = &ops[(*nops)++];
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count =
trailing_metadata_count_;
op->data.send_status_from_server.trailing_metadata = trailing_metadata_;
op->data.send_status_from_server.status = send_status_code_;
op->data.send_status_from_server.status_details =
send_status_details_.empty() ? nullptr : send_status_details_.c_str();
op->flags = 0;
op->reserved = NULL;
}
void FinishOp(bool* status, int max_message_size) {
if (!send_status_available_) return;
gpr_free(trailing_metadata_);
send_status_available_ = false;
}
private:
bool send_status_available_;
grpc_status_code send_status_code_;
grpc::string send_status_details_;
size_t trailing_metadata_count_;
grpc_metadata* trailing_metadata_;
};
class CallOpRecvInitialMetadata {
public:
CallOpRecvInitialMetadata() : recv_initial_metadata_(nullptr) {}
void RecvInitialMetadata(ClientContext* context) {
context->initial_metadata_received_ = true;
recv_initial_metadata_ = &context->recv_initial_metadata_;
}
protected:
void AddOp(grpc_op* ops, size_t* nops) {
if (!recv_initial_metadata_) return;
memset(&recv_initial_metadata_arr_, 0, sizeof(recv_initial_metadata_arr_));
grpc_op* op = &ops[(*nops)++];
op->op = GRPC_OP_RECV_INITIAL_METADATA;
op->data.recv_initial_metadata = &recv_initial_metadata_arr_;
op->flags = 0;
op->reserved = NULL;
}
void FinishOp(bool* status, int max_message_size) {
if (recv_initial_metadata_ == nullptr) return;
FillMetadataMap(&recv_initial_metadata_arr_, recv_initial_metadata_);
recv_initial_metadata_ = nullptr;
}
private:
std::multimap<grpc::string_ref, grpc::string_ref>* recv_initial_metadata_;
grpc_metadata_array recv_initial_metadata_arr_;
};
class CallOpClientRecvStatus {
public:
CallOpClientRecvStatus() : recv_status_(nullptr) {}
void ClientRecvStatus(ClientContext* context, Status* status) {
recv_trailing_metadata_ = &context->trailing_metadata_;
recv_status_ = status;
}
protected:
void AddOp(grpc_op* ops, size_t* nops) {
if (recv_status_ == nullptr) return;
memset(&recv_trailing_metadata_arr_, 0,
sizeof(recv_trailing_metadata_arr_));
status_details_ = nullptr;
status_details_capacity_ = 0;
grpc_op* op = &ops[(*nops)++];
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
op->data.recv_status_on_client.trailing_metadata =
&recv_trailing_metadata_arr_;
op->data.recv_status_on_client.status = &status_code_;
op->data.recv_status_on_client.status_details = &status_details_;
op->data.recv_status_on_client.status_details_capacity =
&status_details_capacity_;
op->flags = 0;
op->reserved = NULL;
}
void FinishOp(bool* status, int max_message_size) {
if (recv_status_ == nullptr) return;
FillMetadataMap(&recv_trailing_metadata_arr_, recv_trailing_metadata_);
*recv_status_ = Status(
static_cast<StatusCode>(status_code_),
status_details_ ? grpc::string(status_details_) : grpc::string());
gpr_free(status_details_);
recv_status_ = nullptr;
}
private:
std::multimap<grpc::string_ref, grpc::string_ref>* recv_trailing_metadata_;
Status* recv_status_;
grpc_metadata_array recv_trailing_metadata_arr_;
grpc_status_code status_code_;
char* status_details_;
size_t status_details_capacity_;
};
/// An abstract collection of call ops, used to generate the
/// grpc_call_op structure to pass down to the lower layers,
/// and as it is-a CompletionQueueTag, also massages the final
/// completion into the correct form for consumption in the C++
/// API.
class CallOpSetInterface : public CompletionQueueTag {
public:
CallOpSetInterface() : max_message_size_(0) {}
/// Fills in grpc_op, starting from ops[*nops] and moving
/// upwards.
virtual void FillOps(grpc_op* ops, size_t* nops) = 0;
void set_max_message_size(int max_message_size) {
max_message_size_ = max_message_size;
}
protected:
int max_message_size_;
};
/// Primary implementaiton of CallOpSetInterface.
/// Since we cannot use variadic templates, we declare slots up to
/// the maximum count of ops we'll need in a set. We leverage the
/// empty base class optimization to slim this class (especially
/// when there are many unused slots used). To avoid duplicate base classes,
/// the template parmeter for CallNoOp is varied by argument position.
template <class Op1 = CallNoOp<1>, class Op2 = CallNoOp<2>,
class Op3 = CallNoOp<3>, class Op4 = CallNoOp<4>,
class Op5 = CallNoOp<5>, class Op6 = CallNoOp<6>>
class CallOpSet : public CallOpSetInterface,
public Op1,
public Op2,
public Op3,
public Op4,
public Op5,
public Op6 {
public:
CallOpSet() : return_tag_(this) {}
void FillOps(grpc_op* ops, size_t* nops) GRPC_OVERRIDE {
this->Op1::AddOp(ops, nops);
this->Op2::AddOp(ops, nops);
this->Op3::AddOp(ops, nops);
this->Op4::AddOp(ops, nops);
this->Op5::AddOp(ops, nops);
this->Op6::AddOp(ops, nops);
}
bool FinalizeResult(void** tag, bool* status) GRPC_OVERRIDE {
this->Op1::FinishOp(status, max_message_size_);
this->Op2::FinishOp(status, max_message_size_);
this->Op3::FinishOp(status, max_message_size_);
this->Op4::FinishOp(status, max_message_size_);
this->Op5::FinishOp(status, max_message_size_);
this->Op6::FinishOp(status, max_message_size_);
*tag = return_tag_;
return true;
}
void set_output_tag(void* return_tag) { return_tag_ = return_tag; }
private:
void* return_tag_;
};
/// A CallOpSet that does not post completions to the completion queue.
///
/// Allows hiding some completions that the C core must generate from
/// C++ users.
template <class Op1 = CallNoOp<1>, class Op2 = CallNoOp<2>,
class Op3 = CallNoOp<3>, class Op4 = CallNoOp<4>,
class Op5 = CallNoOp<5>, class Op6 = CallNoOp<6>>
class SneakyCallOpSet : public CallOpSet<Op1, Op2, Op3, Op4, Op5, Op6> {
public:
bool FinalizeResult(void** tag, bool* status) GRPC_OVERRIDE {
typedef CallOpSet<Op1, Op2, Op3, Op4, Op5, Op6> Base;
return Base::FinalizeResult(tag, status) && false;
}
};
// Straightforward wrapping of the C call object
class Call GRPC_FINAL {
public:
/* call is owned by the caller */
Call(grpc_call* call, CallHook* call_hook_, CompletionQueue* cq);
Call(grpc_call* call, CallHook* call_hook_, CompletionQueue* cq,
int max_message_size);
void PerformOps(CallOpSetInterface* ops);
grpc_call* call() { return call_; }
CompletionQueue* cq() { return cq_; }
int max_message_size() { return max_message_size_; }
private:
CallHook* call_hook_;
CompletionQueue* cq_;
grpc_call* call_;
int max_message_size_;
};
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_CALL_H

@ -0,0 +1,51 @@
/*
*
* Copyright 2015-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 GRPCXX_IMPL_CODEGEN_CALL_HOOK_H
#define GRPCXX_IMPL_CODEGEN_CALL_HOOK_H
namespace grpc {
class CallOpSetInterface;
class Call;
/// Channel and Server implement this to allow them to hook performing ops
class CallHook {
public:
virtual ~CallHook() {}
virtual void PerformOpsOnCall(CallOpSetInterface* ops, Call* call) = 0;
};
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_CALL_HOOK_H

@ -0,0 +1,123 @@
/*
*
* 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 GRPCXX_IMPL_CODEGEN_CHANNEL_INTERFACE_H
#define GRPCXX_IMPL_CODEGEN_CHANNEL_INTERFACE_H
#include <grpc++/impl/codegen/status.h>
#include <grpc++/impl/codegen/time.h>
#include <grpc/impl/codegen/connectivity_state.h>
namespace grpc {
class Call;
class ClientContext;
class RpcMethod;
class CallOpSetInterface;
class CompletionQueue;
template <class R>
class ClientReader;
template <class W>
class ClientWriter;
template <class W, class R>
class ClientReaderWriter;
template <class R>
class ClientAsyncReader;
template <class W>
class ClientAsyncWriter;
template <class W, class R>
class ClientAsyncReaderWriter;
template <class R>
class ClientAsyncResponseReader;
/// Codegen interface for \a grpc::Channel.
class ChannelInterface {
public:
virtual ~ChannelInterface() {}
/// Get the current channel state. If the channel is in IDLE and
/// \a try_to_connect is set to true, try to connect.
virtual grpc_connectivity_state GetState(bool try_to_connect) = 0;
/// Return the \a tag on \a cq when the channel state is changed or \a
/// deadline expires. \a GetState needs to called to get the current state.
template <typename T>
void NotifyOnStateChange(grpc_connectivity_state last_observed, T deadline,
CompletionQueue* cq, void* tag) {
TimePoint<T> deadline_tp(deadline);
NotifyOnStateChangeImpl(last_observed, deadline_tp.raw_time(), cq, tag);
}
/// Blocking wait for channel state change or \a deadline expiration.
/// \a GetState needs to called to get the current state.
template <typename T>
bool WaitForStateChange(grpc_connectivity_state last_observed, T deadline) {
TimePoint<T> deadline_tp(deadline);
return WaitForStateChangeImpl(last_observed, deadline_tp.raw_time());
}
private:
template <class R>
friend class ::grpc::ClientReader;
template <class W>
friend class ::grpc::ClientWriter;
template <class W, class R>
friend class ::grpc::ClientReaderWriter;
template <class R>
friend class ::grpc::ClientAsyncReader;
template <class W>
friend class ::grpc::ClientAsyncWriter;
template <class W, class R>
friend class ::grpc::ClientAsyncReaderWriter;
template <class R>
friend class ::grpc::ClientAsyncResponseReader;
template <class InputMessage, class OutputMessage>
friend Status BlockingUnaryCall(ChannelInterface* channel,
const RpcMethod& method,
ClientContext* context,
const InputMessage& request,
OutputMessage* result);
friend class ::grpc::RpcMethod;
virtual Call CreateCall(const RpcMethod& method, ClientContext* context,
CompletionQueue* cq) = 0;
virtual void PerformOpsOnCall(CallOpSetInterface* ops, Call* call) = 0;
virtual void* RegisterMethod(const char* method) = 0;
virtual void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed,
gpr_timespec deadline,
CompletionQueue* cq, void* tag) = 0;
virtual bool WaitForStateChangeImpl(grpc_connectivity_state last_observed,
gpr_timespec deadline) = 0;
};
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_CHANNEL_INTERFACE_H

@ -0,0 +1,354 @@
/*
*
* Copyright 2015-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.
*
*/
/// A ClientContext allows the person implementing a service client to:
///
/// - Add custom metadata key-value pairs that will propagated to the server
/// side.
/// - Control call settings such as compression and authentication.
/// - Initial and trailing metadata coming from the server.
/// - Get performance metrics (ie, census).
///
/// Context settings are only relevant to the call they are invoked with, that
/// is to say, they aren't sticky. Some of these settings, such as the
/// compression options, can be made persistant at channel construction time
/// (see \a grpc::CreateCustomChannel).
///
/// \warning ClientContext instances should \em not be reused across rpcs.
#ifndef GRPCXX_IMPL_CODEGEN_CLIENT_CONTEXT_H
#define GRPCXX_IMPL_CODEGEN_CLIENT_CONTEXT_H
#include <map>
#include <memory>
#include <string>
#include <grpc++/impl/codegen/config.h>
#include <grpc++/impl/codegen/security/auth_context.h>
#include <grpc++/impl/codegen/status.h>
#include <grpc++/impl/codegen/string_ref.h>
#include <grpc++/impl/codegen/sync.h>
#include <grpc++/impl/codegen/time.h>
#include <grpc/impl/codegen/compression_types.h>
#include <grpc/impl/codegen/log.h>
#include <grpc/impl/codegen/propagation_bits.h>
#include <grpc/impl/codegen/time.h>
struct census_context;
struct grpc_call;
namespace grpc {
class Channel;
class ChannelInterface;
class CompletionQueue;
class CallCredentials;
class RpcMethod;
template <class R>
class ClientReader;
template <class W>
class ClientWriter;
template <class W, class R>
class ClientReaderWriter;
template <class R>
class ClientAsyncReader;
template <class W>
class ClientAsyncWriter;
template <class W, class R>
class ClientAsyncReaderWriter;
template <class R>
class ClientAsyncResponseReader;
class ServerContext;
/// Options for \a ClientContext::FromServerContext specifying which traits from
/// the \a ServerContext to propagate (copy) from it into a new \a
/// ClientContext.
///
/// \see ClientContext::FromServerContext
class PropagationOptions {
public:
PropagationOptions() : propagate_(GRPC_PROPAGATE_DEFAULTS) {}
PropagationOptions& enable_deadline_propagation() {
propagate_ |= GRPC_PROPAGATE_DEADLINE;
return *this;
}
PropagationOptions& disable_deadline_propagation() {
propagate_ &= ~GRPC_PROPAGATE_DEADLINE;
return *this;
}
PropagationOptions& enable_census_stats_propagation() {
propagate_ |= GRPC_PROPAGATE_CENSUS_STATS_CONTEXT;
return *this;
}
PropagationOptions& disable_census_stats_propagation() {
propagate_ &= ~GRPC_PROPAGATE_CENSUS_STATS_CONTEXT;
return *this;
}
PropagationOptions& enable_census_tracing_propagation() {
propagate_ |= GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT;
return *this;
}
PropagationOptions& disable_census_tracing_propagation() {
propagate_ &= ~GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT;
return *this;
}
PropagationOptions& enable_cancellation_propagation() {
propagate_ |= GRPC_PROPAGATE_CANCELLATION;
return *this;
}
PropagationOptions& disable_cancellation_propagation() {
propagate_ &= ~GRPC_PROPAGATE_CANCELLATION;
return *this;
}
uint32_t c_bitmask() const { return propagate_; }
private:
uint32_t propagate_;
};
namespace testing {
class InteropClientContextInspector;
} // namespace testing
class ClientContext {
public:
ClientContext();
~ClientContext();
/// Create a new \a ClientContext as a child of an incoming server call,
/// according to \a options (\see PropagationOptions).
///
/// \param server_context The source server context to use as the basis for
/// constructing the client context.
/// \param options The options controlling what to copy from the \a
/// server_context.
///
/// \return A newly constructed \a ClientContext instance based on \a
/// server_context, with traits propagated (copied) according to \a options.
static std::unique_ptr<ClientContext> FromServerContext(
const ServerContext& server_context,
PropagationOptions options = PropagationOptions());
/// Add the (\a meta_key, \a meta_value) pair to the metadata associated with
/// a client call. These are made available at the server side by the \a
/// grpc::ServerContext::client_metadata() method.
///
/// \warning This method should only be called before invoking the rpc.
///
/// \param meta_key The metadata key. If \a meta_value is binary data, it must
/// end in "-bin".
/// \param meta_value The metadata value. If its value is binary, it must be
/// base64-encoding (see https://tools.ietf.org/html/rfc4648#section-4) and \a
/// meta_key must end in "-bin".
void AddMetadata(const grpc::string& meta_key,
const grpc::string& meta_value);
/// Return a collection of initial metadata key-value pairs. Note that keys
/// may happen more than once (ie, a \a std::multimap is returned).
///
/// \warning This method should only be called after initial metadata has been
/// received. For streaming calls, see \a
/// ClientReaderInterface::WaitForInitialMetadata().
///
/// \return A multimap of initial metadata key-value pairs from the server.
const std::multimap<grpc::string_ref, grpc::string_ref>&
GetServerInitialMetadata() {
GPR_ASSERT(initial_metadata_received_);
return recv_initial_metadata_;
}
/// Return a collection of trailing metadata key-value pairs. Note that keys
/// may happen more than once (ie, a \a std::multimap is returned).
///
/// \warning This method is only callable once the stream has finished.
///
/// \return A multimap of metadata trailing key-value pairs from the server.
const std::multimap<grpc::string_ref, grpc::string_ref>&
GetServerTrailingMetadata() {
// TODO(yangg) check finished
return trailing_metadata_;
}
/// Set the deadline for the client call.
///
/// \warning This method should only be called before invoking the rpc.
///
/// \param deadline the deadline for the client call. Units are determined by
/// the type used.
template <typename T>
void set_deadline(const T& deadline) {
TimePoint<T> deadline_tp(deadline);
deadline_ = deadline_tp.raw_time();
}
#ifndef GRPC_CXX0X_NO_CHRONO
/// Return the deadline for the client call.
std::chrono::system_clock::time_point deadline() {
return Timespec2Timepoint(deadline_);
}
#endif // !GRPC_CXX0X_NO_CHRONO
/// Return a \a gpr_timespec representation of the client call's deadline.
gpr_timespec raw_deadline() { return deadline_; }
/// Set the per call authority header (see
/// https://tools.ietf.org/html/rfc7540#section-8.1.2.3).
void set_authority(const grpc::string& authority) { authority_ = authority; }
/// Return the authentication context for this client call.
///
/// \see grpc::AuthContext.
std::shared_ptr<const AuthContext> auth_context() const;
/// Set credentials for the client call.
///
/// A credentials object encapsulates all the state needed by a client to
/// authenticate with a server and make various assertions, e.g., about the
/// client’s identity, role, or whether it is authorized to make a particular
/// call.
///
/// \see http://www.grpc.io/docs/guides/auth.html
void set_credentials(const std::shared_ptr<CallCredentials>& creds) {
creds_ = creds;
}
/// Return the compression algorithm to be used by the client call.
grpc_compression_algorithm compression_algorithm() const {
return compression_algorithm_;
}
/// Set \a algorithm to be the compression algorithm used for the client call.
///
/// \param algorith The compression algorithm used for the client call.
void set_compression_algorithm(grpc_compression_algorithm algorithm);
/// Return the peer uri in a string.
///
/// \warning This value is never authenticated or subject to any security
/// related code. It must not be used for any authentication related
/// functionality. Instead, use auth_context.
///
/// \return The call's peer URI.
grpc::string peer() const;
/// Get and set census context.
void set_census_context(struct census_context* ccp) { census_context_ = ccp; }
struct census_context* census_context() const {
return census_context_;
}
/// Send a best-effort out-of-band cancel. The call could be in any stage.
/// e.g. if it is already finished, it may still return success.
///
/// There is no guarantee the call will be cancelled.
void TryCancel();
/// Global Callbacks
///
/// Can be set exactly once per application to install hooks whenever
/// a client context is constructed and destructed.
class GlobalCallbacks {
public:
virtual ~GlobalCallbacks() {}
virtual void DefaultConstructor(ClientContext* context) = 0;
virtual void Destructor(ClientContext* context) = 0;
};
static void SetGlobalCallbacks(GlobalCallbacks* callbacks);
private:
// Disallow copy and assign.
ClientContext(const ClientContext&);
ClientContext& operator=(const ClientContext&);
friend class ::grpc::testing::InteropClientContextInspector;
friend class CallOpClientRecvStatus;
friend class CallOpRecvInitialMetadata;
friend class Channel;
template <class R>
friend class ::grpc::ClientReader;
template <class W>
friend class ::grpc::ClientWriter;
template <class W, class R>
friend class ::grpc::ClientReaderWriter;
template <class R>
friend class ::grpc::ClientAsyncReader;
template <class W>
friend class ::grpc::ClientAsyncWriter;
template <class W, class R>
friend class ::grpc::ClientAsyncReaderWriter;
template <class R>
friend class ::grpc::ClientAsyncResponseReader;
template <class InputMessage, class OutputMessage>
friend Status BlockingUnaryCall(ChannelInterface* channel,
const RpcMethod& method,
ClientContext* context,
const InputMessage& request,
OutputMessage* result);
grpc_call* call() { return call_; }
void set_call(grpc_call* call, const std::shared_ptr<Channel>& channel);
grpc::string authority() { return authority_; }
bool initial_metadata_received_;
std::shared_ptr<Channel> channel_;
grpc::mutex mu_;
grpc_call* call_;
bool call_canceled_;
gpr_timespec deadline_;
grpc::string authority_;
std::shared_ptr<CallCredentials> creds_;
mutable std::shared_ptr<const AuthContext> auth_context_;
struct census_context* census_context_;
std::multimap<grpc::string, grpc::string> send_initial_metadata_;
std::multimap<grpc::string_ref, grpc::string_ref> recv_initial_metadata_;
std::multimap<grpc::string_ref, grpc::string_ref> trailing_metadata_;
grpc_call* propagate_from_call_;
PropagationOptions propagation_options_;
grpc_compression_algorithm compression_algorithm_;
};
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_CLIENT_CONTEXT_H

@ -0,0 +1,75 @@
/*
*
* Copyright 2015-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 GRPCXX_IMPL_CODEGEN_CLIENT_UNARY_CALL_H
#define GRPCXX_IMPL_CODEGEN_CLIENT_UNARY_CALL_H
#include <grpc++/impl/codegen/call.h>
#include <grpc++/impl/codegen/channel_interface.h>
#include <grpc++/impl/codegen/config.h>
#include <grpc++/impl/codegen/status.h>
namespace grpc {
class Channel;
class ClientContext;
class CompletionQueue;
class RpcMethod;
// Wrapper that performs a blocking unary call
template <class InputMessage, class OutputMessage>
Status BlockingUnaryCall(ChannelInterface* channel, const RpcMethod& method,
ClientContext* context, const InputMessage& request,
OutputMessage* result) {
CompletionQueue cq;
Call call(channel->CreateCall(method, context, &cq));
CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
CallOpRecvInitialMetadata, CallOpRecvMessage<OutputMessage>,
CallOpClientSendClose, CallOpClientRecvStatus> ops;
Status status = ops.SendMessage(request);
if (!status.ok()) {
return status;
}
ops.SendInitialMetadata(context->send_initial_metadata_);
ops.RecvInitialMetadata(context);
ops.RecvMessage(result);
ops.ClientSendClose();
ops.ClientRecvStatus(context, &status);
call.PerformOps(&ops);
GPR_ASSERT((cq.Pluck(&ops) && ops.got_message) || !status.ok());
return status;
}
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_CLIENT_UNARY_CALL_H

@ -0,0 +1,202 @@
/*
*
* Copyright 2015-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.
*
*/
/// A completion queue implements a concurrent producer-consumer queue, with two
/// main methods, \a Next and \a AsyncNext.
#ifndef GRPCXX_IMPL_CODEGEN_COMPLETION_QUEUE_H
#define GRPCXX_IMPL_CODEGEN_COMPLETION_QUEUE_H
#include <grpc++/impl/codegen/grpc_library.h>
#include <grpc++/impl/codegen/status.h>
#include <grpc++/impl/codegen/time.h>
struct grpc_completion_queue;
namespace grpc {
template <class R>
class ClientReader;
template <class W>
class ClientWriter;
template <class W, class R>
class ClientReaderWriter;
template <class R>
class ServerReader;
template <class W>
class ServerWriter;
template <class W, class R>
class ServerReaderWriter;
template <class ServiceType, class RequestType, class ResponseType>
class RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
class ClientStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
class ServerStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
class BidiStreamingHandler;
class UnknownMethodHandler;
class Channel;
class ChannelInterface;
class ClientContext;
class CompletionQueueTag;
class CompletionQueue;
class RpcMethod;
class Server;
class ServerBuilder;
class ServerContext;
/// A thin wrapper around \a grpc_completion_queue (see / \a
/// src/core/surface/completion_queue.h).
class CompletionQueue : private GrpcLibrary {
public:
/// Default constructor. Implicitly creates a \a grpc_completion_queue
/// instance.
CompletionQueue();
/// Wrap \a take, taking ownership of the instance.
///
/// \param take The completion queue instance to wrap. Ownership is taken.
explicit CompletionQueue(grpc_completion_queue* take);
/// Destructor. Destroys the owned wrapped completion queue / instance.
~CompletionQueue();
/// Tri-state return for AsyncNext: SHUTDOWN, GOT_EVENT, TIMEOUT.
enum NextStatus {
SHUTDOWN, ///< The completion queue has been shutdown.
GOT_EVENT, ///< Got a new event; \a tag will be filled in with its
///< associated value; \a ok indicating its success.
TIMEOUT ///< deadline was reached.
};
/// Read from the queue, blocking up to \a deadline (or the queue's shutdown).
/// Both \a tag and \a ok are updated upon success (if an event is available
/// within the \a deadline). A \a tag points to an arbitrary location usually
/// employed to uniquely identify an event.
///
/// \param tag[out] Upon sucess, updated to point to the event's tag.
/// \param ok[out] Upon sucess, true if read a regular event, false otherwise.
/// \param deadline[in] How long to block in wait for an event.
///
/// \return The type of event read.
template <typename T>
NextStatus AsyncNext(void** tag, bool* ok, const T& deadline) {
TimePoint<T> deadline_tp(deadline);
return AsyncNextInternal(tag, ok, deadline_tp.raw_time());
}
/// Read from the queue, blocking until an event is available or the queue is
/// shutting down.
///
/// \param tag[out] Updated to point to the read event's tag.
/// \param ok[out] true if read a regular event, false otherwise.
///
/// \return true if read a regular event, false if the queue is shutting down.
bool Next(void** tag, bool* ok) {
return (AsyncNextInternal(tag, ok, gpr_inf_future(GPR_CLOCK_REALTIME)) !=
SHUTDOWN);
}
/// Request the shutdown of the queue.
///
/// \warning This method must be called at some point. Once invoked, \a Next
/// will start to return false and \a AsyncNext will return \a
/// NextStatus::SHUTDOWN. Only once either one of these methods does that
/// (that is, once the queue has been \em drained) can an instance of this
/// class be destroyed.
void Shutdown();
/// Returns a \em raw pointer to the underlying \a grpc_completion_queue
/// instance.
///
/// \warning Remember that the returned instance is owned. No transfer of
/// owership is performed.
grpc_completion_queue* cq() { return cq_; }
private:
// Friend synchronous wrappers so that they can access Pluck(), which is
// a semi-private API geared towards the synchronous implementation.
template <class R>
friend class ::grpc::ClientReader;
template <class W>
friend class ::grpc::ClientWriter;
template <class W, class R>
friend class ::grpc::ClientReaderWriter;
template <class R>
friend class ::grpc::ServerReader;
template <class W>
friend class ::grpc::ServerWriter;
template <class W, class R>
friend class ::grpc::ServerReaderWriter;
template <class ServiceType, class RequestType, class ResponseType>
friend class RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
friend class ClientStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
friend class ServerStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
friend class BidiStreamingHandler;
friend class UnknownMethodHandler;
friend class ::grpc::Server;
friend class ::grpc::ServerContext;
template <class InputMessage, class OutputMessage>
friend Status BlockingUnaryCall(ChannelInterface* channel,
const RpcMethod& method,
ClientContext* context,
const InputMessage& request,
OutputMessage* result);
NextStatus AsyncNextInternal(void** tag, bool* ok, gpr_timespec deadline);
/// Wraps \a grpc_completion_queue_pluck.
/// \warning Must not be mixed with calls to \a Next.
bool Pluck(CompletionQueueTag* tag);
/// Performs a single polling pluck on \a tag.
void TryPluck(CompletionQueueTag* tag);
grpc_completion_queue* cq_; // owned
};
/// A specific type of completion queue used by the processing of notifications
/// by servers. Instantiated by \a ServerBuilder.
class ServerCompletionQueue : public CompletionQueue {
private:
friend class ServerBuilder;
ServerCompletionQueue() {}
};
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_COMPLETION_QUEUE_H

@ -0,0 +1,52 @@
/*
*
* Copyright 2015-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 GRPCXX_COMPLETION_QUEUE_TAG_H
#define GRPCXX_COMPLETION_QUEUE_TAG_H
namespace grpc {
/// An interface allowing implementors to process and filter event tags.
class CompletionQueueTag {
public:
virtual ~CompletionQueueTag() {}
// Called prior to returning from Next(), return value is the status of the
// operation (return status is the default thing to do). If this function
// returns false, the tag is dropped and not returned from the completion
// queue
virtual bool FinalizeResult(void** tag, bool* status) = 0;
};
} // namespace grpc
#endif // GRPCXX_COMPLETION_QUEUE_TAG_H

@ -0,0 +1,116 @@
/*
*
* 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 GRPCXX_IMPL_CODEGEN_CONFIG_H
#define GRPCXX_IMPL_CODEGEN_CONFIG_H
#if !defined(GRPC_NO_AUTODETECT_PLATFORM)
#ifdef _MSC_VER
// Visual Studio 2010 is 1600.
#if _MSC_VER < 1600
#error "gRPC is only supported with Visual Studio starting at 2010"
// Visual Studio 2013 is 1800.
#elif _MSC_VER < 1800
#define GRPC_CXX0X_NO_FINAL 1
#define GRPC_CXX0X_NO_OVERRIDE 1
#define GRPC_CXX0X_NO_CHRONO 1
#define GRPC_CXX0X_NO_THREAD 1
#endif
#endif // Visual Studio
#ifndef __clang__
#ifdef __GNUC__
// nullptr was added in gcc 4.6
#if (__GNUC__ * 100 + __GNUC_MINOR__ < 406)
#define GRPC_CXX0X_NO_NULLPTR 1
#endif
// final and override were added in gcc 4.7
#if (__GNUC__ * 100 + __GNUC_MINOR__ < 407)
#define GRPC_CXX0X_NO_FINAL 1
#define GRPC_CXX0X_NO_OVERRIDE 1
#endif
#endif
#endif
#endif
#ifdef GRPC_CXX0X_NO_FINAL
#define GRPC_FINAL
#else
#define GRPC_FINAL final
#endif
#ifdef GRPC_CXX0X_NO_OVERRIDE
#define GRPC_OVERRIDE
#else
#define GRPC_OVERRIDE override
#endif
#ifdef GRPC_CXX0X_NO_NULLPTR
#include <memory>
namespace grpc {
const class {
public:
template <class T>
operator T *() const {
return static_cast<T *>(0);
}
template <class T>
operator std::unique_ptr<T>() const {
return std::unique_ptr<T>(static_cast<T *>(0));
}
template <class T>
operator std::shared_ptr<T>() const {
return std::shared_ptr<T>(static_cast<T *>(0));
}
operator bool() const { return false; }
private:
void operator&() const = delete;
} nullptr = {};
}
#endif
#ifndef GRPC_CUSTOM_STRING
#include <string>
#define GRPC_CUSTOM_STRING std::string
#endif
namespace grpc {
typedef GRPC_CUSTOM_STRING string;
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_CONFIG_H

@ -0,0 +1,72 @@
/*
*
* Copyright 2015-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 GRPCXX_IMPL_CODEGEN_CONFIG_PROTOBUF_H
#define GRPCXX_IMPL_CODEGEN_CONFIG_PROTOBUF_H
#ifndef GRPC_CUSTOM_PROTOBUF_INT64
#include <google/protobuf/stubs/common.h>
#define GRPC_CUSTOM_PROTOBUF_INT64 ::google::protobuf::int64
#endif
#ifndef GRPC_CUSTOM_MESSAGE
#include <google/protobuf/message.h>
#define GRPC_CUSTOM_MESSAGE ::google::protobuf::Message
#endif
#ifndef GRPC_CUSTOM_ZEROCOPYOUTPUTSTREAM
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream.h>
#define GRPC_CUSTOM_ZEROCOPYOUTPUTSTREAM \
::google::protobuf::io::ZeroCopyOutputStream
#define GRPC_CUSTOM_ZEROCOPYINPUTSTREAM \
::google::protobuf::io::ZeroCopyInputStream
#define GRPC_CUSTOM_CODEDINPUTSTREAM ::google::protobuf::io::CodedInputStream
#endif
namespace grpc {
namespace protobuf {
typedef GRPC_CUSTOM_MESSAGE Message;
typedef GRPC_CUSTOM_PROTOBUF_INT64 int64;
namespace io {
typedef GRPC_CUSTOM_ZEROCOPYOUTPUTSTREAM ZeroCopyOutputStream;
typedef GRPC_CUSTOM_ZEROCOPYINPUTSTREAM ZeroCopyInputStream;
typedef GRPC_CUSTOM_CODEDINPUTSTREAM CodedInputStream;
} // namespace io
} // namespace protobuf
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_CONFIG_PROTOBUF_H

@ -0,0 +1,67 @@
/*
*
* 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 GRPCXX_IMPL_CODEGEN_GRPC_LIBRARY_H
#define GRPCXX_IMPL_CODEGEN_GRPC_LIBRARY_H
#include <grpc/impl/codegen/log.h>
namespace grpc {
class GrpcLibraryInterface {
public:
virtual void init() = 0;
virtual void shutdown() = 0;
};
extern GrpcLibraryInterface* g_glip;
class GrpcLibrary {
public:
GrpcLibrary() {
GPR_ASSERT(g_glip &&
"gRPC library not initialized. See "
"grpc::internal::GrpcLibraryInitializer.");
g_glip->init();
}
virtual ~GrpcLibrary() {
GPR_ASSERT(g_glip &&
"gRPC library not initialized. See "
"grpc::internal::GrpcLibraryInitializer.");
g_glip->shutdown();
}
};
} // namespace grpc
#endif // GRPCXX_IMPL_GRPC_LIBRARY_H

@ -0,0 +1,203 @@
/*
*
* Copyright 2015-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 GRPCXX_IMPL_CODEGEN_METHOD_HANDLER_IMPL_H
#define GRPCXX_IMPL_CODEGEN_METHOD_HANDLER_IMPL_H
#include <grpc++/impl/codegen/rpc_service_method.h>
#include <grpc++/impl/codegen/sync_stream.h>
namespace grpc {
// A wrapper class of an application provided rpc method handler.
template <class ServiceType, class RequestType, class ResponseType>
class RpcMethodHandler : public MethodHandler {
public:
RpcMethodHandler(
std::function<Status(ServiceType*, ServerContext*, const RequestType*,
ResponseType*)> func,
ServiceType* service)
: func_(func), service_(service) {}
void RunHandler(const HandlerParameter& param) GRPC_FINAL {
RequestType req;
Status status = SerializationTraits<RequestType>::Deserialize(
param.request, &req, param.max_message_size);
ResponseType rsp;
if (status.ok()) {
status = func_(service_, param.server_context, &req, &rsp);
}
GPR_ASSERT(!param.server_context->sent_initial_metadata_);
CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
CallOpServerSendStatus> ops;
ops.SendInitialMetadata(param.server_context->initial_metadata_);
if (status.ok()) {
status = ops.SendMessage(rsp);
}
ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
param.call->PerformOps(&ops);
param.call->cq()->Pluck(&ops);
}
private:
// Application provided rpc handler function.
std::function<Status(ServiceType*, ServerContext*, const RequestType*,
ResponseType*)> func_;
// The class the above handler function lives in.
ServiceType* service_;
};
// A wrapper class of an application provided client streaming handler.
template <class ServiceType, class RequestType, class ResponseType>
class ClientStreamingHandler : public MethodHandler {
public:
ClientStreamingHandler(
std::function<Status(ServiceType*, ServerContext*,
ServerReader<RequestType>*, ResponseType*)> func,
ServiceType* service)
: func_(func), service_(service) {}
void RunHandler(const HandlerParameter& param) GRPC_FINAL {
ServerReader<RequestType> reader(param.call, param.server_context);
ResponseType rsp;
Status status = func_(service_, param.server_context, &reader, &rsp);
GPR_ASSERT(!param.server_context->sent_initial_metadata_);
CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
CallOpServerSendStatus> ops;
ops.SendInitialMetadata(param.server_context->initial_metadata_);
if (status.ok()) {
status = ops.SendMessage(rsp);
}
ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
param.call->PerformOps(&ops);
param.call->cq()->Pluck(&ops);
}
private:
std::function<Status(ServiceType*, ServerContext*, ServerReader<RequestType>*,
ResponseType*)> func_;
ServiceType* service_;
};
// A wrapper class of an application provided server streaming handler.
template <class ServiceType, class RequestType, class ResponseType>
class ServerStreamingHandler : public MethodHandler {
public:
ServerStreamingHandler(
std::function<Status(ServiceType*, ServerContext*, const RequestType*,
ServerWriter<ResponseType>*)> func,
ServiceType* service)
: func_(func), service_(service) {}
void RunHandler(const HandlerParameter& param) GRPC_FINAL {
RequestType req;
Status status = SerializationTraits<RequestType>::Deserialize(
param.request, &req, param.max_message_size);
if (status.ok()) {
ServerWriter<ResponseType> writer(param.call, param.server_context);
status = func_(service_, param.server_context, &req, &writer);
}
CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> ops;
if (!param.server_context->sent_initial_metadata_) {
ops.SendInitialMetadata(param.server_context->initial_metadata_);
}
ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
param.call->PerformOps(&ops);
param.call->cq()->Pluck(&ops);
}
private:
std::function<Status(ServiceType*, ServerContext*, const RequestType*,
ServerWriter<ResponseType>*)> func_;
ServiceType* service_;
};
// A wrapper class of an application provided bidi-streaming handler.
template <class ServiceType, class RequestType, class ResponseType>
class BidiStreamingHandler : public MethodHandler {
public:
BidiStreamingHandler(
std::function<Status(ServiceType*, ServerContext*,
ServerReaderWriter<ResponseType, RequestType>*)>
func,
ServiceType* service)
: func_(func), service_(service) {}
void RunHandler(const HandlerParameter& param) GRPC_FINAL {
ServerReaderWriter<ResponseType, RequestType> stream(param.call,
param.server_context);
Status status = func_(service_, param.server_context, &stream);
CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> ops;
if (!param.server_context->sent_initial_metadata_) {
ops.SendInitialMetadata(param.server_context->initial_metadata_);
}
ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
param.call->PerformOps(&ops);
param.call->cq()->Pluck(&ops);
}
private:
std::function<Status(ServiceType*, ServerContext*,
ServerReaderWriter<ResponseType, RequestType>*)> func_;
ServiceType* service_;
};
// Handle unknown method by returning UNIMPLEMENTED error.
class UnknownMethodHandler : public MethodHandler {
public:
template <class T>
static void FillOps(ServerContext* context, T* ops) {
Status status(StatusCode::UNIMPLEMENTED, "");
if (!context->sent_initial_metadata_) {
ops->SendInitialMetadata(context->initial_metadata_);
context->sent_initial_metadata_ = true;
}
ops->ServerSendStatus(context->trailing_metadata_, status);
}
void RunHandler(const HandlerParameter& param) GRPC_FINAL {
CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> ops;
FillOps(param.server_context, &ops);
param.call->PerformOps(&ops);
param.call->cq()->Pluck(&ops);
}
};
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_METHOD_HANDLER_IMPL_H

@ -0,0 +1,76 @@
/*
*
* Copyright 2015-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 GRPCXX_IMPL_CODEGEN_PROTO_UTILS_H
#define GRPCXX_IMPL_CODEGEN_PROTO_UTILS_H
#include <type_traits>
#include <grpc/impl/codegen/byte_buffer.h>
#include <grpc++/impl/codegen/serialization_traits.h>
#include <grpc++/impl/codegen/config_protobuf.h>
#include <grpc++/impl/codegen/status.h>
namespace grpc {
// Serialize the msg into a buffer created inside the function. The caller
// should destroy the returned buffer when done with it. If serialization fails,
// false is returned and buffer is left unchanged.
Status SerializeProto(const grpc::protobuf::Message& msg,
grpc_byte_buffer** buffer);
// The caller keeps ownership of buffer and msg.
Status DeserializeProto(grpc_byte_buffer* buffer, grpc::protobuf::Message* msg,
int max_message_size);
template <class T>
class SerializationTraits<T, typename std::enable_if<std::is_base_of<
grpc::protobuf::Message, T>::value>::type> {
public:
static Status Serialize(const grpc::protobuf::Message& msg,
grpc_byte_buffer** buffer, bool* own_buffer) {
*own_buffer = true;
return SerializeProto(msg, buffer);
}
static Status Deserialize(grpc_byte_buffer* buffer,
grpc::protobuf::Message* msg,
int max_message_size) {
auto status = DeserializeProto(buffer, msg, max_message_size);
grpc_byte_buffer_destroy(buffer);
return status;
}
};
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_PROTO_UTILS_H

@ -0,0 +1,73 @@
/*
*
* Copyright 2015-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 GRPCXX_IMPL_CODEGEN_RPC_METHOD_H
#define GRPCXX_IMPL_CODEGEN_RPC_METHOD_H
#include <memory>
#include <grpc++/impl/codegen/channel_interface.h>
namespace grpc {
class RpcMethod {
public:
enum RpcType {
NORMAL_RPC = 0,
CLIENT_STREAMING, // request streaming
SERVER_STREAMING, // response streaming
BIDI_STREAMING
};
RpcMethod(const char* name, RpcType type)
: name_(name), method_type_(type), channel_tag_(NULL) {}
RpcMethod(const char* name, RpcType type,
const std::shared_ptr<ChannelInterface>& channel)
: name_(name),
method_type_(type),
channel_tag_(channel->RegisterMethod(name)) {}
const char* name() const { return name_; }
RpcType method_type() const { return method_type_; }
void* channel_tag() const { return channel_tag_; }
private:
const char* const name_;
const RpcType method_type_;
void* const channel_tag_;
};
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_RPC_METHOD_H

@ -0,0 +1,92 @@
/*
*
* 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 GRPCXX_IMPL_CODEGEN_RPC_SERVICE_METHOD_H
#define GRPCXX_IMPL_CODEGEN_RPC_SERVICE_METHOD_H
#include <climits>
#include <functional>
#include <map>
#include <memory>
#include <vector>
#include <grpc++/impl/codegen/config.h>
#include <grpc++/impl/codegen/rpc_method.h>
#include <grpc++/impl/codegen/status.h>
namespace grpc {
class ServerContext;
class StreamContextInterface;
// Base class for running an RPC handler.
class MethodHandler {
public:
virtual ~MethodHandler() {}
struct HandlerParameter {
HandlerParameter(Call* c, ServerContext* context, grpc_byte_buffer* req,
int max_size)
: call(c),
server_context(context),
request(req),
max_message_size(max_size) {}
Call* call;
ServerContext* server_context;
// Handler required to grpc_byte_buffer_destroy this
grpc_byte_buffer* request;
int max_message_size;
};
virtual void RunHandler(const HandlerParameter& param) = 0;
};
// Server side rpc method class
class RpcServiceMethod : public RpcMethod {
public:
// Takes ownership of the handler
RpcServiceMethod(const char* name, RpcMethod::RpcType type,
MethodHandler* handler)
: RpcMethod(name, type), server_tag_(nullptr), handler_(handler) {}
void set_server_tag(void* tag) { server_tag_ = tag; }
void* server_tag() const { return server_tag_; }
// if MethodHandler is nullptr, then this is an async method
MethodHandler* handler() const { return handler_.get(); }
void ResetHandler() { handler_.reset(); }
private:
void* server_tag_;
std::unique_ptr<MethodHandler> handler_;
};
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_RPC_SERVICE_METHOD_H

@ -0,0 +1,110 @@
/*
*
* Copyright 2015-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 GRPCXX_IMPL_CODEGEN_SECURITY_AUTH_CONTEXT_H
#define GRPCXX_IMPL_CODEGEN_SECURITY_AUTH_CONTEXT_H
#include <iterator>
#include <vector>
#include <grpc++/impl/codegen/config.h>
#include <grpc++/impl/codegen/string_ref.h>
struct grpc_auth_context;
struct grpc_auth_property;
struct grpc_auth_property_iterator;
namespace grpc {
class SecureAuthContext;
typedef std::pair<grpc::string_ref, grpc::string_ref> AuthProperty;
class AuthPropertyIterator
: public std::iterator<std::input_iterator_tag, const AuthProperty> {
public:
~AuthPropertyIterator();
AuthPropertyIterator& operator++();
AuthPropertyIterator operator++(int);
bool operator==(const AuthPropertyIterator& rhs) const;
bool operator!=(const AuthPropertyIterator& rhs) const;
const AuthProperty operator*();
protected:
AuthPropertyIterator();
AuthPropertyIterator(const grpc_auth_property* property,
const grpc_auth_property_iterator* iter);
private:
friend class SecureAuthContext;
const grpc_auth_property* property_;
// The following items form a grpc_auth_property_iterator.
const grpc_auth_context* ctx_;
size_t index_;
const char* name_;
};
/// Class encapsulating the Authentication Information.
///
/// It includes the secure identity of the peer, the type of secure transport
/// used as well as any other properties required by the authorization layer.
class AuthContext {
public:
virtual ~AuthContext() {}
/// Returns true if the peer is authenticated.
virtual bool IsPeerAuthenticated() const = 0;
/// A peer identity.
///
/// It is, in general, comprised of one or more properties (in which case they
/// have the same name).
virtual std::vector<grpc::string_ref> GetPeerIdentity() const = 0;
virtual grpc::string GetPeerIdentityPropertyName() const = 0;
/// Returns all the property values with the given name.
virtual std::vector<grpc::string_ref> FindPropertyValues(
const grpc::string& name) const = 0;
/// Iteration over all the properties.
virtual AuthPropertyIterator begin() const = 0;
virtual AuthPropertyIterator end() const = 0;
// Mutation functions: should only be used by an AuthMetadataProcessor.
virtual void AddProperty(const grpc::string& key,
const grpc::string_ref& value) = 0;
virtual bool SetPeerIdentityPropertyName(const grpc::string& name) = 0;
};
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_SECURITY_AUTH_CONTEXT_H

@ -0,0 +1,68 @@
/*
*
* Copyright 2015-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 GRPCXX_IMPL_CODEGEN_SERIALIZATION_TRAITS_H
#define GRPCXX_IMPL_CODEGEN_SERIALIZATION_TRAITS_H
namespace grpc {
/// Defines how to serialize and deserialize some type.
///
/// Used for hooking different message serialization API's into GRPC.
/// Each SerializationTraits implementation must provide the following
/// functions:
/// static Status Serialize(const Message& msg,
/// grpc_byte_buffer** buffer,
// bool* own_buffer);
/// static Status Deserialize(grpc_byte_buffer* buffer,
/// Message* msg,
/// int max_message_size);
///
/// Serialize is required to convert message to a grpc_byte_buffer, and
/// to store a pointer to that byte buffer at *buffer. *own_buffer should
/// be set to true if the caller owns said byte buffer, or false if
/// ownership is retained elsewhere.
///
/// Deserialize is required to convert buffer into the message stored at
/// msg. max_message_size is passed in as a bound on the maximum number of
/// message bytes Deserialize should accept.
///
/// Both functions return a Status, allowing them to explain what went
/// wrong if required.
template <class Message,
class UnusedButHereForPartialTemplateSpecialization = void>
class SerializationTraits;
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_SERIALIZATION_TRAITS_H

@ -0,0 +1,201 @@
/*
*
* Copyright 2015-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 GRPCXX_IMPL_CODEGEN_SERVER_CONTEXT_H
#define GRPCXX_IMPL_CODEGEN_SERVER_CONTEXT_H
#include <map>
#include <memory>
#include <grpc/impl/codegen/compression_types.h>
#include <grpc/impl/codegen/time.h>
#include <grpc++/impl/codegen/security/auth_context.h>
#include <grpc++/impl/codegen/config.h>
#include <grpc++/impl/codegen/string_ref.h>
#include <grpc++/impl/codegen/time.h>
struct gpr_timespec;
struct grpc_metadata;
struct grpc_call;
struct census_context;
namespace grpc {
class ClientContext;
template <class W, class R>
class ServerAsyncReader;
template <class W>
class ServerAsyncWriter;
template <class W>
class ServerAsyncResponseWriter;
template <class W, class R>
class ServerAsyncReaderWriter;
template <class R>
class ServerReader;
template <class W>
class ServerWriter;
template <class W, class R>
class ServerReaderWriter;
template <class ServiceType, class RequestType, class ResponseType>
class RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
class ClientStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
class ServerStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
class BidiStreamingHandler;
class UnknownMethodHandler;
class Call;
class CallOpBuffer;
class CompletionQueue;
class Server;
class ServerInterface;
namespace testing {
class InteropServerContextInspector;
} // namespace testing
// Interface of server side rpc context.
class ServerContext {
public:
ServerContext(); // for async calls
~ServerContext();
#ifndef GRPC_CXX0X_NO_CHRONO
std::chrono::system_clock::time_point deadline() {
return Timespec2Timepoint(deadline_);
}
#endif // !GRPC_CXX0X_NO_CHRONO
gpr_timespec raw_deadline() { return deadline_; }
void AddInitialMetadata(const grpc::string& key, const grpc::string& value);
void AddTrailingMetadata(const grpc::string& key, const grpc::string& value);
bool IsCancelled() const;
const std::multimap<grpc::string_ref, grpc::string_ref>& client_metadata() {
return client_metadata_;
}
grpc_compression_level compression_level() const {
return compression_level_;
}
void set_compression_level(grpc_compression_level level);
grpc_compression_algorithm compression_algorithm() const {
return compression_algorithm_;
}
void set_compression_algorithm(grpc_compression_algorithm algorithm);
std::shared_ptr<const AuthContext> auth_context() const;
// Return the peer uri in a string.
// WARNING: this value is never authenticated or subject to any security
// related code. It must not be used for any authentication related
// functionality. Instead, use auth_context.
grpc::string peer() const;
const struct census_context* census_context() const;
// Async only. Has to be called before the rpc starts.
// Returns the tag in completion queue when the rpc finishes.
// IsCancelled() can then be called to check whether the rpc was cancelled.
void AsyncNotifyWhenDone(void* tag) {
has_notify_when_done_tag_ = true;
async_notify_when_done_tag_ = tag;
}
private:
friend class ::grpc::testing::InteropServerContextInspector;
friend class ::grpc::ServerInterface;
friend class ::grpc::Server;
template <class W, class R>
friend class ::grpc::ServerAsyncReader;
template <class W>
friend class ::grpc::ServerAsyncWriter;
template <class W>
friend class ::grpc::ServerAsyncResponseWriter;
template <class W, class R>
friend class ::grpc::ServerAsyncReaderWriter;
template <class R>
friend class ::grpc::ServerReader;
template <class W>
friend class ::grpc::ServerWriter;
template <class W, class R>
friend class ::grpc::ServerReaderWriter;
template <class ServiceType, class RequestType, class ResponseType>
friend class RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
friend class ClientStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
friend class ServerStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
friend class BidiStreamingHandler;
friend class UnknownMethodHandler;
friend class ::grpc::ClientContext;
// Prevent copying.
ServerContext(const ServerContext&);
ServerContext& operator=(const ServerContext&);
class CompletionOp;
void BeginCompletionOp(Call* call);
ServerContext(gpr_timespec deadline, grpc_metadata* metadata,
size_t metadata_count);
void set_call(grpc_call* call);
CompletionOp* completion_op_;
bool has_notify_when_done_tag_;
void* async_notify_when_done_tag_;
gpr_timespec deadline_;
grpc_call* call_;
CompletionQueue* cq_;
bool sent_initial_metadata_;
mutable std::shared_ptr<const AuthContext> auth_context_;
std::multimap<grpc::string_ref, grpc::string_ref> client_metadata_;
std::multimap<grpc::string, grpc::string> initial_metadata_;
std::multimap<grpc::string, grpc::string> trailing_metadata_;
grpc_compression_level compression_level_;
grpc_compression_algorithm compression_algorithm_;
};
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_SERVER_CONTEXT_H

@ -0,0 +1,254 @@
/*
*
* Copyright 2015-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 GRPCXX_IMPL_CODEGEN_SERVER_INTERFACE_H
#define GRPCXX_IMPL_CODEGEN_SERVER_INTERFACE_H
#include <grpc++/impl/codegen/call_hook.h>
#include <grpc++/impl/codegen/completion_queue_tag.h>
#include <grpc++/impl/codegen/rpc_service_method.h>
namespace grpc {
class AsyncGenericService;
class AsynchronousService;
class GenericServerContext;
class RpcService;
class ServerAsyncStreamingInterface;
class ServerCompletionQueue;
class ServerContext;
class ServerCredentials;
class Service;
class ThreadPoolInterface;
/// Models a gRPC server.
///
/// Servers are configured and started via \a grpc::ServerBuilder.
class ServerInterface : public CallHook {
public:
virtual ~ServerInterface() {}
/// Shutdown the server, blocking until all rpc processing finishes.
/// Forcefully terminate pending calls after \a deadline expires.
///
/// \param deadline How long to wait until pending rpcs are forcefully
/// terminated.
template <class T>
void Shutdown(const T& deadline) {
ShutdownInternal(TimePoint<T>(deadline).raw_time());
}
/// Shutdown the server, waiting for all rpc processing to finish.
void Shutdown() { ShutdownInternal(gpr_inf_future(GPR_CLOCK_MONOTONIC)); }
/// Block waiting for all work to complete.
///
/// \warning The server must be either shutting down or some other thread must
/// call \a Shutdown for this function to ever return.
virtual void Wait() = 0;
protected:
friend class AsynchronousService;
friend class Service;
/// Register a service. This call does not take ownership of the service.
/// The service must exist for the lifetime of the Server instance.
virtual bool RegisterService(const grpc::string* host, Service* service) = 0;
/// Register a generic service. This call does not take ownership of the
/// service. The service must exist for the lifetime of the Server instance.
virtual void RegisterAsyncGenericService(AsyncGenericService* service) = 0;
/// Tries to bind \a server to the given \a addr.
///
/// It can be invoked multiple times.
///
/// \param addr The address to try to bind to the server (eg, localhost:1234,
/// 192.168.1.1:31416, [::1]:27182, etc.).
/// \params creds The credentials associated with the server.
///
/// \return bound port number on sucess, 0 on failure.
///
/// \warning It's an error to call this method on an already started server.
virtual int AddListeningPort(const grpc::string& addr,
ServerCredentials* creds) = 0;
/// Start the server.
///
/// \param cqs Completion queues for handling asynchronous services. The
/// caller is required to keep all completion queues live until the server is
/// destroyed.
/// \param num_cqs How many completion queues does \a cqs hold.
///
/// \return true on a successful shutdown.
virtual bool Start(ServerCompletionQueue** cqs, size_t num_cqs) = 0;
/// Process one or more incoming calls.
virtual void RunRpc() = 0;
/// Schedule \a RunRpc to run in the threadpool.
virtual void ScheduleCallback() = 0;
virtual void ShutdownInternal(gpr_timespec deadline) = 0;
virtual int max_message_size() const = 0;
virtual grpc_server* server() = 0;
virtual void PerformOpsOnCall(CallOpSetInterface* ops, Call* call) = 0;
class BaseAsyncRequest : public CompletionQueueTag {
public:
BaseAsyncRequest(ServerInterface* server, ServerContext* context,
ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq, void* tag,
bool delete_on_finalize);
virtual ~BaseAsyncRequest() {}
bool FinalizeResult(void** tag, bool* status) GRPC_OVERRIDE;
protected:
ServerInterface* const server_;
ServerContext* const context_;
ServerAsyncStreamingInterface* const stream_;
CompletionQueue* const call_cq_;
void* const tag_;
const bool delete_on_finalize_;
grpc_call* call_;
grpc_metadata_array initial_metadata_array_;
};
class RegisteredAsyncRequest : public BaseAsyncRequest {
public:
RegisteredAsyncRequest(ServerInterface* server, ServerContext* context,
ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq, void* tag);
// uses BaseAsyncRequest::FinalizeResult
protected:
void IssueRequest(void* registered_method, grpc_byte_buffer** payload,
ServerCompletionQueue* notification_cq);
};
class NoPayloadAsyncRequest GRPC_FINAL : public RegisteredAsyncRequest {
public:
NoPayloadAsyncRequest(void* registered_method, ServerInterface* server,
ServerContext* context,
ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag)
: RegisteredAsyncRequest(server, context, stream, call_cq, tag) {
IssueRequest(registered_method, nullptr, notification_cq);
}
// uses RegisteredAsyncRequest::FinalizeResult
};
template <class Message>
class PayloadAsyncRequest GRPC_FINAL : public RegisteredAsyncRequest {
public:
PayloadAsyncRequest(void* registered_method, ServerInterface* server,
ServerContext* context,
ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag,
Message* request)
: RegisteredAsyncRequest(server, context, stream, call_cq, tag),
request_(request) {
IssueRequest(registered_method, &payload_, notification_cq);
}
bool FinalizeResult(void** tag, bool* status) GRPC_OVERRIDE {
bool serialization_status =
*status && payload_ &&
SerializationTraits<Message>::Deserialize(
payload_, request_, server_->max_message_size()).ok();
bool ret = RegisteredAsyncRequest::FinalizeResult(tag, status);
*status = serialization_status&&* status;
return ret;
}
private:
grpc_byte_buffer* payload_;
Message* const request_;
};
class GenericAsyncRequest : public BaseAsyncRequest {
public:
GenericAsyncRequest(ServerInterface* server, GenericServerContext* context,
ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag,
bool delete_on_finalize);
bool FinalizeResult(void** tag, bool* status) GRPC_OVERRIDE;
private:
grpc_call_details call_details_;
};
template <class Message>
void RequestAsyncCall(RpcServiceMethod* method, ServerContext* context,
ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag,
Message* message) {
GPR_ASSERT(method);
new PayloadAsyncRequest<Message>(method->server_tag(), this, context,
stream, call_cq, notification_cq, tag,
message);
}
void RequestAsyncCall(RpcServiceMethod* method, ServerContext* context,
ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag) {
GPR_ASSERT(method);
new NoPayloadAsyncRequest(method->server_tag(), this, context, stream,
call_cq, notification_cq, tag);
}
void RequestAsyncGenericCall(GenericServerContext* context,
ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq,
void* tag) {
new GenericAsyncRequest(this, context, stream, call_cq, notification_cq,
tag, true);
}
};
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_SERVER_INTERFACE_H

@ -0,0 +1,161 @@
/*
*
* Copyright 2015-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 GRPCXX_IMPL_CODEGEN_SERVICE_TYPE_H
#define GRPCXX_IMPL_CODEGEN_SERVICE_TYPE_H
#include <grpc++/impl/codegen/config.h>
#include <grpc++/impl/codegen/rpc_service_method.h>
#include <grpc++/impl/codegen/serialization_traits.h>
#include <grpc++/impl/codegen/server_interface.h>
#include <grpc++/impl/codegen/status.h>
namespace grpc {
class Call;
class CompletionQueue;
class Server;
class ServerInterface;
class ServerCompletionQueue;
class ServerContext;
class ServerAsyncStreamingInterface {
public:
virtual ~ServerAsyncStreamingInterface() {}
virtual void SendInitialMetadata(void* tag) = 0;
private:
friend class ServerInterface;
virtual void BindCall(Call* call) = 0;
};
class Service {
public:
Service() : server_(nullptr) {}
virtual ~Service() {}
bool has_async_methods() const {
for (auto it = methods_.begin(); it != methods_.end(); ++it) {
if (*it && (*it)->handler() == nullptr) {
return true;
}
}
return false;
}
bool has_synchronous_methods() const {
for (auto it = methods_.begin(); it != methods_.end(); ++it) {
if (*it && (*it)->handler() != nullptr) {
return true;
}
}
return false;
}
bool has_generic_methods() const {
for (auto it = methods_.begin(); it != methods_.end(); ++it) {
if (it->get() == nullptr) {
return true;
}
}
return false;
}
protected:
template <class Message>
void RequestAsyncUnary(int index, ServerContext* context, Message* request,
ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag) {
server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq,
notification_cq, tag, request);
}
void RequestAsyncClientStreaming(int index, ServerContext* context,
ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq,
void* tag) {
server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq,
notification_cq, tag);
}
template <class Message>
void RequestAsyncServerStreaming(int index, ServerContext* context,
Message* request,
ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq,
void* tag) {
server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq,
notification_cq, tag, request);
}
void RequestAsyncBidiStreaming(int index, ServerContext* context,
ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq,
void* tag) {
server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq,
notification_cq, tag);
}
void AddMethod(RpcServiceMethod* method) { methods_.emplace_back(method); }
void MarkMethodAsync(int index) {
if (methods_[index].get() == nullptr) {
gpr_log(GPR_ERROR,
"Cannot mark the method as 'async' because it has already been "
"marked as 'generic'.");
return;
}
methods_[index]->ResetHandler();
}
void MarkMethodGeneric(int index) {
if (methods_[index]->handler() == nullptr) {
gpr_log(GPR_ERROR,
"Cannot mark the method as 'generic' because it has already been "
"marked as 'async'.");
}
methods_[index].reset();
}
private:
friend class Server;
friend class ServerInterface;
ServerInterface* server_;
std::vector<std::unique_ptr<RpcServiceMethod>> methods_;
};
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_SERVICE_TYPE_H

@ -0,0 +1,76 @@
/*
*
* 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 GRPCXX_IMPL_CODEGEN_STATUS_H
#define GRPCXX_IMPL_CODEGEN_STATUS_H
#include <grpc++/impl/codegen/config.h>
#include <grpc++/impl/codegen/status_code_enum.h>
namespace grpc {
/// Did it work? If it didn't, why?
///
/// See \a grpc::StatusCode for details on the available code and their meaning.
class Status {
public:
/// Construct an OK instance.
Status() : code_(StatusCode::OK) {}
/// Construct an instance with associated \a code and \a details (also
// referred to as "error_message").
Status(StatusCode code, const grpc::string& details)
: code_(code), details_(details) {}
// Pre-defined special status objects.
/// An OK pre-defined instance.
static const Status& OK;
/// A CANCELLED pre-defined instance.
static const Status& CANCELLED;
/// Return the instance's error code.
StatusCode error_code() const { return code_; }
/// Return the instance's error message.
grpc::string error_message() const { return details_; }
/// Is the status OK?
bool ok() const { return code_ == StatusCode::OK; }
private:
StatusCode code_;
grpc::string details_;
};
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_STATUS_H

@ -0,0 +1,152 @@
/*
*
* 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 GRPCXX_IMPL_CODEGEN_STATUS_CODE_ENUM_H
#define GRPCXX_IMPL_CODEGEN_STATUS_CODE_ENUM_H
namespace grpc {
enum StatusCode {
/// Not an error; returned on success.
OK = 0,
/// The operation was cancelled (typically by the caller).
CANCELLED = 1,
/// Unknown error. An example of where this error may be returned is if a
/// Status value received from another address space belongs to an error-space
/// that is not known in this address space. Also errors raised by APIs that
/// do not return enough error information may be converted to this error.
UNKNOWN = 2,
/// Client specified an invalid argument. Note that this differs from
/// FAILED_PRECONDITION. INVALID_ARGUMENT indicates arguments that are
/// problematic regardless of the state of the system (e.g., a malformed file
/// name).
INVALID_ARGUMENT = 3,
/// Deadline expired before operation could complete. For operations that
/// change the state of the system, this error may be returned even if the
/// operation has completed successfully. For example, a successful response
/// from a server could have been delayed long enough for the deadline to
/// expire.
DEADLINE_EXCEEDED = 4,
/// Some requested entity (e.g., file or directory) was not found.
NOT_FOUND = 5,
/// Some entity that we attempted to create (e.g., file or directory) already
/// exists.
ALREADY_EXISTS = 6,
/// The caller does not have permission to execute the specified operation.
/// PERMISSION_DENIED must not be used for rejections caused by exhausting
/// some resource (use RESOURCE_EXHAUSTED instead for those errors).
/// PERMISSION_DENIED must not be used if the caller can not be identified
/// (use UNAUTHENTICATED instead for those errors).
PERMISSION_DENIED = 7,
/// The request does not have valid authentication credentials for the
/// operation.
UNAUTHENTICATED = 16,
/// Some resource has been exhausted, perhaps a per-user quota, or perhaps the
/// entire file system is out of space.
RESOURCE_EXHAUSTED = 8,
/// Operation was rejected because the system is not in a state required for
/// the operation's execution. For example, directory to be deleted may be
/// non-empty, an rmdir operation is applied to a non-directory, etc.
///
/// A litmus test that may help a service implementor in deciding
/// between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE:
/// (a) Use UNAVAILABLE if the client can retry just the failing call.
/// (b) Use ABORTED if the client should retry at a higher-level
/// (e.g., restarting a read-modify-write sequence).
/// (c) Use FAILED_PRECONDITION if the client should not retry until
/// the system state has been explicitly fixed. E.g., if an "rmdir"
/// fails because the directory is non-empty, FAILED_PRECONDITION
/// should be returned since the client should not retry unless
/// they have first fixed up the directory by deleting files from it.
/// (d) Use FAILED_PRECONDITION if the client performs conditional
/// REST Get/Update/Delete on a resource and the resource on the
/// server does not match the condition. E.g., conflicting
/// read-modify-write on the same resource.
FAILED_PRECONDITION = 9,
/// The operation was aborted, typically due to a concurrency issue like
/// sequencer check failures, transaction aborts, etc.
///
/// See litmus test above for deciding between FAILED_PRECONDITION, ABORTED,
/// and UNAVAILABLE.
ABORTED = 10,
/// Operation was attempted past the valid range. E.g., seeking or reading
/// past end of file.
///
/// Unlike INVALID_ARGUMENT, this error indicates a problem that may be fixed
/// if the system state changes. For example, a 32-bit file system will
/// generate INVALID_ARGUMENT if asked to read at an offset that is not in the
/// range [0,2^32-1], but it will generate OUT_OF_RANGE if asked to read from
/// an offset past the current file size.
///
/// There is a fair bit of overlap between FAILED_PRECONDITION and
/// OUT_OF_RANGE. We recommend using OUT_OF_RANGE (the more specific error)
/// when it applies so that callers who are iterating through a space can
/// easily look for an OUT_OF_RANGE error to detect when they are done.
OUT_OF_RANGE = 11,
/// Operation is not implemented or not supported/enabled in this service.
UNIMPLEMENTED = 12,
/// Internal errors. Means some invariants expected by underlying System has
/// been broken. If you see one of these errors, Something is very broken.
INTERNAL = 13,
/// The service is currently unavailable. This is a most likely a transient
/// condition and may be corrected by retrying with a backoff.
///
/// See litmus test above for deciding between FAILED_PRECONDITION, ABORTED,
/// and UNAVAILABLE.
UNAVAILABLE = 14,
/// Unrecoverable data loss or corruption.
DATA_LOSS = 15,
/// Force users to include a default branch:
DO_NOT_USE = -1
};
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_STATUS_CODE_ENUM_H

@ -0,0 +1,123 @@
/*
*
* Copyright 2015-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 GRPCXX_IMPL_CODEGEN_STRING_REF_H
#define GRPCXX_IMPL_CODEGEN_STRING_REF_H
#include <iterator>
#include <iosfwd>
#include <grpc++/impl/codegen/config.h>
namespace grpc {
/// This class is a non owning reference to a string.
///
/// It should be a strict subset of the upcoming std::string_ref.
///
/// \see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html
///
/// The constexpr is dropped or replaced with const for legacy compiler
/// compatibility.
class string_ref {
public:
// types
typedef const char* const_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
// constants
const static size_t npos;
// construct/copy.
string_ref() : data_(nullptr), length_(0) {}
string_ref(const string_ref& other)
: data_(other.data_), length_(other.length_) {}
string_ref& operator=(const string_ref& rhs);
string_ref(const char* s);
string_ref(const char* s, size_t l) : data_(s), length_(l) {}
string_ref(const grpc::string& s) : data_(s.data()), length_(s.length()) {}
// iterators
const_iterator begin() const { return data_; }
const_iterator end() const { return data_ + length_; }
const_iterator cbegin() const { return data_; }
const_iterator cend() const { return data_ + length_; }
const_reverse_iterator rbegin() const {
return const_reverse_iterator(end());
}
const_reverse_iterator rend() const {
return const_reverse_iterator(begin());
}
const_reverse_iterator crbegin() const {
return const_reverse_iterator(end());
}
const_reverse_iterator crend() const {
return const_reverse_iterator(begin());
}
// capacity
size_t size() const { return length_; }
size_t length() const { return length_; }
size_t max_size() const { return length_; }
bool empty() const { return length_ == 0; }
// element access
const char* data() const { return data_; }
// string operations
int compare(string_ref x) const;
bool starts_with(string_ref x) const;
bool ends_with(string_ref x) const;
size_t find(string_ref s) const;
size_t find(char c) const;
string_ref substr(size_t pos, size_t n = npos) const;
private:
const char* data_;
size_t length_;
};
// Comparison operators
bool operator==(string_ref x, string_ref y);
bool operator!=(string_ref x, string_ref y);
bool operator<(string_ref x, string_ref y);
bool operator>(string_ref x, string_ref y);
bool operator<=(string_ref x, string_ref y);
bool operator>=(string_ref x, string_ref y);
std::ostream& operator<<(std::ostream& stream, const string_ref& string);
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_STRING_REF_H

@ -0,0 +1,43 @@
/*
*
* Copyright 2015-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 GRPCXX_IMPL_CODEGEN_STUB_OPTIONS_H
#define GRPCXX_IMPL_CODEGEN_STUB_OPTIONS_H
namespace grpc {
class StubOptions {};
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_STUB_OPTIONS_H

@ -0,0 +1,45 @@
/*
*
* Copyright 2015-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 GRPCXX_IMPL_CODEGEN_SYNC_H
#define GRPCXX_IMPL_CODEGEN_SYNC_H
#include <grpc++/impl/codegen/config.h>
#ifdef GRPC_CXX0X_NO_THREAD
#include <grpc++/impl/codegen/sync_no_cxx11.h>
#else
#include <grpc++/impl/codegen/sync_cxx11.h>
#endif
#endif // GRPCXX_IMPL_CODEGEN_SYNC_H

@ -0,0 +1,49 @@
/*
*
* Copyright 2015-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 GRPCXX_IMPL_CODEGEN_SYNC_CXX11_H
#define GRPCXX_IMPL_CODEGEN_SYNC_CXX11_H
#include <condition_variable>
#include <mutex>
namespace grpc {
using std::condition_variable;
using std::mutex;
using std::lock_guard;
using std::unique_lock;
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_SYNC_CXX11_H

@ -0,0 +1,105 @@
/*
*
* Copyright 2015-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 GRPCXX_IMPL_CODEGEN_SYNC_NO_CXX11_H
#define GRPCXX_IMPL_CODEGEN_SYNC_NO_CXX11_H
#include <grpc/impl/codegen/sync.h>
namespace grpc {
template <class mutex>
class lock_guard;
class condition_variable;
class mutex {
public:
mutex() { gpr_mu_init(&mu_); }
~mutex() { gpr_mu_destroy(&mu_); }
private:
::gpr_mu mu_;
template <class mutex>
friend class lock_guard;
friend class condition_variable;
};
template <class mutex>
class lock_guard {
public:
lock_guard(mutex &mu) : mu_(mu), locked(true) { gpr_mu_lock(&mu.mu_); }
~lock_guard() { unlock_internal(); }
protected:
void lock_internal() {
if (!locked) gpr_mu_lock(&mu_.mu_);
locked = true;
}
void unlock_internal() {
if (locked) gpr_mu_unlock(&mu_.mu_);
locked = false;
}
private:
mutex &mu_;
bool locked;
friend class condition_variable;
};
template <class mutex>
class unique_lock : public lock_guard<mutex> {
public:
unique_lock(mutex &mu) : lock_guard<mutex>(mu) {}
void lock() { this->lock_internal(); }
void unlock() { this->unlock_internal(); }
};
class condition_variable {
public:
condition_variable() { gpr_cv_init(&cv_); }
~condition_variable() { gpr_cv_destroy(&cv_); }
void wait(lock_guard<mutex> &mu) {
mu.locked = false;
gpr_cv_wait(&cv_, &mu.mu_.mu_, gpr_inf_future(GPR_CLOCK_REALTIME));
mu.locked = true;
}
void notify_one() { gpr_cv_signal(&cv_); }
void notify_all() { gpr_cv_broadcast(&cv_); }
private:
gpr_cv cv_;
};
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_SYNC_NO_CXX11_H

@ -0,0 +1,415 @@
/*
*
* Copyright 2015-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 GRPCXX_IMPL_CODEGEN_SYNC_STREAM_H
#define GRPCXX_IMPL_CODEGEN_SYNC_STREAM_H
#include <grpc++/impl/codegen/call.h>
#include <grpc++/impl/codegen/channel_interface.h>
#include <grpc++/impl/codegen/client_context.h>
#include <grpc++/impl/codegen/completion_queue.h>
#include <grpc++/impl/codegen/server_context.h>
#include <grpc++/impl/codegen/service_type.h>
#include <grpc++/impl/codegen/status.h>
#include <grpc/impl/codegen/log.h>
namespace grpc {
/// Common interface for all synchronous client side streaming.
class ClientStreamingInterface {
public:
virtual ~ClientStreamingInterface() {}
/// Wait until the stream finishes, and return the final status. When the
/// client side declares it has no more message to send, either implicitly or
/// by calling \a WritesDone(), it needs to make sure there is no more message
/// to be received from the server, either implicitly or by getting a false
/// from a \a Read().
///
/// This function will return either:
/// - when all incoming messages have been read and the server has returned
/// status.
/// - OR when the server has returned a non-OK status.
virtual Status Finish() = 0;
};
/// An interface that yields a sequence of messages of type \a R.
template <class R>
class ReaderInterface {
public:
virtual ~ReaderInterface() {}
/// Blocking read a message and parse to \a msg. Returns \a true on success.
///
/// \param[out] msg The read message.
///
/// \return \a false when there will be no more incoming messages, either
/// because the other side has called \a WritesDone() or the stream has failed
/// (or been cancelled).
virtual bool Read(R* msg) = 0;
};
/// An interface that can be fed a sequence of messages of type \a W.
template <class W>
class WriterInterface {
public:
virtual ~WriterInterface() {}
/// Blocking write \a msg to the stream with options.
///
/// \param msg The message to be written to the stream.
/// \param options Options affecting the write operation.
///
/// \return \a true on success, \a false when the stream has been closed.
virtual bool Write(const W& msg, const WriteOptions& options) = 0;
/// Blocking write \a msg to the stream with default options.
///
/// \param msg The message to be written to the stream.
///
/// \return \a true on success, \a false when the stream has been closed.
inline bool Write(const W& msg) { return Write(msg, WriteOptions()); }
};
/// Client-side interface for streaming reads of message of type \a R.
template <class R>
class ClientReaderInterface : public ClientStreamingInterface,
public ReaderInterface<R> {
public:
/// Blocking wait for initial metadata from server. The received metadata
/// can only be accessed after this call returns. Should only be called before
/// the first read. Calling this method is optional, and if it is not called
/// the metadata will be available in ClientContext after the first read.
virtual void WaitForInitialMetadata() = 0;
};
template <class R>
class ClientReader GRPC_FINAL : public ClientReaderInterface<R> {
public:
/// Blocking create a stream and write the first request out.
template <class W>
ClientReader(ChannelInterface* channel, const RpcMethod& method,
ClientContext* context, const W& request)
: context_(context), call_(channel->CreateCall(method, context, &cq_)) {
CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
CallOpClientSendClose> ops;
ops.SendInitialMetadata(context->send_initial_metadata_);
// TODO(ctiller): don't assert
GPR_ASSERT(ops.SendMessage(request).ok());
ops.ClientSendClose();
call_.PerformOps(&ops);
cq_.Pluck(&ops);
}
void WaitForInitialMetadata() GRPC_OVERRIDE {
GPR_ASSERT(!context_->initial_metadata_received_);
CallOpSet<CallOpRecvInitialMetadata> ops;
ops.RecvInitialMetadata(context_);
call_.PerformOps(&ops);
cq_.Pluck(&ops); /// status ignored
}
bool Read(R* msg) GRPC_OVERRIDE {
CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>> ops;
if (!context_->initial_metadata_received_) {
ops.RecvInitialMetadata(context_);
}
ops.RecvMessage(msg);
call_.PerformOps(&ops);
return cq_.Pluck(&ops) && ops.got_message;
}
Status Finish() GRPC_OVERRIDE {
CallOpSet<CallOpClientRecvStatus> ops;
Status status;
ops.ClientRecvStatus(context_, &status);
call_.PerformOps(&ops);
GPR_ASSERT(cq_.Pluck(&ops));
return status;
}
private:
ClientContext* context_;
CompletionQueue cq_;
Call call_;
};
/// Client-side interface for streaming writes of message of type \a W.
template <class W>
class ClientWriterInterface : public ClientStreamingInterface,
public WriterInterface<W> {
public:
/// Half close writing from the client.
/// Block until writes are completed.
///
/// \return Whether the writes were successful.
virtual bool WritesDone() = 0;
};
template <class W>
class ClientWriter : public ClientWriterInterface<W> {
public:
/// Blocking create a stream.
template <class R>
ClientWriter(ChannelInterface* channel, const RpcMethod& method,
ClientContext* context, R* response)
: context_(context), call_(channel->CreateCall(method, context, &cq_)) {
finish_ops_.RecvMessage(response);
CallOpSet<CallOpSendInitialMetadata> ops;
ops.SendInitialMetadata(context->send_initial_metadata_);
call_.PerformOps(&ops);
cq_.Pluck(&ops);
}
using WriterInterface<W>::Write;
bool Write(const W& msg, const WriteOptions& options) GRPC_OVERRIDE {
CallOpSet<CallOpSendMessage> ops;
if (!ops.SendMessage(msg, options).ok()) {
return false;
}
call_.PerformOps(&ops);
return cq_.Pluck(&ops);
}
bool WritesDone() GRPC_OVERRIDE {
CallOpSet<CallOpClientSendClose> ops;
ops.ClientSendClose();
call_.PerformOps(&ops);
return cq_.Pluck(&ops);
}
/// Read the final response and wait for the final status.
Status Finish() GRPC_OVERRIDE {
Status status;
finish_ops_.ClientRecvStatus(context_, &status);
call_.PerformOps(&finish_ops_);
GPR_ASSERT(cq_.Pluck(&finish_ops_));
return status;
}
private:
ClientContext* context_;
CallOpSet<CallOpGenericRecvMessage, CallOpClientRecvStatus> finish_ops_;
CompletionQueue cq_;
Call call_;
};
/// Client-side interface for bi-directional streaming.
template <class W, class R>
class ClientReaderWriterInterface : public ClientStreamingInterface,
public WriterInterface<W>,
public ReaderInterface<R> {
public:
/// Blocking wait for initial metadata from server. The received metadata
/// can only be accessed after this call returns. Should only be called before
/// the first read. Calling this method is optional, and if it is not called
/// the metadata will be available in ClientContext after the first read.
virtual void WaitForInitialMetadata() = 0;
/// Block until writes are completed.
///
/// \return Whether the writes were successful.
virtual bool WritesDone() = 0;
};
template <class W, class R>
class ClientReaderWriter GRPC_FINAL : public ClientReaderWriterInterface<W, R> {
public:
/// Blocking create a stream.
ClientReaderWriter(ChannelInterface* channel, const RpcMethod& method,
ClientContext* context)
: context_(context), call_(channel->CreateCall(method, context, &cq_)) {
CallOpSet<CallOpSendInitialMetadata> ops;
ops.SendInitialMetadata(context->send_initial_metadata_);
call_.PerformOps(&ops);
cq_.Pluck(&ops);
}
void WaitForInitialMetadata() GRPC_OVERRIDE {
GPR_ASSERT(!context_->initial_metadata_received_);
CallOpSet<CallOpRecvInitialMetadata> ops;
ops.RecvInitialMetadata(context_);
call_.PerformOps(&ops);
cq_.Pluck(&ops); // status ignored
}
bool Read(R* msg) GRPC_OVERRIDE {
CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>> ops;
if (!context_->initial_metadata_received_) {
ops.RecvInitialMetadata(context_);
}
ops.RecvMessage(msg);
call_.PerformOps(&ops);
return cq_.Pluck(&ops) && ops.got_message;
}
using WriterInterface<W>::Write;
bool Write(const W& msg, const WriteOptions& options) GRPC_OVERRIDE {
CallOpSet<CallOpSendMessage> ops;
if (!ops.SendMessage(msg, options).ok()) return false;
call_.PerformOps(&ops);
return cq_.Pluck(&ops);
}
bool WritesDone() GRPC_OVERRIDE {
CallOpSet<CallOpClientSendClose> ops;
ops.ClientSendClose();
call_.PerformOps(&ops);
return cq_.Pluck(&ops);
}
Status Finish() GRPC_OVERRIDE {
CallOpSet<CallOpClientRecvStatus> ops;
Status status;
ops.ClientRecvStatus(context_, &status);
call_.PerformOps(&ops);
GPR_ASSERT(cq_.Pluck(&ops));
return status;
}
private:
ClientContext* context_;
CompletionQueue cq_;
Call call_;
};
template <class R>
class ServerReader GRPC_FINAL : public ReaderInterface<R> {
public:
ServerReader(Call* call, ServerContext* ctx) : call_(call), ctx_(ctx) {}
void SendInitialMetadata() {
GPR_ASSERT(!ctx_->sent_initial_metadata_);
CallOpSet<CallOpSendInitialMetadata> ops;
ops.SendInitialMetadata(ctx_->initial_metadata_);
ctx_->sent_initial_metadata_ = true;
call_->PerformOps(&ops);
call_->cq()->Pluck(&ops);
}
bool Read(R* msg) GRPC_OVERRIDE {
CallOpSet<CallOpRecvMessage<R>> ops;
ops.RecvMessage(msg);
call_->PerformOps(&ops);
return call_->cq()->Pluck(&ops) && ops.got_message;
}
private:
Call* const call_;
ServerContext* const ctx_;
};
template <class W>
class ServerWriter GRPC_FINAL : public WriterInterface<W> {
public:
ServerWriter(Call* call, ServerContext* ctx) : call_(call), ctx_(ctx) {}
void SendInitialMetadata() {
GPR_ASSERT(!ctx_->sent_initial_metadata_);
CallOpSet<CallOpSendInitialMetadata> ops;
ops.SendInitialMetadata(ctx_->initial_metadata_);
ctx_->sent_initial_metadata_ = true;
call_->PerformOps(&ops);
call_->cq()->Pluck(&ops);
}
using WriterInterface<W>::Write;
bool Write(const W& msg, const WriteOptions& options) GRPC_OVERRIDE {
CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage> ops;
if (!ops.SendMessage(msg, options).ok()) {
return false;
}
if (!ctx_->sent_initial_metadata_) {
ops.SendInitialMetadata(ctx_->initial_metadata_);
ctx_->sent_initial_metadata_ = true;
}
call_->PerformOps(&ops);
return call_->cq()->Pluck(&ops);
}
private:
Call* const call_;
ServerContext* const ctx_;
};
/// Server-side interface for bi-directional streaming.
template <class W, class R>
class ServerReaderWriter GRPC_FINAL : public WriterInterface<W>,
public ReaderInterface<R> {
public:
ServerReaderWriter(Call* call, ServerContext* ctx) : call_(call), ctx_(ctx) {}
void SendInitialMetadata() {
GPR_ASSERT(!ctx_->sent_initial_metadata_);
CallOpSet<CallOpSendInitialMetadata> ops;
ops.SendInitialMetadata(ctx_->initial_metadata_);
ctx_->sent_initial_metadata_ = true;
call_->PerformOps(&ops);
call_->cq()->Pluck(&ops);
}
bool Read(R* msg) GRPC_OVERRIDE {
CallOpSet<CallOpRecvMessage<R>> ops;
ops.RecvMessage(msg);
call_->PerformOps(&ops);
return call_->cq()->Pluck(&ops) && ops.got_message;
}
using WriterInterface<W>::Write;
bool Write(const W& msg, const WriteOptions& options) GRPC_OVERRIDE {
CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage> ops;
if (!ops.SendMessage(msg, options).ok()) {
return false;
}
if (!ctx_->sent_initial_metadata_) {
ops.SendInitialMetadata(ctx_->initial_metadata_);
ctx_->sent_initial_metadata_ = true;
}
call_->PerformOps(&ops);
return call_->cq()->Pluck(&ops);
}
private:
Call* const call_;
ServerContext* const ctx_;
};
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_SYNC_STREAM_H

@ -0,0 +1,111 @@
/*
*
* Copyright 2015-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 GRPCXX_IMPL_CODEGEN_TIME_H
#define GRPCXX_IMPL_CODEGEN_TIME_H
#include <grpc++/impl/codegen/config.h>
#include <grpc/impl/codegen/time.h>
namespace grpc {
/* If you are trying to use CompletionQueue::AsyncNext with a time class that
isn't either gpr_timespec or std::chrono::system_clock::time_point, you
will most likely be looking at this comment as your compiler will have
fired an error below. In order to fix this issue, you have two potential
solutions:
1. Use gpr_timespec or std::chrono::system_clock::time_point instead
2. Specialize the TimePoint class with whichever time class that you
want to use here. See below for two examples of how to do this.
*/
template <typename T>
class TimePoint {
public:
TimePoint(const T& time) { you_need_a_specialization_of_TimePoint(); }
gpr_timespec raw_time() {
gpr_timespec t;
return t;
}
private:
void you_need_a_specialization_of_TimePoint();
};
template <>
class TimePoint<gpr_timespec> {
public:
TimePoint(const gpr_timespec& time) : time_(time) {}
gpr_timespec raw_time() { return time_; }
private:
gpr_timespec time_;
};
} // namespace grpc
#ifndef GRPC_CXX0X_NO_CHRONO
#include <chrono>
#include <grpc/impl/codegen/time.h>
namespace grpc {
// from and to should be absolute time.
void Timepoint2Timespec(const std::chrono::system_clock::time_point& from,
gpr_timespec* to);
void TimepointHR2Timespec(
const std::chrono::high_resolution_clock::time_point& from,
gpr_timespec* to);
std::chrono::system_clock::time_point Timespec2Timepoint(gpr_timespec t);
template <>
class TimePoint<std::chrono::system_clock::time_point> {
public:
TimePoint(const std::chrono::system_clock::time_point& time) {
Timepoint2Timespec(time, &time_);
}
gpr_timespec raw_time() const { return time_; }
private:
gpr_timespec time_;
};
} // namespace grpc
#endif // !GRPC_CXX0X_NO_CHRONO
#endif // GRPCXX_IMPL_CODEGEN_TIME_H

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -34,16 +34,34 @@
#ifndef GRPCXX_IMPL_GRPC_LIBRARY_H
#define GRPCXX_IMPL_GRPC_LIBRARY_H
#include <iostream>
#include <grpc++/impl/codegen/config.h>
#include <grpc++/impl/codegen/grpc_library.h>
#include <grpc/grpc.h>
namespace grpc {
class GrpcLibrary {
namespace internal {
class GrpcLibrary GRPC_FINAL : public GrpcLibraryInterface {
public:
GrpcLibrary() { grpc_init(); }
virtual ~GrpcLibrary() { grpc_shutdown(); }
void init() GRPC_OVERRIDE { grpc_init(); }
void shutdown() GRPC_OVERRIDE { grpc_shutdown(); }
};
static GrpcLibrary g_gli;
class GrpcLibraryInitializer GRPC_FINAL {
public:
GrpcLibraryInitializer() { grpc::g_glip = &g_gli; }
/// A no-op method to force the linker to reference this class, which will
/// take care of initializing and shutting down the gRPC runtime.
int summon() { return 0; }
};
} // namespace internal
} // namespace grpc
#endif // GRPCXX_IMPL_GRPC_LIBRARY_H

@ -0,0 +1,39 @@
/*
*
* Copyright 2015-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 GRPCXX_IMPL_METHOD_HANDLER_IMPL_H
#define GRPCXX_IMPL_METHOD_HANDLER_IMPL_H
#include <grpc++/impl/codegen/method_handler_impl.h>
#endif // GRPCXX_IMPL_METHOD_HANDLER_IMPL_H

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -34,43 +34,6 @@
#ifndef GRPC_INTERNAL_CPP_PROTO_PROTO_UTILS_H
#define GRPC_INTERNAL_CPP_PROTO_PROTO_UTILS_H
#include <type_traits>
#include <grpc/grpc.h>
#include <grpc++/impl/serialization_traits.h>
#include <grpc++/support/config_protobuf.h>
#include <grpc++/support/status.h>
namespace grpc {
// Serialize the msg into a buffer created inside the function. The caller
// should destroy the returned buffer when done with it. If serialization fails,
// false is returned and buffer is left unchanged.
Status SerializeProto(const grpc::protobuf::Message& msg,
grpc_byte_buffer** buffer);
// The caller keeps ownership of buffer and msg.
Status DeserializeProto(grpc_byte_buffer* buffer, grpc::protobuf::Message* msg,
int max_message_size);
template <class T>
class SerializationTraits<T, typename std::enable_if<std::is_base_of<
grpc::protobuf::Message, T>::value>::type> {
public:
static Status Serialize(const grpc::protobuf::Message& msg,
grpc_byte_buffer** buffer, bool* own_buffer) {
*own_buffer = true;
return SerializeProto(msg, buffer);
}
static Status Deserialize(grpc_byte_buffer* buffer,
grpc::protobuf::Message* msg,
int max_message_size) {
auto status = DeserializeProto(buffer, msg, max_message_size);
grpc_byte_buffer_destroy(buffer);
return status;
}
};
} // namespace grpc
#include <grpc++/impl/codegen/proto_utils.h>
#endif // GRPC_INTERNAL_CPP_PROTO_PROTO_UTILS_H

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -34,40 +34,6 @@
#ifndef GRPCXX_IMPL_RPC_METHOD_H
#define GRPCXX_IMPL_RPC_METHOD_H
#include <memory>
#include <grpc++/channel.h>
namespace grpc {
class RpcMethod {
public:
enum RpcType {
NORMAL_RPC = 0,
CLIENT_STREAMING, // request streaming
SERVER_STREAMING, // response streaming
BIDI_STREAMING
};
RpcMethod(const char* name, RpcType type)
: name_(name), method_type_(type), channel_tag_(NULL) {}
RpcMethod(const char* name, RpcType type,
const std::shared_ptr<Channel>& channel)
: name_(name),
method_type_(type),
channel_tag_(channel->RegisterMethod(name)) {}
const char* name() const { return name_; }
RpcType method_type() const { return method_type_; }
void* channel_tag() const { return channel_tag_; }
private:
const char* const name_;
const RpcType method_type_;
void* const channel_tag_;
};
} // namespace grpc
#include <grpc++/impl/codegen/rpc_method.h>
#endif // GRPCXX_IMPL_RPC_METHOD_H

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -34,234 +34,6 @@
#ifndef GRPCXX_IMPL_RPC_SERVICE_METHOD_H
#define GRPCXX_IMPL_RPC_SERVICE_METHOD_H
#include <climits>
#include <functional>
#include <map>
#include <memory>
#include <vector>
#include <grpc++/impl/rpc_method.h>
#include <grpc++/support/config.h>
#include <grpc++/support/status.h>
#include <grpc++/support/sync_stream.h>
namespace grpc {
class ServerContext;
class StreamContextInterface;
// TODO(rocking): we might need to split this file into multiple ones.
// Base class for running an RPC handler.
class MethodHandler {
public:
virtual ~MethodHandler() {}
struct HandlerParameter {
HandlerParameter(Call* c, ServerContext* context, grpc_byte_buffer* req,
int max_size)
: call(c),
server_context(context),
request(req),
max_message_size(max_size) {}
Call* call;
ServerContext* server_context;
// Handler required to grpc_byte_buffer_destroy this
grpc_byte_buffer* request;
int max_message_size;
};
virtual void RunHandler(const HandlerParameter& param) = 0;
};
// A wrapper class of an application provided rpc method handler.
template <class ServiceType, class RequestType, class ResponseType>
class RpcMethodHandler : public MethodHandler {
public:
RpcMethodHandler(
std::function<Status(ServiceType*, ServerContext*, const RequestType*,
ResponseType*)> func,
ServiceType* service)
: func_(func), service_(service) {}
void RunHandler(const HandlerParameter& param) GRPC_FINAL {
RequestType req;
Status status = SerializationTraits<RequestType>::Deserialize(
param.request, &req, param.max_message_size);
ResponseType rsp;
if (status.ok()) {
status = func_(service_, param.server_context, &req, &rsp);
}
GPR_ASSERT(!param.server_context->sent_initial_metadata_);
CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
CallOpServerSendStatus> ops;
ops.SendInitialMetadata(param.server_context->initial_metadata_);
if (status.ok()) {
status = ops.SendMessage(rsp);
}
ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
param.call->PerformOps(&ops);
param.call->cq()->Pluck(&ops);
}
private:
// Application provided rpc handler function.
std::function<Status(ServiceType*, ServerContext*, const RequestType*,
ResponseType*)> func_;
// The class the above handler function lives in.
ServiceType* service_;
};
// A wrapper class of an application provided client streaming handler.
template <class ServiceType, class RequestType, class ResponseType>
class ClientStreamingHandler : public MethodHandler {
public:
ClientStreamingHandler(
std::function<Status(ServiceType*, ServerContext*,
ServerReader<RequestType>*, ResponseType*)> func,
ServiceType* service)
: func_(func), service_(service) {}
void RunHandler(const HandlerParameter& param) GRPC_FINAL {
ServerReader<RequestType> reader(param.call, param.server_context);
ResponseType rsp;
Status status = func_(service_, param.server_context, &reader, &rsp);
GPR_ASSERT(!param.server_context->sent_initial_metadata_);
CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
CallOpServerSendStatus> ops;
ops.SendInitialMetadata(param.server_context->initial_metadata_);
if (status.ok()) {
status = ops.SendMessage(rsp);
}
ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
param.call->PerformOps(&ops);
param.call->cq()->Pluck(&ops);
}
private:
std::function<Status(ServiceType*, ServerContext*, ServerReader<RequestType>*,
ResponseType*)> func_;
ServiceType* service_;
};
// A wrapper class of an application provided server streaming handler.
template <class ServiceType, class RequestType, class ResponseType>
class ServerStreamingHandler : public MethodHandler {
public:
ServerStreamingHandler(
std::function<Status(ServiceType*, ServerContext*, const RequestType*,
ServerWriter<ResponseType>*)> func,
ServiceType* service)
: func_(func), service_(service) {}
void RunHandler(const HandlerParameter& param) GRPC_FINAL {
RequestType req;
Status status = SerializationTraits<RequestType>::Deserialize(
param.request, &req, param.max_message_size);
if (status.ok()) {
ServerWriter<ResponseType> writer(param.call, param.server_context);
status = func_(service_, param.server_context, &req, &writer);
}
CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> ops;
if (!param.server_context->sent_initial_metadata_) {
ops.SendInitialMetadata(param.server_context->initial_metadata_);
}
ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
param.call->PerformOps(&ops);
param.call->cq()->Pluck(&ops);
}
private:
std::function<Status(ServiceType*, ServerContext*, const RequestType*,
ServerWriter<ResponseType>*)> func_;
ServiceType* service_;
};
// A wrapper class of an application provided bidi-streaming handler.
template <class ServiceType, class RequestType, class ResponseType>
class BidiStreamingHandler : public MethodHandler {
public:
BidiStreamingHandler(
std::function<Status(ServiceType*, ServerContext*,
ServerReaderWriter<ResponseType, RequestType>*)>
func,
ServiceType* service)
: func_(func), service_(service) {}
void RunHandler(const HandlerParameter& param) GRPC_FINAL {
ServerReaderWriter<ResponseType, RequestType> stream(param.call,
param.server_context);
Status status = func_(service_, param.server_context, &stream);
CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> ops;
if (!param.server_context->sent_initial_metadata_) {
ops.SendInitialMetadata(param.server_context->initial_metadata_);
}
ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
param.call->PerformOps(&ops);
param.call->cq()->Pluck(&ops);
}
private:
std::function<Status(ServiceType*, ServerContext*,
ServerReaderWriter<ResponseType, RequestType>*)> func_;
ServiceType* service_;
};
// Handle unknown method by returning UNIMPLEMENTED error.
class UnknownMethodHandler : public MethodHandler {
public:
template <class T>
static void FillOps(ServerContext* context, T* ops) {
Status status(StatusCode::UNIMPLEMENTED, "");
if (!context->sent_initial_metadata_) {
ops->SendInitialMetadata(context->initial_metadata_);
context->sent_initial_metadata_ = true;
}
ops->ServerSendStatus(context->trailing_metadata_, status);
}
void RunHandler(const HandlerParameter& param) GRPC_FINAL {
CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> ops;
FillOps(param.server_context, &ops);
param.call->PerformOps(&ops);
param.call->cq()->Pluck(&ops);
}
};
// Server side rpc method class
class RpcServiceMethod : public RpcMethod {
public:
// Takes ownership of the handler
RpcServiceMethod(const char* name, RpcMethod::RpcType type,
MethodHandler* handler)
: RpcMethod(name, type), handler_(handler) {}
MethodHandler* handler() { return handler_.get(); }
private:
std::unique_ptr<MethodHandler> handler_;
};
// This class contains all the method information for an rpc service. It is
// used for registering a service on a grpc server.
class RpcService {
public:
// Takes ownership.
void AddMethod(RpcServiceMethod* method) { methods_.emplace_back(method); }
RpcServiceMethod* GetMethod(int i) { return methods_[i].get(); }
int GetMethodCount() const {
// On win x64, int is only 32bit
GPR_ASSERT(methods_.size() <= INT_MAX);
return (int)methods_.size();
}
private:
std::vector<std::unique_ptr<RpcServiceMethod>> methods_;
};
} // namespace grpc
#include <grpc++/impl/codegen/rpc_service_method.h>
#endif // GRPCXX_IMPL_RPC_SERVICE_METHOD_H

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -34,35 +34,6 @@
#ifndef GRPCXX_IMPL_SERIALIZATION_TRAITS_H
#define GRPCXX_IMPL_SERIALIZATION_TRAITS_H
namespace grpc {
/// Defines how to serialize and deserialize some type.
///
/// Used for hooking different message serialization API's into GRPC.
/// Each SerializationTraits implementation must provide the following
/// functions:
/// static Status Serialize(const Message& msg,
/// grpc_byte_buffer** buffer,
// bool* own_buffer);
/// static Status Deserialize(grpc_byte_buffer* buffer,
/// Message* msg,
/// int max_message_size);
///
/// Serialize is required to convert message to a grpc_byte_buffer, and
/// to store a pointer to that byte buffer at *buffer. *own_buffer should
/// be set to true if the caller owns said byte buffer, or false if
/// ownership is retained elsewhere.
///
/// Deserialize is required to convert buffer into the message stored at
/// msg. max_message_size is passed in as a bound on the maximum number of
/// message bytes Deserialize should accept.
///
/// Both functions return a Status, allowing them to explain what went
/// wrong if required.
template <class Message,
class UnusedButHereForPartialTemplateSpecialization = void>
class SerializationTraits;
} // namespace grpc
#include <grpc++/impl/codegen/serialization_traits.h>
#endif // GRPCXX_IMPL_SERIALIZATION_TRAITS_H

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -34,90 +34,6 @@
#ifndef GRPCXX_IMPL_SERVICE_TYPE_H
#define GRPCXX_IMPL_SERVICE_TYPE_H
#include <grpc++/impl/serialization_traits.h>
#include <grpc++/server.h>
#include <grpc++/support/config.h>
#include <grpc++/support/status.h>
namespace grpc {
class Call;
class CompletionQueue;
class RpcService;
class Server;
class ServerCompletionQueue;
class ServerContext;
class SynchronousService {
public:
virtual ~SynchronousService() {}
virtual RpcService* service() = 0;
};
class ServerAsyncStreamingInterface {
public:
virtual ~ServerAsyncStreamingInterface() {}
virtual void SendInitialMetadata(void* tag) = 0;
private:
friend class Server;
virtual void BindCall(Call* call) = 0;
};
class AsynchronousService {
public:
AsynchronousService(const char** method_names, size_t method_count)
: server_(nullptr),
method_names_(method_names),
method_count_(method_count),
request_args_(nullptr) {}
~AsynchronousService() { delete[] request_args_; }
protected:
template <class Message>
void RequestAsyncUnary(int index, ServerContext* context, Message* request,
ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag) {
server_->RequestAsyncCall(request_args_[index], context, stream, call_cq,
notification_cq, tag, request);
}
void RequestClientStreaming(int index, ServerContext* context,
ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq,
void* tag) {
server_->RequestAsyncCall(request_args_[index], context, stream, call_cq,
notification_cq, tag);
}
template <class Message>
void RequestServerStreaming(int index, ServerContext* context,
Message* request,
ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq,
void* tag) {
server_->RequestAsyncCall(request_args_[index], context, stream, call_cq,
notification_cq, tag, request);
}
void RequestBidiStreaming(int index, ServerContext* context,
ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag) {
server_->RequestAsyncCall(request_args_[index], context, stream, call_cq,
notification_cq, tag);
}
private:
friend class Server;
Server* server_;
const char** const method_names_;
size_t method_count_;
void** request_args_;
};
} // namespace grpc
#include <grpc++/impl/codegen/service_type.h>
#endif // GRPCXX_IMPL_SERVICE_TYPE_H

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -34,12 +34,6 @@
#ifndef GRPCXX_IMPL_SYNC_H
#define GRPCXX_IMPL_SYNC_H
#include <grpc++/support/config.h>
#ifdef GRPC_CXX0X_NO_THREAD
#include <grpc++/impl/sync_no_cxx11.h>
#else
#include <grpc++/impl/sync_cxx11.h>
#endif
#include <grpc++/impl/codegen/sync.h>
#endif // GRPCXX_IMPL_SYNC_H

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -34,16 +34,6 @@
#ifndef GRPCXX_IMPL_SYNC_CXX11_H
#define GRPCXX_IMPL_SYNC_CXX11_H
#include <condition_variable>
#include <mutex>
namespace grpc {
using std::condition_variable;
using std::mutex;
using std::lock_guard;
using std::unique_lock;
} // namespace grpc
#include <grpc++/impl/codegen/sync_cxx11.h>
#endif // GRPCXX_IMPL_SYNC_CXX11_H

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -34,72 +34,6 @@
#ifndef GRPCXX_IMPL_SYNC_NO_CXX11_H
#define GRPCXX_IMPL_SYNC_NO_CXX11_H
#include <grpc/support/sync.h>
namespace grpc {
template <class mutex>
class lock_guard;
class condition_variable;
class mutex {
public:
mutex() { gpr_mu_init(&mu_); }
~mutex() { gpr_mu_destroy(&mu_); }
private:
::gpr_mu mu_;
template <class mutex>
friend class lock_guard;
friend class condition_variable;
};
template <class mutex>
class lock_guard {
public:
lock_guard(mutex &mu) : mu_(mu), locked(true) { gpr_mu_lock(&mu.mu_); }
~lock_guard() { unlock_internal(); }
protected:
void lock_internal() {
if (!locked) gpr_mu_lock(&mu_.mu_);
locked = true;
}
void unlock_internal() {
if (locked) gpr_mu_unlock(&mu_.mu_);
locked = false;
}
private:
mutex &mu_;
bool locked;
friend class condition_variable;
};
template <class mutex>
class unique_lock : public lock_guard<mutex> {
public:
unique_lock(mutex &mu) : lock_guard<mutex>(mu) {}
void lock() { this->lock_internal(); }
void unlock() { this->unlock_internal(); }
};
class condition_variable {
public:
condition_variable() { gpr_cv_init(&cv_); }
~condition_variable() { gpr_cv_destroy(&cv_); }
void wait(lock_guard<mutex> &mu) {
mu.locked = false;
gpr_cv_wait(&cv_, &mu.mu_.mu_, gpr_inf_future(GPR_CLOCK_REALTIME));
mu.locked = true;
}
void notify_one() { gpr_cv_signal(&cv_); }
void notify_all() { gpr_cv_broadcast(&cv_); }
private:
gpr_cv cv_;
};
} // namespace grpc
#include <grpc++/impl/codegen/sync_no_cxx11.h>
#endif // GRPCXX_IMPL_SYNC_NO_CXX11_H

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -34,77 +34,6 @@
#ifndef GRPCXX_SUPPORT_AUTH_CONTEXT_H
#define GRPCXX_SUPPORT_AUTH_CONTEXT_H
#include <iterator>
#include <vector>
#include <grpc++/support/config.h>
#include <grpc++/support/string_ref.h>
struct grpc_auth_context;
struct grpc_auth_property;
struct grpc_auth_property_iterator;
namespace grpc {
class SecureAuthContext;
typedef std::pair<grpc::string_ref, grpc::string_ref> AuthProperty;
class AuthPropertyIterator
: public std::iterator<std::input_iterator_tag, const AuthProperty> {
public:
~AuthPropertyIterator();
AuthPropertyIterator& operator++();
AuthPropertyIterator operator++(int);
bool operator==(const AuthPropertyIterator& rhs) const;
bool operator!=(const AuthPropertyIterator& rhs) const;
const AuthProperty operator*();
protected:
AuthPropertyIterator();
AuthPropertyIterator(const grpc_auth_property* property,
const grpc_auth_property_iterator* iter);
private:
friend class SecureAuthContext;
const grpc_auth_property* property_;
// The following items form a grpc_auth_property_iterator.
const grpc_auth_context* ctx_;
size_t index_;
const char* name_;
};
/// Class encapsulating the Authentication Information.
///
/// It includes the secure identity of the peer, the type of secure transport
/// used as well as any other properties required by the authorization layer.
class AuthContext {
public:
virtual ~AuthContext() {}
/// Returns true if the peer is authenticated.
virtual bool IsPeerAuthenticated() const = 0;
/// A peer identity.
///
/// It is, in general, comprised of one or more properties (in which case they
/// have the same name).
virtual std::vector<grpc::string_ref> GetPeerIdentity() const = 0;
virtual grpc::string GetPeerIdentityPropertyName() const = 0;
/// Returns all the property values with the given name.
virtual std::vector<grpc::string_ref> FindPropertyValues(
const grpc::string& name) const = 0;
/// Iteration over all the properties.
virtual AuthPropertyIterator begin() const = 0;
virtual AuthPropertyIterator end() const = 0;
// Mutation functions: should only be used by an AuthMetadataProcessor.
virtual void AddProperty(const grpc::string& key,
const grpc::string_ref& value) = 0;
virtual bool SetPeerIdentityPropertyName(const grpc::string& name) = 0;
};
} // namespace grpc
#include <grpc++/impl/codegen/security/auth_context.h>
#endif // GRPCXX_SUPPORT_AUTH_CONTEXT_H

@ -37,12 +37,13 @@
#include <map>
#include <memory>
#include <grpc++/impl/grpc_library.h>
#include <grpc++/impl/codegen/grpc_library.h>
#include <grpc++/security/auth_context.h>
#include <grpc++/support/config.h>
#include <grpc++/support/status.h>
#include <grpc++/support/string_ref.h>
struct grpc_call;
namespace grpc {
class ChannelArguments;
class Channel;
@ -56,9 +57,10 @@ class SecureCallCredentials;
/// for all the calls on that channel.
///
/// \see http://www.grpc.io/docs/guides/auth.html
class ChannelCredentials : public GrpcLibrary {
class ChannelCredentials : private GrpcLibrary {
public:
~ChannelCredentials() GRPC_OVERRIDE;
ChannelCredentials();
~ChannelCredentials();
protected:
friend std::shared_ptr<ChannelCredentials> CompositeChannelCredentials(
@ -81,9 +83,10 @@ class ChannelCredentials : public GrpcLibrary {
/// authenticate with a server for a given call on a channel.
///
/// \see http://www.grpc.io/docs/guides/auth.html
class CallCredentials : public GrpcLibrary {
class CallCredentials {
public:
~CallCredentials() GRPC_OVERRIDE;
CallCredentials();
~CallCredentials();
/// Apply this instance's credentials to \a call.
virtual bool ApplyToCall(grpc_call* call) = 0;

@ -39,7 +39,9 @@
#include <grpc++/completion_queue.h>
#include <grpc++/impl/call.h>
#include <grpc++/impl/grpc_library.h>
#include <grpc++/impl/codegen/grpc_library.h>
#include <grpc++/impl/codegen/server_interface.h>
#include <grpc++/impl/rpc_service_method.h>
#include <grpc++/impl/sync.h>
#include <grpc++/security/server_credentials.h>
#include <grpc++/support/channel_arguments.h>
@ -51,11 +53,8 @@ struct grpc_server;
namespace grpc {
class AsynchronousService;
class GenericServerContext;
class AsyncGenericService;
class RpcService;
class RpcServiceMethod;
class ServerAsyncStreamingInterface;
class ServerContext;
class ThreadPoolInterface;
@ -63,28 +62,15 @@ class ThreadPoolInterface;
/// Models a gRPC server.
///
/// Servers are configured and started via \a grpc::ServerBuilder.
class Server GRPC_FINAL : public GrpcLibrary, private CallHook {
class Server GRPC_FINAL : public ServerInterface, private GrpcLibrary {
public:
~Server();
/// Shutdown the server, blocking until all rpc processing finishes.
/// Forcefully terminate pending calls after \a deadline expires.
///
/// \param deadline How long to wait until pending rpcs are forcefully
/// terminated.
template <class T>
void Shutdown(const T& deadline) {
ShutdownInternal(TimePoint<T>(deadline).raw_time());
}
/// Shutdown the server, waiting for all rpc processing to finish.
void Shutdown() { ShutdownInternal(gpr_inf_future(GPR_CLOCK_MONOTONIC)); }
/// Block waiting for all work to complete.
///
/// \warning The server must be either shutting down or some other thread must
/// call \a Shutdown for this function to ever return.
void Wait();
void Wait() GRPC_OVERRIDE;
/// Global Callbacks
///
@ -105,13 +91,16 @@ class Server GRPC_FINAL : public GrpcLibrary, private CallHook {
private:
friend class AsyncGenericService;
friend class AsynchronousService;
friend class ServerBuilder;
class SyncRequest;
class AsyncRequest;
class ShutdownRequest;
class UnimplementedAsyncRequestContext;
class UnimplementedAsyncRequest;
class UnimplementedAsyncResponse;
/// Server constructors. To be used by \a ServerBuilder only.
///
/// \param thread_pool The threadpool instance to use for call processing.
@ -123,16 +112,12 @@ class Server GRPC_FINAL : public GrpcLibrary, private CallHook {
/// Register a service. This call does not take ownership of the service.
/// The service must exist for the lifetime of the Server instance.
bool RegisterService(const grpc::string* host, RpcService* service);
/// Register an asynchronous service. This call does not take ownership of the
/// service. The service must exist for the lifetime of the Server instance.
bool RegisterAsyncService(const grpc::string* host,
AsynchronousService* service);
bool RegisterService(const grpc::string* host,
Service* service) GRPC_OVERRIDE;
/// Register a generic service. This call does not take ownership of the
/// service. The service must exist for the lifetime of the Server instance.
void RegisterAsyncGenericService(AsyncGenericService* service);
void RegisterAsyncGenericService(AsyncGenericService* service) GRPC_OVERRIDE;
/// Tries to bind \a server to the given \a addr.
///
@ -145,7 +130,8 @@ class Server GRPC_FINAL : public GrpcLibrary, private CallHook {
/// \return bound port number on sucess, 0 on failure.
///
/// \warning It's an error to call this method on an already started server.
int AddListeningPort(const grpc::string& addr, ServerCredentials* creds);
int AddListeningPort(const grpc::string& addr,
ServerCredentials* creds) GRPC_OVERRIDE;
/// Start the server.
///
@ -155,141 +141,21 @@ class Server GRPC_FINAL : public GrpcLibrary, private CallHook {
/// \param num_cqs How many completion queues does \a cqs hold.
///
/// \return true on a successful shutdown.
bool Start(ServerCompletionQueue** cqs, size_t num_cqs);
void HandleQueueClosed();
bool Start(ServerCompletionQueue** cqs, size_t num_cqs) GRPC_OVERRIDE;
/// Process one or more incoming calls.
void RunRpc();
void RunRpc() GRPC_OVERRIDE;
/// Schedule \a RunRpc to run in the threadpool.
void ScheduleCallback();
void ScheduleCallback() GRPC_OVERRIDE;
void PerformOpsOnCall(CallOpSetInterface* ops, Call* call) GRPC_OVERRIDE;
void ShutdownInternal(gpr_timespec deadline);
class BaseAsyncRequest : public CompletionQueueTag {
public:
BaseAsyncRequest(Server* server, ServerContext* context,
ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq, void* tag,
bool delete_on_finalize);
virtual ~BaseAsyncRequest();
bool FinalizeResult(void** tag, bool* status) GRPC_OVERRIDE;
protected:
Server* const server_;
ServerContext* const context_;
ServerAsyncStreamingInterface* const stream_;
CompletionQueue* const call_cq_;
void* const tag_;
const bool delete_on_finalize_;
grpc_call* call_;
grpc_metadata_array initial_metadata_array_;
};
class RegisteredAsyncRequest : public BaseAsyncRequest {
public:
RegisteredAsyncRequest(Server* server, ServerContext* context,
ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq, void* tag);
// uses BaseAsyncRequest::FinalizeResult
void ShutdownInternal(gpr_timespec deadline) GRPC_OVERRIDE;
protected:
void IssueRequest(void* registered_method, grpc_byte_buffer** payload,
ServerCompletionQueue* notification_cq);
};
class NoPayloadAsyncRequest GRPC_FINAL : public RegisteredAsyncRequest {
public:
NoPayloadAsyncRequest(void* registered_method, Server* server,
ServerContext* context,
ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag)
: RegisteredAsyncRequest(server, context, stream, call_cq, tag) {
IssueRequest(registered_method, nullptr, notification_cq);
}
// uses RegisteredAsyncRequest::FinalizeResult
};
template <class Message>
class PayloadAsyncRequest GRPC_FINAL : public RegisteredAsyncRequest {
public:
PayloadAsyncRequest(void* registered_method, Server* server,
ServerContext* context,
ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag,
Message* request)
: RegisteredAsyncRequest(server, context, stream, call_cq, tag),
request_(request) {
IssueRequest(registered_method, &payload_, notification_cq);
}
bool FinalizeResult(void** tag, bool* status) GRPC_OVERRIDE {
bool serialization_status =
*status && payload_ &&
SerializationTraits<Message>::Deserialize(
payload_, request_, server_->max_message_size_).ok();
bool ret = RegisteredAsyncRequest::FinalizeResult(tag, status);
*status = serialization_status&&* status;
return ret;
}
private:
grpc_byte_buffer* payload_;
Message* const request_;
};
class GenericAsyncRequest : public BaseAsyncRequest {
public:
GenericAsyncRequest(Server* server, GenericServerContext* context,
ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag,
bool delete_on_finalize);
bool FinalizeResult(void** tag, bool* status) GRPC_OVERRIDE;
private:
grpc_call_details call_details_;
};
class UnimplementedAsyncRequestContext;
class UnimplementedAsyncRequest;
class UnimplementedAsyncResponse;
int max_message_size() const GRPC_OVERRIDE { return max_message_size_; };
template <class Message>
void RequestAsyncCall(void* registered_method, ServerContext* context,
ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag,
Message* message) {
new PayloadAsyncRequest<Message>(registered_method, this, context, stream,
call_cq, notification_cq, tag, message);
}
void RequestAsyncCall(void* registered_method, ServerContext* context,
ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag) {
new NoPayloadAsyncRequest(registered_method, this, context, stream, call_cq,
notification_cq, tag);
}
void RequestAsyncGenericCall(GenericServerContext* context,
ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq,
void* tag) {
new GenericAsyncRequest(this, context, stream, call_cq, notification_cq,
tag, true);
}
grpc_server* server() GRPC_OVERRIDE { return server_; };
const int max_message_size_;

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -44,14 +44,12 @@
namespace grpc {
class AsyncGenericService;
class AsynchronousService;
class CompletionQueue;
class RpcService;
class Server;
class ServerCompletionQueue;
class ServerCredentials;
class SynchronousService;
class ThreadPoolInterface;
class Service;
/// A builder class for the creation and startup of \a grpc::Server instances.
class ServerBuilder {
@ -62,14 +60,7 @@ class ServerBuilder {
/// The service must exist for the lifetime of the \a Server instance returned
/// by \a BuildAndStart().
/// Matches requests with any :authority
void RegisterService(SynchronousService* service);
/// Register an asynchronous service.
/// This call does not take ownership of the service or completion queue.
/// The service and completion queuemust exist for the lifetime of the \a
/// Server instance returned by \a BuildAndStart().
/// Matches requests with any :authority
void RegisterAsyncService(AsynchronousService* service);
void RegisterService(Service* service);
/// Register a generic service.
/// Matches requests with any :authority
@ -79,15 +70,7 @@ class ServerBuilder {
/// The service must exist for the lifetime of the \a Server instance returned
/// by BuildAndStart().
/// Only matches requests with :authority \a host
void RegisterService(const grpc::string& host, SynchronousService* service);
/// Register an asynchronous service.
/// This call does not take ownership of the service or completion queue.
/// The service and completion queuemust exist for the lifetime of the \a
/// Server instance returned by \a BuildAndStart().
/// Only matches requests with :authority equal to \a host
void RegisterAsyncService(const grpc::string& host,
AsynchronousService* service);
void RegisterService(const grpc::string& host, Service* service);
/// Set max message size in bytes.
void SetMaxMessageSize(int max_message_size) {
@ -132,26 +115,22 @@ class ServerBuilder {
};
typedef std::unique_ptr<grpc::string> HostString;
template <class T>
struct NamedService {
explicit NamedService(T* s) : service(s) {}
NamedService(const grpc::string& h, T* s)
explicit NamedService(Service* s) : service(s) {}
NamedService(const grpc::string& h, Service* s)
: host(new grpc::string(h)), service(s) {}
HostString host;
T* service;
Service* service;
};
int max_message_size_;
grpc_compression_options compression_options_;
std::vector<std::unique_ptr<ServerBuilderOption>> options_;
std::vector<std::unique_ptr<NamedService<RpcService>>> services_;
std::vector<std::unique_ptr<NamedService<AsynchronousService>>>
async_services_;
std::vector<std::unique_ptr<NamedService>> services_;
std::vector<Port> ports_;
std::vector<ServerCompletionQueue*> cqs_;
std::shared_ptr<ServerCredentials> creds_;
AsyncGenericService* generic_service_;
ThreadPoolInterface* thread_pool_;
};
} // namespace grpc

@ -34,166 +34,6 @@
#ifndef GRPCXX_SERVER_CONTEXT_H
#define GRPCXX_SERVER_CONTEXT_H
#include <map>
#include <memory>
#include <grpc/compression.h>
#include <grpc/support/time.h>
#include <grpc++/security/auth_context.h>
#include <grpc++/support/config.h>
#include <grpc++/support/string_ref.h>
#include <grpc++/support/time.h>
struct gpr_timespec;
struct grpc_metadata;
struct grpc_call;
struct census_context;
namespace grpc {
class ClientContext;
template <class W, class R>
class ServerAsyncReader;
template <class W>
class ServerAsyncWriter;
template <class W>
class ServerAsyncResponseWriter;
template <class W, class R>
class ServerAsyncReaderWriter;
template <class R>
class ServerReader;
template <class W>
class ServerWriter;
template <class W, class R>
class ServerReaderWriter;
template <class ServiceType, class RequestType, class ResponseType>
class RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
class ClientStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
class ServerStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
class BidiStreamingHandler;
class UnknownMethodHandler;
class Call;
class CallOpBuffer;
class CompletionQueue;
class Server;
namespace testing {
class InteropServerContextInspector;
} // namespace testing
// Interface of server side rpc context.
class ServerContext {
public:
ServerContext(); // for async calls
~ServerContext();
#ifndef GRPC_CXX0X_NO_CHRONO
std::chrono::system_clock::time_point deadline() {
return Timespec2Timepoint(deadline_);
}
#endif // !GRPC_CXX0X_NO_CHRONO
gpr_timespec raw_deadline() { return deadline_; }
void AddInitialMetadata(const grpc::string& key, const grpc::string& value);
void AddTrailingMetadata(const grpc::string& key, const grpc::string& value);
bool IsCancelled() const;
const std::multimap<grpc::string_ref, grpc::string_ref>& client_metadata() {
return client_metadata_;
}
grpc_compression_level compression_level() const {
return compression_level_;
}
void set_compression_level(grpc_compression_level level);
grpc_compression_algorithm compression_algorithm() const {
return compression_algorithm_;
}
void set_compression_algorithm(grpc_compression_algorithm algorithm);
std::shared_ptr<const AuthContext> auth_context() const;
// Return the peer uri in a string.
// WARNING: this value is never authenticated or subject to any security
// related code. It must not be used for any authentication related
// functionality. Instead, use auth_context.
grpc::string peer() const;
const struct census_context* census_context() const;
// Async only. Has to be called before the rpc starts.
// Returns the tag in completion queue when the rpc finishes.
// IsCancelled() can then be called to check whether the rpc was cancelled.
void AsyncNotifyWhenDone(void* tag) {
has_notify_when_done_tag_ = true;
async_notify_when_done_tag_ = tag;
}
private:
friend class ::grpc::testing::InteropServerContextInspector;
friend class ::grpc::Server;
template <class W, class R>
friend class ::grpc::ServerAsyncReader;
template <class W>
friend class ::grpc::ServerAsyncWriter;
template <class W>
friend class ::grpc::ServerAsyncResponseWriter;
template <class W, class R>
friend class ::grpc::ServerAsyncReaderWriter;
template <class R>
friend class ::grpc::ServerReader;
template <class W>
friend class ::grpc::ServerWriter;
template <class W, class R>
friend class ::grpc::ServerReaderWriter;
template <class ServiceType, class RequestType, class ResponseType>
friend class RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
friend class ClientStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
friend class ServerStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
friend class BidiStreamingHandler;
friend class UnknownMethodHandler;
friend class ::grpc::ClientContext;
// Prevent copying.
ServerContext(const ServerContext&);
ServerContext& operator=(const ServerContext&);
class CompletionOp;
void BeginCompletionOp(Call* call);
ServerContext(gpr_timespec deadline, grpc_metadata* metadata,
size_t metadata_count);
void set_call(grpc_call* call);
CompletionOp* completion_op_;
bool has_notify_when_done_tag_;
void* async_notify_when_done_tag_;
gpr_timespec deadline_;
grpc_call* call_;
CompletionQueue* cq_;
bool sent_initial_metadata_;
mutable std::shared_ptr<const AuthContext> auth_context_;
std::multimap<grpc::string_ref, grpc::string_ref> client_metadata_;
std::multimap<grpc::string, grpc::string> initial_metadata_;
std::multimap<grpc::string, grpc::string> trailing_metadata_;
grpc_compression_level compression_level_;
grpc_compression_algorithm compression_algorithm_;
};
} // namespace grpc
#include <grpc++/impl/codegen/server_context.h>
#endif // GRPCXX_SERVER_CONTEXT_H

@ -34,430 +34,6 @@
#ifndef GRPCXX_SUPPORT_ASYNC_STREAM_H
#define GRPCXX_SUPPORT_ASYNC_STREAM_H
#include <grpc/support/log.h>
#include <grpc++/channel.h>
#include <grpc++/client_context.h>
#include <grpc++/completion_queue.h>
#include <grpc++/impl/call.h>
#include <grpc++/impl/service_type.h>
#include <grpc++/server_context.h>
#include <grpc++/support/status.h>
namespace grpc {
/// Common interface for all client side asynchronous streaming.
class ClientAsyncStreamingInterface {
public:
virtual ~ClientAsyncStreamingInterface() {}
/// Request notification of the reading of the initial metadata. Completion
/// will be notified by \a tag on the associated completion queue.
///
/// \param[in] tag Tag identifying this request.
virtual void ReadInitialMetadata(void* tag) = 0;
/// Request notification completion.
///
/// \param[out] status To be updated with the operation status.
/// \param[in] tag Tag identifying this request.
virtual void Finish(Status* status, void* tag) = 0;
};
/// An interface that yields a sequence of messages of type \a R.
template <class R>
class AsyncReaderInterface {
public:
virtual ~AsyncReaderInterface() {}
/// Read a message of type \a R into \a msg. Completion will be notified by \a
/// tag on the associated completion queue.
///
/// \param[out] msg Where to eventually store the read message.
/// \param[in] tag The tag identifying the operation.
virtual void Read(R* msg, void* tag) = 0;
};
/// An interface that can be fed a sequence of messages of type \a W.
template <class W>
class AsyncWriterInterface {
public:
virtual ~AsyncWriterInterface() {}
/// Request the writing of \a msg with identifying tag \a tag.
///
/// 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.
///
/// \param[in] msg The message to be written.
/// \param[in] tag The tag identifying the operation.
virtual void Write(const W& msg, void* tag) = 0;
};
template <class R>
class ClientAsyncReaderInterface : public ClientAsyncStreamingInterface,
public AsyncReaderInterface<R> {};
template <class R>
class ClientAsyncReader GRPC_FINAL : public ClientAsyncReaderInterface<R> {
public:
/// Create a stream and write the first request out.
template <class W>
ClientAsyncReader(Channel* channel, CompletionQueue* cq,
const RpcMethod& method, ClientContext* context,
const W& request, void* tag)
: context_(context), call_(channel->CreateCall(method, context, cq)) {
init_ops_.set_output_tag(tag);
init_ops_.SendInitialMetadata(context->send_initial_metadata_);
// TODO(ctiller): don't assert
GPR_ASSERT(init_ops_.SendMessage(request).ok());
init_ops_.ClientSendClose();
call_.PerformOps(&init_ops_);
}
void ReadInitialMetadata(void* tag) GRPC_OVERRIDE {
GPR_ASSERT(!context_->initial_metadata_received_);
meta_ops_.set_output_tag(tag);
meta_ops_.RecvInitialMetadata(context_);
call_.PerformOps(&meta_ops_);
}
void Read(R* msg, void* tag) GRPC_OVERRIDE {
read_ops_.set_output_tag(tag);
if (!context_->initial_metadata_received_) {
read_ops_.RecvInitialMetadata(context_);
}
read_ops_.RecvMessage(msg);
call_.PerformOps(&read_ops_);
}
void Finish(Status* status, void* tag) GRPC_OVERRIDE {
finish_ops_.set_output_tag(tag);
if (!context_->initial_metadata_received_) {
finish_ops_.RecvInitialMetadata(context_);
}
finish_ops_.ClientRecvStatus(context_, status);
call_.PerformOps(&finish_ops_);
}
private:
ClientContext* context_;
Call call_;
CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage, CallOpClientSendClose>
init_ops_;
CallOpSet<CallOpRecvInitialMetadata> meta_ops_;
CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>> read_ops_;
CallOpSet<CallOpRecvInitialMetadata, CallOpClientRecvStatus> finish_ops_;
};
/// Common interface for client side asynchronous writing.
template <class W>
class ClientAsyncWriterInterface : public ClientAsyncStreamingInterface,
public AsyncWriterInterface<W> {
public:
/// Signal the client is done with the writes.
///
/// \param[in] tag The tag identifying the operation.
virtual void WritesDone(void* tag) = 0;
};
template <class W>
class ClientAsyncWriter GRPC_FINAL : public ClientAsyncWriterInterface<W> {
public:
template <class R>
ClientAsyncWriter(Channel* channel, CompletionQueue* cq,
const RpcMethod& method, ClientContext* context,
R* response, void* tag)
: context_(context), call_(channel->CreateCall(method, context, cq)) {
finish_ops_.RecvMessage(response);
init_ops_.set_output_tag(tag);
init_ops_.SendInitialMetadata(context->send_initial_metadata_);
call_.PerformOps(&init_ops_);
}
void ReadInitialMetadata(void* tag) GRPC_OVERRIDE {
GPR_ASSERT(!context_->initial_metadata_received_);
meta_ops_.set_output_tag(tag);
meta_ops_.RecvInitialMetadata(context_);
call_.PerformOps(&meta_ops_);
}
void Write(const W& msg, void* tag) GRPC_OVERRIDE {
write_ops_.set_output_tag(tag);
// TODO(ctiller): don't assert
GPR_ASSERT(write_ops_.SendMessage(msg).ok());
call_.PerformOps(&write_ops_);
}
void WritesDone(void* tag) GRPC_OVERRIDE {
writes_done_ops_.set_output_tag(tag);
writes_done_ops_.ClientSendClose();
call_.PerformOps(&writes_done_ops_);
}
void Finish(Status* status, void* tag) GRPC_OVERRIDE {
finish_ops_.set_output_tag(tag);
if (!context_->initial_metadata_received_) {
finish_ops_.RecvInitialMetadata(context_);
}
finish_ops_.ClientRecvStatus(context_, status);
call_.PerformOps(&finish_ops_);
}
private:
ClientContext* context_;
Call call_;
CallOpSet<CallOpSendInitialMetadata> init_ops_;
CallOpSet<CallOpRecvInitialMetadata> meta_ops_;
CallOpSet<CallOpSendMessage> write_ops_;
CallOpSet<CallOpClientSendClose> writes_done_ops_;
CallOpSet<CallOpRecvInitialMetadata, CallOpGenericRecvMessage,
CallOpClientRecvStatus> finish_ops_;
};
/// Client-side interface for asynchronous bi-directional streaming.
template <class W, class R>
class ClientAsyncReaderWriterInterface : public ClientAsyncStreamingInterface,
public AsyncWriterInterface<W>,
public AsyncReaderInterface<R> {
public:
/// Signal the client is done with the writes.
///
/// \param[in] tag The tag identifying the operation.
virtual void WritesDone(void* tag) = 0;
};
template <class W, class R>
class ClientAsyncReaderWriter GRPC_FINAL
: public ClientAsyncReaderWriterInterface<W, R> {
public:
ClientAsyncReaderWriter(Channel* channel, CompletionQueue* cq,
const RpcMethod& method, ClientContext* context,
void* tag)
: context_(context), call_(channel->CreateCall(method, context, cq)) {
init_ops_.set_output_tag(tag);
init_ops_.SendInitialMetadata(context->send_initial_metadata_);
call_.PerformOps(&init_ops_);
}
void ReadInitialMetadata(void* tag) GRPC_OVERRIDE {
GPR_ASSERT(!context_->initial_metadata_received_);
meta_ops_.set_output_tag(tag);
meta_ops_.RecvInitialMetadata(context_);
call_.PerformOps(&meta_ops_);
}
void Read(R* msg, void* tag) GRPC_OVERRIDE {
read_ops_.set_output_tag(tag);
if (!context_->initial_metadata_received_) {
read_ops_.RecvInitialMetadata(context_);
}
read_ops_.RecvMessage(msg);
call_.PerformOps(&read_ops_);
}
void Write(const W& msg, void* tag) GRPC_OVERRIDE {
write_ops_.set_output_tag(tag);
// TODO(ctiller): don't assert
GPR_ASSERT(write_ops_.SendMessage(msg).ok());
call_.PerformOps(&write_ops_);
}
void WritesDone(void* tag) GRPC_OVERRIDE {
writes_done_ops_.set_output_tag(tag);
writes_done_ops_.ClientSendClose();
call_.PerformOps(&writes_done_ops_);
}
void Finish(Status* status, void* tag) GRPC_OVERRIDE {
finish_ops_.set_output_tag(tag);
if (!context_->initial_metadata_received_) {
finish_ops_.RecvInitialMetadata(context_);
}
finish_ops_.ClientRecvStatus(context_, status);
call_.PerformOps(&finish_ops_);
}
private:
ClientContext* context_;
Call call_;
CallOpSet<CallOpSendInitialMetadata> init_ops_;
CallOpSet<CallOpRecvInitialMetadata> meta_ops_;
CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>> read_ops_;
CallOpSet<CallOpSendMessage> write_ops_;
CallOpSet<CallOpClientSendClose> writes_done_ops_;
CallOpSet<CallOpRecvInitialMetadata, CallOpClientRecvStatus> finish_ops_;
};
template <class W, class R>
class ServerAsyncReader GRPC_FINAL : public ServerAsyncStreamingInterface,
public AsyncReaderInterface<R> {
public:
explicit ServerAsyncReader(ServerContext* ctx)
: call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
void SendInitialMetadata(void* tag) GRPC_OVERRIDE {
GPR_ASSERT(!ctx_->sent_initial_metadata_);
meta_ops_.set_output_tag(tag);
meta_ops_.SendInitialMetadata(ctx_->initial_metadata_);
ctx_->sent_initial_metadata_ = true;
call_.PerformOps(&meta_ops_);
}
void Read(R* msg, void* tag) GRPC_OVERRIDE {
read_ops_.set_output_tag(tag);
read_ops_.RecvMessage(msg);
call_.PerformOps(&read_ops_);
}
void Finish(const W& msg, const Status& status, void* tag) {
finish_ops_.set_output_tag(tag);
if (!ctx_->sent_initial_metadata_) {
finish_ops_.SendInitialMetadata(ctx_->initial_metadata_);
ctx_->sent_initial_metadata_ = true;
}
// The response is dropped if the status is not OK.
if (status.ok()) {
finish_ops_.ServerSendStatus(ctx_->trailing_metadata_,
finish_ops_.SendMessage(msg));
} else {
finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
}
call_.PerformOps(&finish_ops_);
}
void FinishWithError(const Status& status, void* tag) {
GPR_ASSERT(!status.ok());
finish_ops_.set_output_tag(tag);
if (!ctx_->sent_initial_metadata_) {
finish_ops_.SendInitialMetadata(ctx_->initial_metadata_);
ctx_->sent_initial_metadata_ = true;
}
finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
call_.PerformOps(&finish_ops_);
}
private:
void BindCall(Call* call) GRPC_OVERRIDE { call_ = *call; }
Call call_;
ServerContext* ctx_;
CallOpSet<CallOpSendInitialMetadata> meta_ops_;
CallOpSet<CallOpRecvMessage<R>> read_ops_;
CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
CallOpServerSendStatus> finish_ops_;
};
template <class W>
class ServerAsyncWriter GRPC_FINAL : public ServerAsyncStreamingInterface,
public AsyncWriterInterface<W> {
public:
explicit ServerAsyncWriter(ServerContext* ctx)
: call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
void SendInitialMetadata(void* tag) GRPC_OVERRIDE {
GPR_ASSERT(!ctx_->sent_initial_metadata_);
meta_ops_.set_output_tag(tag);
meta_ops_.SendInitialMetadata(ctx_->initial_metadata_);
ctx_->sent_initial_metadata_ = true;
call_.PerformOps(&meta_ops_);
}
void Write(const W& msg, void* tag) GRPC_OVERRIDE {
write_ops_.set_output_tag(tag);
if (!ctx_->sent_initial_metadata_) {
write_ops_.SendInitialMetadata(ctx_->initial_metadata_);
ctx_->sent_initial_metadata_ = true;
}
// TODO(ctiller): don't assert
GPR_ASSERT(write_ops_.SendMessage(msg).ok());
call_.PerformOps(&write_ops_);
}
void Finish(const Status& status, void* tag) {
finish_ops_.set_output_tag(tag);
if (!ctx_->sent_initial_metadata_) {
finish_ops_.SendInitialMetadata(ctx_->initial_metadata_);
ctx_->sent_initial_metadata_ = true;
}
finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
call_.PerformOps(&finish_ops_);
}
private:
void BindCall(Call* call) GRPC_OVERRIDE { call_ = *call; }
Call call_;
ServerContext* ctx_;
CallOpSet<CallOpSendInitialMetadata> meta_ops_;
CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage> write_ops_;
CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> finish_ops_;
};
/// Server-side interface for asynchronous bi-directional streaming.
template <class W, class R>
class ServerAsyncReaderWriter GRPC_FINAL : public ServerAsyncStreamingInterface,
public AsyncWriterInterface<W>,
public AsyncReaderInterface<R> {
public:
explicit ServerAsyncReaderWriter(ServerContext* ctx)
: call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
void SendInitialMetadata(void* tag) GRPC_OVERRIDE {
GPR_ASSERT(!ctx_->sent_initial_metadata_);
meta_ops_.set_output_tag(tag);
meta_ops_.SendInitialMetadata(ctx_->initial_metadata_);
ctx_->sent_initial_metadata_ = true;
call_.PerformOps(&meta_ops_);
}
void Read(R* msg, void* tag) GRPC_OVERRIDE {
read_ops_.set_output_tag(tag);
read_ops_.RecvMessage(msg);
call_.PerformOps(&read_ops_);
}
void Write(const W& msg, void* tag) GRPC_OVERRIDE {
write_ops_.set_output_tag(tag);
if (!ctx_->sent_initial_metadata_) {
write_ops_.SendInitialMetadata(ctx_->initial_metadata_);
ctx_->sent_initial_metadata_ = true;
}
// TODO(ctiller): don't assert
GPR_ASSERT(write_ops_.SendMessage(msg).ok());
call_.PerformOps(&write_ops_);
}
void Finish(const Status& status, void* tag) {
finish_ops_.set_output_tag(tag);
if (!ctx_->sent_initial_metadata_) {
finish_ops_.SendInitialMetadata(ctx_->initial_metadata_);
ctx_->sent_initial_metadata_ = true;
}
finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
call_.PerformOps(&finish_ops_);
}
private:
friend class ::grpc::Server;
void BindCall(Call* call) GRPC_OVERRIDE { call_ = *call; }
Call call_;
ServerContext* ctx_;
CallOpSet<CallOpSendInitialMetadata> meta_ops_;
CallOpSet<CallOpRecvMessage<R>> read_ops_;
CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage> write_ops_;
CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> finish_ops_;
};
} // namespace grpc
#include <grpc++/impl/codegen/async_stream.h>
#endif // GRPCXX_SUPPORT_ASYNC_STREAM_H

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -34,122 +34,6 @@
#ifndef GRPCXX_SUPPORT_ASYNC_UNARY_CALL_H
#define GRPCXX_SUPPORT_ASYNC_UNARY_CALL_H
#include <grpc/support/log.h>
#include <grpc++/channel.h>
#include <grpc++/client_context.h>
#include <grpc++/completion_queue.h>
#include <grpc++/server_context.h>
#include <grpc++/impl/call.h>
#include <grpc++/impl/service_type.h>
#include <grpc++/support/status.h>
namespace grpc {
template <class R>
class ClientAsyncResponseReaderInterface {
public:
virtual ~ClientAsyncResponseReaderInterface() {}
virtual void ReadInitialMetadata(void* tag) = 0;
virtual void Finish(R* msg, Status* status, void* tag) = 0;
};
template <class R>
class ClientAsyncResponseReader GRPC_FINAL
: public ClientAsyncResponseReaderInterface<R> {
public:
template <class W>
ClientAsyncResponseReader(Channel* channel, CompletionQueue* cq,
const RpcMethod& method, ClientContext* context,
const W& request)
: context_(context), call_(channel->CreateCall(method, context, cq)) {
init_buf_.SendInitialMetadata(context->send_initial_metadata_);
// TODO(ctiller): don't assert
GPR_ASSERT(init_buf_.SendMessage(request).ok());
init_buf_.ClientSendClose();
call_.PerformOps(&init_buf_);
}
void ReadInitialMetadata(void* tag) {
GPR_ASSERT(!context_->initial_metadata_received_);
meta_buf_.set_output_tag(tag);
meta_buf_.RecvInitialMetadata(context_);
call_.PerformOps(&meta_buf_);
}
void Finish(R* msg, Status* status, void* tag) {
finish_buf_.set_output_tag(tag);
if (!context_->initial_metadata_received_) {
finish_buf_.RecvInitialMetadata(context_);
}
finish_buf_.RecvMessage(msg);
finish_buf_.ClientRecvStatus(context_, status);
call_.PerformOps(&finish_buf_);
}
private:
ClientContext* context_;
Call call_;
SneakyCallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
CallOpClientSendClose> init_buf_;
CallOpSet<CallOpRecvInitialMetadata> meta_buf_;
CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>,
CallOpClientRecvStatus> finish_buf_;
};
template <class W>
class ServerAsyncResponseWriter GRPC_FINAL
: public ServerAsyncStreamingInterface {
public:
explicit ServerAsyncResponseWriter(ServerContext* ctx)
: call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
void SendInitialMetadata(void* tag) GRPC_OVERRIDE {
GPR_ASSERT(!ctx_->sent_initial_metadata_);
meta_buf_.set_output_tag(tag);
meta_buf_.SendInitialMetadata(ctx_->initial_metadata_);
ctx_->sent_initial_metadata_ = true;
call_.PerformOps(&meta_buf_);
}
void Finish(const W& msg, const Status& status, void* tag) {
finish_buf_.set_output_tag(tag);
if (!ctx_->sent_initial_metadata_) {
finish_buf_.SendInitialMetadata(ctx_->initial_metadata_);
ctx_->sent_initial_metadata_ = true;
}
// The response is dropped if the status is not OK.
if (status.ok()) {
finish_buf_.ServerSendStatus(ctx_->trailing_metadata_,
finish_buf_.SendMessage(msg));
} else {
finish_buf_.ServerSendStatus(ctx_->trailing_metadata_, status);
}
call_.PerformOps(&finish_buf_);
}
void FinishWithError(const Status& status, void* tag) {
GPR_ASSERT(!status.ok());
finish_buf_.set_output_tag(tag);
if (!ctx_->sent_initial_metadata_) {
finish_buf_.SendInitialMetadata(ctx_->initial_metadata_);
ctx_->sent_initial_metadata_ = true;
}
finish_buf_.ServerSendStatus(ctx_->trailing_metadata_, status);
call_.PerformOps(&finish_buf_);
}
private:
void BindCall(Call* call) GRPC_OVERRIDE { call_ = *call; }
Call call_;
ServerContext* ctx_;
CallOpSet<CallOpSendInitialMetadata> meta_buf_;
CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
CallOpServerSendStatus> finish_buf_;
};
} // namespace grpc
#include <grpc++/impl/codegen/async_unary_call.h>
#endif // GRPCXX_SUPPORT_ASYNC_UNARY_CALL_H

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -34,83 +34,6 @@
#ifndef GRPCXX_SUPPORT_CONFIG_H
#define GRPCXX_SUPPORT_CONFIG_H
#if !defined(GRPC_NO_AUTODETECT_PLATFORM)
#ifdef _MSC_VER
// Visual Studio 2010 is 1600.
#if _MSC_VER < 1600
#error "gRPC is only supported with Visual Studio starting at 2010"
// Visual Studio 2013 is 1800.
#elif _MSC_VER < 1800
#define GRPC_CXX0X_NO_FINAL 1
#define GRPC_CXX0X_NO_OVERRIDE 1
#define GRPC_CXX0X_NO_CHRONO 1
#define GRPC_CXX0X_NO_THREAD 1
#endif
#endif // Visual Studio
#ifndef __clang__
#ifdef __GNUC__
// nullptr was added in gcc 4.6
#if (__GNUC__ * 100 + __GNUC_MINOR__ < 406)
#define GRPC_CXX0X_NO_NULLPTR 1
#endif
// final and override were added in gcc 4.7
#if (__GNUC__ * 100 + __GNUC_MINOR__ < 407)
#define GRPC_CXX0X_NO_FINAL 1
#define GRPC_CXX0X_NO_OVERRIDE 1
#endif
#endif
#endif
#endif
#ifdef GRPC_CXX0X_NO_FINAL
#define GRPC_FINAL
#else
#define GRPC_FINAL final
#endif
#ifdef GRPC_CXX0X_NO_OVERRIDE
#define GRPC_OVERRIDE
#else
#define GRPC_OVERRIDE override
#endif
#ifdef GRPC_CXX0X_NO_NULLPTR
#include <memory>
namespace grpc {
const class {
public:
template <class T>
operator T *() const {
return static_cast<T *>(0);
}
template <class T>
operator std::unique_ptr<T>() const {
return std::unique_ptr<T>(static_cast<T *>(0));
}
template <class T>
operator std::shared_ptr<T>() const {
return std::shared_ptr<T>(static_cast<T *>(0));
}
operator bool() const { return false; }
private:
void operator&() const = delete;
} nullptr = {};
}
#endif
#ifndef GRPC_CUSTOM_STRING
#include <string>
#define GRPC_CUSTOM_STRING std::string
#endif
namespace grpc {
typedef GRPC_CUSTOM_STRING string;
} // namespace grpc
#include <grpc++/impl/codegen/config.h>
#endif // GRPCXX_SUPPORT_CONFIG_H

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -34,39 +34,6 @@
#ifndef GRPCXX_SUPPORT_CONFIG_PROTOBUF_H
#define GRPCXX_SUPPORT_CONFIG_PROTOBUF_H
#ifndef GRPC_CUSTOM_PROTOBUF_INT64
#include <google/protobuf/stubs/common.h>
#define GRPC_CUSTOM_PROTOBUF_INT64 ::google::protobuf::int64
#endif
#ifndef GRPC_CUSTOM_MESSAGE
#include <google/protobuf/message.h>
#define GRPC_CUSTOM_MESSAGE ::google::protobuf::Message
#endif
#ifndef GRPC_CUSTOM_ZEROCOPYOUTPUTSTREAM
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream.h>
#define GRPC_CUSTOM_ZEROCOPYOUTPUTSTREAM \
::google::protobuf::io::ZeroCopyOutputStream
#define GRPC_CUSTOM_ZEROCOPYINPUTSTREAM \
::google::protobuf::io::ZeroCopyInputStream
#define GRPC_CUSTOM_CODEDINPUTSTREAM ::google::protobuf::io::CodedInputStream
#endif
namespace grpc {
namespace protobuf {
typedef GRPC_CUSTOM_MESSAGE Message;
typedef GRPC_CUSTOM_PROTOBUF_INT64 int64;
namespace io {
typedef GRPC_CUSTOM_ZEROCOPYOUTPUTSTREAM ZeroCopyOutputStream;
typedef GRPC_CUSTOM_ZEROCOPYINPUTSTREAM ZeroCopyInputStream;
typedef GRPC_CUSTOM_CODEDINPUTSTREAM CodedInputStream;
} // namespace io
} // namespace protobuf
} // namespace grpc
#include <grpc++/impl/codegen/config_protobuf.h>
#endif // GRPCXX_SUPPORT_CONFIG_PROTOBUF_H

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -34,43 +34,6 @@
#ifndef GRPCXX_SUPPORT_STATUS_H
#define GRPCXX_SUPPORT_STATUS_H
#include <grpc++/support/config.h>
#include <grpc++/support/status_code_enum.h>
namespace grpc {
/// Did it work? If it didn't, why?
///
/// See \a grpc::StatusCode for details on the available code and their meaning.
class Status {
public:
/// Construct an OK instance.
Status() : code_(StatusCode::OK) {}
/// Construct an instance with associated \a code and \a details (also
// referred to as "error_message").
Status(StatusCode code, const grpc::string& details)
: code_(code), details_(details) {}
// Pre-defined special status objects.
/// An OK pre-defined instance.
static const Status& OK;
/// A CANCELLED pre-defined instance.
static const Status& CANCELLED;
/// Return the instance's error code.
StatusCode error_code() const { return code_; }
/// Return the instance's error message.
grpc::string error_message() const { return details_; }
/// Is the status OK?
bool ok() const { return code_ == StatusCode::OK; }
private:
StatusCode code_;
grpc::string details_;
};
} // namespace grpc
#include <grpc++/impl/codegen/status.h>
#endif // GRPCXX_SUPPORT_STATUS_H

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -34,119 +34,6 @@
#ifndef GRPCXX_SUPPORT_STATUS_CODE_ENUM_H
#define GRPCXX_SUPPORT_STATUS_CODE_ENUM_H
namespace grpc {
enum StatusCode {
/// Not an error; returned on success.
OK = 0,
/// The operation was cancelled (typically by the caller).
CANCELLED = 1,
/// Unknown error. An example of where this error may be returned is if a
/// Status value received from another address space belongs to an error-space
/// that is not known in this address space. Also errors raised by APIs that
/// do not return enough error information may be converted to this error.
UNKNOWN = 2,
/// Client specified an invalid argument. Note that this differs from
/// FAILED_PRECONDITION. INVALID_ARGUMENT indicates arguments that are
/// problematic regardless of the state of the system (e.g., a malformed file
/// name).
INVALID_ARGUMENT = 3,
/// Deadline expired before operation could complete. For operations that
/// change the state of the system, this error may be returned even if the
/// operation has completed successfully. For example, a successful response
/// from a server could have been delayed long enough for the deadline to
/// expire.
DEADLINE_EXCEEDED = 4,
/// Some requested entity (e.g., file or directory) was not found.
NOT_FOUND = 5,
/// Some entity that we attempted to create (e.g., file or directory) already
/// exists.
ALREADY_EXISTS = 6,
/// The caller does not have permission to execute the specified operation.
/// PERMISSION_DENIED must not be used for rejections caused by exhausting
/// some resource (use RESOURCE_EXHAUSTED instead for those errors).
/// PERMISSION_DENIED must not be used if the caller can not be identified
/// (use UNAUTHENTICATED instead for those errors).
PERMISSION_DENIED = 7,
/// The request does not have valid authentication credentials for the
/// operation.
UNAUTHENTICATED = 16,
/// Some resource has been exhausted, perhaps a per-user quota, or perhaps the
/// entire file system is out of space.
RESOURCE_EXHAUSTED = 8,
/// Operation was rejected because the system is not in a state required for
/// the operation's execution. For example, directory to be deleted may be
/// non-empty, an rmdir operation is applied to a non-directory, etc.
///
/// A litmus test that may help a service implementor in deciding
/// between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE:
/// (a) Use UNAVAILABLE if the client can retry just the failing call.
/// (b) Use ABORTED if the client should retry at a higher-level
/// (e.g., restarting a read-modify-write sequence).
/// (c) Use FAILED_PRECONDITION if the client should not retry until
/// the system state has been explicitly fixed. E.g., if an "rmdir"
/// fails because the directory is non-empty, FAILED_PRECONDITION
/// should be returned since the client should not retry unless
/// they have first fixed up the directory by deleting files from it.
/// (d) Use FAILED_PRECONDITION if the client performs conditional
/// REST Get/Update/Delete on a resource and the resource on the
/// server does not match the condition. E.g., conflicting
/// read-modify-write on the same resource.
FAILED_PRECONDITION = 9,
/// The operation was aborted, typically due to a concurrency issue like
/// sequencer check failures, transaction aborts, etc.
///
/// See litmus test above for deciding between FAILED_PRECONDITION, ABORTED,
/// and UNAVAILABLE.
ABORTED = 10,
/// Operation was attempted past the valid range. E.g., seeking or reading
/// past end of file.
///
/// Unlike INVALID_ARGUMENT, this error indicates a problem that may be fixed
/// if the system state changes. For example, a 32-bit file system will
/// generate INVALID_ARGUMENT if asked to read at an offset that is not in the
/// range [0,2^32-1], but it will generate OUT_OF_RANGE if asked to read from
/// an offset past the current file size.
///
/// There is a fair bit of overlap between FAILED_PRECONDITION and
/// OUT_OF_RANGE. We recommend using OUT_OF_RANGE (the more specific error)
/// when it applies so that callers who are iterating through a space can
/// easily look for an OUT_OF_RANGE error to detect when they are done.
OUT_OF_RANGE = 11,
/// Operation is not implemented or not supported/enabled in this service.
UNIMPLEMENTED = 12,
/// Internal errors. Means some invariants expected by underlying System has
/// been broken. If you see one of these errors, Something is very broken.
INTERNAL = 13,
/// The service is currently unavailable. This is a most likely a transient
/// condition and may be corrected by retrying with a backoff.
///
/// See litmus test above for deciding between FAILED_PRECONDITION, ABORTED,
/// and UNAVAILABLE.
UNAVAILABLE = 14,
/// Unrecoverable data loss or corruption.
DATA_LOSS = 15,
/// Force users to include a default branch:
DO_NOT_USE = -1
};
} // namespace grpc
#include <grpc++/impl/codegen/status_code_enum.h>
#endif // GRPCXX_SUPPORT_STATUS_CODE_ENUM_H

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -34,90 +34,6 @@
#ifndef GRPCXX_SUPPORT_STRING_REF_H
#define GRPCXX_SUPPORT_STRING_REF_H
#include <iterator>
#include <iosfwd>
#include <grpc++/support/config.h>
namespace grpc {
/// This class is a non owning reference to a string.
///
/// It should be a strict subset of the upcoming std::string_ref.
///
/// \see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html
///
/// The constexpr is dropped or replaced with const for legacy compiler
/// compatibility.
class string_ref {
public:
// types
typedef const char* const_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
// constants
const static size_t npos;
// construct/copy.
string_ref() : data_(nullptr), length_(0) {}
string_ref(const string_ref& other)
: data_(other.data_), length_(other.length_) {}
string_ref& operator=(const string_ref& rhs);
string_ref(const char* s);
string_ref(const char* s, size_t l) : data_(s), length_(l) {}
string_ref(const grpc::string& s) : data_(s.data()), length_(s.length()) {}
// iterators
const_iterator begin() const { return data_; }
const_iterator end() const { return data_ + length_; }
const_iterator cbegin() const { return data_; }
const_iterator cend() const { return data_ + length_; }
const_reverse_iterator rbegin() const {
return const_reverse_iterator(end());
}
const_reverse_iterator rend() const {
return const_reverse_iterator(begin());
}
const_reverse_iterator crbegin() const {
return const_reverse_iterator(end());
}
const_reverse_iterator crend() const {
return const_reverse_iterator(begin());
}
// capacity
size_t size() const { return length_; }
size_t length() const { return length_; }
size_t max_size() const { return length_; }
bool empty() const { return length_ == 0; }
// element access
const char* data() const { return data_; }
// string operations
int compare(string_ref x) const;
bool starts_with(string_ref x) const;
bool ends_with(string_ref x) const;
size_t find(string_ref s) const;
size_t find(char c) const;
string_ref substr(size_t pos, size_t n = npos) const;
private:
const char* data_;
size_t length_;
};
// Comparison operators
bool operator==(string_ref x, string_ref y);
bool operator!=(string_ref x, string_ref y);
bool operator<(string_ref x, string_ref y);
bool operator>(string_ref x, string_ref y);
bool operator<=(string_ref x, string_ref y);
bool operator>=(string_ref x, string_ref y);
std::ostream& operator<<(std::ostream& stream, const string_ref& string);
} // namespace grpc
#include <grpc++/impl/codegen/string_ref.h>
#endif // GRPCXX_SUPPORT_STRING_REF_H

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -34,10 +34,6 @@
#ifndef GRPCXX_SUPPORT_STUB_OPTIONS_H
#define GRPCXX_SUPPORT_STUB_OPTIONS_H
namespace grpc {
class StubOptions {};
} // namespace grpc
#include <grpc++/impl/codegen/stub_options.h>
#endif // GRPCXX_SUPPORT_STUB_OPTIONS_H

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -34,382 +34,6 @@
#ifndef GRPCXX_SUPPORT_SYNC_STREAM_H
#define GRPCXX_SUPPORT_SYNC_STREAM_H
#include <grpc/support/log.h>
#include <grpc++/channel.h>
#include <grpc++/client_context.h>
#include <grpc++/completion_queue.h>
#include <grpc++/impl/call.h>
#include <grpc++/impl/service_type.h>
#include <grpc++/server_context.h>
#include <grpc++/support/status.h>
namespace grpc {
/// Common interface for all synchronous client side streaming.
class ClientStreamingInterface {
public:
virtual ~ClientStreamingInterface() {}
/// Wait until the stream finishes, and return the final status. When the
/// client side declares it has no more message to send, either implicitly or
/// by calling \a WritesDone(), it needs to make sure there is no more message
/// to be received from the server, either implicitly or by getting a false
/// from a \a Read().
///
/// This function will return either:
/// - when all incoming messages have been read and the server has returned
/// status.
/// - OR when the server has returned a non-OK status.
virtual Status Finish() = 0;
};
/// An interface that yields a sequence of messages of type \a R.
template <class R>
class ReaderInterface {
public:
virtual ~ReaderInterface() {}
/// Blocking read a message and parse to \a msg. Returns \a true on success.
///
/// \param[out] msg The read message.
///
/// \return \a false when there will be no more incoming messages, either
/// because the other side has called \a WritesDone() or the stream has failed
/// (or been cancelled).
virtual bool Read(R* msg) = 0;
};
/// An interface that can be fed a sequence of messages of type \a W.
template <class W>
class WriterInterface {
public:
virtual ~WriterInterface() {}
/// Blocking write \a msg to the stream with options.
///
/// \param msg The message to be written to the stream.
/// \param options Options affecting the write operation.
///
/// \return \a true on success, \a false when the stream has been closed.
virtual bool Write(const W& msg, const WriteOptions& options) = 0;
/// Blocking write \a msg to the stream with default options.
///
/// \param msg The message to be written to the stream.
///
/// \return \a true on success, \a false when the stream has been closed.
inline bool Write(const W& msg) { return Write(msg, WriteOptions()); }
};
/// Client-side interface for streaming reads of message of type \a R.
template <class R>
class ClientReaderInterface : public ClientStreamingInterface,
public ReaderInterface<R> {
public:
/// Blocking wait for initial metadata from server. The received metadata
/// can only be accessed after this call returns. Should only be called before
/// the first read. Calling this method is optional, and if it is not called
/// the metadata will be available in ClientContext after the first read.
virtual void WaitForInitialMetadata() = 0;
};
template <class R>
class ClientReader GRPC_FINAL : public ClientReaderInterface<R> {
public:
/// Blocking create a stream and write the first request out.
template <class W>
ClientReader(Channel* channel, const RpcMethod& method,
ClientContext* context, const W& request)
: context_(context), call_(channel->CreateCall(method, context, &cq_)) {
CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
CallOpClientSendClose> ops;
ops.SendInitialMetadata(context->send_initial_metadata_);
// TODO(ctiller): don't assert
GPR_ASSERT(ops.SendMessage(request).ok());
ops.ClientSendClose();
call_.PerformOps(&ops);
cq_.Pluck(&ops);
}
void WaitForInitialMetadata() GRPC_OVERRIDE {
GPR_ASSERT(!context_->initial_metadata_received_);
CallOpSet<CallOpRecvInitialMetadata> ops;
ops.RecvInitialMetadata(context_);
call_.PerformOps(&ops);
cq_.Pluck(&ops); /// status ignored
}
bool Read(R* msg) GRPC_OVERRIDE {
CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>> ops;
if (!context_->initial_metadata_received_) {
ops.RecvInitialMetadata(context_);
}
ops.RecvMessage(msg);
call_.PerformOps(&ops);
return cq_.Pluck(&ops) && ops.got_message;
}
Status Finish() GRPC_OVERRIDE {
CallOpSet<CallOpClientRecvStatus> ops;
Status status;
ops.ClientRecvStatus(context_, &status);
call_.PerformOps(&ops);
GPR_ASSERT(cq_.Pluck(&ops));
return status;
}
private:
ClientContext* context_;
CompletionQueue cq_;
Call call_;
};
/// Client-side interface for streaming writes of message of type \a W.
template <class W>
class ClientWriterInterface : public ClientStreamingInterface,
public WriterInterface<W> {
public:
/// Half close writing from the client.
/// Block until writes are completed.
///
/// \return Whether the writes were successful.
virtual bool WritesDone() = 0;
};
template <class W>
class ClientWriter : public ClientWriterInterface<W> {
public:
/// Blocking create a stream.
template <class R>
ClientWriter(Channel* channel, const RpcMethod& method,
ClientContext* context, R* response)
: context_(context), call_(channel->CreateCall(method, context, &cq_)) {
finish_ops_.RecvMessage(response);
CallOpSet<CallOpSendInitialMetadata> ops;
ops.SendInitialMetadata(context->send_initial_metadata_);
call_.PerformOps(&ops);
cq_.Pluck(&ops);
}
using WriterInterface<W>::Write;
bool Write(const W& msg, const WriteOptions& options) GRPC_OVERRIDE {
CallOpSet<CallOpSendMessage> ops;
if (!ops.SendMessage(msg, options).ok()) {
return false;
}
call_.PerformOps(&ops);
return cq_.Pluck(&ops);
}
bool WritesDone() GRPC_OVERRIDE {
CallOpSet<CallOpClientSendClose> ops;
ops.ClientSendClose();
call_.PerformOps(&ops);
return cq_.Pluck(&ops);
}
/// Read the final response and wait for the final status.
Status Finish() GRPC_OVERRIDE {
Status status;
finish_ops_.ClientRecvStatus(context_, &status);
call_.PerformOps(&finish_ops_);
GPR_ASSERT(cq_.Pluck(&finish_ops_));
return status;
}
private:
ClientContext* context_;
CallOpSet<CallOpGenericRecvMessage, CallOpClientRecvStatus> finish_ops_;
CompletionQueue cq_;
Call call_;
};
/// Client-side interface for bi-directional streaming.
template <class W, class R>
class ClientReaderWriterInterface : public ClientStreamingInterface,
public WriterInterface<W>,
public ReaderInterface<R> {
public:
/// Blocking wait for initial metadata from server. The received metadata
/// can only be accessed after this call returns. Should only be called before
/// the first read. Calling this method is optional, and if it is not called
/// the metadata will be available in ClientContext after the first read.
virtual void WaitForInitialMetadata() = 0;
/// Block until writes are completed.
///
/// \return Whether the writes were successful.
virtual bool WritesDone() = 0;
};
template <class W, class R>
class ClientReaderWriter GRPC_FINAL : public ClientReaderWriterInterface<W, R> {
public:
/// Blocking create a stream.
ClientReaderWriter(Channel* channel, const RpcMethod& method,
ClientContext* context)
: context_(context), call_(channel->CreateCall(method, context, &cq_)) {
CallOpSet<CallOpSendInitialMetadata> ops;
ops.SendInitialMetadata(context->send_initial_metadata_);
call_.PerformOps(&ops);
cq_.Pluck(&ops);
}
void WaitForInitialMetadata() GRPC_OVERRIDE {
GPR_ASSERT(!context_->initial_metadata_received_);
CallOpSet<CallOpRecvInitialMetadata> ops;
ops.RecvInitialMetadata(context_);
call_.PerformOps(&ops);
cq_.Pluck(&ops); // status ignored
}
bool Read(R* msg) GRPC_OVERRIDE {
CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>> ops;
if (!context_->initial_metadata_received_) {
ops.RecvInitialMetadata(context_);
}
ops.RecvMessage(msg);
call_.PerformOps(&ops);
return cq_.Pluck(&ops) && ops.got_message;
}
using WriterInterface<W>::Write;
bool Write(const W& msg, const WriteOptions& options) GRPC_OVERRIDE {
CallOpSet<CallOpSendMessage> ops;
if (!ops.SendMessage(msg, options).ok()) return false;
call_.PerformOps(&ops);
return cq_.Pluck(&ops);
}
bool WritesDone() GRPC_OVERRIDE {
CallOpSet<CallOpClientSendClose> ops;
ops.ClientSendClose();
call_.PerformOps(&ops);
return cq_.Pluck(&ops);
}
Status Finish() GRPC_OVERRIDE {
CallOpSet<CallOpClientRecvStatus> ops;
Status status;
ops.ClientRecvStatus(context_, &status);
call_.PerformOps(&ops);
GPR_ASSERT(cq_.Pluck(&ops));
return status;
}
private:
ClientContext* context_;
CompletionQueue cq_;
Call call_;
};
template <class R>
class ServerReader GRPC_FINAL : public ReaderInterface<R> {
public:
ServerReader(Call* call, ServerContext* ctx) : call_(call), ctx_(ctx) {}
void SendInitialMetadata() {
GPR_ASSERT(!ctx_->sent_initial_metadata_);
CallOpSet<CallOpSendInitialMetadata> ops;
ops.SendInitialMetadata(ctx_->initial_metadata_);
ctx_->sent_initial_metadata_ = true;
call_->PerformOps(&ops);
call_->cq()->Pluck(&ops);
}
bool Read(R* msg) GRPC_OVERRIDE {
CallOpSet<CallOpRecvMessage<R>> ops;
ops.RecvMessage(msg);
call_->PerformOps(&ops);
return call_->cq()->Pluck(&ops) && ops.got_message;
}
private:
Call* const call_;
ServerContext* const ctx_;
};
template <class W>
class ServerWriter GRPC_FINAL : public WriterInterface<W> {
public:
ServerWriter(Call* call, ServerContext* ctx) : call_(call), ctx_(ctx) {}
void SendInitialMetadata() {
GPR_ASSERT(!ctx_->sent_initial_metadata_);
CallOpSet<CallOpSendInitialMetadata> ops;
ops.SendInitialMetadata(ctx_->initial_metadata_);
ctx_->sent_initial_metadata_ = true;
call_->PerformOps(&ops);
call_->cq()->Pluck(&ops);
}
using WriterInterface<W>::Write;
bool Write(const W& msg, const WriteOptions& options) GRPC_OVERRIDE {
CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage> ops;
if (!ops.SendMessage(msg, options).ok()) {
return false;
}
if (!ctx_->sent_initial_metadata_) {
ops.SendInitialMetadata(ctx_->initial_metadata_);
ctx_->sent_initial_metadata_ = true;
}
call_->PerformOps(&ops);
return call_->cq()->Pluck(&ops);
}
private:
Call* const call_;
ServerContext* const ctx_;
};
/// Server-side interface for bi-directional streaming.
template <class W, class R>
class ServerReaderWriter GRPC_FINAL : public WriterInterface<W>,
public ReaderInterface<R> {
public:
ServerReaderWriter(Call* call, ServerContext* ctx) : call_(call), ctx_(ctx) {}
void SendInitialMetadata() {
GPR_ASSERT(!ctx_->sent_initial_metadata_);
CallOpSet<CallOpSendInitialMetadata> ops;
ops.SendInitialMetadata(ctx_->initial_metadata_);
ctx_->sent_initial_metadata_ = true;
call_->PerformOps(&ops);
call_->cq()->Pluck(&ops);
}
bool Read(R* msg) GRPC_OVERRIDE {
CallOpSet<CallOpRecvMessage<R>> ops;
ops.RecvMessage(msg);
call_->PerformOps(&ops);
return call_->cq()->Pluck(&ops) && ops.got_message;
}
using WriterInterface<W>::Write;
bool Write(const W& msg, const WriteOptions& options) GRPC_OVERRIDE {
CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage> ops;
if (!ops.SendMessage(msg, options).ok()) {
return false;
}
if (!ctx_->sent_initial_metadata_) {
ops.SendInitialMetadata(ctx_->initial_metadata_);
ctx_->sent_initial_metadata_ = true;
}
call_->PerformOps(&ops);
return call_->cq()->Pluck(&ops);
}
private:
Call* const call_;
ServerContext* const ctx_;
};
} // namespace grpc
#include <grpc++/impl/codegen/sync_stream.h>
#endif // GRPCXX_SUPPORT_SYNC_STREAM_H

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -34,78 +34,6 @@
#ifndef GRPCXX_SUPPORT_TIME_H
#define GRPCXX_SUPPORT_TIME_H
#include <grpc++/support/config.h>
#include <grpc/support/time.h>
namespace grpc {
/* If you are trying to use CompletionQueue::AsyncNext with a time class that
isn't either gpr_timespec or std::chrono::system_clock::time_point, you
will most likely be looking at this comment as your compiler will have
fired an error below. In order to fix this issue, you have two potential
solutions:
1. Use gpr_timespec or std::chrono::system_clock::time_point instead
2. Specialize the TimePoint class with whichever time class that you
want to use here. See below for two examples of how to do this.
*/
template <typename T>
class TimePoint {
public:
TimePoint(const T& time) { you_need_a_specialization_of_TimePoint(); }
gpr_timespec raw_time() {
gpr_timespec t;
return t;
}
private:
void you_need_a_specialization_of_TimePoint();
};
template <>
class TimePoint<gpr_timespec> {
public:
TimePoint(const gpr_timespec& time) : time_(time) {}
gpr_timespec raw_time() { return time_; }
private:
gpr_timespec time_;
};
} // namespace grpc
#ifndef GRPC_CXX0X_NO_CHRONO
#include <chrono>
#include <grpc/support/time.h>
namespace grpc {
// from and to should be absolute time.
void Timepoint2Timespec(const std::chrono::system_clock::time_point& from,
gpr_timespec* to);
void TimepointHR2Timespec(
const std::chrono::high_resolution_clock::time_point& from,
gpr_timespec* to);
std::chrono::system_clock::time_point Timespec2Timepoint(gpr_timespec t);
template <>
class TimePoint<std::chrono::system_clock::time_point> {
public:
TimePoint(const std::chrono::system_clock::time_point& time) {
Timepoint2Timespec(time, &time_);
}
gpr_timespec raw_time() const { return time_; }
private:
gpr_timespec time_;
};
} // namespace grpc
#endif // !GRPC_CXX0X_NO_CHRONO
#include <grpc++/impl/codegen/time.h>
#endif // GRPCXX_SUPPORT_TIME_H

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -34,87 +34,6 @@
#ifndef GRPC_BYTE_BUFFER_H
#define GRPC_BYTE_BUFFER_H
#include <grpc/compression.h>
#include <grpc/support/slice_buffer.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
GRPC_BB_RAW
/* Future types may include GRPC_BB_PROTOBUF, etc. */
} grpc_byte_buffer_type;
struct grpc_byte_buffer {
void *reserved;
grpc_byte_buffer_type type;
union {
struct {
void *reserved[8];
} reserved;
struct {
grpc_compression_algorithm compression;
gpr_slice_buffer slice_buffer;
} raw;
} data;
};
typedef struct grpc_byte_buffer grpc_byte_buffer;
/** Returns a RAW byte buffer instance over the given slices (up to \a nslices).
*
* Increases the reference count for all \a slices processed. The user is
* responsible for invoking grpc_byte_buffer_destroy on the returned instance.*/
grpc_byte_buffer *grpc_raw_byte_buffer_create(gpr_slice *slices,
size_t nslices);
/** Returns a *compressed* RAW byte buffer instance over the given slices (up to
* \a nslices). The \a compression argument defines the compression algorithm
* used to generate the data in \a slices.
*
* Increases the reference count for all \a slices processed. The user is
* responsible for invoking grpc_byte_buffer_destroy on the returned instance.*/
grpc_byte_buffer *grpc_raw_compressed_byte_buffer_create(
gpr_slice *slices, size_t nslices, grpc_compression_algorithm compression);
/** Copies input byte buffer \a bb.
*
* Increases the reference count of all the source slices. The user is
* responsible for calling grpc_byte_buffer_destroy over the returned copy. */
grpc_byte_buffer *grpc_byte_buffer_copy(grpc_byte_buffer *bb);
/** Returns the size of the given byte buffer, in bytes. */
size_t grpc_byte_buffer_length(grpc_byte_buffer *bb);
/** Destroys \a byte_buffer deallocating all its memory. */
void grpc_byte_buffer_destroy(grpc_byte_buffer *byte_buffer);
/** Reader for byte buffers. Iterates over slices in the byte buffer */
struct grpc_byte_buffer_reader;
typedef struct grpc_byte_buffer_reader grpc_byte_buffer_reader;
/** Initialize \a reader to read over \a buffer */
void grpc_byte_buffer_reader_init(grpc_byte_buffer_reader *reader,
grpc_byte_buffer *buffer);
/** Cleanup and destroy \a reader */
void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader *reader);
/** Updates \a slice with the next piece of data from from \a reader and returns
* 1. Returns 0 at the end of the stream. Caller is responsible for calling
* gpr_slice_unref on the result. */
int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader *reader,
gpr_slice *slice);
/** Merge all data from \a reader into single slice */
gpr_slice grpc_byte_buffer_reader_readall(grpc_byte_buffer_reader *reader);
/** Returns a RAW byte buffer instance from the output of \a reader. */
grpc_byte_buffer *grpc_raw_byte_buffer_from_reader(
grpc_byte_buffer_reader *reader);
#ifdef __cplusplus
}
#endif
#include <grpc/impl/codegen/byte_buffer.h>
#endif /* GRPC_BYTE_BUFFER_H */

@ -59,15 +59,15 @@ enum census_features {
* census_initialize() will return a non-zero value. It is an error to call
* census_initialize() more than once (without an intervening
* census_shutdown()). */
int census_initialize(int features);
void census_shutdown(void);
CENSUS_API int census_initialize(int features);
CENSUS_API void census_shutdown(void);
/** Return the features supported by the current census implementation (not all
* features will be available on all platforms). */
int census_supported(void);
CENSUS_API int census_supported(void);
/** Return the census features currently enabled. */
int census_enabled(void);
CENSUS_API int census_enabled(void);
/**
Context is a handle used by census to represent the current tracing and
@ -90,8 +90,8 @@ typedef struct census_context census_context;
*
* TODO(aveitch): determine how best to communicate required/max buffer size
* so caller doesn't have to guess. */
size_t census_context_serialize(const census_context *context, char *buffer,
size_t buf_size);
CENSUS_API size_t census_context_serialize(const census_context *context,
char *buffer, size_t buf_size);
/* Distributed traces can have a number of options. */
enum census_trace_mask_values {
@ -101,10 +101,10 @@ enum census_trace_mask_values {
/** Get the current trace mask associated with this context. The value returned
will be the logical or of census_trace_mask_values values. */
int census_trace_mask(const census_context *context);
CENSUS_API int census_trace_mask(const census_context *context);
/** Set the trace mask associated with a context. */
void census_set_trace_mask(int trace_mask);
CENSUS_API void census_set_trace_mask(int trace_mask);
/* The concept of "operation" is a fundamental concept for Census. In an RPC
system, and operation typcially represents a single RPC, or a significant
@ -152,7 +152,7 @@ typedef struct {
@return A timestamp representing the operation start time.
*/
census_timestamp census_start_rpc_op_timestamp(void);
CENSUS_API census_timestamp census_start_rpc_op_timestamp(void);
/**
Represent functions to map RPC name ID to service/method names. Census
@ -204,7 +204,7 @@ typedef struct {
@return A new census context.
*/
census_context *census_start_client_rpc_op(
CENSUS_API census_context *census_start_client_rpc_op(
const census_context *context, int64_t rpc_name_id,
const census_rpc_name_info *rpc_name_info, const char *peer, int trace_mask,
const census_timestamp *start_time);
@ -212,7 +212,8 @@ census_context *census_start_client_rpc_op(
/**
Add peer information to a context representing a client RPC operation.
*/
void census_set_rpc_client_peer(census_context *context, const char *peer);
CENSUS_API void census_set_rpc_client_peer(census_context *context,
const char *peer);
/**
Start a server RPC operation. Returns a new context to be used in future
@ -232,7 +233,7 @@ void census_set_rpc_client_peer(census_context *context, const char *peer);
@return A new census context.
*/
census_context *census_start_server_rpc_op(
CENSUS_API census_context *census_start_server_rpc_op(
const char *buffer, int64_t rpc_name_id,
const census_rpc_name_info *rpc_name_info, const char *peer, int trace_mask,
census_timestamp *start_time);
@ -262,8 +263,9 @@ census_context *census_start_server_rpc_op(
@return A new census context.
*/
census_context *census_start_op(census_context *context, const char *family,
const char *name, int trace_mask);
CENSUS_API census_context *census_start_op(census_context *context,
const char *family, const char *name,
int trace_mask);
/**
End an operation started by any of the census_start_*_op*() calls. The
@ -274,7 +276,7 @@ census_context *census_start_op(census_context *context, const char *family,
@param status status associated with the operation. Not interpreted by
census.
*/
void census_end_op(census_context *context, int status);
CENSUS_API void census_end_op(census_context *context, int status);
#define CENSUS_TRACE_RECORD_START_OP ((uint32_t)0)
#define CENSUS_TRACE_RECORD_END_OP ((uint32_t)1)
@ -286,8 +288,8 @@ void census_end_op(census_context *context, int status);
@param buffer Pointer to buffer to use
@param n Number of bytes in buffer
*/
void census_trace_print(census_context *context, uint32_t type,
const char *buffer, size_t n);
CENSUS_API void census_trace_print(census_context *context, uint32_t type,
const char *buffer, size_t n);
/** Trace record. */
typedef struct {
@ -308,7 +310,7 @@ typedef struct {
while scanning is ongoing.
@returns 0 on success, non-zero on failure (e.g. if a scan is already ongoing)
*/
int census_trace_scan_start(int consume);
CENSUS_API int census_trace_scan_start(int consume);
/** Get a trace record. The data pointed to by the trace buffer is guaranteed
stable until the next census_get_trace_record() call (if the consume
@ -319,10 +321,10 @@ int census_trace_scan_start(int consume);
census_trace_scan_start()), 0 if there is no more trace data (and
trace_record will not be modified) or 1 otherwise.
*/
int census_get_trace_record(census_trace_record *trace_record);
CENSUS_API int census_get_trace_record(census_trace_record *trace_record);
/** End a scan previously started by census_trace_scan_start() */
void census_trace_scan_end();
CENSUS_API void census_trace_scan_end();
/* A Census tag set is a collection of key:value string pairs; these form the
basis against which Census metrics will be recorded. Keys are unique within
@ -392,16 +394,16 @@ typedef struct {
tag set and status of the tags used in its creation.
@return A new, valid census_tag_set.
*/
census_tag_set *census_tag_set_create(
CENSUS_API census_tag_set *census_tag_set_create(
const census_tag_set *base, const census_tag *tags, int ntags,
census_tag_set_create_status const **status);
/* Destroy a tag set created by census_tag_set_create(). Once this function
has been called, the tag set cannot be reused. */
void census_tag_set_destroy(census_tag_set *tags);
CENSUS_API void census_tag_set_destroy(census_tag_set *tags);
/* Get a pointer to the original status from the creation of this tag set. */
const census_tag_set_create_status *census_tag_set_get_create_status(
CENSUS_API const census_tag_set_create_status *census_tag_set_get_create_status(
const census_tag_set *tags);
/* Structure used for tag set iteration. API clients should not use or
@ -416,18 +418,19 @@ typedef struct {
/* Initialize a tag set iterator. Must be called before first use of the
iterator. */
void census_tag_set_initialize_iterator(const census_tag_set *tags,
census_tag_set_iterator *iterator);
CENSUS_API void census_tag_set_initialize_iterator(
const census_tag_set *tags, census_tag_set_iterator *iterator);
/* Get the contents of the "next" tag in the tag set. If there are no more
tags in the tag set, returns 0 (and 'tag' contents will be unchanged),
otherwise returns 1. */
int census_tag_set_next_tag(census_tag_set_iterator *iterator, census_tag *tag);
CENSUS_API int census_tag_set_next_tag(census_tag_set_iterator *iterator,
census_tag *tag);
/* Get a tag by its key. Returns 0 if the key is not present in the tag
set. */
int census_tag_set_get_tag_by_key(const census_tag_set *tags, const char *key,
census_tag *tag);
CENSUS_API int census_tag_set_get_tag_by_key(const census_tag_set *tags,
const char *key, census_tag *tag);
/* Tag set encode/decode functionality. These functionas are intended
for use by RPC systems only, for purposes of transmitting/receiving tag
@ -449,17 +452,19 @@ int census_tag_set_get_tag_by_key(const census_tag_set *tags, const char *key,
[buffer, buffer + *print_buf_size) and binary tags into
[returned-ptr, returned-ptr + *bin_buf_size) (and the return value
should be buffer + *print_buf_size) */
char *census_tag_set_encode(const census_tag_set *tags, char *buffer,
size_t buf_size, size_t *print_buf_size,
size_t *bin_buf_size);
CENSUS_API char *census_tag_set_encode(const census_tag_set *tags, char *buffer,
size_t buf_size, size_t *print_buf_size,
size_t *bin_buf_size);
/* Decode tag set buffers encoded with census_tag_set_encode_*(). Returns NULL
if there is an error in parsing either buffer. */
census_tag_set *census_tag_set_decode(const char *buffer, size_t size,
const char *bin_buffer, size_t bin_size);
CENSUS_API census_tag_set *census_tag_set_decode(const char *buffer,
size_t size,
const char *bin_buffer,
size_t bin_size);
/* Get a contexts tag set. */
census_tag_set *census_context_tag_set(census_context *context);
CENSUS_API census_tag_set *census_context_tag_set(census_context *context);
/* Core stats collection API's. The following concepts are used:
* Aggregation: A collection of values. Census supports the following
@ -490,8 +495,8 @@ typedef struct {
} census_value;
/* Record new usage values against the given context. */
void census_record_values(census_context *context, census_value *values,
size_t nvalues);
CENSUS_API void census_record_values(census_context *context,
census_value *values, size_t nvalues);
/** Type representing a particular aggregation */
typedef struct census_aggregation_ops census_aggregation_ops;
@ -521,24 +526,25 @@ typedef struct census_view census_view;
@return A new census view
*/
census_view *census_view_create(uint32_t metric_id, const census_tag_set *tags,
const census_aggregation *aggregations,
size_t naggregations);
CENSUS_API census_view *census_view_create(
uint32_t metric_id, const census_tag_set *tags,
const census_aggregation *aggregations, size_t naggregations);
/** Destroy a previously created view. */
void census_view_delete(census_view *view);
CENSUS_API void census_view_delete(census_view *view);
/** Metric ID associated with a view */
size_t census_view_metric(const census_view *view);
CENSUS_API size_t census_view_metric(const census_view *view);
/** Number of aggregations associated with view. */
size_t census_view_naggregations(const census_view *view);
CENSUS_API size_t census_view_naggregations(const census_view *view);
/** Get tags associated with view. */
const census_tag_set *census_view_tags(const census_view *view);
CENSUS_API const census_tag_set *census_view_tags(const census_view *view);
/** Get aggregation descriptors associated with a view. */
const census_aggregation *census_view_aggregrations(const census_view *view);
CENSUS_API const census_aggregation *census_view_aggregrations(
const census_view *view);
/** Holds all the aggregation data for a particular view instantiation. Forms
part of the data returned by census_view_data(). */
@ -557,10 +563,11 @@ typedef struct {
@param view View from which to get data.
@return Full set of data for all aggregations for the view.
*/
const census_view_data *census_view_get_data(const census_view *view);
CENSUS_API const census_view_data *census_view_get_data(
const census_view *view);
/** Reset all view data to zero for the specified view */
void census_view_reset(census_view *view);
CENSUS_API void census_view_reset(census_view *view);
#ifdef __cplusplus
}

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -36,67 +36,43 @@
#include <stdlib.h>
#include <grpc/support/port_platform.h>
#include <grpc/impl/codegen/port_platform.h>
#include <grpc/impl/codegen/compression_types.h>
#ifdef __cplusplus
extern "C" {
#endif
/** To be used in channel arguments */
#define GRPC_COMPRESSION_ALGORITHM_ARG "grpc.compression_algorithm"
#define GRPC_COMPRESSION_ALGORITHM_STATE_ARG "grpc.compression_algorithm_state"
/* The various compression algorithms supported by GRPC */
typedef enum {
GRPC_COMPRESS_NONE = 0,
GRPC_COMPRESS_DEFLATE,
GRPC_COMPRESS_GZIP,
/* TODO(ctiller): snappy */
GRPC_COMPRESS_ALGORITHMS_COUNT
} grpc_compression_algorithm;
typedef enum {
GRPC_COMPRESS_LEVEL_NONE = 0,
GRPC_COMPRESS_LEVEL_LOW,
GRPC_COMPRESS_LEVEL_MED,
GRPC_COMPRESS_LEVEL_HIGH,
GRPC_COMPRESS_LEVEL_COUNT
} grpc_compression_level;
typedef struct grpc_compression_options {
uint32_t enabled_algorithms_bitset; /**< All algs are enabled by default */
grpc_compression_algorithm default_compression_algorithm; /**< for channel */
} grpc_compression_options;
/** Parses the first \a name_length bytes of \a name as a
* grpc_compression_algorithm instance, updating \a algorithm. Returns 1 upon
* success, 0 otherwise. */
int grpc_compression_algorithm_parse(const char *name, size_t name_length,
grpc_compression_algorithm *algorithm);
GRPC_API int grpc_compression_algorithm_parse(
const char *name, size_t name_length,
grpc_compression_algorithm *algorithm);
/** Updates \a name with the encoding name corresponding to a valid \a
* algorithm. Returns 1 upon success, 0 otherwise. */
int grpc_compression_algorithm_name(grpc_compression_algorithm algorithm,
char **name);
GRPC_API int grpc_compression_algorithm_name(
grpc_compression_algorithm algorithm, char **name);
/** Returns the compression algorithm corresponding to \a level.
*
* It abort()s for unknown levels . */
grpc_compression_algorithm grpc_compression_algorithm_for_level(
grpc_compression_level level);
GRPC_API grpc_compression_algorithm
grpc_compression_algorithm_for_level(grpc_compression_level level);
void grpc_compression_options_init(grpc_compression_options *opts);
GRPC_API void grpc_compression_options_init(grpc_compression_options *opts);
/** Mark \a algorithm as enabled in \a opts. */
void grpc_compression_options_enable_algorithm(
GRPC_API void grpc_compression_options_enable_algorithm(
grpc_compression_options *opts, grpc_compression_algorithm algorithm);
/** Mark \a algorithm as disabled in \a opts. */
void grpc_compression_options_disable_algorithm(
GRPC_API void grpc_compression_options_disable_algorithm(
grpc_compression_options *opts, grpc_compression_algorithm algorithm);
/** Returns true if \a algorithm is marked as enabled in \a opts. */
int grpc_compression_options_is_algorithm_enabled(
GRPC_API int grpc_compression_options_is_algorithm_enabled(
const grpc_compression_options *opts, grpc_compression_algorithm algorithm);
#ifdef __cplusplus

@ -40,6 +40,9 @@
#include <grpc/byte_buffer.h>
#include <grpc/support/slice.h>
#include <grpc/support/time.h>
#include <grpc/impl/codegen/connectivity_state.h>
#include <grpc/impl/codegen/propagation_bits.h>
#include <grpc/impl/codegen/grpc_types.h>
#ifdef __cplusplus
extern "C" {
@ -52,348 +55,11 @@ extern "C" {
* functionality lives in grpc_security.h.
*/
/** Completion Queues enable notification of the completion of asynchronous
actions. */
typedef struct grpc_completion_queue grpc_completion_queue;
/** An alarm associated with a completion queue. */
typedef struct grpc_alarm grpc_alarm;
/** The Channel interface allows creation of Call objects. */
typedef struct grpc_channel grpc_channel;
/** A server listens to some port and responds to request calls */
typedef struct grpc_server grpc_server;
/** A Call represents an RPC. When created, it is in a configuration state
allowing properties to be set until it is invoked. After invoke, the Call
can have messages written to it and read from it. */
typedef struct grpc_call grpc_call;
/** Type specifier for grpc_arg */
typedef enum {
GRPC_ARG_STRING,
GRPC_ARG_INTEGER,
GRPC_ARG_POINTER
} grpc_arg_type;
/** A single argument... each argument has a key and a value
A note on naming keys:
Keys are namespaced into groups, usually grouped by library, and are
keys for module XYZ are named XYZ.key1, XYZ.key2, etc. Module names must
be restricted to the regex [A-Za-z][_A-Za-z0-9]{,15}.
Key names must be restricted to the regex [A-Za-z][_A-Za-z0-9]{,47}.
GRPC core library keys are prefixed by grpc.
Library authors are strongly encouraged to \#define symbolic constants for
their keys so that it's possible to change them in the future. */
typedef struct {
grpc_arg_type type;
char *key;
union {
char *string;
int integer;
struct {
void *p;
void *(*copy)(void *p);
void (*destroy)(void *p);
} pointer;
} value;
} grpc_arg;
/** An array of arguments that can be passed around.
Used to set optional channel-level configuration.
These configuration options are modelled as key-value pairs as defined
by grpc_arg; keys are strings to allow easy backwards-compatible extension
by arbitrary parties.
All evaluation is performed at channel creation time (i.e. the values in
this structure need only live through the creation invocation). */
typedef struct {
size_t num_args;
grpc_arg *args;
} grpc_channel_args;
/* Channel argument keys: */
/** Enable census for tracing and stats collection */
#define GRPC_ARG_ENABLE_CENSUS "grpc.census"
/** Maximum number of concurrent incoming streams to allow on a http2
connection */
#define GRPC_ARG_MAX_CONCURRENT_STREAMS "grpc.max_concurrent_streams"
/** Maximum message length that the channel can receive */
#define GRPC_ARG_MAX_MESSAGE_LENGTH "grpc.max_message_length"
/** Initial sequence number for http2 transports */
#define GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER \
"grpc.http2.initial_sequence_number"
/** Amount to read ahead on individual streams. Defaults to 64kb, larger
values can help throughput on high-latency connections.
NOTE: at some point we'd like to auto-tune this, and this parameter
will become a no-op. */
#define GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES "grpc.http2.lookahead_bytes"
/** How much memory to use for hpack decoding */
#define GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER \
"grpc.http2.hpack_table_size.decoder"
/** How much memory to use for hpack encoding */
#define GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_ENCODER \
"grpc.http2.hpack_table_size.encoder"
/** Default authority to pass if none specified on call construction */
#define GRPC_ARG_DEFAULT_AUTHORITY "grpc.default_authority"
/** Primary user agent: goes at the start of the user-agent metadata
sent on each request */
#define GRPC_ARG_PRIMARY_USER_AGENT_STRING "grpc.primary_user_agent"
/** Secondary user agent: goes at the end of the user-agent metadata
sent on each request */
#define GRPC_ARG_SECONDARY_USER_AGENT_STRING "grpc.secondary_user_agent"
/* The caller of the secure_channel_create functions may override the target
name used for SSL host name checking using this channel argument which is of
type GRPC_ARG_STRING. This *should* be used for testing only.
If this argument is not specified, the name used for SSL host name checking
will be the target parameter (assuming that the secure channel is an SSL
channel). If this parameter is specified and the underlying is not an SSL
channel, it will just be ignored. */
#define GRPC_SSL_TARGET_NAME_OVERRIDE_ARG "grpc.ssl_target_name_override"
/** Connectivity state of a channel. */
typedef enum {
/** channel is idle */
GRPC_CHANNEL_IDLE,
/** channel is connecting */
GRPC_CHANNEL_CONNECTING,
/** channel is ready for work */
GRPC_CHANNEL_READY,
/** channel has seen a failure but expects to recover */
GRPC_CHANNEL_TRANSIENT_FAILURE,
/** channel has seen a failure that it cannot recover from */
GRPC_CHANNEL_FATAL_FAILURE
} grpc_connectivity_state;
/** 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.
Receiving any other value listed here is an indication of a bug in the
caller. */
typedef enum grpc_call_error {
/** everything went ok */
GRPC_CALL_OK = 0,
/** something failed, we don't know what */
GRPC_CALL_ERROR,
/** this method is not available on the server */
GRPC_CALL_ERROR_NOT_ON_SERVER,
/** this method is not available on the client */
GRPC_CALL_ERROR_NOT_ON_CLIENT,
/** this method must be called before server_accept */
GRPC_CALL_ERROR_ALREADY_ACCEPTED,
/** this method must be called before invoke */
GRPC_CALL_ERROR_ALREADY_INVOKED,
/** this method must be called after invoke */
GRPC_CALL_ERROR_NOT_INVOKED,
/** this call is already finished
(writes_done or write_status has already been called) */
GRPC_CALL_ERROR_ALREADY_FINISHED,
/** there is already an outstanding read/write operation on the call */
GRPC_CALL_ERROR_TOO_MANY_OPERATIONS,
/** the flags value was illegal for this call */
GRPC_CALL_ERROR_INVALID_FLAGS,
/** invalid metadata was passed to this call */
GRPC_CALL_ERROR_INVALID_METADATA,
/** invalid message was passed to this call */
GRPC_CALL_ERROR_INVALID_MESSAGE,
/** completion queue for notification has not been registered with the
server */
GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE,
/** this batch of operations leads to more operations than allowed */
GRPC_CALL_ERROR_BATCH_TOO_BIG
} grpc_call_error;
/* Write Flags: */
/** Hint that the write may be buffered and need not go out on the wire
immediately. GRPC is free to buffer the message until the next non-buffered
write, or until writes_done, but it need not buffer completely or at all. */
#define GRPC_WRITE_BUFFER_HINT (0x00000001u)
/** Force compression to be disabled for a particular write
(start_write/add_metadata). Illegal on invoke/accept. */
#define GRPC_WRITE_NO_COMPRESS (0x00000002u)
/** Mask of all valid flags. */
#define GRPC_WRITE_USED_MASK (GRPC_WRITE_BUFFER_HINT | GRPC_WRITE_NO_COMPRESS)
/** A single metadata element */
typedef struct grpc_metadata {
const char *key;
const char *value;
size_t value_length;
uint32_t flags;
/** The following fields are reserved for grpc internal use.
There is no need to initialize them, and they will be set to garbage
during calls to grpc. */
struct {
void *obfuscated[4];
} internal_data;
} grpc_metadata;
/** The type of completion (for grpc_event) */
typedef enum grpc_completion_type {
/** Shutting down */
GRPC_QUEUE_SHUTDOWN,
/** No event before timeout */
GRPC_QUEUE_TIMEOUT,
/** Operation completion */
GRPC_OP_COMPLETE
} grpc_completion_type;
/** The result of an operation.
Returned by a completion queue when the operation started with tag. */
typedef struct grpc_event {
/** The type of the completion. */
grpc_completion_type type;
/** non-zero if the operation was successful, 0 upon failure.
Only GRPC_OP_COMPLETE can succeed or fail. */
int success;
/** The tag passed to grpc_call_start_batch etc to start this operation.
Only GRPC_OP_COMPLETE has a tag. */
void *tag;
} grpc_event;
typedef struct {
size_t count;
size_t capacity;
grpc_metadata *metadata;
} grpc_metadata_array;
void grpc_metadata_array_init(grpc_metadata_array *array);
void grpc_metadata_array_destroy(grpc_metadata_array *array);
typedef struct {
char *method;
size_t method_capacity;
char *host;
size_t host_capacity;
gpr_timespec deadline;
void *reserved;
} grpc_call_details;
void grpc_call_details_init(grpc_call_details *details);
void grpc_call_details_destroy(grpc_call_details *details);
typedef enum {
/** Send initial metadata: one and only one instance MUST be sent for each
call, unless the call was cancelled - in which case this can be skipped.
This op completes after all bytes of metadata have been accepted by
outgoing flow control. */
GRPC_OP_SEND_INITIAL_METADATA = 0,
/** Send a message: 0 or more of these operations can occur for each call.
This op completes after all bytes for the message have been accepted by
outgoing flow control. */
GRPC_OP_SEND_MESSAGE,
/** Send a close from the client: one and only one instance MUST be sent from
the client, unless the call was cancelled - in which case this can be
skipped.
This op completes after all bytes for the call (including the close)
have passed outgoing flow control. */
GRPC_OP_SEND_CLOSE_FROM_CLIENT,
/** Send status from the server: one and only one instance MUST be sent from
the server unless the call was cancelled - in which case this can be
skipped.
This op completes after all bytes for the call (including the status)
have passed outgoing flow control. */
GRPC_OP_SEND_STATUS_FROM_SERVER,
/** Receive initial metadata: one and only one MUST be made on the client,
must not be made on the server.
This op completes after all initial metadata has been read from the
peer. */
GRPC_OP_RECV_INITIAL_METADATA,
/** Receive a message: 0 or more of these operations can occur for each call.
This op completes after all bytes of the received message have been
read, or after a half-close has been received on this call. */
GRPC_OP_RECV_MESSAGE,
/** Receive status on the client: one and only one must be made on the client.
This operation always succeeds, meaning ops paired with this operation
will also appear to succeed, even though they may not have. In that case
the status will indicate some failure.
This op completes after all activity on the call has completed. */
GRPC_OP_RECV_STATUS_ON_CLIENT,
/** Receive close on the server: one and only one must be made on the
server.
This op completes after the close has been received by the server. */
GRPC_OP_RECV_CLOSE_ON_SERVER
} grpc_op_type;
/** Operation data: one field for each op type (except SEND_CLOSE_FROM_CLIENT
which has no arguments) */
typedef struct grpc_op {
/** Operation type, as defined by grpc_op_type */
grpc_op_type op;
/** Write flags bitset for grpc_begin_messages */
uint32_t flags;
/** Reserved for future usage */
void *reserved;
union {
/** Reserved for future usage */
struct {
void *reserved[8];
} reserved;
struct {
size_t count;
grpc_metadata *metadata;
} send_initial_metadata;
grpc_byte_buffer *send_message;
struct {
size_t trailing_metadata_count;
grpc_metadata *trailing_metadata;
grpc_status_code status;
const char *status_details;
} send_status_from_server;
/** ownership of the array is with the caller, but ownership of the elements
stays with the call object (ie key, value members are owned by the call
object, recv_initial_metadata->array is owned by the caller).
After the operation completes, call grpc_metadata_array_destroy on this
value, or reuse it in a future op. */
grpc_metadata_array *recv_initial_metadata;
/** ownership of the byte buffer is moved to the caller; the caller must
call grpc_byte_buffer_destroy on this value, or reuse it in a future op.
*/
grpc_byte_buffer **recv_message;
struct {
/** ownership of the array is with the caller, but ownership of the
elements stays with the call object (ie key, value members are owned
by the call object, trailing_metadata->array is owned by the caller).
After the operation completes, call grpc_metadata_array_destroy on
this
value, or reuse it in a future op. */
grpc_metadata_array *trailing_metadata;
grpc_status_code *status;
/** status_details is a buffer owned by the application before the op
completes and after the op has completed. During the operation
status_details may be reallocated to a size larger than
*status_details_capacity, in which case *status_details_capacity will
be updated with the new array capacity.
Pre-allocating space:
size_t my_capacity = 8;
char *my_details = gpr_malloc(my_capacity);
x.status_details = &my_details;
x.status_details_capacity = &my_capacity;
Not pre-allocating space:
size_t my_capacity = 0;
char *my_details = NULL;
x.status_details = &my_details;
x.status_details_capacity = &my_capacity;
After the call:
gpr_free(my_details); */
char **status_details;
size_t *status_details_capacity;
} recv_status_on_client;
struct {
/** out argument, set to 1 if the call failed in any way (seen as a
cancellation on the server), or 0 if the call succeeded */
int *cancelled;
} recv_close_on_server;
} data;
} grpc_op;
GRPC_API void grpc_metadata_array_init(grpc_metadata_array *array);
GRPC_API void grpc_metadata_array_destroy(grpc_metadata_array *array);
GRPC_API void grpc_call_details_init(grpc_call_details *details);
GRPC_API void grpc_call_details_destroy(grpc_call_details *details);
/** Registers a plugin to be initialized and destroyed with the library.
@ -403,27 +69,7 @@ typedef struct grpc_op {
(and hence so will \a init and \a destroy).
It is safe to pass NULL to either argument. Plugins are destroyed in
the reverse order they were initialized. */
void grpc_register_plugin(void (*init)(void), void (*destroy)(void));
/* Propagation bits: this can be bitwise or-ed to form propagation_mask for
* grpc_call */
/** Propagate deadline */
#define GRPC_PROPAGATE_DEADLINE ((uint32_t)1)
/** Propagate census context */
#define GRPC_PROPAGATE_CENSUS_STATS_CONTEXT ((uint32_t)2)
#define GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT ((uint32_t)4)
/** Propagate cancellation */
#define GRPC_PROPAGATE_CANCELLATION ((uint32_t)8)
/* Default propagation mask: clients of the core API are encouraged to encode
deltas from this in their implementations... ie write:
GRPC_PROPAGATE_DEFAULTS & ~GRPC_PROPAGATE_DEADLINE to disable deadline
propagation. Doing so gives flexibility in the future to define new
propagation types that are default inherited or not. */
#define GRPC_PROPAGATE_DEFAULTS \
((uint32_t)(( \
0xffff | GRPC_PROPAGATE_DEADLINE | GRPC_PROPAGATE_CENSUS_STATS_CONTEXT | \
GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT | GRPC_PROPAGATE_CANCELLATION)))
GRPC_API void grpc_register_plugin(void (*init)(void), void (*destroy)(void));
/** Initialize the grpc library.
@ -431,7 +77,7 @@ void grpc_register_plugin(void (*init)(void), void (*destroy)(void));
(To avoid overhead, little checking is done, and some things may work. We
do not warrant that they will continue to do so in future revisions of this
library). */
void grpc_init(void);
GRPC_API void grpc_init(void);
/** Shut down the grpc library.
@ -439,13 +85,13 @@ void grpc_init(void);
executing within the grpc library.
Prior to calling, all application owned grpc objects must have been
destroyed. */
void grpc_shutdown(void);
GRPC_API void grpc_shutdown(void);
/** Return a string representing the current version of grpc */
const char *grpc_version_string(void);
GRPC_API const char *grpc_version_string(void);
/** Create a completion queue */
grpc_completion_queue *grpc_completion_queue_create(void *reserved);
GRPC_API grpc_completion_queue *grpc_completion_queue_create(void *reserved);
/** Blocks until an event is available, the completion queue is being shut down,
or deadline is reached.
@ -455,8 +101,9 @@ grpc_completion_queue *grpc_completion_queue_create(void *reserved);
Callers must not call grpc_completion_queue_next and
grpc_completion_queue_pluck simultaneously on the same completion queue. */
grpc_event grpc_completion_queue_next(grpc_completion_queue *cq,
gpr_timespec deadline, void *reserved);
GRPC_API grpc_event grpc_completion_queue_next(grpc_completion_queue *cq,
gpr_timespec deadline,
void *reserved);
/** Blocks until an event with tag 'tag' is available, the completion queue is
being shutdown or deadline is reached.
@ -469,8 +116,9 @@ grpc_event grpc_completion_queue_next(grpc_completion_queue *cq,
Completion queues support a maximum of GRPC_MAX_COMPLETION_QUEUE_PLUCKERS
concurrently executing plucks at any time. */
grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cq, void *tag,
gpr_timespec deadline, void *reserved);
GRPC_API grpc_event
grpc_completion_queue_pluck(grpc_completion_queue *cq, void *tag,
gpr_timespec deadline, void *reserved);
/** Maximum number of outstanding grpc_completion_queue_pluck executions per
completion queue */
@ -483,11 +131,11 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cq, void *tag,
After calling this function applications should ensure that no
NEW work is added to be published on this completion queue. */
void grpc_completion_queue_shutdown(grpc_completion_queue *cq);
GRPC_API void grpc_completion_queue_shutdown(grpc_completion_queue *cq);
/** Destroy a completion queue. The caller must ensure that the queue is
drained and no threads are executing grpc_completion_queue_next */
void grpc_completion_queue_destroy(grpc_completion_queue *cq);
GRPC_API void grpc_completion_queue_destroy(grpc_completion_queue *cq);
/** Create a completion queue alarm instance associated to \a cq.
*
@ -495,26 +143,27 @@ void grpc_completion_queue_destroy(grpc_completion_queue *cq);
* grpc_alarm_cancel), an event with tag \a tag will be added to \a cq. If the
* alarm expired, the event's success bit will be true, false otherwise (ie,
* upon cancellation). */
grpc_alarm *grpc_alarm_create(grpc_completion_queue *cq, gpr_timespec deadline,
void *tag);
GRPC_API grpc_alarm *grpc_alarm_create(grpc_completion_queue *cq,
gpr_timespec deadline, void *tag);
/** Cancel a completion queue alarm. Calling this function over an alarm that
* has already fired has no effect. */
void grpc_alarm_cancel(grpc_alarm *alarm);
GRPC_API void grpc_alarm_cancel(grpc_alarm *alarm);
/** Destroy the given completion queue alarm, cancelling it in the process. */
void grpc_alarm_destroy(grpc_alarm *alarm);
GRPC_API void grpc_alarm_destroy(grpc_alarm *alarm);
/** Check the connectivity state of a channel. */
grpc_connectivity_state grpc_channel_check_connectivity_state(
grpc_channel *channel, int try_to_connect);
GRPC_API grpc_connectivity_state
grpc_channel_check_connectivity_state(grpc_channel *channel,
int try_to_connect);
/** Watch for a change in connectivity state.
Once the channel connectivity state is different from last_observed_state,
tag will be enqueued on cq with success=1.
If deadline expires BEFORE the state is changed, tag will be enqueued on cq
with success=0. */
void grpc_channel_watch_connectivity_state(
GRPC_API void grpc_channel_watch_connectivity_state(
grpc_channel *channel, grpc_connectivity_state last_observed_state,
gpr_timespec deadline, grpc_completion_queue *cq, void *tag);
@ -524,24 +173,24 @@ void grpc_channel_watch_connectivity_state(
If parent_call is non-NULL, it must be a server-side call. It will be used
to propagate properties from the server call to this new client call.
*/
grpc_call *grpc_channel_create_call(grpc_channel *channel,
grpc_call *parent_call,
uint32_t propagation_mask,
grpc_completion_queue *completion_queue,
const char *method, const char *host,
gpr_timespec deadline, void *reserved);
GRPC_API grpc_call *grpc_channel_create_call(
grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask,
grpc_completion_queue *completion_queue, const char *method,
const char *host, gpr_timespec deadline, void *reserved);
/** Ping the channels peer (load balanced channels will select one sub-channel
to ping); if the channel is not connected, posts a failed. */
void grpc_channel_ping(grpc_channel *channel, grpc_completion_queue *cq,
void *tag, void *reserved);
GRPC_API void grpc_channel_ping(grpc_channel *channel,
grpc_completion_queue *cq, void *tag,
void *reserved);
/** Pre-register a method/host pair on a channel. */
void *grpc_channel_register_call(grpc_channel *channel, const char *method,
const char *host, void *reserved);
GRPC_API void *grpc_channel_register_call(grpc_channel *channel,
const char *method, const char *host,
void *reserved);
/** Create a call given a handle returned from grpc_channel_register_call */
grpc_call *grpc_channel_create_registered_call(
GRPC_API grpc_call *grpc_channel_create_registered_call(
grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask,
grpc_completion_queue *completion_queue, void *registered_call_handle,
gpr_timespec deadline, void *reserved);
@ -557,8 +206,9 @@ grpc_call *grpc_channel_create_registered_call(
needs to be synchronized. As an optimization, you may synchronize batches
containing just send operations independently from batches containing just
receive operations. */
grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops,
size_t nops, void *tag, void *reserved);
GRPC_API grpc_call_error grpc_call_start_batch(grpc_call *call,
const grpc_op *ops, size_t nops,
void *tag, void *reserved);
/** Returns a newly allocated string representing the endpoint to which this
call is communicating with. The string is in the uri format accepted by
@ -568,38 +218,36 @@ grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops,
WARNING: this value is never authenticated or subject to any security
related code. It must not be used for any authentication related
functionality. Instead, use grpc_auth_context. */
char *grpc_call_get_peer(grpc_call *call);
GRPC_API char *grpc_call_get_peer(grpc_call *call);
struct census_context;
/* Set census context for a call; Must be called before first call to
grpc_call_start_batch(). */
void grpc_census_call_set_context(grpc_call *call,
struct census_context *context);
GRPC_API void grpc_census_call_set_context(grpc_call *call,
struct census_context *context);
/* Retrieve the calls current census context. */
struct census_context *grpc_census_call_get_context(grpc_call *call);
GRPC_API struct census_context *grpc_census_call_get_context(grpc_call *call);
/** Return a newly allocated string representing the target a channel was
created for. */
char *grpc_channel_get_target(grpc_channel *channel);
GRPC_API char *grpc_channel_get_target(grpc_channel *channel);
/** Create a client channel to 'target'. Additional channel level configuration
MAY be provided by grpc_channel_args, though the expectation is that most
clients will want to simply pass NULL. See grpc_channel_args definition for
more on this. The data in 'args' need only live through the invocation of
this function. */
grpc_channel *grpc_insecure_channel_create(const char *target,
const grpc_channel_args *args,
void *reserved);
GRPC_API grpc_channel *grpc_insecure_channel_create(
const char *target, const grpc_channel_args *args, void *reserved);
/** Create a lame client: this client fails every operation attempted on it. */
grpc_channel *grpc_lame_client_channel_create(const char *target,
grpc_status_code error_code,
const char *error_message);
GRPC_API grpc_channel *grpc_lame_client_channel_create(
const char *target, grpc_status_code error_code, const char *error_message);
/** Close and destroy a grpc channel */
void grpc_channel_destroy(grpc_channel *channel);
GRPC_API void grpc_channel_destroy(grpc_channel *channel);
/* Error handling for grpc_call
Most grpc_call functions return a grpc_error. If the error is not GRPC_OK
@ -612,7 +260,7 @@ void grpc_channel_destroy(grpc_channel *channel);
THREAD-SAFETY grpc_call_cancel and grpc_call_cancel_with_status
are thread-safe, and can be called at any point before grpc_call_destroy
is called.*/
grpc_call_error grpc_call_cancel(grpc_call *call, void *reserved);
GRPC_API grpc_call_error grpc_call_cancel(grpc_call *call, void *reserved);
/** Called by clients to cancel an RPC on the server.
Can be called multiple times, from any thread.
@ -620,14 +268,13 @@ grpc_call_error grpc_call_cancel(grpc_call *call, void *reserved);
and description passed in.
Importantly, this function does not send status nor description to the
remote endpoint. */
grpc_call_error grpc_call_cancel_with_status(grpc_call *call,
grpc_status_code status,
const char *description,
void *reserved);
GRPC_API grpc_call_error
grpc_call_cancel_with_status(grpc_call *call, grpc_status_code status,
const char *description, void *reserved);
/** Destroy a call.
THREAD SAFETY: grpc_call_destroy is thread-compatible */
void grpc_call_destroy(grpc_call *call);
GRPC_API void grpc_call_destroy(grpc_call *call);
/** Request notification of a new call.
Once a call is received, a notification tagged with \a tag_new is added to
@ -637,11 +284,13 @@ void grpc_call_destroy(grpc_call *call);
to \a cq_bound_to_call.
Note that \a cq_for_notification must have been registered to the server via
\a grpc_server_register_completion_queue. */
grpc_call_error grpc_server_request_call(
grpc_server *server, grpc_call **call, grpc_call_details *details,
grpc_metadata_array *request_metadata,
grpc_completion_queue *cq_bound_to_call,
grpc_completion_queue *cq_for_notification, void *tag_new);
GRPC_API grpc_call_error
grpc_server_request_call(grpc_server *server, grpc_call **call,
grpc_call_details *details,
grpc_metadata_array *request_metadata,
grpc_completion_queue *cq_bound_to_call,
grpc_completion_queue *cq_for_notification,
void *tag_new);
/** Registers a method in the server.
Methods to this (host, method) pair will not be reported by
@ -650,13 +299,14 @@ grpc_call_error grpc_server_request_call(
registered_method (as returned by this function).
Must be called before grpc_server_start.
Returns NULL on failure. */
void *grpc_server_register_method(grpc_server *server, const char *method,
const char *host);
GRPC_API void *grpc_server_register_method(grpc_server *server,
const char *method,
const char *host);
/** Request notification of a new pre-registered call. 'cq_for_notification'
must have been registered to the server via
grpc_server_register_completion_queue. */
grpc_call_error grpc_server_request_registered_call(
GRPC_API grpc_call_error grpc_server_request_registered_call(
grpc_server *server, void *registered_method, grpc_call **call,
gpr_timespec *deadline, grpc_metadata_array *request_metadata,
grpc_byte_buffer **optional_payload,
@ -667,23 +317,25 @@ grpc_call_error grpc_server_request_registered_call(
be specified with args. If no additional configuration is needed, args can
be NULL. See grpc_channel_args for more. The data in 'args' need only live
through the invocation of this function. */
grpc_server *grpc_server_create(const grpc_channel_args *args, void *reserved);
GRPC_API grpc_server *grpc_server_create(const grpc_channel_args *args,
void *reserved);
/** Register a completion queue with the server. Must be done for any
notification completion queue that is passed to grpc_server_request_*_call
and to grpc_server_shutdown_and_notify. Must be performed prior to
grpc_server_start. */
void grpc_server_register_completion_queue(grpc_server *server,
grpc_completion_queue *cq,
void *reserved);
GRPC_API void grpc_server_register_completion_queue(grpc_server *server,
grpc_completion_queue *cq,
void *reserved);
/** Add a HTTP2 over plaintext over tcp listener.
Returns bound port number on success, 0 on failure.
REQUIRES: server not started */
int grpc_server_add_insecure_http2_port(grpc_server *server, const char *addr);
GRPC_API int grpc_server_add_insecure_http2_port(grpc_server *server,
const char *addr);
/** Start a server - tells all listeners to start listening */
void grpc_server_start(grpc_server *server);
GRPC_API void grpc_server_start(grpc_server *server);
/** Begin shutting down a server.
After completion, no new calls or connections will be admitted.
@ -692,18 +344,19 @@ void grpc_server_start(grpc_server *server);
Shutdown is idempotent, and all tags will be notified at once if multiple
grpc_server_shutdown_and_notify calls are made. 'cq' must have been
registered to this server via grpc_server_register_completion_queue. */
void grpc_server_shutdown_and_notify(grpc_server *server,
grpc_completion_queue *cq, void *tag);
GRPC_API void grpc_server_shutdown_and_notify(grpc_server *server,
grpc_completion_queue *cq,
void *tag);
/** Cancel all in-progress calls.
Only usable after shutdown. */
void grpc_server_cancel_all_calls(grpc_server *server);
GRPC_API void grpc_server_cancel_all_calls(grpc_server *server);
/** Destroy a server.
Shutdown must have completed beforehand (i.e. all tags generated by
grpc_server_shutdown_and_notify must have been received, and at least
one call to grpc_server_shutdown_and_notify must have been made). */
void grpc_server_destroy(grpc_server *server);
GRPC_API void grpc_server_destroy(grpc_server *server);
/** Enable or disable a tracer.
@ -713,17 +366,18 @@ void grpc_server_destroy(grpc_server *server);
Use of this function is not strictly thread-safe, but the
thread-safety issues raised by it should not be of concern. */
int grpc_tracer_set_enabled(const char *name, int enabled);
GRPC_API int grpc_tracer_set_enabled(const char *name, int enabled);
/** Check whether a metadata key is legal (will be accepted by core) */
int grpc_header_key_is_legal(const char *key, size_t length);
GRPC_API int grpc_header_key_is_legal(const char *key, size_t length);
/** Check whether a non-binary metadata value is legal (will be accepted by
core) */
int grpc_header_nonbin_value_is_legal(const char *value, size_t length);
GRPC_API int grpc_header_nonbin_value_is_legal(const char *value,
size_t length);
/** Check whether a metadata key corresponds to a binary value */
int grpc_is_binary_header(const char *key, size_t length);
GRPC_API int grpc_is_binary_header(const char *key, size_t length);
#ifdef __cplusplus
}

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -65,37 +65,39 @@ typedef struct grpc_auth_property {
} grpc_auth_property;
/* Returns NULL when the iterator is at the end. */
const grpc_auth_property *grpc_auth_property_iterator_next(
GRPC_API const grpc_auth_property *grpc_auth_property_iterator_next(
grpc_auth_property_iterator *it);
/* Iterates over the auth context. */
grpc_auth_property_iterator grpc_auth_context_property_iterator(
const grpc_auth_context *ctx);
GRPC_API grpc_auth_property_iterator
grpc_auth_context_property_iterator(const grpc_auth_context *ctx);
/* Gets the peer identity. Returns an empty iterator (first _next will return
NULL) if the peer is not authenticated. */
grpc_auth_property_iterator grpc_auth_context_peer_identity(
const grpc_auth_context *ctx);
GRPC_API grpc_auth_property_iterator
grpc_auth_context_peer_identity(const grpc_auth_context *ctx);
/* Finds a property in the context. May return an empty iterator (first _next
will return NULL) if no property with this name was found in the context. */
grpc_auth_property_iterator grpc_auth_context_find_properties_by_name(
const grpc_auth_context *ctx, const char *name);
GRPC_API grpc_auth_property_iterator
grpc_auth_context_find_properties_by_name(const grpc_auth_context *ctx,
const char *name);
/* Gets the name of the property that indicates the peer identity. Will return
NULL if the peer is not authenticated. */
const char *grpc_auth_context_peer_identity_property_name(
GRPC_API const char *grpc_auth_context_peer_identity_property_name(
const grpc_auth_context *ctx);
/* Returns 1 if the peer is authenticated, 0 otherwise. */
int grpc_auth_context_peer_is_authenticated(const grpc_auth_context *ctx);
GRPC_API int grpc_auth_context_peer_is_authenticated(
const grpc_auth_context *ctx);
/* Gets the auth context from the call. Caller needs to call
grpc_auth_context_release on the returned context. */
grpc_auth_context *grpc_call_auth_context(grpc_call *call);
GRPC_API grpc_auth_context *grpc_call_auth_context(grpc_call *call);
/* Releases the auth context returned from grpc_call_auth_context. */
void grpc_auth_context_release(grpc_auth_context *context);
GRPC_API void grpc_auth_context_release(grpc_auth_context *context);
/* --
The following auth context methods should only be called by a server metadata
@ -103,18 +105,20 @@ void grpc_auth_context_release(grpc_auth_context *context);
-- */
/* Add a property. */
void grpc_auth_context_add_property(grpc_auth_context *ctx, const char *name,
const char *value, size_t value_length);
GRPC_API void grpc_auth_context_add_property(grpc_auth_context *ctx,
const char *name,
const char *value,
size_t value_length);
/* Add a C string property. */
void grpc_auth_context_add_cstring_property(grpc_auth_context *ctx,
const char *name,
const char *value);
GRPC_API void grpc_auth_context_add_cstring_property(grpc_auth_context *ctx,
const char *name,
const char *value);
/* Sets the property name. Returns 1 if successful or 0 in case of failure
(which means that no property with this name exists). */
int grpc_auth_context_set_peer_identity_property_name(grpc_auth_context *ctx,
const char *name);
GRPC_API int grpc_auth_context_set_peer_identity_property_name(
grpc_auth_context *ctx, const char *name);
/* --- grpc_channel_credentials object. ---
@ -125,7 +129,7 @@ typedef struct grpc_channel_credentials grpc_channel_credentials;
/* Releases a channel credentials object.
The creator of the credentials object is responsible for its release. */
void grpc_channel_credentials_release(grpc_channel_credentials *creds);
GRPC_API void grpc_channel_credentials_release(grpc_channel_credentials *creds);
/* Environment variable that points to the google default application
credentials json key or refresh token. Used in the
@ -135,7 +139,7 @@ void grpc_channel_credentials_release(grpc_channel_credentials *creds);
/* Creates default credentials to connect to a google gRPC service.
WARNING: Do NOT use this credentials to connect to a non-google service as
this could result in an oauth2 token leak. */
grpc_channel_credentials *grpc_google_default_credentials_create(void);
GRPC_API grpc_channel_credentials *grpc_google_default_credentials_create(void);
/* Environment variable that points to the default SSL roots file. This file
must be a PEM encoded file with all the roots such as the one that can be
@ -143,6 +147,29 @@ grpc_channel_credentials *grpc_google_default_credentials_create(void);
#define GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR \
"GRPC_DEFAULT_SSL_ROOTS_FILE_PATH"
/* Results for the SSL roots override callback. */
typedef enum {
GRPC_SSL_ROOTS_OVERRIDE_OK,
GRPC_SSL_ROOTS_OVERRIDE_FAIL_PERMANENTLY, /* Do not try fallback options. */
GRPC_SSL_ROOTS_OVERRIDE_FAIL
} grpc_ssl_roots_override_result;
/* Callback for getting the SSL roots override from the application.
In case of success, *pem_roots_certs must be set to a NULL terminated string
containing the list of PEM encoded root certificates. The ownership is passed
to the core and freed (laster by the core) with gpr_free.
If this function fails and GRPC_DEFAULT_SSL_ROOTS_FILE_PATH environment is
set to a valid path, it will override the roots specified this func */
typedef grpc_ssl_roots_override_result (*grpc_ssl_roots_override_callback)(
char **pem_root_certs);
/* Setup a callback to override the default TLS/SSL roots.
This function is not thread-safe and must be called at initialization time
before any ssl credentials are created to have the desired side effect.
If GRPC_DEFAULT_SSL_ROOTS_FILE_PATH environment is set to a valid path, the
callback will not be called. */
void grpc_set_ssl_roots_override_callback(grpc_ssl_roots_override_callback cb);
/* Object that holds a private key / certificate chain pair in PEM format. */
typedef struct {
/* private_key is the NULL-terminated string containing the PEM encoding of
@ -159,12 +186,13 @@ typedef struct {
of the server root certificates. If this parameter is NULL, the
implementation will first try to dereference the file pointed by the
GRPC_DEFAULT_SSL_ROOTS_FILE_PATH environment variable, and if that fails,
get the roots from a well-known place on disk (in the grpc install
directory).
try to get the roots set by grpc_override_ssl_default_roots. Eventually,
if all these fail, it will try to get the roots from a well-known place on
disk (in the grpc install directory).
- pem_key_cert_pair is a pointer on the object containing client's private
key and certificate chain. This parameter can be NULL if the client does
not have such a key/cert pair. */
grpc_channel_credentials *grpc_ssl_credentials_create(
GRPC_API grpc_channel_credentials *grpc_ssl_credentials_create(
const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pair,
void *reserved);
@ -178,33 +206,35 @@ typedef struct grpc_call_credentials grpc_call_credentials;
/* Releases a call credentials object.
The creator of the credentials object is responsible for its release. */
void grpc_call_credentials_release(grpc_call_credentials *creds);
GRPC_API void grpc_call_credentials_release(grpc_call_credentials *creds);
/* Creates a composite channel credentials object. */
grpc_channel_credentials *grpc_composite_channel_credentials_create(
GRPC_API grpc_channel_credentials *grpc_composite_channel_credentials_create(
grpc_channel_credentials *channel_creds, grpc_call_credentials *call_creds,
void *reserved);
/* Creates a composite call credentials object. */
grpc_call_credentials *grpc_composite_call_credentials_create(
GRPC_API grpc_call_credentials *grpc_composite_call_credentials_create(
grpc_call_credentials *creds1, grpc_call_credentials *creds2,
void *reserved);
/* Creates a compute engine credentials object for connecting to Google.
WARNING: Do NOT use this credentials to connect to a non-google service as
this could result in an oauth2 token leak. */
grpc_call_credentials *grpc_google_compute_engine_credentials_create(
GRPC_API grpc_call_credentials *grpc_google_compute_engine_credentials_create(
void *reserved);
extern const gpr_timespec grpc_max_auth_token_lifetime;
GRPC_API gpr_timespec grpc_max_auth_token_lifetime();
/* Creates a JWT credentials object. May return NULL if the input is invalid.
- json_key is the JSON key string containing the client's private key.
- token_lifetime is the lifetime of each Json Web Token (JWT) created with
this credentials. It should not exceed grpc_max_auth_token_lifetime or
will be cropped to this value. */
grpc_call_credentials *grpc_service_account_jwt_access_credentials_create(
const char *json_key, gpr_timespec token_lifetime, void *reserved);
GRPC_API grpc_call_credentials *
grpc_service_account_jwt_access_credentials_create(const char *json_key,
gpr_timespec token_lifetime,
void *reserved);
/* Creates an Oauth2 Refresh Token credentials object for connecting to Google.
May return NULL if the input is invalid.
@ -212,16 +242,16 @@ grpc_call_credentials *grpc_service_account_jwt_access_credentials_create(
this could result in an oauth2 token leak.
- json_refresh_token is the JSON string containing the refresh token itself
along with a client_id and client_secret. */
grpc_call_credentials *grpc_google_refresh_token_credentials_create(
GRPC_API grpc_call_credentials *grpc_google_refresh_token_credentials_create(
const char *json_refresh_token, void *reserved);
/* Creates an Oauth2 Access Token credentials with an access token that was
aquired by an out of band mechanism. */
grpc_call_credentials *grpc_access_token_credentials_create(
GRPC_API grpc_call_credentials *grpc_access_token_credentials_create(
const char *access_token, void *reserved);
/* Creates an IAM credentials object for connecting to Google. */
grpc_call_credentials *grpc_google_iam_credentials_create(
GRPC_API grpc_call_credentials *grpc_google_iam_credentials_create(
const char *authorization_token, const char *authority_selector,
void *reserved);
@ -283,16 +313,15 @@ typedef struct {
} grpc_metadata_credentials_plugin;
/* Creates a credentials object from a plugin. */
grpc_call_credentials *grpc_metadata_credentials_create_from_plugin(
GRPC_API grpc_call_credentials *grpc_metadata_credentials_create_from_plugin(
grpc_metadata_credentials_plugin plugin, void *reserved);
/* --- Secure channel creation. --- */
/* Creates a secure channel using the passed-in credentials. */
grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds,
const char *target,
const grpc_channel_args *args,
void *reserved);
GRPC_API grpc_channel *grpc_secure_channel_create(
grpc_channel_credentials *creds, const char *target,
const grpc_channel_args *args, void *reserved);
/* --- grpc_server_credentials object. ---
@ -303,7 +332,7 @@ typedef struct grpc_server_credentials grpc_server_credentials;
/* Releases a server_credentials object.
The creator of the server_credentials object is responsible for its release.
*/
void grpc_server_credentials_release(grpc_server_credentials *creds);
GRPC_API void grpc_server_credentials_release(grpc_server_credentials *creds);
/* Creates an SSL server_credentials object.
- pem_roots_cert is the NULL-terminated string containing the PEM encoding of
@ -316,7 +345,7 @@ void grpc_server_credentials_release(grpc_server_credentials *creds);
- force_client_auth, if set to non-zero will force the client to authenticate
with an SSL cert. Note that this option is ignored if pem_root_certs is
NULL. */
grpc_server_credentials *grpc_ssl_server_credentials_create(
GRPC_API grpc_server_credentials *grpc_ssl_server_credentials_create(
const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
size_t num_key_cert_pairs, int force_client_auth, void *reserved);
@ -325,15 +354,16 @@ grpc_server_credentials *grpc_ssl_server_credentials_create(
/* Add a HTTP2 over an encrypted link over tcp listener.
Returns bound port number on success, 0 on failure.
REQUIRES: server not started */
int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr,
grpc_server_credentials *creds);
GRPC_API int grpc_server_add_secure_http2_port(grpc_server *server,
const char *addr,
grpc_server_credentials *creds);
/* --- Call specific credentials. --- */
/* Sets a credentials to a call. Can only be called on the client side before
grpc_call_start_batch. */
grpc_call_error grpc_call_set_credentials(grpc_call *call,
grpc_call_credentials *creds);
GRPC_API grpc_call_error
grpc_call_set_credentials(grpc_call *call, grpc_call_credentials *creds);
/* --- Auth Metadata Processing --- */
@ -364,7 +394,7 @@ typedef struct {
void *state;
} grpc_auth_metadata_processor;
void grpc_server_credentials_set_auth_metadata_processor(
GRPC_API void grpc_server_credentials_set_auth_metadata_processor(
grpc_server_credentials *creds, grpc_auth_metadata_processor processor);
#ifdef __cplusplus

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

@ -0,0 +1,74 @@
/*
*
* Copyright 2015-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_IMPL_CODEGEN_ALLOC_H
#define GRPC_IMPL_CODEGEN_ALLOC_H
#include <stddef.h>
#include <grpc/impl/codegen/port_platform.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct gpr_allocation_functions {
void *(*malloc_fn)(size_t size);
void *(*realloc_fn)(void *ptr, size_t size);
void (*free_fn)(void *ptr);
} gpr_allocation_functions;
/* malloc, never returns NULL */
GPR_API void *gpr_malloc(size_t size);
/* free */
GPR_API void gpr_free(void *ptr);
/* realloc, never returns NULL */
GPR_API void *gpr_realloc(void *p, size_t size);
/* aligned malloc, never returns NULL, will align to 1 << alignment_log */
GPR_API void *gpr_malloc_aligned(size_t size, size_t alignment_log);
/* free memory allocated by gpr_malloc_aligned */
GPR_API void gpr_free_aligned(void *ptr);
/** Request the family of allocation functions in \a functions be used. NOTE
* that this request will be honored in a *best effort* basis and that no
* guarantees are made about the default functions (eg, malloc) being called. */
GPR_API void gpr_set_allocation_functions(gpr_allocation_functions functions);
/** Return the family of allocation functions currently in effect. */
GPR_API gpr_allocation_functions gpr_get_allocation_functions();
#ifdef __cplusplus
}
#endif
#endif /* GRPC_IMPL_CODEGEN_ALLOC_H */

@ -0,0 +1,92 @@
/*
*
* Copyright 2015-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_IMPL_CODEGEN_ATM_H
#define GRPC_IMPL_CODEGEN_ATM_H
/* This interface provides atomic operations and barriers.
It is internal to gpr support code and should not be used outside it.
If an operation with acquire semantics precedes another memory access by the
same thread, the operation will precede that other access as seen by other
threads.
If an operation with release semantics follows another memory access by the
same thread, the operation will follow that other access as seen by other
threads.
Routines with "acq" or "full" in the name have acquire semantics. Routines
with "rel" or "full" in the name have release semantics. Routines with
"no_barrier" in the name have neither acquire not release semantics.
The routines may be implemented as macros.
// Atomic operations act on an intergral_type gpr_atm that is guaranteed to
// be the same size as a pointer.
typedef intptr_t gpr_atm;
// A memory barrier, providing both acquire and release semantics, but not
// otherwise acting on memory.
void gpr_atm_full_barrier(void);
// Atomically return *p, with acquire semantics.
gpr_atm gpr_atm_acq_load(gpr_atm *p);
// Atomically set *p = value, with release semantics.
void gpr_atm_rel_store(gpr_atm *p, gpr_atm value);
// Atomically add delta to *p, and return the old value of *p, with
// the barriers specified.
gpr_atm gpr_atm_no_barrier_fetch_add(gpr_atm *p, gpr_atm delta);
gpr_atm gpr_atm_full_fetch_add(gpr_atm *p, gpr_atm delta);
// Atomically, if *p==o, set *p=n and return non-zero otherwise return 0,
// with the barriers specified if the operation succeeds.
int gpr_atm_no_barrier_cas(gpr_atm *p, gpr_atm o, gpr_atm n);
int gpr_atm_acq_cas(gpr_atm *p, gpr_atm o, gpr_atm n);
int gpr_atm_rel_cas(gpr_atm *p, gpr_atm o, gpr_atm n);
*/
#include <grpc/impl/codegen/port_platform.h>
#if defined(GPR_GCC_ATOMIC)
#include <grpc/impl/codegen/atm_gcc_atomic.h>
#elif defined(GPR_GCC_SYNC)
#include <grpc/impl/codegen/atm_gcc_sync.h>
#elif defined(GPR_WIN32_ATOMIC)
#include <grpc/impl/codegen/atm_win32.h>
#else
#error could not determine platform for atm
#endif
#endif /* GRPC_IMPL_CODEGEN_ATM_H */

@ -0,0 +1,72 @@
/*
*
* Copyright 2015-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_IMPL_CODEGEN_ATM_GCC_ATOMIC_H
#define GRPC_IMPL_CODEGEN_ATM_GCC_ATOMIC_H
/* atm_platform.h for gcc and gcc-like compilers with the
__atomic_* interface. */
#include <grpc/impl/codegen/port_platform.h>
typedef intptr_t gpr_atm;
#define gpr_atm_full_barrier() (__atomic_thread_fence(__ATOMIC_SEQ_CST))
#define gpr_atm_acq_load(p) (__atomic_load_n((p), __ATOMIC_ACQUIRE))
#define gpr_atm_no_barrier_load(p) (__atomic_load_n((p), __ATOMIC_RELAXED))
#define gpr_atm_rel_store(p, value) \
(__atomic_store_n((p), (intptr_t)(value), __ATOMIC_RELEASE))
#define gpr_atm_no_barrier_store(p, value) \
(__atomic_store_n((p), (intptr_t)(value), __ATOMIC_RELAXED))
#define gpr_atm_no_barrier_fetch_add(p, delta) \
(__atomic_fetch_add((p), (intptr_t)(delta), __ATOMIC_RELAXED))
#define gpr_atm_full_fetch_add(p, delta) \
(__atomic_fetch_add((p), (intptr_t)(delta), __ATOMIC_ACQ_REL))
static __inline int gpr_atm_no_barrier_cas(gpr_atm *p, gpr_atm o, gpr_atm n) {
return __atomic_compare_exchange_n(p, &o, n, 0, __ATOMIC_RELAXED,
__ATOMIC_RELAXED);
}
static __inline int gpr_atm_acq_cas(gpr_atm *p, gpr_atm o, gpr_atm n) {
return __atomic_compare_exchange_n(p, &o, n, 0, __ATOMIC_ACQUIRE,
__ATOMIC_RELAXED);
}
static __inline int gpr_atm_rel_cas(gpr_atm *p, gpr_atm o, gpr_atm n) {
return __atomic_compare_exchange_n(p, &o, n, 0, __ATOMIC_RELEASE,
__ATOMIC_RELAXED);
}
#endif /* GRPC_IMPL_CODEGEN_ATM_GCC_ATOMIC_H */

@ -0,0 +1,87 @@
/*
*
* Copyright 2015-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_IMPL_CODEGEN_ATM_GCC_SYNC_H
#define GRPC_IMPL_CODEGEN_ATM_GCC_SYNC_H
/* variant of atm_platform.h for gcc and gcc-like compiers with __sync_*
interface */
#include <grpc/impl/codegen/port_platform.h>
typedef intptr_t gpr_atm;
#define GPR_ATM_COMPILE_BARRIER_() __asm__ __volatile__("" : : : "memory")
#if defined(__i386) || defined(__x86_64__)
/* All loads are acquire loads and all stores are release stores. */
#define GPR_ATM_LS_BARRIER_() GPR_ATM_COMPILE_BARRIER_()
#else
#define GPR_ATM_LS_BARRIER_() gpr_atm_full_barrier()
#endif
#define gpr_atm_full_barrier() (__sync_synchronize())
static __inline gpr_atm gpr_atm_acq_load(const gpr_atm *p) {
gpr_atm value = *p;
GPR_ATM_LS_BARRIER_();
return value;
}
static __inline gpr_atm gpr_atm_no_barrier_load(const gpr_atm *p) {
gpr_atm value = *p;
GPR_ATM_COMPILE_BARRIER_();
return value;
}
static __inline void gpr_atm_rel_store(gpr_atm *p, gpr_atm value) {
GPR_ATM_LS_BARRIER_();
*p = value;
}
static __inline void gpr_atm_no_barrier_store(gpr_atm *p, gpr_atm value) {
GPR_ATM_COMPILE_BARRIER_();
*p = value;
}
#undef GPR_ATM_LS_BARRIER_
#undef GPR_ATM_COMPILE_BARRIER_
#define gpr_atm_no_barrier_fetch_add(p, delta) \
gpr_atm_full_fetch_add((p), (delta))
#define gpr_atm_full_fetch_add(p, delta) (__sync_fetch_and_add((p), (delta)))
#define gpr_atm_no_barrier_cas(p, o, n) gpr_atm_acq_cas((p), (o), (n))
#define gpr_atm_acq_cas(p, o, n) (__sync_bool_compare_and_swap((p), (o), (n)))
#define gpr_atm_rel_cas(p, o, n) gpr_atm_acq_cas((p), (o), (n))
#endif /* GRPC_IMPL_CODEGEN_ATM_GCC_SYNC_H */

@ -0,0 +1,125 @@
/*
*
* Copyright 2015-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_IMPL_CODEGEN_ATM_WIN32_H
#define GRPC_IMPL_CODEGEN_ATM_WIN32_H
/* Win32 variant of atm_platform.h */
#include <grpc/impl/codegen/port_platform.h>
typedef intptr_t gpr_atm;
#define gpr_atm_full_barrier MemoryBarrier
static __inline gpr_atm gpr_atm_acq_load(const gpr_atm *p) {
gpr_atm result = *p;
gpr_atm_full_barrier();
return result;
}
static __inline gpr_atm gpr_atm_no_barrier_load(const gpr_atm *p) {
/* TODO(dklempner): Can we implement something better here? */
return gpr_atm_acq_load(p);
}
static __inline void gpr_atm_rel_store(gpr_atm *p, gpr_atm value) {
gpr_atm_full_barrier();
*p = value;
}
static __inline void gpr_atm_no_barrier_store(gpr_atm *p, gpr_atm value) {
/* TODO(ctiller): Can we implement something better here? */
gpr_atm_rel_store(p, value);
}
static __inline int gpr_atm_no_barrier_cas(gpr_atm *p, gpr_atm o, gpr_atm n) {
/* InterlockedCompareExchangePointerNoFence() not available on vista or
windows7 */
#ifdef GPR_ARCH_64
return o == (gpr_atm)InterlockedCompareExchangeAcquire64(
(volatile LONGLONG *)p, (LONGLONG)n, (LONGLONG)o);
#else
return o == (gpr_atm)InterlockedCompareExchangeAcquire((volatile LONG *)p,
(LONG)n, (LONG)o);
#endif
}
static __inline int gpr_atm_acq_cas(gpr_atm *p, gpr_atm o, gpr_atm n) {
#ifdef GPR_ARCH_64
return o == (gpr_atm)InterlockedCompareExchangeAcquire64(
(volatile LONGLONG *)p, (LONGLONG)n, (LONGLONG)o);
#else
return o == (gpr_atm)InterlockedCompareExchangeAcquire((volatile LONG *)p,
(LONG)n, (LONG)o);
#endif
}
static __inline int gpr_atm_rel_cas(gpr_atm *p, gpr_atm o, gpr_atm n) {
#ifdef GPR_ARCH_64
return o == (gpr_atm)InterlockedCompareExchangeRelease64(
(volatile LONGLONG *)p, (LONGLONG)n, (LONGLONG)o);
#else
return o == (gpr_atm)InterlockedCompareExchangeRelease((volatile LONG *)p,
(LONG)n, (LONG)o);
#endif
}
static __inline gpr_atm gpr_atm_no_barrier_fetch_add(gpr_atm *p,
gpr_atm delta) {
/* Use the CAS operation to get pointer-sized fetch and add */
gpr_atm old;
do {
old = *p;
} while (!gpr_atm_no_barrier_cas(p, old, old + delta));
return old;
}
static __inline gpr_atm gpr_atm_full_fetch_add(gpr_atm *p, gpr_atm delta) {
/* Use a CAS operation to get pointer-sized fetch and add */
gpr_atm old;
#ifdef GPR_ARCH_64
do {
old = *p;
} while (old != (gpr_atm)InterlockedCompareExchange64((volatile LONGLONG *)p,
(LONGLONG)old + delta,
(LONGLONG)old));
#else
do {
old = *p;
} while (old != (gpr_atm)InterlockedCompareExchange(
(volatile LONG *)p, (LONG)old + delta, (LONG)old));
#endif
return old;
}
#endif /* GRPC_IMPL_CODEGEN_ATM_WIN32_H */

@ -0,0 +1,121 @@
/*
*
* Copyright 2015-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_IMPL_CODEGEN_BYTE_BUFFER_H
#define GRPC_IMPL_CODEGEN_BYTE_BUFFER_H
#include <grpc/impl/codegen/compression_types.h>
#include <grpc/impl/codegen/slice_buffer.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
GRPC_BB_RAW
/* Future types may include GRPC_BB_PROTOBUF, etc. */
} grpc_byte_buffer_type;
struct grpc_byte_buffer {
void *reserved;
grpc_byte_buffer_type type;
union {
struct {
void *reserved[8];
} reserved;
struct {
grpc_compression_algorithm compression;
gpr_slice_buffer slice_buffer;
} raw;
} data;
};
typedef struct grpc_byte_buffer grpc_byte_buffer;
/** Returns a RAW byte buffer instance over the given slices (up to \a nslices).
*
* Increases the reference count for all \a slices processed. The user is
* responsible for invoking grpc_byte_buffer_destroy on the returned instance.*/
GRPC_API grpc_byte_buffer *grpc_raw_byte_buffer_create(gpr_slice *slices,
size_t nslices);
/** Returns a *compressed* RAW byte buffer instance over the given slices (up to
* \a nslices). The \a compression argument defines the compression algorithm
* used to generate the data in \a slices.
*
* Increases the reference count for all \a slices processed. The user is
* responsible for invoking grpc_byte_buffer_destroy on the returned instance.*/
GRPC_API grpc_byte_buffer *grpc_raw_compressed_byte_buffer_create(
gpr_slice *slices, size_t nslices, grpc_compression_algorithm compression);
/** Copies input byte buffer \a bb.
*
* Increases the reference count of all the source slices. The user is
* responsible for calling grpc_byte_buffer_destroy over the returned copy. */
GRPC_API grpc_byte_buffer *grpc_byte_buffer_copy(grpc_byte_buffer *bb);
/** Returns the size of the given byte buffer, in bytes. */
GRPC_API size_t grpc_byte_buffer_length(grpc_byte_buffer *bb);
/** Destroys \a byte_buffer deallocating all its memory. */
GRPC_API void grpc_byte_buffer_destroy(grpc_byte_buffer *byte_buffer);
/** Reader for byte buffers. Iterates over slices in the byte buffer */
struct grpc_byte_buffer_reader;
typedef struct grpc_byte_buffer_reader grpc_byte_buffer_reader;
/** Initialize \a reader to read over \a buffer */
GRPC_API void grpc_byte_buffer_reader_init(grpc_byte_buffer_reader *reader,
grpc_byte_buffer *buffer);
/** Cleanup and destroy \a reader */
GRPC_API void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader *reader);
/** Updates \a slice with the next piece of data from from \a reader and returns
* 1. Returns 0 at the end of the stream. Caller is responsible for calling
* gpr_slice_unref on the result. */
GRPC_API int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader *reader,
gpr_slice *slice);
/** Merge all data from \a reader into single slice */
GRPC_API gpr_slice
grpc_byte_buffer_reader_readall(grpc_byte_buffer_reader *reader);
/** Returns a RAW byte buffer instance from the output of \a reader. */
GRPC_API grpc_byte_buffer *grpc_raw_byte_buffer_from_reader(
grpc_byte_buffer_reader *reader);
#ifdef __cplusplus
}
#endif
#endif /* GRPC_IMPL_CODEGEN_BYTE_BUFFER_H */

@ -0,0 +1,73 @@
/*
*
* 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_IMPL_CODEGEN_COMPRESSION_TYPES_H
#define GRPC_IMPL_CODEGEN_COMPRESSION_TYPES_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/** To be used in channel arguments */
#define GRPC_COMPRESSION_ALGORITHM_ARG "grpc.compression_algorithm"
#define GRPC_COMPRESSION_ALGORITHM_STATE_ARG "grpc.compression_algorithm_state"
/* The various compression algorithms supported by GRPC */
typedef enum {
GRPC_COMPRESS_NONE = 0,
GRPC_COMPRESS_DEFLATE,
GRPC_COMPRESS_GZIP,
/* TODO(ctiller): snappy */
GRPC_COMPRESS_ALGORITHMS_COUNT
} grpc_compression_algorithm;
typedef enum {
GRPC_COMPRESS_LEVEL_NONE = 0,
GRPC_COMPRESS_LEVEL_LOW,
GRPC_COMPRESS_LEVEL_MED,
GRPC_COMPRESS_LEVEL_HIGH,
GRPC_COMPRESS_LEVEL_COUNT
} grpc_compression_level;
typedef struct grpc_compression_options {
uint32_t enabled_algorithms_bitset; /**< All algs are enabled by default */
grpc_compression_algorithm default_compression_algorithm; /**< for channel */
} grpc_compression_options;
#ifdef __cplusplus
}
#endif
#endif /* GRPC_IMPL_CODEGEN_COMPRESSION_TYPES_H */

@ -0,0 +1,59 @@
/*
*
* 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_IMPL_CODEGEN_CONNECTIVITY_STATE_H
#define GRPC_IMPL_CODEGEN_CONNECTIVITY_STATE_H
#ifdef __cplusplus
extern "C" {
#endif
/** Connectivity state of a channel. */
typedef enum {
/** channel is idle */
GRPC_CHANNEL_IDLE,
/** channel is connecting */
GRPC_CHANNEL_CONNECTING,
/** channel is ready for work */
GRPC_CHANNEL_READY,
/** channel has seen a failure but expects to recover */
GRPC_CHANNEL_TRANSIENT_FAILURE,
/** channel has seen a failure that it cannot recover from */
GRPC_CHANNEL_FATAL_FAILURE
} grpc_connectivity_state;
#ifdef __cplusplus
}
#endif
#endif /* GRPC_IMPL_CODEGEN_CONNECTIVITY_STATE_H */

@ -0,0 +1,373 @@
/*
*
* Copyright 2015-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_IMPL_CODEGEN_GRPC_TYPES_H
#define GRPC_IMPL_CODEGEN_GRPC_TYPES_H
#include <grpc/impl/codegen/byte_buffer.h>
#include <grpc/impl/codegen/status.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Completion Queues enable notification of the completion of asynchronous
actions. */
typedef struct grpc_completion_queue grpc_completion_queue;
/** An alarm associated with a completion queue. */
typedef struct grpc_alarm grpc_alarm;
/** The Channel interface allows creation of Call objects. */
typedef struct grpc_channel grpc_channel;
/** A server listens to some port and responds to request calls */
typedef struct grpc_server grpc_server;
/** A Call represents an RPC. When created, it is in a configuration state
allowing properties to be set until it is invoked. After invoke, the Call
can have messages written to it and read from it. */
typedef struct grpc_call grpc_call;
/** Type specifier for grpc_arg */
typedef enum {
GRPC_ARG_STRING,
GRPC_ARG_INTEGER,
GRPC_ARG_POINTER
} grpc_arg_type;
/** A single argument... each argument has a key and a value
A note on naming keys:
Keys are namespaced into groups, usually grouped by library, and are
keys for module XYZ are named XYZ.key1, XYZ.key2, etc. Module names must
be restricted to the regex [A-Za-z][_A-Za-z0-9]{,15}.
Key names must be restricted to the regex [A-Za-z][_A-Za-z0-9]{,47}.
GRPC core library keys are prefixed by grpc.
Library authors are strongly encouraged to \#define symbolic constants for
their keys so that it's possible to change them in the future. */
typedef struct {
grpc_arg_type type;
char *key;
union {
char *string;
int integer;
struct {
void *p;
void *(*copy)(void *p);
void (*destroy)(void *p);
} pointer;
} value;
} grpc_arg;
/** An array of arguments that can be passed around.
Used to set optional channel-level configuration.
These configuration options are modelled as key-value pairs as defined
by grpc_arg; keys are strings to allow easy backwards-compatible extension
by arbitrary parties.
All evaluation is performed at channel creation time (i.e. the values in
this structure need only live through the creation invocation). */
typedef struct {
size_t num_args;
grpc_arg *args;
} grpc_channel_args;
/* Channel argument keys: */
/** Enable census for tracing and stats collection */
#define GRPC_ARG_ENABLE_CENSUS "grpc.census"
/** Maximum number of concurrent incoming streams to allow on a http2
connection */
#define GRPC_ARG_MAX_CONCURRENT_STREAMS "grpc.max_concurrent_streams"
/** Maximum message length that the channel can receive */
#define GRPC_ARG_MAX_MESSAGE_LENGTH "grpc.max_message_length"
/** Initial sequence number for http2 transports */
#define GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER \
"grpc.http2.initial_sequence_number"
/** Amount to read ahead on individual streams. Defaults to 64kb, larger
values can help throughput on high-latency connections.
NOTE: at some point we'd like to auto-tune this, and this parameter
will become a no-op. */
#define GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES "grpc.http2.lookahead_bytes"
/** How much memory to use for hpack decoding */
#define GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER \
"grpc.http2.hpack_table_size.decoder"
/** How much memory to use for hpack encoding */
#define GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_ENCODER \
"grpc.http2.hpack_table_size.encoder"
/** Default authority to pass if none specified on call construction */
#define GRPC_ARG_DEFAULT_AUTHORITY "grpc.default_authority"
/** Primary user agent: goes at the start of the user-agent metadata
sent on each request */
#define GRPC_ARG_PRIMARY_USER_AGENT_STRING "grpc.primary_user_agent"
/** Secondary user agent: goes at the end of the user-agent metadata
sent on each request */
#define GRPC_ARG_SECONDARY_USER_AGENT_STRING "grpc.secondary_user_agent"
/* The caller of the secure_channel_create functions may override the target
name used for SSL host name checking using this channel argument which is of
type GRPC_ARG_STRING. This *should* be used for testing only.
If this argument is not specified, the name used for SSL host name checking
will be the target parameter (assuming that the secure channel is an SSL
channel). If this parameter is specified and the underlying is not an SSL
channel, it will just be ignored. */
#define GRPC_SSL_TARGET_NAME_OVERRIDE_ARG "grpc.ssl_target_name_override"
/** 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.
Receiving any other value listed here is an indication of a bug in the
caller. */
typedef enum grpc_call_error {
/** everything went ok */
GRPC_CALL_OK = 0,
/** something failed, we don't know what */
GRPC_CALL_ERROR,
/** this method is not available on the server */
GRPC_CALL_ERROR_NOT_ON_SERVER,
/** this method is not available on the client */
GRPC_CALL_ERROR_NOT_ON_CLIENT,
/** this method must be called before server_accept */
GRPC_CALL_ERROR_ALREADY_ACCEPTED,
/** this method must be called before invoke */
GRPC_CALL_ERROR_ALREADY_INVOKED,
/** this method must be called after invoke */
GRPC_CALL_ERROR_NOT_INVOKED,
/** this call is already finished
(writes_done or write_status has already been called) */
GRPC_CALL_ERROR_ALREADY_FINISHED,
/** there is already an outstanding read/write operation on the call */
GRPC_CALL_ERROR_TOO_MANY_OPERATIONS,
/** the flags value was illegal for this call */
GRPC_CALL_ERROR_INVALID_FLAGS,
/** invalid metadata was passed to this call */
GRPC_CALL_ERROR_INVALID_METADATA,
/** invalid message was passed to this call */
GRPC_CALL_ERROR_INVALID_MESSAGE,
/** completion queue for notification has not been registered with the
server */
GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE,
/** this batch of operations leads to more operations than allowed */
GRPC_CALL_ERROR_BATCH_TOO_BIG
} grpc_call_error;
/* Write Flags: */
/** Hint that the write may be buffered and need not go out on the wire
immediately. GRPC is free to buffer the message until the next non-buffered
write, or until writes_done, but it need not buffer completely or at all. */
#define GRPC_WRITE_BUFFER_HINT (0x00000001u)
/** Force compression to be disabled for a particular write
(start_write/add_metadata). Illegal on invoke/accept. */
#define GRPC_WRITE_NO_COMPRESS (0x00000002u)
/** Mask of all valid flags. */
#define GRPC_WRITE_USED_MASK (GRPC_WRITE_BUFFER_HINT | GRPC_WRITE_NO_COMPRESS)
/** A single metadata element */
typedef struct grpc_metadata {
const char *key;
const char *value;
size_t value_length;
uint32_t flags;
/** The following fields are reserved for grpc internal use.
There is no need to initialize them, and they will be set to garbage
during calls to grpc. */
struct {
void *obfuscated[4];
} internal_data;
} grpc_metadata;
/** The type of completion (for grpc_event) */
typedef enum grpc_completion_type {
/** Shutting down */
GRPC_QUEUE_SHUTDOWN,
/** No event before timeout */
GRPC_QUEUE_TIMEOUT,
/** Operation completion */
GRPC_OP_COMPLETE
} grpc_completion_type;
/** The result of an operation.
Returned by a completion queue when the operation started with tag. */
typedef struct grpc_event {
/** The type of the completion. */
grpc_completion_type type;
/** non-zero if the operation was successful, 0 upon failure.
Only GRPC_OP_COMPLETE can succeed or fail. */
int success;
/** The tag passed to grpc_call_start_batch etc to start this operation.
Only GRPC_OP_COMPLETE has a tag. */
void *tag;
} grpc_event;
typedef struct {
size_t count;
size_t capacity;
grpc_metadata *metadata;
} grpc_metadata_array;
typedef struct {
char *method;
size_t method_capacity;
char *host;
size_t host_capacity;
gpr_timespec deadline;
void *reserved;
} grpc_call_details;
typedef enum {
/** Send initial metadata: one and only one instance MUST be sent for each
call, unless the call was cancelled - in which case this can be skipped.
This op completes after all bytes of metadata have been accepted by
outgoing flow control. */
GRPC_OP_SEND_INITIAL_METADATA = 0,
/** Send a message: 0 or more of these operations can occur for each call.
This op completes after all bytes for the message have been accepted by
outgoing flow control. */
GRPC_OP_SEND_MESSAGE,
/** Send a close from the client: one and only one instance MUST be sent from
the client, unless the call was cancelled - in which case this can be
skipped.
This op completes after all bytes for the call (including the close)
have passed outgoing flow control. */
GRPC_OP_SEND_CLOSE_FROM_CLIENT,
/** Send status from the server: one and only one instance MUST be sent from
the server unless the call was cancelled - in which case this can be
skipped.
This op completes after all bytes for the call (including the status)
have passed outgoing flow control. */
GRPC_OP_SEND_STATUS_FROM_SERVER,
/** Receive initial metadata: one and only one MUST be made on the client,
must not be made on the server.
This op completes after all initial metadata has been read from the
peer. */
GRPC_OP_RECV_INITIAL_METADATA,
/** Receive a message: 0 or more of these operations can occur for each call.
This op completes after all bytes of the received message have been
read, or after a half-close has been received on this call. */
GRPC_OP_RECV_MESSAGE,
/** Receive status on the client: one and only one must be made on the client.
This operation always succeeds, meaning ops paired with this operation
will also appear to succeed, even though they may not have. In that case
the status will indicate some failure.
This op completes after all activity on the call has completed. */
GRPC_OP_RECV_STATUS_ON_CLIENT,
/** Receive close on the server: one and only one must be made on the
server.
This op completes after the close has been received by the server. */
GRPC_OP_RECV_CLOSE_ON_SERVER
} grpc_op_type;
/** Operation data: one field for each op type (except SEND_CLOSE_FROM_CLIENT
which has no arguments) */
typedef struct grpc_op {
/** Operation type, as defined by grpc_op_type */
grpc_op_type op;
/** Write flags bitset for grpc_begin_messages */
uint32_t flags;
/** Reserved for future usage */
void *reserved;
union {
/** Reserved for future usage */
struct {
void *reserved[8];
} reserved;
struct {
size_t count;
grpc_metadata *metadata;
} send_initial_metadata;
grpc_byte_buffer *send_message;
struct {
size_t trailing_metadata_count;
grpc_metadata *trailing_metadata;
grpc_status_code status;
const char *status_details;
} send_status_from_server;
/** ownership of the array is with the caller, but ownership of the elements
stays with the call object (ie key, value members are owned by the call
object, recv_initial_metadata->array is owned by the caller).
After the operation completes, call grpc_metadata_array_destroy on this
value, or reuse it in a future op. */
grpc_metadata_array *recv_initial_metadata;
/** ownership of the byte buffer is moved to the caller; the caller must
call grpc_byte_buffer_destroy on this value, or reuse it in a future op.
*/
grpc_byte_buffer **recv_message;
struct {
/** ownership of the array is with the caller, but ownership of the
elements stays with the call object (ie key, value members are owned
by the call object, trailing_metadata->array is owned by the caller).
After the operation completes, call grpc_metadata_array_destroy on
this
value, or reuse it in a future op. */
grpc_metadata_array *trailing_metadata;
grpc_status_code *status;
/** status_details is a buffer owned by the application before the op
completes and after the op has completed. During the operation
status_details may be reallocated to a size larger than
*status_details_capacity, in which case *status_details_capacity will
be updated with the new array capacity.
Pre-allocating space:
size_t my_capacity = 8;
char *my_details = gpr_malloc(my_capacity);
x.status_details = &my_details;
x.status_details_capacity = &my_capacity;
Not pre-allocating space:
size_t my_capacity = 0;
char *my_details = NULL;
x.status_details = &my_details;
x.status_details_capacity = &my_capacity;
After the call:
gpr_free(my_details); */
char **status_details;
size_t *status_details_capacity;
} recv_status_on_client;
struct {
/** out argument, set to 1 if the call failed in any way (seen as a
cancellation on the server), or 0 if the call succeeded */
int *cancelled;
} recv_close_on_server;
} data;
} grpc_op;
#ifdef __cplusplus
}
#endif
#endif /* GRPC_IMPL_CODEGEN_GRPC_TYPES_H */

@ -0,0 +1,110 @@
/*
*
* Copyright 2015-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_IMPL_CODEGEN_LOG_H
#define GRPC_IMPL_CODEGEN_LOG_H
#include <stdlib.h> /* for abort() */
#include <stdarg.h>
#include <grpc/impl/codegen/port_platform.h>
#ifdef __cplusplus
extern "C" {
#endif
/* GPR log API.
Usage (within grpc):
int argument1 = 3;
char* argument2 = "hello";
gpr_log(GPR_DEBUG, "format string %d", argument1);
gpr_log(GPR_INFO, "hello world");
gpr_log(GPR_ERROR, "%d %s!!", argument1, argument2); */
/* The severity of a log message - use the #defines below when calling into
gpr_log to additionally supply file and line data */
typedef enum gpr_log_severity {
GPR_LOG_SEVERITY_DEBUG,
GPR_LOG_SEVERITY_INFO,
GPR_LOG_SEVERITY_ERROR
} gpr_log_severity;
/* Returns a string representation of the log severity */
const char *gpr_log_severity_string(gpr_log_severity severity);
/* Macros to build log contexts at various severity levels */
#define GPR_DEBUG __FILE__, __LINE__, GPR_LOG_SEVERITY_DEBUG
#define GPR_INFO __FILE__, __LINE__, GPR_LOG_SEVERITY_INFO
#define GPR_ERROR __FILE__, __LINE__, GPR_LOG_SEVERITY_ERROR
/* Log a message. It's advised to use GPR_xxx above to generate the context
* for each message */
GPR_API void gpr_log(const char *file, int line, gpr_log_severity severity,
const char *format, ...);
GPR_API void gpr_log_message(const char *file, int line,
gpr_log_severity severity, const char *message);
/* Log overrides: applications can use this API to intercept logging calls
and use their own implementations */
typedef struct {
const char *file;
int line;
gpr_log_severity severity;
const char *message;
} gpr_log_func_args;
typedef void (*gpr_log_func)(gpr_log_func_args *args);
GPR_API void gpr_set_log_function(gpr_log_func func);
/* abort() the process if x is zero, having written a line to the log.
Intended for internal invariants. If the error can be recovered from,
without the possibility of corruption, or might best be reflected via
an exception in a higher-level language, consider returning error code. */
#define GPR_ASSERT(x) \
do { \
if (!(x)) { \
gpr_log(GPR_ERROR, "assertion failed: %s", #x); \
abort(); \
} \
} while (0)
#ifdef __cplusplus
}
#endif
#endif /* GRPC_IMPL_CODEGEN_LOG_H */

@ -0,0 +1,349 @@
/*
*
* Copyright 2015-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_IMPL_CODEGEN_PORT_PLATFORM_H
#define GRPC_IMPL_CODEGEN_PORT_PLATFORM_H
/* Get windows.h included everywhere (we need it) */
#if defined(_WIN64) || defined(WIN64) || defined(_WIN32) || defined(WIN32)
#ifndef WIN32_LEAN_AND_MEAN
#define GRPC_WIN32_LEAN_AND_MEAN_WAS_NOT_DEFINED
#define WIN32_LEAN_AND_MEAN
#endif /* WIN32_LEAN_AND_MEAN */
#ifndef NOMINMAX
#define GRPC_NOMINMX_WAS_NOT_DEFINED
#define NOMINMAX
#endif /* NOMINMAX */
#ifndef _WIN32_WINNT
#error \
"Please compile grpc with _WIN32_WINNT of at least 0x600 (aka Windows Vista)"
#else /* !defined(_WIN32_WINNT) */
#if (_WIN32_WINNT < 0x0600)
#error \
"Please compile grpc with _WIN32_WINNT of at least 0x600 (aka Windows Vista)"
#endif /* _WIN32_WINNT < 0x0600 */
#endif /* defined(_WIN32_WINNT) */
#include <windows.h>
#ifdef GRPC_WIN32_LEAN_AND_MEAN_WAS_NOT_DEFINED
#undef GRPC_WIN32_LEAN_AND_MEAN_WAS_NOT_DEFINED
#undef WIN32_LEAN_AND_MEAN
#endif /* GRPC_WIN32_LEAN_AND_MEAN_WAS_NOT_DEFINED */
#ifdef GRPC_NOMINMAX_WAS_NOT_DEFINED
#undef GRPC_NOMINMAX_WAS_NOT_DEFINED
#undef NOMINMAX
#endif /* GRPC_WIN32_LEAN_AND_MEAN_WAS_NOT_DEFINED */
#endif /* defined(_WIN64) || defined(WIN64) || defined(_WIN32) || \
defined(WIN32) */
/* Override this file with one for your platform if you need to redefine
things. */
#if !defined(GPR_NO_AUTODETECT_PLATFORM)
#if defined(_WIN64) || defined(WIN64)
#define GPR_PLATFORM_STRING "windows"
#define GPR_WIN32 1
#define GPR_ARCH_64 1
#define GPR_GETPID_IN_PROCESS_H 1
#define GPR_WINSOCK_SOCKET 1
#define GPR_WINDOWS_SUBPROCESS 1
#ifdef __GNUC__
#define GPR_GCC_ATOMIC 1
#define GPR_GCC_TLS 1
#else
#define GPR_WIN32_ATOMIC 1
#define GPR_MSVC_TLS 1
#endif
#define GPR_WINDOWS_CRASH_HANDLER 1
#elif defined(_WIN32) || defined(WIN32)
#define GPR_PLATFORM_STRING "windows"
#define GPR_ARCH_32 1
#define GPR_WIN32 1
#define GPR_GETPID_IN_PROCESS_H 1
#define GPR_WINSOCK_SOCKET 1
#define GPR_WINDOWS_SUBPROCESS 1
#ifdef __GNUC__
#define GPR_GCC_ATOMIC 1
#define GPR_GCC_TLS 1
#else
#define GPR_WIN32_ATOMIC 1
#define GPR_MSVC_TLS 1
#endif
#define GPR_WINDOWS_CRASH_HANDLER 1
#elif defined(ANDROID) || defined(__ANDROID__)
#define GPR_PLATFORM_STRING "android"
#define GPR_ANDROID 1
#define GPR_ARCH_32 1
#define GPR_CPU_LINUX 1
#define GPR_GCC_SYNC 1
#define GPR_GCC_TLS 1
#define GPR_POSIX_MULTIPOLL_WITH_POLL 1
#define GPR_POSIX_WAKEUP_FD 1
#define GPR_LINUX_EVENTFD 1
#define GPR_POSIX_SOCKET 1
#define GPR_POSIX_SOCKETADDR 1
#define GPR_POSIX_SOCKETUTILS 1
#define GPR_POSIX_ENV 1
#define GPR_POSIX_FILE 1
#define GPR_POSIX_STRING 1
#define GPR_POSIX_SUBPROCESS 1
#define GPR_POSIX_SYNC 1
#define GPR_POSIX_TIME 1
#define GPR_GETPID_IN_UNISTD_H 1
#define GPR_HAVE_MSG_NOSIGNAL 1
#elif defined(__linux__)
#define GPR_POSIX_CRASH_HANDLER 1
#define GPR_PLATFORM_STRING "linux"
#ifndef _BSD_SOURCE
#define _BSD_SOURCE
#endif
#ifndef _DEFAULT_SOURCE
#define _DEFAULT_SOURCE
#endif
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <features.h>
#define GPR_CPU_LINUX 1
#define GPR_GCC_ATOMIC 1
#define GPR_GCC_TLS 1
#define GPR_LINUX 1
#define GPR_LINUX_MULTIPOLL_WITH_EPOLL 1
#define GPR_POSIX_WAKEUP_FD 1
#define GPR_POSIX_SOCKET 1
#define GPR_POSIX_SOCKETADDR 1
#ifdef __GLIBC_PREREQ
#if __GLIBC_PREREQ(2, 9)
#define GPR_LINUX_EVENTFD 1
#endif
#if __GLIBC_PREREQ(2, 10)
#define GPR_LINUX_SOCKETUTILS 1
#endif
#endif
#define GPR_LINUX_ENV 1
#ifndef GPR_LINUX_EVENTFD
#define GPR_POSIX_NO_SPECIAL_WAKEUP_FD 1
#endif
#ifndef GPR_LINUX_SOCKETUTILS
#define GPR_POSIX_SOCKETUTILS
#endif
#define GPR_POSIX_FILE 1
#define GPR_POSIX_STRING 1
#define GPR_POSIX_SUBPROCESS 1
#define GPR_POSIX_SYNC 1
#define GPR_POSIX_TIME 1
#define GPR_GETPID_IN_UNISTD_H 1
#define GPR_HAVE_MSG_NOSIGNAL 1
#ifdef _LP64
#define GPR_ARCH_64 1
#else /* _LP64 */
#define GPR_ARCH_32 1
#endif /* _LP64 */
#elif defined(__APPLE__)
#include <TargetConditionals.h>
#ifndef _BSD_SOURCE
#define _BSD_SOURCE
#endif
#define GPR_MSG_IOVLEN_TYPE int
#if TARGET_OS_IPHONE
#define GPR_FORBID_UNREACHABLE_CODE 1
#define GPR_PLATFORM_STRING "ios"
#define GPR_CPU_IPHONE 1
#define GPR_PTHREAD_TLS 1
#else /* TARGET_OS_IPHONE */
#define GPR_PLATFORM_STRING "osx"
#define GPR_CPU_POSIX 1
#define GPR_GCC_TLS 1
#define GPR_POSIX_CRASH_HANDLER 1
#endif
#define GPR_GCC_ATOMIC 1
#define GPR_POSIX_LOG 1
#define GPR_POSIX_MULTIPOLL_WITH_POLL 1
#define GPR_POSIX_WAKEUP_FD 1
#define GPR_POSIX_NO_SPECIAL_WAKEUP_FD 1
#define GPR_POSIX_SOCKET 1
#define GPR_POSIX_SOCKETADDR 1
#define GPR_POSIX_SOCKETUTILS 1
#define GPR_POSIX_ENV 1
#define GPR_POSIX_FILE 1
#define GPR_POSIX_STRING 1
#define GPR_POSIX_SUBPROCESS 1
#define GPR_POSIX_SYNC 1
#define GPR_POSIX_TIME 1
#define GPR_GETPID_IN_UNISTD_H 1
#define GPR_HAVE_SO_NOSIGPIPE 1
#ifdef _LP64
#define GPR_ARCH_64 1
#else /* _LP64 */
#define GPR_ARCH_32 1
#endif /* _LP64 */
#elif defined(__FreeBSD__)
#define GPR_PLATFORM_STRING "freebsd"
#ifndef _BSD_SOURCE
#define _BSD_SOURCE
#endif
#define GPR_CPU_POSIX 1
#define GPR_GCC_ATOMIC 1
#define GPR_GCC_TLS 1
#define GPR_POSIX_LOG 1
#define GPR_POSIX_MULTIPOLL_WITH_POLL 1
#define GPR_POSIX_WAKEUP_FD 1
#define GPR_POSIX_NO_SPECIAL_WAKEUP_FD 1
#define GPR_POSIX_SOCKET 1
#define GPR_POSIX_SOCKETADDR 1
#define GPR_POSIX_SOCKETUTILS 1
#define GPR_POSIX_ENV 1
#define GPR_POSIX_FILE 1
#define GPR_POSIX_STRING 1
#define GPR_POSIX_SUBPROCESS 1
#define GPR_POSIX_SYNC 1
#define GPR_POSIX_TIME 1
#define GPR_GETPID_IN_UNISTD_H 1
#define GPR_HAVE_SO_NOSIGPIPE 1
#ifdef _LP64
#define GPR_ARCH_64 1
#else /* _LP64 */
#define GPR_ARCH_32 1
#endif /* _LP64 */
#else
#error Could not auto-detect platform
#endif
#endif /* GPR_NO_AUTODETECT_PLATFORM */
#ifndef GPR_PLATFORM_STRING
#warning "GPR_PLATFORM_STRING not auto-detected"
#define GPR_PLATFORM_STRING "unknown"
#endif
#ifdef GPR_GCOV
#undef GPR_FORBID_UNREACHABLE_CODE
#define GPR_FORBID_UNREACHABLE_CODE 1
#endif
/* For a common case, assume that the platform has a C99-like stdint.h */
#include <stdint.h>
/* Cache line alignment */
#ifndef GPR_CACHELINE_SIZE_LOG
#if defined(__i386__) || defined(__x86_64__)
#define GPR_CACHELINE_SIZE_LOG 6
#endif
#ifndef GPR_CACHELINE_SIZE_LOG
/* A reasonable default guess. Note that overestimates tend to waste more
space, while underestimates tend to waste more time. */
#define GPR_CACHELINE_SIZE_LOG 6
#endif /* GPR_CACHELINE_SIZE_LOG */
#endif /* GPR_CACHELINE_SIZE_LOG */
#define GPR_CACHELINE_SIZE (1 << GPR_CACHELINE_SIZE_LOG)
/* scrub GCC_ATOMIC if it's not available on this compiler */
#if defined(GPR_GCC_ATOMIC) && !defined(__ATOMIC_RELAXED)
#undef GPR_GCC_ATOMIC
#define GPR_GCC_SYNC 1
#endif
/* Validate platform combinations */
#if defined(GPR_GCC_ATOMIC) + defined(GPR_GCC_SYNC) + \
defined(GPR_WIN32_ATOMIC) != \
1
#error Must define exactly one of GPR_GCC_ATOMIC, GPR_GCC_SYNC, GPR_WIN32_ATOMIC
#endif
#if defined(GPR_ARCH_32) + defined(GPR_ARCH_64) != 1
#error Must define exactly one of GPR_ARCH_32, GPR_ARCH_64
#endif
#if defined(GPR_CPU_LINUX) + defined(GPR_CPU_POSIX) + defined(GPR_WIN32) + \
defined(GPR_CPU_IPHONE) + defined(GPR_CPU_CUSTOM) != \
1
#error Must define exactly one of GPR_CPU_LINUX, GPR_CPU_POSIX, GPR_WIN32, GPR_CPU_IPHONE, GPR_CPU_CUSTOM
#endif
#if defined(GPR_POSIX_MULTIPOLL_WITH_POLL) && !defined(GPR_POSIX_SOCKET)
#error Must define GPR_POSIX_SOCKET to use GPR_POSIX_MULTIPOLL_WITH_POLL
#endif
#if defined(GPR_POSIX_SOCKET) + defined(GPR_WINSOCK_SOCKET) + \
defined(GPR_CUSTOM_SOCKET) != \
1
#error Must define exactly one of GPR_POSIX_SOCKET, GPR_WINSOCK_SOCKET, GPR_CUSTOM_SOCKET
#endif
#if defined(GPR_MSVC_TLS) + defined(GPR_GCC_TLS) + defined(GPR_PTHREAD_TLS) + \
defined(GPR_CUSTOM_TLS) != \
1
#error Must define exactly one of GPR_MSVC_TLS, GPR_GCC_TLS, GPR_PTHREAD_TLS, GPR_CUSTOM_TLS
#endif
/* maximum alignment needed for any type on this platform, rounded up to a
power of two */
#define GPR_MAX_ALIGNMENT 16
#ifndef GRPC_MUST_USE_RESULT
#ifdef __GNUC__
#define GRPC_MUST_USE_RESULT __attribute__((warn_unused_result))
#else
#define GRPC_MUST_USE_RESULT
#endif
#endif
#if GPR_FORBID_UNREACHABLE_CODE
#define GPR_UNREACHABLE_CODE(STATEMENT)
#else
#define GPR_UNREACHABLE_CODE(STATEMENT) \
do { \
gpr_log(GPR_ERROR, "Should never reach here."); \
abort(); \
STATEMENT; \
} while (0)
#endif /* GPR_FORBID_UNREACHABLE_CODE */
#ifndef GPR_API
#define GPR_API
#endif
#ifndef GRPC_API
#define GRPC_API GPR_API
#endif
#ifndef CENSUS_API
#define CENSUS_API GRPC_API
#endif
#endif /* GRPC_IMPL_CODEGEN_PORT_PLATFORM_H */

@ -0,0 +1,67 @@
/*
*
* 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_IMPL_CODEGEN_H
#define GRPC_IMPL_CODEGEN_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Propagation bits: this can be bitwise or-ed to form propagation_mask for
* grpc_call */
/** Propagate deadline */
#define GRPC_PROPAGATE_DEADLINE ((uint32_t)1)
/** Propagate census context */
#define GRPC_PROPAGATE_CENSUS_STATS_CONTEXT ((uint32_t)2)
#define GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT ((uint32_t)4)
/** Propagate cancellation */
#define GRPC_PROPAGATE_CANCELLATION ((uint32_t)8)
/* Default propagation mask: clients of the core API are encouraged to encode
deltas from this in their implementations... ie write:
GRPC_PROPAGATE_DEFAULTS & ~GRPC_PROPAGATE_DEADLINE to disable deadline
propagation. Doing so gives flexibility in the future to define new
propagation types that are default inherited or not. */
#define GRPC_PROPAGATE_DEFAULTS \
((uint32_t)(( \
0xffff | GRPC_PROPAGATE_DEADLINE | GRPC_PROPAGATE_CENSUS_STATS_CONTEXT | \
GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT | GRPC_PROPAGATE_CANCELLATION)))
#ifdef __cplusplus
}
#endif
#endif /* GRPC_IMPL_CODEGEN_H */

@ -0,0 +1,182 @@
/*
*
* Copyright 2015-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_IMPL_CODEGEN_SLICE_H
#define GRPC_IMPL_CODEGEN_SLICE_H
#include <grpc/impl/codegen/sync.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Slice API
A slice represents a contiguous reference counted array of bytes.
It is cheap to take references to a slice, and it is cheap to create a
slice pointing to a subset of another slice.
The data-structure for slices is exposed here to allow non-gpr code to
build slices from whatever data they have available.
When defining interfaces that handle slices, care should be taken to define
reference ownership semantics (who should call unref?) and mutability
constraints (is the callee allowed to modify the slice?) */
/* Reference count container for gpr_slice. Contains function pointers to
increment and decrement reference counts. Implementations should cleanup
when the reference count drops to zero.
Typically client code should not touch this, and use gpr_slice_malloc,
gpr_slice_new, or gpr_slice_new_with_len instead. */
typedef struct gpr_slice_refcount {
void (*ref)(void *);
void (*unref)(void *);
} gpr_slice_refcount;
#define GPR_SLICE_INLINED_SIZE (sizeof(size_t) + sizeof(uint8_t *) - 1)
/* A gpr_slice s, if initialized, represents the byte range
s.bytes[0..s.length-1].
It can have an associated ref count which has a destruction routine to be run
when the ref count reaches zero (see gpr_slice_new() and grp_slice_unref()).
Multiple gpr_slice values may share a ref count.
If the slice does not have a refcount, it represents an inlined small piece
of data that is copied by value. */
typedef struct gpr_slice {
struct gpr_slice_refcount *refcount;
union {
struct {
uint8_t *bytes;
size_t length;
} refcounted;
struct {
uint8_t length;
uint8_t bytes[GPR_SLICE_INLINED_SIZE];
} inlined;
} data;
} gpr_slice;
#define GPR_SLICE_START_PTR(slice) \
((slice).refcount ? (slice).data.refcounted.bytes \
: (slice).data.inlined.bytes)
#define GPR_SLICE_LENGTH(slice) \
((slice).refcount ? (slice).data.refcounted.length \
: (slice).data.inlined.length)
#define GPR_SLICE_SET_LENGTH(slice, newlen) \
((slice).refcount ? ((slice).data.refcounted.length = (size_t)(newlen)) \
: ((slice).data.inlined.length = (uint8_t)(newlen)))
#define GPR_SLICE_END_PTR(slice) \
GPR_SLICE_START_PTR(slice) + GPR_SLICE_LENGTH(slice)
#define GPR_SLICE_IS_EMPTY(slice) (GPR_SLICE_LENGTH(slice) == 0)
/* Increment the refcount of s. Requires slice is initialized.
Returns s. */
GPR_API gpr_slice gpr_slice_ref(gpr_slice s);
/* Decrement the ref count of s. If the ref count of s reaches zero, all
slices sharing the ref count are destroyed, and considered no longer
initialized. If s is ultimately derived from a call to gpr_slice_new(start,
len, dest) where dest!=NULL , then (*dest)(start) is called, else if s is
ultimately derived from a call to gpr_slice_new_with_len(start, len, dest)
where dest!=NULL , then (*dest)(start, len). Requires s initialized. */
GPR_API void gpr_slice_unref(gpr_slice s);
/* Create a slice pointing at some data. Calls malloc to allocate a refcount
for the object, and arranges that destroy will be called with the pointer
passed in at destruction. */
GPR_API gpr_slice gpr_slice_new(void *p, size_t len, void (*destroy)(void *));
/* Equivalent to gpr_slice_new, but with a two argument destroy function that
also takes the slice length. */
GPR_API gpr_slice
gpr_slice_new_with_len(void *p, size_t len, void (*destroy)(void *, size_t));
/* Equivalent to gpr_slice_new(malloc(len), len, free), but saves one malloc()
call.
Aborts if malloc() fails. */
GPR_API gpr_slice gpr_slice_malloc(size_t length);
/* Create a slice by copying a string.
Does not preserve null terminators.
Equivalent to:
size_t len = strlen(source);
gpr_slice slice = gpr_slice_malloc(len);
memcpy(slice->data, source, len); */
GPR_API gpr_slice gpr_slice_from_copied_string(const char *source);
/* Create a slice by copying a buffer.
Equivalent to:
gpr_slice slice = gpr_slice_malloc(len);
memcpy(slice->data, source, len); */
GPR_API gpr_slice gpr_slice_from_copied_buffer(const char *source, size_t len);
/* Create a slice pointing to constant memory */
GPR_API gpr_slice gpr_slice_from_static_string(const char *source);
/* Return a result slice derived from s, which shares a ref count with s, where
result.data==s.data+begin, and result.length==end-begin.
The ref count of s is increased by one.
Requires s initialized, begin <= end, begin <= s.length, and
end <= source->length. */
GPR_API gpr_slice gpr_slice_sub(gpr_slice s, size_t begin, size_t end);
/* The same as gpr_slice_sub, but without altering the ref count */
GPR_API gpr_slice gpr_slice_sub_no_ref(gpr_slice s, size_t begin, size_t end);
/* Splits s into two: modifies s to be s[0:split], and returns a new slice,
sharing a refcount with s, that contains s[split:s.length].
Requires s intialized, split <= s.length */
GPR_API gpr_slice gpr_slice_split_tail(gpr_slice *s, size_t split);
/* Splits s into two: modifies s to be s[split:s.length], and returns a new
slice, sharing a refcount with s, that contains s[0:split].
Requires s intialized, split <= s.length */
GPR_API gpr_slice gpr_slice_split_head(gpr_slice *s, size_t split);
GPR_API gpr_slice gpr_empty_slice(void);
/* Returns <0 if a < b, ==0 if a == b, >0 if a > b
The order is arbitrary, and is not guaranteed to be stable across different
versions of the API. */
GPR_API int gpr_slice_cmp(gpr_slice a, gpr_slice b);
GPR_API int gpr_slice_str_cmp(gpr_slice a, const char *b);
#ifdef __cplusplus
}
#endif
#endif /* GRPC_IMPL_CODEGEN_SLICE_H */

@ -0,0 +1,105 @@
/*
*
* Copyright 2015-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_IMPL_CODEGEN_SLICE_BUFFER_H
#define GRPC_IMPL_CODEGEN_SLICE_BUFFER_H
#include <grpc/impl/codegen/slice.h>
#ifdef __cplusplus
extern "C" {
#endif
#define GRPC_SLICE_BUFFER_INLINE_ELEMENTS 8
/* Represents an expandable array of slices, to be interpreted as a single item
TODO(ctiller): inline some small number of elements into the struct, to
avoid per-call allocations */
typedef struct {
/* slices in the array */
gpr_slice *slices;
/* the number of slices in the array */
size_t count;
/* the number of slices allocated in the array */
size_t capacity;
/* the combined length of all slices in the array */
size_t length;
/* inlined elements to avoid allocations */
gpr_slice inlined[GRPC_SLICE_BUFFER_INLINE_ELEMENTS];
} gpr_slice_buffer;
/* initialize a slice buffer */
GPR_API void gpr_slice_buffer_init(gpr_slice_buffer *sb);
/* destroy a slice buffer - unrefs any held elements */
GPR_API void gpr_slice_buffer_destroy(gpr_slice_buffer *sb);
/* Add an element to a slice buffer - takes ownership of the slice.
This function is allowed to concatenate the passed in slice to the end of
some other slice if desired by the slice buffer. */
GPR_API void gpr_slice_buffer_add(gpr_slice_buffer *sb, gpr_slice slice);
/* add an element to a slice buffer - takes ownership of the slice and returns
the index of the slice.
Guarantees that the slice will not be concatenated at the end of another
slice (i.e. the data for this slice will begin at the first byte of the
slice at the returned index in sb->slices)
The implementation MAY decide to concatenate data at the end of a small
slice added in this fashion. */
GPR_API size_t
gpr_slice_buffer_add_indexed(gpr_slice_buffer *sb, gpr_slice slice);
GPR_API void gpr_slice_buffer_addn(gpr_slice_buffer *sb, gpr_slice *slices,
size_t n);
/* add a very small (less than 8 bytes) amount of data to the end of a slice
buffer: returns a pointer into which to add the data */
GPR_API uint8_t *gpr_slice_buffer_tiny_add(gpr_slice_buffer *sb, size_t len);
/* pop the last buffer, but don't unref it */
GPR_API void gpr_slice_buffer_pop(gpr_slice_buffer *sb);
/* clear a slice buffer, unref all elements */
GPR_API void gpr_slice_buffer_reset_and_unref(gpr_slice_buffer *sb);
/* swap the contents of two slice buffers */
GPR_API void gpr_slice_buffer_swap(gpr_slice_buffer *a, gpr_slice_buffer *b);
/* move all of the elements of src into dst */
GPR_API void gpr_slice_buffer_move_into(gpr_slice_buffer *src,
gpr_slice_buffer *dst);
/* remove n bytes from the end of a slice buffer */
GPR_API void gpr_slice_buffer_trim_end(gpr_slice_buffer *src, size_t n,
gpr_slice_buffer *garbage);
/* move the first n bytes of src into dst */
GPR_API void gpr_slice_buffer_move_first(gpr_slice_buffer *src, size_t n,
gpr_slice_buffer *dst);
/* take the first slice in the slice buffer */
GPR_API gpr_slice gpr_slice_buffer_take_first(gpr_slice_buffer *src);
#ifdef __cplusplus
}
#endif
#endif /* GRPC_IMPL_CODEGEN_SLICE_BUFFER_H */

@ -0,0 +1,163 @@
/*
*
* Copyright 2015-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_IMPL_CODEGEN_STATUS_H
#define GRPC_IMPL_CODEGEN_STATUS_H
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
/* Not an error; returned on success */
GRPC_STATUS_OK = 0,
/* The operation was cancelled (typically by the caller). */
GRPC_STATUS_CANCELLED = 1,
/* Unknown error. An example of where this error may be returned is
if a Status value received from another address space belongs to
an error-space that is not known in this address space. Also
errors raised by APIs that do not return enough error information
may be converted to this error. */
GRPC_STATUS_UNKNOWN = 2,
/* Client specified an invalid argument. Note that this differs
from FAILED_PRECONDITION. INVALID_ARGUMENT indicates arguments
that are problematic regardless of the state of the system
(e.g., a malformed file name). */
GRPC_STATUS_INVALID_ARGUMENT = 3,
/* Deadline expired before operation could complete. For operations
that change the state of the system, this error may be returned
even if the operation has completed successfully. For example, a
successful response from a server could have been delayed long
enough for the deadline to expire. */
GRPC_STATUS_DEADLINE_EXCEEDED = 4,
/* Some requested entity (e.g., file or directory) was not found. */
GRPC_STATUS_NOT_FOUND = 5,
/* Some entity that we attempted to create (e.g., file or directory)
already exists. */
GRPC_STATUS_ALREADY_EXISTS = 6,
/* The caller does not have permission to execute the specified
operation. PERMISSION_DENIED must not be used for rejections
caused by exhausting some resource (use RESOURCE_EXHAUSTED
instead for those errors). PERMISSION_DENIED must not be
used if the caller can not be identified (use UNAUTHENTICATED
instead for those errors). */
GRPC_STATUS_PERMISSION_DENIED = 7,
/* The request does not have valid authentication credentials for the
operation. */
GRPC_STATUS_UNAUTHENTICATED = 16,
/* Some resource has been exhausted, perhaps a per-user quota, or
perhaps the entire file system is out of space. */
GRPC_STATUS_RESOURCE_EXHAUSTED = 8,
/* Operation was rejected because the system is not in a state
required for the operation's execution. For example, directory
to be deleted may be non-empty, an rmdir operation is applied to
a non-directory, etc.
A litmus test that may help a service implementor in deciding
between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE:
(a) Use UNAVAILABLE if the client can retry just the failing call.
(b) Use ABORTED if the client should retry at a higher-level
(e.g., restarting a read-modify-write sequence).
(c) Use FAILED_PRECONDITION if the client should not retry until
the system state has been explicitly fixed. E.g., if an "rmdir"
fails because the directory is non-empty, FAILED_PRECONDITION
should be returned since the client should not retry unless
they have first fixed up the directory by deleting files from it.
(d) Use FAILED_PRECONDITION if the client performs conditional
REST Get/Update/Delete on a resource and the resource on the
server does not match the condition. E.g., conflicting
read-modify-write on the same resource. */
GRPC_STATUS_FAILED_PRECONDITION = 9,
/* The operation was aborted, typically due to a concurrency issue
like sequencer check failures, transaction aborts, etc.
See litmus test above for deciding between FAILED_PRECONDITION,
ABORTED, and UNAVAILABLE. */
GRPC_STATUS_ABORTED = 10,
/* Operation was attempted past the valid range. E.g., seeking or
reading past end of file.
Unlike INVALID_ARGUMENT, this error indicates a problem that may
be fixed if the system state changes. For example, a 32-bit file
system will generate INVALID_ARGUMENT if asked to read at an
offset that is not in the range [0,2^32-1], but it will generate
OUT_OF_RANGE if asked to read from an offset past the current
file size.
There is a fair bit of overlap between FAILED_PRECONDITION and
OUT_OF_RANGE. We recommend using OUT_OF_RANGE (the more specific
error) when it applies so that callers who are iterating through
a space can easily look for an OUT_OF_RANGE error to detect when
they are done. */
GRPC_STATUS_OUT_OF_RANGE = 11,
/* Operation is not implemented or not supported/enabled in this service. */
GRPC_STATUS_UNIMPLEMENTED = 12,
/* Internal errors. Means some invariants expected by underlying
system has been broken. If you see one of these errors,
something is very broken. */
GRPC_STATUS_INTERNAL = 13,
/* The service is currently unavailable. This is a most likely a
transient condition and may be corrected by retrying with
a backoff.
See litmus test above for deciding between FAILED_PRECONDITION,
ABORTED, and UNAVAILABLE. */
GRPC_STATUS_UNAVAILABLE = 14,
/* Unrecoverable data loss or corruption. */
GRPC_STATUS_DATA_LOSS = 15,
/* Force users to include a default branch: */
GRPC_STATUS__DO_NOT_USE = -1
} grpc_status_code;
#ifdef __cplusplus
}
#endif
#endif /* GRPC_IMPL_CODEGEN_STATUS_H */

@ -0,0 +1,315 @@
/*
*
* 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_IMPL_CODEGEN_SYNC_H
#define GRPC_IMPL_CODEGEN_SYNC_H
/* Synchronization primitives for GPR.
The type gpr_mu provides a non-reentrant mutex (lock).
The type gpr_cv provides a condition variable.
The type gpr_once provides for one-time initialization.
The type gpr_event provides one-time-setting, reading, and
waiting of a void*, with memory barriers.
The type gpr_refcount provides an object reference counter,
with memory barriers suitable to control
object lifetimes.
The type gpr_stats_counter provides an atomic statistics counter. It
provides no memory barriers.
*/
/* Platform-specific type declarations of gpr_mu and gpr_cv. */
#include <grpc/impl/codegen/port_platform.h>
#include <grpc/impl/codegen/sync_generic.h>
#if defined(GPR_POSIX_SYNC)
#include <grpc/impl/codegen/sync_posix.h>
#elif defined(GPR_WIN32)
#include <grpc/impl/codegen/sync_win32.h>
#elif !defined(GPR_CUSTOM_SYNC)
#error Unable to determine platform for sync
#endif
#include <grpc/impl/codegen/time.h> /* for gpr_timespec */
#ifdef __cplusplus
extern "C" {
#endif
/* --- Mutex interface ---
At most one thread may hold an exclusive lock on a mutex at any given time.
Actions taken by a thread that holds a mutex exclusively happen after
actions taken by all previous holders of the mutex. Variables of type
gpr_mu are uninitialized when first declared. */
/* Initialize *mu. Requires: *mu uninitialized. */
GPR_API void gpr_mu_init(gpr_mu *mu);
/* Cause *mu no longer to be initialized, freeing any memory in use. Requires:
*mu initialized; no other concurrent operation on *mu. */
GPR_API void gpr_mu_destroy(gpr_mu *mu);
/* Wait until no thread has a lock on *mu, cause the calling thread to own an
exclusive lock on *mu, then return. May block indefinitely or crash if the
calling thread has a lock on *mu. Requires: *mu initialized. */
GPR_API void gpr_mu_lock(gpr_mu *mu);
/* Release an exclusive lock on *mu held by the calling thread. Requires: *mu
initialized; the calling thread holds an exclusive lock on *mu. */
GPR_API void gpr_mu_unlock(gpr_mu *mu);
/* Without blocking, attempt to acquire an exclusive lock on *mu for the
calling thread, then return non-zero iff success. Fail, if any thread holds
the lock; succeeds with high probability if no thread holds the lock.
Requires: *mu initialized. */
GPR_API int gpr_mu_trylock(gpr_mu *mu);
/* --- Condition variable interface ---
A while-loop should be used with gpr_cv_wait() when waiting for conditions
to become true. See the example below. Variables of type gpr_cv are
uninitialized when first declared. */
/* Initialize *cv. Requires: *cv uninitialized. */
GPR_API void gpr_cv_init(gpr_cv *cv);
/* Cause *cv no longer to be initialized, freeing any memory in use. Requires:
*cv initialized; no other concurrent operation on *cv.*/
GPR_API void gpr_cv_destroy(gpr_cv *cv);
/* Atomically release *mu and wait on *cv. When the calling thread is woken
from *cv or the deadline abs_deadline is exceeded, execute gpr_mu_lock(mu)
and return whether the deadline was exceeded. Use
abs_deadline==gpr_inf_future for no deadline. May return even when not
woken explicitly. Requires: *mu and *cv initialized; the calling thread
holds an exclusive lock on *mu. */
GPR_API int gpr_cv_wait(gpr_cv *cv, gpr_mu *mu, gpr_timespec abs_deadline);
/* If any threads are waiting on *cv, wake at least one.
Clients may treat this as an optimization of gpr_cv_broadcast()
for use in the case where waking more than one waiter is not useful.
Requires: *cv initialized. */
GPR_API void gpr_cv_signal(gpr_cv *cv);
/* Wake all threads waiting on *cv. Requires: *cv initialized. */
GPR_API void gpr_cv_broadcast(gpr_cv *cv);
/* --- One-time initialization ---
gpr_once must be declared with static storage class, and initialized with
GPR_ONCE_INIT. e.g.,
static gpr_once once_var = GPR_ONCE_INIT; */
/* Ensure that (*init_routine)() has been called exactly once (for the
specified gpr_once instance) and then return.
If multiple threads call gpr_once() on the same gpr_once instance, one of
them will call (*init_routine)(), and the others will block until that call
finishes.*/
GPR_API void gpr_once_init(gpr_once *once, void (*init_routine)(void));
/* --- One-time event notification ---
These operations act on a gpr_event, which should be initialized with
gpr_ev_init(), or with GPR_EVENT_INIT if static, e.g.,
static gpr_event event_var = GPR_EVENT_INIT;
It requires no destruction. */
/* Initialize *ev. */
GPR_API void gpr_event_init(gpr_event *ev);
/* Set *ev so that gpr_event_get() and gpr_event_wait() will return value.
Requires: *ev initialized; value != NULL; no prior or concurrent calls to
gpr_event_set(ev, ...) since initialization. */
GPR_API void gpr_event_set(gpr_event *ev, void *value);
/* Return the value set by gpr_event_set(ev, ...), or NULL if no such call has
completed. If the result is non-NULL, all operations that occurred prior to
the gpr_event_set(ev, ...) set will be visible after this call returns.
Requires: *ev initialized. This operation is faster than acquiring a mutex
on most platforms. */
GPR_API void *gpr_event_get(gpr_event *ev);
/* Wait until *ev is set by gpr_event_set(ev, ...), or abs_deadline is
exceeded, then return gpr_event_get(ev). Requires: *ev initialized. Use
abs_deadline==gpr_inf_future for no deadline. When the event has been
signalled before the call, this operation is faster than acquiring a mutex
on most platforms. */
GPR_API void *gpr_event_wait(gpr_event *ev, gpr_timespec abs_deadline);
/* --- Reference counting ---
These calls act on the type gpr_refcount. It requires no destruction. */
/* Initialize *r to value n. */
GPR_API void gpr_ref_init(gpr_refcount *r, int n);
/* Increment the reference count *r. Requires *r initialized. */
GPR_API void gpr_ref(gpr_refcount *r);
/* Increment the reference count *r by n. Requires *r initialized, n > 0. */
GPR_API void gpr_refn(gpr_refcount *r, int n);
/* Decrement the reference count *r and return non-zero iff it has reached
zero. . Requires *r initialized. */
GPR_API int gpr_unref(gpr_refcount *r);
/* --- Stats counters ---
These calls act on the integral type gpr_stats_counter. It requires no
destruction. Static instances may be initialized with
gpr_stats_counter c = GPR_STATS_INIT;
Beware: These operations do not imply memory barriers. Do not use them to
synchronize other events. */
/* Initialize *c to the value n. */
GPR_API void gpr_stats_init(gpr_stats_counter *c, intptr_t n);
/* *c += inc. Requires: *c initialized. */
GPR_API void gpr_stats_inc(gpr_stats_counter *c, intptr_t inc);
/* Return *c. Requires: *c initialized. */
GPR_API intptr_t gpr_stats_read(const gpr_stats_counter *c);
/* ==================Example use of interface===================
A producer-consumer queue of up to N integers,
illustrating the use of the calls in this interface. */
#if 0
#define N 4
typedef struct queue {
gpr_cv non_empty; /* Signalled when length becomes non-zero. */
gpr_cv non_full; /* Signalled when length becomes non-N. */
gpr_mu mu; /* Protects all fields below.
(That is, except during initialization or
destruction, the fields below should be accessed
only by a thread that holds mu.) */
int head; /* Index of head of queue 0..N-1. */
int length; /* Number of valid elements in queue 0..N. */
int elem[N]; /* elem[head .. head+length-1] are queue elements. */
} queue;
/* Initialize *q. */
void queue_init(queue *q) {
gpr_mu_init(&q->mu);
gpr_cv_init(&q->non_empty);
gpr_cv_init(&q->non_full);
q->head = 0;
q->length = 0;
}
/* Free storage associated with *q. */
void queue_destroy(queue *q) {
gpr_mu_destroy(&q->mu);
gpr_cv_destroy(&q->non_empty);
gpr_cv_destroy(&q->non_full);
}
/* Wait until there is room in *q, then append x to *q. */
void queue_append(queue *q, int x) {
gpr_mu_lock(&q->mu);
/* To wait for a predicate without a deadline, loop on the negation of the
predicate, and use gpr_cv_wait(..., gpr_inf_future) inside the loop
to release the lock, wait, and reacquire on each iteration. Code that
makes the condition true should use gpr_cv_broadcast() on the
corresponding condition variable. The predicate must be on state
protected by the lock. */
while (q->length == N) {
gpr_cv_wait(&q->non_full, &q->mu, gpr_inf_future);
}
if (q->length == 0) { /* Wake threads blocked in queue_remove(). */
/* It's normal to use gpr_cv_broadcast() or gpr_signal() while
holding the lock. */
gpr_cv_broadcast(&q->non_empty);
}
q->elem[(q->head + q->length) % N] = x;
q->length++;
gpr_mu_unlock(&q->mu);
}
/* If it can be done without blocking, append x to *q and return non-zero.
Otherwise return 0. */
int queue_try_append(queue *q, int x) {
int result = 0;
if (gpr_mu_trylock(&q->mu)) {
if (q->length != N) {
if (q->length == 0) { /* Wake threads blocked in queue_remove(). */
gpr_cv_broadcast(&q->non_empty);
}
q->elem[(q->head + q->length) % N] = x;
q->length++;
result = 1;
}
gpr_mu_unlock(&q->mu);
}
return result;
}
/* Wait until the *q is non-empty or deadline abs_deadline passes. If the
queue is non-empty, remove its head entry, place it in *head, and return
non-zero. Otherwise return 0. */
int queue_remove(queue *q, int *head, gpr_timespec abs_deadline) {
int result = 0;
gpr_mu_lock(&q->mu);
/* To wait for a predicate with a deadline, loop on the negation of the
predicate or until gpr_cv_wait() returns true. Code that makes
the condition true should use gpr_cv_broadcast() on the corresponding
condition variable. The predicate must be on state protected by the
lock. */
while (q->length == 0 &&
!gpr_cv_wait(&q->non_empty, &q->mu, abs_deadline)) {
}
if (q->length != 0) { /* Queue is non-empty. */
result = 1;
if (q->length == N) { /* Wake threads blocked in queue_append(). */
gpr_cv_broadcast(&q->non_full);
}
*head = q->elem[q->head];
q->head = (q->head + 1) % N;
q->length--;
} /* else deadline exceeded */
gpr_mu_unlock(&q->mu);
return result;
}
#endif /* 0 */
#ifdef __cplusplus
}
#endif
#endif /* GRPC_IMPL_CODEGEN_SYNC_H */

@ -0,0 +1,55 @@
/*
*
* Copyright 2015-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_IMPL_CODEGEN_SYNC_GENERIC_H
#define GRPC_IMPL_CODEGEN_SYNC_GENERIC_H
/* Generic type defintions for gpr_sync. */
#include <grpc/impl/codegen/atm.h>
/* gpr_event */
typedef struct { gpr_atm state; } gpr_event;
#define GPR_EVENT_INIT \
{ 0 }
/* gpr_refcount */
typedef struct { gpr_atm count; } gpr_refcount;
/* gpr_stats_counter */
typedef struct { gpr_atm value; } gpr_stats_counter;
#define GPR_STATS_INIT \
{ 0 }
#endif /* GRPC_IMPL_CODEGEN_SYNC_GENERIC_H */

@ -0,0 +1,47 @@
/*
*
* Copyright 2015-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_IMPL_CODEGEN_SYNC_POSIX_H
#define GRPC_IMPL_CODEGEN_SYNC_POSIX_H
#include <grpc/impl/codegen/sync_generic.h>
#include <pthread.h>
typedef pthread_mutex_t gpr_mu;
typedef pthread_cond_t gpr_cv;
typedef pthread_once_t gpr_once;
#define GPR_ONCE_INIT PTHREAD_ONCE_INIT
#endif /* GRPC_IMPL_CODEGEN_SYNC_POSIX_H */

@ -0,0 +1,49 @@
/*
*
* Copyright 2015-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_IMPL_CODEGEN_SYNC_WIN32_H
#define GRPC_IMPL_CODEGEN_SYNC_WIN32_H
#include <grpc/impl/codegen/sync_generic.h>
typedef struct {
CRITICAL_SECTION cs; /* Not an SRWLock until Vista is unsupported */
int locked;
} gpr_mu;
typedef CONDITION_VARIABLE gpr_cv;
typedef INIT_ONCE gpr_once;
#define GPR_ONCE_INIT INIT_ONCE_STATIC_INIT
#endif /* GRPC_IMPL_CODEGEN_SYNC_WIN32_H */

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

Loading…
Cancel
Save