grpc 1.0.0.pre1 → 1.0.0.pre2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of grpc might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Makefile +1 -37
- data/include/grpc/impl/codegen/compression_types.h +16 -1
- data/include/grpc/impl/codegen/grpc_types.h +23 -15
- data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c +4 -2
- data/src/core/ext/transport/chttp2/transport/chttp2_plugin.c +3 -0
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.c +305 -64
- data/src/core/ext/transport/chttp2/transport/internal.h +46 -19
- data/src/core/ext/transport/chttp2/transport/parsing.c +6 -5
- data/src/core/ext/transport/chttp2/transport/stream_lists.c +11 -9
- data/src/core/ext/transport/chttp2/transport/writing.c +13 -3
- data/src/core/lib/iomgr/endpoint.c +4 -0
- data/src/core/lib/iomgr/endpoint.h +4 -0
- data/src/core/lib/iomgr/ev_epoll_linux.c +161 -116
- data/src/core/lib/iomgr/ev_poll_and_epoll_posix.c +3 -0
- data/src/core/lib/iomgr/ev_poll_posix.c +3 -0
- data/src/core/lib/iomgr/ev_posix.c +4 -0
- data/src/core/lib/iomgr/ev_posix.h +4 -0
- data/src/core/lib/iomgr/exec_ctx.c +7 -3
- data/src/core/lib/iomgr/exec_ctx.h +5 -1
- data/src/core/lib/iomgr/iomgr.c +3 -0
- data/src/core/lib/iomgr/network_status_tracker.c +9 -6
- data/src/core/lib/iomgr/network_status_tracker.h +4 -0
- data/src/core/lib/iomgr/tcp_posix.c +14 -4
- data/src/core/lib/iomgr/tcp_server_posix.c +2 -1
- data/src/core/lib/iomgr/tcp_windows.c +10 -3
- data/src/core/lib/iomgr/workqueue.h +25 -14
- data/src/core/lib/iomgr/workqueue_posix.c +1 -7
- data/src/core/lib/iomgr/workqueue_posix.h +5 -0
- data/src/core/lib/iomgr/workqueue_windows.c +22 -0
- data/src/core/lib/security/transport/secure_endpoint.c +13 -5
- data/src/core/lib/support/log.c +10 -9
- data/src/core/lib/surface/server.c +45 -31
- data/src/core/lib/surface/version.c +1 -1
- data/src/core/lib/transport/connectivity_state.c +3 -0
- data/src/ruby/bin/math_client.rb +1 -1
- data/src/ruby/bin/{math.rb → math_pb.rb} +0 -0
- data/src/ruby/bin/math_server.rb +1 -1
- data/src/ruby/bin/{math_services.rb → math_services_pb.rb} +4 -4
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/src/ruby/pb/grpc/health/checker.rb +1 -1
- data/src/ruby/pb/grpc/health/v1/{health.rb → health_pb.rb} +0 -0
- data/src/ruby/pb/grpc/health/v1/{health_services.rb → health_services_pb.rb} +1 -1
- data/src/ruby/pb/grpc/testing/duplicate/{echo_duplicate_services.rb → echo_duplicate_services_pb.rb} +2 -2
- data/src/ruby/pb/grpc/testing/{metrics.rb → metrics_pb.rb} +1 -1
- data/src/ruby/pb/grpc/testing/{metrics_services.rb → metrics_services_pb.rb} +2 -2
- data/src/ruby/pb/src/proto/grpc/testing/{empty.rb → empty_pb.rb} +0 -0
- data/src/ruby/pb/src/proto/grpc/testing/{messages.rb → messages_pb.rb} +8 -10
- data/src/ruby/pb/src/proto/grpc/testing/{test.rb → test_pb.rb} +2 -2
- data/src/ruby/pb/src/proto/grpc/testing/{test_services.rb → test_services_pb.rb} +1 -1
- data/src/ruby/pb/test/client.rb +3 -3
- data/src/ruby/pb/test/server.rb +3 -3
- data/src/ruby/spec/pb/duplicate/codegen_spec.rb +2 -2
- data/src/ruby/spec/pb/health/checker_spec.rb +4 -4
- metadata +15 -19
- data/src/ruby/pb/test/proto/empty.rb +0 -15
- data/src/ruby/pb/test/proto/messages.rb +0 -80
- data/src/ruby/pb/test/proto/test.rb +0 -14
- data/src/ruby/pb/test/proto/test_services.rb +0 -64
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a66bb42d25ec71cb62d54fa3fb51c4079daac412
|
4
|
+
data.tar.gz: 2c50fc771054f69a4d0ff9ca0724bbb65eeca137
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 14cebd91ffce3a5b0ce44cb8ae37be42cfb39a60aa566d15c0efce6caa65805096540fd2ac6917c6877e5c915b36fd058155794dfc3b0ee2d980a187e4756a6a
|
7
|
+
data.tar.gz: d047c9804da730b19f1bd8faf43a8231e12ab4cf8d0eb889f643a25de6890582ec929ba50465331d93ac62dd2bd9f69eebd588cfe09ad8c6eceb4b5dff6d7077
|
data/Makefile
CHANGED
@@ -415,7 +415,7 @@ E = @echo
|
|
415
415
|
Q = @
|
416
416
|
endif
|
417
417
|
|
418
|
-
VERSION = 1.0.0-
|
418
|
+
VERSION = 1.0.0-pre2
|
419
419
|
|
420
420
|
CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES))
|
421
421
|
CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS)
|
@@ -991,7 +991,6 @@ transport_security_test: $(BINDIR)/$(CONFIG)/transport_security_test
|
|
991
991
|
udp_server_test: $(BINDIR)/$(CONFIG)/udp_server_test
|
992
992
|
uri_fuzzer_test: $(BINDIR)/$(CONFIG)/uri_fuzzer_test
|
993
993
|
uri_parser_test: $(BINDIR)/$(CONFIG)/uri_parser_test
|
994
|
-
workqueue_test: $(BINDIR)/$(CONFIG)/workqueue_test
|
995
994
|
alarm_cpp_test: $(BINDIR)/$(CONFIG)/alarm_cpp_test
|
996
995
|
async_end2end_test: $(BINDIR)/$(CONFIG)/async_end2end_test
|
997
996
|
auth_property_iterator_test: $(BINDIR)/$(CONFIG)/auth_property_iterator_test
|
@@ -1295,7 +1294,6 @@ buildtests_c: privatelibs_c \
|
|
1295
1294
|
$(BINDIR)/$(CONFIG)/transport_security_test \
|
1296
1295
|
$(BINDIR)/$(CONFIG)/udp_server_test \
|
1297
1296
|
$(BINDIR)/$(CONFIG)/uri_parser_test \
|
1298
|
-
$(BINDIR)/$(CONFIG)/workqueue_test \
|
1299
1297
|
$(BINDIR)/$(CONFIG)/public_headers_must_be_c89 \
|
1300
1298
|
$(BINDIR)/$(CONFIG)/badreq_bad_client_test \
|
1301
1299
|
$(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test \
|
@@ -1674,8 +1672,6 @@ test_c: buildtests_c
|
|
1674
1672
|
$(Q) $(BINDIR)/$(CONFIG)/udp_server_test || ( echo test udp_server_test failed ; exit 1 )
|
1675
1673
|
$(E) "[RUN] Testing uri_parser_test"
|
1676
1674
|
$(Q) $(BINDIR)/$(CONFIG)/uri_parser_test || ( echo test uri_parser_test failed ; exit 1 )
|
1677
|
-
$(E) "[RUN] Testing workqueue_test"
|
1678
|
-
$(Q) $(BINDIR)/$(CONFIG)/workqueue_test || ( echo test workqueue_test failed ; exit 1 )
|
1679
1675
|
$(E) "[RUN] Testing public_headers_must_be_c89"
|
1680
1676
|
$(Q) $(BINDIR)/$(CONFIG)/public_headers_must_be_c89 || ( echo test public_headers_must_be_c89 failed ; exit 1 )
|
1681
1677
|
$(E) "[RUN] Testing badreq_bad_client_test"
|
@@ -10175,38 +10171,6 @@ endif
|
|
10175
10171
|
endif
|
10176
10172
|
|
10177
10173
|
|
10178
|
-
WORKQUEUE_TEST_SRC = \
|
10179
|
-
test/core/iomgr/workqueue_test.c \
|
10180
|
-
|
10181
|
-
WORKQUEUE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(WORKQUEUE_TEST_SRC))))
|
10182
|
-
ifeq ($(NO_SECURE),true)
|
10183
|
-
|
10184
|
-
# You can't build secure targets if you don't have OpenSSL.
|
10185
|
-
|
10186
|
-
$(BINDIR)/$(CONFIG)/workqueue_test: openssl_dep_error
|
10187
|
-
|
10188
|
-
else
|
10189
|
-
|
10190
|
-
|
10191
|
-
|
10192
|
-
$(BINDIR)/$(CONFIG)/workqueue_test: $(WORKQUEUE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
|
10193
|
-
$(E) "[LD] Linking $@"
|
10194
|
-
$(Q) mkdir -p `dirname $@`
|
10195
|
-
$(Q) $(LD) $(LDFLAGS) $(WORKQUEUE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/workqueue_test
|
10196
|
-
|
10197
|
-
endif
|
10198
|
-
|
10199
|
-
$(OBJDIR)/$(CONFIG)/test/core/iomgr/workqueue_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
|
10200
|
-
|
10201
|
-
deps_workqueue_test: $(WORKQUEUE_TEST_OBJS:.o=.dep)
|
10202
|
-
|
10203
|
-
ifneq ($(NO_SECURE),true)
|
10204
|
-
ifneq ($(NO_DEPS),true)
|
10205
|
-
-include $(WORKQUEUE_TEST_OBJS:.o=.dep)
|
10206
|
-
endif
|
10207
|
-
endif
|
10208
|
-
|
10209
|
-
|
10210
10174
|
ALARM_CPP_TEST_SRC = \
|
10211
10175
|
test/cpp/common/alarm_cpp_test.cc \
|
10212
10176
|
|
@@ -46,12 +46,27 @@ extern "C" {
|
|
46
46
|
#define GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY \
|
47
47
|
"grpc-internal-encoding-request"
|
48
48
|
|
49
|
-
/** To be used in channel arguments
|
49
|
+
/** To be used in channel arguments.
|
50
|
+
*
|
51
|
+
* \addtogroup grpc_arg_keys
|
52
|
+
* \{ */
|
53
|
+
/** Default compression algorithm for the channel.
|
54
|
+
* Its value is an int from the \a grpc_compression_algorithm enum. */
|
50
55
|
#define GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM \
|
51
56
|
"grpc.default_compression_algorithm"
|
57
|
+
/** Default compression level for the channel.
|
58
|
+
* Its value is an int from the \a grpc_compression_level enum. */
|
52
59
|
#define GRPC_COMPRESSION_CHANNEL_DEFAULT_LEVEL "grpc.default_compression_level"
|
60
|
+
/** Compression algorithms supported by the channel.
|
61
|
+
* Its value is a bitset (an int). Bits correspond to algorithms in \a
|
62
|
+
* grpc_compression_algorithm. For example, its LSB corresponds to
|
63
|
+
* GRPC_COMPRESS_NONE, the next bit to GRPC_COMPRESS_DEFLATE, etc.
|
64
|
+
* Unset bits disable support for the algorithm. By default all algorithms are
|
65
|
+
* supported. It's not possible to disable GRPC_COMPRESS_NONE (the attempt will
|
66
|
+
* be ignored). */
|
53
67
|
#define GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET \
|
54
68
|
"grpc.compression_enabled_algorithms_bitset"
|
69
|
+
/** \} */
|
55
70
|
|
56
71
|
/* The various compression algorithms supported by gRPC */
|
57
72
|
typedef enum {
|
@@ -106,58 +106,66 @@ typedef struct {
|
|
106
106
|
by grpc_arg; keys are strings to allow easy backwards-compatible extension
|
107
107
|
by arbitrary parties.
|
108
108
|
All evaluation is performed at channel creation time (i.e. the values in
|
109
|
-
this structure need only live through the creation invocation).
|
109
|
+
this structure need only live through the creation invocation).
|
110
|
+
|
111
|
+
See the description of the \ref grpc_arg_keys "available args" for more
|
112
|
+
details. */
|
110
113
|
typedef struct {
|
111
114
|
size_t num_args;
|
112
115
|
grpc_arg *args;
|
113
116
|
} grpc_channel_args;
|
114
117
|
|
115
|
-
|
116
|
-
|
118
|
+
/** \defgroup grpc_arg_keys
|
119
|
+
* Channel argument keys.
|
120
|
+
* \{
|
121
|
+
*/
|
122
|
+
/** If non-zero, enable census for tracing and stats collection. */
|
117
123
|
#define GRPC_ARG_ENABLE_CENSUS "grpc.census"
|
118
|
-
/**
|
124
|
+
/** If non-zero, enable load reporting. */
|
119
125
|
#define GRPC_ARG_ENABLE_LOAD_REPORTING "grpc.loadreporting"
|
120
126
|
/** Maximum number of concurrent incoming streams to allow on a http2
|
121
|
-
connection */
|
127
|
+
connection. Int valued. */
|
122
128
|
#define GRPC_ARG_MAX_CONCURRENT_STREAMS "grpc.max_concurrent_streams"
|
123
|
-
/** Maximum message length that the channel can receive */
|
129
|
+
/** Maximum message length that the channel can receive. Int valued, bytes. */
|
124
130
|
#define GRPC_ARG_MAX_MESSAGE_LENGTH "grpc.max_message_length"
|
125
|
-
/** Initial sequence number for http2 transports */
|
131
|
+
/** Initial sequence number for http2 transports. Int valued. */
|
126
132
|
#define GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER \
|
127
133
|
"grpc.http2.initial_sequence_number"
|
128
134
|
/** Amount to read ahead on individual streams. Defaults to 64kb, larger
|
129
135
|
values can help throughput on high-latency connections.
|
130
136
|
NOTE: at some point we'd like to auto-tune this, and this parameter
|
131
|
-
will become a no-op. */
|
137
|
+
will become a no-op. Int valued, bytes. */
|
132
138
|
#define GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES "grpc.http2.lookahead_bytes"
|
133
|
-
/** How much memory to use for hpack decoding */
|
139
|
+
/** How much memory to use for hpack decoding. Int valued, bytes. */
|
134
140
|
#define GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER \
|
135
141
|
"grpc.http2.hpack_table_size.decoder"
|
136
|
-
/** How much memory to use for hpack encoding */
|
142
|
+
/** How much memory to use for hpack encoding. Int valued, bytes. */
|
137
143
|
#define GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_ENCODER \
|
138
144
|
"grpc.http2.hpack_table_size.encoder"
|
139
|
-
/** Default authority to pass if none specified on call construction
|
145
|
+
/** Default authority to pass if none specified on call construction. A string.
|
146
|
+
* */
|
140
147
|
#define GRPC_ARG_DEFAULT_AUTHORITY "grpc.default_authority"
|
141
148
|
/** Primary user agent: goes at the start of the user-agent metadata
|
142
|
-
sent on each request */
|
149
|
+
sent on each request. A string. */
|
143
150
|
#define GRPC_ARG_PRIMARY_USER_AGENT_STRING "grpc.primary_user_agent"
|
144
151
|
/** Secondary user agent: goes at the end of the user-agent metadata
|
145
|
-
sent on each request */
|
152
|
+
sent on each request. A string. */
|
146
153
|
#define GRPC_ARG_SECONDARY_USER_AGENT_STRING "grpc.secondary_user_agent"
|
147
154
|
/** The maximum time between subsequent connection attempts, in ms */
|
148
155
|
#define GRPC_ARG_MAX_RECONNECT_BACKOFF_MS "grpc.max_reconnect_backoff_ms"
|
149
156
|
/* The caller of the secure_channel_create functions may override the target
|
150
157
|
name used for SSL host name checking using this channel argument which is of
|
151
|
-
type GRPC_ARG_STRING. This *should* be used for testing only.
|
158
|
+
type \a GRPC_ARG_STRING. This *should* be used for testing only.
|
152
159
|
If this argument is not specified, the name used for SSL host name checking
|
153
160
|
will be the target parameter (assuming that the secure channel is an SSL
|
154
161
|
channel). If this parameter is specified and the underlying is not an SSL
|
155
162
|
channel, it will just be ignored. */
|
156
163
|
#define GRPC_SSL_TARGET_NAME_OVERRIDE_ARG "grpc.ssl_target_name_override"
|
157
|
-
/* Maximum metadata size */
|
164
|
+
/* Maximum metadata size, in bytes. */
|
158
165
|
#define GRPC_ARG_MAX_METADATA_SIZE "grpc.max_metadata_size"
|
159
166
|
/** If non-zero, allow the use of SO_REUSEPORT if it's available (default 1) */
|
160
167
|
#define GRPC_ARG_ALLOW_REUSEPORT "grpc.so_reuseport"
|
168
|
+
/** \} */
|
161
169
|
|
162
170
|
/** Result of a grpc call. If the caller satisfies the prerequisites of a
|
163
171
|
particular operation, the grpc_call_error returned will be GRPC_CALL_OK.
|
@@ -91,11 +91,13 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *arg,
|
|
91
91
|
connector *c = arg;
|
92
92
|
grpc_closure *notify;
|
93
93
|
gpr_mu_lock(&c->mu);
|
94
|
+
grpc_error *error = GRPC_ERROR_NONE;
|
94
95
|
if (c->connecting_endpoint == NULL) {
|
95
96
|
memset(c->result, 0, sizeof(*c->result));
|
96
97
|
gpr_mu_unlock(&c->mu);
|
97
98
|
} else if (status != GRPC_SECURITY_OK) {
|
98
|
-
|
99
|
+
error = grpc_error_set_int(GRPC_ERROR_CREATE("Secure handshake failed"),
|
100
|
+
GRPC_ERROR_INT_SECURITY_STATUS, status);
|
99
101
|
memset(c->result, 0, sizeof(*c->result));
|
100
102
|
c->connecting_endpoint = NULL;
|
101
103
|
gpr_mu_unlock(&c->mu);
|
@@ -113,7 +115,7 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *arg,
|
|
113
115
|
}
|
114
116
|
notify = c->notify;
|
115
117
|
c->notify = NULL;
|
116
|
-
grpc_exec_ctx_sched(exec_ctx, notify,
|
118
|
+
grpc_exec_ctx_sched(exec_ctx, notify, error, NULL);
|
117
119
|
}
|
118
120
|
|
119
121
|
static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg,
|
@@ -36,11 +36,14 @@
|
|
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
|
+
|
39
41
|
void grpc_chttp2_plugin_init(void) {
|
40
42
|
grpc_chttp2_base64_encode_and_huffman_compress =
|
41
43
|
grpc_chttp2_base64_encode_and_huffman_compress_impl;
|
42
44
|
grpc_register_tracer("http", &grpc_http_trace);
|
43
45
|
grpc_register_tracer("flowctl", &grpc_flowctl_trace);
|
46
|
+
grpc_register_tracer("http_write_state", &grpc_http_write_state_trace);
|
44
47
|
}
|
45
48
|
|
46
49
|
void grpc_chttp2_plugin_shutdown(void) {}
|
@@ -48,6 +48,7 @@
|
|
48
48
|
#include "src/core/ext/transport/chttp2/transport/status_conversion.h"
|
49
49
|
#include "src/core/ext/transport/chttp2/transport/timeout_encoding.h"
|
50
50
|
#include "src/core/lib/http/parser.h"
|
51
|
+
#include "src/core/lib/iomgr/workqueue.h"
|
51
52
|
#include "src/core/lib/profiling/timers.h"
|
52
53
|
#include "src/core/lib/support/string.h"
|
53
54
|
#include "src/core/lib/transport/static_metadata.h"
|
@@ -60,9 +61,9 @@
|
|
60
61
|
#define DEFAULT_MAX_HEADER_LIST_SIZE (16 * 1024)
|
61
62
|
|
62
63
|
#define MAX_CLIENT_STREAM_ID 0x7fffffffu
|
63
|
-
|
64
64
|
int grpc_http_trace = 0;
|
65
65
|
int grpc_flowctl_trace = 0;
|
66
|
+
int grpc_http_write_state_trace = 0;
|
66
67
|
|
67
68
|
#define TRANSPORT_FROM_WRITING(tw) \
|
68
69
|
((grpc_chttp2_transport *)((char *)(tw)-offsetof(grpc_chttp2_transport, \
|
@@ -88,10 +89,16 @@ static const grpc_transport_vtable vtable;
|
|
88
89
|
static void writing_action(grpc_exec_ctx *exec_ctx, void *t, grpc_error *error);
|
89
90
|
static void reading_action(grpc_exec_ctx *exec_ctx, void *t, grpc_error *error);
|
90
91
|
static void parsing_action(grpc_exec_ctx *exec_ctx, void *t, grpc_error *error);
|
92
|
+
static void initiate_writing(grpc_exec_ctx *exec_ctx, void *t,
|
93
|
+
grpc_error *error);
|
94
|
+
|
95
|
+
static void start_writing(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t);
|
96
|
+
static void end_waiting_for_write(grpc_exec_ctx *exec_ctx,
|
97
|
+
grpc_chttp2_transport *t, grpc_error *error);
|
91
98
|
|
92
99
|
/** Set a transport level setting, and push it to our peer */
|
93
|
-
static void push_setting(
|
94
|
-
uint32_t value);
|
100
|
+
static void push_setting(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
101
|
+
grpc_chttp2_setting_id id, uint32_t value);
|
95
102
|
|
96
103
|
/** Start disconnection chain */
|
97
104
|
static void drop_connection(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
@@ -137,7 +144,7 @@ static void check_read_ops(grpc_exec_ctx *exec_ctx,
|
|
137
144
|
grpc_chttp2_transport_global *transport_global);
|
138
145
|
|
139
146
|
static void incoming_byte_stream_update_flow_control(
|
140
|
-
grpc_chttp2_transport_global *transport_global,
|
147
|
+
grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global,
|
141
148
|
grpc_chttp2_stream_global *stream_global, size_t max_size_hint,
|
142
149
|
size_t have_already);
|
143
150
|
static void incoming_byte_stream_destroy_locked(grpc_exec_ctx *exec_ctx,
|
@@ -201,6 +208,7 @@ static void destruct_transport(grpc_exec_ctx *exec_ctx,
|
|
201
208
|
gpr_free(t);
|
202
209
|
}
|
203
210
|
|
211
|
+
/*#define REFCOUNTING_DEBUG 1*/
|
204
212
|
#ifdef REFCOUNTING_DEBUG
|
205
213
|
#define REF_TRANSPORT(t, r) ref_transport(t, r, __FILE__, __LINE__)
|
206
214
|
#define UNREF_TRANSPORT(cl, t, r) unref_transport(cl, t, r, __FILE__, __LINE__)
|
@@ -231,7 +239,7 @@ static void ref_transport(grpc_chttp2_transport *t) { gpr_ref(&t->refs); }
|
|
231
239
|
|
232
240
|
static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
233
241
|
const grpc_channel_args *channel_args,
|
234
|
-
grpc_endpoint *ep,
|
242
|
+
grpc_endpoint *ep, bool is_client) {
|
235
243
|
size_t i;
|
236
244
|
int j;
|
237
245
|
|
@@ -273,6 +281,7 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
273
281
|
grpc_closure_init(&t->writing_action, writing_action, t);
|
274
282
|
grpc_closure_init(&t->reading_action, reading_action, t);
|
275
283
|
grpc_closure_init(&t->parsing_action, parsing_action, t);
|
284
|
+
grpc_closure_init(&t->initiate_writing, initiate_writing, t);
|
276
285
|
|
277
286
|
gpr_slice_buffer_init(&t->parsing.qbuf);
|
278
287
|
grpc_chttp2_goaway_parser_init(&t->parsing.goaway_parser);
|
@@ -286,6 +295,7 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
286
295
|
gpr_slice_buffer_add(
|
287
296
|
&t->global.qbuf,
|
288
297
|
gpr_slice_from_copied_string(GRPC_CHTTP2_CLIENT_CONNECT_STRING));
|
298
|
+
grpc_chttp2_initiate_write(exec_ctx, &t->global, false, "initial_write");
|
289
299
|
}
|
290
300
|
/* 8 is a random stab in the dark as to a good initial size: it's small enough
|
291
301
|
that it shouldn't waste memory for infrequently used connections, yet
|
@@ -311,11 +321,12 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
311
321
|
|
312
322
|
/* configure http2 the way we like it */
|
313
323
|
if (is_client) {
|
314
|
-
push_setting(t, GRPC_CHTTP2_SETTINGS_ENABLE_PUSH, 0);
|
315
|
-
push_setting(t, GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, 0);
|
324
|
+
push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_ENABLE_PUSH, 0);
|
325
|
+
push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, 0);
|
316
326
|
}
|
317
|
-
push_setting(t, GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE,
|
318
|
-
|
327
|
+
push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE,
|
328
|
+
DEFAULT_WINDOW);
|
329
|
+
push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE,
|
319
330
|
DEFAULT_MAX_HEADER_LIST_SIZE);
|
320
331
|
|
321
332
|
if (channel_args) {
|
@@ -329,7 +340,7 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
329
340
|
gpr_log(GPR_ERROR, "%s: must be an integer",
|
330
341
|
GRPC_ARG_MAX_CONCURRENT_STREAMS);
|
331
342
|
} else {
|
332
|
-
push_setting(t, GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS,
|
343
|
+
push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS,
|
333
344
|
(uint32_t)channel_args->args[i].value.integer);
|
334
345
|
}
|
335
346
|
} else if (0 == strcmp(channel_args->args[i].key,
|
@@ -368,7 +379,7 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
368
379
|
gpr_log(GPR_ERROR, "%s: must be non-negative",
|
369
380
|
GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER);
|
370
381
|
} else {
|
371
|
-
push_setting(t, GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE,
|
382
|
+
push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE,
|
372
383
|
(uint32_t)channel_args->args[i].value.integer);
|
373
384
|
}
|
374
385
|
} else if (0 == strcmp(channel_args->args[i].key,
|
@@ -393,7 +404,7 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
393
404
|
gpr_log(GPR_ERROR, "%s: must be non-negative",
|
394
405
|
GRPC_ARG_MAX_METADATA_SIZE);
|
395
406
|
} else {
|
396
|
-
push_setting(t, GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE,
|
407
|
+
push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE,
|
397
408
|
(uint32_t)channel_args->args[i].value.integer);
|
398
409
|
}
|
399
410
|
}
|
@@ -444,6 +455,9 @@ static void close_transport_locked(grpc_exec_ctx *exec_ctx,
|
|
444
455
|
grpc_chttp2_transport *t,
|
445
456
|
grpc_error *error) {
|
446
457
|
if (!t->closed) {
|
458
|
+
if (grpc_http_write_state_trace) {
|
459
|
+
gpr_log(GPR_DEBUG, "W:%p close transport", t);
|
460
|
+
}
|
447
461
|
t->closed = 1;
|
448
462
|
connectivity_state_set(exec_ctx, &t->global, GRPC_CHANNEL_SHUTDOWN,
|
449
463
|
GRPC_ERROR_REF(error), "close_transport");
|
@@ -590,7 +604,8 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx,
|
|
590
604
|
grpc_chttp2_incoming_metadata_buffer_destroy(
|
591
605
|
&s->global.received_trailing_metadata);
|
592
606
|
gpr_slice_buffer_destroy(&s->writing.flow_controlled_buffer);
|
593
|
-
GRPC_ERROR_UNREF(s->global.
|
607
|
+
GRPC_ERROR_UNREF(s->global.read_closed_error);
|
608
|
+
GRPC_ERROR_UNREF(s->global.write_closed_error);
|
594
609
|
|
595
610
|
UNREF_TRANSPORT(exec_ctx, t, "stream");
|
596
611
|
|
@@ -634,6 +649,36 @@ grpc_chttp2_stream_parsing *grpc_chttp2_parsing_accept_stream(
|
|
634
649
|
* LOCK MANAGEMENT
|
635
650
|
*/
|
636
651
|
|
652
|
+
static const char *write_state_name(grpc_chttp2_write_state state) {
|
653
|
+
switch (state) {
|
654
|
+
case GRPC_CHTTP2_WRITING_INACTIVE:
|
655
|
+
return "INACTIVE";
|
656
|
+
case GRPC_CHTTP2_WRITE_REQUESTED_NO_POLLER:
|
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:
|
663
|
+
return "WRITING";
|
664
|
+
case GRPC_CHTTP2_WRITING_STALE_WITH_POLLER:
|
665
|
+
return "WRITING[p=1]";
|
666
|
+
case GRPC_CHTTP2_WRITING_STALE_NO_POLLER:
|
667
|
+
return "WRITING[p=0]";
|
668
|
+
}
|
669
|
+
GPR_UNREACHABLE_CODE(return "UNKNOWN");
|
670
|
+
}
|
671
|
+
|
672
|
+
static void set_write_state(grpc_chttp2_transport *t,
|
673
|
+
grpc_chttp2_write_state state, const char *reason) {
|
674
|
+
if (grpc_http_write_state_trace) {
|
675
|
+
gpr_log(GPR_DEBUG, "W:%p %s -> %s because %s", t,
|
676
|
+
write_state_name(t->executor.write_state), write_state_name(state),
|
677
|
+
reason);
|
678
|
+
}
|
679
|
+
t->executor.write_state = state;
|
680
|
+
}
|
681
|
+
|
637
682
|
static void finish_global_actions(grpc_exec_ctx *exec_ctx,
|
638
683
|
grpc_chttp2_transport *t) {
|
639
684
|
grpc_chttp2_executor_action_header *hdr;
|
@@ -642,13 +687,6 @@ static void finish_global_actions(grpc_exec_ctx *exec_ctx,
|
|
642
687
|
GPR_TIMER_BEGIN("finish_global_actions", 0);
|
643
688
|
|
644
689
|
for (;;) {
|
645
|
-
if (!t->executor.writing_active && !t->closed &&
|
646
|
-
grpc_chttp2_unlocking_check_writes(exec_ctx, &t->global, &t->writing)) {
|
647
|
-
t->executor.writing_active = 1;
|
648
|
-
REF_TRANSPORT(t, "writing");
|
649
|
-
prevent_endpoint_shutdown(t);
|
650
|
-
grpc_exec_ctx_sched(exec_ctx, &t->writing_action, GRPC_ERROR_NONE, NULL);
|
651
|
-
}
|
652
690
|
check_read_ops(exec_ctx, &t->global);
|
653
691
|
|
654
692
|
gpr_mu_lock(&t->executor.mu);
|
@@ -669,8 +707,28 @@ static void finish_global_actions(grpc_exec_ctx *exec_ctx,
|
|
669
707
|
continue;
|
670
708
|
} else {
|
671
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
|
+
}
|
672
731
|
}
|
673
|
-
gpr_mu_unlock(&t->executor.mu);
|
674
732
|
break;
|
675
733
|
}
|
676
734
|
|
@@ -741,16 +799,118 @@ void grpc_chttp2_run_with_global_lock(grpc_exec_ctx *exec_ctx,
|
|
741
799
|
* OUTPUT PROCESSING
|
742
800
|
*/
|
743
801
|
|
744
|
-
void
|
745
|
-
|
802
|
+
void grpc_chttp2_initiate_write(grpc_exec_ctx *exec_ctx,
|
803
|
+
grpc_chttp2_transport_global *transport_global,
|
804
|
+
bool covered_by_poller, const char *reason) {
|
805
|
+
/* Perform state checks, and transition to a scheduled state if appropriate.
|
806
|
+
Each time we finish the global lock execution, we check if we need to
|
807
|
+
write. If we do:
|
808
|
+
- (if there is a poller surrounding the write) schedule
|
809
|
+
initiate_writing, which locks and calls initiate_writing_locked to...
|
810
|
+
- call start_writing, which verifies (under the global lock) that there
|
811
|
+
are things that need to be written by calling
|
812
|
+
grpc_chttp2_unlocking_check_writes, and if so schedules writing_action
|
813
|
+
against the current exec_ctx, to be executed OUTSIDE of the global lock
|
814
|
+
- eventually writing_action results in grpc_chttp2_terminate_writing being
|
815
|
+
called, which re-takes the global lock, updates state, checks if we need
|
816
|
+
to do *another* write immediately, and if so loops back to
|
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);
|
831
|
+
break;
|
832
|
+
case GRPC_CHTTP2_WRITE_REQUESTED_WITH_POLLER:
|
833
|
+
/* nothing to do: write already requested */
|
834
|
+
break;
|
835
|
+
case GRPC_CHTTP2_WRITE_REQUESTED_NO_POLLER:
|
836
|
+
if (covered_by_poller) {
|
837
|
+
/* upgrade to note poller is available to cover the write */
|
838
|
+
set_write_state(t, GRPC_CHTTP2_WRITE_REQUESTED_WITH_POLLER, reason);
|
839
|
+
}
|
840
|
+
break;
|
841
|
+
case GRPC_CHTTP2_WRITE_SCHEDULED:
|
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);
|
849
|
+
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
|
+
}
|
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);
|
898
|
+
}
|
899
|
+
|
900
|
+
void grpc_chttp2_become_writable(grpc_exec_ctx *exec_ctx,
|
901
|
+
grpc_chttp2_transport_global *transport_global,
|
902
|
+
grpc_chttp2_stream_global *stream_global,
|
903
|
+
bool covered_by_poller, const char *reason) {
|
746
904
|
if (!TRANSPORT_FROM_GLOBAL(transport_global)->closed &&
|
747
905
|
grpc_chttp2_list_add_writable_stream(transport_global, stream_global)) {
|
748
906
|
GRPC_CHTTP2_STREAM_REF(stream_global, "chttp2_writing");
|
907
|
+
grpc_chttp2_initiate_write(exec_ctx, transport_global, covered_by_poller,
|
908
|
+
reason);
|
749
909
|
}
|
750
910
|
}
|
751
911
|
|
752
|
-
static void push_setting(
|
753
|
-
uint32_t value) {
|
912
|
+
static void push_setting(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
913
|
+
grpc_chttp2_setting_id id, uint32_t value) {
|
754
914
|
const grpc_chttp2_setting_parameters *sp =
|
755
915
|
&grpc_chttp2_settings_parameters[id];
|
756
916
|
uint32_t use_value = GPR_CLAMP(value, sp->min_value, sp->max_value);
|
@@ -761,9 +921,22 @@ static void push_setting(grpc_chttp2_transport *t, grpc_chttp2_setting_id id,
|
|
761
921
|
if (use_value != t->global.settings[GRPC_LOCAL_SETTINGS][id]) {
|
762
922
|
t->global.settings[GRPC_LOCAL_SETTINGS][id] = use_value;
|
763
923
|
t->global.dirtied_local_settings = 1;
|
924
|
+
grpc_chttp2_initiate_write(exec_ctx, &t->global, false, "push_setting");
|
764
925
|
}
|
765
926
|
}
|
766
927
|
|
928
|
+
static void end_waiting_for_write(grpc_exec_ctx *exec_ctx,
|
929
|
+
grpc_chttp2_transport *t, grpc_error *error) {
|
930
|
+
grpc_chttp2_stream_global *stream_global;
|
931
|
+
while (grpc_chttp2_list_pop_closed_waiting_for_writing(&t->global,
|
932
|
+
&stream_global)) {
|
933
|
+
fail_pending_writes(exec_ctx, &t->global, stream_global,
|
934
|
+
GRPC_ERROR_REF(error));
|
935
|
+
GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "finish_writes");
|
936
|
+
}
|
937
|
+
GRPC_ERROR_UNREF(error);
|
938
|
+
}
|
939
|
+
|
767
940
|
static void terminate_writing_with_lock(grpc_exec_ctx *exec_ctx,
|
768
941
|
grpc_chttp2_transport *t,
|
769
942
|
grpc_chttp2_stream *s_ignored,
|
@@ -778,24 +951,32 @@ static void terminate_writing_with_lock(grpc_exec_ctx *exec_ctx,
|
|
778
951
|
|
779
952
|
grpc_chttp2_cleanup_writing(exec_ctx, &t->global, &t->writing);
|
780
953
|
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
954
|
+
end_waiting_for_write(exec_ctx, t, error);
|
955
|
+
|
956
|
+
switch (t->executor.write_state) {
|
957
|
+
case GRPC_CHTTP2_WRITING_INACTIVE:
|
958
|
+
case GRPC_CHTTP2_WRITE_REQUESTED_WITH_POLLER:
|
959
|
+
case GRPC_CHTTP2_WRITE_REQUESTED_NO_POLLER:
|
960
|
+
case GRPC_CHTTP2_WRITE_SCHEDULED:
|
961
|
+
GPR_UNREACHABLE_CODE(break);
|
962
|
+
case GRPC_CHTTP2_WRITING:
|
963
|
+
set_write_state(t, GRPC_CHTTP2_WRITING_INACTIVE, "terminate_writing");
|
964
|
+
break;
|
965
|
+
case GRPC_CHTTP2_WRITING_STALE_WITH_POLLER:
|
966
|
+
set_write_state(t, GRPC_CHTTP2_WRITE_REQUESTED_WITH_POLLER,
|
967
|
+
"terminate_writing");
|
968
|
+
break;
|
969
|
+
case GRPC_CHTTP2_WRITING_STALE_NO_POLLER:
|
970
|
+
set_write_state(t, GRPC_CHTTP2_WRITE_REQUESTED_NO_POLLER,
|
971
|
+
"terminate_writing");
|
972
|
+
break;
|
787
973
|
}
|
788
974
|
|
789
|
-
/* leave the writing flag up on shutdown to prevent further writes in
|
790
|
-
unlock()
|
791
|
-
from starting */
|
792
|
-
t->executor.writing_active = 0;
|
793
975
|
if (t->ep && !t->endpoint_reading) {
|
794
976
|
destroy_endpoint(exec_ctx, t);
|
795
977
|
}
|
796
978
|
|
797
979
|
UNREF_TRANSPORT(exec_ctx, t, "writing");
|
798
|
-
GRPC_ERROR_UNREF(error);
|
799
980
|
}
|
800
981
|
|
801
982
|
void grpc_chttp2_terminate_writing(grpc_exec_ctx *exec_ctx,
|
@@ -878,7 +1059,8 @@ static void maybe_start_some_streams(
|
|
878
1059
|
stream_global->id, STREAM_FROM_GLOBAL(stream_global));
|
879
1060
|
stream_global->in_stream_map = true;
|
880
1061
|
transport_global->concurrent_stream_count++;
|
881
|
-
grpc_chttp2_become_writable(transport_global, stream_global
|
1062
|
+
grpc_chttp2_become_writable(exec_ctx, transport_global, stream_global, true,
|
1063
|
+
"new_stream");
|
882
1064
|
}
|
883
1065
|
/* cancel out streams that will never be started */
|
884
1066
|
while (transport_global->next_stream_id >= MAX_CLIENT_STREAM_ID &&
|
@@ -1018,9 +1200,11 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx,
|
|
1018
1200
|
maybe_start_some_streams(exec_ctx, transport_global);
|
1019
1201
|
} else {
|
1020
1202
|
GPR_ASSERT(stream_global->id != 0);
|
1021
|
-
grpc_chttp2_become_writable(transport_global, stream_global
|
1203
|
+
grpc_chttp2_become_writable(exec_ctx, transport_global, stream_global,
|
1204
|
+
true, "op.send_initial_metadata");
|
1022
1205
|
}
|
1023
1206
|
} else {
|
1207
|
+
stream_global->send_trailing_metadata = NULL;
|
1024
1208
|
grpc_chttp2_complete_closure_step(
|
1025
1209
|
exec_ctx, transport_global, stream_global,
|
1026
1210
|
&stream_global->send_initial_metadata_finished,
|
@@ -1042,7 +1226,8 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx,
|
|
1042
1226
|
} else {
|
1043
1227
|
stream_global->send_message = op->send_message;
|
1044
1228
|
if (stream_global->id != 0) {
|
1045
|
-
grpc_chttp2_become_writable(transport_global, stream_global
|
1229
|
+
grpc_chttp2_become_writable(exec_ctx, transport_global, stream_global,
|
1230
|
+
true, "op.send_message");
|
1046
1231
|
}
|
1047
1232
|
}
|
1048
1233
|
}
|
@@ -1075,6 +1260,7 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx,
|
|
1075
1260
|
grpc_chttp2_list_add_check_read_ops(transport_global, stream_global);
|
1076
1261
|
}
|
1077
1262
|
if (stream_global->write_closed) {
|
1263
|
+
stream_global->send_trailing_metadata = NULL;
|
1078
1264
|
grpc_chttp2_complete_closure_step(
|
1079
1265
|
exec_ctx, transport_global, stream_global,
|
1080
1266
|
&stream_global->send_trailing_metadata_finished,
|
@@ -1085,7 +1271,8 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx,
|
|
1085
1271
|
} else if (stream_global->id != 0) {
|
1086
1272
|
/* TODO(ctiller): check if there's flow control for any outstanding
|
1087
1273
|
bytes before going writable */
|
1088
|
-
grpc_chttp2_become_writable(transport_global, stream_global
|
1274
|
+
grpc_chttp2_become_writable(exec_ctx, transport_global, stream_global,
|
1275
|
+
true, "op.send_trailing_metadata");
|
1089
1276
|
}
|
1090
1277
|
}
|
1091
1278
|
}
|
@@ -1106,8 +1293,8 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx,
|
|
1106
1293
|
(stream_global->incoming_frames.head == NULL ||
|
1107
1294
|
stream_global->incoming_frames.head->is_tail)) {
|
1108
1295
|
incoming_byte_stream_update_flow_control(
|
1109
|
-
transport_global, stream_global,
|
1110
|
-
0);
|
1296
|
+
exec_ctx, transport_global, stream_global,
|
1297
|
+
transport_global->stream_lookahead, 0);
|
1111
1298
|
}
|
1112
1299
|
grpc_chttp2_list_add_check_read_ops(transport_global, stream_global);
|
1113
1300
|
}
|
@@ -1135,7 +1322,8 @@ static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
|
|
1135
1322
|
sizeof(*op));
|
1136
1323
|
}
|
1137
1324
|
|
1138
|
-
static void send_ping_locked(
|
1325
|
+
static void send_ping_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
1326
|
+
grpc_closure *on_recv) {
|
1139
1327
|
grpc_chttp2_outstanding_ping *p = gpr_malloc(sizeof(*p));
|
1140
1328
|
p->next = &t->global.pings;
|
1141
1329
|
p->prev = p->next->prev;
|
@@ -1150,6 +1338,7 @@ static void send_ping_locked(grpc_chttp2_transport *t, grpc_closure *on_recv) {
|
|
1150
1338
|
p->id[7] = (uint8_t)(t->global.ping_counter & 0xff);
|
1151
1339
|
p->on_recv = on_recv;
|
1152
1340
|
gpr_slice_buffer_add(&t->global.qbuf, grpc_chttp2_ping_create(0, p->id));
|
1341
|
+
grpc_chttp2_initiate_write(exec_ctx, &t->global, true, "send_ping");
|
1153
1342
|
}
|
1154
1343
|
|
1155
1344
|
static void ack_ping_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
@@ -1209,6 +1398,7 @@ static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx,
|
|
1209
1398
|
close_transport = grpc_chttp2_has_streams(t)
|
1210
1399
|
? GRPC_ERROR_NONE
|
1211
1400
|
: GRPC_ERROR_CREATE("GOAWAY sent");
|
1401
|
+
grpc_chttp2_initiate_write(exec_ctx, &t->global, false, "goaway_sent");
|
1212
1402
|
}
|
1213
1403
|
|
1214
1404
|
if (op->set_accept_stream) {
|
@@ -1226,7 +1416,7 @@ static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx,
|
|
1226
1416
|
}
|
1227
1417
|
|
1228
1418
|
if (op->send_ping) {
|
1229
|
-
send_ping_locked(t, op->send_ping);
|
1419
|
+
send_ping_locked(exec_ctx, t, op->send_ping);
|
1230
1420
|
}
|
1231
1421
|
|
1232
1422
|
if (close_transport != GRPC_ERROR_NONE) {
|
@@ -1414,6 +1604,8 @@ static void cancel_from_api(grpc_exec_ctx *exec_ctx,
|
|
1414
1604
|
&transport_global->qbuf,
|
1415
1605
|
grpc_chttp2_rst_stream_create(stream_global->id, (uint32_t)http_error,
|
1416
1606
|
&stream_global->stats.outgoing));
|
1607
|
+
grpc_chttp2_initiate_write(exec_ctx, transport_global, false,
|
1608
|
+
"rst_stream");
|
1417
1609
|
}
|
1418
1610
|
|
1419
1611
|
const char *msg =
|
@@ -1473,10 +1665,39 @@ void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx,
|
|
1473
1665
|
}
|
1474
1666
|
}
|
1475
1667
|
|
1668
|
+
static void add_error(grpc_error *error, grpc_error **refs, size_t *nrefs) {
|
1669
|
+
if (error == GRPC_ERROR_NONE) return;
|
1670
|
+
for (size_t i = 0; i < *nrefs; i++) {
|
1671
|
+
if (error == refs[i]) {
|
1672
|
+
return;
|
1673
|
+
}
|
1674
|
+
}
|
1675
|
+
refs[*nrefs] = error;
|
1676
|
+
++*nrefs;
|
1677
|
+
}
|
1678
|
+
|
1679
|
+
static grpc_error *removal_error(grpc_error *extra_error,
|
1680
|
+
grpc_chttp2_stream_global *stream_global) {
|
1681
|
+
grpc_error *refs[3];
|
1682
|
+
size_t nrefs = 0;
|
1683
|
+
add_error(stream_global->read_closed_error, refs, &nrefs);
|
1684
|
+
add_error(stream_global->write_closed_error, refs, &nrefs);
|
1685
|
+
add_error(extra_error, refs, &nrefs);
|
1686
|
+
grpc_error *error = GRPC_ERROR_NONE;
|
1687
|
+
if (nrefs > 0) {
|
1688
|
+
error = GRPC_ERROR_CREATE_REFERENCING("Failed due to stream removal", refs,
|
1689
|
+
nrefs);
|
1690
|
+
}
|
1691
|
+
GRPC_ERROR_UNREF(extra_error);
|
1692
|
+
return error;
|
1693
|
+
}
|
1694
|
+
|
1476
1695
|
static void fail_pending_writes(grpc_exec_ctx *exec_ctx,
|
1477
1696
|
grpc_chttp2_transport_global *transport_global,
|
1478
1697
|
grpc_chttp2_stream_global *stream_global,
|
1479
1698
|
grpc_error *error) {
|
1699
|
+
error = removal_error(error, stream_global);
|
1700
|
+
stream_global->send_message = NULL;
|
1480
1701
|
grpc_chttp2_complete_closure_step(
|
1481
1702
|
exec_ctx, transport_global, stream_global,
|
1482
1703
|
&stream_global->send_initial_metadata_finished, GRPC_ERROR_REF(error));
|
@@ -1499,14 +1720,17 @@ void grpc_chttp2_mark_stream_closed(
|
|
1499
1720
|
}
|
1500
1721
|
grpc_chttp2_list_add_check_read_ops(transport_global, stream_global);
|
1501
1722
|
if (close_reads && !stream_global->read_closed) {
|
1723
|
+
stream_global->read_closed_error = GRPC_ERROR_REF(error);
|
1502
1724
|
stream_global->read_closed = true;
|
1503
1725
|
stream_global->published_initial_metadata = true;
|
1504
1726
|
stream_global->published_trailing_metadata = true;
|
1505
1727
|
decrement_active_streams_locked(exec_ctx, transport_global, stream_global);
|
1506
1728
|
}
|
1507
1729
|
if (close_writes && !stream_global->write_closed) {
|
1730
|
+
stream_global->write_closed_error = GRPC_ERROR_REF(error);
|
1508
1731
|
stream_global->write_closed = true;
|
1509
|
-
if (TRANSPORT_FROM_GLOBAL(transport_global)->executor.
|
1732
|
+
if (TRANSPORT_FROM_GLOBAL(transport_global)->executor.write_state !=
|
1733
|
+
GRPC_CHTTP2_WRITING_INACTIVE) {
|
1510
1734
|
GRPC_CHTTP2_STREAM_REF(stream_global, "finish_writes");
|
1511
1735
|
grpc_chttp2_list_add_closed_waiting_for_writing(transport_global,
|
1512
1736
|
stream_global);
|
@@ -1516,7 +1740,6 @@ void grpc_chttp2_mark_stream_closed(
|
|
1516
1740
|
}
|
1517
1741
|
}
|
1518
1742
|
if (stream_global->read_closed && stream_global->write_closed) {
|
1519
|
-
stream_global->removal_error = GRPC_ERROR_REF(error);
|
1520
1743
|
if (stream_global->id != 0 &&
|
1521
1744
|
TRANSPORT_FROM_GLOBAL(transport_global)->executor.parsing_active) {
|
1522
1745
|
grpc_chttp2_list_add_closed_waiting_for_parsing(transport_global,
|
@@ -1524,7 +1747,8 @@ void grpc_chttp2_mark_stream_closed(
|
|
1524
1747
|
} else {
|
1525
1748
|
if (stream_global->id != 0) {
|
1526
1749
|
remove_stream(exec_ctx, TRANSPORT_FROM_GLOBAL(transport_global),
|
1527
|
-
stream_global->id,
|
1750
|
+
stream_global->id,
|
1751
|
+
removal_error(GRPC_ERROR_REF(error), stream_global));
|
1528
1752
|
}
|
1529
1753
|
GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2");
|
1530
1754
|
}
|
@@ -1649,6 +1873,8 @@ static void close_from_api(grpc_exec_ctx *exec_ctx,
|
|
1649
1873
|
|
1650
1874
|
grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global, 1,
|
1651
1875
|
1, error);
|
1876
|
+
grpc_chttp2_initiate_write(exec_ctx, transport_global, false,
|
1877
|
+
"close_from_api");
|
1652
1878
|
}
|
1653
1879
|
|
1654
1880
|
typedef struct {
|
@@ -1678,8 +1904,14 @@ static void drop_connection(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
1678
1904
|
}
|
1679
1905
|
|
1680
1906
|
/** update window from a settings change */
|
1907
|
+
typedef struct {
|
1908
|
+
grpc_chttp2_transport *t;
|
1909
|
+
grpc_exec_ctx *exec_ctx;
|
1910
|
+
} update_global_window_args;
|
1911
|
+
|
1681
1912
|
static void update_global_window(void *args, uint32_t id, void *stream) {
|
1682
|
-
|
1913
|
+
update_global_window_args *a = args;
|
1914
|
+
grpc_chttp2_transport *t = a->t;
|
1683
1915
|
grpc_chttp2_stream *s = stream;
|
1684
1916
|
grpc_chttp2_transport_global *transport_global = &t->global;
|
1685
1917
|
grpc_chttp2_stream_global *stream_global = &s->global;
|
@@ -1693,7 +1925,8 @@ static void update_global_window(void *args, uint32_t id, void *stream) {
|
|
1693
1925
|
is_zero = stream_global->outgoing_window <= 0;
|
1694
1926
|
|
1695
1927
|
if (was_zero && !is_zero) {
|
1696
|
-
grpc_chttp2_become_writable(transport_global, stream_global
|
1928
|
+
grpc_chttp2_become_writable(a->exec_ctx, transport_global, stream_global,
|
1929
|
+
true, "update_global_window");
|
1697
1930
|
}
|
1698
1931
|
}
|
1699
1932
|
|
@@ -1801,14 +2034,19 @@ static void post_parse_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
1801
2034
|
grpc_chttp2_transport_global *transport_global = &t->global;
|
1802
2035
|
grpc_chttp2_transport_parsing *transport_parsing = &t->parsing;
|
1803
2036
|
/* copy parsing qbuf to global qbuf */
|
1804
|
-
|
2037
|
+
if (t->parsing.qbuf.count > 0) {
|
2038
|
+
gpr_slice_buffer_move_into(&t->parsing.qbuf, &t->global.qbuf);
|
2039
|
+
grpc_chttp2_initiate_write(exec_ctx, transport_global, false,
|
2040
|
+
"parsing_qbuf");
|
2041
|
+
}
|
1805
2042
|
/* merge stream lists */
|
1806
2043
|
grpc_chttp2_stream_map_move_into(&t->new_stream_map, &t->parsing_stream_map);
|
1807
2044
|
transport_global->concurrent_stream_count =
|
1808
2045
|
(uint32_t)grpc_chttp2_stream_map_size(&t->parsing_stream_map);
|
1809
2046
|
if (transport_parsing->initial_window_update != 0) {
|
2047
|
+
update_global_window_args args = {t, exec_ctx};
|
1810
2048
|
grpc_chttp2_stream_map_for_each(&t->parsing_stream_map,
|
1811
|
-
update_global_window,
|
2049
|
+
update_global_window, &args);
|
1812
2050
|
transport_parsing->initial_window_update = 0;
|
1813
2051
|
}
|
1814
2052
|
/* handle higher level things */
|
@@ -1831,7 +2069,7 @@ static void post_parse_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
1831
2069
|
GPR_ASSERT(stream_global->write_closed);
|
1832
2070
|
GPR_ASSERT(stream_global->read_closed);
|
1833
2071
|
remove_stream(exec_ctx, t, stream_global->id,
|
1834
|
-
|
2072
|
+
removal_error(GRPC_ERROR_NONE, stream_global));
|
1835
2073
|
GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2");
|
1836
2074
|
}
|
1837
2075
|
|
@@ -1854,11 +2092,12 @@ static void post_reading_action_locked(grpc_exec_ctx *exec_ctx,
|
|
1854
2092
|
}
|
1855
2093
|
drop_connection(exec_ctx, t, GRPC_ERROR_REF(error));
|
1856
2094
|
t->endpoint_reading = 0;
|
1857
|
-
if (
|
1858
|
-
|
1859
|
-
|
1860
|
-
|
1861
|
-
|
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);
|
1862
2101
|
}
|
1863
2102
|
} else if (!t->closed) {
|
1864
2103
|
keep_reading = true;
|
@@ -1942,7 +2181,7 @@ static void incoming_byte_stream_unref(grpc_exec_ctx *exec_ctx,
|
|
1942
2181
|
}
|
1943
2182
|
|
1944
2183
|
static void incoming_byte_stream_update_flow_control(
|
1945
|
-
grpc_chttp2_transport_global *transport_global,
|
2184
|
+
grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global,
|
1946
2185
|
grpc_chttp2_stream_global *stream_global, size_t max_size_hint,
|
1947
2186
|
size_t have_already) {
|
1948
2187
|
uint32_t max_recv_bytes;
|
@@ -1977,7 +2216,8 @@ static void incoming_byte_stream_update_flow_control(
|
|
1977
2216
|
add_max_recv_bytes);
|
1978
2217
|
grpc_chttp2_list_add_unannounced_incoming_window_available(transport_global,
|
1979
2218
|
stream_global);
|
1980
|
-
grpc_chttp2_become_writable(transport_global, stream_global
|
2219
|
+
grpc_chttp2_become_writable(exec_ctx, transport_global, stream_global,
|
2220
|
+
false, "read_incoming_stream");
|
1981
2221
|
}
|
1982
2222
|
}
|
1983
2223
|
|
@@ -1999,8 +2239,9 @@ static void incoming_byte_stream_next_locked(grpc_exec_ctx *exec_ctx,
|
|
1999
2239
|
grpc_chttp2_stream_global *stream_global = &bs->stream->global;
|
2000
2240
|
|
2001
2241
|
if (bs->is_tail) {
|
2002
|
-
incoming_byte_stream_update_flow_control(
|
2003
|
-
|
2242
|
+
incoming_byte_stream_update_flow_control(exec_ctx, transport_global,
|
2243
|
+
stream_global, arg->max_size_hint,
|
2244
|
+
bs->slices.length);
|
2004
2245
|
}
|
2005
2246
|
if (bs->slices.count > 0) {
|
2006
2247
|
*arg->slice = gpr_slice_buffer_take_first(&bs->slices);
|
@@ -2184,7 +2425,7 @@ static char *format_flowctl_context_var(const char *context, const char *var,
|
|
2184
2425
|
if (context == NULL) {
|
2185
2426
|
*scope = NULL;
|
2186
2427
|
gpr_asprintf(&buf, "%s(%" PRId64 ")", var, val);
|
2187
|
-
result = gpr_leftpad(buf, ' ',
|
2428
|
+
result = gpr_leftpad(buf, ' ', 60);
|
2188
2429
|
gpr_free(buf);
|
2189
2430
|
return result;
|
2190
2431
|
}
|
@@ -2197,7 +2438,7 @@ static char *format_flowctl_context_var(const char *context, const char *var,
|
|
2197
2438
|
gpr_free(tmp);
|
2198
2439
|
}
|
2199
2440
|
gpr_asprintf(&buf, "%s.%s(%" PRId64 ")", underscore_pos + 1, var, val);
|
2200
|
-
result = gpr_leftpad(buf, ' ',
|
2441
|
+
result = gpr_leftpad(buf, ' ', 60);
|
2201
2442
|
gpr_free(buf);
|
2202
2443
|
return result;
|
2203
2444
|
}
|
@@ -2230,7 +2471,7 @@ void grpc_chttp2_flowctl_trace(const char *file, int line, const char *phase,
|
|
2230
2471
|
|
2231
2472
|
tmp_phase = gpr_leftpad(phase, ' ', 8);
|
2232
2473
|
tmp_scope1 = gpr_leftpad(scope1, ' ', 11);
|
2233
|
-
gpr_asprintf(&prefix, "FLOW %s: %s %s ",
|
2474
|
+
gpr_asprintf(&prefix, "FLOW %s: %s %s ", tmp_phase, clisvr, scope1);
|
2234
2475
|
gpr_free(tmp_phase);
|
2235
2476
|
gpr_free(tmp_scope1);
|
2236
2477
|
|