aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar vjpai <vpai@google.com>2016-03-03 06:59:16 -0800
committerGravatar vjpai <vpai@google.com>2016-03-03 06:59:16 -0800
commitb7117e409bf35895dd9029bd811ac16fd02e3d83 (patch)
tree732339fe04361ad8ebfdb168dedc465c9cfdd5d5
parentc47c9497fa6518205a598c2bf74517df09541fed (diff)
parent40d27ba78455d9c5ef1feef250d0d889d6bfb746 (diff)
Merge branch 'master' into debug_qps_stream
-rw-r--r--BUILD2
-rw-r--r--Makefile2
-rw-r--r--build.yaml1
-rw-r--r--config.m43
-rw-r--r--doc/health-checking.md4
-rw-r--r--grpc.def1
-rw-r--r--include/grpc++/alarm.h17
-rw-r--r--include/grpc/census.h82
-rw-r--r--include/grpc/impl/codegen/sync.h4
-rw-r--r--package.xml25
-rw-r--r--src/core/census/context.c149
-rw-r--r--src/core/channel/client_channel.c31
-rw-r--r--src/core/client_config/lb_policies/pick_first.c21
-rw-r--r--src/core/client_config/lb_policies/round_robin.c15
-rw-r--r--src/core/client_config/lb_policy.c6
-rw-r--r--src/core/client_config/lb_policy.h5
-rw-r--r--src/core/client_config/subchannel.c24
-rw-r--r--src/core/httpcli/httpcli.c24
-rw-r--r--src/core/httpcli/httpcli.h5
-rw-r--r--src/core/httpcli/httpcli_security_connector.c14
-rw-r--r--src/core/iomgr/fd_posix.c6
-rw-r--r--src/core/iomgr/iomgr.c16
-rw-r--r--src/core/iomgr/iomgr_internal.h6
-rw-r--r--src/core/iomgr/pollset.h19
-rw-r--r--src/core/iomgr/pollset_multipoller_with_epoll.c1
-rw-r--r--src/core/iomgr/pollset_multipoller_with_poll_posix.c8
-rw-r--r--src/core/iomgr/pollset_posix.c54
-rw-r--r--src/core/iomgr/pollset_posix.h12
-rw-r--r--src/core/iomgr/pollset_set.h12
-rw-r--r--src/core/iomgr/pollset_set_posix.c26
-rw-r--r--src/core/iomgr/pollset_set_posix.h20
-rw-r--r--src/core/iomgr/pollset_set_windows.c6
-rw-r--r--src/core/iomgr/pollset_set_windows.h4
-rw-r--r--src/core/iomgr/pollset_windows.c41
-rw-r--r--src/core/iomgr/pollset_windows.h6
-rw-r--r--src/core/iomgr/tcp_client_posix.c12
-rw-r--r--src/core/iomgr/tcp_posix.c6
-rw-r--r--src/core/iomgr/udp_server.h1
-rw-r--r--src/core/iomgr/workqueue_posix.c1
-rw-r--r--src/core/iomgr/workqueue_posix.h4
-rw-r--r--src/core/security/client_auth_filter.c1
-rw-r--r--src/core/security/credentials.c6
-rw-r--r--src/core/security/credentials.h6
-rw-r--r--src/core/security/google_default_credentials.c41
-rw-r--r--src/core/security/handshake.c22
-rw-r--r--src/core/security/handshake.h3
-rw-r--r--src/core/security/security_connector.c125
-rw-r--r--src/core/security/security_connector.h64
-rw-r--r--src/core/security/server_secure_chttp2.c14
-rw-r--r--src/core/support/sync.c7
-rw-r--r--src/core/surface/alarm.c5
-rw-r--r--src/core/surface/completion_queue.c96
-rw-r--r--src/core/surface/secure_channel_create.c11
-rw-r--r--src/core/transport/chttp2/internal.h18
-rw-r--r--src/core/transport/chttp2/parsing.c6
-rw-r--r--src/core/transport/chttp2/stream_lists.c38
-rw-r--r--src/core/transport/chttp2/writing.c37
-rw-r--r--src/core/transport/chttp2_transport.c43
-rw-r--r--src/core/transport/metadata.c8
-rw-r--r--src/core/transport/transport.c2
-rw-r--r--src/cpp/common/alarm.cc51
-rw-r--r--src/csharp/Grpc.Core/Internal/AsyncCallServer.cs10
-rw-r--r--src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs14
-rw-r--r--src/csharp/Grpc.HealthCheck.Tests/HealthServiceImplTest.cs48
-rw-r--r--src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.nuspec2
-rw-r--r--src/csharp/Grpc.HealthCheck/Health.cs72
-rw-r--r--src/csharp/Grpc.HealthCheck/HealthGrpc.cs30
-rw-r--r--src/csharp/Grpc.HealthCheck/HealthServiceImpl.cs46
-rw-r--r--src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs4
-rw-r--r--src/csharp/Grpc.Tools.nuspec17
-rw-r--r--src/csharp/build_packages.bat17
-rwxr-xr-xsrc/csharp/generate_proto_csharp.sh2
-rw-r--r--src/node/health_check/health.js6
-rw-r--r--src/objective-c/tests/GRPCClientTests.m31
-rw-r--r--src/php/README.md36
-rw-r--r--src/proto/grpc/health/v1/health.proto (renamed from src/proto/grpc/health/v1alpha/health.proto)7
-rw-r--r--src/python/grpcio/README.rst14
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi9
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pxd.pxi7
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi52
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi2
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/server.pxd.pxi3
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi23
-rw-r--r--src/python/grpcio/grpc/_cython/imports.generated.c2
-rw-r--r--src/python/grpcio/grpc/_cython/imports.generated.h7
-rw-r--r--src/python/grpcio_health_checking/grpc/health/v1/__init__.py (renamed from src/python/grpcio_health_checking/grpc/health/v1alpha/__init__.py)2
-rw-r--r--src/python/grpcio_health_checking/grpc/health/v1/health.proto (renamed from src/python/grpcio_health_checking/grpc/health/v1alpha/health.proto)4
-rw-r--r--src/python/grpcio_health_checking/grpc/health/v1/health.py (renamed from src/python/grpcio_health_checking/grpc/health/v1alpha/health.py)6
-rw-r--r--src/ruby/.rubocop.yml2
-rw-r--r--src/ruby/ext/grpc/rb_grpc_imports.generated.c2
-rw-r--r--src/ruby/ext/grpc/rb_grpc_imports.generated.h7
-rw-r--r--src/ruby/pb/README.md4
-rwxr-xr-xsrc/ruby/pb/generate_proto_ruby.sh4
-rw-r--r--src/ruby/pb/grpc/health/checker.rb22
-rw-r--r--src/ruby/pb/grpc/health/v1/health.rb28
-rw-r--r--src/ruby/pb/grpc/health/v1/health_services.rb (renamed from src/ruby/pb/grpc/health/v1alpha/health_services.rb)8
-rw-r--r--src/ruby/pb/grpc/health/v1alpha/health.rb29
-rw-r--r--src/ruby/spec/pb/health/checker_spec.rb58
-rw-r--r--templates/README.md111
-rw-r--r--templates/config.m4.template3
-rw-r--r--templates/package.xml.template23
-rw-r--r--templates/src/csharp/build_packages.bat.template17
-rw-r--r--test/core/census/context_test.c137
-rw-r--r--test/core/client_config/set_initial_connect_string_test.c2
-rw-r--r--test/core/end2end/fixtures/h2_full+poll+pipe.c18
-rw-r--r--test/core/end2end/fixtures/h2_full+poll.c16
-rw-r--r--test/core/end2end/fixtures/h2_ssl+poll.c1
-rw-r--r--test/core/end2end/fixtures/h2_uchannel.c49
-rw-r--r--test/core/end2end/fixtures/h2_uds+poll.c18
-rw-r--r--test/core/httpcli/httpcli_test.c48
-rw-r--r--test/core/httpcli/httpscli_test.c48
-rw-r--r--test/core/iomgr/endpoint_pair_test.c19
-rw-r--r--test/core/iomgr/endpoint_tests.c20
-rw-r--r--test/core/iomgr/endpoint_tests.h4
-rw-r--r--test/core/iomgr/fd_posix_test.c97
-rw-r--r--test/core/iomgr/tcp_client_posix_test.c155
-rw-r--r--test/core/iomgr/tcp_posix_test.c107
-rw-r--r--test/core/iomgr/tcp_server_posix_test.c52
-rw-r--r--test/core/iomgr/workqueue_test.c43
-rw-r--r--test/core/security/oauth2_utils.c27
-rw-r--r--test/core/security/print_google_default_creds_token.c38
-rw-r--r--test/core/security/secure_endpoint_test.c26
-rw-r--r--test/core/security/verify_jwt.c33
-rw-r--r--test/core/util/port_posix.c57
-rw-r--r--test/core/util/port_windows.c29
-rw-r--r--test/core/util/test_tcp_server.c19
-rw-r--r--test/core/util/test_tcp_server.h4
-rw-r--r--test/cpp/common/alarm_cpp_test.cc17
-rw-r--r--test/cpp/end2end/end2end_test.cc15
-rw-r--r--test/cpp/end2end/test_service_impl.cc6
-rw-r--r--test/cpp/interop/metrics_client.cc43
-rw-r--r--test/cpp/interop/reconnect_interop_client.cc2
-rw-r--r--test/cpp/util/metrics_server.cc2
-rw-r--r--test/cpp/util/test_credentials_provider.cc82
-rw-r--r--test/cpp/util/test_credentials_provider.h19
-rw-r--r--test/distrib/csharp/DistribTest.sln6
-rw-r--r--test/distrib/csharp/DistribTest/DistribTest.csproj20
-rw-r--r--test/distrib/csharp/run_distrib_test.bat49
-rwxr-xr-xtest/distrib/csharp/run_distrib_test.sh4
-rwxr-xr-xtest/distrib/csharp/update_version.sh10
-rw-r--r--tools/dockerfile/distribtest/python_fedora20_x64/Dockerfile5
-rw-r--r--tools/dockerfile/distribtest/python_fedora21_x64/Dockerfile5
-rw-r--r--tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile4
-rw-r--r--tools/dockerfile/grpc_interop_stress_cxx/Dockerfile5
-rwxr-xr-xtools/dockerfile/grpc_interop_stress_cxx/build_interop_stress.sh2
-rw-r--r--tools/doxygen/Doxyfile.c++.internal1
-rwxr-xr-xtools/gcp/stress_test/run_client.py187
-rwxr-xr-xtools/gcp/stress_test/run_server.py120
-rwxr-xr-xtools/gcp/stress_test/stress_test_utils.py197
-rwxr-xr-xtools/gcp/utils/big_query_utils.py140
-rwxr-xr-xtools/gcp/utils/kubernetes_api.py (renamed from tools/gke/kubernetes_api.py)83
-rwxr-xr-xtools/jenkins/build_interop_stress_image.sh3
-rw-r--r--tools/run_tests/distribtest_targets.py11
-rwxr-xr-xtools/run_tests/jobset.py3
-rw-r--r--tools/run_tests/post_test_node.bat30
-rw-r--r--tools/run_tests/report_utils.py2
-rwxr-xr-xtools/run_tests/run_tests.py5
-rw-r--r--tools/run_tests/sources_and_headers.json2
-rwxr-xr-xtools/run_tests/stress_test/run_stress_tests_on_gke.py556
-rw-r--r--vsprojects/vcxproj/grpc++/grpc++.vcxproj2
-rw-r--r--vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters3
-rw-r--r--vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj2
-rw-r--r--vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters3
163 files changed, 3151 insertions, 1653 deletions
diff --git a/BUILD b/BUILD
index 51eb446630..0e9f37a0e3 100644
--- a/BUILD
+++ b/BUILD
@@ -818,7 +818,6 @@ cc_library(
"src/cpp/client/credentials.cc",
"src/cpp/client/generic_stub.cc",
"src/cpp/client/insecure_credentials.cc",
- "src/cpp/common/alarm.cc",
"src/cpp/common/call.cc",
"src/cpp/common/channel_arguments.cc",
"src/cpp/common/completion_queue.cc",
@@ -942,7 +941,6 @@ cc_library(
"src/cpp/client/credentials.cc",
"src/cpp/client/generic_stub.cc",
"src/cpp/client/insecure_credentials.cc",
- "src/cpp/common/alarm.cc",
"src/cpp/common/call.cc",
"src/cpp/common/channel_arguments.cc",
"src/cpp/common/completion_queue.cc",
diff --git a/Makefile b/Makefile
index 941827bf9c..5be0d146af 100644
--- a/Makefile
+++ b/Makefile
@@ -2990,7 +2990,6 @@ LIBGRPC++_SRC = \
src/cpp/client/credentials.cc \
src/cpp/client/generic_stub.cc \
src/cpp/client/insecure_credentials.cc \
- src/cpp/common/alarm.cc \
src/cpp/common/call.cc \
src/cpp/common/channel_arguments.cc \
src/cpp/common/completion_queue.cc \
@@ -3271,7 +3270,6 @@ LIBGRPC++_UNSECURE_SRC = \
src/cpp/client/credentials.cc \
src/cpp/client/generic_stub.cc \
src/cpp/client/insecure_credentials.cc \
- src/cpp/common/alarm.cc \
src/cpp/common/call.cc \
src/cpp/common/channel_arguments.cc \
src/cpp/common/completion_queue.cc \
diff --git a/build.yaml b/build.yaml
index c4bbca6e2c..a277539a05 100644
--- a/build.yaml
+++ b/build.yaml
@@ -184,7 +184,6 @@ filegroups:
- src/cpp/client/credentials.cc
- src/cpp/client/generic_stub.cc
- src/cpp/client/insecure_credentials.cc
- - src/cpp/common/alarm.cc
- src/cpp/common/call.cc
- src/cpp/common/channel_arguments.cc
- src/cpp/common/completion_queue.cc
diff --git a/config.m4 b/config.m4
index f09ddcb40e..8ab45e6603 100644
--- a/config.m4
+++ b/config.m4
@@ -533,7 +533,8 @@ if test "$PHP_GRPC" != "no"; then
third_party/boringssl/ssl/t1_enc.c \
third_party/boringssl/ssl/t1_lib.c \
third_party/boringssl/ssl/tls_record.c \
- , $ext_shared, , -Wall -Werror -std=c11 \
+ , $ext_shared, , -Wall -Werror \
+ -Wno-parentheses-equality -Wno-unused-value -std=c11 \
-fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN \
-D_HAS_EXCEPTIONS=0 -DNOMINMAX)
diff --git a/doc/health-checking.md b/doc/health-checking.md
index 0b3f9c6a03..92512e942b 100644
--- a/doc/health-checking.md
+++ b/doc/health-checking.md
@@ -26,7 +26,7 @@ The server should export a service defined in the following proto:
```
syntax = "proto3";
-package grpc.health.v1alpha;
+package grpc.health.v1;
message HealthCheckRequest {
string service = 1;
@@ -49,7 +49,7 @@ service Health {
A client can query the server’s health status by calling the `Check` method, and
a deadline should be set on the rpc. The client can optionally set the service
name it wants to query for health status. The suggested format of service name
-is `package_names.ServiceName`, such as `grpc.health.v1alpha.Health`.
+is `package_names.ServiceName`, such as `grpc.health.v1.Health`.
The server should register all the services manually and set
the individual status, including an empty service name and its status. For each
diff --git a/grpc.def b/grpc.def
index bd0bc85a7c..f81aa1b05a 100644
--- a/grpc.def
+++ b/grpc.def
@@ -182,6 +182,7 @@ EXPORTS
gpr_event_wait
gpr_ref_init
gpr_ref
+ gpr_ref_non_zero
gpr_refn
gpr_unref
gpr_stats_init
diff --git a/include/grpc++/alarm.h b/include/grpc++/alarm.h
index 9979c34e4f..3b8104d135 100644
--- a/include/grpc++/alarm.h
+++ b/include/grpc++/alarm.h
@@ -36,9 +36,12 @@
#ifndef GRPCXX_ALARM_H
#define GRPCXX_ALARM_H
+#include <grpc++/impl/codegen/completion_queue.h>
#include <grpc++/impl/codegen/completion_queue_tag.h>
#include <grpc++/impl/codegen/grpc_library.h>
#include <grpc++/impl/codegen/time.h>
+#include <grpc++/impl/grpc_library.h>
+#include <grpc/grpc.h>
struct grpc_alarm;
@@ -54,14 +57,22 @@ class Alarm : private GrpcLibrary {
/// Once the alarm expires (at \a deadline) or it's cancelled (see \a 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).
- Alarm(CompletionQueue* cq, gpr_timespec deadline, void* tag);
+ /// \internal We rely on the presence of \a cq for grpc initialization. If \a
+ /// cq were ever to be removed, a reference to a static
+ /// internal::GrpcLibraryInitializer instance would need to be introduced
+ /// here. \endinternal.
+ template <typename T>
+ Alarm(CompletionQueue* cq, const T& deadline, void* tag)
+ : tag_(tag),
+ alarm_(grpc_alarm_create(cq->cq(), TimePoint<T>(deadline).raw_time(),
+ static_cast<void*>(&tag_))) {}
/// Destroy the given completion queue alarm, cancelling it in the process.
- ~Alarm();
+ ~Alarm() { grpc_alarm_destroy(alarm_); }
/// Cancel a completion queue alarm. Calling this function over an alarm that
/// has already fired has no effect.
- void Cancel();
+ void Cancel() { grpc_alarm_cancel(alarm_); }
private:
class AlarmEntry : public CompletionQueueTag {
diff --git a/include/grpc/census.h b/include/grpc/census.h
index dfa3bd7e0d..442a754f0a 100644
--- a/include/grpc/census.h
+++ b/include/grpc/census.h
@@ -80,18 +80,18 @@ CENSUSAPI int census_enabled(void);
metrics will be recorded. Keys are unique within a context. */
typedef struct census_context census_context;
-/* A tag is a key:value pair. The key is a non-empty, printable (UTF-8
- encoded), nil-terminated string. The value is a binary string, that may be
- printable. There are limits on the sizes of both keys and values (see
- CENSUS_MAX_TAG_KB_LEN definition below), and the number of tags that can be
- propagated (CENSUS_MAX_PROPAGATED_TAGS). Users should also remember that
- some systems may have limits on, e.g., the number of bytes that can be
- transmitted as metadata, and that larger tags means more memory consumed
- and time in processing. */
+/* A tag is a key:value pair. Both keys and values are nil-terminated strings,
+ containing printable ASCII characters (decimal 32-126). Keys must be at
+ least one character in length. Both keys and values can have at most
+ CENSUS_MAX_TAG_KB_LEN characters (including the terminating nil). The
+ maximum number of tags that can be propagated is
+ CENSUS_MAX_PROPAGATED_TAGS. Users should also remember that some systems
+ may have limits on, e.g., the number of bytes that can be transmitted as
+ metadata, and that larger tags means more memory consumed and time in
+ processing. */
typedef struct {
const char *key;
const char *value;
- size_t value_len;
uint8_t flags;
} census_tag;
@@ -103,28 +103,25 @@ typedef struct {
/* Tag flags. */
#define CENSUS_TAG_PROPAGATE 1 /* Tag should be propagated over RPC */
#define CENSUS_TAG_STATS 2 /* Tag will be used for statistics aggregation */
-#define CENSUS_TAG_BINARY 4 /* Tag value is not printable */
-#define CENSUS_TAG_RESERVED 8 /* Reserved for internal use. */
-/* Flag values 8,16,32,64,128 are reserved for future/internal use. Clients
+#define CENSUS_TAG_RESERVED 4 /* Reserved for internal use. */
+/* Flag values 4,8,16,32,64,128 are reserved for future/internal use. Clients
should not use or rely on their values. */
#define CENSUS_TAG_IS_PROPAGATED(flags) (flags & CENSUS_TAG_PROPAGATE)
#define CENSUS_TAG_IS_STATS(flags) (flags & CENSUS_TAG_STATS)
-#define CENSUS_TAG_IS_BINARY(flags) (flags & CENSUS_TAG_BINARY)
/* An instance of this structure is kept by every context, and records the
basic information associated with the creation of that context. */
typedef struct {
- int n_propagated_tags; /* number of propagated printable tags */
- int n_propagated_binary_tags; /* number of propagated binary tags */
- int n_local_tags; /* number of non-propagated (local) tags */
- int n_deleted_tags; /* number of tags that were deleted */
- int n_added_tags; /* number of tags that were added */
- int n_modified_tags; /* number of tags that were modified */
- int n_invalid_tags; /* number of tags with bad keys or values (e.g.
- longer than CENSUS_MAX_TAG_KV_LEN) */
- int n_ignored_tags; /* number of tags ignored because of
- CENSUS_MAX_PROPAGATED_TAGS limit. */
+ int n_propagated_tags; /* number of propagated tags */
+ int n_local_tags; /* number of non-propagated (local) tags */
+ int n_deleted_tags; /* number of tags that were deleted */
+ int n_added_tags; /* number of tags that were added */
+ int n_modified_tags; /* number of tags that were modified */
+ int n_invalid_tags; /* number of tags with bad keys or values (e.g.
+ longer than CENSUS_MAX_TAG_KV_LEN) */
+ int n_ignored_tags; /* number of tags ignored because of
+ CENSUS_MAX_PROPAGATED_TAGS limit. */
} census_context_status;
/* Create a new context, adding and removing tags from an existing context.
@@ -132,10 +129,10 @@ typedef struct {
to add as many tags in a single operation as is practical for the client.
@param base Base context to build upon. Can be NULL.
@param tags A set of tags to be added/changed/deleted. Tags with keys that
- are in 'tags', but not 'base', are added to the tag set. Keys that are in
+ are in 'tags', but not 'base', are added to the context. Keys that are in
both 'tags' and 'base' will have their value/flags modified. Tags with keys
- in both, but with NULL or zero-length values, will be deleted from the tag
- set. Tags with invalid (too long or short) keys or values will be ignored.
+ in both, but with NULL values, will be deleted from the context. Tags with
+ invalid (too long or short) keys or values will be ignored.
If adding a tag will result in more than CENSUS_MAX_PROPAGATED_TAGS in either
binary or non-binary tags, they will be ignored, as will deletions of
tags that don't exist.
@@ -185,32 +182,19 @@ CENSUSAPI int census_context_get_tag(const census_context *context,
for use by RPC systems only, for purposes of transmitting/receiving contexts.
*/
-/* Encode a context into a buffer. The propagated tags are encoded into the
- buffer in two regions: one for printable tags, and one for binary tags.
+/* Encode a context into a buffer.
@param context context to be encoded
- @param buffer pointer to buffer. This address will be used to encode the
- printable tags.
+ @param buffer buffer into which the context will be encoded.
@param buf_size number of available bytes in buffer.
- @param print_buf_size Will be set to the number of bytes consumed by
- printable tags.
- @param bin_buf_size Will be set to the number of bytes used to encode the
- binary tags.
- @return A pointer to the binary tag's encoded, or NULL if the buffer was
- insufficiently large to hold the encoded tags. Thus, if successful,
- printable tags are encoded into
- [buffer, buffer + *print_buf_size) and binary tags into
- [returned-ptr, returned-ptr + *bin_buf_size) (and the returned
- pointer should be buffer + *print_buf_size) */
-CENSUSAPI char *census_context_encode(const census_context *context,
- char *buffer, size_t buf_size,
- size_t *print_buf_size,
- size_t *bin_buf_size);
-
-/* Decode context buffers encoded with census_context_encode(). Returns NULL
+ @return The number of buffer bytes consumed for the encoded context, or
+ zero if the buffer was of insufficient size. */
+CENSUSAPI size_t census_context_encode(const census_context *context,
+ char *buffer, size_t buf_size);
+
+/* Decode context buffer encoded with census_context_encode(). Returns NULL
if there is an error in parsing either buffer. */
-CENSUSAPI census_context *census_context_decode(const char *buffer, size_t size,
- const char *bin_buffer,
- size_t bin_size);
+CENSUSAPI census_context *census_context_decode(const char *buffer,
+ size_t size);
/* Distributed traces can have a number of options. */
enum census_trace_mask_values {
diff --git a/include/grpc/impl/codegen/sync.h b/include/grpc/impl/codegen/sync.h
index d2f19d37d6..6fd7d64b29 100644
--- a/include/grpc/impl/codegen/sync.h
+++ b/include/grpc/impl/codegen/sync.h
@@ -182,6 +182,10 @@ GPRAPI void gpr_ref_init(gpr_refcount *r, int n);
/* Increment the reference count *r. Requires *r initialized. */
GPRAPI void gpr_ref(gpr_refcount *r);
+/* Increment the reference count *r. Requires *r initialized.
+ Crashes if refcount is zero */
+GPRAPI void gpr_ref_non_zero(gpr_refcount *r);
+
/* Increment the reference count *r by n. Requires *r initialized, n > 0. */
GPRAPI void gpr_refn(gpr_refcount *r, int n);
diff --git a/package.xml b/package.xml
index be4cfc79db..e65ab73b54 100644
--- a/package.xml
+++ b/package.xml
@@ -10,11 +10,11 @@
<email>grpc-packages@google.com</email>
<active>yes</active>
</lead>
- <date>2016-02-25</date>
+ <date>2016-03-01</date>
<time>16:06:07</time>
<version>
- <release>0.8.0</release>
- <api>0.8.0</api>
+ <release>0.14.0</release>
+ <api>0.14.0</api>
</version>
<stability>
<release>beta</release>
@@ -22,7 +22,7 @@
</stability>
<license>BSD</license>
<notes>
-- Simplify gRPC PHP installation #4517
+- Increase unit test code coverage #5225
</notes>
<contents>
<dir baseinstalldir="/" name="/">
@@ -963,11 +963,26 @@ Update to wrap gRPC C Core version 0.10.0
<release>beta</release>
<api>beta</api>
</stability>
- <date>2016-02-25</date>
+ <date>2016-02-24</date>
<license>BSD</license>
<notes>
- Simplify gRPC PHP installation #4517
</notes>
</release>
+ <release>
+ <version>
+ <release>0.14.0</release>
+ <api>0.14.0</api>
+ </version>
+ <stability>
+ <release>beta</release>
+ <api>beta</api>
+ </stability>
+ <date>2016-03-01</date>
+ <license>BSD</license>
+ <notes>
+- Increase unit test code coverage #5225
+ </notes>
+ </release>
</changelog>
</package>
diff --git a/src/core/census/context.c b/src/core/census/context.c
index e60330de64..89b8ee0b39 100644
--- a/src/core/census/context.c
+++ b/src/core/census/context.c
@@ -60,10 +60,10 @@
// limit of 255 for both CENSUS_MAX_TAG_KV_LEN and CENSUS_MAX_PROPAGATED_TAGS.
// * Keep all tag information (keys/values/flags) in a single memory buffer,
// that can be directly copied to the wire.
-// * Binary tags share the same structure as, but are encoded separately from,
-// non-binary tags. This is primarily because non-binary tags are far more
-// likely to be repeated across multiple RPC calls, so are more efficiently
-// cached and compressed in any metadata schemes.
+
+// min and max valid chars in tag keys and values. All printable ASCII is OK.
+#define MIN_VALID_TAG_CHAR 32 // ' '
+#define MAX_VALID_TAG_CHAR 126 // '~'
// Structure representing a set of tags. Essentially a count of number of tags
// present, and pointer to a chunk of memory that contains the per-tag details.
@@ -77,7 +77,7 @@ struct tag_set {
char *kvm; // key/value memory. Consists of repeated entries of:
// Offset Size Description
// 0 1 Key length, including trailing 0. (K)
- // 1 1 Value length. (V)
+ // 1 1 Value length, including trailing 0 (V)
// 2 1 Flags
// 3 K Key bytes
// 3 + K V Value bytes
@@ -108,19 +108,36 @@ struct raw_tag {
#define CENSUS_TAG_DELETED CENSUS_TAG_RESERVED
#define CENSUS_TAG_IS_DELETED(flags) (flags & CENSUS_TAG_DELETED)
-// Primary (external) representation of a context. Composed of 3 underlying
-// tag_set structs, one for each of the binary/printable propagated tags, and
-// one for everything else. This is to efficiently support tag
-// encoding/decoding.
+// Primary representation of a context. Composed of 2 underlying tag_set
+// structs, one each for propagated and local (non-propagated) tags. This is
+// to efficiently support tag encoding/decoding.
+// TODO(aveitch): need to add tracing id's/structure.
struct census_context {
- struct tag_set tags[3];
+ struct tag_set tags[2];
census_context_status status;
};
// Indices into the tags member of census_context
#define PROPAGATED_TAGS 0
-#define PROPAGATED_BINARY_TAGS 1
-#define LOCAL_TAGS 2
+#define LOCAL_TAGS 1
+
+// Validate (check all characters are in range and size is less than limit) a
+// key or value string. Returns 0 if the string is invalid, or the length
+// (including terminator) if valid.
+static size_t validate_tag(const char *kv) {
+ size_t len = 1;
+ char ch;
+ while ((ch = *kv++) != 0) {
+ if (ch < MIN_VALID_TAG_CHAR || ch > MAX_VALID_TAG_CHAR) {
+ return 0;
+ }
+ len++;
+ }
+ if (len > CENSUS_MAX_TAG_KV_LEN) {
+ return 0;
+ }
+ return len;
+}
// Extract a raw tag given a pointer (raw) to the tag header. Allow for some
// extra bytes in the tag header (see encode/decode functions for usage: this
@@ -166,9 +183,7 @@ static bool context_delete_tag(census_context *context, const census_tag *tag,
size_t key_len) {
return (
tag_set_delete_tag(&context->tags[LOCAL_TAGS], tag->key, key_len) ||
- tag_set_delete_tag(&context->tags[PROPAGATED_TAGS], tag->key, key_len) ||
- tag_set_delete_tag(&context->tags[PROPAGATED_BINARY_TAGS], tag->key,
- key_len));
+ tag_set_delete_tag(&context->tags[PROPAGATED_TAGS], tag->key, key_len));
}
// Add a tag to a tag_set. Return true on success, false if the tag could
@@ -176,11 +191,11 @@ static bool context_delete_tag(census_context *context, const census_tag *tag,
// not be called if the tag may already exist (in a non-deleted state) in
// the tag_set, as that would result in two tags with the same key.
static bool tag_set_add_tag(struct tag_set *tags, const census_tag *tag,
- size_t key_len) {
+ size_t key_len, size_t value_len) {
if (tags->ntags == CENSUS_MAX_PROPAGATED_TAGS) {
return false;
}
- const size_t tag_size = key_len + tag->value_len + TAG_HEADER_SIZE;
+ const size_t tag_size = key_len + value_len + TAG_HEADER_SIZE;
if (tags->kvm_used + tag_size > tags->kvm_size) {
// allocate new memory if needed
tags->kvm_size += 2 * CENSUS_MAX_TAG_KV_LEN + TAG_HEADER_SIZE;
@@ -191,13 +206,12 @@ static bool tag_set_add_tag(struct tag_set *tags, const census_tag *tag,
}
char *kvp = tags->kvm + tags->kvm_used;
*kvp++ = (char)key_len;
- *kvp++ = (char)tag->value_len;
+ *kvp++ = (char)value_len;
// ensure reserved flags are not used.
- *kvp++ = (char)(tag->flags & (CENSUS_TAG_PROPAGATE | CENSUS_TAG_STATS |
- CENSUS_TAG_BINARY));
+ *kvp++ = (char)(tag->flags & (CENSUS_TAG_PROPAGATE | CENSUS_TAG_STATS));
memcpy(kvp, tag->key, key_len);
kvp += key_len;
- memcpy(kvp, tag->value, tag->value_len);
+ memcpy(kvp, tag->value, value_len);
tags->kvm_used += tag_size;
tags->ntags++;
tags->ntags_alloc++;
@@ -207,30 +221,20 @@ static bool tag_set_add_tag(struct tag_set *tags, const census_tag *tag,
// Add/modify/delete a tag to/in a context. Caller must validate that tag key
// etc. are valid.
static void context_modify_tag(census_context *context, const census_tag *tag,
- size_t key_len) {
+ size_t key_len, size_t value_len) {
// First delete the tag if it is already present.
bool deleted = context_delete_tag(context, tag, key_len);
- // Determine if we need to add it back.
- bool call_add = tag->value != NULL && tag->value_len != 0;
bool added = false;
- if (call_add) {
- if (CENSUS_TAG_IS_PROPAGATED(tag->flags)) {
- if (CENSUS_TAG_IS_BINARY(tag->flags)) {
- added = tag_set_add_tag(&context->tags[PROPAGATED_BINARY_TAGS], tag,
- key_len);
- } else {
- added = tag_set_add_tag(&context->tags[PROPAGATED_TAGS], tag, key_len);
- }
- } else {
- added = tag_set_add_tag(&context->tags[LOCAL_TAGS], tag, key_len);
- }
+ if (CENSUS_TAG_IS_PROPAGATED(tag->flags)) {
+ added = tag_set_add_tag(&context->tags[PROPAGATED_TAGS], tag, key_len,
+ value_len);
+ } else {
+ added =
+ tag_set_add_tag(&context->tags[LOCAL_TAGS], tag, key_len, value_len);
}
+
if (deleted) {
- if (call_add) {
- context->status.n_modified_tags++;
- } else {
- context->status.n_deleted_tags++;
- }
+ context->status.n_modified_tags++;
} else {
if (added) {
context->status.n_added_tags++;
@@ -292,8 +296,6 @@ census_context *census_context_create(const census_context *base,
memset(context, 0, sizeof(census_context));
} else {
tag_set_copy(&context->tags[PROPAGATED_TAGS], &base->tags[PROPAGATED_TAGS]);
- tag_set_copy(&context->tags[PROPAGATED_BINARY_TAGS],
- &base->tags[PROPAGATED_BINARY_TAGS]);
tag_set_copy(&context->tags[LOCAL_TAGS], &base->tags[LOCAL_TAGS]);
memset(&context->status, 0, sizeof(context->status));
}
@@ -301,22 +303,29 @@ census_context *census_context_create(const census_context *base,
// the context to add/replace/delete as required.
for (int i = 0; i < ntags; i++) {
const census_tag *tag = &tags[i];
- size_t key_len = strlen(tag->key) + 1;
- // ignore the tag if it is too long/short.
- if (key_len != 1 && key_len <= CENSUS_MAX_TAG_KV_LEN &&
- tag->value_len <= CENSUS_MAX_TAG_KV_LEN) {
- context_modify_tag(context, tag, key_len);
- } else {
+ size_t key_len = validate_tag(tag->key);
+ // ignore the tag if it is invalid or too short.
+ if (key_len <= 1) {
context->status.n_invalid_tags++;
+ } else {
+ if (tag->value != NULL) {
+ size_t value_len = validate_tag(tag->value);
+ if (value_len != 0) {
+ context_modify_tag(context, tag, key_len, value_len);
+ } else {
+ context->status.n_invalid_tags++;
+ }
+ } else {
+ if (context_delete_tag(context, tag, key_len)) {
+ context->status.n_deleted_tags++;
+ }
+ }
}
}
// Remove any deleted tags, update status if needed, and return.
tag_set_flatten(&context->tags[PROPAGATED_TAGS]);
- tag_set_flatten(&context->tags[PROPAGATED_BINARY_TAGS]);
tag_set_flatten(&context->tags[LOCAL_TAGS]);
context->status.n_propagated_tags = context->tags[PROPAGATED_TAGS].ntags;
- context->status.n_propagated_binary_tags =
- context->tags[PROPAGATED_BINARY_TAGS].ntags;
context->status.n_local_tags = context->tags[LOCAL_TAGS].ntags;
if (status) {
*status = &context->status;
@@ -331,7 +340,6 @@ const census_context_status *census_context_get_status(
void census_context_destroy(census_context *context) {
gpr_free(context->tags[PROPAGATED_TAGS].kvm);
- gpr_free(context->tags[PROPAGATED_BINARY_TAGS].kvm);
gpr_free(context->tags[LOCAL_TAGS].kvm);
gpr_free(context);
}
@@ -343,9 +351,6 @@ void census_context_initialize_iterator(const census_context *context,
if (context->tags[PROPAGATED_TAGS].ntags != 0) {
iterator->base = PROPAGATED_TAGS;
iterator->kvm = context->tags[PROPAGATED_TAGS].kvm;
- } else if (context->tags[PROPAGATED_BINARY_TAGS].ntags != 0) {
- iterator->base = PROPAGATED_BINARY_TAGS;
- iterator->kvm = context->tags[PROPAGATED_BINARY_TAGS].kvm;
} else if (context->tags[LOCAL_TAGS].ntags != 0) {
iterator->base = LOCAL_TAGS;
iterator->kvm = context->tags[LOCAL_TAGS].kvm;
@@ -363,7 +368,6 @@ int census_context_next_tag(census_context_iterator *iterator,
iterator->kvm = decode_tag(&raw, iterator->kvm, 0);
tag->key = raw.key;
tag->value = raw.value;
- tag->value_len = raw.value_len;
tag->flags = raw.flags;
if (++iterator->index == iterator->context->tags[iterator->base].ntags) {
do {
@@ -388,7 +392,6 @@ static bool tag_set_get_tag(const struct tag_set *tags, const char *key,
if (key_len == raw.key_len && memcmp(raw.key, key, key_len) == 0) {
tag->key = raw.key;
tag->value = raw.value;
- tag->value_len = raw.value_len;
tag->flags = raw.flags;
return true;
}
@@ -403,8 +406,6 @@ int census_context_get_tag(const census_context *context, const char *key,
return 0;
}
if (tag_set_get_tag(&context->tags[PROPAGATED_TAGS], key, key_len, tag) ||
- tag_set_get_tag(&context->tags[PROPAGATED_BINARY_TAGS], key, key_len,
- tag) ||
tag_set_get_tag(&context->tags[LOCAL_TAGS], key, key_len, tag)) {
return 1;
}
@@ -447,21 +448,9 @@ static size_t tag_set_encode(const struct tag_set *tags, char *buffer,
return ENCODED_HEADER_SIZE + tags->kvm_used;
}
-char *census_context_encode(const census_context *context, char *buffer,
- size_t buf_size, size_t *print_buf_size,
- size_t *bin_buf_size) {
- *print_buf_size =
- tag_set_encode(&context->tags[PROPAGATED_TAGS], buffer, buf_size);
- if (*print_buf_size == 0) {
- return NULL;
- }
- char *b_buffer = buffer + *print_buf_size;
- *bin_buf_size = tag_set_encode(&context->tags[PROPAGATED_BINARY_TAGS],
- b_buffer, buf_size - *print_buf_size);
- if (*bin_buf_size == 0) {
- return NULL;
- }
- return b_buffer;
+size_t census_context_encode(const census_context *context, char *buffer,
+ size_t buf_size) {
+ return tag_set_encode(&context->tags[PROPAGATED_TAGS], buffer, buf_size);
}
// Decode a tag set.
@@ -506,8 +495,7 @@ static void tag_set_decode(struct tag_set *tags, const char *buffer,
}
}
-census_context *census_context_decode(const char *buffer, size_t size,
- const char *bin_buffer, size_t bin_size) {
+census_context *census_context_decode(const char *buffer, size_t size) {
census_context *context = gpr_malloc(sizeof(census_context));
memset(&context->tags[LOCAL_TAGS], 0, sizeof(struct tag_set));
if (buffer == NULL) {
@@ -515,16 +503,7 @@ census_context *census_context_decode(const char *buffer, size_t size,
} else {
tag_set_decode(&context->tags[PROPAGATED_TAGS], buffer, size);
}
- if (bin_buffer == NULL) {
- memset(&context->tags[PROPAGATED_BINARY_TAGS], 0, sizeof(struct tag_set));
- } else {
- tag_set_decode(&context->tags[PROPAGATED_BINARY_TAGS], bin_buffer,
- bin_size);
- }
memset(&context->status, 0, sizeof(context->status));
context->status.n_propagated_tags = context->tags[PROPAGATED_TAGS].ntags;
- context->status.n_propagated_binary_tags =
- context->tags[PROPAGATED_BINARY_TAGS].ntags;
- // TODO(aveitch): check that BINARY flag is correct for each type.
return context;
}
diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c
index 7176c01b05..eeac3c146c 100644
--- a/src/core/channel/client_channel.c
+++ b/src/core/channel/client_channel.c
@@ -78,8 +78,8 @@ typedef struct client_channel_channel_data {
int exit_idle_when_lb_policy_arrives;
/** owning stack */
grpc_channel_stack *owning_stack;
- /** interested parties */
- grpc_pollset_set interested_parties;
+ /** interested parties (owned) */
+ grpc_pollset_set *interested_parties;
} channel_data;
/** We create one watcher for each new lb_policy that is returned from a
@@ -183,8 +183,8 @@ static void cc_on_config_changed(grpc_exec_ctx *exec_ctx, void *arg,
chand->incoming_configuration = NULL;
if (lb_policy != NULL) {
- grpc_pollset_set_add_pollset_set(exec_ctx, &lb_policy->interested_parties,
- &chand->interested_parties);
+ grpc_pollset_set_add_pollset_set(exec_ctx, lb_policy->interested_parties,
+ chand->interested_parties);
}
gpr_mu_lock(&chand->mu_config);
@@ -231,9 +231,8 @@ static void cc_on_config_changed(grpc_exec_ctx *exec_ctx, void *arg,
}
if (old_lb_policy != NULL) {
- grpc_pollset_set_del_pollset_set(exec_ctx,
- &old_lb_policy->interested_parties,
- &chand->interested_parties);
+ grpc_pollset_set_del_pollset_set(
+ exec_ctx, old_lb_policy->interested_parties, chand->interested_parties);
GRPC_LB_POLICY_UNREF(exec_ctx, old_lb_policy, "channel");
}
@@ -254,7 +253,7 @@ static void cc_start_transport_op(grpc_exec_ctx *exec_ctx,
GPR_ASSERT(op->set_accept_stream == NULL);
if (op->bind_pollset != NULL) {
- grpc_pollset_set_add_pollset(exec_ctx, &chand->interested_parties,
+ grpc_pollset_set_add_pollset(exec_ctx, chand->interested_parties,
op->bind_pollset);
}
@@ -284,8 +283,8 @@ static void cc_start_transport_op(grpc_exec_ctx *exec_ctx,
chand->resolver = NULL;
if (chand->lb_policy != NULL) {
grpc_pollset_set_del_pollset_set(exec_ctx,
- &chand->lb_policy->interested_parties,
- &chand->interested_parties);
+ chand->lb_policy->interested_parties,
+ chand->interested_parties);
GRPC_LB_POLICY_UNREF(exec_ctx, chand->lb_policy, "channel");
chand->lb_policy = NULL;
}
@@ -411,7 +410,7 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_connectivity_state_init(&chand->state_tracker, GRPC_CHANNEL_IDLE,
"client_channel");
- grpc_pollset_set_init(&chand->interested_parties);
+ chand->interested_parties = grpc_pollset_set_create();
}
/* Destructor for channel_data */
@@ -425,12 +424,12 @@ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
}
if (chand->lb_policy != NULL) {
grpc_pollset_set_del_pollset_set(exec_ctx,
- &chand->lb_policy->interested_parties,
- &chand->interested_parties);
+ chand->lb_policy->interested_parties,
+ chand->interested_parties);
GRPC_LB_POLICY_UNREF(exec_ctx, chand->lb_policy, "channel");
}
grpc_connectivity_state_destroy(exec_ctx, &chand->state_tracker);
- grpc_pollset_set_destroy(&chand->interested_parties);
+ grpc_pollset_set_destroy(chand->interested_parties);
gpr_mu_destroy(&chand->mu_config);
}
@@ -501,7 +500,7 @@ static void on_external_watch_complete(grpc_exec_ctx *exec_ctx, void *arg,
bool iomgr_success) {
external_connectivity_watcher *w = arg;
grpc_closure *follow_up = w->on_complete;
- grpc_pollset_set_del_pollset(exec_ctx, &w->chand->interested_parties,
+ grpc_pollset_set_del_pollset(exec_ctx, w->chand->interested_parties,
w->pollset);
GRPC_CHANNEL_STACK_UNREF(exec_ctx, w->chand->owning_stack,
"external_connectivity_watcher");
@@ -517,7 +516,7 @@ void grpc_client_channel_watch_connectivity_state(
w->chand = chand;
w->pollset = pollset;
w->on_complete = on_complete;
- grpc_pollset_set_add_pollset(exec_ctx, &chand->interested_parties, pollset);
+ grpc_pollset_set_add_pollset(exec_ctx, chand->interested_parties, pollset);
grpc_closure_init(&w->my_closure, on_external_watch_complete, w);
GRPC_CHANNEL_STACK_REF(w->chand->owning_stack,
"external_connectivity_watcher");
diff --git a/src/core/client_config/lb_policies/pick_first.c b/src/core/client_config/lb_policies/pick_first.c
index 459bbebb68..81167b31c8 100644
--- a/src/core/client_config/lb_policies/pick_first.c
+++ b/src/core/client_config/lb_policies/pick_first.c
@@ -31,8 +31,8 @@
*
*/
-#include "src/core/client_config/lb_policy_factory.h"
#include "src/core/client_config/lb_policies/pick_first.h"
+#include "src/core/client_config/lb_policy_factory.h"
#include <string.h>
@@ -119,7 +119,7 @@ void pf_shutdown(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
while (pp != NULL) {
pending_pick *next = pp->next;
*pp->target = NULL;
- grpc_pollset_set_del_pollset(exec_ctx, &p->base.interested_parties,
+ grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties,
pp->pollset);
grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, true, NULL);
gpr_free(pp);
@@ -137,7 +137,7 @@ static void pf_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
while (pp != NULL) {
pending_pick *next = pp->next;
if (pp->target == target) {
- grpc_pollset_set_del_pollset(exec_ctx, &p->base.interested_parties,
+ grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties,
pp->pollset);
*target = NULL;
grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, false, NULL);
@@ -158,7 +158,7 @@ static void start_picking(grpc_exec_ctx *exec_ctx, pick_first_lb_policy *p) {
GRPC_LB_POLICY_WEAK_REF(&p->base, "pick_first_connectivity");
grpc_subchannel_notify_on_state_change(
exec_ctx, p->subchannels[p->checking_subchannel],
- &p->base.interested_parties, &p->checking_connectivity,
+ p->base.interested_parties, &p->checking_connectivity,
&p->connectivity_changed);
}
@@ -195,8 +195,7 @@ int pf_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, grpc_pollset *pollset,
if (!p->started_picking) {
start_picking(exec_ctx, p);
}
- grpc_pollset_set_add_pollset(exec_ctx, &p->base.interested_parties,
- pollset);
+ grpc_pollset_set_add_pollset(exec_ctx, p->base.interested_parties, pollset);
pp = gpr_malloc(sizeof(*pp));
pp->next = p->pending_picks;
pp->pollset = pollset;
@@ -253,7 +252,7 @@ static void pf_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg,
p->checking_connectivity, "selected_changed");
if (p->checking_connectivity != GRPC_CHANNEL_FATAL_FAILURE) {
grpc_connected_subchannel_notify_on_state_change(
- exec_ctx, selected, &p->base.interested_parties,
+ exec_ctx, selected, p->base.interested_parties,
&p->checking_connectivity, &p->connectivity_changed);
} else {
GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &p->base, "pick_first_connectivity");
@@ -278,13 +277,13 @@ static void pf_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg,
while ((pp = p->pending_picks)) {
p->pending_picks = pp->next;
*pp->target = selected;
- grpc_pollset_set_del_pollset(exec_ctx, &p->base.interested_parties,
+ grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties,
pp->pollset);
grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, true, NULL);
gpr_free(pp);
}
grpc_connected_subchannel_notify_on_state_change(
- exec_ctx, selected, &p->base.interested_parties,
+ exec_ctx, selected, p->base.interested_parties,
&p->checking_connectivity, &p->connectivity_changed);
break;
case GRPC_CHANNEL_TRANSIENT_FAILURE:
@@ -298,7 +297,7 @@ static void pf_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg,
if (p->checking_connectivity == GRPC_CHANNEL_TRANSIENT_FAILURE) {
grpc_subchannel_notify_on_state_change(
exec_ctx, p->subchannels[p->checking_subchannel],
- &p->base.interested_parties, &p->checking_connectivity,
+ p->base.interested_parties, &p->checking_connectivity,
&p->connectivity_changed);
} else {
goto loop;
@@ -311,7 +310,7 @@ static void pf_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg,
"connecting_changed");
grpc_subchannel_notify_on_state_change(
exec_ctx, p->subchannels[p->checking_subchannel],
- &p->base.interested_parties, &p->checking_connectivity,
+ p->base.interested_parties, &p->checking_connectivity,
&p->connectivity_changed);
break;
case GRPC_CHANNEL_FATAL_FAILURE:
diff --git a/src/core/client_config/lb_policies/round_robin.c b/src/core/client_config/lb_policies/round_robin.c
index b1171c45b0..98d9acc75b 100644
--- a/src/core/client_config/lb_policies/round_robin.c
+++ b/src/core/client_config/lb_policies/round_robin.c
@@ -260,7 +260,7 @@ static void rr_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
while (pp != NULL) {
pending_pick *next = pp->next;
if (pp->target == target) {
- grpc_pollset_set_del_pollset(exec_ctx, &p->base.interested_parties,
+ grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties,
pp->pollset);
*target = NULL;
grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, false, NULL);
@@ -285,7 +285,7 @@ static void start_picking(grpc_exec_ctx *exec_ctx, round_robin_lb_policy *p) {
subchannel_data *sd = p->subchannels[i];
sd->connectivity_state = GRPC_CHANNEL_IDLE;
grpc_subchannel_notify_on_state_change(
- exec_ctx, sd->subchannel, &p->base.interested_parties,
+ exec_ctx, sd->subchannel, p->base.interested_parties,
&sd->connectivity_state, &sd->connectivity_changed_closure);
GRPC_LB_POLICY_WEAK_REF(&p->base, "round_robin_connectivity");
}
@@ -322,8 +322,7 @@ int rr_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, grpc_pollset *pollset,
if (!p->started_picking) {
start_picking(exec_ctx, p);
}
- grpc_pollset_set_add_pollset(exec_ctx, &p->base.interested_parties,
- pollset);
+ grpc_pollset_set_add_pollset(exec_ctx, p->base.interested_parties, pollset);
pp = gpr_malloc(sizeof(*pp));
pp->next = p->pending_picks;
pp->pollset = pollset;
@@ -374,13 +373,13 @@ static void rr_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg,
"[RR CONN CHANGED] TARGET <-- SUBCHANNEL %p (NODE %p)",
selected->subchannel, selected);
}
- grpc_pollset_set_del_pollset(exec_ctx, &p->base.interested_parties,
+ grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties,
pp->pollset);
grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, true, NULL);
gpr_free(pp);
}
grpc_subchannel_notify_on_state_change(
- exec_ctx, sd->subchannel, &p->base.interested_parties,
+ exec_ctx, sd->subchannel, p->base.interested_parties,
&sd->connectivity_state, &sd->connectivity_changed_closure);
break;
case GRPC_CHANNEL_CONNECTING:
@@ -389,13 +388,13 @@ static void rr_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg,
sd->connectivity_state,
"connecting_changed");
grpc_subchannel_notify_on_state_change(
- exec_ctx, sd->subchannel, &p->base.interested_parties,
+ exec_ctx, sd->subchannel, p->base.interested_parties,
&sd->connectivity_state, &sd->connectivity_changed_closure);
break;
case GRPC_CHANNEL_TRANSIENT_FAILURE:
/* renew state notification */
grpc_subchannel_notify_on_state_change(
- exec_ctx, sd->subchannel, &p->base.interested_parties,
+ exec_ctx, sd->subchannel, p->base.interested_parties,
&sd->connectivity_state, &sd->connectivity_changed_closure);
/* remove from ready list if still present */
diff --git a/src/core/client_config/lb_policy.c b/src/core/client_config/lb_policy.c
index d4672f6b25..0d8b007336 100644
--- a/src/core/client_config/lb_policy.c
+++ b/src/core/client_config/lb_policy.c
@@ -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
@@ -39,7 +39,7 @@ void grpc_lb_policy_init(grpc_lb_policy *policy,
const grpc_lb_policy_vtable *vtable) {
policy->vtable = vtable;
gpr_atm_no_barrier_store(&policy->ref_pair, 1 << WEAK_REF_BITS);
- grpc_pollset_set_init(&policy->interested_parties);
+ policy->interested_parties = grpc_pollset_set_create();
}
#ifdef GRPC_LB_POLICY_REFCOUNT_DEBUG
@@ -93,7 +93,7 @@ void grpc_lb_policy_weak_unref(grpc_exec_ctx *exec_ctx,
gpr_atm old_val =
ref_mutate(policy, -(gpr_atm)1, 1 REF_MUTATE_PASS_ARGS("WEAK_UNREF"));
if (old_val == 1) {
- grpc_pollset_set_destroy(&policy->interested_parties);
+ grpc_pollset_set_destroy(policy->interested_parties);
policy->vtable->destroy(exec_ctx, policy);
}
}
diff --git a/src/core/client_config/lb_policy.h b/src/core/client_config/lb_policy.h
index db5238c8ca..3457390606 100644
--- a/src/core/client_config/lb_policy.h
+++ b/src/core/client_config/lb_policy.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
@@ -48,7 +48,8 @@ typedef void (*grpc_lb_completion)(void *cb_arg, grpc_subchannel *subchannel,
struct grpc_lb_policy {
const grpc_lb_policy_vtable *vtable;
gpr_atm ref_pair;
- grpc_pollset_set interested_parties;
+ /* owned pointer to interested parties in load balancing decisions */
+ grpc_pollset_set *interested_parties;
};
struct grpc_lb_policy_vtable {
diff --git a/src/core/client_config/subchannel.c b/src/core/client_config/subchannel.c
index 6599c75dba..d91dd116b8 100644
--- a/src/core/client_config/subchannel.c
+++ b/src/core/client_config/subchannel.c
@@ -108,7 +108,7 @@ struct grpc_subchannel {
/** pollset_set tracking who's interested in a connection
being setup */
- grpc_pollset_set pollset_set;
+ grpc_pollset_set *pollset_set;
/** active connection, or null; of type grpc_connected_subchannel */
gpr_atm connected_subchannel;
@@ -209,7 +209,7 @@ static void subchannel_destroy(grpc_exec_ctx *exec_ctx, void *arg,
gpr_slice_unref(c->initial_connect_string);
grpc_connectivity_state_destroy(exec_ctx, &c->state_tracker);
grpc_connector_unref(exec_ctx, c->connector);
- grpc_pollset_set_destroy(&c->pollset_set);
+ grpc_pollset_set_destroy(c->pollset_set);
grpc_subchannel_key_destroy(exec_ctx, c->key);
gpr_free(c);
}
@@ -326,7 +326,7 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx,
}
c->addr = gpr_malloc(args->addr_len);
memcpy(c->addr, args->addr, args->addr_len);
- grpc_pollset_set_init(&c->pollset_set);
+ c->pollset_set = grpc_pollset_set_create();
c->addr_len = args->addr_len;
grpc_set_initial_connect_string(&c->addr, &c->addr_len,
&c->initial_connect_string);
@@ -345,7 +345,7 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx,
static void continue_connect(grpc_exec_ctx *exec_ctx, grpc_subchannel *c) {
grpc_connect_in_args args;
- args.interested_parties = &c->pollset_set;
+ args.interested_parties = c->pollset_set;
args.addr = c->addr;
args.addr_len = c->addr_len;
args.deadline = compute_connect_deadline(c);
@@ -379,7 +379,7 @@ static void on_external_state_watcher_done(grpc_exec_ctx *exec_ctx, void *arg,
external_state_watcher *w = arg;
grpc_closure *follow_up = w->notify;
if (w->pollset_set != NULL) {
- grpc_pollset_set_del_pollset_set(exec_ctx, &w->subchannel->pollset_set,
+ grpc_pollset_set_del_pollset_set(exec_ctx, w->subchannel->pollset_set,
w->pollset_set);
}
gpr_mu_lock(&w->subchannel->mu);
@@ -395,7 +395,6 @@ void grpc_subchannel_notify_on_state_change(
grpc_exec_ctx *exec_ctx, grpc_subchannel *c,
grpc_pollset_set *interested_parties, grpc_connectivity_state *state,
grpc_closure *notify) {
- int do_connect = 0;
external_state_watcher *w;
if (state == NULL) {
@@ -415,7 +414,7 @@ void grpc_subchannel_notify_on_state_change(
w->notify = notify;
grpc_closure_init(&w->closure, on_external_state_watcher_done, w);
if (interested_parties != NULL) {
- grpc_pollset_set_add_pollset_set(exec_ctx, &c->pollset_set,
+ grpc_pollset_set_add_pollset_set(exec_ctx, c->pollset_set,
interested_parties);
}
GRPC_SUBCHANNEL_WEAK_REF(c, "external_state_watcher");
@@ -425,17 +424,13 @@ void grpc_subchannel_notify_on_state_change(
w->next->prev = w->prev->next = w;
if (grpc_connectivity_state_notify_on_state_change(
exec_ctx, &c->state_tracker, state, &w->closure)) {
- do_connect = 1;
c->connecting = 1;
/* released by connection */
GRPC_SUBCHANNEL_WEAK_REF(c, "connecting");
+ start_connect(exec_ctx, c);
}
gpr_mu_unlock(&c->mu);
}
-
- if (do_connect) {
- start_connect(exec_ctx, c);
- }
}
void grpc_connected_subchannel_process_transport_op(
@@ -573,7 +568,7 @@ static void publish_transport(grpc_exec_ctx *exec_ctx, grpc_subchannel *c) {
GRPC_SUBCHANNEL_WEAK_REF(c, "state_watcher");
GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connecting");
grpc_connected_subchannel_notify_on_state_change(
- exec_ctx, con, &c->pollset_set, &sw_subchannel->connectivity_state,
+ exec_ctx, con, c->pollset_set, &sw_subchannel->connectivity_state,
&sw_subchannel->closure);
/* signal completion */
@@ -635,11 +630,12 @@ static void on_alarm(grpc_exec_ctx *exec_ctx, void *arg, bool iomgr_success) {
if (c->disconnected) {
iomgr_success = 0;
}
- gpr_mu_unlock(&c->mu);
if (iomgr_success) {
update_reconnect_parameters(c);
continue_connect(exec_ctx, c);
+ gpr_mu_unlock(&c->mu);
} else {
+ gpr_mu_unlock(&c->mu);
GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connecting");
}
}
diff --git a/src/core/httpcli/httpcli.c b/src/core/httpcli/httpcli.c
index 71237bb614..1219c444c7 100644
--- a/src/core/httpcli/httpcli.c
+++ b/src/core/httpcli/httpcli.c
@@ -31,20 +31,22 @@
*
*/
-#include "src/core/iomgr/sockaddr.h"
#include "src/core/httpcli/httpcli.h"
+#include "src/core/iomgr/sockaddr.h"
#include <string.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+
+#include "src/core/httpcli/format_request.h"
+#include "src/core/httpcli/parser.h"
#include "src/core/iomgr/endpoint.h"
+#include "src/core/iomgr/iomgr_internal.h"
#include "src/core/iomgr/resolve_address.h"
#include "src/core/iomgr/tcp_client.h"
-#include "src/core/httpcli/format_request.h"
-#include "src/core/httpcli/parser.h"
#include "src/core/support/string.h"
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-#include <grpc/support/string_util.h>
typedef struct {
gpr_slice request_text;
@@ -84,18 +86,18 @@ const grpc_httpcli_handshaker grpc_httpcli_plaintext = {"http",
plaintext_handshake};
void grpc_httpcli_context_init(grpc_httpcli_context *context) {
- grpc_pollset_set_init(&context->pollset_set);
+ context->pollset_set = grpc_pollset_set_create();
}
void grpc_httpcli_context_destroy(grpc_httpcli_context *context) {
- grpc_pollset_set_destroy(&context->pollset_set);
+ grpc_pollset_set_destroy(context->pollset_set);
}
static void next_address(grpc_exec_ctx *exec_ctx, internal_request *req);
static void finish(grpc_exec_ctx *exec_ctx, internal_request *req,
int success) {
- grpc_pollset_set_del_pollset(exec_ctx, &req->context->pollset_set,
+ grpc_pollset_set_del_pollset(exec_ctx, req->context->pollset_set,
req->pollset);
req->on_response(exec_ctx, req->user_data, success ? &req->parser.r : NULL);
grpc_httpcli_parser_destroy(&req->parser);
@@ -197,7 +199,7 @@ static void next_address(grpc_exec_ctx *exec_ctx, internal_request *req) {
addr = &req->addresses->addrs[req->next_address++];
grpc_closure_init(&req->connected, on_connected, req);
grpc_tcp_client_connect(
- exec_ctx, &req->connected, &req->ep, &req->context->pollset_set,
+ exec_ctx, &req->connected, &req->ep, req->context->pollset_set,
(struct sockaddr *)&addr->addr, addr->len, req->deadline);
}
@@ -237,7 +239,7 @@ static void internal_request_begin(
req->host = gpr_strdup(request->host);
req->ssl_host_override = gpr_strdup(request->ssl_host_override);
- grpc_pollset_set_add_pollset(exec_ctx, &req->context->pollset_set,
+ grpc_pollset_set_add_pollset(exec_ctx, req->context->pollset_set,
req->pollset);
grpc_resolve_address(request->host, req->handshaker->default_port,
on_resolved, req);
diff --git a/src/core/httpcli/httpcli.h b/src/core/httpcli/httpcli.h
index 30875d71f1..c9cd987c79 100644
--- a/src/core/httpcli/httpcli.h
+++ b/src/core/httpcli/httpcli.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
@@ -39,6 +39,7 @@
#include <grpc/support/time.h>
#include "src/core/iomgr/endpoint.h"
+#include "src/core/iomgr/iomgr_internal.h"
#include "src/core/iomgr/pollset_set.h"
/* User agent this library reports */
@@ -56,7 +57,7 @@ typedef struct grpc_httpcli_header {
TODO(ctiller): allow caching and capturing multiple requests for the
same content and combining them */
typedef struct grpc_httpcli_context {
- grpc_pollset_set pollset_set;
+ grpc_pollset_set *pollset_set;
} grpc_httpcli_context;
typedef struct {
diff --git a/src/core/httpcli/httpcli_security_connector.c b/src/core/httpcli/httpcli_security_connector.c
index 41ad1de6c0..156961a377 100644
--- a/src/core/httpcli/httpcli_security_connector.c
+++ b/src/core/httpcli/httpcli_security_connector.c
@@ -59,7 +59,7 @@ static void httpcli_ssl_destroy(grpc_security_connector *sc) {
}
static void httpcli_ssl_do_handshake(grpc_exec_ctx *exec_ctx,
- grpc_security_connector *sc,
+ grpc_channel_security_connector *sc,
grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb,
void *user_data) {
@@ -78,8 +78,8 @@ static void httpcli_ssl_do_handshake(grpc_exec_ctx *exec_ctx,
tsi_result_to_string(result));
cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL);
} else {
- grpc_do_security_handshake(exec_ctx, handshaker, sc, nonsecure_endpoint, cb,
- user_data);
+ grpc_do_security_handshake(exec_ctx, handshaker, &sc->base, true,
+ nonsecure_endpoint, cb, user_data);
}
}
@@ -103,7 +103,7 @@ static void httpcli_ssl_check_peer(grpc_exec_ctx *exec_ctx,
}
static grpc_security_connector_vtable httpcli_ssl_vtable = {
- httpcli_ssl_destroy, httpcli_ssl_do_handshake, httpcli_ssl_check_peer};
+ httpcli_ssl_destroy, httpcli_ssl_check_peer};
static grpc_security_status httpcli_ssl_channel_security_connector_create(
const unsigned char *pem_root_certs, size_t pem_root_certs_size,
@@ -121,7 +121,6 @@ static grpc_security_status httpcli_ssl_channel_security_connector_create(
memset(c, 0, sizeof(grpc_httpcli_ssl_channel_security_connector));
gpr_ref_init(&c->base.base.refcount, 1);
- c->base.base.is_client_side = 1;
c->base.base.vtable = &httpcli_ssl_vtable;
if (secure_peer_name != NULL) {
c->secure_peer_name = gpr_strdup(secure_peer_name);
@@ -136,6 +135,7 @@ static grpc_security_status httpcli_ssl_channel_security_connector_create(
*sc = NULL;
return GRPC_SECURITY_ERROR;
}
+ c->base.do_handshake = httpcli_ssl_do_handshake;
*sc = &c->base;
return GRPC_SECURITY_OK;
}
@@ -180,8 +180,8 @@ static void ssl_handshake(grpc_exec_ctx *exec_ctx, void *arg,
GPR_ASSERT(httpcli_ssl_channel_security_connector_create(
pem_root_certs, pem_root_certs_size, host, &sc) ==
GRPC_SECURITY_OK);
- grpc_security_connector_do_handshake(exec_ctx, &sc->base, tcp,
- on_secure_transport_setup_done, c);
+ grpc_channel_security_connector_do_handshake(
+ exec_ctx, sc, tcp, on_secure_transport_setup_done, c);
GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "httpcli");
}
diff --git a/src/core/iomgr/fd_posix.c b/src/core/iomgr/fd_posix.c
index 85eadd754b..4ba7c5df94 100644
--- a/src/core/iomgr/fd_posix.c
+++ b/src/core/iomgr/fd_posix.c
@@ -46,6 +46,8 @@
#include <grpc/support/string_util.h>
#include <grpc/support/useful.h>
+#include "src/core/iomgr/pollset_posix.h"
+
#define CLOSURE_NOT_READY ((grpc_closure *)0)
#define CLOSURE_READY ((grpc_closure *)1)
@@ -175,11 +177,11 @@ int grpc_fd_is_orphaned(grpc_fd *fd) {
}
static void pollset_kick_locked(grpc_fd_watcher *watcher) {
- gpr_mu_lock(GRPC_POLLSET_MU(watcher->pollset));
+ gpr_mu_lock(&watcher->pollset->mu);
GPR_ASSERT(watcher->worker);
grpc_pollset_kick_ext(watcher->pollset, watcher->worker,
GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP);
- gpr_mu_unlock(GRPC_POLLSET_MU(watcher->pollset));
+ gpr_mu_unlock(&watcher->pollset->mu);
}
static void maybe_wake_one_watcher_locked(grpc_fd *fd) {
diff --git a/src/core/iomgr/iomgr.c b/src/core/iomgr/iomgr.c
index 04580150f3..9c89c2c08a 100644
--- a/src/core/iomgr/iomgr.c
+++ b/src/core/iomgr/iomgr.c
@@ -41,9 +41,11 @@
#include <grpc/support/string_util.h>
#include <grpc/support/sync.h>
#include <grpc/support/thd.h>
+#include <grpc/support/useful.h>
#include "src/core/iomgr/iomgr_internal.h"
#include "src/core/iomgr/timer.h"
+#include "src/core/support/env.h"
#include "src/core/support/string.h"
static gpr_mu g_mu;
@@ -116,6 +118,9 @@ void grpc_iomgr_shutdown(void) {
"memory leaks are likely",
count_objects());
dump_objects("LEAKED");
+ if (grpc_iomgr_abort_on_leaks()) {
+ abort();
+ }
}
break;
}
@@ -154,3 +159,14 @@ void grpc_iomgr_unregister_object(grpc_iomgr_object *obj) {
gpr_mu_unlock(&g_mu);
gpr_free(obj->name);
}
+
+bool grpc_iomgr_abort_on_leaks(void) {
+ char *env = gpr_getenv("GRPC_ABORT_ON_LEAKS");
+ if (env == NULL) return false;
+ static const char *truthy[] = {"yes", "Yes", "YES", "true",
+ "True", "TRUE", "1"};
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(truthy); i++) {
+ if (0 == strcmp(env, truthy[i])) return true;
+ }
+ return false;
+}
diff --git a/src/core/iomgr/iomgr_internal.h b/src/core/iomgr/iomgr_internal.h
index e372c18e8a..ac2c46ebe6 100644
--- a/src/core/iomgr/iomgr_internal.h
+++ b/src/core/iomgr/iomgr_internal.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,6 +34,8 @@
#ifndef GRPC_INTERNAL_CORE_IOMGR_IOMGR_INTERNAL_H
#define GRPC_INTERNAL_CORE_IOMGR_IOMGR_INTERNAL_H
+#include <stdbool.h>
+
#include "src/core/iomgr/iomgr.h"
#include <grpc/support/sync.h>
@@ -55,4 +57,6 @@ void grpc_iomgr_platform_flush(void);
/** tear down all platform specific global iomgr structures */
void grpc_iomgr_platform_shutdown(void);
+bool grpc_iomgr_abort_on_leaks(void);
+
#endif /* GRPC_INTERNAL_CORE_IOMGR_IOMGR_INTERNAL_H */
diff --git a/src/core/iomgr/pollset.h b/src/core/iomgr/pollset.h
index c6b0214dea..92a0374ddd 100644
--- a/src/core/iomgr/pollset.h
+++ b/src/core/iomgr/pollset.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
@@ -35,8 +35,11 @@
#define GRPC_INTERNAL_CORE_IOMGR_POLLSET_H
#include <grpc/support/port_platform.h>
+#include <grpc/support/sync.h>
#include <grpc/support/time.h>
+#include "src/core/iomgr/exec_ctx.h"
+
#define GRPC_POLLSET_KICK_BROADCAST ((grpc_pollset_worker *)1)
/* A grpc_pollset is a set of file descriptors that a higher level item is
@@ -46,15 +49,11 @@
- a completion queue might keep a pollset with an entry for each transport
that is servicing a call that it's tracking */
-#ifdef GPR_POSIX_SOCKET
-#include "src/core/iomgr/pollset_posix.h"
-#endif
-
-#ifdef GPR_WIN32
-#include "src/core/iomgr/pollset_windows.h"
-#endif
+typedef struct grpc_pollset grpc_pollset;
+typedef struct grpc_pollset_worker grpc_pollset_worker;
-void grpc_pollset_init(grpc_pollset *pollset);
+size_t grpc_pollset_size(void);
+void grpc_pollset_init(grpc_pollset *pollset, gpr_mu **mu);
/* Begin shutting down the pollset, and call closure when done.
* GRPC_POLLSET_MU(pollset) must be held */
void grpc_pollset_shutdown(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
@@ -83,7 +82,7 @@ void grpc_pollset_destroy(grpc_pollset *pollset);
pollset
lock */
void grpc_pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
- grpc_pollset_worker *worker, gpr_timespec now,
+ grpc_pollset_worker **worker, gpr_timespec now,
gpr_timespec deadline);
/* Break one polling thread out of polling work for this pollset.
diff --git a/src/core/iomgr/pollset_multipoller_with_epoll.c b/src/core/iomgr/pollset_multipoller_with_epoll.c
index 4acae2bb71..2e0f27fab8 100644
--- a/src/core/iomgr/pollset_multipoller_with_epoll.c
+++ b/src/core/iomgr/pollset_multipoller_with_epoll.c
@@ -45,6 +45,7 @@
#include <grpc/support/log.h>
#include <grpc/support/useful.h>
#include "src/core/iomgr/fd_posix.h"
+#include "src/core/iomgr/pollset_posix.h"
#include "src/core/profiling/timers.h"
#include "src/core/support/block_annotate.h"
diff --git a/src/core/iomgr/pollset_multipoller_with_poll_posix.c b/src/core/iomgr/pollset_multipoller_with_poll_posix.c
index 809f8f39da..4dddfff230 100644
--- a/src/core/iomgr/pollset_multipoller_with_poll_posix.c
+++ b/src/core/iomgr/pollset_multipoller_with_poll_posix.c
@@ -42,13 +42,15 @@
#include <stdlib.h>
#include <string.h>
-#include "src/core/iomgr/fd_posix.h"
-#include "src/core/iomgr/iomgr_internal.h"
-#include "src/core/support/block_annotate.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/useful.h>
+#include "src/core/iomgr/fd_posix.h"
+#include "src/core/iomgr/iomgr_internal.h"
+#include "src/core/iomgr/pollset_posix.h"
+#include "src/core/support/block_annotate.h"
+
typedef struct {
/* all polled fds */
size_t fd_count;
diff --git a/src/core/iomgr/pollset_posix.c b/src/core/iomgr/pollset_posix.c
index 1063727248..e895a77884 100644
--- a/src/core/iomgr/pollset_posix.c
+++ b/src/core/iomgr/pollset_posix.c
@@ -42,16 +42,16 @@
#include <string.h>
#include <unistd.h>
-#include "src/core/iomgr/fd_posix.h"
-#include "src/core/iomgr/iomgr_internal.h"
-#include "src/core/iomgr/socket_utils_posix.h"
-#include "src/core/profiling/timers.h"
-#include "src/core/support/block_annotate.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/thd.h>
#include <grpc/support/tls.h>
#include <grpc/support/useful.h>
+#include "src/core/iomgr/fd_posix.h"
+#include "src/core/iomgr/iomgr_internal.h"
+#include "src/core/iomgr/socket_utils_posix.h"
+#include "src/core/profiling/timers.h"
+#include "src/core/support/block_annotate.h"
GPR_TLS_DECL(g_current_thread_poller);
GPR_TLS_DECL(g_current_thread_worker);
@@ -97,6 +97,8 @@ static void push_front_worker(grpc_pollset *p, grpc_pollset_worker *worker) {
worker->prev->next = worker->next->prev = worker;
}
+size_t grpc_pollset_size(void) { return sizeof(grpc_pollset); }
+
void grpc_pollset_kick_ext(grpc_pollset *p,
grpc_pollset_worker *specific_worker,
uint32_t flags) {
@@ -186,8 +188,9 @@ void grpc_kick_poller(void) { grpc_wakeup_fd_wakeup(&grpc_global_wakeup_fd); }
static void become_basic_pollset(grpc_pollset *pollset, grpc_fd *fd_or_null);
-void grpc_pollset_init(grpc_pollset *pollset) {
+void grpc_pollset_init(grpc_pollset *pollset, gpr_mu **mu) {
gpr_mu_init(&pollset->mu);
+ *mu = &pollset->mu;
pollset->root_worker.next = pollset->root_worker.prev = &pollset->root_worker;
pollset->in_flight_cbs = 0;
pollset->shutting_down = 0;
@@ -204,7 +207,6 @@ void grpc_pollset_destroy(grpc_pollset *pollset) {
GPR_ASSERT(!grpc_pollset_has_workers(pollset));
GPR_ASSERT(pollset->idle_jobs.head == pollset->idle_jobs.tail);
pollset->vtable->destroy(pollset);
- gpr_mu_destroy(&pollset->mu);
while (pollset->local_wakeup_cache) {
grpc_cached_wakeup_fd *next = pollset->local_wakeup_cache->next;
grpc_wakeup_fd_destroy(&pollset->local_wakeup_cache->fd);
@@ -246,8 +248,11 @@ static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset) {
}
void grpc_pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
- grpc_pollset_worker *worker, gpr_timespec now,
+ grpc_pollset_worker **worker_hdl, gpr_timespec now,
gpr_timespec deadline) {
+ grpc_pollset_worker worker;
+ *worker_hdl = &worker;
+
/* pollset->mu already held */
int added_worker = 0;
int locked = 1;
@@ -255,16 +260,16 @@ void grpc_pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
int keep_polling = 0;
GPR_TIMER_BEGIN("grpc_pollset_work", 0);
/* this must happen before we (potentially) drop pollset->mu */
- worker->next = worker->prev = NULL;
- worker->reevaluate_polling_on_wakeup = 0;
+ worker.next = worker.prev = NULL;
+ worker.reevaluate_polling_on_wakeup = 0;
if (pollset->local_wakeup_cache != NULL) {
- worker->wakeup_fd = pollset->local_wakeup_cache;
- pollset->local_wakeup_cache = worker->wakeup_fd->next;
+ worker.wakeup_fd = pollset->local_wakeup_cache;
+ pollset->local_wakeup_cache = worker.wakeup_fd->next;
} else {
- worker->wakeup_fd = gpr_malloc(sizeof(*worker->wakeup_fd));
- grpc_wakeup_fd_init(&worker->wakeup_fd->fd);
+ worker.wakeup_fd = gpr_malloc(sizeof(*worker.wakeup_fd));
+ grpc_wakeup_fd_init(&worker.wakeup_fd->fd);
}
- worker->kicked_specifically = 0;
+ worker.kicked_specifically = 0;
/* If there's work waiting for the pollset to be idle, and the
pollset is idle, then do that work */
if (!grpc_pollset_has_workers(pollset) &&
@@ -293,13 +298,13 @@ void grpc_pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
keep_polling = 0;
if (!pollset->kicked_without_pollers) {
if (!added_worker) {
- push_front_worker(pollset, worker);
+ push_front_worker(pollset, &worker);
added_worker = 1;
- gpr_tls_set(&g_current_thread_worker, (intptr_t)worker);
+ gpr_tls_set(&g_current_thread_worker, (intptr_t)&worker);
}
gpr_tls_set(&g_current_thread_poller, (intptr_t)pollset);
GPR_TIMER_BEGIN("maybe_work_and_unlock", 0);
- pollset->vtable->maybe_work_and_unlock(exec_ctx, pollset, worker,
+ pollset->vtable->maybe_work_and_unlock(exec_ctx, pollset, &worker,
deadline, now);
GPR_TIMER_END("maybe_work_and_unlock", 0);
locked = 0;
@@ -321,10 +326,10 @@ void grpc_pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
/* If we're forced to re-evaluate polling (via grpc_pollset_kick with
GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP) then we land here and force
a loop */
- if (worker->reevaluate_polling_on_wakeup) {
- worker->reevaluate_polling_on_wakeup = 0;
+ if (worker.reevaluate_polling_on_wakeup) {
+ worker.reevaluate_polling_on_wakeup = 0;
pollset->kicked_without_pollers = 0;
- if (queued_work || worker->kicked_specifically) {
+ if (queued_work || worker.kicked_specifically) {
/* If there's queued work on the list, then set the deadline to be
immediate so we get back out of the polling loop quickly */
deadline = gpr_inf_past(GPR_CLOCK_MONOTONIC);
@@ -333,12 +338,12 @@ void grpc_pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
}
}
if (added_worker) {
- remove_worker(pollset, worker);
+ remove_worker(pollset, &worker);
gpr_tls_set(&g_current_thread_worker, 0);
}
/* release wakeup fd to the local pool */
- worker->wakeup_fd->next = pollset->local_wakeup_cache;
- pollset->local_wakeup_cache = worker->wakeup_fd;
+ worker.wakeup_fd->next = pollset->local_wakeup_cache;
+ pollset->local_wakeup_cache = worker.wakeup_fd;
/* check shutdown conditions */
if (pollset->shutting_down) {
if (grpc_pollset_has_workers(pollset)) {
@@ -360,6 +365,7 @@ void grpc_pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
gpr_mu_lock(&pollset->mu);
}
}
+ *worker_hdl = NULL;
GPR_TIMER_END("grpc_pollset_work", 0);
}
diff --git a/src/core/iomgr/pollset_posix.h b/src/core/iomgr/pollset_posix.h
index 5868b3fa21..bbedb66b00 100644
--- a/src/core/iomgr/pollset_posix.h
+++ b/src/core/iomgr/pollset_posix.h
@@ -37,8 +37,10 @@
#include <poll.h>
#include <grpc/support/sync.h>
+
#include "src/core/iomgr/exec_ctx.h"
#include "src/core/iomgr/iomgr.h"
+#include "src/core/iomgr/pollset.h"
#include "src/core/iomgr/wakeup_fd_posix.h"
typedef struct grpc_pollset_vtable grpc_pollset_vtable;
@@ -53,15 +55,15 @@ typedef struct grpc_cached_wakeup_fd {
struct grpc_cached_wakeup_fd *next;
} grpc_cached_wakeup_fd;
-typedef struct grpc_pollset_worker {
+struct grpc_pollset_worker {
grpc_cached_wakeup_fd *wakeup_fd;
int reevaluate_polling_on_wakeup;
int kicked_specifically;
struct grpc_pollset_worker *next;
struct grpc_pollset_worker *prev;
-} grpc_pollset_worker;
+};
-typedef struct grpc_pollset {
+struct grpc_pollset {
/* pollsets under posix can mutate representation as fds are added and
removed.
For example, we may choose a poll() based implementation on linux for
@@ -81,7 +83,7 @@ typedef struct grpc_pollset {
} data;
/* Local cache of eventfds for workers */
grpc_cached_wakeup_fd *local_wakeup_cache;
-} grpc_pollset;
+};
struct grpc_pollset_vtable {
void (*add_fd)(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
@@ -93,8 +95,6 @@ struct grpc_pollset_vtable {
void (*destroy)(grpc_pollset *pollset);
};
-#define GRPC_POLLSET_MU(pollset) (&(pollset)->mu)
-
/* Add an fd to a pollset */
void grpc_pollset_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
struct grpc_fd *fd);
diff --git a/src/core/iomgr/pollset_set.h b/src/core/iomgr/pollset_set.h
index 09c04438f7..dddcd8313f 100644
--- a/src/core/iomgr/pollset_set.h
+++ b/src/core/iomgr/pollset_set.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
@@ -41,15 +41,9 @@
fd's (etc) that have been registered with the set_set to that pollset.
Registering fd's automatically adds them to all current pollsets. */
-#ifdef GPR_POSIX_SOCKET
-#include "src/core/iomgr/pollset_set_posix.h"
-#endif
+typedef struct grpc_pollset_set grpc_pollset_set;
-#ifdef GPR_WIN32
-#include "src/core/iomgr/pollset_set_windows.h"
-#endif
-
-void grpc_pollset_set_init(grpc_pollset_set *pollset_set);
+grpc_pollset_set *grpc_pollset_set_create(void);
void grpc_pollset_set_destroy(grpc_pollset_set *pollset_set);
void grpc_pollset_set_add_pollset(grpc_exec_ctx *exec_ctx,
grpc_pollset_set *pollset_set,
diff --git a/src/core/iomgr/pollset_set_posix.c b/src/core/iomgr/pollset_set_posix.c
index 4ec92202e3..9dc9aff4a8 100644
--- a/src/core/iomgr/pollset_set_posix.c
+++ b/src/core/iomgr/pollset_set_posix.c
@@ -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
@@ -41,11 +41,30 @@
#include <grpc/support/alloc.h>
#include <grpc/support/useful.h>
-#include "src/core/iomgr/pollset_set.h"
+#include "src/core/iomgr/pollset_posix.h"
+#include "src/core/iomgr/pollset_set_posix.h"
-void grpc_pollset_set_init(grpc_pollset_set *pollset_set) {
+struct grpc_pollset_set {
+ gpr_mu mu;
+
+ size_t pollset_count;
+ size_t pollset_capacity;
+ grpc_pollset **pollsets;
+
+ size_t pollset_set_count;
+ size_t pollset_set_capacity;
+ struct grpc_pollset_set **pollset_sets;
+
+ size_t fd_count;
+ size_t fd_capacity;
+ grpc_fd **fds;
+};
+
+grpc_pollset_set *grpc_pollset_set_create(void) {
+ grpc_pollset_set *pollset_set = gpr_malloc(sizeof(*pollset_set));
memset(pollset_set, 0, sizeof(*pollset_set));
gpr_mu_init(&pollset_set->mu);
+ return pollset_set;
}
void grpc_pollset_set_destroy(grpc_pollset_set *pollset_set) {
@@ -57,6 +76,7 @@ void grpc_pollset_set_destroy(grpc_pollset_set *pollset_set) {
gpr_free(pollset_set->pollsets);
gpr_free(pollset_set->pollset_sets);
gpr_free(pollset_set->fds);
+ gpr_free(pollset_set);
}
void grpc_pollset_set_add_pollset(grpc_exec_ctx *exec_ctx,
diff --git a/src/core/iomgr/pollset_set_posix.h b/src/core/iomgr/pollset_set_posix.h
index 4820a61e4b..7d1aaf4181 100644
--- a/src/core/iomgr/pollset_set_posix.h
+++ b/src/core/iomgr/pollset_set_posix.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
@@ -35,23 +35,7 @@
#define GRPC_INTERNAL_CORE_IOMGR_POLLSET_SET_POSIX_H
#include "src/core/iomgr/fd_posix.h"
-#include "src/core/iomgr/pollset_posix.h"
-
-typedef struct grpc_pollset_set {
- gpr_mu mu;
-
- size_t pollset_count;
- size_t pollset_capacity;
- grpc_pollset **pollsets;
-
- size_t pollset_set_count;
- size_t pollset_set_capacity;
- struct grpc_pollset_set **pollset_sets;
-
- size_t fd_count;
- size_t fd_capacity;
- grpc_fd **fds;
-} grpc_pollset_set;
+#include "src/core/iomgr/pollset_set.h"
void grpc_pollset_set_add_fd(grpc_exec_ctx *exec_ctx,
grpc_pollset_set *pollset_set, grpc_fd *fd);
diff --git a/src/core/iomgr/pollset_set_windows.c b/src/core/iomgr/pollset_set_windows.c
index 157b46ec32..3b8eca28e6 100644
--- a/src/core/iomgr/pollset_set_windows.c
+++ b/src/core/iomgr/pollset_set_windows.c
@@ -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
@@ -35,9 +35,9 @@
#ifdef GPR_WINSOCK_SOCKET
-#include "src/core/iomgr/pollset_set.h"
+#include "src/core/iomgr/pollset_set_windows.h"
-void grpc_pollset_set_init(grpc_pollset_set* pollset_set) {}
+grpc_pollset_set* grpc_pollset_set_create(pollset_set) { return NULL; }
void grpc_pollset_set_destroy(grpc_pollset_set* pollset_set) {}
diff --git a/src/core/iomgr/pollset_set_windows.h b/src/core/iomgr/pollset_set_windows.h
index cada0d2b61..9661cd2c39 100644
--- a/src/core/iomgr/pollset_set_windows.h
+++ b/src/core/iomgr/pollset_set_windows.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,6 +34,6 @@
#ifndef GRPC_INTERNAL_CORE_IOMGR_POLLSET_SET_WINDOWS_H
#define GRPC_INTERNAL_CORE_IOMGR_POLLSET_SET_WINDOWS_H
-typedef struct grpc_pollset_set { void *unused; } grpc_pollset_set;
+#include "src/core/iomgr/pollset_set.h"
#endif /* GRPC_INTERNAL_CORE_IOMGR_POLLSET_WINDOWS_H */
diff --git a/src/core/iomgr/pollset_windows.c b/src/core/iomgr/pollset_windows.c
index 35a956b27f..c7f30f435f 100644
--- a/src/core/iomgr/pollset_windows.c
+++ b/src/core/iomgr/pollset_windows.c
@@ -89,12 +89,15 @@ static void push_front_worker(grpc_pollset_worker *root,
worker->links[type].next->links[type].prev = worker;
}
+size_t grpc_pollset_size(void) { return sizeof(grpc_pollset); }
+
/* There isn't really any such thing as a pollset under Windows, due to the
nature of the IO completion ports. We're still going to provide a minimal
set of features for the sake of the rest of grpc. But grpc_pollset_work
won't actually do any polling, and return as quickly as possible. */
-void grpc_pollset_init(grpc_pollset *pollset) {
+void grpc_pollset_init(grpc_pollset *pollset, gpr_mu **mu) {
+ *mu = &grpc_polling_mu;
memset(pollset, 0, sizeof(*pollset));
pollset->root_worker.links[GRPC_POLLSET_WORKER_LINK_POLLSET].next =
pollset->root_worker.links[GRPC_POLLSET_WORKER_LINK_POLLSET].prev =
@@ -125,22 +128,25 @@ void grpc_pollset_reset(grpc_pollset *pollset) {
}
void grpc_pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
- grpc_pollset_worker *worker, gpr_timespec now,
+ grpc_pollset_worker **worker_hdl, gpr_timespec now,
gpr_timespec deadline) {
+ grpc_pollset_worker worker;
+ *worker_hdl = &worker;
+
int added_worker = 0;
- worker->links[GRPC_POLLSET_WORKER_LINK_POLLSET].next =
- worker->links[GRPC_POLLSET_WORKER_LINK_POLLSET].prev =
- worker->links[GRPC_POLLSET_WORKER_LINK_GLOBAL].next =
- worker->links[GRPC_POLLSET_WORKER_LINK_GLOBAL].prev = NULL;
- worker->kicked = 0;
- worker->pollset = pollset;
- gpr_cv_init(&worker->cv);
+ worker.links[GRPC_POLLSET_WORKER_LINK_POLLSET].next =
+ worker.links[GRPC_POLLSET_WORKER_LINK_POLLSET].prev =
+ worker.links[GRPC_POLLSET_WORKER_LINK_GLOBAL].next =
+ worker.links[GRPC_POLLSET_WORKER_LINK_GLOBAL].prev = NULL;
+ worker.kicked = 0;
+ worker.pollset = pollset;
+ gpr_cv_init(&worker.cv);
if (!pollset->kicked_without_pollers && !pollset->shutting_down) {
if (g_active_poller == NULL) {
grpc_pollset_worker *next_worker;
/* become poller */
pollset->is_iocp_worker = 1;
- g_active_poller = worker;
+ g_active_poller = &worker;
gpr_mu_unlock(&grpc_polling_mu);
grpc_iocp_work(exec_ctx, deadline);
grpc_exec_ctx_flush(exec_ctx);
@@ -167,12 +173,12 @@ void grpc_pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
goto done;
}
push_front_worker(&g_global_root_worker, GRPC_POLLSET_WORKER_LINK_GLOBAL,
- worker);
+ &worker);
push_front_worker(&pollset->root_worker, GRPC_POLLSET_WORKER_LINK_POLLSET,
- worker);
+ &worker);
added_worker = 1;
- while (!worker->kicked) {
- if (gpr_cv_wait(&worker->cv, &grpc_polling_mu, deadline)) {
+ while (!worker.kicked) {
+ if (gpr_cv_wait(&worker.cv, &grpc_polling_mu, deadline)) {
break;
}
}
@@ -186,10 +192,11 @@ done:
gpr_mu_lock(&grpc_polling_mu);
}
if (added_worker) {
- remove_worker(worker, GRPC_POLLSET_WORKER_LINK_GLOBAL);
- remove_worker(worker, GRPC_POLLSET_WORKER_LINK_POLLSET);
+ remove_worker(&worker, GRPC_POLLSET_WORKER_LINK_GLOBAL);
+ remove_worker(&worker, GRPC_POLLSET_WORKER_LINK_POLLSET);
}
- gpr_cv_destroy(&worker->cv);
+ gpr_cv_destroy(&worker.cv);
+ *worker_hdl = NULL;
}
void grpc_pollset_kick(grpc_pollset *p, grpc_pollset_worker *specific_worker) {
diff --git a/src/core/iomgr/pollset_windows.h b/src/core/iomgr/pollset_windows.h
index 65ba80619b..dc0b7a4104 100644
--- a/src/core/iomgr/pollset_windows.h
+++ b/src/core/iomgr/pollset_windows.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
@@ -72,8 +72,4 @@ struct grpc_pollset {
grpc_closure *on_shutdown;
};
-extern gpr_mu grpc_polling_mu;
-
-#define GRPC_POLLSET_MU(pollset) (&grpc_polling_mu)
-
#endif /* GRPC_INTERNAL_CORE_IOMGR_POLLSET_WINDOWS_H */
diff --git a/src/core/iomgr/tcp_client_posix.c b/src/core/iomgr/tcp_client_posix.c
index c76c2e3b0f..15727856ab 100644
--- a/src/core/iomgr/tcp_client_posix.c
+++ b/src/core/iomgr/tcp_client_posix.c
@@ -42,17 +42,19 @@
#include <string.h>
#include <unistd.h>
-#include "src/core/iomgr/timer.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/time.h>
+
#include "src/core/iomgr/iomgr_posix.h"
#include "src/core/iomgr/pollset_posix.h"
+#include "src/core/iomgr/pollset_set_posix.h"
#include "src/core/iomgr/sockaddr_utils.h"
#include "src/core/iomgr/socket_utils_posix.h"
#include "src/core/iomgr/tcp_posix.h"
+#include "src/core/iomgr/timer.h"
#include "src/core/support/string.h"
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-#include <grpc/support/string_util.h>
-#include <grpc/support/time.h>
extern int grpc_tcp_trace;
diff --git a/src/core/iomgr/tcp_posix.c b/src/core/iomgr/tcp_posix.c
index 048e907441..f74eb3fe51 100644
--- a/src/core/iomgr/tcp_posix.c
+++ b/src/core/iomgr/tcp_posix.c
@@ -40,8 +40,8 @@
#include <errno.h>
#include <stdlib.h>
#include <string.h>
-#include <sys/types.h>
#include <sys/socket.h>
+#include <sys/types.h>
#include <unistd.h>
#include <grpc/support/alloc.h>
@@ -51,9 +51,11 @@
#include <grpc/support/sync.h>
#include <grpc/support/time.h>
-#include "src/core/support/string.h"
#include "src/core/debug/trace.h"
+#include "src/core/iomgr/pollset_posix.h"
+#include "src/core/iomgr/pollset_set_posix.h"
#include "src/core/profiling/timers.h"
+#include "src/core/support/string.h"
#ifdef GPR_HAVE_MSG_NOSIGNAL
#define SENDMSG_FLAGS MSG_NOSIGNAL
diff --git a/src/core/iomgr/udp_server.h b/src/core/iomgr/udp_server.h
index 73a21c80ab..a9d0489edf 100644
--- a/src/core/iomgr/udp_server.h
+++ b/src/core/iomgr/udp_server.h
@@ -35,6 +35,7 @@
#define GRPC_INTERNAL_CORE_IOMGR_UDP_SERVER_H
#include "src/core/iomgr/endpoint.h"
+#include "src/core/iomgr/fd_posix.h"
/* Forward decl of grpc_server */
typedef struct grpc_server grpc_server;
diff --git a/src/core/iomgr/workqueue_posix.c b/src/core/iomgr/workqueue_posix.c
index da11df67ef..c096dbfb30 100644
--- a/src/core/iomgr/workqueue_posix.c
+++ b/src/core/iomgr/workqueue_posix.c
@@ -44,6 +44,7 @@
#include <grpc/support/useful.h>
#include "src/core/iomgr/fd_posix.h"
+#include "src/core/iomgr/pollset_posix.h"
static void on_readable(grpc_exec_ctx *exec_ctx, void *arg, bool success);
diff --git a/src/core/iomgr/workqueue_posix.h b/src/core/iomgr/workqueue_posix.h
index 589034fe1b..68f195ee0d 100644
--- a/src/core/iomgr/workqueue_posix.h
+++ b/src/core/iomgr/workqueue_posix.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,6 +34,8 @@
#ifndef GRPC_INTERNAL_CORE_IOMGR_WORKQUEUE_POSIX_H
#define GRPC_INTERNAL_CORE_IOMGR_WORKQUEUE_POSIX_H
+#include "src/core/iomgr/wakeup_fd_posix.h"
+
struct grpc_fd;
struct grpc_workqueue {
diff --git a/src/core/security/client_auth_filter.c b/src/core/security/client_auth_filter.c
index 57b367d00f..332d4259d2 100644
--- a/src/core/security/client_auth_filter.c
+++ b/src/core/security/client_auth_filter.c
@@ -310,7 +310,6 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
GPR_ASSERT(auth_context != NULL);
/* initialize members */
- GPR_ASSERT(sc->is_client_side);
chand->security_connector =
(grpc_channel_security_connector *)GRPC_SECURITY_CONNECTOR_REF(
sc, "client_auth_filter");
diff --git a/src/core/security/credentials.c b/src/core/security/credentials.c
index c58574bd6d..b4fa616fa7 100644
--- a/src/core/security/credentials.c
+++ b/src/core/security/credentials.c
@@ -166,7 +166,7 @@ void grpc_server_credentials_release(grpc_server_credentials *creds) {
}
grpc_security_status grpc_server_credentials_create_security_connector(
- grpc_server_credentials *creds, grpc_security_connector **sc) {
+ grpc_server_credentials *creds, grpc_server_security_connector **sc) {
if (creds == NULL || creds->vtable->create_security_connector == NULL) {
gpr_log(GPR_ERROR, "Server credentials cannot create security context.");
return GRPC_SECURITY_ERROR;
@@ -298,7 +298,7 @@ static grpc_security_status ssl_create_security_connector(
}
static grpc_security_status ssl_server_create_security_connector(
- grpc_server_credentials *creds, grpc_security_connector **sc) {
+ grpc_server_credentials *creds, grpc_server_security_connector **sc) {
grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds;
return grpc_ssl_server_security_connector_create(&c->config, sc);
}
@@ -894,7 +894,7 @@ static grpc_security_status fake_transport_security_create_security_connector(
static grpc_security_status
fake_transport_security_server_create_security_connector(
- grpc_server_credentials *c, grpc_security_connector **sc) {
+ grpc_server_credentials *c, grpc_server_security_connector **sc) {
*sc = grpc_fake_server_security_connector_create();
return GRPC_SECURITY_OK;
}
diff --git a/src/core/security/credentials.h b/src/core/security/credentials.h
index 3cd652cd57..0de4cd9468 100644
--- a/src/core/security/credentials.h
+++ b/src/core/security/credentials.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
@@ -234,7 +234,7 @@ grpc_refresh_token_credentials_create_from_auth_refresh_token(
typedef struct {
void (*destruct)(grpc_server_credentials *c);
grpc_security_status (*create_security_connector)(
- grpc_server_credentials *c, grpc_security_connector **sc);
+ grpc_server_credentials *c, grpc_server_security_connector **sc);
} grpc_server_credentials_vtable;
struct grpc_server_credentials {
@@ -245,7 +245,7 @@ struct grpc_server_credentials {
};
grpc_security_status grpc_server_credentials_create_security_connector(
- grpc_server_credentials *creds, grpc_security_connector **sc);
+ grpc_server_credentials *creds, grpc_server_security_connector **sc);
grpc_server_credentials *grpc_server_credentials_ref(
grpc_server_credentials *creds);
diff --git a/src/core/security/google_default_credentials.c b/src/core/security/google_default_credentials.c
index bd4b0e462a..1f4f3e4aa5 100644
--- a/src/core/security/google_default_credentials.c
+++ b/src/core/security/google_default_credentials.c
@@ -52,13 +52,14 @@
static grpc_channel_credentials *default_credentials = NULL;
static int compute_engine_detection_done = 0;
-static gpr_mu g_mu;
+static gpr_mu g_state_mu;
+static gpr_mu *g_polling_mu;
static gpr_once g_once = GPR_ONCE_INIT;
-static void init_default_credentials(void) { gpr_mu_init(&g_mu); }
+static void init_default_credentials(void) { gpr_mu_init(&g_state_mu); }
typedef struct {
- grpc_pollset pollset;
+ grpc_pollset *pollset;
int is_done;
int success;
} compute_engine_detector;
@@ -80,10 +81,10 @@ static void on_compute_engine_detection_http_response(
}
}
}
- gpr_mu_lock(GRPC_POLLSET_MU(&detector->pollset));
+ gpr_mu_lock(g_polling_mu);
detector->is_done = 1;
- grpc_pollset_kick(&detector->pollset, NULL);
- gpr_mu_unlock(GRPC_POLLSET_MU(&detector->pollset));
+ grpc_pollset_kick(detector->pollset, NULL);
+ gpr_mu_unlock(g_polling_mu);
}
static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *p, bool s) {
@@ -101,7 +102,8 @@ static int is_stack_running_on_compute_engine(void) {
on compute engine. */
gpr_timespec max_detection_delay = gpr_time_from_seconds(1, GPR_TIMESPAN);
- grpc_pollset_init(&detector.pollset);
+ detector.pollset = gpr_malloc(grpc_pollset_size());
+ grpc_pollset_init(detector.pollset, &g_polling_mu);
detector.is_done = 0;
detector.success = 0;
@@ -112,7 +114,7 @@ static int is_stack_running_on_compute_engine(void) {
grpc_httpcli_context_init(&context);
grpc_httpcli_get(
- &exec_ctx, &context, &detector.pollset, &request,
+ &exec_ctx, &context, detector.pollset, &request,
gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), max_detection_delay),
on_compute_engine_detection_http_response, &detector);
@@ -120,19 +122,22 @@ static int is_stack_running_on_compute_engine(void) {
/* Block until we get the response. This is not ideal but this should only be
called once for the lifetime of the process by the default credentials. */
- gpr_mu_lock(GRPC_POLLSET_MU(&detector.pollset));
+ gpr_mu_lock(g_polling_mu);
while (!detector.is_done) {
- grpc_pollset_worker worker;
- grpc_pollset_work(&exec_ctx, &detector.pollset, &worker,
+ grpc_pollset_worker *worker = NULL;
+ grpc_pollset_work(&exec_ctx, detector.pollset, &worker,
gpr_now(GPR_CLOCK_MONOTONIC),
gpr_inf_future(GPR_CLOCK_MONOTONIC));
}
- gpr_mu_unlock(GRPC_POLLSET_MU(&detector.pollset));
+ gpr_mu_unlock(g_polling_mu);
grpc_httpcli_context_destroy(&context);
- grpc_closure_init(&destroy_closure, destroy_pollset, &detector.pollset);
- grpc_pollset_shutdown(&exec_ctx, &detector.pollset, &destroy_closure);
+ grpc_closure_init(&destroy_closure, destroy_pollset, detector.pollset);
+ grpc_pollset_shutdown(&exec_ctx, detector.pollset, &destroy_closure);
grpc_exec_ctx_finish(&exec_ctx);
+ g_polling_mu = NULL;
+
+ gpr_free(detector.pollset);
return detector.success;
}
@@ -184,7 +189,7 @@ grpc_channel_credentials *grpc_google_default_credentials_create(void) {
gpr_once_init(&g_once, init_default_credentials);
- gpr_mu_lock(&g_mu);
+ gpr_mu_lock(&g_state_mu);
if (default_credentials != NULL) {
result = grpc_channel_credentials_ref(default_credentials);
@@ -230,19 +235,19 @@ end:
gpr_log(GPR_ERROR, "Could not create google default credentials.");
}
}
- gpr_mu_unlock(&g_mu);
+ gpr_mu_unlock(&g_state_mu);
return result;
}
void grpc_flush_cached_google_default_credentials(void) {
gpr_once_init(&g_once, init_default_credentials);
- gpr_mu_lock(&g_mu);
+ gpr_mu_lock(&g_state_mu);
if (default_credentials != NULL) {
grpc_channel_credentials_unref(default_credentials);
default_credentials = NULL;
}
compute_engine_detection_done = 0;
- gpr_mu_unlock(&g_mu);
+ gpr_mu_unlock(&g_state_mu);
}
/* -- Well known credentials path. -- */
diff --git a/src/core/security/handshake.c b/src/core/security/handshake.c
index a8b2fef629..b5bb6667a7 100644
--- a/src/core/security/handshake.c
+++ b/src/core/security/handshake.c
@@ -33,6 +33,7 @@
#include "src/core/security/handshake.h"
+#include <stdbool.h>
#include <string.h>
#include "src/core/security/security_context.h"
@@ -46,6 +47,7 @@
typedef struct {
grpc_security_connector *connector;
tsi_handshaker *handshaker;
+ bool is_client_side;
unsigned char *handshake_buffer;
size_t handshake_buffer_size;
grpc_endpoint *wrapped_endpoint;
@@ -67,9 +69,11 @@ static void on_handshake_data_sent_to_peer(grpc_exec_ctx *exec_ctx, void *setup,
bool success);
static void security_connector_remove_handshake(grpc_security_handshake *h) {
+ GPR_ASSERT(!h->is_client_side);
grpc_security_connector_handshake_list *node;
grpc_security_connector_handshake_list *tmp;
- grpc_security_connector *sc = h->connector;
+ grpc_server_security_connector *sc =
+ (grpc_server_security_connector *)h->connector;
gpr_mu_lock(&sc->mu);
node = sc->handshaking_handshakes;
if (node && node->handshake == h) {
@@ -94,7 +98,7 @@ static void security_connector_remove_handshake(grpc_security_handshake *h) {
static void security_handshake_done(grpc_exec_ctx *exec_ctx,
grpc_security_handshake *h,
int is_success) {
- if (!h->connector->is_client_side) {
+ if (!h->is_client_side) {
security_connector_remove_handshake(h);
}
if (is_success) {
@@ -290,6 +294,7 @@ static void on_handshake_data_sent_to_peer(grpc_exec_ctx *exec_ctx,
void grpc_do_security_handshake(grpc_exec_ctx *exec_ctx,
tsi_handshaker *handshaker,
grpc_security_connector *connector,
+ bool is_client_side,
grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb,
void *user_data) {
@@ -298,6 +303,7 @@ void grpc_do_security_handshake(grpc_exec_ctx *exec_ctx,
memset(h, 0, sizeof(grpc_security_handshake));
h->handshaker = handshaker;
h->connector = GRPC_SECURITY_CONNECTOR_REF(connector, "handshake");
+ h->is_client_side = is_client_side;
h->handshake_buffer_size = GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE;
h->handshake_buffer = gpr_malloc(h->handshake_buffer_size);
h->wrapped_endpoint = nonsecure_endpoint;
@@ -310,13 +316,15 @@ void grpc_do_security_handshake(grpc_exec_ctx *exec_ctx,
gpr_slice_buffer_init(&h->left_overs);
gpr_slice_buffer_init(&h->outgoing);
gpr_slice_buffer_init(&h->incoming);
- if (!connector->is_client_side) {
+ if (!is_client_side) {
+ grpc_server_security_connector *server_connector =
+ (grpc_server_security_connector *)connector;
handshake_node = gpr_malloc(sizeof(grpc_security_connector_handshake_list));
handshake_node->handshake = h;
- gpr_mu_lock(&connector->mu);
- handshake_node->next = connector->handshaking_handshakes;
- connector->handshaking_handshakes = handshake_node;
- gpr_mu_unlock(&connector->mu);
+ gpr_mu_lock(&server_connector->mu);
+ handshake_node->next = server_connector->handshaking_handshakes;
+ server_connector->handshaking_handshakes = handshake_node;
+ gpr_mu_unlock(&server_connector->mu);
}
send_handshake_bytes_to_peer(exec_ctx, h);
}
diff --git a/src/core/security/handshake.h b/src/core/security/handshake.h
index 44215d16ef..db8b374921 100644
--- a/src/core/security/handshake.h
+++ b/src/core/security/handshake.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
@@ -41,6 +41,7 @@
void grpc_do_security_handshake(grpc_exec_ctx *exec_ctx,
tsi_handshaker *handshaker,
grpc_security_connector *connector,
+ bool is_client_side,
grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb,
void *user_data);
diff --git a/src/core/security/security_connector.c b/src/core/security/security_connector.c
index 51a99b4492..33c62a20c2 100644
--- a/src/core/security/security_connector.c
+++ b/src/core/security/security_connector.c
@@ -33,6 +33,7 @@
#include "src/core/security/security_connector.h"
+#include <stdbool.h>
#include <string.h>
#include <grpc/support/alloc.h>
@@ -110,31 +111,39 @@ const tsi_peer_property *tsi_peer_get_property_by_name(const tsi_peer *peer,
return NULL;
}
-void grpc_security_connector_shutdown(grpc_exec_ctx *exec_ctx,
- grpc_security_connector *connector) {
+void grpc_server_security_connector_shutdown(
+ grpc_exec_ctx *exec_ctx, grpc_server_security_connector *connector) {
grpc_security_connector_handshake_list *tmp;
- if (!connector->is_client_side) {
- gpr_mu_lock(&connector->mu);
- while (connector->handshaking_handshakes) {
- tmp = connector->handshaking_handshakes;
- grpc_security_handshake_shutdown(
- exec_ctx, connector->handshaking_handshakes->handshake);
- connector->handshaking_handshakes = tmp->next;
- gpr_free(tmp);
- }
- gpr_mu_unlock(&connector->mu);
+ gpr_mu_lock(&connector->mu);
+ while (connector->handshaking_handshakes) {
+ tmp = connector->handshaking_handshakes;
+ grpc_security_handshake_shutdown(
+ exec_ctx, connector->handshaking_handshakes->handshake);
+ connector->handshaking_handshakes = tmp->next;
+ gpr_free(tmp);
+ }
+ gpr_mu_unlock(&connector->mu);
+}
+
+void grpc_channel_security_connector_do_handshake(
+ grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *sc,
+ grpc_endpoint *nonsecure_endpoint, grpc_security_handshake_done_cb cb,
+ void *user_data) {
+ if (sc == NULL || nonsecure_endpoint == NULL) {
+ cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL);
+ } else {
+ sc->do_handshake(exec_ctx, sc, nonsecure_endpoint, cb, user_data);
}
}
-void grpc_security_connector_do_handshake(grpc_exec_ctx *exec_ctx,
- grpc_security_connector *sc,
- grpc_endpoint *nonsecure_endpoint,
- grpc_security_handshake_done_cb cb,
- void *user_data) {
+void grpc_server_security_connector_do_handshake(
+ grpc_exec_ctx *exec_ctx, grpc_server_security_connector *sc,
+ grpc_tcp_server_acceptor *acceptor, grpc_endpoint *nonsecure_endpoint,
+ grpc_security_handshake_done_cb cb, void *user_data) {
if (sc == NULL || nonsecure_endpoint == NULL) {
cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL);
} else {
- sc->vtable->do_handshake(exec_ctx, sc, nonsecure_endpoint, cb, user_data);
+ sc->do_handshake(exec_ctx, sc, acceptor, nonsecure_endpoint, cb, user_data);
}
}
@@ -248,7 +257,8 @@ static void fake_channel_destroy(grpc_security_connector *sc) {
}
static void fake_server_destroy(grpc_security_connector *sc) {
- gpr_mu_destroy(&sc->mu);
+ grpc_server_security_connector *c = (grpc_server_security_connector *)sc;
+ gpr_mu_destroy(&c->mu);
gpr_free(sc);
}
@@ -298,49 +308,52 @@ static void fake_channel_check_call_host(grpc_exec_ctx *exec_ctx,
}
static void fake_channel_do_handshake(grpc_exec_ctx *exec_ctx,
- grpc_security_connector *sc,
+ grpc_channel_security_connector *sc,
grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb,
void *user_data) {
- grpc_do_security_handshake(exec_ctx, tsi_create_fake_handshaker(1), sc,
- nonsecure_endpoint, cb, user_data);
+ grpc_do_security_handshake(exec_ctx, tsi_create_fake_handshaker(1), &sc->base,
+ true, nonsecure_endpoint, cb, user_data);
}
static void fake_server_do_handshake(grpc_exec_ctx *exec_ctx,
- grpc_security_connector *sc,
+ grpc_server_security_connector *sc,
+ grpc_tcp_server_acceptor *acceptor,
grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb,
void *user_data) {
- grpc_do_security_handshake(exec_ctx, tsi_create_fake_handshaker(0), sc,
- nonsecure_endpoint, cb, user_data);
+ grpc_do_security_handshake(exec_ctx, tsi_create_fake_handshaker(0), &sc->base,
+ false, nonsecure_endpoint, cb, user_data);
}
static grpc_security_connector_vtable fake_channel_vtable = {
- fake_channel_destroy, fake_channel_do_handshake, fake_check_peer};
+ fake_channel_destroy, fake_check_peer};
-static grpc_security_connector_vtable fake_server_vtable = {
- fake_server_destroy, fake_server_do_handshake, fake_check_peer};
+static grpc_security_connector_vtable fake_server_vtable = {fake_server_destroy,
+ fake_check_peer};
grpc_channel_security_connector *grpc_fake_channel_security_connector_create(
grpc_call_credentials *request_metadata_creds) {
grpc_channel_security_connector *c = gpr_malloc(sizeof(*c));
memset(c, 0, sizeof(*c));
gpr_ref_init(&c->base.refcount, 1);
- c->base.is_client_side = 1;
c->base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME;
c->base.vtable = &fake_channel_vtable;
c->request_metadata_creds = grpc_call_credentials_ref(request_metadata_creds);
c->check_call_host = fake_channel_check_call_host;
+ c->do_handshake = fake_channel_do_handshake;
return c;
}
-grpc_security_connector *grpc_fake_server_security_connector_create(void) {
- grpc_security_connector *c = gpr_malloc(sizeof(grpc_security_connector));
- memset(c, 0, sizeof(grpc_security_connector));
- gpr_ref_init(&c->refcount, 1);
- c->is_client_side = 0;
- c->vtable = &fake_server_vtable;
- c->url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME;
+grpc_server_security_connector *grpc_fake_server_security_connector_create(
+ void) {
+ grpc_server_security_connector *c =
+ gpr_malloc(sizeof(grpc_server_security_connector));
+ memset(c, 0, sizeof(*c));
+ gpr_ref_init(&c->base.refcount, 1);
+ c->base.vtable = &fake_server_vtable;
+ c->base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME;
+ c->do_handshake = fake_server_do_handshake;
gpr_mu_init(&c->mu);
return c;
}
@@ -355,7 +368,7 @@ typedef struct {
} grpc_ssl_channel_security_connector;
typedef struct {
- grpc_security_connector base;
+ grpc_server_security_connector base;
tsi_ssl_handshaker_factory *handshaker_factory;
} grpc_ssl_server_security_connector;
@@ -378,12 +391,12 @@ static void ssl_server_destroy(grpc_security_connector *sc) {
if (c->handshaker_factory != NULL) {
tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
}
- gpr_mu_destroy(&sc->mu);
+ gpr_mu_destroy(&c->base.mu);
gpr_free(sc);
}
static grpc_security_status ssl_create_handshaker(
- tsi_ssl_handshaker_factory *handshaker_factory, int is_client,
+ tsi_ssl_handshaker_factory *handshaker_factory, bool is_client,
const char *peer_name, tsi_handshaker **handshaker) {
tsi_result result = TSI_OK;
if (handshaker_factory == NULL) return GRPC_SECURITY_ERROR;
@@ -398,7 +411,7 @@ static grpc_security_status ssl_create_handshaker(
}
static void ssl_channel_do_handshake(grpc_exec_ctx *exec_ctx,
- grpc_security_connector *sc,
+ grpc_channel_security_connector *sc,
grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb,
void *user_data) {
@@ -406,20 +419,21 @@ static void ssl_channel_do_handshake(grpc_exec_ctx *exec_ctx,
(grpc_ssl_channel_security_connector *)sc;
tsi_handshaker *handshaker;
grpc_security_status status = ssl_create_handshaker(
- c->handshaker_factory, 1,
+ c->handshaker_factory, true,
c->overridden_target_name != NULL ? c->overridden_target_name
: c->target_name,
&handshaker);
if (status != GRPC_SECURITY_OK) {
cb(exec_ctx, user_data, status, NULL, NULL);
} else {
- grpc_do_security_handshake(exec_ctx, handshaker, sc, nonsecure_endpoint, cb,
- user_data);
+ grpc_do_security_handshake(exec_ctx, handshaker, &sc->base, true,
+ nonsecure_endpoint, cb, user_data);
}
}
static void ssl_server_do_handshake(grpc_exec_ctx *exec_ctx,
- grpc_security_connector *sc,
+ grpc_server_security_connector *sc,
+ grpc_tcp_server_acceptor *acceptor,
grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb,
void *user_data) {
@@ -427,12 +441,12 @@ static void ssl_server_do_handshake(grpc_exec_ctx *exec_ctx,
(grpc_ssl_server_security_connector *)sc;
tsi_handshaker *handshaker;
grpc_security_status status =
- ssl_create_handshaker(c->handshaker_factory, 0, NULL, &handshaker);
+ ssl_create_handshaker(c->handshaker_factory, false, NULL, &handshaker);
if (status != GRPC_SECURITY_OK) {
cb(exec_ctx, user_data, status, NULL, NULL);
} else {
- grpc_do_security_handshake(exec_ctx, handshaker, sc, nonsecure_endpoint, cb,
- user_data);
+ grpc_do_security_handshake(exec_ctx, handshaker, &sc->base, false,
+ nonsecure_endpoint, cb, user_data);
}
}
@@ -603,10 +617,10 @@ static void ssl_channel_check_call_host(grpc_exec_ctx *exec_ctx,
}
static grpc_security_connector_vtable ssl_channel_vtable = {
- ssl_channel_destroy, ssl_channel_do_handshake, ssl_channel_check_peer};
+ ssl_channel_destroy, ssl_channel_check_peer};
static grpc_security_connector_vtable ssl_server_vtable = {
- ssl_server_destroy, ssl_server_do_handshake, ssl_server_check_peer};
+ ssl_server_destroy, ssl_server_check_peer};
static gpr_slice compute_default_pem_root_certs_once(void) {
gpr_slice result = gpr_empty_slice();
@@ -700,11 +714,11 @@ grpc_security_status grpc_ssl_channel_security_connector_create(
gpr_ref_init(&c->base.base.refcount, 1);
c->base.base.vtable = &ssl_channel_vtable;
- c->base.base.is_client_side = 1;
c->base.base.url_scheme = GRPC_SSL_URL_SCHEME;
c->base.request_metadata_creds =
grpc_call_credentials_ref(request_metadata_creds);
c->base.check_call_host = ssl_channel_check_call_host;
+ c->base.do_handshake = ssl_channel_do_handshake;
gpr_split_host_port(target_name, &c->target_name, &port);
gpr_free(port);
if (overridden_target_name != NULL) {
@@ -735,7 +749,7 @@ error:
}
grpc_security_status grpc_ssl_server_security_connector_create(
- const grpc_ssl_server_config *config, grpc_security_connector **sc) {
+ const grpc_ssl_server_config *config, grpc_server_security_connector **sc) {
size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions();
const unsigned char **alpn_protocol_strings =
gpr_malloc(sizeof(const char *) * num_alpn_protocols);
@@ -759,9 +773,9 @@ grpc_security_status grpc_ssl_server_security_connector_create(
c = gpr_malloc(sizeof(grpc_ssl_server_security_connector));
memset(c, 0, sizeof(grpc_ssl_server_security_connector));
- gpr_ref_init(&c->base.refcount, 1);
- c->base.url_scheme = GRPC_SSL_URL_SCHEME;
- c->base.vtable = &ssl_server_vtable;
+ gpr_ref_init(&c->base.base.refcount, 1);
+ c->base.base.url_scheme = GRPC_SSL_URL_SCHEME;
+ c->base.base.vtable = &ssl_server_vtable;
result = tsi_create_ssl_server_handshaker_factory(
(const unsigned char **)config->pem_private_keys,
config->pem_private_keys_sizes,
@@ -774,11 +788,12 @@ grpc_security_status grpc_ssl_server_security_connector_create(
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
tsi_result_to_string(result));
- ssl_server_destroy(&c->base);
+ ssl_server_destroy(&c->base.base);
*sc = NULL;
goto error;
}
gpr_mu_init(&c->base.mu);
+ c->base.do_handshake = ssl_server_do_handshake;
*sc = &c->base;
gpr_free((void *)alpn_protocol_strings);
gpr_free(alpn_protocol_string_lengths);
diff --git a/src/core/security/security_connector.h b/src/core/security/security_connector.h
index 39df7821f0..1e35d3f9b7 100644
--- a/src/core/security/security_connector.h
+++ b/src/core/security/security_connector.h
@@ -36,6 +36,7 @@
#include <grpc/grpc_security.h>
#include "src/core/iomgr/endpoint.h"
+#include "src/core/iomgr/tcp_server.h"
#include "src/core/tsi/transport_security_interface.h"
/* --- status enum. --- */
@@ -68,9 +69,6 @@ typedef void (*grpc_security_handshake_done_cb)(
typedef struct {
void (*destroy)(grpc_security_connector *sc);
- void (*do_handshake)(grpc_exec_ctx *exec_ctx, grpc_security_connector *sc,
- grpc_endpoint *nonsecure_endpoint,
- grpc_security_handshake_done_cb cb, void *user_data);
void (*check_peer)(grpc_exec_ctx *exec_ctx, grpc_security_connector *sc,
tsi_peer peer, grpc_security_peer_check_cb cb,
void *user_data);
@@ -84,13 +82,7 @@ typedef struct grpc_security_connector_handshake_list {
struct grpc_security_connector {
const grpc_security_connector_vtable *vtable;
gpr_refcount refcount;
- int is_client_side;
const char *url_scheme;
- /* Used on server side only. */
- /* TODO(yangg): Create a grpc_server_security_connector with these. */
- gpr_mu mu;
- grpc_security_connector_handshake_list *handshaking_handshakes;
- const grpc_channel_args *channel_args;
};
/* Refcounting. */
@@ -113,13 +105,6 @@ grpc_security_connector *grpc_security_connector_ref(
void grpc_security_connector_unref(grpc_security_connector *policy);
#endif
-/* Handshake. */
-void grpc_security_connector_do_handshake(grpc_exec_ctx *exec_ctx,
- grpc_security_connector *connector,
- grpc_endpoint *nonsecure_endpoint,
- grpc_security_handshake_done_cb cb,
- void *user_data);
-
/* Check the peer. Callee takes ownership of the peer object.
The callback will include the resulting auth_context. */
void grpc_security_connector_check_peer(grpc_exec_ctx *exec_ctx,
@@ -128,9 +113,6 @@ void grpc_security_connector_check_peer(grpc_exec_ctx *exec_ctx,
grpc_security_peer_check_cb cb,
void *user_data);
-void grpc_security_connector_shutdown(grpc_exec_ctx *exec_ctx,
- grpc_security_connector *connector);
-
/* Util to encapsulate the connector in a channel arg. */
grpc_arg grpc_security_connector_to_arg(grpc_security_connector *sc);
@@ -153,12 +135,16 @@ typedef void (*grpc_security_call_host_check_cb)(grpc_exec_ctx *exec_ctx,
grpc_security_status status);
struct grpc_channel_security_connector {
- grpc_security_connector base; /* requires is_client_side to be non 0. */
+ grpc_security_connector base;
grpc_call_credentials *request_metadata_creds;
void (*check_call_host)(grpc_exec_ctx *exec_ctx,
grpc_channel_security_connector *sc, const char *host,
grpc_auth_context *auth_context,
grpc_security_call_host_check_cb cb, void *user_data);
+ void (*do_handshake)(grpc_exec_ctx *exec_ctx,
+ grpc_channel_security_connector *sc,
+ grpc_endpoint *nonsecure_endpoint,
+ grpc_security_handshake_done_cb cb, void *user_data);
};
/* Checks that the host that will be set for a call is acceptable. */
@@ -167,6 +153,39 @@ void grpc_channel_security_connector_check_call_host(
const char *host, grpc_auth_context *auth_context,
grpc_security_call_host_check_cb cb, void *user_data);
+/* Handshake. */
+void grpc_channel_security_connector_do_handshake(
+ grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *connector,
+ grpc_endpoint *nonsecure_endpoint, grpc_security_handshake_done_cb cb,
+ void *user_data);
+
+/* --- server_security_connector object. ---
+
+ A server security connector object represents away to configure the
+ underlying transport security mechanism on the server side. */
+
+typedef struct grpc_server_security_connector grpc_server_security_connector;
+
+struct grpc_server_security_connector {
+ grpc_security_connector base;
+ gpr_mu mu;
+ grpc_security_connector_handshake_list *handshaking_handshakes;
+ const grpc_channel_args *channel_args;
+ void (*do_handshake)(grpc_exec_ctx *exec_ctx,
+ grpc_server_security_connector *sc,
+ grpc_tcp_server_acceptor *acceptor,
+ grpc_endpoint *nonsecure_endpoint,
+ grpc_security_handshake_done_cb cb, void *user_data);
+};
+
+void grpc_server_security_connector_do_handshake(
+ grpc_exec_ctx *exec_ctx, grpc_server_security_connector *sc,
+ grpc_tcp_server_acceptor *acceptor, grpc_endpoint *nonsecure_endpoint,
+ grpc_security_handshake_done_cb cb, void *user_data);
+
+void grpc_server_security_connector_shutdown(
+ grpc_exec_ctx *exec_ctx, grpc_server_security_connector *connector);
+
/* --- Creation security connectors. --- */
/* For TESTING ONLY!
@@ -176,7 +195,8 @@ grpc_channel_security_connector *grpc_fake_channel_security_connector_create(
/* For TESTING ONLY!
Creates a fake connector that emulates real server security. */
-grpc_security_connector *grpc_fake_server_security_connector_create(void);
+grpc_server_security_connector *grpc_fake_server_security_connector_create(
+ void);
/* Config for ssl clients. */
typedef struct {
@@ -231,7 +251,7 @@ typedef struct {
specific error code otherwise.
*/
grpc_security_status grpc_ssl_server_security_connector_create(
- const grpc_ssl_server_config *config, grpc_security_connector **sc);
+ const grpc_ssl_server_config *config, grpc_server_security_connector **sc);
/* Util. */
const tsi_peer_property *tsi_peer_get_property_by_name(const tsi_peer *peer,
diff --git a/src/core/security/server_secure_chttp2.c b/src/core/security/server_secure_chttp2.c
index 84a883390c..91547eb26e 100644
--- a/src/core/security/server_secure_chttp2.c
+++ b/src/core/security/server_secure_chttp2.c
@@ -55,7 +55,7 @@
typedef struct grpc_server_secure_state {
grpc_server *server;
grpc_tcp_server *tcp;
- grpc_security_connector *sc;
+ grpc_server_security_connector *sc;
grpc_server_credentials *creds;
int is_shutdown;
gpr_mu mu;
@@ -74,7 +74,7 @@ static void state_unref(grpc_server_secure_state *state) {
gpr_mu_lock(&state->mu);
gpr_mu_unlock(&state->mu);
/* clean up */
- GRPC_SECURITY_CONNECTOR_UNREF(state->sc, "server");
+ GRPC_SECURITY_CONNECTOR_UNREF(&state->sc->base, "server");
grpc_server_credentials_unref(state->creds);
gpr_free(state);
}
@@ -130,8 +130,8 @@ static void on_accept(grpc_exec_ctx *exec_ctx, void *statep, grpc_endpoint *tcp,
grpc_tcp_server_acceptor *acceptor) {
grpc_server_secure_state *state = statep;
state_ref(state);
- grpc_security_connector_do_handshake(exec_ctx, state->sc, tcp,
- on_secure_handshake_done, state);
+ grpc_server_security_connector_do_handshake(
+ exec_ctx, state->sc, acceptor, tcp, on_secure_handshake_done, state);
}
/* Server callback: start listening on our ports */
@@ -148,7 +148,7 @@ static void destroy_done(grpc_exec_ctx *exec_ctx, void *statep, bool success) {
state->destroy_callback->cb(exec_ctx, state->destroy_callback->cb_arg,
success);
}
- grpc_security_connector_shutdown(exec_ctx, state->sc);
+ grpc_server_security_connector_shutdown(exec_ctx, state->sc);
state_unref(state);
}
@@ -176,7 +176,7 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr,
int port_num = -1;
int port_temp;
grpc_security_status status = GRPC_SECURITY_ERROR;
- grpc_security_connector *sc = NULL;
+ grpc_server_security_connector *sc = NULL;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
GRPC_API_TRACE(
@@ -256,7 +256,7 @@ error:
grpc_tcp_server_unref(&exec_ctx, tcp);
} else {
if (sc) {
- GRPC_SECURITY_CONNECTOR_UNREF(sc, "server");
+ GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "server");
}
if (state) {
gpr_free(state);
diff --git a/src/core/support/sync.c b/src/core/support/sync.c
index d368422d9e..69e3e39c5c 100644
--- a/src/core/support/sync.c
+++ b/src/core/support/sync.c
@@ -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
@@ -98,6 +98,11 @@ void gpr_ref_init(gpr_refcount *r, int n) { gpr_atm_rel_store(&r->count, n); }
void gpr_ref(gpr_refcount *r) { gpr_atm_no_barrier_fetch_add(&r->count, 1); }
+void gpr_ref_non_zero(gpr_refcount *r) {
+ gpr_atm prior = gpr_atm_no_barrier_fetch_add(&r->count, 1);
+ GPR_ASSERT(prior > 0);
+}
+
void gpr_refn(gpr_refcount *r, int n) {
gpr_atm_no_barrier_fetch_add(&r->count, n);
}
diff --git a/src/core/surface/alarm.c b/src/core/surface/alarm.c
index fb496f6c47..8169ede065 100644
--- a/src/core/surface/alarm.c
+++ b/src/core/surface/alarm.c
@@ -64,8 +64,9 @@ grpc_alarm *grpc_alarm_create(grpc_completion_queue *cq, gpr_timespec deadline,
alarm->tag = tag;
grpc_cq_begin_op(cq, tag);
- grpc_timer_init(&exec_ctx, &alarm->alarm, deadline, alarm_cb, alarm,
- gpr_now(GPR_CLOCK_MONOTONIC));
+ grpc_timer_init(&exec_ctx, &alarm->alarm,
+ gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC),
+ alarm_cb, alarm, gpr_now(GPR_CLOCK_MONOTONIC));
grpc_exec_ctx_finish(&exec_ctx);
return alarm;
}
diff --git a/src/core/surface/completion_queue.c b/src/core/surface/completion_queue.c
index 0a80680f02..f6a95ebbd3 100644
--- a/src/core/surface/completion_queue.c
+++ b/src/core/surface/completion_queue.c
@@ -36,26 +36,29 @@
#include <stdio.h>
#include <string.h>
-#include "src/core/iomgr/timer.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/atm.h>
+#include <grpc/support/log.h>
+#include <grpc/support/time.h>
+
#include "src/core/iomgr/pollset.h"
+#include "src/core/iomgr/timer.h"
+#include "src/core/profiling/timers.h"
#include "src/core/support/string.h"
#include "src/core/surface/api_trace.h"
#include "src/core/surface/call.h"
#include "src/core/surface/event_string.h"
#include "src/core/surface/surface_trace.h"
-#include "src/core/profiling/timers.h"
-#include <grpc/support/alloc.h>
-#include <grpc/support/atm.h>
-#include <grpc/support/log.h>
-#include <grpc/support/time.h>
typedef struct {
- grpc_pollset_worker *worker;
+ grpc_pollset_worker **worker;
void *tag;
} plucker;
/* Completion queue structure */
struct grpc_completion_queue {
+ /** owned by pollset */
+ gpr_mu *mu;
/** completed events */
grpc_cq_completion completed_head;
grpc_cq_completion *completed_tail;
@@ -63,8 +66,6 @@ struct grpc_completion_queue {
gpr_refcount pending_events;
/** Once owning_refs drops to zero, we will destroy the cq */
gpr_refcount owning_refs;
- /** the set of low level i/o things that concern this cq */
- grpc_pollset pollset;
/** 0 initially, 1 once we've begun shutting down */
int shutdown;
int shutdown_called;
@@ -82,6 +83,8 @@ struct grpc_completion_queue {
grpc_completion_queue *next_free;
};
+#define POLLSET_FROM_CQ(cq) ((grpc_pollset *)(cq + 1))
+
static gpr_mu g_freelist_mu;
grpc_completion_queue *g_freelist;
@@ -94,7 +97,7 @@ void grpc_cq_global_shutdown(void) {
gpr_mu_destroy(&g_freelist_mu);
while (g_freelist) {
grpc_completion_queue *next = g_freelist->next_free;
- grpc_pollset_destroy(&g_freelist->pollset);
+ grpc_pollset_destroy(POLLSET_FROM_CQ(g_freelist));
#ifndef NDEBUG
gpr_free(g_freelist->outstanding_tags);
#endif
@@ -124,8 +127,8 @@ grpc_completion_queue *grpc_completion_queue_create(void *reserved) {
if (g_freelist == NULL) {
gpr_mu_unlock(&g_freelist_mu);
- cc = gpr_malloc(sizeof(grpc_completion_queue));
- grpc_pollset_init(&cc->pollset);
+ cc = gpr_malloc(sizeof(grpc_completion_queue) + grpc_pollset_size());
+ grpc_pollset_init(POLLSET_FROM_CQ(cc), &cc->mu);
#ifndef NDEBUG
cc->outstanding_tags = NULL;
cc->outstanding_tag_capacity = 0;
@@ -184,7 +187,7 @@ void grpc_cq_internal_unref(grpc_completion_queue *cc) {
#endif
if (gpr_unref(&cc->owning_refs)) {
GPR_ASSERT(cc->completed_head.next == (uintptr_t)&cc->completed_head);
- grpc_pollset_reset(&cc->pollset);
+ grpc_pollset_reset(POLLSET_FROM_CQ(cc));
gpr_mu_lock(&g_freelist_mu);
cc->next_free = g_freelist;
g_freelist = cc;
@@ -194,7 +197,7 @@ void grpc_cq_internal_unref(grpc_completion_queue *cc) {
void grpc_cq_begin_op(grpc_completion_queue *cc, void *tag) {
#ifndef NDEBUG
- gpr_mu_lock(GRPC_POLLSET_MU(&cc->pollset));
+ gpr_mu_lock(cc->mu);
GPR_ASSERT(!cc->shutdown_called);
if (cc->outstanding_tag_count == cc->outstanding_tag_capacity) {
cc->outstanding_tag_capacity = GPR_MAX(4, 2 * cc->outstanding_tag_capacity);
@@ -203,7 +206,7 @@ void grpc_cq_begin_op(grpc_completion_queue *cc, void *tag) {
cc->outstanding_tag_capacity);
}
cc->outstanding_tags[cc->outstanding_tag_count++] = tag;
- gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
+ gpr_mu_unlock(cc->mu);
#endif
gpr_ref(&cc->pending_events);
}
@@ -231,7 +234,7 @@ void grpc_cq_end_op(grpc_exec_ctx *exec_ctx, grpc_completion_queue *cc,
storage->next =
((uintptr_t)&cc->completed_head) | ((uintptr_t)(success != 0));
- gpr_mu_lock(GRPC_POLLSET_MU(&cc->pollset));
+ gpr_mu_lock(cc->mu);
#ifndef NDEBUG
for (i = 0; i < (int)cc->outstanding_tag_count; i++) {
if (cc->outstanding_tags[i] == tag) {
@@ -252,12 +255,12 @@ void grpc_cq_end_op(grpc_exec_ctx *exec_ctx, grpc_completion_queue *cc,
pluck_worker = NULL;
for (i = 0; i < cc->num_pluckers; i++) {
if (cc->pluckers[i].tag == tag) {
- pluck_worker = cc->pluckers[i].worker;
+ pluck_worker = *cc->pluckers[i].worker;
break;
}
}
- grpc_pollset_kick(&cc->pollset, pluck_worker);
- gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
+ grpc_pollset_kick(POLLSET_FROM_CQ(cc), pluck_worker);
+ gpr_mu_unlock(cc->mu);
} else {
cc->completed_tail->next =
((uintptr_t)storage) | (1u & (uintptr_t)cc->completed_tail->next);
@@ -265,8 +268,9 @@ void grpc_cq_end_op(grpc_exec_ctx *exec_ctx, grpc_completion_queue *cc,
GPR_ASSERT(!cc->shutdown);
GPR_ASSERT(cc->shutdown_called);
cc->shutdown = 1;
- grpc_pollset_shutdown(exec_ctx, &cc->pollset, &cc->pollset_shutdown_done);
- gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
+ grpc_pollset_shutdown(exec_ctx, POLLSET_FROM_CQ(cc),
+ &cc->pollset_shutdown_done);
+ gpr_mu_unlock(cc->mu);
}
GPR_TIMER_END("grpc_cq_end_op", 0);
@@ -275,7 +279,7 @@ void grpc_cq_end_op(grpc_exec_ctx *exec_ctx, grpc_completion_queue *cc,
grpc_event grpc_completion_queue_next(grpc_completion_queue *cc,
gpr_timespec deadline, void *reserved) {
grpc_event ret;
- grpc_pollset_worker worker;
+ grpc_pollset_worker *worker = NULL;
int first_loop = 1;
gpr_timespec now;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
@@ -294,7 +298,7 @@ grpc_event grpc_completion_queue_next(grpc_completion_queue *cc,
deadline = gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC);
GRPC_CQ_INTERNAL_REF(cc, "next");
- gpr_mu_lock(GRPC_POLLSET_MU(&cc->pollset));
+ gpr_mu_lock(cc->mu);
for (;;) {
if (cc->completed_tail != &cc->completed_head) {
grpc_cq_completion *c = (grpc_cq_completion *)cc->completed_head.next;
@@ -302,7 +306,7 @@ grpc_event grpc_completion_queue_next(grpc_completion_queue *cc,
if (c == cc->completed_tail) {
cc->completed_tail = &cc->completed_head;
}
- gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
+ gpr_mu_unlock(cc->mu);
ret.type = GRPC_OP_COMPLETE;
ret.success = c->next & 1u;
ret.tag = c->tag;
@@ -310,14 +314,14 @@ grpc_event grpc_completion_queue_next(grpc_completion_queue *cc,
break;
}
if (cc->shutdown) {
- gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
+ gpr_mu_unlock(cc->mu);
memset(&ret, 0, sizeof(ret));
ret.type = GRPC_QUEUE_SHUTDOWN;
break;
}
now = gpr_now(GPR_CLOCK_MONOTONIC);
if (!first_loop && gpr_time_cmp(now, deadline) >= 0) {
- gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
+ gpr_mu_unlock(cc->mu);
memset(&ret, 0, sizeof(ret));
ret.type = GRPC_QUEUE_TIMEOUT;
break;
@@ -330,11 +334,12 @@ grpc_event grpc_completion_queue_next(grpc_completion_queue *cc,
gpr_timespec iteration_deadline = deadline;
if (grpc_timer_check(&exec_ctx, now, &iteration_deadline)) {
GPR_TIMER_MARK("alarm_triggered", 0);
- gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
+ gpr_mu_unlock(cc->mu);
grpc_exec_ctx_flush(&exec_ctx);
- gpr_mu_lock(GRPC_POLLSET_MU(&cc->pollset));
+ gpr_mu_lock(cc->mu);
+ continue;
} else {
- grpc_pollset_work(&exec_ctx, &cc->pollset, &worker, now,
+ grpc_pollset_work(&exec_ctx, POLLSET_FROM_CQ(cc), &worker, now,
iteration_deadline);
}
}
@@ -348,7 +353,7 @@ grpc_event grpc_completion_queue_next(grpc_completion_queue *cc,
}
static int add_plucker(grpc_completion_queue *cc, void *tag,
- grpc_pollset_worker *worker) {
+ grpc_pollset_worker **worker) {
if (cc->num_pluckers == GRPC_MAX_COMPLETION_QUEUE_PLUCKERS) {
return 0;
}
@@ -359,7 +364,7 @@ static int add_plucker(grpc_completion_queue *cc, void *tag,
}
static void del_plucker(grpc_completion_queue *cc, void *tag,
- grpc_pollset_worker *worker) {
+ grpc_pollset_worker **worker) {
int i;
for (i = 0; i < cc->num_pluckers; i++) {
if (cc->pluckers[i].tag == tag && cc->pluckers[i].worker == worker) {
@@ -376,7 +381,7 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag,
grpc_event ret;
grpc_cq_completion *c;
grpc_cq_completion *prev;
- grpc_pollset_worker worker;
+ grpc_pollset_worker *worker = NULL;
gpr_timespec now;
int first_loop = 1;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
@@ -395,7 +400,7 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag,
deadline = gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC);
GRPC_CQ_INTERNAL_REF(cc, "pluck");
- gpr_mu_lock(GRPC_POLLSET_MU(&cc->pollset));
+ gpr_mu_lock(cc->mu);
for (;;) {
prev = &cc->completed_head;
while ((c = (grpc_cq_completion *)(prev->next & ~(uintptr_t)1)) !=
@@ -405,7 +410,7 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag,
if (c == cc->completed_tail) {
cc->completed_tail = prev;
}
- gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
+ gpr_mu_unlock(cc->mu);
ret.type = GRPC_OP_COMPLETE;
ret.success = c->next & 1u;
ret.tag = c->tag;
@@ -415,7 +420,7 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag,
prev = c;
}
if (cc->shutdown) {
- gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
+ gpr_mu_unlock(cc->mu);
memset(&ret, 0, sizeof(ret));
ret.type = GRPC_QUEUE_SHUTDOWN;
break;
@@ -425,7 +430,7 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag,
"Too many outstanding grpc_completion_queue_pluck calls: maximum "
"is %d",
GRPC_MAX_COMPLETION_QUEUE_PLUCKERS);
- gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
+ gpr_mu_unlock(cc->mu);
memset(&ret, 0, sizeof(ret));
/* TODO(ctiller): should we use a different result here */
ret.type = GRPC_QUEUE_TIMEOUT;
@@ -434,7 +439,7 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag,
now = gpr_now(GPR_CLOCK_MONOTONIC);
if (!first_loop && gpr_time_cmp(now, deadline) >= 0) {
del_plucker(cc, tag, &worker);
- gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
+ gpr_mu_unlock(cc->mu);
memset(&ret, 0, sizeof(ret));
ret.type = GRPC_QUEUE_TIMEOUT;
break;
@@ -447,11 +452,11 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag,
gpr_timespec iteration_deadline = deadline;
if (grpc_timer_check(&exec_ctx, now, &iteration_deadline)) {
GPR_TIMER_MARK("alarm_triggered", 0);
- gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
+ gpr_mu_unlock(cc->mu);
grpc_exec_ctx_flush(&exec_ctx);
- gpr_mu_lock(GRPC_POLLSET_MU(&cc->pollset));
+ gpr_mu_lock(cc->mu);
} else {
- grpc_pollset_work(&exec_ctx, &cc->pollset, &worker, now,
+ grpc_pollset_work(&exec_ctx, POLLSET_FROM_CQ(cc), &worker, now,
iteration_deadline);
}
del_plucker(cc, tag, &worker);
@@ -472,9 +477,9 @@ void grpc_completion_queue_shutdown(grpc_completion_queue *cc) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
GPR_TIMER_BEGIN("grpc_completion_queue_shutdown", 0);
GRPC_API_TRACE("grpc_completion_queue_shutdown(cc=%p)", 1, (cc));
- gpr_mu_lock(GRPC_POLLSET_MU(&cc->pollset));
+ gpr_mu_lock(cc->mu);
if (cc->shutdown_called) {
- gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
+ gpr_mu_unlock(cc->mu);
GPR_TIMER_END("grpc_completion_queue_shutdown", 0);
return;
}
@@ -482,9 +487,10 @@ void grpc_completion_queue_shutdown(grpc_completion_queue *cc) {
if (gpr_unref(&cc->pending_events)) {
GPR_ASSERT(!cc->shutdown);
cc->shutdown = 1;
- grpc_pollset_shutdown(&exec_ctx, &cc->pollset, &cc->pollset_shutdown_done);
+ grpc_pollset_shutdown(&exec_ctx, POLLSET_FROM_CQ(cc),
+ &cc->pollset_shutdown_done);
}
- gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
+ gpr_mu_unlock(cc->mu);
grpc_exec_ctx_finish(&exec_ctx);
GPR_TIMER_END("grpc_completion_queue_shutdown", 0);
}
@@ -498,7 +504,7 @@ void grpc_completion_queue_destroy(grpc_completion_queue *cc) {
}
grpc_pollset *grpc_cq_pollset(grpc_completion_queue *cc) {
- return &cc->pollset;
+ return POLLSET_FROM_CQ(cc);
}
void grpc_cq_mark_server_cq(grpc_completion_queue *cc) { cc->is_server_cq = 1; }
diff --git a/src/core/surface/secure_channel_create.c b/src/core/surface/secure_channel_create.c
index 9c04426d87..aadfac4c91 100644
--- a/src/core/surface/secure_channel_create.c
+++ b/src/core/surface/secure_channel_create.c
@@ -130,9 +130,9 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *arg,
static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg,
bool success) {
connector *c = arg;
- grpc_security_connector_do_handshake(exec_ctx, &c->security_connector->base,
- c->connecting_endpoint,
- on_secure_handshake_done, c);
+ grpc_channel_security_connector_do_handshake(exec_ctx, c->security_connector,
+ c->connecting_endpoint,
+ on_secure_handshake_done, c);
}
static void connected(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
@@ -153,9 +153,8 @@ static void connected(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
grpc_endpoint_write(exec_ctx, tcp, &c->initial_string_buffer,
&c->initial_string_sent);
} else {
- grpc_security_connector_do_handshake(exec_ctx,
- &c->security_connector->base, tcp,
- on_secure_handshake_done, c);
+ grpc_channel_security_connector_do_handshake(
+ exec_ctx, c->security_connector, tcp, on_secure_handshake_done, c);
}
} else {
memset(c->result, 0, sizeof(*c->result));
diff --git a/src/core/transport/chttp2/internal.h b/src/core/transport/chttp2/internal.h
index d76d31be23..891aad6ef2 100644
--- a/src/core/transport/chttp2/internal.h
+++ b/src/core/transport/chttp2/internal.h
@@ -417,7 +417,7 @@ typedef struct {
/** HTTP2 stream id for this stream, or zero if one has not been assigned */
uint32_t id;
uint8_t fetching;
- uint8_t sent_initial_metadata;
+ bool sent_initial_metadata;
uint8_t sent_message;
uint8_t sent_trailing_metadata;
uint8_t read_closed;
@@ -509,7 +509,7 @@ void grpc_chttp2_publish_reads(grpc_exec_ctx *exec_ctx,
grpc_chttp2_transport_global *global,
grpc_chttp2_transport_parsing *parsing);
-void grpc_chttp2_list_add_writable_stream(
+bool grpc_chttp2_list_add_writable_stream(
grpc_chttp2_transport_global *transport_global,
grpc_chttp2_stream_global *stream_global);
/** Get a writable stream
@@ -519,14 +519,13 @@ int grpc_chttp2_list_pop_writable_stream(
grpc_chttp2_transport_writing *transport_writing,
grpc_chttp2_stream_global **stream_global,
grpc_chttp2_stream_writing **stream_writing);
-void grpc_chttp2_list_remove_writable_stream(
+bool grpc_chttp2_list_remove_writable_stream(
grpc_chttp2_transport_global *transport_global,
- grpc_chttp2_stream_global *stream_global);
+ grpc_chttp2_stream_global *stream_global) GRPC_MUST_USE_RESULT;
-/* returns 1 if stream added, 0 if it was already present */
-int grpc_chttp2_list_add_writing_stream(
+void grpc_chttp2_list_add_writing_stream(
grpc_chttp2_transport_writing *transport_writing,
- grpc_chttp2_stream_writing *stream_writing) GRPC_MUST_USE_RESULT;
+ grpc_chttp2_stream_writing *stream_writing);
int grpc_chttp2_list_have_writing_streams(
grpc_chttp2_transport_writing *transport_writing);
int grpc_chttp2_list_pop_writing_stream(
@@ -770,4 +769,9 @@ void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx,
grpc_chttp2_transport_parsing *parsing,
const uint8_t *opaque_8bytes);
+/** add a ref to the stream and add it to the writable list;
+ ref will be dropped in writing.c */
+void grpc_chttp2_become_writable(grpc_chttp2_transport_global *transport_global,
+ grpc_chttp2_stream_global *stream_global);
+
#endif
diff --git a/src/core/transport/chttp2/parsing.c b/src/core/transport/chttp2/parsing.c
index 8fdebd7f13..0516f39fa9 100644
--- a/src/core/transport/chttp2/parsing.c
+++ b/src/core/transport/chttp2/parsing.c
@@ -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
@@ -149,7 +149,7 @@ void grpc_chttp2_publish_reads(
if (was_zero && !is_zero) {
while (grpc_chttp2_list_pop_stalled_by_transport(transport_global,
&stream_global)) {
- grpc_chttp2_list_add_writable_stream(transport_global, stream_global);
+ grpc_chttp2_become_writable(transport_global, stream_global);
}
}
@@ -178,7 +178,7 @@ void grpc_chttp2_publish_reads(
outgoing_window);
is_zero = stream_global->outgoing_window <= 0;
if (was_zero && !is_zero) {
- grpc_chttp2_list_add_writable_stream(transport_global, stream_global);
+ grpc_chttp2_become_writable(transport_global, stream_global);
}
stream_global->max_recv_bytes -= (uint32_t)GPR_MIN(
diff --git a/src/core/transport/chttp2/stream_lists.c b/src/core/transport/chttp2/stream_lists.c
index b284c78818..60fe735cfc 100644
--- a/src/core/transport/chttp2/stream_lists.c
+++ b/src/core/transport/chttp2/stream_lists.c
@@ -100,11 +100,14 @@ static void stream_list_remove(grpc_chttp2_transport *t, grpc_chttp2_stream *s,
}
}
-static void stream_list_maybe_remove(grpc_chttp2_transport *t,
+static bool stream_list_maybe_remove(grpc_chttp2_transport *t,
grpc_chttp2_stream *s,
grpc_chttp2_stream_list_id id) {
if (s->included[id]) {
stream_list_remove(t, s, id);
+ return true;
+ } else {
+ return false;
}
}
@@ -125,23 +128,24 @@ static void stream_list_add_tail(grpc_chttp2_transport *t,
s->included[id] = 1;
}
-static int stream_list_add(grpc_chttp2_transport *t, grpc_chttp2_stream *s,
- grpc_chttp2_stream_list_id id) {
+static bool stream_list_add(grpc_chttp2_transport *t, grpc_chttp2_stream *s,
+ grpc_chttp2_stream_list_id id) {
if (s->included[id]) {
- return 0;
+ return false;
}
stream_list_add_tail(t, s, id);
- return 1;
+ return true;
}
/* wrappers for specializations */
-void grpc_chttp2_list_add_writable_stream(
+bool grpc_chttp2_list_add_writable_stream(
grpc_chttp2_transport_global *transport_global,
grpc_chttp2_stream_global *stream_global) {
GPR_ASSERT(stream_global->id != 0);
- stream_list_add(TRANSPORT_FROM_GLOBAL(transport_global),
- STREAM_FROM_GLOBAL(stream_global), GRPC_CHTTP2_LIST_WRITABLE);
+ return stream_list_add(TRANSPORT_FROM_GLOBAL(transport_global),
+ STREAM_FROM_GLOBAL(stream_global),
+ GRPC_CHTTP2_LIST_WRITABLE);
}
int grpc_chttp2_list_pop_writable_stream(
@@ -159,20 +163,20 @@ int grpc_chttp2_list_pop_writable_stream(
return r;
}
-void grpc_chttp2_list_remove_writable_stream(
+bool grpc_chttp2_list_remove_writable_stream(
grpc_chttp2_transport_global *transport_global,
grpc_chttp2_stream_global *stream_global) {
- stream_list_maybe_remove(TRANSPORT_FROM_GLOBAL(transport_global),
- STREAM_FROM_GLOBAL(stream_global),
- GRPC_CHTTP2_LIST_WRITABLE);
+ return stream_list_maybe_remove(TRANSPORT_FROM_GLOBAL(transport_global),
+ STREAM_FROM_GLOBAL(stream_global),
+ GRPC_CHTTP2_LIST_WRITABLE);
}
-int grpc_chttp2_list_add_writing_stream(
+void grpc_chttp2_list_add_writing_stream(
grpc_chttp2_transport_writing *transport_writing,
grpc_chttp2_stream_writing *stream_writing) {
- return stream_list_add(TRANSPORT_FROM_WRITING(transport_writing),
- STREAM_FROM_WRITING(stream_writing),
- GRPC_CHTTP2_LIST_WRITING);
+ GPR_ASSERT(stream_list_add(TRANSPORT_FROM_WRITING(transport_writing),
+ STREAM_FROM_WRITING(stream_writing),
+ GRPC_CHTTP2_LIST_WRITING));
}
int grpc_chttp2_list_have_writing_streams(
@@ -332,7 +336,7 @@ void grpc_chttp2_list_flush_writing_stalled_by_transport(
while (stream_list_pop(transport, &stream,
GRPC_CHTTP2_LIST_WRITING_STALLED_BY_TRANSPORT)) {
if (is_window_available) {
- grpc_chttp2_list_add_writable_stream(&transport->global, &stream->global);
+ grpc_chttp2_become_writable(&transport->global, &stream->global);
} else {
grpc_chttp2_list_add_stalled_by_transport(transport_writing,
&stream->writing);
diff --git a/src/core/transport/chttp2/writing.c b/src/core/transport/chttp2/writing.c
index 356fd8174a..107725cbc7 100644
--- a/src/core/transport/chttp2/writing.c
+++ b/src/core/transport/chttp2/writing.c
@@ -83,7 +83,8 @@ int grpc_chttp2_unlocking_check_writes(
(according to available window sizes) and add to the output buffer */
while (grpc_chttp2_list_pop_writable_stream(
transport_global, transport_writing, &stream_global, &stream_writing)) {
- uint8_t sent_initial_metadata;
+ bool sent_initial_metadata = stream_writing->sent_initial_metadata;
+ bool become_writable = false;
stream_writing->id = stream_global->id;
stream_writing->read_closed = stream_global->read_closed;
@@ -92,16 +93,12 @@ int grpc_chttp2_unlocking_check_writes(
outgoing_window, stream_global,
outgoing_window);
- sent_initial_metadata = stream_writing->sent_initial_metadata;
if (!sent_initial_metadata && stream_global->send_initial_metadata) {
stream_writing->send_initial_metadata =
stream_global->send_initial_metadata;
stream_global->send_initial_metadata = NULL;
- if (grpc_chttp2_list_add_writing_stream(transport_writing,
- stream_writing)) {
- GRPC_CHTTP2_STREAM_REF(stream_global, "chttp2_writing");
- }
- sent_initial_metadata = 1;
+ become_writable = true;
+ sent_initial_metadata = true;
}
if (sent_initial_metadata) {
if (stream_global->send_message != NULL) {
@@ -128,10 +125,7 @@ int grpc_chttp2_unlocking_check_writes(
stream_writing->flow_controlled_buffer.length > 0) &&
stream_writing->outgoing_window > 0) {
if (transport_writing->outgoing_window > 0) {
- if (grpc_chttp2_list_add_writing_stream(transport_writing,
- stream_writing)) {
- GRPC_CHTTP2_STREAM_REF(stream_global, "chttp2_writing");
- }
+ become_writable = true;
} else {
grpc_chttp2_list_add_stalled_by_transport(transport_writing,
stream_writing);
@@ -141,10 +135,7 @@ int grpc_chttp2_unlocking_check_writes(
stream_writing->send_trailing_metadata =
stream_global->send_trailing_metadata;
stream_global->send_trailing_metadata = NULL;
- if (grpc_chttp2_list_add_writing_stream(transport_writing,
- stream_writing)) {
- GRPC_CHTTP2_STREAM_REF(stream_global, "chttp2_writing");
- }
+ become_writable = true;
}
}
@@ -153,10 +144,13 @@ int grpc_chttp2_unlocking_check_writes(
GRPC_CHTTP2_FLOW_MOVE_STREAM("write", transport_global, stream_writing,
announce_window, stream_global,
unannounced_incoming_window_for_writing);
- if (grpc_chttp2_list_add_writing_stream(transport_writing,
- stream_writing)) {
- GRPC_CHTTP2_STREAM_REF(stream_global, "chttp2_writing");
- }
+ become_writable = true;
+ }
+
+ if (become_writable) {
+ grpc_chttp2_list_add_writing_stream(transport_writing, stream_writing);
+ } else {
+ GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2_writing");
}
}
@@ -310,10 +304,7 @@ static void finalize_outbuf(grpc_exec_ctx *exec_ctx,
(stream_writing->send_message && !stream_writing->fetching)) &&
stream_writing->outgoing_window > 0) {
if (transport_writing->outgoing_window > 0) {
- if (grpc_chttp2_list_add_writing_stream(transport_writing,
- stream_writing)) {
- /* do nothing - already reffed */
- }
+ grpc_chttp2_list_add_writing_stream(transport_writing, stream_writing);
} else {
grpc_chttp2_list_add_writing_stalled_by_transport(transport_writing,
stream_writing);
diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c
index b9f511e946..a1ca78d4c4 100644
--- a/src/core/transport/chttp2_transport.c
+++ b/src/core/transport/chttp2_transport.c
@@ -142,7 +142,7 @@ static void incoming_byte_stream_update_flow_control(
static void fail_pending_writes(grpc_exec_ctx *exec_ctx,
grpc_chttp2_stream_global *stream_global);
-/*
+/*******************************************************************************
* CONSTRUCTION/DESTRUCTION/REFCOUNTING
*/
@@ -521,7 +521,6 @@ static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
s->global.id) == NULL);
}
- grpc_chttp2_list_remove_writable_stream(&t->global, &s->global);
grpc_chttp2_list_remove_unannounced_incoming_window_available(&t->global,
&s->global);
grpc_chttp2_list_remove_stalled_by_transport(&t->global, &s->global);
@@ -583,7 +582,7 @@ grpc_chttp2_stream_parsing *grpc_chttp2_parsing_accept_stream(
return &accepting->parsing;
}
-/*
+/*******************************************************************************
* LOCK MANAGEMENT
*/
@@ -611,10 +610,18 @@ static void unlock(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t) {
GPR_TIMER_END("unlock", 0);
}
-/*
+/*******************************************************************************
* OUTPUT PROCESSING
*/
+void grpc_chttp2_become_writable(grpc_chttp2_transport_global *transport_global,
+ grpc_chttp2_stream_global *stream_global) {
+ if (!TRANSPORT_FROM_GLOBAL(transport_global)->closed &&
+ grpc_chttp2_list_add_writable_stream(transport_global, stream_global)) {
+ GRPC_CHTTP2_STREAM_REF(stream_global, "chttp2_writing");
+ }
+}
+
static void push_setting(grpc_chttp2_transport *t, grpc_chttp2_setting_id id,
uint32_t value) {
const grpc_chttp2_setting_parameters *sp =
@@ -732,7 +739,7 @@ static void maybe_start_some_streams(
stream_global->id, STREAM_FROM_GLOBAL(stream_global));
stream_global->in_stream_map = 1;
transport_global->concurrent_stream_count++;
- grpc_chttp2_list_add_writable_stream(transport_global, stream_global);
+ grpc_chttp2_become_writable(transport_global, stream_global);
}
/* cancel out streams that will never be started */
while (transport_global->next_stream_id >= MAX_CLIENT_STREAM_ID &&
@@ -821,7 +828,7 @@ static void perform_stream_op_locked(
maybe_start_some_streams(exec_ctx, transport_global);
} else {
GPR_ASSERT(stream_global->id != 0);
- grpc_chttp2_list_add_writable_stream(transport_global, stream_global);
+ grpc_chttp2_become_writable(transport_global, stream_global);
}
} else {
grpc_chttp2_complete_closure_step(
@@ -838,7 +845,7 @@ static void perform_stream_op_locked(
exec_ctx, &stream_global->send_message_finished, 0);
} else if (stream_global->id != 0) {
stream_global->send_message = op->send_message;
- grpc_chttp2_list_add_writable_stream(transport_global, stream_global);
+ grpc_chttp2_become_writable(transport_global, stream_global);
}
}
@@ -858,7 +865,7 @@ static void perform_stream_op_locked(
} else if (stream_global->id != 0) {
/* TODO(ctiller): check if there's flow control for any outstanding
bytes before going writable */
- grpc_chttp2_list_add_writable_stream(transport_global, stream_global);
+ grpc_chttp2_become_writable(transport_global, stream_global);
}
}
@@ -999,7 +1006,7 @@ static void perform_transport_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
}
}
-/*
+/*******************************************************************************
* INPUT PROCESSING
*/
@@ -1064,7 +1071,6 @@ static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
if (!s) {
s = grpc_chttp2_stream_map_delete(&t->new_stream_map, id);
}
- grpc_chttp2_list_remove_writable_stream(&t->global, &s->global);
GPR_ASSERT(s);
s->global.in_stream_map = 0;
if (t->parsing.incoming_stream == &s->parsing) {
@@ -1080,6 +1086,9 @@ static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
if (grpc_chttp2_unregister_stream(t, s) && t->global.sent_goaway) {
close_transport_locked(exec_ctx, t);
}
+ if (grpc_chttp2_list_remove_writable_stream(&t->global, &s->global)) {
+ GRPC_CHTTP2_STREAM_UNREF(exec_ctx, &s->global, "chttp2_writing");
+ }
new_stream_count = grpc_chttp2_stream_map_size(&t->parsing_stream_map) +
grpc_chttp2_stream_map_size(&t->new_stream_map);
@@ -1331,7 +1340,7 @@ static void update_global_window(void *args, uint32_t id, void *stream) {
is_zero = stream_global->outgoing_window <= 0;
if (was_zero && !is_zero) {
- grpc_chttp2_list_add_writable_stream(transport_global, stream_global);
+ grpc_chttp2_become_writable(transport_global, stream_global);
}
}
@@ -1426,7 +1435,7 @@ static void recv_data(grpc_exec_ctx *exec_ctx, void *tp, bool success) {
GPR_TIMER_END("recv_data", 0);
}
-/*
+/*******************************************************************************
* CALLBACK LOOP
*/
@@ -1440,7 +1449,7 @@ static void connectivity_state_set(
state, reason);
}
-/*
+/*******************************************************************************
* POLLSET STUFF
*/
@@ -1468,7 +1477,7 @@ static void set_pollset(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
unlock(exec_ctx, t);
}
-/*
+/*******************************************************************************
* BYTE STREAM
*/
@@ -1508,7 +1517,7 @@ static void incoming_byte_stream_update_flow_control(
add_max_recv_bytes);
grpc_chttp2_list_add_unannounced_incoming_window_available(transport_global,
stream_global);
- grpc_chttp2_list_add_writable_stream(transport_global, stream_global);
+ grpc_chttp2_become_writable(transport_global, stream_global);
}
}
@@ -1623,7 +1632,7 @@ grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create(
return incoming_byte_stream;
}
-/*
+/*******************************************************************************
* TRACING
*/
@@ -1709,7 +1718,7 @@ void grpc_chttp2_flowctl_trace(const char *file, int line, const char *phase,
gpr_free(prefix);
}
-/*
+/*******************************************************************************
* INTEGRATION GLUE
*/
diff --git a/src/core/transport/metadata.c b/src/core/transport/metadata.c
index 14912af7df..807ae071a3 100644
--- a/src/core/transport/metadata.c
+++ b/src/core/transport/metadata.c
@@ -43,11 +43,13 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/time.h>
+
#include "src/core/profiling/timers.h"
#include "src/core/support/murmur_hash.h"
#include "src/core/support/string.h"
#include "src/core/transport/chttp2/bin_encoder.h"
#include "src/core/transport/static_metadata.h"
+#include "src/core/iomgr/iomgr_internal.h"
/* There are two kinds of mdelem and mdstr instances.
* Static instances are declared in static_metadata.{h,c} and
@@ -227,6 +229,9 @@ void grpc_mdctx_global_shutdown(void) {
if (shard->count != 0) {
gpr_log(GPR_DEBUG, "WARNING: %d metadata elements were leaked",
shard->count);
+ if (grpc_iomgr_abort_on_leaks()) {
+ abort();
+ }
}
gpr_free(shard->elems);
}
@@ -237,6 +242,9 @@ void grpc_mdctx_global_shutdown(void) {
if (shard->count != 0) {
gpr_log(GPR_DEBUG, "WARNING: %d metadata strings were leaked",
shard->count);
+ if (grpc_iomgr_abort_on_leaks()) {
+ abort();
+ }
}
gpr_free(shard->strs);
}
diff --git a/src/core/transport/transport.c b/src/core/transport/transport.c
index 6e154b629a..3b555fa933 100644
--- a/src/core/transport/transport.c
+++ b/src/core/transport/transport.c
@@ -45,7 +45,7 @@ void grpc_stream_ref(grpc_stream_refcount *refcount, const char *reason) {
#else
void grpc_stream_ref(grpc_stream_refcount *refcount) {
#endif
- gpr_ref(&refcount->refs);
+ gpr_ref_non_zero(&refcount->refs);
}
#ifdef GRPC_STREAM_REFCOUNT_DEBUG
diff --git a/src/cpp/common/alarm.cc b/src/cpp/common/alarm.cc
deleted file mode 100644
index a289688768..0000000000
--- a/src/cpp/common/alarm.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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.
- *
- */
-
-#include <grpc++/alarm.h>
-#include <grpc++/completion_queue.h>
-#include <grpc++/impl/grpc_library.h>
-#include <grpc/grpc.h>
-
-namespace grpc {
-
-static internal::GrpcLibraryInitializer g_gli_initializer;
-Alarm::Alarm(CompletionQueue* cq, gpr_timespec deadline, void* tag)
- : tag_(tag),
- alarm_(grpc_alarm_create(cq->cq(), deadline, static_cast<void*>(&tag_))) {
- g_gli_initializer.summon();
-}
-
-Alarm::~Alarm() { grpc_alarm_destroy(alarm_); }
-
-void Alarm::Cancel() { grpc_alarm_cancel(alarm_); }
-
-} // namespace grpc
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
index b72cbd795f..9380c0d0ea 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
@@ -193,16 +193,6 @@ namespace Grpc.Core.Internal
lock (myLock)
{
finished = true;
-
- if (cancelled)
- {
- // Once we cancel, we don't have to care that much
- // about reads and writes.
-
- // TODO(jtattermusch): is this still necessary?
- Cancel();
- }
-
ReleaseResourcesIfPossible();
}
// TODO(jtattermusch): handle error
diff --git a/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs b/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs
index a8a76c7492..c3fac05324 100644
--- a/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs
+++ b/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs
@@ -36,7 +36,7 @@ using System.Text;
using System.Threading.Tasks;
using Grpc.Core;
-using Grpc.Health.V1Alpha;
+using Grpc.Health.V1;
using NUnit.Framework;
namespace Grpc.HealthCheck.Tests
@@ -49,7 +49,7 @@ namespace Grpc.HealthCheck.Tests
const string Host = "localhost";
Server server;
Channel channel;
- Grpc.Health.V1Alpha.Health.IHealthClient client;
+ Grpc.Health.V1.Health.IHealthClient client;
Grpc.HealthCheck.HealthServiceImpl serviceImpl;
[TestFixtureSetUp]
@@ -59,13 +59,13 @@ namespace Grpc.HealthCheck.Tests
server = new Server
{
- Services = { Grpc.Health.V1Alpha.Health.BindService(serviceImpl) },
+ Services = { Grpc.Health.V1.Health.BindService(serviceImpl) },
Ports = { { Host, ServerPort.PickUnused, ServerCredentials.Insecure } }
};
server.Start();
channel = new Channel(Host, server.Ports.Single().BoundPort, ChannelCredentials.Insecure);
- client = Grpc.Health.V1Alpha.Health.NewClient(channel);
+ client = Grpc.Health.V1.Health.NewClient(channel);
}
[TestFixtureTearDown]
@@ -79,16 +79,16 @@ namespace Grpc.HealthCheck.Tests
[Test]
public void ServiceIsRunning()
{
- serviceImpl.SetStatus("", "", HealthCheckResponse.Types.ServingStatus.SERVING);
+ serviceImpl.SetStatus("", HealthCheckResponse.Types.ServingStatus.SERVING);
- var response = client.Check(new HealthCheckRequest { Host = "", Service = "" });
+ var response = client.Check(new HealthCheckRequest { Service = "" });
Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.SERVING, response.Status);
}
[Test]
public void ServiceDoesntExist()
{
- Assert.Throws(Is.TypeOf(typeof(RpcException)).And.Property("Status").Property("StatusCode").EqualTo(StatusCode.NotFound), () => client.Check(new HealthCheckRequest { Host = "", Service = "nonexistent.service" }));
+ Assert.Throws(Is.TypeOf(typeof(RpcException)).And.Property("Status").Property("StatusCode").EqualTo(StatusCode.NotFound), () => client.Check(new HealthCheckRequest { Service = "nonexistent.service" }));
}
// TODO(jtattermusch): add test with timeout once timeouts are supported
diff --git a/src/csharp/Grpc.HealthCheck.Tests/HealthServiceImplTest.cs b/src/csharp/Grpc.HealthCheck.Tests/HealthServiceImplTest.cs
index 2097c0dc8c..47e4b7c2a7 100644
--- a/src/csharp/Grpc.HealthCheck.Tests/HealthServiceImplTest.cs
+++ b/src/csharp/Grpc.HealthCheck.Tests/HealthServiceImplTest.cs
@@ -1,5 +1,5 @@
#region Copyright notice and license
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -36,7 +36,7 @@ using System.Text;
using System.Threading.Tasks;
using Grpc.Core;
-using Grpc.Health.V1Alpha;
+using Grpc.Health.V1;
using NUnit.Framework;
namespace Grpc.HealthCheck.Tests
@@ -50,58 +50,56 @@ namespace Grpc.HealthCheck.Tests
public void SetStatus()
{
var impl = new HealthServiceImpl();
- impl.SetStatus("", "", HealthCheckResponse.Types.ServingStatus.SERVING);
- Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.SERVING, GetStatusHelper(impl, "", ""));
+ impl.SetStatus("", HealthCheckResponse.Types.ServingStatus.SERVING);
+ Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.SERVING, GetStatusHelper(impl, ""));
- impl.SetStatus("", "", HealthCheckResponse.Types.ServingStatus.NOT_SERVING);
- Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.NOT_SERVING, GetStatusHelper(impl, "", ""));
+ impl.SetStatus("", HealthCheckResponse.Types.ServingStatus.NOT_SERVING);
+ Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.NOT_SERVING, GetStatusHelper(impl, ""));
- impl.SetStatus("virtual-host", "", HealthCheckResponse.Types.ServingStatus.UNKNOWN);
- Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.UNKNOWN, GetStatusHelper(impl, "virtual-host", ""));
+ impl.SetStatus("", HealthCheckResponse.Types.ServingStatus.UNKNOWN);
+ Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.UNKNOWN, GetStatusHelper(impl, ""));
- impl.SetStatus("virtual-host", "grpc.test.TestService", HealthCheckResponse.Types.ServingStatus.SERVING);
- Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.SERVING, GetStatusHelper(impl, "virtual-host", "grpc.test.TestService"));
+ impl.SetStatus("grpc.test.TestService", HealthCheckResponse.Types.ServingStatus.SERVING);
+ Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.SERVING, GetStatusHelper(impl, "grpc.test.TestService"));
}
[Test]
public void ClearStatus()
{
var impl = new HealthServiceImpl();
- impl.SetStatus("", "", HealthCheckResponse.Types.ServingStatus.SERVING);
- impl.SetStatus("virtual-host", "", HealthCheckResponse.Types.ServingStatus.UNKNOWN);
+ impl.SetStatus("", HealthCheckResponse.Types.ServingStatus.SERVING);
+ impl.SetStatus("grpc.test.TestService", HealthCheckResponse.Types.ServingStatus.UNKNOWN);
- impl.ClearStatus("", "");
+ impl.ClearStatus("");
- Assert.Throws(Is.TypeOf(typeof(RpcException)).And.Property("Status").Property("StatusCode").EqualTo(StatusCode.NotFound), () => GetStatusHelper(impl, "", ""));
- Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.UNKNOWN, GetStatusHelper(impl, "virtual-host", ""));
+ Assert.Throws(Is.TypeOf(typeof(RpcException)).And.Property("Status").Property("StatusCode").EqualTo(StatusCode.NotFound), () => GetStatusHelper(impl, ""));
+ Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.UNKNOWN, GetStatusHelper(impl, "grpc.test.TestService"));
}
[Test]
public void ClearAll()
{
var impl = new HealthServiceImpl();
- impl.SetStatus("", "", HealthCheckResponse.Types.ServingStatus.SERVING);
- impl.SetStatus("virtual-host", "", HealthCheckResponse.Types.ServingStatus.UNKNOWN);
+ impl.SetStatus("", HealthCheckResponse.Types.ServingStatus.SERVING);
+ impl.SetStatus("grpc.test.TestService", HealthCheckResponse.Types.ServingStatus.UNKNOWN);
impl.ClearAll();
- Assert.Throws(typeof(RpcException), () => GetStatusHelper(impl, "", ""));
- Assert.Throws(typeof(RpcException), () => GetStatusHelper(impl, "virtual-host", ""));
+ Assert.Throws(typeof(RpcException), () => GetStatusHelper(impl, ""));
+ Assert.Throws(typeof(RpcException), () => GetStatusHelper(impl, "grpc.test.TestService"));
}
[Test]
public void NullsRejected()
{
var impl = new HealthServiceImpl();
- Assert.Throws(typeof(ArgumentNullException), () => impl.SetStatus(null, "", HealthCheckResponse.Types.ServingStatus.SERVING));
- Assert.Throws(typeof(ArgumentNullException), () => impl.SetStatus("", null, HealthCheckResponse.Types.ServingStatus.SERVING));
+ Assert.Throws(typeof(ArgumentNullException), () => impl.SetStatus(null, HealthCheckResponse.Types.ServingStatus.SERVING));
- Assert.Throws(typeof(ArgumentNullException), () => impl.ClearStatus(null, ""));
- Assert.Throws(typeof(ArgumentNullException), () => impl.ClearStatus("", null));
+ Assert.Throws(typeof(ArgumentNullException), () => impl.ClearStatus(null));
}
- private static HealthCheckResponse.Types.ServingStatus GetStatusHelper(HealthServiceImpl impl, string host, string service)
+ private static HealthCheckResponse.Types.ServingStatus GetStatusHelper(HealthServiceImpl impl, string service)
{
- return impl.Check(new HealthCheckRequest { Host = host, Service = service }, null).Result.Status;
+ return impl.Check(new HealthCheckRequest { Service = service }, null).Result.Status;
}
}
}
diff --git a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.nuspec b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.nuspec
index 66386288df..7b3b391009 100644
--- a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.nuspec
+++ b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.nuspec
@@ -4,7 +4,7 @@
<id>Grpc.HealthCheck</id>
<title>gRPC C# Healthchecking</title>
<summary>Implementation of gRPC health service</summary>
- <description>Example implementation of grpc.health.v1alpha service that can be used for health-checking.</description>
+ <description>Example implementation of grpc.health.v1 service that can be used for health-checking.</description>
<version>$version$</version>
<authors>Google Inc.</authors>
<owners>grpc-packages</owners>
diff --git a/src/csharp/Grpc.HealthCheck/Health.cs b/src/csharp/Grpc.HealthCheck/Health.cs
index 56673f1adf..d0d0c0b519 100644
--- a/src/csharp/Grpc.HealthCheck/Health.cs
+++ b/src/csharp/Grpc.HealthCheck/Health.cs
@@ -7,7 +7,7 @@ using pb = global::Google.Protobuf;
using pbc = global::Google.Protobuf.Collections;
using pbr = global::Google.Protobuf.Reflection;
using scg = global::System.Collections.Generic;
-namespace Grpc.Health.V1Alpha {
+namespace Grpc.Health.V1 {
/// <summary>Holder for reflection information generated from health.proto</summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -23,20 +23,19 @@ namespace Grpc.Health.V1Alpha {
static HealthReflection() {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
- "CgxoZWFsdGgucHJvdG8SE2dycGMuaGVhbHRoLnYxYWxwaGEiMwoSSGVhbHRo",
- "Q2hlY2tSZXF1ZXN0EgwKBGhvc3QYASABKAkSDwoHc2VydmljZRgCIAEoCSKZ",
- "AQoTSGVhbHRoQ2hlY2tSZXNwb25zZRJGCgZzdGF0dXMYASABKA4yNi5ncnBj",
- "LmhlYWx0aC52MWFscGhhLkhlYWx0aENoZWNrUmVzcG9uc2UuU2VydmluZ1N0",
- "YXR1cyI6Cg1TZXJ2aW5nU3RhdHVzEgsKB1VOS05PV04QABILCgdTRVJWSU5H",
- "EAESDwoLTk9UX1NFUlZJTkcQAjJkCgZIZWFsdGgSWgoFQ2hlY2sSJy5ncnBj",
- "LmhlYWx0aC52MWFscGhhLkhlYWx0aENoZWNrUmVxdWVzdBooLmdycGMuaGVh",
- "bHRoLnYxYWxwaGEuSGVhbHRoQ2hlY2tSZXNwb25zZUIWqgITR3JwYy5IZWFs",
- "dGguVjFBbHBoYWIGcHJvdG8z"));
+ "CgxoZWFsdGgucHJvdG8SDmdycGMuaGVhbHRoLnYxIiUKEkhlYWx0aENoZWNr",
+ "UmVxdWVzdBIPCgdzZXJ2aWNlGAEgASgJIpQBChNIZWFsdGhDaGVja1Jlc3Bv",
+ "bnNlEkEKBnN0YXR1cxgBIAEoDjIxLmdycGMuaGVhbHRoLnYxLkhlYWx0aENo",
+ "ZWNrUmVzcG9uc2UuU2VydmluZ1N0YXR1cyI6Cg1TZXJ2aW5nU3RhdHVzEgsK",
+ "B1VOS05PV04QABILCgdTRVJWSU5HEAESDwoLTk9UX1NFUlZJTkcQAjJaCgZI",
+ "ZWFsdGgSUAoFQ2hlY2sSIi5ncnBjLmhlYWx0aC52MS5IZWFsdGhDaGVja1Jl",
+ "cXVlc3QaIy5ncnBjLmhlYWx0aC52MS5IZWFsdGhDaGVja1Jlc3BvbnNlQhGq",
+ "Ag5HcnBjLkhlYWx0aC5WMWIGcHJvdG8z"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Grpc.Health.V1Alpha.HealthCheckRequest), global::Grpc.Health.V1Alpha.HealthCheckRequest.Parser, new[]{ "Host", "Service" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Grpc.Health.V1Alpha.HealthCheckResponse), global::Grpc.Health.V1Alpha.HealthCheckResponse.Parser, new[]{ "Status" }, null, new[]{ typeof(global::Grpc.Health.V1Alpha.HealthCheckResponse.Types.ServingStatus) }, null)
+ new pbr::GeneratedCodeInfo(typeof(global::Grpc.Health.V1.HealthCheckRequest), global::Grpc.Health.V1.HealthCheckRequest.Parser, new[]{ "Service" }, null, null, null),
+ new pbr::GeneratedCodeInfo(typeof(global::Grpc.Health.V1.HealthCheckResponse), global::Grpc.Health.V1.HealthCheckResponse.Parser, new[]{ "Status" }, null, new[]{ typeof(global::Grpc.Health.V1.HealthCheckResponse.Types.ServingStatus) }, null)
}));
}
#endregion
@@ -49,7 +48,7 @@ namespace Grpc.Health.V1Alpha {
public static pb::MessageParser<HealthCheckRequest> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Grpc.Health.V1Alpha.HealthReflection.Descriptor.MessageTypes[0]; }
+ get { return global::Grpc.Health.V1.HealthReflection.Descriptor.MessageTypes[0]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -63,7 +62,6 @@ namespace Grpc.Health.V1Alpha {
partial void OnConstruction();
public HealthCheckRequest(HealthCheckRequest other) : this() {
- host_ = other.host_;
service_ = other.service_;
}
@@ -71,18 +69,8 @@ namespace Grpc.Health.V1Alpha {
return new HealthCheckRequest(this);
}
- /// <summary>Field number for the "host" field.</summary>
- public const int HostFieldNumber = 1;
- private string host_ = "";
- public string Host {
- get { return host_; }
- set {
- host_ = pb::Preconditions.CheckNotNull(value, "value");
- }
- }
-
/// <summary>Field number for the "service" field.</summary>
- public const int ServiceFieldNumber = 2;
+ public const int ServiceFieldNumber = 1;
private string service_ = "";
public string Service {
get { return service_; }
@@ -102,14 +90,12 @@ namespace Grpc.Health.V1Alpha {
if (ReferenceEquals(other, this)) {
return true;
}
- if (Host != other.Host) return false;
if (Service != other.Service) return false;
return true;
}
public override int GetHashCode() {
int hash = 1;
- if (Host.Length != 0) hash ^= Host.GetHashCode();
if (Service.Length != 0) hash ^= Service.GetHashCode();
return hash;
}
@@ -119,21 +105,14 @@ namespace Grpc.Health.V1Alpha {
}
public void WriteTo(pb::CodedOutputStream output) {
- if (Host.Length != 0) {
- output.WriteRawTag(10);
- output.WriteString(Host);
- }
if (Service.Length != 0) {
- output.WriteRawTag(18);
+ output.WriteRawTag(10);
output.WriteString(Service);
}
}
public int CalculateSize() {
int size = 0;
- if (Host.Length != 0) {
- size += 1 + pb::CodedOutputStream.ComputeStringSize(Host);
- }
if (Service.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(Service);
}
@@ -144,9 +123,6 @@ namespace Grpc.Health.V1Alpha {
if (other == null) {
return;
}
- if (other.Host.Length != 0) {
- Host = other.Host;
- }
if (other.Service.Length != 0) {
Service = other.Service;
}
@@ -160,10 +136,6 @@ namespace Grpc.Health.V1Alpha {
input.SkipLastField();
break;
case 10: {
- Host = input.ReadString();
- break;
- }
- case 18: {
Service = input.ReadString();
break;
}
@@ -179,7 +151,7 @@ namespace Grpc.Health.V1Alpha {
public static pb::MessageParser<HealthCheckResponse> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Grpc.Health.V1Alpha.HealthReflection.Descriptor.MessageTypes[1]; }
+ get { return global::Grpc.Health.V1.HealthReflection.Descriptor.MessageTypes[1]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -202,8 +174,8 @@ namespace Grpc.Health.V1Alpha {
/// <summary>Field number for the "status" field.</summary>
public const int StatusFieldNumber = 1;
- private global::Grpc.Health.V1Alpha.HealthCheckResponse.Types.ServingStatus status_ = global::Grpc.Health.V1Alpha.HealthCheckResponse.Types.ServingStatus.UNKNOWN;
- public global::Grpc.Health.V1Alpha.HealthCheckResponse.Types.ServingStatus Status {
+ private global::Grpc.Health.V1.HealthCheckResponse.Types.ServingStatus status_ = global::Grpc.Health.V1.HealthCheckResponse.Types.ServingStatus.UNKNOWN;
+ public global::Grpc.Health.V1.HealthCheckResponse.Types.ServingStatus Status {
get { return status_; }
set {
status_ = value;
@@ -227,7 +199,7 @@ namespace Grpc.Health.V1Alpha {
public override int GetHashCode() {
int hash = 1;
- if (Status != global::Grpc.Health.V1Alpha.HealthCheckResponse.Types.ServingStatus.UNKNOWN) hash ^= Status.GetHashCode();
+ if (Status != global::Grpc.Health.V1.HealthCheckResponse.Types.ServingStatus.UNKNOWN) hash ^= Status.GetHashCode();
return hash;
}
@@ -236,7 +208,7 @@ namespace Grpc.Health.V1Alpha {
}
public void WriteTo(pb::CodedOutputStream output) {
- if (Status != global::Grpc.Health.V1Alpha.HealthCheckResponse.Types.ServingStatus.UNKNOWN) {
+ if (Status != global::Grpc.Health.V1.HealthCheckResponse.Types.ServingStatus.UNKNOWN) {
output.WriteRawTag(8);
output.WriteEnum((int) Status);
}
@@ -244,7 +216,7 @@ namespace Grpc.Health.V1Alpha {
public int CalculateSize() {
int size = 0;
- if (Status != global::Grpc.Health.V1Alpha.HealthCheckResponse.Types.ServingStatus.UNKNOWN) {
+ if (Status != global::Grpc.Health.V1.HealthCheckResponse.Types.ServingStatus.UNKNOWN) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Status);
}
return size;
@@ -254,7 +226,7 @@ namespace Grpc.Health.V1Alpha {
if (other == null) {
return;
}
- if (other.Status != global::Grpc.Health.V1Alpha.HealthCheckResponse.Types.ServingStatus.UNKNOWN) {
+ if (other.Status != global::Grpc.Health.V1.HealthCheckResponse.Types.ServingStatus.UNKNOWN) {
Status = other.Status;
}
}
@@ -267,7 +239,7 @@ namespace Grpc.Health.V1Alpha {
input.SkipLastField();
break;
case 8: {
- status_ = (global::Grpc.Health.V1Alpha.HealthCheckResponse.Types.ServingStatus) input.ReadEnum();
+ status_ = (global::Grpc.Health.V1.HealthCheckResponse.Types.ServingStatus) input.ReadEnum();
break;
}
}
diff --git a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
index 882edd5627..68320eb5c2 100644
--- a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
+++ b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
@@ -7,15 +7,15 @@ using System.Threading;
using System.Threading.Tasks;
using Grpc.Core;
-namespace Grpc.Health.V1Alpha {
+namespace Grpc.Health.V1 {
public static class Health
{
- static readonly string __ServiceName = "grpc.health.v1alpha.Health";
+ static readonly string __ServiceName = "grpc.health.v1.Health";
- static readonly Marshaller<global::Grpc.Health.V1Alpha.HealthCheckRequest> __Marshaller_HealthCheckRequest = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Health.V1Alpha.HealthCheckRequest.Parser.ParseFrom);
- static readonly Marshaller<global::Grpc.Health.V1Alpha.HealthCheckResponse> __Marshaller_HealthCheckResponse = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Health.V1Alpha.HealthCheckResponse.Parser.ParseFrom);
+ static readonly Marshaller<global::Grpc.Health.V1.HealthCheckRequest> __Marshaller_HealthCheckRequest = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Health.V1.HealthCheckRequest.Parser.ParseFrom);
+ static readonly Marshaller<global::Grpc.Health.V1.HealthCheckResponse> __Marshaller_HealthCheckResponse = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Health.V1.HealthCheckResponse.Parser.ParseFrom);
- static readonly Method<global::Grpc.Health.V1Alpha.HealthCheckRequest, global::Grpc.Health.V1Alpha.HealthCheckResponse> __Method_Check = new Method<global::Grpc.Health.V1Alpha.HealthCheckRequest, global::Grpc.Health.V1Alpha.HealthCheckResponse>(
+ static readonly Method<global::Grpc.Health.V1.HealthCheckRequest, global::Grpc.Health.V1.HealthCheckResponse> __Method_Check = new Method<global::Grpc.Health.V1.HealthCheckRequest, global::Grpc.Health.V1.HealthCheckResponse>(
MethodType.Unary,
__ServiceName,
"Check",
@@ -25,22 +25,22 @@ namespace Grpc.Health.V1Alpha {
// service descriptor
public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
{
- get { return global::Grpc.Health.V1Alpha.HealthReflection.Descriptor.Services[0]; }
+ get { return global::Grpc.Health.V1.HealthReflection.Descriptor.Services[0]; }
}
// client interface
public interface IHealthClient
{
- global::Grpc.Health.V1Alpha.HealthCheckResponse Check(global::Grpc.Health.V1Alpha.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
- global::Grpc.Health.V1Alpha.HealthCheckResponse Check(global::Grpc.Health.V1Alpha.HealthCheckRequest request, CallOptions options);
- AsyncUnaryCall<global::Grpc.Health.V1Alpha.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1Alpha.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
- AsyncUnaryCall<global::Grpc.Health.V1Alpha.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1Alpha.HealthCheckRequest request, CallOptions options);
+ global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+ global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, CallOptions options);
+ AsyncUnaryCall<global::Grpc.Health.V1.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+ AsyncUnaryCall<global::Grpc.Health.V1.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, CallOptions options);
}
// server-side interface
public interface IHealth
{
- Task<global::Grpc.Health.V1Alpha.HealthCheckResponse> Check(global::Grpc.Health.V1Alpha.HealthCheckRequest request, ServerCallContext context);
+ Task<global::Grpc.Health.V1.HealthCheckResponse> Check(global::Grpc.Health.V1.HealthCheckRequest request, ServerCallContext context);
}
// client stub
@@ -49,22 +49,22 @@ namespace Grpc.Health.V1Alpha {
public HealthClient(Channel channel) : base(channel)
{
}
- public global::Grpc.Health.V1Alpha.HealthCheckResponse Check(global::Grpc.Health.V1Alpha.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
var call = CreateCall(__Method_Check, new CallOptions(headers, deadline, cancellationToken));
return Calls.BlockingUnaryCall(call, request);
}
- public global::Grpc.Health.V1Alpha.HealthCheckResponse Check(global::Grpc.Health.V1Alpha.HealthCheckRequest request, CallOptions options)
+ public global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, CallOptions options)
{
var call = CreateCall(__Method_Check, options);
return Calls.BlockingUnaryCall(call, request);
}
- public AsyncUnaryCall<global::Grpc.Health.V1Alpha.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1Alpha.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public AsyncUnaryCall<global::Grpc.Health.V1.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
var call = CreateCall(__Method_Check, new CallOptions(headers, deadline, cancellationToken));
return Calls.AsyncUnaryCall(call, request);
}
- public AsyncUnaryCall<global::Grpc.Health.V1Alpha.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1Alpha.HealthCheckRequest request, CallOptions options)
+ public AsyncUnaryCall<global::Grpc.Health.V1.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, CallOptions options)
{
var call = CreateCall(__Method_Check, options);
return Calls.AsyncUnaryCall(call, request);
diff --git a/src/csharp/Grpc.HealthCheck/HealthServiceImpl.cs b/src/csharp/Grpc.HealthCheck/HealthServiceImpl.cs
index e2ad1a834b..21482b302b 100644
--- a/src/csharp/Grpc.HealthCheck/HealthServiceImpl.cs
+++ b/src/csharp/Grpc.HealthCheck/HealthServiceImpl.cs
@@ -37,7 +37,7 @@ using System.Threading.Tasks;
using Grpc.Core;
using Grpc.Core.Utils;
-using Grpc.Health.V1Alpha;
+using Grpc.Health.V1;
namespace Grpc.HealthCheck
{
@@ -48,44 +48,42 @@ namespace Grpc.HealthCheck
/// <code>
/// var serviceImpl = new HealthServiceImpl();
/// server = new Server();
- /// server.AddServiceDefinition(Grpc.Health.V1Alpha.Health.BindService(serviceImpl));
+ /// server.AddServiceDefinition(Grpc.Health.V1.Health.BindService(serviceImpl));
/// </code>
/// </summary>
- public class HealthServiceImpl : Grpc.Health.V1Alpha.Health.IHealth
+ public class HealthServiceImpl : Grpc.Health.V1.Health.IHealth
{
private readonly object myLock = new object();
- private readonly Dictionary<Key, HealthCheckResponse.Types.ServingStatus> statusMap =
- new Dictionary<Key, HealthCheckResponse.Types.ServingStatus>();
+ private readonly Dictionary<string, HealthCheckResponse.Types.ServingStatus> statusMap =
+ new Dictionary<string, HealthCheckResponse.Types.ServingStatus>();
/// <summary>
- /// Sets the health status for given host and service.
+ /// Sets the health status for given service.
/// </summary>
- /// <param name="host">The host. Cannot be null.</param>
/// <param name="service">The service. Cannot be null.</param>
/// <param name="status">the health status</param>
- public void SetStatus(string host, string service, HealthCheckResponse.Types.ServingStatus status)
+ public void SetStatus(string service, HealthCheckResponse.Types.ServingStatus status)
{
lock (myLock)
{
- statusMap[CreateKey(host, service)] = status;
+ statusMap[service] = status;
}
}
/// <summary>
- /// Clears health status for given host and service.
+ /// Clears health status for given service.
/// </summary>
- /// <param name="host">The host. Cannot be null.</param>
/// <param name="service">The service. Cannot be null.</param>
- public void ClearStatus(string host, string service)
+ public void ClearStatus(string service)
{
lock (myLock)
{
- statusMap.Remove(CreateKey(host, service));
+ statusMap.Remove(service);
}
}
/// <summary>
- /// Clears statuses for all hosts and services.
+ /// Clears statuses for all services.
/// </summary>
public void ClearAll()
{
@@ -105,11 +103,10 @@ namespace Grpc.HealthCheck
{
lock (myLock)
{
- var host = request.Host;
var service = request.Service;
HealthCheckResponse.Types.ServingStatus status;
- if (!statusMap.TryGetValue(CreateKey(host, service), out status))
+ if (!statusMap.TryGetValue(service, out status))
{
// TODO(jtattermusch): returning specific status from server handler is not supported yet.
throw new RpcException(new Status(StatusCode.NotFound, ""));
@@ -117,22 +114,5 @@ namespace Grpc.HealthCheck
return Task.FromResult(new HealthCheckResponse { Status = status });
}
}
-
- private static Key CreateKey(string host, string service)
- {
- return new Key(host, service);
- }
-
- private struct Key
- {
- public Key(string host, string service)
- {
- this.Host = GrpcPreconditions.CheckNotNull(host);
- this.Service = GrpcPreconditions.CheckNotNull(service);
- }
-
- readonly string Host;
- readonly string Service;
- }
}
}
diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs b/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs
index 18168f9970..0d12c4168c 100644
--- a/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs
+++ b/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs
@@ -1,6 +1,6 @@
#region Copyright notice and license
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -140,14 +140,12 @@ namespace Grpc.IntegrationTesting
}
[Test]
- [Ignore("TODO: see #4427")]
public async Task StatusCodeAndMessage()
{
await InteropClient.RunStatusCodeAndMessageAsync(client);
}
[Test]
- [Ignore("TODO: see #4427")]
public void UnimplementedMethod()
{
InteropClient.RunUnimplementedMethod(UnimplementedService.NewClient(channel));
diff --git a/src/csharp/Grpc.Tools.nuspec b/src/csharp/Grpc.Tools.nuspec
index 48a7b1f3af..31d1bed647 100644
--- a/src/csharp/Grpc.Tools.nuspec
+++ b/src/csharp/Grpc.Tools.nuspec
@@ -4,18 +4,29 @@
<id>Grpc.Tools</id>
<title>gRPC C# Tools</title>
<summary>Tools for C# implementation of gRPC - an RPC library and framework</summary>
- <description>Precompiled Windows binary for generating gRPC client/server code</description>
+ <description>Precompiled protobuf compiler and gRPC protobuf compiler plugin for generating gRPC client/server C# code. Binaries are available for Windows, Linux and MacOS.</description>
<version>$version$</version>
<authors>Google Inc.</authors>
<owners>grpc-packages</owners>
<licenseUrl>https://github.com/grpc/grpc/blob/master/LICENSE</licenseUrl>
<projectUrl>https://github.com/grpc/grpc</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
- <releaseNotes>grpc_csharp_plugin.exe - gRPC C# protoc plugin version $version$</releaseNotes>
+ <releaseNotes>Release $version$</releaseNotes>
<copyright>Copyright 2015, Google Inc.</copyright>
<tags>gRPC RPC Protocol HTTP/2</tags>
</metadata>
<files>
- <file src="..\..\vsprojects\Release\grpc_csharp_plugin.exe" target="tools" />
+ <file src="protoc_plugins\windows_x86\protoc.exe" target="tools\windows_x86\protoc.exe" />
+ <file src="protoc_plugins\windows_x86\grpc_csharp_plugin.exe" target="tools\windows_x86\grpc_csharp_plugin.exe" />
+ <file src="protoc_plugins\windows_x64\protoc.exe" target="tools\windows_x64\protoc.exe" />
+ <file src="protoc_plugins\windows_x64\grpc_csharp_plugin.exe" target="tools\windows_x64\grpc_csharp_plugin.exe" />
+ <file src="protoc_plugins\linux_x86\protoc" target="tools\linux_x86\protoc" />
+ <file src="protoc_plugins\linux_x86\grpc_csharp_plugin" target="tools\linux_x86\grpc_csharp_plugin" />
+ <file src="protoc_plugins\linux_x64\protoc" target="tools\linux_x64\protoc" />
+ <file src="protoc_plugins\linux_x64\grpc_csharp_plugin" target="tools\linux_x64\grpc_csharp_plugin" />
+ <file src="protoc_plugins\macosx_x86\protoc" target="tools\macosx_x86\protoc" />
+ <file src="protoc_plugins\macosx_x86\grpc_csharp_plugin" target="tools\macosx_x86\grpc_csharp_plugin" />
+ <file src="protoc_plugins\macosx_x64\protoc" target="tools\macosx_x64\protoc" />
+ <file src="protoc_plugins\macosx_x64\grpc_csharp_plugin" target="tools\macosx_x64\grpc_csharp_plugin" />
</files>
</package>
diff --git a/src/csharp/build_packages.bat b/src/csharp/build_packages.bat
index b7768f7821..7c42a6d3fc 100644
--- a/src/csharp/build_packages.bat
+++ b/src/csharp/build_packages.bat
@@ -19,6 +19,14 @@ xcopy /Y /I ..\..\architecture=x64,language=csharp,platform=linux\artifacts\* gr
xcopy /Y /I ..\..\architecture=x86,language=csharp,platform=macos\artifacts\* grpc.native.csharp\macosx_x86\
xcopy /Y /I ..\..\architecture=x64,language=csharp,platform=macos\artifacts\* grpc.native.csharp\macosx_x64\
+@rem Collect protoc artifacts built by the previous build step
+xcopy /Y /I ..\..\architecture=x86,language=protoc,platform=windows\artifacts\* protoc_plugins\windows_x86\
+xcopy /Y /I ..\..\architecture=x64,language=protoc,platform=windows\artifacts\* protoc_plugins\windows_x64\
+xcopy /Y /I ..\..\architecture=x86,language=protoc,platform=linux\artifacts\* protoc_plugins\linux_x86\
+xcopy /Y /I ..\..\architecture=x64,language=protoc,platform=linux\artifacts\* protoc_plugins\linux_x64\
+xcopy /Y /I ..\..\architecture=x86,language=protoc,platform=macos\artifacts\* protoc_plugins\macosx_x86\
+xcopy /Y /I ..\..\architecture=x64,language=protoc,platform=macos\artifacts\* protoc_plugins\macosx_x64\
+
@rem Fetch all dependencies
%NUGET% restore ..\..\vsprojects\grpc_csharp_ext.sln || goto :error
%NUGET% restore Grpc.sln || goto :error
@@ -27,24 +35,19 @@ setlocal
@call "%VS120COMNTOOLS%\..\..\vc\vcvarsall.bat" x86
-@rem We won't use the native libraries from this step, but without this Grpc.sln will fail.
+@rem We won't use the native libraries from this step, but without this Grpc.sln will fail.
msbuild ..\..\vsprojects\grpc_csharp_ext.sln /p:Configuration=Release /p:PlatformToolset=v120 || goto :error
msbuild Grpc.sln /p:Configuration=ReleaseSigned || goto :error
endlocal
-@rem TODO(jtattermusch): re-enable protoc plugin building
-@rem @call ..\..\vsprojects\build_plugins.bat || goto :error
-
%NUGET% pack grpc.native.csharp\grpc.native.csharp.nuspec -Version %VERSION% || goto :error
%NUGET% pack Grpc.Auth\Grpc.Auth.nuspec -Symbols -Version %VERSION% || goto :error
%NUGET% pack Grpc.Core\Grpc.Core.nuspec -Symbols -Version %VERSION% || goto :error
%NUGET% pack Grpc.HealthCheck\Grpc.HealthCheck.nuspec -Symbols -Version %VERSION_WITH_BETA% -Properties ProtobufVersion=%PROTOBUF_VERSION% || goto :error
%NUGET% pack Grpc.nuspec -Version %VERSION% || goto :error
-
-@rem TODO(jtattermusch): re-enable building Grpc.Tools package
-@rem %NUGET% pack Grpc.Tools.nuspec -Version %VERSION% || goto :error
+%NUGET% pack Grpc.Tools.nuspec -Version %VERSION% || goto :error
@rem copy resulting nuget packages to artifacts directory
xcopy /Y /I *.nupkg ..\..\artifacts\
diff --git a/src/csharp/generate_proto_csharp.sh b/src/csharp/generate_proto_csharp.sh
index 0261a458af..23e0540253 100755
--- a/src/csharp/generate_proto_csharp.sh
+++ b/src/csharp/generate_proto_csharp.sh
@@ -42,7 +42,7 @@ $PROTOC --plugin=$PLUGIN --csharp_out=$EXAMPLES_DIR --grpc_out=$EXAMPLES_DIR \
-I src/proto/math src/proto/math/math.proto
$PROTOC --plugin=$PLUGIN --csharp_out=$HEALTHCHECK_DIR --grpc_out=$HEALTHCHECK_DIR \
- -I src/proto/grpc/health/v1alpha src/proto/grpc/health/v1alpha/health.proto
+ -I src/proto/grpc/health/v1 src/proto/grpc/health/v1/health.proto
$PROTOC --plugin=$PLUGIN --csharp_out=$TESTING_DIR --grpc_out=$TESTING_DIR \
-I . src/proto/grpc/testing/{control,empty,messages,payloads,services,stats,test}.proto
diff --git a/src/node/health_check/health.js b/src/node/health_check/health.js
index 1a2c036687..6ab4157183 100644
--- a/src/node/health_check/health.js
+++ b/src/node/health_check/health.js
@@ -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
@@ -38,9 +38,9 @@ var grpc = require('../');
var _ = require('lodash');
var health_proto = grpc.load(__dirname +
- '/../../proto/grpc/health/v1alpha/health.proto');
+ '/../../proto/grpc/health/v1/health.proto');
-var HealthClient = health_proto.grpc.health.v1alpha.Health;
+var HealthClient = health_proto.grpc.health.v1.Health;
function HealthImplementation(statusMap) {
this.statusMap = _.clone(statusMap);
diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m
index 9a3e5b5009..624958f4b9 100644
--- a/src/objective-c/tests/GRPCClientTests.m
+++ b/src/objective-c/tests/GRPCClientTests.m
@@ -103,6 +103,8 @@ static ProtoMethod *kUnaryCallMethod;
@implementation GRPCClientTests
- (void)setUp {
+ // Add a custom user agent prefix that will be used in test
+ [GRPCCall setUserAgentPrefix:@"Foo" forHost:kHostAddress];
// Register test server as non-SSL.
[GRPCCall useInsecureConnectionsForHost:kHostAddress];
@@ -257,6 +259,35 @@ static ProtoMethod *kUnaryCallMethod;
[self waitForExpectationsWithTimeout:8 handler:nil];
}
+- (void)testUserAgentPrefix {
+ __weak XCTestExpectation *response = [self expectationWithDescription:@"Empty response received."];
+ __weak XCTestExpectation *completion = [self expectationWithDescription:@"Empty RPC completed."];
+
+ GRPCCall *call = [[GRPCCall alloc] initWithHost:kHostAddress
+ path:kEmptyCallMethod.HTTPPath
+ requestsWriter:[GRXWriter writerWithValue:[NSData data]]];
+ // Setting this special key in the header will cause the interop server to echo back the
+ // user-agent value, which we confirm.
+ call.requestHeaders[@"x-grpc-test-echo-useragent"] = @"";
+
+ id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
+ XCTAssertNotNil(value, @"nil value received as response.");
+ XCTAssertEqual([value length], 0, @"Non-empty response received: %@", value);
+ XCTAssertEqualObjects(call.responseHeaders[@"x-grpc-test-echo-useragent"],
+ @"Foo grpc-objc/0.13.0 grpc-c/0.14.0-dev (ios)",
+ @"Did not receive expected user agent %@",
+ call.responseHeaders[@"x-grpc-test-echo-useragent"]);
+ [response fulfill];
+ } completionHandler:^(NSError *errorOrNil) {
+ XCTAssertNil(errorOrNil, @"Finished with unexpected error: %@", errorOrNil);
+ [completion fulfill];
+ }];
+
+ [call startWithWriteable:responsesWriteable];
+
+ [self waitForExpectationsWithTimeout:8 handler:nil];
+}
+
// TODO(makarandd): Move to a different file that contains only unit tests
- (void)testExceptions {
// Try to set userAgentPrefix for host that is nil. This should cause
diff --git a/src/php/README.md b/src/php/README.md
index b1823b9226..b368482f06 100644
--- a/src/php/README.md
+++ b/src/php/README.md
@@ -33,45 +33,12 @@ $ sudo mv phpunit.phar /usr/local/bin/phpunit
## Quick Install
-**Linux (Debian):**
-
-Add [Debian jessie-backports][] to your `sources.list` file. Example:
-
-```sh
-echo "deb http://http.debian.net/debian jessie-backports main" | \
-sudo tee -a /etc/apt/sources.list
-```
-
-Install the gRPC Debian package
-
-```sh
-sudo apt-get update
-sudo apt-get install libgrpc-dev
-```
-
Install the gRPC PHP extension
```sh
sudo pecl install grpc-beta
```
-**Mac OS X:**
-
-Install [homebrew][]. Example:
-
-```sh
-ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
-```
-
-Install the gRPC core library and the PHP extension in one step
-
-```sh
-$ curl -fsSL https://goo.gl/getgrpc | bash -s php
-```
-
-This will download and run the [gRPC install script][] and compile the gRPC PHP extension.
-
-
## Build from Source
Clone this repository
@@ -297,7 +264,4 @@ Connect to `localhost/math_client.php` in your browser, or run this from command
$ curl localhost/math_client.php
```
-[homebrew]:http://brew.sh
-[gRPC install script]:https://raw.githubusercontent.com/grpc/homebrew-grpc/master/scripts/install
[Node]:https://github.com/grpc/grpc/tree/master/src/node/examples
-[Debian jessie-backports]:http://backports.debian.org/Instructions/
diff --git a/src/proto/grpc/health/v1alpha/health.proto b/src/proto/grpc/health/v1/health.proto
index 05f837dd99..6e27606d1b 100644
--- a/src/proto/grpc/health/v1alpha/health.proto
+++ b/src/proto/grpc/health/v1/health.proto
@@ -29,12 +29,11 @@
syntax = "proto3";
-package grpc.health.v1alpha;
-option csharp_namespace = "Grpc.Health.V1Alpha";
+package grpc.health.v1;
+option csharp_namespace = "Grpc.Health.V1";
message HealthCheckRequest {
- string host = 1;
- string service = 2;
+ string service = 1;
}
message HealthCheckResponse {
diff --git a/src/python/grpcio/README.rst b/src/python/grpcio/README.rst
index 698c760ebe..f3e962c197 100644
--- a/src/python/grpcio/README.rst
+++ b/src/python/grpcio/README.rst
@@ -38,3 +38,17 @@ package named `python-dev`).
Note that `$REPO_ROOT` can be assigned to whatever directory name floats your
fancy.
+
+Troubleshooting
+~~~~~~~~~~~~~~~
+
+Help, I ...
+
+* **... see a** :code:`pkg_resources.VersionConflict` **when I try to install
+ grpc!**
+
+ This is likely because :code:`pip` doesn't own the offending dependency,
+ which in turn is likely because your operating system's package manager owns
+ it. You'll need to force the installation of the dependency:
+
+ :code:`pip install --ignore-installed $OFFENDING_DEPENDENCY`
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
index ac67f32d92..1f1833d5ec 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -89,12 +89,13 @@ cdef class Channel:
def check_connectivity_state(self, bint try_to_connect):
return grpc_channel_check_connectivity_state(self.c_channel,
- try_to_connect)
+ try_to_connect)
def watch_connectivity_state(
- self, last_observed_state, Timespec deadline not None,
- CompletionQueue queue not None, tag):
+ self, grpc_connectivity_state last_observed_state,
+ Timespec deadline not None, CompletionQueue queue not None, tag):
cdef OperationTag operation_tag = OperationTag(tag)
+ operation_tag.references = [self, queue]
cpython.Py_INCREF(operation_tag)
grpc_channel_watch_connectivity_state(
self.c_channel, last_observed_state, deadline.c_time,
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pxd.pxi
index 757f1245e8..305475c006 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pxd.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pxd.pxi
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,9 @@
cdef class CompletionQueue:
cdef grpc_completion_queue *c_completion_queue
- cdef object poll_condition
- cdef bint is_polling
+ cdef object pluck_condition
+ cdef int num_plucking
+ cdef int num_polling
cdef bint is_shutting_down
cdef bint is_shutdown
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi
index bbf8413299..c139147114 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -39,8 +39,9 @@ cdef class CompletionQueue:
self.c_completion_queue = grpc_completion_queue_create(NULL)
self.is_shutting_down = False
self.is_shutdown = False
- self.poll_condition = threading.Condition()
- self.is_polling = False
+ self.pluck_condition = threading.Condition()
+ self.num_plucking = 0
+ self.num_polling = 0
cdef _interpret_event(self, grpc_event event):
cdef OperationTag tag = None
@@ -87,19 +88,15 @@ cdef class CompletionQueue:
c_deadline = deadline.c_time
cdef grpc_event event
- # Poll within a critical section
- # TODO(atash) consider making queue polling contention a hard error to
- # enable easier bug discovery
- with self.poll_condition:
- while self.is_polling:
- self.poll_condition.wait(float(deadline) - time.time())
- self.is_polling = True
+ # Poll within a critical section to detect contention
+ with self.pluck_condition:
+ assert self.num_plucking == 0, 'cannot simultaneously pluck and poll'
+ self.num_polling += 1
with nogil:
event = grpc_completion_queue_next(
self.c_completion_queue, c_deadline, NULL)
- with self.poll_condition:
- self.is_polling = False
- self.poll_condition.notify()
+ with self.pluck_condition:
+ self.num_polling -= 1
return self._interpret_event(event)
def pluck(self, OperationTag tag, Timespec deadline=None):
@@ -111,19 +108,18 @@ cdef class CompletionQueue:
c_deadline = deadline.c_time
cdef grpc_event event
- # Poll within a critical section
- # TODO(atash) consider making queue polling contention a hard error to
- # enable easier bug discovery
- with self.poll_condition:
- while self.is_polling:
- self.poll_condition.wait(float(deadline) - time.time())
- self.is_polling = True
+ # Pluck within a critical section to detect contention
+ with self.pluck_condition:
+ assert self.num_polling == 0, 'cannot simultaneously pluck and poll'
+ assert self.num_plucking < GRPC_MAX_COMPLETION_QUEUE_PLUCKERS, (
+ 'cannot pluck more than {} times simultaneously'.format(
+ GRPC_MAX_COMPLETION_QUEUE_PLUCKERS))
+ self.num_plucking += 1
with nogil:
event = grpc_completion_queue_pluck(
self.c_completion_queue, <cpython.PyObject *>tag, c_deadline, NULL)
- with self.poll_condition:
- self.is_polling = False
- self.poll_condition.notify()
+ with self.pluck_condition:
+ self.num_plucking -= 1
return self._interpret_event(event)
def shutdown(self):
@@ -137,10 +133,14 @@ cdef class CompletionQueue:
pass
def __dealloc__(self):
+ cdef gpr_timespec c_deadline = gpr_inf_future(GPR_CLOCK_REALTIME)
if self.c_completion_queue != NULL:
- # Ensure shutdown, pump the queue
+ # Ensure shutdown
if not self.is_shutting_down:
- self.shutdown()
+ grpc_completion_queue_shutdown(self.c_completion_queue)
+ # Pump the queue
while not self.is_shutdown:
- self.poll()
+ event = grpc_completion_queue_next(
+ self.c_completion_queue, c_deadline, NULL)
+ self._interpret_event(event)
grpc_completion_queue_destroy(self.c_completion_queue)
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
index 800d0ea2f6..dbf0045710 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
@@ -138,6 +138,8 @@ cdef extern from "grpc/_cython/loader.h":
const int GRPC_WRITE_NO_COMPRESS
const int GRPC_WRITE_USED_MASK
+ const int GRPC_MAX_COMPLETION_QUEUE_PLUCKERS
+
ctypedef struct grpc_completion_queue:
# We don't care about the internals (and in fact don't know them)
pass
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pxd.pxi
index 9db49e4d30..a344230be4 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pxd.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pxd.pxi
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -39,4 +39,5 @@ cdef class Server:
cdef list references
cdef list registered_completion_queues
+ cdef _c_shutdown(self, CompletionQueue queue, tag)
cdef notify_shutdown_complete(self)
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
index 8b65935c3b..fe93da6c12 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -102,6 +102,16 @@ cdef class Server:
else:
return grpc_server_add_insecure_http2_port(self.c_server, address)
+ cdef _c_shutdown(self, CompletionQueue queue, tag):
+ self.is_shutting_down = True
+ operation_tag = OperationTag(tag)
+ operation_tag.shutting_down_server = self
+ operation_tag.references.extend([self, queue])
+ cpython.Py_INCREF(operation_tag)
+ grpc_server_shutdown_and_notify(
+ self.c_server, queue.c_completion_queue,
+ <cpython.PyObject *>operation_tag)
+
def shutdown(self, CompletionQueue queue not None, tag):
cdef OperationTag operation_tag
if queue.is_shutting_down:
@@ -113,14 +123,7 @@ cdef class Server:
elif queue not in self.registered_completion_queues:
raise ValueError("expected registered completion queue")
else:
- self.is_shutting_down = True
- operation_tag = OperationTag(tag)
- operation_tag.shutting_down_server = self
- operation_tag.references.extend([self, queue])
- cpython.Py_INCREF(operation_tag)
- grpc_server_shutdown_and_notify(
- self.c_server, queue.c_completion_queue,
- <cpython.PyObject *>operation_tag)
+ self._c_shutdown(queue, tag)
cdef notify_shutdown_complete(self):
# called only by a completion queue on receiving our shutdown operation tag
@@ -142,7 +145,7 @@ cdef class Server:
pass
elif not self.is_shutting_down:
# the user didn't call shutdown - use our backup queue
- self.shutdown(self.backup_shutdown_queue, None)
+ self._c_shutdown(self.backup_shutdown_queue, None)
# and now we wait
while not self.is_shutdown:
self.backup_shutdown_queue.poll()
diff --git a/src/python/grpcio/grpc/_cython/imports.generated.c b/src/python/grpcio/grpc/_cython/imports.generated.c
index 4b1860ce8c..8bd6ae6372 100644
--- a/src/python/grpcio/grpc/_cython/imports.generated.c
+++ b/src/python/grpcio/grpc/_cython/imports.generated.c
@@ -220,6 +220,7 @@ gpr_event_get_type gpr_event_get_import;
gpr_event_wait_type gpr_event_wait_import;
gpr_ref_init_type gpr_ref_init_import;
gpr_ref_type gpr_ref_import;
+gpr_ref_non_zero_type gpr_ref_non_zero_import;
gpr_refn_type gpr_refn_import;
gpr_unref_type gpr_unref_import;
gpr_stats_init_type gpr_stats_init_import;
@@ -485,6 +486,7 @@ void pygrpc_load_imports(HMODULE library) {
gpr_event_wait_import = (gpr_event_wait_type) GetProcAddress(library, "gpr_event_wait");
gpr_ref_init_import = (gpr_ref_init_type) GetProcAddress(library, "gpr_ref_init");
gpr_ref_import = (gpr_ref_type) GetProcAddress(library, "gpr_ref");
+ gpr_ref_non_zero_import = (gpr_ref_non_zero_type) GetProcAddress(library, "gpr_ref_non_zero");
gpr_refn_import = (gpr_refn_type) GetProcAddress(library, "gpr_refn");
gpr_unref_import = (gpr_unref_type) GetProcAddress(library, "gpr_unref");
gpr_stats_init_import = (gpr_stats_init_type) GetProcAddress(library, "gpr_stats_init");
diff --git a/src/python/grpcio/grpc/_cython/imports.generated.h b/src/python/grpcio/grpc/_cython/imports.generated.h
index ca30742abc..b70dcccd17 100644
--- a/src/python/grpcio/grpc/_cython/imports.generated.h
+++ b/src/python/grpcio/grpc/_cython/imports.generated.h
@@ -91,10 +91,10 @@ extern census_context_next_tag_type census_context_next_tag_import;
typedef int(*census_context_get_tag_type)(const census_context *context, const char *key, census_tag *tag);
extern census_context_get_tag_type census_context_get_tag_import;
#define census_context_get_tag census_context_get_tag_import
-typedef char *(*census_context_encode_type)(const census_context *context, char *buffer, size_t buf_size, size_t *print_buf_size, size_t *bin_buf_size);
+typedef size_t(*census_context_encode_type)(const census_context *context, char *buffer, size_t buf_size);
extern census_context_encode_type census_context_encode_import;
#define census_context_encode census_context_encode_import
-typedef census_context *(*census_context_decode_type)(const char *buffer, size_t size, const char *bin_buffer, size_t bin_size);
+typedef census_context *(*census_context_decode_type)(const char *buffer, size_t size);
extern census_context_decode_type census_context_decode_import;
#define census_context_decode census_context_decode_import
typedef int(*census_trace_mask_type)(const census_context *context);
@@ -610,6 +610,9 @@ extern gpr_ref_init_type gpr_ref_init_import;
typedef void(*gpr_ref_type)(gpr_refcount *r);
extern gpr_ref_type gpr_ref_import;
#define gpr_ref gpr_ref_import
+typedef void(*gpr_ref_non_zero_type)(gpr_refcount *r);
+extern gpr_ref_non_zero_type gpr_ref_non_zero_import;
+#define gpr_ref_non_zero gpr_ref_non_zero_import
typedef void(*gpr_refn_type)(gpr_refcount *r, int n);
extern gpr_refn_type gpr_refn_import;
#define gpr_refn gpr_refn_import
diff --git a/src/python/grpcio_health_checking/grpc/health/v1alpha/__init__.py b/src/python/grpcio_health_checking/grpc/health/v1/__init__.py
index 7086519106..13aac79160 100644
--- a/src/python/grpcio_health_checking/grpc/health/v1alpha/__init__.py
+++ b/src/python/grpcio_health_checking/grpc/health/v1/__init__.py
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
diff --git a/src/python/grpcio_health_checking/grpc/health/v1alpha/health.proto b/src/python/grpcio_health_checking/grpc/health/v1/health.proto
index 57f4aaa9c0..de10719b6c 100644
--- a/src/python/grpcio_health_checking/grpc/health/v1alpha/health.proto
+++ b/src/python/grpcio_health_checking/grpc/health/v1/health.proto
@@ -1,4 +1,4 @@
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -29,7 +29,7 @@
syntax = "proto3";
-package grpc.health.v1alpha;
+package grpc.health.v1;
message HealthCheckRequest {
string service = 1;
diff --git a/src/python/grpcio_health_checking/grpc/health/v1alpha/health.py b/src/python/grpcio_health_checking/grpc/health/v1/health.py
index 9dfcd962f0..60cbd64433 100644
--- a/src/python/grpcio_health_checking/grpc/health/v1alpha/health.py
+++ b/src/python/grpcio_health_checking/grpc/health/v1/health.py
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -33,7 +33,7 @@ import abc
import enum
import threading
-from grpc.health.v1alpha import health_pb2
+from grpc.health.v1 import health_pb2
@enum.unique
@@ -64,7 +64,7 @@ class _HealthServicer(health_pb2.EarlyAdopterHealthServicer):
def set(service, status):
if not isinstance(status, HealthStatus):
- raise TypeError('expected grpc.health.v1alpha.health.HealthStatus '
+ raise TypeError('expected grpc.health.v1.health.HealthStatus '
'for argument `status` but got {}'.format(status))
with self._server_status_lock:
self._server_status[service] = status
diff --git a/src/ruby/.rubocop.yml b/src/ruby/.rubocop.yml
index dd57ab6082..ff5cf8db83 100644
--- a/src/ruby/.rubocop.yml
+++ b/src/ruby/.rubocop.yml
@@ -7,7 +7,7 @@ AllCops:
- 'bin/apis/**/*'
- 'bin/math.rb'
- 'bin/math_services.rb'
- - 'pb/grpc/health/v1alpha/*'
+ - 'pb/grpc/health/v1/*'
- 'pb/test/**/*'
Metrics/CyclomaticComplexity:
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c
index 1af34d97fb..56db4ec686 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c
@@ -220,6 +220,7 @@ gpr_event_get_type gpr_event_get_import;
gpr_event_wait_type gpr_event_wait_import;
gpr_ref_init_type gpr_ref_init_import;
gpr_ref_type gpr_ref_import;
+gpr_ref_non_zero_type gpr_ref_non_zero_import;
gpr_refn_type gpr_refn_import;
gpr_unref_type gpr_unref_import;
gpr_stats_init_type gpr_stats_init_import;
@@ -481,6 +482,7 @@ void grpc_rb_load_imports(HMODULE library) {
gpr_event_wait_import = (gpr_event_wait_type) GetProcAddress(library, "gpr_event_wait");
gpr_ref_init_import = (gpr_ref_init_type) GetProcAddress(library, "gpr_ref_init");
gpr_ref_import = (gpr_ref_type) GetProcAddress(library, "gpr_ref");
+ gpr_ref_non_zero_import = (gpr_ref_non_zero_type) GetProcAddress(library, "gpr_ref_non_zero");
gpr_refn_import = (gpr_refn_type) GetProcAddress(library, "gpr_refn");
gpr_unref_import = (gpr_unref_type) GetProcAddress(library, "gpr_unref");
gpr_stats_init_import = (gpr_stats_init_type) GetProcAddress(library, "gpr_stats_init");
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
index b61c5282b6..b972f60fc3 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
@@ -91,10 +91,10 @@ extern census_context_next_tag_type census_context_next_tag_import;
typedef int(*census_context_get_tag_type)(const census_context *context, const char *key, census_tag *tag);
extern census_context_get_tag_type census_context_get_tag_import;
#define census_context_get_tag census_context_get_tag_import
-typedef char *(*census_context_encode_type)(const census_context *context, char *buffer, size_t buf_size, size_t *print_buf_size, size_t *bin_buf_size);
+typedef size_t(*census_context_encode_type)(const census_context *context, char *buffer, size_t buf_size);
extern census_context_encode_type census_context_encode_import;
#define census_context_encode census_context_encode_import
-typedef census_context *(*census_context_decode_type)(const char *buffer, size_t size, const char *bin_buffer, size_t bin_size);
+typedef census_context *(*census_context_decode_type)(const char *buffer, size_t size);
extern census_context_decode_type census_context_decode_import;
#define census_context_decode census_context_decode_import
typedef int(*census_trace_mask_type)(const census_context *context);
@@ -610,6 +610,9 @@ extern gpr_ref_init_type gpr_ref_init_import;
typedef void(*gpr_ref_type)(gpr_refcount *r);
extern gpr_ref_type gpr_ref_import;
#define gpr_ref gpr_ref_import
+typedef void(*gpr_ref_non_zero_type)(gpr_refcount *r);
+extern gpr_ref_non_zero_type gpr_ref_non_zero_import;
+#define gpr_ref_non_zero gpr_ref_non_zero_import
typedef void(*gpr_refn_type)(gpr_refcount *r, int n);
extern gpr_refn_type gpr_refn_import;
#define gpr_refn gpr_refn_import
diff --git a/src/ruby/pb/README.md b/src/ruby/pb/README.md
index e04aef185c..d9e30bbc85 100644
--- a/src/ruby/pb/README.md
+++ b/src/ruby/pb/README.md
@@ -11,7 +11,7 @@ The code is is generated using the protoc (> 3.0.0.alpha.1) and the
grpc_ruby_plugin. These must be installed to regenerate the IDL defined
classes, but that's not necessary just to use them.
-health_check/v1alpha
+health_check/v1
--------------------
This package defines the surface of a simple health check service that gRPC
@@ -20,7 +20,7 @@ re-generate the surface.
```bash
$ # (from this directory)
-$ protoc -I ../../proto ../../proto/grpc/health/v1alpha/health.proto \
+$ protoc -I ../../proto ../../proto/grpc/health/v1/health.proto \
--grpc_out=. \
--ruby_out=. \
--plugin=protoc-gen-grpc=`which grpc_ruby_plugin`
diff --git a/src/ruby/pb/generate_proto_ruby.sh b/src/ruby/pb/generate_proto_ruby.sh
index 576b1c08d3..86c082099d 100755
--- a/src/ruby/pb/generate_proto_ruby.sh
+++ b/src/ruby/pb/generate_proto_ruby.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -35,7 +35,7 @@ cd $(dirname $0)/../../..
PROTOC=bins/opt/protobuf/protoc
PLUGIN=protoc-gen-grpc=bins/opt/grpc_ruby_plugin
-$PROTOC -I src/proto src/proto/grpc/health/v1alpha/health.proto \
+$PROTOC -I src/proto src/proto/grpc/health/v1/health.proto \
--grpc_out=src/ruby/pb \
--ruby_out=src/ruby/pb \
--plugin=$PLUGIN
diff --git a/src/ruby/pb/grpc/health/checker.rb b/src/ruby/pb/grpc/health/checker.rb
index 8c692e74f9..9f1ee65c41 100644
--- a/src/ruby/pb/grpc/health/checker.rb
+++ b/src/ruby/pb/grpc/health/checker.rb
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -28,7 +28,7 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
require 'grpc'
-require 'grpc/health/v1alpha/health_services'
+require 'grpc/health/v1/health_services'
require 'thread'
module Grpc
@@ -36,9 +36,9 @@ module Grpc
# service.
module Health
# Checker is implementation of the schema-specified health checking service.
- class Checker < V1alpha::Health::Service
+ class Checker < V1::Health::Service
StatusCodes = GRPC::Core::StatusCodes
- HealthCheckResponse = V1alpha::HealthCheckResponse
+ HealthCheckResponse = V1::HealthCheckResponse
# Initializes the statuses of participating services
def initialize
@@ -50,20 +50,20 @@ module Grpc
def check(req, _call)
status = nil
@status_mutex.synchronize do
- status = @statuses["#{req.host}/#{req.service}"]
+ status = @statuses["#{req.service}"]
end
fail GRPC::BadStatus, StatusCodes::NOT_FOUND if status.nil?
HealthCheckResponse.new(status: status)
end
- # Adds the health status for a given host and service.
- def add_status(host, service, status)
- @status_mutex.synchronize { @statuses["#{host}/#{service}"] = status }
+ # Adds the health status for a given service.
+ def add_status(service, status)
+ @status_mutex.synchronize { @statuses["#{service}"] = status }
end
- # Clears the status for the given host or service.
- def clear_status(host, service)
- @status_mutex.synchronize { @statuses.delete("#{host}/#{service}") }
+ # Clears the status for the given service.
+ def clear_status(service)
+ @status_mutex.synchronize { @statuses.delete("#{service}") }
end
# Clears alls the statuses.
diff --git a/src/ruby/pb/grpc/health/v1/health.rb b/src/ruby/pb/grpc/health/v1/health.rb
new file mode 100644
index 0000000000..aa87a93918
--- /dev/null
+++ b/src/ruby/pb/grpc/health/v1/health.rb
@@ -0,0 +1,28 @@
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: grpc/health/v1/health.proto
+
+require 'google/protobuf'
+
+Google::Protobuf::DescriptorPool.generated_pool.build do
+ add_message "grpc.health.v1.HealthCheckRequest" do
+ optional :service, :string, 1
+ end
+ add_message "grpc.health.v1.HealthCheckResponse" do
+ optional :status, :enum, 1, "grpc.health.v1.HealthCheckResponse.ServingStatus"
+ end
+ add_enum "grpc.health.v1.HealthCheckResponse.ServingStatus" do
+ value :UNKNOWN, 0
+ value :SERVING, 1
+ value :NOT_SERVING, 2
+ end
+end
+
+module Grpc
+ module Health
+ module V1
+ HealthCheckRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.health.v1.HealthCheckRequest").msgclass
+ HealthCheckResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.health.v1.HealthCheckResponse").msgclass
+ HealthCheckResponse::ServingStatus = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.health.v1.HealthCheckResponse.ServingStatus").enummodule
+ end
+ end
+end
diff --git a/src/ruby/pb/grpc/health/v1alpha/health_services.rb b/src/ruby/pb/grpc/health/v1/health_services.rb
index d5cba2e9ec..cb79b20437 100644
--- a/src/ruby/pb/grpc/health/v1alpha/health_services.rb
+++ b/src/ruby/pb/grpc/health/v1/health_services.rb
@@ -1,12 +1,12 @@
# Generated by the protocol buffer compiler. DO NOT EDIT!
-# Source: grpc/health/v1alpha/health.proto for package 'grpc.health.v1alpha'
+# Source: grpc/health/v1/health.proto for package 'grpc.health.v1'
require 'grpc'
-require 'grpc/health/v1alpha/health'
+require 'grpc/health/v1/health'
module Grpc
module Health
- module V1alpha
+ module V1
module Health
# TODO: add proto service documentation here
@@ -16,7 +16,7 @@ module Grpc
self.marshal_class_method = :encode
self.unmarshal_class_method = :decode
- self.service_name = 'grpc.health.v1alpha.Health'
+ self.service_name = 'grpc.health.v1.Health'
rpc :Check, HealthCheckRequest, HealthCheckResponse
end
diff --git a/src/ruby/pb/grpc/health/v1alpha/health.rb b/src/ruby/pb/grpc/health/v1alpha/health.rb
deleted file mode 100644
index 9c04298ea5..0000000000
--- a/src/ruby/pb/grpc/health/v1alpha/health.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-# Generated by the protocol buffer compiler. DO NOT EDIT!
-# source: grpc/health/v1alpha/health.proto
-
-require 'google/protobuf'
-
-Google::Protobuf::DescriptorPool.generated_pool.build do
- add_message "grpc.health.v1alpha.HealthCheckRequest" do
- optional :host, :string, 1
- optional :service, :string, 2
- end
- add_message "grpc.health.v1alpha.HealthCheckResponse" do
- optional :status, :enum, 1, "grpc.health.v1alpha.HealthCheckResponse.ServingStatus"
- end
- add_enum "grpc.health.v1alpha.HealthCheckResponse.ServingStatus" do
- value :UNKNOWN, 0
- value :SERVING, 1
- value :NOT_SERVING, 2
- end
-end
-
-module Grpc
- module Health
- module V1alpha
- HealthCheckRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.health.v1alpha.HealthCheckRequest").msgclass
- HealthCheckResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.health.v1alpha.HealthCheckResponse").msgclass
- HealthCheckResponse::ServingStatus = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.health.v1alpha.HealthCheckResponse.ServingStatus").enummodule
- end
- end
-end
diff --git a/src/ruby/spec/pb/health/checker_spec.rb b/src/ruby/spec/pb/health/checker_spec.rb
index c1decd822a..9bb79bb4ca 100644
--- a/src/ruby/spec/pb/health/checker_spec.rb
+++ b/src/ruby/spec/pb/health/checker_spec.rb
@@ -28,7 +28,7 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
require 'grpc'
-require 'grpc/health/v1alpha/health'
+require 'grpc/health/v1/health'
require 'grpc/health/checker'
require 'open3'
require 'tmpdir'
@@ -43,7 +43,7 @@ describe 'Health protobuf code generation' do
skip 'protoc || grpc_ruby_plugin missing, cannot verify health code-gen'
else
it 'should already be loaded indirectly i.e, used by the other specs' do
- expect(require('grpc/health/v1alpha/health_services')).to be(false)
+ expect(require('grpc/health/v1/health_services')).to be(false)
end
it 'should have the same content as created by code generation' do
@@ -52,7 +52,7 @@ describe 'Health protobuf code generation' do
# Get the current content
service_path = File.join(root_dir, 'ruby', 'pb', 'grpc',
- 'health', 'v1alpha', 'health_services.rb')
+ 'health', 'v1', 'health_services.rb')
want = nil
File.open(service_path) { |f| want = f.read }
@@ -61,12 +61,12 @@ describe 'Health protobuf code generation' do
plugin = plugin.strip
got = nil
Dir.mktmpdir do |tmp_dir|
- gen_out = File.join(tmp_dir, 'grpc', 'health', 'v1alpha',
+ gen_out = File.join(tmp_dir, 'grpc', 'health', 'v1',
'health_services.rb')
pid = spawn(
'protoc',
'-I.',
- 'grpc/health/v1alpha/health.proto',
+ 'grpc/health/v1/health.proto',
"--grpc_out=#{tmp_dir}",
"--plugin=protoc-gen-grpc=#{plugin}",
chdir: pb_dir)
@@ -81,27 +81,17 @@ end
describe Grpc::Health::Checker do
StatusCodes = GRPC::Core::StatusCodes
- ServingStatus = Grpc::Health::V1alpha::HealthCheckResponse::ServingStatus
- HCResp = Grpc::Health::V1alpha::HealthCheckResponse
- HCReq = Grpc::Health::V1alpha::HealthCheckRequest
+ ServingStatus = Grpc::Health::V1::HealthCheckResponse::ServingStatus
+ HCResp = Grpc::Health::V1::HealthCheckResponse
+ HCReq = Grpc::Health::V1::HealthCheckRequest
success_tests =
[
{
- desc: 'neither host or service are specified',
- host: '',
+ desc: 'the service is not specified',
service: ''
}, {
- desc: 'only the host is specified',
- host: 'test-fake-host',
- service: ''
- }, {
- desc: 'the host and service are specified',
- host: 'test-fake-host',
+ desc: 'the service is specified',
service: 'fake-service-1'
- }, {
- desc: 'only the service is specified',
- host: '',
- service: 'fake-service-2'
}
]
@@ -114,9 +104,8 @@ describe Grpc::Health::Checker do
context 'method `add_status` and `check`' do
success_tests.each do |t|
it "should succeed when #{t[:desc]}" do
- subject.add_status(t[:host], t[:service], ServingStatus::NOT_SERVING)
- got = subject.check(HCReq.new(host: t[:host], service: t[:service]),
- nil)
+ subject.add_status(t[:service], ServingStatus::NOT_SERVING)
+ got = subject.check(HCReq.new(service: t[:service]), nil)
want = HCResp.new(status: ServingStatus::NOT_SERVING)
expect(got).to eq(want)
end
@@ -127,7 +116,7 @@ describe Grpc::Health::Checker do
success_tests.each do |t|
it "should fail with NOT_FOUND when #{t[:desc]}" do
blk = proc do
- subject.check(HCReq.new(host: t[:host], service: t[:service]), nil)
+ subject.check(HCReq.new(service: t[:service]), nil)
end
expected_msg = /#{StatusCodes::NOT_FOUND}/
expect(&blk).to raise_error GRPC::BadStatus, expected_msg
@@ -138,16 +127,14 @@ describe Grpc::Health::Checker do
context 'method `clear_status`' do
success_tests.each do |t|
it "should fail after clearing status when #{t[:desc]}" do
- subject.add_status(t[:host], t[:service], ServingStatus::NOT_SERVING)
- got = subject.check(HCReq.new(host: t[:host], service: t[:service]),
- nil)
+ subject.add_status(t[:service], ServingStatus::NOT_SERVING)
+ got = subject.check(HCReq.new(service: t[:service]), nil)
want = HCResp.new(status: ServingStatus::NOT_SERVING)
expect(got).to eq(want)
- subject.clear_status(t[:host], t[:service])
+ subject.clear_status(t[:service])
blk = proc do
- subject.check(HCReq.new(host: t[:host], service: t[:service]),
- nil)
+ subject.check(HCReq.new(service: t[:service]), nil)
end
expected_msg = /#{StatusCodes::NOT_FOUND}/
expect(&blk).to raise_error GRPC::BadStatus, expected_msg
@@ -158,9 +145,8 @@ describe Grpc::Health::Checker do
context 'method `clear_all`' do
it 'should return NOT_FOUND after being invoked' do
success_tests.each do |t|
- subject.add_status(t[:host], t[:service], ServingStatus::NOT_SERVING)
- got = subject.check(HCReq.new(host: t[:host], service: t[:service]),
- nil)
+ subject.add_status(t[:service], ServingStatus::NOT_SERVING)
+ got = subject.check(HCReq.new(service: t[:service]), nil)
want = HCResp.new(status: ServingStatus::NOT_SERVING)
expect(got).to eq(want)
end
@@ -169,7 +155,7 @@ describe Grpc::Health::Checker do
success_tests.each do |t|
blk = proc do
- subject.check(HCReq.new(host: t[:host], service: t[:service]), nil)
+ subject.check(HCReq.new(service: t[:service]), nil)
end
expected_msg = /#{StatusCodes::NOT_FOUND}/
expect(&blk).to raise_error GRPC::BadStatus, expected_msg
@@ -203,7 +189,7 @@ describe Grpc::Health::Checker do
it 'should receive the correct status', server: true do
@srv.handle(subject)
- subject.add_status('', '', ServingStatus::NOT_SERVING)
+ subject.add_status('', ServingStatus::NOT_SERVING)
t = Thread.new { @srv.run }
@srv.wait_till_running
@@ -221,7 +207,7 @@ describe Grpc::Health::Checker do
@srv.wait_till_running
blk = proc do
stub = CheckerStub.new(@host, :this_channel_is_insecure, **@client_opts)
- stub.check(HCReq.new(host: 'unknown', service: 'unknown'))
+ stub.check(HCReq.new(service: 'unknown'))
end
expected_msg = /#{StatusCodes::NOT_FOUND}/
expect(&blk).to raise_error GRPC::BadStatus, expected_msg
diff --git a/templates/README.md b/templates/README.md
index 6740972cfb..eedc6e9c09 100644
--- a/templates/README.md
+++ b/templates/README.md
@@ -6,78 +6,92 @@ was going to single handedly cover all of our usage cases.
So instead we decided to work the following way:
-* A build.json file at the root is the source of truth for listing all of the
-target and files needed to build grpc and its tests, as well as basic system
-dependencies description.
+* A `build.yaml` file at the root is the source of truth for listing all the
+targets and files needed to build grpc and its tests, as well as a basic system
+for dependency description.
* Each project file (Makefile, Visual Studio project files, Bazel's BUILD) is
-a plain-text template that uses the build.json file to generate the final
-output file.
+a [YAML](http://yaml.org) file used by the `build.yaml` file to generate the
+final output file.
This way we can maintain as many project system as we see fit, without having
to manually maintain them when we add or remove new code to the repository.
Only the structure of the project file is relevant to the template. The actual
list of source code and targets isn't.
-We currently have template files for GNU Make, Visual Studio 2010 to 2015,
-and Bazel. In the future, we would like to expand to generating gyp or cmake
-project files (or potentially both), XCode project files, and an Android.mk
-file to be able to compile gRPC using Android's NDK.
+We currently have template files for GNU Make, Visual Studio 2013,
+[Bazel](http://bazel.io) and [gyp](https://gyp.gsrc.io/) (albeit only for
+Node.js). In the future, we
+would like to expand to also generate [cmake](https://cmake.org)
+project files, XCode project files, and an Android.mk file allowing to compile
+gRPC using Android's NDK.
We'll gladly accept contribution that'd create additional project files
using that system.
-# Structure of build.json
+# Structure of `build.yaml`
-The build.json file has the following structure:
+The `build.yaml` file has the following structure:
```
-{
- "settings": { ... }, # global settings, such as version number
- "filegroups": [ ... ], # groups of file that is automatically expanded
- "libs": [ ... ], # list of libraries to build
- "targets": [ ... ], # list of targets to build
-}
+settings: # global settings, such as version number
+ ...
+filegroups: # groups of files that are automatically expanded
+ ...
+libs: # list of libraries to build
+ ...
+target: # list of targets to build
+ ...
```
The `filegroups` are helpful to re-use a subset of files in multiple targets.
One `filegroups` entry has the following structure:
```
-{
- "name": "arbitrary string", # the name of the filegroup
- "public_headers": [ ... ], # list of public headers defined in that filegroup
- "headers": [ ... ], # list of headers defined in that filegroup
- "src": [ ... ], # list of source files defined in that filegroup
-}
+- name: "arbitrary string", # the name of the filegroup
+ public_headers: # list of public headers defined in that filegroup
+ - ...
+ headers: # list of headers defined in that filegroup
+ - ...
+ src: # list of source files defined in that filegroup
+ - ...
```
-The `libs` array contains the list of all the libraries we describe. Some may be
+The `libs` collection contains the list of all the libraries we describe. Some may be
helper libraries for the tests. Some may be installable libraries. Some may be
helper libraries for installable binaries.
The `targets` array contains the list of all the binary targets we describe. Some may
be installable binaries.
-One `libs` or `targets` entry has the following structure:
+One `libs` or `targets` entry has the following structure (see below for
+details):
```
-{
- "name": "arbitrary string", # the name of the library
- "build": "build type", # in which situation we want that library to be
- # built and potentially installed
- "language": "...", # the language tag; "c" or "c++"
- "public_headers": [ ... ], # list of public headers to install
- "headers": [ ... ], # list of headers used by that target
- "src": [ ... ], # list of files to compile
- "secure": "...", # "yes", "no" or "check"
- "baselib": boolean, # this is a low level library that has system
- # dependencies
- "vs_project_guid: "...", # Visual Studio's unique guid for that project
- "filegroups": [ ... ], # list of filegroups to merge to that project
- # note that this will be expanded automatically
- "deps": [ ... ], # list of libraries this target depends on
-}
+name: "arbitrary string", # the name of the library
+build: "build type", # in which situation we want that library to be
+ # built and potentially installed (see below).
+language: "...", # the language tag; "c" or "c++"
+public_headers: # list of public headers to install
+headers: # list of headers used by that target
+src: # list of files to compile
+secure: boolean, # see below
+baselib: boolean, # this is a low level library that has system
+ # dependencies
+vs_project_guid: '{...}', # Visual Studio's unique guid for that project
+filegroups: # list of filegroups to merge to that project
+ # note that this will be expanded automatically
+deps: # list of libraries this target depends on
+deps_linkage: "..." # "static" or "dynamic". Used by the Makefile only to
+ # determine the way dependencies are linkned. Defaults
+ # to "dynamic".
+dll: "..." # see below.
+dll_def: "..." # Visual Studio's dll definition file.
+vs_props: # List of property sheets to attach to that project.
+vs_config_type: "..." # DynamicLibrary/StaticLibrary. Used only when
+ # creating a library. Specifies if we're building a
+ # static library or a dll. Use in conjunction with `dll_def`.
+vs_packages: # List of nuget packages this project depends on.
```
## The `"build"` tag
@@ -86,8 +100,9 @@ Currently, the "`build`" tag have these meanings:
* `"all"`: library to build on `"make all"`, and install on the system.
* `"protoc"`: a protoc plugin to build on `"make all"` and install on the system.
-* `"priviate"`: a library to only build for tests.
+* `"private"`: a library to only build for tests.
* `"test"`: a test binary to run on `"make test"`.
+* `"tool"`: a binary to be built upon `"make tools"`.
All of the targets should always be present in the generated project file, if
possible and applicable. But the build tag is what should group the targets
@@ -111,6 +126,18 @@ should merge OpenSSL, protobuf or zlib inside that library. That effect depends
on the `"language"` tag. OpenSSL and zlib are for `"c"` libraries, while
protobuf is for `"c++"` ones.
+## The `"dll"` tag
+
+Used only by Visual Studio's project files. "true" means the project will be
+built with both static and dynamic runtimes. "false" means it'll only be built
+with static runtime. "only" means it'll only be built with the dll runtime.
+
+## The `"dll_def"` tag
+
+Specifies the visual studio's dll definition file. When creating a DLL, you
+sometimes (not always) need a def file (see grpc.def).
+
+
# The template system
We're currently using the [mako templates](http://www.makotemplates.org/)
diff --git a/templates/config.m4.template b/templates/config.m4.template
index 5e73901efa..5847d456f5 100644
--- a/templates/config.m4.template
+++ b/templates/config.m4.template
@@ -38,7 +38,8 @@
% endfor
% endif
% endfor
- , $ext_shared, , -Wall -Werror -std=c11 ${"\\"}
+ , $ext_shared, , -Wall -Werror ${"\\"}
+ -Wno-parentheses-equality -Wno-unused-value -std=c11 ${"\\"}
-fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN ${"\\"}
-D_HAS_EXCEPTIONS=0 -DNOMINMAX)
diff --git a/templates/package.xml.template b/templates/package.xml.template
index 067c8839d5..d309bfddbc 100644
--- a/templates/package.xml.template
+++ b/templates/package.xml.template
@@ -12,11 +12,11 @@
<email>grpc-packages@google.com</email>
<active>yes</active>
</lead>
- <date>2016-02-24</date>
+ <date>2016-03-01</date>
<time>16:06:07</time>
<version>
- <release>0.8.0</release>
- <api>0.8.0</api>
+ <release>0.14.0</release>
+ <api>0.14.0</api>
</version>
<stability>
<release>beta</release>
@@ -24,7 +24,7 @@
</stability>
<license>BSD</license>
<notes>
- - Simplify gRPC PHP installation #4517
+ - Increase unit test code coverage #5225
</notes>
<contents>
<dir baseinstalldir="/" name="/">
@@ -155,5 +155,20 @@
- Simplify gRPC PHP installation #4517
</notes>
</release>
+ <release>
+ <version>
+ <release>0.14.0</release>
+ <api>0.14.0</api>
+ </version>
+ <stability>
+ <release>beta</release>
+ <api>beta</api>
+ </stability>
+ <date>2016-03-01</date>
+ <license>BSD</license>
+ <notes>
+ - Increase unit test code coverage #5225
+ </notes>
+ </release>
</changelog>
</package>
diff --git a/templates/src/csharp/build_packages.bat.template b/templates/src/csharp/build_packages.bat.template
index b855126ae6..32455683be 100644
--- a/templates/src/csharp/build_packages.bat.template
+++ b/templates/src/csharp/build_packages.bat.template
@@ -21,6 +21,14 @@
xcopy /Y /I ..\..\architecture=x86,language=csharp,platform=macos\artifacts\* grpc.native.csharp\macosx_x86${"\\"}
xcopy /Y /I ..\..\architecture=x64,language=csharp,platform=macos\artifacts\* grpc.native.csharp\macosx_x64${"\\"}
+ @rem Collect protoc artifacts built by the previous build step
+ xcopy /Y /I ..\..\architecture=x86,language=protoc,platform=windows\artifacts\* protoc_plugins\windows_x86${"\\"}
+ xcopy /Y /I ..\..\architecture=x64,language=protoc,platform=windows\artifacts\* protoc_plugins\windows_x64${"\\"}
+ xcopy /Y /I ..\..\architecture=x86,language=protoc,platform=linux\artifacts\* protoc_plugins\linux_x86${"\\"}
+ xcopy /Y /I ..\..\architecture=x64,language=protoc,platform=linux\artifacts\* protoc_plugins\linux_x64${"\\"}
+ xcopy /Y /I ..\..\architecture=x86,language=protoc,platform=macos\artifacts\* protoc_plugins\macosx_x86${"\\"}
+ xcopy /Y /I ..\..\architecture=x64,language=protoc,platform=macos\artifacts\* protoc_plugins\macosx_x64${"\\"}
+
@rem Fetch all dependencies
%%NUGET% restore ..\..\vsprojects\grpc_csharp_ext.sln || goto :error
%%NUGET% restore Grpc.sln || goto :error
@@ -29,24 +37,19 @@
@call "%VS120COMNTOOLS%\..\..\vc\vcvarsall.bat" x86
- @rem We won't use the native libraries from this step, but without this Grpc.sln will fail.
+ @rem We won't use the native libraries from this step, but without this Grpc.sln will fail.
msbuild ..\..\vsprojects\grpc_csharp_ext.sln /p:Configuration=Release /p:PlatformToolset=v120 || goto :error
msbuild Grpc.sln /p:Configuration=ReleaseSigned || goto :error
endlocal
- @rem TODO(jtattermusch): re-enable protoc plugin building
- @rem @call ..\..\vsprojects\build_plugins.bat || goto :error
-
%%NUGET% pack grpc.native.csharp\grpc.native.csharp.nuspec -Version %VERSION% || goto :error
%%NUGET% pack Grpc.Auth\Grpc.Auth.nuspec -Symbols -Version %VERSION% || goto :error
%%NUGET% pack Grpc.Core\Grpc.Core.nuspec -Symbols -Version %VERSION% || goto :error
%%NUGET% pack Grpc.HealthCheck\Grpc.HealthCheck.nuspec -Symbols -Version %VERSION_WITH_BETA% -Properties ProtobufVersion=%PROTOBUF_VERSION% || goto :error
%%NUGET% pack Grpc.nuspec -Version %VERSION% || goto :error
-
- @rem TODO(jtattermusch): re-enable building Grpc.Tools package
- @rem %NUGET% pack Grpc.Tools.nuspec -Version %VERSION% || goto :error
+ %%NUGET% pack Grpc.Tools.nuspec -Version %VERSION% || goto :error
@rem copy resulting nuget packages to artifacts directory
xcopy /Y /I *.nupkg ..\..\artifacts${"\\"}
diff --git a/test/core/census/context_test.c b/test/core/census/context_test.c
index 63e7103ddc..ad4c337465 100644
--- a/test/core/census/context_test.c
+++ b/test/core/census/context_test.c
@@ -42,60 +42,48 @@
#include <string.h>
#include "test/core/util/test_config.h"
-static uint8_t one_byte_val = 7;
-static uint32_t four_byte_val = 0x12345678;
-static uint64_t eight_byte_val = 0x1234567890abcdef;
-
-// A set of tags Used to create a basic context for testing. Each tag has a
-// unique set of flags. Note that replace_add_delete_test() relies on specific
-// offsets into this array - if you add or delete entries, you will also need
-// to change the test.
+// A set of tags Used to create a basic context for testing. Note that
+// replace_add_delete_test() relies on specific offsets into this array - if
+// you add or delete entries, you will also need to change the test.
#define BASIC_TAG_COUNT 8
static census_tag basic_tags[BASIC_TAG_COUNT] = {
- /* 0 */ {"key0", "printable", 10, 0},
- /* 1 */ {"k1", "a", 2, CENSUS_TAG_PROPAGATE},
- /* 2 */ {"k2", "longer printable string", 24, CENSUS_TAG_STATS},
- /* 3 */ {"key_three", (char *)&one_byte_val, 1, CENSUS_TAG_BINARY},
- /* 4 */ {"really_long_key_4", "random", 7,
+ /* 0 */ {"key0", "tag value", 0},
+ /* 1 */ {"k1", "a", CENSUS_TAG_PROPAGATE},
+ /* 2 */ {"k2", "a longer tag value supercalifragilisticexpialiadocious",
+ CENSUS_TAG_STATS},
+ /* 3 */ {"key_three", "", 0},
+ /* 4 */ {"a_really_really_really_really_long_key_4", "random",
CENSUS_TAG_PROPAGATE | CENSUS_TAG_STATS},
- /* 5 */ {"k5", (char *)&four_byte_val, 4,
- CENSUS_TAG_PROPAGATE | CENSUS_TAG_BINARY},
- /* 6 */ {"k6", (char *)&eight_byte_val, 8,
- CENSUS_TAG_STATS | CENSUS_TAG_BINARY},
- /* 7 */ {"k7", (char *)&four_byte_val, 4,
- CENSUS_TAG_PROPAGATE | CENSUS_TAG_STATS | CENSUS_TAG_BINARY}};
+ /* 5 */ {"k5", "v5", CENSUS_TAG_PROPAGATE},
+ /* 6 */ {"k6", "v6", CENSUS_TAG_STATS},
+ /* 7 */ {"k7", "v7", CENSUS_TAG_PROPAGATE | CENSUS_TAG_STATS}};
// Set of tags used to modify the basic context. Note that
// replace_add_delete_test() relies on specific offsets into this array - if
// you add or delete entries, you will also need to change the test. Other
// tests that rely on specific instances have XXX_XXX_OFFSET definitions (also
// change the defines below if you add/delete entires).
-#define MODIFY_TAG_COUNT 11
+#define MODIFY_TAG_COUNT 10
static census_tag modify_tags[MODIFY_TAG_COUNT] = {
#define REPLACE_VALUE_OFFSET 0
- /* 0 */ {"key0", "replace printable", 18, 0}, // replaces tag value only
+ /* 0 */ {"key0", "replace key0", 0}, // replaces tag value only
#define ADD_TAG_OFFSET 1
- /* 1 */ {"new_key", "xyzzy", 6, CENSUS_TAG_STATS}, // new tag
+ /* 1 */ {"new_key", "xyzzy", CENSUS_TAG_STATS}, // new tag
#define DELETE_TAG_OFFSET 2
- /* 2 */ {"k5", NULL, 5,
- 0}, // should delete tag, despite bogus value length
- /* 3 */ {"k6", "foo", 0, 0}, // should delete tag, despite bogus value
- /* 4 */ {"k6", "foo", 0, 0}, // try deleting already-deleted tag
- /* 5 */ {"non-existent", NULL, 0, 0}, // another non-existent tag
-#define REPLACE_FLAG_OFFSET 6
- /* 6 */ {"k1", "a", 2, 0}, // change flags only
- /* 7 */ {"k7", "bar", 4, CENSUS_TAG_STATS}, // change flags and value
- /* 8 */ {"k2", (char *)&eight_byte_val, 8,
- CENSUS_TAG_BINARY | CENSUS_TAG_PROPAGATE}, // more flags change
- // non-binary -> binary
- /* 9 */ {"k6", "bar", 4, 0}, // add back tag, with different value
- /* 10 */ {"foo", "bar", 4, CENSUS_TAG_PROPAGATE}, // another new tag
+ /* 2 */ {"k5", NULL, 0}, // should delete tag
+ /* 3 */ {"k5", NULL, 0}, // try deleting already-deleted tag
+ /* 4 */ {"non-existent", NULL, 0}, // delete non-existent tag
+#define REPLACE_FLAG_OFFSET 5
+ /* 5 */ {"k1", "a", 0}, // change flags only
+ /* 6 */ {"k7", "bar", CENSUS_TAG_STATS}, // change flags and value
+ /* 7 */ {"k2", "", CENSUS_TAG_PROPAGATE}, // more value and flags change
+ /* 8 */ {"k5", "bar", 0}, // add back tag, with different value
+ /* 9 */ {"foo", "bar", CENSUS_TAG_PROPAGATE}, // another new tag
};
// Utility function to compare tags. Returns true if all fields match.
static bool compare_tag(const census_tag *t1, const census_tag *t2) {
- return (strcmp(t1->key, t2->key) == 0 && t1->value_len == t2->value_len &&
- memcmp(t1->value, t2->value, t1->value_len) == 0 &&
+ return (strcmp(t1->key, t2->key) == 0 && strcmp(t1->value, t2->value) == 0 &&
t1->flags == t2->flags);
}
@@ -111,7 +99,7 @@ static void empty_test(void) {
struct census_context *context = census_context_create(NULL, NULL, 0, NULL);
GPR_ASSERT(context != NULL);
const census_context_status *status = census_context_get_status(context);
- census_context_status expected = {0, 0, 0, 0, 0, 0, 0, 0};
+ census_context_status expected = {0, 0, 0, 0, 0, 0, 0};
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
census_context_destroy(context);
}
@@ -121,7 +109,7 @@ static void basic_test(void) {
const census_context_status *status;
struct census_context *context =
census_context_create(NULL, basic_tags, BASIC_TAG_COUNT, &status);
- census_context_status expected = {2, 2, 4, 0, 8, 0, 0, 0};
+ census_context_status expected = {4, 4, 0, 8, 0, 0, 0};
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
census_context_iterator it;
census_context_initialize_iterator(context, &it);
@@ -161,15 +149,18 @@ static void invalid_test(void) {
memset(key, 'k', 299);
key[299] = 0;
char value[300];
- memset(value, 'v', 300);
- census_tag tag = {key, value, 3, CENSUS_TAG_BINARY};
+ memset(value, 'v', 299);
+ value[299] = 0;
+ census_tag tag = {key, value, 0};
// long keys, short value. Key lengths (including terminator) should be
// <= 255 (CENSUS_MAX_TAG_KV_LEN)
+ value[3] = 0;
+ GPR_ASSERT(strlen(value) == 3);
GPR_ASSERT(strlen(key) == 299);
const census_context_status *status;
struct census_context *context =
census_context_create(NULL, &tag, 1, &status);
- census_context_status expected = {0, 0, 0, 0, 0, 0, 1, 0};
+ census_context_status expected = {0, 0, 0, 0, 0, 1, 0};
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
census_context_destroy(context);
key[CENSUS_MAX_TAG_KV_LEN] = 0;
@@ -180,24 +171,44 @@ static void invalid_test(void) {
key[CENSUS_MAX_TAG_KV_LEN - 1] = 0;
GPR_ASSERT(strlen(key) == CENSUS_MAX_TAG_KV_LEN - 1);
context = census_context_create(NULL, &tag, 1, &status);
- census_context_status expected2 = {0, 0, 1, 0, 1, 0, 0, 0};
+ census_context_status expected2 = {0, 1, 0, 1, 0, 0, 0};
GPR_ASSERT(memcmp(status, &expected2, sizeof(expected2)) == 0);
census_context_destroy(context);
// now try with long values
- tag.value_len = 300;
+ value[3] = 'v';
+ GPR_ASSERT(strlen(value) == 299);
context = census_context_create(NULL, &tag, 1, &status);
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
census_context_destroy(context);
- tag.value_len = CENSUS_MAX_TAG_KV_LEN + 1;
+ value[CENSUS_MAX_TAG_KV_LEN] = 0;
+ GPR_ASSERT(strlen(value) == CENSUS_MAX_TAG_KV_LEN);
context = census_context_create(NULL, &tag, 1, &status);
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
census_context_destroy(context);
- tag.value_len = CENSUS_MAX_TAG_KV_LEN;
+ value[CENSUS_MAX_TAG_KV_LEN - 1] = 0;
+ GPR_ASSERT(strlen(value) == CENSUS_MAX_TAG_KV_LEN - 1);
context = census_context_create(NULL, &tag, 1, &status);
GPR_ASSERT(memcmp(status, &expected2, sizeof(expected2)) == 0);
census_context_destroy(context);
// 0 length key.
key[0] = 0;
+ GPR_ASSERT(strlen(key) == 0);
+ context = census_context_create(NULL, &tag, 1, &status);
+ GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
+ census_context_destroy(context);
+ // invalid key character
+ key[0] = 31; // 32 (' ') is the first valid character value
+ key[1] = 0;
+ GPR_ASSERT(strlen(key) == 1);
+ context = census_context_create(NULL, &tag, 1, &status);
+ GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
+ census_context_destroy(context);
+ // invalid value character
+ key[0] = ' ';
+ value[5] = 127; // 127 (DEL) is ('~' + 1)
+ value[8] = 0;
+ GPR_ASSERT(strlen(key) == 1);
+ GPR_ASSERT(strlen(value) == 8);
context = census_context_create(NULL, &tag, 1, &status);
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
census_context_destroy(context);
@@ -210,7 +221,7 @@ static void copy_test(void) {
const census_context_status *status;
struct census_context *context2 =
census_context_create(context, NULL, 0, &status);
- census_context_status expected = {2, 2, 4, 0, 0, 0, 0, 0};
+ census_context_status expected = {4, 4, 0, 0, 0, 0, 0};
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
for (int i = 0; i < BASIC_TAG_COUNT; i++) {
census_tag tag;
@@ -228,7 +239,7 @@ static void replace_value_test(void) {
const census_context_status *status;
struct census_context *context2 = census_context_create(
context, modify_tags + REPLACE_VALUE_OFFSET, 1, &status);
- census_context_status expected = {2, 2, 4, 0, 0, 1, 0, 0};
+ census_context_status expected = {4, 4, 0, 0, 1, 0, 0};
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
census_tag tag;
GPR_ASSERT(census_context_get_tag(
@@ -245,7 +256,7 @@ static void replace_flags_test(void) {
const census_context_status *status;
struct census_context *context2 = census_context_create(
context, modify_tags + REPLACE_FLAG_OFFSET, 1, &status);
- census_context_status expected = {1, 2, 5, 0, 0, 1, 0, 0};
+ census_context_status expected = {3, 5, 0, 0, 1, 0, 0};
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
census_tag tag;
GPR_ASSERT(census_context_get_tag(
@@ -262,7 +273,7 @@ static void delete_tag_test(void) {
const census_context_status *status;
struct census_context *context2 = census_context_create(
context, modify_tags + DELETE_TAG_OFFSET, 1, &status);
- census_context_status expected = {2, 1, 4, 1, 0, 0, 0, 0};
+ census_context_status expected = {3, 4, 1, 0, 0, 0, 0};
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
census_tag tag;
GPR_ASSERT(census_context_get_tag(
@@ -278,7 +289,7 @@ static void add_tag_test(void) {
const census_context_status *status;
struct census_context *context2 =
census_context_create(context, modify_tags + ADD_TAG_OFFSET, 1, &status);
- census_context_status expected = {2, 2, 5, 0, 1, 0, 0, 0};
+ census_context_status expected = {4, 5, 0, 1, 0, 0, 0};
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
census_tag tag;
GPR_ASSERT(census_context_get_tag(context2, modify_tags[ADD_TAG_OFFSET].key,
@@ -295,24 +306,24 @@ static void replace_add_delete_test(void) {
const census_context_status *status;
struct census_context *context2 =
census_context_create(context, modify_tags, MODIFY_TAG_COUNT, &status);
- census_context_status expected = {2, 1, 6, 2, 3, 4, 0, 2};
+ census_context_status expected = {3, 7, 1, 3, 4, 0, 0};
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
// validate context contents. Use specific indices into the two arrays
// holding tag values.
GPR_ASSERT(validate_tag(context2, &basic_tags[3]));
GPR_ASSERT(validate_tag(context2, &basic_tags[4]));
+ GPR_ASSERT(validate_tag(context2, &basic_tags[6]));
GPR_ASSERT(validate_tag(context2, &modify_tags[0]));
GPR_ASSERT(validate_tag(context2, &modify_tags[1]));
+ GPR_ASSERT(validate_tag(context2, &modify_tags[5]));
GPR_ASSERT(validate_tag(context2, &modify_tags[6]));
GPR_ASSERT(validate_tag(context2, &modify_tags[7]));
GPR_ASSERT(validate_tag(context2, &modify_tags[8]));
GPR_ASSERT(validate_tag(context2, &modify_tags[9]));
- GPR_ASSERT(validate_tag(context2, &modify_tags[10]));
GPR_ASSERT(!validate_tag(context2, &basic_tags[0]));
GPR_ASSERT(!validate_tag(context2, &basic_tags[1]));
GPR_ASSERT(!validate_tag(context2, &basic_tags[2]));
GPR_ASSERT(!validate_tag(context2, &basic_tags[5]));
- GPR_ASSERT(!validate_tag(context2, &basic_tags[6]));
GPR_ASSERT(!validate_tag(context2, &basic_tags[7]));
census_context_destroy(context);
census_context_destroy(context2);
@@ -325,21 +336,15 @@ static void encode_decode_test(void) {
char buffer[BUF_SIZE];
struct census_context *context =
census_context_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
- size_t print_bsize;
- size_t bin_bsize;
// Test with too small a buffer
- GPR_ASSERT(census_context_encode(context, buffer, 2, &print_bsize,
- &bin_bsize) == NULL);
- char *b_buffer = census_context_encode(context, buffer, BUF_SIZE,
- &print_bsize, &bin_bsize);
- GPR_ASSERT(b_buffer != NULL && print_bsize > 0 && bin_bsize > 0 &&
- print_bsize + bin_bsize <= BUF_SIZE &&
- b_buffer == buffer + print_bsize);
- census_context *context2 =
- census_context_decode(buffer, print_bsize, b_buffer, bin_bsize);
+ GPR_ASSERT(census_context_encode(context, buffer, 2) == 0);
+ // Test with sufficient buffer
+ size_t buf_used = census_context_encode(context, buffer, BUF_SIZE);
+ GPR_ASSERT(buf_used != 0);
+ census_context *context2 = census_context_decode(buffer, buf_used);
GPR_ASSERT(context2 != NULL);
const census_context_status *status = census_context_get_status(context2);
- census_context_status expected = {2, 2, 0, 0, 0, 0, 0, 0};
+ census_context_status expected = {4, 0, 0, 0, 0, 0, 0};
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
for (int i = 0; i < BASIC_TAG_COUNT; i++) {
census_tag tag;
diff --git a/test/core/client_config/set_initial_connect_string_test.c b/test/core/client_config/set_initial_connect_string_test.c
index bcd1f26123..3cf267fb3b 100644
--- a/test/core/client_config/set_initial_connect_string_test.c
+++ b/test/core/client_config/set_initial_connect_string_test.c
@@ -85,7 +85,7 @@ static void on_connect(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *tcp,
gpr_slice_buffer_init(&state.incoming_buffer);
gpr_slice_buffer_init(&state.temp_incoming_buffer);
state.tcp = tcp;
- grpc_endpoint_add_to_pollset(exec_ctx, tcp, &server->pollset);
+ grpc_endpoint_add_to_pollset(exec_ctx, tcp, server->pollset);
grpc_endpoint_read(exec_ctx, tcp, &state.temp_incoming_buffer, &on_read);
}
diff --git a/test/core/end2end/fixtures/h2_full+poll+pipe.c b/test/core/end2end/fixtures/h2_full+poll+pipe.c
index d475a7bb55..682598fbe2 100644
--- a/test/core/end2end/fixtures/h2_full+poll+pipe.c
+++ b/test/core/end2end/fixtures/h2_full+poll+pipe.c
@@ -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
@@ -35,21 +35,23 @@
#include <string.h>
-#include "src/core/channel/client_channel.h"
-#include "src/core/channel/connected_channel.h"
-#include "src/core/channel/http_server_filter.h"
-#include "src/core/surface/channel.h"
-#include "src/core/surface/server.h"
-#include "src/core/transport/chttp2_transport.h"
#include <grpc/support/alloc.h>
#include <grpc/support/host_port.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
#include <grpc/support/thd.h>
#include <grpc/support/useful.h>
+
+#include "src/core/channel/client_channel.h"
+#include "src/core/channel/connected_channel.h"
+#include "src/core/channel/http_server_filter.h"
+#include "src/core/iomgr/pollset_posix.h"
+#include "src/core/iomgr/wakeup_fd_posix.h"
+#include "src/core/surface/channel.h"
+#include "src/core/surface/server.h"
+#include "src/core/transport/chttp2_transport.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
-#include "src/core/iomgr/wakeup_fd_posix.h"
typedef struct fullstack_fixture_data {
char *localaddr;
diff --git a/test/core/end2end/fixtures/h2_full+poll.c b/test/core/end2end/fixtures/h2_full+poll.c
index 3f5e6096f6..5a0b2ef495 100644
--- a/test/core/end2end/fixtures/h2_full+poll.c
+++ b/test/core/end2end/fixtures/h2_full+poll.c
@@ -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
@@ -35,18 +35,20 @@
#include <string.h>
-#include "src/core/channel/client_channel.h"
-#include "src/core/channel/connected_channel.h"
-#include "src/core/channel/http_server_filter.h"
-#include "src/core/surface/channel.h"
-#include "src/core/surface/server.h"
-#include "src/core/transport/chttp2_transport.h"
#include <grpc/support/alloc.h>
#include <grpc/support/host_port.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
#include <grpc/support/thd.h>
#include <grpc/support/useful.h>
+
+#include "src/core/channel/client_channel.h"
+#include "src/core/channel/connected_channel.h"
+#include "src/core/channel/http_server_filter.h"
+#include "src/core/iomgr/pollset_posix.h"
+#include "src/core/surface/channel.h"
+#include "src/core/surface/server.h"
+#include "src/core/transport/chttp2_transport.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
diff --git a/test/core/end2end/fixtures/h2_ssl+poll.c b/test/core/end2end/fixtures/h2_ssl+poll.c
index 0b88876d13..66268c77d5 100644
--- a/test/core/end2end/fixtures/h2_ssl+poll.c
+++ b/test/core/end2end/fixtures/h2_ssl+poll.c
@@ -41,6 +41,7 @@
#include <grpc/support/log.h>
#include "src/core/channel/channel_args.h"
+#include "src/core/iomgr/pollset_posix.h"
#include "src/core/security/credentials.h"
#include "src/core/support/env.h"
#include "src/core/support/tmpfile.h"
diff --git a/test/core/end2end/fixtures/h2_uchannel.c b/test/core/end2end/fixtures/h2_uchannel.c
index dbdd3524ed..87bbd64d09 100644
--- a/test/core/end2end/fixtures/h2_uchannel.c
+++ b/test/core/end2end/fixtures/h2_uchannel.c
@@ -35,6 +35,13 @@
#include <string.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/host_port.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/thd.h>
+#include <grpc/support/useful.h>
#include "src/core/channel/channel_args.h"
#include "src/core/channel/client_channel.h"
#include "src/core/channel/client_uchannel.h"
@@ -46,13 +53,6 @@
#include "src/core/surface/channel.h"
#include "src/core/surface/server.h"
#include "src/core/transport/chttp2_transport.h"
-#include <grpc/support/alloc.h>
-#include <grpc/support/host_port.h>
-#include <grpc/support/log.h>
-#include <grpc/support/string_util.h>
-#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
-#include <grpc/support/useful.h>
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
@@ -238,12 +238,12 @@ static grpc_end2end_test_fixture chttp2_create_fixture_micro_fullstack(
}
grpc_connectivity_state g_state = GRPC_CHANNEL_IDLE;
-grpc_pollset_set g_interested_parties;
+grpc_pollset_set *g_interested_parties;
static void state_changed(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
if (g_state != GRPC_CHANNEL_READY) {
grpc_subchannel_notify_on_state_change(
- exec_ctx, arg, &g_interested_parties, &g_state,
+ exec_ctx, arg, g_interested_parties, &g_state,
grpc_closure_create(state_changed, arg));
}
}
@@ -253,30 +253,31 @@ static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
}
static grpc_connected_subchannel *connect_subchannel(grpc_subchannel *c) {
- grpc_pollset pollset;
+ gpr_mu *mu;
+ grpc_pollset *pollset = gpr_malloc(grpc_pollset_size());
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
- grpc_pollset_init(&pollset);
- grpc_pollset_set_init(&g_interested_parties);
- grpc_pollset_set_add_pollset(&exec_ctx, &g_interested_parties, &pollset);
- grpc_subchannel_notify_on_state_change(&exec_ctx, c, &g_interested_parties,
+ grpc_pollset_init(pollset, &mu);
+ g_interested_parties = grpc_pollset_set_create();
+ grpc_pollset_set_add_pollset(&exec_ctx, g_interested_parties, pollset);
+ grpc_subchannel_notify_on_state_change(&exec_ctx, c, g_interested_parties,
&g_state,
grpc_closure_create(state_changed, c));
grpc_exec_ctx_flush(&exec_ctx);
- gpr_mu_lock(GRPC_POLLSET_MU(&pollset));
+ gpr_mu_lock(mu);
while (g_state != GRPC_CHANNEL_READY) {
- grpc_pollset_worker worker;
- grpc_pollset_work(&exec_ctx, &pollset, &worker,
- gpr_now(GPR_CLOCK_MONOTONIC),
+ grpc_pollset_worker *worker = NULL;
+ grpc_pollset_work(&exec_ctx, pollset, &worker, gpr_now(GPR_CLOCK_MONOTONIC),
GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1));
- gpr_mu_unlock(GRPC_POLLSET_MU(&pollset));
+ gpr_mu_unlock(mu);
grpc_exec_ctx_flush(&exec_ctx);
- gpr_mu_lock(GRPC_POLLSET_MU(&pollset));
+ gpr_mu_lock(mu);
}
- grpc_pollset_shutdown(&exec_ctx, &pollset,
- grpc_closure_create(destroy_pollset, &pollset));
- grpc_pollset_set_destroy(&g_interested_parties);
- gpr_mu_unlock(GRPC_POLLSET_MU(&pollset));
+ grpc_pollset_shutdown(&exec_ctx, pollset,
+ grpc_closure_create(destroy_pollset, pollset));
+ grpc_pollset_set_destroy(g_interested_parties);
+ gpr_mu_unlock(mu);
grpc_exec_ctx_finish(&exec_ctx);
+ gpr_free(pollset);
return grpc_subchannel_get_connected_subchannel(c);
}
diff --git a/test/core/end2end/fixtures/h2_uds+poll.c b/test/core/end2end/fixtures/h2_uds+poll.c
index 155017c887..c3a855ff88 100644
--- a/test/core/end2end/fixtures/h2_uds+poll.c
+++ b/test/core/end2end/fixtures/h2_uds+poll.c
@@ -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
@@ -37,13 +37,6 @@
#include <string.h>
#include <unistd.h>
-#include "src/core/channel/client_channel.h"
-#include "src/core/channel/connected_channel.h"
-#include "src/core/channel/http_server_filter.h"
-#include "src/core/support/string.h"
-#include "src/core/surface/channel.h"
-#include "src/core/surface/server.h"
-#include "src/core/transport/chttp2_transport.h"
#include <grpc/support/alloc.h>
#include <grpc/support/host_port.h>
#include <grpc/support/log.h>
@@ -51,6 +44,15 @@
#include <grpc/support/sync.h>
#include <grpc/support/thd.h>
#include <grpc/support/useful.h>
+
+#include "src/core/channel/client_channel.h"
+#include "src/core/channel/connected_channel.h"
+#include "src/core/channel/http_server_filter.h"
+#include "src/core/iomgr/pollset_posix.h"
+#include "src/core/support/string.h"
+#include "src/core/surface/channel.h"
+#include "src/core/surface/server.h"
+#include "src/core/transport/chttp2_transport.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
diff --git a/test/core/httpcli/httpcli_test.c b/test/core/httpcli/httpcli_test.c
index 651ef1fa3b..da1463329d 100644
--- a/test/core/httpcli/httpcli_test.c
+++ b/test/core/httpcli/httpcli_test.c
@@ -36,18 +36,19 @@
#include <string.h>
#include <grpc/grpc.h>
-#include "src/core/iomgr/iomgr.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/subprocess.h>
#include <grpc/support/sync.h>
+#include "src/core/iomgr/iomgr.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
static int g_done = 0;
static grpc_httpcli_context g_context;
-static grpc_pollset g_pollset;
+static gpr_mu *g_mu;
+static grpc_pollset *g_pollset;
static gpr_timespec n_seconds_time(int seconds) {
return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(seconds);
@@ -63,10 +64,10 @@ static void on_finish(grpc_exec_ctx *exec_ctx, void *arg,
GPR_ASSERT(response->status == 200);
GPR_ASSERT(response->body_length == strlen(expect));
GPR_ASSERT(0 == memcmp(expect, response->body, response->body_length));
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
g_done = 1;
- grpc_pollset_kick(&g_pollset, NULL);
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ grpc_pollset_kick(g_pollset, NULL);
+ gpr_mu_unlock(g_mu);
}
static void test_get(int port) {
@@ -85,18 +86,18 @@ static void test_get(int port) {
req.path = "/get";
req.handshaker = &grpc_httpcli_plaintext;
- grpc_httpcli_get(&exec_ctx, &g_context, &g_pollset, &req, n_seconds_time(15),
+ grpc_httpcli_get(&exec_ctx, &g_context, g_pollset, &req, n_seconds_time(15),
on_finish, (void *)42);
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
while (!g_done) {
- grpc_pollset_worker worker;
- grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+ grpc_pollset_worker *worker = NULL;
+ grpc_pollset_work(&exec_ctx, g_pollset, &worker,
gpr_now(GPR_CLOCK_MONOTONIC), n_seconds_time(20));
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
grpc_exec_ctx_finish(&exec_ctx);
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
}
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
gpr_free(host);
}
@@ -116,18 +117,18 @@ static void test_post(int port) {
req.path = "/post";
req.handshaker = &grpc_httpcli_plaintext;
- grpc_httpcli_post(&exec_ctx, &g_context, &g_pollset, &req, "hello", 5,
+ grpc_httpcli_post(&exec_ctx, &g_context, g_pollset, &req, "hello", 5,
n_seconds_time(15), on_finish, (void *)42);
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
while (!g_done) {
- grpc_pollset_worker worker;
- grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+ grpc_pollset_worker *worker = NULL;
+ grpc_pollset_work(&exec_ctx, g_pollset, &worker,
gpr_now(GPR_CLOCK_MONOTONIC), n_seconds_time(20));
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
grpc_exec_ctx_finish(&exec_ctx);
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
}
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
gpr_free(host);
}
@@ -175,17 +176,20 @@ int main(int argc, char **argv) {
grpc_test_init(argc, argv);
grpc_init();
grpc_httpcli_context_init(&g_context);
- grpc_pollset_init(&g_pollset);
+ g_pollset = gpr_malloc(grpc_pollset_size());
+ grpc_pollset_init(g_pollset, &g_mu);
test_get(port);
test_post(port);
grpc_httpcli_context_destroy(&g_context);
- grpc_closure_init(&destroyed, destroy_pollset, &g_pollset);
- grpc_pollset_shutdown(&exec_ctx, &g_pollset, &destroyed);
+ grpc_closure_init(&destroyed, destroy_pollset, g_pollset);
+ grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
grpc_exec_ctx_finish(&exec_ctx);
grpc_shutdown();
+ gpr_free(g_pollset);
+
gpr_subprocess_destroy(server);
return 0;
diff --git a/test/core/httpcli/httpscli_test.c b/test/core/httpcli/httpscli_test.c
index db41be17e7..7f765bc614 100644
--- a/test/core/httpcli/httpscli_test.c
+++ b/test/core/httpcli/httpscli_test.c
@@ -36,18 +36,19 @@
#include <string.h>
#include <grpc/grpc.h>
-#include "src/core/iomgr/iomgr.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/subprocess.h>
#include <grpc/support/sync.h>
+#include "src/core/iomgr/iomgr.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
static int g_done = 0;
static grpc_httpcli_context g_context;
-static grpc_pollset g_pollset;
+static gpr_mu *g_mu;
+static grpc_pollset *g_pollset;
static gpr_timespec n_seconds_time(int seconds) {
return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(seconds);
@@ -63,10 +64,10 @@ static void on_finish(grpc_exec_ctx *exec_ctx, void *arg,
GPR_ASSERT(response->status == 200);
GPR_ASSERT(response->body_length == strlen(expect));
GPR_ASSERT(0 == memcmp(expect, response->body, response->body_length));
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
g_done = 1;
- grpc_pollset_kick(&g_pollset, NULL);
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ grpc_pollset_kick(g_pollset, NULL);
+ gpr_mu_unlock(g_mu);
}
static void test_get(int port) {
@@ -86,18 +87,18 @@ static void test_get(int port) {
req.path = "/get";
req.handshaker = &grpc_httpcli_ssl;
- grpc_httpcli_get(&exec_ctx, &g_context, &g_pollset, &req, n_seconds_time(15),
+ grpc_httpcli_get(&exec_ctx, &g_context, g_pollset, &req, n_seconds_time(15),
on_finish, (void *)42);
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
while (!g_done) {
- grpc_pollset_worker worker;
- grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+ grpc_pollset_worker *worker = NULL;
+ grpc_pollset_work(&exec_ctx, g_pollset, &worker,
gpr_now(GPR_CLOCK_MONOTONIC), n_seconds_time(20));
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
grpc_exec_ctx_finish(&exec_ctx);
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
}
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
gpr_free(host);
}
@@ -118,18 +119,18 @@ static void test_post(int port) {
req.path = "/post";
req.handshaker = &grpc_httpcli_ssl;
- grpc_httpcli_post(&exec_ctx, &g_context, &g_pollset, &req, "hello", 5,
+ grpc_httpcli_post(&exec_ctx, &g_context, g_pollset, &req, "hello", 5,
n_seconds_time(15), on_finish, (void *)42);
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
while (!g_done) {
- grpc_pollset_worker worker;
- grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+ grpc_pollset_worker *worker = NULL;
+ grpc_pollset_work(&exec_ctx, g_pollset, &worker,
gpr_now(GPR_CLOCK_MONOTONIC), n_seconds_time(20));
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
grpc_exec_ctx_finish(&exec_ctx);
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
}
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
gpr_free(host);
}
@@ -178,17 +179,20 @@ int main(int argc, char **argv) {
grpc_test_init(argc, argv);
grpc_init();
grpc_httpcli_context_init(&g_context);
- grpc_pollset_init(&g_pollset);
+ g_pollset = gpr_malloc(grpc_pollset_size());
+ grpc_pollset_init(g_pollset, &g_mu);
test_get(port);
test_post(port);
grpc_httpcli_context_destroy(&g_context);
- grpc_closure_init(&destroyed, destroy_pollset, &g_pollset);
- grpc_pollset_shutdown(&exec_ctx, &g_pollset, &destroyed);
+ grpc_closure_init(&destroyed, destroy_pollset, g_pollset);
+ grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
grpc_exec_ctx_finish(&exec_ctx);
grpc_shutdown();
+ gpr_free(g_pollset);
+
gpr_subprocess_destroy(server);
return 0;
diff --git a/test/core/iomgr/endpoint_pair_test.c b/test/core/iomgr/endpoint_pair_test.c
index 7e266ebfb9..c3a91088a5 100644
--- a/test/core/iomgr/endpoint_pair_test.c
+++ b/test/core/iomgr/endpoint_pair_test.c
@@ -39,10 +39,11 @@
#include <grpc/support/time.h>
#include <grpc/support/useful.h>
#include "src/core/iomgr/endpoint_pair.h"
-#include "test/core/util/test_config.h"
#include "test/core/iomgr/endpoint_tests.h"
+#include "test/core/util/test_config.h"
-static grpc_pollset g_pollset;
+static gpr_mu *g_mu;
+static grpc_pollset *g_pollset;
static void clean_up(void) {}
@@ -54,8 +55,8 @@ static grpc_endpoint_test_fixture create_fixture_endpoint_pair(
f.client_ep = p.client;
f.server_ep = p.server;
- grpc_endpoint_add_to_pollset(&exec_ctx, f.client_ep, &g_pollset);
- grpc_endpoint_add_to_pollset(&exec_ctx, f.server_ep, &g_pollset);
+ grpc_endpoint_add_to_pollset(&exec_ctx, f.client_ep, g_pollset);
+ grpc_endpoint_add_to_pollset(&exec_ctx, f.server_ep, g_pollset);
grpc_exec_ctx_finish(&exec_ctx);
return f;
@@ -74,12 +75,14 @@ int main(int argc, char **argv) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_test_init(argc, argv);
grpc_init();
- grpc_pollset_init(&g_pollset);
- grpc_endpoint_tests(configs[0], &g_pollset);
- grpc_closure_init(&destroyed, destroy_pollset, &g_pollset);
- grpc_pollset_shutdown(&exec_ctx, &g_pollset, &destroyed);
+ g_pollset = gpr_malloc(grpc_pollset_size());
+ grpc_pollset_init(g_pollset, &g_mu);
+ grpc_endpoint_tests(configs[0], g_pollset, g_mu);
+ grpc_closure_init(&destroyed, destroy_pollset, g_pollset);
+ grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
grpc_exec_ctx_finish(&exec_ctx);
grpc_shutdown();
+ gpr_free(g_pollset);
return 0;
}
diff --git a/test/core/iomgr/endpoint_tests.c b/test/core/iomgr/endpoint_tests.c
index 1b6a78da9a..f689e4ba7f 100644
--- a/test/core/iomgr/endpoint_tests.c
+++ b/test/core/iomgr/endpoint_tests.c
@@ -36,8 +36,8 @@
#include <sys/types.h>
#include <grpc/support/alloc.h>
-#include <grpc/support/slice.h>
#include <grpc/support/log.h>
+#include <grpc/support/slice.h>
#include <grpc/support/time.h>
#include <grpc/support/useful.h>
#include "test/core/util/test_config.h"
@@ -58,6 +58,7 @@
*/
+static gpr_mu *g_mu;
static grpc_pollset *g_pollset;
size_t count_slices(gpr_slice *slices, size_t nslices, int *current_data) {
@@ -134,10 +135,10 @@ static void read_and_write_test_read_handler(grpc_exec_ctx *exec_ctx,
state->incoming.slices, state->incoming.count, &state->current_read_data);
if (state->bytes_read == state->target_bytes || !success) {
gpr_log(GPR_INFO, "Read handler done");
- gpr_mu_lock(GRPC_POLLSET_MU(g_pollset));
+ gpr_mu_lock(g_mu);
state->read_done = 1 + success;
grpc_pollset_kick(g_pollset, NULL);
- gpr_mu_unlock(GRPC_POLLSET_MU(g_pollset));
+ gpr_mu_unlock(g_mu);
} else if (success) {
grpc_endpoint_read(exec_ctx, state->read_ep, &state->incoming,
&state->done_read);
@@ -169,10 +170,10 @@ static void read_and_write_test_write_handler(grpc_exec_ctx *exec_ctx,
}
gpr_log(GPR_INFO, "Write handler done");
- gpr_mu_lock(GRPC_POLLSET_MU(g_pollset));
+ gpr_mu_lock(g_mu);
state->write_done = 1 + success;
grpc_pollset_kick(g_pollset, NULL);
- gpr_mu_unlock(GRPC_POLLSET_MU(g_pollset));
+ gpr_mu_unlock(g_mu);
}
/* Do both reading and writing using the grpc_endpoint API.
@@ -232,14 +233,14 @@ static void read_and_write_test(grpc_endpoint_test_config config,
}
grpc_exec_ctx_finish(&exec_ctx);
- gpr_mu_lock(GRPC_POLLSET_MU(g_pollset));
+ gpr_mu_lock(g_mu);
while (!state.read_done || !state.write_done) {
- grpc_pollset_worker worker;
+ grpc_pollset_worker *worker = NULL;
GPR_ASSERT(gpr_time_cmp(gpr_now(GPR_CLOCK_MONOTONIC), deadline) < 0);
grpc_pollset_work(&exec_ctx, g_pollset, &worker,
gpr_now(GPR_CLOCK_MONOTONIC), deadline);
}
- gpr_mu_unlock(GRPC_POLLSET_MU(g_pollset));
+ gpr_mu_unlock(g_mu);
grpc_exec_ctx_finish(&exec_ctx);
end_test(config);
@@ -251,9 +252,10 @@ static void read_and_write_test(grpc_endpoint_test_config config,
}
void grpc_endpoint_tests(grpc_endpoint_test_config config,
- grpc_pollset *pollset) {
+ grpc_pollset *pollset, gpr_mu *mu) {
size_t i;
g_pollset = pollset;
+ g_mu = mu;
read_and_write_test(config, 10000000, 100000, 8192, 0);
read_and_write_test(config, 1000000, 100000, 1, 0);
read_and_write_test(config, 100000000, 100000, 1, 1);
diff --git a/test/core/iomgr/endpoint_tests.h b/test/core/iomgr/endpoint_tests.h
index 700f854891..8ea47e345c 100644
--- a/test/core/iomgr/endpoint_tests.h
+++ b/test/core/iomgr/endpoint_tests.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
@@ -53,6 +53,6 @@ struct grpc_endpoint_test_config {
};
void grpc_endpoint_tests(grpc_endpoint_test_config config,
- grpc_pollset *pollset);
+ grpc_pollset *pollset, gpr_mu *mu);
#endif /* GRPC_TEST_CORE_IOMGR_ENDPOINT_TESTS_H */
diff --git a/test/core/iomgr/fd_posix_test.c b/test/core/iomgr/fd_posix_test.c
index 347a86af10..99689ebcc3 100644
--- a/test/core/iomgr/fd_posix_test.c
+++ b/test/core/iomgr/fd_posix_test.c
@@ -49,9 +49,12 @@
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
#include <grpc/support/time.h>
+
+#include "src/core/iomgr/pollset_posix.h"
#include "test/core/util/test_config.h"
-static grpc_pollset g_pollset;
+static gpr_mu *g_mu;
+static grpc_pollset *g_pollset;
/* buffer size used to send and receive data.
1024 is the minimal value to set TCP send and receive buffer. */
@@ -179,10 +182,10 @@ static void listen_shutdown_cb(grpc_exec_ctx *exec_ctx, void *arg /*server */,
grpc_fd_orphan(exec_ctx, sv->em_fd, NULL, NULL, "b");
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
sv->done = 1;
- grpc_pollset_kick(&g_pollset, NULL);
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ grpc_pollset_kick(g_pollset, NULL);
+ gpr_mu_unlock(g_mu);
}
/* Called when a new TCP connection request arrives in the listening port. */
@@ -209,7 +212,7 @@ static void listen_cb(grpc_exec_ctx *exec_ctx, void *arg, /*=sv_arg*/
se = gpr_malloc(sizeof(*se));
se->sv = sv;
se->em_fd = grpc_fd_create(fd, "listener");
- grpc_pollset_add_fd(exec_ctx, &g_pollset, se->em_fd);
+ grpc_pollset_add_fd(exec_ctx, g_pollset, se->em_fd);
se->session_read_closure.cb = session_read_cb;
se->session_read_closure.cb_arg = se;
grpc_fd_notify_on_read(exec_ctx, se->em_fd, &se->session_read_closure);
@@ -238,7 +241,7 @@ static int server_start(grpc_exec_ctx *exec_ctx, server *sv) {
GPR_ASSERT(listen(fd, MAX_NUM_FD) == 0);
sv->em_fd = grpc_fd_create(fd, "server");
- grpc_pollset_add_fd(exec_ctx, &g_pollset, sv->em_fd);
+ grpc_pollset_add_fd(exec_ctx, g_pollset, sv->em_fd);
/* Register to be interested in reading from listen_fd. */
sv->listen_closure.cb = listen_cb;
sv->listen_closure.cb_arg = sv;
@@ -249,18 +252,18 @@ static int server_start(grpc_exec_ctx *exec_ctx, server *sv) {
/* Wait and shutdown a sever. */
static void server_wait_and_shutdown(server *sv) {
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
while (!sv->done) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
- grpc_pollset_worker worker;
- grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+ grpc_pollset_worker *worker = NULL;
+ grpc_pollset_work(&exec_ctx, g_pollset, &worker,
gpr_now(GPR_CLOCK_MONOTONIC),
gpr_inf_future(GPR_CLOCK_MONOTONIC));
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
grpc_exec_ctx_finish(&exec_ctx);
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
}
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
}
/* ===An upload client to test notify_on_write=== */
@@ -296,7 +299,7 @@ static void client_session_shutdown_cb(grpc_exec_ctx *exec_ctx,
client *cl = arg;
grpc_fd_orphan(exec_ctx, cl->em_fd, NULL, NULL, "c");
cl->done = 1;
- grpc_pollset_kick(&g_pollset, NULL);
+ grpc_pollset_kick(g_pollset, NULL);
}
/* Write as much as possible, then register notify_on_write. */
@@ -307,9 +310,9 @@ static void client_session_write(grpc_exec_ctx *exec_ctx, void *arg, /*client */
ssize_t write_once = 0;
if (!success) {
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
client_session_shutdown_cb(exec_ctx, arg, 1);
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
return;
}
@@ -319,7 +322,7 @@ static void client_session_write(grpc_exec_ctx *exec_ctx, void *arg, /*client */
} while (write_once > 0);
if (errno == EAGAIN) {
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
if (cl->client_write_cnt < CLIENT_TOTAL_WRITE_CNT) {
cl->write_closure.cb = client_session_write;
cl->write_closure.cb_arg = cl;
@@ -328,7 +331,7 @@ static void client_session_write(grpc_exec_ctx *exec_ctx, void *arg, /*client */
} else {
client_session_shutdown_cb(exec_ctx, arg, 1);
}
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
} else {
gpr_log(GPR_ERROR, "unknown errno %s", strerror(errno));
abort();
@@ -357,25 +360,25 @@ static void client_start(grpc_exec_ctx *exec_ctx, client *cl, int port) {
}
cl->em_fd = grpc_fd_create(fd, "client");
- grpc_pollset_add_fd(exec_ctx, &g_pollset, cl->em_fd);
+ grpc_pollset_add_fd(exec_ctx, g_pollset, cl->em_fd);
client_session_write(exec_ctx, cl, 1);
}
/* Wait for the signal to shutdown a client. */
static void client_wait_and_shutdown(client *cl) {
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
while (!cl->done) {
- grpc_pollset_worker worker;
+ grpc_pollset_worker *worker = NULL;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
- grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+ grpc_pollset_work(&exec_ctx, g_pollset, &worker,
gpr_now(GPR_CLOCK_MONOTONIC),
gpr_inf_future(GPR_CLOCK_MONOTONIC));
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
grpc_exec_ctx_finish(&exec_ctx);
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
}
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
}
/* Test grpc_fd. Start an upload server and client, upload a stream of
@@ -410,20 +413,20 @@ static void first_read_callback(grpc_exec_ctx *exec_ctx,
void *arg /* fd_change_data */, bool success) {
fd_change_data *fdc = arg;
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
fdc->cb_that_ran = first_read_callback;
- grpc_pollset_kick(&g_pollset, NULL);
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ grpc_pollset_kick(g_pollset, NULL);
+ gpr_mu_unlock(g_mu);
}
static void second_read_callback(grpc_exec_ctx *exec_ctx,
void *arg /* fd_change_data */, bool success) {
fd_change_data *fdc = arg;
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
fdc->cb_that_ran = second_read_callback;
- grpc_pollset_kick(&g_pollset, NULL);
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ grpc_pollset_kick(g_pollset, NULL);
+ gpr_mu_unlock(g_mu);
}
/* Test that changing the callback we use for notify_on_read actually works.
@@ -456,7 +459,7 @@ static void test_grpc_fd_change(void) {
GPR_ASSERT(fcntl(sv[1], F_SETFL, flags | O_NONBLOCK) == 0);
em_fd = grpc_fd_create(sv[0], "test_grpc_fd_change");
- grpc_pollset_add_fd(&exec_ctx, &g_pollset, em_fd);
+ grpc_pollset_add_fd(&exec_ctx, g_pollset, em_fd);
/* Register the first callback, then make its FD readable */
grpc_fd_notify_on_read(&exec_ctx, em_fd, &first_closure);
@@ -465,18 +468,18 @@ static void test_grpc_fd_change(void) {
GPR_ASSERT(result == 1);
/* And now wait for it to run. */
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
while (a.cb_that_ran == NULL) {
- grpc_pollset_worker worker;
- grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+ grpc_pollset_worker *worker = NULL;
+ grpc_pollset_work(&exec_ctx, g_pollset, &worker,
gpr_now(GPR_CLOCK_MONOTONIC),
gpr_inf_future(GPR_CLOCK_MONOTONIC));
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
grpc_exec_ctx_finish(&exec_ctx);
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
}
GPR_ASSERT(a.cb_that_ran == first_read_callback);
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
/* And drain the socket so we can generate a new read edge */
result = read(sv[0], &data, 1);
@@ -489,19 +492,19 @@ static void test_grpc_fd_change(void) {
result = write(sv[1], &data, 1);
GPR_ASSERT(result == 1);
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
while (b.cb_that_ran == NULL) {
- grpc_pollset_worker worker;
- grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+ grpc_pollset_worker *worker = NULL;
+ grpc_pollset_work(&exec_ctx, g_pollset, &worker,
gpr_now(GPR_CLOCK_MONOTONIC),
gpr_inf_future(GPR_CLOCK_MONOTONIC));
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
grpc_exec_ctx_finish(&exec_ctx);
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
}
/* Except now we verify that second_read_callback ran instead */
GPR_ASSERT(b.cb_that_ran == second_read_callback);
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
grpc_fd_orphan(&exec_ctx, em_fd, NULL, NULL, "d");
grpc_exec_ctx_finish(&exec_ctx);
@@ -519,12 +522,14 @@ int main(int argc, char **argv) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_test_init(argc, argv);
grpc_iomgr_init();
- grpc_pollset_init(&g_pollset);
+ g_pollset = gpr_malloc(grpc_pollset_size());
+ grpc_pollset_init(g_pollset, &g_mu);
test_grpc_fd();
test_grpc_fd_change();
- grpc_closure_init(&destroyed, destroy_pollset, &g_pollset);
- grpc_pollset_shutdown(&exec_ctx, &g_pollset, &destroyed);
+ grpc_closure_init(&destroyed, destroy_pollset, g_pollset);
+ grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
grpc_exec_ctx_finish(&exec_ctx);
+ gpr_free(g_pollset);
grpc_iomgr_shutdown();
return 0;
}
diff --git a/test/core/iomgr/tcp_client_posix_test.c b/test/core/iomgr/tcp_client_posix_test.c
index b57478059f..746dfd85be 100644
--- a/test/core/iomgr/tcp_client_posix_test.c
+++ b/test/core/iomgr/tcp_client_posix_test.c
@@ -40,6 +40,7 @@
#include <unistd.h>
#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/time.h>
@@ -48,8 +49,9 @@
#include "src/core/iomgr/timer.h"
#include "test/core/util/test_config.h"
-static grpc_pollset_set g_pollset_set;
-static grpc_pollset g_pollset;
+static grpc_pollset_set *g_pollset_set;
+static gpr_mu *g_mu;
+static grpc_pollset *g_pollset;
static int g_connections_complete = 0;
static grpc_endpoint *g_connecting = NULL;
@@ -58,10 +60,10 @@ static gpr_timespec test_deadline(void) {
}
static void finish_connection() {
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
g_connections_complete++;
- grpc_pollset_kick(&g_pollset, NULL);
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ grpc_pollset_kick(g_pollset, NULL);
+ gpr_mu_unlock(g_mu);
}
static void must_succeed(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
@@ -99,14 +101,14 @@ void test_succeeds(void) {
GPR_ASSERT(0 == bind(svr_fd, (struct sockaddr *)&addr, addr_len));
GPR_ASSERT(0 == listen(svr_fd, 1));
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
connections_complete_before = g_connections_complete;
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
/* connect to it */
GPR_ASSERT(getsockname(svr_fd, (struct sockaddr *)&addr, &addr_len) == 0);
grpc_closure_init(&done, must_succeed, NULL);
- grpc_tcp_client_connect(&exec_ctx, &done, &g_connecting, &g_pollset_set,
+ grpc_tcp_client_connect(&exec_ctx, &done, &g_connecting, g_pollset_set,
(struct sockaddr *)&addr, addr_len,
gpr_inf_future(GPR_CLOCK_REALTIME));
@@ -118,19 +120,19 @@ void test_succeeds(void) {
GPR_ASSERT(r >= 0);
close(r);
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
while (g_connections_complete == connections_complete_before) {
- grpc_pollset_worker worker;
- grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+ grpc_pollset_worker *worker = NULL;
+ grpc_pollset_work(&exec_ctx, g_pollset, &worker,
gpr_now(GPR_CLOCK_MONOTONIC),
GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5));
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
grpc_exec_ctx_flush(&exec_ctx);
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
}
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
grpc_exec_ctx_finish(&exec_ctx);
}
@@ -147,127 +149,35 @@ void test_fails(void) {
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
connections_complete_before = g_connections_complete;
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
/* connect to a broken address */
grpc_closure_init(&done, must_fail, NULL);
- grpc_tcp_client_connect(&exec_ctx, &done, &g_connecting, &g_pollset_set,
+ grpc_tcp_client_connect(&exec_ctx, &done, &g_connecting, g_pollset_set,
(struct sockaddr *)&addr, addr_len,
gpr_inf_future(GPR_CLOCK_REALTIME));
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
/* wait for the connection callback to finish */
while (g_connections_complete == connections_complete_before) {
- grpc_pollset_worker worker;
+ grpc_pollset_worker *worker = NULL;
gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
gpr_timespec polling_deadline = test_deadline();
if (!grpc_timer_check(&exec_ctx, now, &polling_deadline)) {
- grpc_pollset_work(&exec_ctx, &g_pollset, &worker, now, polling_deadline);
+ grpc_pollset_work(&exec_ctx, g_pollset, &worker, now, polling_deadline);
}
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
grpc_exec_ctx_flush(&exec_ctx);
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
}
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
grpc_exec_ctx_finish(&exec_ctx);
}
-void test_times_out(void) {
- struct sockaddr_in addr;
- socklen_t addr_len = sizeof(addr);
- int svr_fd;
-#define NUM_CLIENT_CONNECTS 100
- int client_fd[NUM_CLIENT_CONNECTS];
- int i;
- int r;
- int connections_complete_before;
- gpr_timespec connect_deadline;
- grpc_closure done;
- grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-
- gpr_log(GPR_DEBUG, "test_times_out");
-
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
-
- /* create a dummy server */
- svr_fd = socket(AF_INET, SOCK_STREAM, 0);
- GPR_ASSERT(svr_fd >= 0);
- GPR_ASSERT(0 == bind(svr_fd, (struct sockaddr *)&addr, addr_len));
- GPR_ASSERT(0 == listen(svr_fd, 1));
- /* Get its address */
- GPR_ASSERT(getsockname(svr_fd, (struct sockaddr *)&addr, &addr_len) == 0);
-
- /* tie up the listen buffer, which is somewhat arbitrarily sized. */
- for (i = 0; i < NUM_CLIENT_CONNECTS; ++i) {
- client_fd[i] = socket(AF_INET, SOCK_STREAM, 0);
- grpc_set_socket_nonblocking(client_fd[i], 1);
- do {
- r = connect(client_fd[i], (struct sockaddr *)&addr, addr_len);
- } while (r == -1 && errno == EINTR);
- GPR_ASSERT(r < 0);
- GPR_ASSERT(errno == EWOULDBLOCK || errno == EINPROGRESS);
- }
-
- /* connect to dummy server address */
-
- connect_deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1);
-
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
- connections_complete_before = g_connections_complete;
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
-
- grpc_closure_init(&done, must_fail, NULL);
- grpc_tcp_client_connect(&exec_ctx, &done, &g_connecting, &g_pollset_set,
- (struct sockaddr *)&addr, addr_len, connect_deadline);
-
- /* Make sure the event doesn't trigger early */
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
- for (;;) {
- grpc_pollset_worker worker;
- gpr_timespec now = gpr_now(connect_deadline.clock_type);
- gpr_timespec continue_verifying_time =
- gpr_time_from_seconds(5, GPR_TIMESPAN);
- gpr_timespec grace_time = gpr_time_from_seconds(3, GPR_TIMESPAN);
- gpr_timespec finish_time =
- gpr_time_add(connect_deadline, continue_verifying_time);
- gpr_timespec restart_verifying_time =
- gpr_time_add(connect_deadline, grace_time);
- int is_after_deadline = gpr_time_cmp(now, connect_deadline) > 0;
- if (gpr_time_cmp(now, finish_time) > 0) {
- break;
- }
- gpr_log(GPR_DEBUG, "now=%lld.%09d connect_deadline=%lld.%09d",
- (long long)now.tv_sec, (int)now.tv_nsec,
- (long long)connect_deadline.tv_sec, (int)connect_deadline.tv_nsec);
- if (is_after_deadline && gpr_time_cmp(now, restart_verifying_time) <= 0) {
- /* allow some slack before insisting that things be done */
- } else {
- GPR_ASSERT(g_connections_complete ==
- connections_complete_before + is_after_deadline);
- }
- gpr_timespec polling_deadline = GRPC_TIMEOUT_MILLIS_TO_DEADLINE(10);
- if (!grpc_timer_check(&exec_ctx, now, &polling_deadline)) {
- grpc_pollset_work(&exec_ctx, &g_pollset, &worker, now, polling_deadline);
- }
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
- grpc_exec_ctx_flush(&exec_ctx);
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
- }
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
-
- grpc_exec_ctx_finish(&exec_ctx);
-
- close(svr_fd);
- for (i = 0; i < NUM_CLIENT_CONNECTS; ++i) {
- close(client_fd[i]);
- }
-}
-
static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *p, bool success) {
grpc_pollset_destroy(p);
}
@@ -277,18 +187,19 @@ int main(int argc, char **argv) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_test_init(argc, argv);
grpc_init();
- grpc_pollset_set_init(&g_pollset_set);
- grpc_pollset_init(&g_pollset);
- grpc_pollset_set_add_pollset(&exec_ctx, &g_pollset_set, &g_pollset);
+ g_pollset_set = grpc_pollset_set_create();
+ g_pollset = gpr_malloc(grpc_pollset_size());
+ grpc_pollset_init(g_pollset, &g_mu);
+ grpc_pollset_set_add_pollset(&exec_ctx, g_pollset_set, g_pollset);
grpc_exec_ctx_finish(&exec_ctx);
test_succeeds();
gpr_log(GPR_ERROR, "End of first test");
test_fails();
- test_times_out();
- grpc_pollset_set_destroy(&g_pollset_set);
- grpc_closure_init(&destroyed, destroy_pollset, &g_pollset);
- grpc_pollset_shutdown(&exec_ctx, &g_pollset, &destroyed);
+ grpc_pollset_set_destroy(g_pollset_set);
+ grpc_closure_init(&destroyed, destroy_pollset, g_pollset);
+ grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
grpc_exec_ctx_finish(&exec_ctx);
grpc_shutdown();
+ gpr_free(g_pollset);
return 0;
}
diff --git a/test/core/iomgr/tcp_posix_test.c b/test/core/iomgr/tcp_posix_test.c
index d290c6bc3a..4351642ab6 100644
--- a/test/core/iomgr/tcp_posix_test.c
+++ b/test/core/iomgr/tcp_posix_test.c
@@ -36,8 +36,8 @@
#include <errno.h>
#include <fcntl.h>
#include <string.h>
-#include <sys/types.h>
#include <sys/socket.h>
+#include <sys/types.h>
#include <unistd.h>
#include <grpc/grpc.h>
@@ -45,10 +45,11 @@
#include <grpc/support/log.h>
#include <grpc/support/time.h>
#include <grpc/support/useful.h>
-#include "test/core/util/test_config.h"
#include "test/core/iomgr/endpoint_tests.h"
+#include "test/core/util/test_config.h"
-static grpc_pollset g_pollset;
+static gpr_mu *g_mu;
+static grpc_pollset *g_pollset;
/*
General test notes:
@@ -145,7 +146,7 @@ static void read_cb(grpc_exec_ctx *exec_ctx, void *user_data, bool success) {
GPR_ASSERT(success);
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
current_data = state->read_bytes % 256;
read_bytes = count_slices(state->incoming.slices, state->incoming.count,
&current_data);
@@ -153,10 +154,10 @@ static void read_cb(grpc_exec_ctx *exec_ctx, void *user_data, bool success) {
gpr_log(GPR_INFO, "Read %d bytes of %d", read_bytes,
state->target_read_bytes);
if (state->read_bytes >= state->target_read_bytes) {
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
} else {
grpc_endpoint_read(exec_ctx, state->ep, &state->incoming, &state->read_cb);
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
}
}
@@ -175,7 +176,7 @@ static void read_test(size_t num_bytes, size_t slice_size) {
create_sockets(sv);
ep = grpc_tcp_create(grpc_fd_create(sv[1], "read_test"), slice_size, "test");
- grpc_endpoint_add_to_pollset(&exec_ctx, ep, &g_pollset);
+ grpc_endpoint_add_to_pollset(&exec_ctx, ep, g_pollset);
written_bytes = fill_socket_partial(sv[0], num_bytes);
gpr_log(GPR_INFO, "Wrote %d bytes", written_bytes);
@@ -188,17 +189,17 @@ static void read_test(size_t num_bytes, size_t slice_size) {
grpc_endpoint_read(&exec_ctx, ep, &state.incoming, &state.read_cb);
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
while (state.read_bytes < state.target_read_bytes) {
- grpc_pollset_worker worker;
- grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+ grpc_pollset_worker *worker = NULL;
+ grpc_pollset_work(&exec_ctx, g_pollset, &worker,
gpr_now(GPR_CLOCK_MONOTONIC), deadline);
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
grpc_exec_ctx_finish(&exec_ctx);
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
}
GPR_ASSERT(state.read_bytes == state.target_read_bytes);
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
gpr_slice_buffer_destroy(&state.incoming);
grpc_endpoint_destroy(&exec_ctx, ep);
@@ -221,7 +222,7 @@ static void large_read_test(size_t slice_size) {
ep = grpc_tcp_create(grpc_fd_create(sv[1], "large_read_test"), slice_size,
"test");
- grpc_endpoint_add_to_pollset(&exec_ctx, ep, &g_pollset);
+ grpc_endpoint_add_to_pollset(&exec_ctx, ep, g_pollset);
written_bytes = fill_socket(sv[0]);
gpr_log(GPR_INFO, "Wrote %d bytes", written_bytes);
@@ -234,17 +235,17 @@ static void large_read_test(size_t slice_size) {
grpc_endpoint_read(&exec_ctx, ep, &state.incoming, &state.read_cb);
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
while (state.read_bytes < state.target_read_bytes) {
- grpc_pollset_worker worker;
- grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+ grpc_pollset_worker *worker = NULL;
+ grpc_pollset_work(&exec_ctx, g_pollset, &worker,
gpr_now(GPR_CLOCK_MONOTONIC), deadline);
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
grpc_exec_ctx_finish(&exec_ctx);
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
}
GPR_ASSERT(state.read_bytes == state.target_read_bytes);
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
gpr_slice_buffer_destroy(&state.incoming);
grpc_endpoint_destroy(&exec_ctx, ep);
@@ -283,11 +284,11 @@ static void write_done(grpc_exec_ctx *exec_ctx,
void *user_data /* write_socket_state */, bool success) {
struct write_socket_state *state = (struct write_socket_state *)user_data;
gpr_log(GPR_INFO, "Write done callback called");
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
gpr_log(GPR_INFO, "Signalling write done");
state->write_done = 1;
- grpc_pollset_kick(&g_pollset, NULL);
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ grpc_pollset_kick(g_pollset, NULL);
+ gpr_mu_unlock(g_mu);
}
void drain_socket_blocking(int fd, size_t num_bytes, size_t read_size) {
@@ -303,12 +304,12 @@ void drain_socket_blocking(int fd, size_t num_bytes, size_t read_size) {
GPR_ASSERT(fcntl(fd, F_SETFL, flags & ~O_NONBLOCK) == 0);
for (;;) {
- grpc_pollset_worker worker;
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
- grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+ grpc_pollset_worker *worker = NULL;
+ gpr_mu_lock(g_mu);
+ grpc_pollset_work(&exec_ctx, g_pollset, &worker,
gpr_now(GPR_CLOCK_MONOTONIC),
GRPC_TIMEOUT_MILLIS_TO_DEADLINE(10));
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
grpc_exec_ctx_finish(&exec_ctx);
do {
bytes_read =
@@ -350,7 +351,7 @@ static void write_test(size_t num_bytes, size_t slice_size) {
ep = grpc_tcp_create(grpc_fd_create(sv[1], "write_test"),
GRPC_TCP_DEFAULT_READ_SLICE_SIZE, "test");
- grpc_endpoint_add_to_pollset(&exec_ctx, ep, &g_pollset);
+ grpc_endpoint_add_to_pollset(&exec_ctx, ep, g_pollset);
state.ep = ep;
state.write_done = 0;
@@ -363,19 +364,19 @@ static void write_test(size_t num_bytes, size_t slice_size) {
grpc_endpoint_write(&exec_ctx, ep, &outgoing, &write_done_closure);
drain_socket_blocking(sv[0], num_bytes, num_bytes);
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
for (;;) {
- grpc_pollset_worker worker;
+ grpc_pollset_worker *worker = NULL;
if (state.write_done) {
break;
}
- grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+ grpc_pollset_work(&exec_ctx, g_pollset, &worker,
gpr_now(GPR_CLOCK_MONOTONIC), deadline);
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
grpc_exec_ctx_finish(&exec_ctx);
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
}
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
gpr_slice_buffer_destroy(&outgoing);
grpc_endpoint_destroy(&exec_ctx, ep);
@@ -386,7 +387,7 @@ static void write_test(size_t num_bytes, size_t slice_size) {
void on_fd_released(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
int *done = arg;
*done = 1;
- grpc_pollset_kick(&g_pollset, NULL);
+ grpc_pollset_kick(g_pollset, NULL);
}
/* Do a read_test, then release fd and try to read/write again. Verify that
@@ -410,7 +411,7 @@ static void release_fd_test(size_t num_bytes, size_t slice_size) {
ep = grpc_tcp_create(grpc_fd_create(sv[1], "read_test"), slice_size, "test");
GPR_ASSERT(grpc_tcp_fd(ep) == sv[1] && sv[1] >= 0);
- grpc_endpoint_add_to_pollset(&exec_ctx, ep, &g_pollset);
+ grpc_endpoint_add_to_pollset(&exec_ctx, ep, g_pollset);
written_bytes = fill_socket_partial(sv[0], num_bytes);
gpr_log(GPR_INFO, "Wrote %d bytes", written_bytes);
@@ -423,27 +424,27 @@ static void release_fd_test(size_t num_bytes, size_t slice_size) {
grpc_endpoint_read(&exec_ctx, ep, &state.incoming, &state.read_cb);
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
while (state.read_bytes < state.target_read_bytes) {
- grpc_pollset_worker worker;
- grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+ grpc_pollset_worker *worker = NULL;
+ grpc_pollset_work(&exec_ctx, g_pollset, &worker,
gpr_now(GPR_CLOCK_MONOTONIC), deadline);
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
grpc_exec_ctx_finish(&exec_ctx);
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
}
GPR_ASSERT(state.read_bytes == state.target_read_bytes);
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
gpr_slice_buffer_destroy(&state.incoming);
grpc_tcp_destroy_and_release_fd(&exec_ctx, ep, &fd, &fd_released_cb);
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
while (!fd_released_done) {
- grpc_pollset_worker worker;
- grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+ grpc_pollset_worker *worker = NULL;
+ grpc_pollset_work(&exec_ctx, g_pollset, &worker,
gpr_now(GPR_CLOCK_MONOTONIC), deadline);
}
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
GPR_ASSERT(fd_released_done == 1);
GPR_ASSERT(fd == sv[1]);
grpc_exec_ctx_finish(&exec_ctx);
@@ -491,8 +492,8 @@ static grpc_endpoint_test_fixture create_fixture_tcp_socketpair(
slice_size, "test");
f.server_ep = grpc_tcp_create(grpc_fd_create(sv[1], "fixture:server"),
slice_size, "test");
- grpc_endpoint_add_to_pollset(&exec_ctx, f.client_ep, &g_pollset);
- grpc_endpoint_add_to_pollset(&exec_ctx, f.server_ep, &g_pollset);
+ grpc_endpoint_add_to_pollset(&exec_ctx, f.client_ep, g_pollset);
+ grpc_endpoint_add_to_pollset(&exec_ctx, f.server_ep, g_pollset);
grpc_exec_ctx_finish(&exec_ctx);
@@ -512,13 +513,15 @@ int main(int argc, char **argv) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_test_init(argc, argv);
grpc_init();
- grpc_pollset_init(&g_pollset);
+ g_pollset = gpr_malloc(grpc_pollset_size());
+ grpc_pollset_init(g_pollset, &g_mu);
run_tests();
- grpc_endpoint_tests(configs[0], &g_pollset);
- grpc_closure_init(&destroyed, destroy_pollset, &g_pollset);
- grpc_pollset_shutdown(&exec_ctx, &g_pollset, &destroyed);
+ grpc_endpoint_tests(configs[0], g_pollset, g_mu);
+ grpc_closure_init(&destroyed, destroy_pollset, g_pollset);
+ grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
grpc_exec_ctx_finish(&exec_ctx);
grpc_shutdown();
+ gpr_free(g_pollset);
return 0;
}
diff --git a/test/core/iomgr/tcp_server_posix_test.c b/test/core/iomgr/tcp_server_posix_test.c
index 272d97bfcb..7933468355 100644
--- a/test/core/iomgr/tcp_server_posix_test.c
+++ b/test/core/iomgr/tcp_server_posix_test.c
@@ -32,24 +32,28 @@
*/
#include "src/core/iomgr/tcp_server.h"
-#include "src/core/iomgr/iomgr.h"
-#include "src/core/iomgr/sockaddr_utils.h"
+
+#include <errno.h>
+#include <netinet/in.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
#include <grpc/support/time.h>
+
+#include "src/core/iomgr/iomgr.h"
+#include "src/core/iomgr/sockaddr_utils.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
-#include <errno.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <unistd.h>
-
#define LOG_TEST(x) gpr_log(GPR_INFO, "%s", #x)
-static grpc_pollset g_pollset;
+static gpr_mu *g_mu;
+static grpc_pollset *g_pollset;
static int g_nconnects = 0;
typedef struct on_connect_result {
@@ -113,11 +117,11 @@ static void on_connect(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *tcp,
grpc_endpoint_shutdown(exec_ctx, tcp);
grpc_endpoint_destroy(exec_ctx, tcp);
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
on_connect_result_set(&g_result, acceptor);
g_nconnects++;
- grpc_pollset_kick(&g_pollset, NULL);
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ grpc_pollset_kick(g_pollset, NULL);
+ gpr_mu_unlock(g_mu);
}
static void test_no_op(void) {
@@ -174,7 +178,7 @@ static void tcp_connect(grpc_exec_ctx *exec_ctx, const struct sockaddr *remote,
int clifd = socket(remote->sa_family, SOCK_STREAM, 0);
int nconnects_before;
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
nconnects_before = g_nconnects;
on_connect_result_init(&g_result);
GPR_ASSERT(clifd >= 0);
@@ -183,19 +187,19 @@ static void tcp_connect(grpc_exec_ctx *exec_ctx, const struct sockaddr *remote,
gpr_log(GPR_DEBUG, "wait");
while (g_nconnects == nconnects_before &&
gpr_time_cmp(deadline, gpr_now(deadline.clock_type)) > 0) {
- grpc_pollset_worker worker;
- grpc_pollset_work(exec_ctx, &g_pollset, &worker,
+ grpc_pollset_worker *worker = NULL;
+ grpc_pollset_work(exec_ctx, g_pollset, &worker,
gpr_now(GPR_CLOCK_MONOTONIC), deadline);
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
grpc_exec_ctx_finish(exec_ctx);
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
}
gpr_log(GPR_DEBUG, "wait done");
GPR_ASSERT(g_nconnects == nconnects_before + 1);
close(clifd);
*result = g_result;
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_unlock(g_mu);
}
/* Tests a tcp server with multiple ports. TODO(daniel-j-born): Multiple fds for
@@ -210,7 +214,6 @@ static void test_connect(unsigned n) {
unsigned svr1_fd_count;
int svr1_port;
grpc_tcp_server *s = grpc_tcp_server_create(NULL);
- grpc_pollset *pollsets[1];
unsigned i;
server_weak_ref weak_ref;
server_weak_ref_init(&weak_ref);
@@ -259,8 +262,7 @@ static void test_connect(unsigned n) {
}
}
- pollsets[0] = &g_pollset;
- grpc_tcp_server_start(&exec_ctx, s, pollsets, 1, on_connect, NULL);
+ grpc_tcp_server_start(&exec_ctx, s, &g_pollset, 1, on_connect, NULL);
for (i = 0; i < n; i++) {
on_connect_result result;
@@ -312,7 +314,8 @@ int main(int argc, char **argv) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_test_init(argc, argv);
grpc_init();
- grpc_pollset_init(&g_pollset);
+ g_pollset = gpr_malloc(grpc_pollset_size());
+ grpc_pollset_init(g_pollset, &g_mu);
test_no_op();
test_no_op_with_start();
@@ -321,9 +324,10 @@ int main(int argc, char **argv) {
test_connect(1);
test_connect(10);
- grpc_closure_init(&destroyed, destroy_pollset, &g_pollset);
- grpc_pollset_shutdown(&exec_ctx, &g_pollset, &destroyed);
+ grpc_closure_init(&destroyed, destroy_pollset, g_pollset);
+ grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
grpc_exec_ctx_finish(&exec_ctx);
grpc_shutdown();
+ gpr_free(g_pollset);
return 0;
}
diff --git a/test/core/iomgr/workqueue_test.c b/test/core/iomgr/workqueue_test.c
index 500170b542..8a1faf6303 100644
--- a/test/core/iomgr/workqueue_test.c
+++ b/test/core/iomgr/workqueue_test.c
@@ -34,18 +34,20 @@
#include "src/core/iomgr/workqueue.h"
#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "test/core/util/test_config.h"
-static grpc_pollset g_pollset;
+static gpr_mu *g_mu;
+static grpc_pollset *g_pollset;
static void must_succeed(grpc_exec_ctx *exec_ctx, void *p, bool success) {
GPR_ASSERT(success == 1);
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
*(int *)p = 1;
- grpc_pollset_kick(&g_pollset, NULL);
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ grpc_pollset_kick(g_pollset, NULL);
+ gpr_mu_unlock(g_mu);
}
static void test_ref_unref(void) {
@@ -63,17 +65,17 @@ static void test_add_closure(void) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_workqueue *wq = grpc_workqueue_create(&exec_ctx);
gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5);
- grpc_pollset_worker worker;
+ grpc_pollset_worker *worker = NULL;
grpc_closure_init(&c, must_succeed, &done);
grpc_workqueue_push(wq, &c, 1);
- grpc_workqueue_add_to_pollset(&exec_ctx, wq, &g_pollset);
+ grpc_workqueue_add_to_pollset(&exec_ctx, wq, g_pollset);
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
GPR_ASSERT(!done);
- grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
- gpr_now(deadline.clock_type), deadline);
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ grpc_pollset_work(&exec_ctx, g_pollset, &worker, gpr_now(deadline.clock_type),
+ deadline);
+ gpr_mu_unlock(g_mu);
grpc_exec_ctx_finish(&exec_ctx);
GPR_ASSERT(done);
@@ -87,18 +89,18 @@ static void test_flush(void) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_workqueue *wq = grpc_workqueue_create(&exec_ctx);
gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5);
- grpc_pollset_worker worker;
+ grpc_pollset_worker *worker = NULL;
grpc_closure_init(&c, must_succeed, &done);
grpc_exec_ctx_enqueue(&exec_ctx, &c, true, NULL);
grpc_workqueue_flush(&exec_ctx, wq);
- grpc_workqueue_add_to_pollset(&exec_ctx, wq, &g_pollset);
+ grpc_workqueue_add_to_pollset(&exec_ctx, wq, g_pollset);
- gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ gpr_mu_lock(g_mu);
GPR_ASSERT(!done);
- grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
- gpr_now(deadline.clock_type), deadline);
- gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ grpc_pollset_work(&exec_ctx, g_pollset, &worker, gpr_now(deadline.clock_type),
+ deadline);
+ gpr_mu_unlock(g_mu);
grpc_exec_ctx_finish(&exec_ctx);
GPR_ASSERT(done);
@@ -115,15 +117,18 @@ int main(int argc, char **argv) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_test_init(argc, argv);
grpc_init();
- grpc_pollset_init(&g_pollset);
+ g_pollset = gpr_malloc(grpc_pollset_size());
+ grpc_pollset_init(g_pollset, &g_mu);
test_ref_unref();
test_add_closure();
test_flush();
- grpc_closure_init(&destroyed, destroy_pollset, &g_pollset);
- grpc_pollset_shutdown(&exec_ctx, &g_pollset, &destroyed);
+ grpc_closure_init(&destroyed, destroy_pollset, g_pollset);
+ grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
grpc_exec_ctx_finish(&exec_ctx);
grpc_shutdown();
+
+ gpr_free(g_pollset);
return 0;
}
diff --git a/test/core/security/oauth2_utils.c b/test/core/security/oauth2_utils.c
index 55ac31e62c..9b70afffe1 100644
--- a/test/core/security/oauth2_utils.c
+++ b/test/core/security/oauth2_utils.c
@@ -45,7 +45,8 @@
#include "src/core/security/credentials.h"
typedef struct {
- grpc_pollset pollset;
+ gpr_mu *mu;
+ grpc_pollset *pollset;
int is_done;
char *token;
} oauth2_request;
@@ -66,11 +67,11 @@ static void on_oauth2_response(grpc_exec_ctx *exec_ctx, void *user_data,
GPR_SLICE_LENGTH(token_slice));
token[GPR_SLICE_LENGTH(token_slice)] = '\0';
}
- gpr_mu_lock(GRPC_POLLSET_MU(&request->pollset));
+ gpr_mu_lock(request->mu);
request->is_done = 1;
request->token = token;
- grpc_pollset_kick(&request->pollset, NULL);
- gpr_mu_unlock(GRPC_POLLSET_MU(&request->pollset));
+ grpc_pollset_kick(request->pollset, NULL);
+ gpr_mu_unlock(request->mu);
}
static void do_nothing(grpc_exec_ctx *exec_ctx, void *unused, bool success) {}
@@ -82,28 +83,30 @@ char *grpc_test_fetch_oauth2_token_with_credentials(
grpc_closure do_nothing_closure;
grpc_auth_metadata_context null_ctx = {"", "", NULL, NULL};
- grpc_pollset_init(&request.pollset);
+ request.pollset = gpr_malloc(grpc_pollset_size());
+ grpc_pollset_init(request.pollset, &request.mu);
request.is_done = 0;
grpc_closure_init(&do_nothing_closure, do_nothing, NULL);
- grpc_call_credentials_get_request_metadata(&exec_ctx, creds, &request.pollset,
+ grpc_call_credentials_get_request_metadata(&exec_ctx, creds, request.pollset,
null_ctx, on_oauth2_response,
&request);
grpc_exec_ctx_finish(&exec_ctx);
- gpr_mu_lock(GRPC_POLLSET_MU(&request.pollset));
+ gpr_mu_lock(request.mu);
while (!request.is_done) {
- grpc_pollset_worker worker;
- grpc_pollset_work(&exec_ctx, &request.pollset, &worker,
+ grpc_pollset_worker *worker = NULL;
+ grpc_pollset_work(&exec_ctx, request.pollset, &worker,
gpr_now(GPR_CLOCK_MONOTONIC),
gpr_inf_future(GPR_CLOCK_MONOTONIC));
}
- gpr_mu_unlock(GRPC_POLLSET_MU(&request.pollset));
+ gpr_mu_unlock(request.mu);
- grpc_pollset_shutdown(&exec_ctx, &request.pollset, &do_nothing_closure);
+ grpc_pollset_shutdown(&exec_ctx, request.pollset, &do_nothing_closure);
grpc_exec_ctx_finish(&exec_ctx);
- grpc_pollset_destroy(&request.pollset);
+ grpc_pollset_destroy(request.pollset);
+ gpr_free(request.pollset);
return request.token;
}
diff --git a/test/core/security/print_google_default_creds_token.c b/test/core/security/print_google_default_creds_token.c
index 50fe61c996..09673f362c 100644
--- a/test/core/security/print_google_default_creds_token.c
+++ b/test/core/security/print_google_default_creds_token.c
@@ -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,8 +34,6 @@
#include <stdio.h>
#include <string.h>
-#include "src/core/security/credentials.h"
-#include "src/core/support/string.h"
#include <grpc/grpc.h>
#include <grpc/grpc_security.h>
#include <grpc/support/alloc.h>
@@ -44,8 +42,12 @@
#include <grpc/support/slice.h>
#include <grpc/support/sync.h>
+#include "src/core/security/credentials.h"
+#include "src/core/support/string.h"
+
typedef struct {
- grpc_pollset pollset;
+ gpr_mu *mu;
+ grpc_pollset *pollset;
int is_done;
} synchronizer;
@@ -62,10 +64,10 @@ static void on_metadata_response(grpc_exec_ctx *exec_ctx, void *user_data,
printf("\nGot token: %s\n\n", token);
gpr_free(token);
}
- gpr_mu_lock(GRPC_POLLSET_MU(&sync->pollset));
+ gpr_mu_lock(sync->mu);
sync->is_done = 1;
- grpc_pollset_kick(&sync->pollset, NULL);
- gpr_mu_unlock(GRPC_POLLSET_MU(&sync->pollset));
+ grpc_pollset_kick(sync->pollset, NULL);
+ gpr_mu_unlock(sync->mu);
}
int main(int argc, char **argv) {
@@ -91,26 +93,30 @@ int main(int argc, char **argv) {
goto end;
}
- grpc_pollset_init(&sync.pollset);
+ sync.pollset = gpr_malloc(grpc_pollset_size());
+ grpc_pollset_init(sync.pollset, &sync.mu);
sync.is_done = 0;
grpc_call_credentials_get_request_metadata(
&exec_ctx, ((grpc_composite_channel_credentials *)creds)->call_creds,
- &sync.pollset, context, on_metadata_response, &sync);
+ sync.pollset, context, on_metadata_response, &sync);
- gpr_mu_lock(GRPC_POLLSET_MU(&sync.pollset));
+ gpr_mu_lock(sync.mu);
while (!sync.is_done) {
- grpc_pollset_worker worker;
- grpc_pollset_work(&exec_ctx, &sync.pollset, &worker,
+ grpc_pollset_worker *worker = NULL;
+ grpc_pollset_work(&exec_ctx, sync.pollset, &worker,
gpr_now(GPR_CLOCK_MONOTONIC),
gpr_inf_future(GPR_CLOCK_MONOTONIC));
- gpr_mu_unlock(GRPC_POLLSET_MU(&sync.pollset));
- grpc_exec_ctx_finish(&exec_ctx);
- gpr_mu_lock(GRPC_POLLSET_MU(&sync.pollset));
+ gpr_mu_unlock(sync.mu);
+ grpc_exec_ctx_flush(&exec_ctx);
+ gpr_mu_lock(sync.mu);
}
- gpr_mu_unlock(GRPC_POLLSET_MU(&sync.pollset));
+ gpr_mu_unlock(sync.mu);
+
+ grpc_exec_ctx_finish(&exec_ctx);
grpc_channel_credentials_release(creds);
+ gpr_free(sync.pollset);
end:
gpr_cmdline_destroy(cl);
diff --git a/test/core/security/secure_endpoint_test.c b/test/core/security/secure_endpoint_test.c
index fb4bd30e2d..0e8c38a53e 100644
--- a/test/core/security/secure_endpoint_test.c
+++ b/test/core/security/secure_endpoint_test.c
@@ -36,16 +36,17 @@
#include <fcntl.h>
#include <sys/types.h>
-#include "src/core/security/secure_endpoint.h"
-#include "src/core/iomgr/endpoint_pair.h"
-#include "src/core/iomgr/iomgr.h"
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
-#include "test/core/util/test_config.h"
+#include "src/core/iomgr/endpoint_pair.h"
+#include "src/core/iomgr/iomgr.h"
+#include "src/core/security/secure_endpoint.h"
#include "src/core/tsi/fake_transport_security.h"
+#include "test/core/util/test_config.h"
-static grpc_pollset g_pollset;
+static gpr_mu *g_mu;
+static grpc_pollset *g_pollset;
static grpc_endpoint_test_fixture secure_endpoint_create_fixture_tcp_socketpair(
size_t slice_size, gpr_slice *leftover_slices, size_t leftover_nslices) {
@@ -56,8 +57,8 @@ static grpc_endpoint_test_fixture secure_endpoint_create_fixture_tcp_socketpair(
grpc_endpoint_pair tcp;
tcp = grpc_iomgr_create_endpoint_pair("fixture", slice_size);
- grpc_endpoint_add_to_pollset(&exec_ctx, tcp.client, &g_pollset);
- grpc_endpoint_add_to_pollset(&exec_ctx, tcp.server, &g_pollset);
+ grpc_endpoint_add_to_pollset(&exec_ctx, tcp.client, g_pollset);
+ grpc_endpoint_add_to_pollset(&exec_ctx, tcp.server, g_pollset);
if (leftover_nslices == 0) {
f.client_ep =
@@ -181,13 +182,16 @@ int main(int argc, char **argv) {
grpc_test_init(argc, argv);
grpc_init();
- grpc_pollset_init(&g_pollset);
- grpc_endpoint_tests(configs[0], &g_pollset);
+ g_pollset = gpr_malloc(grpc_pollset_size());
+ grpc_pollset_init(g_pollset, &g_mu);
+ grpc_endpoint_tests(configs[0], g_pollset, g_mu);
test_leftover(configs[1], 1);
- grpc_closure_init(&destroyed, destroy_pollset, &g_pollset);
- grpc_pollset_shutdown(&exec_ctx, &g_pollset, &destroyed);
+ grpc_closure_init(&destroyed, destroy_pollset, g_pollset);
+ grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
grpc_exec_ctx_finish(&exec_ctx);
grpc_shutdown();
+ gpr_free(g_pollset);
+
return 0;
}
diff --git a/test/core/security/verify_jwt.c b/test/core/security/verify_jwt.c
index 378a37f26c..eb86589681 100644
--- a/test/core/security/verify_jwt.c
+++ b/test/core/security/verify_jwt.c
@@ -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,7 +34,6 @@
#include <stdio.h>
#include <string.h>
-#include "src/core/security/jwt_verifier.h"
#include <grpc/grpc.h>
#include <grpc/grpc_security.h>
#include <grpc/support/alloc.h>
@@ -43,8 +42,11 @@
#include <grpc/support/slice.h>
#include <grpc/support/sync.h>
+#include "src/core/security/jwt_verifier.h"
+
typedef struct {
- grpc_pollset pollset;
+ grpc_pollset *pollset;
+ gpr_mu *mu;
int is_done;
int success;
} synchronizer;
@@ -77,10 +79,10 @@ static void on_jwt_verification_done(void *user_data,
grpc_jwt_verifier_status_to_string(status));
}
- gpr_mu_lock(GRPC_POLLSET_MU(&sync->pollset));
+ gpr_mu_lock(sync->mu);
sync->is_done = 1;
- grpc_pollset_kick(&sync->pollset, NULL);
- gpr_mu_unlock(GRPC_POLLSET_MU(&sync->pollset));
+ grpc_pollset_kick(sync->pollset, NULL);
+ gpr_mu_unlock(sync->mu);
}
int main(int argc, char **argv) {
@@ -103,23 +105,26 @@ int main(int argc, char **argv) {
grpc_init();
- grpc_pollset_init(&sync.pollset);
+ sync.pollset = gpr_malloc(grpc_pollset_size());
+ grpc_pollset_init(sync.pollset, &sync.mu);
sync.is_done = 0;
- grpc_jwt_verifier_verify(&exec_ctx, verifier, &sync.pollset, jwt, aud,
+ grpc_jwt_verifier_verify(&exec_ctx, verifier, sync.pollset, jwt, aud,
on_jwt_verification_done, &sync);
- gpr_mu_lock(GRPC_POLLSET_MU(&sync.pollset));
+ gpr_mu_lock(sync.mu);
while (!sync.is_done) {
- grpc_pollset_worker worker;
- grpc_pollset_work(&exec_ctx, &sync.pollset, &worker,
+ grpc_pollset_worker *worker = NULL;
+ grpc_pollset_work(&exec_ctx, sync.pollset, &worker,
gpr_now(GPR_CLOCK_MONOTONIC),
gpr_inf_future(GPR_CLOCK_MONOTONIC));
- gpr_mu_unlock(GRPC_POLLSET_MU(&sync.pollset));
+ gpr_mu_unlock(sync.mu);
grpc_exec_ctx_finish(&exec_ctx);
- gpr_mu_lock(GRPC_POLLSET_MU(&sync.pollset));
+ gpr_mu_lock(sync.mu);
}
- gpr_mu_unlock(GRPC_POLLSET_MU(&sync.pollset));
+ gpr_mu_unlock(sync.mu);
+
+ gpr_free(sync.pollset);
grpc_jwt_verifier_destroy(verifier);
gpr_cmdline_destroy(cl);
diff --git a/test/core/util/port_posix.c b/test/core/util/port_posix.c
index 4b31f810e5..ba382d242a 100644
--- a/test/core/util/port_posix.c
+++ b/test/core/util/port_posix.c
@@ -69,7 +69,8 @@ static int has_port_been_chosen(int port) {
}
typedef struct freereq {
- grpc_pollset pollset;
+ gpr_mu *mu;
+ grpc_pollset *pollset;
int done;
} freereq;
@@ -82,10 +83,10 @@ static void destroy_pollset_and_shutdown(grpc_exec_ctx *exec_ctx, void *p,
static void freed_port_from_server(grpc_exec_ctx *exec_ctx, void *arg,
const grpc_httpcli_response *response) {
freereq *pr = arg;
- gpr_mu_lock(GRPC_POLLSET_MU(&pr->pollset));
+ gpr_mu_lock(pr->mu);
pr->done = 1;
- grpc_pollset_kick(&pr->pollset, NULL);
- gpr_mu_unlock(GRPC_POLLSET_MU(&pr->pollset));
+ grpc_pollset_kick(pr->pollset, NULL);
+ gpr_mu_unlock(pr->mu);
}
static void free_port_using_server(char *server, int port) {
@@ -100,31 +101,34 @@ static void free_port_using_server(char *server, int port) {
memset(&pr, 0, sizeof(pr));
memset(&req, 0, sizeof(req));
- grpc_pollset_init(&pr.pollset);
+
+ pr.pollset = gpr_malloc(grpc_pollset_size());
+ grpc_pollset_init(pr.pollset, &pr.mu);
grpc_closure_init(&shutdown_closure, destroy_pollset_and_shutdown,
- &pr.pollset);
+ pr.pollset);
req.host = server;
gpr_asprintf(&path, "/drop/%d", port);
req.path = path;
grpc_httpcli_context_init(&context);
- grpc_httpcli_get(&exec_ctx, &context, &pr.pollset, &req,
+ grpc_httpcli_get(&exec_ctx, &context, pr.pollset, &req,
GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10), freed_port_from_server,
&pr);
- gpr_mu_lock(GRPC_POLLSET_MU(&pr.pollset));
+ gpr_mu_lock(pr.mu);
while (!pr.done) {
- grpc_pollset_worker worker;
- grpc_pollset_work(&exec_ctx, &pr.pollset, &worker,
+ grpc_pollset_worker *worker = NULL;
+ grpc_pollset_work(&exec_ctx, pr.pollset, &worker,
gpr_now(GPR_CLOCK_MONOTONIC),
GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1));
}
- gpr_mu_unlock(GRPC_POLLSET_MU(&pr.pollset));
+ gpr_mu_unlock(pr.mu);
grpc_httpcli_context_destroy(&context);
grpc_exec_ctx_finish(&exec_ctx);
- grpc_pollset_shutdown(&exec_ctx, &pr.pollset, &shutdown_closure);
+ grpc_pollset_shutdown(&exec_ctx, pr.pollset, &shutdown_closure);
grpc_exec_ctx_finish(&exec_ctx);
+ gpr_free(pr.pollset);
gpr_free(path);
}
@@ -202,7 +206,8 @@ static int is_port_available(int *port, int is_tcp) {
}
typedef struct portreq {
- grpc_pollset pollset;
+ gpr_mu *mu;
+ grpc_pollset *pollset;
int port;
int retries;
char *server;
@@ -234,7 +239,7 @@ static void got_port_from_server(grpc_exec_ctx *exec_ctx, void *arg,
pr->retries++;
req.host = pr->server;
req.path = "/get";
- grpc_httpcli_get(exec_ctx, pr->ctx, &pr->pollset, &req,
+ grpc_httpcli_get(exec_ctx, pr->ctx, pr->pollset, &req,
GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10), got_port_from_server,
pr);
return;
@@ -246,10 +251,10 @@ static void got_port_from_server(grpc_exec_ctx *exec_ctx, void *arg,
port = port * 10 + response->body[i] - '0';
}
GPR_ASSERT(port > 1024);
- gpr_mu_lock(GRPC_POLLSET_MU(&pr->pollset));
+ gpr_mu_lock(pr->mu);
pr->port = port;
- grpc_pollset_kick(&pr->pollset, NULL);
- gpr_mu_unlock(GRPC_POLLSET_MU(&pr->pollset));
+ grpc_pollset_kick(pr->pollset, NULL);
+ gpr_mu_unlock(pr->mu);
}
static int pick_port_using_server(char *server) {
@@ -263,9 +268,10 @@ static int pick_port_using_server(char *server) {
memset(&pr, 0, sizeof(pr));
memset(&req, 0, sizeof(req));
- grpc_pollset_init(&pr.pollset);
+ pr.pollset = gpr_malloc(grpc_pollset_size());
+ grpc_pollset_init(pr.pollset, &pr.mu);
grpc_closure_init(&shutdown_closure, destroy_pollset_and_shutdown,
- &pr.pollset);
+ pr.pollset);
pr.port = -1;
pr.server = server;
pr.ctx = &context;
@@ -274,22 +280,23 @@ static int pick_port_using_server(char *server) {
req.path = "/get";
grpc_httpcli_context_init(&context);
- grpc_httpcli_get(&exec_ctx, &context, &pr.pollset, &req,
+ grpc_httpcli_get(&exec_ctx, &context, pr.pollset, &req,
GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10), got_port_from_server,
&pr);
grpc_exec_ctx_finish(&exec_ctx);
- gpr_mu_lock(GRPC_POLLSET_MU(&pr.pollset));
+ gpr_mu_lock(pr.mu);
while (pr.port == -1) {
- grpc_pollset_worker worker;
- grpc_pollset_work(&exec_ctx, &pr.pollset, &worker,
+ grpc_pollset_worker *worker = NULL;
+ grpc_pollset_work(&exec_ctx, pr.pollset, &worker,
gpr_now(GPR_CLOCK_MONOTONIC),
GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1));
}
- gpr_mu_unlock(GRPC_POLLSET_MU(&pr.pollset));
+ gpr_mu_unlock(pr.mu);
grpc_httpcli_context_destroy(&context);
- grpc_pollset_shutdown(&exec_ctx, &pr.pollset, &shutdown_closure);
+ grpc_pollset_shutdown(&exec_ctx, pr.pollset, &shutdown_closure);
grpc_exec_ctx_finish(&exec_ctx);
+ gpr_free(pr.pollset);
return pr.port;
}
diff --git a/test/core/util/port_windows.c b/test/core/util/port_windows.c
index 85d7c0ce07..3b20aeb718 100644
--- a/test/core/util/port_windows.c
+++ b/test/core/util/port_windows.c
@@ -129,7 +129,8 @@ static int is_port_available(int *port, int is_tcp) {
}
typedef struct portreq {
- grpc_pollset pollset;
+ grpc_pollset *pollset;
+ gpr_mu *mu;
int port;
} portreq;
@@ -145,10 +146,10 @@ static void got_port_from_server(grpc_exec_ctx *exec_ctx, void *arg,
port = port * 10 + response->body[i] - '0';
}
GPR_ASSERT(port > 1024);
- gpr_mu_lock(GRPC_POLLSET_MU(&pr->pollset));
+ gpr_mu_lock(pr->mu);
pr->port = port;
- grpc_pollset_kick(&pr->pollset, NULL);
- gpr_mu_unlock(GRPC_POLLSET_MU(&pr->pollset));
+ grpc_pollset_kick(pr->pollset, NULL);
+ gpr_mu_unlock(pr->mu);
}
static void destroy_pollset_and_shutdown(grpc_exec_ctx *exec_ctx, void *p,
@@ -168,32 +169,34 @@ static int pick_port_using_server(char *server) {
memset(&pr, 0, sizeof(pr));
memset(&req, 0, sizeof(req));
- grpc_pollset_init(&pr.pollset);
+ pr.pollset = gpr_malloc(grpc_pollset_size());
+ grpc_pollset_init(pr.pollset, &pr.mu);
pr.port = -1;
req.host = server;
req.path = "/get";
grpc_httpcli_context_init(&context);
- grpc_httpcli_get(&exec_ctx, &context, &pr.pollset, &req,
+ grpc_httpcli_get(&exec_ctx, &context, pr.pollset, &req,
GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10), got_port_from_server,
&pr);
- gpr_mu_lock(GRPC_POLLSET_MU(&pr.pollset));
+ gpr_mu_lock(pr.mu);
while (pr.port == -1) {
- grpc_pollset_worker worker;
- grpc_pollset_work(&exec_ctx, &pr.pollset, &worker,
+ grpc_pollset_worker *worker = NULL;
+ grpc_pollset_work(&exec_ctx, pr.pollset, &worker,
gpr_now(GPR_CLOCK_MONOTONIC),
GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1));
- gpr_mu_unlock(GRPC_POLLSET_MU(&pr.pollset));
+ gpr_mu_unlock(pr.mu);
grpc_exec_ctx_flush(&exec_ctx);
- gpr_mu_lock(GRPC_POLLSET_MU(&pr.pollset));
+ gpr_mu_lock(pr.mu);
}
- gpr_mu_unlock(GRPC_POLLSET_MU(&pr.pollset));
+ gpr_mu_unlock(pr.mu);
grpc_httpcli_context_destroy(&context);
grpc_closure_init(&destroy_pollset_closure, destroy_pollset_and_shutdown,
&pr.pollset);
- grpc_pollset_shutdown(&exec_ctx, &pr.pollset, &destroy_pollset_closure);
+ grpc_pollset_shutdown(&exec_ctx, pr.pollset, &destroy_pollset_closure);
+ gpr_free(pr.pollset);
grpc_exec_ctx_finish(&exec_ctx);
return pr.port;
diff --git a/test/core/util/test_tcp_server.c b/test/core/util/test_tcp_server.c
index 66470c0288..ab379441d8 100644
--- a/test/core/util/test_tcp_server.c
+++ b/test/core/util/test_tcp_server.c
@@ -57,8 +57,8 @@ void test_tcp_server_init(test_tcp_server *server,
server->tcp_server = NULL;
grpc_closure_init(&server->shutdown_complete, on_server_destroyed, server);
server->shutdown = 0;
- grpc_pollset_init(&server->pollset);
- server->pollsets[0] = &server->pollset;
+ server->pollset = gpr_malloc(grpc_pollset_size());
+ grpc_pollset_init(server->pollset, &server->mu);
server->on_connect = on_connect;
server->cb_data = user_data;
}
@@ -77,7 +77,7 @@ void test_tcp_server_start(test_tcp_server *server, int port) {
grpc_tcp_server_add_port(server->tcp_server, &addr, sizeof(addr));
GPR_ASSERT(port_added == port);
- grpc_tcp_server_start(&exec_ctx, server->tcp_server, server->pollsets, 1,
+ grpc_tcp_server_start(&exec_ctx, server->tcp_server, &server->pollset, 1,
server->on_connect, server->cb_data);
gpr_log(GPR_INFO, "test tcp server listening on 0.0.0.0:%d", port);
@@ -85,15 +85,15 @@ void test_tcp_server_start(test_tcp_server *server, int port) {
}
void test_tcp_server_poll(test_tcp_server *server, int seconds) {
- grpc_pollset_worker worker;
+ grpc_pollset_worker *worker = NULL;
gpr_timespec deadline =
gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
gpr_time_from_seconds(seconds, GPR_TIMESPAN));
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
- gpr_mu_lock(GRPC_POLLSET_MU(&server->pollset));
- grpc_pollset_work(&exec_ctx, &server->pollset, &worker,
+ gpr_mu_lock(server->mu);
+ grpc_pollset_work(&exec_ctx, server->pollset, &worker,
gpr_now(GPR_CLOCK_MONOTONIC), deadline);
- gpr_mu_unlock(GRPC_POLLSET_MU(&server->pollset));
+ gpr_mu_unlock(server->mu);
grpc_exec_ctx_finish(&exec_ctx);
}
@@ -111,8 +111,9 @@ void test_tcp_server_destroy(test_tcp_server *server) {
gpr_time_cmp(gpr_now(GPR_CLOCK_MONOTONIC), shutdown_deadline) < 0) {
test_tcp_server_poll(server, 1);
}
- grpc_pollset_shutdown(&exec_ctx, &server->pollset, &do_nothing_cb);
+ grpc_pollset_shutdown(&exec_ctx, server->pollset, &do_nothing_cb);
grpc_exec_ctx_finish(&exec_ctx);
- grpc_pollset_destroy(&server->pollset);
+ grpc_pollset_destroy(server->pollset);
+ gpr_free(server->pollset);
grpc_shutdown();
}
diff --git a/test/core/util/test_tcp_server.h b/test/core/util/test_tcp_server.h
index 51119cf6c8..15fcb4fb87 100644
--- a/test/core/util/test_tcp_server.h
+++ b/test/core/util/test_tcp_server.h
@@ -41,8 +41,8 @@ typedef struct test_tcp_server {
grpc_tcp_server *tcp_server;
grpc_closure shutdown_complete;
int shutdown;
- grpc_pollset pollset;
- grpc_pollset *pollsets[1];
+ gpr_mu *mu;
+ grpc_pollset *pollset;
grpc_tcp_server_cb on_connect;
void *cb_data;
} test_tcp_server;
diff --git a/test/cpp/common/alarm_cpp_test.cc b/test/cpp/common/alarm_cpp_test.cc
index 5d7344046c..d4381c0515 100644
--- a/test/cpp/common/alarm_cpp_test.cc
+++ b/test/cpp/common/alarm_cpp_test.cc
@@ -55,6 +55,23 @@ TEST(AlarmTest, RegularExpiry) {
EXPECT_EQ(junk, output_tag);
}
+TEST(AlarmTest, RegularExpiryChrono) {
+ CompletionQueue cq;
+ void* junk = reinterpret_cast<void*>(1618033);
+ std::chrono::system_clock::time_point one_sec_deadline =
+ std::chrono::system_clock::now() + std::chrono::seconds(1);
+ Alarm alarm(&cq, one_sec_deadline, junk);
+
+ void* output_tag;
+ bool ok;
+ const CompletionQueue::NextStatus status = cq.AsyncNext(
+ (void**)&output_tag, &ok, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(2));
+
+ EXPECT_EQ(status, CompletionQueue::GOT_EVENT);
+ EXPECT_TRUE(ok);
+ EXPECT_EQ(junk, output_tag);
+}
+
TEST(AlarmTest, ZeroExpiry) {
CompletionQueue cq;
void* junk = reinterpret_cast<void*>(1618033);
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index ce8e4d2a10..dc2c4f6426 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -437,9 +437,10 @@ class End2endServerTryCancelTest : public End2endTest {
break;
case CANCEL_AFTER_PROCESSING:
- // Server cancelled after writing all messages. Client must have read
- // all messages
- EXPECT_EQ(num_msgs_read, kNumResponseStreamsMsgs);
+ // Even though the Server cancelled after writing all messages, the RPC
+ // may be cancelled before the Client got a chance to read all the
+ // messages.
+ EXPECT_LE(num_msgs_read, kNumResponseStreamsMsgs);
break;
default: {
@@ -519,7 +520,11 @@ class End2endServerTryCancelTest : public End2endTest {
case CANCEL_AFTER_PROCESSING:
EXPECT_EQ(num_msgs_sent, num_messages);
- EXPECT_EQ(num_msgs_read, num_msgs_sent);
+
+ // The Server cancelled after reading the last message and after writing
+ // the message to the client. However, the RPC cancellation might have
+ // taken effect before the client actually read the response.
+ EXPECT_LE(num_msgs_read, num_msgs_sent);
break;
default:
@@ -904,9 +909,9 @@ TEST_P(End2endTest, SimultaneousReadWritesDone) {
std::thread reader_thread(ReaderThreadFunc, stream.get(), &ev);
gpr_event_wait(&ev, gpr_inf_future(GPR_CLOCK_REALTIME));
stream->WritesDone();
+ reader_thread.join();
Status s = stream->Finish();
EXPECT_TRUE(s.ok());
- reader_thread.join();
}
TEST_P(End2endTest, ChannelState) {
diff --git a/test/cpp/end2end/test_service_impl.cc b/test/cpp/end2end/test_service_impl.cc
index 66d11d0dfc..7c3e514eff 100644
--- a/test/cpp/end2end/test_service_impl.cc
+++ b/test/cpp/end2end/test_service_impl.cc
@@ -326,7 +326,11 @@ void TestServiceImpl::ServerTryCancel(ServerContext* context) {
EXPECT_FALSE(context->IsCancelled());
context->TryCancel();
gpr_log(GPR_INFO, "Server called TryCancel() to cancel the request");
- EXPECT_TRUE(context->IsCancelled());
+ // Now wait until it's really canceled
+ while (!context->IsCancelled()) {
+ gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
+ gpr_time_from_micros(1000, GPR_TIMESPAN)));
+ }
}
} // namespace testing
diff --git a/test/cpp/interop/metrics_client.cc b/test/cpp/interop/metrics_client.cc
index 0c140ffd85..bd48c7d4ef 100644
--- a/test/cpp/interop/metrics_client.cc
+++ b/test/cpp/interop/metrics_client.cc
@@ -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
@@ -37,39 +37,45 @@
#include <gflags/gflags.h>
#include <grpc++/grpc++.h>
-#include "test/cpp/util/metrics_server.h"
-#include "test/cpp/util/test_config.h"
#include "src/proto/grpc/testing/metrics.grpc.pb.h"
#include "src/proto/grpc/testing/metrics.pb.h"
+#include "test/cpp/util/metrics_server.h"
+#include "test/cpp/util/test_config.h"
DEFINE_string(metrics_server_address, "",
"The metrics server addresses in the fomrat <hostname>:<port>");
+DEFINE_bool(total_only, false,
+ "If true, this prints only the total value of all gauges");
+
+int kDeadlineSecs = 10;
using grpc::testing::EmptyMessage;
using grpc::testing::GaugeResponse;
using grpc::testing::MetricsService;
using grpc::testing::MetricsServiceImpl;
-void PrintMetrics(const grpc::string& server_address) {
- gpr_log(GPR_INFO, "creating a channel to %s", server_address.c_str());
- std::shared_ptr<grpc::Channel> channel(
- grpc::CreateChannel(server_address, grpc::InsecureChannelCredentials()));
-
- std::unique_ptr<MetricsService::Stub> stub(MetricsService::NewStub(channel));
-
+// Prints the values of all Gauges (unless total_only is set to 'true' in which
+// case this only prints the sum of all gauge values).
+bool PrintMetrics(std::unique_ptr<MetricsService::Stub> stub, bool total_only) {
grpc::ClientContext context;
EmptyMessage message;
+ std::chrono::system_clock::time_point deadline =
+ std::chrono::system_clock::now() + std::chrono::seconds(kDeadlineSecs);
+
+ context.set_deadline(deadline);
+
std::unique_ptr<grpc::ClientReader<GaugeResponse>> reader(
stub->GetAllGauges(&context, message));
GaugeResponse gauge_response;
long overall_qps = 0;
- int idx = 0;
while (reader->Read(&gauge_response)) {
if (gauge_response.value_case() == GaugeResponse::kLongValue) {
- gpr_log(GPR_INFO, "Gauge: %d (%s: %ld)", ++idx,
- gauge_response.name().c_str(), gauge_response.long_value());
+ if (!total_only) {
+ gpr_log(GPR_INFO, "%s: %ld", gauge_response.name().c_str(),
+ gauge_response.long_value());
+ }
overall_qps += gauge_response.long_value();
} else {
gpr_log(GPR_INFO, "Gauge %s is not a long value",
@@ -77,12 +83,14 @@ void PrintMetrics(const grpc::string& server_address) {
}
}
- gpr_log(GPR_INFO, "OVERALL: %ld", overall_qps);
+ gpr_log(GPR_INFO, "%ld", overall_qps);
const grpc::Status status = reader->Finish();
if (!status.ok()) {
gpr_log(GPR_ERROR, "Error in getting metrics from the client");
}
+
+ return status.ok();
}
int main(int argc, char** argv) {
@@ -97,7 +105,12 @@ int main(int argc, char** argv) {
return 1;
}
- PrintMetrics(FLAGS_metrics_server_address);
+ std::shared_ptr<grpc::Channel> channel(grpc::CreateChannel(
+ FLAGS_metrics_server_address, grpc::InsecureChannelCredentials()));
+
+ if (!PrintMetrics(MetricsService::NewStub(channel), FLAGS_total_only)) {
+ return 1;
+ }
return 0;
}
diff --git a/test/cpp/interop/reconnect_interop_client.cc b/test/cpp/interop/reconnect_interop_client.cc
index 1f6b352db1..79a60cc860 100644
--- a/test/cpp/interop/reconnect_interop_client.cc
+++ b/test/cpp/interop/reconnect_interop_client.cc
@@ -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
diff --git a/test/cpp/util/metrics_server.cc b/test/cpp/util/metrics_server.cc
index 07978d0bdb..34d51eb316 100644
--- a/test/cpp/util/metrics_server.cc
+++ b/test/cpp/util/metrics_server.cc
@@ -57,7 +57,7 @@ long Gauge::Get() {
grpc::Status MetricsServiceImpl::GetAllGauges(
ServerContext* context, const EmptyMessage* request,
ServerWriter<GaugeResponse>* writer) {
- gpr_log(GPR_INFO, "GetAllGauges called");
+ gpr_log(GPR_DEBUG, "GetAllGauges called");
std::lock_guard<std::mutex> lock(mu_);
for (auto it = gauges_.begin(); it != gauges_.end(); it++) {
diff --git a/test/cpp/util/test_credentials_provider.cc b/test/cpp/util/test_credentials_provider.cc
index 7e1eb0d501..e314fd6d75 100644
--- a/test/cpp/util/test_credentials_provider.cc
+++ b/test/cpp/util/test_credentials_provider.cc
@@ -34,6 +34,8 @@
#include "test/cpp/util/test_credentials_provider.h"
+#include <unordered_map>
+
#include <grpc/support/sync.h>
#include <grpc++/impl/sync.h>
@@ -48,12 +50,36 @@ using grpc::InsecureServerCredentials;
using grpc::ServerCredentials;
using grpc::SslCredentialsOptions;
using grpc::SslServerCredentialsOptions;
-using grpc::testing::CredentialsProvider;
+using grpc::testing::CredentialTypeProvider;
+
+// Provide test credentials. Thread-safe.
+class CredentialsProvider {
+ public:
+ virtual ~CredentialsProvider() {}
+
+ virtual void AddSecureType(
+ const grpc::string& type,
+ std::unique_ptr<CredentialTypeProvider> type_provider) = 0;
+ virtual std::shared_ptr<ChannelCredentials> GetChannelCredentials(
+ const grpc::string& type, ChannelArguments* args) = 0;
+ virtual std::shared_ptr<ServerCredentials> GetServerCredentials(
+ const grpc::string& type) = 0;
+ virtual std::vector<grpc::string> GetSecureCredentialsTypeList() = 0;
+};
class DefaultCredentialsProvider : public CredentialsProvider {
public:
~DefaultCredentialsProvider() override {}
+ void AddSecureType(
+ const grpc::string& type,
+ std::unique_ptr<CredentialTypeProvider> type_provider) override {
+ // This clobbers any existing entry for type, except the defaults, which
+ // can't be clobbered.
+ grpc::unique_lock<grpc::mutex> lock(mu_);
+ added_secure_types_[type] = std::move(type_provider);
+ }
+
std::shared_ptr<ChannelCredentials> GetChannelCredentials(
const grpc::string& type, ChannelArguments* args) override {
if (type == grpc::testing::kInsecureCredentialsType) {
@@ -63,9 +89,14 @@ class DefaultCredentialsProvider : public CredentialsProvider {
args->SetSslTargetNameOverride("foo.test.google.fr");
return SslCredentials(ssl_opts);
} else {
- gpr_log(GPR_ERROR, "Unsupported credentials type %s.", type.c_str());
+ grpc::unique_lock<grpc::mutex> lock(mu_);
+ auto it(added_secure_types_.find(type));
+ if (it == added_secure_types_.end()) {
+ gpr_log(GPR_ERROR, "Unsupported credentials type %s.", type.c_str());
+ return nullptr;
+ }
+ return it->second->GetChannelCredentials(args);
}
- return nullptr;
}
std::shared_ptr<ServerCredentials> GetServerCredentials(
@@ -80,33 +111,38 @@ class DefaultCredentialsProvider : public CredentialsProvider {
ssl_opts.pem_key_cert_pairs.push_back(pkcp);
return SslServerCredentials(ssl_opts);
} else {
- gpr_log(GPR_ERROR, "Unsupported credentials type %s.", type.c_str());
+ grpc::unique_lock<grpc::mutex> lock(mu_);
+ auto it(added_secure_types_.find(type));
+ if (it == added_secure_types_.end()) {
+ gpr_log(GPR_ERROR, "Unsupported credentials type %s.", type.c_str());
+ return nullptr;
+ }
+ return it->second->GetServerCredentials();
}
- return nullptr;
}
std::vector<grpc::string> GetSecureCredentialsTypeList() override {
std::vector<grpc::string> types;
types.push_back(grpc::testing::kTlsCredentialsType);
+ grpc::unique_lock<grpc::mutex> lock(mu_);
+ for (const auto& type_pair : added_secure_types_) {
+ types.push_back(type_pair.first);
+ }
return types;
}
+
+ private:
+ grpc::mutex mu_;
+ std::unordered_map<grpc::string, std::unique_ptr<CredentialTypeProvider> >
+ added_secure_types_;
};
-gpr_once g_once_init_provider_mu = GPR_ONCE_INIT;
-grpc::mutex* g_provider_mu = nullptr;
+gpr_once g_once_init_provider = GPR_ONCE_INIT;
CredentialsProvider* g_provider = nullptr;
-void InitProviderMu() { g_provider_mu = new grpc::mutex; }
-
-grpc::mutex& GetMu() {
- gpr_once_init(&g_once_init_provider_mu, &InitProviderMu);
- return *g_provider_mu;
-}
+void CreateDefaultProvider() { g_provider = new DefaultCredentialsProvider; }
CredentialsProvider* GetProvider() {
- grpc::unique_lock<grpc::mutex> lock(GetMu());
- if (g_provider == nullptr) {
- g_provider = new DefaultCredentialsProvider;
- }
+ gpr_once_init(&g_once_init_provider, &CreateDefaultProvider);
return g_provider;
}
@@ -115,15 +151,9 @@ CredentialsProvider* GetProvider() {
namespace grpc {
namespace testing {
-// Note that it is not thread-safe to set a provider while concurrently using
-// the previously set provider, as this deletes and replaces it. nullptr may be
-// given to reset to the default.
-void SetTestCredentialsProvider(std::unique_ptr<CredentialsProvider> provider) {
- grpc::unique_lock<grpc::mutex> lock(GetMu());
- if (g_provider != nullptr) {
- delete g_provider;
- }
- g_provider = provider.release();
+void AddSecureType(const grpc::string& type,
+ std::unique_ptr<CredentialTypeProvider> type_provider) {
+ GetProvider()->AddSecureType(type, std::move(type_provider));
}
std::shared_ptr<ChannelCredentials> GetChannelCredentials(
diff --git a/test/cpp/util/test_credentials_provider.h b/test/cpp/util/test_credentials_provider.h
index a6b547cb07..50fadb53a2 100644
--- a/test/cpp/util/test_credentials_provider.h
+++ b/test/cpp/util/test_credentials_provider.h
@@ -46,20 +46,21 @@ namespace testing {
const char kInsecureCredentialsType[] = "INSECURE_CREDENTIALS";
const char kTlsCredentialsType[] = "TLS_CREDENTIALS";
-class CredentialsProvider {
+// Provide test credentials of a particular type.
+class CredentialTypeProvider {
public:
- virtual ~CredentialsProvider() {}
+ virtual ~CredentialTypeProvider() {}
virtual std::shared_ptr<ChannelCredentials> GetChannelCredentials(
- const grpc::string& type, ChannelArguments* args) = 0;
- virtual std::shared_ptr<ServerCredentials> GetServerCredentials(
- const grpc::string& type) = 0;
- virtual std::vector<grpc::string> GetSecureCredentialsTypeList() = 0;
+ ChannelArguments* args) = 0;
+ virtual std::shared_ptr<ServerCredentials> GetServerCredentials() = 0;
};
-// Set the CredentialsProvider used by the other functions in this file. If this
-// is not set, a default provider will be used.
-void SetTestCredentialsProvider(std::unique_ptr<CredentialsProvider> provider);
+// Add a secure type in addition to the defaults above
+// (kInsecureCredentialsType, kTlsCredentialsType) that can be returned from the
+// functions below.
+void AddSecureType(const grpc::string& type,
+ std::unique_ptr<CredentialTypeProvider> type_provider);
// Provide channel credentials according to the given type. Alter the channel
// arguments if needed.
diff --git a/test/distrib/csharp/DistribTest.sln b/test/distrib/csharp/DistribTest.sln
index 0eca35c30f..78d5397ca9 100644
--- a/test/distrib/csharp/DistribTest.sln
+++ b/test/distrib/csharp/DistribTest.sln
@@ -8,13 +8,19 @@ EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A3E61CC3-3710-49A3-A830-A0066EDBCE2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A3E61CC3-3710-49A3-A830-A0066EDBCE2F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A3E61CC3-3710-49A3-A830-A0066EDBCE2F}.Debug|x64.ActiveCfg = Debug|x64
+ {A3E61CC3-3710-49A3-A830-A0066EDBCE2F}.Debug|x64.Build.0 = Debug|x64
{A3E61CC3-3710-49A3-A830-A0066EDBCE2F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A3E61CC3-3710-49A3-A830-A0066EDBCE2F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A3E61CC3-3710-49A3-A830-A0066EDBCE2F}.Release|x64.ActiveCfg = Release|x64
+ {A3E61CC3-3710-49A3-A830-A0066EDBCE2F}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/test/distrib/csharp/DistribTest/DistribTest.csproj b/test/distrib/csharp/DistribTest/DistribTest.csproj
index 124fc1bdf0..7605495f0f 100644
--- a/test/distrib/csharp/DistribTest/DistribTest.csproj
+++ b/test/distrib/csharp/DistribTest/DistribTest.csproj
@@ -32,6 +32,26 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\x64\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>x64</PlatformTarget>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <Prefer32Bit>true</Prefer32Bit>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+ <OutputPath>bin\x64\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <Optimize>true</Optimize>
+ <DebugType>pdbonly</DebugType>
+ <PlatformTarget>x64</PlatformTarget>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <Prefer32Bit>true</Prefer32Bit>
+ </PropertyGroup>
<ItemGroup>
<Reference Include="BouncyCastle.Crypto">
<HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
diff --git a/test/distrib/csharp/run_distrib_test.bat b/test/distrib/csharp/run_distrib_test.bat
new file mode 100644
index 0000000000..67bfc58ac8
--- /dev/null
+++ b/test/distrib/csharp/run_distrib_test.bat
@@ -0,0 +1,49 @@
+@rem Copyright 2016, Google Inc.
+@rem All rights reserved.
+@rem
+@rem Redistribution and use in source and binary forms, with or without
+@rem modification, are permitted provided that the following conditions are
+@rem met:
+@rem
+@rem * Redistributions of source code must retain the above copyright
+@rem notice, this list of conditions and the following disclaimer.
+@rem * Redistributions in binary form must reproduce the above
+@rem copyright notice, this list of conditions and the following disclaimer
+@rem in the documentation and/or other materials provided with the
+@rem distribution.
+@rem * Neither the name of Google Inc. nor the names of its
+@rem contributors may be used to endorse or promote products derived from
+@rem this software without specific prior written permission.
+@rem
+@rem THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+@rem "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+@rem LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+@rem A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+@rem OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+@rem SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+@rem LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+@rem DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+@rem THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+@rem (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+@rem OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+@rem enter this directory
+cd /d %~dp0
+
+@rem extract input artifacts
+powershell -Command "Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::ExtractToDirectory('../../../input_artifacts/csharp_nugets.zip', 'TestNugetFeed');"
+
+update_version.sh auto
+
+set NUGET=C:\nuget\nuget.exe
+%NUGET% restore || goto :error
+
+@call build_vs2015.bat DistribTest.sln %MSBUILD_EXTRA_ARGS% || goto :error
+
+%DISTRIBTEST_OUTPATH%\DistribTest.exe || goto :error
+
+goto :EOF
+
+:error
+echo Failed!
+exit /b %errorlevel%
diff --git a/test/distrib/csharp/run_distrib_test.sh b/test/distrib/csharp/run_distrib_test.sh
index 1de62041b3..934174a9a4 100755
--- a/test/distrib/csharp/run_distrib_test.sh
+++ b/test/distrib/csharp/run_distrib_test.sh
@@ -34,9 +34,7 @@ cd $(dirname $0)
unzip -o "$EXTERNAL_GIT_ROOT/input_artifacts/csharp_nugets.zip" -d TestNugetFeed
-# Extract the version number from Grpc nuget package name.
-CSHARP_VERSION=$(ls TestNugetFeed | grep '^Grpc\.[0-9].*\.nupkg$' | sed s/^Grpc\.// | sed s/\.nupkg$//)
-./update_version.sh $CSHARP_VERSION
+./update_version.sh auto
nuget restore
diff --git a/test/distrib/csharp/update_version.sh b/test/distrib/csharp/update_version.sh
index f2554e8998..b0d07721f6 100755
--- a/test/distrib/csharp/update_version.sh
+++ b/test/distrib/csharp/update_version.sh
@@ -32,5 +32,13 @@ set -e
cd $(dirname $0)
+CSHARP_VERSION="$1"
+if [ "$CSHARP_VERSION" == "auto" ]
+then
+ # autodetect C# version
+ CSHARP_VERSION=$(ls TestNugetFeed | grep '^Grpc\.[0-9].*\.nupkg$' | sed s/^Grpc\.// | sed s/\.nupkg$//)
+ echo "Autodetected nuget ${CSHARP_VERSION}"
+fi
+
# Replaces version placeholder with value provided as first argument.
-sed -ibak "s/__GRPC_NUGET_VERSION__/$1/g" DistribTest/packages.config DistribTest/DistribTest.csproj
+sed -ibak "s/__GRPC_NUGET_VERSION__/${CSHARP_VERSION}/g" DistribTest/packages.config DistribTest/DistribTest.csproj
diff --git a/tools/dockerfile/distribtest/python_fedora20_x64/Dockerfile b/tools/dockerfile/distribtest/python_fedora20_x64/Dockerfile
index d58036410f..5e6cb15762 100644
--- a/tools/dockerfile/distribtest/python_fedora20_x64/Dockerfile
+++ b/tools/dockerfile/distribtest/python_fedora20_x64/Dockerfile
@@ -30,3 +30,8 @@
FROM fedora:20
RUN yum clean all && yum update -y && yum install -y python python-pip
+
+# Upgrading six would fail because of docker issue when using overlay.
+# Trying twice makes it work fine.
+# https://github.com/docker/docker/issues/10180
+RUN pip install --upgrade six || pip install --upgrade six
diff --git a/tools/dockerfile/distribtest/python_fedora21_x64/Dockerfile b/tools/dockerfile/distribtest/python_fedora21_x64/Dockerfile
index 1eb4c1e775..f1b0e2f4b2 100644
--- a/tools/dockerfile/distribtest/python_fedora21_x64/Dockerfile
+++ b/tools/dockerfile/distribtest/python_fedora21_x64/Dockerfile
@@ -35,3 +35,8 @@ FROM fedora:21
RUN yum install -y yum-plugin-ovl
RUN yum clean all && yum update -y && yum install -y python python-pip
+
+# Upgrading six would fail because of docker issue when using overlay.
+# Trying twice makes it work fine.
+# https://github.com/docker/docker/issues/10180
+RUN pip2 install --upgrade six || pip2 install --upgrade six
diff --git a/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile
index f65b8690d7..b943b67e8a 100644
--- a/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile
+++ b/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile
@@ -35,7 +35,9 @@ RUN yum install -y tar which
# Install rvm
RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
-RUN \curl -sSL https://get.rvm.io | bash -s stable --ruby
+# Running the installation twice to work around docker issue when using overlay.
+# https://github.com/docker/docker/issues/10180
+RUN (curl -sSL https://get.rvm.io | bash -s stable --ruby) || (curl -sSL https://get.rvm.io | bash -s stable --ruby)
RUN /bin/bash -l -c "echo '. /etc/profile.d/rvm.sh' >> ~/.bashrc"
RUN /bin/bash -l -c "gem install --update bundler"
diff --git a/tools/dockerfile/grpc_interop_stress_cxx/Dockerfile b/tools/dockerfile/grpc_interop_stress_cxx/Dockerfile
index 58a8c32e34..4123cc1a26 100644
--- a/tools/dockerfile/grpc_interop_stress_cxx/Dockerfile
+++ b/tools/dockerfile/grpc_interop_stress_cxx/Dockerfile
@@ -59,6 +59,8 @@ RUN apt-get update && apt-get install -y \
wget \
zip && apt-get clean
+RUN easy_install -U pip
+
# Prepare ccache
RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
RUN ln -s /usr/bin/ccache /usr/local/bin/g++
@@ -71,5 +73,8 @@ RUN ln -s /usr/bin/ccache /usr/local/bin/clang++
# C++ dependencies
RUN apt-get update && apt-get -y install libgflags-dev libgtest-dev libc++-dev clang
+# Google Cloud platform API libraries (for BigQuery)
+RUN pip install --upgrade google-api-python-client
+
# Define the default command.
CMD ["bash"]
diff --git a/tools/dockerfile/grpc_interop_stress_cxx/build_interop_stress.sh b/tools/dockerfile/grpc_interop_stress_cxx/build_interop_stress.sh
index 6ed3ccb3fa..392bdfccda 100755
--- a/tools/dockerfile/grpc_interop_stress_cxx/build_interop_stress.sh
+++ b/tools/dockerfile/grpc_interop_stress_cxx/build_interop_stress.sh
@@ -42,4 +42,4 @@ cd /var/local/git/grpc
make install-certs
# build C++ interop stress client, interop client and server
-make stress_test interop_client interop_server
+make stress_test metrics_client interop_client interop_server
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index d5e5df86f6..a285310847 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -854,7 +854,6 @@ src/cpp/client/create_channel_internal.cc \
src/cpp/client/credentials.cc \
src/cpp/client/generic_stub.cc \
src/cpp/client/insecure_credentials.cc \
-src/cpp/common/alarm.cc \
src/cpp/common/call.cc \
src/cpp/common/channel_arguments.cc \
src/cpp/common/completion_queue.cc \
diff --git a/tools/gcp/stress_test/run_client.py b/tools/gcp/stress_test/run_client.py
new file mode 100755
index 0000000000..0fa1bf1cb9
--- /dev/null
+++ b/tools/gcp/stress_test/run_client.py
@@ -0,0 +1,187 @@
+#!/usr/bin/env python2.7
+# 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.
+
+import datetime
+import os
+import re
+import select
+import subprocess
+import sys
+import time
+
+from stress_test_utils import EventType
+from stress_test_utils import BigQueryHelper
+
+
+# TODO (sree): Write a python grpc client to directly query the metrics instead
+# of calling metrics_client
+def _get_qps(metrics_cmd):
+ qps = 0
+ try:
+ # Note: gpr_log() writes even non-error messages to stderr stream. So it is
+ # important that we set stderr=subprocess.STDOUT
+ p = subprocess.Popen(args=metrics_cmd,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ retcode = p.wait()
+ (out_str, err_str) = p.communicate()
+ if retcode != 0:
+ print 'Error in reading metrics information'
+ print 'Output: ', out_str
+ else:
+ # The overall qps is printed at the end of the line
+ m = re.search('\d+$', out_str)
+ qps = int(m.group()) if m else 0
+ except Exception as ex:
+ print 'Exception while reading metrics information: ' + str(ex)
+ return qps
+
+
+def run_client():
+ """This is a wrapper around the stress test client and performs the following:
+ 1) Create the following two tables in Big Query:
+ (i) Summary table: To record events like the test started, completed
+ successfully or failed
+ (ii) Qps table: To periodically record the QPS sent by this client
+ 2) Start the stress test client and add a row in the Big Query summary
+ table
+ 3) Once every few seconds (as specificed by the poll_interval_secs) poll
+ the status of the stress test client process and perform the
+ following:
+ 3.1) If the process is still running, get the current qps by invoking
+ the metrics client program and add a row in the Big Query
+ Qps table. Sleep for a duration specified by poll_interval_secs
+ 3.2) If the process exited successfully, add a row in the Big Query
+ Summary table and exit
+ 3.3) If the process failed, add a row in Big Query summary table and
+ wait forever.
+ NOTE: This script typically runs inside a GKE pod which means
+ that the pod gets destroyed when the script exits. However, in
+ case the stress test client fails, we would not want the pod to
+ be destroyed (since we might want to connect to the pod for
+ examining logs). This is the reason why the script waits forever
+ in case of failures
+ """
+ env = dict(os.environ)
+ image_type = env['STRESS_TEST_IMAGE_TYPE']
+ image_name = env['STRESS_TEST_IMAGE']
+ args_str = env['STRESS_TEST_ARGS_STR']
+ metrics_client_image = env['METRICS_CLIENT_IMAGE']
+ metrics_client_args_str = env['METRICS_CLIENT_ARGS_STR']
+ run_id = env['RUN_ID']
+ pod_name = env['POD_NAME']
+ logfile_name = env.get('LOGFILE_NAME')
+ poll_interval_secs = float(env['POLL_INTERVAL_SECS'])
+ project_id = env['GCP_PROJECT_ID']
+ dataset_id = env['DATASET_ID']
+ summary_table_id = env['SUMMARY_TABLE_ID']
+ qps_table_id = env['QPS_TABLE_ID']
+
+ bq_helper = BigQueryHelper(run_id, image_type, pod_name, project_id,
+ dataset_id, summary_table_id, qps_table_id)
+ bq_helper.initialize()
+
+ # Create BigQuery Dataset and Tables: Summary Table and Metrics Table
+ if not bq_helper.setup_tables():
+ print 'Error in creating BigQuery tables'
+ return
+
+ start_time = datetime.datetime.now()
+
+ logfile = None
+ details = 'Logging to stdout'
+ if logfile_name is not None:
+ print 'Opening logfile: %s ...' % logfile_name
+ details = 'Logfile: %s' % logfile_name
+ logfile = open(logfile_name, 'w')
+
+ # Update status that the test is starting (in the status table)
+ bq_helper.insert_summary_row(EventType.STARTING, details)
+
+ metrics_cmd = [metrics_client_image
+ ] + [x for x in metrics_client_args_str.split()]
+ stress_cmd = [image_name] + [x for x in args_str.split()]
+
+ print 'Launching process %s ...' % stress_cmd
+ stress_p = subprocess.Popen(args=stress_cmd,
+ stdout=logfile,
+ stderr=subprocess.STDOUT)
+
+ qps_history = [1, 1, 1] # Maintain the last 3 qps readings
+ qps_history_idx = 0 # Index into the qps_history list
+
+ is_error = False
+ while True:
+ # Check if stress_client is still running. If so, collect metrics and upload
+ # to BigQuery status table
+ if stress_p.poll() is not None:
+ end_time = datetime.datetime.now().isoformat()
+ event_type = EventType.SUCCESS
+ details = 'End time: %s' % end_time
+ if stress_p.returncode != 0:
+ event_type = EventType.FAILURE
+ details = 'Return code = %d. End time: %s' % (stress_p.returncode,
+ end_time)
+ is_error = True
+ bq_helper.insert_summary_row(event_type, details)
+ print details
+ break
+
+ # Stress client still running. Get metrics
+ qps = _get_qps(metrics_cmd)
+ qps_recorded_at = datetime.datetime.now().isoformat()
+ print 'qps: %d at %s' % (qps, qps_recorded_at)
+
+ # If QPS has been zero for the last 3 iterations, flag it as error and exit
+ qps_history[qps_history_idx] = qps
+ qps_history_idx = (qps_history_idx + 1) % len(qps_history)
+ if sum(qps_history) == 0:
+ details = 'QPS has been zero for the last %d seconds - as of : %s' % (
+ poll_interval_secs * 3, qps_recorded_at)
+ is_error = True
+ bq_helper.insert_summary_row(EventType.FAILURE, details)
+ print details
+ break
+
+ # Upload qps metrics to BiqQuery
+ bq_helper.insert_qps_row(qps, qps_recorded_at)
+
+ time.sleep(poll_interval_secs)
+
+ if is_error:
+ print 'Waiting indefinitely..'
+ select.select([], [], [])
+
+ print 'Completed'
+ return
+
+
+if __name__ == '__main__':
+ run_client()
diff --git a/tools/gcp/stress_test/run_server.py b/tools/gcp/stress_test/run_server.py
new file mode 100755
index 0000000000..64322f6100
--- /dev/null
+++ b/tools/gcp/stress_test/run_server.py
@@ -0,0 +1,120 @@
+#!/usr/bin/env python2.7
+# 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.
+
+import datetime
+import os
+import select
+import subprocess
+import sys
+import time
+
+from stress_test_utils import BigQueryHelper
+from stress_test_utils import EventType
+
+
+def run_server():
+ """This is a wrapper around the interop server and performs the following:
+ 1) Create a 'Summary table' in Big Query to record events like the server
+ started, completed successfully or failed. NOTE: This also creates
+ another table called the QPS table which is currently NOT needed on the
+ server (it is needed on the stress test clients)
+ 2) Start the server process and add a row in Big Query summary table
+ 3) Wait for the server process to terminate. The server process does not
+ terminate unless there is an error.
+ If the server process terminated with a failure, add a row in Big Query
+ and wait forever.
+ NOTE: This script typically runs inside a GKE pod which means that the
+ pod gets destroyed when the script exits. However, in case the server
+ process fails, we would not want the pod to be destroyed (since we
+ might want to connect to the pod for examining logs). This is the
+ reason why the script waits forever in case of failures.
+ """
+
+ # Read the parameters from environment variables
+ env = dict(os.environ)
+
+ run_id = env['RUN_ID'] # The unique run id for this test
+ image_type = env['STRESS_TEST_IMAGE_TYPE']
+ image_name = env['STRESS_TEST_IMAGE']
+ args_str = env['STRESS_TEST_ARGS_STR']
+ pod_name = env['POD_NAME']
+ project_id = env['GCP_PROJECT_ID']
+ dataset_id = env['DATASET_ID']
+ summary_table_id = env['SUMMARY_TABLE_ID']
+ qps_table_id = env['QPS_TABLE_ID']
+
+ logfile_name = env.get('LOGFILE_NAME')
+
+ print('pod_name: %s, project_id: %s, run_id: %s, dataset_id: %s, '
+ 'summary_table_id: %s, qps_table_id: %s') % (
+ pod_name, project_id, run_id, dataset_id, summary_table_id,
+ qps_table_id)
+
+ bq_helper = BigQueryHelper(run_id, image_type, pod_name, project_id,
+ dataset_id, summary_table_id, qps_table_id)
+ bq_helper.initialize()
+
+ # Create BigQuery Dataset and Tables: Summary Table and Metrics Table
+ if not bq_helper.setup_tables():
+ print 'Error in creating BigQuery tables'
+ return
+
+ start_time = datetime.datetime.now()
+
+ logfile = None
+ details = 'Logging to stdout'
+ if logfile_name is not None:
+ print 'Opening log file: ', logfile_name
+ logfile = open(logfile_name, 'w')
+ details = 'Logfile: %s' % logfile_name
+
+ # Update status that the test is starting (in the status table)
+ bq_helper.insert_summary_row(EventType.STARTING, details)
+
+ stress_cmd = [image_name] + [x for x in args_str.split()]
+
+ print 'Launching process %s ...' % stress_cmd
+ stress_p = subprocess.Popen(args=stress_cmd,
+ stdout=logfile,
+ stderr=subprocess.STDOUT)
+
+ returncode = stress_p.wait()
+ if returncode != 0:
+ end_time = datetime.datetime.now().isoformat()
+ event_type = EventType.FAILURE
+ details = 'Returncode: %d; End time: %s' % (returncode, end_time)
+ bq_helper.insert_summary_row(event_type, details)
+ print 'Waiting indefinitely..'
+ select.select([], [], [])
+ return returncode
+
+
+if __name__ == '__main__':
+ run_server()
diff --git a/tools/gcp/stress_test/stress_test_utils.py b/tools/gcp/stress_test/stress_test_utils.py
new file mode 100755
index 0000000000..c4b437e345
--- /dev/null
+++ b/tools/gcp/stress_test/stress_test_utils.py
@@ -0,0 +1,197 @@
+#!/usr/bin/env python2.7
+# 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.
+
+import datetime
+import json
+import os
+import re
+import select
+import subprocess
+import sys
+import time
+
+# Import big_query_utils module
+bq_utils_dir = os.path.abspath(os.path.join(
+ os.path.dirname(__file__), '../utils'))
+sys.path.append(bq_utils_dir)
+import big_query_utils as bq_utils
+
+
+class EventType:
+ STARTING = 'STARTING'
+ SUCCESS = 'SUCCESS'
+ FAILURE = 'FAILURE'
+
+
+class BigQueryHelper:
+ """Helper class for the stress test wrappers to interact with BigQuery.
+ """
+
+ def __init__(self, run_id, image_type, pod_name, project_id, dataset_id,
+ summary_table_id, qps_table_id):
+ self.run_id = run_id
+ self.image_type = image_type
+ self.pod_name = pod_name
+ self.project_id = project_id
+ self.dataset_id = dataset_id
+ self.summary_table_id = summary_table_id
+ self.qps_table_id = qps_table_id
+
+ def initialize(self):
+ self.bq = bq_utils.create_big_query()
+
+ def setup_tables(self):
+ return bq_utils.create_dataset(self.bq, self.project_id, self.dataset_id) \
+ and self.__create_summary_table() \
+ and self.__create_qps_table()
+
+ def insert_summary_row(self, event_type, details):
+ row_values_dict = {
+ 'run_id': self.run_id,
+ 'image_type': self.image_type,
+ 'pod_name': self.pod_name,
+ 'event_date': datetime.datetime.now().isoformat(),
+ 'event_type': event_type,
+ 'details': details
+ }
+ # row_unique_id is something that uniquely identifies the row (BigQuery uses
+ # it for duplicate detection).
+ row_unique_id = '%s_%s_%s' % (self.run_id, self.pod_name, event_type)
+ row = bq_utils.make_row(row_unique_id, row_values_dict)
+ return bq_utils.insert_rows(self.bq, self.project_id, self.dataset_id,
+ self.summary_table_id, [row])
+
+ def insert_qps_row(self, qps, recorded_at):
+ row_values_dict = {
+ 'run_id': self.run_id,
+ 'pod_name': self.pod_name,
+ 'recorded_at': recorded_at,
+ 'qps': qps
+ }
+
+ # row_unique_id is something that uniquely identifies the row (BigQuery uses
+ # it for duplicate detection).
+ row_unique_id = '%s_%s_%s' % (self.run_id, self.pod_name, recorded_at)
+ row = bq_utils.make_row(row_unique_id, row_values_dict)
+ return bq_utils.insert_rows(self.bq, self.project_id, self.dataset_id,
+ self.qps_table_id, [row])
+
+ def check_if_any_tests_failed(self, num_query_retries=3):
+ query = ('SELECT event_type FROM %s.%s WHERE run_id = \'%s\' AND '
+ 'event_type="%s"') % (self.dataset_id, self.summary_table_id,
+ self.run_id, EventType.FAILURE)
+ query_job = bq_utils.sync_query_job(self.bq, self.project_id, query)
+ page = self.bq.jobs().getQueryResults(**query_job['jobReference']).execute(
+ num_retries=num_query_retries)
+ num_failures = int(page['totalRows'])
+ print 'num rows: ', num_failures
+ return num_failures > 0
+
+ def print_summary_records(self, num_query_retries=3):
+ line = '-' * 120
+ print line
+ print 'Summary records'
+ print 'Run Id: ', self.run_id
+ print 'Dataset Id: ', self.dataset_id
+ print line
+ query = ('SELECT pod_name, image_type, event_type, event_date, details'
+ ' FROM %s.%s WHERE run_id = \'%s\' ORDER by event_date;') % (
+ self.dataset_id, self.summary_table_id, self.run_id)
+ query_job = bq_utils.sync_query_job(self.bq, self.project_id, query)
+
+ print '{:<25} {:<12} {:<12} {:<30} {}'.format(
+ 'Pod name', 'Image type', 'Event type', 'Date', 'Details')
+ print line
+ page_token = None
+ while True:
+ page = self.bq.jobs().getQueryResults(
+ pageToken=page_token,
+ **query_job['jobReference']).execute(num_retries=num_query_retries)
+ rows = page.get('rows', [])
+ for row in rows:
+ print '{:<25} {:<12} {:<12} {:<30} {}'.format(
+ row['f'][0]['v'], row['f'][1]['v'], row['f'][2]['v'],
+ row['f'][3]['v'], row['f'][4]['v'])
+ page_token = page.get('pageToken')
+ if not page_token:
+ break
+
+ def print_qps_records(self, num_query_retries=3):
+ line = '-' * 80
+ print line
+ print 'QPS Summary'
+ print 'Run Id: ', self.run_id
+ print 'Dataset Id: ', self.dataset_id
+ print line
+ query = (
+ 'SELECT pod_name, recorded_at, qps FROM %s.%s WHERE run_id = \'%s\' '
+ 'ORDER by recorded_at;') % (self.dataset_id, self.qps_table_id,
+ self.run_id)
+ query_job = bq_utils.sync_query_job(self.bq, self.project_id, query)
+ print '{:<25} {:30} {}'.format('Pod name', 'Recorded at', 'Qps')
+ print line
+ page_token = None
+ while True:
+ page = self.bq.jobs().getQueryResults(
+ pageToken=page_token,
+ **query_job['jobReference']).execute(num_retries=num_query_retries)
+ rows = page.get('rows', [])
+ for row in rows:
+ print '{:<25} {:30} {}'.format(row['f'][0]['v'], row['f'][1]['v'],
+ row['f'][2]['v'])
+ page_token = page.get('pageToken')
+ if not page_token:
+ break
+
+ def __create_summary_table(self):
+ summary_table_schema = [
+ ('run_id', 'STRING', 'Test run id'),
+ ('image_type', 'STRING', 'Client or Server?'),
+ ('pod_name', 'STRING', 'GKE pod hosting this image'),
+ ('event_date', 'STRING', 'The date of this event'),
+ ('event_type', 'STRING', 'STARTED/SUCCESS/FAILURE'),
+ ('details', 'STRING', 'Any other relevant details')
+ ]
+ desc = ('The table that contains START/SUCCESS/FAILURE events for '
+ ' the stress test clients and servers')
+ return bq_utils.create_table(self.bq, self.project_id, self.dataset_id,
+ self.summary_table_id, summary_table_schema,
+ desc)
+
+ def __create_qps_table(self):
+ qps_table_schema = [
+ ('run_id', 'STRING', 'Test run id'),
+ ('pod_name', 'STRING', 'GKE pod hosting this image'),
+ ('recorded_at', 'STRING', 'Metrics recorded at time'),
+ ('qps', 'INTEGER', 'Queries per second')
+ ]
+ desc = 'The table that cointains the qps recorded at various intervals'
+ return bq_utils.create_table(self.bq, self.project_id, self.dataset_id,
+ self.qps_table_id, qps_table_schema, desc)
diff --git a/tools/gcp/utils/big_query_utils.py b/tools/gcp/utils/big_query_utils.py
new file mode 100755
index 0000000000..7bb1e14354
--- /dev/null
+++ b/tools/gcp/utils/big_query_utils.py
@@ -0,0 +1,140 @@
+#!/usr/bin/env python2.7
+# 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.
+
+import argparse
+import json
+import uuid
+import httplib2
+
+from apiclient import discovery
+from apiclient.errors import HttpError
+from oauth2client.client import GoogleCredentials
+
+NUM_RETRIES = 3
+
+
+def create_big_query():
+ """Authenticates with cloud platform and gets a BiqQuery service object
+ """
+ creds = GoogleCredentials.get_application_default()
+ return discovery.build('bigquery', 'v2', credentials=creds)
+
+
+def create_dataset(biq_query, project_id, dataset_id):
+ is_success = True
+ body = {
+ 'datasetReference': {
+ 'projectId': project_id,
+ 'datasetId': dataset_id
+ }
+ }
+
+ try:
+ dataset_req = biq_query.datasets().insert(projectId=project_id, body=body)
+ dataset_req.execute(num_retries=NUM_RETRIES)
+ except HttpError as http_error:
+ if http_error.resp.status == 409:
+ print 'Warning: The dataset %s already exists' % dataset_id
+ else:
+ # Note: For more debugging info, print "http_error.content"
+ print 'Error in creating dataset: %s. Err: %s' % (dataset_id, http_error)
+ is_success = False
+ return is_success
+
+
+def create_table(big_query, project_id, dataset_id, table_id, table_schema,
+ description):
+ is_success = True
+
+ body = {
+ 'description': description,
+ 'schema': {
+ 'fields': [{
+ 'name': field_name,
+ 'type': field_type,
+ 'description': field_description
+ } for (field_name, field_type, field_description) in table_schema]
+ },
+ 'tableReference': {
+ 'datasetId': dataset_id,
+ 'projectId': project_id,
+ 'tableId': table_id
+ }
+ }
+
+ try:
+ table_req = big_query.tables().insert(projectId=project_id,
+ datasetId=dataset_id,
+ body=body)
+ res = table_req.execute(num_retries=NUM_RETRIES)
+ print 'Successfully created %s "%s"' % (res['kind'], res['id'])
+ except HttpError as http_error:
+ if http_error.resp.status == 409:
+ print 'Warning: Table %s already exists' % table_id
+ else:
+ print 'Error in creating table: %s. Err: %s' % (table_id, http_error)
+ is_success = False
+ return is_success
+
+
+def insert_rows(big_query, project_id, dataset_id, table_id, rows_list):
+ is_success = True
+ body = {'rows': rows_list}
+ try:
+ insert_req = big_query.tabledata().insertAll(projectId=project_id,
+ datasetId=dataset_id,
+ tableId=table_id,
+ body=body)
+ print body
+ res = insert_req.execute(num_retries=NUM_RETRIES)
+ print res
+ except HttpError as http_error:
+ print 'Error in inserting rows in the table %s' % table_id
+ is_success = False
+ return is_success
+
+
+def sync_query_job(big_query, project_id, query, timeout=5000):
+ query_data = {'query': query, 'timeoutMs': timeout}
+ query_job = None
+ try:
+ query_job = big_query.jobs().query(
+ projectId=project_id,
+ body=query_data).execute(num_retries=NUM_RETRIES)
+ except HttpError as http_error:
+ print 'Query execute job failed with error: %s' % http_error
+ print http_error.content
+ return query_job
+
+ # List of (column name, column type, description) tuples
+def make_row(unique_row_id, row_values_dict):
+ """row_values_dict is a dictionary of column name and column value.
+ """
+ return {'insertId': unique_row_id, 'json': row_values_dict}
diff --git a/tools/gke/kubernetes_api.py b/tools/gcp/utils/kubernetes_api.py
index 7dd3015365..e8ddd2f1b3 100755
--- a/tools/gke/kubernetes_api.py
+++ b/tools/gcp/utils/kubernetes_api.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python2.7
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,9 @@ import json
_REQUEST_TIMEOUT_SECS = 10
+
def _make_pod_config(pod_name, image_name, container_port_list, cmd_list,
- arg_list):
+ arg_list, env_dict):
"""Creates a string containing the Pod defintion as required by the Kubernetes API"""
body = {
'kind': 'Pod',
@@ -48,20 +49,23 @@ def _make_pod_config(pod_name, image_name, container_port_list, cmd_list,
{
'name': pod_name,
'image': image_name,
- 'ports': []
+ 'ports': [{'containerPort': port,
+ 'protocol': 'TCP'}
+ for port in container_port_list],
+ 'imagePullPolicy': 'Always'
}
]
}
}
- # Populate the 'ports' list
- for port in container_port_list:
- port_entry = {'containerPort': port, 'protocol': 'TCP'}
- body['spec']['containers'][0]['ports'].append(port_entry)
+
+ env_list = [{'name': k, 'value': v} for (k, v) in env_dict.iteritems()]
+ if len(env_list) > 0:
+ body['spec']['containers'][0]['env'] = env_list
# Add the 'Command' and 'Args' attributes if they are passed.
# Note:
# - 'Command' overrides the ENTRYPOINT in the Docker Image
- # - 'Args' override the COMMAND in Docker image (yes, it is confusing!)
+ # - 'Args' override the CMD in Docker image (yes, it is confusing!)
if len(cmd_list) > 0:
body['spec']['containers'][0]['command'] = cmd_list
if len(arg_list) > 0:
@@ -70,7 +74,7 @@ def _make_pod_config(pod_name, image_name, container_port_list, cmd_list,
def _make_service_config(service_name, pod_name, service_port_list,
- container_port_list, is_headless):
+ container_port_list, is_headless):
"""Creates a string containing the Service definition as required by the Kubernetes API.
NOTE:
@@ -124,6 +128,7 @@ def _print_connection_error(msg):
print('ERROR: Connection failed. Did you remember to run Kubenetes proxy on '
'localhost (i.e kubectl proxy --port=<proxy_port>) ?. Error: %s' % msg)
+
def _do_post(post_url, api_name, request_body):
"""Helper to do HTTP POST.
@@ -135,7 +140,9 @@ def _do_post(post_url, api_name, request_body):
"""
is_success = True
try:
- r = requests.post(post_url, data=request_body, timeout=_REQUEST_TIMEOUT_SECS)
+ r = requests.post(post_url,
+ data=request_body,
+ timeout=_REQUEST_TIMEOUT_SECS)
if r.status_code == requests.codes.conflict:
print('WARN: Looks like the resource already exists. Api: %s, url: %s' %
(api_name, post_url))
@@ -143,7 +150,8 @@ def _do_post(post_url, api_name, request_body):
print('ERROR: %s API returned error. HTTP response: (%d) %s' %
(api_name, r.status_code, r.text))
is_success = False
- except(requests.exceptions.Timeout, requests.exceptions.ConnectionError) as e:
+ except (requests.exceptions.Timeout,
+ requests.exceptions.ConnectionError) as e:
is_success = False
_print_connection_error(str(e))
return is_success
@@ -165,7 +173,8 @@ def _do_delete(del_url, api_name):
print('ERROR: %s API returned error. HTTP response: %s' %
(api_name, r.text))
is_success = False
- except(requests.exceptions.Timeout, requests.exceptions.ConnectionError) as e:
+ except (requests.exceptions.Timeout,
+ requests.exceptions.ConnectionError) as e:
is_success = False
_print_connection_error(str(e))
return is_success
@@ -179,12 +188,12 @@ def create_service(kube_host, kube_port, namespace, service_name, pod_name,
post_url = 'http://%s:%d/api/v1/namespaces/%s/services' % (
kube_host, kube_port, namespace)
request_body = _make_service_config(service_name, pod_name, service_port_list,
- container_port_list, is_headless)
+ container_port_list, is_headless)
return _do_post(post_url, 'Create Service', request_body)
def create_pod(kube_host, kube_port, namespace, pod_name, image_name,
- container_port_list, cmd_list, arg_list):
+ container_port_list, cmd_list, arg_list, env_dict):
"""Creates a Kubernetes Pod.
Note that it is generally NOT considered a good practice to directly create
@@ -200,7 +209,7 @@ def create_pod(kube_host, kube_port, namespace, pod_name, image_name,
post_url = 'http://%s:%d/api/v1/namespaces/%s/pods' % (kube_host, kube_port,
namespace)
request_body = _make_pod_config(pod_name, image_name, container_port_list,
- cmd_list, arg_list)
+ cmd_list, arg_list, env_dict)
return _do_post(post_url, 'Create Pod', request_body)
@@ -214,3 +223,47 @@ def delete_pod(kube_host, kube_port, namespace, pod_name):
del_url = 'http://%s:%d/api/v1/namespaces/%s/pods/%s' % (kube_host, kube_port,
namespace, pod_name)
return _do_delete(del_url, 'Delete Pod')
+
+
+def create_pod_and_service(kube_host, kube_port, namespace, pod_name,
+ image_name, container_port_list, cmd_list, arg_list,
+ env_dict, is_headless_service):
+ """A helper function that creates a pod and a service (if pod creation was successful)."""
+ is_success = create_pod(kube_host, kube_port, namespace, pod_name, image_name,
+ container_port_list, cmd_list, arg_list, env_dict)
+ if not is_success:
+ print 'Error in creating Pod'
+ return False
+
+ is_success = create_service(
+ kube_host,
+ kube_port,
+ namespace,
+ pod_name, # Use pod_name for service
+ pod_name,
+ container_port_list, # Service port list same as container port list
+ container_port_list,
+ is_headless_service)
+ if not is_success:
+ print 'Error in creating Service'
+ return False
+
+ print 'Successfully created the pod/service %s' % pod_name
+ return True
+
+
+def delete_pod_and_service(kube_host, kube_port, namespace, pod_name):
+ """ A helper function that calls delete_pod and delete_service """
+ is_success = delete_pod(kube_host, kube_port, namespace, pod_name)
+ if not is_success:
+ print 'Error in deleting pod %s' % pod_name
+ return False
+
+ # Note: service name assumed to the the same as pod name
+ is_success = delete_service(kube_host, kube_port, namespace, pod_name)
+ if not is_success:
+ print 'Error in deleting service %s' % pod_name
+ return False
+
+ print 'Successfully deleted the Pod/Service: %s' % pod_name
+ return True
diff --git a/tools/jenkins/build_interop_stress_image.sh b/tools/jenkins/build_interop_stress_image.sh
index 92f2dab5e3..501dc5b7ca 100755
--- a/tools/jenkins/build_interop_stress_image.sh
+++ b/tools/jenkins/build_interop_stress_image.sh
@@ -35,6 +35,8 @@ set -x
# Params:
# INTEROP_IMAGE - name of tag of the final interop image
+# INTEROP_IMAGE_TAG - Optional. If set, the created image will be tagged using
+# the command: 'docker tag $INTEROP_IMAGE $INTEROP_IMAGE_REPOSITORY_TAG'
# BASE_NAME - base name used to locate the base Dockerfile and build script
# TTY_FLAG - optional -t flag to make docker allocate tty
# BUILD_INTEROP_DOCKER_EXTRA_ARGS - optional args to be passed to the
@@ -77,6 +79,7 @@ CONTAINER_NAME="build_${BASE_NAME}_$(uuidgen)"
$BASE_IMAGE \
bash -l /var/local/jenkins/grpc/tools/dockerfile/$BASE_NAME/build_interop_stress.sh \
&& docker commit $CONTAINER_NAME $INTEROP_IMAGE \
+ && ( if [ -n "$INTEROP_IMAGE_REPOSITORY_TAG" ]; then docker tag -f $INTEROP_IMAGE $INTEROP_IMAGE_REPOSITORY_TAG ; fi ) \
&& echo "Successfully built image $INTEROP_IMAGE")
EXITCODE=$?
diff --git a/tools/run_tests/distribtest_targets.py b/tools/run_tests/distribtest_targets.py
index 933103f0a0..34cc1cd710 100644
--- a/tools/run_tests/distribtest_targets.py
+++ b/tools/run_tests/distribtest_targets.py
@@ -96,6 +96,15 @@ class CSharpDistribTest(object):
return create_jobspec(self.name,
['test/distrib/csharp/run_distrib_test.sh'],
environ={'EXTERNAL_GIT_ROOT': '../../..'})
+ elif self.platform == 'windows':
+ if self.arch == 'x64':
+ environ={'MSBUILD_EXTRA_ARGS': '/p:Platform=x64',
+ 'DISTRIBTEST_OUTPATH': 'DistribTest\\bin\\x64\\Debug'}
+ else:
+ environ={'DISTRIBTEST_OUTPATH': 'DistribTest\\bin\\\Debug'}
+ return create_jobspec(self.name,
+ ['test\\distrib\\csharp\\run_distrib_test.bat'],
+ environ=environ)
else:
raise Exception("Not supported yet.")
@@ -240,6 +249,8 @@ def targets():
CSharpDistribTest('linux', 'x64', 'ubuntu1510'),
CSharpDistribTest('linux', 'x64', 'ubuntu1604'),
CSharpDistribTest('macos', 'x86'),
+ CSharpDistribTest('windows', 'x86'),
+ CSharpDistribTest('windows', 'x64'),
PythonDistribTest('linux', 'x64', 'wheezy'),
PythonDistribTest('linux', 'x64', 'jessie'),
PythonDistribTest('linux', 'x86', 'jessie'),
diff --git a/tools/run_tests/jobset.py b/tools/run_tests/jobset.py
index adf178bb3c..a3b246dc08 100755
--- a/tools/run_tests/jobset.py
+++ b/tools/run_tests/jobset.py
@@ -384,7 +384,8 @@ class Jobset(object):
self._travis,
self._add_env)
self._running.add(job)
- self.resultset[job.GetSpec().shortname] = []
+ if not self.resultset.has_key(job.GetSpec().shortname):
+ self.resultset[job.GetSpec().shortname] = []
return True
def reap(self):
diff --git a/tools/run_tests/post_test_node.bat b/tools/run_tests/post_test_node.bat
new file mode 100644
index 0000000000..1a2a5491fa
--- /dev/null
+++ b/tools/run_tests/post_test_node.bat
@@ -0,0 +1,30 @@
+@rem Copyright 2016, Google Inc.
+@rem All rights reserved.
+@rem
+@rem Redistribution and use in source and binary forms, with or without
+@rem modification, are permitted provided that the following conditions are
+@rem met:
+@rem
+@rem * Redistributions of source code must retain the above copyright
+@rem notice, this list of conditions and the following disclaimer.
+@rem * Redistributions in binary form must reproduce the above
+@rem copyright notice, this list of conditions and the following disclaimer
+@rem in the documentation and/or other materials provided with the
+@rem distribution.
+@rem * Neither the name of Google Inc. nor the names of its
+@rem contributors may be used to endorse or promote products derived from
+@rem this software without specific prior written permission.
+@rem
+@rem THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+@rem "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+@rem LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+@rem A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+@rem OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+@rem SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+@rem LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+@rem DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+@rem THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+@rem (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+@rem OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+rmdir node_modules /S /Q \ No newline at end of file
diff --git a/tools/run_tests/report_utils.py b/tools/run_tests/report_utils.py
index 0032a98523..df114e5dae 100644
--- a/tools/run_tests/report_utils.py
+++ b/tools/run_tests/report_utils.py
@@ -47,7 +47,7 @@ def _filter_msg(msg, output_format):
# that make XML report unparseable.
filtered_msg = filter(
lambda x: x in string.printable and x != '\f' and x != '\v',
- msg.decode(errors='ignore'))
+ msg.decode('UTF-8', 'ignore'))
if output_format == 'HTML':
filtered_msg = filtered_msg.replace('"', '&quot;')
return filtered_msg
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index 75de4cb71d..08a5ff0e8f 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -290,7 +290,10 @@ class NodeLanguage(object):
return [['tools/run_tests/build_node.sh', self.node_version]]
def post_tests_steps(self):
- return []
+ if self.platform == 'windows':
+ return [['tools\\run_tests\\post_test_node.bat']]
+ else:
+ return []
def makefile_name(self):
return 'Makefile'
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index 6b70f091eb..0c7a6c7b5f 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -5041,7 +5041,6 @@
"src/cpp/client/secure_credentials.cc",
"src/cpp/client/secure_credentials.h",
"src/cpp/codegen/grpc_library.cc",
- "src/cpp/common/alarm.cc",
"src/cpp/common/auth_property_iterator.cc",
"src/cpp/common/call.cc",
"src/cpp/common/channel_arguments.cc",
@@ -5300,7 +5299,6 @@
"src/cpp/client/generic_stub.cc",
"src/cpp/client/insecure_credentials.cc",
"src/cpp/codegen/grpc_library.cc",
- "src/cpp/common/alarm.cc",
"src/cpp/common/call.cc",
"src/cpp/common/channel_arguments.cc",
"src/cpp/common/completion_queue.cc",
diff --git a/tools/run_tests/stress_test/run_stress_tests_on_gke.py b/tools/run_tests/stress_test/run_stress_tests_on_gke.py
new file mode 100755
index 0000000000..634eb1aca5
--- /dev/null
+++ b/tools/run_tests/stress_test/run_stress_tests_on_gke.py
@@ -0,0 +1,556 @@
+#!/usr/bin/env python2.7
+# 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.
+import argparse
+import datetime
+import os
+import subprocess
+import sys
+import time
+
+stress_test_utils_dir = os.path.abspath(os.path.join(
+ os.path.dirname(__file__), '../../gcp/stress_test'))
+sys.path.append(stress_test_utils_dir)
+from stress_test_utils import BigQueryHelper
+
+kubernetes_api_dir = os.path.abspath(os.path.join(
+ os.path.dirname(__file__), '../../gcp/utils'))
+sys.path.append(kubernetes_api_dir)
+
+import kubernetes_api
+
+_GRPC_ROOT = os.path.abspath(os.path.join(
+ os.path.dirname(sys.argv[0]), '../../..'))
+os.chdir(_GRPC_ROOT)
+
+# num of seconds to wait for the GKE image to start and warmup
+_GKE_IMAGE_WARMUP_WAIT_SECS = 60
+
+_SERVER_POD_NAME = 'stress-server'
+_CLIENT_POD_NAME_PREFIX = 'stress-client'
+_DATASET_ID_PREFIX = 'stress_test'
+_SUMMARY_TABLE_ID = 'summary'
+_QPS_TABLE_ID = 'qps'
+
+_DEFAULT_DOCKER_IMAGE_NAME = 'grpc_stress_test'
+
+# The default port on which the kubernetes proxy server is started on localhost
+# (i.e kubectl proxy --port=<port>)
+_DEFAULT_KUBERNETES_PROXY_PORT = 8001
+
+# How frequently should the stress client wrapper script (running inside a GKE
+# container) poll the health of the stress client (also running inside the GKE
+# container) and upload metrics to BigQuery
+_DEFAULT_STRESS_CLIENT_POLL_INTERVAL_SECS = 60
+
+# The default setting for stress test server and client
+_DEFAULT_STRESS_SERVER_PORT = 8080
+_DEFAULT_METRICS_PORT = 8081
+_DEFAULT_TEST_CASES_STR = 'empty_unary:1,large_unary:1,client_streaming:1,server_streaming:1,empty_stream:1'
+_DEFAULT_NUM_CHANNELS_PER_SERVER = 5
+_DEFAULT_NUM_STUBS_PER_CHANNEL = 10
+_DEFAULT_METRICS_COLLECTION_INTERVAL_SECS = 30
+
+# Number of stress client instances to launch
+_DEFAULT_NUM_CLIENTS = 3
+
+# How frequently should this test monitor the health of Stress clients and
+# Servers running in GKE
+_DEFAULT_TEST_POLL_INTERVAL_SECS = 60
+
+# Default run time for this test (2 hour)
+_DEFAULT_TEST_DURATION_SECS = 7200
+
+# The number of seconds it would take a GKE pod to warm up (i.e get to 'Running'
+# state from the time of creation). Ideally this is something the test should
+# automatically determine by using Kubernetes API to poll the pods status.
+_DEFAULT_GKE_WARMUP_SECS = 60
+
+
+class KubernetesProxy:
+ """ Class to start a proxy on localhost to the Kubernetes API server """
+
+ def __init__(self, api_port):
+ self.port = api_port
+ self.p = None
+ self.started = False
+
+ def start(self):
+ cmd = ['kubectl', 'proxy', '--port=%d' % self.port]
+ self.p = subprocess.Popen(args=cmd)
+ self.started = True
+ time.sleep(2)
+ print '..Started'
+
+ def get_port(self):
+ return self.port
+
+ def is_started(self):
+ return self.started
+
+ def __del__(self):
+ if self.p is not None:
+ print 'Shutting down Kubernetes proxy..'
+ self.p.kill()
+
+
+class TestSettings:
+
+ def __init__(self, build_docker_image, test_poll_interval_secs,
+ test_duration_secs, kubernetes_proxy_port):
+ self.build_docker_image = build_docker_image
+ self.test_poll_interval_secs = test_poll_interval_secs
+ self.test_duration_secs = test_duration_secs
+ self.kubernetes_proxy_port = kubernetes_proxy_port
+
+
+class GkeSettings:
+
+ def __init__(self, project_id, docker_image_name):
+ self.project_id = project_id
+ self.docker_image_name = docker_image_name
+ self.tag_name = 'gcr.io/%s/%s' % (project_id, docker_image_name)
+
+
+class BigQuerySettings:
+
+ def __init__(self, run_id, dataset_id, summary_table_id, qps_table_id):
+ self.run_id = run_id
+ self.dataset_id = dataset_id
+ self.summary_table_id = summary_table_id
+ self.qps_table_id = qps_table_id
+
+
+class StressServerSettings:
+
+ def __init__(self, server_pod_name, server_port):
+ self.server_pod_name = server_pod_name
+ self.server_port = server_port
+
+
+class StressClientSettings:
+
+ def __init__(self, num_clients, client_pod_name_prefix, server_pod_name,
+ server_port, metrics_port, metrics_collection_interval_secs,
+ stress_client_poll_interval_secs, num_channels_per_server,
+ num_stubs_per_channel, test_cases_str):
+ self.num_clients = num_clients
+ self.client_pod_name_prefix = client_pod_name_prefix
+ self.server_pod_name = server_pod_name
+ self.server_port = server_port
+ self.metrics_port = metrics_port
+ self.metrics_collection_interval_secs = metrics_collection_interval_secs
+ self.stress_client_poll_interval_secs = stress_client_poll_interval_secs
+ self.num_channels_per_server = num_channels_per_server
+ self.num_stubs_per_channel = num_stubs_per_channel
+ self.test_cases_str = test_cases_str
+
+ # == Derived properties ==
+ # Note: Client can accept a list of server addresses (a comma separated list
+ # of 'server_name:server_port'). In this case, we only have one server
+ # address to pass
+ self.server_addresses = '%s.default.svc.cluster.local:%d' % (
+ server_pod_name, server_port)
+ self.client_pod_names_list = ['%s-%d' % (client_pod_name_prefix, i)
+ for i in range(1, num_clients + 1)]
+
+
+def _build_docker_image(image_name, tag_name):
+ """ Build the docker image and add tag it to the GKE repository """
+ print 'Building docker image: %s' % image_name
+ os.environ['INTEROP_IMAGE'] = image_name
+ os.environ['INTEROP_IMAGE_REPOSITORY_TAG'] = tag_name
+ # Note that 'BASE_NAME' HAS to be 'grpc_interop_stress_cxx' since the script
+ # build_interop_stress_image.sh invokes the following script:
+ # tools/dockerfile/$BASE_NAME/build_interop_stress.sh
+ os.environ['BASE_NAME'] = 'grpc_interop_stress_cxx'
+ cmd = ['tools/jenkins/build_interop_stress_image.sh']
+ retcode = subprocess.call(args=cmd)
+ if retcode != 0:
+ print 'Error in building docker image'
+ return False
+ return True
+
+
+def _push_docker_image_to_gke_registry(docker_tag_name):
+ """Executes 'gcloud docker push <docker_tag_name>' to push the image to GKE registry"""
+ cmd = ['gcloud', 'docker', 'push', docker_tag_name]
+ print 'Pushing %s to GKE registry..' % docker_tag_name
+ retcode = subprocess.call(args=cmd)
+ if retcode != 0:
+ print 'Error in pushing docker image %s to the GKE registry' % docker_tag_name
+ return False
+ return True
+
+
+def _launch_server(gke_settings, stress_server_settings, bq_settings,
+ kubernetes_proxy):
+ """ Launches a stress test server instance in GKE cluster """
+ if not kubernetes_proxy.is_started:
+ print 'Kubernetes proxy must be started before calling this function'
+ return False
+
+ # This is the wrapper script that is run in the container. This script runs
+ # the actual stress test server
+ server_cmd_list = ['/var/local/git/grpc/tools/gcp/stress_test/run_server.py']
+
+ # run_server.py does not take any args from the command line. The args are
+ # instead passed via environment variables (see server_env below)
+ server_arg_list = []
+
+ # The parameters to the script run_server.py are injected into the container
+ # via environment variables
+ server_env = {
+ 'STRESS_TEST_IMAGE_TYPE': 'SERVER',
+ 'STRESS_TEST_IMAGE': '/var/local/git/grpc/bins/opt/interop_server',
+ 'STRESS_TEST_ARGS_STR': '--port=%s' % stress_server_settings.server_port,
+ 'RUN_ID': bq_settings.run_id,
+ 'POD_NAME': stress_server_settings.server_pod_name,
+ 'GCP_PROJECT_ID': gke_settings.project_id,
+ 'DATASET_ID': bq_settings.dataset_id,
+ 'SUMMARY_TABLE_ID': bq_settings.summary_table_id,
+ 'QPS_TABLE_ID': bq_settings.qps_table_id
+ }
+
+ # Launch Server
+ is_success = kubernetes_api.create_pod_and_service(
+ 'localhost',
+ kubernetes_proxy.get_port(),
+ 'default', # Use 'default' namespace
+ stress_server_settings.server_pod_name,
+ gke_settings.tag_name,
+ [stress_server_settings.server_port], # Port that should be exposed
+ server_cmd_list,
+ server_arg_list,
+ server_env,
+ True # Headless = True for server. Since we want DNS records to be created by GKE
+ )
+
+ return is_success
+
+
+def _launch_client(gke_settings, stress_server_settings, stress_client_settings,
+ bq_settings, kubernetes_proxy):
+ """ Launches a configurable number of stress test clients on GKE cluster """
+ if not kubernetes_proxy.is_started:
+ print 'Kubernetes proxy must be started before calling this function'
+ return False
+
+ stress_client_arg_list = [
+ '--server_addresses=%s' % stress_client_settings.server_addresses,
+ '--test_cases=%s' % stress_client_settings.test_cases_str,
+ '--num_stubs_per_channel=%d' %
+ stress_client_settings.num_stubs_per_channel
+ ]
+
+ # This is the wrapper script that is run in the container. This script runs
+ # the actual stress client
+ client_cmd_list = ['/var/local/git/grpc/tools/gcp/stress_test/run_client.py']
+
+ # run_client.py takes no args. All args are passed as env variables (see
+ # client_env)
+ client_arg_list = []
+
+ metrics_server_address = 'localhost:%d' % stress_client_settings.metrics_port
+ metrics_client_arg_list = [
+ '--metrics_server_address=%s' % metrics_server_address,
+ '--total_only=true'
+ ]
+
+ # The parameters to the script run_client.py are injected into the container
+ # via environment variables
+ client_env = {
+ 'STRESS_TEST_IMAGE_TYPE': 'CLIENT',
+ 'STRESS_TEST_IMAGE': '/var/local/git/grpc/bins/opt/stress_test',
+ 'STRESS_TEST_ARGS_STR': ' '.join(stress_client_arg_list),
+ 'METRICS_CLIENT_IMAGE': '/var/local/git/grpc/bins/opt/metrics_client',
+ 'METRICS_CLIENT_ARGS_STR': ' '.join(metrics_client_arg_list),
+ 'RUN_ID': bq_settings.run_id,
+ 'POLL_INTERVAL_SECS':
+ str(stress_client_settings.stress_client_poll_interval_secs),
+ 'GCP_PROJECT_ID': gke_settings.project_id,
+ 'DATASET_ID': bq_settings.dataset_id,
+ 'SUMMARY_TABLE_ID': bq_settings.summary_table_id,
+ 'QPS_TABLE_ID': bq_settings.qps_table_id
+ }
+
+ for pod_name in stress_client_settings.client_pod_names_list:
+ client_env['POD_NAME'] = pod_name
+ is_success = kubernetes_api.create_pod_and_service(
+ 'localhost', # Since proxy is running on localhost
+ kubernetes_proxy.get_port(),
+ 'default', # default namespace
+ pod_name,
+ gke_settings.tag_name,
+ [stress_client_settings.metrics_port
+ ], # Client pods expose metrics port
+ client_cmd_list,
+ client_arg_list,
+ client_env,
+ False # Client is not a headless service
+ )
+ if not is_success:
+ print 'Error in launching client %s' % pod_name
+ return False
+
+ return True
+
+
+def _launch_server_and_client(gke_settings, stress_server_settings,
+ stress_client_settings, bq_settings,
+ kubernetes_proxy_port):
+ # Start kubernetes proxy
+ print 'Kubernetes proxy'
+ kubernetes_proxy = KubernetesProxy(kubernetes_proxy_port)
+ kubernetes_proxy.start()
+
+ print 'Launching server..'
+ is_success = _launch_server(gke_settings, stress_server_settings, bq_settings,
+ kubernetes_proxy)
+ if not is_success:
+ print 'Error in launching server'
+ return False
+
+ # Server takes a while to start.
+ # TODO(sree) Use Kubernetes API to query the status of the server instead of
+ # sleeping
+ print 'Waiting for %s seconds for the server to start...' % _GKE_IMAGE_WARMUP_WAIT_SECS
+ time.sleep(_GKE_IMAGE_WARMUP_WAIT_SECS)
+
+ # Launch client
+ client_pod_name_prefix = 'stress-client'
+ is_success = _launch_client(gke_settings, stress_server_settings,
+ stress_client_settings, bq_settings,
+ kubernetes_proxy)
+
+ if not is_success:
+ print 'Error in launching client(s)'
+ return False
+
+ print 'Waiting for %s seconds for the client images to start...' % _GKE_IMAGE_WARMUP_WAIT_SECS
+ time.sleep(_GKE_IMAGE_WARMUP_WAIT_SECS)
+ return True
+
+
+def _delete_server_and_client(stress_server_settings, stress_client_settings,
+ kubernetes_proxy_port):
+ kubernetes_proxy = KubernetesProxy(kubernetes_proxy_port)
+ kubernetes_proxy.start()
+
+ # Delete clients first
+ is_success = True
+ for pod_name in stress_client_settings.client_pod_names_list:
+ is_success = kubernetes_api.delete_pod_and_service(
+ 'localhost', kubernetes_proxy_port, 'default', pod_name)
+ if not is_success:
+ return False
+
+ # Delete server
+ is_success = kubernetes_api.delete_pod_and_service(
+ 'localhost', kubernetes_proxy_port, 'default',
+ stress_server_settings.server_pod_name)
+ return is_success
+
+
+def run_test_main(test_settings, gke_settings, stress_server_settings,
+ stress_client_clients):
+ is_success = True
+
+ if test_settings.build_docker_image:
+ is_success = _build_docker_image(gke_settings.docker_image_name,
+ gke_settings.tag_name)
+ if not is_success:
+ return False
+
+ is_success = _push_docker_image_to_gke_registry(gke_settings.tag_name)
+ if not is_success:
+ return False
+
+ # Create a unique id for this run (Note: Using timestamp instead of UUID to
+ # make it easier to deduce the date/time of the run just by looking at the run
+ # run id. This is useful in debugging when looking at records in Biq query)
+ run_id = datetime.datetime.now().strftime('%Y_%m_%d_%H_%M_%S')
+ dataset_id = '%s_%s' % (_DATASET_ID_PREFIX, run_id)
+
+ # Big Query settings (common for both Stress Server and Client)
+ bq_settings = BigQuerySettings(run_id, dataset_id, _SUMMARY_TABLE_ID,
+ _QPS_TABLE_ID)
+
+ bq_helper = BigQueryHelper(run_id, '', '', args.project_id, dataset_id,
+ _SUMMARY_TABLE_ID, _QPS_TABLE_ID)
+ bq_helper.initialize()
+
+ try:
+ is_success = _launch_server_and_client(gke_settings, stress_server_settings,
+ stress_client_settings, bq_settings,
+ test_settings.kubernetes_proxy_port)
+ if not is_success:
+ return False
+
+ start_time = datetime.datetime.now()
+ end_time = start_time + datetime.timedelta(
+ seconds=test_settings.test_duration_secs)
+ print 'Running the test until %s' % end_time.isoformat()
+
+ while True:
+ if datetime.datetime.now() > end_time:
+ print 'Test was run for %d seconds' % test_settings.test_duration_secs
+ break
+
+ # Check if either stress server or clients have failed
+ if bq_helper.check_if_any_tests_failed():
+ is_success = False
+ print 'Some tests failed.'
+ break
+
+ # Things seem to be running fine. Wait until next poll time to check the
+ # status
+ print 'Sleeping for %d seconds..' % test_settings.test_poll_interval_secs
+ time.sleep(test_settings.test_poll_interval_secs)
+
+ # Print BiqQuery tables
+ bq_helper.print_summary_records()
+ bq_helper.print_qps_records()
+
+ finally:
+ # If is_success is False at this point, it means that the stress tests were
+ # started successfully but failed while running the tests. In this case we
+ # do should not delete the pods (since they contain all the failure
+ # information)
+ if is_success:
+ _delete_server_and_client(stress_server_settings, stress_client_settings,
+ test_settings.kubernetes_proxy_port)
+
+ return is_success
+
+
+argp = argparse.ArgumentParser(
+ description='Launch stress tests in GKE',
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter)
+argp.add_argument('--project_id',
+ required=True,
+ help='The Google Cloud Platform Project Id')
+argp.add_argument('--num_clients',
+ default=1,
+ type=int,
+ help='Number of client instances to start')
+argp.add_argument('--docker_image_name',
+ default=_DEFAULT_DOCKER_IMAGE_NAME,
+ help='The name of the docker image containing stress client '
+ 'and stress servers')
+argp.add_argument('--build_docker_image',
+ dest='build_docker_image',
+ action='store_true',
+ help='Build a docker image and push to Google Container '
+ 'Registry')
+argp.add_argument('--do_not_build_docker_image',
+ dest='build_docker_image',
+ action='store_false',
+ help='Do not build and push docker image to Google Container '
+ 'Registry')
+argp.set_defaults(build_docker_image=True)
+
+argp.add_argument('--test_poll_interval_secs',
+ default=_DEFAULT_TEST_POLL_INTERVAL_SECS,
+ type=int,
+ help='How frequently should this script should monitor the '
+ 'health of stress clients and servers running in the GKE '
+ 'cluster')
+argp.add_argument('--test_duration_secs',
+ default=_DEFAULT_TEST_DURATION_SECS,
+ type=int,
+ help='How long should this test be run')
+argp.add_argument('--kubernetes_proxy_port',
+ default=_DEFAULT_KUBERNETES_PROXY_PORT,
+ type=int,
+ help='The port on which the kubernetes proxy (on localhost)'
+ ' is started')
+argp.add_argument('--stress_server_port',
+ default=_DEFAULT_STRESS_SERVER_PORT,
+ type=int,
+ help='The port on which the stress server (in GKE '
+ 'containers) listens')
+argp.add_argument('--stress_client_metrics_port',
+ default=_DEFAULT_METRICS_PORT,
+ type=int,
+ help='The port on which the stress clients (in GKE '
+ 'containers) expose metrics')
+argp.add_argument('--stress_client_poll_interval_secs',
+ default=_DEFAULT_STRESS_CLIENT_POLL_INTERVAL_SECS,
+ type=int,
+ help='How frequently should the stress client wrapper script'
+ ' running inside GKE should monitor health of the actual '
+ ' stress client process and upload the metrics to BigQuery')
+argp.add_argument('--stress_client_metrics_collection_interval_secs',
+ default=_DEFAULT_METRICS_COLLECTION_INTERVAL_SECS,
+ type=int,
+ help='How frequently should metrics be collected in-memory on'
+ ' the stress clients (running inside GKE containers). Note '
+ 'that this is NOT the same as the upload-to-BigQuery '
+ 'frequency. The metrics upload frequency is controlled by the'
+ ' --stress_client_poll_interval_secs flag')
+argp.add_argument('--stress_client_num_channels_per_server',
+ default=_DEFAULT_NUM_CHANNELS_PER_SERVER,
+ type=int,
+ help='The number of channels created to each server from a '
+ 'stress client')
+argp.add_argument('--stress_client_num_stubs_per_channel',
+ default=_DEFAULT_NUM_STUBS_PER_CHANNEL,
+ type=int,
+ help='The number of stubs created per channel. This number '
+ 'indicates the max number of RPCs that can be made in '
+ 'parallel on each channel at any given time')
+argp.add_argument('--stress_client_test_cases',
+ default=_DEFAULT_TEST_CASES_STR,
+ help='List of test cases (with weights) to be executed by the'
+ ' stress test client. The list is in the following format:\n'
+ ' <testcase_1:w_1,<test_case2:w_2>..<testcase_n:w_n>\n'
+ ' (Note: The weights do not have to add up to 100)')
+
+if __name__ == '__main__':
+ args = argp.parse_args()
+
+ test_settings = TestSettings(
+ args.build_docker_image, args.test_poll_interval_secs,
+ args.test_duration_secs, args.kubernetes_proxy_port)
+
+ gke_settings = GkeSettings(args.project_id, args.docker_image_name)
+
+ stress_server_settings = StressServerSettings(_SERVER_POD_NAME,
+ args.stress_server_port)
+ stress_client_settings = StressClientSettings(
+ args.num_clients, _CLIENT_POD_NAME_PREFIX, _SERVER_POD_NAME,
+ args.stress_server_port, args.stress_client_metrics_port,
+ args.stress_client_metrics_collection_interval_secs,
+ args.stress_client_poll_interval_secs,
+ args.stress_client_num_channels_per_server,
+ args.stress_client_num_stubs_per_channel, args.stress_client_test_cases)
+
+ run_test_main(test_settings, gke_settings, stress_server_settings,
+ stress_client_settings)
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
index c62faf33e6..0b8c345196 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
@@ -369,8 +369,6 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\cpp\client\insecure_credentials.cc">
</ClCompile>
- <ClCompile Include="$(SolutionDir)\..\src\cpp\common\alarm.cc">
- </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\cpp\common\call.cc">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\cpp\common\channel_arguments.cc">
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
index 5f9350e76a..0f3dccf17c 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
@@ -40,9 +40,6 @@
<ClCompile Include="$(SolutionDir)\..\src\cpp\client\insecure_credentials.cc">
<Filter>src\cpp\client</Filter>
</ClCompile>
- <ClCompile Include="$(SolutionDir)\..\src\cpp\common\alarm.cc">
- <Filter>src\cpp\common</Filter>
- </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\cpp\common\call.cc">
<Filter>src\cpp\common</Filter>
</ClCompile>
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
index fb4246580f..2dcadbaec0 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
@@ -356,8 +356,6 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\cpp\client\insecure_credentials.cc">
</ClCompile>
- <ClCompile Include="$(SolutionDir)\..\src\cpp\common\alarm.cc">
- </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\cpp\common\call.cc">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\cpp\common\channel_arguments.cc">
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
index eeff7d3697..3572c651b6 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
@@ -25,9 +25,6 @@
<ClCompile Include="$(SolutionDir)\..\src\cpp\client\insecure_credentials.cc">
<Filter>src\cpp\client</Filter>
</ClCompile>
- <ClCompile Include="$(SolutionDir)\..\src\cpp\common\alarm.cc">
- <Filter>src\cpp\common</Filter>
- </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\cpp\common\call.cc">
<Filter>src\cpp\common</Filter>
</ClCompile>