aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Nicolas "Pixel" Noble <pixel@nobis-crew.org>2017-08-30 23:13:25 +0200
committerGravatar Nicolas "Pixel" Noble <pixel@nobis-crew.org>2017-08-30 23:13:25 +0200
commit90df76b4633c6a3c8a492148ba5268b94284ea6a (patch)
tree91ec10271620b7d9baaf510bbfc11349bd4fa663 /src
parent2bc5e3ac40fc1b6f7d329a1727c78e8a820d5cf6 (diff)
parent7a8488c4d2b0274c7c71cd15d39f0cf277a3a119 (diff)
Merge branch 'master' of https://github.com/grpc/grpc into visibility
Diffstat (limited to 'src')
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c1
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c27
-rw-r--r--src/core/ext/filters/http/message_compress/message_compress_filter.c121
-rw-r--r--src/core/ext/transport/chttp2/transport/chttp2_transport.c12
-rw-r--r--src/core/ext/transport/chttp2/transport/flow_control.c4
-rw-r--r--src/core/ext/transport/chttp2/transport/hpack_parser.c24
-rw-r--r--src/core/lib/channel/channel_args.c98
-rw-r--r--src/core/lib/channel/channel_args.h31
-rw-r--r--src/core/lib/compression/algorithm_metadata.h14
-rw-r--r--src/core/lib/compression/compression.c100
-rw-r--r--src/core/lib/iomgr/ev_epoll1_linux.c281
-rw-r--r--src/core/lib/iomgr/ev_epollex_linux.c2
-rw-r--r--src/core/lib/profiling/timers.h26
-rw-r--r--src/core/lib/security/credentials/jwt/jwt_verifier.c17
-rw-r--r--src/core/lib/security/credentials/oauth2/oauth2_credentials.c8
-rw-r--r--src/core/lib/support/block_annotate.h22
-rw-r--r--src/core/lib/surface/call.c300
-rw-r--r--src/core/lib/surface/call_test_only.h12
-rw-r--r--src/core/lib/surface/channel.c29
-rw-r--r--src/core/lib/surface/completion_queue.c2
-rw-r--r--src/core/lib/surface/version.c2
-rw-r--r--src/core/lib/transport/static_metadata.c816
-rw-r--r--src/core/lib/transport/static_metadata.h296
-rw-r--r--src/cpp/common/channel_filter.cc2
-rw-r--r--src/cpp/common/channel_filter.h2
-rw-r--r--src/cpp/common/version_cc.cc2
-rw-r--r--src/csharp/Grpc.Core.Tests/NUnitMain.cs2
-rw-r--r--src/csharp/Grpc.Core/Grpc.Core.targets8
-rw-r--r--src/csharp/Grpc.Core/GrpcEnvironment.cs2
-rw-r--r--src/csharp/Grpc.Core/Internal/AtomicCounter.cs2
-rw-r--r--src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs37
-rw-r--r--src/csharp/Grpc.Core/Logging/LogLevel.cs6
-rw-r--r--src/csharp/Grpc.Core/Logging/LogLevelFilterLogger.cs43
-rwxr-xr-xsrc/csharp/Grpc.Core/Version.csproj.include2
-rw-r--r--src/csharp/Grpc.Core/VersionInfo.cs4
-rw-r--r--src/csharp/Grpc.Examples.Tests/NUnitMain.cs2
-rw-r--r--src/csharp/Grpc.HealthCheck.Tests/NUnitMain.cs2
-rw-r--r--src/csharp/Grpc.IntegrationTesting/NUnitMain.cs2
-rw-r--r--src/csharp/Grpc.Microbenchmarks/Program.cs2
-rw-r--r--src/csharp/Grpc.Reflection.Tests/NUnitMain.cs2
-rwxr-xr-xsrc/csharp/build_packages_dotnetcli.bat2
-rwxr-xr-xsrc/csharp/build_packages_dotnetcli.sh4
-rw-r--r--src/node/health_check/package.json4
-rw-r--r--src/node/tools/package.json2
-rw-r--r--src/objective-c/!ProtoCompiler-gRPCPlugin.podspec2
-rw-r--r--src/objective-c/GRPCClient/GRPCCall+GID.h29
-rw-r--r--src/objective-c/GRPCClient/GRPCCall+GID.m (renamed from src/core/lib/support/thd_internal.h)14
-rw-r--r--src/objective-c/GRPCClient/GRPCCall+OAuth2.h15
-rw-r--r--src/objective-c/GRPCClient/GRPCCall+OAuth2.m11
-rw-r--r--src/objective-c/GRPCClient/GRPCCall.m73
-rw-r--r--src/objective-c/GRPCClient/private/GRPCRequestHeaders.m1
-rw-r--r--src/objective-c/GRPCClient/private/GRPCWrappedCall.m2
-rw-r--r--src/objective-c/GRPCClient/private/version.h2
-rw-r--r--src/objective-c/RxLibrary/GRXConcurrentWriteable.m38
-rwxr-xr-xsrc/objective-c/tests/build_one_example.sh6
-rwxr-xr-xsrc/objective-c/tests/run_tests.sh22
-rw-r--r--src/php/composer.json2
-rw-r--r--src/php/ext/grpc/call_credentials.c2
-rw-r--r--src/php/ext/grpc/channel.c40
-rw-r--r--src/php/ext/grpc/channel_credentials.c8
-rw-r--r--src/php/ext/grpc/php_grpc.c42
-rw-r--r--src/php/ext/grpc/php_grpc.h6
-rw-r--r--src/php/ext/grpc/version.h2
-rw-r--r--src/php/lib/Grpc/ServerStreamingCall.php28
-rw-r--r--src/php/lib/Grpc/UnaryCall.php28
-rw-r--r--src/php/tests/unit_tests/ChannelTest.php15
-rw-r--r--src/python/grpcio/grpc/_grpcio_metadata.py2
-rw-r--r--src/python/grpcio/grpc_version.py2
-rw-r--r--src/python/grpcio_health_checking/grpc_version.py2
-rw-r--r--src/python/grpcio_reflection/grpc_version.py2
-rw-r--r--src/python/grpcio_tests/grpc_version.py2
-rw-r--r--src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py3
-rw-r--r--src/ruby/ext/grpc/rb_call.c3
-rw-r--r--src/ruby/ext/grpc/rb_grpc_imports.generated.c6
-rw-r--r--src/ruby/ext/grpc/rb_grpc_imports.generated.h9
-rw-r--r--src/ruby/lib/grpc/generic/rpc_desc.rb6
-rw-r--r--src/ruby/lib/grpc/version.rb2
-rw-r--r--src/ruby/spec/generic/rpc_desc_spec.rb38
-rw-r--r--src/ruby/tools/version.rb2
79 files changed, 2004 insertions, 842 deletions
diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c
index bb9217d843..087b4076e2 100644
--- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c
@@ -1544,6 +1544,7 @@ static void lb_on_response_received_locked(grpc_exec_ctx *exec_ctx, void *arg,
grpc_byte_buffer_reader bbr;
grpc_byte_buffer_reader_init(&bbr, glb_policy->lb_response_payload);
grpc_slice response_slice = grpc_byte_buffer_reader_readall(&bbr);
+ grpc_byte_buffer_reader_destroy(&bbr);
grpc_byte_buffer_destroy(glb_policy->lb_response_payload);
grpc_grpclb_initial_response *response = NULL;
diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c
index a7f7e9542c..110a9c8047 100644
--- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c
+++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c
@@ -74,9 +74,6 @@ typedef struct round_robin_lb_policy {
bool started_picking;
/** are we shutting down? */
bool shutdown;
- /** has the policy gotten into the GRPC_CHANNEL_SHUTDOWN? No picks can be
- * service after this point, the policy will never transition out. */
- bool in_connectivity_shutdown;
/** List of picks that are waiting on connectivity */
pending_pick *pending_picks;
@@ -424,7 +421,6 @@ static int rr_pick_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
grpc_closure *on_complete) {
round_robin_lb_policy *p = (round_robin_lb_policy *)pol;
GPR_ASSERT(!p->shutdown);
- GPR_ASSERT(!p->in_connectivity_shutdown);
if (GRPC_TRACER_ON(grpc_lb_round_robin_trace)) {
gpr_log(GPR_INFO, "[RR %p] Trying to pick", (void *)pol);
}
@@ -537,7 +533,7 @@ static grpc_connectivity_state update_lb_connectivity_status_locked(
grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_REF(error),
"rr_shutdown");
- p->in_connectivity_shutdown = true;
+ p->shutdown = true;
new_state = GRPC_CHANNEL_SHUTDOWN;
} else if (subchannel_list->num_transient_failures ==
p->subchannel_list->num_subchannels) { /* 4) TRANSIENT_FAILURE */
@@ -811,19 +807,30 @@ static void rr_update_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
sc_args.args = new_args;
grpc_subchannel *subchannel = grpc_client_channel_factory_create_subchannel(
exec_ctx, args->client_channel_factory, &sc_args);
+ grpc_channel_args_destroy(exec_ctx, new_args);
+ grpc_error *error;
+ // Get the connectivity state of the subchannel. Already existing ones may
+ // be in a state other than INIT.
+ const grpc_connectivity_state subchannel_connectivity_state =
+ grpc_subchannel_check_connectivity(subchannel, &error);
+ if (error != GRPC_ERROR_NONE) {
+ // The subchannel is in error (e.g. shutting down). Ignore it.
+ GRPC_SUBCHANNEL_UNREF(exec_ctx, subchannel, "new_sc_connectivity_error");
+ GRPC_ERROR_UNREF(error);
+ continue;
+ }
if (GRPC_TRACER_ON(grpc_lb_round_robin_trace)) {
char *address_uri =
grpc_sockaddr_to_uri(&addresses->addresses[i].address);
gpr_log(
GPR_DEBUG,
"[RR %p] index %lu: Created subchannel %p for address uri %s into "
- "subchannel_list %p",
+ "subchannel_list %p. Connectivity state %s",
(void *)p, (unsigned long)subchannel_index, (void *)subchannel,
- address_uri, (void *)subchannel_list);
+ address_uri, (void *)subchannel_list,
+ grpc_connectivity_state_name(subchannel_connectivity_state));
gpr_free(address_uri);
}
- grpc_channel_args_destroy(exec_ctx, new_args);
-
subchannel_data *sd = &subchannel_list->subchannels[subchannel_index++];
sd->subchannel_list = subchannel_list;
sd->subchannel = subchannel;
@@ -835,7 +842,7 @@ static void rr_update_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
* won't be referring to this value again and it'll be overwritten after
* the first call to rr_connectivity_changed_locked */
sd->prev_connectivity_state = GRPC_CHANNEL_INIT;
- sd->curr_connectivity_state = GRPC_CHANNEL_IDLE;
+ sd->curr_connectivity_state = subchannel_connectivity_state;
sd->user_data_vtable = addresses->user_data_vtable;
if (sd->user_data_vtable != NULL) {
sd->user_data =
diff --git a/src/core/ext/filters/http/message_compress/message_compress_filter.c b/src/core/ext/filters/http/message_compress/message_compress_filter.c
index 20a3488115..a32819bfe4 100644
--- a/src/core/ext/filters/http/message_compress/message_compress_filter.c
+++ b/src/core/ext/filters/http/message_compress/message_compress_filter.c
@@ -44,7 +44,9 @@
typedef struct call_data {
grpc_slice_buffer slices; /**< Buffers up input slices to be compressed */
grpc_linked_mdelem compression_algorithm_storage;
+ grpc_linked_mdelem stream_compression_algorithm_storage;
grpc_linked_mdelem accept_encoding_storage;
+ grpc_linked_mdelem accept_stream_encoding_storage;
uint32_t remaining_slice_bytes;
/** Compression algorithm we'll try to use. It may be given by incoming
* metadata, or by the channel's default compression settings. */
@@ -75,6 +77,13 @@ typedef struct channel_data {
uint32_t enabled_algorithms_bitset;
/** Supported compression algorithms */
uint32_t supported_compression_algorithms;
+
+ /** The default, channel-level, stream compression algorithm */
+ grpc_stream_compression_algorithm default_stream_compression_algorithm;
+ /** Bitset of enabled stream compression algorithms */
+ uint32_t enabled_stream_compression_algorithms_bitset;
+ /** Supported stream compression algorithms */
+ uint32_t supported_stream_compression_algorithms;
} channel_data;
static bool skip_compression(grpc_call_element *elem, uint32_t flags,
@@ -106,31 +115,56 @@ static grpc_error *process_send_initial_metadata(
call_data *calld = elem->call_data;
channel_data *channeld = elem->channel_data;
*has_compression_algorithm = false;
- /* Parse incoming request for compression. If any, it'll be available
- * at calld->compression_algorithm */
- if (initial_metadata->idx.named.grpc_internal_encoding_request != NULL) {
+ grpc_stream_compression_algorithm stream_compression_algorithm =
+ GRPC_STREAM_COMPRESS_NONE;
+ if (initial_metadata->idx.named.grpc_internal_stream_encoding_request !=
+ NULL) {
grpc_mdelem md =
- initial_metadata->idx.named.grpc_internal_encoding_request->md;
- if (!grpc_compression_algorithm_parse(GRPC_MDVALUE(md),
- &calld->compression_algorithm)) {
+ initial_metadata->idx.named.grpc_internal_stream_encoding_request->md;
+ if (!grpc_stream_compression_algorithm_parse(
+ GRPC_MDVALUE(md), &stream_compression_algorithm)) {
char *val = grpc_slice_to_c_string(GRPC_MDVALUE(md));
gpr_log(GPR_ERROR,
- "Invalid compression algorithm: '%s' (unknown). Ignoring.", val);
+ "Invalid stream compression algorithm: '%s' (unknown). Ignoring.",
+ val);
gpr_free(val);
- calld->compression_algorithm = GRPC_COMPRESS_NONE;
+ stream_compression_algorithm = GRPC_STREAM_COMPRESS_NONE;
+ }
+ if (!GPR_BITGET(channeld->enabled_stream_compression_algorithms_bitset,
+ stream_compression_algorithm)) {
+ char *val = grpc_slice_to_c_string(GRPC_MDVALUE(md));
+ gpr_log(
+ GPR_ERROR,
+ "Invalid stream compression algorithm: '%s' (previously disabled). "
+ "Ignoring.",
+ val);
+ gpr_free(val);
+ stream_compression_algorithm = GRPC_STREAM_COMPRESS_NONE;
+ }
+ *has_compression_algorithm = true;
+ grpc_metadata_batch_remove(
+ exec_ctx, initial_metadata,
+ initial_metadata->idx.named.grpc_internal_stream_encoding_request);
+ /* Disable message-wise compression */
+ calld->compression_algorithm = GRPC_COMPRESS_NONE;
+ if (initial_metadata->idx.named.grpc_internal_encoding_request != NULL) {
+ grpc_metadata_batch_remove(
+ exec_ctx, initial_metadata,
+ initial_metadata->idx.named.grpc_internal_encoding_request);
}
- if (!GPR_BITGET(channeld->enabled_algorithms_bitset,
- calld->compression_algorithm)) {
+ } else if (initial_metadata->idx.named.grpc_internal_encoding_request !=
+ NULL) {
+ grpc_mdelem md =
+ initial_metadata->idx.named.grpc_internal_encoding_request->md;
+ if (!grpc_compression_algorithm_parse(GRPC_MDVALUE(md),
+ &calld->compression_algorithm)) {
char *val = grpc_slice_to_c_string(GRPC_MDVALUE(md));
gpr_log(GPR_ERROR,
- "Invalid compression algorithm: '%s' (previously disabled). "
- "Ignoring.",
- val);
+ "Invalid compression algorithm: '%s' (unknown). Ignoring.", val);
gpr_free(val);
calld->compression_algorithm = GRPC_COMPRESS_NONE;
}
*has_compression_algorithm = true;
-
grpc_metadata_batch_remove(
exec_ctx, initial_metadata,
initial_metadata->idx.named.grpc_internal_encoding_request);
@@ -138,13 +172,25 @@ static grpc_error *process_send_initial_metadata(
/* If no algorithm was found in the metadata and we aren't
* exceptionally skipping compression, fall back to the channel
* default */
- calld->compression_algorithm = channeld->default_compression_algorithm;
+ if (channeld->default_stream_compression_algorithm !=
+ GRPC_STREAM_COMPRESS_NONE) {
+ stream_compression_algorithm =
+ channeld->default_stream_compression_algorithm;
+ calld->compression_algorithm = GRPC_COMPRESS_NONE;
+ } else {
+ calld->compression_algorithm = channeld->default_compression_algorithm;
+ }
*has_compression_algorithm = true;
}
grpc_error *error = GRPC_ERROR_NONE;
/* hint compression algorithm */
- if (calld->compression_algorithm != GRPC_COMPRESS_NONE) {
+ if (stream_compression_algorithm != GRPC_STREAM_COMPRESS_NONE) {
+ error = grpc_metadata_batch_add_tail(
+ exec_ctx, initial_metadata,
+ &calld->stream_compression_algorithm_storage,
+ grpc_stream_compression_encoding_mdelem(stream_compression_algorithm));
+ } else if (calld->compression_algorithm != GRPC_COMPRESS_NONE) {
error = grpc_metadata_batch_add_tail(
exec_ctx, initial_metadata, &calld->compression_algorithm_storage,
grpc_compression_encoding_mdelem(calld->compression_algorithm));
@@ -158,6 +204,16 @@ static grpc_error *process_send_initial_metadata(
GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(
channeld->supported_compression_algorithms));
+ if (error != GRPC_ERROR_NONE) return error;
+
+ /* Do not overwrite accept-encoding header if it already presents. */
+ if (!initial_metadata->idx.named.accept_encoding) {
+ error = grpc_metadata_batch_add_tail(
+ exec_ctx, initial_metadata, &calld->accept_stream_encoding_storage,
+ GRPC_MDELEM_ACCEPT_STREAM_ENCODING_FOR_ALGORITHMS(
+ channeld->supported_stream_compression_algorithms));
+ }
+
return error;
}
@@ -435,6 +491,7 @@ static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element_args *args) {
channel_data *channeld = elem->channel_data;
+ /* Configuration for message compression */
channeld->enabled_algorithms_bitset =
grpc_channel_args_compression_algorithm_get_states(args->channel_args);
@@ -449,16 +506,32 @@ static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
channeld->default_compression_algorithm = GRPC_COMPRESS_NONE;
}
- channeld->supported_compression_algorithms = 1; /* always support identity */
- for (grpc_compression_algorithm algo_idx = 1;
- algo_idx < GRPC_COMPRESS_ALGORITHMS_COUNT; ++algo_idx) {
- /* skip disabled algorithms */
- if (!GPR_BITGET(channeld->enabled_algorithms_bitset, algo_idx)) {
- continue;
- }
- channeld->supported_compression_algorithms |= 1u << algo_idx;
+ channeld->supported_compression_algorithms =
+ (((1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1) &
+ channeld->enabled_algorithms_bitset) |
+ 1u;
+
+ /* Configuration for stream compression */
+ channeld->enabled_stream_compression_algorithms_bitset =
+ grpc_channel_args_stream_compression_algorithm_get_states(
+ args->channel_args);
+
+ channeld->default_stream_compression_algorithm =
+ grpc_channel_args_get_stream_compression_algorithm(args->channel_args);
+
+ if (!GPR_BITGET(channeld->enabled_stream_compression_algorithms_bitset,
+ channeld->default_stream_compression_algorithm)) {
+ gpr_log(GPR_DEBUG,
+ "stream compression algorithm %d not enabled: switching to none",
+ channeld->default_stream_compression_algorithm);
+ channeld->default_stream_compression_algorithm = GRPC_STREAM_COMPRESS_NONE;
}
+ channeld->supported_stream_compression_algorithms =
+ (((1u << GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT) - 1) &
+ channeld->enabled_stream_compression_algorithms_bitset) |
+ 1u;
+
GPR_ASSERT(!args->is_last);
return GRPC_ERROR_NONE;
}
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
index 7bad188f4e..7541bd5c92 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
@@ -1298,6 +1298,15 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
if (op->send_initial_metadata) {
GPR_ASSERT(s->send_initial_metadata_finished == NULL);
on_complete->next_data.scratch |= CLOSURE_BARRIER_MAY_COVER_WRITE;
+
+ /* Identify stream compression */
+ if ((s->stream_compression_send_enabled =
+ (op_payload->send_initial_metadata.send_initial_metadata->idx.named
+ .content_encoding != NULL)) == true) {
+ s->compressed_data_buffer = gpr_malloc(sizeof(grpc_slice_buffer));
+ grpc_slice_buffer_init(s->compressed_data_buffer);
+ }
+
s->send_initial_metadata_finished = add_closure_barrier(on_complete);
s->send_initial_metadata =
op_payload->send_initial_metadata.send_initial_metadata;
@@ -2703,6 +2712,9 @@ static grpc_error *incoming_byte_stream_pull(grpc_exec_ctx *exec_ctx,
grpc_stream_compression_context_destroy(s->stream_decompression_ctx);
s->stream_decompression_ctx = NULL;
}
+ if (s->unprocessed_incoming_frames_buffer.length == 0) {
+ *slice = grpc_empty_slice();
+ }
}
error = grpc_deframe_unprocessed_incoming_frames(
exec_ctx, &s->data_parser, s, &s->unprocessed_incoming_frames_buffer,
diff --git a/src/core/ext/transport/chttp2/transport/flow_control.c b/src/core/ext/transport/chttp2/transport/flow_control.c
index 8dbdd1290a..cec99f6fb6 100644
--- a/src/core/ext/transport/chttp2/transport/flow_control.c
+++ b/src/core/ext/transport/chttp2/transport/flow_control.c
@@ -482,8 +482,8 @@ grpc_chttp2_flowctl_action grpc_chttp2_flowctl_get_bdp_action(
double bw_dbl = -1;
if (grpc_bdp_estimator_get_bw(&tfc->bdp_estimator, &bw_dbl)) {
// we target the max of BDP or bandwidth in microseconds.
- int32_t frame_size =
- GPR_CLAMP(GPR_MAX((int32_t)bw_dbl / 1000, bdp), 16384, 16777215);
+ int32_t frame_size = (int32_t)GPR_CLAMP(
+ GPR_MAX((int32_t)bw_dbl / 1000, bdp), 16384, 16777215);
grpc_chttp2_flowctl_urgency frame_size_urgency = delta_is_significant(
tfc, frame_size, GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE);
if (frame_size_urgency != GRPC_CHTTP2_FLOWCTL_NO_ACTION_NEEDED) {
diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.c b/src/core/ext/transport/chttp2/transport/hpack_parser.c
index 7f37365558..c21d76ba71 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_parser.c
+++ b/src/core/ext/transport/chttp2/transport/hpack_parser.c
@@ -1655,6 +1655,23 @@ static void force_client_rst_stream(grpc_exec_ctx *exec_ctx, void *sp,
GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "final_rst");
}
+static void parse_stream_compression_md(grpc_exec_ctx *exec_ctx,
+ grpc_chttp2_transport *t,
+ grpc_chttp2_stream *s,
+ grpc_metadata_batch *initial_metadata) {
+ if (initial_metadata->idx.named.content_encoding != NULL) {
+ grpc_slice content_encoding =
+ GRPC_MDVALUE(initial_metadata->idx.named.content_encoding->md);
+ if (!grpc_slice_eq(content_encoding, GRPC_MDSTR_IDENTITY)) {
+ if (grpc_slice_eq(content_encoding, GRPC_MDSTR_GZIP)) {
+ s->stream_compression_recv_enabled = true;
+ s->decompressed_data_buffer = gpr_malloc(sizeof(grpc_slice_buffer));
+ grpc_slice_buffer_init(s->decompressed_data_buffer);
+ }
+ }
+ }
+}
+
grpc_error *grpc_chttp2_header_parser_parse(grpc_exec_ctx *exec_ctx,
void *hpack_parser,
grpc_chttp2_transport *t,
@@ -1681,9 +1698,16 @@ grpc_error *grpc_chttp2_header_parser_parse(grpc_exec_ctx *exec_ctx,
if (s != NULL) {
if (parser->is_boundary) {
if (s->header_frames_received == GPR_ARRAY_SIZE(s->metadata_buffer)) {
+ GPR_TIMER_END("grpc_chttp2_hpack_parser_parse", 0);
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Too many trailer frames");
}
+ /* Process stream compression md element if it exists */
+ if (s->header_frames_received ==
+ 0) { /* Only acts on initial metadata */
+ parse_stream_compression_md(exec_ctx, t, s,
+ &s->metadata_buffer[0].batch);
+ }
s->published_metadata[s->header_frames_received] =
GRPC_METADATA_PUBLISHED_FROM_WIRE;
maybe_complete_funcs[s->header_frames_received](exec_ctx, t, s);
diff --git a/src/core/lib/channel/channel_args.c b/src/core/lib/channel/channel_args.c
index 8fdef0bc64..02db798b5c 100644
--- a/src/core/lib/channel/channel_args.c
+++ b/src/core/lib/channel/channel_args.c
@@ -221,6 +221,21 @@ grpc_compression_algorithm grpc_channel_args_get_compression_algorithm(
return GRPC_COMPRESS_NONE;
}
+grpc_stream_compression_algorithm
+grpc_channel_args_get_stream_compression_algorithm(const grpc_channel_args *a) {
+ size_t i;
+ if (a == NULL) return 0;
+ for (i = 0; i < a->num_args; ++i) {
+ if (a->args[i].type == GRPC_ARG_INTEGER &&
+ !strcmp(GRPC_STREAM_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM,
+ a->args[i].key)) {
+ return (grpc_stream_compression_algorithm)a->args[i].value.integer;
+ break;
+ }
+ }
+ return GRPC_STREAM_COMPRESS_NONE;
+}
+
grpc_channel_args *grpc_channel_args_set_compression_algorithm(
grpc_channel_args *a, grpc_compression_algorithm algorithm) {
GPR_ASSERT(algorithm < GRPC_COMPRESS_ALGORITHMS_COUNT);
@@ -231,6 +246,16 @@ grpc_channel_args *grpc_channel_args_set_compression_algorithm(
return grpc_channel_args_copy_and_add(a, &tmp, 1);
}
+grpc_channel_args *grpc_channel_args_set_stream_compression_algorithm(
+ grpc_channel_args *a, grpc_stream_compression_algorithm algorithm) {
+ GPR_ASSERT(algorithm < GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT);
+ grpc_arg tmp;
+ tmp.type = GRPC_ARG_INTEGER;
+ tmp.key = GRPC_STREAM_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM;
+ tmp.value.integer = algorithm;
+ return grpc_channel_args_copy_and_add(a, &tmp, 1);
+}
+
/** Returns 1 if the argument for compression algorithm's enabled states bitset
* was found in \a a, returning the arg's value in \a states. Otherwise, returns
* 0. */
@@ -251,6 +276,26 @@ static int find_compression_algorithm_states_bitset(const grpc_channel_args *a,
return 0; /* GPR_FALSE */
}
+/** Returns 1 if the argument for compression algorithm's enabled states bitset
+ * was found in \a a, returning the arg's value in \a states. Otherwise, returns
+ * 0. */
+static int find_stream_compression_algorithm_states_bitset(
+ const grpc_channel_args *a, int **states_arg) {
+ if (a != NULL) {
+ size_t i;
+ for (i = 0; i < a->num_args; ++i) {
+ if (a->args[i].type == GRPC_ARG_INTEGER &&
+ !strcmp(GRPC_STREAM_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET,
+ a->args[i].key)) {
+ *states_arg = &a->args[i].value.integer;
+ **states_arg |= 0x1; /* forcefully enable support for no compression */
+ return 1;
+ }
+ }
+ }
+ return 0; /* GPR_FALSE */
+}
+
grpc_channel_args *grpc_channel_args_compression_algorithm_set_state(
grpc_exec_ctx *exec_ctx, grpc_channel_args **a,
grpc_compression_algorithm algorithm, int state) {
@@ -292,6 +337,48 @@ grpc_channel_args *grpc_channel_args_compression_algorithm_set_state(
return result;
}
+grpc_channel_args *grpc_channel_args_stream_compression_algorithm_set_state(
+ grpc_exec_ctx *exec_ctx, grpc_channel_args **a,
+ grpc_stream_compression_algorithm algorithm, int state) {
+ int *states_arg = NULL;
+ grpc_channel_args *result = *a;
+ const int states_arg_found =
+ find_stream_compression_algorithm_states_bitset(*a, &states_arg);
+
+ if (grpc_channel_args_get_stream_compression_algorithm(*a) == algorithm &&
+ state == 0) {
+ char *algo_name = NULL;
+ GPR_ASSERT(grpc_stream_compression_algorithm_name(algorithm, &algo_name) !=
+ 0);
+ gpr_log(GPR_ERROR,
+ "Tried to disable default stream compression algorithm '%s'. The "
+ "operation has been ignored.",
+ algo_name);
+ } else if (states_arg_found) {
+ if (state != 0) {
+ GPR_BITSET((unsigned *)states_arg, algorithm);
+ } else if (algorithm != GRPC_STREAM_COMPRESS_NONE) {
+ GPR_BITCLEAR((unsigned *)states_arg, algorithm);
+ }
+ } else {
+ /* create a new arg */
+ grpc_arg tmp;
+ tmp.type = GRPC_ARG_INTEGER;
+ tmp.key = GRPC_STREAM_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET;
+ /* all enabled by default */
+ tmp.value.integer = (1u << GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT) - 1;
+ if (state != 0) {
+ GPR_BITSET((unsigned *)&tmp.value.integer, algorithm);
+ } else if (algorithm != GRPC_STREAM_COMPRESS_NONE) {
+ GPR_BITCLEAR((unsigned *)&tmp.value.integer, algorithm);
+ }
+ result = grpc_channel_args_copy_and_add(*a, &tmp, 1);
+ grpc_channel_args_destroy(exec_ctx, *a);
+ *a = result;
+ }
+ return result;
+}
+
uint32_t grpc_channel_args_compression_algorithm_get_states(
const grpc_channel_args *a) {
int *states_arg;
@@ -302,6 +389,17 @@ uint32_t grpc_channel_args_compression_algorithm_get_states(
}
}
+uint32_t grpc_channel_args_stream_compression_algorithm_get_states(
+ const grpc_channel_args *a) {
+ int *states_arg;
+ if (find_stream_compression_algorithm_states_bitset(a, &states_arg)) {
+ return (uint32_t)*states_arg;
+ } else {
+ return (1u << GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT) -
+ 1; /* All algs. enabled */
+ }
+}
+
grpc_channel_args *grpc_channel_args_set_socket_mutator(
grpc_channel_args *a, grpc_socket_mutator *mutator) {
grpc_arg tmp = grpc_socket_mutator_to_arg(mutator);
diff --git a/src/core/lib/channel/channel_args.h b/src/core/lib/channel/channel_args.h
index f649a8d9ec..0599e189c3 100644
--- a/src/core/lib/channel/channel_args.h
+++ b/src/core/lib/channel/channel_args.h
@@ -59,12 +59,24 @@ void grpc_channel_args_destroy(grpc_exec_ctx *exec_ctx, grpc_channel_args *a);
grpc_compression_algorithm grpc_channel_args_get_compression_algorithm(
const grpc_channel_args *a);
+/** Returns the stream compression algorithm set in \a a. */
+grpc_stream_compression_algorithm
+grpc_channel_args_get_stream_compression_algorithm(const grpc_channel_args *a);
+
/** Returns a channel arg instance with compression enabled. If \a a is
* non-NULL, its args are copied. N.B. GRPC_COMPRESS_NONE disables compression
* for the channel. */
grpc_channel_args *grpc_channel_args_set_compression_algorithm(
grpc_channel_args *a, grpc_compression_algorithm algorithm);
+/** Returns a channel arg instance with stream compression enabled. If \a a is
+ * non-NULL, its args are copied. N.B. GRPC_STREAM_COMPRESS_NONE disables
+ * stream compression for the channel. If a value other than
+ * GRPC_STREAM_COMPRESS_NONE is set, it takes precedence over message-wise
+ * compression algorithms. */
+grpc_channel_args *grpc_channel_args_set_stream_compression_algorithm(
+ grpc_channel_args *a, grpc_stream_compression_algorithm algorithm);
+
/** Sets the support for the given compression algorithm. By default, all
* compression algorithms are enabled. It's an error to disable an algorithm set
* by grpc_channel_args_set_compression_algorithm.
@@ -76,6 +88,17 @@ grpc_channel_args *grpc_channel_args_compression_algorithm_set_state(
grpc_exec_ctx *exec_ctx, grpc_channel_args **a,
grpc_compression_algorithm algorithm, int enabled);
+/** Sets the support for the given stream compression algorithm. By default, all
+ * stream compression algorithms are enabled. It's an error to disable an
+ * algorithm set by grpc_channel_args_set_stream_compression_algorithm.
+ *
+ * Returns an instance with the updated algorithm states. The \a a pointer is
+ * modified to point to the returned instance (which may be different from the
+ * input value of \a a). */
+grpc_channel_args *grpc_channel_args_stream_compression_algorithm_set_state(
+ grpc_exec_ctx *exec_ctx, grpc_channel_args **a,
+ grpc_stream_compression_algorithm algorithm, int enabled);
+
/** Returns the bitset representing the support state (true for enabled, false
* for disabled) for compression algorithms.
*
@@ -84,6 +107,14 @@ grpc_channel_args *grpc_channel_args_compression_algorithm_set_state(
uint32_t grpc_channel_args_compression_algorithm_get_states(
const grpc_channel_args *a);
+/** Returns the bitset representing the support state (true for enabled, false
+ * for disabled) for stream compression algorithms.
+ *
+ * The i-th bit of the returned bitset corresponds to the i-th entry in the
+ * grpc_stream_compression_algorithm enum. */
+uint32_t grpc_channel_args_stream_compression_algorithm_get_states(
+ const grpc_channel_args *a);
+
int grpc_channel_args_compare(const grpc_channel_args *a,
const grpc_channel_args *b);
diff --git a/src/core/lib/compression/algorithm_metadata.h b/src/core/lib/compression/algorithm_metadata.h
index 4717af6e2b..08feafc1bb 100644
--- a/src/core/lib/compression/algorithm_metadata.h
+++ b/src/core/lib/compression/algorithm_metadata.h
@@ -26,13 +26,27 @@
grpc_slice grpc_compression_algorithm_slice(
grpc_compression_algorithm algorithm);
+/** Return stream compression algorithm based metadata value */
+grpc_slice grpc_stream_compression_algorithm_slice(
+ grpc_stream_compression_algorithm algorithm);
+
/** Return compression algorithm based metadata element (grpc-encoding: xxx) */
grpc_mdelem grpc_compression_encoding_mdelem(
grpc_compression_algorithm algorithm);
+/** Return stream compression algorithm based metadata element
+ * (content-encoding: xxx) */
+grpc_mdelem grpc_stream_compression_encoding_mdelem(
+ grpc_stream_compression_algorithm algorithm);
+
/** Find compression algorithm based on passed in mdstr - returns
* GRPC_COMPRESS_ALGORITHM_COUNT on failure */
grpc_compression_algorithm grpc_compression_algorithm_from_slice(
grpc_slice str);
+/** Find stream compression algorithm based on passed in mdstr - returns
+ * GRPC_STREAM_COMPRESS_ALGORITHM_COUNT on failure */
+grpc_stream_compression_algorithm grpc_stream_compression_algorithm_from_slice(
+ grpc_slice str);
+
#endif /* GRPC_CORE_LIB_COMPRESSION_ALGORITHM_METADATA_H */
diff --git a/src/core/lib/compression/compression.c b/src/core/lib/compression/compression.c
index 8deae2798f..ec84c01811 100644
--- a/src/core/lib/compression/compression.c
+++ b/src/core/lib/compression/compression.c
@@ -46,6 +46,19 @@ int grpc_compression_algorithm_parse(grpc_slice name,
}
}
+int grpc_stream_compression_algorithm_parse(
+ grpc_slice name, grpc_stream_compression_algorithm *algorithm) {
+ if (grpc_slice_eq(name, GRPC_MDSTR_IDENTITY)) {
+ *algorithm = GRPC_STREAM_COMPRESS_NONE;
+ return 1;
+ } else if (grpc_slice_eq(name, GRPC_MDSTR_GZIP)) {
+ *algorithm = GRPC_STREAM_COMPRESS_GZIP;
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
int grpc_compression_algorithm_name(grpc_compression_algorithm algorithm,
char **name) {
GRPC_API_TRACE("grpc_compression_algorithm_parse(algorithm=%d, name=%p)", 2,
@@ -66,6 +79,24 @@ int grpc_compression_algorithm_name(grpc_compression_algorithm algorithm,
return 0;
}
+int grpc_stream_compression_algorithm_name(
+ grpc_stream_compression_algorithm algorithm, char **name) {
+ GRPC_API_TRACE(
+ "grpc_stream_compression_algorithm_parse(algorithm=%d, name=%p)", 2,
+ ((int)algorithm, name));
+ switch (algorithm) {
+ case GRPC_STREAM_COMPRESS_NONE:
+ *name = "identity";
+ return 1;
+ case GRPC_STREAM_COMPRESS_GZIP:
+ *name = "gzip";
+ return 1;
+ case GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT:
+ return 0;
+ }
+ return 0;
+}
+
grpc_compression_algorithm grpc_compression_algorithm_from_slice(
grpc_slice str) {
if (grpc_slice_eq(str, GRPC_MDSTR_IDENTITY)) return GRPC_COMPRESS_NONE;
@@ -74,6 +105,13 @@ grpc_compression_algorithm grpc_compression_algorithm_from_slice(
return GRPC_COMPRESS_ALGORITHMS_COUNT;
}
+grpc_stream_compression_algorithm grpc_stream_compression_algorithm_from_slice(
+ grpc_slice str) {
+ if (grpc_slice_eq(str, GRPC_MDSTR_IDENTITY)) return GRPC_STREAM_COMPRESS_NONE;
+ if (grpc_slice_eq(str, GRPC_MDSTR_GZIP)) return GRPC_STREAM_COMPRESS_GZIP;
+ return GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT;
+}
+
grpc_slice grpc_compression_algorithm_slice(
grpc_compression_algorithm algorithm) {
switch (algorithm) {
@@ -89,6 +127,19 @@ grpc_slice grpc_compression_algorithm_slice(
return grpc_empty_slice();
}
+grpc_slice grpc_stream_compression_algorithm_slice(
+ grpc_stream_compression_algorithm algorithm) {
+ switch (algorithm) {
+ case GRPC_STREAM_COMPRESS_NONE:
+ return GRPC_MDSTR_IDENTITY;
+ case GRPC_STREAM_COMPRESS_GZIP:
+ return GRPC_MDSTR_GZIP;
+ case GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT:
+ return grpc_empty_slice();
+ }
+ return grpc_empty_slice();
+}
+
grpc_mdelem grpc_compression_encoding_mdelem(
grpc_compression_algorithm algorithm) {
switch (algorithm) {
@@ -104,10 +155,25 @@ grpc_mdelem grpc_compression_encoding_mdelem(
return GRPC_MDNULL;
}
+grpc_mdelem grpc_stream_compression_encoding_mdelem(
+ grpc_stream_compression_algorithm algorithm) {
+ switch (algorithm) {
+ case GRPC_STREAM_COMPRESS_NONE:
+ return GRPC_MDELEM_CONTENT_ENCODING_IDENTITY;
+ case GRPC_STREAM_COMPRESS_GZIP:
+ return GRPC_MDELEM_CONTENT_ENCODING_GZIP;
+ default:
+ break;
+ }
+ return GRPC_MDNULL;
+}
+
void grpc_compression_options_init(grpc_compression_options *opts) {
memset(opts, 0, sizeof(*opts));
/* all enabled by default */
opts->enabled_algorithms_bitset = (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1;
+ opts->enabled_stream_compression_algorithms_bitset =
+ (1u << GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT) - 1;
}
void grpc_compression_options_enable_algorithm(
@@ -126,6 +192,13 @@ int grpc_compression_options_is_algorithm_enabled(
return GPR_BITGET(opts->enabled_algorithms_bitset, algorithm);
}
+int grpc_compression_options_is_stream_compression_algorithm_enabled(
+ const grpc_compression_options *opts,
+ grpc_stream_compression_algorithm algorithm) {
+ return GPR_BITGET(opts->enabled_stream_compression_algorithms_bitset,
+ algorithm);
+}
+
/* TODO(dgq): Add the ability to specify parameters to the individual
* compression algorithms */
grpc_compression_algorithm grpc_compression_algorithm_for_level(
@@ -181,3 +254,30 @@ grpc_compression_algorithm grpc_compression_algorithm_for_level(
abort();
};
}
+
+GRPCAPI grpc_stream_compression_algorithm
+grpc_stream_compression_algorithm_for_level(
+ grpc_stream_compression_level level, uint32_t accepted_stream_encodings) {
+ GRPC_API_TRACE("grpc_stream_compression_algorithm_for_level(level=%d)", 1,
+ ((int)level));
+ if (level > GRPC_STREAM_COMPRESS_LEVEL_HIGH) {
+ gpr_log(GPR_ERROR, "Unknown compression level %d.", (int)level);
+ abort();
+ }
+
+ switch (level) {
+ case GRPC_STREAM_COMPRESS_LEVEL_NONE:
+ return GRPC_STREAM_COMPRESS_NONE;
+ case GRPC_STREAM_COMPRESS_LEVEL_LOW:
+ case GRPC_STREAM_COMPRESS_LEVEL_MED:
+ case GRPC_STREAM_COMPRESS_LEVEL_HIGH:
+ if (GPR_BITGET(accepted_stream_encodings, GRPC_STREAM_COMPRESS_GZIP) ==
+ 1) {
+ return GRPC_STREAM_COMPRESS_GZIP;
+ } else {
+ return GRPC_STREAM_COMPRESS_NONE;
+ }
+ default:
+ abort();
+ }
+}
diff --git a/src/core/lib/iomgr/ev_epoll1_linux.c b/src/core/lib/iomgr/ev_epoll1_linux.c
index 90e0ce36cd..b940d48ba9 100644
--- a/src/core/lib/iomgr/ev_epoll1_linux.c
+++ b/src/core/lib/iomgr/ev_epoll1_linux.c
@@ -48,7 +48,60 @@
#include "src/core/lib/support/string.h"
static grpc_wakeup_fd global_wakeup_fd;
-static int g_epfd;
+
+/*******************************************************************************
+ * Singleton epoll set related fields
+ */
+
+#define MAX_EPOLL_EVENTS 100
+#define MAX_EPOLL_EVENTS_HANDLED_PER_ITERATION 1
+
+/* NOTE ON SYNCHRONIZATION:
+ * - Fields in this struct are only modified by the designated poller. Hence
+ * there is no need for any locks to protect the struct.
+ * - num_events and cursor fields have to be of atomic type to provide memory
+ * visibility guarantees only. i.e In case of multiple pollers, the designated
+ * polling thread keeps changing; the thread that wrote these values may be
+ * different from the thread reading the values
+ */
+typedef struct epoll_set {
+ int epfd;
+
+ /* The epoll_events after the last call to epoll_wait() */
+ struct epoll_event events[MAX_EPOLL_EVENTS];
+
+ /* The number of epoll_events after the last call to epoll_wait() */
+ gpr_atm num_events;
+
+ /* Index of the first event in epoll_events that has to be processed. This
+ * field is only valid if num_events > 0 */
+ gpr_atm cursor;
+} epoll_set;
+
+/* The global singleton epoll set */
+static epoll_set g_epoll_set;
+
+/* Must be called *only* once */
+static bool epoll_set_init() {
+ g_epoll_set.epfd = epoll_create1(EPOLL_CLOEXEC);
+ if (g_epoll_set.epfd < 0) {
+ gpr_log(GPR_ERROR, "epoll unavailable");
+ return false;
+ }
+
+ gpr_log(GPR_INFO, "grpc epoll fd: %d", g_epoll_set.epfd);
+ gpr_atm_no_barrier_store(&g_epoll_set.num_events, 0);
+ gpr_atm_no_barrier_store(&g_epoll_set.cursor, 0);
+ return true;
+}
+
+/* epoll_set_init() MUST be called before calling this. */
+static void epoll_set_shutdown() {
+ if (g_epoll_set.epfd >= 0) {
+ close(g_epoll_set.epfd);
+ g_epoll_set.epfd = -1;
+ }
+}
/*******************************************************************************
* Fd Declarations
@@ -122,7 +175,7 @@ struct grpc_pollset {
bool kicked_without_poller;
/* Set to true if the pollset is observed to have no workers available to
- * poll */
+ poll */
bool seen_inactive;
bool shutting_down; /* Is the pollset shutting down ? */
grpc_closure *shutdown_closure; /* Called after after shutdown is complete */
@@ -228,7 +281,7 @@ static grpc_fd *fd_create(int fd, const char *name) {
struct epoll_event ev = {.events = (uint32_t)(EPOLLIN | EPOLLOUT | EPOLLET),
.data.ptr = new_fd};
- if (epoll_ctl(g_epfd, EPOLL_CTL_ADD, fd, &ev) != 0) {
+ if (epoll_ctl(g_epoll_set.epfd, EPOLL_CTL_ADD, fd, &ev) != 0) {
gpr_log(GPR_ERROR, "epoll_ctl failed: %s", strerror(errno));
}
@@ -326,7 +379,10 @@ static void fd_become_writable(grpc_exec_ctx *exec_ctx, grpc_fd *fd) {
GPR_TLS_DECL(g_current_thread_pollset);
GPR_TLS_DECL(g_current_thread_worker);
+
+/* The designated poller */
static gpr_atm g_active_poller;
+
static pollset_neighbourhood *g_neighbourhoods;
static size_t g_num_neighbourhoods;
@@ -380,7 +436,8 @@ static grpc_error *pollset_global_init(void) {
if (err != GRPC_ERROR_NONE) return err;
struct epoll_event ev = {.events = (uint32_t)(EPOLLIN | EPOLLET),
.data.ptr = &global_wakeup_fd};
- if (epoll_ctl(g_epfd, EPOLL_CTL_ADD, global_wakeup_fd.read_fd, &ev) != 0) {
+ if (epoll_ctl(g_epoll_set.epfd, EPOLL_CTL_ADD, global_wakeup_fd.read_fd,
+ &ev) != 0) {
return GRPC_OS_ERROR(errno, "epoll_ctl");
}
g_num_neighbourhoods = GPR_CLAMP(gpr_cpu_num_cores(), 1, MAX_NEIGHBOURHOODS);
@@ -406,7 +463,14 @@ static void pollset_init(grpc_pollset *pollset, gpr_mu **mu) {
gpr_mu_init(&pollset->mu);
*mu = &pollset->mu;
pollset->neighbourhood = &g_neighbourhoods[choose_neighbourhood()];
+ pollset->reassigning_neighbourhood = false;
+ pollset->root_worker = NULL;
+ pollset->kicked_without_poller = false;
pollset->seen_inactive = true;
+ pollset->shutting_down = false;
+ pollset->shutdown_closure = NULL;
+ pollset->begin_refs = 0;
+ pollset->next = pollset->prev = NULL;
}
static void pollset_destroy(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset) {
@@ -438,6 +502,7 @@ static void pollset_destroy(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset) {
}
static grpc_error *pollset_kick_all(grpc_pollset *pollset) {
+ GPR_TIMER_BEGIN("pollset_kick_all", 0);
grpc_error *error = GRPC_ERROR_NONE;
if (pollset->root_worker != NULL) {
grpc_pollset_worker *worker = pollset->root_worker;
@@ -463,7 +528,7 @@ static grpc_error *pollset_kick_all(grpc_pollset *pollset) {
}
// TODO: sreek. Check if we need to set 'kicked_without_poller' to true here
// in the else case
-
+ GPR_TIMER_END("pollset_kick_all", 0);
return error;
}
@@ -471,6 +536,7 @@ static void pollset_maybe_finish_shutdown(grpc_exec_ctx *exec_ctx,
grpc_pollset *pollset) {
if (pollset->shutdown_closure != NULL && pollset->root_worker == NULL &&
pollset->begin_refs == 0) {
+ GPR_TIMER_MARK("pollset_finish_shutdown", 0);
GRPC_CLOSURE_SCHED(exec_ctx, pollset->shutdown_closure, GRPC_ERROR_NONE);
pollset->shutdown_closure = NULL;
}
@@ -478,16 +544,16 @@ static void pollset_maybe_finish_shutdown(grpc_exec_ctx *exec_ctx,
static void pollset_shutdown(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
grpc_closure *closure) {
+ GPR_TIMER_BEGIN("pollset_shutdown", 0);
GPR_ASSERT(pollset->shutdown_closure == NULL);
GPR_ASSERT(!pollset->shutting_down);
pollset->shutdown_closure = closure;
pollset->shutting_down = true;
GRPC_LOG_IF_ERROR("pollset_shutdown", pollset_kick_all(pollset));
pollset_maybe_finish_shutdown(exec_ctx, pollset);
+ GPR_TIMER_END("pollset_shutdown", 0);
}
-#define MAX_EPOLL_EVENTS 100
-
static int poll_deadline_to_millis_timeout(gpr_timespec deadline,
gpr_timespec now) {
gpr_timespec timeout;
@@ -506,52 +572,93 @@ static int poll_deadline_to_millis_timeout(gpr_timespec deadline,
return millis >= 1 ? millis : 1;
}
-static grpc_error *pollset_epoll(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
- gpr_timespec now, gpr_timespec deadline) {
- struct epoll_event events[MAX_EPOLL_EVENTS];
- static const char *err_desc = "pollset_poll";
-
- int timeout = poll_deadline_to_millis_timeout(deadline, now);
-
- if (timeout != 0) {
- GRPC_SCHEDULING_START_BLOCKING_REGION;
- }
- int r;
- do {
- r = epoll_wait(g_epfd, events, MAX_EPOLL_EVENTS, timeout);
- } while (r < 0 && errno == EINTR);
- if (timeout != 0) {
- GRPC_SCHEDULING_END_BLOCKING_REGION;
- }
+/* Process the epoll events found by do_epoll_wait() function.
+ - g_epoll_set.cursor points to the index of the first event to be processed
+ - This function then processes up-to MAX_EPOLL_EVENTS_PER_ITERATION and
+ updates the g_epoll_set.cursor
+
+ NOTE ON SYNCRHONIZATION: Similar to do_epoll_wait(), this function is only
+ called by g_active_poller thread. So there is no need for synchronization
+ when accessing fields in g_epoll_set */
+static grpc_error *process_epoll_events(grpc_exec_ctx *exec_ctx,
+ grpc_pollset *pollset) {
+ static const char *err_desc = "process_events";
+ grpc_error *error = GRPC_ERROR_NONE;
- if (r < 0) return GRPC_OS_ERROR(errno, "epoll_wait");
+ GPR_TIMER_BEGIN("process_epoll_events", 0);
+ long num_events = gpr_atm_acq_load(&g_epoll_set.num_events);
+ long cursor = gpr_atm_acq_load(&g_epoll_set.cursor);
+ for (int idx = 0;
+ (idx < MAX_EPOLL_EVENTS_HANDLED_PER_ITERATION) && cursor != num_events;
+ idx++) {
+ long c = cursor++;
+ struct epoll_event *ev = &g_epoll_set.events[c];
+ void *data_ptr = ev->data.ptr;
- grpc_error *error = GRPC_ERROR_NONE;
- for (int i = 0; i < r; i++) {
- void *data_ptr = events[i].data.ptr;
if (data_ptr == &global_wakeup_fd) {
append_error(&error, grpc_wakeup_fd_consume_wakeup(&global_wakeup_fd),
err_desc);
} else {
grpc_fd *fd = (grpc_fd *)(data_ptr);
- bool cancel = (events[i].events & (EPOLLERR | EPOLLHUP)) != 0;
- bool read_ev = (events[i].events & (EPOLLIN | EPOLLPRI)) != 0;
- bool write_ev = (events[i].events & EPOLLOUT) != 0;
+ bool cancel = (ev->events & (EPOLLERR | EPOLLHUP)) != 0;
+ bool read_ev = (ev->events & (EPOLLIN | EPOLLPRI)) != 0;
+ bool write_ev = (ev->events & EPOLLOUT) != 0;
+
if (read_ev || cancel) {
fd_become_readable(exec_ctx, fd, pollset);
}
+
if (write_ev || cancel) {
fd_become_writable(exec_ctx, fd);
}
}
}
-
+ gpr_atm_rel_store(&g_epoll_set.cursor, cursor);
+ GPR_TIMER_END("process_epoll_events", 0);
return error;
}
+/* Do epoll_wait and store the events in g_epoll_set.events field. This does not
+ "process" any of the events yet; that is done in process_epoll_events().
+ *See process_epoll_events() function for more details.
+
+ NOTE ON SYNCHRONIZATION: At any point of time, only the g_active_poller
+ (i.e the designated poller thread) will be calling this function. So there is
+ no need for any synchronization when accesing fields in g_epoll_set */
+static grpc_error *do_epoll_wait(grpc_exec_ctx *exec_ctx, grpc_pollset *ps,
+ gpr_timespec now, gpr_timespec deadline) {
+ GPR_TIMER_BEGIN("do_epoll_wait", 0);
+
+ int r;
+ int timeout = poll_deadline_to_millis_timeout(deadline, now);
+ if (timeout != 0) {
+ GRPC_SCHEDULING_START_BLOCKING_REGION;
+ }
+ do {
+ r = epoll_wait(g_epoll_set.epfd, g_epoll_set.events, MAX_EPOLL_EVENTS,
+ timeout);
+ } while (r < 0 && errno == EINTR);
+ if (timeout != 0) {
+ GRPC_SCHEDULING_END_BLOCKING_REGION;
+ }
+
+ if (r < 0) return GRPC_OS_ERROR(errno, "epoll_wait");
+
+ if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ gpr_log(GPR_DEBUG, "ps: %p poll got %d events", ps, r);
+ }
+
+ gpr_atm_rel_store(&g_epoll_set.num_events, r);
+ gpr_atm_rel_store(&g_epoll_set.cursor, 0);
+
+ GPR_TIMER_END("do_epoll_wait", 0);
+ return GRPC_ERROR_NONE;
+}
+
static bool begin_worker(grpc_pollset *pollset, grpc_pollset_worker *worker,
grpc_pollset_worker **worker_hdl, gpr_timespec *now,
gpr_timespec deadline) {
+ GPR_TIMER_BEGIN("begin_worker", 0);
if (worker_hdl != NULL) *worker_hdl = worker;
worker->initialized_cv = false;
SET_KICK_STATE(worker, UNKICKED);
@@ -656,14 +763,17 @@ static bool begin_worker(grpc_pollset *pollset, grpc_pollset_worker *worker,
if (pollset->kicked_without_poller) {
pollset->kicked_without_poller = false;
+ GPR_TIMER_END("begin_worker", 0);
return false;
}
+ GPR_TIMER_END("begin_worker", 0);
return worker->kick_state == DESIGNATED_POLLER && !pollset->shutting_down;
}
static bool check_neighbourhood_for_available_poller(
pollset_neighbourhood *neighbourhood) {
+ GPR_TIMER_BEGIN("check_neighbourhood_for_available_poller", 0);
bool found_worker = false;
do {
grpc_pollset *inspect = neighbourhood->active_root;
@@ -685,6 +795,7 @@ static bool check_neighbourhood_for_available_poller(
}
SET_KICK_STATE(inspect_worker, DESIGNATED_POLLER);
if (inspect_worker->initialized_cv) {
+ GPR_TIMER_MARK("signal worker", 0);
gpr_cv_signal(&inspect_worker->cv);
}
} else {
@@ -720,12 +831,14 @@ static bool check_neighbourhood_for_available_poller(
}
gpr_mu_unlock(&inspect->mu);
} while (!found_worker);
+ GPR_TIMER_END("check_neighbourhood_for_available_poller", 0);
return found_worker;
}
static void end_worker(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
grpc_pollset_worker *worker,
grpc_pollset_worker **worker_hdl) {
+ GPR_TIMER_BEGIN("end_worker", 0);
if (GRPC_TRACER_ON(grpc_polling_trace)) {
gpr_log(GPR_DEBUG, "PS:%p END_WORKER:%p", pollset, worker);
}
@@ -795,42 +908,71 @@ static void end_worker(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
pollset_maybe_finish_shutdown(exec_ctx, pollset);
}
GPR_ASSERT(gpr_atm_no_barrier_load(&g_active_poller) != (gpr_atm)worker);
+ GPR_TIMER_END("end_worker", 0);
}
/* pollset->po.mu lock must be held by the caller before calling this.
The function pollset_work() may temporarily release the lock (pollset->po.mu)
during the course of its execution but it will always re-acquire the lock and
ensure that it is held by the time the function returns */
-static grpc_error *pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
+static grpc_error *pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *ps,
grpc_pollset_worker **worker_hdl,
gpr_timespec now, gpr_timespec deadline) {
grpc_pollset_worker worker;
grpc_error *error = GRPC_ERROR_NONE;
static const char *err_desc = "pollset_work";
- if (pollset->kicked_without_poller) {
- pollset->kicked_without_poller = false;
+ GPR_TIMER_BEGIN("pollset_work", 0);
+ if (ps->kicked_without_poller) {
+ ps->kicked_without_poller = false;
+ GPR_TIMER_END("pollset_work", 0);
return GRPC_ERROR_NONE;
}
- if (begin_worker(pollset, &worker, worker_hdl, &now, deadline)) {
- gpr_tls_set(&g_current_thread_pollset, (intptr_t)pollset);
+
+ if (begin_worker(ps, &worker, worker_hdl, &now, deadline)) {
+ gpr_tls_set(&g_current_thread_pollset, (intptr_t)ps);
gpr_tls_set(&g_current_thread_worker, (intptr_t)&worker);
- GPR_ASSERT(!pollset->shutting_down);
- GPR_ASSERT(!pollset->seen_inactive);
- gpr_mu_unlock(&pollset->mu);
- append_error(&error, pollset_epoll(exec_ctx, pollset, now, deadline),
- err_desc);
- gpr_mu_lock(&pollset->mu);
+ GPR_ASSERT(!ps->shutting_down);
+ GPR_ASSERT(!ps->seen_inactive);
+
+ gpr_mu_unlock(&ps->mu); /* unlock */
+ /* This is the designated polling thread at this point and should ideally do
+ polling. However, if there are unprocessed events left from a previous
+ call to do_epoll_wait(), skip calling epoll_wait() in this iteration and
+ process the pending epoll events.
+
+ The reason for decoupling do_epoll_wait and process_epoll_events is to
+ better distrubute the work (i.e handling epoll events) across multiple
+ threads
+
+ process_epoll_events() returns very quickly: It just queues the work on
+ exec_ctx but does not execute it (the actual exectution or more
+ accurately grpc_exec_ctx_flush() happens in end_worker() AFTER selecting
+ a designated poller). So we are not waiting long periods without a
+ designated poller */
+ if (gpr_atm_acq_load(&g_epoll_set.cursor) ==
+ gpr_atm_acq_load(&g_epoll_set.num_events)) {
+ append_error(&error, do_epoll_wait(exec_ctx, ps, now, deadline),
+ err_desc);
+ }
+ append_error(&error, process_epoll_events(exec_ctx, ps), err_desc);
+
+ gpr_mu_lock(&ps->mu); /* lock */
+
gpr_tls_set(&g_current_thread_worker, 0);
} else {
- gpr_tls_set(&g_current_thread_pollset, (intptr_t)pollset);
+ gpr_tls_set(&g_current_thread_pollset, (intptr_t)ps);
}
- end_worker(exec_ctx, pollset, &worker, worker_hdl);
+ end_worker(exec_ctx, ps, &worker, worker_hdl);
+
gpr_tls_set(&g_current_thread_pollset, 0);
+ GPR_TIMER_END("pollset_work", 0);
return error;
}
static grpc_error *pollset_kick(grpc_pollset *pollset,
grpc_pollset_worker *specific_worker) {
+ GPR_TIMER_BEGIN("pollset_kick", 0);
+ grpc_error *ret_err = GRPC_ERROR_NONE;
if (GRPC_TRACER_ON(grpc_polling_trace)) {
gpr_strvec log;
gpr_strvec_init(&log);
@@ -865,7 +1007,7 @@ static grpc_error *pollset_kick(grpc_pollset *pollset,
if (GRPC_TRACER_ON(grpc_polling_trace)) {
gpr_log(GPR_ERROR, " .. kicked_without_poller");
}
- return GRPC_ERROR_NONE;
+ goto done;
}
grpc_pollset_worker *next_worker = root_worker->next;
if (root_worker->kick_state == KICKED) {
@@ -873,13 +1015,13 @@ static grpc_error *pollset_kick(grpc_pollset *pollset,
gpr_log(GPR_ERROR, " .. already kicked %p", root_worker);
}
SET_KICK_STATE(root_worker, KICKED);
- return GRPC_ERROR_NONE;
+ goto done;
} else if (next_worker->kick_state == KICKED) {
if (GRPC_TRACER_ON(grpc_polling_trace)) {
gpr_log(GPR_ERROR, " .. already kicked %p", next_worker);
}
SET_KICK_STATE(next_worker, KICKED);
- return GRPC_ERROR_NONE;
+ goto done;
} else if (root_worker ==
next_worker && // only try and wake up a poller if
// there is no next worker
@@ -889,7 +1031,8 @@ static grpc_error *pollset_kick(grpc_pollset *pollset,
gpr_log(GPR_ERROR, " .. kicked %p", root_worker);
}
SET_KICK_STATE(root_worker, KICKED);
- return grpc_wakeup_fd_wakeup(&global_wakeup_fd);
+ ret_err = grpc_wakeup_fd_wakeup(&global_wakeup_fd);
+ goto done;
} else if (next_worker->kick_state == UNKICKED) {
if (GRPC_TRACER_ON(grpc_polling_trace)) {
gpr_log(GPR_ERROR, " .. kicked %p", next_worker);
@@ -897,7 +1040,7 @@ static grpc_error *pollset_kick(grpc_pollset *pollset,
GPR_ASSERT(next_worker->initialized_cv);
SET_KICK_STATE(next_worker, KICKED);
gpr_cv_signal(&next_worker->cv);
- return GRPC_ERROR_NONE;
+ goto done;
} else if (next_worker->kick_state == DESIGNATED_POLLER) {
if (root_worker->kick_state != DESIGNATED_POLLER) {
if (GRPC_TRACER_ON(grpc_polling_trace)) {
@@ -910,59 +1053,64 @@ static grpc_error *pollset_kick(grpc_pollset *pollset,
if (root_worker->initialized_cv) {
gpr_cv_signal(&root_worker->cv);
}
- return GRPC_ERROR_NONE;
+ goto done;
} else {
if (GRPC_TRACER_ON(grpc_polling_trace)) {
gpr_log(GPR_ERROR, " .. non-root poller %p (root=%p)", next_worker,
root_worker);
}
SET_KICK_STATE(next_worker, KICKED);
- return grpc_wakeup_fd_wakeup(&global_wakeup_fd);
+ ret_err = grpc_wakeup_fd_wakeup(&global_wakeup_fd);
+ goto done;
}
} else {
GPR_ASSERT(next_worker->kick_state == KICKED);
SET_KICK_STATE(next_worker, KICKED);
- return GRPC_ERROR_NONE;
+ goto done;
}
} else {
if (GRPC_TRACER_ON(grpc_polling_trace)) {
gpr_log(GPR_ERROR, " .. kicked while waking up");
}
- return GRPC_ERROR_NONE;
+ goto done;
}
} else if (specific_worker->kick_state == KICKED) {
if (GRPC_TRACER_ON(grpc_polling_trace)) {
gpr_log(GPR_ERROR, " .. specific worker already kicked");
}
- return GRPC_ERROR_NONE;
+ goto done;
} else if (gpr_tls_get(&g_current_thread_worker) ==
(intptr_t)specific_worker) {
if (GRPC_TRACER_ON(grpc_polling_trace)) {
gpr_log(GPR_ERROR, " .. mark %p kicked", specific_worker);
}
SET_KICK_STATE(specific_worker, KICKED);
- return GRPC_ERROR_NONE;
+ goto done;
} else if (specific_worker ==
(grpc_pollset_worker *)gpr_atm_no_barrier_load(&g_active_poller)) {
if (GRPC_TRACER_ON(grpc_polling_trace)) {
gpr_log(GPR_ERROR, " .. kick active poller");
}
SET_KICK_STATE(specific_worker, KICKED);
- return grpc_wakeup_fd_wakeup(&global_wakeup_fd);
+ ret_err = grpc_wakeup_fd_wakeup(&global_wakeup_fd);
+ goto done;
} else if (specific_worker->initialized_cv) {
if (GRPC_TRACER_ON(grpc_polling_trace)) {
gpr_log(GPR_ERROR, " .. kick waiting worker");
}
SET_KICK_STATE(specific_worker, KICKED);
gpr_cv_signal(&specific_worker->cv);
- return GRPC_ERROR_NONE;
+ goto done;
} else {
if (GRPC_TRACER_ON(grpc_polling_trace)) {
gpr_log(GPR_ERROR, " .. kick non-waiting worker");
}
SET_KICK_STATE(specific_worker, KICKED);
- return GRPC_ERROR_NONE;
+ goto done;
}
+done:
+ GPR_TIMER_END("pollset_kick", 0);
+ return ret_err;
}
static void pollset_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
@@ -1006,7 +1154,7 @@ static void pollset_set_del_pollset_set(grpc_exec_ctx *exec_ctx,
static void shutdown_engine(void) {
fd_global_shutdown();
pollset_global_shutdown();
- close(g_epfd);
+ epoll_set_shutdown();
}
static const grpc_event_engine_vtable vtable = {
@@ -1041,10 +1189,9 @@ static const grpc_event_engine_vtable vtable = {
};
/* It is possible that GLIBC has epoll but the underlying kernel doesn't.
- * Create a dummy epoll_fd to make sure epoll support is available */
+ * Create epoll_fd (epoll_set_init() takes care of that) to make sure epoll
+ * support is available */
const grpc_event_engine_vtable *grpc_init_epoll1_linux(bool explicit_request) {
- /* TODO(sreek): Temporarily disable this poller unless explicitly requested
- * via GRPC_POLL_STRATEGY */
if (!explicit_request) {
return NULL;
}
@@ -1053,22 +1200,18 @@ const grpc_event_engine_vtable *grpc_init_epoll1_linux(bool explicit_request) {
return NULL;
}
- g_epfd = epoll_create1(EPOLL_CLOEXEC);
- if (g_epfd < 0) {
- gpr_log(GPR_ERROR, "epoll unavailable");
+ if (!epoll_set_init()) {
return NULL;
}
fd_global_init();
if (!GRPC_LOG_IF_ERROR("pollset_global_init", pollset_global_init())) {
- close(g_epfd);
fd_global_shutdown();
+ epoll_set_shutdown();
return NULL;
}
- gpr_log(GPR_ERROR, "grpc epoll fd: %d", g_epfd);
-
return &vtable;
}
diff --git a/src/core/lib/iomgr/ev_epollex_linux.c b/src/core/lib/iomgr/ev_epollex_linux.c
index 770d1fd0a9..1f4adea5d4 100644
--- a/src/core/lib/iomgr/ev_epollex_linux.c
+++ b/src/core/lib/iomgr/ev_epollex_linux.c
@@ -49,7 +49,7 @@
#include "src/core/lib/support/spinlock.h"
/*******************************************************************************
- * Pollset-set sibling link
+ * Polling object
*/
typedef enum {
diff --git a/src/core/lib/profiling/timers.h b/src/core/lib/profiling/timers.h
index 58e6659e6d..7f02b4bf84 100644
--- a/src/core/lib/profiling/timers.h
+++ b/src/core/lib/profiling/timers.h
@@ -37,7 +37,8 @@ void gpr_timers_set_log_filename(const char *filename);
void gpr_timer_set_enabled(int enabled);
-#if !(defined(GRPC_STAP_PROFILER) + defined(GRPC_BASIC_PROFILER))
+#if !(defined(GRPC_STAP_PROFILER) + defined(GRPC_BASIC_PROFILER) + \
+ defined(GRPC_CUSTOM_PROFILER))
/* No profiling. No-op all the things. */
#define GPR_TIMER_MARK(tag, important) \
do { \
@@ -56,6 +57,12 @@ void gpr_timer_set_enabled(int enabled);
#if defined(GRPC_STAP_PROFILER) && defined(GRPC_BASIC_PROFILER)
#error "GRPC_STAP_PROFILER and GRPC_BASIC_PROFILER are mutually exclusive."
#endif
+#if defined(GRPC_STAP_PROFILER) && defined(GRPC_CUSTOM_PROFILER)
+#error "GRPC_STAP_PROFILER and GRPC_CUSTOM_PROFILER are mutually exclusive."
+#endif
+#if defined(GRPC_CUSTOM_PROFILER) && defined(GRPC_BASIC_PROFILER)
+#error "GRPC_CUSTOM_PROFILER and GRPC_BASIC_PROFILER are mutually exclusive."
+#endif
/* Generic profiling interface. */
#define GPR_TIMER_MARK(tag, important) \
@@ -80,22 +87,25 @@ void gpr_timer_set_enabled(int enabled);
#ifdef __cplusplus
}
-#if (defined(GRPC_STAP_PROFILER) + defined(GRPC_BASIC_PROFILER))
+#if (defined(GRPC_STAP_PROFILER) + defined(GRPC_BASIC_PROFILER) + \
+ defined(GRPC_CUSTOM_PROFILER))
namespace grpc {
class ProfileScope {
public:
- ProfileScope(const char *desc, bool important) : desc_(desc) {
- GPR_TIMER_BEGIN(desc_, important ? 1 : 0);
+ ProfileScope(const char *desc, bool important, const char *file, int line)
+ : desc_(desc) {
+ gpr_timer_begin(desc_, important ? 1 : 0, file, line);
}
- ~ProfileScope() { GPR_TIMER_END(desc_, 0); }
+ ~ProfileScope() { gpr_timer_end(desc_, 0, "n/a", 0); }
private:
const char *const desc_;
};
-}
+} // namespace grpc
-#define GPR_TIMER_SCOPE(tag, important) \
- ::grpc::ProfileScope _profile_scope_##__LINE__((tag), (important))
+#define GPR_TIMER_SCOPE(tag, important) \
+ ::grpc::ProfileScope _profile_scope_##__LINE__((tag), (important), __FILE__, \
+ __LINE__)
#else
#define GPR_TIMER_SCOPE(tag, important) \
do { \
diff --git a/src/core/lib/security/credentials/jwt/jwt_verifier.c b/src/core/lib/security/credentials/jwt/jwt_verifier.c
index 6cd558d123..a27284bc50 100644
--- a/src/core/lib/security/credentials/jwt/jwt_verifier.c
+++ b/src/core/lib/security/credentials/jwt/jwt_verifier.c
@@ -442,7 +442,7 @@ static EVP_PKEY *extract_pkey_from_x509(const char *x509_str) {
end:
BIO_free(bio);
- if (x509 != NULL) X509_free(x509);
+ X509_free(x509);
return result;
}
@@ -496,6 +496,8 @@ static EVP_PKEY *pkey_from_jwk(grpc_exec_ctx *exec_ctx, const grpc_json *json,
const grpc_json *key_prop;
RSA *rsa = NULL;
EVP_PKEY *result = NULL;
+ BIGNUM *tmp_n = NULL;
+ BIGNUM *tmp_e = NULL;
GPR_ASSERT(kty != NULL && json != NULL);
if (strcmp(kty, "RSA") != 0) {
@@ -507,8 +509,6 @@ static EVP_PKEY *pkey_from_jwk(grpc_exec_ctx *exec_ctx, const grpc_json *json,
gpr_log(GPR_ERROR, "Could not create rsa key.");
goto end;
}
- BIGNUM *tmp_n = NULL;
- BIGNUM *tmp_e = NULL;
for (key_prop = json->child; key_prop != NULL; key_prop = key_prop->next) {
if (strcmp(key_prop->key, "n") == 0) {
tmp_n =
@@ -528,11 +528,16 @@ static EVP_PKEY *pkey_from_jwk(grpc_exec_ctx *exec_ctx, const grpc_json *json,
gpr_log(GPR_ERROR, "Cannot set RSA key from inputs.");
goto end;
}
+ /* RSA_set0_key takes ownership on success. */
+ tmp_n = NULL;
+ tmp_e = NULL;
result = EVP_PKEY_new();
EVP_PKEY_set1_RSA(result, rsa); /* uprefs rsa. */
end:
- if (rsa != NULL) RSA_free(rsa);
+ RSA_free(rsa);
+ BN_free(tmp_n);
+ BN_free(tmp_e);
return result;
}
@@ -618,7 +623,7 @@ static int verify_jwt_signature(EVP_PKEY *key, const char *alg,
result = 1;
end:
- if (md_ctx != NULL) EVP_MD_CTX_destroy(md_ctx);
+ EVP_MD_CTX_destroy(md_ctx);
return result;
}
@@ -658,7 +663,7 @@ static void on_keys_retrieved(grpc_exec_ctx *exec_ctx, void *user_data,
end:
if (json != NULL) grpc_json_destroy(json);
- if (verification_key != NULL) EVP_PKEY_free(verification_key);
+ EVP_PKEY_free(verification_key);
ctx->user_cb(exec_ctx, ctx->user_data, status, claims);
verifier_cb_ctx_destroy(exec_ctx, ctx);
}
diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.c b/src/core/lib/security/credentials/oauth2/oauth2_credentials.c
index c59e55136c..10b270c49c 100644
--- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.c
+++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.c
@@ -296,10 +296,10 @@ static bool oauth2_token_fetcher_get_request_metadata(
gpr_mu_unlock(&c->mu);
if (start_fetch) {
grpc_call_credentials_ref(creds);
- c->fetch_func(exec_ctx, grpc_credentials_metadata_request_create(creds),
- &c->httpcli_context, &c->pollent,
- on_oauth2_token_fetcher_http_response,
- gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), refresh_threshold));
+ c->fetch_func(
+ exec_ctx, grpc_credentials_metadata_request_create(creds),
+ &c->httpcli_context, &c->pollent, on_oauth2_token_fetcher_http_response,
+ gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), refresh_threshold));
}
return false;
}
diff --git a/src/core/lib/support/block_annotate.h b/src/core/lib/support/block_annotate.h
index 0a2cb45018..8e3ef7df65 100644
--- a/src/core/lib/support/block_annotate.h
+++ b/src/core/lib/support/block_annotate.h
@@ -19,15 +19,37 @@
#ifndef GRPC_CORE_LIB_SUPPORT_BLOCK_ANNOTATE_H
#define GRPC_CORE_LIB_SUPPORT_BLOCK_ANNOTATE_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void gpr_thd_start_blocking_region();
+void gpr_thd_end_blocking_region();
+
+#ifdef __cplusplus
+}
+#endif
+
/* These annotations identify the beginning and end of regions where
the code may block for reasons other than synchronization functions.
These include poll, epoll, and getaddrinfo. */
+#ifdef GRPC_SCHEDULING_MARK_BLOCKING_REGION
+#define GRPC_SCHEDULING_START_BLOCKING_REGION \
+ do { \
+ gpr_thd_start_blocking_region(); \
+ } while (0)
+#define GRPC_SCHEDULING_END_BLOCKING_REGION \
+ do { \
+ gpr_thd_end_blocking_region(); \
+ } while (0)
+#else
#define GRPC_SCHEDULING_START_BLOCKING_REGION \
do { \
} while (0)
#define GRPC_SCHEDULING_END_BLOCKING_REGION \
do { \
} while (0)
+#endif
#endif /* GRPC_CORE_LIB_SUPPORT_BLOCK_ANNOTATE_H */
diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c
index 00ec9c7c9a..62d542d2c5 100644
--- a/src/core/lib/surface/call.c
+++ b/src/core/lib/surface/call.c
@@ -144,6 +144,9 @@ typedef struct {
grpc_call *sibling_prev;
} child_call;
+#define RECV_NONE ((gpr_atm)0)
+#define RECV_INITIAL_METADATA_FIRST ((gpr_atm)1)
+
struct grpc_call {
gpr_refcount ext_ref;
gpr_arena *arena;
@@ -170,9 +173,6 @@ struct grpc_call {
gpr_atm any_ops_sent_atm;
gpr_atm received_final_op_atm;
- /* have we received initial metadata */
- bool has_initial_md_been_received;
-
batch_control *active_batches[MAX_CONCURRENT_BATCHES];
grpc_transport_stream_op_batch_payload stream_op_payload;
@@ -192,8 +192,12 @@ struct grpc_call {
/* Compression algorithm for *incoming* data */
grpc_compression_algorithm incoming_compression_algorithm;
+ /* Stream compression algorithm for *incoming* data */
+ grpc_stream_compression_algorithm incoming_stream_compression_algorithm;
/* Supported encodings (compression algorithms), a bitset */
uint32_t encodings_accepted_by_peer;
+ /* Supported stream encodings (stream compression algorithms), a bitset */
+ uint32_t stream_encodings_accepted_by_peer;
/* Contexts for various subsystems (security, tracing, ...). */
grpc_call_context_element context[GRPC_CONTEXT_COUNT];
@@ -226,7 +230,23 @@ struct grpc_call {
} server;
} final_op;
- void *saved_receiving_stream_ready_bctlp;
+ /* recv_state can contain one of the following values:
+ RECV_NONE : : no initial metadata and messages received
+ RECV_INITIAL_METADATA_FIRST : received initial metadata first
+ a batch_control* : received messages first
+
+ +------1------RECV_NONE------3-----+
+ | |
+ | |
+ v v
+ RECV_INITIAL_METADATA_FIRST receiving_stream_ready_bctlp
+ | ^ | ^
+ | | | |
+ +-----2-----+ +-----4-----+
+
+ For 1, 4: See receiving_initial_metadata_ready() function
+ For 2, 3: See receiving_stream_ready() function */
+ gpr_atm recv_state;
};
grpc_tracer_flag grpc_call_error_trace =
@@ -752,6 +772,12 @@ static void set_incoming_compression_algorithm(
call->incoming_compression_algorithm = algo;
}
+static void set_incoming_stream_compression_algorithm(
+ grpc_call *call, grpc_stream_compression_algorithm algo) {
+ GPR_ASSERT(algo < GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT);
+ call->incoming_stream_compression_algorithm = algo;
+}
+
grpc_compression_algorithm grpc_call_test_only_get_compression_algorithm(
grpc_call *call) {
grpc_compression_algorithm algorithm;
@@ -765,6 +791,13 @@ static grpc_compression_algorithm compression_algorithm_for_level_locked(
call->encodings_accepted_by_peer);
}
+static grpc_stream_compression_algorithm
+stream_compression_algorithm_for_level_locked(
+ grpc_call *call, grpc_stream_compression_level level) {
+ return grpc_stream_compression_algorithm_for_level(
+ level, call->stream_encodings_accepted_by_peer);
+}
+
uint32_t grpc_call_test_only_get_message_flags(grpc_call *call) {
uint32_t flags;
flags = call->test_only_last_message_flags;
@@ -819,12 +852,70 @@ static void set_encodings_accepted_by_peer(grpc_exec_ctx *exec_ctx,
(void *)(((uintptr_t)call->encodings_accepted_by_peer) + 1));
}
+static void set_stream_encodings_accepted_by_peer(grpc_exec_ctx *exec_ctx,
+ grpc_call *call,
+ grpc_mdelem mdel) {
+ size_t i;
+ grpc_stream_compression_algorithm algorithm;
+ grpc_slice_buffer accept_encoding_parts;
+ grpc_slice accept_encoding_slice;
+ void *accepted_user_data;
+
+ accepted_user_data =
+ grpc_mdelem_get_user_data(mdel, destroy_encodings_accepted_by_peer);
+ if (accepted_user_data != NULL) {
+ call->stream_encodings_accepted_by_peer =
+ (uint32_t)(((uintptr_t)accepted_user_data) - 1);
+ return;
+ }
+
+ accept_encoding_slice = GRPC_MDVALUE(mdel);
+ grpc_slice_buffer_init(&accept_encoding_parts);
+ grpc_slice_split(accept_encoding_slice, ",", &accept_encoding_parts);
+
+ /* Always support no compression */
+ GPR_BITSET(&call->stream_encodings_accepted_by_peer,
+ GRPC_STREAM_COMPRESS_NONE);
+ for (i = 0; i < accept_encoding_parts.count; i++) {
+ grpc_slice accept_encoding_entry_slice = accept_encoding_parts.slices[i];
+ if (grpc_stream_compression_algorithm_parse(accept_encoding_entry_slice,
+ &algorithm)) {
+ GPR_BITSET(&call->stream_encodings_accepted_by_peer, algorithm);
+ } else {
+ char *accept_encoding_entry_str =
+ grpc_slice_to_c_string(accept_encoding_entry_slice);
+ gpr_log(GPR_ERROR,
+ "Invalid entry in accept encoding metadata: '%s'. Ignoring.",
+ accept_encoding_entry_str);
+ gpr_free(accept_encoding_entry_str);
+ }
+ }
+
+ grpc_slice_buffer_destroy_internal(exec_ctx, &accept_encoding_parts);
+
+ grpc_mdelem_set_user_data(
+ mdel, destroy_encodings_accepted_by_peer,
+ (void *)(((uintptr_t)call->stream_encodings_accepted_by_peer) + 1));
+}
+
uint32_t grpc_call_test_only_get_encodings_accepted_by_peer(grpc_call *call) {
uint32_t encodings_accepted_by_peer;
encodings_accepted_by_peer = call->encodings_accepted_by_peer;
return encodings_accepted_by_peer;
}
+uint32_t grpc_call_test_only_get_stream_encodings_accepted_by_peer(
+ grpc_call *call) {
+ uint32_t stream_encodings_accepted_by_peer;
+ stream_encodings_accepted_by_peer = call->stream_encodings_accepted_by_peer;
+ return stream_encodings_accepted_by_peer;
+}
+
+grpc_stream_compression_algorithm
+grpc_call_test_only_get_incoming_stream_encodings(grpc_call *call) {
+ return call->incoming_stream_compression_algorithm;
+}
+
static grpc_linked_mdelem *linked_from_md(const grpc_metadata *md) {
return (grpc_linked_mdelem *)&md->internal_data;
}
@@ -936,6 +1027,22 @@ static grpc_compression_algorithm decode_compression(grpc_mdelem md) {
return algorithm;
}
+static grpc_stream_compression_algorithm decode_stream_compression(
+ grpc_mdelem md) {
+ grpc_stream_compression_algorithm algorithm =
+ grpc_stream_compression_algorithm_from_slice(GRPC_MDVALUE(md));
+ if (algorithm == GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT) {
+ char *md_c_str = grpc_slice_to_c_string(GRPC_MDVALUE(md));
+ gpr_log(GPR_ERROR,
+ "Invalid incoming stream compression algorithm: '%s'. Interpreting "
+ "incoming data as uncompressed.",
+ md_c_str);
+ gpr_free(md_c_str);
+ return GRPC_STREAM_COMPRESS_NONE;
+ }
+ return algorithm;
+}
+
static void publish_app_metadata(grpc_call *call, grpc_metadata_batch *b,
int is_trailing) {
if (b->list.count == 0) return;
@@ -960,7 +1067,19 @@ static void publish_app_metadata(grpc_call *call, grpc_metadata_batch *b,
static void recv_initial_filter(grpc_exec_ctx *exec_ctx, grpc_call *call,
grpc_metadata_batch *b) {
- if (b->idx.named.grpc_encoding != NULL) {
+ if (b->idx.named.content_encoding != NULL) {
+ if (b->idx.named.grpc_encoding != NULL) {
+ gpr_log(GPR_ERROR,
+ "Received both content-encoding and grpc-encoding header. "
+ "Ignoring grpc-encoding.");
+ grpc_metadata_batch_remove(exec_ctx, b, b->idx.named.grpc_encoding);
+ }
+ GPR_TIMER_BEGIN("incoming_stream_compression_algorithm", 0);
+ set_incoming_stream_compression_algorithm(
+ call, decode_stream_compression(b->idx.named.content_encoding->md));
+ GPR_TIMER_END("incoming_stream_compression_algorithm", 0);
+ grpc_metadata_batch_remove(exec_ctx, b, b->idx.named.content_encoding);
+ } else if (b->idx.named.grpc_encoding != NULL) {
GPR_TIMER_BEGIN("incoming_compression_algorithm", 0);
set_incoming_compression_algorithm(
call, decode_compression(b->idx.named.grpc_encoding->md));
@@ -974,6 +1093,13 @@ static void recv_initial_filter(grpc_exec_ctx *exec_ctx, grpc_call *call,
grpc_metadata_batch_remove(exec_ctx, b, b->idx.named.grpc_accept_encoding);
GPR_TIMER_END("encodings_accepted_by_peer", 0);
}
+ if (b->idx.named.accept_encoding != NULL) {
+ GPR_TIMER_BEGIN("stream_encodings_accepted_by_peer", 0);
+ set_stream_encodings_accepted_by_peer(exec_ctx, call,
+ b->idx.named.accept_encoding->md);
+ grpc_metadata_batch_remove(exec_ctx, b, b->idx.named.accept_encoding);
+ GPR_TIMER_END("stream_encodings_accepted_by_peer", 0);
+ }
publish_app_metadata(call, b, false);
}
@@ -1290,19 +1416,61 @@ static void receiving_stream_ready(grpc_exec_ctx *exec_ctx, void *bctlp,
cancel_with_error(exec_ctx, call, STATUS_FROM_SURFACE,
GRPC_ERROR_REF(error));
}
- if (call->has_initial_md_been_received || error != GRPC_ERROR_NONE ||
- call->receiving_stream == NULL) {
+ /* If recv_state is RECV_NONE, we will save the batch_control
+ * object with rel_cas, and will not use it after the cas. Its corresponding
+ * acq_load is in receiving_initial_metadata_ready() */
+ if (error != GRPC_ERROR_NONE || call->receiving_stream == NULL ||
+ !gpr_atm_rel_cas(&call->recv_state, RECV_NONE, (gpr_atm)bctlp)) {
process_data_after_md(exec_ctx, bctlp);
- } else {
- call->saved_receiving_stream_ready_bctlp = bctlp;
}
}
static void validate_filtered_metadata(grpc_exec_ctx *exec_ctx,
batch_control *bctl) {
grpc_call *call = bctl->call;
- /* validate call->incoming_compression_algorithm */
- if (call->incoming_compression_algorithm != GRPC_COMPRESS_NONE) {
+ /* validate compression algorithms */
+ if (call->incoming_stream_compression_algorithm !=
+ GRPC_STREAM_COMPRESS_NONE) {
+ const grpc_stream_compression_algorithm algo =
+ call->incoming_stream_compression_algorithm;
+ char *error_msg = NULL;
+ const grpc_compression_options compression_options =
+ grpc_channel_compression_options(call->channel);
+ if (algo >= GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT) {
+ gpr_asprintf(&error_msg,
+ "Invalid stream compression algorithm value '%d'.", algo);
+ gpr_log(GPR_ERROR, "%s", error_msg);
+ cancel_with_status(exec_ctx, call, STATUS_FROM_SURFACE,
+ GRPC_STATUS_UNIMPLEMENTED, error_msg);
+ } else if (grpc_compression_options_is_stream_compression_algorithm_enabled(
+ &compression_options, algo) == 0) {
+ /* check if algorithm is supported by current channel config */
+ char *algo_name = NULL;
+ grpc_stream_compression_algorithm_name(algo, &algo_name);
+ gpr_asprintf(&error_msg, "Stream compression algorithm '%s' is disabled.",
+ algo_name);
+ gpr_log(GPR_ERROR, "%s", error_msg);
+ cancel_with_status(exec_ctx, call, STATUS_FROM_SURFACE,
+ GRPC_STATUS_UNIMPLEMENTED, error_msg);
+ }
+ gpr_free(error_msg);
+
+ GPR_ASSERT(call->stream_encodings_accepted_by_peer != 0);
+ if (!GPR_BITGET(call->stream_encodings_accepted_by_peer,
+ call->incoming_stream_compression_algorithm)) {
+ if (GRPC_TRACER_ON(grpc_compression_trace)) {
+ char *algo_name = NULL;
+ grpc_stream_compression_algorithm_name(
+ call->incoming_stream_compression_algorithm, &algo_name);
+ gpr_log(
+ GPR_ERROR,
+ "Stream compression algorithm (content-encoding = '%s') not "
+ "present in the bitset of accepted encodings (accept-encodings: "
+ "'0x%x')",
+ algo_name, call->stream_encodings_accepted_by_peer);
+ }
+ }
+ } else if (call->incoming_compression_algorithm != GRPC_COMPRESS_NONE) {
const grpc_compression_algorithm algo =
call->incoming_compression_algorithm;
char *error_msg = NULL;
@@ -1329,22 +1497,20 @@ static void validate_filtered_metadata(grpc_exec_ctx *exec_ctx,
call->incoming_compression_algorithm = algo;
}
gpr_free(error_msg);
- }
- /* make sure the received grpc-encoding is amongst the ones listed in
- * grpc-accept-encoding */
- GPR_ASSERT(call->encodings_accepted_by_peer != 0);
- if (!GPR_BITGET(call->encodings_accepted_by_peer,
- call->incoming_compression_algorithm)) {
- if (GRPC_TRACER_ON(grpc_compression_trace)) {
- char *algo_name = NULL;
- grpc_compression_algorithm_name(call->incoming_compression_algorithm,
- &algo_name);
- gpr_log(GPR_ERROR,
- "Compression algorithm (grpc-encoding = '%s') not present in "
- "the bitset of accepted encodings (grpc-accept-encodings: "
- "'0x%x')",
- algo_name, call->encodings_accepted_by_peer);
+ GPR_ASSERT(call->encodings_accepted_by_peer != 0);
+ if (!GPR_BITGET(call->encodings_accepted_by_peer,
+ call->incoming_compression_algorithm)) {
+ if (GRPC_TRACER_ON(grpc_compression_trace)) {
+ char *algo_name = NULL;
+ grpc_compression_algorithm_name(call->incoming_compression_algorithm,
+ &algo_name);
+ gpr_log(GPR_ERROR,
+ "Compression algorithm (grpc-encoding = '%s') not present in "
+ "the bitset of accepted encodings (grpc-accept-encodings: "
+ "'0x%x')",
+ algo_name, call->encodings_accepted_by_peer);
+ }
}
}
}
@@ -1384,12 +1550,31 @@ static void receiving_initial_metadata_ready(grpc_exec_ctx *exec_ctx,
}
}
- call->has_initial_md_been_received = true;
- if (call->saved_receiving_stream_ready_bctlp != NULL) {
- grpc_closure *saved_rsr_closure = GRPC_CLOSURE_CREATE(
- receiving_stream_ready, call->saved_receiving_stream_ready_bctlp,
- grpc_schedule_on_exec_ctx);
- call->saved_receiving_stream_ready_bctlp = NULL;
+ grpc_closure *saved_rsr_closure = NULL;
+ while (true) {
+ gpr_atm rsr_bctlp = gpr_atm_acq_load(&call->recv_state);
+ /* Should only receive initial metadata once */
+ GPR_ASSERT(rsr_bctlp != 1);
+ if (rsr_bctlp == 0) {
+ /* We haven't seen initial metadata and messages before, thus initial
+ * metadata is received first.
+ * no_barrier_cas is used, as this function won't access the batch_control
+ * object saved by receiving_stream_ready() if the initial metadata is
+ * received first. */
+ if (gpr_atm_no_barrier_cas(&call->recv_state, RECV_NONE,
+ RECV_INITIAL_METADATA_FIRST)) {
+ break;
+ }
+ } else {
+ /* Already received messages */
+ saved_rsr_closure = GRPC_CLOSURE_CREATE(receiving_stream_ready,
+ (batch_control *)rsr_bctlp,
+ grpc_schedule_on_exec_ctx);
+ /* No need to modify recv_state */
+ break;
+ }
+ }
+ if (saved_rsr_closure != NULL) {
GRPC_CLOSURE_RUN(exec_ctx, saved_rsr_closure, GRPC_ERROR_REF(error));
}
@@ -1471,29 +1656,56 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
/* process compression level */
memset(&compression_md, 0, sizeof(compression_md));
size_t additional_metadata_count = 0;
- grpc_compression_level effective_compression_level;
+ grpc_compression_level effective_compression_level =
+ GRPC_COMPRESS_LEVEL_NONE;
+ grpc_stream_compression_level effective_stream_compression_level =
+ GRPC_STREAM_COMPRESS_LEVEL_NONE;
bool level_set = false;
- if (op->data.send_initial_metadata.maybe_compression_level.is_set) {
+ bool stream_compression = false;
+ if (op->data.send_initial_metadata.maybe_stream_compression_level
+ .is_set) {
+ effective_stream_compression_level =
+ op->data.send_initial_metadata.maybe_stream_compression_level
+ .level;
+ level_set = true;
+ stream_compression = true;
+ } else if (op->data.send_initial_metadata.maybe_compression_level
+ .is_set) {
effective_compression_level =
op->data.send_initial_metadata.maybe_compression_level.level;
level_set = true;
} else {
const grpc_compression_options copts =
grpc_channel_compression_options(call->channel);
- level_set = copts.default_level.is_set;
- if (level_set) {
+ if (copts.default_stream_compression_level.is_set) {
+ level_set = true;
+ effective_stream_compression_level =
+ copts.default_stream_compression_level.level;
+ stream_compression = true;
+ } else if (copts.default_level.is_set) {
+ level_set = true;
effective_compression_level = copts.default_level.level;
}
}
if (level_set && !call->is_client) {
- const grpc_compression_algorithm calgo =
- compression_algorithm_for_level_locked(
- call, effective_compression_level);
- // the following will be picked up by the compress filter and used as
- // the call's compression algorithm.
- compression_md.key = GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST;
- compression_md.value = grpc_compression_algorithm_slice(calgo);
- additional_metadata_count++;
+ if (stream_compression) {
+ const grpc_stream_compression_algorithm calgo =
+ stream_compression_algorithm_for_level_locked(
+ call, effective_stream_compression_level);
+ compression_md.key =
+ GRPC_MDSTR_GRPC_INTERNAL_STREAM_ENCODING_REQUEST;
+ compression_md.value =
+ grpc_stream_compression_algorithm_slice(calgo);
+ } else {
+ const grpc_compression_algorithm calgo =
+ compression_algorithm_for_level_locked(
+ call, effective_compression_level);
+ /* the following will be picked up by the compress filter and used
+ * as the call's compression algorithm. */
+ compression_md.key = GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST;
+ compression_md.value = grpc_compression_algorithm_slice(calgo);
+ additional_metadata_count++;
+ }
}
if (op->data.send_initial_metadata.count + additional_metadata_count >
diff --git a/src/core/lib/surface/call_test_only.h b/src/core/lib/surface/call_test_only.h
index 2f1b80bfd7..a5a01b3679 100644
--- a/src/core/lib/surface/call_test_only.h
+++ b/src/core/lib/surface/call_test_only.h
@@ -42,6 +42,18 @@ uint32_t grpc_call_test_only_get_message_flags(grpc_call *call);
* To be indexed by grpc_compression_algorithm enum values. */
uint32_t grpc_call_test_only_get_encodings_accepted_by_peer(grpc_call *call);
+/** Returns a bitset for the stream encodings (stream compression algorithms)
+ * supported by \a call's peer.
+ *
+ * To be indexed by grpc_stream_compression_algorithm enum values. */
+uint32_t grpc_call_test_only_get_stream_encodings_accepted_by_peer(
+ grpc_call *call);
+
+/** Returns the incoming stream compression algorithm (content-encoding header)
+ * received by a call. */
+grpc_stream_compression_algorithm
+grpc_call_test_only_get_incoming_stream_encodings(grpc_call *call);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/core/lib/surface/channel.c b/src/core/lib/surface/channel.c
index 5780a18ce8..850fbe6a69 100644
--- a/src/core/lib/surface/channel.c
+++ b/src/core/lib/surface/channel.c
@@ -142,6 +142,16 @@ grpc_channel *grpc_channel_create_with_builder(
GRPC_COMPRESS_LEVEL_NONE,
GRPC_COMPRESS_LEVEL_COUNT - 1});
} else if (0 == strcmp(args->args[i].key,
+ GRPC_STREAM_COMPRESSION_CHANNEL_DEFAULT_LEVEL)) {
+ channel->compression_options.default_stream_compression_level.is_set =
+ true;
+ channel->compression_options.default_stream_compression_level.level =
+ (grpc_stream_compression_level)grpc_channel_arg_get_integer(
+ &args->args[i],
+ (grpc_integer_options){GRPC_STREAM_COMPRESS_LEVEL_NONE,
+ GRPC_STREAM_COMPRESS_LEVEL_NONE,
+ GRPC_STREAM_COMPRESS_LEVEL_COUNT - 1});
+ } else if (0 == strcmp(args->args[i].key,
GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM)) {
channel->compression_options.default_algorithm.is_set = true;
channel->compression_options.default_algorithm.algorithm =
@@ -149,12 +159,31 @@ grpc_channel *grpc_channel_create_with_builder(
&args->args[i],
(grpc_integer_options){GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE,
GRPC_COMPRESS_ALGORITHMS_COUNT - 1});
+ } else if (0 == strcmp(args->args[i].key,
+ GRPC_STREAM_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM)) {
+ channel->compression_options.default_stream_compression_algorithm.is_set =
+ true;
+ channel->compression_options.default_stream_compression_algorithm
+ .algorithm =
+ (grpc_stream_compression_algorithm)grpc_channel_arg_get_integer(
+ &args->args[i],
+ (grpc_integer_options){
+ GRPC_STREAM_COMPRESS_NONE, GRPC_STREAM_COMPRESS_NONE,
+ GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT - 1});
} else if (0 ==
strcmp(args->args[i].key,
GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET)) {
channel->compression_options.enabled_algorithms_bitset =
(uint32_t)args->args[i].value.integer |
0x1; /* always support no compression */
+ } else if (0 ==
+ strcmp(
+ args->args[i].key,
+ GRPC_STREAM_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET)) {
+ channel->compression_options
+ .enabled_stream_compression_algorithms_bitset =
+ (uint32_t)args->args[i].value.integer |
+ 0x1; /* always support no compression */
}
}
diff --git a/src/core/lib/surface/completion_queue.c b/src/core/lib/surface/completion_queue.c
index c20cfbc740..10e4e5ab0c 100644
--- a/src/core/lib/surface/completion_queue.c
+++ b/src/core/lib/surface/completion_queue.c
@@ -976,7 +976,6 @@ static void cq_shutdown_next(grpc_exec_ctx *exec_ctx,
if (cqd->shutdown_called) {
gpr_mu_unlock(cq->mu);
GRPC_CQ_INTERNAL_UNREF(exec_ctx, cq, "shutting_down");
- GPR_TIMER_END("grpc_completion_queue_shutdown", 0);
return;
}
cqd->shutdown_called = true;
@@ -1208,7 +1207,6 @@ static void cq_shutdown_pluck(grpc_exec_ctx *exec_ctx,
if (cqd->shutdown_called) {
gpr_mu_unlock(cq->mu);
GRPC_CQ_INTERNAL_UNREF(exec_ctx, cq, "shutting_down (pluck cq)");
- GPR_TIMER_END("grpc_completion_queue_shutdown", 0);
return;
}
cqd->shutdown_called = true;
diff --git a/src/core/lib/surface/version.c b/src/core/lib/surface/version.c
index 8cef15da80..96c16105e7 100644
--- a/src/core/lib/surface/version.c
+++ b/src/core/lib/surface/version.c
@@ -23,4 +23,4 @@
const char *grpc_version_string(void) { return "4.0.0-dev"; }
-const char *grpc_g_stands_for(void) { return "gregarious"; }
+const char *grpc_g_stands_for(void) { return "gambit"; }
diff --git a/src/core/lib/transport/static_metadata.c b/src/core/lib/transport/static_metadata.c
index 2388f19f81..28f05d5c44 100644
--- a/src/core/lib/transport/static_metadata.c
+++ b/src/core/lib/transport/static_metadata.c
@@ -40,65 +40,68 @@ static uint8_t g_bytes[] = {
114, 45, 115, 116, 97, 116, 115, 45, 98, 105, 110, 103, 114, 112, 99,
45, 116, 97, 103, 115, 45, 98, 105, 110, 103, 114, 112, 99, 45, 116,
114, 97, 99, 101, 45, 98, 105, 110, 99, 111, 110, 116, 101, 110, 116,
- 45, 116, 121, 112, 101, 103, 114, 112, 99, 45, 105, 110, 116, 101, 114,
- 110, 97, 108, 45, 101, 110, 99, 111, 100, 105, 110, 103, 45, 114, 101,
- 113, 117, 101, 115, 116, 117, 115, 101, 114, 45, 97, 103, 101, 110, 116,
- 104, 111, 115, 116, 108, 98, 45, 116, 111, 107, 101, 110, 103, 114, 112,
- 99, 45, 116, 105, 109, 101, 111, 117, 116, 103, 114, 112, 99, 46, 119,
- 97, 105, 116, 95, 102, 111, 114, 95, 114, 101, 97, 100, 121, 103, 114,
- 112, 99, 46, 116, 105, 109, 101, 111, 117, 116, 103, 114, 112, 99, 46,
- 109, 97, 120, 95, 114, 101, 113, 117, 101, 115, 116, 95, 109, 101, 115,
- 115, 97, 103, 101, 95, 98, 121, 116, 101, 115, 103, 114, 112, 99, 46,
- 109, 97, 120, 95, 114, 101, 115, 112, 111, 110, 115, 101, 95, 109, 101,
- 115, 115, 97, 103, 101, 95, 98, 121, 116, 101, 115, 47, 103, 114, 112,
- 99, 46, 108, 98, 46, 118, 49, 46, 76, 111, 97, 100, 66, 97, 108,
- 97, 110, 99, 101, 114, 47, 66, 97, 108, 97, 110, 99, 101, 76, 111,
- 97, 100, 48, 49, 50, 105, 100, 101, 110, 116, 105, 116, 121, 103, 122,
- 105, 112, 100, 101, 102, 108, 97, 116, 101, 116, 114, 97, 105, 108, 101,
- 114, 115, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 103,
- 114, 112, 99, 80, 79, 83, 84, 50, 48, 48, 52, 48, 52, 104, 116,
- 116, 112, 104, 116, 116, 112, 115, 103, 114, 112, 99, 71, 69, 84, 80,
- 85, 84, 47, 47, 105, 110, 100, 101, 120, 46, 104, 116, 109, 108, 50,
- 48, 52, 50, 48, 54, 51, 48, 52, 52, 48, 48, 53, 48, 48, 97,
- 99, 99, 101, 112, 116, 45, 99, 104, 97, 114, 115, 101, 116, 97, 99,
- 99, 101, 112, 116, 45, 101, 110, 99, 111, 100, 105, 110, 103, 103, 122,
- 105, 112, 44, 32, 100, 101, 102, 108, 97, 116, 101, 97, 99, 99, 101,
- 112, 116, 45, 108, 97, 110, 103, 117, 97, 103, 101, 97, 99, 99, 101,
- 112, 116, 45, 114, 97, 110, 103, 101, 115, 97, 99, 99, 101, 112, 116,
- 97, 99, 99, 101, 115, 115, 45, 99, 111, 110, 116, 114, 111, 108, 45,
- 97, 108, 108, 111, 119, 45, 111, 114, 105, 103, 105, 110, 97, 103, 101,
- 97, 108, 108, 111, 119, 97, 117, 116, 104, 111, 114, 105, 122, 97, 116,
- 105, 111, 110, 99, 97, 99, 104, 101, 45, 99, 111, 110, 116, 114, 111,
- 108, 99, 111, 110, 116, 101, 110, 116, 45, 100, 105, 115, 112, 111, 115,
- 105, 116, 105, 111, 110, 99, 111, 110, 116, 101, 110, 116, 45, 101, 110,
- 99, 111, 100, 105, 110, 103, 99, 111, 110, 116, 101, 110, 116, 45, 108,
- 97, 110, 103, 117, 97, 103, 101, 99, 111, 110, 116, 101, 110, 116, 45,
- 108, 101, 110, 103, 116, 104, 99, 111, 110, 116, 101, 110, 116, 45, 108,
- 111, 99, 97, 116, 105, 111, 110, 99, 111, 110, 116, 101, 110, 116, 45,
- 114, 97, 110, 103, 101, 99, 111, 111, 107, 105, 101, 100, 97, 116, 101,
- 101, 116, 97, 103, 101, 120, 112, 101, 99, 116, 101, 120, 112, 105, 114,
- 101, 115, 102, 114, 111, 109, 105, 102, 45, 109, 97, 116, 99, 104, 105,
- 102, 45, 109, 111, 100, 105, 102, 105, 101, 100, 45, 115, 105, 110, 99,
- 101, 105, 102, 45, 110, 111, 110, 101, 45, 109, 97, 116, 99, 104, 105,
- 102, 45, 114, 97, 110, 103, 101, 105, 102, 45, 117, 110, 109, 111, 100,
- 105, 102, 105, 101, 100, 45, 115, 105, 110, 99, 101, 108, 97, 115, 116,
- 45, 109, 111, 100, 105, 102, 105, 101, 100, 108, 98, 45, 99, 111, 115,
- 116, 45, 98, 105, 110, 108, 105, 110, 107, 108, 111, 99, 97, 116, 105,
- 111, 110, 109, 97, 120, 45, 102, 111, 114, 119, 97, 114, 100, 115, 112,
- 114, 111, 120, 121, 45, 97, 117, 116, 104, 101, 110, 116, 105, 99, 97,
- 116, 101, 112, 114, 111, 120, 121, 45, 97, 117, 116, 104, 111, 114, 105,
- 122, 97, 116, 105, 111, 110, 114, 97, 110, 103, 101, 114, 101, 102, 101,
- 114, 101, 114, 114, 101, 102, 114, 101, 115, 104, 114, 101, 116, 114, 121,
- 45, 97, 102, 116, 101, 114, 115, 101, 114, 118, 101, 114, 115, 101, 116,
- 45, 99, 111, 111, 107, 105, 101, 115, 116, 114, 105, 99, 116, 45, 116,
- 114, 97, 110, 115, 112, 111, 114, 116, 45, 115, 101, 99, 117, 114, 105,
- 116, 121, 116, 114, 97, 110, 115, 102, 101, 114, 45, 101, 110, 99, 111,
- 100, 105, 110, 103, 118, 97, 114, 121, 118, 105, 97, 119, 119, 119, 45,
- 97, 117, 116, 104, 101, 110, 116, 105, 99, 97, 116, 101, 105, 100, 101,
- 110, 116, 105, 116, 121, 44, 100, 101, 102, 108, 97, 116, 101, 105, 100,
- 101, 110, 116, 105, 116, 121, 44, 103, 122, 105, 112, 100, 101, 102, 108,
- 97, 116, 101, 44, 103, 122, 105, 112, 105, 100, 101, 110, 116, 105, 116,
- 121, 44, 100, 101, 102, 108, 97, 116, 101, 44, 103, 122, 105, 112};
+ 45, 116, 121, 112, 101, 99, 111, 110, 116, 101, 110, 116, 45, 101, 110,
+ 99, 111, 100, 105, 110, 103, 97, 99, 99, 101, 112, 116, 45, 101, 110,
+ 99, 111, 100, 105, 110, 103, 103, 114, 112, 99, 45, 105, 110, 116, 101,
+ 114, 110, 97, 108, 45, 101, 110, 99, 111, 100, 105, 110, 103, 45, 114,
+ 101, 113, 117, 101, 115, 116, 103, 114, 112, 99, 45, 105, 110, 116, 101,
+ 114, 110, 97, 108, 45, 115, 116, 114, 101, 97, 109, 45, 101, 110, 99,
+ 111, 100, 105, 110, 103, 45, 114, 101, 113, 117, 101, 115, 116, 117, 115,
+ 101, 114, 45, 97, 103, 101, 110, 116, 104, 111, 115, 116, 108, 98, 45,
+ 116, 111, 107, 101, 110, 103, 114, 112, 99, 45, 116, 105, 109, 101, 111,
+ 117, 116, 103, 114, 112, 99, 46, 119, 97, 105, 116, 95, 102, 111, 114,
+ 95, 114, 101, 97, 100, 121, 103, 114, 112, 99, 46, 116, 105, 109, 101,
+ 111, 117, 116, 103, 114, 112, 99, 46, 109, 97, 120, 95, 114, 101, 113,
+ 117, 101, 115, 116, 95, 109, 101, 115, 115, 97, 103, 101, 95, 98, 121,
+ 116, 101, 115, 103, 114, 112, 99, 46, 109, 97, 120, 95, 114, 101, 115,
+ 112, 111, 110, 115, 101, 95, 109, 101, 115, 115, 97, 103, 101, 95, 98,
+ 121, 116, 101, 115, 47, 103, 114, 112, 99, 46, 108, 98, 46, 118, 49,
+ 46, 76, 111, 97, 100, 66, 97, 108, 97, 110, 99, 101, 114, 47, 66,
+ 97, 108, 97, 110, 99, 101, 76, 111, 97, 100, 48, 49, 50, 105, 100,
+ 101, 110, 116, 105, 116, 121, 103, 122, 105, 112, 100, 101, 102, 108, 97,
+ 116, 101, 116, 114, 97, 105, 108, 101, 114, 115, 97, 112, 112, 108, 105,
+ 99, 97, 116, 105, 111, 110, 47, 103, 114, 112, 99, 80, 79, 83, 84,
+ 50, 48, 48, 52, 48, 52, 104, 116, 116, 112, 104, 116, 116, 112, 115,
+ 103, 114, 112, 99, 71, 69, 84, 80, 85, 84, 47, 47, 105, 110, 100,
+ 101, 120, 46, 104, 116, 109, 108, 50, 48, 52, 50, 48, 54, 51, 48,
+ 52, 52, 48, 48, 53, 48, 48, 97, 99, 99, 101, 112, 116, 45, 99,
+ 104, 97, 114, 115, 101, 116, 103, 122, 105, 112, 44, 32, 100, 101, 102,
+ 108, 97, 116, 101, 97, 99, 99, 101, 112, 116, 45, 108, 97, 110, 103,
+ 117, 97, 103, 101, 97, 99, 99, 101, 112, 116, 45, 114, 97, 110, 103,
+ 101, 115, 97, 99, 99, 101, 112, 116, 97, 99, 99, 101, 115, 115, 45,
+ 99, 111, 110, 116, 114, 111, 108, 45, 97, 108, 108, 111, 119, 45, 111,
+ 114, 105, 103, 105, 110, 97, 103, 101, 97, 108, 108, 111, 119, 97, 117,
+ 116, 104, 111, 114, 105, 122, 97, 116, 105, 111, 110, 99, 97, 99, 104,
+ 101, 45, 99, 111, 110, 116, 114, 111, 108, 99, 111, 110, 116, 101, 110,
+ 116, 45, 100, 105, 115, 112, 111, 115, 105, 116, 105, 111, 110, 99, 111,
+ 110, 116, 101, 110, 116, 45, 108, 97, 110, 103, 117, 97, 103, 101, 99,
+ 111, 110, 116, 101, 110, 116, 45, 108, 101, 110, 103, 116, 104, 99, 111,
+ 110, 116, 101, 110, 116, 45, 108, 111, 99, 97, 116, 105, 111, 110, 99,
+ 111, 110, 116, 101, 110, 116, 45, 114, 97, 110, 103, 101, 99, 111, 111,
+ 107, 105, 101, 100, 97, 116, 101, 101, 116, 97, 103, 101, 120, 112, 101,
+ 99, 116, 101, 120, 112, 105, 114, 101, 115, 102, 114, 111, 109, 105, 102,
+ 45, 109, 97, 116, 99, 104, 105, 102, 45, 109, 111, 100, 105, 102, 105,
+ 101, 100, 45, 115, 105, 110, 99, 101, 105, 102, 45, 110, 111, 110, 101,
+ 45, 109, 97, 116, 99, 104, 105, 102, 45, 114, 97, 110, 103, 101, 105,
+ 102, 45, 117, 110, 109, 111, 100, 105, 102, 105, 101, 100, 45, 115, 105,
+ 110, 99, 101, 108, 97, 115, 116, 45, 109, 111, 100, 105, 102, 105, 101,
+ 100, 108, 98, 45, 99, 111, 115, 116, 45, 98, 105, 110, 108, 105, 110,
+ 107, 108, 111, 99, 97, 116, 105, 111, 110, 109, 97, 120, 45, 102, 111,
+ 114, 119, 97, 114, 100, 115, 112, 114, 111, 120, 121, 45, 97, 117, 116,
+ 104, 101, 110, 116, 105, 99, 97, 116, 101, 112, 114, 111, 120, 121, 45,
+ 97, 117, 116, 104, 111, 114, 105, 122, 97, 116, 105, 111, 110, 114, 97,
+ 110, 103, 101, 114, 101, 102, 101, 114, 101, 114, 114, 101, 102, 114, 101,
+ 115, 104, 114, 101, 116, 114, 121, 45, 97, 102, 116, 101, 114, 115, 101,
+ 114, 118, 101, 114, 115, 101, 116, 45, 99, 111, 111, 107, 105, 101, 115,
+ 116, 114, 105, 99, 116, 45, 116, 114, 97, 110, 115, 112, 111, 114, 116,
+ 45, 115, 101, 99, 117, 114, 105, 116, 121, 116, 114, 97, 110, 115, 102,
+ 101, 114, 45, 101, 110, 99, 111, 100, 105, 110, 103, 118, 97, 114, 121,
+ 118, 105, 97, 119, 119, 119, 45, 97, 117, 116, 104, 101, 110, 116, 105,
+ 99, 97, 116, 101, 105, 100, 101, 110, 116, 105, 116, 121, 44, 100, 101,
+ 102, 108, 97, 116, 101, 105, 100, 101, 110, 116, 105, 116, 121, 44, 103,
+ 122, 105, 112, 100, 101, 102, 108, 97, 116, 101, 44, 103, 122, 105, 112,
+ 105, 100, 101, 110, 116, 105, 116, 121, 44, 100, 101, 102, 108, 97, 116,
+ 101, 44, 103, 122, 105, 112};
static void static_ref(void *unused) {}
static void static_unref(grpc_exec_ctx *exec_ctx, void *unused) {}
@@ -209,6 +212,7 @@ grpc_slice_refcount grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT] = {
{&grpc_static_metadata_vtable, &static_sub_refcnt},
{&grpc_static_metadata_vtable, &static_sub_refcnt},
{&grpc_static_metadata_vtable, &static_sub_refcnt},
+ {&grpc_static_metadata_vtable, &static_sub_refcnt},
};
const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT] = {
@@ -243,193 +247,194 @@ const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT] = {
{.refcount = &grpc_static_metadata_refcounts[14],
.data.refcounted = {g_bytes + 158, 12}},
{.refcount = &grpc_static_metadata_refcounts[15],
- .data.refcounted = {g_bytes + 170, 30}},
+ .data.refcounted = {g_bytes + 170, 16}},
{.refcount = &grpc_static_metadata_refcounts[16],
- .data.refcounted = {g_bytes + 200, 10}},
+ .data.refcounted = {g_bytes + 186, 15}},
{.refcount = &grpc_static_metadata_refcounts[17],
- .data.refcounted = {g_bytes + 210, 4}},
+ .data.refcounted = {g_bytes + 201, 30}},
{.refcount = &grpc_static_metadata_refcounts[18],
- .data.refcounted = {g_bytes + 214, 8}},
+ .data.refcounted = {g_bytes + 231, 37}},
{.refcount = &grpc_static_metadata_refcounts[19],
- .data.refcounted = {g_bytes + 222, 12}},
+ .data.refcounted = {g_bytes + 268, 10}},
{.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}},
+ .data.refcounted = {g_bytes + 278, 4}},
{.refcount = &grpc_static_metadata_refcounts[21],
- .data.refcounted = {g_bytes + 234, 19}},
+ .data.refcounted = {g_bytes + 282, 8}},
{.refcount = &grpc_static_metadata_refcounts[22],
- .data.refcounted = {g_bytes + 253, 12}},
+ .data.refcounted = {g_bytes + 290, 12}},
{.refcount = &grpc_static_metadata_refcounts[23],
- .data.refcounted = {g_bytes + 265, 30}},
+ .data.refcounted = {g_bytes + 302, 0}},
{.refcount = &grpc_static_metadata_refcounts[24],
- .data.refcounted = {g_bytes + 295, 31}},
+ .data.refcounted = {g_bytes + 302, 19}},
{.refcount = &grpc_static_metadata_refcounts[25],
- .data.refcounted = {g_bytes + 326, 36}},
+ .data.refcounted = {g_bytes + 321, 12}},
{.refcount = &grpc_static_metadata_refcounts[26],
- .data.refcounted = {g_bytes + 362, 1}},
+ .data.refcounted = {g_bytes + 333, 30}},
{.refcount = &grpc_static_metadata_refcounts[27],
- .data.refcounted = {g_bytes + 363, 1}},
+ .data.refcounted = {g_bytes + 363, 31}},
{.refcount = &grpc_static_metadata_refcounts[28],
- .data.refcounted = {g_bytes + 364, 1}},
+ .data.refcounted = {g_bytes + 394, 36}},
{.refcount = &grpc_static_metadata_refcounts[29],
- .data.refcounted = {g_bytes + 365, 8}},
+ .data.refcounted = {g_bytes + 430, 1}},
{.refcount = &grpc_static_metadata_refcounts[30],
- .data.refcounted = {g_bytes + 373, 4}},
+ .data.refcounted = {g_bytes + 431, 1}},
{.refcount = &grpc_static_metadata_refcounts[31],
- .data.refcounted = {g_bytes + 377, 7}},
+ .data.refcounted = {g_bytes + 432, 1}},
{.refcount = &grpc_static_metadata_refcounts[32],
- .data.refcounted = {g_bytes + 384, 8}},
+ .data.refcounted = {g_bytes + 433, 8}},
{.refcount = &grpc_static_metadata_refcounts[33],
- .data.refcounted = {g_bytes + 392, 16}},
+ .data.refcounted = {g_bytes + 441, 4}},
{.refcount = &grpc_static_metadata_refcounts[34],
- .data.refcounted = {g_bytes + 408, 4}},
+ .data.refcounted = {g_bytes + 445, 7}},
{.refcount = &grpc_static_metadata_refcounts[35],
- .data.refcounted = {g_bytes + 412, 3}},
+ .data.refcounted = {g_bytes + 452, 8}},
{.refcount = &grpc_static_metadata_refcounts[36],
- .data.refcounted = {g_bytes + 415, 3}},
+ .data.refcounted = {g_bytes + 460, 16}},
{.refcount = &grpc_static_metadata_refcounts[37],
- .data.refcounted = {g_bytes + 418, 4}},
+ .data.refcounted = {g_bytes + 476, 4}},
{.refcount = &grpc_static_metadata_refcounts[38],
- .data.refcounted = {g_bytes + 422, 5}},
+ .data.refcounted = {g_bytes + 480, 3}},
{.refcount = &grpc_static_metadata_refcounts[39],
- .data.refcounted = {g_bytes + 427, 4}},
+ .data.refcounted = {g_bytes + 483, 3}},
{.refcount = &grpc_static_metadata_refcounts[40],
- .data.refcounted = {g_bytes + 431, 3}},
+ .data.refcounted = {g_bytes + 486, 4}},
{.refcount = &grpc_static_metadata_refcounts[41],
- .data.refcounted = {g_bytes + 434, 3}},
+ .data.refcounted = {g_bytes + 490, 5}},
{.refcount = &grpc_static_metadata_refcounts[42],
- .data.refcounted = {g_bytes + 437, 1}},
+ .data.refcounted = {g_bytes + 495, 4}},
{.refcount = &grpc_static_metadata_refcounts[43],
- .data.refcounted = {g_bytes + 438, 11}},
+ .data.refcounted = {g_bytes + 499, 3}},
{.refcount = &grpc_static_metadata_refcounts[44],
- .data.refcounted = {g_bytes + 449, 3}},
+ .data.refcounted = {g_bytes + 502, 3}},
{.refcount = &grpc_static_metadata_refcounts[45],
- .data.refcounted = {g_bytes + 452, 3}},
+ .data.refcounted = {g_bytes + 505, 1}},
{.refcount = &grpc_static_metadata_refcounts[46],
- .data.refcounted = {g_bytes + 455, 3}},
+ .data.refcounted = {g_bytes + 506, 11}},
{.refcount = &grpc_static_metadata_refcounts[47],
- .data.refcounted = {g_bytes + 458, 3}},
+ .data.refcounted = {g_bytes + 517, 3}},
{.refcount = &grpc_static_metadata_refcounts[48],
- .data.refcounted = {g_bytes + 461, 3}},
+ .data.refcounted = {g_bytes + 520, 3}},
{.refcount = &grpc_static_metadata_refcounts[49],
- .data.refcounted = {g_bytes + 464, 14}},
+ .data.refcounted = {g_bytes + 523, 3}},
{.refcount = &grpc_static_metadata_refcounts[50],
- .data.refcounted = {g_bytes + 478, 15}},
+ .data.refcounted = {g_bytes + 526, 3}},
{.refcount = &grpc_static_metadata_refcounts[51],
- .data.refcounted = {g_bytes + 493, 13}},
+ .data.refcounted = {g_bytes + 529, 3}},
{.refcount = &grpc_static_metadata_refcounts[52],
- .data.refcounted = {g_bytes + 506, 15}},
+ .data.refcounted = {g_bytes + 532, 14}},
{.refcount = &grpc_static_metadata_refcounts[53],
- .data.refcounted = {g_bytes + 521, 13}},
+ .data.refcounted = {g_bytes + 546, 13}},
{.refcount = &grpc_static_metadata_refcounts[54],
- .data.refcounted = {g_bytes + 534, 6}},
+ .data.refcounted = {g_bytes + 559, 15}},
{.refcount = &grpc_static_metadata_refcounts[55],
- .data.refcounted = {g_bytes + 540, 27}},
+ .data.refcounted = {g_bytes + 574, 13}},
{.refcount = &grpc_static_metadata_refcounts[56],
- .data.refcounted = {g_bytes + 567, 3}},
+ .data.refcounted = {g_bytes + 587, 6}},
{.refcount = &grpc_static_metadata_refcounts[57],
- .data.refcounted = {g_bytes + 570, 5}},
+ .data.refcounted = {g_bytes + 593, 27}},
{.refcount = &grpc_static_metadata_refcounts[58],
- .data.refcounted = {g_bytes + 575, 13}},
+ .data.refcounted = {g_bytes + 620, 3}},
{.refcount = &grpc_static_metadata_refcounts[59],
- .data.refcounted = {g_bytes + 588, 13}},
+ .data.refcounted = {g_bytes + 623, 5}},
{.refcount = &grpc_static_metadata_refcounts[60],
- .data.refcounted = {g_bytes + 601, 19}},
+ .data.refcounted = {g_bytes + 628, 13}},
{.refcount = &grpc_static_metadata_refcounts[61],
- .data.refcounted = {g_bytes + 620, 16}},
+ .data.refcounted = {g_bytes + 641, 13}},
{.refcount = &grpc_static_metadata_refcounts[62],
- .data.refcounted = {g_bytes + 636, 16}},
+ .data.refcounted = {g_bytes + 654, 19}},
{.refcount = &grpc_static_metadata_refcounts[63],
- .data.refcounted = {g_bytes + 652, 14}},
+ .data.refcounted = {g_bytes + 673, 16}},
{.refcount = &grpc_static_metadata_refcounts[64],
- .data.refcounted = {g_bytes + 666, 16}},
+ .data.refcounted = {g_bytes + 689, 14}},
{.refcount = &grpc_static_metadata_refcounts[65],
- .data.refcounted = {g_bytes + 682, 13}},
+ .data.refcounted = {g_bytes + 703, 16}},
{.refcount = &grpc_static_metadata_refcounts[66],
- .data.refcounted = {g_bytes + 695, 6}},
+ .data.refcounted = {g_bytes + 719, 13}},
{.refcount = &grpc_static_metadata_refcounts[67],
- .data.refcounted = {g_bytes + 701, 4}},
+ .data.refcounted = {g_bytes + 732, 6}},
{.refcount = &grpc_static_metadata_refcounts[68],
- .data.refcounted = {g_bytes + 705, 4}},
+ .data.refcounted = {g_bytes + 738, 4}},
{.refcount = &grpc_static_metadata_refcounts[69],
- .data.refcounted = {g_bytes + 709, 6}},
+ .data.refcounted = {g_bytes + 742, 4}},
{.refcount = &grpc_static_metadata_refcounts[70],
- .data.refcounted = {g_bytes + 715, 7}},
+ .data.refcounted = {g_bytes + 746, 6}},
{.refcount = &grpc_static_metadata_refcounts[71],
- .data.refcounted = {g_bytes + 722, 4}},
+ .data.refcounted = {g_bytes + 752, 7}},
{.refcount = &grpc_static_metadata_refcounts[72],
- .data.refcounted = {g_bytes + 726, 8}},
+ .data.refcounted = {g_bytes + 759, 4}},
{.refcount = &grpc_static_metadata_refcounts[73],
- .data.refcounted = {g_bytes + 734, 17}},
+ .data.refcounted = {g_bytes + 763, 8}},
{.refcount = &grpc_static_metadata_refcounts[74],
- .data.refcounted = {g_bytes + 751, 13}},
+ .data.refcounted = {g_bytes + 771, 17}},
{.refcount = &grpc_static_metadata_refcounts[75],
- .data.refcounted = {g_bytes + 764, 8}},
+ .data.refcounted = {g_bytes + 788, 13}},
{.refcount = &grpc_static_metadata_refcounts[76],
- .data.refcounted = {g_bytes + 772, 19}},
+ .data.refcounted = {g_bytes + 801, 8}},
{.refcount = &grpc_static_metadata_refcounts[77],
- .data.refcounted = {g_bytes + 791, 13}},
+ .data.refcounted = {g_bytes + 809, 19}},
{.refcount = &grpc_static_metadata_refcounts[78],
- .data.refcounted = {g_bytes + 804, 11}},
+ .data.refcounted = {g_bytes + 828, 13}},
{.refcount = &grpc_static_metadata_refcounts[79],
- .data.refcounted = {g_bytes + 815, 4}},
+ .data.refcounted = {g_bytes + 841, 11}},
{.refcount = &grpc_static_metadata_refcounts[80],
- .data.refcounted = {g_bytes + 819, 8}},
+ .data.refcounted = {g_bytes + 852, 4}},
{.refcount = &grpc_static_metadata_refcounts[81],
- .data.refcounted = {g_bytes + 827, 12}},
+ .data.refcounted = {g_bytes + 856, 8}},
{.refcount = &grpc_static_metadata_refcounts[82],
- .data.refcounted = {g_bytes + 839, 18}},
+ .data.refcounted = {g_bytes + 864, 12}},
{.refcount = &grpc_static_metadata_refcounts[83],
- .data.refcounted = {g_bytes + 857, 19}},
+ .data.refcounted = {g_bytes + 876, 18}},
{.refcount = &grpc_static_metadata_refcounts[84],
- .data.refcounted = {g_bytes + 876, 5}},
+ .data.refcounted = {g_bytes + 894, 19}},
{.refcount = &grpc_static_metadata_refcounts[85],
- .data.refcounted = {g_bytes + 881, 7}},
+ .data.refcounted = {g_bytes + 913, 5}},
{.refcount = &grpc_static_metadata_refcounts[86],
- .data.refcounted = {g_bytes + 888, 7}},
+ .data.refcounted = {g_bytes + 918, 7}},
{.refcount = &grpc_static_metadata_refcounts[87],
- .data.refcounted = {g_bytes + 895, 11}},
+ .data.refcounted = {g_bytes + 925, 7}},
{.refcount = &grpc_static_metadata_refcounts[88],
- .data.refcounted = {g_bytes + 906, 6}},
+ .data.refcounted = {g_bytes + 932, 11}},
{.refcount = &grpc_static_metadata_refcounts[89],
- .data.refcounted = {g_bytes + 912, 10}},
+ .data.refcounted = {g_bytes + 943, 6}},
{.refcount = &grpc_static_metadata_refcounts[90],
- .data.refcounted = {g_bytes + 922, 25}},
+ .data.refcounted = {g_bytes + 949, 10}},
{.refcount = &grpc_static_metadata_refcounts[91],
- .data.refcounted = {g_bytes + 947, 17}},
+ .data.refcounted = {g_bytes + 959, 25}},
{.refcount = &grpc_static_metadata_refcounts[92],
- .data.refcounted = {g_bytes + 964, 4}},
+ .data.refcounted = {g_bytes + 984, 17}},
{.refcount = &grpc_static_metadata_refcounts[93],
- .data.refcounted = {g_bytes + 968, 3}},
+ .data.refcounted = {g_bytes + 1001, 4}},
{.refcount = &grpc_static_metadata_refcounts[94],
- .data.refcounted = {g_bytes + 971, 16}},
+ .data.refcounted = {g_bytes + 1005, 3}},
{.refcount = &grpc_static_metadata_refcounts[95],
- .data.refcounted = {g_bytes + 987, 16}},
+ .data.refcounted = {g_bytes + 1008, 16}},
{.refcount = &grpc_static_metadata_refcounts[96],
- .data.refcounted = {g_bytes + 1003, 13}},
+ .data.refcounted = {g_bytes + 1024, 16}},
{.refcount = &grpc_static_metadata_refcounts[97],
- .data.refcounted = {g_bytes + 1016, 12}},
+ .data.refcounted = {g_bytes + 1040, 13}},
{.refcount = &grpc_static_metadata_refcounts[98],
- .data.refcounted = {g_bytes + 1028, 21}},
+ .data.refcounted = {g_bytes + 1053, 12}},
+ {.refcount = &grpc_static_metadata_refcounts[99],
+ .data.refcounted = {g_bytes + 1065, 21}},
};
uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 6, 6, 8, 8};
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 6, 6, 8, 8, 2, 4, 4};
static const int8_t elems_r[] = {
- 10, 8, -3, 0, 9, 21, -77, 22, 0, 10, -7, 0, 0, 0,
- 14, 0, 13, 12, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, -50, -51, 16, -53, -54, -55, -56,
- -56, -57, -58, -59, 0, 37, 36, 35, 34, 33, 32, 31, 30, 29,
- 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15,
- 14, 13, 12, 11, 10, 13, 12, 11, 10, 9, 8, 7, 0};
+ 11, 9, -3, 0, 10, 27, -74, 28, 0, 14, -7, 0, 0, 0, 18, 8, -2,
+ 0, 0, 13, 12, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, -50, 0, -33, -55, -56, -57, -58, -57, 0, 40, 39, 38, 37, 36, 35, 34,
+ 33, 32, 31, 30, 29, 28, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 22,
+ 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 12, 11, 0};
static uint32_t elems_phash(uint32_t i) {
- i -= 42;
- uint32_t x = i % 97;
- uint32_t y = i / 97;
+ i -= 45;
+ uint32_t x = i % 98;
+ uint32_t y = i / 98;
uint32_t h = x;
if (y < GPR_ARRAY_SIZE(elems_r)) {
uint32_t delta = (uint32_t)elems_r[y];
@@ -439,30 +444,31 @@ static uint32_t elems_phash(uint32_t i) {
}
static const uint16_t elem_keys[] = {
- 1019, 1020, 1021, 242, 243, 244, 245, 246, 139, 140, 42, 43,
- 433, 434, 435, 920, 921, 922, 719, 720, 1406, 527, 721, 1604,
- 1703, 1802, 4871, 4970, 5001, 5168, 5267, 5366, 5465, 1419, 5564, 5663,
- 5762, 5861, 5960, 6059, 6158, 6257, 6356, 6455, 6554, 6653, 6752, 6851,
- 6950, 7049, 7148, 7247, 7346, 7445, 7544, 7643, 7742, 7841, 7940, 8039,
- 8138, 8237, 8336, 8435, 8534, 8633, 1085, 1086, 1087, 1088, 8732, 8831,
- 8930, 9029, 9128, 9227, 9326, 0, 317, 0, 0, 0, 0, 0,
+ 1032, 1033, 1034, 247, 248, 249, 250, 251, 1623, 143, 144, 45,
+ 46, 440, 441, 442, 1523, 1632, 1633, 932, 933, 934, 729, 730,
+ 1423, 1532, 1533, 535, 731, 1923, 2023, 2123, 5223, 5523, 5623, 5723,
+ 5823, 1436, 1653, 5923, 6023, 6123, 6223, 6323, 6423, 6523, 6623, 6723,
+ 6823, 6923, 7023, 7123, 7223, 5423, 7323, 7423, 7523, 7623, 7723, 7823,
+ 7923, 8023, 8123, 8223, 1096, 1097, 1098, 1099, 8323, 8423, 8523, 8623,
+ 8723, 8823, 8923, 9023, 9123, 9223, 9323, 323, 9423, 9523, 1697, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 133, 233, 234, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 137, 238, 239, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0};
+ 0, 0, 0, 0, 0};
static const uint8_t elem_idxs[] = {
- 74, 77, 75, 19, 20, 21, 22, 23, 15, 16, 17, 18, 11, 12, 13,
- 3, 4, 5, 0, 1, 41, 6, 2, 70, 48, 55, 24, 25, 26, 27,
- 28, 29, 30, 7, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 42,
- 43, 44, 45, 46, 47, 49, 50, 51, 52, 53, 54, 56, 57, 58, 59,
- 60, 61, 62, 63, 64, 65, 76, 78, 79, 80, 66, 67, 68, 69, 71,
- 72, 73, 255, 14, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 8, 9, 10};
+ 76, 79, 77, 19, 20, 21, 22, 23, 25, 15, 16, 17, 18, 11,
+ 12, 13, 38, 83, 84, 3, 4, 5, 0, 1, 43, 36, 37, 6,
+ 2, 72, 50, 57, 24, 28, 29, 30, 31, 7, 26, 32, 33, 34,
+ 35, 39, 40, 41, 42, 44, 45, 46, 47, 48, 49, 27, 51, 52,
+ 53, 54, 55, 56, 58, 59, 60, 61, 78, 80, 81, 82, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71, 73, 14, 74, 75, 85, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 8, 9, 10};
grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b) {
if (a == -1 || b == -1) return GRPC_MDNULL;
- uint32_t k = (uint32_t)(a * 99 + b);
+ uint32_t k = (uint32_t)(a * 100 + b);
uint32_t h = elems_phash(k);
return h < GPR_ARRAY_SIZE(elem_keys) && elem_keys[h] == k &&
elem_idxs[h] != 255
@@ -474,328 +480,350 @@ grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b) {
grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = {
{{.refcount = &grpc_static_metadata_refcounts[7],
.data.refcounted = {g_bytes + 50, 11}},
- {.refcount = &grpc_static_metadata_refcounts[26],
- .data.refcounted = {g_bytes + 362, 1}}},
+ {.refcount = &grpc_static_metadata_refcounts[29],
+ .data.refcounted = {g_bytes + 430, 1}}},
{{.refcount = &grpc_static_metadata_refcounts[7],
.data.refcounted = {g_bytes + 50, 11}},
- {.refcount = &grpc_static_metadata_refcounts[27],
- .data.refcounted = {g_bytes + 363, 1}}},
+ {.refcount = &grpc_static_metadata_refcounts[30],
+ .data.refcounted = {g_bytes + 431, 1}}},
{{.refcount = &grpc_static_metadata_refcounts[7],
.data.refcounted = {g_bytes + 50, 11}},
- {.refcount = &grpc_static_metadata_refcounts[28],
- .data.refcounted = {g_bytes + 364, 1}}},
+ {.refcount = &grpc_static_metadata_refcounts[31],
+ .data.refcounted = {g_bytes + 432, 1}}},
{{.refcount = &grpc_static_metadata_refcounts[9],
.data.refcounted = {g_bytes + 77, 13}},
- {.refcount = &grpc_static_metadata_refcounts[29],
- .data.refcounted = {g_bytes + 365, 8}}},
+ {.refcount = &grpc_static_metadata_refcounts[32],
+ .data.refcounted = {g_bytes + 433, 8}}},
{{.refcount = &grpc_static_metadata_refcounts[9],
.data.refcounted = {g_bytes + 77, 13}},
- {.refcount = &grpc_static_metadata_refcounts[30],
- .data.refcounted = {g_bytes + 373, 4}}},
+ {.refcount = &grpc_static_metadata_refcounts[33],
+ .data.refcounted = {g_bytes + 441, 4}}},
{{.refcount = &grpc_static_metadata_refcounts[9],
.data.refcounted = {g_bytes + 77, 13}},
- {.refcount = &grpc_static_metadata_refcounts[31],
- .data.refcounted = {g_bytes + 377, 7}}},
+ {.refcount = &grpc_static_metadata_refcounts[34],
+ .data.refcounted = {g_bytes + 445, 7}}},
{{.refcount = &grpc_static_metadata_refcounts[5],
.data.refcounted = {g_bytes + 36, 2}},
- {.refcount = &grpc_static_metadata_refcounts[32],
- .data.refcounted = {g_bytes + 384, 8}}},
+ {.refcount = &grpc_static_metadata_refcounts[35],
+ .data.refcounted = {g_bytes + 452, 8}}},
{{.refcount = &grpc_static_metadata_refcounts[14],
.data.refcounted = {g_bytes + 158, 12}},
- {.refcount = &grpc_static_metadata_refcounts[33],
- .data.refcounted = {g_bytes + 392, 16}}},
+ {.refcount = &grpc_static_metadata_refcounts[36],
+ .data.refcounted = {g_bytes + 460, 16}}},
{{.refcount = &grpc_static_metadata_refcounts[1],
.data.refcounted = {g_bytes + 5, 7}},
- {.refcount = &grpc_static_metadata_refcounts[34],
- .data.refcounted = {g_bytes + 408, 4}}},
+ {.refcount = &grpc_static_metadata_refcounts[37],
+ .data.refcounted = {g_bytes + 476, 4}}},
{{.refcount = &grpc_static_metadata_refcounts[2],
.data.refcounted = {g_bytes + 12, 7}},
- {.refcount = &grpc_static_metadata_refcounts[35],
- .data.refcounted = {g_bytes + 412, 3}}},
+ {.refcount = &grpc_static_metadata_refcounts[38],
+ .data.refcounted = {g_bytes + 480, 3}}},
{{.refcount = &grpc_static_metadata_refcounts[2],
.data.refcounted = {g_bytes + 12, 7}},
- {.refcount = &grpc_static_metadata_refcounts[36],
- .data.refcounted = {g_bytes + 415, 3}}},
+ {.refcount = &grpc_static_metadata_refcounts[39],
+ .data.refcounted = {g_bytes + 483, 3}}},
{{.refcount = &grpc_static_metadata_refcounts[4],
.data.refcounted = {g_bytes + 29, 7}},
- {.refcount = &grpc_static_metadata_refcounts[37],
- .data.refcounted = {g_bytes + 418, 4}}},
+ {.refcount = &grpc_static_metadata_refcounts[40],
+ .data.refcounted = {g_bytes + 486, 4}}},
{{.refcount = &grpc_static_metadata_refcounts[4],
.data.refcounted = {g_bytes + 29, 7}},
- {.refcount = &grpc_static_metadata_refcounts[38],
- .data.refcounted = {g_bytes + 422, 5}}},
+ {.refcount = &grpc_static_metadata_refcounts[41],
+ .data.refcounted = {g_bytes + 490, 5}}},
{{.refcount = &grpc_static_metadata_refcounts[4],
.data.refcounted = {g_bytes + 29, 7}},
- {.refcount = &grpc_static_metadata_refcounts[39],
- .data.refcounted = {g_bytes + 427, 4}}},
+ {.refcount = &grpc_static_metadata_refcounts[42],
+ .data.refcounted = {g_bytes + 495, 4}}},
{{.refcount = &grpc_static_metadata_refcounts[3],
.data.refcounted = {g_bytes + 19, 10}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[1],
.data.refcounted = {g_bytes + 5, 7}},
- {.refcount = &grpc_static_metadata_refcounts[40],
- .data.refcounted = {g_bytes + 431, 3}}},
+ {.refcount = &grpc_static_metadata_refcounts[43],
+ .data.refcounted = {g_bytes + 499, 3}}},
{{.refcount = &grpc_static_metadata_refcounts[1],
.data.refcounted = {g_bytes + 5, 7}},
- {.refcount = &grpc_static_metadata_refcounts[41],
- .data.refcounted = {g_bytes + 434, 3}}},
+ {.refcount = &grpc_static_metadata_refcounts[44],
+ .data.refcounted = {g_bytes + 502, 3}}},
{{.refcount = &grpc_static_metadata_refcounts[0],
.data.refcounted = {g_bytes + 0, 5}},
- {.refcount = &grpc_static_metadata_refcounts[42],
- .data.refcounted = {g_bytes + 437, 1}}},
+ {.refcount = &grpc_static_metadata_refcounts[45],
+ .data.refcounted = {g_bytes + 505, 1}}},
{{.refcount = &grpc_static_metadata_refcounts[0],
.data.refcounted = {g_bytes + 0, 5}},
- {.refcount = &grpc_static_metadata_refcounts[43],
- .data.refcounted = {g_bytes + 438, 11}}},
+ {.refcount = &grpc_static_metadata_refcounts[46],
+ .data.refcounted = {g_bytes + 506, 11}}},
{{.refcount = &grpc_static_metadata_refcounts[2],
.data.refcounted = {g_bytes + 12, 7}},
- {.refcount = &grpc_static_metadata_refcounts[44],
- .data.refcounted = {g_bytes + 449, 3}}},
+ {.refcount = &grpc_static_metadata_refcounts[47],
+ .data.refcounted = {g_bytes + 517, 3}}},
{{.refcount = &grpc_static_metadata_refcounts[2],
.data.refcounted = {g_bytes + 12, 7}},
- {.refcount = &grpc_static_metadata_refcounts[45],
- .data.refcounted = {g_bytes + 452, 3}}},
+ {.refcount = &grpc_static_metadata_refcounts[48],
+ .data.refcounted = {g_bytes + 520, 3}}},
{{.refcount = &grpc_static_metadata_refcounts[2],
.data.refcounted = {g_bytes + 12, 7}},
- {.refcount = &grpc_static_metadata_refcounts[46],
- .data.refcounted = {g_bytes + 455, 3}}},
+ {.refcount = &grpc_static_metadata_refcounts[49],
+ .data.refcounted = {g_bytes + 523, 3}}},
{{.refcount = &grpc_static_metadata_refcounts[2],
.data.refcounted = {g_bytes + 12, 7}},
- {.refcount = &grpc_static_metadata_refcounts[47],
- .data.refcounted = {g_bytes + 458, 3}}},
+ {.refcount = &grpc_static_metadata_refcounts[50],
+ .data.refcounted = {g_bytes + 526, 3}}},
{{.refcount = &grpc_static_metadata_refcounts[2],
.data.refcounted = {g_bytes + 12, 7}},
- {.refcount = &grpc_static_metadata_refcounts[48],
- .data.refcounted = {g_bytes + 461, 3}}},
- {{.refcount = &grpc_static_metadata_refcounts[49],
- .data.refcounted = {g_bytes + 464, 14}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
- {{.refcount = &grpc_static_metadata_refcounts[50],
- .data.refcounted = {g_bytes + 478, 15}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
- {{.refcount = &grpc_static_metadata_refcounts[50],
- .data.refcounted = {g_bytes + 478, 15}},
{.refcount = &grpc_static_metadata_refcounts[51],
- .data.refcounted = {g_bytes + 493, 13}}},
+ .data.refcounted = {g_bytes + 529, 3}}},
{{.refcount = &grpc_static_metadata_refcounts[52],
- .data.refcounted = {g_bytes + 506, 15}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
- {{.refcount = &grpc_static_metadata_refcounts[53],
- .data.refcounted = {g_bytes + 521, 13}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 532, 14}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
+ {{.refcount = &grpc_static_metadata_refcounts[16],
+ .data.refcounted = {g_bytes + 186, 15}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
+ {{.refcount = &grpc_static_metadata_refcounts[16],
+ .data.refcounted = {g_bytes + 186, 15}},
+ {.refcount = &grpc_static_metadata_refcounts[53],
+ .data.refcounted = {g_bytes + 546, 13}}},
{{.refcount = &grpc_static_metadata_refcounts[54],
- .data.refcounted = {g_bytes + 534, 6}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 559, 15}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[55],
- .data.refcounted = {g_bytes + 540, 27}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 574, 13}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[56],
- .data.refcounted = {g_bytes + 567, 3}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 587, 6}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[57],
- .data.refcounted = {g_bytes + 570, 5}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 593, 27}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[58],
- .data.refcounted = {g_bytes + 575, 13}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 620, 3}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[59],
- .data.refcounted = {g_bytes + 588, 13}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 623, 5}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[60],
- .data.refcounted = {g_bytes + 601, 19}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 628, 13}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[61],
- .data.refcounted = {g_bytes + 620, 16}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 641, 13}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[62],
- .data.refcounted = {g_bytes + 636, 16}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 654, 19}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
+ {{.refcount = &grpc_static_metadata_refcounts[15],
+ .data.refcounted = {g_bytes + 170, 16}},
+ {.refcount = &grpc_static_metadata_refcounts[32],
+ .data.refcounted = {g_bytes + 433, 8}}},
+ {{.refcount = &grpc_static_metadata_refcounts[15],
+ .data.refcounted = {g_bytes + 170, 16}},
+ {.refcount = &grpc_static_metadata_refcounts[33],
+ .data.refcounted = {g_bytes + 441, 4}}},
+ {{.refcount = &grpc_static_metadata_refcounts[15],
+ .data.refcounted = {g_bytes + 170, 16}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[63],
- .data.refcounted = {g_bytes + 652, 14}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 673, 16}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[64],
- .data.refcounted = {g_bytes + 666, 16}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 689, 14}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[65],
- .data.refcounted = {g_bytes + 682, 13}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 703, 16}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
+ {{.refcount = &grpc_static_metadata_refcounts[66],
+ .data.refcounted = {g_bytes + 719, 13}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[14],
.data.refcounted = {g_bytes + 158, 12}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
- {{.refcount = &grpc_static_metadata_refcounts[66],
- .data.refcounted = {g_bytes + 695, 6}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[67],
- .data.refcounted = {g_bytes + 701, 4}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 732, 6}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[68],
- .data.refcounted = {g_bytes + 705, 4}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 738, 4}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[69],
- .data.refcounted = {g_bytes + 709, 6}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 742, 4}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[70],
- .data.refcounted = {g_bytes + 715, 7}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 746, 6}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[71],
- .data.refcounted = {g_bytes + 722, 4}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
- {{.refcount = &grpc_static_metadata_refcounts[17],
- .data.refcounted = {g_bytes + 210, 4}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 752, 7}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[72],
- .data.refcounted = {g_bytes + 726, 8}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 759, 4}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
+ {{.refcount = &grpc_static_metadata_refcounts[20],
+ .data.refcounted = {g_bytes + 278, 4}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[73],
- .data.refcounted = {g_bytes + 734, 17}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 763, 8}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[74],
- .data.refcounted = {g_bytes + 751, 13}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 771, 17}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[75],
- .data.refcounted = {g_bytes + 764, 8}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 788, 13}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[76],
- .data.refcounted = {g_bytes + 772, 19}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 801, 8}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[77],
- .data.refcounted = {g_bytes + 791, 13}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
- {{.refcount = &grpc_static_metadata_refcounts[18],
- .data.refcounted = {g_bytes + 214, 8}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 809, 19}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[78],
- .data.refcounted = {g_bytes + 804, 11}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 828, 13}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
+ {{.refcount = &grpc_static_metadata_refcounts[21],
+ .data.refcounted = {g_bytes + 282, 8}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[79],
- .data.refcounted = {g_bytes + 815, 4}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 841, 11}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[80],
- .data.refcounted = {g_bytes + 819, 8}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 852, 4}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[81],
- .data.refcounted = {g_bytes + 827, 12}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 856, 8}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[82],
- .data.refcounted = {g_bytes + 839, 18}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 864, 12}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[83],
- .data.refcounted = {g_bytes + 857, 19}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 876, 18}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[84],
- .data.refcounted = {g_bytes + 876, 5}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 894, 19}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[85],
- .data.refcounted = {g_bytes + 881, 7}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 913, 5}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[86],
- .data.refcounted = {g_bytes + 888, 7}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 918, 7}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[87],
- .data.refcounted = {g_bytes + 895, 11}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 925, 7}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[88],
- .data.refcounted = {g_bytes + 906, 6}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 932, 11}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[89],
- .data.refcounted = {g_bytes + 912, 10}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 943, 6}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[90],
- .data.refcounted = {g_bytes + 922, 25}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 949, 10}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[91],
- .data.refcounted = {g_bytes + 947, 17}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
- {{.refcount = &grpc_static_metadata_refcounts[16],
- .data.refcounted = {g_bytes + 200, 10}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 959, 25}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[92],
- .data.refcounted = {g_bytes + 964, 4}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 984, 17}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
+ {{.refcount = &grpc_static_metadata_refcounts[19],
+ .data.refcounted = {g_bytes + 268, 10}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[93],
- .data.refcounted = {g_bytes + 968, 3}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
+ .data.refcounted = {g_bytes + 1001, 4}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[94],
- .data.refcounted = {g_bytes + 971, 16}},
- {.refcount = &grpc_static_metadata_refcounts[20],
- .data.refcounted = {g_bytes + 234, 0}}},
- {{.refcount = &grpc_static_metadata_refcounts[10],
- .data.refcounted = {g_bytes + 90, 20}},
- {.refcount = &grpc_static_metadata_refcounts[29],
- .data.refcounted = {g_bytes + 365, 8}}},
+ .data.refcounted = {g_bytes + 1005, 3}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
+ {{.refcount = &grpc_static_metadata_refcounts[95],
+ .data.refcounted = {g_bytes + 1008, 16}},
+ {.refcount = &grpc_static_metadata_refcounts[23],
+ .data.refcounted = {g_bytes + 302, 0}}},
{{.refcount = &grpc_static_metadata_refcounts[10],
.data.refcounted = {g_bytes + 90, 20}},
- {.refcount = &grpc_static_metadata_refcounts[31],
- .data.refcounted = {g_bytes + 377, 7}}},
+ {.refcount = &grpc_static_metadata_refcounts[32],
+ .data.refcounted = {g_bytes + 433, 8}}},
{{.refcount = &grpc_static_metadata_refcounts[10],
.data.refcounted = {g_bytes + 90, 20}},
- {.refcount = &grpc_static_metadata_refcounts[95],
- .data.refcounted = {g_bytes + 987, 16}}},
+ {.refcount = &grpc_static_metadata_refcounts[34],
+ .data.refcounted = {g_bytes + 445, 7}}},
{{.refcount = &grpc_static_metadata_refcounts[10],
.data.refcounted = {g_bytes + 90, 20}},
- {.refcount = &grpc_static_metadata_refcounts[30],
- .data.refcounted = {g_bytes + 373, 4}}},
+ {.refcount = &grpc_static_metadata_refcounts[96],
+ .data.refcounted = {g_bytes + 1024, 16}}},
{{.refcount = &grpc_static_metadata_refcounts[10],
.data.refcounted = {g_bytes + 90, 20}},
- {.refcount = &grpc_static_metadata_refcounts[96],
- .data.refcounted = {g_bytes + 1003, 13}}},
+ {.refcount = &grpc_static_metadata_refcounts[33],
+ .data.refcounted = {g_bytes + 441, 4}}},
{{.refcount = &grpc_static_metadata_refcounts[10],
.data.refcounted = {g_bytes + 90, 20}},
{.refcount = &grpc_static_metadata_refcounts[97],
- .data.refcounted = {g_bytes + 1016, 12}}},
+ .data.refcounted = {g_bytes + 1040, 13}}},
{{.refcount = &grpc_static_metadata_refcounts[10],
.data.refcounted = {g_bytes + 90, 20}},
{.refcount = &grpc_static_metadata_refcounts[98],
- .data.refcounted = {g_bytes + 1028, 21}}},
+ .data.refcounted = {g_bytes + 1053, 12}}},
+ {{.refcount = &grpc_static_metadata_refcounts[10],
+ .data.refcounted = {g_bytes + 90, 20}},
+ {.refcount = &grpc_static_metadata_refcounts[99],
+ .data.refcounted = {g_bytes + 1065, 21}}},
+ {{.refcount = &grpc_static_metadata_refcounts[16],
+ .data.refcounted = {g_bytes + 186, 15}},
+ {.refcount = &grpc_static_metadata_refcounts[32],
+ .data.refcounted = {g_bytes + 433, 8}}},
+ {{.refcount = &grpc_static_metadata_refcounts[16],
+ .data.refcounted = {g_bytes + 186, 15}},
+ {.refcount = &grpc_static_metadata_refcounts[33],
+ .data.refcounted = {g_bytes + 441, 4}}},
+ {{.refcount = &grpc_static_metadata_refcounts[16],
+ .data.refcounted = {g_bytes + 186, 15}},
+ {.refcount = &grpc_static_metadata_refcounts[97],
+ .data.refcounted = {g_bytes + 1040, 13}}},
};
-const uint8_t grpc_static_accept_encoding_metadata[8] = {0, 74, 75, 76,
- 77, 78, 79, 80};
+const uint8_t grpc_static_accept_encoding_metadata[8] = {0, 76, 77, 78,
+ 79, 80, 81, 82};
+
+const uint8_t grpc_static_accept_stream_encoding_metadata[4] = {0, 83, 84, 85};
diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h
index baa86de142..93ab90dff8 100644
--- a/src/core/lib/transport/static_metadata.h
+++ b/src/core/lib/transport/static_metadata.h
@@ -29,7 +29,7 @@
#include "src/core/lib/transport/metadata.h"
-#define GRPC_STATIC_MDSTR_COUNT 99
+#define GRPC_STATIC_MDSTR_COUNT 100
extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT];
/* ":path" */
#define GRPC_MDSTR_PATH (grpc_static_slice_table[0])
@@ -61,178 +61,181 @@ extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT];
#define GRPC_MDSTR_GRPC_TRACE_BIN (grpc_static_slice_table[13])
/* "content-type" */
#define GRPC_MDSTR_CONTENT_TYPE (grpc_static_slice_table[14])
+/* "content-encoding" */
+#define GRPC_MDSTR_CONTENT_ENCODING (grpc_static_slice_table[15])
+/* "accept-encoding" */
+#define GRPC_MDSTR_ACCEPT_ENCODING (grpc_static_slice_table[16])
/* "grpc-internal-encoding-request" */
-#define GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST (grpc_static_slice_table[15])
+#define GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST (grpc_static_slice_table[17])
+/* "grpc-internal-stream-encoding-request" */
+#define GRPC_MDSTR_GRPC_INTERNAL_STREAM_ENCODING_REQUEST \
+ (grpc_static_slice_table[18])
/* "user-agent" */
-#define GRPC_MDSTR_USER_AGENT (grpc_static_slice_table[16])
+#define GRPC_MDSTR_USER_AGENT (grpc_static_slice_table[19])
/* "host" */
-#define GRPC_MDSTR_HOST (grpc_static_slice_table[17])
+#define GRPC_MDSTR_HOST (grpc_static_slice_table[20])
/* "lb-token" */
-#define GRPC_MDSTR_LB_TOKEN (grpc_static_slice_table[18])
+#define GRPC_MDSTR_LB_TOKEN (grpc_static_slice_table[21])
/* "grpc-timeout" */
-#define GRPC_MDSTR_GRPC_TIMEOUT (grpc_static_slice_table[19])
+#define GRPC_MDSTR_GRPC_TIMEOUT (grpc_static_slice_table[22])
/* "" */
-#define GRPC_MDSTR_EMPTY (grpc_static_slice_table[20])
+#define GRPC_MDSTR_EMPTY (grpc_static_slice_table[23])
/* "grpc.wait_for_ready" */
-#define GRPC_MDSTR_GRPC_DOT_WAIT_FOR_READY (grpc_static_slice_table[21])
+#define GRPC_MDSTR_GRPC_DOT_WAIT_FOR_READY (grpc_static_slice_table[24])
/* "grpc.timeout" */
-#define GRPC_MDSTR_GRPC_DOT_TIMEOUT (grpc_static_slice_table[22])
+#define GRPC_MDSTR_GRPC_DOT_TIMEOUT (grpc_static_slice_table[25])
/* "grpc.max_request_message_bytes" */
#define GRPC_MDSTR_GRPC_DOT_MAX_REQUEST_MESSAGE_BYTES \
- (grpc_static_slice_table[23])
+ (grpc_static_slice_table[26])
/* "grpc.max_response_message_bytes" */
#define GRPC_MDSTR_GRPC_DOT_MAX_RESPONSE_MESSAGE_BYTES \
- (grpc_static_slice_table[24])
+ (grpc_static_slice_table[27])
/* "/grpc.lb.v1.LoadBalancer/BalanceLoad" */
#define GRPC_MDSTR_SLASH_GRPC_DOT_LB_DOT_V1_DOT_LOADBALANCER_SLASH_BALANCELOAD \
- (grpc_static_slice_table[25])
+ (grpc_static_slice_table[28])
/* "0" */
-#define GRPC_MDSTR_0 (grpc_static_slice_table[26])
+#define GRPC_MDSTR_0 (grpc_static_slice_table[29])
/* "1" */
-#define GRPC_MDSTR_1 (grpc_static_slice_table[27])
+#define GRPC_MDSTR_1 (grpc_static_slice_table[30])
/* "2" */
-#define GRPC_MDSTR_2 (grpc_static_slice_table[28])
+#define GRPC_MDSTR_2 (grpc_static_slice_table[31])
/* "identity" */
-#define GRPC_MDSTR_IDENTITY (grpc_static_slice_table[29])
+#define GRPC_MDSTR_IDENTITY (grpc_static_slice_table[32])
/* "gzip" */
-#define GRPC_MDSTR_GZIP (grpc_static_slice_table[30])
+#define GRPC_MDSTR_GZIP (grpc_static_slice_table[33])
/* "deflate" */
-#define GRPC_MDSTR_DEFLATE (grpc_static_slice_table[31])
+#define GRPC_MDSTR_DEFLATE (grpc_static_slice_table[34])
/* "trailers" */
-#define GRPC_MDSTR_TRAILERS (grpc_static_slice_table[32])
+#define GRPC_MDSTR_TRAILERS (grpc_static_slice_table[35])
/* "application/grpc" */
-#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (grpc_static_slice_table[33])
+#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (grpc_static_slice_table[36])
/* "POST" */
-#define GRPC_MDSTR_POST (grpc_static_slice_table[34])
+#define GRPC_MDSTR_POST (grpc_static_slice_table[37])
/* "200" */
-#define GRPC_MDSTR_200 (grpc_static_slice_table[35])
+#define GRPC_MDSTR_200 (grpc_static_slice_table[38])
/* "404" */
-#define GRPC_MDSTR_404 (grpc_static_slice_table[36])
+#define GRPC_MDSTR_404 (grpc_static_slice_table[39])
/* "http" */
-#define GRPC_MDSTR_HTTP (grpc_static_slice_table[37])
+#define GRPC_MDSTR_HTTP (grpc_static_slice_table[40])
/* "https" */
-#define GRPC_MDSTR_HTTPS (grpc_static_slice_table[38])
+#define GRPC_MDSTR_HTTPS (grpc_static_slice_table[41])
/* "grpc" */
-#define GRPC_MDSTR_GRPC (grpc_static_slice_table[39])
+#define GRPC_MDSTR_GRPC (grpc_static_slice_table[42])
/* "GET" */
-#define GRPC_MDSTR_GET (grpc_static_slice_table[40])
+#define GRPC_MDSTR_GET (grpc_static_slice_table[43])
/* "PUT" */
-#define GRPC_MDSTR_PUT (grpc_static_slice_table[41])
+#define GRPC_MDSTR_PUT (grpc_static_slice_table[44])
/* "/" */
-#define GRPC_MDSTR_SLASH (grpc_static_slice_table[42])
+#define GRPC_MDSTR_SLASH (grpc_static_slice_table[45])
/* "/index.html" */
-#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (grpc_static_slice_table[43])
+#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (grpc_static_slice_table[46])
/* "204" */
-#define GRPC_MDSTR_204 (grpc_static_slice_table[44])
+#define GRPC_MDSTR_204 (grpc_static_slice_table[47])
/* "206" */
-#define GRPC_MDSTR_206 (grpc_static_slice_table[45])
+#define GRPC_MDSTR_206 (grpc_static_slice_table[48])
/* "304" */
-#define GRPC_MDSTR_304 (grpc_static_slice_table[46])
+#define GRPC_MDSTR_304 (grpc_static_slice_table[49])
/* "400" */
-#define GRPC_MDSTR_400 (grpc_static_slice_table[47])
+#define GRPC_MDSTR_400 (grpc_static_slice_table[50])
/* "500" */
-#define GRPC_MDSTR_500 (grpc_static_slice_table[48])
+#define GRPC_MDSTR_500 (grpc_static_slice_table[51])
/* "accept-charset" */
-#define GRPC_MDSTR_ACCEPT_CHARSET (grpc_static_slice_table[49])
-/* "accept-encoding" */
-#define GRPC_MDSTR_ACCEPT_ENCODING (grpc_static_slice_table[50])
+#define GRPC_MDSTR_ACCEPT_CHARSET (grpc_static_slice_table[52])
/* "gzip, deflate" */
-#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (grpc_static_slice_table[51])
+#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (grpc_static_slice_table[53])
/* "accept-language" */
-#define GRPC_MDSTR_ACCEPT_LANGUAGE (grpc_static_slice_table[52])
+#define GRPC_MDSTR_ACCEPT_LANGUAGE (grpc_static_slice_table[54])
/* "accept-ranges" */
-#define GRPC_MDSTR_ACCEPT_RANGES (grpc_static_slice_table[53])
+#define GRPC_MDSTR_ACCEPT_RANGES (grpc_static_slice_table[55])
/* "accept" */
-#define GRPC_MDSTR_ACCEPT (grpc_static_slice_table[54])
+#define GRPC_MDSTR_ACCEPT (grpc_static_slice_table[56])
/* "access-control-allow-origin" */
-#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (grpc_static_slice_table[55])
+#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (grpc_static_slice_table[57])
/* "age" */
-#define GRPC_MDSTR_AGE (grpc_static_slice_table[56])
+#define GRPC_MDSTR_AGE (grpc_static_slice_table[58])
/* "allow" */
-#define GRPC_MDSTR_ALLOW (grpc_static_slice_table[57])
+#define GRPC_MDSTR_ALLOW (grpc_static_slice_table[59])
/* "authorization" */
-#define GRPC_MDSTR_AUTHORIZATION (grpc_static_slice_table[58])
+#define GRPC_MDSTR_AUTHORIZATION (grpc_static_slice_table[60])
/* "cache-control" */
-#define GRPC_MDSTR_CACHE_CONTROL (grpc_static_slice_table[59])
+#define GRPC_MDSTR_CACHE_CONTROL (grpc_static_slice_table[61])
/* "content-disposition" */
-#define GRPC_MDSTR_CONTENT_DISPOSITION (grpc_static_slice_table[60])
-/* "content-encoding" */
-#define GRPC_MDSTR_CONTENT_ENCODING (grpc_static_slice_table[61])
+#define GRPC_MDSTR_CONTENT_DISPOSITION (grpc_static_slice_table[62])
/* "content-language" */
-#define GRPC_MDSTR_CONTENT_LANGUAGE (grpc_static_slice_table[62])
+#define GRPC_MDSTR_CONTENT_LANGUAGE (grpc_static_slice_table[63])
/* "content-length" */
-#define GRPC_MDSTR_CONTENT_LENGTH (grpc_static_slice_table[63])
+#define GRPC_MDSTR_CONTENT_LENGTH (grpc_static_slice_table[64])
/* "content-location" */
-#define GRPC_MDSTR_CONTENT_LOCATION (grpc_static_slice_table[64])
+#define GRPC_MDSTR_CONTENT_LOCATION (grpc_static_slice_table[65])
/* "content-range" */
-#define GRPC_MDSTR_CONTENT_RANGE (grpc_static_slice_table[65])
+#define GRPC_MDSTR_CONTENT_RANGE (grpc_static_slice_table[66])
/* "cookie" */
-#define GRPC_MDSTR_COOKIE (grpc_static_slice_table[66])
+#define GRPC_MDSTR_COOKIE (grpc_static_slice_table[67])
/* "date" */
-#define GRPC_MDSTR_DATE (grpc_static_slice_table[67])
+#define GRPC_MDSTR_DATE (grpc_static_slice_table[68])
/* "etag" */
-#define GRPC_MDSTR_ETAG (grpc_static_slice_table[68])
+#define GRPC_MDSTR_ETAG (grpc_static_slice_table[69])
/* "expect" */
-#define GRPC_MDSTR_EXPECT (grpc_static_slice_table[69])
+#define GRPC_MDSTR_EXPECT (grpc_static_slice_table[70])
/* "expires" */
-#define GRPC_MDSTR_EXPIRES (grpc_static_slice_table[70])
+#define GRPC_MDSTR_EXPIRES (grpc_static_slice_table[71])
/* "from" */
-#define GRPC_MDSTR_FROM (grpc_static_slice_table[71])
+#define GRPC_MDSTR_FROM (grpc_static_slice_table[72])
/* "if-match" */
-#define GRPC_MDSTR_IF_MATCH (grpc_static_slice_table[72])
+#define GRPC_MDSTR_IF_MATCH (grpc_static_slice_table[73])
/* "if-modified-since" */
-#define GRPC_MDSTR_IF_MODIFIED_SINCE (grpc_static_slice_table[73])
+#define GRPC_MDSTR_IF_MODIFIED_SINCE (grpc_static_slice_table[74])
/* "if-none-match" */
-#define GRPC_MDSTR_IF_NONE_MATCH (grpc_static_slice_table[74])
+#define GRPC_MDSTR_IF_NONE_MATCH (grpc_static_slice_table[75])
/* "if-range" */
-#define GRPC_MDSTR_IF_RANGE (grpc_static_slice_table[75])
+#define GRPC_MDSTR_IF_RANGE (grpc_static_slice_table[76])
/* "if-unmodified-since" */
-#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (grpc_static_slice_table[76])
+#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (grpc_static_slice_table[77])
/* "last-modified" */
-#define GRPC_MDSTR_LAST_MODIFIED (grpc_static_slice_table[77])
+#define GRPC_MDSTR_LAST_MODIFIED (grpc_static_slice_table[78])
/* "lb-cost-bin" */
-#define GRPC_MDSTR_LB_COST_BIN (grpc_static_slice_table[78])
+#define GRPC_MDSTR_LB_COST_BIN (grpc_static_slice_table[79])
/* "link" */
-#define GRPC_MDSTR_LINK (grpc_static_slice_table[79])
+#define GRPC_MDSTR_LINK (grpc_static_slice_table[80])
/* "location" */
-#define GRPC_MDSTR_LOCATION (grpc_static_slice_table[80])
+#define GRPC_MDSTR_LOCATION (grpc_static_slice_table[81])
/* "max-forwards" */
-#define GRPC_MDSTR_MAX_FORWARDS (grpc_static_slice_table[81])
+#define GRPC_MDSTR_MAX_FORWARDS (grpc_static_slice_table[82])
/* "proxy-authenticate" */
-#define GRPC_MDSTR_PROXY_AUTHENTICATE (grpc_static_slice_table[82])
+#define GRPC_MDSTR_PROXY_AUTHENTICATE (grpc_static_slice_table[83])
/* "proxy-authorization" */
-#define GRPC_MDSTR_PROXY_AUTHORIZATION (grpc_static_slice_table[83])
+#define GRPC_MDSTR_PROXY_AUTHORIZATION (grpc_static_slice_table[84])
/* "range" */
-#define GRPC_MDSTR_RANGE (grpc_static_slice_table[84])
+#define GRPC_MDSTR_RANGE (grpc_static_slice_table[85])
/* "referer" */
-#define GRPC_MDSTR_REFERER (grpc_static_slice_table[85])
+#define GRPC_MDSTR_REFERER (grpc_static_slice_table[86])
/* "refresh" */
-#define GRPC_MDSTR_REFRESH (grpc_static_slice_table[86])
+#define GRPC_MDSTR_REFRESH (grpc_static_slice_table[87])
/* "retry-after" */
-#define GRPC_MDSTR_RETRY_AFTER (grpc_static_slice_table[87])
+#define GRPC_MDSTR_RETRY_AFTER (grpc_static_slice_table[88])
/* "server" */
-#define GRPC_MDSTR_SERVER (grpc_static_slice_table[88])
+#define GRPC_MDSTR_SERVER (grpc_static_slice_table[89])
/* "set-cookie" */
-#define GRPC_MDSTR_SET_COOKIE (grpc_static_slice_table[89])
+#define GRPC_MDSTR_SET_COOKIE (grpc_static_slice_table[90])
/* "strict-transport-security" */
-#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (grpc_static_slice_table[90])
+#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (grpc_static_slice_table[91])
/* "transfer-encoding" */
-#define GRPC_MDSTR_TRANSFER_ENCODING (grpc_static_slice_table[91])
+#define GRPC_MDSTR_TRANSFER_ENCODING (grpc_static_slice_table[92])
/* "vary" */
-#define GRPC_MDSTR_VARY (grpc_static_slice_table[92])
+#define GRPC_MDSTR_VARY (grpc_static_slice_table[93])
/* "via" */
-#define GRPC_MDSTR_VIA (grpc_static_slice_table[93])
+#define GRPC_MDSTR_VIA (grpc_static_slice_table[94])
/* "www-authenticate" */
-#define GRPC_MDSTR_WWW_AUTHENTICATE (grpc_static_slice_table[94])
+#define GRPC_MDSTR_WWW_AUTHENTICATE (grpc_static_slice_table[95])
/* "identity,deflate" */
-#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (grpc_static_slice_table[95])
+#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (grpc_static_slice_table[96])
/* "identity,gzip" */
-#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (grpc_static_slice_table[96])
+#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (grpc_static_slice_table[97])
/* "deflate,gzip" */
-#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (grpc_static_slice_table[97])
+#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (grpc_static_slice_table[98])
/* "identity,deflate,gzip" */
#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \
- (grpc_static_slice_table[98])
+ (grpc_static_slice_table[99])
extern const grpc_slice_refcount_vtable grpc_static_metadata_vtable;
extern grpc_slice_refcount
@@ -244,7 +247,7 @@ extern grpc_slice_refcount
#define GRPC_STATIC_METADATA_INDEX(static_slice) \
((int)((static_slice).refcount - grpc_static_metadata_refcounts))
-#define GRPC_STATIC_MDELEM_COUNT 81
+#define GRPC_STATIC_MDELEM_COUNT 86
extern grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];
extern uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT];
/* "grpc-status": "0" */
@@ -355,141 +358,156 @@ extern uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT];
/* "content-disposition": "" */
#define GRPC_MDELEM_CONTENT_DISPOSITION_EMPTY \
(GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[35], GRPC_MDELEM_STORAGE_STATIC))
+/* "content-encoding": "identity" */
+#define GRPC_MDELEM_CONTENT_ENCODING_IDENTITY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[36], GRPC_MDELEM_STORAGE_STATIC))
+/* "content-encoding": "gzip" */
+#define GRPC_MDELEM_CONTENT_ENCODING_GZIP \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[37], GRPC_MDELEM_STORAGE_STATIC))
/* "content-encoding": "" */
#define GRPC_MDELEM_CONTENT_ENCODING_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[36], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[38], GRPC_MDELEM_STORAGE_STATIC))
/* "content-language": "" */
#define GRPC_MDELEM_CONTENT_LANGUAGE_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[37], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[39], GRPC_MDELEM_STORAGE_STATIC))
/* "content-length": "" */
#define GRPC_MDELEM_CONTENT_LENGTH_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[38], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[40], GRPC_MDELEM_STORAGE_STATIC))
/* "content-location": "" */
#define GRPC_MDELEM_CONTENT_LOCATION_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[39], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[41], GRPC_MDELEM_STORAGE_STATIC))
/* "content-range": "" */
#define GRPC_MDELEM_CONTENT_RANGE_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[40], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[42], GRPC_MDELEM_STORAGE_STATIC))
/* "content-type": "" */
#define GRPC_MDELEM_CONTENT_TYPE_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[41], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[43], GRPC_MDELEM_STORAGE_STATIC))
/* "cookie": "" */
#define GRPC_MDELEM_COOKIE_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[42], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[44], GRPC_MDELEM_STORAGE_STATIC))
/* "date": "" */
#define GRPC_MDELEM_DATE_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[43], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[45], GRPC_MDELEM_STORAGE_STATIC))
/* "etag": "" */
#define GRPC_MDELEM_ETAG_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[44], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[46], GRPC_MDELEM_STORAGE_STATIC))
/* "expect": "" */
#define GRPC_MDELEM_EXPECT_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[45], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[47], GRPC_MDELEM_STORAGE_STATIC))
/* "expires": "" */
#define GRPC_MDELEM_EXPIRES_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[46], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[48], GRPC_MDELEM_STORAGE_STATIC))
/* "from": "" */
#define GRPC_MDELEM_FROM_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[47], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[49], GRPC_MDELEM_STORAGE_STATIC))
/* "host": "" */
#define GRPC_MDELEM_HOST_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[48], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[50], GRPC_MDELEM_STORAGE_STATIC))
/* "if-match": "" */
#define GRPC_MDELEM_IF_MATCH_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[49], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[51], GRPC_MDELEM_STORAGE_STATIC))
/* "if-modified-since": "" */
#define GRPC_MDELEM_IF_MODIFIED_SINCE_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[50], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[52], GRPC_MDELEM_STORAGE_STATIC))
/* "if-none-match": "" */
#define GRPC_MDELEM_IF_NONE_MATCH_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[51], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[53], GRPC_MDELEM_STORAGE_STATIC))
/* "if-range": "" */
#define GRPC_MDELEM_IF_RANGE_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[52], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[54], GRPC_MDELEM_STORAGE_STATIC))
/* "if-unmodified-since": "" */
#define GRPC_MDELEM_IF_UNMODIFIED_SINCE_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[53], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[55], GRPC_MDELEM_STORAGE_STATIC))
/* "last-modified": "" */
#define GRPC_MDELEM_LAST_MODIFIED_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[54], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[56], GRPC_MDELEM_STORAGE_STATIC))
/* "lb-token": "" */
#define GRPC_MDELEM_LB_TOKEN_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[55], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[57], GRPC_MDELEM_STORAGE_STATIC))
/* "lb-cost-bin": "" */
#define GRPC_MDELEM_LB_COST_BIN_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[56], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[58], GRPC_MDELEM_STORAGE_STATIC))
/* "link": "" */
#define GRPC_MDELEM_LINK_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[57], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[59], GRPC_MDELEM_STORAGE_STATIC))
/* "location": "" */
#define GRPC_MDELEM_LOCATION_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[58], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[60], GRPC_MDELEM_STORAGE_STATIC))
/* "max-forwards": "" */
#define GRPC_MDELEM_MAX_FORWARDS_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[59], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[61], GRPC_MDELEM_STORAGE_STATIC))
/* "proxy-authenticate": "" */
#define GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[60], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[62], GRPC_MDELEM_STORAGE_STATIC))
/* "proxy-authorization": "" */
#define GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[61], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[63], GRPC_MDELEM_STORAGE_STATIC))
/* "range": "" */
#define GRPC_MDELEM_RANGE_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[62], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[64], GRPC_MDELEM_STORAGE_STATIC))
/* "referer": "" */
#define GRPC_MDELEM_REFERER_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[63], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[65], GRPC_MDELEM_STORAGE_STATIC))
/* "refresh": "" */
#define GRPC_MDELEM_REFRESH_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[64], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[66], GRPC_MDELEM_STORAGE_STATIC))
/* "retry-after": "" */
#define GRPC_MDELEM_RETRY_AFTER_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[65], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[67], GRPC_MDELEM_STORAGE_STATIC))
/* "server": "" */
#define GRPC_MDELEM_SERVER_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[66], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[68], GRPC_MDELEM_STORAGE_STATIC))
/* "set-cookie": "" */
#define GRPC_MDELEM_SET_COOKIE_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[67], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[69], GRPC_MDELEM_STORAGE_STATIC))
/* "strict-transport-security": "" */
#define GRPC_MDELEM_STRICT_TRANSPORT_SECURITY_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[68], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[70], GRPC_MDELEM_STORAGE_STATIC))
/* "transfer-encoding": "" */
#define GRPC_MDELEM_TRANSFER_ENCODING_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[69], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[71], GRPC_MDELEM_STORAGE_STATIC))
/* "user-agent": "" */
#define GRPC_MDELEM_USER_AGENT_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[70], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[72], GRPC_MDELEM_STORAGE_STATIC))
/* "vary": "" */
#define GRPC_MDELEM_VARY_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[71], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[73], GRPC_MDELEM_STORAGE_STATIC))
/* "via": "" */
#define GRPC_MDELEM_VIA_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[72], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[74], GRPC_MDELEM_STORAGE_STATIC))
/* "www-authenticate": "" */
#define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[73], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[75], GRPC_MDELEM_STORAGE_STATIC))
/* "grpc-accept-encoding": "identity" */
#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[74], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[76], GRPC_MDELEM_STORAGE_STATIC))
/* "grpc-accept-encoding": "deflate" */
#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[75], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[77], GRPC_MDELEM_STORAGE_STATIC))
/* "grpc-accept-encoding": "identity,deflate" */
#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[76], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[78], GRPC_MDELEM_STORAGE_STATIC))
/* "grpc-accept-encoding": "gzip" */
#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_GZIP \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[77], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[79], GRPC_MDELEM_STORAGE_STATIC))
/* "grpc-accept-encoding": "identity,gzip" */
#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[78], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[80], GRPC_MDELEM_STORAGE_STATIC))
/* "grpc-accept-encoding": "deflate,gzip" */
#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE_COMMA_GZIP \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[79], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[81], GRPC_MDELEM_STORAGE_STATIC))
/* "grpc-accept-encoding": "identity,deflate,gzip" */
#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \
- (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[80], GRPC_MDELEM_STORAGE_STATIC))
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[82], GRPC_MDELEM_STORAGE_STATIC))
+/* "accept-encoding": "identity" */
+#define GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[83], GRPC_MDELEM_STORAGE_STATIC))
+/* "accept-encoding": "gzip" */
+#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[84], GRPC_MDELEM_STORAGE_STATIC))
+/* "accept-encoding": "identity,gzip" */
+#define GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[85], GRPC_MDELEM_STORAGE_STATIC))
grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b);
typedef enum {
@@ -508,7 +526,10 @@ typedef enum {
GRPC_BATCH_GRPC_TAGS_BIN,
GRPC_BATCH_GRPC_TRACE_BIN,
GRPC_BATCH_CONTENT_TYPE,
+ GRPC_BATCH_CONTENT_ENCODING,
+ GRPC_BATCH_ACCEPT_ENCODING,
GRPC_BATCH_GRPC_INTERNAL_ENCODING_REQUEST,
+ GRPC_BATCH_GRPC_INTERNAL_STREAM_ENCODING_REQUEST,
GRPC_BATCH_USER_AGENT,
GRPC_BATCH_HOST,
GRPC_BATCH_LB_TOKEN,
@@ -533,7 +554,10 @@ typedef union {
struct grpc_linked_mdelem *grpc_tags_bin;
struct grpc_linked_mdelem *grpc_trace_bin;
struct grpc_linked_mdelem *content_type;
+ struct grpc_linked_mdelem *content_encoding;
+ struct grpc_linked_mdelem *accept_encoding;
struct grpc_linked_mdelem *grpc_internal_encoding_request;
+ struct grpc_linked_mdelem *grpc_internal_stream_encoding_request;
struct grpc_linked_mdelem *user_agent;
struct grpc_linked_mdelem *host;
struct grpc_linked_mdelem *lb_token;
@@ -552,4 +576,10 @@ extern const uint8_t grpc_static_accept_encoding_metadata[8];
(GRPC_MAKE_MDELEM( \
&grpc_static_mdelem_table[grpc_static_accept_encoding_metadata[(algs)]], \
GRPC_MDELEM_STORAGE_STATIC))
+
+extern const uint8_t grpc_static_accept_stream_encoding_metadata[4];
+#define GRPC_MDELEM_ACCEPT_STREAM_ENCODING_FOR_ALGORITHMS(algs) \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table \
+ [grpc_static_accept_stream_encoding_metadata[(algs)]], \
+ GRPC_MDELEM_STORAGE_STATIC))
#endif /* GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H */
diff --git a/src/cpp/common/channel_filter.cc b/src/cpp/common/channel_filter.cc
index f870af0c67..448d9fbcf2 100644
--- a/src/cpp/common/channel_filter.cc
+++ b/src/cpp/common/channel_filter.cc
@@ -18,7 +18,9 @@
#include <string.h>
+extern "C" {
#include "src/core/lib/channel/channel_stack.h"
+}
#include "src/cpp/common/channel_filter.h"
#include <grpc++/impl/codegen/slice.h>
diff --git a/src/cpp/common/channel_filter.h b/src/cpp/common/channel_filter.h
index 5d629f7c14..4b37c202f9 100644
--- a/src/cpp/common/channel_filter.h
+++ b/src/cpp/common/channel_filter.h
@@ -26,9 +26,11 @@
#include <functional>
#include <vector>
+extern "C" {
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/surface/channel_init.h"
#include "src/core/lib/transport/metadata_batch.h"
+}
/// An interface to define filters.
///
diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc
index 34558ea216..2e9a51316d 100644
--- a/src/cpp/common/version_cc.cc
+++ b/src/cpp/common/version_cc.cc
@@ -22,5 +22,5 @@
#include <grpc++/grpc++.h>
namespace grpc {
-grpc::string Version() { return "1.5.0-dev"; }
+grpc::string Version() { return "1.7.0-dev"; }
}
diff --git a/src/csharp/Grpc.Core.Tests/NUnitMain.cs b/src/csharp/Grpc.Core.Tests/NUnitMain.cs
index 87972e23ad..49cb8cd3b9 100644
--- a/src/csharp/Grpc.Core.Tests/NUnitMain.cs
+++ b/src/csharp/Grpc.Core.Tests/NUnitMain.cs
@@ -33,7 +33,7 @@ namespace Grpc.Core.Tests
public static int Main(string[] args)
{
// Make logger immune to NUnit capturing stdout and stderr to workaround https://github.com/nunit/nunit/issues/1406.
- GrpcEnvironment.SetLogger(new TextWriterLogger(Console.Error));
+ GrpcEnvironment.SetLogger(new ConsoleLogger());
#if NETCOREAPP1_0
return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In);
#else
diff --git a/src/csharp/Grpc.Core/Grpc.Core.targets b/src/csharp/Grpc.Core/Grpc.Core.targets
index 3367d51a80..cce53db82b 100644
--- a/src/csharp/Grpc.Core/Grpc.Core.targets
+++ b/src/csharp/Grpc.Core/Grpc.Core.targets
@@ -4,26 +4,32 @@
<Content Include="$(MSBuildThisFileDirectory)..\..\runtimes\win\native\grpc_csharp_ext.x86.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Link>grpc_csharp_ext.x86.dll</Link>
+ <Visible>false</Visible>
</Content>
<Content Include="$(MSBuildThisFileDirectory)..\..\runtimes\win\native\grpc_csharp_ext.x64.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Link>grpc_csharp_ext.x64.dll</Link>
+ <Visible>false</Visible>
</Content>
<Content Include="$(MSBuildThisFileDirectory)..\..\runtimes\linux\native\libgrpc_csharp_ext.x86.so">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Link>libgrpc_csharp_ext.x86.so</Link>
+ <Visible>false</Visible>
</Content>
<Content Include="$(MSBuildThisFileDirectory)..\..\runtimes\linux\native\libgrpc_csharp_ext.x64.so">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Link>libgrpc_csharp_ext.x64.so</Link>
+ <Visible>false</Visible>
</Content>
<Content Include="$(MSBuildThisFileDirectory)..\..\runtimes\osx\native\libgrpc_csharp_ext.x86.dylib">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Link>libgrpc_csharp_ext.x86.dylib</Link>
+ <Visible>false</Visible>
</Content>
<Content Include="$(MSBuildThisFileDirectory)..\..\runtimes\osx\native\libgrpc_csharp_ext.x64.dylib">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Link>libgrpc_csharp_ext.x64.dylib</Link>
+ <Visible>false</Visible>
</Content>
</ItemGroup>
-</Project> \ No newline at end of file
+</Project>
diff --git a/src/csharp/Grpc.Core/GrpcEnvironment.cs b/src/csharp/Grpc.Core/GrpcEnvironment.cs
index cbc7d2078c..80031cb7ef 100644
--- a/src/csharp/Grpc.Core/GrpcEnvironment.cs
+++ b/src/csharp/Grpc.Core/GrpcEnvironment.cs
@@ -43,7 +43,7 @@ namespace Grpc.Core
static readonly HashSet<Channel> registeredChannels = new HashSet<Channel>();
static readonly HashSet<Server> registeredServers = new HashSet<Server>();
- static ILogger logger = new NullLogger();
+ static ILogger logger = new LogLevelFilterLogger(new ConsoleLogger(), LogLevel.Off, true);
readonly GrpcThreadPool threadPool;
readonly DebugStats debugStats = new DebugStats();
diff --git a/src/csharp/Grpc.Core/Internal/AtomicCounter.cs b/src/csharp/Grpc.Core/Internal/AtomicCounter.cs
index 64e16e4c54..20e25f9d88 100644
--- a/src/csharp/Grpc.Core/Internal/AtomicCounter.cs
+++ b/src/csharp/Grpc.Core/Internal/AtomicCounter.cs
@@ -64,7 +64,7 @@ namespace Grpc.Core.Internal
{
get
{
- return counter;
+ return Interlocked.Read(ref counter);
}
}
}
diff --git a/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs b/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs
index 19b44c2618..3c94b602c0 100644
--- a/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs
+++ b/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs
@@ -33,8 +33,8 @@ namespace Grpc.Core.Internal
internal class GrpcThreadPool
{
static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<GrpcThreadPool>();
- static readonly WaitCallback RunCompletionQueueEventCallbackSuccess = new WaitCallback((callback) => RunCompletionQueueEventCallback((OpCompletionDelegate) callback, true));
- static readonly WaitCallback RunCompletionQueueEventCallbackFailure = new WaitCallback((callback) => RunCompletionQueueEventCallback((OpCompletionDelegate) callback, false));
+ const int FinishContinuationsSleepMillis = 10;
+ const int MaxFinishContinuationsSleepTotalMillis = 10000;
readonly GrpcEnvironment environment;
readonly object myLock = new object();
@@ -42,6 +42,9 @@ namespace Grpc.Core.Internal
readonly int poolSize;
readonly int completionQueueCount;
readonly bool inlineHandlers;
+ readonly WaitCallback runCompletionQueueEventCallbackSuccess;
+ readonly WaitCallback runCompletionQueueEventCallbackFailure;
+ readonly AtomicCounter queuedContinuationCounter = new AtomicCounter();
readonly List<BasicProfiler> threadProfilers = new List<BasicProfiler>(); // profilers assigned to threadpool threads
@@ -64,6 +67,9 @@ namespace Grpc.Core.Internal
this.inlineHandlers = inlineHandlers;
GrpcPreconditions.CheckArgument(poolSize >= completionQueueCount,
"Thread pool size cannot be smaller than the number of completion queues used.");
+
+ this.runCompletionQueueEventCallbackSuccess = new WaitCallback((callback) => RunCompletionQueueEventCallback((OpCompletionDelegate) callback, true));
+ this.runCompletionQueueEventCallbackFailure = new WaitCallback((callback) => RunCompletionQueueEventCallback((OpCompletionDelegate) callback, false));
}
public void Start()
@@ -173,7 +179,8 @@ namespace Grpc.Core.Internal
// Use cached delegates to avoid unnecessary allocations
if (!inlineHandlers)
{
- ThreadPool.QueueUserWorkItem(success ? RunCompletionQueueEventCallbackSuccess : RunCompletionQueueEventCallbackFailure, callback);
+ queuedContinuationCounter.Increment();
+ ThreadPool.QueueUserWorkItem(success ? runCompletionQueueEventCallbackSuccess : runCompletionQueueEventCallbackFailure, callback);
}
else
{
@@ -187,6 +194,24 @@ namespace Grpc.Core.Internal
}
}
while (ev.type != CompletionQueueEvent.CompletionType.Shutdown);
+
+ // Continuations are running on default threadpool that consists of background threads.
+ // GrpcThreadPool thread (a foreground thread) will not exit unless all queued work had
+ // been finished to prevent terminating the continuations queued prematurely.
+ int sleepIterations = 0;
+ while (queuedContinuationCounter.Count != 0)
+ {
+ // Only happens on shutdown and having pending continuations shouldn't very common,
+ // so sleeping here for a little bit is fine.
+ if (sleepIterations >= MaxFinishContinuationsSleepTotalMillis / FinishContinuationsSleepMillis)
+ {
+ Logger.Warning("Shutting down gRPC thread [{0}] with unfinished callbacks (Timed out waiting for callbacks to finish).",
+ Thread.CurrentThread.Name);
+ break;
+ }
+ Thread.Sleep(FinishContinuationsSleepMillis);
+ sleepIterations ++;
+ }
}
private static IReadOnlyCollection<CompletionQueueSafeHandle> CreateCompletionQueueList(GrpcEnvironment environment, int completionQueueCount)
@@ -200,7 +225,7 @@ namespace Grpc.Core.Internal
return list.AsReadOnly();
}
- private static void RunCompletionQueueEventCallback(OpCompletionDelegate callback, bool success)
+ private void RunCompletionQueueEventCallback(OpCompletionDelegate callback, bool success)
{
try
{
@@ -210,6 +235,10 @@ namespace Grpc.Core.Internal
{
Logger.Error(e, "Exception occured while invoking completion delegate");
}
+ finally
+ {
+ queuedContinuationCounter.Decrement();
+ }
}
}
}
diff --git a/src/csharp/Grpc.Core/Logging/LogLevel.cs b/src/csharp/Grpc.Core/Logging/LogLevel.cs
index 7718e3c2ab..4db0e47b97 100644
--- a/src/csharp/Grpc.Core/Logging/LogLevel.cs
+++ b/src/csharp/Grpc.Core/Logging/LogLevel.cs
@@ -39,6 +39,10 @@ namespace Grpc.Core.Logging
/// <summary>
/// Error severity.
/// </summary>
- Error
+ Error,
+ /// <summary>
+ /// Logging is off.
+ /// </summary>
+ Off = int.MaxValue
}
}
diff --git a/src/csharp/Grpc.Core/Logging/LogLevelFilterLogger.cs b/src/csharp/Grpc.Core/Logging/LogLevelFilterLogger.cs
index b611c191a5..a650d029d7 100644
--- a/src/csharp/Grpc.Core/Logging/LogLevelFilterLogger.cs
+++ b/src/csharp/Grpc.Core/Logging/LogLevelFilterLogger.cs
@@ -27,6 +27,8 @@ namespace Grpc.Core.Logging
/// <summary>Logger that filters out messages below certain log level.</summary>
public class LogLevelFilterLogger : ILogger
{
+ // Verbosity environment variable used by C core.
+ private const string CoreVerbosityEnvVarName = "GRPC_VERBOSITY";
readonly ILogger innerLogger;
readonly LogLevel logLevel;
@@ -40,6 +42,19 @@ namespace Grpc.Core.Logging
}
/// <summary>
+ /// Creates and instance of <c>LogLevelFilter.</c>
+ /// The <c>fromEnvironmentVariable</c> parameter allows looking up "GRPC_VERBOSITY" setting provided by C-core
+ /// and uses the same log level for C# logs. Using this setting is recommended as it can prevent unintentionally hiding
+ /// C core logs requested by "GRPC_VERBOSITY" environment variable (which could happen if C# logger's log level was set to a more restrictive value).
+ /// </summary>
+ /// <param name="logger">the logger to forward filtered logs to.</param>
+ /// <param name="defaultLogLevel">the default log level, unless overriden by env variable.</param>
+ /// <param name="fromEnvironmentVariable">if <c>true</c>, override log level with setting from environment variable.</param>
+ public LogLevelFilterLogger(ILogger logger, LogLevel defaultLogLevel, bool fromEnvironmentVariable) : this(logger, GetLogLevelFromEnvironment(defaultLogLevel, fromEnvironmentVariable))
+ {
+ }
+
+ /// <summary>
/// Returns a logger associated with the specified type.
/// </summary>
public virtual ILogger ForType<T>()
@@ -141,5 +156,33 @@ namespace Grpc.Core.Logging
innerLogger.Error(exception, message);
}
}
+
+ /// <summary>Get log level based on a default and lookup of <c>GRPC_VERBOSITY</c> environment variable.</summary>
+ private static LogLevel GetLogLevelFromEnvironment(LogLevel defaultLogLevel, bool fromEnvironmentVariable)
+ {
+ if (!fromEnvironmentVariable)
+ {
+ return defaultLogLevel;
+ }
+
+ var verbosityString = System.Environment.GetEnvironmentVariable(CoreVerbosityEnvVarName);
+ if (verbosityString == null)
+ {
+ return defaultLogLevel;
+ }
+
+ // NOTE: C core doesn't have "WARNING" log level
+ switch (verbosityString.ToUpperInvariant())
+ {
+ case "DEBUG":
+ return LogLevel.Debug;
+ case "INFO":
+ return LogLevel.Info;
+ case "ERROR":
+ return LogLevel.Error;
+ default:
+ return defaultLogLevel;
+ }
+ }
}
}
diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include
index 81156452f3..124ecab14c 100755
--- a/src/csharp/Grpc.Core/Version.csproj.include
+++ b/src/csharp/Grpc.Core/Version.csproj.include
@@ -1,7 +1,7 @@
<!-- This file is generated -->
<Project>
<PropertyGroup>
- <GrpcCsharpVersion>1.5.0-dev</GrpcCsharpVersion>
+ <GrpcCsharpVersion>1.7.0-dev</GrpcCsharpVersion>
<GoogleProtobufVersion>3.3.0</GoogleProtobufVersion>
</PropertyGroup>
</Project>
diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs
index 92aa0e5aed..588cc84516 100644
--- a/src/csharp/Grpc.Core/VersionInfo.cs
+++ b/src/csharp/Grpc.Core/VersionInfo.cs
@@ -33,11 +33,11 @@ namespace Grpc.Core
/// <summary>
/// Current <c>AssemblyFileVersion</c> of gRPC C# assemblies
/// </summary>
- public const string CurrentAssemblyFileVersion = "1.5.0.0";
+ public const string CurrentAssemblyFileVersion = "1.7.0.0";
/// <summary>
/// Current version of gRPC C#
/// </summary>
- public const string CurrentVersion = "1.5.0-dev";
+ public const string CurrentVersion = "1.7.0-dev";
}
}
diff --git a/src/csharp/Grpc.Examples.Tests/NUnitMain.cs b/src/csharp/Grpc.Examples.Tests/NUnitMain.cs
index a83caea206..bcb8b46b64 100644
--- a/src/csharp/Grpc.Examples.Tests/NUnitMain.cs
+++ b/src/csharp/Grpc.Examples.Tests/NUnitMain.cs
@@ -33,7 +33,7 @@ namespace Grpc.Examples.Tests
public static int Main(string[] args)
{
// Make logger immune to NUnit capturing stdout and stderr to workaround https://github.com/nunit/nunit/issues/1406.
- GrpcEnvironment.SetLogger(new TextWriterLogger(Console.Error));
+ GrpcEnvironment.SetLogger(new ConsoleLogger());
#if NETCOREAPP1_0
return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In);
#else
diff --git a/src/csharp/Grpc.HealthCheck.Tests/NUnitMain.cs b/src/csharp/Grpc.HealthCheck.Tests/NUnitMain.cs
index 57deb3ba30..365551e895 100644
--- a/src/csharp/Grpc.HealthCheck.Tests/NUnitMain.cs
+++ b/src/csharp/Grpc.HealthCheck.Tests/NUnitMain.cs
@@ -33,7 +33,7 @@ namespace Grpc.HealthCheck.Tests
public static int Main(string[] args)
{
// Make logger immune to NUnit capturing stdout and stderr to workaround https://github.com/nunit/nunit/issues/1406.
- GrpcEnvironment.SetLogger(new TextWriterLogger(Console.Error));
+ GrpcEnvironment.SetLogger(new ConsoleLogger());
#if NETCOREAPP1_0
return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In);
#else
diff --git a/src/csharp/Grpc.IntegrationTesting/NUnitMain.cs b/src/csharp/Grpc.IntegrationTesting/NUnitMain.cs
index a36802af55..9d24762e0a 100644
--- a/src/csharp/Grpc.IntegrationTesting/NUnitMain.cs
+++ b/src/csharp/Grpc.IntegrationTesting/NUnitMain.cs
@@ -33,7 +33,7 @@ namespace Grpc.IntegrationTesting
public static int Main(string[] args)
{
// Make logger immune to NUnit capturing stdout and stderr to workaround https://github.com/nunit/nunit/issues/1406.
- GrpcEnvironment.SetLogger(new TextWriterLogger(Console.Error));
+ GrpcEnvironment.SetLogger(new ConsoleLogger());
#if NETCOREAPP1_0
return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In);
#else
diff --git a/src/csharp/Grpc.Microbenchmarks/Program.cs b/src/csharp/Grpc.Microbenchmarks/Program.cs
index 8412ba3245..d07d4187c4 100644
--- a/src/csharp/Grpc.Microbenchmarks/Program.cs
+++ b/src/csharp/Grpc.Microbenchmarks/Program.cs
@@ -27,7 +27,7 @@ namespace Grpc.Microbenchmarks
{
public static void Main(string[] args)
{
- GrpcEnvironment.SetLogger(new TextWriterLogger(Console.Error));
+ GrpcEnvironment.SetLogger(new ConsoleLogger());
var benchmark = new SendMessageBenchmark();
benchmark.Init();
foreach (int threadCount in new int[] {1, 1, 2, 4, 8, 12})
diff --git a/src/csharp/Grpc.Reflection.Tests/NUnitMain.cs b/src/csharp/Grpc.Reflection.Tests/NUnitMain.cs
index a45dab8772..49ed1cc8d4 100644
--- a/src/csharp/Grpc.Reflection.Tests/NUnitMain.cs
+++ b/src/csharp/Grpc.Reflection.Tests/NUnitMain.cs
@@ -33,7 +33,7 @@ namespace Grpc.Reflection.Tests
public static int Main(string[] args)
{
// Make logger immune to NUnit capturing stdout and stderr to workaround https://github.com/nunit/nunit/issues/1406.
- GrpcEnvironment.SetLogger(new TextWriterLogger(Console.Error));
+ GrpcEnvironment.SetLogger(new ConsoleLogger());
#if NETCOREAPP1_0
return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In);
#else
diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat
index 4e3870d71d..c419d87049 100755
--- a/src/csharp/build_packages_dotnetcli.bat
+++ b/src/csharp/build_packages_dotnetcli.bat
@@ -13,7 +13,7 @@
@rem limitations under the License.
@rem Current package versions
-set VERSION=1.5.0-dev
+set VERSION=1.7.0-dev
@rem Adjust the location of nuget.exe
set NUGET=C:\nuget\nuget.exe
diff --git a/src/csharp/build_packages_dotnetcli.sh b/src/csharp/build_packages_dotnetcli.sh
index f259cdb1d5..124dfbb257 100755
--- a/src/csharp/build_packages_dotnetcli.sh
+++ b/src/csharp/build_packages_dotnetcli.sh
@@ -39,7 +39,7 @@ dotnet pack --configuration Release Grpc.Auth --output ../../../artifacts
dotnet pack --configuration Release Grpc.HealthCheck --output ../../../artifacts
dotnet pack --configuration Release Grpc.Reflection --output ../../../artifacts
-nuget pack Grpc.nuspec -Version "1.5.0-dev" -OutputDirectory ../../artifacts
-nuget pack Grpc.Tools.nuspec -Version "1.5.0-dev" -OutputDirectory ../../artifacts
+nuget pack Grpc.nuspec -Version "1.7.0-dev" -OutputDirectory ../../artifacts
+nuget pack Grpc.Tools.nuspec -Version "1.7.0-dev" -OutputDirectory ../../artifacts
(cd ../../artifacts && zip csharp_nugets_dotnetcli.zip *.nupkg)
diff --git a/src/node/health_check/package.json b/src/node/health_check/package.json
index 6aa41522cd..3c7d3707ee 100644
--- a/src/node/health_check/package.json
+++ b/src/node/health_check/package.json
@@ -1,6 +1,6 @@
{
"name": "grpc-health-check",
- "version": "1.5.0-dev",
+ "version": "1.7.0-dev",
"author": "Google Inc.",
"description": "Health check service for use with gRPC",
"repository": {
@@ -15,7 +15,7 @@
}
],
"dependencies": {
- "grpc": "^1.5.0-dev",
+ "grpc": "^1.7.0-dev",
"lodash": "^3.9.3",
"google-protobuf": "^3.0.0"
},
diff --git a/src/node/tools/package.json b/src/node/tools/package.json
index 0a3c32734c..d9b1fb86c9 100644
--- a/src/node/tools/package.json
+++ b/src/node/tools/package.json
@@ -1,6 +1,6 @@
{
"name": "grpc-tools",
- "version": "1.5.0-dev",
+ "version": "1.7.0-dev",
"author": "Google Inc.",
"description": "Tools for developing with gRPC on Node.js",
"homepage": "https://grpc.io/",
diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec
index 345eecc279..3a282b0526 100644
--- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec
+++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec
@@ -42,7 +42,7 @@ Pod::Spec.new do |s|
# exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed
# before them.
s.name = '!ProtoCompiler-gRPCPlugin'
- v = '1.5.0-dev'
+ v = '1.7.0-dev'
s.version = v
s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.'
s.description = <<-DESC
diff --git a/src/objective-c/GRPCClient/GRPCCall+GID.h b/src/objective-c/GRPCClient/GRPCCall+GID.h
new file mode 100644
index 0000000000..3ee732e79e
--- /dev/null
+++ b/src/objective-c/GRPCClient/GRPCCall+GID.h
@@ -0,0 +1,29 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#import "GRPCCall.h"
+#import "GRPCCall+OAuth2.h"
+
+#import <Google/SignIn.h>
+
+/**
+ * Extend GIDSignIn class to comply GRPCAuthorizationProtocol
+ */
+@interface GIDSignIn (GRPC) <GRPCAuthorizationProtocol>
+- (void)getTokenWithHandler:(void (^)(NSString *token))hander;
+@end
diff --git a/src/core/lib/support/thd_internal.h b/src/objective-c/GRPCClient/GRPCCall+GID.m
index cc468c7846..030737147b 100644
--- a/src/core/lib/support/thd_internal.h
+++ b/src/objective-c/GRPCClient/GRPCCall+GID.m
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2017 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,13 @@
*
*/
-#ifndef GRPC_CORE_LIB_SUPPORT_THD_INTERNAL_H
-#define GRPC_CORE_LIB_SUPPORT_THD_INTERNAL_H
+#import "GRPCCall+GID.h"
-/* Internal interfaces between modules within the gpr support library. */
+@implementation GIDSignIn (GRPC)
-#endif /* GRPC_CORE_LIB_SUPPORT_THD_INTERNAL_H */
+- (void)getTokenWithHandler:(void (^)(NSString *token))handler {
+ NSString *token = self.currentUser.authentication.accessToken;
+ handler(token);
+}
+
+@end
diff --git a/src/objective-c/GRPCClient/GRPCCall+OAuth2.h b/src/objective-c/GRPCClient/GRPCCall+OAuth2.h
index 65465e9523..adb1042aa0 100644
--- a/src/objective-c/GRPCClient/GRPCCall+OAuth2.h
+++ b/src/objective-c/GRPCClient/GRPCCall+OAuth2.h
@@ -18,6 +18,13 @@
#import "GRPCCall.h"
+/**
+ * The protocol of an OAuth2 token object from which GRPCCall can acquire a token.
+ */
+@protocol GRPCAuthorizationProtocol
+- (void)getTokenWithHandler:(void (^)(NSString *token))hander;
+@end
+
/** Helpers for setting and reading headers compatible with OAuth2. */
@interface GRPCCall (OAuth2)
@@ -33,4 +40,12 @@
/** Returns the value (if any) of the "www-authenticate" response header (the challenge header). */
@property(atomic, readonly) NSString *oauth2ChallengeHeader;
+/**
+ * The authorization token object to be used when starting the call. If the value is set to nil, no
+ * oauth authentication will be used.
+ *
+ * If tokenProvider exists, it takes precedence over the token set by oauth2AccessToken.
+ */
+@property(atomic, strong) id<GRPCAuthorizationProtocol> tokenProvider;
+
@end
diff --git a/src/objective-c/GRPCClient/GRPCCall+OAuth2.m b/src/objective-c/GRPCClient/GRPCCall+OAuth2.m
index eaa7465087..8451ebe870 100644
--- a/src/objective-c/GRPCClient/GRPCCall+OAuth2.m
+++ b/src/objective-c/GRPCClient/GRPCCall+OAuth2.m
@@ -16,6 +16,8 @@
*
*/
+#import <objc/runtime.h>
+
#import "GRPCCall+OAuth2.h"
static NSString * const kAuthorizationHeader = @"authorization";
@@ -23,6 +25,7 @@ static NSString * const kBearerPrefix = @"Bearer ";
static NSString * const kChallengeHeader = @"www-authenticate";
@implementation GRPCCall (OAuth2)
+@dynamic tokenProvider;
- (NSString *)oauth2AccessToken {
NSString *headerValue = self.requestHeaders[kAuthorizationHeader];
@@ -45,4 +48,12 @@ static NSString * const kChallengeHeader = @"www-authenticate";
return self.responseHeaders[kChallengeHeader];
}
+- (void)setTokenProvider:(id<GRPCAuthorizationProtocol>)tokenProvider {
+ objc_setAssociatedObject(self, @selector(tokenProvider), tokenProvider, OBJC_ASSOCIATION_RETAIN);
+}
+
+- (id<GRPCAuthorizationProtocol>)tokenProvider {
+ return objc_getAssociatedObject(self, @selector(tokenProvider));
+}
+
@end
diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m
index 872362419e..436c19e354 100644
--- a/src/objective-c/GRPCClient/GRPCCall.m
+++ b/src/objective-c/GRPCClient/GRPCCall.m
@@ -18,6 +18,8 @@
#import "GRPCCall.h"
+#import "GRPCCall+OAuth2.h"
+
#include <grpc/grpc.h>
#include <grpc/support/time.h>
#import <RxLibrary/GRXConcurrentWriteable.h>
@@ -40,10 +42,14 @@ NSString * const kGRPCHeadersKey = @"io.grpc.HeadersKey";
NSString * const kGRPCTrailersKey = @"io.grpc.TrailersKey";
static NSMutableDictionary *callFlags;
+static NSString * const kAuthorizationHeader = @"authorization";
+static NSString * const kBearerPrefix = @"Bearer ";
+
@interface GRPCCall () <GRXWriteable>
// Make them read-write.
@property(atomic, strong) NSDictionary *responseHeaders;
@property(atomic, strong) NSDictionary *responseTrailers;
+@property(atomic) BOOL isWaitingForToken;
@end
// The following methods of a C gRPC call object aren't reentrant, and thus
@@ -181,9 +187,6 @@ static NSMutableDictionary *callFlags;
- (void)finishWithError:(NSError *)errorOrNil {
@synchronized(self) {
- if (_state == GRXWriterStateFinished) {
- return;
- }
_state = GRXWriterStateFinished;
}
@@ -211,7 +214,11 @@ static NSMutableDictionary *callFlags;
[self finishWithError:[NSError errorWithDomain:kGRPCErrorDomain
code:GRPCErrorCodeCancelled
userInfo:@{NSLocalizedDescriptionKey: @"Canceled by app"}]];
- [self cancelCall];
+ if (!self.isWaitingForToken) {
+ [self cancelCall];
+ } else {
+ self.isWaitingForToken = NO;
+ }
}
- (void)dealloc {
@@ -410,22 +417,13 @@ static NSMutableDictionary *callFlags;
#pragma mark GRXWriter implementation
-- (void)startWithWriteable:(id<GRXWriteable>)writeable {
- @synchronized(self) {
- _state = GRXWriterStateStarted;
- }
-
- // Create a retain cycle so that this instance lives until the RPC finishes (or is cancelled).
- // This makes RPCs in which the call isn't externally retained possible (as long as it is started
- // before being autoreleased).
- // Care is taken not to retain self strongly in any of the blocks used in this implementation, so
- // that the life of the instance is determined by this retain cycle.
- _retainSelf = self;
-
+- (void)startCallWithWriteable:(id<GRXWriteable>)writeable {
_responseWriteable = [[GRXConcurrentWriteable alloc] initWithWriteable:writeable
dispatchQueue:_responseQueue];
- _wrappedCall = [[GRPCWrappedCall alloc] initWithHost:_host serverName:_serverName path:_path];
+ _wrappedCall = [[GRPCWrappedCall alloc] initWithHost:_host
+ serverName:_serverName
+ path:_path];
NSAssert(_wrappedCall, @"Error allocating RPC objects. Low memory?");
[self sendHeaders:_requestHeaders];
@@ -437,20 +435,49 @@ static NSMutableDictionary *callFlags;
// TODO(jcanizales): Check this on init.
[NSException raise:NSInvalidArgumentException format:@"host of %@ is nil", _host];
}
- __weak typeof(self) weakSelf = self;
_connectivityMonitor = [GRPCConnectivityMonitor monitorWithHost:host];
+ __weak typeof(self) weakSelf = self;
void (^handler)() = ^{
typeof(self) strongSelf = weakSelf;
- if (strongSelf) {
- [strongSelf finishWithError:[NSError errorWithDomain:kGRPCErrorDomain
- code:GRPCErrorCodeUnavailable
- userInfo:@{ NSLocalizedDescriptionKey : @"Connectivity lost." }]];
- }
+ [strongSelf finishWithError:[NSError errorWithDomain:kGRPCErrorDomain
+ code:GRPCErrorCodeUnavailable
+ userInfo:@{ NSLocalizedDescriptionKey : @"Connectivity lost." }]];
};
[_connectivityMonitor handleLossWithHandler:handler
wifiStatusChangeHandler:nil];
}
+- (void)startWithWriteable:(id<GRXWriteable>)writeable {
+ @synchronized(self) {
+ _state = GRXWriterStateStarted;
+ }
+
+ // Create a retain cycle so that this instance lives until the RPC finishes (or is cancelled).
+ // This makes RPCs in which the call isn't externally retained possible (as long as it is started
+ // before being autoreleased).
+ // Care is taken not to retain self strongly in any of the blocks used in this implementation, so
+ // that the life of the instance is determined by this retain cycle.
+ _retainSelf = self;
+
+ if (self.tokenProvider != nil) {
+ self.isWaitingForToken = YES;
+ __weak typeof(self) weakSelf = self;
+ [self.tokenProvider getTokenWithHandler:^(NSString *token){
+ typeof(self) strongSelf = weakSelf;
+ if (strongSelf && strongSelf.isWaitingForToken) {
+ if (token) {
+ NSString *t = [kBearerPrefix stringByAppendingString:token];
+ strongSelf.requestHeaders[kAuthorizationHeader] = t;
+ }
+ [strongSelf startCallWithWriteable:writeable];
+ strongSelf.isWaitingForToken = NO;
+ }
+ }];
+ } else {
+ [self startCallWithWriteable:writeable];
+ }
+}
+
- (void)setState:(GRXWriterState)newState {
@synchronized(self) {
// Manual transitions are only allowed from the started or paused states.
diff --git a/src/objective-c/GRPCClient/private/GRPCRequestHeaders.m b/src/objective-c/GRPCClient/private/GRPCRequestHeaders.m
index 7640a64d6d..5de1d8fff5 100644
--- a/src/objective-c/GRPCClient/private/GRPCRequestHeaders.m
+++ b/src/objective-c/GRPCClient/private/GRPCRequestHeaders.m
@@ -103,7 +103,6 @@ static void CheckKeyValuePairIsValid(NSString *key, id value) {
}
- (void)setObject:(id)obj forKey:(NSString *)key {
- [self checkCallIsNotStarted];
CheckIsNonNilASCII(@"Header name", key);
key = key.lowercaseString;
CheckKeyValuePairIsValid(key, obj);
diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m
index 9802465001..87dc33af88 100644
--- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m
+++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m
@@ -68,6 +68,8 @@
_op.data.send_initial_metadata.metadata = metadata.grpc_metadataArray;
_op.data.send_initial_metadata.maybe_compression_level.is_set = false;
_op.data.send_initial_metadata.maybe_compression_level.level = 0;
+ _op.data.send_initial_metadata.maybe_stream_compression_level.is_set = false;
+ _op.data.send_initial_metadata.maybe_stream_compression_level.level = 0;
_op.flags = flags;
_handler = handler;
}
diff --git a/src/objective-c/GRPCClient/private/version.h b/src/objective-c/GRPCClient/private/version.h
index d9cb3881e1..843954e84a 100644
--- a/src/objective-c/GRPCClient/private/version.h
+++ b/src/objective-c/GRPCClient/private/version.h
@@ -23,4 +23,4 @@
// `tools/buildgen/generate_projects.sh`.
-#define GRPC_OBJC_VERSION_STRING @"1.5.0-dev"
+#define GRPC_OBJC_VERSION_STRING @"1.7.0-dev"
diff --git a/src/objective-c/RxLibrary/GRXConcurrentWriteable.m b/src/objective-c/RxLibrary/GRXConcurrentWriteable.m
index cb5d0a63f0..bbfe491783 100644
--- a/src/objective-c/RxLibrary/GRXConcurrentWriteable.m
+++ b/src/objective-c/RxLibrary/GRXConcurrentWriteable.m
@@ -28,7 +28,7 @@
@implementation GRXConcurrentWriteable {
dispatch_queue_t _writeableQueue;
// This ensures that writesFinishedWithError: is only sent once to the writeable.
- dispatch_once_t _alreadyFinished;
+ BOOL _alreadyFinished;
}
- (instancetype)init {
@@ -65,19 +65,35 @@
- (void)enqueueSuccessfulCompletion {
dispatch_async(_writeableQueue, ^{
- dispatch_once(&_alreadyFinished, ^{
+ BOOL finished = NO;
+ @synchronized (self) {
+ if (!_alreadyFinished) {
+ _alreadyFinished = YES;
+ } else {
+ finished = YES;
+ }
+ }
+ if (!finished) {
// Cancellation is now impossible. None of the other three blocks can run concurrently with
// this one.
[self.writeable writesFinishedWithError:nil];
// Skip any possible message to the wrapped writeable enqueued after this one.
self.writeable = nil;
- });
+ }
});
}
- (void)cancelWithError:(NSError *)error {
NSAssert(error, @"For a successful completion, use enqueueSuccessfulCompletion.");
- dispatch_once(&_alreadyFinished, ^{
+ BOOL finished = NO;
+ @synchronized (self) {
+ if (!_alreadyFinished) {
+ _alreadyFinished = YES;
+ } else {
+ finished = YES;
+ }
+ }
+ if (!finished) {
// Skip any of the still-enqueued messages to the wrapped writeable. We use the atomic setter to
// nillify writeable because we might be running concurrently with the blocks in
// _writeableQueue, and assignment with ARC isn't atomic.
@@ -87,15 +103,23 @@
dispatch_async(_writeableQueue, ^{
[writeable writesFinishedWithError:error];
});
- });
+ }
}
- (void)cancelSilently {
- dispatch_once(&_alreadyFinished, ^{
+ BOOL finished = NO;
+ @synchronized (self) {
+ if (!_alreadyFinished) {
+ _alreadyFinished = YES;
+ } else {
+ finished = YES;
+ }
+ }
+ if (!finished) {
// Skip any of the still-enqueued messages to the wrapped writeable. We use the atomic setter to
// nillify writeable because we might be running concurrently with the blocks in
// _writeableQueue, and assignment with ARC isn't atomic.
self.writeable = nil;
- });
+ }
}
@end
diff --git a/src/objective-c/tests/build_one_example.sh b/src/objective-c/tests/build_one_example.sh
index 298d8e7043..985d55f3cc 100755
--- a/src/objective-c/tests/build_one_example.sh
+++ b/src/objective-c/tests/build_one_example.sh
@@ -37,11 +37,11 @@ rm -f Podfile.lock
pod install
set -o pipefail
-XCODEBUILD_FILTER='(^===|^\*\*|\bfatal\b|\berror\b|\bwarning\b|\bfail|\bpassed\b)'
+XCODEBUILD_FILTER='(^CompileC |^Ld |^.*clang |^ *cd |^ *export |^Libtool |^.*libtool |^CpHeader |^ *builtin-copy )'
xcodebuild \
build \
-workspace *.xcworkspace \
-scheme $SCHEME \
-destination name="iPhone 6" \
- | egrep "$XCODEBUILD_FILTER" \
- | egrep -v "(GPBDictionary|GPBArray)" -
+ | egrep -v "$XCODEBUILD_FILTER" \
+ | egrep -v "^$" -
diff --git a/src/objective-c/tests/run_tests.sh b/src/objective-c/tests/run_tests.sh
index 8843edaede..5b7a2d104a 100755
--- a/src/objective-c/tests/run_tests.sh
+++ b/src/objective-c/tests/run_tests.sh
@@ -38,7 +38,7 @@ trap 'kill -9 `jobs -p` ; echo "EXIT TIME: $(date)"' EXIT
# element of the pipe fails.
# TODO(jcanizales): Use xctool instead? Issue #2540.
set -o pipefail
-XCODEBUILD_FILTER='(^===|^\*\*|\bfatal\b|\berror\b|\bwarning\b|\bfail|\bpassed\b)'
+XCODEBUILD_FILTER='(^CompileC |^Ld |^.*clang |^ *cd |^ *export |^Libtool |^.*libtool |^CpHeader |^ *builtin-copy )'
echo "TIME: $(date)"
xcodebuild \
-workspace Tests.xcworkspace \
@@ -48,8 +48,8 @@ xcodebuild \
HOST_PORT_LOCAL=localhost:5050 \
HOST_PORT_REMOTE=grpc-test.sandbox.googleapis.com \
test \
- | egrep "$XCODEBUILD_FILTER" \
- | egrep -v "(GPBDictionary|GPBArray)" -
+ | egrep -v "$XCODEBUILD_FILTER" \
+ | egrep -v '^$' -
echo "TIME: $(date)"
xcodebuild \
@@ -60,16 +60,12 @@ xcodebuild \
| egrep "$XCODEBUILD_FILTER" \
| egrep -v "(GPBDictionary|GPBArray)" -
-# Temporarily disabled for (possible) flakiness on Jenkins.
-# Fix or reenable after confirmation/disconfirmation that it is the source of
-# Jenkins problem.
-
-# echo "TIME: $(date)"
-# xcodebuild \
-# -workspace Tests.xcworkspace \
-# -scheme CronetUnitTests \
-# -destination name="iPhone 6" \
-# test | xcpretty
+echo "TIME: $(date)"
+xcodebuild \
+ -workspace Tests.xcworkspace \
+ -scheme CronetUnitTests \
+ -destination name="iPhone 6" \
+ test | xcpretty
echo "TIME: $(date)"
xcodebuild \
diff --git a/src/php/composer.json b/src/php/composer.json
index c6a74c5c84..3606a18f34 100644
--- a/src/php/composer.json
+++ b/src/php/composer.json
@@ -2,7 +2,7 @@
"name": "grpc/grpc-dev",
"description": "gRPC library for PHP - for Developement use only",
"license": "Apache-2.0",
- "version": "1.5.0",
+ "version": "1.7.0",
"require": {
"php": ">=5.5.0",
"google/protobuf": "^v3.3.0"
diff --git a/src/php/ext/grpc/call_credentials.c b/src/php/ext/grpc/call_credentials.c
index f46091d709..1eee8645df 100644
--- a/src/php/ext/grpc/call_credentials.c
+++ b/src/php/ext/grpc/call_credentials.c
@@ -179,7 +179,7 @@ void plugin_get_metadata(void *ptr, grpc_auth_metadata_context context,
grpc_metadata_array metadata;
bool cleanup = true;
- if (Z_TYPE_P(retval) != IS_ARRAY) {
+ if (retval == NULL || Z_TYPE_P(retval) != IS_ARRAY) {
cleanup = false;
code = GRPC_STATUS_INVALID_ARGUMENT;
} else if (!create_metadata_array(retval, &metadata)) {
diff --git a/src/php/ext/grpc/channel.c b/src/php/ext/grpc/channel.c
index f1187e8722..dc3acc89bb 100644
--- a/src/php/ext/grpc/channel.c
+++ b/src/php/ext/grpc/channel.c
@@ -66,6 +66,8 @@ PHP_GRPC_FREE_WRAPPED_FUNC_START(wrapped_grpc_channel)
if (!(PHP_GRPC_PERSISTENT_LIST_FIND(&EG(persistent_list), p->wrapper->key,
key_len, rsrc))) {
grpc_channel_destroy(p->wrapper->wrapped);
+ free(p->wrapper->target);
+ free(p->wrapper->args_hashstr);
}
gpr_mu_unlock(&global_persistent_list_mu);
}
@@ -158,7 +160,7 @@ void create_and_add_channel_to_persistent_list(
grpc_channel_args args,
wrapped_grpc_channel_credentials *creds,
char *key,
- php_grpc_int key_len) {
+ php_grpc_int key_len TSRMLS_DC) {
php_grpc_zend_resource new_rsrc;
channel_persistent_le_t *le;
// this links each persistent list entry to a destructor
@@ -187,10 +189,8 @@ void create_and_add_channel_to_persistent_list(
* credentials.
*
* If the $args array contains a "force_new" key mapping to a boolean value
- * of "true", a new underlying grpc_channel will be created regardless. If
- * there are any opened channels on the same hostname, user must manually
- * call close() on those dangling channels before the end of the PHP
- * script.
+ * of "true", a new and separate underlying grpc_channel will be created
+ * and returned. This will not affect existing channels.
*
* @param string $target The hostname to associate with this channel
* @param array $args_array The arguments to pass to the Channel
@@ -273,19 +273,15 @@ PHP_METHOD(Channel, __construct) {
}
channel->wrapper = malloc(sizeof(grpc_channel_wrapper));
channel->wrapper->key = key;
- channel->wrapper->target = target;
- channel->wrapper->args_hashstr = sha1str;
+ channel->wrapper->target = strdup(target);
+ channel->wrapper->args_hashstr = strdup(sha1str);
if (creds != NULL && creds->hashstr != NULL) {
channel->wrapper->creds_hashstr = creds->hashstr;
}
gpr_mu_init(&channel->wrapper->mu);
smart_str_free(&buf);
- if (force_new) {
- php_grpc_delete_persistent_list_entry(key, key_len TSRMLS_CC);
- }
-
- if (creds != NULL && creds->has_call_creds) {
+ if (force_new || (creds != NULL && creds->has_call_creds)) {
// If the ChannelCredentials object was composed with a CallCredentials
// object, there is no way we can tell them apart. Do NOT persist
// them. They should be individually destroyed.
@@ -293,7 +289,7 @@ PHP_METHOD(Channel, __construct) {
} else if (!(PHP_GRPC_PERSISTENT_LIST_FIND(&EG(persistent_list), key,
key_len, rsrc))) {
create_and_add_channel_to_persistent_list(
- channel, target, args, creds, key, key_len);
+ channel, target, args, creds, key, key_len TSRMLS_CC);
} else {
// Found a previously stored channel in the persistent list
channel_persistent_le_t *le = (channel_persistent_le_t *)rsrc->ptr;
@@ -303,7 +299,7 @@ PHP_METHOD(Channel, __construct) {
strcmp(creds->hashstr, le->channel->creds_hashstr) != 0)) {
// somehow hash collision
create_and_add_channel_to_persistent_list(
- channel, target, args, creds, key, key_len);
+ channel, target, args, creds, key, key_len TSRMLS_CC);
} else {
channel->wrapper = le->channel;
}
@@ -416,12 +412,14 @@ PHP_METHOD(Channel, close) {
gpr_mu_lock(&channel->wrapper->mu);
if (channel->wrapper->wrapped != NULL) {
grpc_channel_destroy(channel->wrapper->wrapped);
+ free(channel->wrapper->target);
+ free(channel->wrapper->args_hashstr);
channel->wrapper->wrapped = NULL;
- }
- php_grpc_delete_persistent_list_entry(channel->wrapper->key,
- strlen(channel->wrapper->key)
- TSRMLS_CC);
+ php_grpc_delete_persistent_list_entry(channel->wrapper->key,
+ strlen(channel->wrapper->key)
+ TSRMLS_CC);
+ }
gpr_mu_unlock(&channel->wrapper->mu);
}
@@ -449,12 +447,11 @@ static void php_grpc_channel_plink_dtor(php_grpc_zend_resource *rsrc
gpr_mu_lock(&le->channel->mu);
if (le->channel->wrapped != NULL) {
grpc_channel_destroy(le->channel->wrapped);
- free(le->channel->key);
- free(le->channel);
+ free(le->channel->target);
+ free(le->channel->args_hashstr);
}
gpr_mu_unlock(&le->channel->mu);
}
- free(le);
}
ZEND_BEGIN_ARG_INFO_EX(arginfo_construct, 0, 0, 2)
@@ -496,6 +493,7 @@ GRPC_STARTUP_FUNCTION(channel) {
INIT_CLASS_ENTRY(ce, "Grpc\\Channel", channel_methods);
ce.create_object = create_wrapped_grpc_channel;
grpc_ce_channel = zend_register_internal_class(&ce TSRMLS_CC);
+ gpr_mu_init(&global_persistent_list_mu);
le_plink = zend_register_list_destructors_ex(
NULL, php_grpc_channel_plink_dtor, "Persistent Channel", module_number);
PHP_GRPC_INIT_HANDLER(wrapped_grpc_channel, channel_ce_handlers);
diff --git a/src/php/ext/grpc/channel_credentials.c b/src/php/ext/grpc/channel_credentials.c
index 19e1cefb6f..86e4f46c67 100644
--- a/src/php/ext/grpc/channel_credentials.c
+++ b/src/php/ext/grpc/channel_credentials.c
@@ -135,6 +135,8 @@ PHP_METHOD(ChannelCredentials, createSsl) {
pem_key_cert_pair.private_key = pem_key_cert_pair.cert_chain = NULL;
+ grpc_set_ssl_roots_override_callback(get_ssl_roots_override);
+
/* "|s!s!s!" == 3 optional nullable strings */
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!s!",
&pem_root_certs, &root_certs_length,
@@ -148,7 +150,7 @@ PHP_METHOD(ChannelCredentials, createSsl) {
}
php_grpc_int hashkey_len = root_certs_length + cert_chain_length;
- char hashkey[hashkey_len];
+ char *hashkey = emalloc(hashkey_len);
if (root_certs_length > 0) {
strcpy(hashkey, pem_root_certs);
}
@@ -164,6 +166,7 @@ PHP_METHOD(ChannelCredentials, createSsl) {
pem_key_cert_pair.private_key == NULL ? NULL : &pem_key_cert_pair, NULL);
zval *creds_object = grpc_php_wrap_channel_credentials(creds, hashstr, false
TSRMLS_CC);
+ efree(hashkey);
RETURN_DESTROY_ZVAL(creds_object);
}
@@ -177,6 +180,8 @@ PHP_METHOD(ChannelCredentials, createComposite) {
zval *cred1_obj;
zval *cred2_obj;
+ grpc_set_ssl_roots_override_callback(get_ssl_roots_override);
+
/* "OO" == 2 Objects */
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OO", &cred1_obj,
grpc_ce_channel_credentials, &cred2_obj,
@@ -245,7 +250,6 @@ void grpc_init_channel_credentials(TSRMLS_D) {
zend_class_entry ce;
INIT_CLASS_ENTRY(ce, "Grpc\\ChannelCredentials",
channel_credentials_methods);
- grpc_set_ssl_roots_override_callback(get_ssl_roots_override);
ce.create_object = create_wrapped_grpc_channel_credentials;
grpc_ce_channel_credentials = zend_register_internal_class(&ce TSRMLS_CC);
PHP_GRPC_INIT_HANDLER(wrapped_grpc_channel_credentials,
diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c
index a96daf7d9b..4ed56de993 100644
--- a/src/php/ext/grpc/php_grpc.c
+++ b/src/php/ext/grpc/php_grpc.c
@@ -34,7 +34,8 @@
#include <ext/standard/info.h>
#include "php_grpc.h"
-// ZEND_DECLARE_MODULE_GLOBALS(grpc)
+ZEND_DECLARE_MODULE_GLOBALS(grpc)
+static PHP_GINIT_FUNCTION(grpc);
/* {{{ grpc_functions[]
*
@@ -55,13 +56,17 @@ zend_module_entry grpc_module_entry = {
grpc_functions,
PHP_MINIT(grpc),
PHP_MSHUTDOWN(grpc),
- NULL,
+ PHP_RINIT(grpc),
NULL,
PHP_MINFO(grpc),
#if ZEND_MODULE_API_NO >= 20010901
PHP_GRPC_VERSION,
#endif
- STANDARD_MODULE_PROPERTIES};
+ PHP_MODULE_GLOBALS(grpc),
+ PHP_GINIT(grpc),
+ NULL,
+ NULL,
+ STANDARD_MODULE_PROPERTIES_EX};
/* }}} */
#ifdef COMPILE_DL_GRPC
@@ -99,7 +104,6 @@ PHP_MINIT_FUNCTION(grpc) {
REGISTER_INI_ENTRIES();
*/
/* Register call error constants */
- grpc_init();
REGISTER_LONG_CONSTANT("Grpc\\CALL_OK", GRPC_CALL_OK,
CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("Grpc\\CALL_ERROR", GRPC_CALL_ERROR,
@@ -227,7 +231,6 @@ PHP_MINIT_FUNCTION(grpc) {
grpc_init_channel_credentials(TSRMLS_C);
grpc_init_call_credentials(TSRMLS_C);
grpc_init_server_credentials(TSRMLS_C);
- grpc_php_init_completion_queue(TSRMLS_C);
return SUCCESS;
}
/* }}} */
@@ -240,9 +243,12 @@ PHP_MSHUTDOWN_FUNCTION(grpc) {
*/
// WARNING: This function IS being called by PHP when the extension
// is unloaded but the logs were somehow suppressed.
- grpc_shutdown_timeval(TSRMLS_C);
- grpc_php_shutdown_completion_queue(TSRMLS_C);
- grpc_shutdown();
+ if (GRPC_G(initialized)) {
+ grpc_shutdown_timeval(TSRMLS_C);
+ grpc_php_shutdown_completion_queue(TSRMLS_C);
+ grpc_shutdown();
+ GRPC_G(initialized) = 0;
+ }
return SUCCESS;
}
/* }}} */
@@ -259,6 +265,26 @@ PHP_MINFO_FUNCTION(grpc) {
*/
}
/* }}} */
+
+/* {{{ PHP_RINIT_FUNCTION
+ */
+PHP_RINIT_FUNCTION(grpc) {
+ if (!GRPC_G(initialized)) {
+ grpc_init();
+ grpc_php_init_completion_queue(TSRMLS_C);
+ GRPC_G(initialized) = 1;
+ }
+ return SUCCESS;
+}
+/* }}} */
+
+/* {{{ PHP_GINIT_FUNCTION
+ */
+static PHP_GINIT_FUNCTION(grpc) {
+ grpc_globals->initialized = 0;
+}
+/* }}} */
+
/* The previous line is meant for vim and emacs, so it can correctly fold and
unfold functions in source code. See the corresponding marks just before
function definition, where the functions purpose is also documented. Please
diff --git a/src/php/ext/grpc/php_grpc.h b/src/php/ext/grpc/php_grpc.h
index 32329178dc..e30f011c39 100644
--- a/src/php/ext/grpc/php_grpc.h
+++ b/src/php/ext/grpc/php_grpc.h
@@ -49,14 +49,16 @@ PHP_MINIT_FUNCTION(grpc);
PHP_MSHUTDOWN_FUNCTION(grpc);
/* Displays information about the module */
PHP_MINFO_FUNCTION(grpc);
+/* Code that runs at request start */
+PHP_RINIT_FUNCTION(grpc);
/*
Declare any global variables you may need between the BEGIN
and END macros here:
-
+*/
ZEND_BEGIN_MODULE_GLOBALS(grpc)
+ zend_bool initialized;
ZEND_END_MODULE_GLOBALS(grpc)
-*/
/* In every utility function you add that needs to use variables
in php_grpc_globals, call TSRMLS_FETCH(); after declaring other
diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h
index 744028b2ca..07d8eee7fe 100644
--- a/src/php/ext/grpc/version.h
+++ b/src/php/ext/grpc/version.h
@@ -20,6 +20,6 @@
#ifndef VERSION_H
#define VERSION_H
-#define PHP_GRPC_VERSION "1.5.0dev"
+#define PHP_GRPC_VERSION "1.7.0dev"
#endif /* VERSION_H */
diff --git a/src/php/lib/Grpc/ServerStreamingCall.php b/src/php/lib/Grpc/ServerStreamingCall.php
index 269a99ab59..f8fddfea01 100644
--- a/src/php/lib/Grpc/ServerStreamingCall.php
+++ b/src/php/lib/Grpc/ServerStreamingCall.php
@@ -40,13 +40,11 @@ class ServerStreamingCall extends AbstractCall
if (array_key_exists('flags', $options)) {
$message_array['flags'] = $options['flags'];
}
- $event = $this->call->startBatch([
+ $this->call->startBatch([
OP_SEND_INITIAL_METADATA => $metadata,
- OP_RECV_INITIAL_METADATA => true,
OP_SEND_MESSAGE => $message_array,
OP_SEND_CLOSE_FROM_CLIENT => true,
]);
- $this->metadata = $event->metadata;
}
/**
@@ -54,9 +52,15 @@ class ServerStreamingCall extends AbstractCall
*/
public function responses()
{
- $response = $this->call->startBatch([
- OP_RECV_MESSAGE => true,
- ])->message;
+ $batch = [OP_RECV_MESSAGE => true];
+ if ($this->metadata === null) {
+ $batch[OP_RECV_INITIAL_METADATA] = true;
+ }
+ $read_event = $this->call->startBatch($batch);
+ if ($this->metadata === null) {
+ $this->metadata = $read_event->metadata;
+ }
+ $response = $read_event->message;
while ($response !== null) {
yield $this->_deserializeResponse($response);
$response = $this->call->startBatch([
@@ -81,4 +85,16 @@ class ServerStreamingCall extends AbstractCall
return $status_event->status;
}
+
+ /**
+ * @return mixed The metadata sent by the server
+ */
+ public function getMetadata()
+ {
+ if ($this->metadata === null) {
+ $event = $this->call->startBatch([OP_RECV_INITIAL_METADATA => true]);
+ $this->metadata = $event->metadata;
+ }
+ return $this->metadata;
+ }
}
diff --git a/src/php/lib/Grpc/UnaryCall.php b/src/php/lib/Grpc/UnaryCall.php
index dd55d02165..e8496492b8 100644
--- a/src/php/lib/Grpc/UnaryCall.php
+++ b/src/php/lib/Grpc/UnaryCall.php
@@ -40,13 +40,11 @@ class UnaryCall extends AbstractCall
if (isset($options['flags'])) {
$message_array['flags'] = $options['flags'];
}
- $event = $this->call->startBatch([
+ $this->call->startBatch([
OP_SEND_INITIAL_METADATA => $metadata,
- OP_RECV_INITIAL_METADATA => true,
OP_SEND_MESSAGE => $message_array,
OP_SEND_CLOSE_FROM_CLIENT => true,
]);
- $this->metadata = $event->metadata;
}
/**
@@ -56,14 +54,32 @@ class UnaryCall extends AbstractCall
*/
public function wait()
{
- $event = $this->call->startBatch([
+ $batch = [
OP_RECV_MESSAGE => true,
OP_RECV_STATUS_ON_CLIENT => true,
- ]);
-
+ ];
+ if ($this->metadata === null) {
+ $batch[OP_RECV_INITIAL_METADATA] = true;
+ }
+ $event = $this->call->startBatch($batch);
+ if ($this->metadata === null) {
+ $this->metadata = $event->metadata;
+ }
$status = $event->status;
$this->trailing_metadata = $status->metadata;
return [$this->_deserializeResponse($event->message), $status];
}
+
+ /**
+ * @return mixed The metadata sent by the server
+ */
+ public function getMetadata()
+ {
+ if ($this->metadata === null) {
+ $event = $this->call->startBatch([OP_RECV_INITIAL_METADATA => true]);
+ $this->metadata = $event->metadata;
+ }
+ return $this->metadata;
+ }
}
diff --git a/src/php/tests/unit_tests/ChannelTest.php b/src/php/tests/unit_tests/ChannelTest.php
index 400df0fb66..c375a16269 100644
--- a/src/php/tests/unit_tests/ChannelTest.php
+++ b/src/php/tests/unit_tests/ChannelTest.php
@@ -517,8 +517,6 @@ class ChannelTest extends PHPUnit_Framework_TestCase
$state = $this->channel2->getConnectivityState();
$this->assertEquals(GRPC\CHANNEL_IDLE, $state);
- // any dangling old connection to the same host must be
- // manually closed
$this->channel1->close();
$this->channel2->close();
}
@@ -529,6 +527,7 @@ class ChannelTest extends PHPUnit_Framework_TestCase
$this->channel1 = new Grpc\Channel('localhost:1', []);
$this->channel2 = new Grpc\Channel('localhost:1',
["force_new" => true]);
+ // channel3 shares with channel1
$this->channel3 = new Grpc\Channel('localhost:1', []);
// try to connect on channel2
@@ -540,29 +539,31 @@ class ChannelTest extends PHPUnit_Framework_TestCase
$state = $this->channel2->getConnectivityState();
$this->assertConnecting($state);
$state = $this->channel3->getConnectivityState();
- $this->assertConnecting($state);
+ $this->assertEquals(GRPC\CHANNEL_IDLE, $state);
$this->channel1->close();
$this->channel2->close();
}
+ /**
+ * @expectedException RuntimeException
+ */
public function testPersistentChannelForceNewOldChannelClose()
{
$this->channel1 = new Grpc\Channel('localhost:1', []);
$this->channel2 = new Grpc\Channel('localhost:1',
["force_new" => true]);
+ // channel3 shares with channel1
$this->channel3 = new Grpc\Channel('localhost:1', []);
$this->channel1->close();
$state = $this->channel2->getConnectivityState();
$this->assertEquals(GRPC\CHANNEL_IDLE, $state);
- $state = $this->channel3->getConnectivityState();
- $this->assertEquals(GRPC\CHANNEL_IDLE, $state);
- $this->channel2->close();
- $this->channel3->close();
+ // channel3 already closed
+ $state = $this->channel3->getConnectivityState();
}
public function testPersistentChannelForceNewNewChannelClose()
diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py
index dcb46459a2..a4eb358c4e 100644
--- a/src/python/grpcio/grpc/_grpcio_metadata.py
+++ b/src/python/grpcio/grpc/_grpcio_metadata.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!!
-__version__ = """1.5.0.dev0"""
+__version__ = """1.7.0.dev0"""
diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py
index 1bbd1e149e..3194a893d7 100644
--- a/src/python/grpcio/grpc_version.py
+++ b/src/python/grpcio/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!!
-VERSION='1.5.0.dev0'
+VERSION='1.7.0.dev0'
diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py
index 8aa5118f39..ef68bad17a 100644
--- a/src/python/grpcio_health_checking/grpc_version.py
+++ b/src/python/grpcio_health_checking/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!!
-VERSION='1.5.0.dev0'
+VERSION='1.7.0.dev0'
diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py
index a23b9b5edb..55ab959cc5 100644
--- a/src/python/grpcio_reflection/grpc_version.py
+++ b/src/python/grpcio_reflection/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!!
-VERSION='1.5.0.dev0'
+VERSION='1.7.0.dev0'
diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py
index fd47b426ac..9e54dc9f75 100644
--- a/src/python/grpcio_tests/grpc_version.py
+++ b/src/python/grpcio_tests/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!!
-VERSION='1.5.0.dev0'
+VERSION='1.7.0.dev0'
diff --git a/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py b/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py
index 299ce75e79..a86743fa5a 100644
--- a/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py
+++ b/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py
@@ -95,9 +95,6 @@ class ReflectionServicerTest(unittest.TestCase):
)),)
self.assertSequenceEqual(expected_responses, responses)
- @unittest.skip(
- 'TODO(mmx): enable when (pure) python protobuf issue is fixed'
- '(see https://github.com/google/protobuf/issues/2882)')
def testFileContainingExtension(self):
requests = (reflection_pb2.ServerReflectionRequest(
file_containing_extension=reflection_pb2.ExtensionRequest(
diff --git a/src/ruby/ext/grpc/rb_call.c b/src/ruby/ext/grpc/rb_call.c
index 74f189e1e0..5550bb7d5f 100644
--- a/src/ruby/ext/grpc/rb_call.c
+++ b/src/ruby/ext/grpc/rb_call.c
@@ -905,6 +905,9 @@ static void Init_grpc_error_codes() {
rb_define_const(grpc_rb_mRpcErrors, "INVALID_FLAGS",
UINT2NUM(GRPC_CALL_ERROR_INVALID_FLAGS));
+ /* Hint the GC that this is a global and shouldn't be sweeped. */
+ rb_global_variable(&rb_error_code_details);
+
/* Add the detail strings to a Hash */
rb_error_code_details = rb_hash_new();
rb_hash_aset(rb_error_code_details, UINT2NUM(GRPC_CALL_OK),
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c
index e83c38841b..9671d794c5 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c
@@ -62,11 +62,14 @@ census_resource_id_type census_resource_id_import;
census_record_values_type census_record_values_import;
grpc_compression_algorithm_parse_type grpc_compression_algorithm_parse_import;
grpc_compression_algorithm_name_type grpc_compression_algorithm_name_import;
+grpc_stream_compression_algorithm_name_type grpc_stream_compression_algorithm_name_import;
grpc_compression_algorithm_for_level_type grpc_compression_algorithm_for_level_import;
+grpc_stream_compression_algorithm_for_level_type grpc_stream_compression_algorithm_for_level_import;
grpc_compression_options_init_type grpc_compression_options_init_import;
grpc_compression_options_enable_algorithm_type grpc_compression_options_enable_algorithm_import;
grpc_compression_options_disable_algorithm_type grpc_compression_options_disable_algorithm_import;
grpc_compression_options_is_algorithm_enabled_type grpc_compression_options_is_algorithm_enabled_import;
+grpc_compression_options_is_stream_compression_algorithm_enabled_type grpc_compression_options_is_stream_compression_algorithm_enabled_import;
grpc_metadata_array_init_type grpc_metadata_array_init_import;
grpc_metadata_array_destroy_type grpc_metadata_array_destroy_import;
grpc_call_details_init_type grpc_call_details_init_import;
@@ -365,11 +368,14 @@ void grpc_rb_load_imports(HMODULE library) {
census_record_values_import = (census_record_values_type) GetProcAddress(library, "census_record_values");
grpc_compression_algorithm_parse_import = (grpc_compression_algorithm_parse_type) GetProcAddress(library, "grpc_compression_algorithm_parse");
grpc_compression_algorithm_name_import = (grpc_compression_algorithm_name_type) GetProcAddress(library, "grpc_compression_algorithm_name");
+ grpc_stream_compression_algorithm_name_import = (grpc_stream_compression_algorithm_name_type) GetProcAddress(library, "grpc_stream_compression_algorithm_name");
grpc_compression_algorithm_for_level_import = (grpc_compression_algorithm_for_level_type) GetProcAddress(library, "grpc_compression_algorithm_for_level");
+ grpc_stream_compression_algorithm_for_level_import = (grpc_stream_compression_algorithm_for_level_type) GetProcAddress(library, "grpc_stream_compression_algorithm_for_level");
grpc_compression_options_init_import = (grpc_compression_options_init_type) GetProcAddress(library, "grpc_compression_options_init");
grpc_compression_options_enable_algorithm_import = (grpc_compression_options_enable_algorithm_type) GetProcAddress(library, "grpc_compression_options_enable_algorithm");
grpc_compression_options_disable_algorithm_import = (grpc_compression_options_disable_algorithm_type) GetProcAddress(library, "grpc_compression_options_disable_algorithm");
grpc_compression_options_is_algorithm_enabled_import = (grpc_compression_options_is_algorithm_enabled_type) GetProcAddress(library, "grpc_compression_options_is_algorithm_enabled");
+ grpc_compression_options_is_stream_compression_algorithm_enabled_import = (grpc_compression_options_is_stream_compression_algorithm_enabled_type) GetProcAddress(library, "grpc_compression_options_is_stream_compression_algorithm_enabled");
grpc_metadata_array_init_import = (grpc_metadata_array_init_type) GetProcAddress(library, "grpc_metadata_array_init");
grpc_metadata_array_destroy_import = (grpc_metadata_array_destroy_type) GetProcAddress(library, "grpc_metadata_array_destroy");
grpc_call_details_init_import = (grpc_call_details_init_type) GetProcAddress(library, "grpc_call_details_init");
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
index 5288704350..b64199be8e 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
@@ -167,9 +167,15 @@ extern grpc_compression_algorithm_parse_type grpc_compression_algorithm_parse_im
typedef int(*grpc_compression_algorithm_name_type)(grpc_compression_algorithm algorithm, char **name);
extern grpc_compression_algorithm_name_type grpc_compression_algorithm_name_import;
#define grpc_compression_algorithm_name grpc_compression_algorithm_name_import
+typedef int(*grpc_stream_compression_algorithm_name_type)(grpc_stream_compression_algorithm algorithm, char **name);
+extern grpc_stream_compression_algorithm_name_type grpc_stream_compression_algorithm_name_import;
+#define grpc_stream_compression_algorithm_name grpc_stream_compression_algorithm_name_import
typedef grpc_compression_algorithm(*grpc_compression_algorithm_for_level_type)(grpc_compression_level level, uint32_t accepted_encodings);
extern grpc_compression_algorithm_for_level_type grpc_compression_algorithm_for_level_import;
#define grpc_compression_algorithm_for_level grpc_compression_algorithm_for_level_import
+typedef grpc_stream_compression_algorithm(*grpc_stream_compression_algorithm_for_level_type)(grpc_stream_compression_level level, uint32_t accepted_stream_encodings);
+extern grpc_stream_compression_algorithm_for_level_type grpc_stream_compression_algorithm_for_level_import;
+#define grpc_stream_compression_algorithm_for_level grpc_stream_compression_algorithm_for_level_import
typedef void(*grpc_compression_options_init_type)(grpc_compression_options *opts);
extern grpc_compression_options_init_type grpc_compression_options_init_import;
#define grpc_compression_options_init grpc_compression_options_init_import
@@ -182,6 +188,9 @@ extern grpc_compression_options_disable_algorithm_type grpc_compression_options_
typedef int(*grpc_compression_options_is_algorithm_enabled_type)(const grpc_compression_options *opts, grpc_compression_algorithm algorithm);
extern grpc_compression_options_is_algorithm_enabled_type grpc_compression_options_is_algorithm_enabled_import;
#define grpc_compression_options_is_algorithm_enabled grpc_compression_options_is_algorithm_enabled_import
+typedef int(*grpc_compression_options_is_stream_compression_algorithm_enabled_type)(const grpc_compression_options *opts, grpc_stream_compression_algorithm algorithm);
+extern grpc_compression_options_is_stream_compression_algorithm_enabled_type grpc_compression_options_is_stream_compression_algorithm_enabled_import;
+#define grpc_compression_options_is_stream_compression_algorithm_enabled grpc_compression_options_is_stream_compression_algorithm_enabled_import
typedef void(*grpc_metadata_array_init_type)(grpc_metadata_array *array);
extern grpc_metadata_array_init_type grpc_metadata_array_init_import;
#define grpc_metadata_array_init grpc_metadata_array_init_import
diff --git a/src/ruby/lib/grpc/generic/rpc_desc.rb b/src/ruby/lib/grpc/generic/rpc_desc.rb
index 89cf8ff6a0..6fb6c412fb 100644
--- a/src/ruby/lib/grpc/generic/rpc_desc.rb
+++ b/src/ruby/lib/grpc/generic/rpc_desc.rb
@@ -99,9 +99,13 @@ module GRPC
# event. Send a status of deadline exceeded
GRPC.logger.warn("late call: #{active_call}")
send_status(active_call, DEADLINE_EXCEEDED, 'late')
- rescue StandardError => e
+ rescue StandardError, NotImplementedError => e
# This will usuaally be an unhandled error in the handling code.
# Send back a UNKNOWN status to the client
+ #
+ # Note: this intentionally does not map NotImplementedError to
+ # UNIMPLEMENTED because NotImplementedError is intended for low-level
+ # OS interaction (e.g. syscalls) not supported by the current OS.
GRPC.logger.warn("failed handler: #{active_call}; sending status:UNKNOWN")
GRPC.logger.warn(e)
send_status(active_call, UNKNOWN, "#{e.class}: #{e.message}")
diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb
index 0aaf44947a..228c01a92c 100644
--- a/src/ruby/lib/grpc/version.rb
+++ b/src/ruby/lib/grpc/version.rb
@@ -14,5 +14,5 @@
# GRPC contains the General RPC module.
module GRPC
- VERSION = '1.5.0.dev'
+ VERSION = '1.7.0.dev'
end
diff --git a/src/ruby/spec/generic/rpc_desc_spec.rb b/src/ruby/spec/generic/rpc_desc_spec.rb
index be578c40d3..6852b9804f 100644
--- a/src/ruby/spec/generic/rpc_desc_spec.rb
+++ b/src/ruby/spec/generic/rpc_desc_spec.rb
@@ -52,6 +52,13 @@ describe GRPC::RpcDesc do
this_desc.run_server_method(@call, method(:other_error))
end
+ it 'sends status UNKNOWN if NotImplementedErrors are raised' do
+ expect(@call).to receive(:read_unary_request).once.and_return(Object.new)
+ expect(@call).to receive(:send_status).once.with(
+ UNKNOWN, not_implemented_error_msg, false, metadata: {})
+ this_desc.run_server_method(@call, method(:not_implemented))
+ end
+
it 'absorbs CallError with no further action' do
expect(@call).to receive(:read_unary_request).once.and_raise(CallError)
blk = proc do
@@ -102,6 +109,12 @@ describe GRPC::RpcDesc do
@client_streamer.run_server_method(@call, method(:other_error_alt))
end
+ it 'sends status UNKNOWN if NotImplementedErrors are raised' do
+ expect(@call).to receive(:send_status).once.with(
+ UNKNOWN, not_implemented_error_msg, false, metadata: {})
+ @client_streamer.run_server_method(@call, method(:not_implemented_alt))
+ end
+
it 'absorbs CallError with no further action' do
expect(@call).to receive(:server_unary_response).once.and_raise(
CallError)
@@ -166,6 +179,14 @@ describe GRPC::RpcDesc do
@bidi_streamer.run_server_method(@call, method(:other_error_alt))
end
+ it 'sends status UNKNOWN if NotImplementedErrors are raised' do
+ expect(@call).to receive(:run_server_bidi).and_raise(
+ not_implemented_error)
+ expect(@call).to receive(:send_status).once.with(
+ UNKNOWN, not_implemented_error_msg, false, metadata: {})
+ @bidi_streamer.run_server_method(@call, method(:not_implemented_alt))
+ end
+
it 'closes the stream if there no errors' do
expect(@call).to receive(:run_server_bidi)
expect(@call).to receive(:output_metadata).and_return(fake_md)
@@ -329,8 +350,25 @@ describe GRPC::RpcDesc do
fail(ArgumentError, 'other error')
end
+ def not_implemented(_req, _call)
+ fail not_implemented_error
+ end
+
+ def not_implemented_alt(_call)
+ fail not_implemented_error
+ end
+
def arg_error_msg(error = nil)
error ||= ArgumentError.new('other error')
"#{error.class}: #{error.message}"
end
+
+ def not_implemented_error
+ NotImplementedError.new('some OS feature not implemented')
+ end
+
+ def not_implemented_error_msg(error = nil)
+ error ||= not_implemented_error
+ "#{error.class}: #{error.message}"
+ end
end
diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb
index 4c5293241d..ea0c4ae56c 100644
--- a/src/ruby/tools/version.rb
+++ b/src/ruby/tools/version.rb
@@ -14,6 +14,6 @@
module GRPC
module Tools
- VERSION = '1.5.0.dev'
+ VERSION = '1.7.0.dev'
end
end