Merge branch 'master' of https://github.com/grpc/grpc into no-more-extern-c

pull/13432/head
ncteisen 7 years ago
commit aa358d5e43
  1. 14
      BUILD
  2. 32
      CMakeLists.txt
  3. 41
      Makefile
  4. 16
      build.yaml
  5. 1
      config.m4
  6. 1
      config.w32
  7. 197
      doc/core/transport_explainer.md
  8. 1
      doc/g_stands_for.md
  9. 5
      gRPC-Core.podspec
  10. 2
      gRPC-ProtoRPC.podspec
  11. 2
      gRPC-RxLibrary.podspec
  12. 2
      gRPC.podspec
  13. 2
      grpc.gemspec
  14. 1
      grpc.gyp
  15. 2
      include/grpc/grpc_security.h
  16. 2
      include/grpc/support/alloc.h
  17. 2
      include/grpc/support/log.h
  18. 6
      package.xml
  19. 2
      src/core/ext/filters/client_channel/subchannel_index.cc
  20. 137
      src/core/lib/support/stack_lockfree.cc
  21. 38
      src/core/lib/support/stack_lockfree.h
  22. 2
      src/core/lib/surface/version.cc
  23. 2
      src/cpp/common/version_cc.cc
  24. 2
      src/csharp/Grpc.Core/Version.csproj.include
  25. 4
      src/csharp/Grpc.Core/VersionInfo.cs
  26. 2
      src/csharp/build_packages_dotnetcli.bat
  27. 4
      src/csharp/build_packages_dotnetcli.sh
  28. 2
      src/objective-c/!ProtoCompiler-gRPCPlugin.podspec
  29. 6
      src/objective-c/GRPCClient/GRPCCall.m
  30. 4
      src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.h
  31. 4
      src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m
  32. 2
      src/objective-c/GRPCClient/private/GRPCHost.m
  33. 10
      src/objective-c/GRPCClient/private/GRPCWrappedCall.h
  34. 14
      src/objective-c/GRPCClient/private/GRPCWrappedCall.m
  35. 2
      src/objective-c/GRPCClient/private/version.h
  36. 2
      src/objective-c/RxLibrary/GRXConcurrentWriteable.h
  37. 2
      src/objective-c/RxLibrary/GRXConcurrentWriteable.m
  38. 2
      src/objective-c/RxLibrary/GRXImmediateWriter.h
  39. 2
      src/objective-c/RxLibrary/GRXImmediateWriter.m
  40. 2
      src/objective-c/RxLibrary/GRXWriter+Immediate.h
  41. 2
      src/objective-c/RxLibrary/GRXWriter+Immediate.m
  42. 2
      src/objective-c/RxLibrary/NSEnumerator+GRXUtil.h
  43. 2
      src/objective-c/RxLibrary/NSEnumerator+GRXUtil.m
  44. 2
      src/objective-c/RxLibrary/private/GRXNSBlockEnumerator.h
  45. 4
      src/objective-c/RxLibrary/private/GRXNSBlockEnumerator.m
  46. 2
      src/objective-c/tests/version.h
  47. 2
      src/php/composer.json
  48. 2
      src/php/ext/grpc/version.h
  49. 2
      src/python/grpcio/grpc/_grpcio_metadata.py
  50. 1
      src/python/grpcio/grpc_core_dependencies.py
  51. 2
      src/python/grpcio/grpc_version.py
  52. 2
      src/python/grpcio_health_checking/grpc_version.py
  53. 2
      src/python/grpcio_reflection/grpc_version.py
  54. 2
      src/python/grpcio_testing/grpc_version.py
  55. 2
      src/python/grpcio_tests/grpc_version.py
  56. 6
      src/ruby/end2end/channel_closing_driver.rb
  57. 7
      src/ruby/end2end/channel_state_driver.rb
  58. 6
      src/ruby/end2end/end2end_common.rb
  59. 6
      src/ruby/end2end/forking_client_driver.rb
  60. 2
      src/ruby/end2end/grpc_class_init_client.rb
  61. 56
      src/ruby/end2end/killed_client_thread_driver.rb
  62. 2
      src/ruby/end2end/multiple_killed_watching_threads_driver.rb
  63. 30
      src/ruby/end2end/sig_handling_client.rb
  64. 35
      src/ruby/end2end/sig_handling_driver.rb
  65. 4
      src/ruby/end2end/sig_int_during_channel_watch_driver.rb
  66. 6
      src/ruby/ext/grpc/rb_grpc_imports.generated.h
  67. 37
      src/ruby/lib/grpc/generic/rpc_server.rb
  68. 2
      src/ruby/lib/grpc/version.rb
  69. 14
      src/ruby/pb/grpc/health/checker.rb
  70. 12
      src/ruby/qps/worker.rb
  71. 29
      src/ruby/spec/pb/health/checker_spec.rb
  72. 2
      src/ruby/tools/version.rb
  73. 22
      test/core/support/BUILD
  74. 140
      test/core/support/stack_lockfree_test.cc
  75. 2
      tools/distrib/python/grpcio_tools/grpc_version.py
  76. 2
      tools/doxygen/Doxyfile.c++
  77. 3
      tools/doxygen/Doxyfile.c++.internal
  78. 1
      tools/doxygen/Doxyfile.core
  79. 3
      tools/doxygen/Doxyfile.core.internal
  80. 2
      tools/interop_matrix/run_interop_matrix_tests.py
  81. 18
      tools/run_tests/generated/sources_and_headers.json
  82. 24
      tools/run_tests/generated/tests.json

14
BUILD

@ -455,7 +455,6 @@ grpc_cc_library(
"src/core/lib/support/log_windows.cc",
"src/core/lib/support/mpscq.cc",
"src/core/lib/support/murmur_hash.cc",
"src/core/lib/support/stack_lockfree.cc",
"src/core/lib/support/string.cc",
"src/core/lib/support/string_posix.cc",
"src/core/lib/support/string_util_windows.cc",
@ -486,23 +485,22 @@ grpc_cc_library(
"src/core/lib/support/atomic_with_atm.h",
"src/core/lib/support/atomic_with_std.h",
"src/core/lib/support/env.h",
"src/core/lib/support/memory.h",
"src/core/lib/support/vector.h",
"src/core/lib/support/manual_constructor.h",
"src/core/lib/support/memory.h",
"src/core/lib/support/mpscq.h",
"src/core/lib/support/murmur_hash.h",
"src/core/lib/support/spinlock.h",
"src/core/lib/support/stack_lockfree.h",
"src/core/lib/support/string.h",
"src/core/lib/support/string_windows.h",
"src/core/lib/support/time_precise.h",
"src/core/lib/support/tmpfile.h",
"src/core/lib/support/vector.h",
],
language = "c++",
public_hdrs = GPR_PUBLIC_HDRS,
deps = [
"gpr_codegen",
"@com_google_absl//absl/container:inlined_vector"
"@com_google_absl//absl/container:inlined_vector",
],
)
@ -672,6 +670,7 @@ grpc_cc_library(
"src/core/lib/transport/transport_op_string.cc",
],
hdrs = [
"src/core/lib/backoff/backoff.h",
"src/core/lib/channel/channel_args.h",
"src/core/lib/channel/channel_stack.h",
"src/core/lib/channel/channel_stack_builder.h",
@ -690,6 +689,7 @@ grpc_cc_library(
"src/core/lib/http/format_request.h",
"src/core/lib/http/httpcli.h",
"src/core/lib/http/parser.h",
"src/core/lib/iomgr/block_annotate.h",
"src/core/lib/iomgr/call_combiner.h",
"src/core/lib/iomgr/closure.h",
"src/core/lib/iomgr/combiner.h",
@ -734,7 +734,6 @@ grpc_cc_library(
"src/core/lib/iomgr/socket_utils_posix.h",
"src/core/lib/iomgr/socket_windows.h",
"src/core/lib/iomgr/sys_epoll_wrapper.h",
"src/core/lib/iomgr/block_annotate.h",
"src/core/lib/iomgr/tcp_client.h",
"src/core/lib/iomgr/tcp_client_posix.h",
"src/core/lib/iomgr/tcp_posix.h",
@ -790,7 +789,6 @@ grpc_cc_library(
"src/core/lib/transport/timeout_encoding.h",
"src/core/lib/transport/transport.h",
"src/core/lib/transport/transport_impl.h",
"src/core/lib/backoff/backoff.h",
],
external_deps = [
"zlib",
@ -1250,8 +1248,8 @@ grpc_cc_library(
"src/core/ext/transport/chttp2/transport/bin_decoder.h",
"src/core/ext/transport/chttp2/transport/bin_encoder.h",
"src/core/ext/transport/chttp2/transport/chttp2_transport.h",
"src/core/ext/transport/chttp2/transport/frame.h",
"src/core/ext/transport/chttp2/transport/flow_control.h",
"src/core/ext/transport/chttp2/transport/frame.h",
"src/core/ext/transport/chttp2/transport/frame_data.h",
"src/core/ext/transport/chttp2/transport/frame_goaway.h",
"src/core/ext/transport/chttp2/transport/frame_ping.h",

@ -24,7 +24,7 @@
cmake_minimum_required(VERSION 2.8)
set(PACKAGE_NAME "grpc")
set(PACKAGE_VERSION "1.8.0-dev")
set(PACKAGE_VERSION "1.9.0-dev")
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}")
set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/")
@ -433,7 +433,6 @@ add_dependencies(buildtests_c gpr_log_test)
add_dependencies(buildtests_c gpr_manual_constructor_test)
add_dependencies(buildtests_c gpr_mpscq_test)
add_dependencies(buildtests_c gpr_spinlock_test)
add_dependencies(buildtests_c gpr_stack_lockfree_test)
add_dependencies(buildtests_c gpr_string_test)
add_dependencies(buildtests_c gpr_sync_test)
add_dependencies(buildtests_c gpr_thd_test)
@ -807,7 +806,6 @@ add_library(gpr
src/core/lib/support/log_windows.cc
src/core/lib/support/mpscq.cc
src/core/lib/support/murmur_hash.cc
src/core/lib/support/stack_lockfree.cc
src/core/lib/support/string.cc
src/core/lib/support/string_posix.cc
src/core/lib/support/string_util_windows.cc
@ -6475,34 +6473,6 @@ target_link_libraries(gpr_spinlock_test
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(gpr_stack_lockfree_test
test/core/support/stack_lockfree_test.cc
)
target_include_directories(gpr_stack_lockfree_test
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${BORINGSSL_ROOT_DIR}/include
PRIVATE ${PROTOBUF_ROOT_DIR}/src
PRIVATE ${BENCHMARK_ROOT_DIR}/include
PRIVATE ${ZLIB_ROOT_DIR}
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
PRIVATE ${CARES_INCLUDE_DIR}
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/third_party/abseil-cpp
)
target_link_libraries(gpr_stack_lockfree_test
${_gRPC_ALLTARGETS_LIBRARIES}
gpr_test_util
gpr
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(gpr_string_test
test/core/support/string_test.cc
)

@ -412,8 +412,8 @@ Q = @
endif
CORE_VERSION = 5.0.0-dev
CPP_VERSION = 1.8.0-dev
CSHARP_VERSION = 1.8.0-dev
CPP_VERSION = 1.9.0-dev
CSHARP_VERSION = 1.9.0-dev
CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES))
CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS)
@ -994,7 +994,6 @@ gpr_log_test: $(BINDIR)/$(CONFIG)/gpr_log_test
gpr_manual_constructor_test: $(BINDIR)/$(CONFIG)/gpr_manual_constructor_test
gpr_mpscq_test: $(BINDIR)/$(CONFIG)/gpr_mpscq_test
gpr_spinlock_test: $(BINDIR)/$(CONFIG)/gpr_spinlock_test
gpr_stack_lockfree_test: $(BINDIR)/$(CONFIG)/gpr_stack_lockfree_test
gpr_string_test: $(BINDIR)/$(CONFIG)/gpr_string_test
gpr_sync_test: $(BINDIR)/$(CONFIG)/gpr_sync_test
gpr_thd_test: $(BINDIR)/$(CONFIG)/gpr_thd_test
@ -1389,7 +1388,6 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/gpr_manual_constructor_test \
$(BINDIR)/$(CONFIG)/gpr_mpscq_test \
$(BINDIR)/$(CONFIG)/gpr_spinlock_test \
$(BINDIR)/$(CONFIG)/gpr_stack_lockfree_test \
$(BINDIR)/$(CONFIG)/gpr_string_test \
$(BINDIR)/$(CONFIG)/gpr_sync_test \
$(BINDIR)/$(CONFIG)/gpr_thd_test \
@ -1840,8 +1838,6 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/gpr_mpscq_test || ( echo test gpr_mpscq_test failed ; exit 1 )
$(E) "[RUN] Testing gpr_spinlock_test"
$(Q) $(BINDIR)/$(CONFIG)/gpr_spinlock_test || ( echo test gpr_spinlock_test failed ; exit 1 )
$(E) "[RUN] Testing gpr_stack_lockfree_test"
$(Q) $(BINDIR)/$(CONFIG)/gpr_stack_lockfree_test || ( echo test gpr_stack_lockfree_test failed ; exit 1 )
$(E) "[RUN] Testing gpr_string_test"
$(Q) $(BINDIR)/$(CONFIG)/gpr_string_test || ( echo test gpr_string_test failed ; exit 1 )
$(E) "[RUN] Testing gpr_sync_test"
@ -2836,7 +2832,6 @@ LIBGPR_SRC = \
src/core/lib/support/log_windows.cc \
src/core/lib/support/mpscq.cc \
src/core/lib/support/murmur_hash.cc \
src/core/lib/support/stack_lockfree.cc \
src/core/lib/support/string.cc \
src/core/lib/support/string_posix.cc \
src/core/lib/support/string_util_windows.cc \
@ -10258,38 +10253,6 @@ endif
endif
GPR_STACK_LOCKFREE_TEST_SRC = \
test/core/support/stack_lockfree_test.cc \
GPR_STACK_LOCKFREE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GPR_STACK_LOCKFREE_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/gpr_stack_lockfree_test: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/gpr_stack_lockfree_test: $(GPR_STACK_LOCKFREE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(GPR_STACK_LOCKFREE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_stack_lockfree_test
endif
$(OBJDIR)/$(CONFIG)/test/core/support/stack_lockfree_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_gpr_stack_lockfree_test: $(GPR_STACK_LOCKFREE_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(GPR_STACK_LOCKFREE_TEST_OBJS:.o=.dep)
endif
endif
GPR_STRING_TEST_SRC = \
test/core/support/string_test.cc \

@ -13,8 +13,8 @@ settings:
'#09': Per-language overrides are possible with (eg) ruby_version tag here
'#10': See the expand_version.py for all the quirks here
core_version: 5.0.0-dev
g_stands_for: generous
version: 1.8.0-dev
g_stands_for: glossy
version: 1.9.0-dev
filegroups:
- name: census
public_headers:
@ -49,7 +49,6 @@ filegroups:
- src/core/lib/support/log_windows.cc
- src/core/lib/support/mpscq.cc
- src/core/lib/support/murmur_hash.cc
- src/core/lib/support/stack_lockfree.cc
- src/core/lib/support/string.cc
- src/core/lib/support/string_posix.cc
- src/core/lib/support/string_util_windows.cc
@ -115,7 +114,6 @@ filegroups:
- src/core/lib/support/mpscq.h
- src/core/lib/support/murmur_hash.h
- src/core/lib/support/spinlock.h
- src/core/lib/support/stack_lockfree.h
- src/core/lib/support/string.h
- src/core/lib/support/string_windows.h
- src/core/lib/support/time_precise.h
@ -2246,16 +2244,6 @@ targets:
- gpr_test_util
- gpr
uses_polling: false
- name: gpr_stack_lockfree_test
cpu_cost: 7
build: test
language: c
src:
- test/core/support/stack_lockfree_test.cc
deps:
- gpr_test_util
- gpr
uses_polling: false
- name: gpr_string_test
build: test
language: c

@ -62,7 +62,6 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/support/log_windows.cc \
src/core/lib/support/mpscq.cc \
src/core/lib/support/murmur_hash.cc \
src/core/lib/support/stack_lockfree.cc \
src/core/lib/support/string.cc \
src/core/lib/support/string_posix.cc \
src/core/lib/support/string_util_windows.cc \

@ -39,7 +39,6 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\support\\log_windows.cc " +
"src\\core\\lib\\support\\mpscq.cc " +
"src\\core\\lib\\support\\murmur_hash.cc " +
"src\\core\\lib\\support\\stack_lockfree.cc " +
"src\\core\\lib\\support\\string.cc " +
"src\\core\\lib\\support\\string_posix.cc " +
"src\\core\\lib\\support\\string_util_windows.cc " +

@ -0,0 +1,197 @@
# Transport Explainer
@vjpai
## Existing Transports
[gRPC
transports](https://github.com/grpc/grpc/tree/master/src/core/ext/transport)
plug in below the core API (one level below the C++ or other wrapped-language
API). You can write your transport in C or C++ though; currently (Nov 2017) all
the transports are nominally written in C++ though they are idiomatically C. The
existing transports are:
* [HTTP/2](https://github.com/grpc/grpc/tree/master/src/core/ext/transport/chttp2)
* [Cronet](https://github.com/grpc/grpc/tree/master/src/core/ext/transport/cronet)
* [In-process](https://github.com/grpc/grpc/tree/master/src/core/ext/transport/inproc)
Among these, the in-process is likely the easiest to understand, though arguably
also the least similar to a "real" sockets-based transport since it is only used
in a single process.
## Transport stream ops
In the gRPC core implementation, a fundamental struct is the
`grpc_transport_stream_op_batch` which represents a collection of stream
operations sent to a transport. (Note that in gRPC, _stream_ and _RPC_ are used
synonymously since all RPCs are actually streams internally.) The ops in a batch
can include:
* send\_initial\_metadata
- Client: initate an RPC
- Server: supply response headers
* recv\_initial\_metadata
- Client: get response headers
- Server: accept an RPC
* send\_message (zero or more) : send a data buffer
* recv\_message (zero or more) : receive a data buffer
* send\_trailing\_metadata
- Client: half-close indicating that no more messages will be coming
- Server: full-close providing final status for the RPC
* recv\_trailing\_metadata: get final status for the RPC
- Server extra: This op shouldn't actually be considered complete until the
server has also sent trailing metadata to provide the other side with final
status
* cancel\_stream: Attempt to cancel an RPC
* collect\_stats: Get stats
The fundamental responsibility of the transport is to transform between this
internal format and an actual wire format, so the processing of these operations
is largely transport-specific.
One or more of these ops are grouped into a batch. Applications can start all of
a call's ops in a single batch, or they can split them up into multiple
batches. Results of each batch are returned asynchronously via a completion
queue.
Internally, we use callbacks to indicate completion. The surface layer creates a
callback when starting a new batch and sends it down the filter stack along with
the batch. The transport must invoke this callback when the batch is complete,
and then the surface layer returns an event to the application via the
completion queue. Each batch can have up to 3 callbacks:
* recv\_initial\_metadata\_ready (called by the transport when the
recv\_initial\_metadata op is complete)
* recv\_message\_ready (called by the transport when the recv_message op is
complete)
* on\_complete (called by the transport when the entire batch is complete)
## Timelines of transport stream op batches
The transport's job is to sequence and interpret various possible interleavings
of the basic stream ops. For example, a sample timeline of batches would be:
1. Client send\_initial\_metadata: Initiate an RPC with a path (method) and authority
1. Server recv\_initial\_metadata: accept an RPC
1. Client send\_message: Supply the input proto for the RPC
1. Server recv\_message: Get the input proto from the RPC
1. Client send\_trailing\_metadata: This is a half-close indicating that the
client will not be sending any more messages
1. Server recv\_trailing\_metadata: The server sees this from the client and
knows that it will not get any more messages. This won't complete yet though,
as described above.
1. Server send\_initial\_metadata, send\_message, send\_trailing\_metadata: A
batch can contain multiple ops, and this batch provides the RPC response
headers, response content, and status. Note that sending the trailing
metadata will also complete the server's receive of trailing metadata.
1. Client recv\_initial\_metadata: The number of ops in one side of the batch
has no relation with the number of ops on the other side of the batch. In
this case, the client is just collecting the response headers.
1. Client recv\_message, recv\_trailing\_metadata: Get the data response and
status
There are other possible sample timelines. For example, for client-side streaming, a "typical" sequence would be:
1. Server: recv\_initial\_metadata
- At API-level, that would be the server requesting an RPC
1. Server: recv\_trailing\_metadata
- This is for when the server wants to know the final completion of the RPC
through an `AsyncNotifyWhenDone` API in C++
1. Client: send\_initial\_metadata, recv\_message, recv\_trailing\_metadata
- At API-level, that's a client invoking a client-side streaming call. The
send\_initial\_metadata is the call invocation, the recv\_message colects
the final response from the server, and the recv\_trailing\_metadata gets
the `grpc::Status` value that will be returned from the call
1. Client: send\_message / Server: recv\_message
- Repeat the above step numerous times; these correspond to a client issuing
`Write` in a loop and a server doing `Read` in a loop until `Read` fails
1. Client: send\_trailing\_metadata / Server: recv\_message that indicates doneness (NULL)
- These correspond to a client issuing `WritesDone` which causes the server's
`Read` to fail
1. Server: send\_message, send\_trailing\_metadata
- These correpond to the server doing `Finish`
The sends on one side will call their own callbacks when complete, and they will
in turn trigger actions that cause the other side's recv operations to
complete. In some transports, a send can sometimes complete before the recv on
the other side (e.g., in HTTP/2 if there is sufficient flow-control buffer space
available)
## Other transport duties
In addition to these basic stream ops, the transport must handle cancellations
of a stream at any time and pass their effects to the other side. For example,
in HTTP/2, this triggers a `RST_STREAM` being sent on the wire. The transport
must perform operations like pings and statistics that are used to shape
transport-level characteristics like flow control (see, for example, their use
in the HTTP/2 transport).
## Putting things together with detail: Sending Metadata
* API layer: `map<string, string>` that is specific to this RPC
* Core surface layer: array of `{slice, slice}` pairs where each slice
references an underlying string
* [Core transport
layer](https://github.com/grpc/grpc/tree/master/src/core/lib/transport): list
of `{slice, slice}` pairs that includes the above plus possibly some general
metadata (e.g., Method and Authority for initial metadata)
* [Specific transport
layer](https://github.com/grpc/grpc/tree/master/src/core/ext/transport):
- Either send it to the other side using transport-specific API (e.g., Cronet)
- Or have it sent through the [iomgr/endpoint
layer](https://github.com/grpc/grpc/tree/master/src/core/lib/iomgr) (e.g.,
HTTP/2)
- Or just manipulate pointers to get it from one side to the other (e.g.,
In-process)
## Requirements for any transport
Each transport implements several operations in a vtbl (may change to actual
virtual functions as transport moves to idiomatic C++).
The most important and common one is `perform_stream_op`. This function
processes a single stream op batch on a specific stream that is associated with
a specific transport:
* Gets the 6 ops/cancel passed down from the surface
* Pass metadata from one side to the other as described above
* Transform messages between slice buffer structure and stream of bytes to pass
to other side
- May require insertion of extra bytes (e.g., per-message headers in HTTP/2)
* React to metadata to preserve expected orderings (*)
* Schedule invocation of completion callbacks
There are other functions in the vtbl as well.
* `perform_transport_op`
- Configure the transport instance for the connectivity state change notifier
or the server-side accept callback
- Disconnect transport or set up a goaway for later streams
* `init_stream`
- Starts a stream from the client-side
- (*) Server-side of the transport must call `accept_stream_cb` when a new
stream is available
* Triggers request-matcher
* `destroy_stream`, `destroy_transport`
- Free up data related to a stream or transport
* `set_pollset`, `set_pollset_set`, `get_endpoint`
- Map each specific instance of the transport to FDs being used by iomgr (for
HTTP/2)
- Get a pointer to the endpoint structure that actually moves the data
(wrapper around a socket for HTTP/2)
## Book-keeping responsibilities of the transport layer
A given transport must keep all of its transport and streams ref-counted. This
is essential to make sure that no struct disappears before it is done being
used.
A transport must also preserve relevant orders for the different categories of
ops on a stream, as described above. A transport must also make sure that all
relevant batch operations have completed before scheduling the `on_complete`
closure for a batch. Further examples include the idea that the server logic
expects to not complete recv\_trailing\_metadata until after it actually sends
trailing metadata since it would have already found this out by seeing a NULL’ed
recv\_message. This is considered part of the transport's duties in preserving
orders.

@ -12,3 +12,4 @@ future), and the corresponding version numbers that used them:
- 1.6 'g' stands for 'garcia'
- 1.7 'g' stands for 'gambit'
- 1.8 'g' stands for 'generous'
- 1.9 'g' stands for 'glossy'

@ -22,7 +22,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-Core'
version = '1.8.0-dev'
version = '1.9.0-dev'
s.version = version
s.summary = 'Core cross-platform gRPC library, written in C'
s.homepage = 'https://grpc.io'
@ -198,7 +198,6 @@ Pod::Spec.new do |s|
'src/core/lib/support/mpscq.h',
'src/core/lib/support/murmur_hash.h',
'src/core/lib/support/spinlock.h',
'src/core/lib/support/stack_lockfree.h',
'src/core/lib/support/string.h',
'src/core/lib/support/string_windows.h',
'src/core/lib/support/time_precise.h',
@ -226,7 +225,6 @@ Pod::Spec.new do |s|
'src/core/lib/support/log_windows.cc',
'src/core/lib/support/mpscq.cc',
'src/core/lib/support/murmur_hash.cc',
'src/core/lib/support/stack_lockfree.cc',
'src/core/lib/support/string.cc',
'src/core/lib/support/string_posix.cc',
'src/core/lib/support/string_util_windows.cc',
@ -718,7 +716,6 @@ Pod::Spec.new do |s|
'src/core/lib/support/mpscq.h',
'src/core/lib/support/murmur_hash.h',
'src/core/lib/support/spinlock.h',
'src/core/lib/support/stack_lockfree.h',
'src/core/lib/support/string.h',
'src/core/lib/support/string_windows.h',
'src/core/lib/support/time_precise.h',

@ -21,7 +21,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-ProtoRPC'
version = '1.8.0-dev'
version = '1.9.0-dev'
s.version = version
s.summary = 'RPC library for Protocol Buffers, based on gRPC'
s.homepage = 'https://grpc.io'

@ -21,7 +21,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-RxLibrary'
version = '1.8.0-dev'
version = '1.9.0-dev'
s.version = version
s.summary = 'Reactive Extensions library for iOS/OSX.'
s.homepage = 'https://grpc.io'

@ -20,7 +20,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC'
version = '1.8.0-dev'
version = '1.9.0-dev'
s.version = version
s.summary = 'gRPC client library for iOS/OSX'
s.homepage = 'https://grpc.io'

@ -95,7 +95,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/support/mpscq.h )
s.files += %w( src/core/lib/support/murmur_hash.h )
s.files += %w( src/core/lib/support/spinlock.h )
s.files += %w( src/core/lib/support/stack_lockfree.h )
s.files += %w( src/core/lib/support/string.h )
s.files += %w( src/core/lib/support/string_windows.h )
s.files += %w( src/core/lib/support/time_precise.h )
@ -123,7 +122,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/support/log_windows.cc )
s.files += %w( src/core/lib/support/mpscq.cc )
s.files += %w( src/core/lib/support/murmur_hash.cc )
s.files += %w( src/core/lib/support/stack_lockfree.cc )
s.files += %w( src/core/lib/support/string.cc )
s.files += %w( src/core/lib/support/string_posix.cc )
s.files += %w( src/core/lib/support/string_util_windows.cc )

@ -184,7 +184,6 @@
'src/core/lib/support/log_windows.cc',
'src/core/lib/support/mpscq.cc',
'src/core/lib/support/murmur_hash.cc',
'src/core/lib/support/stack_lockfree.cc',
'src/core/lib/support/string.cc',
'src/core/lib/support/string_posix.cc',
'src/core/lib/support/string_util_windows.cc',

@ -185,7 +185,7 @@ GRPCAPI grpc_call_credentials* grpc_composite_call_credentials_create(
GRPCAPI grpc_call_credentials* grpc_google_compute_engine_credentials_create(
void* reserved);
GRPCAPI gpr_timespec grpc_max_auth_token_lifetime();
GRPCAPI gpr_timespec grpc_max_auth_token_lifetime(void);
/** 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.

@ -58,7 +58,7 @@ GPRAPI void gpr_free_aligned(void* ptr);
GPRAPI void gpr_set_allocation_functions(gpr_allocation_functions functions);
/** Return the family of allocation functions currently in effect. */
GPRAPI gpr_allocation_functions gpr_get_allocation_functions();
GPRAPI gpr_allocation_functions gpr_get_allocation_functions(void);
#ifdef __cplusplus
}

@ -68,7 +68,7 @@ GPRAPI void gpr_log_message(const char* file, int line,
/** Set global log verbosity */
GPRAPI void gpr_set_log_verbosity(gpr_log_severity min_severity_to_print);
GPRAPI void gpr_log_verbosity_init();
GPRAPI void gpr_log_verbosity_init(void);
/** Log overrides: applications can use this API to intercept logging calls
and use their own implementations */

@ -13,8 +13,8 @@
<date>2017-08-24</date>
<time>16:06:07</time>
<version>
<release>1.8.0dev</release>
<api>1.8.0dev</api>
<release>1.9.0dev</release>
<api>1.9.0dev</api>
</version>
<stability>
<release>beta</release>
@ -107,7 +107,6 @@
<file baseinstalldir="/" name="src/core/lib/support/mpscq.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/murmur_hash.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/spinlock.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/stack_lockfree.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/string.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/string_windows.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/time_precise.h" role="src" />
@ -135,7 +134,6 @@
<file baseinstalldir="/" name="src/core/lib/support/log_windows.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/mpscq.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/murmur_hash.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/stack_lockfree.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/string.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/string_posix.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/string_util_windows.cc" role="src" />

@ -163,7 +163,7 @@ grpc_subchannel* grpc_subchannel_index_register(grpc_exec_ctx* exec_ctx,
grpc_subchannel_key* key,
grpc_subchannel* constructed) {
grpc_subchannel* c = nullptr;
bool need_to_unref_constructed;
bool need_to_unref_constructed = false;
while (c == nullptr) {
need_to_unref_constructed = false;

@ -1,137 +0,0 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include "src/core/lib/support/stack_lockfree.h"
#include <stdlib.h>
#include <string.h>
#include <grpc/support/alloc.h>
#include <grpc/support/atm.h>
#include <grpc/support/log.h>
#include <grpc/support/port_platform.h>
/* The lockfree node structure is a single architecture-level
word that allows for an atomic CAS to set it up. */
struct lockfree_node_contents {
/* next thing to look at. Actual index for head, next index otherwise */
uint16_t index;
#ifdef GPR_ARCH_64
uint16_t pad;
uint32_t aba_ctr;
#else
#ifdef GPR_ARCH_32
uint16_t aba_ctr;
#else
#error Unsupported bit width architecture
#endif
#endif
};
/* Use a union to make sure that these are in the same bits as an atm word */
typedef union lockfree_node {
gpr_atm atm;
struct lockfree_node_contents contents;
} lockfree_node;
/* make sure that entries aligned to 8-bytes */
#define ENTRY_ALIGNMENT_BITS 3
/* reserve this entry as invalid */
#define INVALID_ENTRY_INDEX ((1 << 16) - 1)
struct gpr_stack_lockfree {
lockfree_node* entries;
lockfree_node head; /* An atomic entry describing curr head */
};
gpr_stack_lockfree* gpr_stack_lockfree_create(size_t entries) {
gpr_stack_lockfree* stack;
stack = (gpr_stack_lockfree*)gpr_malloc(sizeof(*stack));
/* Since we only allocate 16 bits to represent an entry number,
* make sure that we are within the desired range */
/* Reserve the highest entry number as a dummy */
GPR_ASSERT(entries < INVALID_ENTRY_INDEX);
stack->entries = (lockfree_node*)gpr_malloc_aligned(
entries * sizeof(stack->entries[0]), ENTRY_ALIGNMENT_BITS);
/* Clear out all entries */
memset(stack->entries, 0, entries * sizeof(stack->entries[0]));
memset(&stack->head, 0, sizeof(stack->head));
GPR_ASSERT(sizeof(stack->entries->atm) == sizeof(stack->entries->contents));
/* Point the head at reserved dummy entry */
stack->head.contents.index = INVALID_ENTRY_INDEX;
/* Fill in the pad and aba_ctr to avoid confusing memcheck tools */
#ifdef GPR_ARCH_64
stack->head.contents.pad = 0;
#endif
stack->head.contents.aba_ctr = 0;
return stack;
}
void gpr_stack_lockfree_destroy(gpr_stack_lockfree* stack) {
gpr_free_aligned(stack->entries);
gpr_free(stack);
}
int gpr_stack_lockfree_push(gpr_stack_lockfree* stack, int entry) {
lockfree_node head;
lockfree_node newhead;
lockfree_node curent;
lockfree_node newent;
/* First fill in the entry's index and aba ctr for new head */
newhead.contents.index = (uint16_t)entry;
#ifdef GPR_ARCH_64
/* Fill in the pad to avoid confusing memcheck tools */
newhead.contents.pad = 0;
#endif
/* Also post-increment the aba_ctr */
curent.atm = gpr_atm_no_barrier_load(&stack->entries[entry].atm);
newhead.contents.aba_ctr = ++curent.contents.aba_ctr;
gpr_atm_no_barrier_store(&stack->entries[entry].atm, curent.atm);
do {
/* Atomically get the existing head value for use */
head.atm = gpr_atm_no_barrier_load(&(stack->head.atm));
/* Point to it */
newent.atm = gpr_atm_no_barrier_load(&stack->entries[entry].atm);
newent.contents.index = head.contents.index;
gpr_atm_no_barrier_store(&stack->entries[entry].atm, newent.atm);
} while (!gpr_atm_rel_cas(&(stack->head.atm), head.atm, newhead.atm));
/* Use rel_cas above to make sure that entry index is set properly */
return head.contents.index == INVALID_ENTRY_INDEX;
}
int gpr_stack_lockfree_pop(gpr_stack_lockfree* stack) {
lockfree_node head;
lockfree_node newhead;
do {
head.atm = gpr_atm_acq_load(&(stack->head.atm));
if (head.contents.index == INVALID_ENTRY_INDEX) {
return -1;
}
newhead.atm =
gpr_atm_no_barrier_load(&(stack->entries[head.contents.index].atm));
} while (!gpr_atm_no_barrier_cas(&(stack->head.atm), head.atm, newhead.atm));
return head.contents.index;
}

@ -1,38 +0,0 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef GRPC_CORE_LIB_SUPPORT_STACK_LOCKFREE_H
#define GRPC_CORE_LIB_SUPPORT_STACK_LOCKFREE_H
#include <stddef.h>
typedef struct gpr_stack_lockfree gpr_stack_lockfree;
/* This stack must specify the maximum number of entries to track.
The current implementation only allows up to 65534 entries */
gpr_stack_lockfree* gpr_stack_lockfree_create(size_t entries);
void gpr_stack_lockfree_destroy(gpr_stack_lockfree* stack);
/* Pass in a valid entry number for the next stack entry */
/* Returns 1 if this is the first element on the stack, 0 otherwise */
int gpr_stack_lockfree_push(gpr_stack_lockfree*, int entry);
/* Returns -1 on empty or the actual entry number */
int gpr_stack_lockfree_pop(gpr_stack_lockfree* stack);
#endif /* GRPC_CORE_LIB_SUPPORT_STACK_LOCKFREE_H */

@ -23,4 +23,4 @@
const char* grpc_version_string(void) { return "5.0.0-dev"; }
const char* grpc_g_stands_for(void) { return "generous"; }
const char* grpc_g_stands_for(void) { return "glossy"; }

@ -22,5 +22,5 @@
#include <grpc++/grpc++.h>
namespace grpc {
grpc::string Version() { return "1.8.0-dev"; }
grpc::string Version() { return "1.9.0-dev"; }
} // namespace grpc

@ -1,7 +1,7 @@
<!-- This file is generated -->
<Project>
<PropertyGroup>
<GrpcCsharpVersion>1.8.0-dev</GrpcCsharpVersion>
<GrpcCsharpVersion>1.9.0-dev</GrpcCsharpVersion>
<GoogleProtobufVersion>3.3.0</GoogleProtobufVersion>
</PropertyGroup>
</Project>

@ -33,11 +33,11 @@ namespace Grpc.Core
/// <summary>
/// Current <c>AssemblyFileVersion</c> of gRPC C# assemblies
/// </summary>
public const string CurrentAssemblyFileVersion = "1.8.0.0";
public const string CurrentAssemblyFileVersion = "1.9.0.0";
/// <summary>
/// Current version of gRPC C#
/// </summary>
public const string CurrentVersion = "1.8.0-dev";
public const string CurrentVersion = "1.9.0-dev";
}
}

@ -13,7 +13,7 @@
@rem limitations under the License.
@rem Current package versions
set VERSION=1.8.0-dev
set VERSION=1.9.0-dev
@rem Adjust the location of nuget.exe
set NUGET=C:\nuget\nuget.exe

@ -39,7 +39,7 @@ dotnet pack --configuration Release Grpc.Auth --output ../../../artifacts
dotnet pack --configuration Release Grpc.HealthCheck --output ../../../artifacts
dotnet pack --configuration Release Grpc.Reflection --output ../../../artifacts
nuget pack Grpc.nuspec -Version "1.8.0-dev" -OutputDirectory ../../artifacts
nuget pack Grpc.Tools.nuspec -Version "1.8.0-dev" -OutputDirectory ../../artifacts
nuget pack Grpc.nuspec -Version "1.9.0-dev" -OutputDirectory ../../artifacts
nuget pack Grpc.Tools.nuspec -Version "1.9.0-dev" -OutputDirectory ../../artifacts
(cd ../../artifacts && zip csharp_nugets_dotnetcli.zip *.nupkg)

@ -42,7 +42,7 @@ Pod::Spec.new do |s|
# exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed
# before them.
s.name = '!ProtoCompiler-gRPCPlugin'
v = '1.8.0-dev'
v = '1.9.0-dev'
s.version = v
s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.'
s.description = <<-DESC

@ -299,7 +299,7 @@ static NSString * const kBearerPrefix = @"Bearer ";
// network queue if the write didn't succeed.
// If the call is a unary call, parameter \a errorHandler will be ignored and
// the error handler of GRPCOpSendClose will be executed in case of error.
- (void)writeMessage:(NSData *)message withErrorHandler:(void (^)())errorHandler {
- (void)writeMessage:(NSData *)message withErrorHandler:(void (^)(void))errorHandler {
__weak GRPCCall *weakSelf = self;
void(^resumingHandler)(void) = ^{
@ -345,7 +345,7 @@ static NSString * const kBearerPrefix = @"Bearer ";
// Only called from the call queue. The error handler will be called from the
// network queue if the requests stream couldn't be closed successfully.
- (void)finishRequestWithErrorHandler:(void (^)())errorHandler {
- (void)finishRequestWithErrorHandler:(void (^)(void))errorHandler {
if (!_unaryCall) {
[_wrappedCall startBatchWithOperations:@[[[GRPCOpSendClose alloc] init]]
errorHandler:errorHandler];
@ -441,7 +441,7 @@ static NSString * const kBearerPrefix = @"Bearer ";
}
_connectivityMonitor = [GRPCConnectivityMonitor monitorWithHost:host];
__weak typeof(self) weakSelf = self;
void (^handler)() = ^{
void (^handler)(void) = ^{
typeof(self) strongSelf = weakSelf;
[strongSelf finishWithError:[NSError errorWithDomain:kGRPCErrorDomain
code:GRPCErrorCodeUnavailable

@ -57,6 +57,6 @@
* Only one handler is active at a time, so if this method is called again before the previous
* handler has been called, it might never be called at all (or yes, if it has already been queued).
*/
- (void)handleLossWithHandler:(nullable void (^)())lossHandler
wifiStatusChangeHandler:(nullable void (^)())wifiStatusChangeHandler;
- (void)handleLossWithHandler:(nullable void (^)(void))lossHandler
wifiStatusChangeHandler:(nullable void (^)(void))wifiStatusChangeHandler;
@end

@ -136,8 +136,8 @@ static void PassFlagsToContextInfoBlock(SCNetworkReachabilityRef target,
return returnValue;
}
- (void)handleLossWithHandler:(nullable void (^)())lossHandler
wifiStatusChangeHandler:(nullable void (^)())wifiStatusChangeHandler {
- (void)handleLossWithHandler:(nullable void (^)(void))lossHandler
wifiStatusChangeHandler:(nullable void (^)(void))wifiStatusChangeHandler {
__weak typeof(self) weakSelf = self;
[self startListeningWithHandler:^(GRPCReachabilityFlags *flags) {
typeof(self) strongSelf = weakSelf;

@ -93,7 +93,7 @@ static GRPCConnectivityMonitor *connectivityMonitor = nil;
if (!connectivityMonitor) {
connectivityMonitor =
[GRPCConnectivityMonitor monitorWithHost:hostURL.host];
void (^handler)() = ^{
void (^handler)(void) = ^{
[GRPCHost flushChannelCache];
};
[connectivityMonitor handleLossWithHandler:handler

@ -30,24 +30,24 @@
@interface GRPCOpSendMetadata : GRPCOperation
- (instancetype)initWithMetadata:(NSDictionary *)metadata
handler:(void(^)())handler;
handler:(void(^)(void))handler;
- (instancetype)initWithMetadata:(NSDictionary *)metadata
flags:(uint32_t)flags
handler:(void(^)())handler NS_DESIGNATED_INITIALIZER;
handler:(void(^)(void))handler NS_DESIGNATED_INITIALIZER;
@end
@interface GRPCOpSendMessage : GRPCOperation
- (instancetype)initWithMessage:(NSData *)message
handler:(void(^)())handler NS_DESIGNATED_INITIALIZER;
handler:(void(^)(void))handler NS_DESIGNATED_INITIALIZER;
@end
@interface GRPCOpSendClose : GRPCOperation
- (instancetype)initWithHandler:(void(^)())handler NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithHandler:(void(^)(void))handler NS_DESIGNATED_INITIALIZER;
@end
@ -79,7 +79,7 @@
path:(NSString *)path
timeout:(NSTimeInterval)timeout NS_DESIGNATED_INITIALIZER;
- (void)startBatchWithOperations:(NSArray *)ops errorHandler:(void(^)())errorHandler;
- (void)startBatchWithOperations:(NSArray *)ops errorHandler:(void(^)(void))errorHandler;
- (void)startBatchWithOperations:(NSArray *)ops;

@ -36,12 +36,12 @@
// Most operation subclasses don't set any flags in the grpc_op, and rely on the flag member being
// initialized to zero.
grpc_op _op;
void(^_handler)();
void(^_handler)(void);
}
- (void)finish {
if (_handler) {
void(^handler)() = _handler;
void(^handler)(void) = _handler;
_handler = nil;
handler();
}
@ -55,13 +55,13 @@
}
- (instancetype)initWithMetadata:(NSDictionary *)metadata
handler:(void (^)())handler {
handler:(void (^)(void))handler {
return [self initWithMetadata:metadata flags:0 handler:handler];
}
- (instancetype)initWithMetadata:(NSDictionary *)metadata
flags:(uint32_t)flags
handler:(void (^)())handler {
handler:(void (^)(void))handler {
if (self = [super init]) {
_op.op = GRPC_OP_SEND_INITIAL_METADATA;
_op.data.send_initial_metadata.count = metadata.count;
@ -92,7 +92,7 @@
return [self initWithMessage:nil handler:nil];
}
- (instancetype)initWithMessage:(NSData *)message handler:(void (^)())handler {
- (instancetype)initWithMessage:(NSData *)message handler:(void (^)(void))handler {
if (!message) {
[NSException raise:NSInvalidArgumentException format:@"message cannot be nil"];
}
@ -116,7 +116,7 @@
return [self initWithHandler:nil];
}
- (instancetype)initWithHandler:(void (^)())handler {
- (instancetype)initWithHandler:(void (^)(void))handler {
if (self = [super init]) {
_op.op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
_handler = handler;
@ -271,7 +271,7 @@
[self startBatchWithOperations:operations errorHandler:nil];
}
- (void)startBatchWithOperations:(NSArray *)operations errorHandler:(void (^)())errorHandler {
- (void)startBatchWithOperations:(NSArray *)operations errorHandler:(void (^)(void))errorHandler {
// Keep logs of op batches when we are running tests. Disabled when in production for improved
// performance.
#ifdef GRPC_TEST_OBJC

@ -23,4 +23,4 @@
// `tools/buildgen/generate_projects.sh`.
#define GRPC_OBJC_VERSION_STRING @"1.8.0-dev"
#define GRPC_OBJC_VERSION_STRING @"1.9.0-dev"

@ -46,7 +46,7 @@
* Enqueues writeValue: to be sent to the writeable in the main thread.
* The passed handler is invoked from the main thread after writeValue: returns.
*/
- (void)enqueueValue:(id)value completionHandler:(void (^)())handler;
- (void)enqueueValue:(id)value completionHandler:(void (^)(void))handler;
/**
* Enqueues writesFinishedWithError:nil to be sent to the writeable in the main thread. After that

@ -50,7 +50,7 @@
dispatchQueue:dispatch_get_main_queue()];
}
- (void)enqueueValue:(id)value completionHandler:(void (^)())handler {
- (void)enqueueValue:(id)value completionHandler:(void (^)(void))handler {
dispatch_async(_writeableQueue, ^{
// We're racing a possible cancellation performed by another thread. To turn all already-
// enqueued messages into noops, cancellation nillifies the writeable property. If we get it

@ -46,7 +46,7 @@
* Returns a writer that pushes to its writeable the successive values returned by the passed
* block. When the block first returns nil, it is released.
*/
+ (GRXWriter *)writerWithValueSupplier:(id (^)())block;
+ (GRXWriter *)writerWithValueSupplier:(id (^)(void))block;
/**
* Returns a writer that iterates over the values of the passed container and pushes them to

@ -52,7 +52,7 @@
return [self writerWithEnumerator:enumerator error:nil];
}
+ (GRXWriter *)writerWithValueSupplier:(id (^)())block {
+ (GRXWriter *)writerWithValueSupplier:(id (^)(void))block {
return [self writerWithEnumerator:[NSEnumerator grx_enumeratorWithValueSupplier:block]];
}

@ -30,7 +30,7 @@
* Returns a writer that pushes to its writeable the successive values returned by the passed
* block. When the block first returns nil, it is released.
*/
+ (instancetype)writerWithValueSupplier:(id (^)())block;
+ (instancetype)writerWithValueSupplier:(id (^)(void))block;
/**
* Returns a writer that iterates over the values of the passed container and pushes them to

@ -27,7 +27,7 @@
return [GRXImmediateWriter writerWithEnumerator:enumerator];
}
+ (instancetype)writerWithValueSupplier:(id (^)())block {
+ (instancetype)writerWithValueSupplier:(id (^)(void))block {
return [GRXImmediateWriter writerWithValueSupplier:block];
}

@ -38,5 +38,5 @@
* Returns a NSEnumerator instance that delegates the invocations of nextObject to the passed block.
* When the block first returns nil, it is released.
*/
+ (NSEnumerator *)grx_enumeratorWithValueSupplier:(id (^)())block;
+ (NSEnumerator *)grx_enumeratorWithValueSupplier:(id (^)(void))block;
@end

@ -33,7 +33,7 @@
return [[GRXNSScalarEnumerator alloc] initWithValue:value];
}
+ (NSEnumerator *)grx_enumeratorWithValueSupplier:(id (^)())block {
+ (NSEnumerator *)grx_enumeratorWithValueSupplier:(id (^)(void))block {
return [[GRXNSBlockEnumerator alloc] initWithValueSupplier:block];
}
@end

@ -27,5 +27,5 @@
* The first time the passed block returns nil, the enumeration will end and the block will be
* released.
*/
- (instancetype)initWithValueSupplier:(id (^)())block;
- (instancetype)initWithValueSupplier:(id (^)(void))block;
@end

@ -19,14 +19,14 @@
#import "GRXNSBlockEnumerator.h"
@implementation GRXNSBlockEnumerator {
id (^_block)();
id (^_block)(void);
}
- (instancetype)init {
return [self initWithValueSupplier:nil];
}
- (instancetype)initWithValueSupplier:(id (^)())block {
- (instancetype)initWithValueSupplier:(id (^)(void))block {
if ((self = [super init])) {
_block = block;
}

@ -23,5 +23,5 @@
// `tools/buildgen/generate_projects.sh`.
#define GRPC_OBJC_VERSION_STRING @"1.8.0-dev"
#define GRPC_OBJC_VERSION_STRING @"1.9.0-dev"
#define GRPC_C_VERSION_STRING @"5.0.0-dev"

@ -2,7 +2,7 @@
"name": "grpc/grpc-dev",
"description": "gRPC library for PHP - for Developement use only",
"license": "Apache-2.0",
"version": "1.8.0",
"version": "1.9.0",
"require": {
"php": ">=5.5.0",
"google/protobuf": "^v3.3.0"

@ -20,6 +20,6 @@
#ifndef VERSION_H
#define VERSION_H
#define PHP_GRPC_VERSION "1.8.0dev"
#define PHP_GRPC_VERSION "1.9.0dev"
#endif /* VERSION_H */

@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!!
__version__ = """1.8.0.dev0"""
__version__ = """1.9.0.dev0"""

@ -38,7 +38,6 @@ CORE_SOURCE_FILES = [
'src/core/lib/support/log_windows.cc',
'src/core/lib/support/mpscq.cc',
'src/core/lib/support/murmur_hash.cc',
'src/core/lib/support/stack_lockfree.cc',
'src/core/lib/support/string.cc',
'src/core/lib/support/string_posix.cc',
'src/core/lib/support/string_util_windows.cc',

@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!!
VERSION='1.8.0.dev0'
VERSION='1.9.0.dev0'

@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!!
VERSION='1.8.0.dev0'
VERSION='1.9.0.dev0'

@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!!
VERSION='1.8.0.dev0'
VERSION='1.9.0.dev0'

@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!!
VERSION='1.8.0.dev0'
VERSION='1.9.0.dev0'

@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!!
VERSION='1.8.0.dev0'
VERSION='1.9.0.dev0'

@ -23,13 +23,11 @@ def main
STDERR.puts 'start server'
server_runner = ServerRunner.new(EchoServerImpl)
server_port = server_runner.run
sleep 1
STDERR.puts 'start client'
control_stub, client_pid = start_client('channel_closing_client.rb',
server_port)
# sleep to allow time for the client to get into
# the middle of a "watch connectivity state" call
sleep 3
begin

@ -22,14 +22,11 @@ def main
STDERR.puts 'start server'
server_runner = ServerRunner.new(EchoServerImpl)
server_port = server_runner.run
sleep 1
STDERR.puts 'start client'
_, client_pid = start_client('channel_state_client.rb', server_port)
# sleep to allow time for the client to get into
# the middle of a "watch connectivity state" call
sleep 3
Process.kill('SIGTERM', client_pid)
begin

@ -40,12 +40,13 @@ end
# ServerRunner starts an "echo server" that test clients can make calls to
class ServerRunner
def initialize(service_impl)
def initialize(service_impl, rpc_server_args: {})
@service_impl = service_impl
@rpc_server_args = rpc_server_args
end
def run
@srv = GRPC::RpcServer.new
@srv = GRPC::RpcServer.new(@rpc_server_args)
port = @srv.add_http2_port('0.0.0.0:0', :this_port_is_insecure)
@srv.handle(@service_impl)
@ -75,7 +76,6 @@ def start_client(client_main, server_port)
client_path,
"--client_control_port=#{client_control_port}",
"--server_port=#{server_port}")
sleep 1
control_stub = ClientControl::ClientController::Stub.new(
"localhost:#{client_control_port}", :this_channel_is_insecure)
[control_stub, client_pid]

@ -20,12 +20,6 @@ def main
STDERR.puts 'start server'
server_runner = ServerRunner.new(EchoServerImpl)
server_port = server_runner.run
# TODO(apolcyn) Can we get rid of this sleep?
# Without it, an immediate call to the just started EchoServer
# fails with UNAVAILABLE
sleep 1
STDERR.puts 'start client'
_, client_pid = start_client('forking_client_client.rb',
server_port)

@ -54,7 +54,7 @@ def run_concurrency_stress_test(test_proc)
test_proc.call
fail 'exception thrown while child thread initing class'
fail '(expected) exception thrown while child thread initing class'
end
# default (no gc_stress and no concurrency_stress)

@ -17,56 +17,46 @@
require_relative './end2end_common'
# Service that sleeps for a long time upon receiving an 'echo request'
# Also, this notifies @call_started_cv once it has received a request.
# Also, this calls it's callback upon receiving an RPC as a method
# of synchronization/waiting for the child to start.
class SleepingEchoServerImpl < Echo::EchoServer::Service
def initialize(call_started, call_started_mu, call_started_cv)
@call_started = call_started
@call_started_mu = call_started_mu
@call_started_cv = call_started_cv
def initialize(received_rpc_callback)
@received_rpc_callback = received_rpc_callback
end
def echo(echo_req, _)
@call_started_mu.synchronize do
@call_started.set_true
@call_started_cv.signal
end
sleep 1000
@received_rpc_callback.call
# sleep forever to get the client stuck waiting
sleep
Echo::EchoReply.new(response: echo_req.request)
end
end
# Mutable boolean
class BoolHolder
attr_reader :val
def init
@val = false
end
def set_true
@val = true
end
end
def main
STDERR.puts 'start server'
call_started = BoolHolder.new
call_started_mu = Mutex.new
call_started_cv = ConditionVariable.new
client_started = false
client_started_mu = Mutex.new
client_started_cv = ConditionVariable.new
received_rpc_callback = proc do
client_started_mu.synchronize do
client_started = true
client_started_cv.signal
end
end
service_impl = SleepingEchoServerImpl.new(call_started,
call_started_mu,
call_started_cv)
server_runner = ServerRunner.new(service_impl)
service_impl = SleepingEchoServerImpl.new(received_rpc_callback)
# RPCs against the server will all be hanging, so kill thread
# pool workers immediately rather than after waiting for a second.
rpc_server_args = { poll_period: 0, pool_keep_alive: 0 }
server_runner = ServerRunner.new(service_impl, rpc_server_args: rpc_server_args)
server_port = server_runner.run
STDERR.puts 'start client'
_, client_pid = start_client('killed_client_thread_client.rb',
server_port)
call_started_mu.synchronize do
call_started_cv.wait(call_started_mu) until call_started.val
client_started_mu.synchronize do
client_started_cv.wait(client_started_mu) until client_started
end
# SIGTERM the child process now that it's

@ -26,6 +26,8 @@ def watch_state(ch)
fail "non-idle state: #{state}" unless state == IDLE
ch.watch_connectivity_state(IDLE, Time.now + 360)
end
# sleep to get the thread into the middle of a
# "watch connectivity state" call
sleep 0.1
thd.kill
end

@ -30,16 +30,18 @@ class SigHandlingClientController < ClientControl::ClientController::Service
end
def shutdown(_, _)
Thread.new do
# TODO(apolcyn) There is a race between stopping the
# server and the "shutdown" rpc completing,
# See if stop method on server can end active RPC cleanly, to
# avoid this sleep.
sleep 3
# Spawn a new thread because RpcServer#stop is
# synchronous and blocks until either this RPC has finished,
# or the server's "poll_period" seconds have passed.
@shutdown_thread = Thread.new do
@srv.stop
end
ClientControl::Void.new
end
def join_shutdown_thread
@shutdown_thread.join
end
end
def main
@ -62,13 +64,23 @@ def main
STDERR.puts 'SIGINT received'
end
srv = GRPC::RpcServer.new
# The "shutdown" RPC should end very quickly.
# Allow a few seconds to be safe.
srv = GRPC::RpcServer.new(poll_period: 3)
srv.add_http2_port("0.0.0.0:#{client_control_port}",
:this_port_is_insecure)
stub = Echo::EchoServer::Stub.new("localhost:#{server_port}",
:this_channel_is_insecure)
srv.handle(SigHandlingClientController.new(srv, stub))
srv.run
control_service = SigHandlingClientController.new(srv, stub)
srv.handle(control_service)
server_thread = Thread.new do
srv.run
end
srv.wait_till_running
# send a first RPC to notify the parent process that we've started
stub.echo(Echo::EchoRequest.new(request: 'client/child started'))
server_thread.join
control_service.join_shutdown_thread
end
main

@ -19,17 +19,42 @@
require_relative './end2end_common'
# A service that calls back it's received_rpc_callback
# upon receiving an RPC. Used for synchronization/waiting
# for child process to start.
class ClientStartedService < Echo::EchoServer::Service
def initialize(received_rpc_callback)
@received_rpc_callback = received_rpc_callback
end
def echo(echo_req, _)
@received_rpc_callback.call unless @received_rpc_callback.nil?
@received_rpc_callback = nil
Echo::EchoReply.new(response: echo_req.request)
end
end
def main
STDERR.puts 'start server'
server_runner = ServerRunner.new(EchoServerImpl)
server_port = server_runner.run
sleep 1
client_started = false
client_started_mu = Mutex.new
client_started_cv = ConditionVariable.new
received_rpc_callback = proc do
client_started_mu.synchronize do
client_started = true
client_started_cv.signal
end
end
client_started_service = ClientStartedService.new(received_rpc_callback)
server_runner = ServerRunner.new(client_started_service)
server_port = server_runner.run
STDERR.puts 'start client'
control_stub, client_pid = start_client('sig_handling_client.rb', server_port)
sleep 1
client_started_mu.synchronize do
client_started_cv.wait(client_started_mu) until client_started
end
count = 0
while count < 5

@ -23,13 +23,9 @@ def main
STDERR.puts 'start server'
server_runner = ServerRunner.new(EchoServerImpl)
server_port = server_runner.run
sleep 1
STDERR.puts 'start client'
_, client_pid = start_client('sig_int_during_channel_watch_client.rb',
server_port)
# give time for the client to get into the middle
# of a channel state watch call
sleep 1

@ -337,7 +337,7 @@ extern grpc_composite_call_credentials_create_type grpc_composite_call_credentia
typedef grpc_call_credentials*(*grpc_google_compute_engine_credentials_create_type)(void* reserved);
extern grpc_google_compute_engine_credentials_create_type grpc_google_compute_engine_credentials_create_import;
#define grpc_google_compute_engine_credentials_create grpc_google_compute_engine_credentials_create_import
typedef gpr_timespec(*grpc_max_auth_token_lifetime_type)();
typedef gpr_timespec(*grpc_max_auth_token_lifetime_type)(void);
extern grpc_max_auth_token_lifetime_type grpc_max_auth_token_lifetime_import;
#define grpc_max_auth_token_lifetime grpc_max_auth_token_lifetime_import
typedef grpc_call_credentials*(*grpc_service_account_jwt_access_credentials_create_type)(const char* json_key, gpr_timespec token_lifetime, void* reserved);
@ -589,7 +589,7 @@ extern gpr_free_aligned_type gpr_free_aligned_import;
typedef void(*gpr_set_allocation_functions_type)(gpr_allocation_functions functions);
extern gpr_set_allocation_functions_type gpr_set_allocation_functions_import;
#define gpr_set_allocation_functions gpr_set_allocation_functions_import
typedef gpr_allocation_functions(*gpr_get_allocation_functions_type)();
typedef gpr_allocation_functions(*gpr_get_allocation_functions_type)(void);
extern gpr_get_allocation_functions_type gpr_get_allocation_functions_import;
#define gpr_get_allocation_functions gpr_get_allocation_functions_import
typedef gpr_avl(*gpr_avl_create_type)(const gpr_avl_vtable* vtable);
@ -712,7 +712,7 @@ extern gpr_log_message_type gpr_log_message_import;
typedef void(*gpr_set_log_verbosity_type)(gpr_log_severity min_severity_to_print);
extern gpr_set_log_verbosity_type gpr_set_log_verbosity_import;
#define gpr_set_log_verbosity gpr_set_log_verbosity_import
typedef void(*gpr_log_verbosity_init_type)();
typedef void(*gpr_log_verbosity_init_type)(void);
extern gpr_log_verbosity_init_type gpr_log_verbosity_init_import;
#define gpr_log_verbosity_init gpr_log_verbosity_init_import
typedef void(*gpr_set_log_function_type)(gpr_log_func func);

@ -92,9 +92,13 @@ module GRPC
# Stops the jobs in the pool
def stop
GRPC.logger.info('stopping, will wait for all the workers to exit')
schedule { throw :exit } while ready_for_work?
@stop_mutex.synchronize do # wait @keep_alive for works to stop
@stop_mutex.synchronize do # wait @keep_alive seconds for workers to stop
@stopped = true
loop do
break unless ready_for_work?
worker_queue = @ready_workers.pop
worker_queue << [proc { throw :exit }, []]
end
@stop_cond.wait(@stop_mutex, @keep_alive) if @workers.size > 0
end
forcibly_stop_workers
@ -138,7 +142,10 @@ module GRPC
end
# there shouldn't be any work given to this thread while its busy
fail('received a task while busy') unless worker_queue.empty?
@ready_workers << worker_queue
@stop_mutex.synchronize do
return if @stopped
@ready_workers << worker_queue
end
end
end
end
@ -186,8 +193,13 @@ module GRPC
# * max_waiting_requests: Deprecated due to internal changes to the thread
# pool. This is still an argument for compatibility but is ignored.
#
# * poll_period: when present, the server polls for new events with this
# period
# * poll_period: The amount of time in seconds to wait for
# currently-serviced RPC's to finish before cancelling them when shutting
# down the server.
#
# * pool_keep_alive: The amount of time in seconds to wait
# for currently busy thread-pool threads to finish before
# forcing an abrupt exit to each thread.
#
# * connect_md_proc:
# when non-nil is a proc for determining metadata to to send back the client
@ -202,17 +214,18 @@ module GRPC
# intercepting server handlers to provide extra functionality.
# Interceptors are an EXPERIMENTAL API.
#
def initialize(pool_size:DEFAULT_POOL_SIZE,
max_waiting_requests:DEFAULT_MAX_WAITING_REQUESTS,
poll_period:DEFAULT_POLL_PERIOD,
connect_md_proc:nil,
server_args:{},
interceptors:[])
def initialize(pool_size: DEFAULT_POOL_SIZE,
max_waiting_requests: DEFAULT_MAX_WAITING_REQUESTS,
poll_period: DEFAULT_POLL_PERIOD,
pool_keep_alive: GRPC::RpcServer::DEFAULT_POOL_SIZE,
connect_md_proc: nil,
server_args: {},
interceptors: [])
@connect_md_proc = RpcServer.setup_connect_md_proc(connect_md_proc)
@max_waiting_requests = max_waiting_requests
@poll_period = poll_period
@pool_size = pool_size
@pool = Pool.new(@pool_size)
@pool = Pool.new(@pool_size, keep_alive: pool_keep_alive)
@run_cond = ConditionVariable.new
@run_mutex = Mutex.new
# running_state can take 4 values: :not_started, :running, :stopping, and

@ -14,5 +14,5 @@
# GRPC contains the General RPC module.
module GRPC
VERSION = '1.8.0.dev'
VERSION = '1.9.0.dev'
end

@ -48,6 +48,20 @@ module Grpc
@status_mutex.synchronize { @statuses["#{service}"] = status }
end
# Adds given health status for all given services
def set_status_for_services(status, *services)
@status_mutex.synchronize do
services.each { |service| @statuses["#{service}"] = status }
end
end
# Adds health status for each service given within hash
def add_statuses(service_statuses = {})
@status_mutex.synchronize do
service_statuses.each_pair { |service, status| @statuses["#{service}"] = status }
end
end
# Clears the status for the given service.
def clear_status(service)
@status_mutex.synchronize { @statuses.delete("#{service}") }

@ -77,8 +77,7 @@ class WorkerServiceImpl < Grpc::Testing::WorkerService::Service
Grpc::Testing::CoreResponse.new(cores: cpu_cores)
end
def quit_worker(_args, _call)
Thread.new {
sleep 3
@shutdown_thread = Thread.new {
@server.stop
}
Grpc::Testing::Void.new
@ -87,6 +86,9 @@ class WorkerServiceImpl < Grpc::Testing::WorkerService::Service
@server = s
@server_port = sp
end
def join_shutdown_thread
@shutdown_thread.join
end
end
def main
@ -107,11 +109,13 @@ def main
# Configure any errors with client or server child threads to surface
Thread.abort_on_exception = true
s = GRPC::RpcServer.new
s = GRPC::RpcServer.new(poll_period: 3)
s.add_http2_port("0.0.0.0:" + options['driver_port'].to_s,
:this_port_is_insecure)
s.handle(WorkerServiceImpl.new(s, options['server_port'].to_i))
worker_service = WorkerServiceImpl.new(s, options['server_port'].to_i)
s.handle(worker_service)
s.run
worker_service.join_shutdown_thread
end
main

@ -99,6 +99,35 @@ describe Grpc::Health::Checker do
end
end
context 'method `add_statuses`' do
it 'should add status to each service' do
checker = Grpc::Health::Checker.new
checker.add_statuses(
'service1' => ServingStatus::SERVING,
'service2' => ServingStatus::NOT_SERVING
)
service1_health = checker.check(HCReq.new(service: 'service1'), nil)
service2_health = checker.check(HCReq.new(service: 'service2'), nil)
expect(service1_health).to eq(HCResp.new(status: ServingStatus::SERVING))
expect(service2_health).to eq(HCResp.new(status: ServingStatus::NOT_SERVING))
end
end
context 'method `set_status_for_services`' do
it 'should add given status to all given services' do
checker = Grpc::Health::Checker.new
checker.set_status_for_services(
ServingStatus::SERVING,
'service1',
'service2'
)
service1_health = checker.check(HCReq.new(service: 'service1'), nil)
service2_health = checker.check(HCReq.new(service: 'service2'), nil)
expect(service1_health).to eq(HCResp.new(status: ServingStatus::SERVING))
expect(service2_health).to eq(HCResp.new(status: ServingStatus::SERVING))
end
end
context 'method `check`' do
success_tests.each do |t|
it "should fail with NOT_FOUND when #{t[:desc]}" do

@ -14,6 +14,6 @@
module GRPC
module Tools
VERSION = '1.8.0.dev'
VERSION = '1.9.0.dev'
end
end

@ -118,16 +118,6 @@ grpc_cc_test(
],
)
grpc_cc_test(
name = "stack_lockfree_test",
srcs = ["stack_lockfree_test.cc"],
language = "C++",
deps = [
"//:gpr",
"//test/core/util:gpr_test_util",
],
)
grpc_cc_test(
name = "string_test",
srcs = ["string_test.cc"],
@ -211,25 +201,25 @@ grpc_cc_test(
grpc_cc_test(
name = "memory_test",
srcs = ["memory_test.cc"],
external_deps = [
"gtest",
],
language = "C++",
deps = [
"//:grpc",
"//test/core/util:gpr_test_util",
],
external_deps = [
"gtest",
],
)
grpc_cc_test(
name = "vector_test",
srcs = ["vector_test.cc"],
external_deps = [
"gtest",
],
language = "C++",
deps = [
"//:grpc",
"//test/core/util:gpr_test_util",
],
external_deps = [
"gtest",
],
)

@ -1,140 +0,0 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include "src/core/lib/support/stack_lockfree.h"
#include <stdlib.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
#include <grpc/support/thd.h>
#include "test/core/util/test_config.h"
/* max stack size supported */
#define MAX_STACK_SIZE 65534
#define MAX_THREADS 32
static void test_serial_sized(size_t size) {
gpr_stack_lockfree* stack = gpr_stack_lockfree_create(size);
size_t i;
size_t j;
/* First try popping empty */
GPR_ASSERT(gpr_stack_lockfree_pop(stack) == -1);
/* Now add one item and check it */
gpr_stack_lockfree_push(stack, 3);
GPR_ASSERT(gpr_stack_lockfree_pop(stack) == 3);
GPR_ASSERT(gpr_stack_lockfree_pop(stack) == -1);
/* Now add repeatedly more items and check them */
for (i = 1; i < size; i *= 2) {
for (j = 0; j <= i; j++) {
GPR_ASSERT(gpr_stack_lockfree_push(stack, (int)j) == (j == 0));
}
for (j = 0; j <= i; j++) {
GPR_ASSERT(gpr_stack_lockfree_pop(stack) == (int)(i - j));
}
GPR_ASSERT(gpr_stack_lockfree_pop(stack) == -1);
}
gpr_stack_lockfree_destroy(stack);
}
static void test_serial() {
size_t i;
for (i = 128; i < MAX_STACK_SIZE; i *= 2) {
test_serial_sized(i);
}
test_serial_sized(MAX_STACK_SIZE);
}
struct test_arg {
gpr_stack_lockfree* stack;
int stack_size;
int nthreads;
int rank;
int sum;
};
static void test_mt_body(void* v) {
struct test_arg* arg = (struct test_arg*)v;
int lo, hi;
int i;
int res;
lo = arg->rank * arg->stack_size / arg->nthreads;
hi = (arg->rank + 1) * arg->stack_size / arg->nthreads;
for (i = lo; i < hi; i++) {
gpr_stack_lockfree_push(arg->stack, i);
if ((res = gpr_stack_lockfree_pop(arg->stack)) != -1) {
arg->sum += res;
}
}
while ((res = gpr_stack_lockfree_pop(arg->stack)) != -1) {
arg->sum += res;
}
}
static void test_mt_sized(size_t size, int nth) {
gpr_stack_lockfree* stack;
struct test_arg args[MAX_THREADS];
gpr_thd_id thds[MAX_THREADS];
int sum;
int i;
gpr_thd_options options = gpr_thd_options_default();
stack = gpr_stack_lockfree_create(size);
for (i = 0; i < nth; i++) {
args[i].stack = stack;
args[i].stack_size = (int)size;
args[i].nthreads = nth;
args[i].rank = i;
args[i].sum = 0;
}
gpr_thd_options_set_joinable(&options);
for (i = 0; i < nth; i++) {
GPR_ASSERT(gpr_thd_new(&thds[i], test_mt_body, &args[i], &options));
}
sum = 0;
for (i = 0; i < nth; i++) {
gpr_thd_join(thds[i]);
sum = sum + args[i].sum;
}
GPR_ASSERT((unsigned)sum == ((unsigned)size * (size - 1)) / 2);
gpr_stack_lockfree_destroy(stack);
}
static void test_mt() {
size_t size;
int nth;
for (nth = 1; nth < MAX_THREADS; nth++) {
for (size = 128; size < MAX_STACK_SIZE; size *= 2) {
test_mt_sized(size, nth);
}
test_mt_sized(MAX_STACK_SIZE, nth);
}
}
int main(int argc, char** argv) {
grpc_test_init(argc, argv);
test_serial();
test_mt();
return 0;
}

@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!!
VERSION='1.8.0.dev0'
VERSION='1.9.0.dev0'

@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++"
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = 1.8.0-dev
PROJECT_NUMBER = 1.9.0-dev
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a

@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++"
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = 1.8.0-dev
PROJECT_NUMBER = 1.9.0-dev
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
@ -1037,7 +1037,6 @@ src/core/lib/support/memory.h \
src/core/lib/support/mpscq.h \
src/core/lib/support/murmur_hash.h \
src/core/lib/support/spinlock.h \
src/core/lib/support/stack_lockfree.h \
src/core/lib/support/string.h \
src/core/lib/support/string_windows.h \
src/core/lib/support/time_precise.h \

@ -774,6 +774,7 @@ doc/connectivity-semantics-and-api.md \
doc/core/grpc-error.md \
doc/core/moving-to-c++.md \
doc/core/pending_api_cleanups.md \
doc/core/transport_explainer.md \
doc/cpp-style-guide.md \
doc/environment_variables.md \
doc/epoll-polling-engine.md \

@ -774,6 +774,7 @@ doc/connectivity-semantics-and-api.md \
doc/core/grpc-error.md \
doc/core/moving-to-c++.md \
doc/core/pending_api_cleanups.md \
doc/core/transport_explainer.md \
doc/cpp-style-guide.md \
doc/environment_variables.md \
doc/epoll-polling-engine.md \
@ -1299,8 +1300,6 @@ src/core/lib/support/mpscq.h \
src/core/lib/support/murmur_hash.cc \
src/core/lib/support/murmur_hash.h \
src/core/lib/support/spinlock.h \
src/core/lib/support/stack_lockfree.cc \
src/core/lib/support/stack_lockfree.h \
src/core/lib/support/string.cc \
src/core/lib/support/string.h \
src/core/lib/support/string_posix.cc \

@ -100,7 +100,7 @@ def find_all_images_for_lang(lang):
jobset.message('SKIPPED',
'%s for %s is not defined' % (args.release, lang),
do_newline=True)
return []
return {}
releases = [args.release]
# Images tuples keyed by runtime.

@ -793,21 +793,6 @@
"third_party": false,
"type": "target"
},
{
"deps": [
"gpr",
"gpr_test_util"
],
"headers": [],
"is_filegroup": false,
"language": "c",
"name": "gpr_stack_lockfree_test",
"src": [
"test/core/support/stack_lockfree_test.cc"
],
"third_party": false,
"type": "target"
},
{
"deps": [
"gpr",
@ -7770,7 +7755,6 @@
"src/core/lib/support/log_windows.cc",
"src/core/lib/support/mpscq.cc",
"src/core/lib/support/murmur_hash.cc",
"src/core/lib/support/stack_lockfree.cc",
"src/core/lib/support/string.cc",
"src/core/lib/support/string_posix.cc",
"src/core/lib/support/string_util_windows.cc",
@ -7840,7 +7824,6 @@
"src/core/lib/support/mpscq.h",
"src/core/lib/support/murmur_hash.h",
"src/core/lib/support/spinlock.h",
"src/core/lib/support/stack_lockfree.h",
"src/core/lib/support/string.h",
"src/core/lib/support/string_windows.h",
"src/core/lib/support/time_precise.h",
@ -7889,7 +7872,6 @@
"src/core/lib/support/mpscq.h",
"src/core/lib/support/murmur_hash.h",
"src/core/lib/support/spinlock.h",
"src/core/lib/support/stack_lockfree.h",
"src/core/lib/support/string.h",
"src/core/lib/support/string_windows.h",
"src/core/lib/support/time_precise.h",

@ -983,30 +983,6 @@
],
"uses_polling": false
},
{
"args": [],
"benchmark": false,
"ci_platforms": [
"linux",
"mac",
"posix",
"windows"
],
"cpu_cost": 7,
"exclude_configs": [],
"exclude_iomgrs": [],
"flaky": false,
"gtest": false,
"language": "c",
"name": "gpr_stack_lockfree_test",
"platforms": [
"linux",
"mac",
"posix",
"windows"
],
"uses_polling": false
},
{
"args": [],
"benchmark": false,

Loading…
Cancel
Save