grpc 1.0.1 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Makefile +3696 -867
- data/etc/roots.pem +39 -111
- data/include/grpc/byte_buffer.h +64 -1
- data/include/grpc/census.h +40 -96
- data/include/grpc/compression.h +2 -1
- data/include/grpc/grpc.h +42 -7
- data/include/grpc/grpc_posix.h +8 -5
- data/include/grpc/impl/codegen/atm.h +3 -0
- data/include/grpc/impl/codegen/atm_gcc_atomic.h +2 -0
- data/include/grpc/impl/codegen/atm_gcc_sync.h +8 -0
- data/include/grpc/impl/codegen/atm_windows.h +4 -0
- data/include/grpc/impl/codegen/byte_buffer_reader.h +4 -4
- data/include/grpc/impl/codegen/compression_types.h +1 -1
- data/include/grpc/impl/codegen/connectivity_state.h +2 -0
- data/include/grpc/impl/codegen/exec_ctx_fwd.h +41 -0
- data/include/grpc/impl/codegen/gpr_slice.h +84 -0
- data/include/grpc/impl/codegen/{alloc.h → gpr_types.h} +30 -29
- data/include/grpc/impl/codegen/grpc_types.h +91 -9
- data/include/grpc/impl/codegen/port_platform.h +25 -92
- data/include/grpc/impl/codegen/slice.h +54 -97
- data/include/grpc/impl/codegen/sync.h +0 -253
- data/include/grpc/module.modulemap +0 -2
- data/include/grpc/slice.h +132 -0
- data/include/grpc/{impl/codegen/slice_buffer.h → slice_buffer.h} +22 -39
- data/include/grpc/support/alloc.h +40 -1
- data/include/grpc/support/log.h +80 -1
- data/include/grpc/support/log_windows.h +2 -0
- data/include/grpc/support/string_util.h +1 -1
- data/include/grpc/support/sync.h +252 -0
- data/include/grpc/support/time.h +67 -1
- data/src/boringssl/err_data.c +639 -627
- data/src/core/ext/census/base_resources.c +71 -0
- data/src/core/ext/census/base_resources.h +39 -0
- data/src/core/ext/census/gen/census.pb.c +26 -29
- data/src/core/ext/census/gen/census.pb.h +68 -67
- data/src/core/ext/census/gen/trace_context.pb.c +81 -0
- data/src/core/ext/census/gen/trace_context.pb.h +99 -0
- data/src/core/ext/census/grpc_filter.c +22 -16
- data/src/core/ext/census/grpc_plugin.c +2 -1
- data/src/core/ext/census/initialize.c +16 -4
- data/src/core/ext/census/mlog.h +1 -1
- data/src/core/ext/census/placeholders.c +0 -45
- data/src/core/ext/census/resource.c +312 -0
- data/src/core/ext/census/resource.h +63 -0
- data/src/core/ext/census/trace_context.c +86 -0
- data/src/core/ext/census/trace_context.h +68 -0
- data/src/core/ext/census/tracing.c +8 -2
- data/src/core/ext/{client_config → client_channel}/channel_connectivity.c +8 -4
- data/src/core/ext/client_channel/client_channel.c +1218 -0
- data/src/core/ext/{client_config → client_channel}/client_channel.h +8 -11
- data/src/core/ext/{client_config → client_channel}/client_channel_factory.c +33 -3
- data/src/core/ext/{client_config → client_channel}/client_channel_factory.h +15 -8
- data/src/core/ext/{client_config/client_config_plugin.c → client_channel/client_channel_plugin.c} +16 -15
- data/src/core/ext/{client_config → client_channel}/connector.c +1 -1
- data/src/core/ext/{client_config → client_channel}/connector.h +5 -8
- data/{include/grpc/support/slice_buffer.h → src/core/ext/client_channel/default_initial_connect_string.c} +4 -5
- data/src/core/ext/client_channel/http_connect_handshaker.c +399 -0
- data/src/core/ext/client_channel/http_connect_handshaker.h +52 -0
- data/src/core/ext/{client_config → client_channel}/initial_connect_string.c +6 -7
- data/src/core/ext/{client_config → client_channel}/initial_connect_string.h +10 -10
- data/src/core/ext/{client_config → client_channel}/lb_policy.c +11 -11
- data/src/core/ext/{client_config → client_channel}/lb_policy.h +68 -27
- data/src/core/ext/client_channel/lb_policy_factory.c +163 -0
- data/src/core/ext/{client_config → client_channel}/lb_policy_factory.h +64 -9
- data/src/core/ext/{client_config → client_channel}/lb_policy_registry.c +6 -4
- data/src/core/ext/{client_config → client_channel}/lb_policy_registry.h +4 -4
- data/src/core/ext/{client_config → client_channel}/parse_address.c +21 -14
- data/src/core/ext/{client_config → client_channel}/parse_address.h +8 -10
- data/src/core/ext/{client_config → client_channel}/resolver.c +3 -4
- data/src/core/ext/{client_config → client_channel}/resolver.h +11 -15
- data/src/core/ext/{client_config → client_channel}/resolver_factory.c +4 -3
- data/src/core/ext/{client_config → client_channel}/resolver_factory.h +13 -11
- data/src/core/ext/{client_config → client_channel}/resolver_registry.c +54 -34
- data/src/core/ext/{client_config → client_channel}/resolver_registry.h +21 -8
- data/src/core/ext/{client_config → client_channel}/subchannel.c +208 -119
- data/src/core/ext/{client_config → client_channel}/subchannel.h +21 -11
- data/src/core/ext/{client_config → client_channel}/subchannel_index.c +6 -17
- data/src/core/ext/{client_config → client_channel}/subchannel_index.h +7 -7
- data/src/core/ext/{client_config → client_channel}/uri_parser.c +21 -28
- data/src/core/ext/{client_config → client_channel}/uri_parser.h +3 -3
- data/src/core/ext/lb_policy/grpclb/grpclb.c +1406 -0
- data/src/core/ext/lb_policy/grpclb/grpclb.h +44 -0
- data/src/core/ext/lb_policy/grpclb/load_balancer_api.c +117 -37
- data/src/core/ext/lb_policy/grpclb/load_balancer_api.h +31 -12
- data/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c +6 -36
- data/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h +22 -42
- data/src/core/ext/lb_policy/pick_first/pick_first.c +64 -46
- data/src/core/ext/lb_policy/round_robin/round_robin.c +324 -160
- data/src/core/ext/load_reporting/load_reporting.c +7 -56
- data/src/core/ext/load_reporting/load_reporting.h +41 -28
- data/src/core/ext/load_reporting/load_reporting_filter.c +132 -42
- data/src/core/ext/load_reporting/load_reporting_filter.h +1 -0
- data/src/core/ext/resolver/dns/native/dns_resolver.c +88 -80
- data/src/core/ext/resolver/sockaddr/sockaddr_resolver.c +57 -102
- data/src/core/ext/transport/chttp2/alpn/alpn.c +1 -1
- data/src/core/ext/transport/chttp2/client/chttp2_connector.c +253 -0
- data/src/core/{lib/iomgr/ev_poll_and_epoll_posix.h → ext/transport/chttp2/client/chttp2_connector.h} +5 -5
- data/src/core/ext/transport/chttp2/client/insecure/channel_create.c +31 -160
- data/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c +5 -5
- data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c +44 -243
- data/src/core/ext/transport/chttp2/server/chttp2_server.c +342 -0
- data/src/core/ext/transport/chttp2/server/chttp2_server.h +47 -0
- data/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c +11 -124
- data/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c +20 -9
- data/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c +28 -236
- data/src/core/ext/transport/chttp2/transport/bin_decoder.c +31 -27
- data/src/core/ext/transport/chttp2/transport/bin_decoder.h +5 -4
- data/src/core/ext/transport/chttp2/transport/bin_encoder.c +25 -22
- data/src/core/ext/transport/chttp2/transport/bin_encoder.h +8 -7
- data/src/core/ext/transport/chttp2/transport/chttp2_plugin.c +0 -3
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.c +1345 -1521
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +3 -1
- data/src/core/ext/transport/chttp2/transport/frame.h +3 -5
- data/src/core/ext/transport/chttp2/transport/frame_data.c +50 -47
- data/src/core/ext/transport/chttp2/transport/frame_data.h +8 -9
- data/src/core/ext/transport/chttp2/transport/frame_goaway.c +19 -21
- data/src/core/ext/transport/chttp2/transport/frame_goaway.h +9 -8
- data/src/core/ext/transport/chttp2/transport/frame_ping.c +13 -12
- data/src/core/ext/transport/chttp2/transport/frame_ping.h +6 -6
- data/src/core/ext/transport/chttp2/transport/frame_rst_stream.c +31 -19
- data/src/core/ext/transport/chttp2/transport/frame_rst_stream.h +8 -7
- data/src/core/ext/transport/chttp2/transport/frame_settings.c +22 -25
- data/src/core/ext/transport/chttp2/transport/frame_settings.h +9 -8
- data/src/core/ext/transport/chttp2/transport/frame_window_update.c +26 -18
- data/src/core/ext/transport/chttp2/transport/frame_window_update.h +5 -6
- data/src/core/ext/transport/chttp2/transport/hpack_encoder.c +68 -58
- data/src/core/ext/transport/chttp2/transport/hpack_encoder.h +8 -5
- data/src/core/ext/transport/chttp2/transport/hpack_parser.c +327 -214
- data/src/core/ext/transport/chttp2/transport/hpack_parser.h +14 -9
- data/src/core/ext/transport/chttp2/transport/hpack_table.c +24 -19
- data/src/core/ext/transport/chttp2/transport/hpack_table.h +9 -6
- data/src/core/ext/transport/chttp2/transport/incoming_metadata.c +2 -2
- data/src/core/ext/transport/chttp2/transport/incoming_metadata.h +1 -1
- data/src/core/ext/transport/chttp2/transport/internal.h +284 -436
- data/src/core/ext/transport/chttp2/transport/parsing.c +355 -590
- data/src/core/ext/transport/chttp2/transport/stream_lists.c +36 -309
- data/src/core/ext/transport/chttp2/transport/stream_map.c +13 -34
- data/src/core/ext/transport/chttp2/transport/stream_map.h +3 -4
- data/src/core/ext/transport/chttp2/transport/writing.c +174 -286
- data/src/core/lib/channel/channel_args.c +70 -13
- data/src/core/lib/channel/channel_args.h +28 -2
- data/src/core/lib/channel/channel_stack.c +77 -28
- data/src/core/lib/channel/channel_stack.h +61 -23
- data/src/core/lib/channel/channel_stack_builder.c +33 -25
- data/src/core/lib/channel/channel_stack_builder.h +17 -8
- data/src/core/lib/channel/compress_filter.c +52 -36
- data/src/core/lib/channel/connected_channel.c +20 -12
- data/src/core/lib/channel/connected_channel.h +2 -1
- data/src/core/lib/channel/context.h +13 -1
- data/src/core/lib/channel/deadline_filter.c +344 -0
- data/src/core/lib/channel/deadline_filter.h +99 -0
- data/src/core/lib/channel/handshaker.c +240 -0
- data/src/core/lib/channel/handshaker.h +164 -0
- data/src/core/lib/{security/credentials/google_default/credentials_windows.c → channel/handshaker_factory.c} +16 -23
- data/src/core/lib/channel/handshaker_factory.h +66 -0
- data/src/core/lib/channel/handshaker_registry.c +113 -0
- data/src/core/{ext/client_config/client_config.h → lib/channel/handshaker_registry.h} +26 -16
- data/src/core/lib/channel/http_client_filter.c +248 -46
- data/src/core/lib/channel/http_client_filter.h +3 -0
- data/src/core/lib/channel/http_server_filter.c +136 -24
- data/src/core/lib/channel/message_size_filter.c +261 -0
- data/src/core/lib/channel/message_size_filter.h +39 -0
- data/src/core/lib/compression/message_compress.c +43 -37
- data/src/core/lib/compression/message_compress.h +7 -5
- data/src/core/lib/http/format_request.c +26 -11
- data/src/core/lib/http/format_request.h +7 -5
- data/src/core/lib/http/httpcli.c +45 -27
- data/src/core/lib/http/httpcli.h +4 -4
- data/src/core/lib/http/httpcli_security_connector.c +56 -46
- data/src/core/lib/http/parser.c +17 -14
- data/src/core/lib/http/parser.h +4 -2
- data/src/core/lib/iomgr/closure.c +49 -7
- data/src/core/lib/iomgr/closure.h +56 -14
- data/src/core/lib/iomgr/combiner.c +422 -0
- data/src/core/lib/iomgr/combiner.h +64 -0
- data/src/core/lib/iomgr/endpoint.c +8 -2
- data/src/core/lib/iomgr/endpoint.h +17 -7
- data/src/core/lib/iomgr/endpoint_pair.h +3 -2
- data/src/core/lib/iomgr/endpoint_pair_posix.c +9 -8
- data/src/core/{ext/client_config/lb_policy_factory.c → lib/iomgr/endpoint_pair_uv.c} +18 -13
- data/src/core/lib/iomgr/endpoint_pair_windows.c +7 -6
- data/src/core/lib/iomgr/error.c +72 -6
- data/src/core/lib/iomgr/error.h +30 -3
- data/src/core/lib/iomgr/ev_epoll_linux.c +500 -382
- data/src/core/lib/iomgr/ev_epoll_linux.h +3 -2
- data/src/core/lib/iomgr/ev_poll_posix.c +317 -30
- data/src/core/lib/iomgr/ev_poll_posix.h +1 -0
- data/src/core/lib/iomgr/ev_posix.c +26 -5
- data/src/core/lib/iomgr/ev_posix.h +12 -1
- data/src/core/lib/iomgr/exec_ctx.c +27 -94
- data/src/core/lib/iomgr/exec_ctx.h +19 -22
- data/src/core/lib/iomgr/executor.c +29 -8
- data/src/core/lib/iomgr/executor.h +2 -4
- data/src/core/lib/iomgr/iocp_windows.c +3 -4
- data/src/core/lib/iomgr/iomgr.c +14 -10
- data/src/core/lib/iomgr/iomgr.h +6 -2
- data/src/core/lib/iomgr/iomgr_posix.c +2 -2
- data/src/core/lib/iomgr/iomgr_uv.c +49 -0
- data/src/core/lib/iomgr/iomgr_windows.c +2 -2
- data/src/core/lib/iomgr/load_file.c +3 -3
- data/src/core/lib/iomgr/load_file.h +2 -2
- data/src/core/lib/iomgr/network_status_tracker.c +1 -1
- data/src/core/lib/iomgr/pollset_set_uv.c +62 -0
- data/src/core/lib/iomgr/pollset_set_windows.c +3 -3
- data/src/core/lib/iomgr/pollset_uv.c +142 -0
- data/src/core/lib/iomgr/pollset_uv.h +42 -0
- data/src/core/lib/iomgr/pollset_windows.c +5 -6
- data/src/core/lib/iomgr/port.h +129 -0
- data/src/core/lib/iomgr/resolve_address.h +2 -1
- data/src/core/lib/iomgr/resolve_address_posix.c +14 -13
- data/src/core/lib/iomgr/resolve_address_uv.c +233 -0
- data/src/core/lib/iomgr/resolve_address_windows.c +14 -12
- data/src/core/lib/iomgr/resource_quota.c +832 -0
- data/src/core/lib/iomgr/resource_quota.h +159 -0
- data/src/core/lib/iomgr/sockaddr.h +10 -2
- data/src/core/lib/iomgr/sockaddr_utils.c +63 -36
- data/src/core/lib/iomgr/sockaddr_utils.h +14 -14
- data/src/core/lib/iomgr/socket_mutator.c +98 -0
- data/src/core/lib/iomgr/socket_mutator.h +80 -0
- data/src/core/lib/iomgr/socket_utils.h +42 -0
- data/src/core/lib/iomgr/socket_utils_common_posix.c +28 -13
- data/src/core/lib/iomgr/socket_utils_linux.c +11 -5
- data/src/core/lib/iomgr/socket_utils_posix.c +10 -7
- data/src/core/lib/iomgr/socket_utils_posix.h +11 -4
- data/src/core/lib/iomgr/socket_utils_uv.c +49 -0
- data/src/core/lib/iomgr/socket_utils_windows.c +52 -0
- data/src/core/lib/iomgr/socket_windows.c +14 -6
- data/src/core/lib/iomgr/socket_windows.h +1 -0
- data/src/core/lib/iomgr/tcp_client.h +8 -2
- data/src/core/lib/iomgr/tcp_client_posix.c +131 -82
- data/src/core/lib/iomgr/tcp_client_posix.h +45 -0
- data/src/core/lib/iomgr/tcp_client_uv.c +190 -0
- data/src/core/lib/iomgr/tcp_client_windows.c +54 -30
- data/src/core/lib/iomgr/tcp_posix.c +135 -56
- data/src/core/lib/iomgr/tcp_posix.h +2 -2
- data/src/core/lib/iomgr/tcp_server.h +14 -6
- data/src/core/lib/iomgr/tcp_server_posix.c +154 -118
- data/src/core/lib/iomgr/tcp_server_uv.c +388 -0
- data/src/core/lib/iomgr/tcp_server_windows.c +127 -100
- data/src/core/lib/iomgr/tcp_uv.c +367 -0
- data/src/core/lib/iomgr/tcp_uv.h +59 -0
- data/src/core/lib/iomgr/tcp_windows.c +65 -48
- data/src/core/lib/iomgr/tcp_windows.h +3 -1
- data/src/core/lib/iomgr/timer.h +21 -21
- data/src/core/lib/iomgr/{timer.c → timer_generic.c} +15 -10
- data/src/core/lib/iomgr/timer_generic.h +49 -0
- data/src/core/lib/iomgr/timer_heap.c +6 -0
- data/src/core/lib/iomgr/timer_uv.c +99 -0
- data/src/core/lib/iomgr/timer_uv.h +47 -0
- data/src/core/lib/iomgr/udp_server.c +116 -98
- data/src/core/lib/iomgr/udp_server.h +5 -3
- data/src/core/lib/iomgr/unix_sockets_posix.c +14 -6
- data/src/core/lib/iomgr/unix_sockets_posix.h +6 -5
- data/src/core/lib/iomgr/unix_sockets_posix_noop.c +4 -4
- data/src/core/lib/iomgr/wakeup_fd_cv.c +118 -0
- data/src/core/lib/iomgr/wakeup_fd_cv.h +80 -0
- data/src/core/lib/iomgr/wakeup_fd_eventfd.c +3 -3
- data/src/core/lib/iomgr/wakeup_fd_nospecial.c +3 -3
- data/src/core/lib/iomgr/wakeup_fd_pipe.c +12 -6
- data/src/core/lib/iomgr/wakeup_fd_posix.c +34 -5
- data/src/core/lib/iomgr/wakeup_fd_posix.h +5 -0
- data/src/core/lib/iomgr/workqueue.h +12 -20
- data/src/core/{ext/client_config/client_config.c → lib/iomgr/workqueue_uv.c} +24 -33
- data/{include/grpc/support/slice.h → src/core/lib/iomgr/workqueue_uv.h} +4 -6
- data/src/core/lib/iomgr/workqueue_windows.c +9 -8
- data/src/core/lib/json/json.c +3 -3
- data/src/core/lib/json/json.h +11 -11
- data/src/core/lib/json/json_reader.c +9 -5
- data/src/core/lib/profiling/basic_timers.c +10 -1
- data/src/core/lib/profiling/timers.h +2 -0
- data/src/core/lib/security/context/security_context.c +13 -3
- data/src/core/lib/security/context/security_context.h +20 -0
- data/src/core/lib/security/credentials/composite/composite_credentials.c +28 -14
- data/src/core/lib/security/credentials/composite/composite_credentials.h +2 -2
- data/src/core/lib/security/credentials/credentials.c +48 -19
- data/src/core/lib/security/credentials/credentials.h +36 -19
- data/src/core/lib/security/credentials/credentials_metadata.c +11 -8
- data/src/core/lib/security/credentials/fake/fake_credentials.c +15 -11
- data/src/core/lib/security/credentials/google_default/{credentials_posix.c → credentials_generic.c} +7 -14
- data/src/core/lib/security/credentials/google_default/google_default_credentials.c +33 -21
- data/src/core/lib/security/credentials/google_default/google_default_credentials.h +14 -0
- data/src/core/lib/security/credentials/iam/iam_credentials.c +3 -2
- data/src/core/lib/security/credentials/jwt/json_token.c +1 -0
- data/src/core/lib/security/credentials/jwt/json_token.h +1 -1
- data/src/core/lib/security/credentials/jwt/jwt_credentials.c +54 -19
- data/src/core/lib/security/credentials/jwt/jwt_credentials.h +2 -1
- data/src/core/lib/security/credentials/jwt/jwt_verifier.c +129 -79
- data/src/core/lib/security/credentials/jwt/jwt_verifier.h +9 -6
- data/src/core/lib/security/credentials/oauth2/oauth2_credentials.c +63 -28
- data/src/core/lib/security/credentials/oauth2/oauth2_credentials.h +1 -1
- data/src/core/lib/security/credentials/plugin/plugin_credentials.c +32 -11
- data/src/core/lib/security/credentials/ssl/ssl_credentials.c +13 -9
- data/src/core/lib/security/transport/client_auth_filter.c +33 -27
- data/src/core/lib/security/transport/secure_endpoint.c +93 -68
- data/src/core/lib/security/transport/secure_endpoint.h +2 -2
- data/src/core/lib/security/transport/security_connector.c +133 -168
- data/src/core/lib/security/transport/security_connector.h +31 -46
- data/src/core/lib/security/transport/security_handshaker.c +501 -0
- data/src/core/lib/security/transport/{handshake.h → security_handshaker.h} +10 -10
- data/src/core/lib/security/transport/server_auth_filter.c +50 -38
- data/src/core/lib/security/util/b64.c +11 -8
- data/src/core/lib/security/util/b64.h +5 -4
- data/src/core/lib/slice/percent_encoding.c +182 -0
- data/src/core/lib/slice/percent_encoding.h +78 -0
- data/src/core/lib/{support → slice}/slice.c +81 -50
- data/src/core/lib/{support → slice}/slice_buffer.c +78 -60
- data/src/core/lib/slice/slice_internal.h +49 -0
- data/src/core/lib/slice/slice_string_helpers.c +90 -0
- data/src/core/lib/{iomgr/workqueue_posix.h → slice/slice_string_helpers.h} +18 -18
- data/src/core/lib/support/backoff.c +24 -13
- data/src/core/lib/support/backoff.h +5 -2
- data/src/core/lib/support/env.h +0 -2
- data/src/core/lib/support/log.c +5 -4
- data/src/core/lib/support/log_linux.c +0 -1
- data/src/core/lib/support/log_posix.c +1 -1
- data/src/core/lib/support/mpscq.c +83 -0
- data/src/core/lib/support/mpscq.h +65 -0
- data/src/core/lib/support/string.c +58 -49
- data/src/core/lib/support/string.h +11 -8
- data/src/core/lib/support/subprocess_posix.c +5 -2
- data/src/core/lib/support/thd.c +1 -1
- data/src/core/lib/support/time.c +43 -79
- data/src/core/lib/support/time_posix.c +1 -1
- data/src/core/lib/support/tmpfile.h +0 -2
- data/src/core/lib/surface/alarm.c +4 -1
- data/src/core/lib/surface/byte_buffer.c +17 -11
- data/src/core/lib/surface/byte_buffer_reader.c +23 -15
- data/src/core/lib/surface/call.c +294 -276
- data/src/core/lib/surface/call.h +24 -9
- data/src/core/lib/surface/call_log_batch.c +5 -3
- data/src/core/lib/surface/channel.c +127 -111
- data/src/core/lib/surface/channel.h +14 -5
- data/src/core/lib/surface/channel_init.c +1 -1
- data/src/core/lib/surface/channel_init.h +10 -1
- data/src/core/lib/surface/channel_ping.c +7 -6
- data/src/core/lib/surface/completion_queue.c +154 -18
- data/src/core/lib/surface/completion_queue.h +5 -0
- data/src/core/lib/surface/init.c +40 -6
- data/src/core/lib/surface/init.h +1 -0
- data/src/core/lib/surface/init_secure.c +5 -2
- data/src/core/lib/surface/lame_client.c +28 -18
- data/src/core/lib/surface/server.c +134 -87
- data/src/core/lib/surface/server.h +8 -0
- data/src/core/lib/surface/validate_metadata.c +1 -1
- data/src/core/lib/surface/version.c +3 -1
- data/src/core/lib/transport/byte_stream.c +7 -4
- data/src/core/lib/transport/byte_stream.h +6 -10
- data/src/core/lib/transport/connectivity_state.c +21 -12
- data/src/core/lib/transport/connectivity_state.h +4 -1
- data/src/core/lib/transport/mdstr_hash_table.c +118 -0
- data/src/core/lib/transport/mdstr_hash_table.h +77 -0
- data/src/core/lib/transport/metadata.c +83 -60
- data/src/core/lib/transport/metadata.h +41 -23
- data/src/core/lib/transport/metadata_batch.c +17 -11
- data/src/core/lib/transport/metadata_batch.h +20 -6
- data/src/core/lib/transport/pid_controller.c +57 -0
- data/src/core/lib/transport/pid_controller.h +64 -0
- data/src/core/lib/transport/service_config.c +251 -0
- data/src/core/lib/transport/service_config.h +71 -0
- data/src/core/lib/transport/static_metadata.c +18 -16
- data/src/core/lib/transport/static_metadata.h +113 -107
- data/src/core/{ext/transport/chttp2 → lib}/transport/timeout_encoding.c +3 -3
- data/src/core/{ext/transport/chttp2 → lib}/transport/timeout_encoding.h +7 -7
- data/src/core/lib/transport/transport.c +84 -23
- data/src/core/lib/transport/transport.h +53 -8
- data/src/core/lib/transport/transport_impl.h +3 -0
- data/src/core/lib/transport/transport_op_string.c +92 -20
- data/src/core/lib/tsi/ssl_transport_security.c +3 -1
- data/src/core/plugin_registry/grpc_plugin_registry.c +8 -4
- data/src/ruby/ext/grpc/extconf.rb +0 -1
- data/src/ruby/ext/grpc/rb_byte_buffer.c +8 -7
- data/src/ruby/ext/grpc/rb_call.c +15 -5
- data/src/ruby/ext/grpc/rb_channel.c +1 -1
- data/src/ruby/ext/grpc/rb_compression_options.c +466 -0
- data/src/{core/ext/client_config/default_initial_connect_string.c → ruby/ext/grpc/rb_compression_options.h} +10 -5
- data/src/ruby/ext/grpc/rb_grpc.c +3 -1
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +198 -190
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +306 -294
- data/src/ruby/ext/grpc/rb_server.c +18 -12
- data/src/ruby/lib/grpc/errors.rb +154 -2
- data/src/ruby/lib/grpc/generic/active_call.rb +144 -63
- data/src/ruby/lib/grpc/generic/bidi_call.rb +18 -2
- data/src/ruby/lib/grpc/generic/client_stub.rb +7 -5
- data/src/ruby/lib/grpc/generic/rpc_desc.rb +39 -13
- data/src/ruby/lib/grpc/generic/rpc_server.rb +51 -24
- data/src/ruby/lib/grpc/generic/service.rb +3 -2
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/src/ruby/pb/grpc/health/checker.rb +3 -1
- data/src/ruby/pb/src/proto/grpc/testing/test_services_pb.rb +7 -0
- data/src/ruby/pb/test/client.rb +307 -7
- data/src/ruby/pb/test/server.rb +26 -1
- data/src/ruby/spec/compression_options_spec.rb +164 -0
- data/src/ruby/spec/error_sanity_spec.rb +64 -0
- data/src/ruby/spec/generic/active_call_spec.rb +290 -12
- data/src/ruby/spec/generic/client_stub_spec.rb +91 -41
- data/src/ruby/spec/generic/rpc_desc_spec.rb +36 -16
- data/src/ruby/spec/generic/rpc_server_pool_spec.rb +22 -28
- data/src/ruby/spec/generic/rpc_server_spec.rb +6 -6
- data/src/ruby/spec/pb/health/checker_spec.rb +27 -19
- data/src/ruby/spec/spec_helper.rb +2 -0
- data/third_party/boringssl/crypto/aes/aes.c +12 -12
- data/third_party/boringssl/crypto/aes/mode_wrappers.c +6 -2
- data/third_party/boringssl/crypto/asn1/a_d2i_fp.c +28 -13
- data/third_party/boringssl/crypto/asn1/a_gentm.c +2 -0
- data/third_party/boringssl/crypto/asn1/a_object.c +7 -3
- data/third_party/boringssl/crypto/asn1/a_strnid.c +1 -0
- data/third_party/boringssl/crypto/asn1/a_time.c +0 -11
- data/third_party/boringssl/crypto/asn1/a_type.c +0 -2
- data/third_party/boringssl/crypto/asn1/a_utctm.c +1 -30
- data/third_party/boringssl/crypto/asn1/asn1_lib.c +56 -76
- data/third_party/boringssl/crypto/asn1/asn1_locl.h +0 -10
- data/third_party/boringssl/crypto/asn1/asn1_par.c +0 -322
- data/third_party/boringssl/crypto/asn1/f_enum.c +1 -108
- data/third_party/boringssl/crypto/asn1/f_int.c +1 -106
- data/third_party/boringssl/crypto/asn1/f_string.c +1 -106
- data/third_party/boringssl/crypto/asn1/tasn_dec.c +10 -14
- data/third_party/boringssl/crypto/asn1/tasn_enc.c +17 -11
- data/third_party/boringssl/crypto/asn1/tasn_typ.c +29 -42
- data/third_party/boringssl/crypto/asn1/tasn_utl.c +1 -1
- data/third_party/boringssl/crypto/base64/base64.c +249 -285
- data/third_party/boringssl/crypto/bio/bio.c +13 -23
- data/third_party/boringssl/crypto/bio/bio_mem.c +3 -2
- data/third_party/boringssl/crypto/bio/connect.c +12 -3
- data/third_party/boringssl/crypto/bio/fd.c +22 -15
- data/third_party/boringssl/crypto/bio/file.c +2 -38
- data/third_party/boringssl/crypto/bio/hexdump.c +1 -2
- data/third_party/boringssl/crypto/bio/internal.h +3 -0
- data/third_party/boringssl/crypto/bio/pair.c +1 -1
- data/third_party/boringssl/crypto/bio/socket.c +10 -2
- data/third_party/boringssl/crypto/bio/socket_helper.c +2 -2
- data/third_party/boringssl/crypto/bn/asm/x86_64-gcc.c +0 -8
- data/third_party/boringssl/crypto/bn/bn.c +38 -0
- data/third_party/boringssl/crypto/bn/cmp.c +25 -0
- data/third_party/boringssl/crypto/bn/convert.c +73 -76
- data/third_party/boringssl/crypto/bn/div.c +136 -70
- data/third_party/boringssl/crypto/bn/exponentiation.c +86 -381
- data/third_party/boringssl/crypto/bn/gcd.c +213 -296
- data/third_party/boringssl/crypto/bn/generic.c +0 -80
- data/third_party/boringssl/crypto/bn/internal.h +15 -3
- data/third_party/boringssl/crypto/bn/montgomery.c +57 -207
- data/third_party/boringssl/crypto/bn/montgomery_inv.c +160 -0
- data/third_party/boringssl/crypto/bn/mul.c +2 -1
- data/third_party/boringssl/crypto/bn/prime.c +24 -8
- data/third_party/boringssl/crypto/bn/random.c +47 -33
- data/third_party/boringssl/crypto/bn/sqrt.c +4 -5
- data/third_party/boringssl/crypto/buf/buf.c +25 -21
- data/third_party/boringssl/crypto/bytestring/ber.c +1 -0
- data/third_party/boringssl/crypto/bytestring/cbb.c +50 -22
- data/third_party/boringssl/crypto/bytestring/cbs.c +28 -4
- data/third_party/boringssl/crypto/chacha/{chacha_generic.c → chacha.c} +56 -29
- data/third_party/boringssl/crypto/cipher/aead.c +11 -22
- data/third_party/boringssl/crypto/cipher/cipher.c +2 -2
- data/third_party/boringssl/crypto/cipher/e_aes.c +53 -103
- data/third_party/boringssl/crypto/cipher/e_chacha20poly1305.c +2 -8
- data/third_party/boringssl/crypto/cipher/e_des.c +3 -5
- data/third_party/boringssl/crypto/cipher/e_null.c +1 -1
- data/third_party/boringssl/crypto/cipher/e_rc2.c +1 -1
- data/third_party/boringssl/crypto/cipher/e_rc4.c +1 -1
- data/third_party/boringssl/crypto/cipher/e_ssl3.c +3 -63
- data/third_party/boringssl/crypto/cipher/e_tls.c +12 -83
- data/third_party/boringssl/crypto/cipher/internal.h +8 -10
- data/third_party/boringssl/crypto/cipher/tls_cbc.c +69 -40
- data/third_party/boringssl/crypto/conf/conf.c +2 -1
- data/third_party/boringssl/crypto/cpu-aarch64-linux.c +61 -0
- data/third_party/boringssl/crypto/cpu-arm-linux.c +360 -0
- data/third_party/boringssl/crypto/cpu-arm.c +0 -161
- data/third_party/boringssl/crypto/cpu-intel.c +5 -3
- data/third_party/boringssl/{ssl/test/scoped_types.h → crypto/cpu-ppc64le.c} +21 -9
- data/third_party/boringssl/crypto/crypto.c +29 -7
- data/third_party/boringssl/crypto/curve25519/curve25519.c +284 -242
- data/third_party/boringssl/crypto/curve25519/internal.h +64 -0
- data/third_party/boringssl/crypto/curve25519/spake25519.c +464 -0
- data/third_party/boringssl/crypto/curve25519/x25519-x86_64.c +21 -0
- data/third_party/boringssl/crypto/dh/check.c +22 -6
- data/third_party/boringssl/crypto/dh/dh.c +45 -21
- data/third_party/boringssl/crypto/dh/dh_asn1.c +96 -20
- data/third_party/boringssl/crypto/dh/params.c +30 -78
- data/third_party/boringssl/crypto/digest/digest.c +3 -3
- data/third_party/boringssl/crypto/dsa/dsa.c +59 -29
- data/third_party/boringssl/crypto/dsa/dsa_asn1.c +4 -0
- data/third_party/boringssl/crypto/ec/ec.c +84 -140
- data/third_party/boringssl/crypto/ec/ec_asn1.c +82 -52
- data/third_party/boringssl/crypto/ec/ec_key.c +15 -15
- data/third_party/boringssl/crypto/ec/ec_montgomery.c +87 -50
- data/third_party/boringssl/crypto/ec/internal.h +12 -36
- data/third_party/boringssl/crypto/ec/oct.c +11 -11
- data/third_party/boringssl/crypto/ec/p224-64.c +59 -116
- data/third_party/boringssl/crypto/ec/p256-64.c +88 -163
- data/third_party/boringssl/crypto/ec/p256-x86_64.c +46 -58
- data/third_party/boringssl/crypto/ec/simple.c +81 -201
- data/third_party/boringssl/crypto/ec/util-64.c +0 -74
- data/third_party/boringssl/crypto/ecdh/ecdh.c +7 -1
- data/third_party/boringssl/crypto/ecdsa/ecdsa.c +28 -46
- data/third_party/boringssl/crypto/ecdsa/ecdsa_asn1.c +1 -0
- data/third_party/boringssl/crypto/engine/engine.c +1 -1
- data/third_party/boringssl/crypto/err/err.c +3 -3
- data/third_party/boringssl/crypto/evp/evp.c +14 -59
- data/third_party/boringssl/crypto/evp/evp_asn1.c +144 -87
- data/third_party/boringssl/crypto/evp/evp_ctx.c +7 -7
- data/third_party/boringssl/crypto/evp/internal.h +4 -46
- data/third_party/boringssl/crypto/evp/p_dsa_asn1.c +8 -157
- data/third_party/boringssl/crypto/evp/p_ec.c +1 -1
- data/third_party/boringssl/crypto/evp/p_ec_asn1.c +22 -170
- data/third_party/boringssl/crypto/evp/p_rsa.c +1 -1
- data/third_party/boringssl/crypto/evp/p_rsa_asn1.c +10 -548
- data/third_party/boringssl/crypto/evp/print.c +520 -0
- data/third_party/boringssl/crypto/ex_data.c +4 -6
- data/third_party/boringssl/crypto/hkdf/hkdf.c +38 -17
- data/third_party/boringssl/crypto/hmac/hmac.c +6 -6
- data/third_party/boringssl/crypto/internal.h +57 -77
- data/third_party/boringssl/crypto/lhash/lhash.c +6 -10
- data/third_party/boringssl/crypto/md4/md4.c +9 -0
- data/third_party/boringssl/crypto/mem.c +19 -19
- data/third_party/boringssl/crypto/modes/cfb.c +5 -6
- data/third_party/boringssl/crypto/modes/ctr.c +10 -18
- data/third_party/boringssl/crypto/modes/gcm.c +100 -66
- data/third_party/boringssl/crypto/modes/internal.h +15 -27
- data/third_party/boringssl/crypto/modes/ofb.c +9 -22
- data/third_party/boringssl/crypto/newhope/error_correction.c +131 -0
- data/third_party/boringssl/crypto/newhope/internal.h +71 -0
- data/third_party/boringssl/crypto/newhope/newhope.c +174 -0
- data/third_party/boringssl/crypto/newhope/ntt.c +148 -0
- data/third_party/boringssl/crypto/newhope/poly.c +183 -0
- data/third_party/boringssl/crypto/newhope/precomp.c +306 -0
- data/third_party/boringssl/crypto/newhope/reduce.c +42 -0
- data/third_party/boringssl/crypto/obj/obj.c +111 -135
- data/third_party/boringssl/crypto/obj/obj_dat.h +4 -10
- data/third_party/boringssl/crypto/pem/pem_lib.c +6 -43
- data/third_party/boringssl/crypto/pem/pem_pkey.c +10 -19
- data/third_party/boringssl/crypto/pkcs8/p5_pbe.c +1 -0
- data/third_party/boringssl/crypto/pkcs8/p5_pbev2.c +2 -1
- data/third_party/boringssl/crypto/pkcs8/p8_pkey.c +2 -2
- data/third_party/boringssl/crypto/pkcs8/pkcs8.c +95 -87
- data/third_party/boringssl/crypto/{test/test_util.h → poly1305/internal.h} +15 -10
- data/third_party/boringssl/crypto/poly1305/poly1305.c +8 -15
- data/third_party/boringssl/crypto/poly1305/poly1305_arm.c +1 -0
- data/third_party/boringssl/crypto/poly1305/poly1305_vec.c +3 -3
- data/third_party/boringssl/crypto/rand/deterministic.c +47 -0
- data/third_party/boringssl/crypto/rand/rand.c +4 -1
- data/third_party/boringssl/crypto/rand/urandom.c +5 -7
- data/third_party/boringssl/crypto/rand/windows.c +5 -8
- data/third_party/boringssl/crypto/rc4/rc4.c +24 -209
- data/third_party/boringssl/crypto/refcount_lock.c +2 -2
- data/third_party/boringssl/crypto/rsa/blinding.c +74 -232
- data/third_party/boringssl/crypto/rsa/internal.h +5 -13
- data/third_party/boringssl/crypto/rsa/padding.c +64 -63
- data/third_party/boringssl/crypto/rsa/rsa.c +50 -28
- data/third_party/boringssl/crypto/rsa/rsa_asn1.c +8 -16
- data/third_party/boringssl/crypto/rsa/rsa_impl.c +134 -122
- data/third_party/boringssl/crypto/sha/sha256.c +2 -2
- data/third_party/boringssl/crypto/sha/sha512.c +7 -7
- data/third_party/boringssl/crypto/stack/stack.c +13 -22
- data/third_party/boringssl/crypto/thread.c +21 -12
- data/third_party/boringssl/crypto/thread_none.c +6 -2
- data/third_party/boringssl/crypto/thread_pthread.c +16 -7
- data/third_party/boringssl/crypto/thread_win.c +38 -85
- data/third_party/boringssl/crypto/x509/a_sign.c +3 -3
- data/third_party/boringssl/crypto/x509/a_strex.c +1 -1
- data/third_party/boringssl/crypto/x509/a_verify.c +2 -2
- data/third_party/boringssl/crypto/{evp → x509}/algorithm.c +37 -53
- data/third_party/boringssl/crypto/x509/asn1_gen.c +1 -2
- data/third_party/boringssl/crypto/x509/by_dir.c +6 -6
- data/third_party/boringssl/crypto/x509/internal.h +66 -0
- data/third_party/boringssl/crypto/x509/rsa_pss.c +385 -0
- data/third_party/boringssl/crypto/x509/t_x509.c +10 -12
- data/third_party/boringssl/crypto/x509/x509.c +5 -0
- data/third_party/boringssl/crypto/x509/x509_att.c +9 -3
- data/third_party/boringssl/crypto/x509/x509_lu.c +34 -44
- data/third_party/boringssl/crypto/x509/x509_obj.c +19 -2
- data/third_party/boringssl/crypto/x509/x509_r2x.c +9 -5
- data/third_party/boringssl/crypto/x509/x509_set.c +5 -0
- data/third_party/boringssl/crypto/x509/x509_txt.c +5 -0
- data/third_party/boringssl/crypto/x509/x509_vfy.c +63 -32
- data/third_party/boringssl/crypto/x509/x509_vpm.c +29 -18
- data/third_party/boringssl/crypto/x509/x509cset.c +2 -1
- data/third_party/boringssl/crypto/x509/x_crl.c +2 -2
- data/third_party/boringssl/crypto/x509/x_name.c +14 -17
- data/third_party/boringssl/crypto/x509/x_pubkey.c +10 -7
- data/third_party/boringssl/crypto/x509/x_x509.c +67 -6
- data/third_party/boringssl/crypto/x509v3/pcy_cache.c +2 -2
- data/third_party/boringssl/crypto/x509v3/pcy_tree.c +2 -1
- data/third_party/boringssl/crypto/x509v3/v3_conf.c +4 -3
- data/third_party/boringssl/crypto/x509v3/v3_cpols.c +5 -0
- data/third_party/boringssl/crypto/x509v3/v3_prn.c +0 -3
- data/third_party/boringssl/crypto/x509v3/v3_purp.c +2 -2
- data/third_party/boringssl/crypto/x509v3/v3_utl.c +2 -1
- data/third_party/boringssl/include/openssl/aead.h +72 -73
- data/third_party/boringssl/include/openssl/arm_arch.h +0 -6
- data/third_party/boringssl/include/openssl/asn1.h +103 -235
- data/third_party/boringssl/include/openssl/asn1_mac.h +17 -74
- data/third_party/boringssl/include/openssl/asn1t.h +1 -11
- data/third_party/boringssl/include/openssl/base.h +145 -3
- data/third_party/boringssl/include/openssl/base64.h +20 -17
- data/third_party/boringssl/include/openssl/bio.h +59 -34
- data/third_party/boringssl/include/openssl/bn.h +118 -51
- data/third_party/boringssl/include/openssl/buf.h +15 -0
- data/third_party/boringssl/include/openssl/bytestring.h +52 -4
- data/third_party/boringssl/include/openssl/chacha.h +2 -2
- data/third_party/boringssl/include/openssl/cipher.h +18 -1
- data/third_party/boringssl/include/openssl/cmac.h +11 -0
- data/third_party/boringssl/include/openssl/conf.h +13 -2
- data/third_party/boringssl/include/openssl/cpu.h +20 -23
- data/third_party/boringssl/include/openssl/crypto.h +22 -1
- data/third_party/boringssl/include/openssl/curve25519.h +96 -4
- data/third_party/boringssl/include/openssl/dh.h +71 -16
- data/third_party/boringssl/include/openssl/digest.h +38 -11
- data/third_party/boringssl/include/openssl/dsa.h +40 -4
- data/third_party/boringssl/include/openssl/ec.h +44 -18
- data/third_party/boringssl/include/openssl/ec_key.h +27 -6
- data/third_party/boringssl/include/openssl/ecdsa.h +11 -0
- data/third_party/boringssl/include/openssl/engine.h +11 -0
- data/third_party/boringssl/include/openssl/evp.h +52 -88
- data/third_party/boringssl/include/openssl/hkdf.h +24 -4
- data/third_party/boringssl/include/openssl/hmac.h +20 -6
- data/third_party/boringssl/include/openssl/md4.h +4 -0
- data/third_party/boringssl/include/openssl/mem.h +19 -0
- data/third_party/boringssl/include/openssl/newhope.h +158 -0
- data/third_party/boringssl/include/openssl/nid.h +4166 -0
- data/third_party/boringssl/include/openssl/obj.h +31 -3
- data/third_party/boringssl/include/openssl/obj_mac.h +17 -4143
- data/third_party/boringssl/include/openssl/{opensslfeatures.h → opensslconf.h} +3 -3
- data/third_party/boringssl/include/openssl/pem.h +5 -0
- data/third_party/boringssl/include/openssl/pkcs8.h +12 -0
- data/third_party/boringssl/include/openssl/rand.h +6 -0
- data/third_party/boringssl/include/openssl/rc4.h +6 -0
- data/third_party/boringssl/{crypto/dh/internal.h → include/openssl/ripemd.h} +38 -11
- data/third_party/boringssl/include/openssl/rsa.h +127 -65
- data/third_party/boringssl/include/openssl/sha.h +14 -10
- data/third_party/boringssl/include/openssl/ssl.h +561 -275
- data/third_party/boringssl/include/openssl/ssl3.h +18 -25
- data/third_party/boringssl/include/openssl/stack.h +2 -4
- data/third_party/boringssl/include/openssl/stack_macros.h +321 -353
- data/third_party/boringssl/include/openssl/thread.h +31 -13
- data/third_party/boringssl/include/openssl/time_support.h +1 -0
- data/third_party/boringssl/include/openssl/tls1.h +37 -33
- data/third_party/boringssl/include/openssl/x509.h +69 -26
- data/third_party/boringssl/include/openssl/x509_vfy.h +12 -10
- data/third_party/boringssl/include/openssl/x509v3.h +23 -2
- data/third_party/boringssl/ssl/custom_extensions.c +3 -5
- data/third_party/boringssl/ssl/d1_both.c +463 -499
- data/third_party/boringssl/ssl/d1_lib.c +38 -109
- data/third_party/boringssl/ssl/d1_pkt.c +173 -334
- data/third_party/boringssl/ssl/d1_srtp.c +20 -18
- data/third_party/boringssl/ssl/{d1_meth.c → dtls_method.c} +88 -15
- data/third_party/boringssl/ssl/dtls_record.c +27 -26
- data/third_party/boringssl/ssl/{s3_clnt.c → handshake_client.c} +816 -904
- data/third_party/boringssl/ssl/handshake_server.c +1932 -0
- data/third_party/boringssl/ssl/internal.h +712 -439
- data/third_party/boringssl/ssl/s3_both.c +445 -257
- data/third_party/boringssl/ssl/s3_enc.c +53 -36
- data/third_party/boringssl/ssl/s3_lib.c +23 -268
- data/third_party/boringssl/ssl/s3_pkt.c +168 -364
- data/third_party/boringssl/ssl/ssl_aead_ctx.c +46 -17
- data/third_party/boringssl/ssl/ssl_asn1.c +56 -26
- data/third_party/boringssl/ssl/ssl_buffer.c +16 -24
- data/third_party/boringssl/ssl/ssl_cert.c +324 -49
- data/third_party/boringssl/ssl/ssl_cipher.c +205 -150
- data/third_party/boringssl/ssl/ssl_ecdh.c +287 -51
- data/third_party/boringssl/ssl/ssl_file.c +21 -68
- data/third_party/boringssl/ssl/ssl_lib.c +881 -510
- data/third_party/boringssl/ssl/ssl_rsa.c +404 -34
- data/third_party/boringssl/ssl/ssl_session.c +324 -103
- data/third_party/boringssl/ssl/ssl_stat.c +6 -88
- data/third_party/boringssl/ssl/t1_enc.c +23 -39
- data/third_party/boringssl/ssl/t1_lib.c +1120 -622
- data/third_party/boringssl/ssl/tls13_both.c +440 -0
- data/third_party/boringssl/ssl/tls13_client.c +682 -0
- data/third_party/boringssl/ssl/tls13_enc.c +391 -0
- data/third_party/boringssl/ssl/tls13_server.c +672 -0
- data/third_party/boringssl/ssl/{s3_meth.c → tls_method.c} +100 -21
- data/third_party/boringssl/ssl/tls_record.c +159 -77
- data/third_party/nanopb/pb.h +60 -28
- data/third_party/nanopb/pb_decode.c +120 -92
- data/third_party/nanopb/pb_decode.h +3 -3
- data/third_party/nanopb/pb_encode.c +73 -67
- data/third_party/nanopb/pb_encode.h +4 -4
- metadata +155 -89
- data/include/grpc/impl/codegen/byte_buffer.h +0 -122
- data/include/grpc/impl/codegen/log.h +0 -118
- data/include/grpc/impl/codegen/time.h +0 -130
- data/src/core/ext/client_config/client_channel.c +0 -593
- data/src/core/ext/client_config/subchannel_call_holder.c +0 -272
- data/src/core/ext/client_config/subchannel_call_holder.h +0 -99
- data/src/core/lib/iomgr/ev_poll_and_epoll_posix.c +0 -2046
- data/src/core/lib/iomgr/workqueue_posix.c +0 -151
- data/src/core/lib/security/transport/handshake.c +0 -368
- data/third_party/boringssl/crypto/asn1/a_bytes.c +0 -308
- data/third_party/boringssl/crypto/asn1/bio_asn1.c +0 -477
- data/third_party/boringssl/crypto/asn1/bio_ndef.c +0 -251
- data/third_party/boringssl/crypto/asn1/t_pkey.c +0 -110
- data/third_party/boringssl/crypto/asn1/tasn_prn.c +0 -596
- data/third_party/boringssl/crypto/chacha/chacha_vec.c +0 -328
- data/third_party/boringssl/crypto/directory.h +0 -66
- data/third_party/boringssl/crypto/directory_posix.c +0 -108
- data/third_party/boringssl/crypto/directory_win.c +0 -144
- data/third_party/boringssl/crypto/test/scoped_types.h +0 -140
- data/third_party/boringssl/include/openssl/pqueue.h +0 -146
- data/third_party/boringssl/ssl/d1_clnt.c +0 -561
- data/third_party/boringssl/ssl/d1_srvr.c +0 -476
- data/third_party/boringssl/ssl/pqueue/pqueue.c +0 -197
- data/third_party/boringssl/ssl/s3_srvr.c +0 -2272
- data/third_party/boringssl/ssl/test/async_bio.h +0 -45
- data/third_party/boringssl/ssl/test/packeted_bio.h +0 -44
- data/third_party/boringssl/ssl/test/test_config.h +0 -110
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_BIN_DECODER_H
|
|
35
35
|
#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_BIN_DECODER_H
|
|
36
36
|
|
|
37
|
-
#include <grpc/
|
|
37
|
+
#include <grpc/slice.h>
|
|
38
38
|
#include <stdbool.h>
|
|
39
39
|
|
|
40
40
|
struct grpc_base64_decode_context {
|
|
@@ -55,12 +55,13 @@ bool grpc_base64_decode_partial(struct grpc_base64_decode_context *ctx);
|
|
|
55
55
|
|
|
56
56
|
/* base64 decode a slice with pad chars. Returns a new slice, does not take
|
|
57
57
|
ownership of the input. Returns an empty slice if decoding is failed. */
|
|
58
|
-
|
|
58
|
+
grpc_slice grpc_chttp2_base64_decode(grpc_exec_ctx *exec_ctx, grpc_slice input);
|
|
59
59
|
|
|
60
60
|
/* base64 decode a slice without pad chars, data length is needed. Returns a new
|
|
61
61
|
slice, does not take ownership of the input. Returns an empty slice if
|
|
62
62
|
decoding is failed. */
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
grpc_slice grpc_chttp2_base64_decode_with_length(grpc_exec_ctx *exec_ctx,
|
|
64
|
+
grpc_slice input,
|
|
65
|
+
size_t output_length);
|
|
65
66
|
|
|
66
67
|
#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_BIN_DECODER_H */
|
|
@@ -61,14 +61,14 @@ static const b64_huff_sym huff_alphabet[64] = {
|
|
|
61
61
|
|
|
62
62
|
static const uint8_t tail_xtra[3] = {0, 2, 3};
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
size_t input_length =
|
|
64
|
+
grpc_slice grpc_chttp2_base64_encode(grpc_slice input) {
|
|
65
|
+
size_t input_length = GRPC_SLICE_LENGTH(input);
|
|
66
66
|
size_t input_triplets = input_length / 3;
|
|
67
67
|
size_t tail_case = input_length % 3;
|
|
68
68
|
size_t output_length = input_triplets * 4 + tail_xtra[tail_case];
|
|
69
|
-
|
|
70
|
-
uint8_t *in =
|
|
71
|
-
char *out = (char *)
|
|
69
|
+
grpc_slice output = grpc_slice_malloc(output_length);
|
|
70
|
+
uint8_t *in = GRPC_SLICE_START_PTR(input);
|
|
71
|
+
char *out = (char *)GRPC_SLICE_START_PTR(output);
|
|
72
72
|
size_t i;
|
|
73
73
|
|
|
74
74
|
/* encode full triplets */
|
|
@@ -100,27 +100,29 @@ gpr_slice grpc_chttp2_base64_encode(gpr_slice input) {
|
|
|
100
100
|
break;
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
GPR_ASSERT(out == (char *)
|
|
104
|
-
GPR_ASSERT(in ==
|
|
103
|
+
GPR_ASSERT(out == (char *)GRPC_SLICE_END_PTR(output));
|
|
104
|
+
GPR_ASSERT(in == GRPC_SLICE_END_PTR(input));
|
|
105
105
|
return output;
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
-
|
|
108
|
+
grpc_slice grpc_chttp2_huffman_compress(grpc_slice input) {
|
|
109
109
|
size_t nbits;
|
|
110
110
|
uint8_t *in;
|
|
111
111
|
uint8_t *out;
|
|
112
|
-
|
|
112
|
+
grpc_slice output;
|
|
113
113
|
uint32_t temp = 0;
|
|
114
114
|
uint32_t temp_length = 0;
|
|
115
115
|
|
|
116
116
|
nbits = 0;
|
|
117
|
-
for (in =
|
|
117
|
+
for (in = GRPC_SLICE_START_PTR(input); in != GRPC_SLICE_END_PTR(input);
|
|
118
|
+
++in) {
|
|
118
119
|
nbits += grpc_chttp2_huffsyms[*in].length;
|
|
119
120
|
}
|
|
120
121
|
|
|
121
|
-
output =
|
|
122
|
-
out =
|
|
123
|
-
for (in =
|
|
122
|
+
output = grpc_slice_malloc(nbits / 8 + (nbits % 8 != 0));
|
|
123
|
+
out = GRPC_SLICE_START_PTR(output);
|
|
124
|
+
for (in = GRPC_SLICE_START_PTR(input); in != GRPC_SLICE_END_PTR(input);
|
|
125
|
+
++in) {
|
|
124
126
|
int sym = *in;
|
|
125
127
|
temp <<= grpc_chttp2_huffsyms[sym].length;
|
|
126
128
|
temp |= grpc_chttp2_huffsyms[sym].bits;
|
|
@@ -141,7 +143,7 @@ gpr_slice grpc_chttp2_huffman_compress(gpr_slice input) {
|
|
|
141
143
|
(uint8_t)(0xffu >> temp_length));
|
|
142
144
|
}
|
|
143
145
|
|
|
144
|
-
GPR_ASSERT(out ==
|
|
146
|
+
GPR_ASSERT(out == GRPC_SLICE_END_PTR(output));
|
|
145
147
|
|
|
146
148
|
return output;
|
|
147
149
|
}
|
|
@@ -175,16 +177,17 @@ static void enc_add1(huff_out *out, uint8_t a) {
|
|
|
175
177
|
enc_flush_some(out);
|
|
176
178
|
}
|
|
177
179
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
+
grpc_slice grpc_chttp2_base64_encode_and_huffman_compress_impl(
|
|
181
|
+
grpc_slice input) {
|
|
182
|
+
size_t input_length = GRPC_SLICE_LENGTH(input);
|
|
180
183
|
size_t input_triplets = input_length / 3;
|
|
181
184
|
size_t tail_case = input_length % 3;
|
|
182
185
|
size_t output_syms = input_triplets * 4 + tail_xtra[tail_case];
|
|
183
186
|
size_t max_output_bits = 11 * output_syms;
|
|
184
187
|
size_t max_output_length = max_output_bits / 8 + (max_output_bits % 8 != 0);
|
|
185
|
-
|
|
186
|
-
uint8_t *in =
|
|
187
|
-
uint8_t *start_out =
|
|
188
|
+
grpc_slice output = grpc_slice_malloc(max_output_length);
|
|
189
|
+
uint8_t *in = GRPC_SLICE_START_PTR(input);
|
|
190
|
+
uint8_t *start_out = GRPC_SLICE_START_PTR(output);
|
|
188
191
|
huff_out out;
|
|
189
192
|
size_t i;
|
|
190
193
|
|
|
@@ -231,9 +234,9 @@ gpr_slice grpc_chttp2_base64_encode_and_huffman_compress_impl(gpr_slice input) {
|
|
|
231
234
|
(uint8_t)(0xffu >> out.temp_length));
|
|
232
235
|
}
|
|
233
236
|
|
|
234
|
-
GPR_ASSERT(out.out <=
|
|
235
|
-
|
|
237
|
+
GPR_ASSERT(out.out <= GRPC_SLICE_END_PTR(output));
|
|
238
|
+
GRPC_SLICE_SET_LENGTH(output, out.out - start_out);
|
|
236
239
|
|
|
237
|
-
GPR_ASSERT(in ==
|
|
240
|
+
GPR_ASSERT(in == GRPC_SLICE_END_PTR(input));
|
|
238
241
|
return output;
|
|
239
242
|
}
|
|
@@ -34,21 +34,22 @@
|
|
|
34
34
|
#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_BIN_ENCODER_H
|
|
35
35
|
#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_BIN_ENCODER_H
|
|
36
36
|
|
|
37
|
-
#include <grpc/
|
|
37
|
+
#include <grpc/slice.h>
|
|
38
38
|
|
|
39
39
|
/* base64 encode a slice. Returns a new slice, does not take ownership of the
|
|
40
40
|
input */
|
|
41
|
-
|
|
41
|
+
grpc_slice grpc_chttp2_base64_encode(grpc_slice input);
|
|
42
42
|
|
|
43
43
|
/* Compress a slice with the static huffman encoder detailed in the hpack
|
|
44
44
|
standard. Returns a new slice, does not take ownership of the input */
|
|
45
|
-
|
|
45
|
+
grpc_slice grpc_chttp2_huffman_compress(grpc_slice input);
|
|
46
46
|
|
|
47
47
|
/* equivalent to:
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
grpc_slice x = grpc_chttp2_base64_encode(input);
|
|
49
|
+
grpc_slice y = grpc_chttp2_huffman_compress(x);
|
|
50
|
+
grpc_slice_unref_internal(exec_ctx, x);
|
|
51
51
|
return y; */
|
|
52
|
-
|
|
52
|
+
grpc_slice grpc_chttp2_base64_encode_and_huffman_compress_impl(
|
|
53
|
+
grpc_slice input);
|
|
53
54
|
|
|
54
55
|
#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_BIN_ENCODER_H */
|
|
@@ -36,14 +36,11 @@
|
|
|
36
36
|
#include "src/core/lib/debug/trace.h"
|
|
37
37
|
#include "src/core/lib/transport/metadata.h"
|
|
38
38
|
|
|
39
|
-
extern int grpc_http_write_state_trace;
|
|
40
|
-
|
|
41
39
|
void grpc_chttp2_plugin_init(void) {
|
|
42
40
|
grpc_chttp2_base64_encode_and_huffman_compress =
|
|
43
41
|
grpc_chttp2_base64_encode_and_huffman_compress_impl;
|
|
44
42
|
grpc_register_tracer("http", &grpc_http_trace);
|
|
45
43
|
grpc_register_tracer("flowctl", &grpc_flowctl_trace);
|
|
46
|
-
grpc_register_tracer("http_write_state", &grpc_http_write_state_trace);
|
|
47
44
|
}
|
|
48
45
|
|
|
49
46
|
void grpc_chttp2_plugin_shutdown(void) {}
|
|
@@ -33,128 +33,95 @@
|
|
|
33
33
|
|
|
34
34
|
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
|
|
35
35
|
|
|
36
|
+
#include <limits.h>
|
|
36
37
|
#include <math.h>
|
|
37
38
|
#include <stdio.h>
|
|
38
39
|
#include <string.h>
|
|
39
40
|
|
|
41
|
+
#include <grpc/slice_buffer.h>
|
|
40
42
|
#include <grpc/support/alloc.h>
|
|
41
43
|
#include <grpc/support/log.h>
|
|
42
|
-
#include <grpc/support/slice_buffer.h>
|
|
43
44
|
#include <grpc/support/string_util.h>
|
|
44
45
|
#include <grpc/support/useful.h>
|
|
45
46
|
|
|
46
47
|
#include "src/core/ext/transport/chttp2/transport/http2_errors.h"
|
|
47
48
|
#include "src/core/ext/transport/chttp2/transport/internal.h"
|
|
48
49
|
#include "src/core/ext/transport/chttp2/transport/status_conversion.h"
|
|
49
|
-
#include "src/core/ext/transport/chttp2/transport/
|
|
50
|
+
#include "src/core/ext/transport/chttp2/transport/varint.h"
|
|
51
|
+
#include "src/core/lib/channel/channel_args.h"
|
|
50
52
|
#include "src/core/lib/http/parser.h"
|
|
51
53
|
#include "src/core/lib/iomgr/workqueue.h"
|
|
52
54
|
#include "src/core/lib/profiling/timers.h"
|
|
55
|
+
#include "src/core/lib/slice/slice_internal.h"
|
|
56
|
+
#include "src/core/lib/slice/slice_string_helpers.h"
|
|
53
57
|
#include "src/core/lib/support/string.h"
|
|
54
58
|
#include "src/core/lib/transport/static_metadata.h"
|
|
59
|
+
#include "src/core/lib/transport/timeout_encoding.h"
|
|
55
60
|
#include "src/core/lib/transport/transport_impl.h"
|
|
56
61
|
|
|
57
62
|
#define DEFAULT_WINDOW 65535
|
|
58
63
|
#define DEFAULT_CONNECTION_WINDOW_TARGET (1024 * 1024)
|
|
59
64
|
#define MAX_WINDOW 0x7fffffffu
|
|
60
|
-
|
|
65
|
+
#define MAX_WRITE_BUFFER_SIZE (64 * 1024 * 1024)
|
|
61
66
|
#define DEFAULT_MAX_HEADER_LIST_SIZE (16 * 1024)
|
|
62
67
|
|
|
63
68
|
#define MAX_CLIENT_STREAM_ID 0x7fffffffu
|
|
64
69
|
int grpc_http_trace = 0;
|
|
65
70
|
int grpc_flowctl_trace = 0;
|
|
66
|
-
int grpc_http_write_state_trace = 0;
|
|
67
|
-
|
|
68
|
-
#define TRANSPORT_FROM_WRITING(tw) \
|
|
69
|
-
((grpc_chttp2_transport *)((char *)(tw)-offsetof(grpc_chttp2_transport, \
|
|
70
|
-
writing)))
|
|
71
|
-
|
|
72
|
-
#define TRANSPORT_FROM_PARSING(tp) \
|
|
73
|
-
((grpc_chttp2_transport *)((char *)(tp)-offsetof(grpc_chttp2_transport, \
|
|
74
|
-
parsing)))
|
|
75
|
-
|
|
76
|
-
#define TRANSPORT_FROM_GLOBAL(tg) \
|
|
77
|
-
((grpc_chttp2_transport *)((char *)(tg)-offsetof(grpc_chttp2_transport, \
|
|
78
|
-
global)))
|
|
79
|
-
|
|
80
|
-
#define STREAM_FROM_GLOBAL(sg) \
|
|
81
|
-
((grpc_chttp2_stream *)((char *)(sg)-offsetof(grpc_chttp2_stream, global)))
|
|
82
|
-
|
|
83
|
-
#define STREAM_FROM_PARSING(sg) \
|
|
84
|
-
((grpc_chttp2_stream *)((char *)(sg)-offsetof(grpc_chttp2_stream, parsing)))
|
|
85
71
|
|
|
86
72
|
static const grpc_transport_vtable vtable;
|
|
87
73
|
|
|
88
74
|
/* forward declarations of various callbacks that we'll build closures around */
|
|
89
|
-
static void
|
|
90
|
-
|
|
91
|
-
static void
|
|
92
|
-
static void
|
|
93
|
-
|
|
75
|
+
static void write_action_begin_locked(grpc_exec_ctx *exec_ctx, void *t,
|
|
76
|
+
grpc_error *error);
|
|
77
|
+
static void write_action(grpc_exec_ctx *exec_ctx, void *t, grpc_error *error);
|
|
78
|
+
static void write_action_end_locked(grpc_exec_ctx *exec_ctx, void *t,
|
|
79
|
+
grpc_error *error);
|
|
94
80
|
|
|
95
|
-
static void
|
|
96
|
-
|
|
97
|
-
grpc_chttp2_transport *t, grpc_error *error);
|
|
81
|
+
static void read_action_locked(grpc_exec_ctx *exec_ctx, void *t,
|
|
82
|
+
grpc_error *error);
|
|
98
83
|
|
|
84
|
+
static void complete_fetch_locked(grpc_exec_ctx *exec_ctx, void *gs,
|
|
85
|
+
grpc_error *error);
|
|
99
86
|
/** Set a transport level setting, and push it to our peer */
|
|
100
87
|
static void push_setting(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
101
88
|
grpc_chttp2_setting_id id, uint32_t value);
|
|
102
89
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
grpc_error *error);
|
|
106
|
-
|
|
107
|
-
/** Perform a transport_op */
|
|
108
|
-
static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx,
|
|
109
|
-
grpc_chttp2_transport *t,
|
|
110
|
-
grpc_chttp2_stream *s, void *transport_op);
|
|
111
|
-
|
|
112
|
-
/** Cancel a stream: coming from the transport API */
|
|
113
|
-
static void cancel_from_api(grpc_exec_ctx *exec_ctx,
|
|
114
|
-
grpc_chttp2_transport_global *transport_global,
|
|
115
|
-
grpc_chttp2_stream_global *stream_global,
|
|
116
|
-
grpc_error *error);
|
|
117
|
-
|
|
118
|
-
static void close_from_api(grpc_exec_ctx *exec_ctx,
|
|
119
|
-
grpc_chttp2_transport_global *transport_global,
|
|
120
|
-
grpc_chttp2_stream_global *stream_global,
|
|
121
|
-
grpc_error *error);
|
|
122
|
-
|
|
123
|
-
/** Add endpoint from this transport to pollset */
|
|
124
|
-
static void add_to_pollset_locked(grpc_exec_ctx *exec_ctx,
|
|
125
|
-
grpc_chttp2_transport *t,
|
|
126
|
-
grpc_chttp2_stream *s_ignored, void *pollset);
|
|
127
|
-
static void add_to_pollset_set_locked(grpc_exec_ctx *exec_ctx,
|
|
128
|
-
grpc_chttp2_transport *t,
|
|
129
|
-
grpc_chttp2_stream *s_ignored,
|
|
130
|
-
void *pollset_set);
|
|
90
|
+
static void close_from_api(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
91
|
+
grpc_chttp2_stream *s, grpc_error *error);
|
|
131
92
|
|
|
132
93
|
/** Start new streams that have been created if we can */
|
|
133
|
-
static void maybe_start_some_streams(
|
|
134
|
-
|
|
94
|
+
static void maybe_start_some_streams(grpc_exec_ctx *exec_ctx,
|
|
95
|
+
grpc_chttp2_transport *t);
|
|
135
96
|
|
|
136
|
-
static void
|
|
137
|
-
|
|
97
|
+
static void connectivity_state_set(grpc_exec_ctx *exec_ctx,
|
|
98
|
+
grpc_chttp2_transport *t,
|
|
99
|
+
grpc_connectivity_state state,
|
|
100
|
+
grpc_error *error, const char *reason);
|
|
101
|
+
|
|
102
|
+
static void incoming_byte_stream_update_flow_control(grpc_exec_ctx *exec_ctx,
|
|
103
|
+
grpc_chttp2_transport *t,
|
|
104
|
+
grpc_chttp2_stream *s,
|
|
105
|
+
size_t max_size_hint,
|
|
106
|
+
size_t have_already);
|
|
107
|
+
static void incoming_byte_stream_destroy_locked(grpc_exec_ctx *exec_ctx,
|
|
108
|
+
void *byte_stream,
|
|
109
|
+
grpc_error *error_ignored);
|
|
138
110
|
|
|
139
|
-
static void
|
|
140
|
-
|
|
141
|
-
|
|
111
|
+
static void benign_reclaimer_locked(grpc_exec_ctx *exec_ctx, void *t,
|
|
112
|
+
grpc_error *error);
|
|
113
|
+
static void destructive_reclaimer_locked(grpc_exec_ctx *exec_ctx, void *t,
|
|
114
|
+
grpc_error *error);
|
|
142
115
|
|
|
143
|
-
static void
|
|
144
|
-
|
|
116
|
+
static void post_benign_reclaimer(grpc_exec_ctx *exec_ctx,
|
|
117
|
+
grpc_chttp2_transport *t);
|
|
118
|
+
static void post_destructive_reclaimer(grpc_exec_ctx *exec_ctx,
|
|
119
|
+
grpc_chttp2_transport *t);
|
|
145
120
|
|
|
146
|
-
static void
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
static void incoming_byte_stream_destroy_locked(grpc_exec_ctx *exec_ctx,
|
|
151
|
-
grpc_chttp2_transport *t,
|
|
152
|
-
grpc_chttp2_stream *s,
|
|
153
|
-
void *byte_stream);
|
|
154
|
-
static void fail_pending_writes(grpc_exec_ctx *exec_ctx,
|
|
155
|
-
grpc_chttp2_transport_global *transport_global,
|
|
156
|
-
grpc_chttp2_stream_global *stream_global,
|
|
157
|
-
grpc_error *error);
|
|
121
|
+
static void close_transport_locked(grpc_exec_ctx *exec_ctx,
|
|
122
|
+
grpc_chttp2_transport *t, grpc_error *error);
|
|
123
|
+
static void end_all_the_calls(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
124
|
+
grpc_error *error);
|
|
158
125
|
|
|
159
126
|
/*******************************************************************************
|
|
160
127
|
* CONSTRUCTION/DESTRUCTION/REFCOUNTING
|
|
@@ -164,77 +131,74 @@ static void destruct_transport(grpc_exec_ctx *exec_ctx,
|
|
|
164
131
|
grpc_chttp2_transport *t) {
|
|
165
132
|
size_t i;
|
|
166
133
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
GPR_ASSERT(t->ep == NULL);
|
|
134
|
+
grpc_endpoint_destroy(exec_ctx, t->ep);
|
|
170
135
|
|
|
171
|
-
|
|
136
|
+
grpc_slice_buffer_destroy_internal(exec_ctx, &t->qbuf);
|
|
172
137
|
|
|
173
|
-
|
|
174
|
-
grpc_chttp2_hpack_compressor_destroy(&t->
|
|
138
|
+
grpc_slice_buffer_destroy_internal(exec_ctx, &t->outbuf);
|
|
139
|
+
grpc_chttp2_hpack_compressor_destroy(exec_ctx, &t->hpack_compressor);
|
|
175
140
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
grpc_chttp2_goaway_parser_destroy(&t->parsing.goaway_parser);
|
|
141
|
+
grpc_slice_buffer_destroy_internal(exec_ctx, &t->read_buffer);
|
|
142
|
+
grpc_chttp2_hpack_parser_destroy(exec_ctx, &t->hpack_parser);
|
|
143
|
+
grpc_chttp2_goaway_parser_destroy(&t->goaway_parser);
|
|
180
144
|
|
|
181
145
|
for (i = 0; i < STREAM_LIST_COUNT; i++) {
|
|
182
146
|
GPR_ASSERT(t->lists[i].head == NULL);
|
|
183
147
|
GPR_ASSERT(t->lists[i].tail == NULL);
|
|
184
148
|
}
|
|
185
149
|
|
|
186
|
-
GPR_ASSERT(grpc_chttp2_stream_map_size(&t->
|
|
187
|
-
GPR_ASSERT(grpc_chttp2_stream_map_size(&t->new_stream_map) == 0);
|
|
150
|
+
GPR_ASSERT(grpc_chttp2_stream_map_size(&t->stream_map) == 0);
|
|
188
151
|
|
|
189
|
-
grpc_chttp2_stream_map_destroy(&t->
|
|
190
|
-
grpc_chttp2_stream_map_destroy(&t->new_stream_map);
|
|
152
|
+
grpc_chttp2_stream_map_destroy(&t->stream_map);
|
|
191
153
|
grpc_connectivity_state_destroy(exec_ctx, &t->channel_callback.state_tracker);
|
|
192
154
|
|
|
193
|
-
|
|
194
|
-
gpr_mu_destroy(&t->executor.mu);
|
|
155
|
+
grpc_combiner_destroy(exec_ctx, t->combiner);
|
|
195
156
|
|
|
196
157
|
/* callback remaining pings: they're not allowed to call into the transpot,
|
|
197
158
|
and maybe they hold resources that need to be freed */
|
|
198
|
-
while (t->
|
|
199
|
-
grpc_chttp2_outstanding_ping *ping = t->
|
|
200
|
-
|
|
201
|
-
|
|
159
|
+
while (t->pings.next != &t->pings) {
|
|
160
|
+
grpc_chttp2_outstanding_ping *ping = t->pings.next;
|
|
161
|
+
grpc_closure_sched(exec_ctx, ping->on_recv,
|
|
162
|
+
GRPC_ERROR_CREATE("Transport closed"));
|
|
202
163
|
ping->next->prev = ping->prev;
|
|
203
164
|
ping->prev->next = ping->next;
|
|
204
165
|
gpr_free(ping);
|
|
205
166
|
}
|
|
206
167
|
|
|
168
|
+
while (t->write_cb_pool) {
|
|
169
|
+
grpc_chttp2_write_cb *next = t->write_cb_pool->next;
|
|
170
|
+
gpr_free(t->write_cb_pool);
|
|
171
|
+
t->write_cb_pool = next;
|
|
172
|
+
}
|
|
173
|
+
|
|
207
174
|
gpr_free(t->peer_string);
|
|
208
175
|
gpr_free(t);
|
|
209
176
|
}
|
|
210
177
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
gpr_log(GPR_DEBUG, "chttp2:unref:%p %d->%d %s [%s:%d]", t, t->refs.count,
|
|
218
|
-
t->refs.count - 1, reason, file, line);
|
|
178
|
+
#ifdef GRPC_CHTTP2_REFCOUNTING_DEBUG
|
|
179
|
+
void grpc_chttp2_unref_transport(grpc_exec_ctx *exec_ctx,
|
|
180
|
+
grpc_chttp2_transport *t, const char *reason,
|
|
181
|
+
const char *file, int line) {
|
|
182
|
+
gpr_log(GPR_DEBUG, "chttp2:unref:%p %" PRIdPTR "->%" PRIdPTR " %s [%s:%d]", t,
|
|
183
|
+
t->refs.count, t->refs.count - 1, reason, file, line);
|
|
219
184
|
if (!gpr_unref(&t->refs)) return;
|
|
220
185
|
destruct_transport(exec_ctx, t);
|
|
221
186
|
}
|
|
222
187
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
gpr_log(GPR_DEBUG, "chttp2: ref:%p %
|
|
226
|
-
t->refs.count + 1, reason, file, line);
|
|
188
|
+
void grpc_chttp2_ref_transport(grpc_chttp2_transport *t, const char *reason,
|
|
189
|
+
const char *file, int line) {
|
|
190
|
+
gpr_log(GPR_DEBUG, "chttp2: ref:%p %" PRIdPTR "->%" PRIdPTR " %s [%s:%d]", t,
|
|
191
|
+
t->refs.count, t->refs.count + 1, reason, file, line);
|
|
227
192
|
gpr_ref(&t->refs);
|
|
228
193
|
}
|
|
229
194
|
#else
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
static void unref_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t) {
|
|
195
|
+
void grpc_chttp2_unref_transport(grpc_exec_ctx *exec_ctx,
|
|
196
|
+
grpc_chttp2_transport *t) {
|
|
233
197
|
if (!gpr_unref(&t->refs)) return;
|
|
234
198
|
destruct_transport(exec_ctx, t);
|
|
235
199
|
}
|
|
236
200
|
|
|
237
|
-
|
|
201
|
+
void grpc_chttp2_ref_transport(grpc_chttp2_transport *t) { gpr_ref(&t->refs); }
|
|
238
202
|
#endif
|
|
239
203
|
|
|
240
204
|
static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
@@ -250,74 +214,70 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
|
250
214
|
|
|
251
215
|
t->base.vtable = &vtable;
|
|
252
216
|
t->ep = ep;
|
|
253
|
-
/* one ref is for destroy
|
|
254
|
-
gpr_ref_init(&t->refs,
|
|
255
|
-
|
|
256
|
-
gpr_ref_init(&t->shutdown_ep_refs, 1);
|
|
257
|
-
gpr_mu_init(&t->executor.mu);
|
|
217
|
+
/* one ref is for destroy */
|
|
218
|
+
gpr_ref_init(&t->refs, 1);
|
|
219
|
+
t->combiner = grpc_combiner_create(grpc_endpoint_get_workqueue(ep));
|
|
258
220
|
t->peer_string = grpc_endpoint_get_peer(ep);
|
|
259
221
|
t->endpoint_reading = 1;
|
|
260
|
-
t->
|
|
261
|
-
t->
|
|
262
|
-
t->
|
|
263
|
-
t->
|
|
264
|
-
t->
|
|
265
|
-
t->
|
|
266
|
-
t->
|
|
267
|
-
t->
|
|
268
|
-
t->
|
|
269
|
-
t->
|
|
270
|
-
is_client ? GRPC_DTS_FH_0 : GRPC_DTS_CLIENT_PREFIX_0;
|
|
271
|
-
t->parsing.is_first_frame = true;
|
|
272
|
-
t->writing.is_client = is_client;
|
|
222
|
+
t->next_stream_id = is_client ? 1 : 2;
|
|
223
|
+
t->is_client = is_client;
|
|
224
|
+
t->outgoing_window = DEFAULT_WINDOW;
|
|
225
|
+
t->incoming_window = DEFAULT_WINDOW;
|
|
226
|
+
t->stream_lookahead = DEFAULT_WINDOW;
|
|
227
|
+
t->connection_window_target = DEFAULT_CONNECTION_WINDOW_TARGET;
|
|
228
|
+
t->ping_counter = 1;
|
|
229
|
+
t->pings.next = t->pings.prev = &t->pings;
|
|
230
|
+
t->deframe_state = is_client ? GRPC_DTS_FH_0 : GRPC_DTS_CLIENT_PREFIX_0;
|
|
231
|
+
t->is_first_frame = true;
|
|
273
232
|
grpc_connectivity_state_init(
|
|
274
233
|
&t->channel_callback.state_tracker, GRPC_CHANNEL_READY,
|
|
275
234
|
is_client ? "client_transport" : "server_transport");
|
|
276
235
|
|
|
277
|
-
|
|
236
|
+
grpc_slice_buffer_init(&t->qbuf);
|
|
278
237
|
|
|
279
|
-
|
|
280
|
-
grpc_chttp2_hpack_compressor_init(&t->
|
|
281
|
-
grpc_closure_init(&t->writing_action, writing_action, t);
|
|
282
|
-
grpc_closure_init(&t->reading_action, reading_action, t);
|
|
283
|
-
grpc_closure_init(&t->parsing_action, parsing_action, t);
|
|
284
|
-
grpc_closure_init(&t->initiate_writing, initiate_writing, t);
|
|
238
|
+
grpc_slice_buffer_init(&t->outbuf);
|
|
239
|
+
grpc_chttp2_hpack_compressor_init(&t->hpack_compressor);
|
|
285
240
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
241
|
+
grpc_closure_init(&t->write_action, write_action, t,
|
|
242
|
+
grpc_schedule_on_exec_ctx);
|
|
243
|
+
grpc_closure_init(&t->read_action_locked, read_action_locked, t,
|
|
244
|
+
grpc_combiner_scheduler(t->combiner, false));
|
|
245
|
+
grpc_closure_init(&t->benign_reclaimer_locked, benign_reclaimer_locked, t,
|
|
246
|
+
grpc_combiner_scheduler(t->combiner, false));
|
|
247
|
+
grpc_closure_init(&t->destructive_reclaimer_locked,
|
|
248
|
+
destructive_reclaimer_locked, t,
|
|
249
|
+
grpc_combiner_scheduler(t->combiner, false));
|
|
289
250
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
251
|
+
grpc_chttp2_goaway_parser_init(&t->goaway_parser);
|
|
252
|
+
grpc_chttp2_hpack_parser_init(exec_ctx, &t->hpack_parser);
|
|
253
|
+
|
|
254
|
+
grpc_slice_buffer_init(&t->read_buffer);
|
|
293
255
|
|
|
294
|
-
if (is_client) {
|
|
295
|
-
gpr_slice_buffer_add(
|
|
296
|
-
&t->global.qbuf,
|
|
297
|
-
gpr_slice_from_copied_string(GRPC_CHTTP2_CLIENT_CONNECT_STRING));
|
|
298
|
-
grpc_chttp2_initiate_write(exec_ctx, &t->global, false, "initial_write");
|
|
299
|
-
}
|
|
300
256
|
/* 8 is a random stab in the dark as to a good initial size: it's small enough
|
|
301
257
|
that it shouldn't waste memory for infrequently used connections, yet
|
|
302
258
|
large enough that the exponential growth should happen nicely when it's
|
|
303
259
|
needed.
|
|
304
260
|
TODO(ctiller): tune this */
|
|
305
|
-
grpc_chttp2_stream_map_init(&t->
|
|
306
|
-
grpc_chttp2_stream_map_init(&t->new_stream_map, 8);
|
|
261
|
+
grpc_chttp2_stream_map_init(&t->stream_map, 8);
|
|
307
262
|
|
|
308
263
|
/* copy in initial settings to all setting sets */
|
|
309
264
|
for (i = 0; i < GRPC_CHTTP2_NUM_SETTINGS; i++) {
|
|
310
|
-
t->parsing.settings[i] = grpc_chttp2_settings_parameters[i].default_value;
|
|
311
265
|
for (j = 0; j < GRPC_NUM_SETTING_SETS; j++) {
|
|
312
|
-
t->
|
|
313
|
-
grpc_chttp2_settings_parameters[i].default_value;
|
|
266
|
+
t->settings[j][i] = grpc_chttp2_settings_parameters[i].default_value;
|
|
314
267
|
}
|
|
315
268
|
}
|
|
316
|
-
t->
|
|
269
|
+
t->dirtied_local_settings = 1;
|
|
317
270
|
/* Hack: it's common for implementations to assume 65536 bytes initial send
|
|
318
271
|
window -- this should by rights be 0 */
|
|
319
|
-
t->
|
|
320
|
-
t->
|
|
272
|
+
t->force_send_settings = 1 << GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
|
|
273
|
+
t->sent_local_settings = 0;
|
|
274
|
+
t->write_buffer_size = DEFAULT_WINDOW;
|
|
275
|
+
|
|
276
|
+
if (is_client) {
|
|
277
|
+
grpc_slice_buffer_add(&t->outbuf, grpc_slice_from_copied_string(
|
|
278
|
+
GRPC_CHTTP2_CLIENT_CONNECT_STRING));
|
|
279
|
+
grpc_chttp2_initiate_write(exec_ctx, t, false, "initial_write");
|
|
280
|
+
}
|
|
321
281
|
|
|
322
282
|
/* configure http2 the way we like it */
|
|
323
283
|
if (is_client) {
|
|
@@ -331,681 +291,483 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
|
331
291
|
|
|
332
292
|
if (channel_args) {
|
|
333
293
|
for (i = 0; i < channel_args->num_args; i++) {
|
|
334
|
-
if (0 ==
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER)) {
|
|
348
|
-
if (channel_args->args[i].type != GRPC_ARG_INTEGER) {
|
|
349
|
-
gpr_log(GPR_ERROR, "%s: must be an integer",
|
|
350
|
-
GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER);
|
|
351
|
-
} else if ((t->global.next_stream_id & 1) !=
|
|
352
|
-
(channel_args->args[i].value.integer & 1)) {
|
|
353
|
-
gpr_log(GPR_ERROR, "%s: low bit must be %d on %s",
|
|
354
|
-
GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER,
|
|
355
|
-
t->global.next_stream_id & 1,
|
|
356
|
-
is_client ? "client" : "server");
|
|
357
|
-
} else {
|
|
358
|
-
t->global.next_stream_id =
|
|
359
|
-
(uint32_t)channel_args->args[i].value.integer;
|
|
294
|
+
if (0 == strcmp(channel_args->args[i].key,
|
|
295
|
+
GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER)) {
|
|
296
|
+
const grpc_integer_options options = {-1, 0, INT_MAX};
|
|
297
|
+
const int value =
|
|
298
|
+
grpc_channel_arg_get_integer(&channel_args->args[i], options);
|
|
299
|
+
if (value >= 0) {
|
|
300
|
+
if ((t->next_stream_id & 1) != (value & 1)) {
|
|
301
|
+
gpr_log(GPR_ERROR, "%s: low bit must be %d on %s",
|
|
302
|
+
GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER,
|
|
303
|
+
t->next_stream_id & 1, is_client ? "client" : "server");
|
|
304
|
+
} else {
|
|
305
|
+
t->next_stream_id = (uint32_t)value;
|
|
306
|
+
}
|
|
360
307
|
}
|
|
361
308
|
} else if (0 == strcmp(channel_args->args[i].key,
|
|
362
309
|
GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES)) {
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES);
|
|
369
|
-
} else {
|
|
370
|
-
t->global.stream_lookahead =
|
|
371
|
-
(uint32_t)channel_args->args[i].value.integer;
|
|
372
|
-
}
|
|
373
|
-
} else if (0 == strcmp(channel_args->args[i].key,
|
|
374
|
-
GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER)) {
|
|
375
|
-
if (channel_args->args[i].type != GRPC_ARG_INTEGER) {
|
|
376
|
-
gpr_log(GPR_ERROR, "%s: must be an integer",
|
|
377
|
-
GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER);
|
|
378
|
-
} else if (channel_args->args[i].value.integer < 0) {
|
|
379
|
-
gpr_log(GPR_ERROR, "%s: must be non-negative",
|
|
380
|
-
GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER);
|
|
381
|
-
} else {
|
|
382
|
-
push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE,
|
|
383
|
-
(uint32_t)channel_args->args[i].value.integer);
|
|
310
|
+
const grpc_integer_options options = {-1, 5, INT_MAX};
|
|
311
|
+
const int value =
|
|
312
|
+
grpc_channel_arg_get_integer(&channel_args->args[i], options);
|
|
313
|
+
if (value >= 0) {
|
|
314
|
+
t->stream_lookahead = (uint32_t)value;
|
|
384
315
|
}
|
|
385
316
|
} else if (0 == strcmp(channel_args->args[i].key,
|
|
386
317
|
GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_ENCODER)) {
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
} else {
|
|
394
|
-
grpc_chttp2_hpack_compressor_set_max_usable_size(
|
|
395
|
-
&t->writing.hpack_compressor,
|
|
396
|
-
(uint32_t)channel_args->args[i].value.integer);
|
|
318
|
+
const grpc_integer_options options = {-1, 0, INT_MAX};
|
|
319
|
+
const int value =
|
|
320
|
+
grpc_channel_arg_get_integer(&channel_args->args[i], options);
|
|
321
|
+
if (value >= 0) {
|
|
322
|
+
grpc_chttp2_hpack_compressor_set_max_usable_size(&t->hpack_compressor,
|
|
323
|
+
(uint32_t)value);
|
|
397
324
|
}
|
|
398
325
|
} else if (0 == strcmp(channel_args->args[i].key,
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
326
|
+
GRPC_ARG_HTTP2_WRITE_BUFFER_SIZE)) {
|
|
327
|
+
t->write_buffer_size = (uint32_t)grpc_channel_arg_get_integer(
|
|
328
|
+
&channel_args->args[i],
|
|
329
|
+
(grpc_integer_options){0, 0, MAX_WRITE_BUFFER_SIZE});
|
|
330
|
+
} else {
|
|
331
|
+
static const struct {
|
|
332
|
+
const char *channel_arg_name;
|
|
333
|
+
grpc_chttp2_setting_id setting_id;
|
|
334
|
+
grpc_integer_options integer_options;
|
|
335
|
+
bool availability[2] /* server, client */;
|
|
336
|
+
} settings_map[] = {
|
|
337
|
+
{GRPC_ARG_MAX_CONCURRENT_STREAMS,
|
|
338
|
+
GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS,
|
|
339
|
+
{-1, 0, INT_MAX},
|
|
340
|
+
{true, false}},
|
|
341
|
+
{GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER,
|
|
342
|
+
GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE,
|
|
343
|
+
{-1, 0, INT_MAX},
|
|
344
|
+
{true, true}},
|
|
345
|
+
{GRPC_ARG_MAX_METADATA_SIZE,
|
|
346
|
+
GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE,
|
|
347
|
+
{-1, 0, INT_MAX},
|
|
348
|
+
{true, true}},
|
|
349
|
+
{GRPC_ARG_HTTP2_MAX_FRAME_SIZE,
|
|
350
|
+
GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE,
|
|
351
|
+
{-1, 16384, 16777215},
|
|
352
|
+
{true, true}},
|
|
353
|
+
};
|
|
354
|
+
for (j = 0; j < (int)GPR_ARRAY_SIZE(settings_map); j++) {
|
|
355
|
+
if (0 == strcmp(channel_args->args[i].key,
|
|
356
|
+
settings_map[j].channel_arg_name)) {
|
|
357
|
+
if (!settings_map[j].availability[is_client]) {
|
|
358
|
+
gpr_log(GPR_DEBUG, "%s is not available on %s",
|
|
359
|
+
settings_map[j].channel_arg_name,
|
|
360
|
+
is_client ? "clients" : "servers");
|
|
361
|
+
} else {
|
|
362
|
+
int value = grpc_channel_arg_get_integer(
|
|
363
|
+
&channel_args->args[i], settings_map[j].integer_options);
|
|
364
|
+
if (value >= 0) {
|
|
365
|
+
push_setting(exec_ctx, t, settings_map[j].setting_id,
|
|
366
|
+
(uint32_t)value);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
break;
|
|
370
|
+
}
|
|
409
371
|
}
|
|
410
372
|
}
|
|
411
373
|
}
|
|
412
374
|
}
|
|
375
|
+
|
|
376
|
+
grpc_chttp2_initiate_write(exec_ctx, t, false, "init");
|
|
377
|
+
post_benign_reclaimer(exec_ctx, t);
|
|
413
378
|
}
|
|
414
379
|
|
|
415
|
-
static void destroy_transport_locked(grpc_exec_ctx *exec_ctx,
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
void *arg_ignored) {
|
|
380
|
+
static void destroy_transport_locked(grpc_exec_ctx *exec_ctx, void *tp,
|
|
381
|
+
grpc_error *error) {
|
|
382
|
+
grpc_chttp2_transport *t = tp;
|
|
419
383
|
t->destroying = 1;
|
|
420
|
-
|
|
384
|
+
close_transport_locked(
|
|
385
|
+
exec_ctx, t,
|
|
386
|
+
grpc_error_set_int(GRPC_ERROR_CREATE("Transport destroyed"),
|
|
387
|
+
GRPC_ERROR_INT_OCCURRED_DURING_WRITE, t->write_state));
|
|
388
|
+
GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "destroy");
|
|
421
389
|
}
|
|
422
390
|
|
|
423
391
|
static void destroy_transport(grpc_exec_ctx *exec_ctx, grpc_transport *gt) {
|
|
424
392
|
grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt;
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
/** block grpc_endpoint_shutdown being called until a paired
|
|
431
|
-
allow_endpoint_shutdown is made */
|
|
432
|
-
static void prevent_endpoint_shutdown(grpc_chttp2_transport *t) {
|
|
433
|
-
GPR_ASSERT(t->ep);
|
|
434
|
-
gpr_ref(&t->shutdown_ep_refs);
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
static void allow_endpoint_shutdown_locked(grpc_exec_ctx *exec_ctx,
|
|
438
|
-
grpc_chttp2_transport *t) {
|
|
439
|
-
if (gpr_unref(&t->shutdown_ep_refs)) {
|
|
440
|
-
if (t->ep) {
|
|
441
|
-
grpc_endpoint_shutdown(exec_ctx, t->ep);
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
static void destroy_endpoint(grpc_exec_ctx *exec_ctx,
|
|
447
|
-
grpc_chttp2_transport *t) {
|
|
448
|
-
grpc_endpoint_destroy(exec_ctx, t->ep);
|
|
449
|
-
t->ep = NULL;
|
|
450
|
-
/* safe because we'll still have the ref for write */
|
|
451
|
-
UNREF_TRANSPORT(exec_ctx, t, "disconnect");
|
|
393
|
+
grpc_closure_sched(exec_ctx, grpc_closure_create(
|
|
394
|
+
destroy_transport_locked, t,
|
|
395
|
+
grpc_combiner_scheduler(t->combiner, false)),
|
|
396
|
+
GRPC_ERROR_NONE);
|
|
452
397
|
}
|
|
453
398
|
|
|
454
399
|
static void close_transport_locked(grpc_exec_ctx *exec_ctx,
|
|
455
400
|
grpc_chttp2_transport *t,
|
|
456
401
|
grpc_error *error) {
|
|
457
402
|
if (!t->closed) {
|
|
458
|
-
if (
|
|
459
|
-
|
|
403
|
+
if (t->write_state != GRPC_CHTTP2_WRITE_STATE_IDLE) {
|
|
404
|
+
if (t->close_transport_on_writes_finished == NULL) {
|
|
405
|
+
t->close_transport_on_writes_finished =
|
|
406
|
+
GRPC_ERROR_CREATE("Delayed close due to in-progress write");
|
|
407
|
+
}
|
|
408
|
+
t->close_transport_on_writes_finished =
|
|
409
|
+
grpc_error_add_child(t->close_transport_on_writes_finished, error);
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
if (!grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, NULL)) {
|
|
413
|
+
error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS,
|
|
414
|
+
GRPC_STATUS_UNAVAILABLE);
|
|
460
415
|
}
|
|
461
416
|
t->closed = 1;
|
|
462
|
-
connectivity_state_set(exec_ctx,
|
|
417
|
+
connectivity_state_set(exec_ctx, t, GRPC_CHANNEL_SHUTDOWN,
|
|
463
418
|
GRPC_ERROR_REF(error), "close_transport");
|
|
464
|
-
|
|
465
|
-
allow_endpoint_shutdown_locked(exec_ctx, t);
|
|
466
|
-
}
|
|
419
|
+
grpc_endpoint_shutdown(exec_ctx, t->ep);
|
|
467
420
|
|
|
468
421
|
/* flush writable stream list to avoid dangling references */
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
&t->global, &t->writing, &stream_global, &stream_writing)) {
|
|
473
|
-
GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2_writing");
|
|
422
|
+
grpc_chttp2_stream *s;
|
|
423
|
+
while (grpc_chttp2_list_pop_writable_stream(t, &s)) {
|
|
424
|
+
GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing:close");
|
|
474
425
|
}
|
|
426
|
+
end_all_the_calls(exec_ctx, t, GRPC_ERROR_REF(error));
|
|
475
427
|
}
|
|
476
428
|
GRPC_ERROR_UNREF(error);
|
|
477
429
|
}
|
|
478
430
|
|
|
479
431
|
#ifdef GRPC_STREAM_REFCOUNT_DEBUG
|
|
480
|
-
void grpc_chttp2_stream_ref(
|
|
481
|
-
|
|
482
|
-
grpc_stream_ref(STREAM_FROM_GLOBAL(stream_global)->refcount, reason);
|
|
432
|
+
void grpc_chttp2_stream_ref(grpc_chttp2_stream *s, const char *reason) {
|
|
433
|
+
grpc_stream_ref(s->refcount, reason);
|
|
483
434
|
}
|
|
484
|
-
void grpc_chttp2_stream_unref(grpc_exec_ctx *exec_ctx,
|
|
485
|
-
grpc_chttp2_stream_global *stream_global,
|
|
435
|
+
void grpc_chttp2_stream_unref(grpc_exec_ctx *exec_ctx, grpc_chttp2_stream *s,
|
|
486
436
|
const char *reason) {
|
|
487
|
-
grpc_stream_unref(exec_ctx,
|
|
488
|
-
reason);
|
|
437
|
+
grpc_stream_unref(exec_ctx, s->refcount, reason);
|
|
489
438
|
}
|
|
490
439
|
#else
|
|
491
|
-
void grpc_chttp2_stream_ref(
|
|
492
|
-
grpc_stream_ref(
|
|
440
|
+
void grpc_chttp2_stream_ref(grpc_chttp2_stream *s) {
|
|
441
|
+
grpc_stream_ref(s->refcount);
|
|
493
442
|
}
|
|
494
|
-
void grpc_chttp2_stream_unref(grpc_exec_ctx *exec_ctx,
|
|
495
|
-
|
|
496
|
-
grpc_stream_unref(exec_ctx, STREAM_FROM_GLOBAL(stream_global)->refcount);
|
|
443
|
+
void grpc_chttp2_stream_unref(grpc_exec_ctx *exec_ctx, grpc_chttp2_stream *s) {
|
|
444
|
+
grpc_stream_unref(exec_ctx, s->refcount);
|
|
497
445
|
}
|
|
498
446
|
#endif
|
|
499
447
|
|
|
500
|
-
static void finish_init_stream_locked(grpc_exec_ctx *exec_ctx,
|
|
501
|
-
grpc_chttp2_transport *t,
|
|
502
|
-
grpc_chttp2_stream *s,
|
|
503
|
-
void *arg_ignored) {
|
|
504
|
-
grpc_chttp2_register_stream(t, s);
|
|
505
|
-
}
|
|
506
|
-
|
|
507
448
|
static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
|
|
508
449
|
grpc_stream *gs, grpc_stream_refcount *refcount,
|
|
509
450
|
const void *server_data) {
|
|
451
|
+
GPR_TIMER_BEGIN("init_stream", 0);
|
|
510
452
|
grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt;
|
|
511
453
|
grpc_chttp2_stream *s = (grpc_chttp2_stream *)gs;
|
|
512
454
|
|
|
513
455
|
memset(s, 0, sizeof(*s));
|
|
514
456
|
|
|
457
|
+
s->t = t;
|
|
515
458
|
s->refcount = refcount;
|
|
516
459
|
/* We reserve one 'active stream' that's dropped when the stream is
|
|
517
460
|
read-closed. The others are for incoming_byte_streams that are actively
|
|
518
461
|
reading */
|
|
519
|
-
gpr_ref_init(&s->
|
|
520
|
-
GRPC_CHTTP2_STREAM_REF(
|
|
462
|
+
gpr_ref_init(&s->active_streams, 1);
|
|
463
|
+
GRPC_CHTTP2_STREAM_REF(s, "chttp2");
|
|
521
464
|
|
|
522
|
-
grpc_chttp2_incoming_metadata_buffer_init(&s->
|
|
523
|
-
grpc_chttp2_incoming_metadata_buffer_init(&s->
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
gpr_slice_buffer_init(&s->writing.flow_controlled_buffer);
|
|
530
|
-
s->global.deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
|
|
465
|
+
grpc_chttp2_incoming_metadata_buffer_init(&s->metadata_buffer[0]);
|
|
466
|
+
grpc_chttp2_incoming_metadata_buffer_init(&s->metadata_buffer[1]);
|
|
467
|
+
grpc_chttp2_data_parser_init(&s->data_parser);
|
|
468
|
+
grpc_slice_buffer_init(&s->flow_controlled_buffer);
|
|
469
|
+
s->deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
|
|
470
|
+
grpc_closure_init(&s->complete_fetch_locked, complete_fetch_locked, s,
|
|
471
|
+
grpc_schedule_on_exec_ctx);
|
|
531
472
|
|
|
532
|
-
|
|
473
|
+
GRPC_CHTTP2_REF_TRANSPORT(t, "stream");
|
|
533
474
|
|
|
534
475
|
if (server_data) {
|
|
535
|
-
|
|
536
|
-
s->
|
|
537
|
-
|
|
538
|
-
s->
|
|
539
|
-
t->
|
|
540
|
-
|
|
541
|
-
s->parsing.incoming_window = s->global.max_recv_bytes =
|
|
542
|
-
t->global.settings[GRPC_SENT_SETTINGS]
|
|
543
|
-
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
|
|
476
|
+
s->id = (uint32_t)(uintptr_t)server_data;
|
|
477
|
+
s->outgoing_window = t->settings[GRPC_PEER_SETTINGS]
|
|
478
|
+
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
|
|
479
|
+
s->incoming_window = s->max_recv_bytes =
|
|
480
|
+
t->settings[GRPC_SENT_SETTINGS]
|
|
481
|
+
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
|
|
544
482
|
*t->accepting_stream = s;
|
|
545
|
-
grpc_chttp2_stream_map_add(&t->
|
|
546
|
-
|
|
483
|
+
grpc_chttp2_stream_map_add(&t->stream_map, s->id, s);
|
|
484
|
+
post_destructive_reclaimer(exec_ctx, t);
|
|
547
485
|
}
|
|
548
486
|
|
|
549
|
-
|
|
550
|
-
NULL, 0);
|
|
487
|
+
GPR_TIMER_END("init_stream", 0);
|
|
551
488
|
|
|
552
489
|
return 0;
|
|
553
490
|
}
|
|
554
491
|
|
|
555
|
-
static void destroy_stream_locked(grpc_exec_ctx *exec_ctx,
|
|
556
|
-
|
|
557
|
-
grpc_chttp2_stream *s, void *arg) {
|
|
492
|
+
static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp,
|
|
493
|
+
grpc_error *error) {
|
|
558
494
|
grpc_byte_stream *bs;
|
|
495
|
+
grpc_chttp2_stream *s = sp;
|
|
496
|
+
grpc_chttp2_transport *t = s->t;
|
|
559
497
|
|
|
560
498
|
GPR_TIMER_BEGIN("destroy_stream", 0);
|
|
561
499
|
|
|
562
|
-
GPR_ASSERT((s->
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
if (grpc_chttp2_unregister_stream(t, s) && t->global.sent_goaway) {
|
|
566
|
-
close_transport_locked(
|
|
567
|
-
exec_ctx, t,
|
|
568
|
-
GRPC_ERROR_CREATE("Last stream closed after sending goaway"));
|
|
569
|
-
}
|
|
570
|
-
if (!t->executor.parsing_active && s->global.id) {
|
|
571
|
-
GPR_ASSERT(grpc_chttp2_stream_map_find(&t->parsing_stream_map,
|
|
572
|
-
s->global.id) == NULL);
|
|
500
|
+
GPR_ASSERT((s->write_closed && s->read_closed) || s->id == 0);
|
|
501
|
+
if (s->id != 0) {
|
|
502
|
+
GPR_ASSERT(grpc_chttp2_stream_map_find(&t->stream_map, s->id) == NULL);
|
|
573
503
|
}
|
|
574
504
|
|
|
575
|
-
while (
|
|
576
|
-
|
|
577
|
-
incoming_byte_stream_destroy_locked(exec_ctx, NULL, NULL, bs);
|
|
505
|
+
while ((bs = grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames))) {
|
|
506
|
+
incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE);
|
|
578
507
|
}
|
|
579
508
|
|
|
580
|
-
|
|
581
|
-
&s->global);
|
|
582
|
-
grpc_chttp2_list_remove_stalled_by_transport(&t->global, &s->global);
|
|
583
|
-
grpc_chttp2_list_remove_check_read_ops(&t->global, &s->global);
|
|
509
|
+
grpc_chttp2_list_remove_stalled_by_transport(t, s);
|
|
584
510
|
|
|
585
511
|
for (int i = 0; i < STREAM_LIST_COUNT; i++) {
|
|
586
512
|
if (s->included[i]) {
|
|
587
513
|
gpr_log(GPR_ERROR, "%s stream %d still included in list %d",
|
|
588
|
-
t->
|
|
514
|
+
t->is_client ? "client" : "server", s->id, i);
|
|
589
515
|
abort();
|
|
590
516
|
}
|
|
591
517
|
}
|
|
592
518
|
|
|
593
|
-
GPR_ASSERT(s->
|
|
594
|
-
GPR_ASSERT(s->
|
|
595
|
-
GPR_ASSERT(s->
|
|
596
|
-
GPR_ASSERT(s->
|
|
597
|
-
GPR_ASSERT(s->
|
|
598
|
-
GPR_ASSERT(s->
|
|
599
|
-
grpc_chttp2_data_parser_destroy(exec_ctx, &s->
|
|
600
|
-
grpc_chttp2_incoming_metadata_buffer_destroy(
|
|
601
|
-
|
|
602
|
-
grpc_chttp2_incoming_metadata_buffer_destroy(
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
UNREF_TRANSPORT(exec_ctx, t, "stream");
|
|
519
|
+
GPR_ASSERT(s->send_initial_metadata_finished == NULL);
|
|
520
|
+
GPR_ASSERT(s->fetching_send_message == NULL);
|
|
521
|
+
GPR_ASSERT(s->send_trailing_metadata_finished == NULL);
|
|
522
|
+
GPR_ASSERT(s->recv_initial_metadata_ready == NULL);
|
|
523
|
+
GPR_ASSERT(s->recv_message_ready == NULL);
|
|
524
|
+
GPR_ASSERT(s->recv_trailing_metadata_finished == NULL);
|
|
525
|
+
grpc_chttp2_data_parser_destroy(exec_ctx, &s->data_parser);
|
|
526
|
+
grpc_chttp2_incoming_metadata_buffer_destroy(exec_ctx,
|
|
527
|
+
&s->metadata_buffer[0]);
|
|
528
|
+
grpc_chttp2_incoming_metadata_buffer_destroy(exec_ctx,
|
|
529
|
+
&s->metadata_buffer[1]);
|
|
530
|
+
grpc_slice_buffer_destroy_internal(exec_ctx, &s->flow_controlled_buffer);
|
|
531
|
+
GRPC_ERROR_UNREF(s->read_closed_error);
|
|
532
|
+
GRPC_ERROR_UNREF(s->write_closed_error);
|
|
533
|
+
|
|
534
|
+
GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "stream");
|
|
611
535
|
|
|
612
536
|
GPR_TIMER_END("destroy_stream", 0);
|
|
613
537
|
|
|
614
|
-
gpr_free(
|
|
538
|
+
gpr_free(s->destroy_stream_arg);
|
|
615
539
|
}
|
|
616
540
|
|
|
617
541
|
static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
|
|
618
542
|
grpc_stream *gs, void *and_free_memory) {
|
|
543
|
+
GPR_TIMER_BEGIN("destroy_stream", 0);
|
|
619
544
|
grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt;
|
|
620
545
|
grpc_chttp2_stream *s = (grpc_chttp2_stream *)gs;
|
|
621
546
|
|
|
622
|
-
|
|
623
|
-
|
|
547
|
+
s->destroy_stream_arg = and_free_memory;
|
|
548
|
+
grpc_closure_sched(
|
|
549
|
+
exec_ctx, grpc_closure_init(&s->destroy_stream, destroy_stream_locked, s,
|
|
550
|
+
grpc_combiner_scheduler(t->combiner, false)),
|
|
551
|
+
GRPC_ERROR_NONE);
|
|
552
|
+
GPR_TIMER_END("destroy_stream", 0);
|
|
624
553
|
}
|
|
625
554
|
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
grpc_chttp2_stream *s =
|
|
630
|
-
grpc_chttp2_stream_map_find(&t->parsing_stream_map, id);
|
|
631
|
-
return s ? &s->parsing : NULL;
|
|
555
|
+
grpc_chttp2_stream *grpc_chttp2_parsing_lookup_stream(grpc_chttp2_transport *t,
|
|
556
|
+
uint32_t id) {
|
|
557
|
+
return grpc_chttp2_stream_map_find(&t->stream_map, id);
|
|
632
558
|
}
|
|
633
559
|
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
560
|
+
grpc_chttp2_stream *grpc_chttp2_parsing_accept_stream(grpc_exec_ctx *exec_ctx,
|
|
561
|
+
grpc_chttp2_transport *t,
|
|
562
|
+
uint32_t id) {
|
|
563
|
+
if (t->channel_callback.accept_stream == NULL) {
|
|
564
|
+
return NULL;
|
|
565
|
+
}
|
|
637
566
|
grpc_chttp2_stream *accepting;
|
|
638
|
-
grpc_chttp2_transport *t = TRANSPORT_FROM_PARSING(transport_parsing);
|
|
639
567
|
GPR_ASSERT(t->accepting_stream == NULL);
|
|
640
568
|
t->accepting_stream = &accepting;
|
|
641
569
|
t->channel_callback.accept_stream(exec_ctx,
|
|
642
570
|
t->channel_callback.accept_stream_user_data,
|
|
643
571
|
&t->base, (void *)(uintptr_t)id);
|
|
644
572
|
t->accepting_stream = NULL;
|
|
645
|
-
return
|
|
573
|
+
return accepting;
|
|
646
574
|
}
|
|
647
575
|
|
|
648
576
|
/*******************************************************************************
|
|
649
|
-
*
|
|
577
|
+
* OUTPUT PROCESSING
|
|
650
578
|
*/
|
|
651
579
|
|
|
652
|
-
static const char *write_state_name(grpc_chttp2_write_state
|
|
653
|
-
switch (
|
|
654
|
-
case
|
|
655
|
-
return "
|
|
656
|
-
case
|
|
657
|
-
return "REQUESTED[p=0]";
|
|
658
|
-
case GRPC_CHTTP2_WRITE_REQUESTED_WITH_POLLER:
|
|
659
|
-
return "REQUESTED[p=1]";
|
|
660
|
-
case GRPC_CHTTP2_WRITE_SCHEDULED:
|
|
661
|
-
return "SCHEDULED";
|
|
662
|
-
case GRPC_CHTTP2_WRITING:
|
|
580
|
+
static const char *write_state_name(grpc_chttp2_write_state st) {
|
|
581
|
+
switch (st) {
|
|
582
|
+
case GRPC_CHTTP2_WRITE_STATE_IDLE:
|
|
583
|
+
return "IDLE";
|
|
584
|
+
case GRPC_CHTTP2_WRITE_STATE_WRITING:
|
|
663
585
|
return "WRITING";
|
|
664
|
-
case
|
|
665
|
-
return "WRITING
|
|
666
|
-
case
|
|
667
|
-
return "WRITING
|
|
586
|
+
case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE:
|
|
587
|
+
return "WRITING+MORE";
|
|
588
|
+
case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_AND_COVERED_BY_POLLER:
|
|
589
|
+
return "WRITING+MORE+COVERED";
|
|
668
590
|
}
|
|
669
591
|
GPR_UNREACHABLE_CODE(return "UNKNOWN");
|
|
670
592
|
}
|
|
671
593
|
|
|
672
|
-
static void set_write_state(grpc_chttp2_transport *t,
|
|
673
|
-
grpc_chttp2_write_state
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
grpc_chttp2_executor_action_header *next;
|
|
686
|
-
|
|
687
|
-
GPR_TIMER_BEGIN("finish_global_actions", 0);
|
|
688
|
-
|
|
689
|
-
for (;;) {
|
|
690
|
-
check_read_ops(exec_ctx, &t->global);
|
|
691
|
-
|
|
692
|
-
gpr_mu_lock(&t->executor.mu);
|
|
693
|
-
if (t->executor.pending_actions_head != NULL) {
|
|
694
|
-
hdr = t->executor.pending_actions_head;
|
|
695
|
-
t->executor.pending_actions_head = t->executor.pending_actions_tail =
|
|
696
|
-
NULL;
|
|
697
|
-
gpr_mu_unlock(&t->executor.mu);
|
|
698
|
-
while (hdr != NULL) {
|
|
699
|
-
GPR_TIMER_BEGIN("chttp2:locked_action", 0);
|
|
700
|
-
hdr->action(exec_ctx, t, hdr->stream, hdr->arg);
|
|
701
|
-
GPR_TIMER_END("chttp2:locked_action", 0);
|
|
702
|
-
next = hdr->next;
|
|
703
|
-
gpr_free(hdr);
|
|
704
|
-
UNREF_TRANSPORT(exec_ctx, t, "pending_action");
|
|
705
|
-
hdr = next;
|
|
706
|
-
}
|
|
707
|
-
continue;
|
|
708
|
-
} else {
|
|
709
|
-
t->executor.global_active = false;
|
|
710
|
-
switch (t->executor.write_state) {
|
|
711
|
-
case GRPC_CHTTP2_WRITE_REQUESTED_WITH_POLLER:
|
|
712
|
-
set_write_state(t, GRPC_CHTTP2_WRITE_SCHEDULED, "unlocking");
|
|
713
|
-
REF_TRANSPORT(t, "initiate_writing");
|
|
714
|
-
gpr_mu_unlock(&t->executor.mu);
|
|
715
|
-
grpc_exec_ctx_sched(
|
|
716
|
-
exec_ctx, &t->initiate_writing, GRPC_ERROR_NONE,
|
|
717
|
-
t->ep != NULL ? grpc_endpoint_get_workqueue(t->ep) : NULL);
|
|
718
|
-
break;
|
|
719
|
-
case GRPC_CHTTP2_WRITE_REQUESTED_NO_POLLER:
|
|
720
|
-
start_writing(exec_ctx, t);
|
|
721
|
-
gpr_mu_unlock(&t->executor.mu);
|
|
722
|
-
break;
|
|
723
|
-
case GRPC_CHTTP2_WRITING_INACTIVE:
|
|
724
|
-
case GRPC_CHTTP2_WRITING:
|
|
725
|
-
case GRPC_CHTTP2_WRITING_STALE_WITH_POLLER:
|
|
726
|
-
case GRPC_CHTTP2_WRITING_STALE_NO_POLLER:
|
|
727
|
-
case GRPC_CHTTP2_WRITE_SCHEDULED:
|
|
728
|
-
gpr_mu_unlock(&t->executor.mu);
|
|
729
|
-
break;
|
|
730
|
-
}
|
|
594
|
+
static void set_write_state(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
595
|
+
grpc_chttp2_write_state st, const char *reason) {
|
|
596
|
+
GRPC_CHTTP2_IF_TRACING(gpr_log(GPR_DEBUG, "W:%p %s state %s -> %s [%s]", t,
|
|
597
|
+
t->is_client ? "CLIENT" : "SERVER",
|
|
598
|
+
write_state_name(t->write_state),
|
|
599
|
+
write_state_name(st), reason));
|
|
600
|
+
t->write_state = st;
|
|
601
|
+
if (st == GRPC_CHTTP2_WRITE_STATE_IDLE) {
|
|
602
|
+
grpc_closure_list_sched(exec_ctx, &t->run_after_write);
|
|
603
|
+
if (t->close_transport_on_writes_finished != NULL) {
|
|
604
|
+
grpc_error *err = t->close_transport_on_writes_finished;
|
|
605
|
+
t->close_transport_on_writes_finished = NULL;
|
|
606
|
+
close_transport_locked(exec_ctx, t, err);
|
|
731
607
|
}
|
|
732
|
-
break;
|
|
733
608
|
}
|
|
734
|
-
|
|
735
|
-
GPR_TIMER_END("finish_global_actions", 0);
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
void grpc_chttp2_run_with_global_lock(grpc_exec_ctx *exec_ctx,
|
|
739
|
-
grpc_chttp2_transport *t,
|
|
740
|
-
grpc_chttp2_stream *optional_stream,
|
|
741
|
-
grpc_chttp2_locked_action action,
|
|
742
|
-
void *arg, size_t sizeof_arg) {
|
|
743
|
-
grpc_chttp2_executor_action_header *hdr;
|
|
744
|
-
|
|
745
|
-
GPR_TIMER_BEGIN("grpc_chttp2_run_with_global_lock", 0);
|
|
746
|
-
|
|
747
|
-
REF_TRANSPORT(t, "run_global");
|
|
748
|
-
gpr_mu_lock(&t->executor.mu);
|
|
749
|
-
|
|
750
|
-
for (;;) {
|
|
751
|
-
if (!t->executor.global_active) {
|
|
752
|
-
t->executor.global_active = 1;
|
|
753
|
-
gpr_mu_unlock(&t->executor.mu);
|
|
754
|
-
|
|
755
|
-
GPR_TIMER_BEGIN("chttp2:locked_action", 0);
|
|
756
|
-
action(exec_ctx, t, optional_stream, arg);
|
|
757
|
-
GPR_TIMER_END("chttp2:locked_action", 0);
|
|
758
|
-
|
|
759
|
-
finish_global_actions(exec_ctx, t);
|
|
760
|
-
} else {
|
|
761
|
-
gpr_mu_unlock(&t->executor.mu);
|
|
762
|
-
|
|
763
|
-
hdr = gpr_malloc(sizeof(*hdr) + sizeof_arg);
|
|
764
|
-
hdr->stream = optional_stream;
|
|
765
|
-
hdr->action = action;
|
|
766
|
-
if (sizeof_arg == 0) {
|
|
767
|
-
hdr->arg = arg;
|
|
768
|
-
} else {
|
|
769
|
-
hdr->arg = hdr + 1;
|
|
770
|
-
memcpy(hdr->arg, arg, sizeof_arg);
|
|
771
|
-
}
|
|
772
|
-
|
|
773
|
-
gpr_mu_lock(&t->executor.mu);
|
|
774
|
-
if (!t->executor.global_active) {
|
|
775
|
-
/* global lock was released while allocating memory: release & retry */
|
|
776
|
-
gpr_free(hdr);
|
|
777
|
-
continue;
|
|
778
|
-
}
|
|
779
|
-
hdr->next = NULL;
|
|
780
|
-
if (t->executor.pending_actions_head != NULL) {
|
|
781
|
-
t->executor.pending_actions_tail =
|
|
782
|
-
t->executor.pending_actions_tail->next = hdr;
|
|
783
|
-
} else {
|
|
784
|
-
t->executor.pending_actions_tail = t->executor.pending_actions_head =
|
|
785
|
-
hdr;
|
|
786
|
-
}
|
|
787
|
-
REF_TRANSPORT(t, "pending_action");
|
|
788
|
-
gpr_mu_unlock(&t->executor.mu);
|
|
789
|
-
}
|
|
790
|
-
break;
|
|
791
|
-
}
|
|
792
|
-
|
|
793
|
-
UNREF_TRANSPORT(exec_ctx, t, "run_global");
|
|
794
|
-
|
|
795
|
-
GPR_TIMER_END("grpc_chttp2_run_with_global_lock", 0);
|
|
796
609
|
}
|
|
797
610
|
|
|
798
|
-
/*******************************************************************************
|
|
799
|
-
* OUTPUT PROCESSING
|
|
800
|
-
*/
|
|
801
|
-
|
|
802
611
|
void grpc_chttp2_initiate_write(grpc_exec_ctx *exec_ctx,
|
|
803
|
-
|
|
612
|
+
grpc_chttp2_transport *t,
|
|
804
613
|
bool covered_by_poller, const char *reason) {
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
start_writing.
|
|
818
|
-
|
|
819
|
-
Current problems:
|
|
820
|
-
- too much lock entry/exiting
|
|
821
|
-
- the writing thread can become stuck indefinitely (punt through the
|
|
822
|
-
workqueue periodically to fix) */
|
|
823
|
-
|
|
824
|
-
grpc_chttp2_transport *t = TRANSPORT_FROM_GLOBAL(transport_global);
|
|
825
|
-
switch (t->executor.write_state) {
|
|
826
|
-
case GRPC_CHTTP2_WRITING_INACTIVE:
|
|
827
|
-
set_write_state(t, covered_by_poller
|
|
828
|
-
? GRPC_CHTTP2_WRITE_REQUESTED_WITH_POLLER
|
|
829
|
-
: GRPC_CHTTP2_WRITE_REQUESTED_NO_POLLER,
|
|
830
|
-
reason);
|
|
614
|
+
GPR_TIMER_BEGIN("grpc_chttp2_initiate_write", 0);
|
|
615
|
+
|
|
616
|
+
switch (t->write_state) {
|
|
617
|
+
case GRPC_CHTTP2_WRITE_STATE_IDLE:
|
|
618
|
+
set_write_state(exec_ctx, t, GRPC_CHTTP2_WRITE_STATE_WRITING, reason);
|
|
619
|
+
GRPC_CHTTP2_REF_TRANSPORT(t, "writing");
|
|
620
|
+
grpc_closure_sched(
|
|
621
|
+
exec_ctx,
|
|
622
|
+
grpc_closure_init(
|
|
623
|
+
&t->write_action_begin_locked, write_action_begin_locked, t,
|
|
624
|
+
grpc_combiner_finally_scheduler(t->combiner, covered_by_poller)),
|
|
625
|
+
GRPC_ERROR_NONE);
|
|
831
626
|
break;
|
|
832
|
-
case
|
|
833
|
-
|
|
627
|
+
case GRPC_CHTTP2_WRITE_STATE_WRITING:
|
|
628
|
+
set_write_state(
|
|
629
|
+
exec_ctx, t,
|
|
630
|
+
covered_by_poller
|
|
631
|
+
? GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_AND_COVERED_BY_POLLER
|
|
632
|
+
: GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE,
|
|
633
|
+
reason);
|
|
834
634
|
break;
|
|
835
|
-
case
|
|
635
|
+
case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE:
|
|
836
636
|
if (covered_by_poller) {
|
|
837
|
-
|
|
838
|
-
|
|
637
|
+
set_write_state(
|
|
638
|
+
exec_ctx, t,
|
|
639
|
+
GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_AND_COVERED_BY_POLLER,
|
|
640
|
+
reason);
|
|
839
641
|
}
|
|
840
642
|
break;
|
|
841
|
-
case
|
|
842
|
-
/* nothing to do: write already scheduled */
|
|
843
|
-
break;
|
|
844
|
-
case GRPC_CHTTP2_WRITING:
|
|
845
|
-
set_write_state(t,
|
|
846
|
-
covered_by_poller ? GRPC_CHTTP2_WRITING_STALE_WITH_POLLER
|
|
847
|
-
: GRPC_CHTTP2_WRITING_STALE_NO_POLLER,
|
|
848
|
-
reason);
|
|
643
|
+
case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_AND_COVERED_BY_POLLER:
|
|
849
644
|
break;
|
|
850
|
-
case GRPC_CHTTP2_WRITING_STALE_WITH_POLLER:
|
|
851
|
-
/* nothing to do: write already requested */
|
|
852
|
-
break;
|
|
853
|
-
case GRPC_CHTTP2_WRITING_STALE_NO_POLLER:
|
|
854
|
-
if (covered_by_poller) {
|
|
855
|
-
/* upgrade to note poller is available to cover the write */
|
|
856
|
-
set_write_state(t, GRPC_CHTTP2_WRITING_STALE_WITH_POLLER, reason);
|
|
857
|
-
}
|
|
858
|
-
break;
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
|
|
862
|
-
static void start_writing(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t) {
|
|
863
|
-
GPR_ASSERT(t->executor.write_state == GRPC_CHTTP2_WRITE_SCHEDULED ||
|
|
864
|
-
t->executor.write_state == GRPC_CHTTP2_WRITE_REQUESTED_NO_POLLER);
|
|
865
|
-
if (!t->closed &&
|
|
866
|
-
grpc_chttp2_unlocking_check_writes(exec_ctx, &t->global, &t->writing)) {
|
|
867
|
-
set_write_state(t, GRPC_CHTTP2_WRITING, "start_writing");
|
|
868
|
-
REF_TRANSPORT(t, "writing");
|
|
869
|
-
prevent_endpoint_shutdown(t);
|
|
870
|
-
grpc_exec_ctx_sched(exec_ctx, &t->writing_action, GRPC_ERROR_NONE, NULL);
|
|
871
|
-
} else {
|
|
872
|
-
if (t->closed) {
|
|
873
|
-
set_write_state(t, GRPC_CHTTP2_WRITING_INACTIVE,
|
|
874
|
-
"start_writing:transport_closed");
|
|
875
|
-
} else {
|
|
876
|
-
set_write_state(t, GRPC_CHTTP2_WRITING_INACTIVE,
|
|
877
|
-
"start_writing:nothing_to_write");
|
|
878
|
-
}
|
|
879
|
-
end_waiting_for_write(exec_ctx, t, GRPC_ERROR_CREATE("Nothing to write"));
|
|
880
|
-
if (t->ep && !t->endpoint_reading) {
|
|
881
|
-
destroy_endpoint(exec_ctx, t);
|
|
882
|
-
}
|
|
883
645
|
}
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
static void initiate_writing_locked(grpc_exec_ctx *exec_ctx,
|
|
887
|
-
grpc_chttp2_transport *t,
|
|
888
|
-
grpc_chttp2_stream *s_unused,
|
|
889
|
-
void *arg_ignored) {
|
|
890
|
-
start_writing(exec_ctx, t);
|
|
891
|
-
UNREF_TRANSPORT(exec_ctx, t, "initiate_writing");
|
|
892
|
-
}
|
|
893
|
-
|
|
894
|
-
static void initiate_writing(grpc_exec_ctx *exec_ctx, void *arg,
|
|
895
|
-
grpc_error *error) {
|
|
896
|
-
grpc_chttp2_run_with_global_lock(exec_ctx, arg, NULL, initiate_writing_locked,
|
|
897
|
-
NULL, 0);
|
|
646
|
+
GPR_TIMER_END("grpc_chttp2_initiate_write", 0);
|
|
898
647
|
}
|
|
899
648
|
|
|
900
649
|
void grpc_chttp2_become_writable(grpc_exec_ctx *exec_ctx,
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
if (!
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
grpc_chttp2_initiate_write(exec_ctx, transport_global, covered_by_poller,
|
|
908
|
-
reason);
|
|
650
|
+
grpc_chttp2_transport *t,
|
|
651
|
+
grpc_chttp2_stream *s, bool covered_by_poller,
|
|
652
|
+
const char *reason) {
|
|
653
|
+
if (!t->closed && grpc_chttp2_list_add_writable_stream(t, s)) {
|
|
654
|
+
GRPC_CHTTP2_STREAM_REF(s, "chttp2_writing:become");
|
|
655
|
+
grpc_chttp2_initiate_write(exec_ctx, t, covered_by_poller, reason);
|
|
909
656
|
}
|
|
910
657
|
}
|
|
911
658
|
|
|
912
|
-
static void
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
if (
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
t
|
|
923
|
-
|
|
924
|
-
|
|
659
|
+
static void write_action_begin_locked(grpc_exec_ctx *exec_ctx, void *gt,
|
|
660
|
+
grpc_error *error_ignored) {
|
|
661
|
+
GPR_TIMER_BEGIN("write_action_begin_locked", 0);
|
|
662
|
+
grpc_chttp2_transport *t = gt;
|
|
663
|
+
GPR_ASSERT(t->write_state != GRPC_CHTTP2_WRITE_STATE_IDLE);
|
|
664
|
+
if (!t->closed && grpc_chttp2_begin_write(exec_ctx, t)) {
|
|
665
|
+
set_write_state(exec_ctx, t, GRPC_CHTTP2_WRITE_STATE_WRITING,
|
|
666
|
+
"begin writing");
|
|
667
|
+
grpc_closure_sched(exec_ctx, &t->write_action, GRPC_ERROR_NONE);
|
|
668
|
+
} else {
|
|
669
|
+
set_write_state(exec_ctx, t, GRPC_CHTTP2_WRITE_STATE_IDLE,
|
|
670
|
+
"begin writing nothing");
|
|
671
|
+
GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "writing");
|
|
925
672
|
}
|
|
673
|
+
GPR_TIMER_END("write_action_begin_locked", 0);
|
|
926
674
|
}
|
|
927
675
|
|
|
928
|
-
static void
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
}
|
|
937
|
-
GRPC_ERROR_UNREF(error);
|
|
676
|
+
static void write_action(grpc_exec_ctx *exec_ctx, void *gt, grpc_error *error) {
|
|
677
|
+
grpc_chttp2_transport *t = gt;
|
|
678
|
+
GPR_TIMER_BEGIN("write_action", 0);
|
|
679
|
+
grpc_endpoint_write(
|
|
680
|
+
exec_ctx, t->ep, &t->outbuf,
|
|
681
|
+
grpc_closure_init(&t->write_action_end_locked, write_action_end_locked, t,
|
|
682
|
+
grpc_combiner_scheduler(t->combiner, false)));
|
|
683
|
+
GPR_TIMER_END("write_action", 0);
|
|
938
684
|
}
|
|
939
685
|
|
|
940
|
-
static void
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
grpc_error *error = a;
|
|
945
|
-
|
|
946
|
-
allow_endpoint_shutdown_locked(exec_ctx, t);
|
|
686
|
+
static void write_action_end_locked(grpc_exec_ctx *exec_ctx, void *tp,
|
|
687
|
+
grpc_error *error) {
|
|
688
|
+
GPR_TIMER_BEGIN("terminate_writing_with_lock", 0);
|
|
689
|
+
grpc_chttp2_transport *t = tp;
|
|
947
690
|
|
|
948
691
|
if (error != GRPC_ERROR_NONE) {
|
|
949
|
-
|
|
692
|
+
close_transport_locked(exec_ctx, t, GRPC_ERROR_REF(error));
|
|
950
693
|
}
|
|
951
694
|
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
695
|
+
if (t->sent_goaway_state == GRPC_CHTTP2_GOAWAY_SEND_SCHEDULED) {
|
|
696
|
+
t->sent_goaway_state = GRPC_CHTTP2_GOAWAY_SENT;
|
|
697
|
+
if (grpc_chttp2_stream_map_size(&t->stream_map) == 0) {
|
|
698
|
+
close_transport_locked(exec_ctx, t, GRPC_ERROR_CREATE("goaway sent"));
|
|
699
|
+
}
|
|
700
|
+
}
|
|
955
701
|
|
|
956
|
-
switch (t->
|
|
957
|
-
case
|
|
958
|
-
case GRPC_CHTTP2_WRITE_REQUESTED_WITH_POLLER:
|
|
959
|
-
case GRPC_CHTTP2_WRITE_REQUESTED_NO_POLLER:
|
|
960
|
-
case GRPC_CHTTP2_WRITE_SCHEDULED:
|
|
702
|
+
switch (t->write_state) {
|
|
703
|
+
case GRPC_CHTTP2_WRITE_STATE_IDLE:
|
|
961
704
|
GPR_UNREACHABLE_CODE(break);
|
|
962
|
-
case
|
|
963
|
-
|
|
705
|
+
case GRPC_CHTTP2_WRITE_STATE_WRITING:
|
|
706
|
+
GPR_TIMER_MARK("state=writing", 0);
|
|
707
|
+
set_write_state(exec_ctx, t, GRPC_CHTTP2_WRITE_STATE_IDLE,
|
|
708
|
+
"finish writing");
|
|
964
709
|
break;
|
|
965
|
-
case
|
|
966
|
-
|
|
967
|
-
|
|
710
|
+
case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE:
|
|
711
|
+
GPR_TIMER_MARK("state=writing_stale_no_poller", 0);
|
|
712
|
+
set_write_state(exec_ctx, t, GRPC_CHTTP2_WRITE_STATE_WRITING,
|
|
713
|
+
"continue writing [!covered]");
|
|
714
|
+
GRPC_CHTTP2_REF_TRANSPORT(t, "writing");
|
|
715
|
+
grpc_closure_run(
|
|
716
|
+
exec_ctx,
|
|
717
|
+
grpc_closure_init(
|
|
718
|
+
&t->write_action_begin_locked, write_action_begin_locked, t,
|
|
719
|
+
grpc_combiner_finally_scheduler(t->combiner, false)),
|
|
720
|
+
GRPC_ERROR_NONE);
|
|
968
721
|
break;
|
|
969
|
-
case
|
|
970
|
-
|
|
971
|
-
|
|
722
|
+
case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_AND_COVERED_BY_POLLER:
|
|
723
|
+
GPR_TIMER_MARK("state=writing_stale_with_poller", 0);
|
|
724
|
+
set_write_state(exec_ctx, t, GRPC_CHTTP2_WRITE_STATE_WRITING,
|
|
725
|
+
"continue writing [covered]");
|
|
726
|
+
GRPC_CHTTP2_REF_TRANSPORT(t, "writing");
|
|
727
|
+
grpc_closure_run(
|
|
728
|
+
exec_ctx,
|
|
729
|
+
grpc_closure_init(&t->write_action_begin_locked,
|
|
730
|
+
write_action_begin_locked, t,
|
|
731
|
+
grpc_combiner_finally_scheduler(t->combiner, true)),
|
|
732
|
+
GRPC_ERROR_NONE);
|
|
972
733
|
break;
|
|
973
734
|
}
|
|
974
735
|
|
|
975
|
-
|
|
976
|
-
destroy_endpoint(exec_ctx, t);
|
|
977
|
-
}
|
|
736
|
+
grpc_chttp2_end_write(exec_ctx, t, GRPC_ERROR_REF(error));
|
|
978
737
|
|
|
979
|
-
|
|
738
|
+
GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "writing");
|
|
739
|
+
GPR_TIMER_END("terminate_writing_with_lock", 0);
|
|
980
740
|
}
|
|
981
741
|
|
|
982
|
-
void
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
742
|
+
static void push_setting(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
743
|
+
grpc_chttp2_setting_id id, uint32_t value) {
|
|
744
|
+
const grpc_chttp2_setting_parameters *sp =
|
|
745
|
+
&grpc_chttp2_settings_parameters[id];
|
|
746
|
+
uint32_t use_value = GPR_CLAMP(value, sp->min_value, sp->max_value);
|
|
747
|
+
if (use_value != value) {
|
|
748
|
+
gpr_log(GPR_INFO, "Requested parameter %s clamped from %d to %d", sp->name,
|
|
749
|
+
value, use_value);
|
|
750
|
+
}
|
|
751
|
+
if (use_value != t->settings[GRPC_LOCAL_SETTINGS][id]) {
|
|
752
|
+
t->settings[GRPC_LOCAL_SETTINGS][id] = use_value;
|
|
753
|
+
t->dirtied_local_settings = 1;
|
|
754
|
+
grpc_chttp2_initiate_write(exec_ctx, t, false, "push_setting");
|
|
755
|
+
}
|
|
995
756
|
}
|
|
996
757
|
|
|
997
|
-
void grpc_chttp2_add_incoming_goaway(
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
758
|
+
void grpc_chttp2_add_incoming_goaway(grpc_exec_ctx *exec_ctx,
|
|
759
|
+
grpc_chttp2_transport *t,
|
|
760
|
+
uint32_t goaway_error,
|
|
761
|
+
grpc_slice goaway_text) {
|
|
762
|
+
char *msg = grpc_dump_slice(goaway_text, GPR_DUMP_HEX | GPR_DUMP_ASCII);
|
|
1001
763
|
GRPC_CHTTP2_IF_TRACING(
|
|
1002
764
|
gpr_log(GPR_DEBUG, "got goaway [%d]: %s", goaway_error, msg));
|
|
1003
|
-
|
|
1004
|
-
|
|
765
|
+
grpc_slice_unref_internal(exec_ctx, goaway_text);
|
|
766
|
+
t->seen_goaway = 1;
|
|
1005
767
|
/* lie: use transient failure from the transport to indicate goaway has been
|
|
1006
768
|
* received */
|
|
1007
769
|
connectivity_state_set(
|
|
1008
|
-
exec_ctx,
|
|
770
|
+
exec_ctx, t, GRPC_CHANNEL_TRANSIENT_FAILURE,
|
|
1009
771
|
grpc_error_set_str(
|
|
1010
772
|
grpc_error_set_int(GRPC_ERROR_CREATE("GOAWAY received"),
|
|
1011
773
|
GRPC_ERROR_INT_HTTP2_ERROR,
|
|
@@ -1015,65 +777,61 @@ void grpc_chttp2_add_incoming_goaway(
|
|
|
1015
777
|
gpr_free(msg);
|
|
1016
778
|
}
|
|
1017
779
|
|
|
1018
|
-
static void maybe_start_some_streams(
|
|
1019
|
-
|
|
1020
|
-
|
|
780
|
+
static void maybe_start_some_streams(grpc_exec_ctx *exec_ctx,
|
|
781
|
+
grpc_chttp2_transport *t) {
|
|
782
|
+
grpc_chttp2_stream *s;
|
|
1021
783
|
uint32_t stream_incoming_window;
|
|
1022
784
|
/* start streams where we have free grpc_chttp2_stream ids and free
|
|
1023
785
|
* concurrency */
|
|
1024
|
-
while (
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
grpc_chttp2_list_pop_waiting_for_concurrency(transport_global,
|
|
1030
|
-
&stream_global)) {
|
|
786
|
+
while (t->next_stream_id <= MAX_CLIENT_STREAM_ID &&
|
|
787
|
+
grpc_chttp2_stream_map_size(&t->stream_map) <
|
|
788
|
+
t->settings[GRPC_PEER_SETTINGS]
|
|
789
|
+
[GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS] &&
|
|
790
|
+
grpc_chttp2_list_pop_waiting_for_concurrency(t, &s)) {
|
|
1031
791
|
/* safe since we can't (legally) be parsing this stream yet */
|
|
1032
|
-
grpc_chttp2_stream_parsing *stream_parsing =
|
|
1033
|
-
&STREAM_FROM_GLOBAL(stream_global)->parsing;
|
|
1034
792
|
GRPC_CHTTP2_IF_TRACING(gpr_log(
|
|
1035
793
|
GPR_DEBUG, "HTTP:%s: Allocating new grpc_chttp2_stream %p to id %d",
|
|
1036
|
-
|
|
1037
|
-
transport_global->next_stream_id));
|
|
794
|
+
t->is_client ? "CLI" : "SVR", s, t->next_stream_id));
|
|
1038
795
|
|
|
1039
|
-
GPR_ASSERT(
|
|
1040
|
-
|
|
1041
|
-
|
|
796
|
+
GPR_ASSERT(s->id == 0);
|
|
797
|
+
s->id = t->next_stream_id;
|
|
798
|
+
t->next_stream_id += 2;
|
|
1042
799
|
|
|
1043
|
-
if (
|
|
1044
|
-
connectivity_state_set(
|
|
1045
|
-
|
|
1046
|
-
|
|
800
|
+
if (t->next_stream_id >= MAX_CLIENT_STREAM_ID) {
|
|
801
|
+
connectivity_state_set(exec_ctx, t, GRPC_CHANNEL_TRANSIENT_FAILURE,
|
|
802
|
+
GRPC_ERROR_CREATE("Stream IDs exhausted"),
|
|
803
|
+
"no_more_stream_ids");
|
|
1047
804
|
}
|
|
1048
805
|
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
&TRANSPORT_FROM_GLOBAL(transport_global)->new_stream_map,
|
|
1059
|
-
stream_global->id, STREAM_FROM_GLOBAL(stream_global));
|
|
1060
|
-
stream_global->in_stream_map = true;
|
|
1061
|
-
transport_global->concurrent_stream_count++;
|
|
1062
|
-
grpc_chttp2_become_writable(exec_ctx, transport_global, stream_global, true,
|
|
1063
|
-
"new_stream");
|
|
806
|
+
s->outgoing_window = t->settings[GRPC_PEER_SETTINGS]
|
|
807
|
+
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
|
|
808
|
+
s->incoming_window = stream_incoming_window =
|
|
809
|
+
t->settings[GRPC_SENT_SETTINGS]
|
|
810
|
+
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
|
|
811
|
+
s->max_recv_bytes = GPR_MAX(stream_incoming_window, s->max_recv_bytes);
|
|
812
|
+
grpc_chttp2_stream_map_add(&t->stream_map, s->id, s);
|
|
813
|
+
post_destructive_reclaimer(exec_ctx, t);
|
|
814
|
+
grpc_chttp2_become_writable(exec_ctx, t, s, true, "new_stream");
|
|
1064
815
|
}
|
|
1065
816
|
/* cancel out streams that will never be started */
|
|
1066
|
-
while (
|
|
1067
|
-
grpc_chttp2_list_pop_waiting_for_concurrency(
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
817
|
+
while (t->next_stream_id >= MAX_CLIENT_STREAM_ID &&
|
|
818
|
+
grpc_chttp2_list_pop_waiting_for_concurrency(t, &s)) {
|
|
819
|
+
grpc_chttp2_cancel_stream(
|
|
820
|
+
exec_ctx, t, s,
|
|
821
|
+
grpc_error_set_int(GRPC_ERROR_CREATE("Stream IDs exhausted"),
|
|
822
|
+
GRPC_ERROR_INT_GRPC_STATUS,
|
|
823
|
+
GRPC_STATUS_UNAVAILABLE));
|
|
1073
824
|
}
|
|
1074
825
|
}
|
|
1075
826
|
|
|
827
|
+
/* Flag that this closure barrier wants stats to be updated before finishing */
|
|
1076
828
|
#define CLOSURE_BARRIER_STATS_BIT (1 << 0)
|
|
829
|
+
/* Flag that this closure barrier may be covering a write in a pollset, and so
|
|
830
|
+
we should not complete this closure until we can prove that the write got
|
|
831
|
+
scheduled */
|
|
832
|
+
#define CLOSURE_BARRIER_MAY_COVER_WRITE (1 << 1)
|
|
833
|
+
/* First bit of the reference count, stored in the high order bits (with the low
|
|
834
|
+
bits being used for flags defined above) */
|
|
1077
835
|
#define CLOSURE_BARRIER_FIRST_REF_BIT (1 << 16)
|
|
1078
836
|
|
|
1079
837
|
static grpc_closure *add_closure_barrier(grpc_closure *closure) {
|
|
@@ -1081,104 +839,216 @@ static grpc_closure *add_closure_barrier(grpc_closure *closure) {
|
|
|
1081
839
|
return closure;
|
|
1082
840
|
}
|
|
1083
841
|
|
|
1084
|
-
void
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
842
|
+
static void null_then_run_closure(grpc_exec_ctx *exec_ctx,
|
|
843
|
+
grpc_closure **closure, grpc_error *error) {
|
|
844
|
+
grpc_closure *c = *closure;
|
|
845
|
+
*closure = NULL;
|
|
846
|
+
grpc_closure_run(exec_ctx, c, error);
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
void grpc_chttp2_complete_closure_step(grpc_exec_ctx *exec_ctx,
|
|
850
|
+
grpc_chttp2_transport *t,
|
|
851
|
+
grpc_chttp2_stream *s,
|
|
852
|
+
grpc_closure **pclosure,
|
|
853
|
+
grpc_error *error, const char *desc) {
|
|
1088
854
|
grpc_closure *closure = *pclosure;
|
|
855
|
+
*pclosure = NULL;
|
|
1089
856
|
if (closure == NULL) {
|
|
1090
857
|
GRPC_ERROR_UNREF(error);
|
|
1091
858
|
return;
|
|
1092
859
|
}
|
|
1093
860
|
closure->next_data.scratch -= CLOSURE_BARRIER_FIRST_REF_BIT;
|
|
861
|
+
if (grpc_http_trace) {
|
|
862
|
+
const char *errstr = grpc_error_string(error);
|
|
863
|
+
gpr_log(GPR_DEBUG,
|
|
864
|
+
"complete_closure_step: %p refs=%d flags=0x%04x desc=%s err=%s",
|
|
865
|
+
closure,
|
|
866
|
+
(int)(closure->next_data.scratch / CLOSURE_BARRIER_FIRST_REF_BIT),
|
|
867
|
+
(int)(closure->next_data.scratch % CLOSURE_BARRIER_FIRST_REF_BIT),
|
|
868
|
+
desc, errstr);
|
|
869
|
+
grpc_error_free_string(errstr);
|
|
870
|
+
}
|
|
1094
871
|
if (error != GRPC_ERROR_NONE) {
|
|
1095
|
-
if (closure->error == GRPC_ERROR_NONE) {
|
|
1096
|
-
closure->error =
|
|
872
|
+
if (closure->error_data.error == GRPC_ERROR_NONE) {
|
|
873
|
+
closure->error_data.error =
|
|
1097
874
|
GRPC_ERROR_CREATE("Error in HTTP transport completing operation");
|
|
1098
|
-
closure->error =
|
|
1099
|
-
closure->error,
|
|
1100
|
-
|
|
875
|
+
closure->error_data.error =
|
|
876
|
+
grpc_error_set_str(closure->error_data.error,
|
|
877
|
+
GRPC_ERROR_STR_TARGET_ADDRESS, t->peer_string);
|
|
1101
878
|
}
|
|
1102
|
-
closure->error =
|
|
879
|
+
closure->error_data.error =
|
|
880
|
+
grpc_error_add_child(closure->error_data.error, error);
|
|
1103
881
|
}
|
|
1104
882
|
if (closure->next_data.scratch < CLOSURE_BARRIER_FIRST_REF_BIT) {
|
|
1105
883
|
if (closure->next_data.scratch & CLOSURE_BARRIER_STATS_BIT) {
|
|
1106
|
-
grpc_transport_move_stats(&
|
|
1107
|
-
|
|
1108
|
-
|
|
884
|
+
grpc_transport_move_stats(&s->stats, s->collecting_stats);
|
|
885
|
+
s->collecting_stats = NULL;
|
|
886
|
+
}
|
|
887
|
+
if ((t->write_state == GRPC_CHTTP2_WRITE_STATE_IDLE) ||
|
|
888
|
+
!(closure->next_data.scratch & CLOSURE_BARRIER_MAY_COVER_WRITE)) {
|
|
889
|
+
grpc_closure_run(exec_ctx, closure, closure->error_data.error);
|
|
890
|
+
} else {
|
|
891
|
+
grpc_closure_list_append(&t->run_after_write, closure,
|
|
892
|
+
closure->error_data.error);
|
|
1109
893
|
}
|
|
1110
|
-
grpc_exec_ctx_sched(exec_ctx, closure, closure->error, NULL);
|
|
1111
894
|
}
|
|
1112
|
-
*pclosure = NULL;
|
|
1113
895
|
}
|
|
1114
896
|
|
|
1115
|
-
static
|
|
1116
|
-
grpc_chttp2_transport_global *transport_global,
|
|
1117
|
-
grpc_metadata_batch *batch) {
|
|
897
|
+
static bool contains_non_ok_status(grpc_metadata_batch *batch) {
|
|
1118
898
|
grpc_linked_mdelem *l;
|
|
1119
899
|
for (l = batch->list.head; l; l = l->next) {
|
|
1120
900
|
if (l->md->key == GRPC_MDSTR_GRPC_STATUS &&
|
|
1121
901
|
l->md != GRPC_MDELEM_GRPC_STATUS_0) {
|
|
1122
|
-
return
|
|
902
|
+
return true;
|
|
1123
903
|
}
|
|
1124
904
|
}
|
|
1125
|
-
return
|
|
905
|
+
return false;
|
|
1126
906
|
}
|
|
1127
907
|
|
|
1128
|
-
static void
|
|
908
|
+
static void maybe_become_writable_due_to_send_msg(grpc_exec_ctx *exec_ctx,
|
|
909
|
+
grpc_chttp2_transport *t,
|
|
910
|
+
grpc_chttp2_stream *s) {
|
|
911
|
+
if (s->id != 0 && (!s->write_buffering ||
|
|
912
|
+
s->flow_controlled_buffer.length > t->write_buffer_size)) {
|
|
913
|
+
grpc_chttp2_become_writable(exec_ctx, t, s, true, "op.send_message");
|
|
914
|
+
}
|
|
915
|
+
}
|
|
1129
916
|
|
|
1130
|
-
static void
|
|
917
|
+
static void add_fetched_slice_locked(grpc_exec_ctx *exec_ctx,
|
|
1131
918
|
grpc_chttp2_transport *t,
|
|
1132
|
-
grpc_chttp2_stream *s
|
|
919
|
+
grpc_chttp2_stream *s) {
|
|
920
|
+
s->fetched_send_message_length +=
|
|
921
|
+
(uint32_t)GRPC_SLICE_LENGTH(s->fetching_slice);
|
|
922
|
+
grpc_slice_buffer_add(&s->flow_controlled_buffer, s->fetching_slice);
|
|
923
|
+
maybe_become_writable_due_to_send_msg(exec_ctx, t, s);
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
static void continue_fetching_send_locked(grpc_exec_ctx *exec_ctx,
|
|
927
|
+
grpc_chttp2_transport *t,
|
|
928
|
+
grpc_chttp2_stream *s) {
|
|
929
|
+
for (;;) {
|
|
930
|
+
if (s->fetching_send_message == NULL) {
|
|
931
|
+
/* Stream was cancelled before message fetch completed */
|
|
932
|
+
abort(); /* TODO(ctiller): what cleanup here? */
|
|
933
|
+
return; /* early out */
|
|
934
|
+
}
|
|
935
|
+
if (s->fetched_send_message_length == s->fetching_send_message->length) {
|
|
936
|
+
int64_t notify_offset = s->next_message_end_offset;
|
|
937
|
+
if (notify_offset <= s->flow_controlled_bytes_written) {
|
|
938
|
+
grpc_chttp2_complete_closure_step(
|
|
939
|
+
exec_ctx, t, s, &s->fetching_send_message_finished, GRPC_ERROR_NONE,
|
|
940
|
+
"fetching_send_message_finished");
|
|
941
|
+
} else {
|
|
942
|
+
grpc_chttp2_write_cb *cb = t->write_cb_pool;
|
|
943
|
+
if (cb == NULL) {
|
|
944
|
+
cb = gpr_malloc(sizeof(*cb));
|
|
945
|
+
} else {
|
|
946
|
+
t->write_cb_pool = cb->next;
|
|
947
|
+
}
|
|
948
|
+
cb->call_at_byte = notify_offset;
|
|
949
|
+
cb->closure = s->fetching_send_message_finished;
|
|
950
|
+
s->fetching_send_message_finished = NULL;
|
|
951
|
+
cb->next = s->on_write_finished_cbs;
|
|
952
|
+
s->on_write_finished_cbs = cb;
|
|
953
|
+
}
|
|
954
|
+
s->fetching_send_message = NULL;
|
|
955
|
+
return; /* early out */
|
|
956
|
+
} else if (grpc_byte_stream_next(exec_ctx, s->fetching_send_message,
|
|
957
|
+
&s->fetching_slice, UINT32_MAX,
|
|
958
|
+
&s->complete_fetch)) {
|
|
959
|
+
add_fetched_slice_locked(exec_ctx, t, s);
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
static void complete_fetch_locked(grpc_exec_ctx *exec_ctx, void *gs,
|
|
965
|
+
grpc_error *error) {
|
|
966
|
+
grpc_chttp2_stream *s = gs;
|
|
967
|
+
grpc_chttp2_transport *t = s->t;
|
|
968
|
+
if (error == GRPC_ERROR_NONE) {
|
|
969
|
+
add_fetched_slice_locked(exec_ctx, t, s);
|
|
970
|
+
continue_fetching_send_locked(exec_ctx, t, s);
|
|
971
|
+
} else {
|
|
972
|
+
/* TODO(ctiller): what to do here */
|
|
973
|
+
abort();
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
static void do_nothing(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {}
|
|
978
|
+
|
|
979
|
+
static void log_metadata(const grpc_metadata_batch *md_batch, uint32_t id,
|
|
980
|
+
bool is_client, bool is_initial) {
|
|
981
|
+
for (grpc_linked_mdelem *md = md_batch->list.head; md != md_batch->list.tail;
|
|
982
|
+
md = md->next) {
|
|
983
|
+
gpr_log(GPR_INFO, "HTTP:%d:%s:%s: %s: %s", id, is_initial ? "HDR" : "TRL",
|
|
984
|
+
is_client ? "CLI" : "SVR", grpc_mdstr_as_c_string(md->md->key),
|
|
985
|
+
grpc_mdstr_as_c_string(md->md->value));
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
|
|
990
|
+
grpc_error *error_ignored) {
|
|
1133
991
|
GPR_TIMER_BEGIN("perform_stream_op_locked", 0);
|
|
1134
992
|
|
|
1135
993
|
grpc_transport_stream_op *op = stream_op;
|
|
1136
|
-
|
|
1137
|
-
|
|
994
|
+
grpc_chttp2_transport *t = op->transport_private.args[0];
|
|
995
|
+
grpc_chttp2_stream *s = op->transport_private.args[1];
|
|
996
|
+
|
|
997
|
+
if (grpc_http_trace) {
|
|
998
|
+
char *str = grpc_transport_stream_op_string(op);
|
|
999
|
+
gpr_log(GPR_DEBUG, "perform_stream_op_locked: %s; on_complete = %p", str,
|
|
1000
|
+
op->on_complete);
|
|
1001
|
+
gpr_free(str);
|
|
1002
|
+
if (op->send_initial_metadata) {
|
|
1003
|
+
log_metadata(op->send_initial_metadata, s->id, t->is_client, true);
|
|
1004
|
+
}
|
|
1005
|
+
if (op->send_trailing_metadata) {
|
|
1006
|
+
log_metadata(op->send_trailing_metadata, s->id, t->is_client, false);
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1138
1009
|
|
|
1139
1010
|
grpc_closure *on_complete = op->on_complete;
|
|
1140
1011
|
if (on_complete == NULL) {
|
|
1141
|
-
on_complete =
|
|
1012
|
+
on_complete =
|
|
1013
|
+
grpc_closure_create(do_nothing, NULL, grpc_schedule_on_exec_ctx);
|
|
1142
1014
|
}
|
|
1015
|
+
|
|
1143
1016
|
/* use final_data as a barrier until enqueue time; the inital counter is
|
|
1144
1017
|
dropped at the end of this function */
|
|
1145
1018
|
on_complete->next_data.scratch = CLOSURE_BARRIER_FIRST_REF_BIT;
|
|
1146
|
-
on_complete->error = GRPC_ERROR_NONE;
|
|
1019
|
+
on_complete->error_data.error = GRPC_ERROR_NONE;
|
|
1147
1020
|
|
|
1148
1021
|
if (op->collect_stats != NULL) {
|
|
1149
|
-
GPR_ASSERT(
|
|
1150
|
-
|
|
1022
|
+
GPR_ASSERT(s->collecting_stats == NULL);
|
|
1023
|
+
s->collecting_stats = op->collect_stats;
|
|
1151
1024
|
on_complete->next_data.scratch |= CLOSURE_BARRIER_STATS_BIT;
|
|
1152
1025
|
}
|
|
1153
1026
|
|
|
1154
1027
|
if (op->cancel_error != GRPC_ERROR_NONE) {
|
|
1155
|
-
|
|
1156
|
-
GRPC_ERROR_REF(op->cancel_error));
|
|
1028
|
+
grpc_chttp2_cancel_stream(exec_ctx, t, s, GRPC_ERROR_REF(op->cancel_error));
|
|
1157
1029
|
}
|
|
1158
1030
|
|
|
1159
1031
|
if (op->close_error != GRPC_ERROR_NONE) {
|
|
1160
|
-
close_from_api(exec_ctx,
|
|
1161
|
-
GRPC_ERROR_REF(op->close_error));
|
|
1032
|
+
close_from_api(exec_ctx, t, s, GRPC_ERROR_REF(op->close_error));
|
|
1162
1033
|
}
|
|
1163
1034
|
|
|
1164
1035
|
if (op->send_initial_metadata != NULL) {
|
|
1165
|
-
GPR_ASSERT(
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1036
|
+
GPR_ASSERT(s->send_initial_metadata_finished == NULL);
|
|
1037
|
+
on_complete->next_data.scratch |= CLOSURE_BARRIER_MAY_COVER_WRITE;
|
|
1038
|
+
s->send_initial_metadata_finished = add_closure_barrier(on_complete);
|
|
1039
|
+
s->send_initial_metadata = op->send_initial_metadata;
|
|
1169
1040
|
const size_t metadata_size =
|
|
1170
1041
|
grpc_metadata_batch_size(op->send_initial_metadata);
|
|
1171
1042
|
const size_t metadata_peer_limit =
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
if (
|
|
1175
|
-
|
|
1176
|
-
gpr_time_min(
|
|
1177
|
-
stream_global->send_initial_metadata->deadline);
|
|
1043
|
+
t->settings[GRPC_PEER_SETTINGS]
|
|
1044
|
+
[GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE];
|
|
1045
|
+
if (t->is_client) {
|
|
1046
|
+
s->deadline =
|
|
1047
|
+
gpr_time_min(s->deadline, s->send_initial_metadata->deadline);
|
|
1178
1048
|
}
|
|
1179
1049
|
if (metadata_size > metadata_peer_limit) {
|
|
1180
|
-
|
|
1181
|
-
exec_ctx,
|
|
1050
|
+
grpc_chttp2_cancel_stream(
|
|
1051
|
+
exec_ctx, t, s,
|
|
1182
1052
|
grpc_error_set_int(
|
|
1183
1053
|
grpc_error_set_int(
|
|
1184
1054
|
grpc_error_set_int(
|
|
@@ -1188,63 +1058,85 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx,
|
|
|
1188
1058
|
GRPC_ERROR_INT_LIMIT, (intptr_t)metadata_peer_limit),
|
|
1189
1059
|
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED));
|
|
1190
1060
|
} else {
|
|
1191
|
-
if (contains_non_ok_status(
|
|
1192
|
-
|
|
1193
|
-
grpc_chttp2_list_add_check_read_ops(transport_global, stream_global);
|
|
1061
|
+
if (contains_non_ok_status(op->send_initial_metadata)) {
|
|
1062
|
+
s->seen_error = true;
|
|
1194
1063
|
}
|
|
1195
|
-
if (!
|
|
1196
|
-
if (
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1064
|
+
if (!s->write_closed) {
|
|
1065
|
+
if (t->is_client) {
|
|
1066
|
+
if (!t->closed) {
|
|
1067
|
+
GPR_ASSERT(s->id == 0);
|
|
1068
|
+
grpc_chttp2_list_add_waiting_for_concurrency(t, s);
|
|
1069
|
+
maybe_start_some_streams(exec_ctx, t);
|
|
1070
|
+
} else {
|
|
1071
|
+
grpc_chttp2_cancel_stream(exec_ctx, t, s,
|
|
1072
|
+
GRPC_ERROR_CREATE("Transport closed"));
|
|
1073
|
+
}
|
|
1201
1074
|
} else {
|
|
1202
|
-
GPR_ASSERT(
|
|
1203
|
-
grpc_chttp2_become_writable(exec_ctx,
|
|
1204
|
-
|
|
1075
|
+
GPR_ASSERT(s->id != 0);
|
|
1076
|
+
grpc_chttp2_become_writable(exec_ctx, t, s, true,
|
|
1077
|
+
"op.send_initial_metadata");
|
|
1205
1078
|
}
|
|
1206
1079
|
} else {
|
|
1207
|
-
|
|
1080
|
+
s->send_initial_metadata = NULL;
|
|
1208
1081
|
grpc_chttp2_complete_closure_step(
|
|
1209
|
-
exec_ctx,
|
|
1210
|
-
&stream_global->send_initial_metadata_finished,
|
|
1082
|
+
exec_ctx, t, s, &s->send_initial_metadata_finished,
|
|
1211
1083
|
GRPC_ERROR_CREATE(
|
|
1212
|
-
"Attempt to send initial metadata after stream was closed")
|
|
1084
|
+
"Attempt to send initial metadata after stream was closed"),
|
|
1085
|
+
"send_initial_metadata_finished");
|
|
1213
1086
|
}
|
|
1214
1087
|
}
|
|
1215
1088
|
}
|
|
1216
1089
|
|
|
1217
1090
|
if (op->send_message != NULL) {
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
if (stream_global->write_closed) {
|
|
1091
|
+
on_complete->next_data.scratch |= CLOSURE_BARRIER_MAY_COVER_WRITE;
|
|
1092
|
+
s->fetching_send_message_finished = add_closure_barrier(op->on_complete);
|
|
1093
|
+
if (s->write_closed) {
|
|
1222
1094
|
grpc_chttp2_complete_closure_step(
|
|
1223
|
-
exec_ctx,
|
|
1224
|
-
|
|
1225
|
-
|
|
1095
|
+
exec_ctx, t, s, &s->fetching_send_message_finished,
|
|
1096
|
+
GRPC_ERROR_CREATE("Attempt to send message after stream was closed"),
|
|
1097
|
+
"fetching_send_message_finished");
|
|
1226
1098
|
} else {
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1099
|
+
GPR_ASSERT(s->fetching_send_message == NULL);
|
|
1100
|
+
uint8_t *frame_hdr =
|
|
1101
|
+
grpc_slice_buffer_tiny_add(&s->flow_controlled_buffer, 5);
|
|
1102
|
+
uint32_t flags = op->send_message->flags;
|
|
1103
|
+
frame_hdr[0] = (flags & GRPC_WRITE_INTERNAL_COMPRESS) != 0;
|
|
1104
|
+
size_t len = op->send_message->length;
|
|
1105
|
+
frame_hdr[1] = (uint8_t)(len >> 24);
|
|
1106
|
+
frame_hdr[2] = (uint8_t)(len >> 16);
|
|
1107
|
+
frame_hdr[3] = (uint8_t)(len >> 8);
|
|
1108
|
+
frame_hdr[4] = (uint8_t)(len);
|
|
1109
|
+
s->fetching_send_message = op->send_message;
|
|
1110
|
+
s->fetched_send_message_length = 0;
|
|
1111
|
+
s->next_message_end_offset = s->flow_controlled_bytes_written +
|
|
1112
|
+
(int64_t)s->flow_controlled_buffer.length +
|
|
1113
|
+
(int64_t)len;
|
|
1114
|
+
s->complete_fetch_covered_by_poller = op->covered_by_poller;
|
|
1115
|
+
if (flags & GRPC_WRITE_BUFFER_HINT) {
|
|
1116
|
+
s->next_message_end_offset -= t->write_buffer_size;
|
|
1117
|
+
s->write_buffering = true;
|
|
1118
|
+
} else {
|
|
1119
|
+
s->write_buffering = false;
|
|
1231
1120
|
}
|
|
1121
|
+
continue_fetching_send_locked(exec_ctx, t, s);
|
|
1122
|
+
maybe_become_writable_due_to_send_msg(exec_ctx, t, s);
|
|
1232
1123
|
}
|
|
1233
1124
|
}
|
|
1234
1125
|
|
|
1235
1126
|
if (op->send_trailing_metadata != NULL) {
|
|
1236
|
-
GPR_ASSERT(
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1127
|
+
GPR_ASSERT(s->send_trailing_metadata_finished == NULL);
|
|
1128
|
+
on_complete->next_data.scratch |= CLOSURE_BARRIER_MAY_COVER_WRITE;
|
|
1129
|
+
s->send_trailing_metadata_finished = add_closure_barrier(on_complete);
|
|
1130
|
+
s->send_trailing_metadata = op->send_trailing_metadata;
|
|
1131
|
+
s->write_buffering = false;
|
|
1240
1132
|
const size_t metadata_size =
|
|
1241
1133
|
grpc_metadata_batch_size(op->send_trailing_metadata);
|
|
1242
1134
|
const size_t metadata_peer_limit =
|
|
1243
|
-
|
|
1244
|
-
|
|
1135
|
+
t->settings[GRPC_PEER_SETTINGS]
|
|
1136
|
+
[GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE];
|
|
1245
1137
|
if (metadata_size > metadata_peer_limit) {
|
|
1246
|
-
|
|
1247
|
-
exec_ctx,
|
|
1138
|
+
grpc_chttp2_cancel_stream(
|
|
1139
|
+
exec_ctx, t, s,
|
|
1248
1140
|
grpc_error_set_int(
|
|
1249
1141
|
grpc_error_set_int(
|
|
1250
1142
|
grpc_error_set_int(
|
|
@@ -1254,135 +1146,139 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx,
|
|
|
1254
1146
|
GRPC_ERROR_INT_LIMIT, (intptr_t)metadata_peer_limit),
|
|
1255
1147
|
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED));
|
|
1256
1148
|
} else {
|
|
1257
|
-
if (contains_non_ok_status(
|
|
1258
|
-
|
|
1259
|
-
stream_global->seen_error = true;
|
|
1260
|
-
grpc_chttp2_list_add_check_read_ops(transport_global, stream_global);
|
|
1149
|
+
if (contains_non_ok_status(op->send_trailing_metadata)) {
|
|
1150
|
+
s->seen_error = true;
|
|
1261
1151
|
}
|
|
1262
|
-
if (
|
|
1263
|
-
|
|
1152
|
+
if (s->write_closed) {
|
|
1153
|
+
s->send_trailing_metadata = NULL;
|
|
1264
1154
|
grpc_chttp2_complete_closure_step(
|
|
1265
|
-
exec_ctx,
|
|
1266
|
-
&stream_global->send_trailing_metadata_finished,
|
|
1155
|
+
exec_ctx, t, s, &s->send_trailing_metadata_finished,
|
|
1267
1156
|
grpc_metadata_batch_is_empty(op->send_trailing_metadata)
|
|
1268
1157
|
? GRPC_ERROR_NONE
|
|
1269
1158
|
: GRPC_ERROR_CREATE("Attempt to send trailing metadata after "
|
|
1270
|
-
"stream was closed")
|
|
1271
|
-
|
|
1159
|
+
"stream was closed"),
|
|
1160
|
+
"send_trailing_metadata_finished");
|
|
1161
|
+
} else if (s->id != 0) {
|
|
1272
1162
|
/* TODO(ctiller): check if there's flow control for any outstanding
|
|
1273
1163
|
bytes before going writable */
|
|
1274
|
-
grpc_chttp2_become_writable(exec_ctx,
|
|
1275
|
-
|
|
1164
|
+
grpc_chttp2_become_writable(exec_ctx, t, s, true,
|
|
1165
|
+
"op.send_trailing_metadata");
|
|
1276
1166
|
}
|
|
1277
1167
|
}
|
|
1278
1168
|
}
|
|
1279
1169
|
|
|
1280
1170
|
if (op->recv_initial_metadata != NULL) {
|
|
1281
|
-
GPR_ASSERT(
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
grpc_chttp2_list_add_check_read_ops(transport_global, stream_global);
|
|
1171
|
+
GPR_ASSERT(s->recv_initial_metadata_ready == NULL);
|
|
1172
|
+
s->recv_initial_metadata_ready = op->recv_initial_metadata_ready;
|
|
1173
|
+
s->recv_initial_metadata = op->recv_initial_metadata;
|
|
1174
|
+
grpc_chttp2_maybe_complete_recv_initial_metadata(exec_ctx, t, s);
|
|
1286
1175
|
}
|
|
1287
1176
|
|
|
1288
1177
|
if (op->recv_message != NULL) {
|
|
1289
|
-
GPR_ASSERT(
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
if (
|
|
1293
|
-
(
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
exec_ctx, transport_global, stream_global,
|
|
1297
|
-
transport_global->stream_lookahead, 0);
|
|
1178
|
+
GPR_ASSERT(s->recv_message_ready == NULL);
|
|
1179
|
+
s->recv_message_ready = op->recv_message_ready;
|
|
1180
|
+
s->recv_message = op->recv_message;
|
|
1181
|
+
if (s->id != 0 &&
|
|
1182
|
+
(s->incoming_frames.head == NULL || s->incoming_frames.head->is_tail)) {
|
|
1183
|
+
incoming_byte_stream_update_flow_control(exec_ctx, t, s,
|
|
1184
|
+
t->stream_lookahead, 0);
|
|
1298
1185
|
}
|
|
1299
|
-
|
|
1186
|
+
grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s);
|
|
1300
1187
|
}
|
|
1301
1188
|
|
|
1302
1189
|
if (op->recv_trailing_metadata != NULL) {
|
|
1303
|
-
GPR_ASSERT(
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
grpc_chttp2_list_add_check_read_ops(transport_global, stream_global);
|
|
1190
|
+
GPR_ASSERT(s->recv_trailing_metadata_finished == NULL);
|
|
1191
|
+
s->recv_trailing_metadata_finished = add_closure_barrier(on_complete);
|
|
1192
|
+
s->recv_trailing_metadata = op->recv_trailing_metadata;
|
|
1193
|
+
s->final_metadata_requested = true;
|
|
1194
|
+
grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s);
|
|
1309
1195
|
}
|
|
1310
1196
|
|
|
1311
|
-
grpc_chttp2_complete_closure_step(exec_ctx,
|
|
1312
|
-
|
|
1197
|
+
grpc_chttp2_complete_closure_step(exec_ctx, t, s, &on_complete,
|
|
1198
|
+
GRPC_ERROR_NONE, "op->on_complete");
|
|
1313
1199
|
|
|
1314
1200
|
GPR_TIMER_END("perform_stream_op_locked", 0);
|
|
1201
|
+
GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "perform_stream_op");
|
|
1315
1202
|
}
|
|
1316
1203
|
|
|
1317
1204
|
static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
|
|
1318
1205
|
grpc_stream *gs, grpc_transport_stream_op *op) {
|
|
1206
|
+
GPR_TIMER_BEGIN("perform_stream_op", 0);
|
|
1319
1207
|
grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt;
|
|
1320
1208
|
grpc_chttp2_stream *s = (grpc_chttp2_stream *)gs;
|
|
1321
|
-
|
|
1322
|
-
|
|
1209
|
+
|
|
1210
|
+
if (grpc_http_trace) {
|
|
1211
|
+
char *str = grpc_transport_stream_op_string(op);
|
|
1212
|
+
gpr_log(GPR_DEBUG, "perform_stream_op[s=%p/%d]: %s", s, s->id, str);
|
|
1213
|
+
gpr_free(str);
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
op->transport_private.args[0] = gt;
|
|
1217
|
+
op->transport_private.args[1] = gs;
|
|
1218
|
+
GRPC_CHTTP2_STREAM_REF(s, "perform_stream_op");
|
|
1219
|
+
grpc_closure_sched(
|
|
1220
|
+
exec_ctx,
|
|
1221
|
+
grpc_closure_init(
|
|
1222
|
+
&op->transport_private.closure, perform_stream_op_locked, op,
|
|
1223
|
+
grpc_combiner_scheduler(t->combiner, op->covered_by_poller)),
|
|
1224
|
+
GRPC_ERROR_NONE);
|
|
1225
|
+
GPR_TIMER_END("perform_stream_op", 0);
|
|
1323
1226
|
}
|
|
1324
1227
|
|
|
1325
1228
|
static void send_ping_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
1326
1229
|
grpc_closure *on_recv) {
|
|
1327
1230
|
grpc_chttp2_outstanding_ping *p = gpr_malloc(sizeof(*p));
|
|
1328
|
-
p->next = &t->
|
|
1231
|
+
p->next = &t->pings;
|
|
1329
1232
|
p->prev = p->next->prev;
|
|
1330
1233
|
p->prev->next = p->next->prev = p;
|
|
1331
|
-
p->id[0] = (uint8_t)((t->
|
|
1332
|
-
p->id[1] = (uint8_t)((t->
|
|
1333
|
-
p->id[2] = (uint8_t)((t->
|
|
1334
|
-
p->id[3] = (uint8_t)((t->
|
|
1335
|
-
p->id[4] = (uint8_t)((t->
|
|
1336
|
-
p->id[5] = (uint8_t)((t->
|
|
1337
|
-
p->id[6] = (uint8_t)((t->
|
|
1338
|
-
p->id[7] = (uint8_t)(t->
|
|
1234
|
+
p->id[0] = (uint8_t)((t->ping_counter >> 56) & 0xff);
|
|
1235
|
+
p->id[1] = (uint8_t)((t->ping_counter >> 48) & 0xff);
|
|
1236
|
+
p->id[2] = (uint8_t)((t->ping_counter >> 40) & 0xff);
|
|
1237
|
+
p->id[3] = (uint8_t)((t->ping_counter >> 32) & 0xff);
|
|
1238
|
+
p->id[4] = (uint8_t)((t->ping_counter >> 24) & 0xff);
|
|
1239
|
+
p->id[5] = (uint8_t)((t->ping_counter >> 16) & 0xff);
|
|
1240
|
+
p->id[6] = (uint8_t)((t->ping_counter >> 8) & 0xff);
|
|
1241
|
+
p->id[7] = (uint8_t)(t->ping_counter & 0xff);
|
|
1242
|
+
t->ping_counter++;
|
|
1339
1243
|
p->on_recv = on_recv;
|
|
1340
|
-
|
|
1341
|
-
grpc_chttp2_initiate_write(exec_ctx,
|
|
1244
|
+
grpc_slice_buffer_add(&t->qbuf, grpc_chttp2_ping_create(0, p->id));
|
|
1245
|
+
grpc_chttp2_initiate_write(exec_ctx, t, true, "send_ping");
|
|
1342
1246
|
}
|
|
1343
1247
|
|
|
1344
|
-
|
|
1345
|
-
|
|
1248
|
+
void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
1249
|
+
const uint8_t *opaque_8bytes) {
|
|
1346
1250
|
grpc_chttp2_outstanding_ping *ping;
|
|
1347
|
-
|
|
1348
|
-
for (ping = transport_global->pings.next; ping != &transport_global->pings;
|
|
1349
|
-
ping = ping->next) {
|
|
1251
|
+
for (ping = t->pings.next; ping != &t->pings; ping = ping->next) {
|
|
1350
1252
|
if (0 == memcmp(opaque_8bytes, ping->id, 8)) {
|
|
1351
|
-
|
|
1253
|
+
grpc_closure_sched(exec_ctx, ping->on_recv, GRPC_ERROR_NONE);
|
|
1352
1254
|
ping->next->prev = ping->prev;
|
|
1353
1255
|
ping->prev->next = ping->next;
|
|
1354
1256
|
gpr_free(ping);
|
|
1355
|
-
|
|
1257
|
+
return;
|
|
1356
1258
|
}
|
|
1357
1259
|
}
|
|
1260
|
+
char *msg = gpr_dump((const char *)opaque_8bytes, 8, GPR_DUMP_HEX);
|
|
1261
|
+
char *from = grpc_endpoint_get_peer(t->ep);
|
|
1262
|
+
gpr_log(GPR_DEBUG, "Unknown ping response from %s: %s", from, msg);
|
|
1263
|
+
gpr_free(from);
|
|
1264
|
+
gpr_free(msg);
|
|
1358
1265
|
}
|
|
1359
1266
|
|
|
1360
|
-
void
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1267
|
+
static void send_goaway(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
1268
|
+
grpc_chttp2_error_code error, grpc_slice data) {
|
|
1269
|
+
t->sent_goaway_state = GRPC_CHTTP2_GOAWAY_SEND_SCHEDULED;
|
|
1270
|
+
grpc_chttp2_goaway_append(t->last_new_stream_id, (uint32_t)error, data,
|
|
1271
|
+
&t->qbuf);
|
|
1272
|
+
grpc_chttp2_initiate_write(exec_ctx, t, false, "goaway_sent");
|
|
1366
1273
|
}
|
|
1367
1274
|
|
|
1368
1275
|
static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx,
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
void *stream_op) {
|
|
1276
|
+
void *stream_op,
|
|
1277
|
+
grpc_error *error_ignored) {
|
|
1372
1278
|
grpc_transport_op *op = stream_op;
|
|
1279
|
+
grpc_chttp2_transport *t = op->transport_private.args[0];
|
|
1373
1280
|
grpc_error *close_transport = op->disconnect_with_error;
|
|
1374
1281
|
|
|
1375
|
-
/* If there's a set_accept_stream ensure that we're not parsing
|
|
1376
|
-
to avoid changing things out from underneath */
|
|
1377
|
-
if (t->executor.parsing_active && op->set_accept_stream) {
|
|
1378
|
-
GPR_ASSERT(t->post_parsing_op == NULL);
|
|
1379
|
-
t->post_parsing_op = gpr_malloc(sizeof(*op));
|
|
1380
|
-
memcpy(t->post_parsing_op, op, sizeof(*op));
|
|
1381
|
-
return;
|
|
1382
|
-
}
|
|
1383
|
-
|
|
1384
|
-
grpc_exec_ctx_sched(exec_ctx, op->on_consumed, GRPC_ERROR_NONE, NULL);
|
|
1385
|
-
|
|
1386
1282
|
if (op->on_connectivity_state_change != NULL) {
|
|
1387
1283
|
grpc_connectivity_state_notify_on_state_change(
|
|
1388
1284
|
exec_ctx, &t->channel_callback.state_tracker, op->connectivity_state,
|
|
@@ -1390,15 +1286,9 @@ static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx,
|
|
|
1390
1286
|
}
|
|
1391
1287
|
|
|
1392
1288
|
if (op->send_goaway) {
|
|
1393
|
-
t
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
(uint32_t)grpc_chttp2_grpc_status_to_http2_error(op->goaway_status),
|
|
1397
|
-
gpr_slice_ref(*op->goaway_message), &t->global.qbuf);
|
|
1398
|
-
close_transport = grpc_chttp2_has_streams(t)
|
|
1399
|
-
? GRPC_ERROR_NONE
|
|
1400
|
-
: GRPC_ERROR_CREATE("GOAWAY sent");
|
|
1401
|
-
grpc_chttp2_initiate_write(exec_ctx, &t->global, false, "goaway_sent");
|
|
1289
|
+
send_goaway(exec_ctx, t,
|
|
1290
|
+
grpc_chttp2_grpc_status_to_http2_error(op->goaway_status),
|
|
1291
|
+
grpc_slice_ref_internal(*op->goaway_message));
|
|
1402
1292
|
}
|
|
1403
1293
|
|
|
1404
1294
|
if (op->set_accept_stream) {
|
|
@@ -1408,11 +1298,11 @@ static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx,
|
|
|
1408
1298
|
}
|
|
1409
1299
|
|
|
1410
1300
|
if (op->bind_pollset) {
|
|
1411
|
-
|
|
1301
|
+
grpc_endpoint_add_to_pollset(exec_ctx, t->ep, op->bind_pollset);
|
|
1412
1302
|
}
|
|
1413
1303
|
|
|
1414
1304
|
if (op->bind_pollset_set) {
|
|
1415
|
-
|
|
1305
|
+
grpc_endpoint_add_to_pollset_set(exec_ctx, t->ep, op->bind_pollset_set);
|
|
1416
1306
|
}
|
|
1417
1307
|
|
|
1418
1308
|
if (op->send_ping) {
|
|
@@ -1422,144 +1312,133 @@ static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx,
|
|
|
1422
1312
|
if (close_transport != GRPC_ERROR_NONE) {
|
|
1423
1313
|
close_transport_locked(exec_ctx, t, close_transport);
|
|
1424
1314
|
}
|
|
1315
|
+
|
|
1316
|
+
grpc_closure_run(exec_ctx, op->on_consumed, GRPC_ERROR_NONE);
|
|
1317
|
+
|
|
1318
|
+
GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "transport_op");
|
|
1425
1319
|
}
|
|
1426
1320
|
|
|
1427
1321
|
static void perform_transport_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
|
|
1428
1322
|
grpc_transport_op *op) {
|
|
1429
1323
|
grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt;
|
|
1430
|
-
|
|
1431
|
-
|
|
1324
|
+
char *msg = grpc_transport_op_string(op);
|
|
1325
|
+
gpr_free(msg);
|
|
1326
|
+
op->transport_private.args[0] = gt;
|
|
1327
|
+
GRPC_CHTTP2_REF_TRANSPORT(t, "transport_op");
|
|
1328
|
+
grpc_closure_sched(
|
|
1329
|
+
exec_ctx, grpc_closure_init(&op->transport_private.closure,
|
|
1330
|
+
perform_transport_op_locked, op,
|
|
1331
|
+
grpc_combiner_scheduler(t->combiner, false)),
|
|
1332
|
+
GRPC_ERROR_NONE);
|
|
1432
1333
|
}
|
|
1433
1334
|
|
|
1434
1335
|
/*******************************************************************************
|
|
1435
1336
|
* INPUT PROCESSING - GENERAL
|
|
1436
1337
|
*/
|
|
1437
1338
|
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1339
|
+
void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_exec_ctx *exec_ctx,
|
|
1340
|
+
grpc_chttp2_transport *t,
|
|
1341
|
+
grpc_chttp2_stream *s) {
|
|
1441
1342
|
grpc_byte_stream *bs;
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
if (
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
&stream_global->incoming_frames)) != NULL) {
|
|
1449
|
-
incoming_byte_stream_destroy_locked(exec_ctx, NULL, NULL, bs);
|
|
1450
|
-
}
|
|
1451
|
-
if (stream_global->exceeded_metadata_size) {
|
|
1452
|
-
cancel_from_api(
|
|
1453
|
-
exec_ctx, transport_global, stream_global,
|
|
1454
|
-
grpc_error_set_int(
|
|
1455
|
-
GRPC_ERROR_CREATE(
|
|
1456
|
-
"received initial metadata size exceeds limit"),
|
|
1457
|
-
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED));
|
|
1458
|
-
}
|
|
1343
|
+
if (s->recv_initial_metadata_ready != NULL &&
|
|
1344
|
+
s->published_metadata[0] != GRPC_METADATA_NOT_PUBLISHED) {
|
|
1345
|
+
if (s->seen_error) {
|
|
1346
|
+
while ((bs = grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames)) !=
|
|
1347
|
+
NULL) {
|
|
1348
|
+
incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE);
|
|
1459
1349
|
}
|
|
1460
|
-
grpc_chttp2_incoming_metadata_buffer_publish(
|
|
1461
|
-
&stream_global->received_initial_metadata,
|
|
1462
|
-
stream_global->recv_initial_metadata);
|
|
1463
|
-
grpc_exec_ctx_sched(exec_ctx, stream_global->recv_initial_metadata_ready,
|
|
1464
|
-
GRPC_ERROR_NONE, NULL);
|
|
1465
|
-
stream_global->recv_initial_metadata_ready = NULL;
|
|
1466
1350
|
}
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
grpc_exec_ctx_sched(exec_ctx, stream_global->recv_message_ready,
|
|
1484
|
-
GRPC_ERROR_NONE, NULL);
|
|
1485
|
-
stream_global->recv_message_ready = NULL;
|
|
1486
|
-
}
|
|
1351
|
+
grpc_chttp2_incoming_metadata_buffer_publish(&s->metadata_buffer[0],
|
|
1352
|
+
s->recv_initial_metadata);
|
|
1353
|
+
null_then_run_closure(exec_ctx, &s->recv_initial_metadata_ready,
|
|
1354
|
+
GRPC_ERROR_NONE);
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1357
|
+
|
|
1358
|
+
void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx,
|
|
1359
|
+
grpc_chttp2_transport *t,
|
|
1360
|
+
grpc_chttp2_stream *s) {
|
|
1361
|
+
grpc_byte_stream *bs;
|
|
1362
|
+
if (s->recv_message_ready != NULL) {
|
|
1363
|
+
while (s->final_metadata_requested && s->seen_error &&
|
|
1364
|
+
(bs = grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames)) !=
|
|
1365
|
+
NULL) {
|
|
1366
|
+
incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE);
|
|
1487
1367
|
}
|
|
1488
|
-
if (
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1368
|
+
if (s->incoming_frames.head != NULL) {
|
|
1369
|
+
*s->recv_message =
|
|
1370
|
+
grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames);
|
|
1371
|
+
GPR_ASSERT(*s->recv_message != NULL);
|
|
1372
|
+
null_then_run_closure(exec_ctx, &s->recv_message_ready, GRPC_ERROR_NONE);
|
|
1373
|
+
} else if (s->published_metadata[1] != GRPC_METADATA_NOT_PUBLISHED) {
|
|
1374
|
+
*s->recv_message = NULL;
|
|
1375
|
+
null_then_run_closure(exec_ctx, &s->recv_message_ready, GRPC_ERROR_NONE);
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1378
|
+
}
|
|
1379
|
+
|
|
1380
|
+
void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_exec_ctx *exec_ctx,
|
|
1381
|
+
grpc_chttp2_transport *t,
|
|
1382
|
+
grpc_chttp2_stream *s) {
|
|
1383
|
+
grpc_byte_stream *bs;
|
|
1384
|
+
grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s);
|
|
1385
|
+
if (s->recv_trailing_metadata_finished != NULL && s->read_closed &&
|
|
1386
|
+
s->write_closed) {
|
|
1387
|
+
if (s->seen_error) {
|
|
1388
|
+
while ((bs = grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames)) !=
|
|
1389
|
+
NULL) {
|
|
1390
|
+
incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE);
|
|
1511
1391
|
}
|
|
1512
1392
|
}
|
|
1393
|
+
if (s->all_incoming_byte_streams_finished &&
|
|
1394
|
+
s->recv_trailing_metadata_finished != NULL) {
|
|
1395
|
+
grpc_chttp2_incoming_metadata_buffer_publish(&s->metadata_buffer[1],
|
|
1396
|
+
s->recv_trailing_metadata);
|
|
1397
|
+
grpc_chttp2_complete_closure_step(
|
|
1398
|
+
exec_ctx, t, s, &s->recv_trailing_metadata_finished, GRPC_ERROR_NONE,
|
|
1399
|
+
"recv_trailing_metadata_finished");
|
|
1400
|
+
}
|
|
1513
1401
|
}
|
|
1514
1402
|
}
|
|
1515
1403
|
|
|
1516
|
-
static void decrement_active_streams_locked(
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
if ((
|
|
1520
|
-
|
|
1521
|
-
grpc_chttp2_list_add_check_read_ops(transport_global, stream_global);
|
|
1404
|
+
static void decrement_active_streams_locked(grpc_exec_ctx *exec_ctx,
|
|
1405
|
+
grpc_chttp2_transport *t,
|
|
1406
|
+
grpc_chttp2_stream *s) {
|
|
1407
|
+
if ((s->all_incoming_byte_streams_finished = gpr_unref(&s->active_streams))) {
|
|
1408
|
+
grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s);
|
|
1522
1409
|
}
|
|
1523
1410
|
}
|
|
1524
1411
|
|
|
1525
1412
|
static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
1526
1413
|
uint32_t id, grpc_error *error) {
|
|
1527
|
-
|
|
1528
|
-
grpc_chttp2_stream *s =
|
|
1529
|
-
grpc_chttp2_stream_map_delete(&t->parsing_stream_map, id);
|
|
1530
|
-
if (!s) {
|
|
1531
|
-
s = grpc_chttp2_stream_map_delete(&t->new_stream_map, id);
|
|
1532
|
-
}
|
|
1414
|
+
grpc_chttp2_stream *s = grpc_chttp2_stream_map_delete(&t->stream_map, id);
|
|
1533
1415
|
GPR_ASSERT(s);
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
t
|
|
1537
|
-
grpc_chttp2_parsing_become_skip_parser(exec_ctx, &t->parsing);
|
|
1416
|
+
if (t->incoming_stream == s) {
|
|
1417
|
+
t->incoming_stream = NULL;
|
|
1418
|
+
grpc_chttp2_parsing_become_skip_parser(exec_ctx, t);
|
|
1538
1419
|
}
|
|
1539
|
-
if (s->
|
|
1420
|
+
if (s->data_parser.parsing_frame != NULL) {
|
|
1540
1421
|
grpc_chttp2_incoming_byte_stream_finished(
|
|
1541
|
-
exec_ctx, s->
|
|
1542
|
-
|
|
1543
|
-
s->parsing.data_parser.parsing_frame = NULL;
|
|
1422
|
+
exec_ctx, s->data_parser.parsing_frame, GRPC_ERROR_REF(error));
|
|
1423
|
+
s->data_parser.parsing_frame = NULL;
|
|
1544
1424
|
}
|
|
1545
1425
|
|
|
1546
|
-
if (
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1426
|
+
if (grpc_chttp2_stream_map_size(&t->stream_map) == 0) {
|
|
1427
|
+
post_benign_reclaimer(exec_ctx, t);
|
|
1428
|
+
if (t->sent_goaway_state == GRPC_CHTTP2_GOAWAY_SENT) {
|
|
1429
|
+
close_transport_locked(
|
|
1430
|
+
exec_ctx, t,
|
|
1431
|
+
GRPC_ERROR_CREATE_REFERENCING(
|
|
1432
|
+
"Last stream closed after sending GOAWAY", &error, 1));
|
|
1433
|
+
}
|
|
1550
1434
|
}
|
|
1551
|
-
if (grpc_chttp2_list_remove_writable_stream(
|
|
1552
|
-
GRPC_CHTTP2_STREAM_UNREF(exec_ctx,
|
|
1435
|
+
if (grpc_chttp2_list_remove_writable_stream(t, s)) {
|
|
1436
|
+
GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing:remove_stream");
|
|
1553
1437
|
}
|
|
1554
1438
|
|
|
1555
|
-
new_stream_count = grpc_chttp2_stream_map_size(&t->parsing_stream_map) +
|
|
1556
|
-
grpc_chttp2_stream_map_size(&t->new_stream_map);
|
|
1557
|
-
GPR_ASSERT(new_stream_count <= UINT32_MAX);
|
|
1558
|
-
if (new_stream_count != t->global.concurrent_stream_count) {
|
|
1559
|
-
t->global.concurrent_stream_count = (uint32_t)new_stream_count;
|
|
1560
|
-
maybe_start_some_streams(exec_ctx, &t->global);
|
|
1561
|
-
}
|
|
1562
1439
|
GRPC_ERROR_UNREF(error);
|
|
1440
|
+
|
|
1441
|
+
maybe_start_some_streams(exec_ctx, t);
|
|
1563
1442
|
}
|
|
1564
1443
|
|
|
1565
1444
|
static void status_codes_from_error(grpc_error *error, gpr_timespec deadline,
|
|
@@ -1589,23 +1468,20 @@ static void status_codes_from_error(grpc_error *error, gpr_timespec deadline,
|
|
|
1589
1468
|
}
|
|
1590
1469
|
}
|
|
1591
1470
|
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
if (!stream_global->read_closed || !stream_global->write_closed) {
|
|
1471
|
+
void grpc_chttp2_cancel_stream(grpc_exec_ctx *exec_ctx,
|
|
1472
|
+
grpc_chttp2_transport *t, grpc_chttp2_stream *s,
|
|
1473
|
+
grpc_error *due_to_error) {
|
|
1474
|
+
if (!s->read_closed || !s->write_closed) {
|
|
1597
1475
|
grpc_status_code grpc_status;
|
|
1598
1476
|
grpc_chttp2_error_code http_error;
|
|
1599
|
-
status_codes_from_error(due_to_error,
|
|
1477
|
+
status_codes_from_error(due_to_error, s->deadline, &http_error,
|
|
1600
1478
|
&grpc_status);
|
|
1601
1479
|
|
|
1602
|
-
if (
|
|
1603
|
-
|
|
1604
|
-
&
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
grpc_chttp2_initiate_write(exec_ctx, transport_global, false,
|
|
1608
|
-
"rst_stream");
|
|
1480
|
+
if (s->id != 0) {
|
|
1481
|
+
grpc_slice_buffer_add(
|
|
1482
|
+
&t->qbuf, grpc_chttp2_rst_stream_create(s->id, (uint32_t)http_error,
|
|
1483
|
+
&s->stats.outgoing));
|
|
1484
|
+
grpc_chttp2_initiate_write(exec_ctx, t, false, "rst_stream");
|
|
1609
1485
|
}
|
|
1610
1486
|
|
|
1611
1487
|
const char *msg =
|
|
@@ -1615,26 +1491,22 @@ static void cancel_from_api(grpc_exec_ctx *exec_ctx,
|
|
|
1615
1491
|
free_msg = true;
|
|
1616
1492
|
msg = grpc_error_string(due_to_error);
|
|
1617
1493
|
}
|
|
1618
|
-
|
|
1619
|
-
grpc_chttp2_fake_status(exec_ctx,
|
|
1620
|
-
grpc_status, &msg_slice);
|
|
1494
|
+
grpc_slice msg_slice = grpc_slice_from_copied_string(msg);
|
|
1495
|
+
grpc_chttp2_fake_status(exec_ctx, t, s, grpc_status, &msg_slice);
|
|
1621
1496
|
if (free_msg) grpc_error_free_string(msg);
|
|
1622
1497
|
}
|
|
1623
|
-
if (due_to_error != GRPC_ERROR_NONE && !
|
|
1624
|
-
|
|
1625
|
-
|
|
1498
|
+
if (due_to_error != GRPC_ERROR_NONE && !s->seen_error) {
|
|
1499
|
+
s->seen_error = true;
|
|
1500
|
+
grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s);
|
|
1626
1501
|
}
|
|
1627
|
-
grpc_chttp2_mark_stream_closed(exec_ctx,
|
|
1628
|
-
1, due_to_error);
|
|
1502
|
+
grpc_chttp2_mark_stream_closed(exec_ctx, t, s, 1, 1, due_to_error);
|
|
1629
1503
|
}
|
|
1630
1504
|
|
|
1631
|
-
void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx,
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
grpc_status_code status, gpr_slice *slice) {
|
|
1505
|
+
void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
1506
|
+
grpc_chttp2_stream *s, grpc_status_code status,
|
|
1507
|
+
grpc_slice *slice) {
|
|
1635
1508
|
if (status != GRPC_STATUS_OK) {
|
|
1636
|
-
|
|
1637
|
-
grpc_chttp2_list_add_check_read_ops(transport_global, stream_global);
|
|
1509
|
+
s->seen_error = true;
|
|
1638
1510
|
}
|
|
1639
1511
|
/* stream_global->recv_trailing_metadata_finished gives us a
|
|
1640
1512
|
last chance replacement: we've received trailing metadata,
|
|
@@ -1642,26 +1514,27 @@ void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx,
|
|
|
1642
1514
|
to the upper layers - drop what we've got, and then publish
|
|
1643
1515
|
what we want - which is safe because we haven't told anyone
|
|
1644
1516
|
about the metadata yet */
|
|
1645
|
-
if (
|
|
1646
|
-
|
|
1517
|
+
if (s->published_metadata[1] == GRPC_METADATA_NOT_PUBLISHED ||
|
|
1518
|
+
s->recv_trailing_metadata_finished != NULL) {
|
|
1647
1519
|
char status_string[GPR_LTOA_MIN_BUFSIZE];
|
|
1648
1520
|
gpr_ltoa(status, status_string);
|
|
1649
1521
|
grpc_chttp2_incoming_metadata_buffer_add(
|
|
1650
|
-
&
|
|
1651
|
-
|
|
1652
|
-
|
|
1522
|
+
&s->metadata_buffer[1], grpc_mdelem_from_metadata_strings(
|
|
1523
|
+
exec_ctx, GRPC_MDSTR_GRPC_STATUS,
|
|
1524
|
+
grpc_mdstr_from_string(status_string)));
|
|
1653
1525
|
if (slice) {
|
|
1654
1526
|
grpc_chttp2_incoming_metadata_buffer_add(
|
|
1655
|
-
&
|
|
1527
|
+
&s->metadata_buffer[1],
|
|
1656
1528
|
grpc_mdelem_from_metadata_strings(
|
|
1657
|
-
GRPC_MDSTR_GRPC_MESSAGE,
|
|
1658
|
-
grpc_mdstr_from_slice(
|
|
1529
|
+
exec_ctx, GRPC_MDSTR_GRPC_MESSAGE,
|
|
1530
|
+
grpc_mdstr_from_slice(exec_ctx,
|
|
1531
|
+
grpc_slice_ref_internal(*slice))));
|
|
1659
1532
|
}
|
|
1660
|
-
|
|
1661
|
-
|
|
1533
|
+
s->published_metadata[1] = GRPC_METADATA_SYNTHESIZED_FROM_FAKE;
|
|
1534
|
+
grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s);
|
|
1662
1535
|
}
|
|
1663
1536
|
if (slice) {
|
|
1664
|
-
|
|
1537
|
+
grpc_slice_unref_internal(exec_ctx, *slice);
|
|
1665
1538
|
}
|
|
1666
1539
|
}
|
|
1667
1540
|
|
|
@@ -1676,112 +1549,118 @@ static void add_error(grpc_error *error, grpc_error **refs, size_t *nrefs) {
|
|
|
1676
1549
|
++*nrefs;
|
|
1677
1550
|
}
|
|
1678
1551
|
|
|
1679
|
-
static grpc_error *removal_error(grpc_error *extra_error,
|
|
1680
|
-
|
|
1552
|
+
static grpc_error *removal_error(grpc_error *extra_error, grpc_chttp2_stream *s,
|
|
1553
|
+
const char *master_error_msg) {
|
|
1681
1554
|
grpc_error *refs[3];
|
|
1682
1555
|
size_t nrefs = 0;
|
|
1683
|
-
add_error(
|
|
1684
|
-
add_error(
|
|
1556
|
+
add_error(s->read_closed_error, refs, &nrefs);
|
|
1557
|
+
add_error(s->write_closed_error, refs, &nrefs);
|
|
1685
1558
|
add_error(extra_error, refs, &nrefs);
|
|
1686
1559
|
grpc_error *error = GRPC_ERROR_NONE;
|
|
1687
1560
|
if (nrefs > 0) {
|
|
1688
|
-
error = GRPC_ERROR_CREATE_REFERENCING(
|
|
1689
|
-
nrefs);
|
|
1561
|
+
error = GRPC_ERROR_CREATE_REFERENCING(master_error_msg, refs, nrefs);
|
|
1690
1562
|
}
|
|
1691
1563
|
GRPC_ERROR_UNREF(extra_error);
|
|
1692
1564
|
return error;
|
|
1693
1565
|
}
|
|
1694
1566
|
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1567
|
+
void grpc_chttp2_fail_pending_writes(grpc_exec_ctx *exec_ctx,
|
|
1568
|
+
grpc_chttp2_transport *t,
|
|
1569
|
+
grpc_chttp2_stream *s, grpc_error *error) {
|
|
1570
|
+
error =
|
|
1571
|
+
removal_error(error, s, "Pending writes failed due to stream closure");
|
|
1572
|
+
s->send_initial_metadata = NULL;
|
|
1701
1573
|
grpc_chttp2_complete_closure_step(
|
|
1702
|
-
exec_ctx,
|
|
1703
|
-
|
|
1574
|
+
exec_ctx, t, s, &s->send_initial_metadata_finished, GRPC_ERROR_REF(error),
|
|
1575
|
+
"send_initial_metadata_finished");
|
|
1576
|
+
|
|
1577
|
+
s->send_trailing_metadata = NULL;
|
|
1578
|
+
grpc_chttp2_complete_closure_step(
|
|
1579
|
+
exec_ctx, t, s, &s->send_trailing_metadata_finished,
|
|
1580
|
+
GRPC_ERROR_REF(error), "send_trailing_metadata_finished");
|
|
1581
|
+
|
|
1582
|
+
s->fetching_send_message = NULL;
|
|
1704
1583
|
grpc_chttp2_complete_closure_step(
|
|
1705
|
-
exec_ctx,
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1584
|
+
exec_ctx, t, s, &s->fetching_send_message_finished, GRPC_ERROR_REF(error),
|
|
1585
|
+
"fetching_send_message_finished");
|
|
1586
|
+
while (s->on_write_finished_cbs) {
|
|
1587
|
+
grpc_chttp2_write_cb *cb = s->on_write_finished_cbs;
|
|
1588
|
+
s->on_write_finished_cbs = cb->next;
|
|
1589
|
+
grpc_chttp2_complete_closure_step(exec_ctx, t, s, &cb->closure,
|
|
1590
|
+
GRPC_ERROR_REF(error),
|
|
1591
|
+
"on_write_finished_cb");
|
|
1592
|
+
cb->next = t->write_cb_pool;
|
|
1593
|
+
t->write_cb_pool = cb;
|
|
1594
|
+
}
|
|
1595
|
+
GRPC_ERROR_UNREF(error);
|
|
1710
1596
|
}
|
|
1711
1597
|
|
|
1712
|
-
void grpc_chttp2_mark_stream_closed(
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
if (
|
|
1598
|
+
void grpc_chttp2_mark_stream_closed(grpc_exec_ctx *exec_ctx,
|
|
1599
|
+
grpc_chttp2_transport *t,
|
|
1600
|
+
grpc_chttp2_stream *s, int close_reads,
|
|
1601
|
+
int close_writes, grpc_error *error) {
|
|
1602
|
+
if (s->read_closed && s->write_closed) {
|
|
1717
1603
|
/* already closed */
|
|
1718
1604
|
GRPC_ERROR_UNREF(error);
|
|
1719
1605
|
return;
|
|
1720
1606
|
}
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
}
|
|
1729
|
-
if (close_writes && !stream_global->write_closed) {
|
|
1730
|
-
stream_global->write_closed_error = GRPC_ERROR_REF(error);
|
|
1731
|
-
stream_global->write_closed = true;
|
|
1732
|
-
if (TRANSPORT_FROM_GLOBAL(transport_global)->executor.write_state !=
|
|
1733
|
-
GRPC_CHTTP2_WRITING_INACTIVE) {
|
|
1734
|
-
GRPC_CHTTP2_STREAM_REF(stream_global, "finish_writes");
|
|
1735
|
-
grpc_chttp2_list_add_closed_waiting_for_writing(transport_global,
|
|
1736
|
-
stream_global);
|
|
1737
|
-
} else {
|
|
1738
|
-
fail_pending_writes(exec_ctx, transport_global, stream_global,
|
|
1739
|
-
GRPC_ERROR_REF(error));
|
|
1607
|
+
if (close_reads && !s->read_closed) {
|
|
1608
|
+
s->read_closed_error = GRPC_ERROR_REF(error);
|
|
1609
|
+
s->read_closed = true;
|
|
1610
|
+
for (int i = 0; i < 2; i++) {
|
|
1611
|
+
if (s->published_metadata[i] == GRPC_METADATA_NOT_PUBLISHED) {
|
|
1612
|
+
s->published_metadata[i] = GPRC_METADATA_PUBLISHED_AT_CLOSE;
|
|
1613
|
+
}
|
|
1740
1614
|
}
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1615
|
+
decrement_active_streams_locked(exec_ctx, t, s);
|
|
1616
|
+
grpc_chttp2_maybe_complete_recv_initial_metadata(exec_ctx, t, s);
|
|
1617
|
+
grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s);
|
|
1618
|
+
grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s);
|
|
1619
|
+
}
|
|
1620
|
+
if (close_writes && !s->write_closed) {
|
|
1621
|
+
s->write_closed_error = GRPC_ERROR_REF(error);
|
|
1622
|
+
s->write_closed = true;
|
|
1623
|
+
grpc_chttp2_fail_pending_writes(exec_ctx, t, s, GRPC_ERROR_REF(error));
|
|
1624
|
+
grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s);
|
|
1625
|
+
}
|
|
1626
|
+
if (s->read_closed && s->write_closed) {
|
|
1627
|
+
if (s->id != 0) {
|
|
1628
|
+
remove_stream(exec_ctx, t, s->id,
|
|
1629
|
+
removal_error(GRPC_ERROR_REF(error), s, "Stream removed"));
|
|
1747
1630
|
} else {
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
stream_global->id,
|
|
1751
|
-
removal_error(GRPC_ERROR_REF(error), stream_global));
|
|
1752
|
-
}
|
|
1753
|
-
GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2");
|
|
1631
|
+
/* Purge streams waiting on concurrency still waiting for id assignment */
|
|
1632
|
+
grpc_chttp2_list_remove_waiting_for_concurrency(t, s);
|
|
1754
1633
|
}
|
|
1634
|
+
GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2");
|
|
1755
1635
|
}
|
|
1756
1636
|
GRPC_ERROR_UNREF(error);
|
|
1757
1637
|
}
|
|
1758
1638
|
|
|
1759
|
-
static void close_from_api(grpc_exec_ctx *exec_ctx,
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
gpr_slice status_hdr;
|
|
1765
|
-
gpr_slice message_pfx;
|
|
1639
|
+
static void close_from_api(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
1640
|
+
grpc_chttp2_stream *s, grpc_error *error) {
|
|
1641
|
+
grpc_slice hdr;
|
|
1642
|
+
grpc_slice status_hdr;
|
|
1643
|
+
grpc_slice message_pfx;
|
|
1766
1644
|
uint8_t *p;
|
|
1767
1645
|
uint32_t len = 0;
|
|
1768
1646
|
grpc_status_code grpc_status;
|
|
1769
1647
|
grpc_chttp2_error_code http_error;
|
|
1770
|
-
status_codes_from_error(error,
|
|
1771
|
-
&grpc_status);
|
|
1648
|
+
status_codes_from_error(error, s->deadline, &http_error, &grpc_status);
|
|
1772
1649
|
|
|
1773
1650
|
GPR_ASSERT(grpc_status >= 0 && (int)grpc_status < 100);
|
|
1774
1651
|
|
|
1775
|
-
if (
|
|
1652
|
+
if (s->id != 0 && !t->is_client) {
|
|
1776
1653
|
/* Hand roll a header block.
|
|
1777
|
-
This is unnecessarily ugly - at some point we should find a more
|
|
1654
|
+
This is unnecessarily ugly - at some point we should find a more
|
|
1655
|
+
elegant
|
|
1778
1656
|
solution.
|
|
1779
|
-
It's complicated by the fact that our send machinery would be dead by
|
|
1657
|
+
It's complicated by the fact that our send machinery would be dead by
|
|
1658
|
+
the
|
|
1780
1659
|
time we got around to sending this, so instead we ignore HPACK
|
|
1781
1660
|
compression
|
|
1782
1661
|
and just write the uncompressed bytes onto the wire. */
|
|
1783
|
-
status_hdr =
|
|
1784
|
-
p =
|
|
1662
|
+
status_hdr = grpc_slice_malloc(15 + (grpc_status >= 10));
|
|
1663
|
+
p = GRPC_SLICE_START_PTR(status_hdr);
|
|
1785
1664
|
*p++ = 0x40; /* literal header */
|
|
1786
1665
|
*p++ = 11; /* len(grpc-status) */
|
|
1787
1666
|
*p++ = 'g';
|
|
@@ -1803,17 +1682,18 @@ static void close_from_api(grpc_exec_ctx *exec_ctx,
|
|
|
1803
1682
|
*p++ = (uint8_t)('0' + (grpc_status / 10));
|
|
1804
1683
|
*p++ = (uint8_t)('0' + (grpc_status % 10));
|
|
1805
1684
|
}
|
|
1806
|
-
GPR_ASSERT(p ==
|
|
1807
|
-
len += (uint32_t)
|
|
1685
|
+
GPR_ASSERT(p == GRPC_SLICE_END_PTR(status_hdr));
|
|
1686
|
+
len += (uint32_t)GRPC_SLICE_LENGTH(status_hdr);
|
|
1808
1687
|
|
|
1809
1688
|
const char *optional_message =
|
|
1810
1689
|
grpc_error_get_str(error, GRPC_ERROR_STR_GRPC_MESSAGE);
|
|
1811
1690
|
|
|
1812
1691
|
if (optional_message != NULL) {
|
|
1813
1692
|
size_t msg_len = strlen(optional_message);
|
|
1814
|
-
GPR_ASSERT(msg_len
|
|
1815
|
-
|
|
1816
|
-
|
|
1693
|
+
GPR_ASSERT(msg_len <= UINT32_MAX);
|
|
1694
|
+
uint32_t msg_len_len = GRPC_CHTTP2_VARINT_LENGTH((uint32_t)msg_len, 0);
|
|
1695
|
+
message_pfx = grpc_slice_malloc(14 + msg_len_len);
|
|
1696
|
+
p = GRPC_SLICE_START_PTR(message_pfx);
|
|
1817
1697
|
*p++ = 0x40;
|
|
1818
1698
|
*p++ = 12; /* len(grpc-message) */
|
|
1819
1699
|
*p++ = 'g';
|
|
@@ -1828,36 +1708,37 @@ static void close_from_api(grpc_exec_ctx *exec_ctx,
|
|
|
1828
1708
|
*p++ = 'a';
|
|
1829
1709
|
*p++ = 'g';
|
|
1830
1710
|
*p++ = 'e';
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1711
|
+
GRPC_CHTTP2_WRITE_VARINT((uint32_t)msg_len, 0, 0, p,
|
|
1712
|
+
(uint32_t)msg_len_len);
|
|
1713
|
+
p += msg_len_len;
|
|
1714
|
+
GPR_ASSERT(p == GRPC_SLICE_END_PTR(message_pfx));
|
|
1715
|
+
len += (uint32_t)GRPC_SLICE_LENGTH(message_pfx);
|
|
1834
1716
|
len += (uint32_t)msg_len;
|
|
1835
1717
|
}
|
|
1836
1718
|
|
|
1837
|
-
hdr =
|
|
1838
|
-
p =
|
|
1719
|
+
hdr = grpc_slice_malloc(9);
|
|
1720
|
+
p = GRPC_SLICE_START_PTR(hdr);
|
|
1839
1721
|
*p++ = (uint8_t)(len >> 16);
|
|
1840
1722
|
*p++ = (uint8_t)(len >> 8);
|
|
1841
1723
|
*p++ = (uint8_t)(len);
|
|
1842
1724
|
*p++ = GRPC_CHTTP2_FRAME_HEADER;
|
|
1843
1725
|
*p++ = GRPC_CHTTP2_DATA_FLAG_END_STREAM | GRPC_CHTTP2_DATA_FLAG_END_HEADERS;
|
|
1844
|
-
*p++ = (uint8_t)(
|
|
1845
|
-
*p++ = (uint8_t)(
|
|
1846
|
-
*p++ = (uint8_t)(
|
|
1847
|
-
*p++ = (uint8_t)(
|
|
1848
|
-
GPR_ASSERT(p ==
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1726
|
+
*p++ = (uint8_t)(s->id >> 24);
|
|
1727
|
+
*p++ = (uint8_t)(s->id >> 16);
|
|
1728
|
+
*p++ = (uint8_t)(s->id >> 8);
|
|
1729
|
+
*p++ = (uint8_t)(s->id);
|
|
1730
|
+
GPR_ASSERT(p == GRPC_SLICE_END_PTR(hdr));
|
|
1731
|
+
|
|
1732
|
+
grpc_slice_buffer_add(&t->qbuf, hdr);
|
|
1733
|
+
grpc_slice_buffer_add(&t->qbuf, status_hdr);
|
|
1852
1734
|
if (optional_message) {
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1735
|
+
grpc_slice_buffer_add(&t->qbuf, message_pfx);
|
|
1736
|
+
grpc_slice_buffer_add(&t->qbuf,
|
|
1737
|
+
grpc_slice_from_copied_string(optional_message));
|
|
1856
1738
|
}
|
|
1857
|
-
|
|
1858
|
-
&
|
|
1859
|
-
|
|
1860
|
-
&stream_global->stats.outgoing));
|
|
1739
|
+
grpc_slice_buffer_add(
|
|
1740
|
+
&t->qbuf, grpc_chttp2_rst_stream_create(s->id, GRPC_CHTTP2_NO_ERROR,
|
|
1741
|
+
&s->stats.outgoing));
|
|
1861
1742
|
}
|
|
1862
1743
|
|
|
1863
1744
|
const char *msg = grpc_error_get_str(error, GRPC_ERROR_STR_GRPC_MESSAGE);
|
|
@@ -1866,43 +1747,34 @@ static void close_from_api(grpc_exec_ctx *exec_ctx,
|
|
|
1866
1747
|
free_msg = true;
|
|
1867
1748
|
msg = grpc_error_string(error);
|
|
1868
1749
|
}
|
|
1869
|
-
|
|
1870
|
-
grpc_chttp2_fake_status(exec_ctx,
|
|
1871
|
-
grpc_status, &msg_slice);
|
|
1750
|
+
grpc_slice msg_slice = grpc_slice_from_copied_string(msg);
|
|
1751
|
+
grpc_chttp2_fake_status(exec_ctx, t, s, grpc_status, &msg_slice);
|
|
1872
1752
|
if (free_msg) grpc_error_free_string(msg);
|
|
1873
1753
|
|
|
1874
|
-
grpc_chttp2_mark_stream_closed(exec_ctx,
|
|
1875
|
-
|
|
1876
|
-
grpc_chttp2_initiate_write(exec_ctx, transport_global, false,
|
|
1877
|
-
"close_from_api");
|
|
1754
|
+
grpc_chttp2_mark_stream_closed(exec_ctx, t, s, 1, 1, error);
|
|
1755
|
+
grpc_chttp2_initiate_write(exec_ctx, t, false, "close_from_api");
|
|
1878
1756
|
}
|
|
1879
1757
|
|
|
1880
1758
|
typedef struct {
|
|
1881
1759
|
grpc_exec_ctx *exec_ctx;
|
|
1882
1760
|
grpc_error *error;
|
|
1761
|
+
grpc_chttp2_transport *t;
|
|
1883
1762
|
} cancel_stream_cb_args;
|
|
1884
1763
|
|
|
1885
|
-
static void cancel_stream_cb(
|
|
1886
|
-
void *user_data,
|
|
1887
|
-
grpc_chttp2_stream_global *stream_global) {
|
|
1764
|
+
static void cancel_stream_cb(void *user_data, uint32_t key, void *stream) {
|
|
1888
1765
|
cancel_stream_cb_args *args = user_data;
|
|
1889
|
-
|
|
1890
|
-
|
|
1766
|
+
grpc_chttp2_stream *s = stream;
|
|
1767
|
+
grpc_chttp2_cancel_stream(args->exec_ctx, args->t, s,
|
|
1768
|
+
GRPC_ERROR_REF(args->error));
|
|
1891
1769
|
}
|
|
1892
1770
|
|
|
1893
1771
|
static void end_all_the_calls(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
1894
1772
|
grpc_error *error) {
|
|
1895
|
-
cancel_stream_cb_args args = {exec_ctx, error};
|
|
1896
|
-
|
|
1773
|
+
cancel_stream_cb_args args = {exec_ctx, error, t};
|
|
1774
|
+
grpc_chttp2_stream_map_for_each(&t->stream_map, cancel_stream_cb, &args);
|
|
1897
1775
|
GRPC_ERROR_UNREF(error);
|
|
1898
1776
|
}
|
|
1899
1777
|
|
|
1900
|
-
static void drop_connection(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
1901
|
-
grpc_error *error) {
|
|
1902
|
-
close_transport_locked(exec_ctx, t, GRPC_ERROR_REF(error));
|
|
1903
|
-
end_all_the_calls(exec_ctx, t, error);
|
|
1904
|
-
}
|
|
1905
|
-
|
|
1906
1778
|
/** update window from a settings change */
|
|
1907
1779
|
typedef struct {
|
|
1908
1780
|
grpc_chttp2_transport *t;
|
|
@@ -1913,20 +1785,23 @@ static void update_global_window(void *args, uint32_t id, void *stream) {
|
|
|
1913
1785
|
update_global_window_args *a = args;
|
|
1914
1786
|
grpc_chttp2_transport *t = a->t;
|
|
1915
1787
|
grpc_chttp2_stream *s = stream;
|
|
1916
|
-
grpc_chttp2_transport_global *transport_global = &t->global;
|
|
1917
|
-
grpc_chttp2_stream_global *stream_global = &s->global;
|
|
1918
1788
|
int was_zero;
|
|
1919
1789
|
int is_zero;
|
|
1920
|
-
int64_t initial_window_update = t->
|
|
1790
|
+
int64_t initial_window_update = t->initial_window_update;
|
|
1921
1791
|
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1792
|
+
if (initial_window_update > 0) {
|
|
1793
|
+
was_zero = s->outgoing_window <= 0;
|
|
1794
|
+
GRPC_CHTTP2_FLOW_CREDIT_STREAM("settings", t, s, outgoing_window,
|
|
1795
|
+
initial_window_update);
|
|
1796
|
+
is_zero = s->outgoing_window <= 0;
|
|
1926
1797
|
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1798
|
+
if (was_zero && !is_zero) {
|
|
1799
|
+
grpc_chttp2_become_writable(a->exec_ctx, t, s, true,
|
|
1800
|
+
"update_global_window");
|
|
1801
|
+
}
|
|
1802
|
+
} else {
|
|
1803
|
+
GRPC_CHTTP2_FLOW_DEBIT_STREAM("settings", t, s, outgoing_window,
|
|
1804
|
+
-initial_window_update);
|
|
1930
1805
|
}
|
|
1931
1806
|
}
|
|
1932
1807
|
|
|
@@ -1934,47 +1809,6 @@ static void update_global_window(void *args, uint32_t id, void *stream) {
|
|
|
1934
1809
|
* INPUT PROCESSING - PARSING
|
|
1935
1810
|
*/
|
|
1936
1811
|
|
|
1937
|
-
static void reading_action_locked(grpc_exec_ctx *exec_ctx,
|
|
1938
|
-
grpc_chttp2_transport *t,
|
|
1939
|
-
grpc_chttp2_stream *s_unused, void *arg);
|
|
1940
|
-
static void parsing_action(grpc_exec_ctx *exec_ctx, void *arg,
|
|
1941
|
-
grpc_error *error);
|
|
1942
|
-
static void post_reading_action_locked(grpc_exec_ctx *exec_ctx,
|
|
1943
|
-
grpc_chttp2_transport *t,
|
|
1944
|
-
grpc_chttp2_stream *s_unused, void *arg);
|
|
1945
|
-
static void post_parse_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
1946
|
-
grpc_chttp2_stream *s_unused, void *arg);
|
|
1947
|
-
|
|
1948
|
-
static void reading_action(grpc_exec_ctx *exec_ctx, void *tp,
|
|
1949
|
-
grpc_error *error) {
|
|
1950
|
-
/* Control flow:
|
|
1951
|
-
reading_action_locked ->
|
|
1952
|
-
(parse_unlocked -> post_parse_locked)? ->
|
|
1953
|
-
post_reading_action_locked */
|
|
1954
|
-
grpc_chttp2_run_with_global_lock(exec_ctx, tp, NULL, reading_action_locked,
|
|
1955
|
-
GRPC_ERROR_REF(error), 0);
|
|
1956
|
-
}
|
|
1957
|
-
|
|
1958
|
-
static void reading_action_locked(grpc_exec_ctx *exec_ctx,
|
|
1959
|
-
grpc_chttp2_transport *t,
|
|
1960
|
-
grpc_chttp2_stream *s_unused, void *arg) {
|
|
1961
|
-
grpc_chttp2_transport_global *transport_global = &t->global;
|
|
1962
|
-
grpc_chttp2_transport_parsing *transport_parsing = &t->parsing;
|
|
1963
|
-
grpc_error *error = arg;
|
|
1964
|
-
|
|
1965
|
-
GPR_ASSERT(!t->executor.parsing_active);
|
|
1966
|
-
if (!t->closed) {
|
|
1967
|
-
t->executor.parsing_active = 1;
|
|
1968
|
-
/* merge stream lists */
|
|
1969
|
-
grpc_chttp2_stream_map_move_into(&t->new_stream_map,
|
|
1970
|
-
&t->parsing_stream_map);
|
|
1971
|
-
grpc_chttp2_prepare_to_read(transport_global, transport_parsing);
|
|
1972
|
-
grpc_exec_ctx_sched(exec_ctx, &t->parsing_action, error, NULL);
|
|
1973
|
-
} else {
|
|
1974
|
-
post_reading_action_locked(exec_ctx, t, s_unused, arg);
|
|
1975
|
-
}
|
|
1976
|
-
}
|
|
1977
|
-
|
|
1978
1812
|
static grpc_error *try_http_parsing(grpc_exec_ctx *exec_ctx,
|
|
1979
1813
|
grpc_chttp2_transport *t) {
|
|
1980
1814
|
grpc_http_parser parser;
|
|
@@ -1987,7 +1821,8 @@ static grpc_error *try_http_parsing(grpc_exec_ctx *exec_ctx,
|
|
|
1987
1821
|
|
|
1988
1822
|
grpc_error *parse_error = GRPC_ERROR_NONE;
|
|
1989
1823
|
for (; i < t->read_buffer.count && parse_error == GRPC_ERROR_NONE; i++) {
|
|
1990
|
-
parse_error =
|
|
1824
|
+
parse_error =
|
|
1825
|
+
grpc_http_parser_parse(&parser, t->read_buffer.slices[i], NULL);
|
|
1991
1826
|
}
|
|
1992
1827
|
if (parse_error == GRPC_ERROR_NONE &&
|
|
1993
1828
|
(parse_error = grpc_http_parser_eof(&parser)) == GRPC_ERROR_NONE) {
|
|
@@ -2002,169 +1837,119 @@ static grpc_error *try_http_parsing(grpc_exec_ctx *exec_ctx,
|
|
|
2002
1837
|
return error;
|
|
2003
1838
|
}
|
|
2004
1839
|
|
|
2005
|
-
static void
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
/* if a stream is in the stream map, and gets cancelled, we need to
|
|
2063
|
-
* ensure we are not parsing before continuing the cancellation to keep
|
|
2064
|
-
* things in a sane state */
|
|
2065
|
-
grpc_chttp2_stream_global *stream_global;
|
|
2066
|
-
while (grpc_chttp2_list_pop_closed_waiting_for_parsing(transport_global,
|
|
2067
|
-
&stream_global)) {
|
|
2068
|
-
GPR_ASSERT(stream_global->in_stream_map);
|
|
2069
|
-
GPR_ASSERT(stream_global->write_closed);
|
|
2070
|
-
GPR_ASSERT(stream_global->read_closed);
|
|
2071
|
-
remove_stream(exec_ctx, t, stream_global->id,
|
|
2072
|
-
removal_error(GRPC_ERROR_NONE, stream_global));
|
|
2073
|
-
GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2");
|
|
2074
|
-
}
|
|
2075
|
-
|
|
2076
|
-
post_reading_action_locked(exec_ctx, t, s_unused, arg);
|
|
2077
|
-
}
|
|
2078
|
-
|
|
2079
|
-
static void post_reading_action_locked(grpc_exec_ctx *exec_ctx,
|
|
2080
|
-
grpc_chttp2_transport *t,
|
|
2081
|
-
grpc_chttp2_stream *s_unused,
|
|
2082
|
-
void *arg) {
|
|
2083
|
-
grpc_error *error = arg;
|
|
1840
|
+
static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp,
|
|
1841
|
+
grpc_error *error) {
|
|
1842
|
+
GPR_TIMER_BEGIN("reading_action_locked", 0);
|
|
1843
|
+
|
|
1844
|
+
grpc_chttp2_transport *t = tp;
|
|
1845
|
+
|
|
1846
|
+
GRPC_ERROR_REF(error);
|
|
1847
|
+
|
|
1848
|
+
grpc_error *err = error;
|
|
1849
|
+
if (err != GRPC_ERROR_NONE) {
|
|
1850
|
+
err = grpc_error_set_int(
|
|
1851
|
+
GRPC_ERROR_CREATE_REFERENCING("Endpoint read failed", &err, 1),
|
|
1852
|
+
GRPC_ERROR_INT_OCCURRED_DURING_WRITE, t->write_state);
|
|
1853
|
+
}
|
|
1854
|
+
GPR_SWAP(grpc_error *, err, error);
|
|
1855
|
+
GRPC_ERROR_UNREF(err);
|
|
1856
|
+
if (!t->closed) {
|
|
1857
|
+
GPR_TIMER_BEGIN("reading_action.parse", 0);
|
|
1858
|
+
size_t i = 0;
|
|
1859
|
+
grpc_error *errors[3] = {GRPC_ERROR_REF(error), GRPC_ERROR_NONE,
|
|
1860
|
+
GRPC_ERROR_NONE};
|
|
1861
|
+
for (; i < t->read_buffer.count && errors[1] == GRPC_ERROR_NONE; i++) {
|
|
1862
|
+
errors[1] =
|
|
1863
|
+
grpc_chttp2_perform_read(exec_ctx, t, t->read_buffer.slices[i]);
|
|
1864
|
+
};
|
|
1865
|
+
if (errors[1] != GRPC_ERROR_NONE) {
|
|
1866
|
+
errors[2] = try_http_parsing(exec_ctx, t);
|
|
1867
|
+
GRPC_ERROR_UNREF(error);
|
|
1868
|
+
error = GRPC_ERROR_CREATE_REFERENCING("Failed parsing HTTP/2", errors,
|
|
1869
|
+
GPR_ARRAY_SIZE(errors));
|
|
1870
|
+
}
|
|
1871
|
+
for (i = 0; i < GPR_ARRAY_SIZE(errors); i++) {
|
|
1872
|
+
GRPC_ERROR_UNREF(errors[i]);
|
|
1873
|
+
}
|
|
1874
|
+
GPR_TIMER_END("reading_action.parse", 0);
|
|
1875
|
+
|
|
1876
|
+
GPR_TIMER_BEGIN("post_parse_locked", 0);
|
|
1877
|
+
if (t->initial_window_update != 0) {
|
|
1878
|
+
update_global_window_args args = {t, exec_ctx};
|
|
1879
|
+
grpc_chttp2_stream_map_for_each(&t->stream_map, update_global_window,
|
|
1880
|
+
&args);
|
|
1881
|
+
t->initial_window_update = 0;
|
|
1882
|
+
}
|
|
1883
|
+
/* handle higher level things */
|
|
1884
|
+
if (t->incoming_window < t->connection_window_target * 3 / 4) {
|
|
1885
|
+
int64_t announce_bytes = t->connection_window_target - t->incoming_window;
|
|
1886
|
+
GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT("parsed", t, announce_incoming_window,
|
|
1887
|
+
announce_bytes);
|
|
1888
|
+
GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT("parsed", t, incoming_window,
|
|
1889
|
+
announce_bytes);
|
|
1890
|
+
grpc_chttp2_initiate_write(exec_ctx, t, false, "global incoming window");
|
|
1891
|
+
}
|
|
1892
|
+
|
|
1893
|
+
GPR_TIMER_END("post_parse_locked", 0);
|
|
1894
|
+
}
|
|
1895
|
+
|
|
1896
|
+
GPR_TIMER_BEGIN("post_reading_action_locked", 0);
|
|
2084
1897
|
bool keep_reading = false;
|
|
2085
1898
|
if (error == GRPC_ERROR_NONE && t->closed) {
|
|
2086
1899
|
error = GRPC_ERROR_CREATE("Transport closed");
|
|
2087
1900
|
}
|
|
2088
1901
|
if (error != GRPC_ERROR_NONE) {
|
|
2089
|
-
|
|
2090
|
-
error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS,
|
|
2091
|
-
GRPC_STATUS_UNAVAILABLE);
|
|
2092
|
-
}
|
|
2093
|
-
drop_connection(exec_ctx, t, GRPC_ERROR_REF(error));
|
|
1902
|
+
close_transport_locked(exec_ctx, t, GRPC_ERROR_REF(error));
|
|
2094
1903
|
t->endpoint_reading = 0;
|
|
2095
|
-
if (grpc_http_write_state_trace) {
|
|
2096
|
-
gpr_log(GPR_DEBUG, "R:%p -> 0 ws=%s", t,
|
|
2097
|
-
write_state_name(t->executor.write_state));
|
|
2098
|
-
}
|
|
2099
|
-
if (t->executor.write_state == GRPC_CHTTP2_WRITING_INACTIVE && t->ep) {
|
|
2100
|
-
destroy_endpoint(exec_ctx, t);
|
|
2101
|
-
}
|
|
2102
1904
|
} else if (!t->closed) {
|
|
2103
1905
|
keep_reading = true;
|
|
2104
|
-
|
|
2105
|
-
prevent_endpoint_shutdown(t);
|
|
1906
|
+
GRPC_CHTTP2_REF_TRANSPORT(t, "keep_reading");
|
|
2106
1907
|
}
|
|
2107
|
-
|
|
2108
|
-
GRPC_ERROR_UNREF(error);
|
|
1908
|
+
grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &t->read_buffer);
|
|
2109
1909
|
|
|
2110
1910
|
if (keep_reading) {
|
|
2111
|
-
grpc_endpoint_read(exec_ctx, t->ep, &t->read_buffer,
|
|
2112
|
-
|
|
2113
|
-
|
|
1911
|
+
grpc_endpoint_read(exec_ctx, t->ep, &t->read_buffer,
|
|
1912
|
+
&t->read_action_locked);
|
|
1913
|
+
GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "keep_reading");
|
|
2114
1914
|
} else {
|
|
2115
|
-
|
|
1915
|
+
GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "reading_action");
|
|
2116
1916
|
}
|
|
1917
|
+
|
|
1918
|
+
GPR_TIMER_END("post_reading_action_locked", 0);
|
|
1919
|
+
|
|
1920
|
+
GRPC_ERROR_UNREF(error);
|
|
1921
|
+
|
|
1922
|
+
GPR_TIMER_END("reading_action_locked", 0);
|
|
2117
1923
|
}
|
|
2118
1924
|
|
|
2119
1925
|
/*******************************************************************************
|
|
2120
1926
|
* CALLBACK LOOP
|
|
2121
1927
|
*/
|
|
2122
1928
|
|
|
2123
|
-
static void connectivity_state_set(
|
|
2124
|
-
|
|
2125
|
-
|
|
1929
|
+
static void connectivity_state_set(grpc_exec_ctx *exec_ctx,
|
|
1930
|
+
grpc_chttp2_transport *t,
|
|
1931
|
+
grpc_connectivity_state state,
|
|
1932
|
+
grpc_error *error, const char *reason) {
|
|
2126
1933
|
GRPC_CHTTP2_IF_TRACING(
|
|
2127
1934
|
gpr_log(GPR_DEBUG, "set connectivity_state=%d", state));
|
|
2128
|
-
grpc_connectivity_state_set(
|
|
2129
|
-
|
|
2130
|
-
&TRANSPORT_FROM_GLOBAL(transport_global)->channel_callback.state_tracker,
|
|
2131
|
-
state, error, reason);
|
|
1935
|
+
grpc_connectivity_state_set(exec_ctx, &t->channel_callback.state_tracker,
|
|
1936
|
+
state, error, reason);
|
|
2132
1937
|
}
|
|
2133
1938
|
|
|
2134
1939
|
/*******************************************************************************
|
|
2135
1940
|
* POLLSET STUFF
|
|
2136
1941
|
*/
|
|
2137
1942
|
|
|
2138
|
-
static void add_to_pollset_locked(grpc_exec_ctx *exec_ctx,
|
|
2139
|
-
grpc_chttp2_transport *t,
|
|
2140
|
-
grpc_chttp2_stream *s_unused, void *pollset) {
|
|
2141
|
-
if (t->ep) {
|
|
2142
|
-
grpc_endpoint_add_to_pollset(exec_ctx, t->ep, pollset);
|
|
2143
|
-
}
|
|
2144
|
-
}
|
|
2145
|
-
|
|
2146
|
-
static void add_to_pollset_set_locked(grpc_exec_ctx *exec_ctx,
|
|
2147
|
-
grpc_chttp2_transport *t,
|
|
2148
|
-
grpc_chttp2_stream *s_unused,
|
|
2149
|
-
void *pollset_set) {
|
|
2150
|
-
if (t->ep) {
|
|
2151
|
-
grpc_endpoint_add_to_pollset_set(exec_ctx, t->ep, pollset_set);
|
|
2152
|
-
}
|
|
2153
|
-
}
|
|
2154
|
-
|
|
2155
1943
|
static void set_pollset(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
|
|
2156
1944
|
grpc_stream *gs, grpc_pollset *pollset) {
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
(grpc_chttp2_stream *)gs,
|
|
2160
|
-
add_to_pollset_locked, pollset, 0);
|
|
1945
|
+
grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt;
|
|
1946
|
+
grpc_endpoint_add_to_pollset(exec_ctx, t->ep, pollset);
|
|
2161
1947
|
}
|
|
2162
1948
|
|
|
2163
1949
|
static void set_pollset_set(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
|
|
2164
1950
|
grpc_stream *gs, grpc_pollset_set *pollset_set) {
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
add_to_pollset_set_locked, pollset_set, 0);
|
|
1951
|
+
grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt;
|
|
1952
|
+
grpc_endpoint_add_to_pollset_set(exec_ctx, t->ep, pollset_set);
|
|
2168
1953
|
}
|
|
2169
1954
|
|
|
2170
1955
|
/*******************************************************************************
|
|
@@ -2175,20 +1960,22 @@ static void incoming_byte_stream_unref(grpc_exec_ctx *exec_ctx,
|
|
|
2175
1960
|
grpc_chttp2_incoming_byte_stream *bs) {
|
|
2176
1961
|
if (gpr_unref(&bs->refs)) {
|
|
2177
1962
|
GRPC_ERROR_UNREF(bs->error);
|
|
2178
|
-
|
|
1963
|
+
grpc_slice_buffer_destroy_internal(exec_ctx, &bs->slices);
|
|
1964
|
+
gpr_mu_destroy(&bs->slice_mu);
|
|
2179
1965
|
gpr_free(bs);
|
|
2180
1966
|
}
|
|
2181
1967
|
}
|
|
2182
1968
|
|
|
2183
|
-
static void incoming_byte_stream_update_flow_control(
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
1969
|
+
static void incoming_byte_stream_update_flow_control(grpc_exec_ctx *exec_ctx,
|
|
1970
|
+
grpc_chttp2_transport *t,
|
|
1971
|
+
grpc_chttp2_stream *s,
|
|
1972
|
+
size_t max_size_hint,
|
|
1973
|
+
size_t have_already) {
|
|
2187
1974
|
uint32_t max_recv_bytes;
|
|
2188
1975
|
|
|
2189
1976
|
/* clamp max recv hint to an allowable size */
|
|
2190
|
-
if (max_size_hint >= UINT32_MAX -
|
|
2191
|
-
max_recv_bytes = UINT32_MAX -
|
|
1977
|
+
if (max_size_hint >= UINT32_MAX - t->stream_lookahead) {
|
|
1978
|
+
max_recv_bytes = UINT32_MAX - t->stream_lookahead;
|
|
2192
1979
|
} else {
|
|
2193
1980
|
max_recv_bytes = (uint32_t)max_size_hint;
|
|
2194
1981
|
}
|
|
@@ -2201,72 +1988,71 @@ static void incoming_byte_stream_update_flow_control(
|
|
|
2201
1988
|
}
|
|
2202
1989
|
|
|
2203
1990
|
/* add some small lookahead to keep pipelines flowing */
|
|
2204
|
-
GPR_ASSERT(max_recv_bytes <= UINT32_MAX -
|
|
2205
|
-
max_recv_bytes +=
|
|
2206
|
-
if (
|
|
2207
|
-
uint32_t add_max_recv_bytes =
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
1991
|
+
GPR_ASSERT(max_recv_bytes <= UINT32_MAX - t->stream_lookahead);
|
|
1992
|
+
max_recv_bytes += t->stream_lookahead;
|
|
1993
|
+
if (s->max_recv_bytes < max_recv_bytes) {
|
|
1994
|
+
uint32_t add_max_recv_bytes = max_recv_bytes - s->max_recv_bytes;
|
|
1995
|
+
bool new_window_write_is_covered_by_poller =
|
|
1996
|
+
s->max_recv_bytes < have_already;
|
|
1997
|
+
GRPC_CHTTP2_FLOW_CREDIT_STREAM("op", t, s, max_recv_bytes,
|
|
1998
|
+
add_max_recv_bytes);
|
|
1999
|
+
GRPC_CHTTP2_FLOW_CREDIT_STREAM("op", t, s, incoming_window,
|
|
2213
2000
|
add_max_recv_bytes);
|
|
2214
|
-
GRPC_CHTTP2_FLOW_CREDIT_STREAM("op",
|
|
2215
|
-
unannounced_incoming_window_for_writing,
|
|
2001
|
+
GRPC_CHTTP2_FLOW_CREDIT_STREAM("op", t, s, announce_window,
|
|
2216
2002
|
add_max_recv_bytes);
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
false, "read_incoming_stream");
|
|
2003
|
+
grpc_chttp2_become_writable(exec_ctx, t, s,
|
|
2004
|
+
new_window_write_is_covered_by_poller,
|
|
2005
|
+
"read_incoming_stream");
|
|
2221
2006
|
}
|
|
2222
2007
|
}
|
|
2223
2008
|
|
|
2224
|
-
typedef struct {
|
|
2225
|
-
grpc_chttp2_incoming_byte_stream *byte_stream;
|
|
2226
|
-
gpr_slice *slice;
|
|
2227
|
-
size_t max_size_hint;
|
|
2228
|
-
grpc_closure *on_complete;
|
|
2229
|
-
} incoming_byte_stream_next_arg;
|
|
2230
|
-
|
|
2231
2009
|
static void incoming_byte_stream_next_locked(grpc_exec_ctx *exec_ctx,
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
(grpc_chttp2_incoming_byte_stream *)arg->byte_stream;
|
|
2238
|
-
grpc_chttp2_transport_global *transport_global = &bs->transport->global;
|
|
2239
|
-
grpc_chttp2_stream_global *stream_global = &bs->stream->global;
|
|
2010
|
+
void *argp,
|
|
2011
|
+
grpc_error *error_ignored) {
|
|
2012
|
+
grpc_chttp2_incoming_byte_stream *bs = argp;
|
|
2013
|
+
grpc_chttp2_transport *t = bs->transport;
|
|
2014
|
+
grpc_chttp2_stream *s = bs->stream;
|
|
2240
2015
|
|
|
2241
2016
|
if (bs->is_tail) {
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2017
|
+
gpr_mu_lock(&bs->slice_mu);
|
|
2018
|
+
size_t cur_length = bs->slices.length;
|
|
2019
|
+
gpr_mu_unlock(&bs->slice_mu);
|
|
2020
|
+
incoming_byte_stream_update_flow_control(
|
|
2021
|
+
exec_ctx, t, s, bs->next_action.max_size_hint, cur_length);
|
|
2245
2022
|
}
|
|
2023
|
+
gpr_mu_lock(&bs->slice_mu);
|
|
2246
2024
|
if (bs->slices.count > 0) {
|
|
2247
|
-
*
|
|
2248
|
-
|
|
2025
|
+
*bs->next_action.slice = grpc_slice_buffer_take_first(&bs->slices);
|
|
2026
|
+
grpc_closure_run(exec_ctx, bs->next_action.on_complete, GRPC_ERROR_NONE);
|
|
2249
2027
|
} else if (bs->error != GRPC_ERROR_NONE) {
|
|
2250
|
-
|
|
2251
|
-
|
|
2028
|
+
grpc_closure_run(exec_ctx, bs->next_action.on_complete,
|
|
2029
|
+
GRPC_ERROR_REF(bs->error));
|
|
2252
2030
|
} else {
|
|
2253
|
-
bs->on_next =
|
|
2254
|
-
bs->next =
|
|
2031
|
+
bs->on_next = bs->next_action.on_complete;
|
|
2032
|
+
bs->next = bs->next_action.slice;
|
|
2255
2033
|
}
|
|
2034
|
+
gpr_mu_unlock(&bs->slice_mu);
|
|
2256
2035
|
incoming_byte_stream_unref(exec_ctx, bs);
|
|
2257
2036
|
}
|
|
2258
2037
|
|
|
2259
2038
|
static int incoming_byte_stream_next(grpc_exec_ctx *exec_ctx,
|
|
2260
2039
|
grpc_byte_stream *byte_stream,
|
|
2261
|
-
|
|
2040
|
+
grpc_slice *slice, size_t max_size_hint,
|
|
2262
2041
|
grpc_closure *on_complete) {
|
|
2042
|
+
GPR_TIMER_BEGIN("incoming_byte_stream_next", 0);
|
|
2263
2043
|
grpc_chttp2_incoming_byte_stream *bs =
|
|
2264
2044
|
(grpc_chttp2_incoming_byte_stream *)byte_stream;
|
|
2265
|
-
incoming_byte_stream_next_arg arg = {bs, slice, max_size_hint, on_complete};
|
|
2266
2045
|
gpr_ref(&bs->refs);
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2046
|
+
bs->next_action.slice = slice;
|
|
2047
|
+
bs->next_action.max_size_hint = max_size_hint;
|
|
2048
|
+
bs->next_action.on_complete = on_complete;
|
|
2049
|
+
grpc_closure_sched(
|
|
2050
|
+
exec_ctx,
|
|
2051
|
+
grpc_closure_init(
|
|
2052
|
+
&bs->next_action.closure, incoming_byte_stream_next_locked, bs,
|
|
2053
|
+
grpc_combiner_scheduler(bs->transport->combiner, false)),
|
|
2054
|
+
GRPC_ERROR_NONE);
|
|
2055
|
+
GPR_TIMER_END("incoming_byte_stream_next", 0);
|
|
2270
2056
|
return 0;
|
|
2271
2057
|
}
|
|
2272
2058
|
|
|
@@ -2274,183 +2060,218 @@ static void incoming_byte_stream_destroy(grpc_exec_ctx *exec_ctx,
|
|
|
2274
2060
|
grpc_byte_stream *byte_stream);
|
|
2275
2061
|
|
|
2276
2062
|
static void incoming_byte_stream_destroy_locked(grpc_exec_ctx *exec_ctx,
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
void *byte_stream) {
|
|
2063
|
+
void *byte_stream,
|
|
2064
|
+
grpc_error *error_ignored) {
|
|
2280
2065
|
grpc_chttp2_incoming_byte_stream *bs = byte_stream;
|
|
2281
2066
|
GPR_ASSERT(bs->base.destroy == incoming_byte_stream_destroy);
|
|
2282
|
-
decrement_active_streams_locked(exec_ctx,
|
|
2283
|
-
&bs->stream->global);
|
|
2067
|
+
decrement_active_streams_locked(exec_ctx, bs->transport, bs->stream);
|
|
2284
2068
|
incoming_byte_stream_unref(exec_ctx, bs);
|
|
2285
2069
|
}
|
|
2286
2070
|
|
|
2287
2071
|
static void incoming_byte_stream_destroy(grpc_exec_ctx *exec_ctx,
|
|
2288
2072
|
grpc_byte_stream *byte_stream) {
|
|
2073
|
+
GPR_TIMER_BEGIN("incoming_byte_stream_destroy", 0);
|
|
2289
2074
|
grpc_chttp2_incoming_byte_stream *bs =
|
|
2290
2075
|
(grpc_chttp2_incoming_byte_stream *)byte_stream;
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
} incoming_byte_stream_push_arg;
|
|
2299
|
-
|
|
2300
|
-
static void incoming_byte_stream_push_locked(grpc_exec_ctx *exec_ctx,
|
|
2301
|
-
grpc_chttp2_transport *t,
|
|
2302
|
-
grpc_chttp2_stream *s,
|
|
2303
|
-
void *argp) {
|
|
2304
|
-
incoming_byte_stream_push_arg *arg = argp;
|
|
2305
|
-
grpc_chttp2_incoming_byte_stream *bs = arg->byte_stream;
|
|
2306
|
-
if (bs->on_next != NULL) {
|
|
2307
|
-
*bs->next = arg->slice;
|
|
2308
|
-
grpc_exec_ctx_sched(exec_ctx, bs->on_next, GRPC_ERROR_NONE, NULL);
|
|
2309
|
-
bs->on_next = NULL;
|
|
2310
|
-
} else {
|
|
2311
|
-
gpr_slice_buffer_add(&bs->slices, arg->slice);
|
|
2312
|
-
}
|
|
2313
|
-
incoming_byte_stream_unref(exec_ctx, bs);
|
|
2314
|
-
}
|
|
2315
|
-
|
|
2316
|
-
void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx,
|
|
2317
|
-
grpc_chttp2_incoming_byte_stream *bs,
|
|
2318
|
-
gpr_slice slice) {
|
|
2319
|
-
incoming_byte_stream_push_arg arg = {bs, slice};
|
|
2320
|
-
gpr_ref(&bs->refs);
|
|
2321
|
-
grpc_chttp2_run_with_global_lock(exec_ctx, bs->transport, bs->stream,
|
|
2322
|
-
incoming_byte_stream_push_locked, &arg,
|
|
2323
|
-
sizeof(arg));
|
|
2324
|
-
}
|
|
2325
|
-
|
|
2326
|
-
typedef struct {
|
|
2327
|
-
grpc_chttp2_incoming_byte_stream *bs;
|
|
2328
|
-
grpc_error *error;
|
|
2329
|
-
} bs_fail_args;
|
|
2330
|
-
|
|
2331
|
-
static bs_fail_args *make_bs_fail_args(grpc_chttp2_incoming_byte_stream *bs,
|
|
2332
|
-
grpc_error *error) {
|
|
2333
|
-
bs_fail_args *a = gpr_malloc(sizeof(*a));
|
|
2334
|
-
a->bs = bs;
|
|
2335
|
-
a->error = error;
|
|
2336
|
-
return a;
|
|
2076
|
+
grpc_closure_sched(
|
|
2077
|
+
exec_ctx,
|
|
2078
|
+
grpc_closure_init(
|
|
2079
|
+
&bs->destroy_action, incoming_byte_stream_destroy_locked, bs,
|
|
2080
|
+
grpc_combiner_scheduler(bs->transport->combiner, false)),
|
|
2081
|
+
GRPC_ERROR_NONE);
|
|
2082
|
+
GPR_TIMER_END("incoming_byte_stream_destroy", 0);
|
|
2337
2083
|
}
|
|
2338
2084
|
|
|
2339
|
-
static void
|
|
2340
|
-
grpc_exec_ctx *exec_ctx,
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
grpc_error *error = a->error;
|
|
2345
|
-
gpr_free(a);
|
|
2346
|
-
grpc_exec_ctx_sched(exec_ctx, bs->on_next, GRPC_ERROR_REF(error), NULL);
|
|
2085
|
+
static void incoming_byte_stream_publish_error(
|
|
2086
|
+
grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs,
|
|
2087
|
+
grpc_error *error) {
|
|
2088
|
+
GPR_ASSERT(error != GRPC_ERROR_NONE);
|
|
2089
|
+
grpc_closure_sched(exec_ctx, bs->on_next, GRPC_ERROR_REF(error));
|
|
2347
2090
|
bs->on_next = NULL;
|
|
2348
2091
|
GRPC_ERROR_UNREF(bs->error);
|
|
2349
2092
|
bs->error = error;
|
|
2350
|
-
incoming_byte_stream_unref(exec_ctx, bs);
|
|
2351
2093
|
}
|
|
2352
2094
|
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2095
|
+
void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx,
|
|
2096
|
+
grpc_chttp2_incoming_byte_stream *bs,
|
|
2097
|
+
grpc_slice slice) {
|
|
2098
|
+
gpr_mu_lock(&bs->slice_mu);
|
|
2099
|
+
if (bs->remaining_bytes < GRPC_SLICE_LENGTH(slice)) {
|
|
2100
|
+
incoming_byte_stream_publish_error(
|
|
2101
|
+
exec_ctx, bs, GRPC_ERROR_CREATE("Too many bytes in stream"));
|
|
2102
|
+
} else {
|
|
2103
|
+
bs->remaining_bytes -= (uint32_t)GRPC_SLICE_LENGTH(slice);
|
|
2104
|
+
if (bs->on_next != NULL) {
|
|
2105
|
+
*bs->next = slice;
|
|
2106
|
+
grpc_closure_sched(exec_ctx, bs->on_next, GRPC_ERROR_NONE);
|
|
2107
|
+
bs->on_next = NULL;
|
|
2108
|
+
} else {
|
|
2109
|
+
grpc_slice_buffer_add(&bs->slices, slice);
|
|
2110
|
+
}
|
|
2111
|
+
}
|
|
2112
|
+
gpr_mu_unlock(&bs->slice_mu);
|
|
2359
2113
|
}
|
|
2360
2114
|
|
|
2361
2115
|
void grpc_chttp2_incoming_byte_stream_finished(
|
|
2362
2116
|
grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs,
|
|
2363
|
-
grpc_error *error
|
|
2364
|
-
if (
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
bs, 0);
|
|
2369
|
-
} else {
|
|
2370
|
-
grpc_chttp2_run_with_global_lock(
|
|
2371
|
-
exec_ctx, bs->transport, bs->stream,
|
|
2372
|
-
incoming_byte_stream_finished_failed_locked,
|
|
2373
|
-
make_bs_fail_args(bs, error), 0);
|
|
2374
|
-
}
|
|
2375
|
-
} else {
|
|
2376
|
-
if (error == GRPC_ERROR_NONE) {
|
|
2377
|
-
incoming_byte_stream_finished_ok_locked(exec_ctx, bs->transport,
|
|
2378
|
-
bs->stream, bs);
|
|
2379
|
-
} else {
|
|
2380
|
-
incoming_byte_stream_finished_failed_locked(
|
|
2381
|
-
exec_ctx, bs->transport, bs->stream, make_bs_fail_args(bs, error));
|
|
2117
|
+
grpc_error *error) {
|
|
2118
|
+
if (error == GRPC_ERROR_NONE) {
|
|
2119
|
+
gpr_mu_lock(&bs->slice_mu);
|
|
2120
|
+
if (bs->remaining_bytes != 0) {
|
|
2121
|
+
error = GRPC_ERROR_CREATE("Truncated message");
|
|
2382
2122
|
}
|
|
2123
|
+
gpr_mu_unlock(&bs->slice_mu);
|
|
2383
2124
|
}
|
|
2125
|
+
if (error != GRPC_ERROR_NONE) {
|
|
2126
|
+
incoming_byte_stream_publish_error(exec_ctx, bs, error);
|
|
2127
|
+
}
|
|
2128
|
+
incoming_byte_stream_unref(exec_ctx, bs);
|
|
2384
2129
|
}
|
|
2385
2130
|
|
|
2386
2131
|
grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create(
|
|
2387
|
-
grpc_exec_ctx *exec_ctx,
|
|
2388
|
-
|
|
2389
|
-
uint32_t flags, grpc_chttp2_incoming_frame_queue *add_to_queue) {
|
|
2132
|
+
grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s,
|
|
2133
|
+
uint32_t frame_size, uint32_t flags) {
|
|
2390
2134
|
grpc_chttp2_incoming_byte_stream *incoming_byte_stream =
|
|
2391
2135
|
gpr_malloc(sizeof(*incoming_byte_stream));
|
|
2392
2136
|
incoming_byte_stream->base.length = frame_size;
|
|
2137
|
+
incoming_byte_stream->remaining_bytes = frame_size;
|
|
2393
2138
|
incoming_byte_stream->base.flags = flags;
|
|
2394
2139
|
incoming_byte_stream->base.next = incoming_byte_stream_next;
|
|
2395
2140
|
incoming_byte_stream->base.destroy = incoming_byte_stream_destroy;
|
|
2141
|
+
gpr_mu_init(&incoming_byte_stream->slice_mu);
|
|
2396
2142
|
gpr_ref_init(&incoming_byte_stream->refs, 2);
|
|
2397
2143
|
incoming_byte_stream->next_message = NULL;
|
|
2398
|
-
incoming_byte_stream->transport =
|
|
2399
|
-
incoming_byte_stream->stream =
|
|
2400
|
-
gpr_ref(&incoming_byte_stream->stream->
|
|
2401
|
-
|
|
2144
|
+
incoming_byte_stream->transport = t;
|
|
2145
|
+
incoming_byte_stream->stream = s;
|
|
2146
|
+
gpr_ref(&incoming_byte_stream->stream->active_streams);
|
|
2147
|
+
grpc_slice_buffer_init(&incoming_byte_stream->slices);
|
|
2402
2148
|
incoming_byte_stream->on_next = NULL;
|
|
2403
2149
|
incoming_byte_stream->is_tail = 1;
|
|
2404
2150
|
incoming_byte_stream->error = GRPC_ERROR_NONE;
|
|
2405
|
-
|
|
2406
|
-
|
|
2151
|
+
grpc_chttp2_incoming_frame_queue *q = &s->incoming_frames;
|
|
2152
|
+
if (q->head == NULL) {
|
|
2153
|
+
q->head = incoming_byte_stream;
|
|
2407
2154
|
} else {
|
|
2408
|
-
|
|
2409
|
-
|
|
2155
|
+
q->tail->is_tail = 0;
|
|
2156
|
+
q->tail->next_message = incoming_byte_stream;
|
|
2410
2157
|
}
|
|
2411
|
-
|
|
2158
|
+
q->tail = incoming_byte_stream;
|
|
2159
|
+
grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s);
|
|
2412
2160
|
return incoming_byte_stream;
|
|
2413
2161
|
}
|
|
2414
2162
|
|
|
2415
2163
|
/*******************************************************************************
|
|
2416
|
-
*
|
|
2164
|
+
* RESOURCE QUOTAS
|
|
2417
2165
|
*/
|
|
2418
2166
|
|
|
2419
|
-
static
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2167
|
+
static void post_benign_reclaimer(grpc_exec_ctx *exec_ctx,
|
|
2168
|
+
grpc_chttp2_transport *t) {
|
|
2169
|
+
if (!t->benign_reclaimer_registered) {
|
|
2170
|
+
t->benign_reclaimer_registered = true;
|
|
2171
|
+
GRPC_CHTTP2_REF_TRANSPORT(t, "benign_reclaimer");
|
|
2172
|
+
grpc_resource_user_post_reclaimer(exec_ctx,
|
|
2173
|
+
grpc_endpoint_get_resource_user(t->ep),
|
|
2174
|
+
false, &t->benign_reclaimer_locked);
|
|
2175
|
+
}
|
|
2176
|
+
}
|
|
2177
|
+
|
|
2178
|
+
static void post_destructive_reclaimer(grpc_exec_ctx *exec_ctx,
|
|
2179
|
+
grpc_chttp2_transport *t) {
|
|
2180
|
+
if (!t->destructive_reclaimer_registered) {
|
|
2181
|
+
t->destructive_reclaimer_registered = true;
|
|
2182
|
+
GRPC_CHTTP2_REF_TRANSPORT(t, "destructive_reclaimer");
|
|
2183
|
+
grpc_resource_user_post_reclaimer(exec_ctx,
|
|
2184
|
+
grpc_endpoint_get_resource_user(t->ep),
|
|
2185
|
+
true, &t->destructive_reclaimer_locked);
|
|
2186
|
+
}
|
|
2187
|
+
}
|
|
2188
|
+
|
|
2189
|
+
static void benign_reclaimer_locked(grpc_exec_ctx *exec_ctx, void *arg,
|
|
2190
|
+
grpc_error *error) {
|
|
2191
|
+
grpc_chttp2_transport *t = arg;
|
|
2192
|
+
if (error == GRPC_ERROR_NONE &&
|
|
2193
|
+
grpc_chttp2_stream_map_size(&t->stream_map) == 0) {
|
|
2194
|
+
/* Channel with no active streams: send a goaway to try and make it
|
|
2195
|
+
* disconnect cleanly */
|
|
2196
|
+
if (grpc_resource_quota_trace) {
|
|
2197
|
+
gpr_log(GPR_DEBUG, "HTTP2: %s - send goaway to free memory",
|
|
2198
|
+
t->peer_string);
|
|
2199
|
+
}
|
|
2200
|
+
send_goaway(exec_ctx, t, GRPC_CHTTP2_ENHANCE_YOUR_CALM,
|
|
2201
|
+
grpc_slice_from_static_string("Buffers full"));
|
|
2202
|
+
} else if (error == GRPC_ERROR_NONE && grpc_resource_quota_trace) {
|
|
2203
|
+
gpr_log(GPR_DEBUG,
|
|
2204
|
+
"HTTP2: %s - skip benign reclamation, there are still %" PRIdPTR
|
|
2205
|
+
" streams",
|
|
2206
|
+
t->peer_string, grpc_chttp2_stream_map_size(&t->stream_map));
|
|
2207
|
+
}
|
|
2208
|
+
t->benign_reclaimer_registered = false;
|
|
2209
|
+
if (error != GRPC_ERROR_CANCELLED) {
|
|
2210
|
+
grpc_resource_user_finish_reclamation(
|
|
2211
|
+
exec_ctx, grpc_endpoint_get_resource_user(t->ep));
|
|
2212
|
+
}
|
|
2213
|
+
GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "benign_reclaimer");
|
|
2444
2214
|
}
|
|
2445
2215
|
|
|
2446
|
-
static
|
|
2447
|
-
|
|
2448
|
-
|
|
2216
|
+
static void destructive_reclaimer_locked(grpc_exec_ctx *exec_ctx, void *arg,
|
|
2217
|
+
grpc_error *error) {
|
|
2218
|
+
grpc_chttp2_transport *t = arg;
|
|
2219
|
+
size_t n = grpc_chttp2_stream_map_size(&t->stream_map);
|
|
2220
|
+
t->destructive_reclaimer_registered = false;
|
|
2221
|
+
if (error == GRPC_ERROR_NONE && n > 0) {
|
|
2222
|
+
grpc_chttp2_stream *s = grpc_chttp2_stream_map_rand(&t->stream_map);
|
|
2223
|
+
if (grpc_resource_quota_trace) {
|
|
2224
|
+
gpr_log(GPR_DEBUG, "HTTP2: %s - abandon stream id %d", t->peer_string,
|
|
2225
|
+
s->id);
|
|
2226
|
+
}
|
|
2227
|
+
grpc_chttp2_cancel_stream(
|
|
2228
|
+
exec_ctx, t, s, grpc_error_set_int(GRPC_ERROR_CREATE("Buffers full"),
|
|
2229
|
+
GRPC_ERROR_INT_HTTP2_ERROR,
|
|
2230
|
+
GRPC_CHTTP2_ENHANCE_YOUR_CALM));
|
|
2231
|
+
if (n > 1) {
|
|
2232
|
+
/* Since we cancel one stream per destructive reclamation, if
|
|
2233
|
+
there are more streams left, we can immediately post a new
|
|
2234
|
+
reclaimer in case the resource quota needs to free more
|
|
2235
|
+
memory */
|
|
2236
|
+
post_destructive_reclaimer(exec_ctx, t);
|
|
2237
|
+
}
|
|
2449
2238
|
}
|
|
2450
|
-
if (
|
|
2451
|
-
|
|
2239
|
+
if (error != GRPC_ERROR_CANCELLED) {
|
|
2240
|
+
grpc_resource_user_finish_reclamation(
|
|
2241
|
+
exec_ctx, grpc_endpoint_get_resource_user(t->ep));
|
|
2452
2242
|
}
|
|
2453
|
-
|
|
2243
|
+
GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "destructive_reclaimer");
|
|
2244
|
+
}
|
|
2245
|
+
|
|
2246
|
+
/*******************************************************************************
|
|
2247
|
+
* TRACING
|
|
2248
|
+
*/
|
|
2249
|
+
|
|
2250
|
+
static char *format_flowctl_context_var(const char *context, const char *var,
|
|
2251
|
+
int64_t val, uint32_t id) {
|
|
2252
|
+
char *name;
|
|
2253
|
+
if (context == NULL) {
|
|
2254
|
+
name = gpr_strdup(var);
|
|
2255
|
+
} else if (0 == strcmp(context, "t")) {
|
|
2256
|
+
GPR_ASSERT(id == 0);
|
|
2257
|
+
gpr_asprintf(&name, "TRANSPORT:%s", var);
|
|
2258
|
+
} else if (0 == strcmp(context, "s")) {
|
|
2259
|
+
GPR_ASSERT(id != 0);
|
|
2260
|
+
gpr_asprintf(&name, "STREAM[%d]:%s", id, var);
|
|
2261
|
+
} else {
|
|
2262
|
+
gpr_asprintf(&name, "BAD_CONTEXT[%s][%d]:%s", context, id, var);
|
|
2263
|
+
}
|
|
2264
|
+
char *name_fld = gpr_leftpad(name, ' ', 64);
|
|
2265
|
+
char *value;
|
|
2266
|
+
gpr_asprintf(&value, "%" PRId64, val);
|
|
2267
|
+
char *value_fld = gpr_leftpad(value, ' ', 8);
|
|
2268
|
+
char *result;
|
|
2269
|
+
gpr_asprintf(&result, "%s %s", name_fld, value_fld);
|
|
2270
|
+
gpr_free(name);
|
|
2271
|
+
gpr_free(name_fld);
|
|
2272
|
+
gpr_free(value);
|
|
2273
|
+
gpr_free(value_fld);
|
|
2274
|
+
return result;
|
|
2454
2275
|
}
|
|
2455
2276
|
|
|
2456
2277
|
void grpc_chttp2_flowctl_trace(const char *file, int line, const char *phase,
|
|
@@ -2458,26 +2279,18 @@ void grpc_chttp2_flowctl_trace(const char *file, int line, const char *phase,
|
|
|
2458
2279
|
const char *var1, const char *context2,
|
|
2459
2280
|
const char *var2, int is_client,
|
|
2460
2281
|
uint32_t stream_id, int64_t val1, int64_t val2) {
|
|
2461
|
-
char *scope1;
|
|
2462
|
-
char *scope2;
|
|
2463
2282
|
char *tmp_phase;
|
|
2464
|
-
char *
|
|
2465
|
-
char *
|
|
2466
|
-
format_flowctl_context_var(context1, var1, val1, stream_id, &scope1);
|
|
2467
|
-
char *label2 =
|
|
2468
|
-
format_flowctl_context_var(context2, var2, val2, stream_id, &scope2);
|
|
2283
|
+
char *label1 = format_flowctl_context_var(context1, var1, val1, stream_id);
|
|
2284
|
+
char *label2 = format_flowctl_context_var(context2, var2, val2, stream_id);
|
|
2469
2285
|
char *clisvr = is_client ? "client" : "server";
|
|
2470
2286
|
char *prefix;
|
|
2471
2287
|
|
|
2472
2288
|
tmp_phase = gpr_leftpad(phase, ' ', 8);
|
|
2473
|
-
|
|
2474
|
-
gpr_asprintf(&prefix, "FLOW %s: %s %s ", tmp_phase, clisvr, scope1);
|
|
2289
|
+
gpr_asprintf(&prefix, "FLOW %s: %s ", tmp_phase, clisvr);
|
|
2475
2290
|
gpr_free(tmp_phase);
|
|
2476
|
-
gpr_free(tmp_scope1);
|
|
2477
2291
|
|
|
2478
2292
|
switch (op) {
|
|
2479
2293
|
case GRPC_CHTTP2_FLOWCTL_MOVE:
|
|
2480
|
-
GPR_ASSERT(samestr(scope1, scope2));
|
|
2481
2294
|
if (val2 != 0) {
|
|
2482
2295
|
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
|
|
2483
2296
|
"%sMOVE %s <- %s giving %" PRId64, prefix, label1, label2,
|
|
@@ -2502,8 +2315,6 @@ void grpc_chttp2_flowctl_trace(const char *file, int line, const char *phase,
|
|
|
2502
2315
|
break;
|
|
2503
2316
|
}
|
|
2504
2317
|
|
|
2505
|
-
gpr_free(scope1);
|
|
2506
|
-
gpr_free(scope2);
|
|
2507
2318
|
gpr_free(label1);
|
|
2508
2319
|
gpr_free(label2);
|
|
2509
2320
|
gpr_free(prefix);
|
|
@@ -2517,6 +2328,14 @@ static char *chttp2_get_peer(grpc_exec_ctx *exec_ctx, grpc_transport *t) {
|
|
|
2517
2328
|
return gpr_strdup(((grpc_chttp2_transport *)t)->peer_string);
|
|
2518
2329
|
}
|
|
2519
2330
|
|
|
2331
|
+
/*******************************************************************************
|
|
2332
|
+
* MONITORING
|
|
2333
|
+
*/
|
|
2334
|
+
static grpc_endpoint *chttp2_get_endpoint(grpc_exec_ctx *exec_ctx,
|
|
2335
|
+
grpc_transport *t) {
|
|
2336
|
+
return ((grpc_chttp2_transport *)t)->ep;
|
|
2337
|
+
}
|
|
2338
|
+
|
|
2520
2339
|
static const grpc_transport_vtable vtable = {sizeof(grpc_chttp2_stream),
|
|
2521
2340
|
"chttp2",
|
|
2522
2341
|
init_stream,
|
|
@@ -2526,7 +2345,8 @@ static const grpc_transport_vtable vtable = {sizeof(grpc_chttp2_stream),
|
|
|
2526
2345
|
perform_transport_op,
|
|
2527
2346
|
destroy_stream,
|
|
2528
2347
|
destroy_transport,
|
|
2529
|
-
chttp2_get_peer
|
|
2348
|
+
chttp2_get_peer,
|
|
2349
|
+
chttp2_get_endpoint};
|
|
2530
2350
|
|
|
2531
2351
|
grpc_transport *grpc_create_chttp2_transport(
|
|
2532
2352
|
grpc_exec_ctx *exec_ctx, const grpc_channel_args *channel_args,
|
|
@@ -2538,9 +2358,13 @@ grpc_transport *grpc_create_chttp2_transport(
|
|
|
2538
2358
|
|
|
2539
2359
|
void grpc_chttp2_transport_start_reading(grpc_exec_ctx *exec_ctx,
|
|
2540
2360
|
grpc_transport *transport,
|
|
2541
|
-
|
|
2361
|
+
grpc_slice_buffer *read_buffer) {
|
|
2542
2362
|
grpc_chttp2_transport *t = (grpc_chttp2_transport *)transport;
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2363
|
+
GRPC_CHTTP2_REF_TRANSPORT(
|
|
2364
|
+
t, "reading_action"); /* matches unref inside reading_action */
|
|
2365
|
+
if (read_buffer != NULL) {
|
|
2366
|
+
grpc_slice_buffer_move_into(read_buffer, &t->read_buffer);
|
|
2367
|
+
gpr_free(read_buffer);
|
|
2368
|
+
}
|
|
2369
|
+
grpc_closure_sched(exec_ctx, &t->read_action_locked, GRPC_ERROR_NONE);
|
|
2546
2370
|
}
|