grpc 1.8.7 → 1.9.0.pre1
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 +549 -325
- data/include/grpc/impl/codegen/grpc_types.h +1 -2
- data/include/grpc/impl/codegen/port_platform.h +46 -5
- data/include/grpc/impl/codegen/slice.h +1 -2
- data/include/grpc/module.modulemap +0 -2
- data/include/grpc/slice_buffer.h +1 -2
- data/include/grpc/support/log.h +4 -2
- data/include/grpc/support/thd.h +4 -1
- data/include/grpc/support/tls.h +6 -0
- data/include/grpc/support/tls_gcc.h +5 -40
- data/include/grpc/support/tls_msvc.h +9 -0
- data/include/grpc/support/tls_pthread.h +9 -0
- data/src/core/ext/filters/client_channel/backup_poller.cc +32 -29
- data/src/core/ext/filters/client_channel/backup_poller.h +2 -2
- data/src/core/ext/filters/client_channel/channel_connectivity.cc +26 -32
- data/src/core/ext/filters/client_channel/client_channel.cc +325 -356
- data/src/core/ext/filters/client_channel/client_channel.h +4 -12
- data/src/core/ext/filters/client_channel/client_channel_factory.cc +9 -14
- data/src/core/ext/filters/client_channel/client_channel_factory.h +7 -20
- data/src/core/ext/filters/client_channel/client_channel_plugin.cc +7 -10
- data/src/core/ext/filters/client_channel/connector.cc +6 -7
- data/src/core/ext/filters/client_channel/connector.h +6 -16
- data/src/core/ext/filters/client_channel/http_connect_handshaker.cc +38 -50
- data/src/core/ext/filters/client_channel/http_connect_handshaker.h +0 -8
- data/src/core/ext/filters/client_channel/http_proxy.cc +9 -13
- data/src/core/ext/filters/client_channel/http_proxy.h +0 -8
- data/src/core/ext/filters/client_channel/lb_policy.cc +72 -94
- data/src/core/ext/filters/client_channel/lb_policy.h +83 -92
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc +14 -19
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h +0 -8
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +474 -591
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h +0 -8
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h +2 -10
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc +6 -6
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h +0 -8
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc +0 -9
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h +0 -9
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c +3 -4
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h +9 -12
- data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +160 -182
- data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +182 -221
- data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc +24 -35
- data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +9 -20
- data/src/core/ext/filters/client_channel/lb_policy_factory.cc +6 -9
- data/src/core/ext/filters/client_channel/lb_policy_factory.h +4 -15
- data/src/core/ext/filters/client_channel/lb_policy_registry.cc +3 -3
- data/src/core/ext/filters/client_channel/lb_policy_registry.h +1 -9
- data/src/core/ext/filters/client_channel/parse_address.cc +1 -1
- data/src/core/ext/filters/client_channel/parse_address.h +0 -8
- data/src/core/ext/filters/client_channel/proxy_mapper.cc +6 -8
- data/src/core/ext/filters/client_channel/proxy_mapper.h +6 -16
- data/src/core/ext/filters/client_channel/proxy_mapper_registry.cc +13 -17
- data/src/core/ext/filters/client_channel/proxy_mapper_registry.h +2 -12
- data/src/core/ext/filters/client_channel/resolver.cc +11 -13
- data/src/core/ext/filters/client_channel/resolver.h +14 -25
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +57 -70
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h +2 -12
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc +23 -31
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +27 -45
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +5 -15
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc +9 -11
- data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +53 -66
- data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +25 -33
- data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h +1 -9
- data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +26 -35
- data/src/core/ext/filters/client_channel/resolver_factory.cc +2 -3
- data/src/core/ext/filters/client_channel/resolver_factory.h +2 -12
- data/src/core/ext/filters/client_channel/resolver_registry.cc +12 -15
- data/src/core/ext/filters/client_channel/resolver_registry.h +3 -12
- data/src/core/ext/filters/client_channel/retry_throttle.h +0 -8
- data/src/core/ext/filters/client_channel/subchannel.cc +289 -301
- data/src/core/ext/filters/client_channel/subchannel.h +57 -84
- data/src/core/ext/filters/client_channel/subchannel_index.cc +30 -33
- data/src/core/ext/filters/client_channel/subchannel_index.h +4 -16
- data/src/core/ext/filters/client_channel/uri_parser.cc +13 -17
- data/src/core/ext/filters/client_channel/uri_parser.h +1 -10
- data/src/core/ext/filters/deadline/deadline_filter.cc +49 -67
- data/src/core/ext/filters/deadline/deadline_filter.h +4 -14
- data/src/core/ext/filters/http/client/http_client_filter.cc +60 -77
- data/src/core/ext/filters/http/client/http_client_filter.h +0 -8
- data/src/core/ext/filters/http/http_filters_plugin.cc +4 -6
- data/src/core/ext/filters/http/message_compress/message_compress_filter.cc +63 -79
- data/src/core/ext/filters/http/message_compress/message_compress_filter.h +0 -8
- data/src/core/ext/filters/http/server/http_server_filter.cc +57 -71
- data/src/core/ext/filters/http/server/http_server_filter.h +0 -8
- data/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc +19 -24
- data/src/core/ext/filters/load_reporting/server_load_reporting_filter.h +0 -8
- data/src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc +3 -3
- data/src/core/ext/filters/load_reporting/server_load_reporting_plugin.h +0 -8
- data/src/core/ext/filters/max_age/max_age_filter.cc +49 -62
- data/src/core/ext/filters/max_age/max_age_filter.h +0 -8
- data/src/core/ext/filters/message_size/message_size_filter.cc +23 -29
- data/src/core/ext/filters/message_size/message_size_filter.h +0 -8
- data/src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc +15 -18
- data/src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h +0 -8
- data/src/core/ext/filters/workarounds/workaround_utils.h +0 -8
- data/src/core/ext/transport/chttp2/alpn/alpn.h +0 -8
- data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +33 -40
- data/src/core/ext/transport/chttp2/client/chttp2_connector.h +0 -8
- data/src/core/ext/transport/chttp2/client/insecure/channel_create.cc +15 -17
- data/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc +8 -8
- data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc +23 -28
- data/src/core/ext/transport/chttp2/server/chttp2_server.cc +50 -57
- data/src/core/ext/transport/chttp2/server/chttp2_server.h +1 -10
- data/src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc +3 -3
- data/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc +7 -10
- data/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc +5 -6
- data/src/core/ext/transport/chttp2/transport/bin_decoder.cc +7 -9
- data/src/core/ext/transport/chttp2/transport/bin_decoder.h +2 -11
- data/src/core/ext/transport/chttp2/transport/bin_encoder.h +1 -9
- data/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc +10 -2
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +516 -636
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +4 -11
- data/src/core/ext/transport/chttp2/transport/flow_control.cc +29 -13
- data/src/core/ext/transport/chttp2/transport/flow_control.h +196 -53
- data/src/core/ext/transport/chttp2/transport/frame.h +0 -8
- data/src/core/ext/transport/chttp2/transport/frame_data.cc +31 -33
- data/src/core/ext/transport/chttp2/transport/frame_data.h +3 -12
- data/src/core/ext/transport/chttp2/transport/frame_goaway.cc +2 -3
- data/src/core/ext/transport/chttp2/transport/frame_goaway.h +1 -10
- data/src/core/ext/transport/chttp2/transport/frame_ping.cc +5 -6
- data/src/core/ext/transport/chttp2/transport/frame_ping.h +1 -9
- data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +2 -3
- data/src/core/ext/transport/chttp2/transport/frame_rst_stream.h +1 -10
- data/src/core/ext/transport/chttp2/transport/frame_settings.cc +8 -3
- data/src/core/ext/transport/chttp2/transport/frame_settings.h +1 -10
- data/src/core/ext/transport/chttp2/transport/frame_window_update.cc +8 -8
- data/src/core/ext/transport/chttp2/transport/frame_window_update.h +5 -11
- data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +63 -81
- data/src/core/ext/transport/chttp2/transport/hpack_encoder.h +2 -12
- data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +230 -318
- data/src/core/ext/transport/chttp2/transport/hpack_parser.h +6 -19
- data/src/core/ext/transport/chttp2/transport/hpack_table.cc +14 -20
- data/src/core/ext/transport/chttp2/transport/hpack_table.h +5 -16
- data/src/core/ext/transport/chttp2/transport/http2_settings.h +0 -7
- data/src/core/ext/transport/chttp2/transport/huffsyms.h +0 -8
- data/src/core/ext/transport/chttp2/transport/incoming_metadata.cc +8 -11
- data/src/core/ext/transport/chttp2/transport/incoming_metadata.h +4 -13
- data/src/core/ext/transport/chttp2/transport/internal.h +51 -75
- data/src/core/ext/transport/chttp2/transport/parsing.cc +83 -109
- data/src/core/ext/transport/chttp2/transport/stream_lists.cc +2 -0
- data/src/core/ext/transport/chttp2/transport/stream_map.h +0 -8
- data/src/core/ext/transport/chttp2/transport/varint.h +0 -8
- data/src/core/ext/transport/chttp2/transport/writing.cc +61 -65
- data/src/core/ext/transport/inproc/inproc_plugin.cc +2 -4
- data/src/core/ext/transport/inproc/inproc_transport.cc +177 -188
- data/src/core/ext/transport/inproc/inproc_transport.h +0 -8
- data/src/core/lib/backoff/backoff.cc +39 -44
- data/src/core/lib/backoff/backoff.h +61 -57
- data/src/core/lib/channel/channel_args.cc +8 -10
- data/src/core/lib/channel/channel_args.h +4 -13
- data/src/core/lib/channel/channel_stack.cc +19 -27
- data/src/core/lib/channel/channel_stack.h +27 -47
- data/src/core/lib/channel/channel_stack_builder.cc +11 -14
- data/src/core/lib/channel/channel_stack_builder.h +4 -15
- data/src/core/lib/channel/connected_channel.cc +23 -36
- data/src/core/lib/channel/connected_channel.h +1 -10
- data/src/core/lib/channel/handshaker.cc +31 -40
- data/src/core/lib/channel/handshaker.h +14 -25
- data/src/core/lib/channel/handshaker_factory.cc +6 -6
- data/src/core/lib/channel/handshaker_factory.h +5 -15
- data/src/core/lib/channel/handshaker_registry.cc +9 -13
- data/src/core/lib/channel/handshaker_registry.h +2 -11
- data/src/core/lib/compression/algorithm_metadata.h +0 -8
- data/src/core/lib/compression/message_compress.cc +19 -23
- data/src/core/lib/compression/message_compress.h +2 -12
- data/src/core/lib/compression/stream_compression.cc +1 -1
- data/src/core/lib/compression/stream_compression.h +0 -8
- data/src/core/lib/compression/stream_compression_gzip.cc +12 -11
- data/src/core/lib/compression/stream_compression_gzip.h +0 -8
- data/src/core/lib/compression/stream_compression_identity.h +0 -8
- data/src/core/lib/debug/stats.cc +4 -4
- data/src/core/lib/debug/stats.h +9 -19
- data/src/core/lib/debug/stats_data.cc +85 -116
- data/src/core/lib/debug/stats_data.h +236 -312
- data/src/core/lib/debug/trace.cc +1 -1
- data/src/core/lib/debug/trace.h +0 -12
- data/src/core/lib/{support → gpr++}/abstract.h +8 -3
- data/src/core/lib/{support → gpr++}/atomic.h +5 -5
- data/src/core/lib/{support → gpr++}/atomic_with_atm.h +3 -3
- data/src/core/lib/{support → gpr++}/atomic_with_std.h +3 -3
- data/src/core/lib/gpr++/debug_location.h +52 -0
- data/src/core/lib/gpr++/inlined_vector.h +112 -0
- data/src/core/lib/{support → gpr++}/manual_constructor.h +2 -2
- data/src/core/lib/{support → gpr++}/memory.h +3 -3
- data/src/core/lib/gpr++/orphanable.h +171 -0
- data/src/core/lib/gpr++/ref_counted.h +133 -0
- data/src/core/lib/gpr++/ref_counted_ptr.h +99 -0
- data/src/core/lib/{support → gpr}/alloc.cc +0 -0
- data/src/core/lib/{support → gpr}/arena.cc +1 -1
- data/src/core/lib/{support → gpr}/arena.h +3 -11
- data/src/core/lib/{support → gpr}/atm.cc +0 -0
- data/src/core/lib/{support → gpr}/avl.cc +0 -0
- data/src/core/lib/{support → gpr}/cmdline.cc +1 -1
- data/src/core/lib/{support → gpr}/cpu_iphone.cc +0 -0
- data/src/core/lib/{support → gpr}/cpu_linux.cc +0 -0
- data/src/core/lib/{support → gpr}/cpu_posix.cc +0 -0
- data/src/core/lib/{support → gpr}/cpu_windows.cc +0 -0
- data/src/core/lib/{support → gpr}/env.h +3 -11
- data/src/core/lib/{support → gpr}/env_linux.cc +2 -2
- data/src/core/lib/{support → gpr}/env_posix.cc +4 -4
- data/src/core/lib/{support → gpr}/env_windows.cc +3 -3
- data/src/core/lib/{support → gpr}/fork.cc +3 -3
- data/src/core/lib/{support → gpr}/fork.h +3 -3
- data/src/core/lib/{support → gpr}/host_port.cc +1 -1
- data/src/core/lib/{support → gpr}/log.cc +3 -3
- data/src/core/lib/{support → gpr}/log_android.cc +3 -3
- data/src/core/lib/{support → gpr}/log_linux.cc +1 -1
- data/src/core/lib/{support → gpr}/log_posix.cc +5 -5
- data/src/core/lib/{support → gpr}/log_windows.cc +3 -3
- data/src/core/lib/{support → gpr}/mpscq.cc +1 -1
- data/src/core/lib/{support → gpr}/mpscq.h +3 -10
- data/src/core/lib/{support → gpr}/murmur_hash.cc +1 -1
- data/src/core/lib/{support → gpr}/murmur_hash.h +3 -11
- data/src/core/lib/{support → gpr}/spinlock.h +3 -3
- data/src/core/lib/{support → gpr}/string.cc +1 -1
- data/src/core/lib/{support → gpr}/string.h +3 -10
- data/src/core/lib/{support → gpr}/string_posix.cc +0 -0
- data/src/core/lib/{support → gpr}/string_util_windows.cc +2 -2
- data/src/core/lib/{support → gpr}/string_windows.cc +1 -1
- data/src/core/lib/{support → gpr}/string_windows.h +3 -11
- data/src/core/lib/{support → gpr}/subprocess_posix.cc +0 -0
- data/src/core/lib/{support → gpr}/subprocess_windows.cc +2 -2
- data/src/core/lib/{support → gpr}/sync.cc +0 -0
- data/src/core/lib/{support → gpr}/sync_posix.cc +10 -1
- data/src/core/lib/{support → gpr}/sync_windows.cc +0 -0
- data/src/core/lib/{support → gpr}/thd.cc +0 -0
- data/src/core/lib/{support → gpr}/thd_internal.h +3 -3
- data/src/core/lib/{support → gpr}/thd_posix.cc +18 -2
- data/src/core/lib/{support → gpr}/thd_windows.cc +2 -1
- data/src/core/lib/{support → gpr}/time.cc +0 -0
- data/src/core/lib/{support → gpr}/time_posix.cc +2 -4
- data/src/core/lib/{support → gpr}/time_precise.cc +1 -1
- data/src/core/lib/{support → gpr}/time_precise.h +3 -11
- data/src/core/lib/{support → gpr}/time_windows.cc +1 -3
- data/src/core/lib/{support → gpr}/tls_pthread.cc +0 -0
- data/src/core/lib/{support → gpr}/tmpfile.h +3 -11
- data/src/core/lib/{support → gpr}/tmpfile_msys.cc +2 -2
- data/src/core/lib/{support → gpr}/tmpfile_posix.cc +2 -2
- data/src/core/lib/{support → gpr}/tmpfile_windows.cc +2 -2
- data/src/core/lib/{support → gpr}/wrap_memcpy.cc +0 -0
- data/src/core/lib/http/format_request.cc +1 -1
- data/src/core/lib/http/format_request.h +0 -8
- data/src/core/lib/http/httpcli.cc +55 -74
- data/src/core/lib/http/httpcli.h +13 -22
- data/src/core/lib/http/httpcli_security_connector.cc +27 -33
- data/src/core/lib/http/parser.h +0 -8
- data/src/core/lib/iomgr/block_annotate.h +10 -17
- data/src/core/lib/iomgr/call_combiner.cc +14 -17
- data/src/core/lib/iomgr/call_combiner.h +16 -34
- data/src/core/lib/iomgr/closure.h +24 -37
- data/src/core/lib/iomgr/combiner.cc +62 -66
- data/src/core/lib/iomgr/combiner.h +6 -16
- data/src/core/lib/iomgr/endpoint.cc +15 -21
- data/src/core/lib/iomgr/endpoint.h +16 -33
- data/src/core/lib/iomgr/endpoint_pair.h +0 -8
- data/src/core/lib/iomgr/endpoint_pair_posix.cc +4 -5
- data/src/core/lib/iomgr/endpoint_pair_windows.cc +4 -6
- data/src/core/lib/iomgr/error.cc +2 -6
- data/src/core/lib/iomgr/error.h +4 -9
- data/src/core/lib/iomgr/error_internal.h +0 -8
- data/src/core/lib/iomgr/ev_epoll1_linux.cc +110 -117
- data/src/core/lib/iomgr/ev_epoll1_linux.h +0 -8
- data/src/core/lib/iomgr/ev_epollex_linux.cc +111 -141
- data/src/core/lib/iomgr/ev_epollex_linux.h +0 -8
- data/src/core/lib/iomgr/ev_epollsig_linux.cc +83 -109
- data/src/core/lib/iomgr/ev_epollsig_linux.h +2 -10
- data/src/core/lib/iomgr/ev_poll_posix.cc +103 -125
- data/src/core/lib/iomgr/ev_poll_posix.h +0 -8
- data/src/core/lib/iomgr/ev_posix.cc +35 -50
- data/src/core/lib/iomgr/ev_posix.h +27 -53
- data/src/core/lib/iomgr/exec_ctx.cc +46 -78
- data/src/core/lib/iomgr/exec_ctx.h +127 -60
- data/src/core/lib/iomgr/executor.cc +34 -38
- data/src/core/lib/iomgr/executor.h +3 -11
- data/src/core/lib/iomgr/fork_posix.cc +13 -12
- data/src/core/lib/iomgr/gethostname.h +0 -8
- data/src/core/lib/iomgr/gethostname_sysconf.cc +1 -1
- data/src/core/lib/iomgr/iocp_windows.cc +14 -16
- data/src/core/lib/iomgr/iocp_windows.h +1 -10
- data/src/core/lib/iomgr/iomgr.cc +60 -59
- data/src/core/lib/iomgr/iomgr.h +3 -12
- data/src/core/lib/iomgr/iomgr_internal.h +0 -8
- data/src/core/lib/iomgr/iomgr_uv.cc +2 -3
- data/src/core/lib/iomgr/iomgr_uv.h +0 -8
- data/src/core/lib/iomgr/is_epollexclusive_available.cc +1 -1
- data/src/core/lib/iomgr/load_file.cc +1 -1
- data/src/core/lib/iomgr/load_file.h +0 -8
- data/src/core/lib/iomgr/lockfree_event.cc +7 -8
- data/src/core/lib/iomgr/lockfree_event.h +3 -3
- data/src/core/lib/iomgr/polling_entity.cc +6 -10
- data/src/core/lib/iomgr/polling_entity.h +2 -11
- data/src/core/lib/iomgr/pollset.h +4 -13
- data/src/core/lib/iomgr/pollset_set.h +5 -18
- data/src/core/lib/iomgr/pollset_set_uv.cc +5 -10
- data/src/core/lib/iomgr/pollset_set_windows.cc +5 -10
- data/src/core/lib/iomgr/pollset_uv.cc +8 -9
- data/src/core/lib/iomgr/pollset_uv.h +0 -8
- data/src/core/lib/iomgr/pollset_windows.cc +14 -15
- data/src/core/lib/iomgr/pollset_windows.h +0 -8
- data/src/core/lib/iomgr/port.h +6 -1
- data/src/core/lib/iomgr/resolve_address.h +1 -10
- data/src/core/lib/iomgr/resolve_address_posix.cc +10 -12
- data/src/core/lib/iomgr/resolve_address_uv.cc +7 -8
- data/src/core/lib/iomgr/resolve_address_windows.cc +8 -9
- data/src/core/lib/iomgr/resource_quota.cc +77 -107
- data/src/core/lib/iomgr/resource_quota.h +8 -25
- data/src/core/lib/iomgr/sockaddr_utils.cc +1 -1
- data/src/core/lib/iomgr/sockaddr_utils.h +0 -8
- data/src/core/lib/iomgr/socket_factory_posix.cc +1 -1
- data/src/core/lib/iomgr/socket_factory_posix.h +0 -8
- data/src/core/lib/iomgr/socket_mutator.cc +1 -1
- data/src/core/lib/iomgr/socket_mutator.h +1 -9
- data/src/core/lib/iomgr/socket_utils.h +0 -8
- data/src/core/lib/iomgr/socket_utils_common_posix.cc +1 -1
- data/src/core/lib/iomgr/socket_utils_posix.h +0 -8
- data/src/core/lib/iomgr/socket_windows.cc +8 -11
- data/src/core/lib/iomgr/socket_windows.h +3 -14
- data/src/core/lib/iomgr/tcp_client.h +1 -10
- data/src/core/lib/iomgr/tcp_client_posix.cc +94 -78
- data/src/core/lib/iomgr/tcp_client_posix.h +36 -8
- data/src/core/lib/iomgr/tcp_client_uv.cc +16 -23
- data/src/core/lib/iomgr/tcp_client_windows.cc +22 -25
- data/src/core/lib/iomgr/tcp_posix.cc +131 -153
- data/src/core/lib/iomgr/tcp_posix.h +3 -12
- data/src/core/lib/iomgr/tcp_server.h +6 -17
- data/src/core/lib/iomgr/tcp_server_posix.cc +31 -35
- data/src/core/lib/iomgr/tcp_server_utils_posix.h +0 -8
- data/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +1 -1
- data/src/core/lib/iomgr/tcp_server_uv.cc +23 -34
- data/src/core/lib/iomgr/tcp_server_windows.cc +24 -34
- data/src/core/lib/iomgr/tcp_uv.cc +42 -56
- data/src/core/lib/iomgr/tcp_uv.h +0 -8
- data/src/core/lib/iomgr/tcp_windows.cc +43 -50
- data/src/core/lib/iomgr/tcp_windows.h +1 -9
- data/src/core/lib/iomgr/time_averaged_stats.h +0 -8
- data/src/core/lib/iomgr/timer.h +6 -15
- data/src/core/lib/iomgr/timer_generic.cc +22 -27
- data/src/core/lib/iomgr/timer_heap.h +0 -8
- data/src/core/lib/iomgr/timer_manager.cc +17 -19
- data/src/core/lib/iomgr/timer_manager.h +0 -8
- data/src/core/lib/iomgr/timer_uv.cc +12 -14
- data/src/core/lib/iomgr/udp_server.cc +148 -54
- data/src/core/lib/iomgr/udp_server.h +16 -21
- data/src/core/lib/iomgr/unix_sockets_posix.h +0 -8
- data/src/core/lib/iomgr/wakeup_fd_cv.cc +4 -4
- data/src/core/lib/iomgr/wakeup_fd_cv.h +12 -20
- data/src/core/lib/iomgr/wakeup_fd_nospecial.cc +1 -1
- data/src/core/lib/iomgr/wakeup_fd_pipe.h +0 -8
- data/src/core/lib/iomgr/wakeup_fd_posix.h +0 -8
- data/src/core/lib/json/json.h +0 -8
- data/src/core/lib/json/json_reader.h +0 -8
- data/src/core/lib/json/json_writer.h +0 -8
- data/src/core/lib/profiling/basic_timers.cc +3 -2
- data/src/core/lib/profiling/timers.h +0 -8
- data/src/core/lib/security/context/security_context.cc +9 -10
- data/src/core/lib/security/context/security_context.h +0 -8
- data/src/core/lib/security/credentials/composite/composite_credentials.cc +23 -28
- data/src/core/lib/security/credentials/composite/composite_credentials.h +0 -8
- data/src/core/lib/security/credentials/credentials.cc +33 -42
- data/src/core/lib/security/credentials/credentials.h +24 -43
- data/src/core/lib/security/credentials/credentials_metadata.cc +2 -2
- data/src/core/lib/security/credentials/fake/fake_credentials.cc +16 -22
- data/src/core/lib/security/credentials/fake/fake_credentials.h +0 -8
- data/src/core/lib/security/credentials/google_default/credentials_generic.cc +3 -3
- data/src/core/lib/security/credentials/google_default/google_default_credentials.cc +28 -34
- data/src/core/lib/security/credentials/google_default/google_default_credentials.h +0 -8
- data/src/core/lib/security/credentials/iam/iam_credentials.cc +9 -13
- data/src/core/lib/security/credentials/jwt/json_token.cc +1 -1
- data/src/core/lib/security/credentials/jwt/json_token.h +0 -8
- data/src/core/lib/security/credentials/jwt/jwt_credentials.cc +14 -20
- data/src/core/lib/security/credentials/jwt/jwt_credentials.h +1 -10
- data/src/core/lib/security/credentials/jwt/jwt_verifier.cc +56 -72
- data/src/core/lib/security/credentials/jwt/jwt_verifier.h +5 -17
- data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +47 -55
- data/src/core/lib/security/credentials/oauth2/oauth2_credentials.h +3 -12
- data/src/core/lib/security/credentials/plugin/plugin_credentials.cc +23 -28
- data/src/core/lib/security/credentials/ssl/ssl_credentials.cc +8 -13
- data/src/core/lib/security/credentials/ssl/ssl_credentials.h +0 -8
- data/src/core/lib/security/transport/auth_filters.h +0 -8
- data/src/core/lib/security/transport/client_auth_filter.cc +45 -54
- data/src/core/lib/security/transport/lb_targets_info.cc +2 -2
- data/src/core/lib/security/transport/lb_targets_info.h +0 -8
- data/src/core/lib/security/transport/secure_endpoint.cc +54 -68
- data/src/core/lib/security/transport/secure_endpoint.h +0 -8
- data/src/core/lib/security/transport/security_connector.cc +62 -86
- data/src/core/lib/security/transport/security_connector.h +22 -39
- data/src/core/lib/security/transport/security_handshaker.cc +83 -106
- data/src/core/lib/security/transport/security_handshaker.h +1 -10
- data/src/core/lib/security/transport/server_auth_filter.cc +31 -38
- data/src/core/lib/security/transport/tsi_error.h +0 -8
- data/src/core/lib/security/util/json_util.h +0 -8
- data/src/core/lib/slice/b64.cc +5 -6
- data/src/core/lib/slice/b64.h +3 -12
- data/src/core/lib/slice/percent_encoding.h +0 -8
- data/src/core/lib/slice/slice.cc +8 -9
- data/src/core/lib/slice/slice_buffer.cc +11 -16
- data/src/core/lib/slice/slice_hash_table.cc +5 -7
- data/src/core/lib/slice/slice_hash_table.h +2 -12
- data/src/core/lib/slice/slice_intern.cc +4 -5
- data/src/core/lib/slice/slice_internal.h +4 -15
- data/src/core/lib/slice/slice_string_helpers.cc +1 -1
- data/src/core/lib/slice/slice_string_helpers.h +1 -9
- data/src/core/lib/surface/alarm.cc +11 -14
- data/src/core/lib/surface/alarm_internal.h +0 -8
- data/src/core/lib/surface/byte_buffer.cc +2 -3
- data/src/core/lib/surface/byte_buffer_reader.cc +7 -9
- data/src/core/lib/surface/call.cc +198 -241
- data/src/core/lib/surface/call.h +9 -23
- data/src/core/lib/surface/call_details.cc +3 -4
- data/src/core/lib/surface/call_log_batch.cc +1 -1
- data/src/core/lib/surface/call_test_only.h +0 -8
- data/src/core/lib/surface/channel.cc +53 -64
- data/src/core/lib/surface/channel.h +12 -23
- data/src/core/lib/surface/channel_init.cc +2 -3
- data/src/core/lib/surface/channel_init.h +2 -12
- data/src/core/lib/surface/channel_ping.cc +7 -9
- data/src/core/lib/surface/channel_stack_type.h +0 -8
- data/src/core/lib/surface/completion_queue.cc +158 -176
- data/src/core/lib/surface/completion_queue.h +9 -20
- data/src/core/lib/surface/completion_queue_factory.h +0 -8
- data/src/core/lib/surface/event_string.cc +1 -1
- data/src/core/lib/surface/event_string.h +0 -8
- data/src/core/lib/surface/init.cc +27 -25
- data/src/core/lib/surface/init.h +0 -8
- data/src/core/lib/surface/init_secure.cc +2 -2
- data/src/core/lib/surface/lame_client.cc +30 -33
- data/src/core/lib/surface/lame_client.h +0 -8
- data/src/core/lib/surface/server.cc +151 -203
- data/src/core/lib/surface/server.h +7 -16
- data/src/core/lib/surface/validate_metadata.h +0 -8
- data/src/core/lib/surface/version.cc +2 -2
- data/src/core/lib/transport/bdp_estimator.cc +2 -2
- data/src/core/lib/transport/bdp_estimator.h +1 -1
- data/src/core/lib/transport/byte_stream.cc +24 -38
- data/src/core/lib/transport/byte_stream.h +10 -25
- data/src/core/lib/transport/connectivity_state.cc +9 -13
- data/src/core/lib/transport/connectivity_state.h +4 -14
- data/src/core/lib/transport/error_utils.cc +6 -6
- data/src/core/lib/transport/error_utils.h +2 -11
- data/src/core/lib/transport/metadata.cc +21 -23
- data/src/core/lib/transport/metadata.h +8 -20
- data/src/core/lib/transport/metadata_batch.cc +34 -45
- data/src/core/lib/transport/metadata_batch.h +18 -32
- data/src/core/lib/transport/service_config.cc +11 -15
- data/src/core/lib/transport/service_config.h +3 -13
- data/src/core/lib/transport/static_metadata.cc +1 -1
- data/src/core/lib/transport/static_metadata.h +1 -7
- data/src/core/lib/transport/status_conversion.cc +2 -3
- data/src/core/lib/transport/status_conversion.h +1 -10
- data/src/core/lib/transport/timeout_encoding.cc +1 -1
- data/src/core/lib/transport/timeout_encoding.h +1 -9
- data/src/core/lib/transport/transport.cc +36 -50
- data/src/core/lib/transport/transport.h +28 -30
- data/src/core/lib/transport/transport_impl.h +12 -23
- data/src/core/lib/transport/transport_op_string.cc +2 -2
- data/src/core/plugin_registry/grpc_plugin_registry.cc +34 -34
- data/src/core/tsi/fake_transport_security.cc +7 -10
- data/src/core/tsi/fake_transport_security.h +0 -8
- data/src/core/tsi/gts_transport_security.cc +2 -2
- data/src/core/tsi/gts_transport_security.h +0 -8
- data/src/core/tsi/ssl_transport_security.cc +3 -0
- data/src/core/tsi/ssl_transport_security.h +0 -8
- data/src/core/tsi/ssl_types.h +0 -8
- data/src/core/tsi/transport_security.h +1 -9
- data/src/core/tsi/transport_security_adapter.h +0 -8
- data/src/core/tsi/transport_security_grpc.cc +11 -18
- data/src/core/tsi/transport_security_grpc.h +9 -21
- data/src/core/tsi/transport_security_interface.h +0 -8
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +0 -30
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +2 -48
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/src/ruby/spec/channel_connection_spec.rb +2 -1
- data/src/ruby/spec/client_auth_spec.rb +1 -1
- data/src/ruby/spec/client_server_spec.rb +2 -2
- data/src/ruby/spec/generic/active_call_spec.rb +1 -1
- data/src/ruby/spec/generic/client_stub_spec.rb +4 -4
- data/src/ruby/spec/generic/interceptor_registry_spec.rb +1 -1
- data/src/ruby/spec/generic/rpc_server_spec.rb +12 -12
- data/src/ruby/spec/google_rpc_status_utils_spec.rb +3 -2
- data/src/ruby/spec/pb/health/checker_spec.rb +1 -1
- data/src/ruby/spec/server_spec.rb +9 -9
- data/src/ruby/spec/support/helpers.rb +35 -1
- metadata +68 -66
- data/include/grpc/impl/codegen/exec_ctx_fwd.h +0 -26
- data/include/grpc/support/histogram.h +0 -64
- data/src/core/lib/support/histogram.cc +0 -227
@@ -21,10 +21,6 @@
|
|
21
21
|
|
22
22
|
#include "src/core/lib/iomgr/timer.h"
|
23
23
|
|
24
|
-
#ifdef __cplusplus
|
25
|
-
extern "C" {
|
26
|
-
#endif
|
27
|
-
|
28
24
|
typedef struct {
|
29
25
|
grpc_timer** timers;
|
30
26
|
uint32_t timer_count;
|
@@ -43,8 +39,4 @@ void grpc_timer_heap_pop(grpc_timer_heap* heap);
|
|
43
39
|
|
44
40
|
int grpc_timer_heap_is_empty(grpc_timer_heap* heap);
|
45
41
|
|
46
|
-
#ifdef __cplusplus
|
47
|
-
}
|
48
|
-
#endif
|
49
|
-
|
50
42
|
#endif /* GRPC_CORE_LIB_IOMGR_TIMER_HEAP_H */
|
@@ -93,18 +93,17 @@ static void start_timer_thread_and_unlock(void) {
|
|
93
93
|
// to leak through g_completed_threads and be freed in gc_completed_threads()
|
94
94
|
// before "&ct->t" is written to, causing a use-after-free.
|
95
95
|
gpr_mu_lock(&g_mu);
|
96
|
-
gpr_thd_new(&ct->t, timer_thread, ct, &opt);
|
96
|
+
gpr_thd_new(&ct->t, "grpc_global_timer", timer_thread, ct, &opt);
|
97
97
|
gpr_mu_unlock(&g_mu);
|
98
98
|
}
|
99
99
|
|
100
100
|
void grpc_timer_manager_tick() {
|
101
|
-
|
101
|
+
grpc_core::ExecCtx exec_ctx;
|
102
102
|
grpc_millis next = GRPC_MILLIS_INF_FUTURE;
|
103
|
-
grpc_timer_check(&
|
104
|
-
grpc_exec_ctx_finish(&exec_ctx);
|
103
|
+
grpc_timer_check(&next);
|
105
104
|
}
|
106
105
|
|
107
|
-
static void run_some_timers(
|
106
|
+
static void run_some_timers() {
|
108
107
|
// if there's something to execute...
|
109
108
|
gpr_mu_lock(&g_mu);
|
110
109
|
// remove a waiter from the pool, and start another thread if necessary
|
@@ -126,7 +125,7 @@ static void run_some_timers(grpc_exec_ctx* exec_ctx) {
|
|
126
125
|
if (grpc_timer_check_trace.enabled()) {
|
127
126
|
gpr_log(GPR_DEBUG, "flush exec_ctx");
|
128
127
|
}
|
129
|
-
|
128
|
+
grpc_core::ExecCtx::Get()->Flush();
|
130
129
|
gpr_mu_lock(&g_mu);
|
131
130
|
// garbage collect any threads hanging out that are dead
|
132
131
|
gc_completed_threads();
|
@@ -138,7 +137,7 @@ static void run_some_timers(grpc_exec_ctx* exec_ctx) {
|
|
138
137
|
// wait until 'next' (or forever if there is already a timed waiter in the pool)
|
139
138
|
// returns true if the thread should continue executing (false if it should
|
140
139
|
// shutdown)
|
141
|
-
static bool wait_until(
|
140
|
+
static bool wait_until(grpc_millis next) {
|
142
141
|
gpr_mu_lock(&g_mu);
|
143
142
|
// if we're not threaded anymore, leave
|
144
143
|
if (!g_threaded) {
|
@@ -179,7 +178,7 @@ static bool wait_until(grpc_exec_ctx* exec_ctx, grpc_millis next) {
|
|
179
178
|
g_timed_waiter_deadline = next;
|
180
179
|
|
181
180
|
if (grpc_timer_check_trace.enabled()) {
|
182
|
-
grpc_millis wait_time = next -
|
181
|
+
grpc_millis wait_time = next - grpc_core::ExecCtx::Get()->Now();
|
183
182
|
gpr_log(GPR_DEBUG, "sleep for a %" PRIdPTR " milliseconds",
|
184
183
|
wait_time);
|
185
184
|
}
|
@@ -193,7 +192,7 @@ static bool wait_until(grpc_exec_ctx* exec_ctx, grpc_millis next) {
|
|
193
192
|
}
|
194
193
|
|
195
194
|
gpr_cv_wait(&g_cv_wait, &g_mu,
|
196
|
-
grpc_millis_to_timespec(next,
|
195
|
+
grpc_millis_to_timespec(next, GPR_CLOCK_MONOTONIC));
|
197
196
|
|
198
197
|
if (grpc_timer_check_trace.enabled()) {
|
199
198
|
gpr_log(GPR_DEBUG, "wait ended: was_timed:%d kicked:%d",
|
@@ -220,15 +219,15 @@ static bool wait_until(grpc_exec_ctx* exec_ctx, grpc_millis next) {
|
|
220
219
|
return true;
|
221
220
|
}
|
222
221
|
|
223
|
-
static void timer_main_loop(
|
222
|
+
static void timer_main_loop() {
|
224
223
|
for (;;) {
|
225
224
|
grpc_millis next = GRPC_MILLIS_INF_FUTURE;
|
226
|
-
|
225
|
+
grpc_core::ExecCtx::Get()->InvalidateNow();
|
227
226
|
|
228
227
|
// check timer state, updates next to the next time to run a check
|
229
|
-
switch (grpc_timer_check(
|
228
|
+
switch (grpc_timer_check(&next)) {
|
230
229
|
case GRPC_TIMERS_FIRED:
|
231
|
-
run_some_timers(
|
230
|
+
run_some_timers();
|
232
231
|
break;
|
233
232
|
case GRPC_TIMERS_NOT_CHECKED:
|
234
233
|
/* This case only happens under contention, meaning more than one timer
|
@@ -246,7 +245,7 @@ static void timer_main_loop(grpc_exec_ctx* exec_ctx) {
|
|
246
245
|
next = GRPC_MILLIS_INF_FUTURE;
|
247
246
|
/* fall through */
|
248
247
|
case GRPC_TIMERS_CHECKED_AND_EMPTY:
|
249
|
-
if (!wait_until(
|
248
|
+
if (!wait_until(next)) {
|
250
249
|
return;
|
251
250
|
}
|
252
251
|
break;
|
@@ -274,10 +273,9 @@ static void timer_thread_cleanup(completed_thread* ct) {
|
|
274
273
|
static void timer_thread(void* completed_thread_ptr) {
|
275
274
|
// this threads exec_ctx: we try to run things through to completion here
|
276
275
|
// since it's easy to spin up new threads
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
grpc_exec_ctx_finish(&exec_ctx);
|
276
|
+
grpc_core::ExecCtx exec_ctx(0);
|
277
|
+
timer_main_loop();
|
278
|
+
|
281
279
|
timer_thread_cleanup((completed_thread*)completed_thread_ptr);
|
282
280
|
}
|
283
281
|
|
@@ -319,7 +317,7 @@ static void stop_threads(void) {
|
|
319
317
|
gpr_log(GPR_DEBUG, "num timer threads: %d", g_thread_count);
|
320
318
|
}
|
321
319
|
while (g_thread_count > 0) {
|
322
|
-
gpr_cv_wait(&g_cv_shutdown, &g_mu, gpr_inf_future(
|
320
|
+
gpr_cv_wait(&g_cv_shutdown, &g_mu, gpr_inf_future(GPR_CLOCK_MONOTONIC));
|
323
321
|
if (grpc_timer_check_trace.enabled()) {
|
324
322
|
gpr_log(GPR_DEBUG, "num timer threads: %d", g_thread_count);
|
325
323
|
}
|
@@ -21,10 +21,6 @@
|
|
21
21
|
|
22
22
|
#include <stdbool.h>
|
23
23
|
|
24
|
-
#ifdef __cplusplus
|
25
|
-
extern "C" {
|
26
|
-
#endif
|
27
|
-
|
28
24
|
/* Timer Manager tries to keep one thread waiting for the next timeout at all
|
29
25
|
times */
|
30
26
|
|
@@ -38,8 +34,4 @@ void grpc_timer_manager_set_threading(bool enabled);
|
|
38
34
|
* disabled */
|
39
35
|
void grpc_timer_manager_tick(void);
|
40
36
|
|
41
|
-
#ifdef __cplusplus
|
42
|
-
}
|
43
|
-
#endif
|
44
|
-
|
45
37
|
#endif /* GRPC_CORE_LIB_IOMGR_TIMER_MANAGER_H */
|
@@ -42,28 +42,27 @@ static void stop_uv_timer(uv_timer_t* handle) {
|
|
42
42
|
|
43
43
|
void run_expired_timer(uv_timer_t* handle) {
|
44
44
|
grpc_timer* timer = (grpc_timer*)handle->data;
|
45
|
-
|
45
|
+
grpc_core::ExecCtx exec_ctx;
|
46
46
|
GRPC_UV_ASSERT_SAME_THREAD();
|
47
47
|
GPR_ASSERT(timer->pending);
|
48
48
|
timer->pending = 0;
|
49
|
-
GRPC_CLOSURE_SCHED(
|
49
|
+
GRPC_CLOSURE_SCHED(timer->closure, GRPC_ERROR_NONE);
|
50
50
|
stop_uv_timer(handle);
|
51
|
-
grpc_exec_ctx_finish(&exec_ctx);
|
52
51
|
}
|
53
52
|
|
54
|
-
void grpc_timer_init(
|
55
|
-
|
53
|
+
void grpc_timer_init(grpc_timer* timer, grpc_millis deadline,
|
54
|
+
grpc_closure* closure) {
|
56
55
|
uint64_t timeout;
|
57
56
|
uv_timer_t* uv_timer;
|
58
57
|
GRPC_UV_ASSERT_SAME_THREAD();
|
59
58
|
timer->closure = closure;
|
60
|
-
if (deadline <=
|
59
|
+
if (deadline <= grpc_core::ExecCtx::Get()->Now()) {
|
61
60
|
timer->pending = 0;
|
62
|
-
GRPC_CLOSURE_SCHED(
|
61
|
+
GRPC_CLOSURE_SCHED(timer->closure, GRPC_ERROR_NONE);
|
63
62
|
return;
|
64
63
|
}
|
65
64
|
timer->pending = 1;
|
66
|
-
timeout = (uint64_t)(deadline -
|
65
|
+
timeout = (uint64_t)(deadline - grpc_core::ExecCtx::Get()->Now());
|
67
66
|
uv_timer = (uv_timer_t*)gpr_malloc(sizeof(uv_timer_t));
|
68
67
|
uv_timer_init(uv_default_loop(), uv_timer);
|
69
68
|
uv_timer->data = timer;
|
@@ -77,22 +76,21 @@ void grpc_timer_init(grpc_exec_ctx* exec_ctx, grpc_timer* timer,
|
|
77
76
|
|
78
77
|
void grpc_timer_init_unset(grpc_timer* timer) { timer->pending = 0; }
|
79
78
|
|
80
|
-
void grpc_timer_cancel(
|
79
|
+
void grpc_timer_cancel(grpc_timer* timer) {
|
81
80
|
GRPC_UV_ASSERT_SAME_THREAD();
|
82
81
|
if (timer->pending) {
|
83
82
|
timer->pending = 0;
|
84
|
-
GRPC_CLOSURE_SCHED(
|
83
|
+
GRPC_CLOSURE_SCHED(timer->closure, GRPC_ERROR_CANCELLED);
|
85
84
|
stop_uv_timer((uv_timer_t*)timer->uv_timer);
|
86
85
|
}
|
87
86
|
}
|
88
87
|
|
89
|
-
grpc_timer_check_result grpc_timer_check(
|
90
|
-
grpc_millis* next) {
|
88
|
+
grpc_timer_check_result grpc_timer_check(grpc_millis* next) {
|
91
89
|
return GRPC_TIMERS_NOT_CHECKED;
|
92
90
|
}
|
93
91
|
|
94
|
-
void grpc_timer_list_init(
|
95
|
-
void grpc_timer_list_shutdown(
|
92
|
+
void grpc_timer_list_init() {}
|
93
|
+
void grpc_timer_list_shutdown() {}
|
96
94
|
|
97
95
|
void grpc_timer_consume_kick(void) {}
|
98
96
|
|
@@ -21,6 +21,10 @@
|
|
21
21
|
#define _GNU_SOURCE
|
22
22
|
#endif
|
23
23
|
|
24
|
+
#ifndef SO_RXQ_OVFL
|
25
|
+
#define SO_RXQ_OVFL 40
|
26
|
+
#endif
|
27
|
+
|
24
28
|
#include "src/core/lib/iomgr/port.h"
|
25
29
|
|
26
30
|
#ifdef GRPC_POSIX_SOCKET
|
@@ -45,15 +49,16 @@
|
|
45
49
|
#include <grpc/support/sync.h>
|
46
50
|
#include <grpc/support/time.h>
|
47
51
|
#include "src/core/lib/channel/channel_args.h"
|
52
|
+
#include "src/core/lib/gpr/string.h"
|
48
53
|
#include "src/core/lib/iomgr/error.h"
|
49
54
|
#include "src/core/lib/iomgr/ev_posix.h"
|
55
|
+
#include "src/core/lib/iomgr/executor.h"
|
50
56
|
#include "src/core/lib/iomgr/resolve_address.h"
|
51
57
|
#include "src/core/lib/iomgr/sockaddr.h"
|
52
58
|
#include "src/core/lib/iomgr/sockaddr_utils.h"
|
53
59
|
#include "src/core/lib/iomgr/socket_factory_posix.h"
|
54
60
|
#include "src/core/lib/iomgr/socket_utils_posix.h"
|
55
61
|
#include "src/core/lib/iomgr/unix_sockets_posix.h"
|
56
|
-
#include "src/core/lib/support/string.h"
|
57
62
|
|
58
63
|
/* one listening port */
|
59
64
|
typedef struct grpc_udp_listener grpc_udp_listener;
|
@@ -71,14 +76,23 @@ struct grpc_udp_listener {
|
|
71
76
|
grpc_udp_server_read_cb read_cb;
|
72
77
|
grpc_udp_server_write_cb write_cb;
|
73
78
|
grpc_udp_server_orphan_cb orphan_cb;
|
79
|
+
grpc_udp_server_start_cb start_cb;
|
80
|
+
// To be scheduled on another thread to actually read/write.
|
81
|
+
grpc_closure do_read_closure;
|
82
|
+
grpc_closure do_write_closure;
|
83
|
+
grpc_closure notify_on_write_closure;
|
74
84
|
// True if orphan_cb is trigered.
|
75
85
|
bool orphan_notified;
|
86
|
+
// True if grpc_fd_notify_on_write() is called after on_write() call.
|
87
|
+
bool notify_on_write_armed;
|
88
|
+
// True if fd has been shutdown.
|
89
|
+
bool already_shutdown;
|
76
90
|
|
77
91
|
struct grpc_udp_listener* next;
|
78
92
|
};
|
79
93
|
|
80
94
|
struct shutdown_fd_args {
|
81
|
-
|
95
|
+
grpc_udp_listener* sp;
|
82
96
|
gpr_mu* server_mu;
|
83
97
|
};
|
84
98
|
|
@@ -141,26 +155,35 @@ grpc_udp_server* grpc_udp_server_create(const grpc_channel_args* args) {
|
|
141
155
|
return s;
|
142
156
|
}
|
143
157
|
|
144
|
-
static void shutdown_fd(
|
145
|
-
grpc_error* error) {
|
158
|
+
static void shutdown_fd(void* args, grpc_error* error) {
|
146
159
|
struct shutdown_fd_args* shutdown_args = (struct shutdown_fd_args*)args;
|
160
|
+
grpc_udp_listener* sp = shutdown_args->sp;
|
161
|
+
gpr_log(GPR_DEBUG, "shutdown fd %d", sp->fd);
|
147
162
|
gpr_mu_lock(shutdown_args->server_mu);
|
148
|
-
grpc_fd_shutdown(
|
163
|
+
grpc_fd_shutdown(sp->emfd, GRPC_ERROR_REF(error));
|
164
|
+
sp->already_shutdown = true;
|
165
|
+
if (!sp->notify_on_write_armed) {
|
166
|
+
// Re-arm write notification to notify listener with error. This is
|
167
|
+
// necessary to decrement active_ports.
|
168
|
+
sp->notify_on_write_armed = true;
|
169
|
+
grpc_fd_notify_on_write(sp->emfd, &sp->write_closure);
|
170
|
+
}
|
149
171
|
gpr_mu_unlock(shutdown_args->server_mu);
|
150
172
|
gpr_free(shutdown_args);
|
151
173
|
}
|
152
174
|
|
153
|
-
static void dummy_cb(
|
175
|
+
static void dummy_cb(void* arg, grpc_error* error) {
|
154
176
|
// No-op.
|
155
177
|
}
|
156
178
|
|
157
|
-
static void finish_shutdown(
|
179
|
+
static void finish_shutdown(grpc_udp_server* s) {
|
158
180
|
if (s->shutdown_complete != nullptr) {
|
159
|
-
GRPC_CLOSURE_SCHED(
|
181
|
+
GRPC_CLOSURE_SCHED(s->shutdown_complete, GRPC_ERROR_NONE);
|
160
182
|
}
|
161
183
|
|
162
184
|
gpr_mu_destroy(&s->mu);
|
163
185
|
|
186
|
+
gpr_log(GPR_DEBUG, "Destroy all listeners.");
|
164
187
|
while (s->head) {
|
165
188
|
grpc_udp_listener* sp = s->head;
|
166
189
|
s->head = sp->next;
|
@@ -174,14 +197,13 @@ static void finish_shutdown(grpc_exec_ctx* exec_ctx, grpc_udp_server* s) {
|
|
174
197
|
gpr_free(s);
|
175
198
|
}
|
176
199
|
|
177
|
-
static void destroyed_port(
|
178
|
-
grpc_error* error) {
|
200
|
+
static void destroyed_port(void* server, grpc_error* error) {
|
179
201
|
grpc_udp_server* s = (grpc_udp_server*)server;
|
180
202
|
gpr_mu_lock(&s->mu);
|
181
203
|
s->destroyed_ports++;
|
182
204
|
if (s->destroyed_ports == s->nports) {
|
183
205
|
gpr_mu_unlock(&s->mu);
|
184
|
-
finish_shutdown(
|
206
|
+
finish_shutdown(s);
|
185
207
|
} else {
|
186
208
|
gpr_mu_unlock(&s->mu);
|
187
209
|
}
|
@@ -190,7 +212,7 @@ static void destroyed_port(grpc_exec_ctx* exec_ctx, void* server,
|
|
190
212
|
/* called when all listening endpoints have been shutdown, so no further
|
191
213
|
events will be received on them - at this point it's safe to destroy
|
192
214
|
things */
|
193
|
-
static void deactivated_all_ports(
|
215
|
+
static void deactivated_all_ports(grpc_udp_server* s) {
|
194
216
|
/* delete ALL the things */
|
195
217
|
gpr_mu_lock(&s->mu);
|
196
218
|
|
@@ -207,24 +229,23 @@ static void deactivated_all_ports(grpc_exec_ctx* exec_ctx, grpc_udp_server* s) {
|
|
207
229
|
/* Call the orphan_cb to signal that the FD is about to be closed and
|
208
230
|
* should no longer be used. Because at this point, all listening ports
|
209
231
|
* have been shutdown already, no need to shutdown again.*/
|
210
|
-
GRPC_CLOSURE_INIT(&sp->orphan_fd_closure, dummy_cb, sp
|
232
|
+
GRPC_CLOSURE_INIT(&sp->orphan_fd_closure, dummy_cb, sp,
|
211
233
|
grpc_schedule_on_exec_ctx);
|
212
234
|
GPR_ASSERT(sp->orphan_cb);
|
213
|
-
|
214
|
-
|
235
|
+
gpr_log(GPR_DEBUG, "Orphan fd %d", sp->fd);
|
236
|
+
sp->orphan_cb(sp->emfd, &sp->orphan_fd_closure, sp->server->user_data);
|
215
237
|
}
|
216
|
-
grpc_fd_orphan(
|
238
|
+
grpc_fd_orphan(sp->emfd, &sp->destroyed_closure, nullptr,
|
217
239
|
false /* already_closed */, "udp_listener_shutdown");
|
218
240
|
}
|
219
241
|
gpr_mu_unlock(&s->mu);
|
220
242
|
} else {
|
221
243
|
gpr_mu_unlock(&s->mu);
|
222
|
-
finish_shutdown(
|
244
|
+
finish_shutdown(s);
|
223
245
|
}
|
224
246
|
}
|
225
247
|
|
226
|
-
void grpc_udp_server_destroy(
|
227
|
-
grpc_closure* on_done) {
|
248
|
+
void grpc_udp_server_destroy(grpc_udp_server* s, grpc_closure* on_done) {
|
228
249
|
grpc_udp_listener* sp;
|
229
250
|
gpr_mu_lock(&s->mu);
|
230
251
|
|
@@ -233,24 +254,24 @@ void grpc_udp_server_destroy(grpc_exec_ctx* exec_ctx, grpc_udp_server* s,
|
|
233
254
|
|
234
255
|
s->shutdown_complete = on_done;
|
235
256
|
|
257
|
+
gpr_log(GPR_DEBUG, "start to destroy udp_server");
|
236
258
|
/* shutdown all fd's */
|
237
259
|
if (s->active_ports) {
|
238
260
|
for (sp = s->head; sp; sp = sp->next) {
|
239
261
|
GPR_ASSERT(sp->orphan_cb);
|
240
262
|
struct shutdown_fd_args* args =
|
241
263
|
(struct shutdown_fd_args*)gpr_malloc(sizeof(*args));
|
242
|
-
args->
|
264
|
+
args->sp = sp;
|
243
265
|
args->server_mu = &s->mu;
|
244
266
|
GRPC_CLOSURE_INIT(&sp->orphan_fd_closure, shutdown_fd, args,
|
245
267
|
grpc_schedule_on_exec_ctx);
|
246
|
-
sp->orphan_cb(
|
247
|
-
sp->server->user_data);
|
268
|
+
sp->orphan_cb(sp->emfd, &sp->orphan_fd_closure, sp->server->user_data);
|
248
269
|
sp->orphan_notified = true;
|
249
270
|
}
|
250
271
|
gpr_mu_unlock(&s->mu);
|
251
272
|
} else {
|
252
273
|
gpr_mu_unlock(&s->mu);
|
253
|
-
deactivated_all_ports(
|
274
|
+
deactivated_all_ports(s);
|
254
275
|
}
|
255
276
|
}
|
256
277
|
|
@@ -263,11 +284,10 @@ static int bind_socket(grpc_socket_factory* socket_factory, int sockfd,
|
|
263
284
|
|
264
285
|
/* Prepare a recently-created socket for listening. */
|
265
286
|
static int prepare_socket(grpc_socket_factory* socket_factory, int fd,
|
266
|
-
const grpc_resolved_address* addr
|
287
|
+
const grpc_resolved_address* addr, int rcv_buf_size,
|
288
|
+
int snd_buf_size) {
|
267
289
|
grpc_resolved_address sockname_temp;
|
268
290
|
struct sockaddr* addr_ptr = (struct sockaddr*)addr->addr;
|
269
|
-
/* Set send/receive socket buffers to 1 MB */
|
270
|
-
int buffer_size_bytes = 1024 * 1024;
|
271
291
|
|
272
292
|
if (fd < 0) {
|
273
293
|
goto error;
|
@@ -308,18 +328,25 @@ static int prepare_socket(grpc_socket_factory* socket_factory, int fd,
|
|
308
328
|
goto error;
|
309
329
|
}
|
310
330
|
|
311
|
-
if (grpc_set_socket_sndbuf(fd,
|
331
|
+
if (grpc_set_socket_sndbuf(fd, snd_buf_size) != GRPC_ERROR_NONE) {
|
312
332
|
gpr_log(GPR_ERROR, "Failed to set send buffer size to %d bytes",
|
313
|
-
|
333
|
+
snd_buf_size);
|
314
334
|
goto error;
|
315
335
|
}
|
316
336
|
|
317
|
-
if (grpc_set_socket_rcvbuf(fd,
|
337
|
+
if (grpc_set_socket_rcvbuf(fd, rcv_buf_size) != GRPC_ERROR_NONE) {
|
318
338
|
gpr_log(GPR_ERROR, "Failed to set receive buffer size to %d bytes",
|
319
|
-
|
339
|
+
rcv_buf_size);
|
320
340
|
goto error;
|
321
341
|
}
|
322
342
|
|
343
|
+
{
|
344
|
+
int get_overflow = 1;
|
345
|
+
if (0 != setsockopt(fd, SOL_SOCKET, SO_RXQ_OVFL, &get_overflow,
|
346
|
+
sizeof(get_overflow))) {
|
347
|
+
gpr_log(GPR_INFO, "Failed to set socket overflow support");
|
348
|
+
}
|
349
|
+
}
|
323
350
|
return grpc_sockaddr_get_port(&sockname_temp);
|
324
351
|
|
325
352
|
error:
|
@@ -329,55 +356,113 @@ error:
|
|
329
356
|
return -1;
|
330
357
|
}
|
331
358
|
|
359
|
+
static void do_read(void* arg, grpc_error* error) {
|
360
|
+
grpc_udp_listener* sp = reinterpret_cast<grpc_udp_listener*>(arg);
|
361
|
+
GPR_ASSERT(sp->read_cb && error == GRPC_ERROR_NONE);
|
362
|
+
/* TODO: the reason we hold server->mu here is merely to prevent fd
|
363
|
+
* shutdown while we are reading. However, it blocks do_write(). Switch to
|
364
|
+
* read lock if available. */
|
365
|
+
gpr_mu_lock(&sp->server->mu);
|
366
|
+
/* Tell the registered callback that data is available to read. */
|
367
|
+
if (!sp->already_shutdown && sp->read_cb(sp->emfd)) {
|
368
|
+
/* There maybe more packets to read. Schedule read_more_cb_ closure to run
|
369
|
+
* after finishing this event loop. */
|
370
|
+
GRPC_CLOSURE_SCHED(&sp->do_read_closure, GRPC_ERROR_NONE);
|
371
|
+
} else {
|
372
|
+
/* Finish reading all the packets, re-arm the notification event so we can
|
373
|
+
* get another chance to read. Or fd already shutdown, re-arm to get a
|
374
|
+
* notification with shutdown error. */
|
375
|
+
grpc_fd_notify_on_read(sp->emfd, &sp->read_closure);
|
376
|
+
}
|
377
|
+
gpr_mu_unlock(&sp->server->mu);
|
378
|
+
}
|
379
|
+
|
332
380
|
/* event manager callback when reads are ready */
|
333
|
-
static void on_read(
|
381
|
+
static void on_read(void* arg, grpc_error* error) {
|
334
382
|
grpc_udp_listener* sp = (grpc_udp_listener*)arg;
|
335
383
|
|
336
384
|
gpr_mu_lock(&sp->server->mu);
|
337
385
|
if (error != GRPC_ERROR_NONE) {
|
338
386
|
if (0 == --sp->server->active_ports && sp->server->shutdown) {
|
339
387
|
gpr_mu_unlock(&sp->server->mu);
|
340
|
-
deactivated_all_ports(
|
388
|
+
deactivated_all_ports(sp->server);
|
341
389
|
} else {
|
342
390
|
gpr_mu_unlock(&sp->server->mu);
|
343
391
|
}
|
344
392
|
return;
|
345
393
|
}
|
346
|
-
|
347
|
-
|
394
|
+
/* Read once. If there is more data to read, off load the work to another
|
395
|
+
* thread to finish. */
|
348
396
|
GPR_ASSERT(sp->read_cb);
|
349
|
-
sp->read_cb(
|
397
|
+
if (sp->read_cb(sp->emfd)) {
|
398
|
+
/* There maybe more packets to read. Schedule read_more_cb_ closure to run
|
399
|
+
* after finishing this event loop. */
|
400
|
+
GRPC_CLOSURE_INIT(&sp->do_read_closure, do_read, arg,
|
401
|
+
grpc_executor_scheduler(GRPC_EXECUTOR_LONG));
|
402
|
+
GRPC_CLOSURE_SCHED(&sp->do_read_closure, GRPC_ERROR_NONE);
|
403
|
+
} else {
|
404
|
+
/* Finish reading all the packets, re-arm the notification event so we can
|
405
|
+
* get another chance to read. Or fd already shutdown, re-arm to get a
|
406
|
+
* notification with shutdown error. */
|
407
|
+
grpc_fd_notify_on_read(sp->emfd, &sp->read_closure);
|
408
|
+
}
|
409
|
+
gpr_mu_unlock(&sp->server->mu);
|
410
|
+
}
|
411
|
+
|
412
|
+
// Wrapper of grpc_fd_notify_on_write() with a grpc_closure callback interface.
|
413
|
+
void fd_notify_on_write_wrapper(void* arg, grpc_error* error) {
|
414
|
+
grpc_udp_listener* sp = reinterpret_cast<grpc_udp_listener*>(arg);
|
415
|
+
gpr_mu_lock(&sp->server->mu);
|
416
|
+
if (!sp->notify_on_write_armed) {
|
417
|
+
grpc_fd_notify_on_write(sp->emfd, &sp->write_closure);
|
418
|
+
sp->notify_on_write_armed = true;
|
419
|
+
}
|
420
|
+
gpr_mu_unlock(&sp->server->mu);
|
421
|
+
}
|
350
422
|
|
351
|
-
|
352
|
-
|
423
|
+
static void do_write(void* arg, grpc_error* error) {
|
424
|
+
grpc_udp_listener* sp = reinterpret_cast<grpc_udp_listener*>(arg);
|
425
|
+
gpr_mu_lock(&sp->server->mu);
|
426
|
+
if (sp->already_shutdown) {
|
427
|
+
// If fd has been shutdown, don't write any more and re-arm notification.
|
428
|
+
grpc_fd_notify_on_write(sp->emfd, &sp->write_closure);
|
429
|
+
} else {
|
430
|
+
sp->notify_on_write_armed = false;
|
431
|
+
/* Tell the registered callback that the socket is writeable. */
|
432
|
+
GPR_ASSERT(sp->write_cb && error == GRPC_ERROR_NONE);
|
433
|
+
GRPC_CLOSURE_INIT(&sp->notify_on_write_closure, fd_notify_on_write_wrapper,
|
434
|
+
arg, grpc_schedule_on_exec_ctx);
|
435
|
+
sp->write_cb(sp->emfd, sp->server->user_data, &sp->notify_on_write_closure);
|
436
|
+
}
|
353
437
|
gpr_mu_unlock(&sp->server->mu);
|
354
438
|
}
|
355
439
|
|
356
|
-
static void on_write(
|
440
|
+
static void on_write(void* arg, grpc_error* error) {
|
357
441
|
grpc_udp_listener* sp = (grpc_udp_listener*)arg;
|
358
442
|
|
359
|
-
gpr_mu_lock(&
|
443
|
+
gpr_mu_lock(&sp->server->mu);
|
360
444
|
if (error != GRPC_ERROR_NONE) {
|
361
445
|
if (0 == --sp->server->active_ports && sp->server->shutdown) {
|
362
446
|
gpr_mu_unlock(&sp->server->mu);
|
363
|
-
deactivated_all_ports(
|
447
|
+
deactivated_all_ports(sp->server);
|
364
448
|
} else {
|
365
449
|
gpr_mu_unlock(&sp->server->mu);
|
366
450
|
}
|
367
451
|
return;
|
368
452
|
}
|
369
453
|
|
370
|
-
/*
|
371
|
-
|
372
|
-
|
454
|
+
/* Schedule actual write in another thread. */
|
455
|
+
GRPC_CLOSURE_INIT(&sp->do_write_closure, do_write, arg,
|
456
|
+
grpc_executor_scheduler(GRPC_EXECUTOR_LONG));
|
373
457
|
|
374
|
-
|
375
|
-
grpc_fd_notify_on_write(exec_ctx, sp->emfd, &sp->write_closure);
|
458
|
+
GRPC_CLOSURE_SCHED(&sp->do_write_closure, GRPC_ERROR_NONE);
|
376
459
|
gpr_mu_unlock(&sp->server->mu);
|
377
460
|
}
|
378
461
|
|
379
462
|
static int add_socket_to_server(grpc_udp_server* s, int fd,
|
380
463
|
const grpc_resolved_address* addr,
|
464
|
+
int rcv_buf_size, int snd_buf_size,
|
465
|
+
grpc_udp_server_start_cb start_cb,
|
381
466
|
grpc_udp_server_read_cb read_cb,
|
382
467
|
grpc_udp_server_write_cb write_cb,
|
383
468
|
grpc_udp_server_orphan_cb orphan_cb) {
|
@@ -386,7 +471,8 @@ static int add_socket_to_server(grpc_udp_server* s, int fd,
|
|
386
471
|
char* addr_str;
|
387
472
|
char* name;
|
388
473
|
|
389
|
-
port =
|
474
|
+
port =
|
475
|
+
prepare_socket(s->socket_factory, fd, addr, rcv_buf_size, snd_buf_size);
|
390
476
|
if (port >= 0) {
|
391
477
|
grpc_sockaddr_to_string(&addr_str, addr, 1);
|
392
478
|
gpr_asprintf(&name, "udp-server-listener:%s", addr_str);
|
@@ -408,7 +494,9 @@ static int add_socket_to_server(grpc_udp_server* s, int fd,
|
|
408
494
|
sp->read_cb = read_cb;
|
409
495
|
sp->write_cb = write_cb;
|
410
496
|
sp->orphan_cb = orphan_cb;
|
497
|
+
sp->start_cb = start_cb;
|
411
498
|
sp->orphan_notified = false;
|
499
|
+
sp->already_shutdown = false;
|
412
500
|
GPR_ASSERT(sp->emfd);
|
413
501
|
gpr_mu_unlock(&s->mu);
|
414
502
|
gpr_free(name);
|
@@ -419,6 +507,8 @@ static int add_socket_to_server(grpc_udp_server* s, int fd,
|
|
419
507
|
|
420
508
|
int grpc_udp_server_add_port(grpc_udp_server* s,
|
421
509
|
const grpc_resolved_address* addr,
|
510
|
+
int rcv_buf_size, int snd_buf_size,
|
511
|
+
grpc_udp_server_start_cb start_cb,
|
422
512
|
grpc_udp_server_read_cb read_cb,
|
423
513
|
grpc_udp_server_write_cb write_cb,
|
424
514
|
grpc_udp_server_orphan_cb orphan_cb) {
|
@@ -469,7 +559,8 @@ int grpc_udp_server_add_port(grpc_udp_server* s,
|
|
469
559
|
GRPC_ERROR_UNREF(grpc_create_dualstack_socket_using_factory(
|
470
560
|
s->socket_factory, addr, SOCK_DGRAM, IPPROTO_UDP, &dsmode, &fd));
|
471
561
|
allocated_port1 =
|
472
|
-
add_socket_to_server(s, fd, addr,
|
562
|
+
add_socket_to_server(s, fd, addr, rcv_buf_size, snd_buf_size, start_cb,
|
563
|
+
read_cb, write_cb, orphan_cb);
|
473
564
|
if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) {
|
474
565
|
goto done;
|
475
566
|
}
|
@@ -492,7 +583,8 @@ int grpc_udp_server_add_port(grpc_udp_server* s,
|
|
492
583
|
addr = &addr4_copy;
|
493
584
|
}
|
494
585
|
allocated_port2 =
|
495
|
-
add_socket_to_server(s, fd, addr,
|
586
|
+
add_socket_to_server(s, fd, addr, rcv_buf_size, snd_buf_size, start_cb,
|
587
|
+
read_cb, write_cb, orphan_cb);
|
496
588
|
|
497
589
|
done:
|
498
590
|
gpr_free(allocated_addr);
|
@@ -512,9 +604,9 @@ int grpc_udp_server_get_fd(grpc_udp_server* s, unsigned port_index) {
|
|
512
604
|
return sp->fd;
|
513
605
|
}
|
514
606
|
|
515
|
-
void grpc_udp_server_start(
|
516
|
-
|
517
|
-
|
607
|
+
void grpc_udp_server_start(grpc_udp_server* s, grpc_pollset** pollsets,
|
608
|
+
size_t pollset_count, void* user_data) {
|
609
|
+
gpr_log(GPR_DEBUG, "grpc_udp_server_start");
|
518
610
|
size_t i;
|
519
611
|
gpr_mu_lock(&s->mu);
|
520
612
|
grpc_udp_listener* sp;
|
@@ -524,16 +616,18 @@ void grpc_udp_server_start(grpc_exec_ctx* exec_ctx, grpc_udp_server* s,
|
|
524
616
|
|
525
617
|
sp = s->head;
|
526
618
|
while (sp != nullptr) {
|
619
|
+
sp->start_cb(sp->emfd, sp->server->user_data);
|
527
620
|
for (i = 0; i < pollset_count; i++) {
|
528
|
-
grpc_pollset_add_fd(
|
621
|
+
grpc_pollset_add_fd(pollsets[i], sp->emfd);
|
529
622
|
}
|
530
623
|
GRPC_CLOSURE_INIT(&sp->read_closure, on_read, sp,
|
531
624
|
grpc_schedule_on_exec_ctx);
|
532
|
-
grpc_fd_notify_on_read(
|
625
|
+
grpc_fd_notify_on_read(sp->emfd, &sp->read_closure);
|
533
626
|
|
534
627
|
GRPC_CLOSURE_INIT(&sp->write_closure, on_write, sp,
|
535
628
|
grpc_schedule_on_exec_ctx);
|
536
|
-
|
629
|
+
sp->notify_on_write_armed = true;
|
630
|
+
grpc_fd_notify_on_write(sp->emfd, &sp->write_closure);
|
537
631
|
|
538
632
|
/* Registered for both read and write callbacks: increment active_ports
|
539
633
|
* twice to account for this, and delay free-ing of memory until both
|