grpc 1.3.4 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of grpc might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Makefile +581 -450
- data/include/grpc/census.h +49 -49
- data/include/grpc/grpc.h +16 -70
- data/include/grpc/grpc_security.h +59 -59
- data/include/grpc/grpc_security_constants.h +9 -9
- data/include/grpc/impl/codegen/atm.h +1 -1
- data/include/grpc/impl/codegen/atm_windows.h +4 -4
- data/include/grpc/impl/codegen/byte_buffer_reader.h +2 -2
- data/include/grpc/impl/codegen/compression_types.h +4 -5
- data/include/grpc/impl/codegen/gpr_slice.h +5 -5
- data/include/grpc/impl/codegen/gpr_types.h +6 -7
- data/include/grpc/impl/codegen/grpc_types.h +128 -59
- data/include/grpc/impl/codegen/port_platform.h +6 -0
- data/include/grpc/impl/codegen/propagation_bits.h +2 -2
- data/include/grpc/impl/codegen/slice.h +13 -12
- data/include/grpc/impl/codegen/status.h +23 -18
- data/include/grpc/impl/codegen/sync.h +1 -1
- data/include/grpc/load_reporting.h +6 -6
- data/include/grpc/slice.h +47 -25
- data/include/grpc/slice_buffer.h +18 -14
- data/include/grpc/support/alloc.h +7 -7
- data/include/grpc/support/cmdline.h +10 -10
- data/include/grpc/support/cpu.h +3 -3
- data/include/grpc/support/histogram.h +1 -1
- data/include/grpc/support/host_port.h +2 -2
- data/include/grpc/support/log.h +9 -9
- data/include/grpc/support/log_windows.h +1 -1
- data/include/grpc/support/string_util.h +3 -3
- data/include/grpc/support/subprocess.h +3 -3
- data/include/grpc/support/sync.h +31 -31
- data/include/grpc/support/thd.h +11 -11
- data/include/grpc/support/time.h +12 -12
- data/include/grpc/support/tls.h +1 -1
- data/include/grpc/support/tls_gcc.h +2 -2
- data/include/grpc/support/tls_msvc.h +1 -1
- data/include/grpc/support/tls_pthread.h +1 -1
- data/include/grpc/support/useful.h +2 -2
- data/include/grpc/support/workaround_list.h +46 -0
- data/src/core/ext/census/context.c +1 -1
- data/src/core/ext/census/intrusive_hash_map.c +319 -0
- data/src/core/ext/census/intrusive_hash_map.h +167 -0
- data/src/core/ext/census/intrusive_hash_map_internal.h +63 -0
- data/src/core/ext/census/resource.c +3 -1
- data/src/core/ext/filters/client_channel/channel_connectivity.c +1 -1
- data/src/core/ext/filters/client_channel/client_channel.c +173 -103
- data/src/core/ext/filters/client_channel/client_channel_plugin.c +3 -2
- data/src/core/ext/filters/client_channel/lb_policy.c +2 -1
- data/src/core/ext/filters/client_channel/lb_policy.h +8 -7
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c +153 -0
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h +42 -0
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c +405 -102
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c +133 -0
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h +65 -0
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c +90 -51
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h +7 -1
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c +19 -8
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h +63 -34
- data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.c +2 -1
- data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c +188 -294
- data/src/core/ext/filters/client_channel/lb_policy_factory.c +28 -5
- data/src/core/ext/filters/client_channel/lb_policy_factory.h +18 -4
- data/src/core/ext/filters/client_channel/parse_address.c +90 -59
- data/src/core/ext/filters/client_channel/parse_address.h +17 -8
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c +11 -7
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c +59 -14
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +6 -0
- data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c +3 -3
- data/src/core/ext/filters/client_channel/subchannel.c +20 -17
- data/src/core/ext/filters/client_channel/subchannel.h +1 -0
- data/src/core/ext/filters/client_channel/subchannel_index.c +11 -1
- data/src/core/ext/filters/client_channel/uri_parser.c +36 -22
- data/src/core/ext/filters/client_channel/uri_parser.h +1 -1
- data/src/core/{lib/channel → ext/filters/deadline}/deadline_filter.c +42 -17
- data/src/core/{lib/channel → ext/filters/deadline}/deadline_filter.h +8 -9
- data/src/core/{lib/channel → ext/filters/http/client}/http_client_filter.c +19 -11
- data/src/core/{lib/channel → ext/filters/http/client}/http_client_filter.h +3 -6
- data/src/core/ext/filters/http/http_filters_plugin.c +104 -0
- data/src/core/{lib/channel/compress_filter.c → ext/filters/http/message_compress/message_compress_filter.c} +124 -23
- data/src/core/{lib/channel/compress_filter.h → ext/filters/http/message_compress/message_compress_filter.h} +5 -6
- data/src/core/{lib/channel → ext/filters/http/server}/http_server_filter.c +4 -6
- data/src/core/{lib/channel → ext/filters/http/server}/http_server_filter.h +3 -3
- data/src/core/ext/filters/load_reporting/load_reporting.c +2 -25
- data/src/core/ext/filters/load_reporting/load_reporting_filter.c +26 -1
- data/src/core/ext/filters/max_age/max_age_filter.c +14 -14
- data/src/core/{lib/channel → ext/filters/message_size}/message_size_filter.c +91 -47
- data/src/core/{lib/channel → ext/filters/message_size}/message_size_filter.h +3 -3
- data/src/core/ext/filters/workarounds/workaround_cronet_compression_filter.c +223 -0
- data/src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h +40 -0
- data/src/core/ext/filters/workarounds/workaround_utils.c +65 -0
- data/src/core/ext/filters/workarounds/workaround_utils.h +52 -0
- data/src/core/ext/transport/chttp2/client/insecure/channel_create.c +1 -1
- data/src/core/ext/transport/chttp2/server/chttp2_server.c +3 -2
- data/src/core/ext/transport/chttp2/transport/bin_decoder.c +2 -2
- data/src/core/ext/transport/chttp2/transport/bin_encoder.c +3 -3
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.c +319 -175
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +3 -2
- data/src/core/ext/transport/chttp2/transport/frame_data.c +203 -164
- data/src/core/ext/transport/chttp2/transport/frame_data.h +8 -14
- data/src/core/ext/transport/chttp2/transport/frame_goaway.c +1 -1
- data/src/core/ext/transport/chttp2/transport/frame_ping.c +1 -1
- data/src/core/ext/transport/chttp2/transport/frame_rst_stream.c +1 -1
- data/src/core/ext/transport/chttp2/transport/frame_settings.c +5 -5
- data/src/core/ext/transport/chttp2/transport/frame_window_update.c +1 -1
- data/src/core/ext/transport/chttp2/transport/hpack_encoder.c +4 -4
- data/src/core/ext/transport/chttp2/transport/hpack_parser.c +2 -4
- data/src/core/ext/transport/chttp2/transport/hpack_table.c +4 -3
- data/src/core/ext/transport/chttp2/transport/internal.h +50 -33
- data/src/core/ext/transport/chttp2/transport/parsing.c +10 -11
- data/src/core/ext/transport/chttp2/transport/writing.c +32 -13
- data/src/core/lib/channel/channel_args.c +30 -9
- data/src/core/lib/channel/channel_args.h +5 -1
- data/src/core/lib/channel/channel_stack.c +1 -1
- data/src/core/lib/channel/channel_stack.h +2 -2
- data/src/core/lib/channel/channel_stack_builder.c +13 -1
- data/src/core/lib/channel/channel_stack_builder.h +5 -1
- data/src/core/lib/channel/connected_channel.c +3 -1
- data/src/core/lib/channel/context.h +2 -2
- data/src/core/lib/compression/message_compress.c +2 -2
- data/src/core/lib/debug/trace.c +13 -6
- data/src/core/lib/debug/trace.h +27 -1
- data/src/core/lib/http/httpcli.c +1 -1
- data/src/core/lib/http/httpcli_security_connector.c +9 -11
- data/src/core/lib/http/parser.c +2 -2
- data/src/core/lib/http/parser.h +2 -1
- data/src/core/lib/iomgr/combiner.c +6 -6
- data/src/core/lib/iomgr/combiner.h +2 -1
- data/src/core/lib/iomgr/error.c +12 -5
- data/src/core/lib/iomgr/error.h +13 -13
- data/src/core/lib/iomgr/ev_epoll1_linux.c +984 -0
- data/src/core/lib/iomgr/ev_epoll1_linux.h +44 -0
- data/src/core/lib/iomgr/ev_epoll_limited_pollers_linux.c +2146 -0
- data/src/core/lib/iomgr/ev_epoll_limited_pollers_linux.h +43 -0
- data/src/core/lib/iomgr/ev_epoll_thread_pool_linux.c +1337 -0
- data/src/core/lib/iomgr/ev_epoll_thread_pool_linux.h +43 -0
- data/src/core/lib/iomgr/ev_epollex_linux.c +1511 -0
- data/src/core/lib/iomgr/ev_epollex_linux.h +43 -0
- data/src/core/lib/iomgr/{ev_epoll_linux.c → ev_epollsig_linux.c} +41 -33
- data/src/core/lib/iomgr/{ev_epoll_linux.h → ev_epollsig_linux.h} +4 -4
- data/src/core/lib/iomgr/ev_poll_posix.c +12 -27
- data/src/core/lib/iomgr/ev_poll_posix.h +2 -2
- data/src/core/lib/iomgr/ev_posix.c +22 -8
- data/src/core/lib/iomgr/ev_posix.h +4 -3
- data/src/core/lib/iomgr/ev_windows.c +43 -0
- data/src/core/lib/iomgr/exec_ctx.c +5 -0
- data/src/core/lib/iomgr/exec_ctx.h +2 -0
- data/src/core/lib/iomgr/iomgr.c +4 -0
- data/src/core/lib/iomgr/iomgr.h +3 -0
- data/src/core/lib/iomgr/is_epollexclusive_available.c +116 -0
- data/src/core/lib/iomgr/is_epollexclusive_available.h +41 -0
- data/src/core/lib/iomgr/lockfree_event.c +16 -0
- data/src/core/lib/iomgr/pollset.h +2 -5
- data/src/core/lib/iomgr/pollset_uv.c +1 -1
- data/src/core/lib/iomgr/pollset_windows.c +3 -3
- data/src/core/lib/iomgr/resource_quota.c +9 -8
- data/src/core/lib/iomgr/resource_quota.h +2 -1
- data/src/core/lib/iomgr/sockaddr_utils.h +1 -1
- data/src/core/lib/iomgr/socket_mutator.h +2 -0
- data/src/core/lib/iomgr/sys_epoll_wrapper.h +43 -0
- data/src/core/lib/iomgr/tcp_client_posix.c +6 -6
- data/src/core/lib/iomgr/tcp_client_uv.c +3 -3
- data/src/core/lib/iomgr/tcp_posix.c +7 -7
- data/src/core/lib/iomgr/tcp_posix.h +2 -1
- data/src/core/lib/iomgr/tcp_server_posix.c +1 -1
- data/src/core/lib/iomgr/tcp_uv.c +6 -6
- data/src/core/lib/iomgr/tcp_uv.h +2 -1
- data/src/core/lib/iomgr/tcp_windows.c +1 -1
- data/src/core/lib/iomgr/timer_generic.c +24 -25
- data/src/core/lib/iomgr/timer_manager.c +276 -0
- data/src/core/lib/iomgr/timer_manager.h +52 -0
- data/src/core/lib/iomgr/timer_uv.c +6 -0
- data/src/core/lib/iomgr/udp_server.c +42 -9
- data/src/core/lib/iomgr/udp_server.h +3 -1
- data/src/core/lib/security/credentials/credentials.c +0 -1
- data/src/core/lib/security/credentials/fake/fake_credentials.c +23 -0
- data/src/core/lib/security/credentials/fake/fake_credentials.h +12 -9
- data/src/core/lib/security/credentials/google_default/google_default_credentials.c +1 -1
- data/src/core/lib/security/credentials/jwt/jwt_credentials.c +1 -1
- data/src/core/lib/security/credentials/oauth2/oauth2_credentials.c +1 -1
- data/src/core/lib/security/credentials/ssl/ssl_credentials.c +24 -53
- data/src/core/lib/security/transport/client_auth_filter.c +9 -3
- data/src/core/lib/security/transport/secure_endpoint.c +7 -7
- data/src/core/lib/security/transport/secure_endpoint.h +1 -1
- data/src/core/lib/security/transport/security_connector.c +45 -57
- data/src/core/lib/security/transport/security_connector.h +10 -14
- data/src/core/lib/security/transport/security_handshaker.c +123 -97
- data/src/core/lib/slice/b64.c +1 -1
- data/src/core/lib/slice/percent_encoding.c +3 -3
- data/src/core/lib/slice/slice.c +66 -33
- data/src/core/lib/slice/slice_buffer.c +25 -6
- data/src/core/lib/slice/slice_hash_table.c +33 -35
- data/src/core/lib/slice/slice_hash_table.h +7 -12
- data/src/core/lib/support/atomic.h +45 -0
- data/src/core/lib/support/atomic_with_atm.h +70 -0
- data/src/core/lib/support/atomic_with_std.h +48 -0
- data/src/core/lib/support/avl.c +14 -14
- data/src/core/lib/support/cmdline.c +3 -3
- data/src/core/lib/support/histogram.c +2 -2
- data/src/core/lib/support/host_port.c +1 -1
- data/src/core/lib/support/memory.h +74 -0
- data/src/core/lib/support/mpscq.c +36 -2
- data/src/core/lib/support/mpscq.h +28 -1
- data/src/core/lib/support/stack_lockfree.c +3 -36
- data/src/core/lib/support/string.c +12 -12
- data/src/core/lib/support/string_posix.c +1 -1
- data/src/core/lib/support/subprocess_posix.c +2 -2
- data/src/core/lib/support/thd_posix.c +1 -1
- data/src/core/lib/support/time_posix.c +8 -0
- data/src/core/lib/support/tmpfile_posix.c +10 -10
- data/src/core/lib/surface/alarm.c +3 -1
- data/src/core/lib/surface/api_trace.c +2 -1
- data/src/core/lib/surface/api_trace.h +2 -2
- data/src/core/lib/surface/byte_buffer_reader.c +1 -1
- data/src/core/lib/surface/call.c +65 -22
- data/src/core/lib/surface/call.h +4 -2
- data/src/core/lib/surface/channel_init.c +2 -19
- data/src/core/lib/surface/channel_stack_type.c +18 -0
- data/src/core/lib/surface/channel_stack_type.h +2 -0
- data/src/core/lib/surface/completion_queue.c +694 -247
- data/src/core/lib/surface/completion_queue.h +30 -13
- data/src/core/lib/surface/completion_queue_factory.c +24 -9
- data/src/core/lib/surface/init.c +1 -52
- data/src/core/lib/surface/{lame_client.c → lame_client.cc} +37 -26
- data/src/core/lib/surface/server.c +79 -110
- data/src/core/lib/surface/server.h +2 -1
- data/src/core/lib/surface/version.c +2 -2
- data/src/core/lib/transport/bdp_estimator.c +25 -9
- data/src/core/lib/transport/bdp_estimator.h +7 -1
- data/src/core/lib/transport/byte_stream.c +23 -9
- data/src/core/lib/transport/byte_stream.h +15 -6
- data/src/core/lib/transport/connectivity_state.c +6 -6
- data/src/core/lib/transport/connectivity_state.h +2 -1
- data/src/core/lib/transport/service_config.c +6 -13
- data/src/core/lib/transport/service_config.h +2 -2
- data/src/core/lib/transport/static_metadata.c +403 -389
- data/src/core/lib/transport/static_metadata.h +127 -114
- data/src/core/plugin_registry/grpc_plugin_registry.c +16 -0
- data/src/core/tsi/fake_transport_security.c +5 -4
- data/src/core/tsi/ssl_transport_security.c +71 -82
- data/src/core/tsi/ssl_transport_security.h +39 -61
- data/src/core/tsi/transport_security.c +83 -2
- data/src/core/tsi/transport_security.h +27 -2
- data/src/core/tsi/transport_security_adapter.c +236 -0
- data/src/core/tsi/transport_security_adapter.h +62 -0
- data/src/core/tsi/transport_security_interface.h +179 -66
- data/src/ruby/ext/grpc/extconf.rb +2 -1
- data/src/ruby/ext/grpc/rb_byte_buffer.c +8 -6
- data/src/ruby/ext/grpc/rb_call.c +56 -48
- data/src/ruby/ext/grpc/rb_call.h +3 -4
- data/src/ruby/ext/grpc/rb_call_credentials.c +23 -22
- data/src/ruby/ext/grpc/rb_channel.c +2 -3
- data/src/ruby/ext/grpc/rb_channel_args.c +11 -9
- data/src/ruby/ext/grpc/rb_channel_credentials.c +16 -12
- data/src/ruby/ext/grpc/rb_completion_queue.c +7 -9
- data/src/ruby/ext/grpc/rb_compression_options.c +7 -6
- data/src/ruby/ext/grpc/rb_event_thread.c +10 -12
- data/src/ruby/ext/grpc/rb_event_thread.h +1 -2
- data/src/ruby/ext/grpc/rb_grpc.c +11 -15
- data/src/ruby/ext/grpc/rb_grpc.h +2 -2
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +16 -6
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +25 -10
- data/src/ruby/ext/grpc/rb_server.c +26 -28
- data/src/ruby/lib/grpc/grpc.rb +1 -1
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/third_party/cares/config_linux/ares_config.h +36 -2
- data/third_party/zlib/adler32.c +14 -7
- data/third_party/zlib/compress.c +24 -18
- data/third_party/zlib/crc32.c +29 -12
- data/third_party/zlib/deflate.c +499 -303
- data/third_party/zlib/deflate.h +19 -16
- data/third_party/zlib/gzguts.h +16 -7
- data/third_party/zlib/gzlib.c +17 -14
- data/third_party/zlib/gzread.c +108 -48
- data/third_party/zlib/gzwrite.c +210 -122
- data/third_party/zlib/infback.c +2 -2
- data/third_party/zlib/inffast.c +34 -51
- data/third_party/zlib/inflate.c +86 -37
- data/third_party/zlib/inflate.h +7 -4
- data/third_party/zlib/inftrees.c +12 -14
- data/third_party/zlib/trees.c +38 -61
- data/third_party/zlib/uncompr.c +66 -32
- data/third_party/zlib/zconf.h +32 -9
- data/third_party/zlib/zlib.h +298 -154
- data/third_party/zlib/zutil.c +25 -24
- data/third_party/zlib/zutil.h +35 -17
- metadata +63 -30
@@ -0,0 +1,167 @@
|
|
1
|
+
/*
|
2
|
+
*
|
3
|
+
* Copyright 2017, Google Inc.
|
4
|
+
* All rights reserved.
|
5
|
+
*
|
6
|
+
* Redistribution and use in source and binary forms, with or without
|
7
|
+
* modification, are permitted provided that the following conditions are
|
8
|
+
* met:
|
9
|
+
*
|
10
|
+
* * Redistributions of source code must retain the above copyright
|
11
|
+
* notice, this list of conditions and the following disclaimer.
|
12
|
+
* * Redistributions in binary form must reproduce the above
|
13
|
+
* copyright notice, this list of conditions and the following disclaimer
|
14
|
+
* in the documentation and/or other materials provided with the
|
15
|
+
* distribution.
|
16
|
+
* * Neither the name of Google Inc. nor the names of its
|
17
|
+
* contributors may be used to endorse or promote products derived from
|
18
|
+
* this software without specific prior written permission.
|
19
|
+
*
|
20
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
21
|
+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
22
|
+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
23
|
+
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
24
|
+
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
25
|
+
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
26
|
+
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
27
|
+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
28
|
+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
29
|
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
30
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
31
|
+
*
|
32
|
+
*/
|
33
|
+
|
34
|
+
#ifndef GRPC_CORE_EXT_CENSUS_INTRUSIVE_HASH_MAP_H
|
35
|
+
#define GRPC_CORE_EXT_CENSUS_INTRUSIVE_HASH_MAP_H
|
36
|
+
|
37
|
+
#include "src/core/ext/census/intrusive_hash_map_internal.h"
|
38
|
+
|
39
|
+
/* intrusive_hash_map is a fast chained hash table. This hash map is faster than
|
40
|
+
* a dense hash map when the application calls insert and erase more often than
|
41
|
+
* find. When the workload is dominated by find() a dense hash map may be
|
42
|
+
* faster.
|
43
|
+
*
|
44
|
+
* intrusive_hash_map uses an intrusive header placed within a user defined
|
45
|
+
* struct. The header field IHM_key MUST be set to a valid value before
|
46
|
+
* insertion into the hash map or undefined behavior may occur. The header field
|
47
|
+
* IHM_hash_link MUST to be set to NULL initially.
|
48
|
+
*
|
49
|
+
* EXAMPLE USAGE:
|
50
|
+
*
|
51
|
+
* typedef struct string_item {
|
52
|
+
* INTRUSIVE_HASH_MAP_HEADER;
|
53
|
+
* // User data.
|
54
|
+
* char *str_buf;
|
55
|
+
* uint16_t len;
|
56
|
+
* } string_item;
|
57
|
+
*
|
58
|
+
* static string_item *make_string_item(uint64_t key, const char *buf,
|
59
|
+
* uint16_t len) {
|
60
|
+
* string_item *item = (string_item *)gpr_malloc(sizeof(string_item));
|
61
|
+
* item->IHM_key = key;
|
62
|
+
* item->IHM_hash_link = NULL;
|
63
|
+
* item->len = len;
|
64
|
+
* item->str_buf = (char *)malloc(len);
|
65
|
+
* memcpy(item->str_buf, buf, len);
|
66
|
+
* return item;
|
67
|
+
* }
|
68
|
+
*
|
69
|
+
* intrusive_hash_map hash_map;
|
70
|
+
* intrusive_hash_map_init(&hash_map, 4);
|
71
|
+
* string_item *new_item1 = make_string_item(10, "test1", 5);
|
72
|
+
* bool ok = intrusive_hash_map_insert(&hash_map, (hm_item *)new_item1);
|
73
|
+
*
|
74
|
+
* string_item *item1 =
|
75
|
+
* (string_item *)intrusive_hash_map_find(&hash_map, 10);
|
76
|
+
*/
|
77
|
+
|
78
|
+
/* Hash map item. Stores key and a pointer to the actual object. A user defined
|
79
|
+
* version of this can be passed in provided the first 2 entries (key and
|
80
|
+
* hash_link) are the same. These entries must be first in the user defined
|
81
|
+
* struct. Pointer to struct will need to be cast as (hm_item *) when passed to
|
82
|
+
* hash map. This allows it to be intrusive. */
|
83
|
+
typedef struct hm_item {
|
84
|
+
uint64_t key;
|
85
|
+
struct hm_item *hash_link;
|
86
|
+
/* Optional user defined data after this. */
|
87
|
+
} hm_item;
|
88
|
+
|
89
|
+
/* Macro provided for ease of use. This must be first in the user defined
|
90
|
+
* struct (i.e. uint64_t key and hm_item * must be the first two elements in
|
91
|
+
* that order). */
|
92
|
+
#define INTRUSIVE_HASH_MAP_HEADER \
|
93
|
+
uint64_t IHM_key; \
|
94
|
+
struct hm_item *IHM_hash_link
|
95
|
+
|
96
|
+
/* Index struct which acts as a pseudo-iterator within the hash map. */
|
97
|
+
typedef struct hm_index {
|
98
|
+
uint32_t bucket_index; // hash map bucket index.
|
99
|
+
hm_item *item; // Pointer to hm_item within the hash map.
|
100
|
+
} hm_index;
|
101
|
+
|
102
|
+
/* Returns true if two hm_indices point to the same object within the hash map
|
103
|
+
* and false otherwise. */
|
104
|
+
inline bool hm_index_compare(const hm_index *A, const hm_index *B) {
|
105
|
+
return (A->item == B->item && A->bucket_index == B->bucket_index);
|
106
|
+
}
|
107
|
+
|
108
|
+
/*
|
109
|
+
* Helper functions for iterating over the hash map.
|
110
|
+
*/
|
111
|
+
|
112
|
+
/* On return idx will contain an invalid index which is always equal to
|
113
|
+
* hash_map->buckets.size_ */
|
114
|
+
void intrusive_hash_map_end(const intrusive_hash_map *hash_map, hm_index *idx);
|
115
|
+
|
116
|
+
/* Iterates index to the next valid entry in the hash map and stores the
|
117
|
+
* index within idx. If end of table is reached, idx will contain the same
|
118
|
+
* values as if intrusive_hash_map_end() was called. */
|
119
|
+
void intrusive_hash_map_next(const intrusive_hash_map *hash_map, hm_index *idx);
|
120
|
+
|
121
|
+
/* On return, idx will contain the index of the first non-null entry in the hash
|
122
|
+
* map. If the hash map is empty, idx will contain the same values as if
|
123
|
+
* intrusive_hash_map_end() was called. */
|
124
|
+
void intrusive_hash_map_begin(const intrusive_hash_map *hash_map,
|
125
|
+
hm_index *idx);
|
126
|
+
|
127
|
+
/* Initialize intrusive hash map data structure. This must be called before
|
128
|
+
* the hash map can be used. The initial size of an intrusive hash map will be
|
129
|
+
* 2^initial_log2_map_size (valid range is [0, 31]). */
|
130
|
+
void intrusive_hash_map_init(intrusive_hash_map *hash_map,
|
131
|
+
uint32_t initial_log2_map_size);
|
132
|
+
|
133
|
+
/* Returns true if the hash map is empty and false otherwise. */
|
134
|
+
bool intrusive_hash_map_empty(const intrusive_hash_map *hash_map);
|
135
|
+
|
136
|
+
/* Returns the number of elements currently in the hash map. */
|
137
|
+
size_t intrusive_hash_map_size(const intrusive_hash_map *hash_map);
|
138
|
+
|
139
|
+
/* Find a hm_item within the hash map by key. Returns NULL if item was not
|
140
|
+
* found. */
|
141
|
+
hm_item *intrusive_hash_map_find(const intrusive_hash_map *hash_map,
|
142
|
+
uint64_t key);
|
143
|
+
|
144
|
+
/* Erase the hm_item that corresponds with key. If the hm_item is found, return
|
145
|
+
* the pointer to the hm_item. Else returns NULL. */
|
146
|
+
hm_item *intrusive_hash_map_erase(intrusive_hash_map *hash_map, uint64_t key);
|
147
|
+
|
148
|
+
/* Attempts to insert a new hm_item into the hash map. If an element with the
|
149
|
+
* same key already exists, it will not insert the new item and return false.
|
150
|
+
* Otherwise, it will insert the new item and return true. */
|
151
|
+
bool intrusive_hash_map_insert(intrusive_hash_map *hash_map, hm_item *item);
|
152
|
+
|
153
|
+
/* Clears entire contents of the hash map, but leaves internal data structure
|
154
|
+
* untouched. Second argument takes a function pointer to a function that will
|
155
|
+
* free the object designated by the user and pointed to by hash_map->value. */
|
156
|
+
void intrusive_hash_map_clear(intrusive_hash_map *hash_map,
|
157
|
+
void (*free_object)(void *));
|
158
|
+
|
159
|
+
/* Erase all contents of hash map and free the memory. Hash map is invalid
|
160
|
+
* after calling this function and cannot be used until it has been
|
161
|
+
* reinitialized (intrusive_hash_map_init()). This function takes a function
|
162
|
+
* pointer to a function that will free the object designated by the user and
|
163
|
+
* pointed to by hash_map->value. */
|
164
|
+
void intrusive_hash_map_free(intrusive_hash_map *hash_map,
|
165
|
+
void (*free_object)(void *));
|
166
|
+
|
167
|
+
#endif /* GRPC_CORE_EXT_CENSUS_INTRUSIVE_HASH_MAP_H */
|
@@ -0,0 +1,63 @@
|
|
1
|
+
/*
|
2
|
+
*
|
3
|
+
* Copyright 2017, Google Inc.
|
4
|
+
* All rights reserved.
|
5
|
+
*
|
6
|
+
* Redistribution and use in source and binary forms, with or without
|
7
|
+
* modification, are permitted provided that the following conditions are
|
8
|
+
* met:
|
9
|
+
*
|
10
|
+
* * Redistributions of source code must retain the above copyright
|
11
|
+
* notice, this list of conditions and the following disclaimer.
|
12
|
+
* * Redistributions in binary form must reproduce the above
|
13
|
+
* copyright notice, this list of conditions and the following disclaimer
|
14
|
+
* in the documentation and/or other materials provided with the
|
15
|
+
* distribution.
|
16
|
+
* * Neither the name of Google Inc. nor the names of its
|
17
|
+
* contributors may be used to endorse or promote products derived from
|
18
|
+
* this software without specific prior written permission.
|
19
|
+
*
|
20
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
21
|
+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
22
|
+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
23
|
+
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
24
|
+
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
25
|
+
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
26
|
+
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
27
|
+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
28
|
+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
29
|
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
30
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
31
|
+
*
|
32
|
+
*/
|
33
|
+
|
34
|
+
#ifndef GRPC_CORE_EXT_CENSUS_INTRUSIVE_HASH_MAP_INTERNAL_H
|
35
|
+
#define GRPC_CORE_EXT_CENSUS_INTRUSIVE_HASH_MAP_INTERNAL_H
|
36
|
+
|
37
|
+
#include <grpc/support/alloc.h>
|
38
|
+
#include <grpc/support/log.h>
|
39
|
+
#include <grpc/support/useful.h>
|
40
|
+
#include <stdbool.h>
|
41
|
+
|
42
|
+
/* The chunked vector is a data structure that allocates buckets for use in the
|
43
|
+
* hash map. ChunkedVector is logically equivalent to T*[N] (cast void* as
|
44
|
+
* T*). It's internally implemented as an array of 1MB arrays to avoid
|
45
|
+
* allocating large consecutive memory chunks. This is an internal data
|
46
|
+
* structure that should never be accessed directly. */
|
47
|
+
typedef struct chunked_vector {
|
48
|
+
size_t size_;
|
49
|
+
void **first_;
|
50
|
+
void ***rest_;
|
51
|
+
} chunked_vector;
|
52
|
+
|
53
|
+
/* Core intrusive hash map data structure. All internal elements are managed by
|
54
|
+
* functions and should not be altered manually. */
|
55
|
+
typedef struct intrusive_hash_map {
|
56
|
+
uint32_t num_items;
|
57
|
+
uint32_t extend_threshold;
|
58
|
+
uint32_t log2_num_buckets;
|
59
|
+
uint32_t hash_mask;
|
60
|
+
chunked_vector buckets;
|
61
|
+
} intrusive_hash_map;
|
62
|
+
|
63
|
+
#endif /* GRPC_CORE_EXT_CENSUS_INTRUSIVE_HASH_MAP_INTERNAL_H */
|
@@ -223,7 +223,9 @@ size_t allocate_resource(void) {
|
|
223
223
|
if (n_resources == n_defined_resources) {
|
224
224
|
size_t new_n_resources = n_resources ? n_resources * 2 : 2;
|
225
225
|
resource **new_resources = gpr_malloc(new_n_resources * sizeof(resource *));
|
226
|
-
|
226
|
+
if (n_resources != 0) {
|
227
|
+
memcpy(new_resources, resources, n_resources * sizeof(resource *));
|
228
|
+
}
|
227
229
|
memset(new_resources + n_resources, 0,
|
228
230
|
(new_n_resources - n_resources) * sizeof(resource *));
|
229
231
|
gpr_free(resources);
|
@@ -134,7 +134,7 @@ static void partly_done(grpc_exec_ctx *exec_ctx, state_watcher *w,
|
|
134
134
|
gpr_mu_lock(&w->mu);
|
135
135
|
|
136
136
|
if (due_to_completion) {
|
137
|
-
if (grpc_trace_operation_failures) {
|
137
|
+
if (GRPC_TRACER_ON(grpc_trace_operation_failures)) {
|
138
138
|
GRPC_LOG_IF_ERROR("watch_completion_error", GRPC_ERROR_REF(error));
|
139
139
|
}
|
140
140
|
GRPC_ERROR_UNREF(error);
|
@@ -49,9 +49,9 @@
|
|
49
49
|
#include "src/core/ext/filters/client_channel/resolver_registry.h"
|
50
50
|
#include "src/core/ext/filters/client_channel/retry_throttle.h"
|
51
51
|
#include "src/core/ext/filters/client_channel/subchannel.h"
|
52
|
+
#include "src/core/ext/filters/deadline/deadline_filter.h"
|
52
53
|
#include "src/core/lib/channel/channel_args.h"
|
53
54
|
#include "src/core/lib/channel/connected_channel.h"
|
54
|
-
#include "src/core/lib/channel/deadline_filter.h"
|
55
55
|
#include "src/core/lib/iomgr/combiner.h"
|
56
56
|
#include "src/core/lib/iomgr/iomgr.h"
|
57
57
|
#include "src/core/lib/iomgr/polling_entity.h"
|
@@ -96,17 +96,10 @@ static void method_parameters_unref(method_parameters *method_params) {
|
|
96
96
|
}
|
97
97
|
}
|
98
98
|
|
99
|
-
static void *method_parameters_copy(void *value) {
|
100
|
-
return method_parameters_ref(value);
|
101
|
-
}
|
102
|
-
|
103
99
|
static void method_parameters_free(grpc_exec_ctx *exec_ctx, void *value) {
|
104
100
|
method_parameters_unref(value);
|
105
101
|
}
|
106
102
|
|
107
|
-
static const grpc_slice_hash_table_vtable method_parameters_vtable = {
|
108
|
-
method_parameters_free, method_parameters_copy};
|
109
|
-
|
110
103
|
static bool parse_wait_for_ready(grpc_json *field,
|
111
104
|
wait_for_ready_value *wait_for_ready) {
|
112
105
|
if (field->type != GRPC_JSON_TRUE && field->type != GRPC_JSON_FALSE) {
|
@@ -185,6 +178,8 @@ typedef struct client_channel_channel_data {
|
|
185
178
|
grpc_resolver *resolver;
|
186
179
|
/** have we started resolving this channel */
|
187
180
|
bool started_resolving;
|
181
|
+
/** is deadline checking enabled? */
|
182
|
+
bool deadline_checking_enabled;
|
188
183
|
/** client channel factory */
|
189
184
|
grpc_client_channel_factory *client_channel_factory;
|
190
185
|
|
@@ -243,14 +238,23 @@ static void set_channel_connectivity_state_locked(grpc_exec_ctx *exec_ctx,
|
|
243
238
|
grpc_connectivity_state state,
|
244
239
|
grpc_error *error,
|
245
240
|
const char *reason) {
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
241
|
+
/* TODO: Improve failure handling:
|
242
|
+
* - Make it possible for policies to return GRPC_CHANNEL_TRANSIENT_FAILURE.
|
243
|
+
* - Hand over pending picks from old policies during the switch that happens
|
244
|
+
* when resolver provides an update. */
|
245
|
+
if (chand->lb_policy != NULL) {
|
246
|
+
if (state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
|
247
|
+
/* cancel picks with wait_for_ready=false */
|
248
|
+
grpc_lb_policy_cancel_picks_locked(
|
249
|
+
exec_ctx, chand->lb_policy,
|
250
|
+
/* mask= */ GRPC_INITIAL_METADATA_WAIT_FOR_READY,
|
251
|
+
/* check= */ 0, GRPC_ERROR_REF(error));
|
252
|
+
} else if (state == GRPC_CHANNEL_SHUTDOWN) {
|
253
|
+
/* cancel all picks */
|
254
|
+
grpc_lb_policy_cancel_picks_locked(exec_ctx, chand->lb_policy,
|
255
|
+
/* mask= */ 0, /* check= */ 0,
|
256
|
+
GRPC_ERROR_REF(error));
|
257
|
+
}
|
254
258
|
}
|
255
259
|
grpc_connectivity_state_set(exec_ctx, &chand->state_tracker, state, error,
|
256
260
|
reason);
|
@@ -353,6 +357,33 @@ static void parse_retry_throttle_params(const grpc_json *field, void *arg) {
|
|
353
357
|
}
|
354
358
|
}
|
355
359
|
|
360
|
+
// Wrap a closure associated with \a lb_policy. The associated callback (\a
|
361
|
+
// wrapped_on_pick_closure_cb) is responsible for unref'ing \a lb_policy after
|
362
|
+
// scheduling \a wrapped_closure.
|
363
|
+
typedef struct wrapped_on_pick_closure_arg {
|
364
|
+
/* the closure instance using this struct as argument */
|
365
|
+
grpc_closure wrapper_closure;
|
366
|
+
|
367
|
+
/* the original closure. Usually a on_complete/notify cb for pick() and ping()
|
368
|
+
* calls against the internal RR instance, respectively. */
|
369
|
+
grpc_closure *wrapped_closure;
|
370
|
+
|
371
|
+
/* The policy instance related to the closure */
|
372
|
+
grpc_lb_policy *lb_policy;
|
373
|
+
} wrapped_on_pick_closure_arg;
|
374
|
+
|
375
|
+
// Invoke \a arg->wrapped_closure, unref \a arg->lb_policy and free \a arg.
|
376
|
+
static void wrapped_on_pick_closure_cb(grpc_exec_ctx *exec_ctx, void *arg,
|
377
|
+
grpc_error *error) {
|
378
|
+
wrapped_on_pick_closure_arg *wc_arg = arg;
|
379
|
+
GPR_ASSERT(wc_arg != NULL);
|
380
|
+
GPR_ASSERT(wc_arg->wrapped_closure != NULL);
|
381
|
+
GPR_ASSERT(wc_arg->lb_policy != NULL);
|
382
|
+
grpc_closure_run(exec_ctx, wc_arg->wrapped_closure, GRPC_ERROR_REF(error));
|
383
|
+
GRPC_LB_POLICY_UNREF(exec_ctx, wc_arg->lb_policy, "pick_subchannel_wrapping");
|
384
|
+
gpr_free(wc_arg);
|
385
|
+
}
|
386
|
+
|
356
387
|
static void on_resolver_result_changed_locked(grpc_exec_ctx *exec_ctx,
|
357
388
|
void *arg, grpc_error *error) {
|
358
389
|
channel_data *chand = arg;
|
@@ -376,26 +407,24 @@ static void on_resolver_result_changed_locked(grpc_exec_ctx *exec_ctx,
|
|
376
407
|
GPR_ASSERT(channel_arg->type == GRPC_ARG_STRING);
|
377
408
|
lb_policy_name = channel_arg->value.string;
|
378
409
|
}
|
379
|
-
// Special case: If
|
380
|
-
//
|
381
|
-
// resolver actually specified.
|
410
|
+
// Special case: If at least one balancer address is present, we use
|
411
|
+
// the grpclb policy, regardless of what the resolver actually specified.
|
382
412
|
channel_arg =
|
383
413
|
grpc_channel_args_find(chand->resolver_result, GRPC_ARG_LB_ADDRESSES);
|
384
414
|
if (channel_arg != NULL && channel_arg->type == GRPC_ARG_POINTER) {
|
385
415
|
grpc_lb_addresses *addresses = channel_arg->value.pointer.p;
|
386
|
-
bool
|
416
|
+
bool found_balancer_address = false;
|
387
417
|
for (size_t i = 0; i < addresses->num_addresses; ++i) {
|
388
|
-
if (
|
389
|
-
|
418
|
+
if (addresses->addresses[i].is_balancer) {
|
419
|
+
found_balancer_address = true;
|
390
420
|
break;
|
391
421
|
}
|
392
422
|
}
|
393
|
-
if (
|
423
|
+
if (found_balancer_address) {
|
394
424
|
if (lb_policy_name != NULL && strcmp(lb_policy_name, "grpclb") != 0) {
|
395
425
|
gpr_log(GPR_INFO,
|
396
|
-
"resolver requested LB policy %s but provided
|
397
|
-
"
|
398
|
-
"policy",
|
426
|
+
"resolver requested LB policy %s but provided at least one "
|
427
|
+
"balancer address -- forcing use of grpclb LB policy",
|
399
428
|
lb_policy_name);
|
400
429
|
}
|
401
430
|
lb_policy_name = "grpclb";
|
@@ -441,7 +470,7 @@ static void on_resolver_result_changed_locked(grpc_exec_ctx *exec_ctx,
|
|
441
470
|
grpc_uri_destroy(uri);
|
442
471
|
method_params_table = grpc_service_config_create_method_config_table(
|
443
472
|
exec_ctx, service_config, method_parameters_create_from_json,
|
444
|
-
|
473
|
+
method_parameters_free);
|
445
474
|
grpc_service_config_destroy(service_config);
|
446
475
|
}
|
447
476
|
}
|
@@ -689,6 +718,8 @@ static grpc_error *cc_init_channel_elem(grpc_exec_ctx *exec_ctx,
|
|
689
718
|
if (chand->resolver == NULL) {
|
690
719
|
return GRPC_ERROR_CREATE_FROM_STATIC_STRING("resolver creation failed");
|
691
720
|
}
|
721
|
+
chand->deadline_checking_enabled =
|
722
|
+
grpc_deadline_checking_enabled(args->channel_args);
|
692
723
|
return GRPC_ERROR_NONE;
|
693
724
|
}
|
694
725
|
|
@@ -743,12 +774,6 @@ static void cc_destroy_channel_elem(grpc_exec_ctx *exec_ctx,
|
|
743
774
|
|
744
775
|
#define CANCELLED_CALL ((grpc_subchannel_call *)1)
|
745
776
|
|
746
|
-
typedef enum {
|
747
|
-
/* zero so that it can be default-initialized */
|
748
|
-
GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING = 0,
|
749
|
-
GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL
|
750
|
-
} subchannel_creation_phase;
|
751
|
-
|
752
777
|
/** Call data. Holds a pointer to grpc_subchannel_call and the
|
753
778
|
associated machinery to create such a pointer.
|
754
779
|
Handles queueing of stream ops until a call object is ready, waiting
|
@@ -776,8 +801,9 @@ typedef struct client_channel_call_data {
|
|
776
801
|
gpr_atm subchannel_call;
|
777
802
|
gpr_arena *arena;
|
778
803
|
|
779
|
-
|
804
|
+
bool pick_pending;
|
780
805
|
grpc_connected_subchannel *connected_subchannel;
|
806
|
+
grpc_call_context_element subchannel_call_context[GRPC_CONTEXT_COUNT];
|
781
807
|
grpc_polling_entity *pollent;
|
782
808
|
|
783
809
|
grpc_transport_stream_op_batch **waiting_ops;
|
@@ -878,12 +904,14 @@ static void apply_final_configuration_locked(grpc_exec_ctx *exec_ctx,
|
|
878
904
|
/* apply service-config level configuration to the call (now that we're
|
879
905
|
* certain it exists) */
|
880
906
|
call_data *calld = elem->call_data;
|
907
|
+
channel_data *chand = elem->channel_data;
|
881
908
|
gpr_timespec per_method_deadline;
|
882
909
|
if (set_call_method_params_from_service_config_locked(exec_ctx, elem,
|
883
910
|
&per_method_deadline)) {
|
884
911
|
// If the deadline from the service config is shorter than the one
|
885
912
|
// from the client API, reset the deadline timer.
|
886
|
-
if (
|
913
|
+
if (chand->deadline_checking_enabled &&
|
914
|
+
gpr_time_cmp(per_method_deadline, calld->deadline) < 0) {
|
887
915
|
calld->deadline = per_method_deadline;
|
888
916
|
grpc_deadline_state_reset(exec_ctx, elem, calld->deadline);
|
889
917
|
}
|
@@ -895,16 +923,18 @@ static void subchannel_ready_locked(grpc_exec_ctx *exec_ctx, void *arg,
|
|
895
923
|
grpc_call_element *elem = arg;
|
896
924
|
call_data *calld = elem->call_data;
|
897
925
|
channel_data *chand = elem->channel_data;
|
898
|
-
GPR_ASSERT(calld->
|
899
|
-
|
926
|
+
GPR_ASSERT(calld->pick_pending);
|
927
|
+
calld->pick_pending = false;
|
900
928
|
grpc_polling_entity_del_from_pollset_set(exec_ctx, calld->pollent,
|
901
929
|
chand->interested_parties);
|
902
|
-
calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
|
903
930
|
if (calld->connected_subchannel == NULL) {
|
904
|
-
gpr_atm_no_barrier_store(&calld->subchannel_call,
|
931
|
+
gpr_atm_no_barrier_store(&calld->subchannel_call, (gpr_atm)CANCELLED_CALL);
|
905
932
|
fail_locked(exec_ctx, calld,
|
906
|
-
|
907
|
-
|
933
|
+
error == GRPC_ERROR_NONE
|
934
|
+
? GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
935
|
+
"Call dropped by load balancing policy")
|
936
|
+
: GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
|
937
|
+
"Failed to create subchannel", &error, 1));
|
908
938
|
} else if (GET_CALL(calld) == CANCELLED_CALL) {
|
909
939
|
/* already cancelled before subchannel became ready */
|
910
940
|
grpc_error *cancellation_error =
|
@@ -925,7 +955,8 @@ static void subchannel_ready_locked(grpc_exec_ctx *exec_ctx, void *arg,
|
|
925
955
|
.path = calld->path,
|
926
956
|
.start_time = calld->call_start_time,
|
927
957
|
.deadline = calld->deadline,
|
928
|
-
.arena = calld->arena
|
958
|
+
.arena = calld->arena,
|
959
|
+
.context = calld->subchannel_call_context};
|
929
960
|
grpc_error *new_error = grpc_connected_subchannel_create_call(
|
930
961
|
exec_ctx, calld->connected_subchannel, &call_args, &subchannel_call);
|
931
962
|
gpr_atm_rel_store(&calld->subchannel_call,
|
@@ -954,6 +985,7 @@ typedef struct {
|
|
954
985
|
grpc_metadata_batch *initial_metadata;
|
955
986
|
uint32_t initial_metadata_flags;
|
956
987
|
grpc_connected_subchannel **connected_subchannel;
|
988
|
+
grpc_call_context_element *subchannel_call_context;
|
957
989
|
grpc_closure *on_ready;
|
958
990
|
grpc_call_element *elem;
|
959
991
|
grpc_closure closure;
|
@@ -965,8 +997,8 @@ typedef struct {
|
|
965
997
|
static bool pick_subchannel_locked(
|
966
998
|
grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
|
967
999
|
grpc_metadata_batch *initial_metadata, uint32_t initial_metadata_flags,
|
968
|
-
grpc_connected_subchannel **connected_subchannel,
|
969
|
-
|
1000
|
+
grpc_connected_subchannel **connected_subchannel,
|
1001
|
+
grpc_call_context_element *subchannel_call_context, grpc_closure *on_ready);
|
970
1002
|
|
971
1003
|
static void continue_picking_locked(grpc_exec_ctx *exec_ctx, void *arg,
|
972
1004
|
grpc_error *error) {
|
@@ -978,49 +1010,49 @@ static void continue_picking_locked(grpc_exec_ctx *exec_ctx, void *arg,
|
|
978
1010
|
} else {
|
979
1011
|
if (pick_subchannel_locked(exec_ctx, cpa->elem, cpa->initial_metadata,
|
980
1012
|
cpa->initial_metadata_flags,
|
981
|
-
cpa->connected_subchannel,
|
982
|
-
|
1013
|
+
cpa->connected_subchannel,
|
1014
|
+
cpa->subchannel_call_context, cpa->on_ready)) {
|
983
1015
|
grpc_closure_sched(exec_ctx, cpa->on_ready, GRPC_ERROR_NONE);
|
984
1016
|
}
|
985
1017
|
}
|
986
1018
|
gpr_free(cpa);
|
987
1019
|
}
|
988
1020
|
|
1021
|
+
static void cancel_pick_locked(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
|
1022
|
+
grpc_error *error) {
|
1023
|
+
channel_data *chand = elem->channel_data;
|
1024
|
+
call_data *calld = elem->call_data;
|
1025
|
+
if (chand->lb_policy != NULL) {
|
1026
|
+
grpc_lb_policy_cancel_pick_locked(exec_ctx, chand->lb_policy,
|
1027
|
+
&calld->connected_subchannel,
|
1028
|
+
GRPC_ERROR_REF(error));
|
1029
|
+
}
|
1030
|
+
for (grpc_closure *closure = chand->waiting_for_config_closures.head;
|
1031
|
+
closure != NULL; closure = closure->next_data.next) {
|
1032
|
+
continue_picking_args *cpa = closure->cb_arg;
|
1033
|
+
if (cpa->connected_subchannel == &calld->connected_subchannel) {
|
1034
|
+
cpa->connected_subchannel = NULL;
|
1035
|
+
grpc_closure_sched(exec_ctx, cpa->on_ready,
|
1036
|
+
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
|
1037
|
+
"Pick cancelled", &error, 1));
|
1038
|
+
}
|
1039
|
+
}
|
1040
|
+
GRPC_ERROR_UNREF(error);
|
1041
|
+
}
|
1042
|
+
|
989
1043
|
static bool pick_subchannel_locked(
|
990
1044
|
grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
|
991
1045
|
grpc_metadata_batch *initial_metadata, uint32_t initial_metadata_flags,
|
992
|
-
grpc_connected_subchannel **connected_subchannel,
|
993
|
-
|
1046
|
+
grpc_connected_subchannel **connected_subchannel,
|
1047
|
+
grpc_call_context_element *subchannel_call_context,
|
1048
|
+
grpc_closure *on_ready) {
|
994
1049
|
GPR_TIMER_BEGIN("pick_subchannel", 0);
|
995
1050
|
|
996
1051
|
channel_data *chand = elem->channel_data;
|
997
1052
|
call_data *calld = elem->call_data;
|
998
|
-
continue_picking_args *cpa;
|
999
|
-
grpc_closure *closure;
|
1000
1053
|
|
1001
1054
|
GPR_ASSERT(connected_subchannel);
|
1002
1055
|
|
1003
|
-
if (initial_metadata == NULL) {
|
1004
|
-
if (chand->lb_policy != NULL) {
|
1005
|
-
grpc_lb_policy_cancel_pick_locked(exec_ctx, chand->lb_policy,
|
1006
|
-
connected_subchannel,
|
1007
|
-
GRPC_ERROR_REF(error));
|
1008
|
-
}
|
1009
|
-
for (closure = chand->waiting_for_config_closures.head; closure != NULL;
|
1010
|
-
closure = closure->next_data.next) {
|
1011
|
-
cpa = closure->cb_arg;
|
1012
|
-
if (cpa->connected_subchannel == connected_subchannel) {
|
1013
|
-
cpa->connected_subchannel = NULL;
|
1014
|
-
grpc_closure_sched(exec_ctx, cpa->on_ready,
|
1015
|
-
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
|
1016
|
-
"Pick cancelled", &error, 1));
|
1017
|
-
}
|
1018
|
-
}
|
1019
|
-
GPR_TIMER_END("pick_subchannel", 0);
|
1020
|
-
GRPC_ERROR_UNREF(error);
|
1021
|
-
return true;
|
1022
|
-
}
|
1023
|
-
GPR_ASSERT(error == GRPC_ERROR_NONE);
|
1024
1056
|
if (chand->lb_policy != NULL) {
|
1025
1057
|
apply_final_configuration_locked(exec_ctx, elem);
|
1026
1058
|
grpc_lb_policy *lb_policy = chand->lb_policy;
|
@@ -1043,13 +1075,30 @@ static bool pick_subchannel_locked(
|
|
1043
1075
|
}
|
1044
1076
|
}
|
1045
1077
|
const grpc_lb_policy_pick_args inputs = {
|
1046
|
-
initial_metadata, initial_metadata_flags, &calld->lb_token_mdelem
|
1047
|
-
|
1048
|
-
|
1049
|
-
|
1078
|
+
initial_metadata, initial_metadata_flags, &calld->lb_token_mdelem};
|
1079
|
+
|
1080
|
+
// Wrap the user-provided callback in order to hold a strong reference to
|
1081
|
+
// the LB policy for the duration of the pick.
|
1082
|
+
wrapped_on_pick_closure_arg *w_on_pick_arg =
|
1083
|
+
gpr_zalloc(sizeof(*w_on_pick_arg));
|
1084
|
+
grpc_closure_init(&w_on_pick_arg->wrapper_closure,
|
1085
|
+
wrapped_on_pick_closure_cb, w_on_pick_arg,
|
1086
|
+
grpc_schedule_on_exec_ctx);
|
1087
|
+
w_on_pick_arg->wrapped_closure = on_ready;
|
1088
|
+
GRPC_LB_POLICY_REF(lb_policy, "pick_subchannel_wrapping");
|
1089
|
+
w_on_pick_arg->lb_policy = lb_policy;
|
1090
|
+
const bool pick_done = grpc_lb_policy_pick_locked(
|
1091
|
+
exec_ctx, lb_policy, &inputs, connected_subchannel,
|
1092
|
+
subchannel_call_context, NULL, &w_on_pick_arg->wrapper_closure);
|
1093
|
+
if (pick_done) {
|
1094
|
+
/* synchronous grpc_lb_policy_pick call. Unref the LB policy. */
|
1095
|
+
GRPC_LB_POLICY_UNREF(exec_ctx, w_on_pick_arg->lb_policy,
|
1096
|
+
"pick_subchannel_wrapping");
|
1097
|
+
gpr_free(w_on_pick_arg);
|
1098
|
+
}
|
1050
1099
|
GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "pick_subchannel");
|
1051
1100
|
GPR_TIMER_END("pick_subchannel", 0);
|
1052
|
-
return
|
1101
|
+
return pick_done;
|
1053
1102
|
}
|
1054
1103
|
if (chand->resolver != NULL && !chand->started_resolving) {
|
1055
1104
|
chand->started_resolving = true;
|
@@ -1059,10 +1108,11 @@ static bool pick_subchannel_locked(
|
|
1059
1108
|
&chand->on_resolver_result_changed);
|
1060
1109
|
}
|
1061
1110
|
if (chand->resolver != NULL) {
|
1062
|
-
cpa = gpr_malloc(sizeof(*cpa));
|
1111
|
+
continue_picking_args *cpa = gpr_malloc(sizeof(*cpa));
|
1063
1112
|
cpa->initial_metadata = initial_metadata;
|
1064
1113
|
cpa->initial_metadata_flags = initial_metadata_flags;
|
1065
1114
|
cpa->connected_subchannel = connected_subchannel;
|
1115
|
+
cpa->subchannel_call_context = subchannel_call_context;
|
1066
1116
|
cpa->on_ready = on_ready;
|
1067
1117
|
cpa->elem = elem;
|
1068
1118
|
grpc_closure_init(&cpa->closure, continue_picking_locked, cpa,
|
@@ -1114,16 +1164,13 @@ static void start_transport_stream_op_batch_locked_inner(
|
|
1114
1164
|
error to the caller when the first op does get passed down. */
|
1115
1165
|
calld->cancel_error =
|
1116
1166
|
GRPC_ERROR_REF(op->payload->cancel_stream.cancel_error);
|
1117
|
-
|
1118
|
-
|
1119
|
-
|
1120
|
-
|
1121
|
-
|
1122
|
-
|
1123
|
-
|
1124
|
-
exec_ctx, elem, NULL, 0, &calld->connected_subchannel, NULL,
|
1125
|
-
GRPC_ERROR_REF(op->payload->cancel_stream.cancel_error));
|
1126
|
-
break;
|
1167
|
+
if (calld->pick_pending) {
|
1168
|
+
cancel_pick_locked(
|
1169
|
+
exec_ctx, elem,
|
1170
|
+
GRPC_ERROR_REF(op->payload->cancel_stream.cancel_error));
|
1171
|
+
} else {
|
1172
|
+
fail_locked(exec_ctx, calld,
|
1173
|
+
GRPC_ERROR_REF(op->payload->cancel_stream.cancel_error));
|
1127
1174
|
}
|
1128
1175
|
grpc_transport_stream_op_batch_finish_with_failure(
|
1129
1176
|
exec_ctx, op,
|
@@ -1133,9 +1180,9 @@ static void start_transport_stream_op_batch_locked_inner(
|
|
1133
1180
|
}
|
1134
1181
|
}
|
1135
1182
|
/* if we don't have a subchannel, try to get one */
|
1136
|
-
if (calld->
|
1137
|
-
|
1138
|
-
calld->
|
1183
|
+
if (!calld->pick_pending && calld->connected_subchannel == NULL &&
|
1184
|
+
op->send_initial_metadata) {
|
1185
|
+
calld->pick_pending = true;
|
1139
1186
|
grpc_closure_init(&calld->next_step, subchannel_ready_locked, elem,
|
1140
1187
|
grpc_combiner_scheduler(chand->combiner, true));
|
1141
1188
|
GRPC_CALL_STACK_REF(calld->owning_call, "pick_subchannel");
|
@@ -1146,24 +1193,34 @@ static void start_transport_stream_op_batch_locked_inner(
|
|
1146
1193
|
exec_ctx, elem,
|
1147
1194
|
op->payload->send_initial_metadata.send_initial_metadata,
|
1148
1195
|
op->payload->send_initial_metadata.send_initial_metadata_flags,
|
1149
|
-
&calld->connected_subchannel,
|
1150
|
-
|
1196
|
+
&calld->connected_subchannel, calld->subchannel_call_context,
|
1197
|
+
&calld->next_step)) {
|
1198
|
+
calld->pick_pending = false;
|
1151
1199
|
GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "pick_subchannel");
|
1200
|
+
if (calld->connected_subchannel == NULL) {
|
1201
|
+
gpr_atm_no_barrier_store(&calld->subchannel_call,
|
1202
|
+
(gpr_atm)CANCELLED_CALL);
|
1203
|
+
grpc_error *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
1204
|
+
"Call dropped by load balancing policy");
|
1205
|
+
fail_locked(exec_ctx, calld, GRPC_ERROR_REF(error));
|
1206
|
+
grpc_transport_stream_op_batch_finish_with_failure(exec_ctx, op, error);
|
1207
|
+
return; // Early out.
|
1208
|
+
}
|
1152
1209
|
} else {
|
1153
1210
|
grpc_polling_entity_add_to_pollset_set(exec_ctx, calld->pollent,
|
1154
1211
|
chand->interested_parties);
|
1155
1212
|
}
|
1156
1213
|
}
|
1157
1214
|
/* if we've got a subchannel, then let's ask it to create a call */
|
1158
|
-
if (calld->
|
1159
|
-
calld->connected_subchannel != NULL) {
|
1215
|
+
if (!calld->pick_pending && calld->connected_subchannel != NULL) {
|
1160
1216
|
grpc_subchannel_call *subchannel_call = NULL;
|
1161
1217
|
const grpc_connected_subchannel_call_args call_args = {
|
1162
1218
|
.pollent = calld->pollent,
|
1163
1219
|
.path = calld->path,
|
1164
1220
|
.start_time = calld->call_start_time,
|
1165
1221
|
.deadline = calld->deadline,
|
1166
|
-
.arena = calld->arena
|
1222
|
+
.arena = calld->arena,
|
1223
|
+
.context = calld->subchannel_call_context};
|
1167
1224
|
grpc_error *error = grpc_connected_subchannel_create_call(
|
1168
1225
|
exec_ctx, calld->connected_subchannel, &call_args, &subchannel_call);
|
1169
1226
|
gpr_atm_rel_store(&calld->subchannel_call,
|
@@ -1241,8 +1298,10 @@ static void cc_start_transport_stream_op_batch(
|
|
1241
1298
|
call_data *calld = elem->call_data;
|
1242
1299
|
channel_data *chand = elem->channel_data;
|
1243
1300
|
GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
|
1244
|
-
|
1245
|
-
|
1301
|
+
if (chand->deadline_checking_enabled) {
|
1302
|
+
grpc_deadline_state_client_start_transport_stream_op_batch(exec_ctx, elem,
|
1303
|
+
op);
|
1304
|
+
}
|
1246
1305
|
/* try to (atomically) get the call */
|
1247
1306
|
grpc_subchannel_call *call = GET_CALL(calld);
|
1248
1307
|
GPR_TIMER_BEGIN("cc_start_transport_stream_op_batch", 0);
|
@@ -1276,14 +1335,16 @@ static grpc_error *cc_init_call_elem(grpc_exec_ctx *exec_ctx,
|
|
1276
1335
|
grpc_call_element *elem,
|
1277
1336
|
const grpc_call_element_args *args) {
|
1278
1337
|
call_data *calld = elem->call_data;
|
1338
|
+
channel_data *chand = elem->channel_data;
|
1279
1339
|
// Initialize data members.
|
1280
|
-
grpc_deadline_state_init(exec_ctx, elem, args->call_stack);
|
1281
1340
|
calld->path = grpc_slice_ref_internal(args->path);
|
1282
1341
|
calld->call_start_time = args->start_time;
|
1283
1342
|
calld->deadline = gpr_convert_clock_type(args->deadline, GPR_CLOCK_MONOTONIC);
|
1284
1343
|
calld->owning_call = args->call_stack;
|
1285
1344
|
calld->arena = args->arena;
|
1286
|
-
|
1345
|
+
if (chand->deadline_checking_enabled) {
|
1346
|
+
grpc_deadline_state_init(exec_ctx, elem, args->call_stack, calld->deadline);
|
1347
|
+
}
|
1287
1348
|
return GRPC_ERROR_NONE;
|
1288
1349
|
}
|
1289
1350
|
|
@@ -1293,7 +1354,10 @@ static void cc_destroy_call_elem(grpc_exec_ctx *exec_ctx,
|
|
1293
1354
|
const grpc_call_final_info *final_info,
|
1294
1355
|
grpc_closure *then_schedule_closure) {
|
1295
1356
|
call_data *calld = elem->call_data;
|
1296
|
-
|
1357
|
+
channel_data *chand = elem->channel_data;
|
1358
|
+
if (chand->deadline_checking_enabled) {
|
1359
|
+
grpc_deadline_state_destroy(exec_ctx, elem);
|
1360
|
+
}
|
1297
1361
|
grpc_slice_unref_internal(exec_ctx, calld->path);
|
1298
1362
|
if (calld->method_params != NULL) {
|
1299
1363
|
method_parameters_unref(calld->method_params);
|
@@ -1305,12 +1369,18 @@ static void cc_destroy_call_elem(grpc_exec_ctx *exec_ctx,
|
|
1305
1369
|
then_schedule_closure = NULL;
|
1306
1370
|
GRPC_SUBCHANNEL_CALL_UNREF(exec_ctx, call, "client_channel_destroy_call");
|
1307
1371
|
}
|
1308
|
-
GPR_ASSERT(calld->
|
1372
|
+
GPR_ASSERT(!calld->pick_pending);
|
1309
1373
|
GPR_ASSERT(calld->waiting_ops_count == 0);
|
1310
1374
|
if (calld->connected_subchannel != NULL) {
|
1311
1375
|
GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, calld->connected_subchannel,
|
1312
1376
|
"picked");
|
1313
1377
|
}
|
1378
|
+
for (size_t i = 0; i < GRPC_CONTEXT_COUNT; ++i) {
|
1379
|
+
if (calld->subchannel_call_context[i].value != NULL) {
|
1380
|
+
calld->subchannel_call_context[i].destroy(
|
1381
|
+
calld->subchannel_call_context[i].value);
|
1382
|
+
}
|
1383
|
+
}
|
1314
1384
|
gpr_free(calld->waiting_ops);
|
1315
1385
|
grpc_closure_sched(exec_ctx, then_schedule_closure, GRPC_ERROR_NONE);
|
1316
1386
|
}
|
@@ -1490,13 +1560,13 @@ static void watch_connectivity_state_locked(grpc_exec_ctx *exec_ctx, void *arg,
|
|
1490
1560
|
|
1491
1561
|
void grpc_client_channel_watch_connectivity_state(
|
1492
1562
|
grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, grpc_pollset *pollset,
|
1493
|
-
grpc_connectivity_state *state, grpc_closure *
|
1563
|
+
grpc_connectivity_state *state, grpc_closure *closure,
|
1494
1564
|
grpc_closure *watcher_timer_init) {
|
1495
1565
|
channel_data *chand = elem->channel_data;
|
1496
1566
|
external_connectivity_watcher *w = gpr_zalloc(sizeof(*w));
|
1497
1567
|
w->chand = chand;
|
1498
1568
|
w->pollset = pollset;
|
1499
|
-
w->on_complete =
|
1569
|
+
w->on_complete = closure;
|
1500
1570
|
w->state = state;
|
1501
1571
|
w->watcher_timer_init = watcher_timer_init;
|
1502
1572
|
|