From 71ed007847622b8aff49136cbf77de4caa790d79 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 1 Jul 2016 08:39:41 -0700 Subject: Change run_interop_tests.py to run status_code_and_message test for Go. --- tools/run_tests/run_interop_tests.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index e3af721ee5..d336c27b43 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -59,8 +59,9 @@ _SKIP_COMPRESSION = ['client_compressed_unary', 'server_compressed_unary', 'server_compressed_streaming'] -_SKIP_ADVANCED = ['custom_metadata', 'status_code_and_message', - 'unimplemented_method'] +_SKIP_ADVANCED_GO = ['custom_metadata', 'unimplemented_method'] + +_SKIP_ADVANCED = _SKIP_ADVANCED_GO + ['status_code_and_message'] _TEST_TIMEOUT = 3*60 @@ -172,10 +173,10 @@ class GoLanguage: return {} def unimplemented_test_cases(self): - return _SKIP_ADVANCED + _SKIP_COMPRESSION + return _SKIP_ADVANCED_GO + _SKIP_COMPRESSION def unimplemented_test_cases_server(self): - return _SKIP_ADVANCED + _SKIP_COMPRESSION + return _SKIP_ADVANCED_GO + _SKIP_COMPRESSION def __str__(self): return 'go' -- cgit v1.2.3 From dbf2adc9804e75c71e7a4158cdac21b11ce5d6c5 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 7 Jul 2016 08:19:27 -0700 Subject: Fix C++ status_code_and_message test to comply with the spec. Enable C++ test in run_interop_tests.py. --- test/cpp/interop/interop_client.cc | 28 ++++++++++++++++++++++++---- test/cpp/interop/interop_server.cc | 5 +++++ tools/run_tests/run_interop_tests.py | 12 ++++++------ 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc index 89f841dbe9..612eda92de 100644 --- a/test/cpp/interop/interop_client.cc +++ b/test/cpp/interop/interop_client.cc @@ -827,21 +827,41 @@ bool InteropClient::DoStatusWithMessage() { gpr_log(GPR_DEBUG, "Sending RPC with a request for status code 2 and message"); + const grpc::StatusCode test_code = grpc::StatusCode::UNKNOWN; + const grpc::string test_msg = "This is a test message"; ClientContext context; + + // Test UnaryCall. SimpleRequest request; SimpleResponse response; EchoStatus* requested_status = request.mutable_response_status(); - requested_status->set_code(grpc::StatusCode::UNKNOWN); - grpc::string test_msg = "This is a test message"; + requested_status->set_code(test_code); requested_status->set_message(test_msg); - Status s = serviceStub_.Get()->UnaryCall(&context, request, &response); - if (!AssertStatusCode(s, grpc::StatusCode::UNKNOWN)) { return false; } + GPR_ASSERT(s.error_message() == test_msg); + // Test FullDuplexCall. + std::shared_ptr> + stream(serviceStub_.Get()->FullDuplexCall(&context)); + StreamingOutputCallRequest streaming_request; + requested_status = streaming_request.mutable_response_status(); + requested_status->set_code(test_code); + requested_status->set_message(test_msg); + stream->Write(streaming_request); + stream->WritesDone(); + StreamingOutputCallResponse streaming_response; + while (stream->Read(&streaming_response)) + ; + s = stream->Finish(); + if (!AssertStatusCode(s, grpc::StatusCode::UNKNOWN)) { + return false; + } GPR_ASSERT(s.error_message() == test_msg); + gpr_log(GPR_DEBUG, "Done testing Status and Message"); return true; } diff --git a/test/cpp/interop/interop_server.cc b/test/cpp/interop/interop_server.cc index ebef0002a3..bb6793d956 100644 --- a/test/cpp/interop/interop_server.cc +++ b/test/cpp/interop/interop_server.cc @@ -259,6 +259,11 @@ class TestServiceImpl : public TestService::Service { StreamingOutputCallResponse response; bool write_success = true; while (write_success && stream->Read(&request)) { + if (request.has_response_status()) { + return Status( + static_cast(request.response_status().code()), + request.response_status().message()); + } if (request.response_parameters_size() != 0) { response.mutable_payload()->set_type(request.payload().type()); response.mutable_payload()->set_body( diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index d336c27b43..516c6dbbbf 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -59,9 +59,9 @@ _SKIP_COMPRESSION = ['client_compressed_unary', 'server_compressed_unary', 'server_compressed_streaming'] -_SKIP_ADVANCED_GO = ['custom_metadata', 'unimplemented_method'] +_SKIP_ADVANCED_CXX_AND_GO = ['custom_metadata', 'unimplemented_method'] -_SKIP_ADVANCED = _SKIP_ADVANCED_GO + ['status_code_and_message'] +_SKIP_ADVANCED = _SKIP_ADVANCED_CXX_AND_GO + ['status_code_and_message'] _TEST_TIMEOUT = 3*60 @@ -85,10 +85,10 @@ class CXXLanguage: return {} def unimplemented_test_cases(self): - return _SKIP_ADVANCED + return _SKIP_ADVANCED_CXX_AND_GO def unimplemented_test_cases_server(self): - return _SKIP_ADVANCED + return _SKIP_ADVANCED_CXX_AND_GO def __str__(self): return 'c++' @@ -173,10 +173,10 @@ class GoLanguage: return {} def unimplemented_test_cases(self): - return _SKIP_ADVANCED_GO + _SKIP_COMPRESSION + return _SKIP_ADVANCED_CXX_AND_GO + _SKIP_COMPRESSION def unimplemented_test_cases_server(self): - return _SKIP_ADVANCED_GO + _SKIP_COMPRESSION + return _SKIP_ADVANCED_CXX_AND_GO + _SKIP_COMPRESSION def __str__(self): return 'go' -- cgit v1.2.3 From b9151e3c0b0a5d01d6077c50e3ed483cb1f49b10 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 7 Jul 2016 08:36:26 -0700 Subject: Use separate client context object for full duplex call. --- test/cpp/interop/interop_client.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc index 612eda92de..b70bb48a49 100644 --- a/test/cpp/interop/interop_client.cc +++ b/test/cpp/interop/interop_client.cc @@ -829,9 +829,9 @@ bool InteropClient::DoStatusWithMessage() { const grpc::StatusCode test_code = grpc::StatusCode::UNKNOWN; const grpc::string test_msg = "This is a test message"; - ClientContext context; // Test UnaryCall. + ClientContext context; SimpleRequest request; SimpleResponse response; EchoStatus* requested_status = request.mutable_response_status(); @@ -844,9 +844,10 @@ bool InteropClient::DoStatusWithMessage() { GPR_ASSERT(s.error_message() == test_msg); // Test FullDuplexCall. + ClientContext stream_context; std::shared_ptr> - stream(serviceStub_.Get()->FullDuplexCall(&context)); + stream(serviceStub_.Get()->FullDuplexCall(&stream_context)); StreamingOutputCallRequest streaming_request; requested_status = streaming_request.mutable_response_status(); requested_status->set_code(test_code); -- cgit v1.2.3 From 2449e193bb42ffbcfc163cae43aacd0f4a777ab7 Mon Sep 17 00:00:00 2001 From: Robbie Shade Date: Fri, 15 Jul 2016 15:16:25 -0400 Subject: Extends the payload test to use large random bodies. --- test/core/end2end/cq_verifier.c | 2 +- test/core/end2end/cq_verifier.h | 1 + test/core/end2end/tests/payload.c | 27 +++++++++++++++++++++++---- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/test/core/end2end/cq_verifier.c b/test/core/end2end/cq_verifier.c index 890309c44a..03a14755a8 100644 --- a/test/core/end2end/cq_verifier.c +++ b/test/core/end2end/cq_verifier.c @@ -128,7 +128,7 @@ static gpr_slice merge_slices(gpr_slice *slices, size_t nslices) { return out; } -static int byte_buffer_eq_slice(grpc_byte_buffer *bb, gpr_slice b) { +int byte_buffer_eq_slice(grpc_byte_buffer *bb, gpr_slice b) { gpr_slice a; int ok; diff --git a/test/core/end2end/cq_verifier.h b/test/core/end2end/cq_verifier.h index 8c9a85c218..3bf2141438 100644 --- a/test/core/end2end/cq_verifier.h +++ b/test/core/end2end/cq_verifier.h @@ -61,6 +61,7 @@ void cq_verify_empty(cq_verifier *v); the event. */ void cq_expect_completion(cq_verifier *v, void *tag, bool success); +int byte_buffer_eq_slice(grpc_byte_buffer *bb, gpr_slice b); int byte_buffer_eq_string(grpc_byte_buffer *byte_buffer, const char *string); int contains_metadata(grpc_metadata_array *array, const char *key, const char *value); diff --git a/test/core/end2end/tests/payload.c b/test/core/end2end/tests/payload.c index 443d85eecc..3cb3f2e53a 100644 --- a/test/core/end2end/tests/payload.c +++ b/test/core/end2end/tests/payload.c @@ -97,9 +97,27 @@ static void end_test(grpc_end2end_test_fixture *f) { grpc_completion_queue_destroy(f->cq); } +/* Creates and returns a gpr_slice of specified length, containing random + * alphanumeric characters. */ +static gpr_slice generate_random_slice(int length_bytes) { + int i; + gpr_slice slice = gpr_slice_malloc(length_bytes); + static const char alphanum[] = "abcdefghijklmnopqrstuvwxyz01234567890"; + for (i = 0; i < length_bytes; ++i) { + *(GPR_SLICE_START_PTR(slice) + i) = + alphanum[rand() % (sizeof(alphanum) - 1)]; + } + return slice; +} + static void request_response_with_payload(grpc_end2end_test_fixture f) { - gpr_slice request_payload_slice = gpr_slice_from_copied_string("hello world"); - gpr_slice response_payload_slice = gpr_slice_from_copied_string("hello you"); + /* Create large request and response bodies. These are big enough to require + * multiple round trips to deliver to the peer, and their exact contents of + * will be verified on completion. */ + int payload_size_bytes = 1024 * 1024; /* 1 MB */ + gpr_slice request_payload_slice = generate_random_slice(payload_size_bytes); + gpr_slice response_payload_slice = generate_random_slice(payload_size_bytes); + grpc_call *c; grpc_call *s; grpc_byte_buffer *request_payload = @@ -224,8 +242,9 @@ static void request_response_with_payload(grpc_end2end_test_fixture f) { GPR_ASSERT(0 == strcmp(call_details.method, "/foo")); GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr")); GPR_ASSERT(was_cancelled == 0); - GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world")); - GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, "hello you")); + GPR_ASSERT(byte_buffer_eq_slice(request_payload_recv, request_payload_slice)); + GPR_ASSERT( + byte_buffer_eq_slice(response_payload_recv, response_payload_slice)); gpr_free(details); grpc_metadata_array_destroy(&initial_metadata_recv); -- cgit v1.2.3 From bd10faaf0f4284576b628ef2b4da5edeac9f6454 Mon Sep 17 00:00:00 2001 From: Robbie Shade Date: Fri, 15 Jul 2016 15:27:01 -0400 Subject: Fixing int conversion warnings --- test/core/end2end/tests/payload.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/core/end2end/tests/payload.c b/test/core/end2end/tests/payload.c index 3cb3f2e53a..0a68a01730 100644 --- a/test/core/end2end/tests/payload.c +++ b/test/core/end2end/tests/payload.c @@ -99,13 +99,13 @@ static void end_test(grpc_end2end_test_fixture *f) { /* Creates and returns a gpr_slice of specified length, containing random * alphanumeric characters. */ -static gpr_slice generate_random_slice(int length_bytes) { - int i; +static gpr_slice generate_random_slice(size_t length_bytes) { + size_t i; gpr_slice slice = gpr_slice_malloc(length_bytes); - static const char alphanum[] = "abcdefghijklmnopqrstuvwxyz01234567890"; + static const uint8_t alphanum[] = "abcdefghijklmnopqrstuvwxyz01234567890"; for (i = 0; i < length_bytes; ++i) { *(GPR_SLICE_START_PTR(slice) + i) = - alphanum[rand() % (sizeof(alphanum) - 1)]; + alphanum[rand() % (int)(sizeof(alphanum) - 1)]; } return slice; } @@ -114,7 +114,7 @@ static void request_response_with_payload(grpc_end2end_test_fixture f) { /* Create large request and response bodies. These are big enough to require * multiple round trips to deliver to the peer, and their exact contents of * will be verified on completion. */ - int payload_size_bytes = 1024 * 1024; /* 1 MB */ + size_t payload_size_bytes = 1024 * 1024; /* 1 MB */ gpr_slice request_payload_slice = generate_random_slice(payload_size_bytes); gpr_slice response_payload_slice = generate_random_slice(payload_size_bytes); -- cgit v1.2.3 From 61aed92b8262b3a7fa86394cc6b89987ada85228 Mon Sep 17 00:00:00 2001 From: Robbie Shade Date: Fri, 15 Jul 2016 16:38:44 -0400 Subject: Just create 1 MB strings, no argument. --- test/core/end2end/tests/payload.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/test/core/end2end/tests/payload.c b/test/core/end2end/tests/payload.c index 0a68a01730..d530443fb8 100644 --- a/test/core/end2end/tests/payload.c +++ b/test/core/end2end/tests/payload.c @@ -97,26 +97,23 @@ static void end_test(grpc_end2end_test_fixture *f) { grpc_completion_queue_destroy(f->cq); } -/* Creates and returns a gpr_slice of specified length, containing random - * alphanumeric characters. */ -static gpr_slice generate_random_slice(size_t length_bytes) { +/* Creates and returns a gpr_slice containing random alphanumeric characters. */ +static gpr_slice generate_random_slice() { size_t i; - gpr_slice slice = gpr_slice_malloc(length_bytes); - static const uint8_t alphanum[] = "abcdefghijklmnopqrstuvwxyz01234567890"; - for (i = 0; i < length_bytes; ++i) { - *(GPR_SLICE_START_PTR(slice) + i) = - alphanum[rand() % (int)(sizeof(alphanum) - 1)]; + static const char chars[] = "abcdefghijklmnopqrstuvwxyz1234567890"; + char output[1024 * 1024]; /* 1 MB */ + for (i = 0; i < 1024 * 1024; ++i) { + output[i] = chars[rand() % (int)(sizeof(chars) - 1)]; } - return slice; + return gpr_slice_from_copied_string(output); } static void request_response_with_payload(grpc_end2end_test_fixture f) { /* Create large request and response bodies. These are big enough to require * multiple round trips to deliver to the peer, and their exact contents of * will be verified on completion. */ - size_t payload_size_bytes = 1024 * 1024; /* 1 MB */ - gpr_slice request_payload_slice = generate_random_slice(payload_size_bytes); - gpr_slice response_payload_slice = generate_random_slice(payload_size_bytes); + gpr_slice request_payload_slice = generate_random_slice(); + gpr_slice response_payload_slice = generate_random_slice(); grpc_call *c; grpc_call *s; -- cgit v1.2.3 From c6f776752d29bc471818258b172602d5e08b6402 Mon Sep 17 00:00:00 2001 From: Robbie Shade Date: Fri, 15 Jul 2016 17:08:08 -0400 Subject: Explicitly add terminating null character. --- test/core/end2end/tests/payload.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/core/end2end/tests/payload.c b/test/core/end2end/tests/payload.c index d530443fb8..fa6a6ea258 100644 --- a/test/core/end2end/tests/payload.c +++ b/test/core/end2end/tests/payload.c @@ -102,9 +102,10 @@ static gpr_slice generate_random_slice() { size_t i; static const char chars[] = "abcdefghijklmnopqrstuvwxyz1234567890"; char output[1024 * 1024]; /* 1 MB */ - for (i = 0; i < 1024 * 1024; ++i) { + for (i = 0; i < 1024 * 1024 - 1; ++i) { output[i] = chars[rand() % (int)(sizeof(chars) - 1)]; } + output[1024 * 1024 - 1] = '\0'; return gpr_slice_from_copied_string(output); } -- cgit v1.2.3 From d5d851baf3dbdf92b1c1946c6c46334e6d095b3d Mon Sep 17 00:00:00 2001 From: Robbie Shade Date: Fri, 15 Jul 2016 17:16:00 -0400 Subject: Add byte_buffer_eq_slice method --- test/core/end2end/cq_verifier.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/test/core/end2end/cq_verifier.c b/test/core/end2end/cq_verifier.c index 03a14755a8..74da9bc406 100644 --- a/test/core/end2end/cq_verifier.c +++ b/test/core/end2end/cq_verifier.c @@ -128,14 +128,14 @@ static gpr_slice merge_slices(gpr_slice *slices, size_t nslices) { return out; } -int byte_buffer_eq_slice(grpc_byte_buffer *bb, gpr_slice b) { +int raw_byte_buffer_eq_slice(grpc_byte_buffer *rbb, gpr_slice b) { gpr_slice a; int ok; - if (!bb) return 0; + if (!rbb) return 0; - a = merge_slices(bb->data.raw.slice_buffer.slices, - bb->data.raw.slice_buffer.count); + a = merge_slices(rbb->data.raw.slice_buffer.slices, + rbb->data.raw.slice_buffer.count); ok = GPR_SLICE_LENGTH(a) == GPR_SLICE_LENGTH(b) && 0 == memcmp(GPR_SLICE_START_PTR(a), GPR_SLICE_START_PTR(b), GPR_SLICE_LENGTH(a)); @@ -144,6 +144,21 @@ int byte_buffer_eq_slice(grpc_byte_buffer *bb, gpr_slice b) { return ok; } +int byte_buffer_eq_slice(grpc_byte_buffer *bb, gpr_slice b) { + grpc_byte_buffer_reader reader; + grpc_byte_buffer *rbb; + int res; + + GPR_ASSERT(grpc_byte_buffer_reader_init(&reader, bb) && + "Couldn't init byte buffer reader"); + rbb = grpc_raw_byte_buffer_from_reader(&reader); + res = raw_byte_buffer_eq_slice(rbb, b); + grpc_byte_buffer_reader_destroy(&reader); + grpc_byte_buffer_destroy(rbb); + + return res; +} + int byte_buffer_eq_string(grpc_byte_buffer *bb, const char *str) { grpc_byte_buffer_reader reader; grpc_byte_buffer *rbb; @@ -152,7 +167,7 @@ int byte_buffer_eq_string(grpc_byte_buffer *bb, const char *str) { GPR_ASSERT(grpc_byte_buffer_reader_init(&reader, bb) && "Couldn't init byte buffer reader"); rbb = grpc_raw_byte_buffer_from_reader(&reader); - res = byte_buffer_eq_slice(rbb, gpr_slice_from_copied_string(str)); + res = raw_byte_buffer_eq_slice(rbb, gpr_slice_from_copied_string(str)); grpc_byte_buffer_reader_destroy(&reader); grpc_byte_buffer_destroy(rbb); -- cgit v1.2.3 From a47563ca8c8cc698f2aea5bf461e039c372df02a Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Sat, 23 Jul 2016 07:56:33 -0700 Subject: progress --- src/core/lib/iomgr/exec_ctx.c | 37 ++++++++++++++++++++++++++++++++++++- src/core/lib/iomgr/exec_ctx.h | 7 ++++++- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/exec_ctx.c b/src/core/lib/iomgr/exec_ctx.c index ac7785ec13..450cf3aa93 100644 --- a/src/core/lib/iomgr/exec_ctx.c +++ b/src/core/lib/iomgr/exec_ctx.c @@ -74,6 +74,30 @@ bool grpc_exec_ctx_flush(grpc_exec_ctx *exec_ctx) { c = next; } } + if (exec_ctx->stealing_from_workqueue != NULL) { + if (grpc_exec_ctx_ready_to_finish(exec_ctx)) { + grpc_workqueue_enqueue(exec_ctx, exec_ctx->stealing_from_workqueue, + exec_ctx->stolen_closure, + exec_ctx->stolen_closure->error); + GRPC_WORKQUEUE_UNREF(exec_ctx, exec_ctx->stealing_from_workqueue, + "exec_ctx_sched"); + exec_ctx->stealing_from_workqueue = NULL; + exec_ctx->stolen_closure = NULL; + } else { + grpc_closure *c = exec_ctx->stolen_closure; + GRPC_WORKQUEUE_UNREF(exec_ctx, exec_ctx->stealing_from_workqueue, + "exec_ctx_sched"); + exec_ctx->stealing_from_workqueue = NULL; + exec_ctx->stolen_closure = NULL; + grpc_error *error = c->error; + GPR_TIMER_BEGIN("grpc_exec_ctx_flush.stolen_cb", 0); + c->cb(exec_ctx, c->cb_arg, error); + GRPC_ERROR_UNREF(error); + GPR_TIMER_END("grpc_exec_ctx_flush.stolen_cb", 0); + grpc_exec_ctx_flush(exec_ctx); + return true; + } + } GPR_TIMER_END("grpc_exec_ctx_flush", 0); return did_something; } @@ -88,9 +112,20 @@ void grpc_exec_ctx_sched(grpc_exec_ctx *exec_ctx, grpc_closure *closure, grpc_workqueue *offload_target_or_null) { if (offload_target_or_null == NULL) { grpc_closure_list_append(&exec_ctx->closure_list, closure, error); - } else { + } else if (exec_ctx->stealing_from_workqueue == NULL) { + exec_ctx->stealing_from_workqueue = offload_target_or_null; + closure->error = error; + exec_ctx->stolen_closure = closure; + } else if (exec_ctx->stealing_from_workqueue != offload_target_or_null) { grpc_workqueue_enqueue(exec_ctx, offload_target_or_null, closure, error); GRPC_WORKQUEUE_UNREF(exec_ctx, offload_target_or_null, "exec_ctx_sched"); + } else { /* stealing_from_workqueue == offload_target_or_null */ + grpc_workqueue_enqueue(exec_ctx, offload_target_or_null, + exec_ctx->stolen_closure, + exec_ctx->stolen_closure->error); + closure->error = error; + exec_ctx->stolen_closure = closure; + GRPC_WORKQUEUE_UNREF(exec_ctx, offload_target_or_null, "exec_ctx_sched"); } } diff --git a/src/core/lib/iomgr/exec_ctx.h b/src/core/lib/iomgr/exec_ctx.h index 1895ee6245..8474905396 100644 --- a/src/core/lib/iomgr/exec_ctx.h +++ b/src/core/lib/iomgr/exec_ctx.h @@ -66,6 +66,8 @@ typedef struct grpc_combiner grpc_combiner; */ struct grpc_exec_ctx { grpc_closure_list closure_list; + grpc_workqueue *stealing_from_workqueue; + grpc_closure *stolen_closure; /** currently active combiner: updated only via combiner.c */ grpc_combiner *active_combiner; bool cached_ready_to_finish; @@ -74,7 +76,10 @@ struct grpc_exec_ctx { }; #define GRPC_EXEC_CTX_INIT_WITH_FINISH_CHECK(finish_check, finish_check_arg) \ - { GRPC_CLOSURE_LIST_INIT, NULL, false, finish_check_arg, finish_check } + { \ + GRPC_CLOSURE_LIST_INIT, NULL, NULL, NULL, false, finish_check_arg, \ + finish_check \ + } #else struct grpc_exec_ctx { bool cached_ready_to_finish; -- cgit v1.2.3 From 2f42fdef8e77c2a1e087384a24c135d8912af80a Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 4 Aug 2016 15:13:18 -0700 Subject: Implement is_finished for cqs --- src/core/lib/iomgr/exec_ctx.h | 6 ++- src/core/lib/surface/completion_queue.c | 81 ++++++++++++++++++++++++++++++++- 2 files changed, 84 insertions(+), 3 deletions(-) diff --git a/src/core/lib/iomgr/exec_ctx.h b/src/core/lib/iomgr/exec_ctx.h index 8474905396..ac4674bbac 100644 --- a/src/core/lib/iomgr/exec_ctx.h +++ b/src/core/lib/iomgr/exec_ctx.h @@ -75,6 +75,8 @@ struct grpc_exec_ctx { bool (*check_ready_to_finish)(grpc_exec_ctx *exec_ctx, void *arg); }; +/* initializer for grpc_exec_ctx: + prefer to use GRPC_EXEC_CTX_INIT whenever possible */ #define GRPC_EXEC_CTX_INIT_WITH_FINISH_CHECK(finish_check, finish_check_arg) \ { \ GRPC_CLOSURE_LIST_INIT, NULL, NULL, NULL, false, finish_check_arg, \ @@ -90,8 +92,10 @@ struct grpc_exec_ctx { { false, finish_check_arg, finish_check } #endif +/* initialize an execution context at the top level of an API call into grpc + (this is safe to use elsewhere, though possibly not as efficient) */ #define GRPC_EXEC_CTX_INIT \ - GRPC_EXEC_CTX_INIT_WITH_FINISH_CHECK(grpc_never_ready_to_finish, NULL) + GRPC_EXEC_CTX_INIT_WITH_FINISH_CHECK(grpc_always_ready_to_finish, NULL) /** Flush any work that has been enqueued onto this grpc_exec_ctx. * Caller must guarantee that no interfering locks are held. diff --git a/src/core/lib/surface/completion_queue.c b/src/core/lib/surface/completion_queue.c index 5978884db8..9eb4dfc618 100644 --- a/src/core/lib/surface/completion_queue.c +++ b/src/core/lib/surface/completion_queue.c @@ -313,13 +313,37 @@ void grpc_cq_end_op(grpc_exec_ctx *exec_ctx, grpc_completion_queue *cc, GRPC_ERROR_UNREF(error); } +typedef struct { + grpc_completion_queue *cq; + gpr_timespec deadline; + grpc_cq_completion *stolen_completion; + void *tag; /* for pluck */ +} cq_is_finished_arg; + +static bool cq_is_next_finished(grpc_exec_ctx *exec_ctx, void *arg) { + cq_is_finished_arg *a = arg; + grpc_completion_queue *cq = a->cq; + GPR_ASSERT(a->stolen_completion == NULL); + gpr_mu_lock(cq->mu); + if (cq->completed_tail != &cq->completed_head) { + a->stolen_completion = (grpc_cq_completion *)cq->completed_head.next; + cq->completed_head.next = a->stolen_completion->next & ~(uintptr_t)1; + if (a->stolen_completion == cq->completed_tail) { + cq->completed_tail = &cq->completed_head; + } + gpr_mu_unlock(cq->mu); + return true; + } + gpr_mu_unlock(cq->mu); + return gpr_time_cmp(a->deadline, gpr_now(a->deadline.clock_type)) > 0; +} + grpc_event grpc_completion_queue_next(grpc_completion_queue *cc, gpr_timespec deadline, void *reserved) { grpc_event ret; grpc_pollset_worker *worker = NULL; int first_loop = 1; gpr_timespec now; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; GPR_TIMER_BEGIN("grpc_completion_queue_next", 0); @@ -335,9 +359,23 @@ grpc_event grpc_completion_queue_next(grpc_completion_queue *cc, deadline = gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC); + cq_is_finished_arg is_finished_arg = {cc, deadline, NULL, NULL}; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT_WITH_FINISH_CHECK( + cq_is_next_finished, &is_finished_arg); + GRPC_CQ_INTERNAL_REF(cc, "next"); gpr_mu_lock(cc->mu); for (;;) { + if (is_finished_arg.stolen_completion != NULL) { + gpr_mu_unlock(cc->mu); + grpc_cq_completion *c = is_finished_arg.stolen_completion; + is_finished_arg.stolen_completion = NULL; + ret.type = GRPC_OP_COMPLETE; + ret.success = c->next & 1u; + ret.tag = c->tag; + c->done(&exec_ctx, c->done_arg, c); + break; + } if (cc->completed_tail != &cc->completed_head) { grpc_cq_completion *c = (grpc_cq_completion *)cc->completed_head.next; cc->completed_head.next = c->next & ~(uintptr_t)1; @@ -394,6 +432,7 @@ grpc_event grpc_completion_queue_next(grpc_completion_queue *cc, GRPC_SURFACE_TRACE_RETURNED_EVENT(cc, &ret); GRPC_CQ_INTERNAL_UNREF(cc, "next"); grpc_exec_ctx_finish(&exec_ctx); + GPR_ASSERT(is_finished_arg.stolen_completion == NULL); GPR_TIMER_END("grpc_completion_queue_next", 0); @@ -424,6 +463,30 @@ static void del_plucker(grpc_completion_queue *cc, void *tag, GPR_UNREACHABLE_CODE(return ); } +static bool cq_is_pluck_finished(grpc_exec_ctx *exec_ctx, void *arg) { + cq_is_finished_arg *a = arg; + grpc_completion_queue *cq = a->cq; + GPR_ASSERT(a->stolen_completion == NULL); + gpr_mu_lock(cq->mu); + grpc_cq_completion *c; + grpc_cq_completion *prev = &cq->completed_head; + while ((c = (grpc_cq_completion *)(prev->next & ~(uintptr_t)1)) != + &cq->completed_head) { + if (c->tag == a->tag) { + prev->next = (prev->next & (uintptr_t)1) | (c->next & ~(uintptr_t)1); + if (c == cq->completed_tail) { + cq->completed_tail = prev; + } + gpr_mu_unlock(cq->mu); + a->stolen_completion = c; + return true; + } + prev = c; + } + gpr_mu_unlock(cq->mu); + return gpr_time_cmp(a->deadline, gpr_now(a->deadline.clock_type)) > 0; +} + grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag, gpr_timespec deadline, void *reserved) { grpc_event ret; @@ -432,7 +495,6 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag, grpc_pollset_worker *worker = NULL; gpr_timespec now; int first_loop = 1; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; GPR_TIMER_BEGIN("grpc_completion_queue_pluck", 0); @@ -450,9 +512,23 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag, deadline = gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC); + cq_is_finished_arg is_finished_arg = {cc, deadline, NULL, tag}; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT_WITH_FINISH_CHECK( + cq_is_pluck_finished, &is_finished_arg); + GRPC_CQ_INTERNAL_REF(cc, "pluck"); gpr_mu_lock(cc->mu); for (;;) { + if (is_finished_arg.stolen_completion != NULL) { + gpr_mu_unlock(cc->mu); + grpc_cq_completion *c = is_finished_arg.stolen_completion; + is_finished_arg.stolen_completion = NULL; + ret.type = GRPC_OP_COMPLETE; + ret.success = c->next & 1u; + ret.tag = c->tag; + c->done(&exec_ctx, c->done_arg, c); + break; + } prev = &cc->completed_head; while ((c = (grpc_cq_completion *)(prev->next & ~(uintptr_t)1)) != &cc->completed_head) { @@ -527,6 +603,7 @@ done: GRPC_SURFACE_TRACE_RETURNED_EVENT(cc, &ret); GRPC_CQ_INTERNAL_UNREF(cc, "pluck"); grpc_exec_ctx_finish(&exec_ctx); + GPR_ASSERT(is_finished_arg.stolen_completion == NULL); GPR_TIMER_END("grpc_completion_queue_pluck", 0); -- cgit v1.2.3 From 5f70fc60f5fbf766aae252a66f5cb447eb6efb0c Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 4 Aug 2016 16:00:00 -0700 Subject: Fixup compilation --- src/core/lib/iomgr/combiner.c | 13 ++++++++++++- src/core/lib/surface/completion_queue.c | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/combiner.c b/src/core/lib/iomgr/combiner.c index eb5ad634bd..1042cd8659 100644 --- a/src/core/lib/iomgr/combiner.c +++ b/src/core/lib/iomgr/combiner.c @@ -171,10 +171,21 @@ static bool start_execute_final(grpc_exec_ctx *exec_ctx, grpc_combiner *lock) { static bool maybe_finish_one(grpc_exec_ctx *exec_ctx, grpc_combiner *lock) { GPR_TIMER_BEGIN("combiner.maybe_finish_one", 0); + GPR_ASSERT(exec_ctx->active_combiner == lock); + if (lock->optional_workqueue != NULL && + grpc_exec_ctx_ready_to_finish(exec_ctx)) { + // this execution context wants to move on, and we have a workqueue (and so + // can help the execution context out): schedule remaining work to be picked + // up on the workqueue + grpc_closure_init(&lock->continue_finishing, continue_finishing_mainline, + lock); + grpc_workqueue_enqueue(exec_ctx, lock->optional_workqueue, + &lock->continue_finishing, GRPC_ERROR_NONE); + return false; + } gpr_mpscq_node *n = gpr_mpscq_pop(&lock->queue); GRPC_COMBINER_TRACE( gpr_log(GPR_DEBUG, "C:%p maybe_finish_one n=%p", lock, n)); - GPR_ASSERT(exec_ctx->active_combiner == lock); if (n == NULL) { // queue is in an inconsistant state: use this as a cue that we should // go off and do something else for a while (and come back later) diff --git a/src/core/lib/surface/completion_queue.c b/src/core/lib/surface/completion_queue.c index 9eb4dfc618..47f53f7ad2 100644 --- a/src/core/lib/surface/completion_queue.c +++ b/src/core/lib/surface/completion_queue.c @@ -521,7 +521,7 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag, for (;;) { if (is_finished_arg.stolen_completion != NULL) { gpr_mu_unlock(cc->mu); - grpc_cq_completion *c = is_finished_arg.stolen_completion; + c = is_finished_arg.stolen_completion; is_finished_arg.stolen_completion = NULL; ret.type = GRPC_OP_COMPLETE; ret.success = c->next & 1u; -- cgit v1.2.3 From ca045622867d4b26ebcd72d85a113ad5d6edd670 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 9 Aug 2016 08:38:03 -0700 Subject: Timing nuances --- src/core/lib/iomgr/combiner.c | 1 + src/core/lib/iomgr/exec_ctx.c | 3 +++ src/core/lib/iomgr/tcp_posix.c | 4 ++-- src/core/lib/profiling/basic_timers.c | 11 ++++++++++- src/core/lib/profiling/timers.h | 2 ++ src/core/lib/surface/completion_queue.c | 4 ++-- test/cpp/qps/driver.cc | 3 +++ 7 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/core/lib/iomgr/combiner.c b/src/core/lib/iomgr/combiner.c index 1042cd8659..946cfc65fc 100644 --- a/src/core/lib/iomgr/combiner.c +++ b/src/core/lib/iomgr/combiner.c @@ -181,6 +181,7 @@ static bool maybe_finish_one(grpc_exec_ctx *exec_ctx, grpc_combiner *lock) { lock); grpc_workqueue_enqueue(exec_ctx, lock->optional_workqueue, &lock->continue_finishing, GRPC_ERROR_NONE); + GPR_TIMER_END("combiner.maybe_finish_one", 0); return false; } gpr_mpscq_node *n = gpr_mpscq_pop(&lock->queue); diff --git a/src/core/lib/iomgr/exec_ctx.c b/src/core/lib/iomgr/exec_ctx.c index 450cf3aa93..12e51ac092 100644 --- a/src/core/lib/iomgr/exec_ctx.c +++ b/src/core/lib/iomgr/exec_ctx.c @@ -95,6 +95,7 @@ bool grpc_exec_ctx_flush(grpc_exec_ctx *exec_ctx) { GRPC_ERROR_UNREF(error); GPR_TIMER_END("grpc_exec_ctx_flush.stolen_cb", 0); grpc_exec_ctx_flush(exec_ctx); + GPR_TIMER_END("grpc_exec_ctx_flush", 0); return true; } } @@ -110,6 +111,7 @@ void grpc_exec_ctx_finish(grpc_exec_ctx *exec_ctx) { void grpc_exec_ctx_sched(grpc_exec_ctx *exec_ctx, grpc_closure *closure, grpc_error *error, grpc_workqueue *offload_target_or_null) { + GPR_TIMER_BEGIN("grpc_exec_ctx_sched", 0); if (offload_target_or_null == NULL) { grpc_closure_list_append(&exec_ctx->closure_list, closure, error); } else if (exec_ctx->stealing_from_workqueue == NULL) { @@ -127,6 +129,7 @@ void grpc_exec_ctx_sched(grpc_exec_ctx *exec_ctx, grpc_closure *closure, exec_ctx->stolen_closure = closure; GRPC_WORKQUEUE_UNREF(exec_ctx, offload_target_or_null, "exec_ctx_sched"); } + GPR_TIMER_END("grpc_exec_ctx_sched", 0); } void grpc_exec_ctx_enqueue_list(grpc_exec_ctx *exec_ctx, diff --git a/src/core/lib/iomgr/tcp_posix.c b/src/core/lib/iomgr/tcp_posix.c index 92767721d5..caaed23212 100644 --- a/src/core/lib/iomgr/tcp_posix.c +++ b/src/core/lib/iomgr/tcp_posix.c @@ -209,11 +209,11 @@ static void tcp_continue_read(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp) { msg.msg_controllen = 0; msg.msg_flags = 0; - GPR_TIMER_BEGIN("recvmsg", 1); + GPR_TIMER_BEGIN("recvmsg", 0); do { read_bytes = recvmsg(tcp->fd, &msg, 0); } while (read_bytes < 0 && errno == EINTR); - GPR_TIMER_END("recvmsg", 0); + GPR_TIMER_END("recvmsg", read_bytes >= 0); if (read_bytes < 0) { /* NB: After calling call_read_cb a parallel call of the read handler may diff --git a/src/core/lib/profiling/basic_timers.c b/src/core/lib/profiling/basic_timers.c index 51813d0461..bdf9af2339 100644 --- a/src/core/lib/profiling/basic_timers.c +++ b/src/core/lib/profiling/basic_timers.c @@ -83,6 +83,7 @@ static int g_shutdown; static gpr_thd_id g_writing_thread; static __thread int g_thread_id; static int g_next_thread_id; +static int g_writing_enabled = 1; static int timer_log_push_back(gpr_timer_log_list *list, gpr_timer_log *log) { if (list->head == NULL) { @@ -177,7 +178,7 @@ static void flush_logs(gpr_timer_log_list *list) { } } -static void finish_writing() { +static void finish_writing(void) { pthread_mutex_lock(&g_mu); g_shutdown = 1; pthread_cond_signal(&g_cv); @@ -230,6 +231,10 @@ static void gpr_timers_log_add(const char *tagstr, marker_type type, int important, const char *file, int line) { gpr_timer_entry *entry; + if (!g_writing_enabled) { + return; + } + if (g_thread_log == NULL || g_thread_log->num_entries == MAX_COUNT) { rotate_log(); } @@ -261,6 +266,8 @@ void gpr_timer_end(const char *tagstr, int important, const char *file, gpr_timers_log_add(tagstr, END, important, file, line); } +void gpr_timer_set_enabled(int enabled) { g_writing_enabled = enabled; } + /* Basic profiler specific API functions. */ void gpr_timers_global_init(void) {} @@ -272,4 +279,6 @@ void gpr_timers_global_init(void) {} void gpr_timers_global_destroy(void) {} void gpr_timers_set_log_filename(const char *filename) {} + +void gpr_timer_set_enabled(int enabled) {} #endif /* GRPC_BASIC_PROFILER */ diff --git a/src/core/lib/profiling/timers.h b/src/core/lib/profiling/timers.h index c8567e8137..621cdbf656 100644 --- a/src/core/lib/profiling/timers.h +++ b/src/core/lib/profiling/timers.h @@ -50,6 +50,8 @@ void gpr_timer_end(const char *tagstr, int important, const char *file, void gpr_timers_set_log_filename(const char *filename); +void gpr_timer_set_enabled(int enabled); + #if !(defined(GRPC_STAP_PROFILER) + defined(GRPC_BASIC_PROFILER)) /* No profiling. No-op all the things. */ #define GPR_TIMER_MARK(tag, important) \ diff --git a/src/core/lib/surface/completion_queue.c b/src/core/lib/surface/completion_queue.c index 47f53f7ad2..2412f78a06 100644 --- a/src/core/lib/surface/completion_queue.c +++ b/src/core/lib/surface/completion_queue.c @@ -335,7 +335,7 @@ static bool cq_is_next_finished(grpc_exec_ctx *exec_ctx, void *arg) { return true; } gpr_mu_unlock(cq->mu); - return gpr_time_cmp(a->deadline, gpr_now(a->deadline.clock_type)) > 0; + return gpr_time_cmp(a->deadline, gpr_now(a->deadline.clock_type)) < 0; } grpc_event grpc_completion_queue_next(grpc_completion_queue *cc, @@ -484,7 +484,7 @@ static bool cq_is_pluck_finished(grpc_exec_ctx *exec_ctx, void *arg) { prev = c; } gpr_mu_unlock(cq->mu); - return gpr_time_cmp(a->deadline, gpr_now(a->deadline.clock_type)) > 0; + return gpr_time_cmp(a->deadline, gpr_now(a->deadline.clock_type)) < 0; } grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag, diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc index 2aeaea51f2..7db99629d4 100644 --- a/test/cpp/qps/driver.cc +++ b/test/cpp/qps/driver.cc @@ -45,6 +45,7 @@ #include #include +#include "src/core/lib/profiling/timers.h" #include "src/core/lib/support/env.h" #include "src/proto/grpc/testing/services.grpc.pb.h" #include "test/core/util/port.h" @@ -405,6 +406,8 @@ std::unique_ptr RunScenario( start, gpr_time_from_seconds(warmup_seconds + benchmark_seconds, GPR_TIMESPAN))); + gpr_timer_set_enabled(0); + // Finish a run std::unique_ptr result(new ScenarioResult); Histogram merged_latencies; -- cgit v1.2.3 From 67eb59ee01269a8c6d87d614aaf548cccc6f7130 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 16 Aug 2016 11:40:54 -0700 Subject: Initial pass reifying read and global locks --- .../transport/chttp2/transport/chttp2_transport.c | 314 ++++----- src/core/ext/transport/chttp2/transport/frame.h | 4 +- .../ext/transport/chttp2/transport/frame_data.c | 29 +- .../ext/transport/chttp2/transport/frame_data.h | 4 +- .../ext/transport/chttp2/transport/frame_goaway.c | 13 +- .../ext/transport/chttp2/transport/frame_goaway.h | 4 +- .../ext/transport/chttp2/transport/frame_ping.c | 8 +- .../ext/transport/chttp2/transport/frame_ping.h | 4 +- .../transport/chttp2/transport/frame_rst_stream.c | 35 +- .../transport/chttp2/transport/frame_rst_stream.h | 4 +- .../transport/chttp2/transport/frame_settings.c | 17 +- .../transport/chttp2/transport/frame_settings.h | 4 +- .../chttp2/transport/frame_window_update.c | 33 +- .../chttp2/transport/frame_window_update.h | 4 +- .../ext/transport/chttp2/transport/hpack_parser.c | 28 +- .../ext/transport/chttp2/transport/hpack_parser.h | 4 +- src/core/ext/transport/chttp2/transport/internal.h | 169 ++--- src/core/ext/transport/chttp2/transport/parsing.c | 759 ++++++++------------- .../ext/transport/chttp2/transport/stream_lists.c | 57 -- 19 files changed, 563 insertions(+), 931 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 16946de853..45ad8d7ed0 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -69,10 +69,6 @@ int grpc_http_write_state_trace = 0; ((grpc_chttp2_transport *)((char *)(tw)-offsetof(grpc_chttp2_transport, \ writing))) -#define TRANSPORT_FROM_PARSING(tp) \ - ((grpc_chttp2_transport *)((char *)(tp)-offsetof(grpc_chttp2_transport, \ - parsing))) - #define TRANSPORT_FROM_GLOBAL(tg) \ ((grpc_chttp2_transport *)((char *)(tg)-offsetof(grpc_chttp2_transport, \ global))) @@ -80,19 +76,13 @@ int grpc_http_write_state_trace = 0; #define STREAM_FROM_GLOBAL(sg) \ ((grpc_chttp2_stream *)((char *)(sg)-offsetof(grpc_chttp2_stream, global))) -#define STREAM_FROM_PARSING(sg) \ - ((grpc_chttp2_stream *)((char *)(sg)-offsetof(grpc_chttp2_stream, parsing))) - static const grpc_transport_vtable vtable; /* forward declarations of various callbacks that we'll build closures around */ static void writing_action(grpc_exec_ctx *exec_ctx, void *t, grpc_error *error); static void reading_action(grpc_exec_ctx *exec_ctx, void *t, grpc_error *error); -static void parsing_action(grpc_exec_ctx *exec_ctx, void *t, grpc_error *error); static void reading_action_locked(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error); -static void post_parse_locked(grpc_exec_ctx *exec_ctx, void *arg, - grpc_error *error); static void initiate_writing_locked(grpc_exec_ctx *exec_ctx, void *t, grpc_error *error); static void initiate_read_flush_locked(grpc_exec_ctx *exec_ctx, void *t, @@ -164,10 +154,9 @@ static void destruct_transport(grpc_exec_ctx *exec_ctx, gpr_slice_buffer_destroy(&t->writing.outbuf); grpc_chttp2_hpack_compressor_destroy(&t->writing.hpack_compressor); - gpr_slice_buffer_destroy(&t->parsing.qbuf); gpr_slice_buffer_destroy(&t->read_buffer); - grpc_chttp2_hpack_parser_destroy(&t->parsing.hpack_parser); - grpc_chttp2_goaway_parser_destroy(&t->parsing.goaway_parser); + grpc_chttp2_hpack_parser_destroy(&t->global.hpack_parser); + grpc_chttp2_goaway_parser_destroy(&t->global.goaway_parser); for (i = 0; i < STREAM_LIST_COUNT; i++) { GPR_ASSERT(t->lists[i].head == NULL); @@ -251,15 +240,14 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, t->global.next_stream_id = is_client ? 1 : 2; t->global.is_client = is_client; t->writing.outgoing_window = DEFAULT_WINDOW; - t->parsing.incoming_window = DEFAULT_WINDOW; + t->global.incoming_window = DEFAULT_WINDOW; t->global.stream_lookahead = DEFAULT_WINDOW; t->global.connection_window_target = DEFAULT_CONNECTION_WINDOW_TARGET; t->global.ping_counter = 1; t->global.pings.next = t->global.pings.prev = &t->global.pings; - t->parsing.is_client = is_client; - t->parsing.deframe_state = + t->global.deframe_state = is_client ? GRPC_DTS_FH_0 : GRPC_DTS_CLIENT_PREFIX_0; - t->parsing.is_first_frame = true; + t->global.is_first_frame = true; t->writing.is_client = is_client; grpc_connectivity_state_init( &t->channel_callback.state_tracker, GRPC_CHANNEL_READY, @@ -272,8 +260,6 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_closure_init(&t->writing_action, writing_action, t); grpc_closure_init(&t->reading_action, reading_action, t); grpc_closure_init(&t->reading_action_locked, reading_action_locked, t); - grpc_closure_init(&t->parsing_action, parsing_action, t); - grpc_closure_init(&t->post_parse_locked, post_parse_locked, t); grpc_closure_init(&t->initiate_writing, initiate_writing_locked, t); grpc_closure_init(&t->terminate_writing, terminate_writing_with_lock, t); grpc_closure_init(&t->initiate_read_flush_locked, initiate_read_flush_locked, @@ -281,9 +267,8 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_closure_init(&t->writing.done_cb, grpc_chttp2_terminate_writing, &t->writing); - gpr_slice_buffer_init(&t->parsing.qbuf); - grpc_chttp2_goaway_parser_init(&t->parsing.goaway_parser); - grpc_chttp2_hpack_parser_init(&t->parsing.hpack_parser); + grpc_chttp2_goaway_parser_init(&t->global.goaway_parser); + grpc_chttp2_hpack_parser_init(&t->global.hpack_parser); gpr_slice_buffer_init(&t->read_buffer); @@ -297,7 +282,6 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, /* copy in initial settings to all setting sets */ for (i = 0; i < GRPC_CHTTP2_NUM_SETTINGS; i++) { - t->parsing.settings[i] = grpc_chttp2_settings_parameters[i].default_value; for (j = 0; j < GRPC_NUM_SETTING_SETS; j++) { t->global.settings[j][i] = grpc_chttp2_settings_parameters[i].default_value; @@ -508,13 +492,9 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, gpr_ref_init(&s->global.active_streams, 1); GRPC_CHTTP2_STREAM_REF(&s->global, "chttp2"); - grpc_chttp2_incoming_metadata_buffer_init(&s->parsing.metadata_buffer[0]); - grpc_chttp2_incoming_metadata_buffer_init(&s->parsing.metadata_buffer[1]); - grpc_chttp2_incoming_metadata_buffer_init( - &s->global.received_initial_metadata); - grpc_chttp2_incoming_metadata_buffer_init( - &s->global.received_trailing_metadata); - grpc_chttp2_data_parser_init(&s->parsing.data_parser); + grpc_chttp2_incoming_metadata_buffer_init(&s->global.metadata_buffer[0]); + grpc_chttp2_incoming_metadata_buffer_init(&s->global.metadata_buffer[1]); + grpc_chttp2_data_parser_init(&s->global.data_parser); gpr_slice_buffer_init(&s->writing.flow_controlled_buffer); s->global.deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC); @@ -523,11 +503,10 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, if (server_data) { GPR_ASSERT(t->executor.parsing_active); s->global.id = (uint32_t)(uintptr_t)server_data; - s->parsing.id = s->global.id; s->global.outgoing_window = t->global.settings[GRPC_PEER_SETTINGS] [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]; - s->parsing.incoming_window = s->global.max_recv_bytes = + s->global.incoming_window = s->global.max_recv_bytes = t->global.settings[GRPC_SENT_SETTINGS] [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]; *t->accepting_stream = s; @@ -571,8 +550,6 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp, incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE); } - grpc_chttp2_list_remove_unannounced_incoming_window_available(&t->global, - &s->global); grpc_chttp2_list_remove_stalled_by_transport(&t->global, &s->global); grpc_chttp2_list_remove_check_read_ops(&t->global, &s->global); @@ -590,13 +567,9 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp, GPR_ASSERT(s->global.recv_initial_metadata_ready == NULL); GPR_ASSERT(s->global.recv_message_ready == NULL); GPR_ASSERT(s->global.recv_trailing_metadata_finished == NULL); - grpc_chttp2_data_parser_destroy(exec_ctx, &s->parsing.data_parser); - grpc_chttp2_incoming_metadata_buffer_destroy(&s->parsing.metadata_buffer[0]); - grpc_chttp2_incoming_metadata_buffer_destroy(&s->parsing.metadata_buffer[1]); - grpc_chttp2_incoming_metadata_buffer_destroy( - &s->global.received_initial_metadata); - grpc_chttp2_incoming_metadata_buffer_destroy( - &s->global.received_trailing_metadata); + grpc_chttp2_data_parser_destroy(exec_ctx, &s->global.data_parser); + grpc_chttp2_incoming_metadata_buffer_destroy(&s->global.metadata_buffer[0]); + grpc_chttp2_incoming_metadata_buffer_destroy(&s->global.metadata_buffer[1]); gpr_slice_buffer_destroy(&s->writing.flow_controlled_buffer); GRPC_ERROR_UNREF(s->global.read_closed_error); GRPC_ERROR_UNREF(s->global.write_closed_error); @@ -621,26 +594,26 @@ static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, GPR_TIMER_END("destroy_stream", 0); } -grpc_chttp2_stream_parsing *grpc_chttp2_parsing_lookup_stream( - grpc_chttp2_transport_parsing *transport_parsing, uint32_t id) { - grpc_chttp2_transport *t = TRANSPORT_FROM_PARSING(transport_parsing); +grpc_chttp2_stream_global *grpc_chttp2_parsing_lookup_stream( + grpc_chttp2_transport_global *transport_global, uint32_t id) { + grpc_chttp2_transport *t = TRANSPORT_FROM_GLOBAL(transport_global); grpc_chttp2_stream *s = grpc_chttp2_stream_map_find(&t->parsing_stream_map, id); - return s ? &s->parsing : NULL; + return s ? &s->global : NULL; } -grpc_chttp2_stream_parsing *grpc_chttp2_parsing_accept_stream( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing, +grpc_chttp2_stream_global *grpc_chttp2_parsing_accept_stream( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, uint32_t id) { grpc_chttp2_stream *accepting; - grpc_chttp2_transport *t = TRANSPORT_FROM_PARSING(transport_parsing); + grpc_chttp2_transport *t = TRANSPORT_FROM_GLOBAL(transport_global); GPR_ASSERT(t->accepting_stream == NULL); t->accepting_stream = &accepting; t->channel_callback.accept_stream(exec_ctx, t->channel_callback.accept_stream_user_data, &t->base, (void *)(uintptr_t)id); t->accepting_stream = NULL; - return &accepting->parsing; + return &accepting->global; } /******************************************************************************* @@ -913,15 +886,13 @@ static void maybe_start_some_streams( grpc_chttp2_list_pop_waiting_for_concurrency(transport_global, &stream_global)) { /* safe since we can't (legally) be parsing this stream yet */ - grpc_chttp2_stream_parsing *stream_parsing = - &STREAM_FROM_GLOBAL(stream_global)->parsing; GRPC_CHTTP2_IF_TRACING(gpr_log( GPR_DEBUG, "HTTP:%s: Allocating new grpc_chttp2_stream %p to id %d", transport_global->is_client ? "CLI" : "SVR", stream_global, transport_global->next_stream_id)); GPR_ASSERT(stream_global->id == 0); - stream_global->id = stream_parsing->id = transport_global->next_stream_id; + stream_global->id = transport_global->next_stream_id; transport_global->next_stream_id += 2; if (transport_global->next_stream_id >= MAX_CLIENT_STREAM_ID) { @@ -933,7 +904,7 @@ static void maybe_start_some_streams( stream_global->outgoing_window = transport_global->settings[GRPC_PEER_SETTINGS] [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]; - stream_parsing->incoming_window = stream_incoming_window = + stream_global->incoming_window = stream_incoming_window = transport_global->settings[GRPC_SENT_SETTINGS] [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]; stream_global->max_recv_bytes = @@ -1271,10 +1242,10 @@ static void ack_ping_locked(grpc_exec_ctx *exec_ctx, void *a, } void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_parsing *transport_parsing, + grpc_chttp2_transport_global *transport_global, const uint8_t *opaque_8bytes) { ack_ping_args *args = gpr_malloc(sizeof(*args)); - args->t = TRANSPORT_FROM_PARSING(transport_parsing); + args->t = TRANSPORT_FROM_GLOBAL(transport_global); memcpy(args->opaque_8bytes, opaque_8bytes, sizeof(args->opaque_8bytes)); grpc_closure_init(&args->closure, ack_ping_locked, args); REF_TRANSPORT(args->t, "ack_ping"); @@ -1366,7 +1337,7 @@ static void check_read_ops(grpc_exec_ctx *exec_ctx, while ( grpc_chttp2_list_pop_check_read_ops(transport_global, &stream_global)) { if (stream_global->recv_initial_metadata_ready != NULL && - stream_global->published_initial_metadata) { + stream_global->published_metadata[0]) { if (stream_global->seen_error) { while ((bs = grpc_chttp2_incoming_frame_queue_pop( &stream_global->incoming_frames)) != NULL) { @@ -1382,7 +1353,7 @@ static void check_read_ops(grpc_exec_ctx *exec_ctx, } } grpc_chttp2_incoming_metadata_buffer_publish( - &stream_global->received_initial_metadata, + &stream_global->metadata_buffer[0], stream_global->recv_initial_metadata); grpc_exec_ctx_sched(exec_ctx, stream_global->recv_initial_metadata_ready, GRPC_ERROR_NONE, NULL); @@ -1402,7 +1373,7 @@ static void check_read_ops(grpc_exec_ctx *exec_ctx, grpc_exec_ctx_sched(exec_ctx, stream_global->recv_message_ready, GRPC_ERROR_NONE, NULL); stream_global->recv_message_ready = NULL; - } else if (stream_global->published_trailing_metadata) { + } else if (stream_global->published_metadata[1]) { *stream_global->recv_message = NULL; grpc_exec_ctx_sched(exec_ctx, stream_global->recv_message_ready, GRPC_ERROR_NONE, NULL); @@ -1427,7 +1398,7 @@ static void check_read_ops(grpc_exec_ctx *exec_ctx, } if (stream_global->all_incoming_byte_streams_finished) { grpc_chttp2_incoming_metadata_buffer_publish( - &stream_global->received_trailing_metadata, + &stream_global->metadata_buffer[0], stream_global->recv_trailing_metadata); grpc_chttp2_complete_closure_step( exec_ctx, transport_global, stream_global, @@ -1458,15 +1429,15 @@ static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, } GPR_ASSERT(s); s->global.in_stream_map = false; - if (t->parsing.incoming_stream == &s->parsing) { - t->parsing.incoming_stream = NULL; - grpc_chttp2_parsing_become_skip_parser(exec_ctx, &t->parsing); + if (t->global.incoming_stream == &s->global) { + t->global.incoming_stream = NULL; + grpc_chttp2_parsing_become_skip_parser(exec_ctx, &t->global); } - if (s->parsing.data_parser.parsing_frame != NULL) { + if (s->global.data_parser.parsing_frame != NULL) { grpc_chttp2_incoming_byte_stream_finished( - exec_ctx, s->parsing.data_parser.parsing_frame, GRPC_ERROR_REF(error), + exec_ctx, s->global.data_parser.parsing_frame, GRPC_ERROR_REF(error), 0); - s->parsing.data_parser.parsing_frame = NULL; + s->global.data_parser.parsing_frame = NULL; } if (grpc_chttp2_unregister_stream(t, s) && t->global.sent_goaway) { @@ -1570,22 +1541,22 @@ void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx, to the upper layers - drop what we've got, and then publish what we want - which is safe because we haven't told anyone about the metadata yet */ - if (!stream_global->published_trailing_metadata || + if (!stream_global->published_metadata[1] || stream_global->recv_trailing_metadata_finished != NULL) { char status_string[GPR_LTOA_MIN_BUFSIZE]; gpr_ltoa(status, status_string); grpc_chttp2_incoming_metadata_buffer_add( - &stream_global->received_trailing_metadata, + &stream_global->metadata_buffer[1], grpc_mdelem_from_metadata_strings( GRPC_MDSTR_GRPC_STATUS, grpc_mdstr_from_string(status_string))); if (slice) { grpc_chttp2_incoming_metadata_buffer_add( - &stream_global->received_trailing_metadata, + &stream_global->metadata_buffer[1], grpc_mdelem_from_metadata_strings( GRPC_MDSTR_GRPC_MESSAGE, grpc_mdstr_from_slice(gpr_slice_ref(*slice)))); } - stream_global->published_trailing_metadata = true; + stream_global->published_metadata[1] = true; grpc_chttp2_list_add_check_read_ops(exec_ctx, transport_global, stream_global); } @@ -1652,8 +1623,8 @@ void grpc_chttp2_mark_stream_closed( if (close_reads && !stream_global->read_closed) { stream_global->read_closed_error = GRPC_ERROR_REF(error); stream_global->read_closed = true; - stream_global->published_initial_metadata = true; - stream_global->published_trailing_metadata = true; + stream_global->published_metadata[0] = true; + stream_global->published_metadata[0] = true; decrement_active_streams_locked(exec_ctx, transport_global, stream_global); } if (close_writes && !stream_global->write_closed) { @@ -1851,7 +1822,7 @@ static void update_global_window(void *args, uint32_t id, void *stream) { grpc_chttp2_stream_global *stream_global = &s->global; int was_zero; int is_zero; - int64_t initial_window_update = t->parsing.initial_window_update; + int64_t initial_window_update = t->global.initial_window_update; was_zero = stream_global->outgoing_window <= 0; GRPC_CHTTP2_FLOW_CREDIT_STREAM("settings", transport_global, stream_global, @@ -1868,13 +1839,6 @@ static void update_global_window(void *args, uint32_t id, void *stream) { * INPUT PROCESSING - PARSING */ -static void parsing_action(grpc_exec_ctx *exec_ctx, void *arg, - grpc_error *error); -static void post_reading_action_locked(grpc_exec_ctx *exec_ctx, void *arg, - grpc_error *error); -static void post_parse_locked(grpc_exec_ctx *exec_ctx, void *arg, - grpc_error *error); - static void reading_action(grpc_exec_ctx *exec_ctx, void *tp, grpc_error *error) { /* Control flow: @@ -1888,30 +1852,6 @@ static void reading_action(grpc_exec_ctx *exec_ctx, void *tp, GPR_TIMER_END("reading_action", 0); } -static void reading_action_locked(grpc_exec_ctx *exec_ctx, void *tp, - grpc_error *error) { - GPR_TIMER_BEGIN("reading_action_locked", 0); - - grpc_chttp2_transport *t = tp; - grpc_chttp2_transport_global *transport_global = &t->global; - grpc_chttp2_transport_parsing *transport_parsing = &t->parsing; - - GPR_ASSERT(!t->executor.parsing_active); - if (!t->closed) { - t->executor.parsing_active = 1; - /* merge stream lists */ - grpc_chttp2_stream_map_move_into(&t->new_stream_map, - &t->parsing_stream_map); - grpc_chttp2_prepare_to_read(transport_global, transport_parsing); - grpc_exec_ctx_sched(exec_ctx, &t->parsing_action, GRPC_ERROR_REF(error), - NULL); - } else { - post_reading_action_locked(exec_ctx, t, error); - } - - GPR_TIMER_END("reading_action_locked", 0); -} - static grpc_error *try_http_parsing(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t) { grpc_http_parser parser; @@ -1939,87 +1879,86 @@ static grpc_error *try_http_parsing(grpc_exec_ctx *exec_ctx, return error; } -static void parsing_action(grpc_exec_ctx *exec_ctx, void *arg, - grpc_error *error) { - grpc_chttp2_transport *t = arg; - grpc_error *err = GRPC_ERROR_NONE; - GPR_TIMER_BEGIN("reading_action.parse", 0); - size_t i = 0; - grpc_error *errors[3] = {GRPC_ERROR_REF(error), GRPC_ERROR_NONE, - GRPC_ERROR_NONE}; - for (; i < t->read_buffer.count && errors[1] == GRPC_ERROR_NONE; i++) { - errors[1] = grpc_chttp2_perform_read(exec_ctx, &t->parsing, - t->read_buffer.slices[i]); - }; - if (errors[1] == GRPC_ERROR_NONE) { - err = GRPC_ERROR_REF(error); - } else { - errors[2] = try_http_parsing(exec_ctx, t); - err = GRPC_ERROR_CREATE_REFERENCING("Failed parsing HTTP/2", errors, - GPR_ARRAY_SIZE(errors)); - } - for (i = 0; i < GPR_ARRAY_SIZE(errors); i++) { - GRPC_ERROR_UNREF(errors[i]); - } - grpc_combiner_execute(exec_ctx, t->executor.combiner, &t->post_parse_locked, - err); - GPR_TIMER_END("reading_action.parse", 0); -} +static void reading_action_locked(grpc_exec_ctx *exec_ctx, void *tp, + grpc_error *error) { + GPR_TIMER_BEGIN("reading_action_locked", 0); -static void post_parse_locked(grpc_exec_ctx *exec_ctx, void *arg, - grpc_error *error) { - GPR_TIMER_BEGIN("post_parse_locked", 0); - grpc_chttp2_transport *t = arg; + grpc_chttp2_transport *t = tp; grpc_chttp2_transport_global *transport_global = &t->global; - grpc_chttp2_transport_parsing *transport_parsing = &t->parsing; - /* copy parsing qbuf to global qbuf */ - if (t->parsing.qbuf.count > 0) { - gpr_slice_buffer_move_into(&t->parsing.qbuf, &t->global.qbuf); - grpc_chttp2_initiate_write(exec_ctx, transport_global, false, - "parsing_qbuf"); - } - /* merge stream lists */ - grpc_chttp2_stream_map_move_into(&t->new_stream_map, &t->parsing_stream_map); - transport_global->concurrent_stream_count = - (uint32_t)grpc_chttp2_stream_map_size(&t->parsing_stream_map); - if (transport_parsing->initial_window_update != 0) { - update_global_window_args args = {t, exec_ctx}; - grpc_chttp2_stream_map_for_each(&t->parsing_stream_map, - update_global_window, &args); - transport_parsing->initial_window_update = 0; - } - /* handle higher level things */ - grpc_chttp2_publish_reads(exec_ctx, transport_global, transport_parsing); - t->executor.parsing_active = 0; - /* handle delayed transport ops (if there is one) */ - if (t->post_parsing_op) { - grpc_transport_op *op = t->post_parsing_op; - t->post_parsing_op = NULL; - perform_transport_op_locked(exec_ctx, op, GRPC_ERROR_NONE); - gpr_free(op); - } - /* if a stream is in the stream map, and gets cancelled, we need to - * ensure we are not parsing before continuing the cancellation to keep - * things in a sane state */ - grpc_chttp2_stream_global *stream_global; - while (grpc_chttp2_list_pop_closed_waiting_for_parsing(transport_global, - &stream_global)) { - GPR_ASSERT(stream_global->in_stream_map); - GPR_ASSERT(stream_global->write_closed); - GPR_ASSERT(stream_global->read_closed); - remove_stream(exec_ctx, t, stream_global->id, - removal_error(GRPC_ERROR_NONE, stream_global)); - GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2"); - } - post_reading_action_locked(exec_ctx, t, error); - GPR_TIMER_END("post_parse_locked", 0); -} + GRPC_ERROR_REF(error); + + GPR_ASSERT(!t->executor.parsing_active); + if (!t->closed) { + t->executor.parsing_active = 1; + /* merge stream lists */ + grpc_chttp2_stream_map_move_into(&t->new_stream_map, + &t->parsing_stream_map); + + GPR_TIMER_BEGIN("reading_action.parse", 0); + size_t i = 0; + grpc_error *errors[3] = {GRPC_ERROR_REF(error), GRPC_ERROR_NONE, + GRPC_ERROR_NONE}; + for (; i < t->read_buffer.count && errors[1] == GRPC_ERROR_NONE; i++) { + errors[1] = grpc_chttp2_perform_read(exec_ctx, &t->global, + t->read_buffer.slices[i]); + }; + if (errors[1] != GRPC_ERROR_NONE) { + errors[2] = try_http_parsing(exec_ctx, t); + GRPC_ERROR_UNREF(error); + error = GRPC_ERROR_CREATE_REFERENCING("Failed parsing HTTP/2", errors, + GPR_ARRAY_SIZE(errors)); + } + for (i = 0; i < GPR_ARRAY_SIZE(errors); i++) { + GRPC_ERROR_UNREF(errors[i]); + } + GPR_TIMER_END("reading_action.parse", 0); + + GPR_TIMER_BEGIN("post_parse_locked", 0); + if (transport_global->initial_window_update != 0) { + update_global_window_args args = {t, exec_ctx}; + grpc_chttp2_stream_map_for_each(&t->parsing_stream_map, + update_global_window, &args); + transport_global->initial_window_update = 0; + } + /* handle higher level things */ + if (transport_global->incoming_window < + transport_global->connection_window_target * 3 / 4) { + int64_t announce_bytes = transport_global->connection_window_target - + transport_global->incoming_window; + GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT( + "parsed", transport_global, announce_incoming_window, announce_bytes); + GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT("parsed", transport_global, + incoming_window, announce_bytes); + grpc_chttp2_initiate_write(exec_ctx, transport_global, false, + "global incoming window"); + } + t->executor.parsing_active = 0; + /* handle delayed transport ops (if there is one) */ + if (t->post_parsing_op) { + grpc_transport_op *op = t->post_parsing_op; + t->post_parsing_op = NULL; + perform_transport_op_locked(exec_ctx, op, GRPC_ERROR_NONE); + gpr_free(op); + } + /* if a stream is in the stream map, and gets cancelled, we need to + * ensure we are not parsing before continuing the cancellation to keep + * things in a sane state */ + grpc_chttp2_stream_global *stream_global; + while (grpc_chttp2_list_pop_closed_waiting_for_parsing(transport_global, + &stream_global)) { + GPR_ASSERT(stream_global->in_stream_map); + GPR_ASSERT(stream_global->write_closed); + GPR_ASSERT(stream_global->read_closed); + remove_stream(exec_ctx, t, stream_global->id, + removal_error(GRPC_ERROR_NONE, stream_global)); + GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2"); + } + + GPR_TIMER_END("post_parse_locked", 0); + } -static void post_reading_action_locked(grpc_exec_ctx *exec_ctx, void *arg, - grpc_error *error) { GPR_TIMER_BEGIN("post_reading_action_locked", 0); - grpc_chttp2_transport *t = arg; bool keep_reading = false; GRPC_ERROR_REF(error); if (error == GRPC_ERROR_NONE && t->closed) { @@ -2049,6 +1988,10 @@ static void post_reading_action_locked(grpc_exec_ctx *exec_ctx, void *arg, GRPC_ERROR_UNREF(error); GPR_TIMER_END("post_reading_action_locked", 0); + + GRPC_ERROR_UNREF(error); + + GPR_TIMER_END("reading_action_locked", 0); } /******************************************************************************* @@ -2125,13 +2068,10 @@ static void incoming_byte_stream_update_flow_control( GRPC_CHTTP2_FLOW_CREDIT_STREAM("op", transport_global, stream_global, max_recv_bytes, add_max_recv_bytes); GRPC_CHTTP2_FLOW_CREDIT_STREAM("op", transport_global, stream_global, - unannounced_incoming_window_for_parse, - add_max_recv_bytes); + incoming_window, add_max_recv_bytes); GRPC_CHTTP2_FLOW_CREDIT_STREAM("op", transport_global, stream_global, unannounced_incoming_window_for_writing, add_max_recv_bytes); - grpc_chttp2_list_add_unannounced_incoming_window_available(transport_global, - stream_global); grpc_chttp2_become_writable(exec_ctx, transport_global, stream_global, false, "read_incoming_stream"); } @@ -2259,8 +2199,8 @@ void grpc_chttp2_incoming_byte_stream_finished( } grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, uint32_t frame_size, + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global, uint32_t frame_size, uint32_t flags, grpc_chttp2_incoming_frame_queue *add_to_queue) { grpc_chttp2_incoming_byte_stream *incoming_byte_stream = gpr_malloc(sizeof(*incoming_byte_stream)); @@ -2271,8 +2211,8 @@ grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( gpr_mu_init(&incoming_byte_stream->slice_mu); gpr_ref_init(&incoming_byte_stream->refs, 2); incoming_byte_stream->next_message = NULL; - incoming_byte_stream->transport = TRANSPORT_FROM_PARSING(transport_parsing); - incoming_byte_stream->stream = STREAM_FROM_PARSING(stream_parsing); + incoming_byte_stream->transport = TRANSPORT_FROM_GLOBAL(transport_global); + incoming_byte_stream->stream = STREAM_FROM_GLOBAL(stream_global); gpr_ref(&incoming_byte_stream->stream->global.active_streams); gpr_slice_buffer_init(&incoming_byte_stream->slices); incoming_byte_stream->on_next = NULL; diff --git a/src/core/ext/transport/chttp2/transport/frame.h b/src/core/ext/transport/chttp2/transport/frame.h index 7776609367..48e3ac6482 100644 --- a/src/core/ext/transport/chttp2/transport/frame.h +++ b/src/core/ext/transport/chttp2/transport/frame.h @@ -40,8 +40,8 @@ #include "src/core/lib/iomgr/error.h" /* defined in internal.h */ -typedef struct grpc_chttp2_stream_parsing grpc_chttp2_stream_parsing; -typedef struct grpc_chttp2_transport_parsing grpc_chttp2_transport_parsing; +typedef struct grpc_chttp2_stream_global grpc_chttp2_stream_global; +typedef struct grpc_chttp2_transport_global grpc_chttp2_transport_global; #define GRPC_CHTTP2_FRAME_DATA 0 #define GRPC_CHTTP2_FRAME_HEADER 1 diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c index 9046fbc453..5c6d6f8ce1 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.c +++ b/src/core/ext/transport/chttp2/transport/frame_data.c @@ -147,8 +147,8 @@ void grpc_chttp2_encode_data(uint32_t id, gpr_slice_buffer *inbuf, grpc_error *grpc_chttp2_data_parser_parse( grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last) { + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global, gpr_slice slice, int is_last) { uint8_t *const beg = GPR_SLICE_START_PTR(slice); uint8_t *const end = GPR_SLICE_END_PTR(slice); uint8_t *cur = beg; @@ -158,7 +158,8 @@ grpc_error *grpc_chttp2_data_parser_parse( char *msg; if (is_last && p->is_last_frame) { - stream_parsing->received_close = 1; + grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global, + true, false, GRPC_ERROR_NONE); } if (cur == end) { @@ -171,7 +172,7 @@ grpc_error *grpc_chttp2_data_parser_parse( return GRPC_ERROR_REF(p->error); fh_0: case GRPC_CHTTP2_DATA_FH_0: - stream_parsing->stats.incoming.framing_bytes++; + stream_global->stats.incoming.framing_bytes++; p->frame_type = *cur; switch (p->frame_type) { case 0: @@ -184,7 +185,7 @@ grpc_error *grpc_chttp2_data_parser_parse( gpr_asprintf(&msg, "Bad GRPC frame type 0x%02x", p->frame_type); p->error = GRPC_ERROR_CREATE(msg); p->error = grpc_error_set_int(p->error, GRPC_ERROR_INT_STREAM_ID, - (intptr_t)stream_parsing->id); + (intptr_t)stream_global->id); gpr_free(msg); msg = gpr_dump_slice(slice, GPR_DUMP_HEX | GPR_DUMP_ASCII); p->error = @@ -201,7 +202,7 @@ grpc_error *grpc_chttp2_data_parser_parse( } /* fallthrough */ case GRPC_CHTTP2_DATA_FH_1: - stream_parsing->stats.incoming.framing_bytes++; + stream_global->stats.incoming.framing_bytes++; p->frame_size = ((uint32_t)*cur) << 24; if (++cur == end) { p->state = GRPC_CHTTP2_DATA_FH_2; @@ -209,7 +210,7 @@ grpc_error *grpc_chttp2_data_parser_parse( } /* fallthrough */ case GRPC_CHTTP2_DATA_FH_2: - stream_parsing->stats.incoming.framing_bytes++; + stream_global->stats.incoming.framing_bytes++; p->frame_size |= ((uint32_t)*cur) << 16; if (++cur == end) { p->state = GRPC_CHTTP2_DATA_FH_3; @@ -217,7 +218,7 @@ grpc_error *grpc_chttp2_data_parser_parse( } /* fallthrough */ case GRPC_CHTTP2_DATA_FH_3: - stream_parsing->stats.incoming.framing_bytes++; + stream_global->stats.incoming.framing_bytes++; p->frame_size |= ((uint32_t)*cur) << 8; if (++cur == end) { p->state = GRPC_CHTTP2_DATA_FH_4; @@ -225,7 +226,7 @@ grpc_error *grpc_chttp2_data_parser_parse( } /* fallthrough */ case GRPC_CHTTP2_DATA_FH_4: - stream_parsing->stats.incoming.framing_bytes++; + stream_global->stats.incoming.framing_bytes++; p->frame_size |= ((uint32_t)*cur); p->state = GRPC_CHTTP2_DATA_FRAME; ++cur; @@ -235,18 +236,16 @@ grpc_error *grpc_chttp2_data_parser_parse( } p->parsing_frame = incoming_byte_stream = grpc_chttp2_incoming_byte_stream_create( - exec_ctx, transport_parsing, stream_parsing, p->frame_size, + exec_ctx, transport_global, stream_global, p->frame_size, message_flags, &p->incoming_frames); /* fallthrough */ case GRPC_CHTTP2_DATA_FRAME: - grpc_chttp2_list_add_parsing_seen_stream(transport_parsing, - stream_parsing); if (cur == end) { return GRPC_ERROR_NONE; } uint32_t remaining = (uint32_t)(end - cur); if (remaining == p->frame_size) { - stream_parsing->stats.incoming.data_bytes += p->frame_size; + stream_global->stats.incoming.data_bytes += p->frame_size; grpc_chttp2_incoming_byte_stream_push( exec_ctx, p->parsing_frame, gpr_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); @@ -256,7 +255,7 @@ grpc_error *grpc_chttp2_data_parser_parse( p->state = GRPC_CHTTP2_DATA_FH_0; return GRPC_ERROR_NONE; } else if (remaining > p->frame_size) { - stream_parsing->stats.incoming.data_bytes += p->frame_size; + stream_global->stats.incoming.data_bytes += p->frame_size; grpc_chttp2_incoming_byte_stream_push( exec_ctx, p->parsing_frame, gpr_slice_sub(slice, (size_t)(cur - beg), @@ -272,7 +271,7 @@ grpc_error *grpc_chttp2_data_parser_parse( exec_ctx, p->parsing_frame, gpr_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); p->frame_size -= remaining; - stream_parsing->stats.incoming.data_bytes += remaining; + stream_global->stats.incoming.data_bytes += remaining; return GRPC_ERROR_NONE; } } diff --git a/src/core/ext/transport/chttp2/transport/frame_data.h b/src/core/ext/transport/chttp2/transport/frame_data.h index a21a7942b9..b0c1cad976 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.h +++ b/src/core/ext/transport/chttp2/transport/frame_data.h @@ -94,8 +94,8 @@ grpc_error *grpc_chttp2_data_parser_begin_frame(grpc_chttp2_data_parser *parser, frame */ grpc_error *grpc_chttp2_data_parser_parse( grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last); + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global, gpr_slice slice, int is_last); void grpc_chttp2_encode_data(uint32_t id, gpr_slice_buffer *inbuf, uint32_t write_bytes, int is_eof, diff --git a/src/core/ext/transport/chttp2/transport/frame_goaway.c b/src/core/ext/transport/chttp2/transport/frame_goaway.c index 299e27ad70..e40c5e393b 100644 --- a/src/core/ext/transport/chttp2/transport/frame_goaway.c +++ b/src/core/ext/transport/chttp2/transport/frame_goaway.c @@ -69,8 +69,8 @@ grpc_error *grpc_chttp2_goaway_parser_begin_frame(grpc_chttp2_goaway_parser *p, grpc_error *grpc_chttp2_goaway_parser_parse( grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last) { + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global, gpr_slice slice, int is_last) { uint8_t *const beg = GPR_SLICE_START_PTR(slice); uint8_t *const end = GPR_SLICE_END_PTR(slice); uint8_t *cur = beg; @@ -148,12 +148,9 @@ grpc_error *grpc_chttp2_goaway_parser_parse( p->debug_pos += (uint32_t)(end - cur); p->state = GRPC_CHTTP2_GOAWAY_DEBUG; if (is_last) { - transport_parsing->goaway_received = 1; - transport_parsing->goaway_last_stream_index = p->last_stream_id; - gpr_slice_unref(transport_parsing->goaway_text); - transport_parsing->goaway_error = (grpc_status_code)p->error_code; - transport_parsing->goaway_text = - gpr_slice_new(p->debug_data, p->debug_length, gpr_free); + grpc_chttp2_add_incoming_goaway( + exec_ctx, transport_global, (uint32_t)p->error_code, + gpr_slice_new(p->debug_data, p->debug_length, gpr_free)); p->debug_data = NULL; } return GRPC_ERROR_NONE; diff --git a/src/core/ext/transport/chttp2/transport/frame_goaway.h b/src/core/ext/transport/chttp2/transport/frame_goaway.h index eb4303405a..f821229931 100644 --- a/src/core/ext/transport/chttp2/transport/frame_goaway.h +++ b/src/core/ext/transport/chttp2/transport/frame_goaway.h @@ -67,8 +67,8 @@ grpc_error *grpc_chttp2_goaway_parser_begin_frame( grpc_chttp2_goaway_parser *parser, uint32_t length, uint8_t flags); grpc_error *grpc_chttp2_goaway_parser_parse( grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last); + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global, gpr_slice slice, int is_last); void grpc_chttp2_goaway_append(uint32_t last_stream_id, uint32_t error_code, gpr_slice debug_data, diff --git a/src/core/ext/transport/chttp2/transport/frame_ping.c b/src/core/ext/transport/chttp2/transport/frame_ping.c index 1f814ab1bd..65b7cec986 100644 --- a/src/core/ext/transport/chttp2/transport/frame_ping.c +++ b/src/core/ext/transport/chttp2/transport/frame_ping.c @@ -75,8 +75,8 @@ grpc_error *grpc_chttp2_ping_parser_begin_frame(grpc_chttp2_ping_parser *parser, grpc_error *grpc_chttp2_ping_parser_parse( grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last) { + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global, gpr_slice slice, int is_last) { uint8_t *const beg = GPR_SLICE_START_PTR(slice); uint8_t *const end = GPR_SLICE_END_PTR(slice); uint8_t *cur = beg; @@ -91,9 +91,9 @@ grpc_error *grpc_chttp2_ping_parser_parse( if (p->byte == 8) { GPR_ASSERT(is_last); if (p->is_ack) { - grpc_chttp2_ack_ping(exec_ctx, transport_parsing, p->opaque_8bytes); + grpc_chttp2_ack_ping(exec_ctx, transport_global, p->opaque_8bytes); } else { - gpr_slice_buffer_add(&transport_parsing->qbuf, + gpr_slice_buffer_add(&transport_global->qbuf, grpc_chttp2_ping_create(1, p->opaque_8bytes)); } } diff --git a/src/core/ext/transport/chttp2/transport/frame_ping.h b/src/core/ext/transport/chttp2/transport/frame_ping.h index 5a8723421c..c2c4fb2ee5 100644 --- a/src/core/ext/transport/chttp2/transport/frame_ping.h +++ b/src/core/ext/transport/chttp2/transport/frame_ping.h @@ -50,7 +50,7 @@ grpc_error *grpc_chttp2_ping_parser_begin_frame(grpc_chttp2_ping_parser *parser, uint32_t length, uint8_t flags); grpc_error *grpc_chttp2_ping_parser_parse( grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last); + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global, gpr_slice slice, int is_last); #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FRAME_PING_H */ diff --git a/src/core/ext/transport/chttp2/transport/frame_rst_stream.c b/src/core/ext/transport/chttp2/transport/frame_rst_stream.c index e3a3c9e4a7..7be664ced4 100644 --- a/src/core/ext/transport/chttp2/transport/frame_rst_stream.c +++ b/src/core/ext/transport/chttp2/transport/frame_rst_stream.c @@ -39,6 +39,8 @@ #include #include "src/core/ext/transport/chttp2/transport/frame.h" +#include "src/core/ext/transport/chttp2/transport/http2_errors.h" +#include "src/core/ext/transport/chttp2/transport/status_conversion.h" gpr_slice grpc_chttp2_rst_stream_create(uint32_t id, uint32_t code, grpc_transport_one_way_stats *stats) { @@ -85,8 +87,8 @@ grpc_error *grpc_chttp2_rst_stream_parser_begin_frame( grpc_error *grpc_chttp2_rst_stream_parser_parse( grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last) { + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global, gpr_slice slice, int is_last) { uint8_t *const beg = GPR_SLICE_START_PTR(slice); uint8_t *const end = GPR_SLICE_END_PTR(slice); uint8_t *cur = beg; @@ -97,19 +99,30 @@ grpc_error *grpc_chttp2_rst_stream_parser_parse( cur++; p->byte++; } - stream_parsing->stats.incoming.framing_bytes += (uint64_t)(end - cur); + stream_global->stats.incoming.framing_bytes += (uint64_t)(end - cur); if (p->byte == 4) { GPR_ASSERT(is_last); - stream_parsing->received_close = 1; - if (stream_parsing->forced_close_error == GRPC_ERROR_NONE) { - stream_parsing->forced_close_error = grpc_error_set_int( - GRPC_ERROR_CREATE("RST_STREAM"), GRPC_ERROR_INT_HTTP2_ERROR, - (intptr_t)((((uint32_t)p->reason_bytes[0]) << 24) | - (((uint32_t)p->reason_bytes[1]) << 16) | - (((uint32_t)p->reason_bytes[2]) << 8) | - (((uint32_t)p->reason_bytes[3])))); + uint32_t reason = (((uint32_t)p->reason_bytes[0]) << 24) | + (((uint32_t)p->reason_bytes[1]) << 16) | + (((uint32_t)p->reason_bytes[2]) << 8) | + (((uint32_t)p->reason_bytes[3])); + grpc_error *error = GRPC_ERROR_NONE; + if (reason != GRPC_CHTTP2_NO_ERROR) { + error = grpc_error_set_int(GRPC_ERROR_CREATE("RST_STREAM"), + GRPC_ERROR_INT_HTTP2_ERROR, reason); + grpc_status_code status_code = grpc_chttp2_http2_error_to_grpc_status( + (grpc_chttp2_error_code)reason, stream_global->deadline); + char *status_details; + gpr_asprintf(&status_details, "Received RST_STREAM with error code %d", + reason); + gpr_slice slice_details = gpr_slice_from_copied_string(status_details); + gpr_free(status_details); + grpc_chttp2_fake_status(exec_ctx, transport_global, stream_global, + status_code, &slice_details); } + grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global, + true, true, error); } return GRPC_ERROR_NONE; diff --git a/src/core/ext/transport/chttp2/transport/frame_rst_stream.h b/src/core/ext/transport/chttp2/transport/frame_rst_stream.h index 11cf94f3ea..64a6a27341 100644 --- a/src/core/ext/transport/chttp2/transport/frame_rst_stream.h +++ b/src/core/ext/transport/chttp2/transport/frame_rst_stream.h @@ -51,7 +51,7 @@ grpc_error *grpc_chttp2_rst_stream_parser_begin_frame( grpc_chttp2_rst_stream_parser *parser, uint32_t length, uint8_t flags); grpc_error *grpc_chttp2_rst_stream_parser_parse( grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last); + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global, gpr_slice slice, int is_last); #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FRAME_RST_STREAM_H */ diff --git a/src/core/ext/transport/chttp2/transport/frame_settings.c b/src/core/ext/transport/chttp2/transport/frame_settings.c index 04b96c4cd9..32e6aa545f 100644 --- a/src/core/ext/transport/chttp2/transport/frame_settings.c +++ b/src/core/ext/transport/chttp2/transport/frame_settings.c @@ -145,8 +145,8 @@ grpc_error *grpc_chttp2_settings_parser_begin_frame( grpc_error *grpc_chttp2_settings_parser_parse( grpc_exec_ctx *exec_ctx, void *p, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last) { + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global, gpr_slice slice, int is_last) { grpc_chttp2_settings_parser *parser = p; const uint8_t *cur = GPR_SLICE_START_PTR(slice); const uint8_t *end = GPR_SLICE_END_PTR(slice); @@ -162,10 +162,9 @@ grpc_error *grpc_chttp2_settings_parser_parse( if (cur == end) { parser->state = GRPC_CHTTP2_SPS_ID0; if (is_last) { - transport_parsing->settings_updated = 1; memcpy(parser->target_settings, parser->incoming_settings, GRPC_CHTTP2_NUM_SETTINGS * sizeof(uint32_t)); - gpr_slice_buffer_add(&transport_parsing->qbuf, + gpr_slice_buffer_add(&transport_global->qbuf, grpc_chttp2_settings_ack_create()); } return GRPC_ERROR_NONE; @@ -226,9 +225,9 @@ grpc_error *grpc_chttp2_settings_parser_parse( break; case GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE: grpc_chttp2_goaway_append( - transport_parsing->last_incoming_stream_id, sp->error_value, + transport_global->last_incoming_stream_id, sp->error_value, gpr_slice_from_static_string("HTTP2 settings error"), - &transport_parsing->qbuf); + &transport_global->qbuf); gpr_asprintf(&msg, "invalid value %u passed for %s", parser->value, sp->name); grpc_error *err = GRPC_ERROR_CREATE(msg); @@ -238,17 +237,17 @@ grpc_error *grpc_chttp2_settings_parser_parse( } if (parser->id == GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE && parser->incoming_settings[parser->id] != parser->value) { - transport_parsing->initial_window_update = + transport_global->initial_window_update = (int64_t)parser->value - parser->incoming_settings[parser->id]; if (grpc_http_trace) { gpr_log(GPR_DEBUG, "adding %d for initial_window change", - (int)transport_parsing->initial_window_update); + (int)transport_global->initial_window_update); } } parser->incoming_settings[parser->id] = parser->value; if (grpc_http_trace) { gpr_log(GPR_DEBUG, "CHTTP2:%s: got setting %d = %d", - transport_parsing->is_client ? "CLI" : "SVR", parser->id, + transport_global->is_client ? "CLI" : "SVR", parser->id, parser->value); } } else if (grpc_http_trace) { diff --git a/src/core/ext/transport/chttp2/transport/frame_settings.h b/src/core/ext/transport/chttp2/transport/frame_settings.h index f654c598c8..c19f8067cc 100644 --- a/src/core/ext/transport/chttp2/transport/frame_settings.h +++ b/src/core/ext/transport/chttp2/transport/frame_settings.h @@ -97,7 +97,7 @@ grpc_error *grpc_chttp2_settings_parser_begin_frame( uint32_t *settings); grpc_error *grpc_chttp2_settings_parser_parse( grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last); + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global, gpr_slice slice, int is_last); #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FRAME_SETTINGS_H */ diff --git a/src/core/ext/transport/chttp2/transport/frame_window_update.c b/src/core/ext/transport/chttp2/transport/frame_window_update.c index 3cf848fd5c..26bd73f0af 100644 --- a/src/core/ext/transport/chttp2/transport/frame_window_update.c +++ b/src/core/ext/transport/chttp2/transport/frame_window_update.c @@ -81,8 +81,8 @@ grpc_error *grpc_chttp2_window_update_parser_begin_frame( grpc_error *grpc_chttp2_window_update_parser_parse( grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last) { + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global, gpr_slice slice, int is_last) { uint8_t *const beg = GPR_SLICE_START_PTR(slice); uint8_t *const end = GPR_SLICE_END_PTR(slice); uint8_t *cur = beg; @@ -94,8 +94,8 @@ grpc_error *grpc_chttp2_window_update_parser_parse( p->byte++; } - if (stream_parsing != NULL) { - stream_parsing->stats.incoming.framing_bytes += (uint32_t)(end - cur); + if (stream_global != NULL) { + stream_global->stats.incoming.framing_bytes += (uint32_t)(end - cur); } if (p->byte == 4) { @@ -109,17 +109,26 @@ grpc_error *grpc_chttp2_window_update_parser_parse( } GPR_ASSERT(is_last); - if (transport_parsing->incoming_stream_id != 0) { - if (stream_parsing != NULL) { - GRPC_CHTTP2_FLOW_CREDIT_STREAM("parse", transport_parsing, - stream_parsing, outgoing_window, - received_update); - grpc_chttp2_list_add_parsing_seen_stream(transport_parsing, - stream_parsing); + if (transport_global->incoming_stream_id != 0) { + if (stream_global != NULL) { + bool was_zero = stream_global->outgoing_window <= 0; + GRPC_CHTTP2_FLOW_CREDIT_STREAM("parse", transport_global, stream_global, + outgoing_window, received_update); + bool is_zero = stream_global->outgoing_window <= 0; + if (was_zero && !is_zero) { + grpc_chttp2_become_writable(exec_ctx, transport_global, stream_global, + false, "stream.read_flow_control"); + } } } else { - GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT("parse", transport_parsing, + bool was_zero = transport_global->outgoing_window <= 0; + GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT("parse", transport_global, outgoing_window, received_update); + bool is_zero = transport_global->outgoing_window <= 0; + if (was_zero && !is_zero) { + grpc_chttp2_initiate_write(exec_ctx, transport_global, false, + "new_global_flow_control"); + } } } diff --git a/src/core/ext/transport/chttp2/transport/frame_window_update.h b/src/core/ext/transport/chttp2/transport/frame_window_update.h index 1bcbbf9247..36ae6bd0b1 100644 --- a/src/core/ext/transport/chttp2/transport/frame_window_update.h +++ b/src/core/ext/transport/chttp2/transport/frame_window_update.h @@ -52,7 +52,7 @@ grpc_error *grpc_chttp2_window_update_parser_begin_frame( grpc_chttp2_window_update_parser *parser, uint32_t length, uint8_t flags); grpc_error *grpc_chttp2_window_update_parser_parse( grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last); + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global, gpr_slice slice, int is_last); #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FRAME_WINDOW_UPDATE_H */ diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.c b/src/core/ext/transport/chttp2/transport/hpack_parser.c index 522455f7dc..a40591c809 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_parser.c +++ b/src/core/ext/transport/chttp2/transport/hpack_parser.c @@ -1496,12 +1496,12 @@ grpc_error *grpc_chttp2_hpack_parser_parse(grpc_chttp2_hpack_parser *p, grpc_error *grpc_chttp2_header_parser_parse( grpc_exec_ctx *exec_ctx, void *hpack_parser, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last) { + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global, gpr_slice slice, int is_last) { grpc_chttp2_hpack_parser *parser = hpack_parser; GPR_TIMER_BEGIN("grpc_chttp2_hpack_parser_parse", 0); - if (stream_parsing != NULL) { - stream_parsing->stats.incoming.header_bytes += GPR_SLICE_LENGTH(slice); + if (stream_global != NULL) { + stream_global->stats.incoming.header_bytes += GPR_SLICE_LENGTH(slice); } grpc_error *error = grpc_chttp2_hpack_parser_parse( parser, GPR_SLICE_START_PTR(slice), GPR_SLICE_END_PTR(slice)); @@ -1517,20 +1517,22 @@ grpc_error *grpc_chttp2_header_parser_parse( } /* need to check for null stream: this can occur if we receive an invalid stream id on a header */ - if (stream_parsing != NULL) { + if (stream_global != NULL) { if (parser->is_boundary) { - if (stream_parsing->header_frames_received == - GPR_ARRAY_SIZE(stream_parsing->got_metadata_on_parse)) { + if (stream_global->header_frames_received == + GPR_ARRAY_SIZE(stream_global->metadata_buffer)) { return GRPC_ERROR_CREATE("Too many trailer frames"); } - stream_parsing - ->got_metadata_on_parse[stream_parsing->header_frames_received] = 1; - stream_parsing->header_frames_received++; - grpc_chttp2_list_add_parsing_seen_stream(transport_parsing, - stream_parsing); + stream_global + ->published_metadata[stream_global->header_frames_received] = true; + stream_global->header_frames_received++; + grpc_chttp2_list_add_check_read_ops(exec_ctx, transport_global, + stream_global); } if (parser->is_eof) { - stream_parsing->received_close = 1; + grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, + stream_global, true, false, + GRPC_ERROR_NONE); } } parser->on_header = NULL; diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.h b/src/core/ext/transport/chttp2/transport/hpack_parser.h index 78eb38db5e..cbcf12ffed 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_parser.h +++ b/src/core/ext/transport/chttp2/transport/hpack_parser.h @@ -112,7 +112,7 @@ grpc_error *grpc_chttp2_hpack_parser_parse(grpc_chttp2_hpack_parser *p, the transport */ grpc_error *grpc_chttp2_header_parser_parse( grpc_exec_ctx *exec_ctx, void *hpack_parser, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last); + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global, gpr_slice slice, int is_last); #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_PARSER_H */ diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index b72cd61fcf..f3c3e1d2fe 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -61,11 +61,9 @@ typedef struct grpc_chttp2_stream grpc_chttp2_stream; typedef enum { GRPC_CHTTP2_LIST_ALL_STREAMS, GRPC_CHTTP2_LIST_CHECK_READ_OPS, - GRPC_CHTTP2_LIST_UNANNOUNCED_INCOMING_WINDOW_AVAILABLE, GRPC_CHTTP2_LIST_WRITABLE, GRPC_CHTTP2_LIST_WRITING, GRPC_CHTTP2_LIST_WRITTEN, - GRPC_CHTTP2_LIST_PARSING_SEEN, GRPC_CHTTP2_LIST_CLOSED_WAITING_FOR_PARSING, GRPC_CHTTP2_LIST_CLOSED_WAITING_FOR_WRITING, GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT, @@ -178,7 +176,7 @@ struct grpc_chttp2_incoming_byte_stream { grpc_closure finished_action; }; -typedef struct { +struct grpc_chttp2_transport_global { /** data to write next write */ gpr_slice_buffer qbuf; @@ -223,36 +221,7 @@ typedef struct { /** concurrent stream count: updated when not parsing, so this is a strict over-estimation on the client */ uint32_t concurrent_stream_count; -} grpc_chttp2_transport_global; - -typedef struct { - /** data to write now */ - gpr_slice_buffer outbuf; - /** hpack encoding */ - grpc_chttp2_hpack_compressor hpack_compressor; - int64_t outgoing_window; - /** is this a client? */ - uint8_t is_client; - /** callback for when writing is done */ - grpc_closure done_cb; -} grpc_chttp2_transport_writing; - -struct grpc_chttp2_transport_parsing { - /** is this transport a client? (boolean) */ - uint8_t is_client; - - /** were settings updated? */ - uint8_t settings_updated; - /** was a settings ack received? */ - uint8_t settings_ack_received; - /** was a goaway frame received? */ - uint8_t goaway_received; - /** initial window change */ - int64_t initial_window_update; - - /** data to write later - after parsing */ - gpr_slice_buffer qbuf; /** parser for headers */ grpc_chttp2_hpack_parser hpack_parser; /** simple one shot parsers */ @@ -265,13 +234,12 @@ struct grpc_chttp2_transport_parsing { /** parser for goaway frames */ grpc_chttp2_goaway_parser goaway_parser; + /** initial window change */ + int64_t initial_window_update; + /** window available for peer to send to us */ int64_t incoming_window; - /** next stream id available at the time of beginning parsing */ - uint32_t next_stream_id; - uint32_t last_incoming_stream_id; - /* deframing */ grpc_chttp2_deframe_transport_state deframe_state; uint8_t incoming_frame_type; @@ -282,29 +250,36 @@ struct grpc_chttp2_transport_parsing { uint32_t incoming_frame_size; uint32_t incoming_stream_id; - /* current max frame size */ - uint32_t max_frame_size; - /* active parser */ void *parser_data; - grpc_chttp2_stream_parsing *incoming_stream; + grpc_chttp2_stream_global *incoming_stream; grpc_error *(*parser)(grpc_exec_ctx *exec_ctx, void *parser_user_data, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global, gpr_slice slice, int is_last); - /* received settings */ - uint32_t settings[GRPC_CHTTP2_NUM_SETTINGS]; - /* last settings that were sent */ - uint32_t last_sent_settings[GRPC_CHTTP2_NUM_SETTINGS]; - /* goaway data */ grpc_status_code goaway_error; uint32_t goaway_last_stream_index; gpr_slice goaway_text; +}; +typedef struct { + /** data to write now */ + gpr_slice_buffer outbuf; + /** hpack encoding */ + grpc_chttp2_hpack_compressor hpack_compressor; int64_t outgoing_window; + /** is this a client? */ + uint8_t is_client; + /** callback for when writing is done */ + grpc_closure done_cb; +} grpc_chttp2_transport_writing; + +#if 0 +struct grpc_chttp2_transport_parsing { }; +#endif typedef enum { /** no writing activity allowed */ @@ -360,9 +335,6 @@ struct grpc_chttp2_transport { set writing_state >= GRPC_WRITING, and only by the writing closure chain. */ grpc_chttp2_transport_writing writing; - /** state only accessible by the chain of execution that - set parsing_active=1 */ - grpc_chttp2_transport_parsing parsing; /** maps stream id to grpc_chttp2_stream objects; owned by the parsing thread when parsing */ @@ -378,9 +350,6 @@ struct grpc_chttp2_transport { /** closure to start reading from the endpoint */ grpc_closure reading_action; grpc_closure reading_action_locked; - grpc_closure post_parse_locked; - /** closure to actually do parsing */ - grpc_closure parsing_action; /** closure to initiate writing */ grpc_closure initiate_writing; /** closure to finish writing */ @@ -410,7 +379,7 @@ struct grpc_chttp2_transport { grpc_transport_op *post_parsing_op; }; -typedef struct { +struct grpc_chttp2_stream_global { /** HTTP2 stream id for this stream, or zero if one has not been assigned */ uint32_t id; @@ -424,7 +393,8 @@ typedef struct { not yet announced to HTTP2 flow control. As the upper layers offer to read more bytes, this value increases. As we advertise incoming flow control window, this value decreases. */ - uint32_t unannounced_incoming_window_for_parse; + /* TODO(ctiller): remove this, it's equivalent to incoming_window now + uint32_t unannounced_incoming_window_for_parse; */ uint32_t unannounced_incoming_window_for_writing; /** things the upper layers would like to send */ grpc_metadata_batch *send_initial_metadata; @@ -465,17 +435,26 @@ typedef struct { /** the error that resulted in this stream being write-closed */ grpc_error *write_closed_error; - bool published_initial_metadata; - bool published_trailing_metadata; + bool published_metadata[2]; bool final_metadata_requested; - grpc_chttp2_incoming_metadata_buffer received_initial_metadata; - grpc_chttp2_incoming_metadata_buffer received_trailing_metadata; + grpc_chttp2_incoming_metadata_buffer metadata_buffer[2]; grpc_chttp2_incoming_frame_queue incoming_frames; gpr_timespec deadline; -} grpc_chttp2_stream_global; + + /** saw some stream level error */ + grpc_error *forced_close_error; + /** how many header frames have we received? */ + uint8_t header_frames_received; + /** window available for peer to send to us */ + int64_t incoming_window; + /** parsing state for data frames */ + grpc_chttp2_data_parser data_parser; + /** number of bytes received - reset at end of parse thread execution */ + int64_t received_bytes; +}; typedef struct { /** HTTP2 stream id for this stream, or zero if one has not been assigned */ @@ -500,41 +479,19 @@ typedef struct { grpc_transport_one_way_stats stats; } grpc_chttp2_stream_writing; +#if 0 struct grpc_chttp2_stream_parsing { - /** saw some stream level error */ - grpc_error *forced_close_error; - /** HTTP2 stream id for this stream, or zero if one has not been assigned */ - uint32_t id; - /** has this stream received a close */ - uint8_t received_close; - /** how many header frames have we received? */ - uint8_t header_frames_received; - /** which metadata did we get (on this parse) */ - uint8_t got_metadata_on_parse[2]; - /** should we raise the seen_error flag in transport_global */ - bool seen_error; - bool exceeded_metadata_size; - /** window available for peer to send to us */ - int64_t incoming_window; - /** parsing state for data frames */ - grpc_chttp2_data_parser data_parser; - /** amount of window given */ - int64_t outgoing_window; - /** number of bytes received - reset at end of parse thread execution */ - int64_t received_bytes; - /** stats gathered during the parse */ - grpc_transport_stream_stats stats; /** incoming metadata */ grpc_chttp2_incoming_metadata_buffer metadata_buffer[2]; }; +#endif struct grpc_chttp2_stream { grpc_chttp2_transport *t; grpc_stream_refcount *refcount; grpc_chttp2_stream_global global; grpc_chttp2_stream_writing writing; - grpc_chttp2_stream_parsing parsing; grpc_closure init_stream; grpc_closure destroy_stream; @@ -574,16 +531,11 @@ void grpc_chttp2_cleanup_writing(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *global, grpc_chttp2_transport_writing *writing); -void grpc_chttp2_prepare_to_read(grpc_chttp2_transport_global *global, - grpc_chttp2_transport_parsing *parsing); /** Process one slice of incoming data; return 1 if the connection is still viable after reading, or 0 if the connection should be torn down */ grpc_error *grpc_chttp2_perform_read( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing, + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, gpr_slice slice); -void grpc_chttp2_publish_reads(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_global *global, - grpc_chttp2_transport_parsing *parsing); bool grpc_chttp2_list_add_writable_stream( grpc_chttp2_transport_global *transport_global, @@ -617,15 +569,6 @@ int grpc_chttp2_list_pop_written_stream( grpc_chttp2_stream_global **stream_global, grpc_chttp2_stream_writing **stream_writing); -void grpc_chttp2_list_add_parsing_seen_stream( - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing); -int grpc_chttp2_list_pop_parsing_seen_stream( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_global **stream_global, - grpc_chttp2_stream_parsing **stream_parsing); - void grpc_chttp2_list_add_waiting_for_concurrency( grpc_chttp2_transport_global *transport_global, grpc_chttp2_stream_global *stream_global); @@ -659,18 +602,6 @@ void grpc_chttp2_list_remove_stalled_by_transport( grpc_chttp2_transport_global *transport_global, grpc_chttp2_stream_global *stream_global); -void grpc_chttp2_list_add_unannounced_incoming_window_available( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global); -void grpc_chttp2_list_remove_unannounced_incoming_window_available( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global); -int grpc_chttp2_list_pop_unannounced_incoming_window_available( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_global **stream_global, - grpc_chttp2_stream_parsing **stream_parsing); - void grpc_chttp2_list_add_closed_waiting_for_parsing( grpc_chttp2_transport_global *transport_global, grpc_chttp2_stream_global *stream_global); @@ -685,10 +616,10 @@ int grpc_chttp2_list_pop_closed_waiting_for_writing( grpc_chttp2_transport_global *transport_global, grpc_chttp2_stream_global **stream_global); -grpc_chttp2_stream_parsing *grpc_chttp2_parsing_lookup_stream( - grpc_chttp2_transport_parsing *transport_parsing, uint32_t id); -grpc_chttp2_stream_parsing *grpc_chttp2_parsing_accept_stream( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing, +grpc_chttp2_stream_global *grpc_chttp2_parsing_lookup_stream( + grpc_chttp2_transport_global *transport_global, uint32_t id); +grpc_chttp2_stream_global *grpc_chttp2_parsing_accept_stream( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, uint32_t id); void grpc_chttp2_add_incoming_goaway( @@ -707,7 +638,7 @@ void grpc_chttp2_for_all_streams( grpc_chttp2_stream_global *stream_global)); void grpc_chttp2_parsing_become_skip_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing); + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global); void grpc_chttp2_complete_closure_step( grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, @@ -835,8 +766,8 @@ void grpc_chttp2_stream_unref(grpc_exec_ctx *exec_ctx, #endif grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, uint32_t frame_size, + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global, uint32_t frame_size, uint32_t flags, grpc_chttp2_incoming_frame_queue *add_to_queue); void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, @@ -846,7 +777,7 @@ void grpc_chttp2_incoming_byte_stream_finished( grpc_error *error, int from_parsing_thread); void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_parsing *parsing, + grpc_chttp2_transport_global *parsing, const uint8_t *opaque_8bytes); /** add a ref to the stream and add it to the writable list; diff --git a/src/core/ext/transport/chttp2/transport/parsing.c b/src/core/ext/transport/chttp2/transport/parsing.c index 0e6d579ba9..ee01d3beb7 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.c +++ b/src/core/ext/transport/chttp2/transport/parsing.c @@ -45,226 +45,33 @@ #include "src/core/lib/transport/static_metadata.h" #include "src/core/lib/transport/timeout_encoding.h" -#define TRANSPORT_FROM_PARSING(tp) \ - ((grpc_chttp2_transport *)((char *)(tp)-offsetof(grpc_chttp2_transport, \ - parsing))) - static grpc_error *init_frame_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing); + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global); static grpc_error *init_header_frame_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing, + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, int is_continuation); static grpc_error *init_data_frame_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing); + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global); static grpc_error *init_rst_stream_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing); + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global); static grpc_error *init_settings_frame_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing); + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global); static grpc_error *init_window_update_frame_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing); + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global); static grpc_error *init_ping_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing); + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global); static grpc_error *init_goaway_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing); + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global); static grpc_error *init_skip_frame_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing, + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, int is_header); static grpc_error *parse_frame_slice( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing, - gpr_slice slice, int is_last); - -void grpc_chttp2_prepare_to_read( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_transport_parsing *transport_parsing) { - grpc_chttp2_stream_global *stream_global; - grpc_chttp2_stream_parsing *stream_parsing; - - GPR_TIMER_BEGIN("grpc_chttp2_prepare_to_read", 0); - - transport_parsing->next_stream_id = transport_global->next_stream_id; - memcpy(transport_parsing->last_sent_settings, - transport_global->settings[GRPC_SENT_SETTINGS], - sizeof(transport_parsing->last_sent_settings)); - transport_parsing->max_frame_size = - transport_global->settings[GRPC_ACKED_SETTINGS] - [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE]; - - /* update the parsing view of incoming window */ - while (grpc_chttp2_list_pop_unannounced_incoming_window_available( - transport_global, transport_parsing, &stream_global, &stream_parsing)) { - GRPC_CHTTP2_FLOW_MOVE_STREAM("parse", transport_parsing, stream_parsing, - incoming_window, stream_global, - unannounced_incoming_window_for_parse); - } - - GPR_TIMER_END("grpc_chttp2_prepare_to_read", 0); -} - -void grpc_chttp2_publish_reads( grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - grpc_chttp2_transport_parsing *transport_parsing) { - grpc_chttp2_stream_global *stream_global; - grpc_chttp2_stream_parsing *stream_parsing; - int was_zero; - int is_zero; - - /* transport_parsing->last_incoming_stream_id is used as - last-grpc_chttp2_stream-id when - sending GOAWAY frame. - https://tools.ietf.org/html/draft-ietf-httpbis-http2-17#section-6.8 - says that last-grpc_chttp2_stream-id is peer-initiated grpc_chttp2_stream - ID. So, - since we don't have server pushed streams, client should send - GOAWAY last-grpc_chttp2_stream-id=0 in this case. */ - if (!transport_parsing->is_client) { - transport_global->last_incoming_stream_id = - transport_parsing->last_incoming_stream_id; - } - - /* update global settings */ - if (transport_parsing->settings_updated) { - memcpy(transport_global->settings[GRPC_PEER_SETTINGS], - transport_parsing->settings, sizeof(transport_parsing->settings)); - transport_parsing->settings_updated = 0; - } - - /* update settings based on ack if received */ - if (transport_parsing->settings_ack_received) { - memcpy(transport_global->settings[GRPC_ACKED_SETTINGS], - transport_global->settings[GRPC_SENT_SETTINGS], - GRPC_CHTTP2_NUM_SETTINGS * sizeof(uint32_t)); - transport_parsing->settings_ack_received = 0; - transport_global->sent_local_settings = 0; - } - - /* move goaway to the global state if we received one (it will be - published later */ - if (transport_parsing->goaway_received) { - grpc_chttp2_add_incoming_goaway(exec_ctx, transport_global, - (uint32_t)transport_parsing->goaway_error, - transport_parsing->goaway_text); - transport_parsing->goaway_text = gpr_empty_slice(); - transport_parsing->goaway_received = 0; - } - - /* propagate flow control tokens to global state */ - was_zero = transport_global->outgoing_window <= 0; - GRPC_CHTTP2_FLOW_MOVE_TRANSPORT("parsed", transport_global, outgoing_window, - transport_parsing, outgoing_window); - is_zero = transport_global->outgoing_window <= 0; - if (was_zero && !is_zero) { - grpc_chttp2_initiate_write(exec_ctx, transport_global, false, - "new_global_flow_control"); - } - - if (transport_parsing->incoming_window < - transport_global->connection_window_target * 3 / 4) { - int64_t announce_bytes = transport_global->connection_window_target - - transport_parsing->incoming_window; - GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT("parsed", transport_global, - announce_incoming_window, announce_bytes); - GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT("parsed", transport_parsing, - incoming_window, announce_bytes); - grpc_chttp2_initiate_write(exec_ctx, transport_global, false, - "global incoming window"); - } - - /* for each stream that saw an update, fixup global state */ - while (grpc_chttp2_list_pop_parsing_seen_stream( - transport_global, transport_parsing, &stream_global, &stream_parsing)) { - if (stream_parsing->seen_error) { - stream_global->seen_error = true; - stream_global->exceeded_metadata_size = - stream_parsing->exceeded_metadata_size; - grpc_chttp2_list_add_check_read_ops(exec_ctx, transport_global, - stream_global); - } - - /* flush stats to global stream state */ - grpc_transport_move_stats(&stream_parsing->stats, &stream_global->stats); - - /* update outgoing flow control window */ - was_zero = stream_global->outgoing_window <= 0; - GRPC_CHTTP2_FLOW_MOVE_STREAM("parsed", transport_global, stream_global, - outgoing_window, stream_parsing, - outgoing_window); - is_zero = stream_global->outgoing_window <= 0; - if (was_zero && !is_zero) { - grpc_chttp2_become_writable(exec_ctx, transport_global, stream_global, - false, "stream.read_flow_control"); - } - - stream_global->max_recv_bytes -= (uint32_t)GPR_MIN( - stream_global->max_recv_bytes, stream_parsing->received_bytes); - stream_parsing->received_bytes = 0; - - /* publish incoming stream ops */ - if (stream_global->incoming_frames.tail != NULL) { - stream_global->incoming_frames.tail->is_tail = 0; - } - if (stream_parsing->data_parser.incoming_frames.head != NULL) { - grpc_chttp2_list_add_check_read_ops(exec_ctx, transport_global, - stream_global); - } - grpc_chttp2_incoming_frame_queue_merge( - &stream_global->incoming_frames, - &stream_parsing->data_parser.incoming_frames); - if (stream_global->incoming_frames.tail != NULL) { - stream_global->incoming_frames.tail->is_tail = 1; - } - - if (!stream_global->published_initial_metadata && - stream_parsing->got_metadata_on_parse[0]) { - stream_parsing->got_metadata_on_parse[0] = 0; - stream_global->published_initial_metadata = 1; - GPR_SWAP(grpc_chttp2_incoming_metadata_buffer, - stream_parsing->metadata_buffer[0], - stream_global->received_initial_metadata); - grpc_chttp2_list_add_check_read_ops(exec_ctx, transport_global, - stream_global); - } - if (!stream_global->published_trailing_metadata && - stream_parsing->got_metadata_on_parse[1]) { - stream_parsing->got_metadata_on_parse[1] = 0; - stream_global->published_trailing_metadata = 1; - GPR_SWAP(grpc_chttp2_incoming_metadata_buffer, - stream_parsing->metadata_buffer[1], - stream_global->received_trailing_metadata); - grpc_chttp2_list_add_check_read_ops(exec_ctx, transport_global, - stream_global); - } - - if (stream_parsing->forced_close_error != GRPC_ERROR_NONE) { - intptr_t reason; - bool has_reason = grpc_error_get_int(stream_parsing->forced_close_error, - GRPC_ERROR_INT_HTTP2_ERROR, &reason); - if (has_reason && reason != GRPC_CHTTP2_NO_ERROR) { - grpc_status_code status_code = - has_reason - ? grpc_chttp2_http2_error_to_grpc_status( - (grpc_chttp2_error_code)reason, stream_global->deadline) - : GRPC_STATUS_INTERNAL; - const char *status_details = - grpc_error_string(stream_parsing->forced_close_error); - gpr_slice slice_details = gpr_slice_from_copied_string(status_details); - grpc_error_free_string(status_details); - grpc_chttp2_fake_status(exec_ctx, transport_global, stream_global, - status_code, &slice_details); - } - grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global, - 1, 1, stream_parsing->forced_close_error); - } - - if (stream_parsing->received_close) { - grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global, - 1, 0, GRPC_ERROR_NONE); - } - } -} + gpr_slice slice, int is_last); grpc_error *grpc_chttp2_perform_read( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing, + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, gpr_slice slice) { uint8_t *beg = GPR_SLICE_START_PTR(slice); uint8_t *end = GPR_SLICE_END_PTR(slice); @@ -273,7 +80,7 @@ grpc_error *grpc_chttp2_perform_read( if (cur == end) return GRPC_ERROR_NONE; - switch (transport_parsing->deframe_state) { + switch (transport_global->deframe_state) { case GRPC_DTS_CLIENT_PREFIX_0: case GRPC_DTS_CLIENT_PREFIX_1: case GRPC_DTS_CLIENT_PREFIX_2: @@ -298,25 +105,25 @@ grpc_error *grpc_chttp2_perform_read( case GRPC_DTS_CLIENT_PREFIX_21: case GRPC_DTS_CLIENT_PREFIX_22: case GRPC_DTS_CLIENT_PREFIX_23: - while (cur != end && transport_parsing->deframe_state != GRPC_DTS_FH_0) { - if (*cur != GRPC_CHTTP2_CLIENT_CONNECT_STRING[transport_parsing + while (cur != end && transport_global->deframe_state != GRPC_DTS_FH_0) { + if (*cur != GRPC_CHTTP2_CLIENT_CONNECT_STRING[transport_global ->deframe_state]) { char *msg; gpr_asprintf( &msg, "Connect string mismatch: expected '%c' (%d) got '%c' (%d) " "at byte %d", - GRPC_CHTTP2_CLIENT_CONNECT_STRING[transport_parsing + GRPC_CHTTP2_CLIENT_CONNECT_STRING[transport_global ->deframe_state], (int)(uint8_t)GRPC_CHTTP2_CLIENT_CONNECT_STRING - [transport_parsing->deframe_state], - *cur, (int)*cur, transport_parsing->deframe_state); + [transport_global->deframe_state], + *cur, (int)*cur, transport_global->deframe_state); err = GRPC_ERROR_CREATE(msg); gpr_free(msg); return err; } ++cur; - ++transport_parsing->deframe_state; + ++transport_global->deframe_state; } if (cur == end) { return GRPC_ERROR_NONE; @@ -325,100 +132,104 @@ grpc_error *grpc_chttp2_perform_read( dts_fh_0: case GRPC_DTS_FH_0: GPR_ASSERT(cur < end); - transport_parsing->incoming_frame_size = ((uint32_t)*cur) << 16; + transport_global->incoming_frame_size = ((uint32_t)*cur) << 16; if (++cur == end) { - transport_parsing->deframe_state = GRPC_DTS_FH_1; + transport_global->deframe_state = GRPC_DTS_FH_1; return GRPC_ERROR_NONE; } /* fallthrough */ case GRPC_DTS_FH_1: GPR_ASSERT(cur < end); - transport_parsing->incoming_frame_size |= ((uint32_t)*cur) << 8; + transport_global->incoming_frame_size |= ((uint32_t)*cur) << 8; if (++cur == end) { - transport_parsing->deframe_state = GRPC_DTS_FH_2; + transport_global->deframe_state = GRPC_DTS_FH_2; return GRPC_ERROR_NONE; } /* fallthrough */ case GRPC_DTS_FH_2: GPR_ASSERT(cur < end); - transport_parsing->incoming_frame_size |= *cur; + transport_global->incoming_frame_size |= *cur; if (++cur == end) { - transport_parsing->deframe_state = GRPC_DTS_FH_3; + transport_global->deframe_state = GRPC_DTS_FH_3; return GRPC_ERROR_NONE; } /* fallthrough */ case GRPC_DTS_FH_3: GPR_ASSERT(cur < end); - transport_parsing->incoming_frame_type = *cur; + transport_global->incoming_frame_type = *cur; if (++cur == end) { - transport_parsing->deframe_state = GRPC_DTS_FH_4; + transport_global->deframe_state = GRPC_DTS_FH_4; return GRPC_ERROR_NONE; } /* fallthrough */ case GRPC_DTS_FH_4: GPR_ASSERT(cur < end); - transport_parsing->incoming_frame_flags = *cur; + transport_global->incoming_frame_flags = *cur; if (++cur == end) { - transport_parsing->deframe_state = GRPC_DTS_FH_5; + transport_global->deframe_state = GRPC_DTS_FH_5; return GRPC_ERROR_NONE; } /* fallthrough */ case GRPC_DTS_FH_5: GPR_ASSERT(cur < end); - transport_parsing->incoming_stream_id = (((uint32_t)*cur) & 0x7f) << 24; + transport_global->incoming_stream_id = (((uint32_t)*cur) & 0x7f) << 24; if (++cur == end) { - transport_parsing->deframe_state = GRPC_DTS_FH_6; + transport_global->deframe_state = GRPC_DTS_FH_6; return GRPC_ERROR_NONE; } /* fallthrough */ case GRPC_DTS_FH_6: GPR_ASSERT(cur < end); - transport_parsing->incoming_stream_id |= ((uint32_t)*cur) << 16; + transport_global->incoming_stream_id |= ((uint32_t)*cur) << 16; if (++cur == end) { - transport_parsing->deframe_state = GRPC_DTS_FH_7; + transport_global->deframe_state = GRPC_DTS_FH_7; return GRPC_ERROR_NONE; } /* fallthrough */ case GRPC_DTS_FH_7: GPR_ASSERT(cur < end); - transport_parsing->incoming_stream_id |= ((uint32_t)*cur) << 8; + transport_global->incoming_stream_id |= ((uint32_t)*cur) << 8; if (++cur == end) { - transport_parsing->deframe_state = GRPC_DTS_FH_8; + transport_global->deframe_state = GRPC_DTS_FH_8; return GRPC_ERROR_NONE; } /* fallthrough */ case GRPC_DTS_FH_8: GPR_ASSERT(cur < end); - transport_parsing->incoming_stream_id |= ((uint32_t)*cur); - transport_parsing->deframe_state = GRPC_DTS_FRAME; - err = init_frame_parser(exec_ctx, transport_parsing); + transport_global->incoming_stream_id |= ((uint32_t)*cur); + transport_global->deframe_state = GRPC_DTS_FRAME; + err = init_frame_parser(exec_ctx, transport_global); if (err != GRPC_ERROR_NONE) { return err; } - if (transport_parsing->incoming_stream_id != 0 && - transport_parsing->incoming_stream_id > - transport_parsing->last_incoming_stream_id) { - transport_parsing->last_incoming_stream_id = - transport_parsing->incoming_stream_id; + if (transport_global->incoming_stream_id != 0 && + transport_global->incoming_stream_id > + transport_global->last_incoming_stream_id) { + transport_global->last_incoming_stream_id = + transport_global->incoming_stream_id; } - if (transport_parsing->incoming_frame_size == 0) { - err = parse_frame_slice(exec_ctx, transport_parsing, gpr_empty_slice(), - 1); + if (transport_global->incoming_frame_size == 0) { + err = + parse_frame_slice(exec_ctx, transport_global, gpr_empty_slice(), 1); if (err != GRPC_ERROR_NONE) { return err; } - transport_parsing->incoming_stream = NULL; + transport_global->incoming_stream = NULL; if (++cur == end) { - transport_parsing->deframe_state = GRPC_DTS_FH_0; + transport_global->deframe_state = GRPC_DTS_FH_0; return GRPC_ERROR_NONE; } goto dts_fh_0; /* loop */ - } else if (transport_parsing->incoming_frame_size > - transport_parsing->max_frame_size) { + } else if (transport_global->incoming_frame_size > + transport_global + ->settings[GRPC_ACKED_SETTINGS] + [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE]) { char *msg; - gpr_asprintf(&msg, "Frame size %d is larger than max frame size %d", - transport_parsing->incoming_frame_size, - transport_parsing->max_frame_size); + gpr_asprintf( + &msg, "Frame size %d is larger than max frame size %d", + transport_global->incoming_frame_size, + transport_global->settings[GRPC_ACKED_SETTINGS] + [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE]); err = GRPC_ERROR_CREATE(msg); gpr_free(msg); return err; @@ -429,41 +240,41 @@ grpc_error *grpc_chttp2_perform_read( /* fallthrough */ case GRPC_DTS_FRAME: GPR_ASSERT(cur < end); - if ((uint32_t)(end - cur) == transport_parsing->incoming_frame_size) { - err = parse_frame_slice(exec_ctx, transport_parsing, + if ((uint32_t)(end - cur) == transport_global->incoming_frame_size) { + err = parse_frame_slice(exec_ctx, transport_global, gpr_slice_sub_no_ref(slice, (size_t)(cur - beg), (size_t)(end - beg)), 1); if (err != GRPC_ERROR_NONE) { return err; } - transport_parsing->deframe_state = GRPC_DTS_FH_0; - transport_parsing->incoming_stream = NULL; + transport_global->deframe_state = GRPC_DTS_FH_0; + transport_global->incoming_stream = NULL; return GRPC_ERROR_NONE; } else if ((uint32_t)(end - cur) > - transport_parsing->incoming_frame_size) { + transport_global->incoming_frame_size) { size_t cur_offset = (size_t)(cur - beg); err = parse_frame_slice( - exec_ctx, transport_parsing, + exec_ctx, transport_global, gpr_slice_sub_no_ref( slice, cur_offset, - cur_offset + transport_parsing->incoming_frame_size), + cur_offset + transport_global->incoming_frame_size), 1); if (err != GRPC_ERROR_NONE) { return err; } - cur += transport_parsing->incoming_frame_size; - transport_parsing->incoming_stream = NULL; + cur += transport_global->incoming_frame_size; + transport_global->incoming_stream = NULL; goto dts_fh_0; /* loop */ } else { - err = parse_frame_slice(exec_ctx, transport_parsing, + err = parse_frame_slice(exec_ctx, transport_global, gpr_slice_sub_no_ref(slice, (size_t)(cur - beg), (size_t)(end - beg)), 0); if (err != GRPC_ERROR_NONE) { return err; } - transport_parsing->incoming_frame_size -= (uint32_t)(end - cur); + transport_global->incoming_frame_size -= (uint32_t)(end - cur); return GRPC_ERROR_NONE; } GPR_UNREACHABLE_CODE(return 0); @@ -473,72 +284,72 @@ grpc_error *grpc_chttp2_perform_read( } static grpc_error *init_frame_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing) { - if (transport_parsing->is_first_frame && - transport_parsing->incoming_frame_type != GRPC_CHTTP2_FRAME_SETTINGS) { + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global) { + if (transport_global->is_first_frame && + transport_global->incoming_frame_type != GRPC_CHTTP2_FRAME_SETTINGS) { char *msg; gpr_asprintf( &msg, "Expected SETTINGS frame as the first frame, got frame type %d", - transport_parsing->incoming_frame_type); + transport_global->incoming_frame_type); grpc_error *err = GRPC_ERROR_CREATE(msg); gpr_free(msg); return err; } - transport_parsing->is_first_frame = false; - if (transport_parsing->expect_continuation_stream_id != 0) { - if (transport_parsing->incoming_frame_type != + transport_global->is_first_frame = false; + if (transport_global->expect_continuation_stream_id != 0) { + if (transport_global->incoming_frame_type != GRPC_CHTTP2_FRAME_CONTINUATION) { char *msg; gpr_asprintf(&msg, "Expected CONTINUATION frame, got frame type %02x", - transport_parsing->incoming_frame_type); + transport_global->incoming_frame_type); grpc_error *err = GRPC_ERROR_CREATE(msg); gpr_free(msg); return err; } - if (transport_parsing->expect_continuation_stream_id != - transport_parsing->incoming_stream_id) { + if (transport_global->expect_continuation_stream_id != + transport_global->incoming_stream_id) { char *msg; gpr_asprintf( &msg, "Expected CONTINUATION frame for grpc_chttp2_stream %08x, got " "grpc_chttp2_stream %08x", - transport_parsing->expect_continuation_stream_id, - transport_parsing->incoming_stream_id); + transport_global->expect_continuation_stream_id, + transport_global->incoming_stream_id); grpc_error *err = GRPC_ERROR_CREATE(msg); gpr_free(msg); return err; } - return init_header_frame_parser(exec_ctx, transport_parsing, 1); + return init_header_frame_parser(exec_ctx, transport_global, 1); } - switch (transport_parsing->incoming_frame_type) { + switch (transport_global->incoming_frame_type) { case GRPC_CHTTP2_FRAME_DATA: - return init_data_frame_parser(exec_ctx, transport_parsing); + return init_data_frame_parser(exec_ctx, transport_global); case GRPC_CHTTP2_FRAME_HEADER: - return init_header_frame_parser(exec_ctx, transport_parsing, 0); + return init_header_frame_parser(exec_ctx, transport_global, 0); case GRPC_CHTTP2_FRAME_CONTINUATION: return GRPC_ERROR_CREATE("Unexpected CONTINUATION frame"); case GRPC_CHTTP2_FRAME_RST_STREAM: - return init_rst_stream_parser(exec_ctx, transport_parsing); + return init_rst_stream_parser(exec_ctx, transport_global); case GRPC_CHTTP2_FRAME_SETTINGS: - return init_settings_frame_parser(exec_ctx, transport_parsing); + return init_settings_frame_parser(exec_ctx, transport_global); case GRPC_CHTTP2_FRAME_WINDOW_UPDATE: - return init_window_update_frame_parser(exec_ctx, transport_parsing); + return init_window_update_frame_parser(exec_ctx, transport_global); case GRPC_CHTTP2_FRAME_PING: - return init_ping_parser(exec_ctx, transport_parsing); + return init_ping_parser(exec_ctx, transport_global); case GRPC_CHTTP2_FRAME_GOAWAY: - return init_goaway_parser(exec_ctx, transport_parsing); + return init_goaway_parser(exec_ctx, transport_global); default: if (grpc_http_trace) { gpr_log(GPR_ERROR, "Unknown frame type %02x", - transport_parsing->incoming_frame_type); + transport_global->incoming_frame_type); } - return init_skip_frame_parser(exec_ctx, transport_parsing, 0); + return init_skip_frame_parser(exec_ctx, transport_global, 0); } } static grpc_error *skip_parser(grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global, gpr_slice slice, int is_last) { return GRPC_ERROR_NONE; } @@ -546,101 +357,100 @@ static grpc_error *skip_parser(grpc_exec_ctx *exec_ctx, void *parser, static void skip_header(void *tp, grpc_mdelem *md) { GRPC_MDELEM_UNREF(md); } static grpc_error *init_skip_frame_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing, + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, int is_header) { if (is_header) { - uint8_t is_eoh = transport_parsing->expect_continuation_stream_id != 0; - transport_parsing->parser = grpc_chttp2_header_parser_parse; - transport_parsing->parser_data = &transport_parsing->hpack_parser; - transport_parsing->hpack_parser.on_header = skip_header; - transport_parsing->hpack_parser.on_header_user_data = NULL; - transport_parsing->hpack_parser.is_boundary = is_eoh; - transport_parsing->hpack_parser.is_eof = - (uint8_t)(is_eoh ? transport_parsing->header_eof : 0); + uint8_t is_eoh = transport_global->expect_continuation_stream_id != 0; + transport_global->parser = grpc_chttp2_header_parser_parse; + transport_global->parser_data = &transport_global->hpack_parser; + transport_global->hpack_parser.on_header = skip_header; + transport_global->hpack_parser.on_header_user_data = NULL; + transport_global->hpack_parser.is_boundary = is_eoh; + transport_global->hpack_parser.is_eof = + (uint8_t)(is_eoh ? transport_global->header_eof : 0); } else { - transport_parsing->parser = skip_parser; + transport_global->parser = skip_parser; } return GRPC_ERROR_NONE; } void grpc_chttp2_parsing_become_skip_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing) { + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global) { init_skip_frame_parser( - exec_ctx, transport_parsing, - transport_parsing->parser == grpc_chttp2_header_parser_parse); + exec_ctx, transport_global, + transport_global->parser == grpc_chttp2_header_parser_parse); } static grpc_error *update_incoming_window( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing) { - uint32_t incoming_frame_size = transport_parsing->incoming_frame_size; - if (incoming_frame_size > transport_parsing->incoming_window) { + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global) { + uint32_t incoming_frame_size = transport_global->incoming_frame_size; + if (incoming_frame_size > transport_global->incoming_window) { char *msg; gpr_asprintf(&msg, "frame of size %d overflows incoming window of %" PRId64, - transport_parsing->incoming_frame_size, - transport_parsing->incoming_window); + transport_global->incoming_frame_size, + transport_global->incoming_window); grpc_error *err = GRPC_ERROR_CREATE(msg); gpr_free(msg); return err; } - if (incoming_frame_size > stream_parsing->incoming_window) { + if (incoming_frame_size > stream_global->incoming_window) { char *msg; gpr_asprintf(&msg, "frame of size %d overflows incoming window of %" PRId64, - transport_parsing->incoming_frame_size, - stream_parsing->incoming_window); + transport_global->incoming_frame_size, + stream_global->incoming_window); grpc_error *err = GRPC_ERROR_CREATE(msg); gpr_free(msg); return err; } - GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("parse", transport_parsing, incoming_window, + GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("parse", transport_global, incoming_window, incoming_frame_size); - GRPC_CHTTP2_FLOW_DEBIT_STREAM("parse", transport_parsing, stream_parsing, + GRPC_CHTTP2_FLOW_DEBIT_STREAM("parse", transport_global, stream_global, incoming_window, incoming_frame_size); - stream_parsing->received_bytes += incoming_frame_size; - - grpc_chttp2_list_add_parsing_seen_stream(transport_parsing, stream_parsing); + stream_global->received_bytes += incoming_frame_size; + stream_global->max_recv_bytes -= + (uint32_t)GPR_MIN(stream_global->max_recv_bytes, incoming_frame_size); return GRPC_ERROR_NONE; } static grpc_error *init_data_frame_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing) { - grpc_chttp2_stream_parsing *stream_parsing = - grpc_chttp2_parsing_lookup_stream(transport_parsing, - transport_parsing->incoming_stream_id); + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global) { + grpc_chttp2_stream_global *stream_global = grpc_chttp2_parsing_lookup_stream( + transport_global, transport_global->incoming_stream_id); grpc_error *err = GRPC_ERROR_NONE; - if (stream_parsing == NULL) { - return init_skip_frame_parser(exec_ctx, transport_parsing, 0); + if (stream_global == NULL) { + return init_skip_frame_parser(exec_ctx, transport_global, 0); } - stream_parsing->stats.incoming.framing_bytes += 9; - if (stream_parsing->received_close) { - return init_skip_frame_parser(exec_ctx, transport_parsing, 0); + stream_global->stats.incoming.framing_bytes += 9; + if (stream_global->read_closed) { + return init_skip_frame_parser(exec_ctx, transport_global, 0); } if (err == GRPC_ERROR_NONE) { - err = update_incoming_window(exec_ctx, transport_parsing, stream_parsing); + err = update_incoming_window(exec_ctx, transport_global, stream_global); } if (err == GRPC_ERROR_NONE) { err = grpc_chttp2_data_parser_begin_frame( - &stream_parsing->data_parser, transport_parsing->incoming_frame_flags, - stream_parsing->id); + &stream_global->data_parser, transport_global->incoming_frame_flags, + stream_global->id); } if (err == GRPC_ERROR_NONE) { - transport_parsing->incoming_stream = stream_parsing; - transport_parsing->parser = grpc_chttp2_data_parser_parse; - transport_parsing->parser_data = &stream_parsing->data_parser; + transport_global->incoming_stream = stream_global; + transport_global->parser = grpc_chttp2_data_parser_parse; + transport_global->parser_data = &stream_global->data_parser; return GRPC_ERROR_NONE; } else if (grpc_error_get_int(err, GRPC_ERROR_INT_STREAM_ID, NULL)) { /* handle stream errors by closing the stream */ - stream_parsing->received_close = 1; - stream_parsing->forced_close_error = err; + grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global, + true, false, GRPC_ERROR_REF(err)); gpr_slice_buffer_add( - &transport_parsing->qbuf, - grpc_chttp2_rst_stream_create(transport_parsing->incoming_stream_id, + &transport_global->qbuf, + grpc_chttp2_rst_stream_create(transport_global->incoming_stream_id, GRPC_CHTTP2_PROTOCOL_ERROR, - &stream_parsing->stats.outgoing)); - return init_skip_frame_parser(exec_ctx, transport_parsing, 0); + &stream_global->stats.outgoing)); + return init_skip_frame_parser(exec_ctx, transport_global, 0); } else { return err; } @@ -649,22 +459,21 @@ static grpc_error *init_data_frame_parser( static void free_timeout(void *p) { gpr_free(p); } static void on_initial_header(void *tp, grpc_mdelem *md) { - grpc_chttp2_transport_parsing *transport_parsing = tp; - grpc_chttp2_stream_parsing *stream_parsing = - transport_parsing->incoming_stream; + grpc_chttp2_transport_global *transport_global = tp; + grpc_chttp2_stream_global *stream_global = transport_global->incoming_stream; GPR_TIMER_BEGIN("on_initial_header", 0); - GPR_ASSERT(stream_parsing); + GPR_ASSERT(stream_global); GRPC_CHTTP2_IF_TRACING(gpr_log( - GPR_INFO, "HTTP:%d:HDR:%s: %s: %s", stream_parsing->id, - transport_parsing->is_client ? "CLI" : "SVR", + GPR_INFO, "HTTP:%d:HDR:%s: %s: %s", stream_global->id, + transport_global->is_client ? "CLI" : "SVR", grpc_mdstr_as_c_string(md->key), grpc_mdstr_as_c_string(md->value))); if (md->key == GRPC_MDSTR_GRPC_STATUS && md != GRPC_MDELEM_GRPC_STATUS_0) { /* TODO(ctiller): check for a status like " 0" */ - stream_parsing->seen_error = true; + stream_global->seen_error = true; } if (md->key == GRPC_MDSTR_GRPC_TIMEOUT) { @@ -681,269 +490,260 @@ static void on_initial_header(void *tp, grpc_mdelem *md) { grpc_mdelem_set_user_data(md, free_timeout, cached_timeout); } grpc_chttp2_incoming_metadata_buffer_set_deadline( - &stream_parsing->metadata_buffer[0], + &stream_global->metadata_buffer[0], gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), *cached_timeout)); GRPC_MDELEM_UNREF(md); } else { const size_t new_size = - stream_parsing->metadata_buffer[0].size + GRPC_MDELEM_LENGTH(md); - grpc_chttp2_transport_global *transport_global = - &TRANSPORT_FROM_PARSING(transport_parsing)->global; + stream_global->metadata_buffer[0].size + GRPC_MDELEM_LENGTH(md); const size_t metadata_size_limit = - transport_global->settings[GRPC_LOCAL_SETTINGS] + transport_global->settings[GRPC_ACKED_SETTINGS] [GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE]; if (new_size > metadata_size_limit) { - if (!stream_parsing->exceeded_metadata_size) { + if (!stream_global->exceeded_metadata_size) { gpr_log(GPR_DEBUG, "received initial metadata size exceeds limit (%" PRIuPTR " vs. %" PRIuPTR ")", new_size, metadata_size_limit); - stream_parsing->seen_error = true; - stream_parsing->exceeded_metadata_size = true; + stream_global->seen_error = true; + stream_global->exceeded_metadata_size = true; } GRPC_MDELEM_UNREF(md); } else { grpc_chttp2_incoming_metadata_buffer_add( - &stream_parsing->metadata_buffer[0], md); + &stream_global->metadata_buffer[0], md); } } - grpc_chttp2_list_add_parsing_seen_stream(transport_parsing, stream_parsing); - GPR_TIMER_END("on_initial_header", 0); } static void on_trailing_header(void *tp, grpc_mdelem *md) { - grpc_chttp2_transport_parsing *transport_parsing = tp; - grpc_chttp2_stream_parsing *stream_parsing = - transport_parsing->incoming_stream; + grpc_chttp2_transport_global *transport_global = tp; + grpc_chttp2_stream_global *stream_global = transport_global->incoming_stream; GPR_TIMER_BEGIN("on_trailing_header", 0); - GPR_ASSERT(stream_parsing); + GPR_ASSERT(stream_global); GRPC_CHTTP2_IF_TRACING(gpr_log( - GPR_INFO, "HTTP:%d:TRL:%s: %s: %s", stream_parsing->id, - transport_parsing->is_client ? "CLI" : "SVR", + GPR_INFO, "HTTP:%d:TRL:%s: %s: %s", stream_global->id, + transport_global->is_client ? "CLI" : "SVR", grpc_mdstr_as_c_string(md->key), grpc_mdstr_as_c_string(md->value))); if (md->key == GRPC_MDSTR_GRPC_STATUS && md != GRPC_MDELEM_GRPC_STATUS_0) { /* TODO(ctiller): check for a status like " 0" */ - stream_parsing->seen_error = true; + stream_global->seen_error = true; } const size_t new_size = - stream_parsing->metadata_buffer[1].size + GRPC_MDELEM_LENGTH(md); - grpc_chttp2_transport_global *transport_global = - &TRANSPORT_FROM_PARSING(transport_parsing)->global; + stream_global->metadata_buffer[1].size + GRPC_MDELEM_LENGTH(md); const size_t metadata_size_limit = - transport_global->settings[GRPC_LOCAL_SETTINGS] + transport_global->settings[GRPC_ACKED_SETTINGS] [GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE]; if (new_size > metadata_size_limit) { - if (!stream_parsing->exceeded_metadata_size) { + if (!stream_global->exceeded_metadata_size) { gpr_log(GPR_DEBUG, "received trailing metadata size exceeds limit (%" PRIuPTR " vs. %" PRIuPTR ")", new_size, metadata_size_limit); - stream_parsing->seen_error = true; - stream_parsing->exceeded_metadata_size = true; + stream_global->seen_error = true; + stream_global->exceeded_metadata_size = true; } GRPC_MDELEM_UNREF(md); } else { - grpc_chttp2_incoming_metadata_buffer_add( - &stream_parsing->metadata_buffer[1], md); + grpc_chttp2_incoming_metadata_buffer_add(&stream_global->metadata_buffer[1], + md); } - grpc_chttp2_list_add_parsing_seen_stream(transport_parsing, stream_parsing); - GPR_TIMER_END("on_trailing_header", 0); } static grpc_error *init_header_frame_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing, + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, int is_continuation) { - uint8_t is_eoh = (transport_parsing->incoming_frame_flags & + uint8_t is_eoh = (transport_global->incoming_frame_flags & GRPC_CHTTP2_DATA_FLAG_END_HEADERS) != 0; int via_accept = 0; - grpc_chttp2_stream_parsing *stream_parsing; + grpc_chttp2_stream_global *stream_global; /* TODO(ctiller): when to increment header_frames_received? */ if (is_eoh) { - transport_parsing->expect_continuation_stream_id = 0; + transport_global->expect_continuation_stream_id = 0; } else { - transport_parsing->expect_continuation_stream_id = - transport_parsing->incoming_stream_id; + transport_global->expect_continuation_stream_id = + transport_global->incoming_stream_id; } if (!is_continuation) { - transport_parsing->header_eof = (transport_parsing->incoming_frame_flags & - GRPC_CHTTP2_DATA_FLAG_END_STREAM) != 0; + transport_global->header_eof = (transport_global->incoming_frame_flags & + GRPC_CHTTP2_DATA_FLAG_END_STREAM) != 0; } /* could be a new grpc_chttp2_stream or an existing grpc_chttp2_stream */ - stream_parsing = grpc_chttp2_parsing_lookup_stream( - transport_parsing, transport_parsing->incoming_stream_id); - if (stream_parsing == NULL) { + stream_global = grpc_chttp2_parsing_lookup_stream( + transport_global, transport_global->incoming_stream_id); + if (stream_global == NULL) { if (is_continuation) { gpr_log(GPR_ERROR, "grpc_chttp2_stream disbanded before CONTINUATION received"); - return init_skip_frame_parser(exec_ctx, transport_parsing, 1); + return init_skip_frame_parser(exec_ctx, transport_global, 1); } - if (transport_parsing->is_client) { - if ((transport_parsing->incoming_stream_id & 1) && - transport_parsing->incoming_stream_id < - transport_parsing->next_stream_id) { + if (transport_global->is_client) { + if ((transport_global->incoming_stream_id & 1) && + transport_global->incoming_stream_id < + transport_global->next_stream_id) { /* this is an old (probably cancelled) grpc_chttp2_stream */ } else { gpr_log(GPR_ERROR, "ignoring new grpc_chttp2_stream creation on client"); } - return init_skip_frame_parser(exec_ctx, transport_parsing, 1); - } else if (transport_parsing->last_incoming_stream_id > - transport_parsing->incoming_stream_id) { + return init_skip_frame_parser(exec_ctx, transport_global, 1); + } else if (transport_global->last_incoming_stream_id > + transport_global->incoming_stream_id) { gpr_log(GPR_ERROR, "ignoring out of order new grpc_chttp2_stream request on server; " "last grpc_chttp2_stream " "id=%d, new grpc_chttp2_stream id=%d", - transport_parsing->last_incoming_stream_id, - transport_parsing->incoming_stream_id); - return init_skip_frame_parser(exec_ctx, transport_parsing, 1); - } else if ((transport_parsing->incoming_stream_id & 1) == 0) { + transport_global->last_incoming_stream_id, + transport_global->incoming_stream_id); + return init_skip_frame_parser(exec_ctx, transport_global, 1); + } else if ((transport_global->incoming_stream_id & 1) == 0) { gpr_log(GPR_ERROR, "ignoring grpc_chttp2_stream with non-client generated index %d", - transport_parsing->incoming_stream_id); - return init_skip_frame_parser(exec_ctx, transport_parsing, 1); + transport_global->incoming_stream_id); + return init_skip_frame_parser(exec_ctx, transport_global, 1); } - stream_parsing = transport_parsing->incoming_stream = - grpc_chttp2_parsing_accept_stream( - exec_ctx, transport_parsing, transport_parsing->incoming_stream_id); - if (stream_parsing == NULL) { + stream_global = transport_global->incoming_stream = + grpc_chttp2_parsing_accept_stream(exec_ctx, transport_global, + transport_global->incoming_stream_id); + if (stream_global == NULL) { gpr_log(GPR_ERROR, "grpc_chttp2_stream not accepted"); - return init_skip_frame_parser(exec_ctx, transport_parsing, 1); + return init_skip_frame_parser(exec_ctx, transport_global, 1); } via_accept = 1; } else { - transport_parsing->incoming_stream = stream_parsing; + transport_global->incoming_stream = stream_global; } - GPR_ASSERT(stream_parsing != NULL && (via_accept == 0 || via_accept == 1)); - stream_parsing->stats.incoming.framing_bytes += 9; - if (stream_parsing->received_close) { + GPR_ASSERT(stream_global != NULL && (via_accept == 0 || via_accept == 1)); + stream_global->stats.incoming.framing_bytes += 9; + if (stream_global->read_closed) { gpr_log(GPR_ERROR, "skipping already closed grpc_chttp2_stream header"); - transport_parsing->incoming_stream = NULL; - return init_skip_frame_parser(exec_ctx, transport_parsing, 1); + transport_global->incoming_stream = NULL; + return init_skip_frame_parser(exec_ctx, transport_global, 1); } - transport_parsing->parser = grpc_chttp2_header_parser_parse; - transport_parsing->parser_data = &transport_parsing->hpack_parser; - switch (stream_parsing->header_frames_received) { + transport_global->parser = grpc_chttp2_header_parser_parse; + transport_global->parser_data = &transport_global->hpack_parser; + switch (stream_global->header_frames_received) { case 0: - transport_parsing->hpack_parser.on_header = on_initial_header; + transport_global->hpack_parser.on_header = on_initial_header; break; case 1: - transport_parsing->hpack_parser.on_header = on_trailing_header; + transport_global->hpack_parser.on_header = on_trailing_header; break; case 2: gpr_log(GPR_ERROR, "too many header frames received"); - return init_skip_frame_parser(exec_ctx, transport_parsing, 1); + return init_skip_frame_parser(exec_ctx, transport_global, 1); } - transport_parsing->hpack_parser.on_header_user_data = transport_parsing; - transport_parsing->hpack_parser.is_boundary = is_eoh; - transport_parsing->hpack_parser.is_eof = - (uint8_t)(is_eoh ? transport_parsing->header_eof : 0); - if (!is_continuation && (transport_parsing->incoming_frame_flags & + transport_global->hpack_parser.on_header_user_data = transport_global; + transport_global->hpack_parser.is_boundary = is_eoh; + transport_global->hpack_parser.is_eof = + (uint8_t)(is_eoh ? transport_global->header_eof : 0); + if (!is_continuation && (transport_global->incoming_frame_flags & GRPC_CHTTP2_FLAG_HAS_PRIORITY)) { - grpc_chttp2_hpack_parser_set_has_priority(&transport_parsing->hpack_parser); + grpc_chttp2_hpack_parser_set_has_priority(&transport_global->hpack_parser); } return GRPC_ERROR_NONE; } static grpc_error *init_window_update_frame_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing) { + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global) { grpc_error *err = grpc_chttp2_window_update_parser_begin_frame( - &transport_parsing->simple.window_update, - transport_parsing->incoming_frame_size, - transport_parsing->incoming_frame_flags); + &transport_global->simple.window_update, + transport_global->incoming_frame_size, + transport_global->incoming_frame_flags); if (err != GRPC_ERROR_NONE) return err; - if (transport_parsing->incoming_stream_id != 0) { - grpc_chttp2_stream_parsing *stream_parsing = - transport_parsing->incoming_stream = grpc_chttp2_parsing_lookup_stream( - transport_parsing, transport_parsing->incoming_stream_id); - if (stream_parsing == NULL) { - return init_skip_frame_parser(exec_ctx, transport_parsing, 0); + if (transport_global->incoming_stream_id != 0) { + grpc_chttp2_stream_global *stream_global = + transport_global->incoming_stream = grpc_chttp2_parsing_lookup_stream( + transport_global, transport_global->incoming_stream_id); + if (stream_global == NULL) { + return init_skip_frame_parser(exec_ctx, transport_global, 0); } - stream_parsing->stats.incoming.framing_bytes += 9; + stream_global->stats.incoming.framing_bytes += 9; } - transport_parsing->parser = grpc_chttp2_window_update_parser_parse; - transport_parsing->parser_data = &transport_parsing->simple.window_update; + transport_global->parser = grpc_chttp2_window_update_parser_parse; + transport_global->parser_data = &transport_global->simple.window_update; return GRPC_ERROR_NONE; } static grpc_error *init_ping_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing) { + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global) { grpc_error *err = grpc_chttp2_ping_parser_begin_frame( - &transport_parsing->simple.ping, transport_parsing->incoming_frame_size, - transport_parsing->incoming_frame_flags); + &transport_global->simple.ping, transport_global->incoming_frame_size, + transport_global->incoming_frame_flags); if (err != GRPC_ERROR_NONE) return err; - transport_parsing->parser = grpc_chttp2_ping_parser_parse; - transport_parsing->parser_data = &transport_parsing->simple.ping; + transport_global->parser = grpc_chttp2_ping_parser_parse; + transport_global->parser_data = &transport_global->simple.ping; return GRPC_ERROR_NONE; } static grpc_error *init_rst_stream_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing) { + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global) { grpc_error *err = grpc_chttp2_rst_stream_parser_begin_frame( - &transport_parsing->simple.rst_stream, - transport_parsing->incoming_frame_size, - transport_parsing->incoming_frame_flags); + &transport_global->simple.rst_stream, + transport_global->incoming_frame_size, + transport_global->incoming_frame_flags); if (err != GRPC_ERROR_NONE) return err; - grpc_chttp2_stream_parsing *stream_parsing = - transport_parsing->incoming_stream = grpc_chttp2_parsing_lookup_stream( - transport_parsing, transport_parsing->incoming_stream_id); - if (!transport_parsing->incoming_stream) { - return init_skip_frame_parser(exec_ctx, transport_parsing, 0); - } - stream_parsing->stats.incoming.framing_bytes += 9; - transport_parsing->parser = grpc_chttp2_rst_stream_parser_parse; - transport_parsing->parser_data = &transport_parsing->simple.rst_stream; + grpc_chttp2_stream_global *stream_global = transport_global->incoming_stream = + grpc_chttp2_parsing_lookup_stream(transport_global, + transport_global->incoming_stream_id); + if (!transport_global->incoming_stream) { + return init_skip_frame_parser(exec_ctx, transport_global, 0); + } + stream_global->stats.incoming.framing_bytes += 9; + transport_global->parser = grpc_chttp2_rst_stream_parser_parse; + transport_global->parser_data = &transport_global->simple.rst_stream; return GRPC_ERROR_NONE; } static grpc_error *init_goaway_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing) { + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global) { grpc_error *err = grpc_chttp2_goaway_parser_begin_frame( - &transport_parsing->goaway_parser, transport_parsing->incoming_frame_size, - transport_parsing->incoming_frame_flags); + &transport_global->goaway_parser, transport_global->incoming_frame_size, + transport_global->incoming_frame_flags); if (err != GRPC_ERROR_NONE) return err; - transport_parsing->parser = grpc_chttp2_goaway_parser_parse; - transport_parsing->parser_data = &transport_parsing->goaway_parser; + transport_global->parser = grpc_chttp2_goaway_parser_parse; + transport_global->parser_data = &transport_global->goaway_parser; return GRPC_ERROR_NONE; } static grpc_error *init_settings_frame_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing) { - if (transport_parsing->incoming_stream_id != 0) { + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global) { + if (transport_global->incoming_stream_id != 0) { return GRPC_ERROR_CREATE("Settings frame received for grpc_chttp2_stream"); } grpc_error *err = grpc_chttp2_settings_parser_begin_frame( - &transport_parsing->simple.settings, - transport_parsing->incoming_frame_size, - transport_parsing->incoming_frame_flags, transport_parsing->settings); + &transport_global->simple.settings, transport_global->incoming_frame_size, + transport_global->incoming_frame_flags, + transport_global->settings[GRPC_PEER_SETTINGS]); if (err != GRPC_ERROR_NONE) { return err; } - if (transport_parsing->incoming_frame_flags & GRPC_CHTTP2_FLAG_ACK) { - transport_parsing->settings_ack_received = 1; + if (transport_global->incoming_frame_flags & GRPC_CHTTP2_FLAG_ACK) { + memcpy(transport_global->settings[GRPC_ACKED_SETTINGS], + transport_global->settings[GRPC_SENT_SETTINGS], + GRPC_CHTTP2_NUM_SETTINGS * sizeof(uint32_t)); grpc_chttp2_hptbl_set_max_bytes( - &transport_parsing->hpack_parser.table, - transport_parsing - ->last_sent_settings[GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE]); - transport_parsing->max_frame_size = - transport_parsing - ->last_sent_settings[GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE]; + &transport_global->hpack_parser.table, + transport_global->settings[GRPC_ACKED_SETTINGS] + [GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE]); + transport_global->sent_local_settings = 0; } - transport_parsing->parser = grpc_chttp2_settings_parser_parse; - transport_parsing->parser_data = &transport_parsing->simple.settings; + transport_global->parser = grpc_chttp2_settings_parser_parse; + transport_global->parser_data = &transport_global->simple.settings; return GRPC_ERROR_NONE; } @@ -954,33 +754,32 @@ static int is_window_update_legal(int64_t window_update, int64_t window) { */ static grpc_error *parse_frame_slice( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing, + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, gpr_slice slice, int is_last) { - grpc_chttp2_stream_parsing *stream_parsing = - transport_parsing->incoming_stream; - grpc_error *err = transport_parsing->parser( - exec_ctx, transport_parsing->parser_data, transport_parsing, - stream_parsing, slice, is_last); + grpc_chttp2_stream_global *stream_global = transport_global->incoming_stream; + grpc_error *err = + transport_global->parser(exec_ctx, transport_global->parser_data, + transport_global, stream_global, slice, is_last); if (err == GRPC_ERROR_NONE) { - if (stream_parsing) { - grpc_chttp2_list_add_parsing_seen_stream(transport_parsing, - stream_parsing); + if (stream_global != NULL) { + grpc_chttp2_list_add_check_read_ops(exec_ctx, transport_global, + stream_global); } - return GRPC_ERROR_NONE; + return err; } else if (grpc_error_get_int(err, GRPC_ERROR_INT_STREAM_ID, NULL)) { if (grpc_http_trace) { const char *msg = grpc_error_string(err); gpr_log(GPR_ERROR, "%s", msg); grpc_error_free_string(msg); } - grpc_chttp2_parsing_become_skip_parser(exec_ctx, transport_parsing); - if (stream_parsing) { - stream_parsing->forced_close_error = err; + grpc_chttp2_parsing_become_skip_parser(exec_ctx, transport_global); + if (stream_global) { + stream_global->forced_close_error = err; gpr_slice_buffer_add( - &transport_parsing->qbuf, - grpc_chttp2_rst_stream_create(transport_parsing->incoming_stream_id, + &transport_global->qbuf, + grpc_chttp2_rst_stream_create(transport_global->incoming_stream_id, GRPC_CHTTP2_PROTOCOL_ERROR, - &stream_parsing->stats.outgoing)); + &stream_global->stats.outgoing)); } else { GRPC_ERROR_UNREF(err); } diff --git a/src/core/ext/transport/chttp2/transport/stream_lists.c b/src/core/ext/transport/chttp2/transport/stream_lists.c index 4dc4968248..7c31466c80 100644 --- a/src/core/ext/transport/chttp2/transport/stream_lists.c +++ b/src/core/ext/transport/chttp2/transport/stream_lists.c @@ -220,63 +220,6 @@ int grpc_chttp2_list_pop_written_stream( return r; } -void grpc_chttp2_list_add_unannounced_incoming_window_available( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global) { - GPR_ASSERT(stream_global->id != 0); - stream_list_add(TRANSPORT_FROM_GLOBAL(transport_global), - STREAM_FROM_GLOBAL(stream_global), - GRPC_CHTTP2_LIST_UNANNOUNCED_INCOMING_WINDOW_AVAILABLE); -} - -void grpc_chttp2_list_remove_unannounced_incoming_window_available( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global) { - stream_list_maybe_remove( - TRANSPORT_FROM_GLOBAL(transport_global), - STREAM_FROM_GLOBAL(stream_global), - GRPC_CHTTP2_LIST_UNANNOUNCED_INCOMING_WINDOW_AVAILABLE); -} - -int grpc_chttp2_list_pop_unannounced_incoming_window_available( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_global **stream_global, - grpc_chttp2_stream_parsing **stream_parsing) { - grpc_chttp2_stream *stream; - int r = - stream_list_pop(TRANSPORT_FROM_GLOBAL(transport_global), &stream, - GRPC_CHTTP2_LIST_UNANNOUNCED_INCOMING_WINDOW_AVAILABLE); - if (r != 0) { - *stream_global = &stream->global; - *stream_parsing = &stream->parsing; - } - return r; -} - -void grpc_chttp2_list_add_parsing_seen_stream( - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing) { - stream_list_add(TRANSPORT_FROM_PARSING(transport_parsing), - STREAM_FROM_PARSING(stream_parsing), - GRPC_CHTTP2_LIST_PARSING_SEEN); -} - -int grpc_chttp2_list_pop_parsing_seen_stream( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_global **stream_global, - grpc_chttp2_stream_parsing **stream_parsing) { - grpc_chttp2_stream *stream; - int r = stream_list_pop(TRANSPORT_FROM_PARSING(transport_parsing), &stream, - GRPC_CHTTP2_LIST_PARSING_SEEN); - if (r != 0) { - *stream_global = &stream->global; - *stream_parsing = &stream->parsing; - } - return r; -} - void grpc_chttp2_list_add_waiting_for_concurrency( grpc_chttp2_transport_global *transport_global, grpc_chttp2_stream_global *stream_global) { -- cgit v1.2.3 From 2679e4c7691104f8dcf2d3c32ebf60a3eb823938 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 16 Aug 2016 14:02:58 -0700 Subject: Fix typo --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 45ad8d7ed0..7bd976093a 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1398,7 +1398,7 @@ static void check_read_ops(grpc_exec_ctx *exec_ctx, } if (stream_global->all_incoming_byte_streams_finished) { grpc_chttp2_incoming_metadata_buffer_publish( - &stream_global->metadata_buffer[0], + &stream_global->metadata_buffer[1], stream_global->recv_trailing_metadata); grpc_chttp2_complete_closure_step( exec_ctx, transport_global, stream_global, -- cgit v1.2.3 From 83200a40a0d5f614be224ecc46160f72cdbd4a78 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 18 Aug 2016 13:55:01 -0700 Subject: Fixes for memory misuse --- .../transport/chttp2/transport/chttp2_transport.c | 44 ++++++---------------- .../ext/transport/chttp2/transport/frame_data.c | 13 ++----- .../ext/transport/chttp2/transport/frame_data.h | 1 - src/core/ext/transport/chttp2/transport/internal.h | 2 +- 4 files changed, 16 insertions(+), 44 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 4f4a423466..71b3006379 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1216,20 +1216,13 @@ static void send_ping_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_initiate_write(exec_ctx, &t->global, true, "send_ping"); } -typedef struct ack_ping_args { - grpc_closure closure; - grpc_chttp2_transport *t; - uint8_t opaque_8bytes[8]; -} ack_ping_args; - -static void ack_ping_locked(grpc_exec_ctx *exec_ctx, void *a, - grpc_error *error_ignored) { - ack_ping_args *args = a; +void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_global *transport_global, + const uint8_t *opaque_8bytes) { grpc_chttp2_outstanding_ping *ping; - grpc_chttp2_transport_global *transport_global = &args->t->global; for (ping = transport_global->pings.next; ping != &transport_global->pings; ping = ping->next) { - if (0 == memcmp(args->opaque_8bytes, ping->id, 8)) { + if (0 == memcmp(opaque_8bytes, ping->id, 8)) { grpc_exec_ctx_sched(exec_ctx, ping->on_recv, GRPC_ERROR_NONE, NULL); ping->next->prev = ping->prev; ping->prev->next = ping->next; @@ -1237,20 +1230,6 @@ static void ack_ping_locked(grpc_exec_ctx *exec_ctx, void *a, break; } } - UNREF_TRANSPORT(exec_ctx, args->t, "ack_ping"); - gpr_free(args); -} - -void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_global *transport_global, - const uint8_t *opaque_8bytes) { - ack_ping_args *args = gpr_malloc(sizeof(*args)); - args->t = TRANSPORT_FROM_GLOBAL(transport_global); - memcpy(args->opaque_8bytes, opaque_8bytes, sizeof(args->opaque_8bytes)); - grpc_closure_init(&args->closure, ack_ping_locked, args); - REF_TRANSPORT(args->t, "ack_ping"); - grpc_combiner_execute(exec_ctx, args->t->executor.combiner, &args->closure, - GRPC_ERROR_NONE); } static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx, @@ -1960,7 +1939,6 @@ static void reading_action_locked(grpc_exec_ctx *exec_ctx, void *tp, GPR_TIMER_BEGIN("post_reading_action_locked", 0); bool keep_reading = false; - GRPC_ERROR_REF(error); if (error == GRPC_ERROR_NONE && t->closed) { error = GRPC_ERROR_CREATE("Transport closed"); } @@ -1985,7 +1963,6 @@ static void reading_action_locked(grpc_exec_ctx *exec_ctx, void *tp, } else { UNREF_TRANSPORT(exec_ctx, t, "reading_action"); } - GRPC_ERROR_UNREF(error); GPR_TIMER_END("post_reading_action_locked", 0); @@ -2201,7 +2178,7 @@ void grpc_chttp2_incoming_byte_stream_finished( grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, grpc_chttp2_stream_global *stream_global, uint32_t frame_size, - uint32_t flags, grpc_chttp2_incoming_frame_queue *add_to_queue) { + uint32_t flags) { grpc_chttp2_incoming_byte_stream *incoming_byte_stream = gpr_malloc(sizeof(*incoming_byte_stream)); incoming_byte_stream->base.length = frame_size; @@ -2218,13 +2195,14 @@ grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( incoming_byte_stream->on_next = NULL; incoming_byte_stream->is_tail = 1; incoming_byte_stream->error = GRPC_ERROR_NONE; - if (add_to_queue->head == NULL) { - add_to_queue->head = incoming_byte_stream; + grpc_chttp2_incoming_frame_queue *q = &stream_global->incoming_frames; + if (q->head == NULL) { + q->head = incoming_byte_stream; } else { - add_to_queue->tail->is_tail = 0; - add_to_queue->tail->next_message = incoming_byte_stream; + q->tail->is_tail = 0; + q->tail->next_message = incoming_byte_stream; } - add_to_queue->tail = incoming_byte_stream; + q->tail = incoming_byte_stream; return incoming_byte_stream; } diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c index 5c6d6f8ce1..18e55b2916 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.c +++ b/src/core/ext/transport/chttp2/transport/frame_data.c @@ -51,16 +51,11 @@ grpc_error *grpc_chttp2_data_parser_init(grpc_chttp2_data_parser *parser) { void grpc_chttp2_data_parser_destroy(grpc_exec_ctx *exec_ctx, grpc_chttp2_data_parser *parser) { - grpc_byte_stream *bs; - if (parser->parsing_frame) { + if (parser->parsing_frame != NULL) { grpc_chttp2_incoming_byte_stream_finished( exec_ctx, parser->parsing_frame, GRPC_ERROR_CREATE("Parser destroyed"), 1); } - while ( - (bs = grpc_chttp2_incoming_frame_queue_pop(&parser->incoming_frames))) { - grpc_byte_stream_destroy(exec_ctx, bs); - } } grpc_error *grpc_chttp2_data_parser_begin_frame(grpc_chttp2_data_parser *parser, @@ -235,9 +230,9 @@ grpc_error *grpc_chttp2_data_parser_parse( message_flags |= GRPC_WRITE_INTERNAL_COMPRESS; } p->parsing_frame = incoming_byte_stream = - grpc_chttp2_incoming_byte_stream_create( - exec_ctx, transport_global, stream_global, p->frame_size, - message_flags, &p->incoming_frames); + grpc_chttp2_incoming_byte_stream_create(exec_ctx, transport_global, + stream_global, p->frame_size, + message_flags); /* fallthrough */ case GRPC_CHTTP2_DATA_FRAME: if (cur == end) { diff --git a/src/core/ext/transport/chttp2/transport/frame_data.h b/src/core/ext/transport/chttp2/transport/frame_data.h index b0c1cad976..c8ff7fe6bc 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.h +++ b/src/core/ext/transport/chttp2/transport/frame_data.h @@ -69,7 +69,6 @@ typedef struct { grpc_error *error; int is_frame_compressed; - grpc_chttp2_incoming_frame_queue incoming_frames; grpc_chttp2_incoming_byte_stream *parsing_frame; } grpc_chttp2_data_parser; diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index f3c3e1d2fe..517b21c5d3 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -768,7 +768,7 @@ void grpc_chttp2_stream_unref(grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, grpc_chttp2_stream_global *stream_global, uint32_t frame_size, - uint32_t flags, grpc_chttp2_incoming_frame_queue *add_to_queue); + uint32_t flags); void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, gpr_slice slice); -- cgit v1.2.3 From 73ba74b19cfe87d61ba2de66b44107b92c1e04e5 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 18 Aug 2016 15:17:46 -0700 Subject: Fix ping --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 9 ++++++++- src/core/ext/transport/chttp2/transport/frame_ping.c | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 71b3006379..0be00a78d4 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1211,6 +1211,7 @@ static void send_ping_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, p->id[5] = (uint8_t)((t->global.ping_counter >> 16) & 0xff); p->id[6] = (uint8_t)((t->global.ping_counter >> 8) & 0xff); p->id[7] = (uint8_t)(t->global.ping_counter & 0xff); + t->global.ping_counter++; p->on_recv = on_recv; gpr_slice_buffer_add(&t->global.qbuf, grpc_chttp2_ping_create(0, p->id)); grpc_chttp2_initiate_write(exec_ctx, &t->global, true, "send_ping"); @@ -1227,9 +1228,15 @@ void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, ping->next->prev = ping->prev; ping->prev->next = ping->next; gpr_free(ping); - break; + return; } } + char *msg = gpr_dump((const char *)opaque_8bytes, 8, GPR_DUMP_HEX); + char *from = + grpc_endpoint_get_peer(TRANSPORT_FROM_GLOBAL(transport_global)->ep); + gpr_log(GPR_DEBUG, "Unknown ping response from %s: %s", from, msg); + gpr_free(from); + gpr_free(msg); } static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx, diff --git a/src/core/ext/transport/chttp2/transport/frame_ping.c b/src/core/ext/transport/chttp2/transport/frame_ping.c index 65b7cec986..9a56e66788 100644 --- a/src/core/ext/transport/chttp2/transport/frame_ping.c +++ b/src/core/ext/transport/chttp2/transport/frame_ping.c @@ -95,6 +95,8 @@ grpc_error *grpc_chttp2_ping_parser_parse( } else { gpr_slice_buffer_add(&transport_global->qbuf, grpc_chttp2_ping_create(1, p->opaque_8bytes)); + grpc_chttp2_initiate_write(exec_ctx, transport_global, false, + "ping response"); } } -- cgit v1.2.3 From 09f9792f8a600787fdfbb467e20286b088f5aa89 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 18 Aug 2016 17:14:31 -0700 Subject: Fix typo --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 0be00a78d4..db592bcb67 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1610,7 +1610,7 @@ void grpc_chttp2_mark_stream_closed( stream_global->read_closed_error = GRPC_ERROR_REF(error); stream_global->read_closed = true; stream_global->published_metadata[0] = true; - stream_global->published_metadata[0] = true; + stream_global->published_metadata[1] = true; decrement_active_streams_locked(exec_ctx, transport_global, stream_global); } if (close_writes && !stream_global->write_closed) { -- cgit v1.2.3 From 8e21465a76b1b806237c66775c5d485da4d739ad Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 19 Aug 2016 09:54:31 -0700 Subject: Make failure to initialize a filter cause the server to silently swallow that request --- src/core/lib/surface/call.c | 97 +++++++++++++++++++++--------------------- src/core/lib/surface/call.h | 32 ++++++++++---- src/core/lib/surface/channel.c | 18 ++++++-- src/core/lib/surface/server.c | 15 +++++-- 4 files changed, 99 insertions(+), 63 deletions(-) diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c index 119f5e82ab..ae9424256c 100644 --- a/src/core/lib/surface/call.c +++ b/src/core/lib/surface/call.c @@ -230,33 +230,33 @@ static void destroy_call(grpc_exec_ctx *exec_ctx, void *call_stack, static void receiving_slice_ready(grpc_exec_ctx *exec_ctx, void *bctlp, grpc_error *error); -grpc_call *grpc_call_create( - grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask, - grpc_completion_queue *cq, grpc_pollset_set *pollset_set_alternative, - const void *server_transport_data, grpc_mdelem **add_initial_metadata, - size_t add_initial_metadata_count, gpr_timespec send_deadline) { +grpc_error *grpc_call_create(const grpc_call_create_args *args, + grpc_call **out_call) { size_t i, j; - grpc_channel_stack *channel_stack = grpc_channel_get_channel_stack(channel); + grpc_channel_stack *channel_stack = + grpc_channel_get_channel_stack(args->channel); grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_call *call; GPR_TIMER_BEGIN("grpc_call_create", 0); - call = gpr_malloc(sizeof(grpc_call) + channel_stack->call_stack_size); + *out_call = call = + gpr_malloc(sizeof(grpc_call) + channel_stack->call_stack_size); memset(call, 0, sizeof(grpc_call)); gpr_mu_init(&call->mu); - call->channel = channel; - call->cq = cq; - call->parent = parent_call; + call->channel = args->channel; + call->cq = args->cq; + call->parent = args->parent_call; /* Always support no compression */ GPR_BITSET(&call->encodings_accepted_by_peer, GRPC_COMPRESS_NONE); - call->is_client = server_transport_data == NULL; + call->is_client = args->server_transport_data == NULL; if (call->is_client) { - GPR_ASSERT(add_initial_metadata_count < MAX_SEND_EXTRA_METADATA_COUNT); - for (i = 0; i < add_initial_metadata_count; i++) { - call->send_extra_metadata[i].md = add_initial_metadata[i]; + GPR_ASSERT(args->add_initial_metadata_count < + MAX_SEND_EXTRA_METADATA_COUNT); + for (i = 0; i < args->add_initial_metadata_count; i++) { + call->send_extra_metadata[i].md = args->add_initial_metadata[i]; } - call->send_extra_metadata_count = (int)add_initial_metadata_count; + call->send_extra_metadata_count = (int)args->add_initial_metadata_count; } else { - GPR_ASSERT(add_initial_metadata_count == 0); + GPR_ASSERT(args->add_initial_metadata_count == 0); call->send_extra_metadata_count = 0; } for (i = 0; i < 2; i++) { @@ -265,78 +265,79 @@ grpc_call *grpc_call_create( } } call->send_deadline = - gpr_convert_clock_type(send_deadline, GPR_CLOCK_MONOTONIC); - GRPC_CHANNEL_INTERNAL_REF(channel, "call"); + gpr_convert_clock_type(args->send_deadline, GPR_CLOCK_MONOTONIC); + GRPC_CHANNEL_INTERNAL_REF(args->channel, "call"); /* initial refcount dropped by grpc_call_destroy */ grpc_error *error = grpc_call_stack_init( &exec_ctx, channel_stack, 1, destroy_call, call, call->context, - server_transport_data, CALL_STACK_FROM_CALL(call)); + args->server_transport_data, CALL_STACK_FROM_CALL(call)); if (error != GRPC_ERROR_NONE) { intptr_t status; - if (!grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, &status)) + if (!grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, &status)) { status = GRPC_STATUS_UNKNOWN; + } const char *error_str = grpc_error_get_str(error, GRPC_ERROR_STR_DESCRIPTION); close_with_status(&exec_ctx, call, (grpc_status_code)status, error_str == NULL ? "unknown error" : error_str); - GRPC_ERROR_UNREF(error); } - if (cq != NULL) { + if (args->cq != NULL) { GPR_ASSERT( - pollset_set_alternative == NULL && + args->pollset_set_alternative == NULL && "Only one of 'cq' and 'pollset_set_alternative' should be non-NULL."); - GRPC_CQ_INTERNAL_REF(cq, "bind"); + GRPC_CQ_INTERNAL_REF(args->cq, "bind"); call->pollent = - grpc_polling_entity_create_from_pollset(grpc_cq_pollset(cq)); + grpc_polling_entity_create_from_pollset(grpc_cq_pollset(args->cq)); } - if (pollset_set_alternative != NULL) { - call->pollent = - grpc_polling_entity_create_from_pollset_set(pollset_set_alternative); + if (args->pollset_set_alternative != NULL) { + call->pollent = grpc_polling_entity_create_from_pollset_set( + args->pollset_set_alternative); } if (!grpc_polling_entity_is_empty(&call->pollent)) { grpc_call_stack_set_pollset_or_pollset_set( &exec_ctx, CALL_STACK_FROM_CALL(call), &call->pollent); } - if (parent_call != NULL) { - GRPC_CALL_INTERNAL_REF(parent_call, "child"); + gpr_timespec send_deadline = args->send_deadline; + if (args->parent_call != NULL) { + GRPC_CALL_INTERNAL_REF(args->parent_call, "child"); GPR_ASSERT(call->is_client); - GPR_ASSERT(!parent_call->is_client); + GPR_ASSERT(!args->parent_call->is_client); - gpr_mu_lock(&parent_call->mu); + gpr_mu_lock(&args->parent_call->mu); - if (propagation_mask & GRPC_PROPAGATE_DEADLINE) { + if (args->propagation_mask & GRPC_PROPAGATE_DEADLINE) { send_deadline = gpr_time_min( gpr_convert_clock_type(send_deadline, - parent_call->send_deadline.clock_type), - parent_call->send_deadline); + args->parent_call->send_deadline.clock_type), + args->parent_call->send_deadline); } /* for now GRPC_PROPAGATE_TRACING_CONTEXT *MUST* be passed with * GRPC_PROPAGATE_STATS_CONTEXT */ /* TODO(ctiller): This should change to use the appropriate census start_op * call. */ - if (propagation_mask & GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT) { - GPR_ASSERT(propagation_mask & GRPC_PROPAGATE_CENSUS_STATS_CONTEXT); - grpc_call_context_set(call, GRPC_CONTEXT_TRACING, - parent_call->context[GRPC_CONTEXT_TRACING].value, - NULL); + if (args->propagation_mask & GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT) { + GPR_ASSERT(args->propagation_mask & GRPC_PROPAGATE_CENSUS_STATS_CONTEXT); + grpc_call_context_set( + call, GRPC_CONTEXT_TRACING, + args->parent_call->context[GRPC_CONTEXT_TRACING].value, NULL); } else { - GPR_ASSERT(propagation_mask & GRPC_PROPAGATE_CENSUS_STATS_CONTEXT); + GPR_ASSERT(args->propagation_mask & GRPC_PROPAGATE_CENSUS_STATS_CONTEXT); } - if (propagation_mask & GRPC_PROPAGATE_CANCELLATION) { + if (args->propagation_mask & GRPC_PROPAGATE_CANCELLATION) { call->cancellation_is_inherited = 1; } - if (parent_call->first_child == NULL) { - parent_call->first_child = call; + if (args->parent_call->first_child == NULL) { + args->parent_call->first_child = call; call->sibling_next = call->sibling_prev = call; } else { - call->sibling_next = parent_call->first_child; - call->sibling_prev = parent_call->first_child->sibling_prev; + call->sibling_next = args->parent_call->first_child; + call->sibling_prev = args->parent_call->first_child->sibling_prev; call->sibling_next->sibling_prev = call->sibling_prev->sibling_next = call; } - gpr_mu_unlock(&parent_call->mu); + gpr_mu_unlock(&args->parent_call->mu); } if (gpr_time_cmp(send_deadline, gpr_inf_future(send_deadline.clock_type)) != 0) { @@ -344,7 +345,7 @@ grpc_call *grpc_call_create( } grpc_exec_ctx_finish(&exec_ctx); GPR_TIMER_END("grpc_call_create", 0); - return call; + return error; } void grpc_call_set_completion_queue(grpc_exec_ctx *exec_ctx, grpc_call *call, diff --git a/src/core/lib/surface/call.h b/src/core/lib/surface/call.h index 3a78fe3aa3..18af41b7fb 100644 --- a/src/core/lib/surface/call.h +++ b/src/core/lib/surface/call.h @@ -49,15 +49,29 @@ typedef void (*grpc_ioreq_completion_func)(grpc_exec_ctx *exec_ctx, grpc_call *call, int success, void *user_data); -grpc_call *grpc_call_create(grpc_channel *channel, grpc_call *parent_call, - uint32_t propagation_mask, - grpc_completion_queue *cq, - /* if not NULL, it'll be used in lieu of \a cq */ - grpc_pollset_set *pollset_set_alternative, - const void *server_transport_data, - grpc_mdelem **add_initial_metadata, - size_t add_initial_metadata_count, - gpr_timespec send_deadline); +typedef struct grpc_call_create_args { + grpc_channel *channel; + + grpc_call *parent_call; + uint32_t propagation_mask; + + grpc_completion_queue *cq; + /* if not NULL, it'll be used in lieu of cq */ + grpc_pollset_set *pollset_set_alternative; + + const void *server_transport_data; + + grpc_mdelem **add_initial_metadata; + size_t add_initial_metadata_count; + + gpr_timespec send_deadline; +} grpc_call_create_args; + +/* Create a new call based on \a args. + Regardless of success or failure, always returns a valid new call into *call + */ +grpc_error *grpc_call_create(const grpc_call_create_args *args, + grpc_call **call); void grpc_call_set_completion_queue(grpc_exec_ctx *exec_ctx, grpc_call *call, grpc_completion_queue *cq); diff --git a/src/core/lib/surface/channel.c b/src/core/lib/surface/channel.c index 52e78567bd..aa8c052b41 100644 --- a/src/core/lib/surface/channel.c +++ b/src/core/lib/surface/channel.c @@ -208,9 +208,21 @@ static grpc_call *grpc_channel_create_call_internal( send_metadata[num_metadata++] = GRPC_MDELEM_REF(channel->default_authority); } - return grpc_call_create(channel, parent_call, propagation_mask, cq, - pollset_set_alternative, NULL, send_metadata, - num_metadata, deadline); + grpc_call_create_args args; + memset(&args, 0, sizeof(args)); + args.channel = channel; + args.parent_call = parent_call; + args.propagation_mask = propagation_mask; + args.cq = cq; + args.pollset_set_alternative = pollset_set_alternative; + args.server_transport_data = NULL; + args.add_initial_metadata = send_metadata; + args.add_initial_metadata_count = num_metadata; + args.send_deadline = deadline; + + grpc_call *call; + GRPC_LOG_IF_ERROR("call_create", grpc_call_create(&args, &call)); + return call; } grpc_call *grpc_channel_create_call(grpc_channel *channel, diff --git a/src/core/lib/surface/server.c b/src/core/lib/surface/server.c index 0827a1e181..fa48764a1c 100644 --- a/src/core/lib/surface/server.c +++ b/src/core/lib/surface/server.c @@ -824,11 +824,20 @@ static void accept_stream(grpc_exec_ctx *exec_ctx, void *cd, const void *transport_server_data) { channel_data *chand = cd; /* create a call */ - grpc_call *call = grpc_call_create(chand->channel, NULL, 0, NULL, NULL, - transport_server_data, NULL, 0, - gpr_inf_future(GPR_CLOCK_MONOTONIC)); + grpc_call_create_args args; + memset(&args, 0, sizeof(args)); + args.channel = chand->channel; + args.server_transport_data = transport_server_data; + args.send_deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC); + grpc_call *call; + grpc_error *error = grpc_call_create(&args, &call); grpc_call_element *elem = grpc_call_stack_element(grpc_call_get_call_stack(call), 0); + if (error != GRPC_ERROR_NONE) { + got_initial_metadata(exec_ctx, elem, error); + GRPC_ERROR_UNREF(error); + return; + } call_data *calld = elem->call_data; grpc_op op; memset(&op, 0, sizeof(op)); -- cgit v1.2.3 From 13e4bf8e6a1ef4b1a952c449b576f6c0f7e127b0 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 19 Aug 2016 10:24:34 -0700 Subject: Simplifications --- src/core/ext/client_config/subchannel.c | 4 +- .../transport/chttp2/transport/chttp2_transport.c | 51 +++------------------- src/core/ext/transport/chttp2/transport/internal.h | 15 ------- .../ext/transport/chttp2/transport/stream_lists.c | 20 --------- src/core/lib/iomgr/error.c | 2 +- src/core/lib/transport/transport.c | 10 +++-- src/core/lib/transport/transport.h | 2 +- 7 files changed, 16 insertions(+), 88 deletions(-) diff --git a/src/core/ext/client_config/subchannel.c b/src/core/ext/client_config/subchannel.c index 2c4364b259..e622862fc9 100644 --- a/src/core/ext/client_config/subchannel.c +++ b/src/core/ext/client_config/subchannel.c @@ -219,8 +219,8 @@ static gpr_atm ref_mutate(grpc_subchannel *c, gpr_atm delta, : gpr_atm_no_barrier_fetch_add(&c->ref_pair, delta); #ifdef GRPC_STREAM_REFCOUNT_DEBUG gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "SUBCHANNEL: %p % 12s 0x%08x -> 0x%08x [%s]", c, purpose, old_val, - old_val + delta, reason); + "SUBCHANNEL: %p %s 0x%08" PRIxPTR " -> 0x%08" PRIxPTR " [%s]", c, + purpose, old_val, old_val + delta, reason); #endif return old_val; } diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 0be00a78d4..82c040b186 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -501,7 +501,6 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, REF_TRANSPORT(t, "stream"); if (server_data) { - GPR_ASSERT(t->executor.parsing_active); s->global.id = (uint32_t)(uintptr_t)server_data; s->global.outgoing_window = t->global.settings[GRPC_PEER_SETTINGS] @@ -540,7 +539,7 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp, exec_ctx, t, GRPC_ERROR_CREATE("Last stream closed after sending goaway")); } - if (!t->executor.parsing_active && s->global.id) { + if (s->global.id != 0) { GPR_ASSERT(grpc_chttp2_stream_map_find(&t->parsing_stream_map, s->global.id) == NULL); } @@ -1246,15 +1245,6 @@ static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t = op->transport_private.args[0]; grpc_error *close_transport = op->disconnect_with_error; - /* If there's a set_accept_stream ensure that we're not parsing - to avoid changing things out from underneath */ - if (t->executor.parsing_active && op->set_accept_stream) { - GPR_ASSERT(t->post_parsing_op == NULL); - t->post_parsing_op = gpr_malloc(sizeof(*op)); - memcpy(t->post_parsing_op, op, sizeof(*op)); - return; - } - if (op->on_connectivity_state_change != NULL) { grpc_connectivity_state_notify_on_state_change( exec_ctx, &t->channel_callback.state_tracker, op->connectivity_state, @@ -1627,18 +1617,12 @@ void grpc_chttp2_mark_stream_closed( } } if (stream_global->read_closed && stream_global->write_closed) { - if (stream_global->id != 0 && - TRANSPORT_FROM_GLOBAL(transport_global)->executor.parsing_active) { - grpc_chttp2_list_add_closed_waiting_for_parsing(transport_global, - stream_global); - } else { - if (stream_global->id != 0) { - remove_stream(exec_ctx, TRANSPORT_FROM_GLOBAL(transport_global), - stream_global->id, - removal_error(GRPC_ERROR_REF(error), stream_global)); - } - GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2"); + if (stream_global->id != 0) { + remove_stream(exec_ctx, TRANSPORT_FROM_GLOBAL(transport_global), + stream_global->id, + removal_error(GRPC_ERROR_REF(error), stream_global)); } + GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2"); } GRPC_ERROR_UNREF(error); } @@ -1874,9 +1858,7 @@ static void reading_action_locked(grpc_exec_ctx *exec_ctx, void *tp, GRPC_ERROR_REF(error); - GPR_ASSERT(!t->executor.parsing_active); if (!t->closed) { - t->executor.parsing_active = 1; /* merge stream lists */ grpc_chttp2_stream_map_move_into(&t->new_stream_map, &t->parsing_stream_map); @@ -1919,27 +1901,6 @@ static void reading_action_locked(grpc_exec_ctx *exec_ctx, void *tp, grpc_chttp2_initiate_write(exec_ctx, transport_global, false, "global incoming window"); } - t->executor.parsing_active = 0; - /* handle delayed transport ops (if there is one) */ - if (t->post_parsing_op) { - grpc_transport_op *op = t->post_parsing_op; - t->post_parsing_op = NULL; - perform_transport_op_locked(exec_ctx, op, GRPC_ERROR_NONE); - gpr_free(op); - } - /* if a stream is in the stream map, and gets cancelled, we need to - * ensure we are not parsing before continuing the cancellation to keep - * things in a sane state */ - grpc_chttp2_stream_global *stream_global; - while (grpc_chttp2_list_pop_closed_waiting_for_parsing(transport_global, - &stream_global)) { - GPR_ASSERT(stream_global->in_stream_map); - GPR_ASSERT(stream_global->write_closed); - GPR_ASSERT(stream_global->read_closed); - remove_stream(exec_ctx, t, stream_global->id, - removal_error(GRPC_ERROR_NONE, stream_global)); - GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2"); - } GPR_TIMER_END("post_parse_locked", 0); } diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 517b21c5d3..da90464400 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -64,7 +64,6 @@ typedef enum { GRPC_CHTTP2_LIST_WRITABLE, GRPC_CHTTP2_LIST_WRITING, GRPC_CHTTP2_LIST_WRITTEN, - GRPC_CHTTP2_LIST_CLOSED_WAITING_FOR_PARSING, GRPC_CHTTP2_LIST_CLOSED_WAITING_FOR_WRITING, GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT, /* streams waiting for the outgoing window in the writing path, they will be @@ -308,10 +307,6 @@ struct grpc_chttp2_transport { struct { grpc_combiner *combiner; - /** is a thread currently in the global lock */ - bool global_active; - /** is a thread currently parsing */ - bool parsing_active; /** write execution state of the transport */ grpc_chttp2_write_state write_state; /** has a check_read_ops been scheduled */ @@ -374,9 +369,6 @@ struct grpc_chttp2_transport { /** connectivity tracking */ grpc_connectivity_state_tracker state_tracker; } channel_callback; - - /** Transport op to be applied post-parsing */ - grpc_transport_op *post_parsing_op; }; struct grpc_chttp2_stream_global { @@ -602,13 +594,6 @@ void grpc_chttp2_list_remove_stalled_by_transport( grpc_chttp2_transport_global *transport_global, grpc_chttp2_stream_global *stream_global); -void grpc_chttp2_list_add_closed_waiting_for_parsing( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global); -int grpc_chttp2_list_pop_closed_waiting_for_parsing( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global **stream_global); - void grpc_chttp2_list_add_closed_waiting_for_writing( grpc_chttp2_transport_global *transport_global, grpc_chttp2_stream_global *stream_global); diff --git a/src/core/ext/transport/chttp2/transport/stream_lists.c b/src/core/ext/transport/chttp2/transport/stream_lists.c index 7c31466c80..0805551b64 100644 --- a/src/core/ext/transport/chttp2/transport/stream_lists.c +++ b/src/core/ext/transport/chttp2/transport/stream_lists.c @@ -334,26 +334,6 @@ void grpc_chttp2_list_remove_stalled_by_transport( GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT); } -void grpc_chttp2_list_add_closed_waiting_for_parsing( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global) { - stream_list_add(TRANSPORT_FROM_GLOBAL(transport_global), - STREAM_FROM_GLOBAL(stream_global), - GRPC_CHTTP2_LIST_CLOSED_WAITING_FOR_PARSING); -} - -int grpc_chttp2_list_pop_closed_waiting_for_parsing( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global **stream_global) { - grpc_chttp2_stream *stream; - int r = stream_list_pop(TRANSPORT_FROM_GLOBAL(transport_global), &stream, - GRPC_CHTTP2_LIST_CLOSED_WAITING_FOR_PARSING); - if (r != 0) { - *stream_global = &stream->global; - } - return r; -} - void grpc_chttp2_list_add_closed_waiting_for_writing( grpc_chttp2_transport_global *transport_global, grpc_chttp2_stream_global *stream_global) { diff --git a/src/core/lib/iomgr/error.c b/src/core/lib/iomgr/error.c index e366961936..45ef75e04d 100644 --- a/src/core/lib/iomgr/error.c +++ b/src/core/lib/iomgr/error.c @@ -265,7 +265,7 @@ static grpc_error *copy_error_and_unref(grpc_error *in) { } else { out = gpr_malloc(sizeof(*out)); #ifdef GRPC_ERROR_REFCOUNT_DEBUG - gpr_log(GPR_DEBUG, "%p create copying", out); + gpr_log(GPR_DEBUG, "%p create copying %p", out, in); #endif out->ints = gpr_avl_ref(in->ints); out->strs = gpr_avl_ref(in->strs); diff --git a/src/core/lib/transport/transport.c b/src/core/lib/transport/transport.c index 08f9d7e8d9..a78ad4349a 100644 --- a/src/core/lib/transport/transport.c +++ b/src/core/lib/transport/transport.c @@ -46,8 +46,9 @@ #ifdef GRPC_STREAM_REFCOUNT_DEBUG void grpc_stream_ref(grpc_stream_refcount *refcount, const char *reason) { gpr_atm val = gpr_atm_no_barrier_load(&refcount->refs.count); - gpr_log(GPR_DEBUG, "%s %p:%p REF %d->%d %s", refcount->object_type, - refcount, refcount->destroy.cb_arg, val, val + 1, reason); + gpr_log(GPR_DEBUG, "%s %p:%p REF %" PRIdPTR "->%" PRIdPTR " %s", + refcount->object_type, refcount, refcount->destroy.cb_arg, val, + val + 1, reason); #else void grpc_stream_ref(grpc_stream_refcount *refcount) { #endif @@ -58,8 +59,9 @@ void grpc_stream_ref(grpc_stream_refcount *refcount) { void grpc_stream_unref(grpc_exec_ctx *exec_ctx, grpc_stream_refcount *refcount, const char *reason) { gpr_atm val = gpr_atm_no_barrier_load(&refcount->refs.count); - gpr_log(GPR_DEBUG, "%s %p:%p UNREF %d->%d %s", refcount->object_type, - refcount, refcount->destroy.cb_arg, val, val - 1, reason); + gpr_log(GPR_DEBUG, "%s %p:%p UNREF %" PRIdPTR "->%" PRIdPTR " %s", + refcount->object_type, refcount, refcount->destroy.cb_arg, val, + val - 1, reason); #else void grpc_stream_unref(grpc_exec_ctx *exec_ctx, grpc_stream_refcount *refcount) { diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h index d0d0c2a461..392a7ca422 100644 --- a/src/core/lib/transport/transport.h +++ b/src/core/lib/transport/transport.h @@ -55,7 +55,7 @@ typedef struct grpc_transport grpc_transport; for a stream. */ typedef struct grpc_stream grpc_stream; -//#define GRPC_STREAM_REFCOUNT_DEBUG +#define GRPC_STREAM_REFCOUNT_DEBUG typedef struct grpc_stream_refcount { gpr_refcount refs; -- cgit v1.2.3 From 796f525f7fffe06c001a974602e71809a20fc7e1 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 19 Aug 2016 10:44:48 -0700 Subject: Eliminate dual stream maps --- .../transport/chttp2/transport/chttp2_transport.c | 50 +++++++--------------- src/core/ext/transport/chttp2/transport/internal.h | 14 +----- 2 files changed, 18 insertions(+), 46 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 82c040b186..55b60992e0 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -163,11 +163,9 @@ static void destruct_transport(grpc_exec_ctx *exec_ctx, GPR_ASSERT(t->lists[i].tail == NULL); } - GPR_ASSERT(grpc_chttp2_stream_map_size(&t->parsing_stream_map) == 0); - GPR_ASSERT(grpc_chttp2_stream_map_size(&t->new_stream_map) == 0); + GPR_ASSERT(grpc_chttp2_stream_map_size(&t->stream_map) == 0); - grpc_chttp2_stream_map_destroy(&t->parsing_stream_map); - grpc_chttp2_stream_map_destroy(&t->new_stream_map); + grpc_chttp2_stream_map_destroy(&t->stream_map); grpc_connectivity_state_destroy(exec_ctx, &t->channel_callback.state_tracker); grpc_combiner_destroy(exec_ctx, t->executor.combiner); @@ -277,8 +275,7 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, large enough that the exponential growth should happen nicely when it's needed. TODO(ctiller): tune this */ - grpc_chttp2_stream_map_init(&t->parsing_stream_map, 8); - grpc_chttp2_stream_map_init(&t->new_stream_map, 8); + grpc_chttp2_stream_map_init(&t->stream_map, 8); /* copy in initial settings to all setting sets */ for (i = 0; i < GRPC_CHTTP2_NUM_SETTINGS; i++) { @@ -509,7 +506,7 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, t->global.settings[GRPC_SENT_SETTINGS] [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]; *t->accepting_stream = s; - grpc_chttp2_stream_map_add(&t->parsing_stream_map, s->global.id, s); + grpc_chttp2_stream_map_add(&t->stream_map, s->global.id, s); s->global.in_stream_map = true; } @@ -540,8 +537,8 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp, GRPC_ERROR_CREATE("Last stream closed after sending goaway")); } if (s->global.id != 0) { - GPR_ASSERT(grpc_chttp2_stream_map_find(&t->parsing_stream_map, - s->global.id) == NULL); + GPR_ASSERT(grpc_chttp2_stream_map_find(&t->stream_map, s->global.id) == + NULL); } while ( @@ -596,8 +593,7 @@ static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, grpc_chttp2_stream_global *grpc_chttp2_parsing_lookup_stream( grpc_chttp2_transport_global *transport_global, uint32_t id) { grpc_chttp2_transport *t = TRANSPORT_FROM_GLOBAL(transport_global); - grpc_chttp2_stream *s = - grpc_chttp2_stream_map_find(&t->parsing_stream_map, id); + grpc_chttp2_stream *s = grpc_chttp2_stream_map_find(&t->stream_map, id); return s ? &s->global : NULL; } @@ -878,7 +874,8 @@ static void maybe_start_some_streams( /* start streams where we have free grpc_chttp2_stream ids and free * concurrency */ while (transport_global->next_stream_id <= MAX_CLIENT_STREAM_ID && - transport_global->concurrent_stream_count < + grpc_chttp2_stream_map_size( + &TRANSPORT_FROM_GLOBAL(transport_global)->stream_map) < transport_global ->settings[GRPC_PEER_SETTINGS] [GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS] && @@ -909,10 +906,9 @@ static void maybe_start_some_streams( stream_global->max_recv_bytes = GPR_MAX(stream_incoming_window, stream_global->max_recv_bytes); grpc_chttp2_stream_map_add( - &TRANSPORT_FROM_GLOBAL(transport_global)->new_stream_map, - stream_global->id, STREAM_FROM_GLOBAL(stream_global)); + &TRANSPORT_FROM_GLOBAL(transport_global)->stream_map, stream_global->id, + STREAM_FROM_GLOBAL(stream_global)); stream_global->in_stream_map = true; - transport_global->concurrent_stream_count++; grpc_chttp2_become_writable(exec_ctx, transport_global, stream_global, true, "new_stream"); } @@ -1397,12 +1393,7 @@ static void decrement_active_streams_locked( static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, uint32_t id, grpc_error *error) { - size_t new_stream_count; - grpc_chttp2_stream *s = - grpc_chttp2_stream_map_delete(&t->parsing_stream_map, id); - if (!s) { - s = grpc_chttp2_stream_map_delete(&t->new_stream_map, id); - } + grpc_chttp2_stream *s = grpc_chttp2_stream_map_delete(&t->stream_map, id); GPR_ASSERT(s); s->global.in_stream_map = false; if (t->global.incoming_stream == &s->global) { @@ -1425,14 +1416,9 @@ static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, GRPC_CHTTP2_STREAM_UNREF(exec_ctx, &s->global, "chttp2_writing"); } - new_stream_count = grpc_chttp2_stream_map_size(&t->parsing_stream_map) + - grpc_chttp2_stream_map_size(&t->new_stream_map); - GPR_ASSERT(new_stream_count <= UINT32_MAX); - if (new_stream_count != t->global.concurrent_stream_count) { - t->global.concurrent_stream_count = (uint32_t)new_stream_count; - maybe_start_some_streams(exec_ctx, &t->global); - } GRPC_ERROR_UNREF(error); + + maybe_start_some_streams(exec_ctx, &t->global); } static void status_codes_from_error(grpc_error *error, gpr_timespec deadline, @@ -1859,10 +1845,6 @@ static void reading_action_locked(grpc_exec_ctx *exec_ctx, void *tp, GRPC_ERROR_REF(error); if (!t->closed) { - /* merge stream lists */ - grpc_chttp2_stream_map_move_into(&t->new_stream_map, - &t->parsing_stream_map); - GPR_TIMER_BEGIN("reading_action.parse", 0); size_t i = 0; grpc_error *errors[3] = {GRPC_ERROR_REF(error), GRPC_ERROR_NONE, @@ -1885,8 +1867,8 @@ static void reading_action_locked(grpc_exec_ctx *exec_ctx, void *tp, GPR_TIMER_BEGIN("post_parse_locked", 0); if (transport_global->initial_window_update != 0) { update_global_window_args args = {t, exec_ctx}; - grpc_chttp2_stream_map_for_each(&t->parsing_stream_map, - update_global_window, &args); + grpc_chttp2_stream_map_for_each(&t->stream_map, update_global_window, + &args); transport_global->initial_window_update = 0; } /* handle higher level things */ diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index da90464400..c487835a9f 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -217,10 +217,6 @@ struct grpc_chttp2_transport_global { /** next payload for an outgoing ping */ uint64_t ping_counter; - /** concurrent stream count: updated when not parsing, - so this is a strict over-estimation on the client */ - uint32_t concurrent_stream_count; - /** parser for headers */ grpc_chttp2_hpack_parser hpack_parser; /** simple one shot parsers */ @@ -331,14 +327,8 @@ struct grpc_chttp2_transport { chain. */ grpc_chttp2_transport_writing writing; - /** maps stream id to grpc_chttp2_stream objects; - owned by the parsing thread when parsing */ - grpc_chttp2_stream_map parsing_stream_map; - - /** streams created by the client (possibly during parsing); - merged with parsing_stream_map during unlock when no - parsing is occurring */ - grpc_chttp2_stream_map new_stream_map; + /** maps stream id to grpc_chttp2_stream objects */ + grpc_chttp2_stream_map stream_map; /** closure to execute writing */ grpc_closure writing_action; -- cgit v1.2.3 From 922f810b2e725306b1b403b3af7b9134dee0c60c Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 19 Aug 2016 11:05:35 -0700 Subject: Eliminate lock during initialization --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 55b60992e0..2ca76b5153 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -507,14 +507,15 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]; *t->accepting_stream = s; grpc_chttp2_stream_map_add(&t->stream_map, s->global.id, s); + grpc_chttp2_register_stream(t, s); s->global.in_stream_map = true; + } else { + grpc_closure_init(&s->init_stream, finish_init_stream_locked, s); + GRPC_CHTTP2_STREAM_REF(&s->global, "init"); + grpc_combiner_execute(exec_ctx, t->executor.combiner, &s->init_stream, + GRPC_ERROR_NONE); } - grpc_closure_init(&s->init_stream, finish_init_stream_locked, s); - GRPC_CHTTP2_STREAM_REF(&s->global, "init"); - grpc_combiner_execute(exec_ctx, t->executor.combiner, &s->init_stream, - GRPC_ERROR_NONE); - GPR_TIMER_END("init_stream", 0); return 0; -- cgit v1.2.3 From f0e1119996b549dcb5e3013f805cd2cd066ed2c9 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 19 Aug 2016 11:32:28 -0700 Subject: Fix refcounting bugs --- src/core/ext/transport/chttp2/transport/frame_data.c | 1 + src/core/ext/transport/chttp2/transport/parsing.c | 2 +- src/core/lib/iomgr/error.h | 2 +- src/core/lib/transport/transport.h | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c index 18e55b2916..388a5aba2b 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.c +++ b/src/core/ext/transport/chttp2/transport/frame_data.c @@ -56,6 +56,7 @@ void grpc_chttp2_data_parser_destroy(grpc_exec_ctx *exec_ctx, exec_ctx, parser->parsing_frame, GRPC_ERROR_CREATE("Parser destroyed"), 1); } + GRPC_ERROR_UNREF(parser->error); } grpc_error *grpc_chttp2_data_parser_begin_frame(grpc_chttp2_data_parser *parser, diff --git a/src/core/ext/transport/chttp2/transport/parsing.c b/src/core/ext/transport/chttp2/transport/parsing.c index ee01d3beb7..4d9e25d985 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.c +++ b/src/core/ext/transport/chttp2/transport/parsing.c @@ -444,7 +444,7 @@ static grpc_error *init_data_frame_parser( } else if (grpc_error_get_int(err, GRPC_ERROR_INT_STREAM_ID, NULL)) { /* handle stream errors by closing the stream */ grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global, - true, false, GRPC_ERROR_REF(err)); + true, false, err); gpr_slice_buffer_add( &transport_global->qbuf, grpc_chttp2_rst_stream_create(transport_global->incoming_stream_id, diff --git a/src/core/lib/iomgr/error.h b/src/core/lib/iomgr/error.h index bc7781250e..e02b12f2f4 100644 --- a/src/core/lib/iomgr/error.h +++ b/src/core/lib/iomgr/error.h @@ -148,7 +148,7 @@ grpc_error *grpc_error_create(const char *file, int line, const char *desc, #define GRPC_ERROR_CREATE_REFERENCING(desc, errs, count) \ grpc_error_create(__FILE__, __LINE__, desc, errs, count) -//#define GRPC_ERROR_REFCOUNT_DEBUG +#define GRPC_ERROR_REFCOUNT_DEBUG #ifdef GRPC_ERROR_REFCOUNT_DEBUG grpc_error *grpc_error_ref(grpc_error *err, const char *file, int line, const char *func); diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h index 392a7ca422..d0d0c2a461 100644 --- a/src/core/lib/transport/transport.h +++ b/src/core/lib/transport/transport.h @@ -55,7 +55,7 @@ typedef struct grpc_transport grpc_transport; for a stream. */ typedef struct grpc_stream grpc_stream; -#define GRPC_STREAM_REFCOUNT_DEBUG +//#define GRPC_STREAM_REFCOUNT_DEBUG typedef struct grpc_stream_refcount { gpr_refcount refs; -- cgit v1.2.3 From 4e41e360d31e71b933e0f8fadfc8995d3d01f8db Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 19 Aug 2016 13:12:54 -0700 Subject: Add tracer for pending tags --- src/core/lib/iomgr/error.h | 2 +- src/core/lib/surface/completion_queue.c | 31 +++++++++++++++++++++++++++++++ src/core/lib/surface/completion_queue.h | 3 +++ src/core/lib/surface/init.c | 3 +++ 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/error.h b/src/core/lib/iomgr/error.h index e02b12f2f4..bc7781250e 100644 --- a/src/core/lib/iomgr/error.h +++ b/src/core/lib/iomgr/error.h @@ -148,7 +148,7 @@ grpc_error *grpc_error_create(const char *file, int line, const char *desc, #define GRPC_ERROR_CREATE_REFERENCING(desc, errs, count) \ grpc_error_create(__FILE__, __LINE__, desc, errs, count) -#define GRPC_ERROR_REFCOUNT_DEBUG +//#define GRPC_ERROR_REFCOUNT_DEBUG #ifdef GRPC_ERROR_REFCOUNT_DEBUG grpc_error *grpc_error_ref(grpc_error *err, const char *file, int line, const char *func); diff --git a/src/core/lib/surface/completion_queue.c b/src/core/lib/surface/completion_queue.c index 2412f78a06..5654b86d8b 100644 --- a/src/core/lib/surface/completion_queue.c +++ b/src/core/lib/surface/completion_queue.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include "src/core/lib/iomgr/pollset.h" @@ -50,6 +51,9 @@ #include "src/core/lib/surface/event_string.h" int grpc_trace_operation_failures; +#ifndef NDEBUG +int grpc_trace_pending_tags; +#endif typedef struct { grpc_pollset_worker **worker; @@ -338,6 +342,25 @@ static bool cq_is_next_finished(grpc_exec_ctx *exec_ctx, void *arg) { return gpr_time_cmp(a->deadline, gpr_now(a->deadline.clock_type)) < 0; } +#ifndef NDEBUG +static void dump_pending_tags(grpc_completion_queue *cc) { + if (!grpc_trace_pending_tags) return; + + gpr_strvec v; + gpr_strvec_init(&v); + gpr_strvec_add(&v, gpr_strdup("PENDING TAGS:")); + for (size_t i = 0; i < cc->outstanding_tag_count; i++) { + char *s; + gpr_asprintf(&s, " %p", cc->outstanding_tags[i]); + gpr_strvec_add(&v, s); + } + char *out = gpr_strvec_flatten(&v, NULL); + gpr_strvec_destroy(&v); + gpr_log(GPR_DEBUG, "%s", out); + gpr_free(out); +} +#endif + grpc_event grpc_completion_queue_next(grpc_completion_queue *cc, gpr_timespec deadline, void *reserved) { grpc_event ret; @@ -357,6 +380,10 @@ grpc_event grpc_completion_queue_next(grpc_completion_queue *cc, reserved)); GPR_ASSERT(!reserved); +#ifndef NDEBUG + dump_pending_tags(cc); +#endif + deadline = gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC); cq_is_finished_arg is_finished_arg = {cc, deadline, NULL, NULL}; @@ -510,6 +537,10 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag, } GPR_ASSERT(!reserved); +#ifndef NDEBUG + dump_pending_tags(cc); +#endif + deadline = gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC); cq_is_finished_arg is_finished_arg = {cc, deadline, NULL, tag}; diff --git a/src/core/lib/surface/completion_queue.h b/src/core/lib/surface/completion_queue.h index 3049284f68..e9d840df77 100644 --- a/src/core/lib/surface/completion_queue.h +++ b/src/core/lib/surface/completion_queue.h @@ -44,6 +44,9 @@ extern int grpc_cq_pluck_trace; extern int grpc_cq_event_timeout_trace; extern int grpc_trace_operation_failures; +#ifndef NDEBUG +extern int grpc_trace_pending_tags; +#endif typedef struct grpc_cq_completion { /** user supplied tag */ diff --git a/src/core/lib/surface/init.c b/src/core/lib/surface/init.c index edda0c85fa..ac111253ef 100644 --- a/src/core/lib/surface/init.c +++ b/src/core/lib/surface/init.c @@ -173,6 +173,9 @@ void grpc_init(void) { // Default timeout trace to 1 grpc_cq_event_timeout_trace = 1; grpc_register_tracer("op_failure", &grpc_trace_operation_failures); +#ifndef NDEBUG + grpc_register_tracer("pending_tags", &grpc_trace_pending_tags); +#endif grpc_security_pre_init(); grpc_iomgr_init(); grpc_executor_init(); -- cgit v1.2.3 From 49c644ca6a382e69f7c85b486601784aff94b81e Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 19 Aug 2016 13:52:23 -0700 Subject: Fix bugs, make it easier to find them --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 2 +- src/core/lib/surface/completion_queue.c | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 2ca76b5153..161f26b39f 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1587,7 +1587,7 @@ void grpc_chttp2_mark_stream_closed( stream_global->read_closed_error = GRPC_ERROR_REF(error); stream_global->read_closed = true; stream_global->published_metadata[0] = true; - stream_global->published_metadata[0] = true; + stream_global->published_metadata[1] = true; decrement_active_streams_locked(exec_ctx, transport_global, stream_global); } if (close_writes && !stream_global->write_closed) { diff --git a/src/core/lib/surface/completion_queue.c b/src/core/lib/surface/completion_queue.c index 5654b86d8b..28450d966c 100644 --- a/src/core/lib/surface/completion_queue.c +++ b/src/core/lib/surface/completion_queue.c @@ -359,6 +359,8 @@ static void dump_pending_tags(grpc_completion_queue *cc) { gpr_log(GPR_DEBUG, "%s", out); gpr_free(out); } +#else +static void dump_pending_tags(grpc_completion_queue *cc) {} #endif grpc_event grpc_completion_queue_next(grpc_completion_queue *cc, @@ -380,9 +382,7 @@ grpc_event grpc_completion_queue_next(grpc_completion_queue *cc, reserved)); GPR_ASSERT(!reserved); -#ifndef NDEBUG dump_pending_tags(cc); -#endif deadline = gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC); @@ -427,6 +427,7 @@ grpc_event grpc_completion_queue_next(grpc_completion_queue *cc, gpr_mu_unlock(cc->mu); memset(&ret, 0, sizeof(ret)); ret.type = GRPC_QUEUE_TIMEOUT; + dump_pending_tags(cc); break; } first_loop = 0; @@ -452,6 +453,7 @@ grpc_event grpc_completion_queue_next(grpc_completion_queue *cc, GRPC_ERROR_UNREF(err); memset(&ret, 0, sizeof(ret)); ret.type = GRPC_QUEUE_TIMEOUT; + dump_pending_tags(cc); break; } } @@ -537,9 +539,7 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag, } GPR_ASSERT(!reserved); -#ifndef NDEBUG dump_pending_tags(cc); -#endif deadline = gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC); @@ -592,6 +592,7 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag, memset(&ret, 0, sizeof(ret)); /* TODO(ctiller): should we use a different result here */ ret.type = GRPC_QUEUE_TIMEOUT; + dump_pending_tags(cc); break; } now = gpr_now(GPR_CLOCK_MONOTONIC); @@ -600,6 +601,7 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag, gpr_mu_unlock(cc->mu); memset(&ret, 0, sizeof(ret)); ret.type = GRPC_QUEUE_TIMEOUT; + dump_pending_tags(cc); break; } first_loop = 0; @@ -625,6 +627,7 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag, GRPC_ERROR_UNREF(err); memset(&ret, 0, sizeof(ret)); ret.type = GRPC_QUEUE_TIMEOUT; + dump_pending_tags(cc); break; } } -- cgit v1.2.3 From 032b515d562b66ba6f5f57299a99c3f808f8eddc Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Sun, 21 Aug 2016 13:30:09 -0700 Subject: Remove global list of streams from transport --- .../transport/chttp2/transport/chttp2_transport.c | 35 ++++++---------------- src/core/ext/transport/chttp2/transport/internal.h | 13 -------- .../ext/transport/chttp2/transport/stream_lists.c | 27 ----------------- 3 files changed, 9 insertions(+), 66 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 161f26b39f..69ea398f66 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -465,13 +465,6 @@ void grpc_chttp2_stream_unref(grpc_exec_ctx *exec_ctx, } #endif -static void finish_init_stream_locked(grpc_exec_ctx *exec_ctx, void *sp, - grpc_error *error) { - grpc_chttp2_stream *s = sp; - grpc_chttp2_register_stream(s->t, s); - GRPC_CHTTP2_STREAM_UNREF(exec_ctx, &s->global, "init"); -} - static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, grpc_stream *gs, grpc_stream_refcount *refcount, const void *server_data) { @@ -507,13 +500,7 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]; *t->accepting_stream = s; grpc_chttp2_stream_map_add(&t->stream_map, s->global.id, s); - grpc_chttp2_register_stream(t, s); s->global.in_stream_map = true; - } else { - grpc_closure_init(&s->init_stream, finish_init_stream_locked, s); - GRPC_CHTTP2_STREAM_REF(&s->global, "init"); - grpc_combiner_execute(exec_ctx, t->executor.combiner, &s->init_stream, - GRPC_ERROR_NONE); } GPR_TIMER_END("init_stream", 0); @@ -532,11 +519,6 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp, GPR_ASSERT((s->global.write_closed && s->global.read_closed) || s->global.id == 0); GPR_ASSERT(!s->global.in_stream_map); - if (grpc_chttp2_unregister_stream(t, s) && t->global.sent_goaway) { - close_transport_locked( - exec_ctx, t, - GRPC_ERROR_CREATE("Last stream closed after sending goaway")); - } if (s->global.id != 0) { GPR_ASSERT(grpc_chttp2_stream_map_find(&t->stream_map, s->global.id) == NULL); @@ -1254,7 +1236,7 @@ static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx, t->global.last_incoming_stream_id, (uint32_t)grpc_chttp2_grpc_status_to_http2_error(op->goaway_status), gpr_slice_ref(*op->goaway_message), &t->global.qbuf); - close_transport = grpc_chttp2_has_streams(t) + close_transport = grpc_chttp2_stream_map_size(&t->stream_map) == 0 ? GRPC_ERROR_NONE : GRPC_ERROR_CREATE("GOAWAY sent"); grpc_chttp2_initiate_write(exec_ctx, &t->global, false, "goaway_sent"); @@ -1408,7 +1390,8 @@ static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, s->global.data_parser.parsing_frame = NULL; } - if (grpc_chttp2_unregister_stream(t, s) && t->global.sent_goaway) { + if (grpc_chttp2_stream_map_size(&t->stream_map) == 0 && + t->global.sent_goaway) { close_transport_locked( exec_ctx, t, GRPC_ERROR_CREATE_REFERENCING( "Last stream closed after sending GOAWAY", &error, 1)); @@ -1738,20 +1721,20 @@ static void close_from_api(grpc_exec_ctx *exec_ctx, typedef struct { grpc_exec_ctx *exec_ctx; grpc_error *error; + grpc_chttp2_transport *t; } cancel_stream_cb_args; -static void cancel_stream_cb(grpc_chttp2_transport_global *transport_global, - void *user_data, - grpc_chttp2_stream_global *stream_global) { +static void cancel_stream_cb(void *user_data, uint32_t key, void *stream) { cancel_stream_cb_args *args = user_data; - cancel_from_api(args->exec_ctx, transport_global, stream_global, + grpc_chttp2_stream *s = stream; + cancel_from_api(args->exec_ctx, &args->t->global, &s->global, GRPC_ERROR_REF(args->error)); } static void end_all_the_calls(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_error *error) { - cancel_stream_cb_args args = {exec_ctx, error}; - grpc_chttp2_for_all_streams(&t->global, &args, cancel_stream_cb); + cancel_stream_cb_args args = {exec_ctx, error, t}; + grpc_chttp2_stream_map_for_each(&t->stream_map, cancel_stream_cb, &args); GRPC_ERROR_UNREF(error); } diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index c487835a9f..4dbeb71d4f 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -59,7 +59,6 @@ typedef struct grpc_chttp2_stream grpc_chttp2_stream; /* streams are kept in various linked lists depending on what things need to happen to them... this enum labels each list */ typedef enum { - GRPC_CHTTP2_LIST_ALL_STREAMS, GRPC_CHTTP2_LIST_CHECK_READ_OPS, GRPC_CHTTP2_LIST_WRITABLE, GRPC_CHTTP2_LIST_WRITING, @@ -475,7 +474,6 @@ struct grpc_chttp2_stream { grpc_chttp2_stream_global global; grpc_chttp2_stream_writing writing; - grpc_closure init_stream; grpc_closure destroy_stream; void *destroy_stream_arg; @@ -601,17 +599,6 @@ void grpc_chttp2_add_incoming_goaway( grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, uint32_t goaway_error, gpr_slice goaway_text); -void grpc_chttp2_register_stream(grpc_chttp2_transport *t, - grpc_chttp2_stream *s); -/* returns 1 if this is the last stream, 0 otherwise */ -int grpc_chttp2_unregister_stream(grpc_chttp2_transport *t, - grpc_chttp2_stream *s) GRPC_MUST_USE_RESULT; -int grpc_chttp2_has_streams(grpc_chttp2_transport *t); -void grpc_chttp2_for_all_streams( - grpc_chttp2_transport_global *transport_global, void *user_data, - void (*cb)(grpc_chttp2_transport_global *transport_global, void *user_data, - grpc_chttp2_stream_global *stream_global)); - void grpc_chttp2_parsing_become_skip_parser( grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global); diff --git a/src/core/ext/transport/chttp2/transport/stream_lists.c b/src/core/ext/transport/chttp2/transport/stream_lists.c index 0805551b64..4ba09087f9 100644 --- a/src/core/ext/transport/chttp2/transport/stream_lists.c +++ b/src/core/ext/transport/chttp2/transport/stream_lists.c @@ -353,30 +353,3 @@ int grpc_chttp2_list_pop_closed_waiting_for_writing( } return r; } - -void grpc_chttp2_register_stream(grpc_chttp2_transport *t, - grpc_chttp2_stream *s) { - stream_list_add_tail(t, s, GRPC_CHTTP2_LIST_ALL_STREAMS); -} - -int grpc_chttp2_unregister_stream(grpc_chttp2_transport *t, - grpc_chttp2_stream *s) { - stream_list_maybe_remove(t, s, GRPC_CHTTP2_LIST_ALL_STREAMS); - return stream_list_empty(t, GRPC_CHTTP2_LIST_ALL_STREAMS); -} - -int grpc_chttp2_has_streams(grpc_chttp2_transport *t) { - return !stream_list_empty(t, GRPC_CHTTP2_LIST_ALL_STREAMS); -} - -void grpc_chttp2_for_all_streams( - grpc_chttp2_transport_global *transport_global, void *user_data, - void (*cb)(grpc_chttp2_transport_global *transport_global, void *user_data, - grpc_chttp2_stream_global *stream_global)) { - grpc_chttp2_stream *s; - grpc_chttp2_transport *t = TRANSPORT_FROM_GLOBAL(transport_global); - for (s = t->lists[GRPC_CHTTP2_LIST_ALL_STREAMS].head; s != NULL; - s = s->links[GRPC_CHTTP2_LIST_ALL_STREAMS].next) { - cb(transport_global, user_data, &s->global); - } -} -- cgit v1.2.3 From 31375ac49caf82e2aaee63aebdbfd50d185cca34 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 22 Aug 2016 09:08:00 -0700 Subject: fixes --- .../transport/chttp2/transport/chttp2_transport.c | 51 +-- .../ext/transport/chttp2/transport/hpack_parser.c | 455 ++++++++++++--------- .../ext/transport/chttp2/transport/hpack_parser.h | 8 +- src/core/ext/transport/chttp2/transport/internal.h | 6 +- src/core/ext/transport/chttp2/transport/parsing.c | 48 ++- .../transport/chttp2/hpack_parser_fuzzer_test.c | 9 +- test/core/transport/chttp2/hpack_parser_test.c | 6 +- 7 files changed, 331 insertions(+), 252 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 161f26b39f..72ac74db06 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -102,12 +102,6 @@ static void push_setting(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, static void drop_connection(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_error *error); -/** Cancel a stream: coming from the transport API */ -static void cancel_from_api(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, - grpc_error *error); - static void close_from_api(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, grpc_chttp2_stream_global *stream_global, @@ -917,10 +911,11 @@ static void maybe_start_some_streams( while (transport_global->next_stream_id >= MAX_CLIENT_STREAM_ID && grpc_chttp2_list_pop_waiting_for_concurrency(transport_global, &stream_global)) { - cancel_from_api(exec_ctx, transport_global, stream_global, - grpc_error_set_int( - GRPC_ERROR_CREATE("Stream IDs exhausted"), - GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE)); + grpc_chttp2_cancel_stream( + exec_ctx, transport_global, stream_global, + grpc_error_set_int(GRPC_ERROR_CREATE("Stream IDs exhausted"), + GRPC_ERROR_INT_GRPC_STATUS, + GRPC_STATUS_UNAVAILABLE)); } } @@ -1010,8 +1005,8 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, } if (op->cancel_error != GRPC_ERROR_NONE) { - cancel_from_api(exec_ctx, transport_global, stream_global, - GRPC_ERROR_REF(op->cancel_error)); + grpc_chttp2_cancel_stream(exec_ctx, transport_global, stream_global, + GRPC_ERROR_REF(op->cancel_error)); } if (op->close_error != GRPC_ERROR_NONE) { @@ -1035,7 +1030,7 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, stream_global->send_initial_metadata->deadline); } if (metadata_size > metadata_peer_limit) { - cancel_from_api( + grpc_chttp2_cancel_stream( exec_ctx, transport_global, stream_global, grpc_error_set_int( grpc_error_set_int( @@ -1102,7 +1097,7 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, transport_global->settings[GRPC_PEER_SETTINGS] [GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE]; if (metadata_size > metadata_peer_limit) { - cancel_from_api( + grpc_chttp2_cancel_stream( exec_ctx, transport_global, stream_global, grpc_error_set_int( grpc_error_set_int( @@ -1316,14 +1311,6 @@ static void check_read_ops(grpc_exec_ctx *exec_ctx, &stream_global->incoming_frames)) != NULL) { incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE); } - if (stream_global->exceeded_metadata_size) { - cancel_from_api( - exec_ctx, transport_global, stream_global, - grpc_error_set_int( - GRPC_ERROR_CREATE( - "received initial metadata size exceeds limit"), - GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED)); - } } grpc_chttp2_incoming_metadata_buffer_publish( &stream_global->metadata_buffer[0], @@ -1360,14 +1347,6 @@ static void check_read_ops(grpc_exec_ctx *exec_ctx, &stream_global->incoming_frames)) != NULL) { incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE); } - if (stream_global->exceeded_metadata_size) { - cancel_from_api( - exec_ctx, transport_global, stream_global, - grpc_error_set_int( - GRPC_ERROR_CREATE( - "received trailing metadata size exceeds limit"), - GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED)); - } } if (stream_global->all_incoming_byte_streams_finished) { grpc_chttp2_incoming_metadata_buffer_publish( @@ -1449,10 +1428,10 @@ static void status_codes_from_error(grpc_error *error, gpr_timespec deadline, } } -static void cancel_from_api(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, - grpc_error *due_to_error) { +void grpc_chttp2_cancel_stream(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global, + grpc_error *due_to_error) { if (!stream_global->read_closed || !stream_global->write_closed) { grpc_status_code grpc_status; grpc_chttp2_error_code http_error; @@ -1744,8 +1723,8 @@ static void cancel_stream_cb(grpc_chttp2_transport_global *transport_global, void *user_data, grpc_chttp2_stream_global *stream_global) { cancel_stream_cb_args *args = user_data; - cancel_from_api(args->exec_ctx, transport_global, stream_global, - GRPC_ERROR_REF(args->error)); + grpc_chttp2_cancel_stream(args->exec_ctx, transport_global, stream_global, + GRPC_ERROR_REF(args->error)); } static void end_all_the_calls(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.c b/src/core/ext/transport/chttp2/transport/hpack_parser.c index a40591c809..931be375d7 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_parser.c +++ b/src/core/ext/transport/chttp2/transport/hpack_parser.c @@ -78,69 +78,96 @@ typedef enum { a set of indirect jumps, and so not waste stack space. */ /* forward declarations for parsing states */ -static grpc_error *parse_begin(grpc_chttp2_hpack_parser *p, const uint8_t *cur, +static grpc_error *parse_begin(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end); -static grpc_error *parse_error(grpc_chttp2_hpack_parser *p, const uint8_t *cur, +static grpc_error *parse_error(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end, grpc_error *error); -static grpc_error *still_parse_error(grpc_chttp2_hpack_parser *p, +static grpc_error *still_parse_error(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end); -static grpc_error *parse_illegal_op(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_illegal_op(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end); -static grpc_error *parse_string_prefix(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_string_prefix(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end); -static grpc_error *parse_key_string(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_key_string(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end); static grpc_error *parse_value_string_with_indexed_key( - grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end); + grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end); static grpc_error *parse_value_string_with_literal_key( - grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end); + grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end); -static grpc_error *parse_value0(grpc_chttp2_hpack_parser *p, const uint8_t *cur, +static grpc_error *parse_value0(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end); -static grpc_error *parse_value1(grpc_chttp2_hpack_parser *p, const uint8_t *cur, +static grpc_error *parse_value1(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end); -static grpc_error *parse_value2(grpc_chttp2_hpack_parser *p, const uint8_t *cur, +static grpc_error *parse_value2(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end); -static grpc_error *parse_value3(grpc_chttp2_hpack_parser *p, const uint8_t *cur, +static grpc_error *parse_value3(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end); -static grpc_error *parse_value4(grpc_chttp2_hpack_parser *p, const uint8_t *cur, +static grpc_error *parse_value4(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end); -static grpc_error *parse_value5up(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_value5up(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end); -static grpc_error *parse_indexed_field(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_indexed_field(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end); -static grpc_error *parse_indexed_field_x(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_indexed_field_x(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end); -static grpc_error *parse_lithdr_incidx(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_lithdr_incidx(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end); -static grpc_error *parse_lithdr_incidx_x(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_lithdr_incidx_x(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end); -static grpc_error *parse_lithdr_incidx_v(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_lithdr_incidx_v(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end); -static grpc_error *parse_lithdr_notidx(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_lithdr_notidx(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end); -static grpc_error *parse_lithdr_notidx_x(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_lithdr_notidx_x(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end); -static grpc_error *parse_lithdr_notidx_v(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_lithdr_notidx_v(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end); -static grpc_error *parse_lithdr_nvridx(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_lithdr_nvridx(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end); -static grpc_error *parse_lithdr_nvridx_x(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_lithdr_nvridx_x(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end); -static grpc_error *parse_lithdr_nvridx_v(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_lithdr_nvridx_v(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end); -static grpc_error *parse_max_tbl_size(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_max_tbl_size(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end); -static grpc_error *parse_max_tbl_size_x(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_max_tbl_size_x(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end); /* we translate the first byte of a hpack field into one of these decoding @@ -639,8 +666,8 @@ static const uint8_t inverse_base64[256] = { }; /* emission helpers */ -static grpc_error *on_hdr(grpc_chttp2_hpack_parser *p, grpc_mdelem *md, - int add_to_table) { +static grpc_error *on_hdr(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_parser *p, + grpc_mdelem *md, int add_to_table) { if (add_to_table) { grpc_error *err = grpc_chttp2_hptbl_add(&p->table, md); if (err != GRPC_ERROR_NONE) return err; @@ -649,7 +676,7 @@ static grpc_error *on_hdr(grpc_chttp2_hpack_parser *p, grpc_mdelem *md, GRPC_MDELEM_UNREF(md); return GRPC_ERROR_CREATE("on_header callback not set"); } - p->on_header(p->on_header_user_data, md); + p->on_header(exec_ctx, p->on_header_user_data, md); return GRPC_ERROR_NONE; } @@ -661,78 +688,86 @@ static grpc_mdstr *take_string(grpc_chttp2_hpack_parser *p, } /* jump to the next state */ -static grpc_error *parse_next(grpc_chttp2_hpack_parser *p, const uint8_t *cur, +static grpc_error *parse_next(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { p->state = *p->next_state++; - return p->state(p, cur, end); + return p->state(exec_ctx, p, cur, end); } /* begin parsing a header: all functionality is encoded into lookup tables above */ -static grpc_error *parse_begin(grpc_chttp2_hpack_parser *p, const uint8_t *cur, +static grpc_error *parse_begin(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { if (cur == end) { p->state = parse_begin; return GRPC_ERROR_NONE; } - return first_byte_action[first_byte_lut[*cur]](p, cur, end); + return first_byte_action[first_byte_lut[*cur]](exec_ctx, p, cur, end); } /* stream dependency and prioritization data: we just skip it */ -static grpc_error *parse_stream_weight(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_stream_weight(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { if (cur == end) { p->state = parse_stream_weight; return GRPC_ERROR_NONE; } - return p->after_prioritization(p, cur + 1, end); + return p->after_prioritization(exec_ctx, p, cur + 1, end); } -static grpc_error *parse_stream_dep3(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_stream_dep3(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { if (cur == end) { p->state = parse_stream_dep3; return GRPC_ERROR_NONE; } - return parse_stream_weight(p, cur + 1, end); + return parse_stream_weight(exec_ctx, p, cur + 1, end); } -static grpc_error *parse_stream_dep2(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_stream_dep2(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { if (cur == end) { p->state = parse_stream_dep2; return GRPC_ERROR_NONE; } - return parse_stream_dep3(p, cur + 1, end); + return parse_stream_dep3(exec_ctx, p, cur + 1, end); } -static grpc_error *parse_stream_dep1(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_stream_dep1(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { if (cur == end) { p->state = parse_stream_dep1; return GRPC_ERROR_NONE; } - return parse_stream_dep2(p, cur + 1, end); + return parse_stream_dep2(exec_ctx, p, cur + 1, end); } -static grpc_error *parse_stream_dep0(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_stream_dep0(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { if (cur == end) { p->state = parse_stream_dep0; return GRPC_ERROR_NONE; } - return parse_stream_dep1(p, cur + 1, end); + return parse_stream_dep1(exec_ctx, p, cur + 1, end); } /* emit an indexed field; for now just logs it to console; jumps to begin the next field on completion */ -static grpc_error *finish_indexed_field(grpc_chttp2_hpack_parser *p, +static grpc_error *finish_indexed_field(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index); @@ -743,21 +778,23 @@ static grpc_error *finish_indexed_field(grpc_chttp2_hpack_parser *p, GRPC_ERROR_INT_SIZE, (intptr_t)p->table.num_ents); } GRPC_MDELEM_REF(md); - grpc_error *err = on_hdr(p, md, 0); + grpc_error *err = on_hdr(exec_ctx, p, md, 0); if (err != GRPC_ERROR_NONE) return err; - return parse_begin(p, cur, end); + return parse_begin(exec_ctx, p, cur, end); } /* parse an indexed field with index < 127 */ -static grpc_error *parse_indexed_field(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_indexed_field(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { p->dynamic_table_update_allowed = 0; p->index = (*cur) & 0x7f; - return finish_indexed_field(p, cur + 1, end); + return finish_indexed_field(exec_ctx, p, cur + 1, end); } /* parse an indexed field with index >= 127 */ -static grpc_error *parse_indexed_field_x(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_indexed_field_x(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { static const grpc_chttp2_hpack_parser_state and_then[] = { @@ -766,49 +803,53 @@ static grpc_error *parse_indexed_field_x(grpc_chttp2_hpack_parser *p, p->next_state = and_then; p->index = 0x7f; p->parsing.value = &p->index; - return parse_value0(p, cur + 1, end); + return parse_value0(exec_ctx, p, cur + 1, end); } /* finish a literal header with incremental indexing: just log, and jump to ' begin */ -static grpc_error *finish_lithdr_incidx(grpc_chttp2_hpack_parser *p, +static grpc_error *finish_lithdr_incidx(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index); GPR_ASSERT(md != NULL); /* handled in string parsing */ - grpc_error *err = - on_hdr(p, grpc_mdelem_from_metadata_strings(GRPC_MDSTR_REF(md->key), - take_string(p, &p->value)), - 1); - if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err); - return parse_begin(p, cur, end); + grpc_error *err = on_hdr( + exec_ctx, p, grpc_mdelem_from_metadata_strings(GRPC_MDSTR_REF(md->key), + take_string(p, &p->value)), + 1); + if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err); + return parse_begin(exec_ctx, p, cur, end); } /* finish a literal header with incremental indexing with no index */ -static grpc_error *finish_lithdr_incidx_v(grpc_chttp2_hpack_parser *p, +static grpc_error *finish_lithdr_incidx_v(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { - grpc_error *err = - on_hdr(p, grpc_mdelem_from_metadata_strings(take_string(p, &p->key), - take_string(p, &p->value)), - 1); - if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err); - return parse_begin(p, cur, end); + grpc_error *err = on_hdr( + exec_ctx, p, grpc_mdelem_from_metadata_strings(take_string(p, &p->key), + take_string(p, &p->value)), + 1); + if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err); + return parse_begin(exec_ctx, p, cur, end); } /* parse a literal header with incremental indexing; index < 63 */ -static grpc_error *parse_lithdr_incidx(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_lithdr_incidx(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { static const grpc_chttp2_hpack_parser_state and_then[] = { parse_value_string_with_indexed_key, finish_lithdr_incidx}; p->dynamic_table_update_allowed = 0; p->next_state = and_then; p->index = (*cur) & 0x3f; - return parse_string_prefix(p, cur + 1, end); + return parse_string_prefix(exec_ctx, p, cur + 1, end); } /* parse a literal header with incremental indexing; index >= 63 */ -static grpc_error *parse_lithdr_incidx_x(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_lithdr_incidx_x(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { static const grpc_chttp2_hpack_parser_state and_then[] = { @@ -818,11 +859,12 @@ static grpc_error *parse_lithdr_incidx_x(grpc_chttp2_hpack_parser *p, p->next_state = and_then; p->index = 0x3f; p->parsing.value = &p->index; - return parse_value0(p, cur + 1, end); + return parse_value0(exec_ctx, p, cur + 1, end); } /* parse a literal header with incremental indexing; index = 0 */ -static grpc_error *parse_lithdr_incidx_v(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_lithdr_incidx_v(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { static const grpc_chttp2_hpack_parser_state and_then[] = { @@ -830,48 +872,52 @@ static grpc_error *parse_lithdr_incidx_v(grpc_chttp2_hpack_parser *p, parse_value_string_with_literal_key, finish_lithdr_incidx_v}; p->dynamic_table_update_allowed = 0; p->next_state = and_then; - return parse_string_prefix(p, cur + 1, end); + return parse_string_prefix(exec_ctx, p, cur + 1, end); } /* finish a literal header without incremental indexing */ -static grpc_error *finish_lithdr_notidx(grpc_chttp2_hpack_parser *p, +static grpc_error *finish_lithdr_notidx(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index); GPR_ASSERT(md != NULL); /* handled in string parsing */ - grpc_error *err = - on_hdr(p, grpc_mdelem_from_metadata_strings(GRPC_MDSTR_REF(md->key), - take_string(p, &p->value)), - 0); - if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err); - return parse_begin(p, cur, end); + grpc_error *err = on_hdr( + exec_ctx, p, grpc_mdelem_from_metadata_strings(GRPC_MDSTR_REF(md->key), + take_string(p, &p->value)), + 0); + if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err); + return parse_begin(exec_ctx, p, cur, end); } /* finish a literal header without incremental indexing with index = 0 */ -static grpc_error *finish_lithdr_notidx_v(grpc_chttp2_hpack_parser *p, +static grpc_error *finish_lithdr_notidx_v(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { - grpc_error *err = - on_hdr(p, grpc_mdelem_from_metadata_strings(take_string(p, &p->key), - take_string(p, &p->value)), - 0); - if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err); - return parse_begin(p, cur, end); + grpc_error *err = on_hdr( + exec_ctx, p, grpc_mdelem_from_metadata_strings(take_string(p, &p->key), + take_string(p, &p->value)), + 0); + if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err); + return parse_begin(exec_ctx, p, cur, end); } /* parse a literal header without incremental indexing; index < 15 */ -static grpc_error *parse_lithdr_notidx(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_lithdr_notidx(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { static const grpc_chttp2_hpack_parser_state and_then[] = { parse_value_string_with_indexed_key, finish_lithdr_notidx}; p->dynamic_table_update_allowed = 0; p->next_state = and_then; p->index = (*cur) & 0xf; - return parse_string_prefix(p, cur + 1, end); + return parse_string_prefix(exec_ctx, p, cur + 1, end); } /* parse a literal header without incremental indexing; index >= 15 */ -static grpc_error *parse_lithdr_notidx_x(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_lithdr_notidx_x(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { static const grpc_chttp2_hpack_parser_state and_then[] = { @@ -881,11 +927,12 @@ static grpc_error *parse_lithdr_notidx_x(grpc_chttp2_hpack_parser *p, p->next_state = and_then; p->index = 0xf; p->parsing.value = &p->index; - return parse_value0(p, cur + 1, end); + return parse_value0(exec_ctx, p, cur + 1, end); } /* parse a literal header without incremental indexing; index == 0 */ -static grpc_error *parse_lithdr_notidx_v(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_lithdr_notidx_v(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { static const grpc_chttp2_hpack_parser_state and_then[] = { @@ -893,48 +940,52 @@ static grpc_error *parse_lithdr_notidx_v(grpc_chttp2_hpack_parser *p, parse_value_string_with_literal_key, finish_lithdr_notidx_v}; p->dynamic_table_update_allowed = 0; p->next_state = and_then; - return parse_string_prefix(p, cur + 1, end); + return parse_string_prefix(exec_ctx, p, cur + 1, end); } /* finish a literal header that is never indexed */ -static grpc_error *finish_lithdr_nvridx(grpc_chttp2_hpack_parser *p, +static grpc_error *finish_lithdr_nvridx(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index); GPR_ASSERT(md != NULL); /* handled in string parsing */ - grpc_error *err = - on_hdr(p, grpc_mdelem_from_metadata_strings(GRPC_MDSTR_REF(md->key), - take_string(p, &p->value)), - 0); - if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err); - return parse_begin(p, cur, end); + grpc_error *err = on_hdr( + exec_ctx, p, grpc_mdelem_from_metadata_strings(GRPC_MDSTR_REF(md->key), + take_string(p, &p->value)), + 0); + if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err); + return parse_begin(exec_ctx, p, cur, end); } /* finish a literal header that is never indexed with an extra value */ -static grpc_error *finish_lithdr_nvridx_v(grpc_chttp2_hpack_parser *p, +static grpc_error *finish_lithdr_nvridx_v(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { - grpc_error *err = - on_hdr(p, grpc_mdelem_from_metadata_strings(take_string(p, &p->key), - take_string(p, &p->value)), - 0); - if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err); - return parse_begin(p, cur, end); + grpc_error *err = on_hdr( + exec_ctx, p, grpc_mdelem_from_metadata_strings(take_string(p, &p->key), + take_string(p, &p->value)), + 0); + if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err); + return parse_begin(exec_ctx, p, cur, end); } /* parse a literal header that is never indexed; index < 15 */ -static grpc_error *parse_lithdr_nvridx(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_lithdr_nvridx(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { static const grpc_chttp2_hpack_parser_state and_then[] = { parse_value_string_with_indexed_key, finish_lithdr_nvridx}; p->dynamic_table_update_allowed = 0; p->next_state = and_then; p->index = (*cur) & 0xf; - return parse_string_prefix(p, cur + 1, end); + return parse_string_prefix(exec_ctx, p, cur + 1, end); } /* parse a literal header that is never indexed; index >= 15 */ -static grpc_error *parse_lithdr_nvridx_x(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_lithdr_nvridx_x(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { static const grpc_chttp2_hpack_parser_state and_then[] = { @@ -944,11 +995,12 @@ static grpc_error *parse_lithdr_nvridx_x(grpc_chttp2_hpack_parser *p, p->next_state = and_then; p->index = 0xf; p->parsing.value = &p->index; - return parse_value0(p, cur + 1, end); + return parse_value0(exec_ctx, p, cur + 1, end); } /* parse a literal header that is never indexed; index == 0 */ -static grpc_error *parse_lithdr_nvridx_v(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_lithdr_nvridx_v(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { static const grpc_chttp2_hpack_parser_state and_then[] = { @@ -956,44 +1008,47 @@ static grpc_error *parse_lithdr_nvridx_v(grpc_chttp2_hpack_parser *p, parse_value_string_with_literal_key, finish_lithdr_nvridx_v}; p->dynamic_table_update_allowed = 0; p->next_state = and_then; - return parse_string_prefix(p, cur + 1, end); + return parse_string_prefix(exec_ctx, p, cur + 1, end); } /* finish parsing a max table size change */ -static grpc_error *finish_max_tbl_size(grpc_chttp2_hpack_parser *p, +static grpc_error *finish_max_tbl_size(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { if (grpc_http_trace) { gpr_log(GPR_INFO, "MAX TABLE SIZE: %d", p->index); } grpc_error *err = grpc_chttp2_hptbl_set_current_table_size(&p->table, p->index); - if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err); - return parse_begin(p, cur, end); + if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err); + return parse_begin(exec_ctx, p, cur, end); } /* parse a max table size change, max size < 15 */ -static grpc_error *parse_max_tbl_size(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_max_tbl_size(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { if (p->dynamic_table_update_allowed == 0) { return parse_error( - p, cur, end, + exec_ctx, p, cur, end, GRPC_ERROR_CREATE( "More than two max table size changes in a single frame")); } p->dynamic_table_update_allowed--; p->index = (*cur) & 0x1f; - return finish_max_tbl_size(p, cur + 1, end); + return finish_max_tbl_size(exec_ctx, p, cur + 1, end); } /* parse a max table size change, max size >= 15 */ -static grpc_error *parse_max_tbl_size_x(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_max_tbl_size_x(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { static const grpc_chttp2_hpack_parser_state and_then[] = { finish_max_tbl_size}; if (p->dynamic_table_update_allowed == 0) { return parse_error( - p, cur, end, + exec_ctx, p, cur, end, GRPC_ERROR_CREATE( "More than two max table size changes in a single frame")); } @@ -1001,11 +1056,12 @@ static grpc_error *parse_max_tbl_size_x(grpc_chttp2_hpack_parser *p, p->next_state = and_then; p->index = 0x1f; p->parsing.value = &p->index; - return parse_value0(p, cur + 1, end); + return parse_value0(exec_ctx, p, cur + 1, end); } /* a parse error: jam the parse state into parse_error, and return error */ -static grpc_error *parse_error(grpc_chttp2_hpack_parser *p, const uint8_t *cur, +static grpc_error *parse_error(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end, grpc_error *err) { GPR_ASSERT(err != GRPC_ERROR_NONE); if (p->last_error == GRPC_ERROR_NONE) { @@ -1015,24 +1071,27 @@ static grpc_error *parse_error(grpc_chttp2_hpack_parser *p, const uint8_t *cur, return err; } -static grpc_error *still_parse_error(grpc_chttp2_hpack_parser *p, +static grpc_error *still_parse_error(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { return GRPC_ERROR_REF(p->last_error); } -static grpc_error *parse_illegal_op(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_illegal_op(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { GPR_ASSERT(cur != end); char *msg; gpr_asprintf(&msg, "Illegal hpack op code %d", *cur); grpc_error *err = GRPC_ERROR_CREATE(msg); gpr_free(msg); - return parse_error(p, cur, end, err); + return parse_error(exec_ctx, p, cur, end, err); } /* parse the 1st byte of a varint into p->parsing.value no overflow is possible */ -static grpc_error *parse_value0(grpc_chttp2_hpack_parser *p, const uint8_t *cur, +static grpc_error *parse_value0(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { if (cur == end) { p->state = parse_value0; @@ -1042,15 +1101,16 @@ static grpc_error *parse_value0(grpc_chttp2_hpack_parser *p, const uint8_t *cur, *p->parsing.value += (*cur) & 0x7f; if ((*cur) & 0x80) { - return parse_value1(p, cur + 1, end); + return parse_value1(exec_ctx, p, cur + 1, end); } else { - return parse_next(p, cur + 1, end); + return parse_next(exec_ctx, p, cur + 1, end); } } /* parse the 2nd byte of a varint into p->parsing.value no overflow is possible */ -static grpc_error *parse_value1(grpc_chttp2_hpack_parser *p, const uint8_t *cur, +static grpc_error *parse_value1(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { if (cur == end) { p->state = parse_value1; @@ -1060,15 +1120,16 @@ static grpc_error *parse_value1(grpc_chttp2_hpack_parser *p, const uint8_t *cur, *p->parsing.value += (((uint32_t)*cur) & 0x7f) << 7; if ((*cur) & 0x80) { - return parse_value2(p, cur + 1, end); + return parse_value2(exec_ctx, p, cur + 1, end); } else { - return parse_next(p, cur + 1, end); + return parse_next(exec_ctx, p, cur + 1, end); } } /* parse the 3rd byte of a varint into p->parsing.value no overflow is possible */ -static grpc_error *parse_value2(grpc_chttp2_hpack_parser *p, const uint8_t *cur, +static grpc_error *parse_value2(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { if (cur == end) { p->state = parse_value2; @@ -1078,15 +1139,16 @@ static grpc_error *parse_value2(grpc_chttp2_hpack_parser *p, const uint8_t *cur, *p->parsing.value += (((uint32_t)*cur) & 0x7f) << 14; if ((*cur) & 0x80) { - return parse_value3(p, cur + 1, end); + return parse_value3(exec_ctx, p, cur + 1, end); } else { - return parse_next(p, cur + 1, end); + return parse_next(exec_ctx, p, cur + 1, end); } } /* parse the 4th byte of a varint into p->parsing.value no overflow is possible */ -static grpc_error *parse_value3(grpc_chttp2_hpack_parser *p, const uint8_t *cur, +static grpc_error *parse_value3(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { if (cur == end) { p->state = parse_value3; @@ -1096,15 +1158,16 @@ static grpc_error *parse_value3(grpc_chttp2_hpack_parser *p, const uint8_t *cur, *p->parsing.value += (((uint32_t)*cur) & 0x7f) << 21; if ((*cur) & 0x80) { - return parse_value4(p, cur + 1, end); + return parse_value4(exec_ctx, p, cur + 1, end); } else { - return parse_next(p, cur + 1, end); + return parse_next(exec_ctx, p, cur + 1, end); } } /* parse the 5th byte of a varint into p->parsing.value depending on the byte, we may overflow, and care must be taken */ -static grpc_error *parse_value4(grpc_chttp2_hpack_parser *p, const uint8_t *cur, +static grpc_error *parse_value4(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { uint8_t c; uint32_t cur_value; @@ -1130,9 +1193,9 @@ static grpc_error *parse_value4(grpc_chttp2_hpack_parser *p, const uint8_t *cur, *p->parsing.value = cur_value + add_value; if ((*cur) & 0x80) { - return parse_value5up(p, cur + 1, end); + return parse_value5up(exec_ctx, p, cur + 1, end); } else { - return parse_next(p, cur + 1, end); + return parse_next(exec_ctx, p, cur + 1, end); } error: @@ -1142,13 +1205,14 @@ error: *p->parsing.value, *cur); grpc_error *err = GRPC_ERROR_CREATE(msg); gpr_free(msg); - return parse_error(p, cur, end, err); + return parse_error(exec_ctx, p, cur, end, err); } /* parse any trailing bytes in a varint: it's possible to append an arbitrary number of 0x80's and not affect the value - a zero will terminate - and anything else will overflow */ -static grpc_error *parse_value5up(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_value5up(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { while (cur != end && *cur == 0x80) { ++cur; @@ -1160,7 +1224,7 @@ static grpc_error *parse_value5up(grpc_chttp2_hpack_parser *p, } if (*cur == 0) { - return parse_next(p, cur + 1, end); + return parse_next(exec_ctx, p, cur + 1, end); } char *msg; @@ -1170,11 +1234,12 @@ static grpc_error *parse_value5up(grpc_chttp2_hpack_parser *p, *p->parsing.value, *cur); grpc_error *err = GRPC_ERROR_CREATE(msg); gpr_free(msg); - return parse_error(p, cur, end, err); + return parse_error(exec_ctx, p, cur, end, err); } /* parse a string prefix */ -static grpc_error *parse_string_prefix(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_string_prefix(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { if (cur == end) { p->state = parse_string_prefix; @@ -1185,9 +1250,9 @@ static grpc_error *parse_string_prefix(grpc_chttp2_hpack_parser *p, p->huff = (*cur) >> 7; if (p->strlen == 0x7f) { p->parsing.value = &p->strlen; - return parse_value0(p, cur + 1, end); + return parse_value0(exec_ctx, p, cur + 1, end); } else { - return parse_next(p, cur + 1, end); + return parse_next(exec_ctx, p, cur + 1, end); } } @@ -1205,7 +1270,8 @@ static void append_bytes(grpc_chttp2_hpack_parser_string *str, str->length += (uint32_t)length; } -static grpc_error *append_string(grpc_chttp2_hpack_parser *p, +static grpc_error *append_string(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { grpc_chttp2_hpack_parser_string *str = p->parsing.str; uint32_t bits; @@ -1223,7 +1289,7 @@ static grpc_error *append_string(grpc_chttp2_hpack_parser *p, bits = inverse_base64[*cur]; ++cur; if (bits == 255) - return parse_error(p, cur, end, + return parse_error(exec_ctx, p, cur, end, GRPC_ERROR_CREATE("Illegal base64 character")); else if (bits == 64) goto b64_byte0; @@ -1238,7 +1304,7 @@ static grpc_error *append_string(grpc_chttp2_hpack_parser *p, bits = inverse_base64[*cur]; ++cur; if (bits == 255) - return parse_error(p, cur, end, + return parse_error(exec_ctx, p, cur, end, GRPC_ERROR_CREATE("Illegal base64 character")); else if (bits == 64) goto b64_byte1; @@ -1253,7 +1319,7 @@ static grpc_error *append_string(grpc_chttp2_hpack_parser *p, bits = inverse_base64[*cur]; ++cur; if (bits == 255) - return parse_error(p, cur, end, + return parse_error(exec_ctx, p, cur, end, GRPC_ERROR_CREATE("Illegal base64 character")); else if (bits == 64) goto b64_byte2; @@ -1268,7 +1334,7 @@ static grpc_error *append_string(grpc_chttp2_hpack_parser *p, bits = inverse_base64[*cur]; ++cur; if (bits == 255) - return parse_error(p, cur, end, + return parse_error(exec_ctx, p, cur, end, GRPC_ERROR_CREATE("Illegal base64 character")); else if (bits == 64) goto b64_byte3; @@ -1281,11 +1347,12 @@ static grpc_error *append_string(grpc_chttp2_hpack_parser *p, goto b64_byte0; } GPR_UNREACHABLE_CODE(return parse_error( - p, cur, end, GRPC_ERROR_CREATE("Should never reach here"))); + exec_ctx, p, cur, end, GRPC_ERROR_CREATE("Should never reach here"))); } /* append a null terminator to a string */ -static grpc_error *finish_str(grpc_chttp2_hpack_parser *p, const uint8_t *cur, +static grpc_error *finish_str(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { uint8_t terminator = 0; uint8_t decoded[2]; @@ -1298,7 +1365,7 @@ static grpc_error *finish_str(grpc_chttp2_hpack_parser *p, const uint8_t *cur, break; case B64_BYTE1: return parse_error( - p, cur, end, + exec_ctx, p, cur, end, GRPC_ERROR_CREATE("illegal base64 encoding")); /* illegal encoding */ case B64_BYTE2: bits = p->base64_buffer; @@ -1308,7 +1375,7 @@ static grpc_error *finish_str(grpc_chttp2_hpack_parser *p, const uint8_t *cur, bits & 0xffff); grpc_error *err = GRPC_ERROR_CREATE(msg); gpr_free(msg); - return parse_error(p, cur, end, err); + return parse_error(exec_ctx, p, cur, end, err); } decoded[0] = (uint8_t)(bits >> 16); append_bytes(str, decoded, 1); @@ -1321,7 +1388,7 @@ static grpc_error *finish_str(grpc_chttp2_hpack_parser *p, const uint8_t *cur, bits & 0xff); grpc_error *err = GRPC_ERROR_CREATE(msg); gpr_free(msg); - return parse_error(p, cur, end, err); + return parse_error(exec_ctx, p, cur, end, err); } decoded[0] = (uint8_t)(bits >> 16); decoded[1] = (uint8_t)(bits >> 8); @@ -1334,13 +1401,14 @@ static grpc_error *finish_str(grpc_chttp2_hpack_parser *p, const uint8_t *cur, } /* decode a nibble from a huffman encoded stream */ -static grpc_error *huff_nibble(grpc_chttp2_hpack_parser *p, uint8_t nibble) { +static grpc_error *huff_nibble(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, uint8_t nibble) { int16_t emit = emit_sub_tbl[16 * emit_tbl[p->huff_state] + nibble]; int16_t next = next_sub_tbl[16 * next_tbl[p->huff_state] + nibble]; if (emit != -1) { if (emit >= 0 && emit < 256) { uint8_t c = (uint8_t)emit; - grpc_error *err = append_string(p, &c, (&c) + 1); + grpc_error *err = append_string(exec_ctx, p, &c, (&c) + 1); if (err != GRPC_ERROR_NONE) return err; } else { assert(emit == 256); @@ -1351,42 +1419,45 @@ static grpc_error *huff_nibble(grpc_chttp2_hpack_parser *p, uint8_t nibble) { } /* decode full bytes from a huffman encoded stream */ -static grpc_error *add_huff_bytes(grpc_chttp2_hpack_parser *p, +static grpc_error *add_huff_bytes(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { for (; cur != end; ++cur) { - grpc_error *err = huff_nibble(p, *cur >> 4); - if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err); - err = huff_nibble(p, *cur & 0xf); - if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err); + grpc_error *err = huff_nibble(exec_ctx, p, *cur >> 4); + if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err); + err = huff_nibble(exec_ctx, p, *cur & 0xf); + if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err); } return GRPC_ERROR_NONE; } /* decode some string bytes based on the current decoding mode (huffman or not) */ -static grpc_error *add_str_bytes(grpc_chttp2_hpack_parser *p, +static grpc_error *add_str_bytes(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { if (p->huff) { - return add_huff_bytes(p, cur, end); + return add_huff_bytes(exec_ctx, p, cur, end); } else { - return append_string(p, cur, end); + return append_string(exec_ctx, p, cur, end); } } /* parse a string - tries to do large chunks at a time */ -static grpc_error *parse_string(grpc_chttp2_hpack_parser *p, const uint8_t *cur, +static grpc_error *parse_string(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { size_t remaining = p->strlen - p->strgot; size_t given = (size_t)(end - cur); if (remaining <= given) { - grpc_error *err = add_str_bytes(p, cur, cur + remaining); - if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err); - err = finish_str(p, cur + remaining, end); - if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err); - return parse_next(p, cur + remaining, end); + grpc_error *err = add_str_bytes(exec_ctx, p, cur, cur + remaining); + if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err); + err = finish_str(exec_ctx, p, cur + remaining, end); + if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err); + return parse_next(exec_ctx, p, cur + remaining, end); } else { - grpc_error *err = add_str_bytes(p, cur, cur + given); - if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err); + grpc_error *err = add_str_bytes(exec_ctx, p, cur, cur + given); + if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err); GPR_ASSERT(given <= UINT32_MAX - p->strgot); p->strgot += (uint32_t)given; p->state = parse_string; @@ -1395,7 +1466,8 @@ static grpc_error *parse_string(grpc_chttp2_hpack_parser *p, const uint8_t *cur, } /* begin parsing a string - performs setup, calls parse_string */ -static grpc_error *begin_parse_string(grpc_chttp2_hpack_parser *p, +static grpc_error *begin_parse_string(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end, uint8_t binary, grpc_chttp2_hpack_parser_string *str) { @@ -1404,13 +1476,14 @@ static grpc_error *begin_parse_string(grpc_chttp2_hpack_parser *p, p->parsing.str = str; p->huff_state = 0; p->binary = binary; - return parse_string(p, cur, end); + return parse_string(exec_ctx, p, cur, end); } /* parse the key string */ -static grpc_error *parse_key_string(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_key_string(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { - return begin_parse_string(p, cur, end, NOT_BINARY, &p->key); + return begin_parse_string(exec_ctx, p, cur, end, NOT_BINARY, &p->key); } /* check if a key represents a binary header or not */ @@ -1435,24 +1508,27 @@ static grpc_error *is_binary_indexed_header(grpc_chttp2_hpack_parser *p, } /* parse the value string */ -static grpc_error *parse_value_string(grpc_chttp2_hpack_parser *p, +static grpc_error *parse_value_string(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end, bool is_binary) { - return begin_parse_string(p, cur, end, is_binary ? B64_BYTE0 : NOT_BINARY, - &p->value); + return begin_parse_string(exec_ctx, p, cur, end, + is_binary ? B64_BYTE0 : NOT_BINARY, &p->value); } static grpc_error *parse_value_string_with_indexed_key( - grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { + grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end) { bool is_binary = false; grpc_error *err = is_binary_indexed_header(p, &is_binary); - if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err); - return parse_value_string(p, cur, end, is_binary); + if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err); + return parse_value_string(exec_ctx, p, cur, end, is_binary); } static grpc_error *parse_value_string_with_literal_key( - grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { - return parse_value_string(p, cur, end, is_binary_literal_header(p)); + grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end) { + return parse_value_string(exec_ctx, p, cur, end, is_binary_literal_header(p)); } /* PUBLIC INTERFACE */ @@ -1484,14 +1560,15 @@ void grpc_chttp2_hpack_parser_destroy(grpc_chttp2_hpack_parser *p) { gpr_free(p->value.str); } -grpc_error *grpc_chttp2_hpack_parser_parse(grpc_chttp2_hpack_parser *p, +grpc_error *grpc_chttp2_hpack_parser_parse(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *beg, const uint8_t *end) { /* TODO(ctiller): limit the distance of end from beg, and perform multiple steps in the event of a large chunk of data to limit stack space usage when no tail call optimization is available */ - return p->state(p, beg, end); + return p->state(exec_ctx, p, beg, end); } grpc_error *grpc_chttp2_header_parser_parse( @@ -1504,7 +1581,7 @@ grpc_error *grpc_chttp2_header_parser_parse( stream_global->stats.incoming.header_bytes += GPR_SLICE_LENGTH(slice); } grpc_error *error = grpc_chttp2_hpack_parser_parse( - parser, GPR_SLICE_START_PTR(slice), GPR_SLICE_END_PTR(slice)); + exec_ctx, parser, GPR_SLICE_START_PTR(slice), GPR_SLICE_END_PTR(slice)); if (error != GRPC_ERROR_NONE) { GPR_TIMER_END("grpc_chttp2_hpack_parser_parse", 0); return error; diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.h b/src/core/ext/transport/chttp2/transport/hpack_parser.h index cbcf12ffed..314bd55965 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_parser.h +++ b/src/core/ext/transport/chttp2/transport/hpack_parser.h @@ -45,7 +45,8 @@ typedef struct grpc_chttp2_hpack_parser grpc_chttp2_hpack_parser; typedef grpc_error *(*grpc_chttp2_hpack_parser_state)( - grpc_chttp2_hpack_parser *p, const uint8_t *beg, const uint8_t *end); + grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_parser *p, const uint8_t *beg, + const uint8_t *end); typedef struct { char *str; @@ -55,7 +56,7 @@ typedef struct { struct grpc_chttp2_hpack_parser { /* user specified callback for each header output */ - void (*on_header)(void *user_data, grpc_mdelem *md); + void (*on_header)(grpc_exec_ctx *exec_ctx, void *user_data, grpc_mdelem *md); void *on_header_user_data; grpc_error *last_error; @@ -104,7 +105,8 @@ void grpc_chttp2_hpack_parser_destroy(grpc_chttp2_hpack_parser *p); void grpc_chttp2_hpack_parser_set_has_priority(grpc_chttp2_hpack_parser *p); /* returns 1 on success, 0 on error */ -grpc_error *grpc_chttp2_hpack_parser_parse(grpc_chttp2_hpack_parser *p, +grpc_error *grpc_chttp2_hpack_parser_parse(grpc_exec_ctx *exec_ctx, + grpc_chttp2_hpack_parser *p, const uint8_t *beg, const uint8_t *end); diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index c487835a9f..8542b8aff5 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -410,7 +410,6 @@ struct grpc_chttp2_stream_global { /** Has this stream seen an error. If true, then pending incoming frames can be thrown away. */ bool seen_error; - bool exceeded_metadata_size; /** the error that resulted in this stream being read-closed */ grpc_error *read_closed_error; @@ -762,4 +761,9 @@ void grpc_chttp2_become_writable(grpc_exec_ctx *exec_ctx, grpc_chttp2_stream_global *stream_global, bool covered_by_poller, const char *reason); +void grpc_chttp2_cancel_stream(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global, + grpc_error *due_to_error); + #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_INTERNAL_H */ diff --git a/src/core/ext/transport/chttp2/transport/parsing.c b/src/core/ext/transport/chttp2/transport/parsing.c index 4d9e25d985..983382ceef 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.c +++ b/src/core/ext/transport/chttp2/transport/parsing.c @@ -354,7 +354,9 @@ static grpc_error *skip_parser(grpc_exec_ctx *exec_ctx, void *parser, return GRPC_ERROR_NONE; } -static void skip_header(void *tp, grpc_mdelem *md) { GRPC_MDELEM_UNREF(md); } +static void skip_header(grpc_exec_ctx *exec_ctx, void *tp, grpc_mdelem *md) { + GRPC_MDELEM_UNREF(md); +} static grpc_error *init_skip_frame_parser( grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, @@ -458,7 +460,8 @@ static grpc_error *init_data_frame_parser( static void free_timeout(void *p) { gpr_free(p); } -static void on_initial_header(void *tp, grpc_mdelem *md) { +static void on_initial_header(grpc_exec_ctx *exec_ctx, void *tp, + grpc_mdelem *md) { grpc_chttp2_transport_global *transport_global = tp; grpc_chttp2_stream_global *stream_global = transport_global->incoming_stream; @@ -500,14 +503,17 @@ static void on_initial_header(void *tp, grpc_mdelem *md) { transport_global->settings[GRPC_ACKED_SETTINGS] [GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE]; if (new_size > metadata_size_limit) { - if (!stream_global->exceeded_metadata_size) { - gpr_log(GPR_DEBUG, - "received initial metadata size exceeds limit (%" PRIuPTR - " vs. %" PRIuPTR ")", - new_size, metadata_size_limit); - stream_global->seen_error = true; - stream_global->exceeded_metadata_size = true; - } + gpr_log(GPR_DEBUG, + "received initial metadata size exceeds limit (%" PRIuPTR + " vs. %" PRIuPTR ")", + new_size, metadata_size_limit); + grpc_chttp2_cancel_stream( + exec_ctx, transport_global, stream_global, + grpc_error_set_int( + GRPC_ERROR_CREATE("received initial metadata size exceeds limit"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED)); + grpc_chttp2_parsing_become_skip_parser(exec_ctx, transport_global); + stream_global->seen_error = true; GRPC_MDELEM_UNREF(md); } else { grpc_chttp2_incoming_metadata_buffer_add( @@ -518,7 +524,8 @@ static void on_initial_header(void *tp, grpc_mdelem *md) { GPR_TIMER_END("on_initial_header", 0); } -static void on_trailing_header(void *tp, grpc_mdelem *md) { +static void on_trailing_header(grpc_exec_ctx *exec_ctx, void *tp, + grpc_mdelem *md) { grpc_chttp2_transport_global *transport_global = tp; grpc_chttp2_stream_global *stream_global = transport_global->incoming_stream; @@ -542,14 +549,17 @@ static void on_trailing_header(void *tp, grpc_mdelem *md) { transport_global->settings[GRPC_ACKED_SETTINGS] [GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE]; if (new_size > metadata_size_limit) { - if (!stream_global->exceeded_metadata_size) { - gpr_log(GPR_DEBUG, - "received trailing metadata size exceeds limit (%" PRIuPTR - " vs. %" PRIuPTR ")", - new_size, metadata_size_limit); - stream_global->seen_error = true; - stream_global->exceeded_metadata_size = true; - } + gpr_log(GPR_DEBUG, + "received trailing metadata size exceeds limit (%" PRIuPTR + " vs. %" PRIuPTR ")", + new_size, metadata_size_limit); + grpc_chttp2_cancel_stream( + exec_ctx, transport_global, stream_global, + grpc_error_set_int( + GRPC_ERROR_CREATE("received trailing metadata size exceeds limit"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED)); + grpc_chttp2_parsing_become_skip_parser(exec_ctx, transport_global); + stream_global->seen_error = true; GRPC_MDELEM_UNREF(md); } else { grpc_chttp2_incoming_metadata_buffer_add(&stream_global->metadata_buffer[1], diff --git a/test/core/transport/chttp2/hpack_parser_fuzzer_test.c b/test/core/transport/chttp2/hpack_parser_fuzzer_test.c index b7f68e0dd4..95acbf1a68 100644 --- a/test/core/transport/chttp2/hpack_parser_fuzzer_test.c +++ b/test/core/transport/chttp2/hpack_parser_fuzzer_test.c @@ -43,7 +43,9 @@ bool squelch = true; bool leak_check = true; -static void onhdr(void *ud, grpc_mdelem *md) { GRPC_MDELEM_UNREF(md); } +static void onhdr(grpc_exec_ctx *exec_ctx, void *ud, grpc_mdelem *md) { + GRPC_MDELEM_UNREF(md); +} static void dont_log(gpr_log_func_args *args) {} int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { @@ -53,7 +55,10 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { grpc_chttp2_hpack_parser parser; grpc_chttp2_hpack_parser_init(&parser); parser.on_header = onhdr; - GRPC_ERROR_UNREF(grpc_chttp2_hpack_parser_parse(&parser, data, data + size)); + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + GRPC_ERROR_UNREF( + grpc_chttp2_hpack_parser_parse(&exec_ctx, &parser, data, data + size)); + grpc_exec_ctx_finish(&exec_ctx); grpc_chttp2_hpack_parser_destroy(&parser); grpc_shutdown(); return 0; diff --git a/test/core/transport/chttp2/hpack_parser_test.c b/test/core/transport/chttp2/hpack_parser_test.c index 9ddceb8981..55b64f5d99 100644 --- a/test/core/transport/chttp2/hpack_parser_test.c +++ b/test/core/transport/chttp2/hpack_parser_test.c @@ -45,7 +45,7 @@ typedef struct { va_list args; } test_checker; -static void onhdr(void *ud, grpc_mdelem *md) { +static void onhdr(grpc_exec_ctx *exec_ctx, void *ud, grpc_mdelem *md) { const char *ekey, *evalue; test_checker *chk = ud; ekey = va_arg(chk->args, char *); @@ -75,9 +75,11 @@ static void test_vector(grpc_chttp2_hpack_parser *parser, gpr_slice_unref(input); for (i = 0; i < nslices; i++) { + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; GPR_ASSERT(grpc_chttp2_hpack_parser_parse( - parser, GPR_SLICE_START_PTR(slices[i]), + &exec_ctx, parser, GPR_SLICE_START_PTR(slices[i]), GPR_SLICE_END_PTR(slices[i])) == GRPC_ERROR_NONE); + grpc_exec_ctx_finish(&exec_ctx); } for (i = 0; i < nslices; i++) { -- cgit v1.2.3 From d09f45c625edc33038915d2cb7cc2a8f809c9e7f Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 22 Aug 2016 09:32:46 -0700 Subject: Ensure ack is sent before relying on that --- test/core/bad_client/tests/large_metadata.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/core/bad_client/tests/large_metadata.c b/test/core/bad_client/tests/large_metadata.c index ded5f17d4a..1152e7d5c0 100644 --- a/test/core/bad_client/tests/large_metadata.c +++ b/test/core/bad_client/tests/large_metadata.c @@ -50,6 +50,7 @@ "\x00\x00\x00\x04\x00\x00\x00\x00\x00" /* headers: generated from \ large_metadata.headers in this \ directory */ \ + "\x00\x00\x00\x04\x01\x00\x00\x00\x00" \ "\x00" \ "5{\x01\x05\x00\x00\x00\x01" \ "\x10\x05:path\x08/foo/bar" \ @@ -92,6 +93,7 @@ in this \ directory \ */ \ + "\x00\x00\x00\x04\x01\x00\x00\x00\x00" \ "\x00\x00\xc9\x01\x04\x00\x00\x00\x01" \ "\x10\x05:path\x08/foo/bar" \ "\x10\x07:scheme\x04http" \ -- cgit v1.2.3 From b2176fcadc7a01e09ff1a44fc23b2b236c174821 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 22 Aug 2016 11:38:30 -0700 Subject: Fix error logic mix up --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 577b8ba876..520fa57c35 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1232,8 +1232,8 @@ static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx, (uint32_t)grpc_chttp2_grpc_status_to_http2_error(op->goaway_status), gpr_slice_ref(*op->goaway_message), &t->global.qbuf); close_transport = grpc_chttp2_stream_map_size(&t->stream_map) == 0 - ? GRPC_ERROR_NONE - : GRPC_ERROR_CREATE("GOAWAY sent"); + ? GRPC_ERROR_CREATE("GOAWAY sent") + : GRPC_ERROR_NONE; grpc_chttp2_initiate_write(exec_ctx, &t->global, false, "goaway_sent"); } -- cgit v1.2.3 From dfd3a8f7a566aaf59b676caf583d4048b8e9ab5b Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 24 Aug 2016 09:43:45 -0700 Subject: Merge combiner and exec_ctx execution better Allows exec_ctx callbacks to be called while a combiner is executing. Also allows guaranteeing direct execution of callbacks from combiners, which should allow reducing cpu burn for up/down stack interactions in the future. --- .../transport/chttp2/transport/chttp2_transport.c | 59 +++-- src/core/ext/transport/chttp2/transport/internal.h | 19 ++ .../ext/transport/chttp2/transport/stream_lists.c | 2 + src/core/lib/iomgr/combiner.c | 278 ++++++++++----------- src/core/lib/iomgr/combiner.h | 2 + src/core/lib/iomgr/exec_ctx.c | 33 ++- src/core/lib/iomgr/exec_ctx.h | 3 +- src/core/lib/profiling/timers.h | 5 + src/core/lib/transport/transport.c | 25 ++ src/core/lib/transport/transport.h | 4 + test/core/end2end/tests/filter_causes_close.c | 7 +- 11 files changed, 243 insertions(+), 194 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 520fa57c35..19e988670c 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -179,33 +179,30 @@ static void destruct_transport(grpc_exec_ctx *exec_ctx, gpr_free(t); } -/*#define REFCOUNTING_DEBUG 1*/ -#ifdef REFCOUNTING_DEBUG -#define REF_TRANSPORT(t, r) ref_transport(t, r, __FILE__, __LINE__) -#define UNREF_TRANSPORT(cl, t, r) unref_transport(cl, t, r, __FILE__, __LINE__) -static void unref_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, - const char *reason, const char *file, int line) { - gpr_log(GPR_DEBUG, "chttp2:unref:%p %d->%d %s [%s:%d]", t, t->refs.count, - t->refs.count - 1, reason, file, line); +#ifdef GRPC_CHTTP2_REFCOUNTING_DEBUG +void grpc_chttp2_unref_transport(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, const char *reason, + const char *file, int line) { + gpr_log(GPR_DEBUG, "chttp2:unref:%p %" PRIdPTR "->%" PRIdPTR " %s [%s:%d]", t, + t->refs.count, t->refs.count - 1, reason, file, line); if (!gpr_unref(&t->refs)) return; destruct_transport(exec_ctx, t); } -static void ref_transport(grpc_chttp2_transport *t, const char *reason, - const char *file, int line) { - gpr_log(GPR_DEBUG, "chttp2: ref:%p %d->%d %s [%s:%d]", t, t->refs.count, - t->refs.count + 1, reason, file, line); +void grpc_chttp2_ref_transport(grpc_chttp2_transport *t, const char *reason, + const char *file, int line) { + gpr_log(GPR_DEBUG, "chttp2: ref:%p %" PRIdPTR "->%" PRIdPTR " %s [%s:%d]", t, + t->refs.count, t->refs.count + 1, reason, file, line); gpr_ref(&t->refs); } #else -#define REF_TRANSPORT(t, r) ref_transport(t) -#define UNREF_TRANSPORT(cl, t, r) unref_transport(cl, t) -static void unref_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t) { +void grpc_chttp2_unref_transport(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t) { if (!gpr_unref(&t->refs)) return; destruct_transport(exec_ctx, t); } -static void ref_transport(grpc_chttp2_transport *t) { gpr_ref(&t->refs); } +void grpc_chttp2_ref_transport(grpc_chttp2_transport *t) { gpr_ref(&t->refs); } #endif static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, @@ -392,7 +389,7 @@ static void destroy_transport_locked(grpc_exec_ctx *exec_ctx, void *tp, grpc_chttp2_transport *t = tp; t->destroying = 1; drop_connection(exec_ctx, t, GRPC_ERROR_CREATE("Transport destroyed")); - UNREF_TRANSPORT(exec_ctx, t, "destroy"); + GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "destroy"); } static void destroy_transport(grpc_exec_ctx *exec_ctx, grpc_transport *gt) { @@ -482,7 +479,7 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, gpr_slice_buffer_init(&s->writing.flow_controlled_buffer); s->global.deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC); - REF_TRANSPORT(t, "stream"); + GRPC_CHTTP2_REF_TRANSPORT(t, "stream"); if (server_data) { s->global.id = (uint32_t)(uintptr_t)server_data; @@ -547,7 +544,7 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp, GRPC_ERROR_UNREF(s->global.read_closed_error); GRPC_ERROR_UNREF(s->global.write_closed_error); - UNREF_TRANSPORT(exec_ctx, t, "stream"); + GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "stream"); GPR_TIMER_END("destroy_stream", 0); @@ -632,6 +629,7 @@ static void initiate_read_flush_locked(grpc_exec_ctx *exec_ctx, void *tp, grpc_chttp2_transport *t = tp; t->executor.check_read_ops_scheduled = false; check_read_ops(exec_ctx, &t->global); + GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "initiate_read_flush_locked"); } /******************************************************************************* @@ -667,7 +665,7 @@ void grpc_chttp2_initiate_write(grpc_exec_ctx *exec_ctx, break; case GRPC_CHTTP2_WRITING_INACTIVE: set_write_state(t, GRPC_CHTTP2_WRITE_SCHEDULED, reason); - REF_TRANSPORT(t, "writing"); + GRPC_CHTTP2_REF_TRANSPORT(t, "writing"); grpc_combiner_execute_finally(exec_ctx, t->executor.combiner, &t->initiate_writing, GRPC_ERROR_NONE, covered_by_poller); @@ -714,7 +712,7 @@ static void start_writing(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t) { "start_writing:nothing_to_write"); } end_waiting_for_write(exec_ctx, t, GRPC_ERROR_NONE); - UNREF_TRANSPORT(exec_ctx, t, "writing"); + GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "writing"); } GPR_TIMER_END("start_writing", 0); } @@ -787,7 +785,7 @@ static void terminate_writing_with_lock(grpc_exec_ctx *exec_ctx, void *tp, case GRPC_CHTTP2_WRITING_STALE_WITH_POLLER: GPR_TIMER_MARK("state=writing_stale_with_poller", 0); set_write_state(t, GRPC_CHTTP2_WRITE_SCHEDULED, "terminate_writing"); - REF_TRANSPORT(t, "writing"); + GRPC_CHTTP2_REF_TRANSPORT(t, "writing"); grpc_combiner_execute_finally(exec_ctx, t->executor.combiner, &t->initiate_writing, GRPC_ERROR_NONE, true); @@ -795,14 +793,14 @@ static void terminate_writing_with_lock(grpc_exec_ctx *exec_ctx, void *tp, case GRPC_CHTTP2_WRITING_STALE_NO_POLLER: GPR_TIMER_MARK("state=writing_stale_no_poller", 0); set_write_state(t, GRPC_CHTTP2_WRITE_SCHEDULED, "terminate_writing"); - REF_TRANSPORT(t, "writing"); + GRPC_CHTTP2_REF_TRANSPORT(t, "writing"); grpc_combiner_execute_finally(exec_ctx, t->executor.combiner, &t->initiate_writing, GRPC_ERROR_NONE, false); break; } - UNREF_TRANSPORT(exec_ctx, t, "writing"); + GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "writing"); GPR_TIMER_END("terminate_writing_with_lock", 0); } @@ -1261,7 +1259,7 @@ static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx, grpc_exec_ctx_sched(exec_ctx, op->on_consumed, GRPC_ERROR_NONE, NULL); - UNREF_TRANSPORT(exec_ctx, t, "transport_op"); + GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "transport_op"); } static void perform_transport_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, @@ -1270,7 +1268,7 @@ static void perform_transport_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, op->transport_private.args[0] = gt; grpc_closure_init(&op->transport_private.closure, perform_transport_op_locked, op); - REF_TRANSPORT(t, "transport_op"); + GRPC_CHTTP2_REF_TRANSPORT(t, "transport_op"); grpc_combiner_execute(exec_ctx, t->executor.combiner, &op->transport_private.closure, GRPC_ERROR_NONE); } @@ -1864,7 +1862,7 @@ static void reading_action_locked(grpc_exec_ctx *exec_ctx, void *tp, } } else if (!t->closed) { keep_reading = true; - REF_TRANSPORT(t, "keep_reading"); + GRPC_CHTTP2_REF_TRANSPORT(t, "keep_reading"); prevent_endpoint_shutdown(t); } gpr_slice_buffer_reset_and_unref(&t->read_buffer); @@ -1872,9 +1870,9 @@ static void reading_action_locked(grpc_exec_ctx *exec_ctx, void *tp, if (keep_reading) { grpc_endpoint_read(exec_ctx, t->ep, &t->read_buffer, &t->reading_action); allow_endpoint_shutdown_locked(exec_ctx, t); - UNREF_TRANSPORT(exec_ctx, t, "keep_reading"); + GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "keep_reading"); } else { - UNREF_TRANSPORT(exec_ctx, t, "reading_action"); + GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "reading_action"); } GPR_TIMER_END("post_reading_action_locked", 0); @@ -2247,7 +2245,8 @@ void grpc_chttp2_transport_start_reading(grpc_exec_ctx *exec_ctx, grpc_transport *transport, gpr_slice_buffer *read_buffer) { grpc_chttp2_transport *t = (grpc_chttp2_transport *)transport; - REF_TRANSPORT(t, "reading_action"); /* matches unref inside reading_action */ + GRPC_CHTTP2_REF_TRANSPORT( + t, "reading_action"); /* matches unref inside reading_action */ if (read_buffer != NULL) { gpr_slice_buffer_move_into(read_buffer, &t->read_buffer); gpr_free(read_buffer); diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 1b48b82f4f..761ed2dad1 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -726,6 +726,25 @@ void grpc_chttp2_stream_unref(grpc_exec_ctx *exec_ctx, grpc_chttp2_stream_global *stream_global); #endif +//#define GRPC_CHTTP2_REFCOUNTING_DEBUG 1 +#ifdef GRPC_CHTTP2_REFCOUNTING_DEBUG +#define GRPC_CHTTP2_REF_TRANSPORT(t, r) \ + grpc_chttp2_ref_transport(t, r, __FILE__, __LINE__) +#define GRPC_CHTTP2_UNREF_TRANSPORT(cl, t, r) \ + grpc_chttp2_unref_transport(cl, t, r, __FILE__, __LINE__) +void grpc_chttp2_unref_transport(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, const char *reason, + const char *file, int line); +void grpc_chttp2_ref_transport(grpc_chttp2_transport *t, const char *reason, + const char *file, int line); +#else +#define GRPC_CHTTP2_REF_TRANSPORT(t, r) grpc_chttp2_ref_transport(t) +#define GRPC_CHTTP2_UNREF_TRANSPORT(cl, t, r) grpc_chttp2_unref_transport(cl, t) +void grpc_chttp2_unref_transport(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t); +void grpc_chttp2_ref_transport(grpc_chttp2_transport *t); +#endif + grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, grpc_chttp2_stream_global *stream_global, uint32_t frame_size, diff --git a/src/core/ext/transport/chttp2/transport/stream_lists.c b/src/core/ext/transport/chttp2/transport/stream_lists.c index 4ba09087f9..6d4863c4aa 100644 --- a/src/core/ext/transport/chttp2/transport/stream_lists.c +++ b/src/core/ext/transport/chttp2/transport/stream_lists.c @@ -245,6 +245,8 @@ void grpc_chttp2_list_add_check_read_ops( grpc_chttp2_stream_global *stream_global) { grpc_chttp2_transport *t = TRANSPORT_FROM_GLOBAL(transport_global); if (!t->executor.check_read_ops_scheduled) { + GRPC_CHTTP2_REF_TRANSPORT(TRANSPORT_FROM_GLOBAL(transport_global), + "initiate_read_flush_locked"); grpc_combiner_execute_finally(exec_ctx, t->executor.combiner, &t->initiate_read_flush_locked, GRPC_ERROR_NONE, false); diff --git a/src/core/lib/iomgr/combiner.c b/src/core/lib/iomgr/combiner.c index 946cfc65fc..f1a2b29519 100644 --- a/src/core/lib/iomgr/combiner.c +++ b/src/core/lib/iomgr/combiner.c @@ -51,6 +51,7 @@ int grpc_combiner_trace = 0; } while (0) struct grpc_combiner { + grpc_combiner *next_combiner_on_this_exec_ctx; grpc_workqueue *optional_workqueue; gpr_mpscq queue; // state is: @@ -58,17 +59,23 @@ struct grpc_combiner { // other bits - number of items queued on the lock gpr_atm state; bool take_async_break_before_final_list; + bool time_to_execute_final_list; grpc_closure_list final_list; - grpc_closure continue_finishing; + grpc_closure offload; }; +static void offload(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error); + grpc_combiner *grpc_combiner_create(grpc_workqueue *optional_workqueue) { grpc_combiner *lock = gpr_malloc(sizeof(*lock)); + lock->next_combiner_on_this_exec_ctx = NULL; + lock->time_to_execute_final_list = false; lock->optional_workqueue = optional_workqueue; gpr_atm_no_barrier_store(&lock->state, 1); gpr_mpscq_init(&lock->queue); lock->take_async_break_before_final_list = false; grpc_closure_list_init(&lock->final_list); + grpc_closure_init(&lock->offload, offload, lock); GRPC_COMBINER_TRACE(gpr_log(GPR_DEBUG, "C:%p create", lock)); return lock; } @@ -90,177 +97,154 @@ void grpc_combiner_destroy(grpc_exec_ctx *exec_ctx, grpc_combiner *lock) { } } -static bool maybe_finish_one(grpc_exec_ctx *exec_ctx, grpc_combiner *lock); -static void finish(grpc_exec_ctx *exec_ctx, grpc_combiner *lock); +static void queue_on_exec_ctx(grpc_exec_ctx *exec_ctx, grpc_combiner *lock) { + lock->next_combiner_on_this_exec_ctx = NULL; + if (exec_ctx->active_combiner == NULL) { + exec_ctx->active_combiner = exec_ctx->last_combiner = lock; + } else { + exec_ctx->last_combiner->next_combiner_on_this_exec_ctx = lock; + exec_ctx->last_combiner = lock; + } +} -static void continue_finishing_mainline(grpc_exec_ctx *exec_ctx, void *arg, - grpc_error *error) { - GPR_TIMER_BEGIN("combiner.continue_executing_mainline", 0); - grpc_combiner *lock = arg; +void grpc_combiner_execute(grpc_exec_ctx *exec_ctx, grpc_combiner *lock, + grpc_closure *cl, grpc_error *error) { GRPC_COMBINER_TRACE( - gpr_log(GPR_DEBUG, "C:%p continue_finishing_mainline", lock)); - GPR_ASSERT(exec_ctx->active_combiner == NULL); - exec_ctx->active_combiner = lock; - if (maybe_finish_one(exec_ctx, lock)) finish(exec_ctx, lock); - GPR_ASSERT(exec_ctx->active_combiner == lock); - exec_ctx->active_combiner = NULL; - GPR_TIMER_END("combiner.continue_executing_mainline", 0); + gpr_log(GPR_DEBUG, "C:%p grpc_combiner_execute c=%p", lock, cl)); + GPR_TIMER_BEGIN("combiner.execute", 0); + gpr_atm last = gpr_atm_full_fetch_add(&lock->state, 2); + GPR_ASSERT(last & 1); // ensure lock has not been destroyed + cl->error = error; + gpr_mpscq_push(&lock->queue, &cl->next_data.atm_next); + if (last == 1) { + // code will be written when the exec_ctx calls + // grpc_combiner_continue_exec_ctx + queue_on_exec_ctx(exec_ctx, lock); + } + GPR_TIMER_END("combiner.execute", 0); } -static void execute_final(grpc_exec_ctx *exec_ctx, grpc_combiner *lock) { - GPR_TIMER_BEGIN("combiner.execute_final", 0); - grpc_closure *c = lock->final_list.head; - GPR_ASSERT(c != NULL); - grpc_closure_list_init(&lock->final_list); - lock->take_async_break_before_final_list = false; - int loops = 0; - while (c != NULL) { - GRPC_COMBINER_TRACE( - gpr_log(GPR_DEBUG, "C:%p execute_final[%d] c=%p", lock, loops, c)); - grpc_closure *next = c->next_data.next; - grpc_error *error = c->error; - c->cb(exec_ctx, c->cb_arg, error); - GRPC_ERROR_UNREF(error); - c = next; - loops++; +static void move_next(grpc_exec_ctx *exec_ctx) { + exec_ctx->active_combiner = + exec_ctx->active_combiner->next_combiner_on_this_exec_ctx; + if (exec_ctx->active_combiner == NULL) { + exec_ctx->last_combiner = NULL; } - GPR_TIMER_END("combiner.execute_final", 0); } -static void continue_executing_final(grpc_exec_ctx *exec_ctx, void *arg, - grpc_error *error) { - GPR_TIMER_BEGIN("combiner.continue_executing_final", 0); +static void offload(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { grpc_combiner *lock = arg; - GRPC_COMBINER_TRACE( - gpr_log(GPR_DEBUG, "C:%p continue_executing_final", lock)); - GPR_ASSERT(exec_ctx->active_combiner == NULL); - exec_ctx->active_combiner = lock; - // quick peek to see if new things have turned up on the queue: if so, go back - // to executing them before the final list - if ((gpr_atm_acq_load(&lock->state) >> 1) > 1) { - if (maybe_finish_one(exec_ctx, lock)) finish(exec_ctx, lock); - } else { - execute_final(exec_ctx, lock); - finish(exec_ctx, lock); - } - GPR_ASSERT(exec_ctx->active_combiner == lock); - exec_ctx->active_combiner = NULL; - GPR_TIMER_END("combiner.continue_executing_final", 0); + queue_on_exec_ctx(exec_ctx, lock); } -static bool start_execute_final(grpc_exec_ctx *exec_ctx, grpc_combiner *lock) { - GPR_TIMER_BEGIN("combiner.start_execute_final", 0); - GPR_ASSERT(exec_ctx->active_combiner == lock); - GRPC_COMBINER_TRACE( - gpr_log(GPR_DEBUG, - "C:%p start_execute_final take_async_break_before_final_list=%d", - lock, lock->take_async_break_before_final_list)); - if (lock->take_async_break_before_final_list) { - grpc_closure_init(&lock->continue_finishing, continue_executing_final, - lock); - grpc_exec_ctx_sched(exec_ctx, &lock->continue_finishing, GRPC_ERROR_NONE, - GRPC_WORKQUEUE_REF(lock->optional_workqueue, "sched")); - GPR_TIMER_END("combiner.start_execute_final", 0); +static void queue_offload(grpc_exec_ctx *exec_ctx, grpc_combiner *lock) { + move_next(exec_ctx); + grpc_workqueue_enqueue(exec_ctx, lock->optional_workqueue, &lock->offload, + GRPC_ERROR_NONE); +} + +bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) { + GPR_TIMER_BEGIN("combiner.continue_exec_ctx", 0); + grpc_combiner *lock = exec_ctx->active_combiner; + if (lock == NULL) { + GPR_TIMER_END("combiner.continue_exec_ctx", 0); return false; - } else { - execute_final(exec_ctx, lock); - GPR_TIMER_END("combiner.start_execute_final", 0); - return true; } -} -static bool maybe_finish_one(grpc_exec_ctx *exec_ctx, grpc_combiner *lock) { - GPR_TIMER_BEGIN("combiner.maybe_finish_one", 0); - GPR_ASSERT(exec_ctx->active_combiner == lock); if (lock->optional_workqueue != NULL && grpc_exec_ctx_ready_to_finish(exec_ctx)) { + GPR_TIMER_MARK("offload_from_finished_exec_ctx", 0); // this execution context wants to move on, and we have a workqueue (and so // can help the execution context out): schedule remaining work to be picked // up on the workqueue - grpc_closure_init(&lock->continue_finishing, continue_finishing_mainline, - lock); - grpc_workqueue_enqueue(exec_ctx, lock->optional_workqueue, - &lock->continue_finishing, GRPC_ERROR_NONE); - GPR_TIMER_END("combiner.maybe_finish_one", 0); - return false; - } - gpr_mpscq_node *n = gpr_mpscq_pop(&lock->queue); - GRPC_COMBINER_TRACE( - gpr_log(GPR_DEBUG, "C:%p maybe_finish_one n=%p", lock, n)); - if (n == NULL) { - // queue is in an inconsistant state: use this as a cue that we should - // go off and do something else for a while (and come back later) - grpc_closure_init(&lock->continue_finishing, continue_finishing_mainline, - lock); - grpc_exec_ctx_sched(exec_ctx, &lock->continue_finishing, GRPC_ERROR_NONE, - GRPC_WORKQUEUE_REF(lock->optional_workqueue, "sched")); - GPR_TIMER_END("combiner.maybe_finish_one", 0); - return false; + queue_offload(exec_ctx, lock); + GPR_TIMER_END("combiner.continue_exec_ctx", 0); + return true; } - grpc_closure *cl = (grpc_closure *)n; - grpc_error *error = cl->error; - cl->cb(exec_ctx, cl->cb_arg, error); - GRPC_ERROR_UNREF(error); - GPR_TIMER_END("combiner.maybe_finish_one", 0); - return true; -} -static void finish(grpc_exec_ctx *exec_ctx, grpc_combiner *lock) { - bool (*executor)(grpc_exec_ctx * exec_ctx, grpc_combiner * lock); - GPR_TIMER_BEGIN("combiner.finish", 0); - int loops = 0; - do { - executor = maybe_finish_one; - gpr_atm old_state = gpr_atm_full_fetch_add(&lock->state, -2); - GRPC_COMBINER_TRACE(gpr_log(GPR_DEBUG, - "C:%p finish[%d] old_state=%" PRIdPTR, lock, - loops, old_state)); - switch (old_state) { - case 5: // we're down to one queued item: if it's the final list we - case 4: // should do that - if (!grpc_closure_list_empty(lock->final_list)) { - executor = start_execute_final; - } - break; - case 3: // had one count, one unorphaned --> unlocked unorphaned - GPR_TIMER_END("combiner.finish", 0); - return; - case 2: // and one count, one orphaned --> unlocked and orphaned - really_destroy(exec_ctx, lock); - GPR_TIMER_END("combiner.finish", 0); - return; - case 1: - case 0: - // these values are illegal - representing an already unlocked or - // deleted lock - GPR_UNREACHABLE_CODE(return ); + if (!lock->time_to_execute_final_list || + // peek to see if something new has shown up, and execute that with + // priority + (gpr_atm_acq_load(&lock->state) >> 1) > 1) { + gpr_mpscq_node *n = gpr_mpscq_pop(&lock->queue); + GRPC_COMBINER_TRACE( + gpr_log(GPR_DEBUG, "C:%p maybe_finish_one n=%p", lock, n)); + if (n == NULL) { + // queue is in an inconsistant state: use this as a cue that we should + // go off and do something else for a while (and come back later) + GPR_TIMER_MARK("delay_busy", 0); + if (lock->optional_workqueue != NULL) { + queue_offload(exec_ctx, lock); + } + GPR_TIMER_END("combiner.continue_exec_ctx", 0); + return true; } - loops++; - } while (executor(exec_ctx, lock)); - GPR_TIMER_END("combiner.finish", 0); -} - -void grpc_combiner_execute(grpc_exec_ctx *exec_ctx, grpc_combiner *lock, - grpc_closure *cl, grpc_error *error) { - GRPC_COMBINER_TRACE( - gpr_log(GPR_DEBUG, "C:%p grpc_combiner_execute c=%p", lock, cl)); - GPR_TIMER_BEGIN("combiner.execute", 0); - gpr_atm last = gpr_atm_full_fetch_add(&lock->state, 2); - GPR_ASSERT(last & 1); // ensure lock has not been destroyed - if (last == 1) { - exec_ctx->active_combiner = lock; - GPR_TIMER_BEGIN("combiner.execute_first_cb", 0); + GPR_TIMER_BEGIN("combiner.exec1", 0); + grpc_closure *cl = (grpc_closure *)n; + grpc_error *error = cl->error; cl->cb(exec_ctx, cl->cb_arg, error); - GPR_TIMER_END("combiner.execute_first_cb", 0); GRPC_ERROR_UNREF(error); - finish(exec_ctx, lock); - GPR_ASSERT(exec_ctx->active_combiner == lock); - exec_ctx->active_combiner = NULL; + GPR_TIMER_END("combiner.exec1", 0); } else { - cl->error = error; - gpr_mpscq_push(&lock->queue, &cl->next_data.atm_next); + if (lock->take_async_break_before_final_list) { + GPR_TIMER_MARK("async_break", 0); + GRPC_COMBINER_TRACE(gpr_log(GPR_DEBUG, "C:%p take async break", lock)); + lock->take_async_break_before_final_list = false; + if (lock->optional_workqueue != NULL) { + queue_offload(exec_ctx, lock); + } + GPR_TIMER_END("combiner.continue_exec_ctx", 0); + return true; + } else { + grpc_closure *c = lock->final_list.head; + GPR_ASSERT(c != NULL); + grpc_closure_list_init(&lock->final_list); + lock->take_async_break_before_final_list = false; + int loops = 0; + while (c != NULL) { + GPR_TIMER_BEGIN("combiner.exec_1final", 0); + GRPC_COMBINER_TRACE( + gpr_log(GPR_DEBUG, "C:%p execute_final[%d] c=%p", lock, loops, c)); + grpc_closure *next = c->next_data.next; + grpc_error *error = c->error; + c->cb(exec_ctx, c->cb_arg, error); + GRPC_ERROR_UNREF(error); + c = next; + GPR_TIMER_END("combiner.exec_1final", 0); + } + } } - GPR_TIMER_END("combiner.execute", 0); + + GPR_TIMER_MARK("unref", 0); + gpr_atm old_state = gpr_atm_full_fetch_add(&lock->state, -2); + GRPC_COMBINER_TRACE( + gpr_log(GPR_DEBUG, "C:%p finish old_state=%" PRIdPTR, lock, old_state)); + lock->time_to_execute_final_list = false; + switch (old_state) { + case 5: // we're down to one queued item: if it's the final list we + case 4: // should do that + if (!grpc_closure_list_empty(lock->final_list)) { + lock->time_to_execute_final_list = true; + } + break; + case 3: // had one count, one unorphaned --> unlocked unorphaned + move_next(exec_ctx); + GPR_TIMER_END("combiner.continue_exec_ctx", 0); + return true; + case 2: // and one count, one orphaned --> unlocked and orphaned + move_next(exec_ctx); + really_destroy(exec_ctx, lock); + GPR_TIMER_END("combiner.continue_exec_ctx", 0); + return true; + case 1: + case 0: + // these values are illegal - representing an already unlocked or + // deleted lock + GPR_TIMER_END("combiner.continue_exec_ctx", 0); + GPR_UNREACHABLE_CODE(return true); + } + GPR_TIMER_END("combiner.continue_exec_ctx", 0); + return true; } static void enqueue_finally(grpc_exec_ctx *exec_ctx, void *closure, diff --git a/src/core/lib/iomgr/combiner.h b/src/core/lib/iomgr/combiner.h index 3eb9f34638..28f548b2f5 100644 --- a/src/core/lib/iomgr/combiner.h +++ b/src/core/lib/iomgr/combiner.h @@ -64,6 +64,8 @@ void grpc_combiner_execute_finally(grpc_exec_ctx *exec_ctx, grpc_combiner *lock, bool hint_async_break); void grpc_combiner_force_async_finally(grpc_combiner *lock); +bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx); + extern int grpc_combiner_trace; #endif /* GRPC_CORE_LIB_IOMGR_COMBINER_H */ diff --git a/src/core/lib/iomgr/exec_ctx.c b/src/core/lib/iomgr/exec_ctx.c index 12e51ac092..747b462a6e 100644 --- a/src/core/lib/iomgr/exec_ctx.c +++ b/src/core/lib/iomgr/exec_ctx.c @@ -37,6 +37,7 @@ #include #include +#include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/workqueue.h" #include "src/core/lib/profiling/timers.h" @@ -60,20 +61,28 @@ bool grpc_always_ready_to_finish(grpc_exec_ctx *exec_ctx, void *arg_ignored) { bool grpc_exec_ctx_flush(grpc_exec_ctx *exec_ctx) { bool did_something = 0; GPR_TIMER_BEGIN("grpc_exec_ctx_flush", 0); - while (!grpc_closure_list_empty(exec_ctx->closure_list)) { - grpc_closure *c = exec_ctx->closure_list.head; - exec_ctx->closure_list.head = exec_ctx->closure_list.tail = NULL; - while (c != NULL) { - grpc_closure *next = c->next_data.next; - grpc_error *error = c->error; - did_something = true; - GPR_TIMER_BEGIN("grpc_exec_ctx_flush.cb", 0); - c->cb(exec_ctx, c->cb_arg, error); - GRPC_ERROR_UNREF(error); - GPR_TIMER_END("grpc_exec_ctx_flush.cb", 0); - c = next; + for (;;) { + if (!grpc_closure_list_empty(exec_ctx->closure_list)) { + grpc_closure *c = exec_ctx->closure_list.head; + exec_ctx->closure_list.head = exec_ctx->closure_list.tail = NULL; + while (c != NULL) { + grpc_closure *next = c->next_data.next; + grpc_error *error = c->error; + did_something = true; + GPR_TIMER_BEGIN("grpc_exec_ctx_flush.cb", 0); + c->cb(exec_ctx, c->cb_arg, error); + GRPC_ERROR_UNREF(error); + GPR_TIMER_END("grpc_exec_ctx_flush.cb", 0); + c = next; + } + continue; + } + if (grpc_combiner_continue_exec_ctx(exec_ctx)) { + continue; } + break; } + GPR_ASSERT(exec_ctx->active_combiner == NULL); if (exec_ctx->stealing_from_workqueue != NULL) { if (grpc_exec_ctx_ready_to_finish(exec_ctx)) { grpc_workqueue_enqueue(exec_ctx, exec_ctx->stealing_from_workqueue, diff --git a/src/core/lib/iomgr/exec_ctx.h b/src/core/lib/iomgr/exec_ctx.h index ac4674bbac..91029f5fba 100644 --- a/src/core/lib/iomgr/exec_ctx.h +++ b/src/core/lib/iomgr/exec_ctx.h @@ -70,6 +70,7 @@ struct grpc_exec_ctx { grpc_closure *stolen_closure; /** currently active combiner: updated only via combiner.c */ grpc_combiner *active_combiner; + grpc_combiner *last_combiner; bool cached_ready_to_finish; void *check_ready_to_finish_arg; bool (*check_ready_to_finish)(grpc_exec_ctx *exec_ctx, void *arg); @@ -79,7 +80,7 @@ struct grpc_exec_ctx { prefer to use GRPC_EXEC_CTX_INIT whenever possible */ #define GRPC_EXEC_CTX_INIT_WITH_FINISH_CHECK(finish_check, finish_check_arg) \ { \ - GRPC_CLOSURE_LIST_INIT, NULL, NULL, NULL, false, finish_check_arg, \ + GRPC_CLOSURE_LIST_INIT, NULL, NULL, NULL, NULL, false, finish_check_arg, \ finish_check \ } #else diff --git a/src/core/lib/profiling/timers.h b/src/core/lib/profiling/timers.h index 621cdbf656..ea0cbca977 100644 --- a/src/core/lib/profiling/timers.h +++ b/src/core/lib/profiling/timers.h @@ -34,6 +34,8 @@ #ifndef GRPC_CORE_LIB_PROFILING_TIMERS_H #define GRPC_CORE_LIB_PROFILING_TIMERS_H +#include + #ifdef __cplusplus extern "C" { #endif @@ -56,14 +58,17 @@ void gpr_timer_set_enabled(int enabled); /* No profiling. No-op all the things. */ #define GPR_TIMER_MARK(tag, important) \ do { \ + /*printf("- %s\n", tag);*/ \ } while (0) #define GPR_TIMER_BEGIN(tag, important) \ do { \ + /*printf("%s {\n", tag);*/ \ } while (0) #define GPR_TIMER_END(tag, important) \ do { \ + /*printf("} // %s\n", tag);*/ \ } while (0) #else /* at least one profiler requested... */ diff --git a/src/core/lib/transport/transport.c b/src/core/lib/transport/transport.c index a78ad4349a..b951218130 100644 --- a/src/core/lib/transport/transport.c +++ b/src/core/lib/transport/transport.c @@ -276,3 +276,28 @@ grpc_transport_op *grpc_make_transport_op(grpc_closure *on_complete) { op->op.on_consumed = &op->outer_on_complete; return &op->op; } + +typedef struct { + grpc_closure outer_on_complete; + grpc_closure *inner_on_complete; + grpc_transport_stream_op op; +} made_transport_stream_op; + +static void destroy_made_transport_stream_op(grpc_exec_ctx *exec_ctx, void *arg, + grpc_error *error) { + made_transport_stream_op *op = arg; + grpc_exec_ctx_sched(exec_ctx, op->inner_on_complete, GRPC_ERROR_REF(error), + NULL); + gpr_free(op); +} + +grpc_transport_stream_op *grpc_make_transport_stream_op( + grpc_closure *on_complete) { + made_transport_stream_op *op = gpr_malloc(sizeof(*op)); + grpc_closure_init(&op->outer_on_complete, destroy_made_transport_stream_op, + op); + op->inner_on_complete = on_complete; + memset(&op->op, 0, sizeof(op->op)); + op->op.on_complete = &op->outer_on_complete; + return &op->op; +} diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h index d0d0c2a461..2c1cc3ee42 100644 --- a/src/core/lib/transport/transport.h +++ b/src/core/lib/transport/transport.h @@ -292,6 +292,10 @@ char *grpc_transport_get_peer(grpc_exec_ctx *exec_ctx, /* Allocate a grpc_transport_op, and preconfigure the on_consumed closure to \a on_consumed and then delete the returned transport op */ grpc_transport_op *grpc_make_transport_op(grpc_closure *on_consumed); +/* Allocate a grpc_transport_stream_op, and preconfigure the on_consumed closure + to \a on_consumed and then delete the returned transport op */ +grpc_transport_stream_op *grpc_make_transport_stream_op( + grpc_closure *on_consumed); #ifdef __cplusplus } diff --git a/test/core/end2end/tests/filter_causes_close.c b/test/core/end2end/tests/filter_causes_close.c index c6c36d668b..ef1a9c4edb 100644 --- a/test/core/end2end/tests/filter_causes_close.c +++ b/test/core/end2end/tests/filter_causes_close.c @@ -211,11 +211,10 @@ static void recv_im_ready(grpc_exec_ctx *exec_ctx, void *arg, // close the stream with an error. gpr_slice message = gpr_slice_from_copied_string("Failure that's not preventable."); - grpc_transport_stream_op op; - memset(&op, 0, sizeof(op)); - grpc_transport_stream_op_add_close(&op, GRPC_STATUS_PERMISSION_DENIED, + grpc_transport_stream_op *op = grpc_make_transport_stream_op(NULL); + grpc_transport_stream_op_add_close(op, GRPC_STATUS_PERMISSION_DENIED, &message); - grpc_call_next_op(exec_ctx, elem, &op); + grpc_call_next_op(exec_ctx, elem, op); } grpc_exec_ctx_sched( exec_ctx, calld->recv_im_ready, -- cgit v1.2.3 From aef3a79ae4cfa7236673407e09aff001a8d2e02f Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 24 Aug 2016 15:13:53 -0700 Subject: Remove extraneous locks on cq checks --- src/core/lib/surface/completion_queue.c | 89 ++++++++++++++++++--------------- 1 file changed, 50 insertions(+), 39 deletions(-) diff --git a/src/core/lib/surface/completion_queue.c b/src/core/lib/surface/completion_queue.c index 28450d966c..1124290699 100644 --- a/src/core/lib/surface/completion_queue.c +++ b/src/core/lib/surface/completion_queue.c @@ -71,6 +71,9 @@ struct grpc_completion_queue { gpr_refcount pending_events; /** Once owning_refs drops to zero, we will destroy the cq */ gpr_refcount owning_refs; + /** counter of how many things have ever been queued on this completion queue + useful for avoiding locks to check the queue */ + gpr_atm things_queued_ever; /** 0 initially, 1 once we've begun shutting down */ int shutdown; int shutdown_called; @@ -125,15 +128,6 @@ void grpc_cq_global_shutdown(void) { } } -struct grpc_cq_alarm { - grpc_timer alarm; - grpc_cq_completion completion; - /** completion queue where events about this alarm will be posted */ - grpc_completion_queue *cq; - /** user supplied tag */ - void *tag; -}; - grpc_completion_queue *grpc_completion_queue_create(void *reserved) { grpc_completion_queue *cc; GPR_ASSERT(!reserved); @@ -170,6 +164,7 @@ grpc_completion_queue *grpc_completion_queue_create(void *reserved) { cc->is_server_cq = 0; cc->is_non_listening_server_cq = 0; cc->num_pluckers = 0; + gpr_atm_no_barrier_store(&cc->things_queued_ever, 0); #ifndef NDEBUG cc->outstanding_tag_count = 0; #endif @@ -280,6 +275,7 @@ void grpc_cq_end_op(grpc_exec_ctx *exec_ctx, grpc_completion_queue *cc, GPR_ASSERT(found); #endif shutdown = gpr_unref(&cc->pending_events); + gpr_atm_no_barrier_fetch_add(&cc->things_queued_ever, 1); if (!shutdown) { cc->completed_tail->next = ((uintptr_t)storage) | (1u & (uintptr_t)cc->completed_tail->next); @@ -318,6 +314,7 @@ void grpc_cq_end_op(grpc_exec_ctx *exec_ctx, grpc_completion_queue *cc, } typedef struct { + gpr_atm last_seen_things_queued_ever; grpc_completion_queue *cq; gpr_timespec deadline; grpc_cq_completion *stolen_completion; @@ -328,17 +325,23 @@ static bool cq_is_next_finished(grpc_exec_ctx *exec_ctx, void *arg) { cq_is_finished_arg *a = arg; grpc_completion_queue *cq = a->cq; GPR_ASSERT(a->stolen_completion == NULL); - gpr_mu_lock(cq->mu); - if (cq->completed_tail != &cq->completed_head) { - a->stolen_completion = (grpc_cq_completion *)cq->completed_head.next; - cq->completed_head.next = a->stolen_completion->next & ~(uintptr_t)1; - if (a->stolen_completion == cq->completed_tail) { - cq->completed_tail = &cq->completed_head; + gpr_atm current_last_seen_things_queued_ever = + gpr_atm_no_barrier_load(&cq->things_queued_ever); + if (current_last_seen_things_queued_ever != a->last_seen_things_queued_ever) { + gpr_mu_lock(cq->mu); + a->last_seen_things_queued_ever = + gpr_atm_no_barrier_load(&cq->things_queued_ever); + if (cq->completed_tail != &cq->completed_head) { + a->stolen_completion = (grpc_cq_completion *)cq->completed_head.next; + cq->completed_head.next = a->stolen_completion->next & ~(uintptr_t)1; + if (a->stolen_completion == cq->completed_tail) { + cq->completed_tail = &cq->completed_head; + } + gpr_mu_unlock(cq->mu); + return true; } gpr_mu_unlock(cq->mu); - return true; } - gpr_mu_unlock(cq->mu); return gpr_time_cmp(a->deadline, gpr_now(a->deadline.clock_type)) < 0; } @@ -386,12 +389,13 @@ grpc_event grpc_completion_queue_next(grpc_completion_queue *cc, deadline = gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC); - cq_is_finished_arg is_finished_arg = {cc, deadline, NULL, NULL}; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT_WITH_FINISH_CHECK( - cq_is_next_finished, &is_finished_arg); - GRPC_CQ_INTERNAL_REF(cc, "next"); gpr_mu_lock(cc->mu); + cq_is_finished_arg is_finished_arg = { + gpr_atm_no_barrier_load(&cc->things_queued_ever), cc, deadline, NULL, + NULL}; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT_WITH_FINISH_CHECK( + cq_is_next_finished, &is_finished_arg); for (;;) { if (is_finished_arg.stolen_completion != NULL) { gpr_mu_unlock(cc->mu); @@ -496,23 +500,29 @@ static bool cq_is_pluck_finished(grpc_exec_ctx *exec_ctx, void *arg) { cq_is_finished_arg *a = arg; grpc_completion_queue *cq = a->cq; GPR_ASSERT(a->stolen_completion == NULL); - gpr_mu_lock(cq->mu); - grpc_cq_completion *c; - grpc_cq_completion *prev = &cq->completed_head; - while ((c = (grpc_cq_completion *)(prev->next & ~(uintptr_t)1)) != - &cq->completed_head) { - if (c->tag == a->tag) { - prev->next = (prev->next & (uintptr_t)1) | (c->next & ~(uintptr_t)1); - if (c == cq->completed_tail) { - cq->completed_tail = prev; + gpr_atm current_last_seen_things_queued_ever = + gpr_atm_no_barrier_load(&cq->things_queued_ever); + if (current_last_seen_things_queued_ever != a->last_seen_things_queued_ever) { + gpr_mu_lock(cq->mu); + a->last_seen_things_queued_ever = + gpr_atm_no_barrier_load(&cq->things_queued_ever); + grpc_cq_completion *c; + grpc_cq_completion *prev = &cq->completed_head; + while ((c = (grpc_cq_completion *)(prev->next & ~(uintptr_t)1)) != + &cq->completed_head) { + if (c->tag == a->tag) { + prev->next = (prev->next & (uintptr_t)1) | (c->next & ~(uintptr_t)1); + if (c == cq->completed_tail) { + cq->completed_tail = prev; + } + gpr_mu_unlock(cq->mu); + a->stolen_completion = c; + return true; } - gpr_mu_unlock(cq->mu); - a->stolen_completion = c; - return true; + prev = c; } - prev = c; + gpr_mu_unlock(cq->mu); } - gpr_mu_unlock(cq->mu); return gpr_time_cmp(a->deadline, gpr_now(a->deadline.clock_type)) < 0; } @@ -543,12 +553,13 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag, deadline = gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC); - cq_is_finished_arg is_finished_arg = {cc, deadline, NULL, tag}; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT_WITH_FINISH_CHECK( - cq_is_pluck_finished, &is_finished_arg); - GRPC_CQ_INTERNAL_REF(cc, "pluck"); gpr_mu_lock(cc->mu); + cq_is_finished_arg is_finished_arg = { + gpr_atm_no_barrier_load(&cc->things_queued_ever), cc, deadline, NULL, + tag}; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT_WITH_FINISH_CHECK( + cq_is_pluck_finished, &is_finished_arg); for (;;) { if (is_finished_arg.stolen_completion != NULL) { gpr_mu_unlock(cc->mu); -- cgit v1.2.3 From 3d7c60944474fd194f491355cd61ae4ad5adfaa4 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 26 Aug 2016 11:39:05 -0700 Subject: Start merging writes with the main transport thread --- .../transport/chttp2/transport/chttp2_transport.c | 1190 ++++++++------------ src/core/ext/transport/chttp2/transport/frame.h | 4 +- .../ext/transport/chttp2/transport/frame_data.h | 8 +- .../ext/transport/chttp2/transport/frame_goaway.h | 9 +- .../ext/transport/chttp2/transport/frame_ping.h | 8 +- .../transport/chttp2/transport/frame_rst_stream.h | 9 +- .../transport/chttp2/transport/frame_settings.h | 9 +- .../chttp2/transport/frame_window_update.h | 5 +- .../ext/transport/chttp2/transport/hpack_parser.h | 9 +- src/core/ext/transport/chttp2/transport/internal.h | 452 +++----- 10 files changed, 681 insertions(+), 1022 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 19e988670c..7a70744e5c 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -63,18 +63,6 @@ #define MAX_CLIENT_STREAM_ID 0x7fffffffu int grpc_http_trace = 0; int grpc_flowctl_trace = 0; -int grpc_http_write_state_trace = 0; - -#define TRANSPORT_FROM_WRITING(tw) \ - ((grpc_chttp2_transport *)((char *)(tw)-offsetof(grpc_chttp2_transport, \ - writing))) - -#define TRANSPORT_FROM_GLOBAL(tg) \ - ((grpc_chttp2_transport *)((char *)(tg)-offsetof(grpc_chttp2_transport, \ - global))) - -#define STREAM_FROM_GLOBAL(sg) \ - ((grpc_chttp2_stream *)((char *)(sg)-offsetof(grpc_chttp2_stream, global))) static const grpc_transport_vtable vtable; @@ -91,8 +79,6 @@ static void terminate_writing_with_lock(grpc_exec_ctx *exec_ctx, void *t, grpc_error *error); static void start_writing(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t); -static void end_waiting_for_write(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport *t, grpc_error *error); /** Set a transport level setting, and push it to our peer */ static void push_setting(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, @@ -102,37 +88,32 @@ static void push_setting(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, static void drop_connection(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_error *error); -static void close_from_api(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, - grpc_error *error); +static void close_from_api(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, + grpc_chttp2_stream *s, grpc_error *error); /** Start new streams that have been created if we can */ -static void maybe_start_some_streams( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global); +static void maybe_start_some_streams(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t); -static void connectivity_state_set( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - grpc_connectivity_state state, grpc_error *error, const char *reason); +static void connectivity_state_set(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + grpc_connectivity_state state, + grpc_error *error, const char *reason); -static void check_read_ops(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_global *transport_global); +static void check_read_ops(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t); -static void incoming_byte_stream_update_flow_control( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, size_t max_size_hint, - size_t have_already); +static void incoming_byte_stream_update_flow_control(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s, + size_t max_size_hint, + size_t have_already); static void incoming_byte_stream_destroy_locked(grpc_exec_ctx *exec_ctx, void *byte_stream, grpc_error *error_ignored); static void fail_pending_writes(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, + grpc_chttp2_transport *t, grpc_chttp2_stream *s, grpc_error *error); -static void set_write_state(grpc_chttp2_transport *t, - grpc_chttp2_write_state state, const char *reason); - /******************************************************************************* * CONSTRUCTION/DESTRUCTION/REFCOUNTING */ @@ -143,14 +124,14 @@ static void destruct_transport(grpc_exec_ctx *exec_ctx, grpc_endpoint_destroy(exec_ctx, t->ep); - gpr_slice_buffer_destroy(&t->global.qbuf); + gpr_slice_buffer_destroy(&t->qbuf); - gpr_slice_buffer_destroy(&t->writing.outbuf); - grpc_chttp2_hpack_compressor_destroy(&t->writing.hpack_compressor); + gpr_slice_buffer_destroy(&t->outbuf); + grpc_chttp2_hpack_compressor_destroy(&t->hpack_compressor); gpr_slice_buffer_destroy(&t->read_buffer); - grpc_chttp2_hpack_parser_destroy(&t->global.hpack_parser); - grpc_chttp2_goaway_parser_destroy(&t->global.goaway_parser); + grpc_chttp2_hpack_parser_destroy(&t->hpack_parser); + grpc_chttp2_goaway_parser_destroy(&t->goaway_parser); for (i = 0; i < STREAM_LIST_COUNT; i++) { GPR_ASSERT(t->lists[i].head == NULL); @@ -162,12 +143,12 @@ static void destruct_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_stream_map_destroy(&t->stream_map); grpc_connectivity_state_destroy(exec_ctx, &t->channel_callback.state_tracker); - grpc_combiner_destroy(exec_ctx, t->executor.combiner); + grpc_combiner_destroy(exec_ctx, t->combiner); /* callback remaining pings: they're not allowed to call into the transpot, and maybe they hold resources that need to be freed */ - while (t->global.pings.next != &t->global.pings) { - grpc_chttp2_outstanding_ping *ping = t->global.pings.next; + while (t->pings.next != &t->pings) { + grpc_chttp2_outstanding_ping *ping = t->pings.next; grpc_exec_ctx_sched(exec_ctx, ping->on_recv, GRPC_ERROR_CREATE("Transport closed"), NULL); ping->next->prev = ping->prev; @@ -217,47 +198,41 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, memset(t, 0, sizeof(*t)); t->base.vtable = &vtable; - t->executor.write_state = GRPC_CHTTP2_WRITES_CORKED; t->ep = ep; /* one ref is for destroy */ gpr_ref_init(&t->refs, 1); /* ref is dropped at transport close() */ gpr_ref_init(&t->shutdown_ep_refs, 1); - t->executor.combiner = grpc_combiner_create(grpc_endpoint_get_workqueue(ep)); + t->combiner = grpc_combiner_create(grpc_endpoint_get_workqueue(ep)); t->peer_string = grpc_endpoint_get_peer(ep); t->endpoint_reading = 1; - t->global.next_stream_id = is_client ? 1 : 2; - t->global.is_client = is_client; - t->writing.outgoing_window = DEFAULT_WINDOW; - t->global.incoming_window = DEFAULT_WINDOW; - t->global.stream_lookahead = DEFAULT_WINDOW; - t->global.connection_window_target = DEFAULT_CONNECTION_WINDOW_TARGET; - t->global.ping_counter = 1; - t->global.pings.next = t->global.pings.prev = &t->global.pings; - t->global.deframe_state = - is_client ? GRPC_DTS_FH_0 : GRPC_DTS_CLIENT_PREFIX_0; - t->global.is_first_frame = true; - t->writing.is_client = is_client; + t->next_stream_id = is_client ? 1 : 2; + t->is_client = is_client; + t->outgoing_window = DEFAULT_WINDOW; + t->incoming_window = DEFAULT_WINDOW; + t->stream_lookahead = DEFAULT_WINDOW; + t->connection_window_target = DEFAULT_CONNECTION_WINDOW_TARGET; + t->ping_counter = 1; + t->pings.next = t->pings.prev = &t->pings; + t->deframe_state = is_client ? GRPC_DTS_FH_0 : GRPC_DTS_CLIENT_PREFIX_0; + t->is_first_frame = true; grpc_connectivity_state_init( &t->channel_callback.state_tracker, GRPC_CHANNEL_READY, is_client ? "client_transport" : "server_transport"); - gpr_slice_buffer_init(&t->global.qbuf); + gpr_slice_buffer_init(&t->qbuf); - gpr_slice_buffer_init(&t->writing.outbuf); - grpc_chttp2_hpack_compressor_init(&t->writing.hpack_compressor); + gpr_slice_buffer_init(&t->outbuf); + grpc_chttp2_hpack_compressor_init(&t->hpack_compressor); grpc_closure_init(&t->writing_action, writing_action, t); grpc_closure_init(&t->reading_action, reading_action, t); grpc_closure_init(&t->reading_action_locked, reading_action_locked, t); - grpc_closure_init(&t->initiate_writing, initiate_writing_locked, t); grpc_closure_init(&t->terminate_writing, terminate_writing_with_lock, t); grpc_closure_init(&t->initiate_read_flush_locked, initiate_read_flush_locked, t); - grpc_closure_init(&t->writing.done_cb, grpc_chttp2_terminate_writing, - &t->writing); - grpc_chttp2_goaway_parser_init(&t->global.goaway_parser); - grpc_chttp2_hpack_parser_init(&t->global.hpack_parser); + grpc_chttp2_goaway_parser_init(&t->goaway_parser); + grpc_chttp2_hpack_parser_init(&t->hpack_parser); gpr_slice_buffer_init(&t->read_buffer); @@ -271,21 +246,19 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, /* copy in initial settings to all setting sets */ for (i = 0; i < GRPC_CHTTP2_NUM_SETTINGS; i++) { for (j = 0; j < GRPC_NUM_SETTING_SETS; j++) { - t->global.settings[j][i] = - grpc_chttp2_settings_parameters[i].default_value; + t->settings[j][i] = grpc_chttp2_settings_parameters[i].default_value; } } - t->global.dirtied_local_settings = 1; + t->dirtied_local_settings = 1; /* Hack: it's common for implementations to assume 65536 bytes initial send window -- this should by rights be 0 */ - t->global.force_send_settings = 1 << GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE; - t->global.sent_local_settings = 0; + t->force_send_settings = 1 << GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE; + t->sent_local_settings = 0; if (is_client) { - gpr_slice_buffer_add( - &t->writing.outbuf, - gpr_slice_from_copied_string(GRPC_CHTTP2_CLIENT_CONNECT_STRING)); - grpc_chttp2_initiate_write(exec_ctx, &t->global, false, "initial_write"); + gpr_slice_buffer_add(&t->outbuf, gpr_slice_from_copied_string( + GRPC_CHTTP2_CLIENT_CONNECT_STRING)); + grpc_chttp2_initiate_write(exec_ctx, t, false, "initial_write"); } /* configure http2 the way we like it */ @@ -317,15 +290,13 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, if (channel_args->args[i].type != GRPC_ARG_INTEGER) { gpr_log(GPR_ERROR, "%s: must be an integer", GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER); - } else if ((t->global.next_stream_id & 1) != + } else if ((t->next_stream_id & 1) != (channel_args->args[i].value.integer & 1)) { gpr_log(GPR_ERROR, "%s: low bit must be %d on %s", - GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER, - t->global.next_stream_id & 1, + GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER, t->next_stream_id & 1, is_client ? "client" : "server"); } else { - t->global.next_stream_id = - (uint32_t)channel_args->args[i].value.integer; + t->next_stream_id = (uint32_t)channel_args->args[i].value.integer; } } else if (0 == strcmp(channel_args->args[i].key, GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES)) { @@ -336,8 +307,7 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, gpr_log(GPR_ERROR, "%s: must be at least 5", GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES); } else { - t->global.stream_lookahead = - (uint32_t)channel_args->args[i].value.integer; + t->stream_lookahead = (uint32_t)channel_args->args[i].value.integer; } } else if (0 == strcmp(channel_args->args[i].key, GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER)) { @@ -361,7 +331,7 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_ENCODER); } else { grpc_chttp2_hpack_compressor_set_max_usable_size( - &t->writing.hpack_compressor, + &t->hpack_compressor, (uint32_t)channel_args->args[i].value.integer); } } else if (0 == strcmp(channel_args->args[i].key, @@ -380,8 +350,7 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, } } - set_write_state(t, GRPC_CHTTP2_WRITING_INACTIVE, "uncork"); - grpc_chttp2_initiate_write(exec_ctx, &t->global, false, "init"); + grpc_chttp2_initiate_write(exec_ctx, t, false, "init"); } static void destroy_transport_locked(grpc_exec_ctx *exec_ctx, void *tp, @@ -394,7 +363,7 @@ static void destroy_transport_locked(grpc_exec_ctx *exec_ctx, void *tp, static void destroy_transport(grpc_exec_ctx *exec_ctx, grpc_transport *gt) { grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt; - grpc_combiner_execute(exec_ctx, t->executor.combiner, + grpc_combiner_execute(exec_ctx, t->combiner, grpc_closure_create(destroy_transport_locked, t), GRPC_ERROR_NONE); } @@ -416,43 +385,34 @@ static void close_transport_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_error *error) { if (!t->closed) { - if (grpc_http_write_state_trace) { - gpr_log(GPR_DEBUG, "W:%p close transport", t); - } t->closed = 1; - connectivity_state_set(exec_ctx, &t->global, GRPC_CHANNEL_SHUTDOWN, + connectivity_state_set(exec_ctx, t, GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_REF(error), "close_transport"); allow_endpoint_shutdown_locked(exec_ctx, t); /* flush writable stream list to avoid dangling references */ - grpc_chttp2_stream_global *stream_global; - grpc_chttp2_stream_writing *stream_writing; - while (grpc_chttp2_list_pop_writable_stream( - &t->global, &t->writing, &stream_global, &stream_writing)) { - GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2_writing"); + grpc_chttp2_stream *s; + while (grpc_chttp2_list_pop_writable_stream(t, &s)) { + GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing"); } } GRPC_ERROR_UNREF(error); } #ifdef GRPC_STREAM_REFCOUNT_DEBUG -void grpc_chttp2_stream_ref(grpc_chttp2_stream_global *stream_global, - const char *reason) { - grpc_stream_ref(STREAM_FROM_GLOBAL(stream_global)->refcount, reason); +void grpc_chttp2_stream_ref(grpc_chttp2_stream *s, const char *reason) { + grpc_stream_ref(s->refcount, reason); } -void grpc_chttp2_stream_unref(grpc_exec_ctx *exec_ctx, - grpc_chttp2_stream_global *stream_global, +void grpc_chttp2_stream_unref(grpc_exec_ctx *exec_ctx, grpc_chttp2_stream *s, const char *reason) { - grpc_stream_unref(exec_ctx, STREAM_FROM_GLOBAL(stream_global)->refcount, - reason); + grpc_stream_unref(exec_ctx, s->refcount, reason); } #else -void grpc_chttp2_stream_ref(grpc_chttp2_stream_global *stream_global) { - grpc_stream_ref(STREAM_FROM_GLOBAL(stream_global)->refcount); +void grpc_chttp2_stream_ref(grpc_chttp2_stream *s) { + grpc_stream_ref(s->refcount); } -void grpc_chttp2_stream_unref(grpc_exec_ctx *exec_ctx, - grpc_chttp2_stream_global *stream_global) { - grpc_stream_unref(exec_ctx, STREAM_FROM_GLOBAL(stream_global)->refcount); +void grpc_chttp2_stream_unref(grpc_exec_ctx *exec_ctx, grpc_chttp2_stream *s) { + grpc_stream_unref(exec_ctx, s->refcount); } #endif @@ -470,28 +430,27 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, /* We reserve one 'active stream' that's dropped when the stream is read-closed. The others are for incoming_byte_streams that are actively reading */ - gpr_ref_init(&s->global.active_streams, 1); - GRPC_CHTTP2_STREAM_REF(&s->global, "chttp2"); + gpr_ref_init(&s->active_streams, 1); + GRPC_CHTTP2_STREAM_REF(s, "chttp2"); - grpc_chttp2_incoming_metadata_buffer_init(&s->global.metadata_buffer[0]); - grpc_chttp2_incoming_metadata_buffer_init(&s->global.metadata_buffer[1]); - grpc_chttp2_data_parser_init(&s->global.data_parser); - gpr_slice_buffer_init(&s->writing.flow_controlled_buffer); - s->global.deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC); + grpc_chttp2_incoming_metadata_buffer_init(&s->metadata_buffer[0]); + grpc_chttp2_incoming_metadata_buffer_init(&s->metadata_buffer[1]); + grpc_chttp2_data_parser_init(&s->data_parser); + gpr_slice_buffer_init(&s->flow_controlled_buffer); + s->deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC); GRPC_CHTTP2_REF_TRANSPORT(t, "stream"); if (server_data) { - s->global.id = (uint32_t)(uintptr_t)server_data; - s->global.outgoing_window = - t->global.settings[GRPC_PEER_SETTINGS] - [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]; - s->global.incoming_window = s->global.max_recv_bytes = - t->global.settings[GRPC_SENT_SETTINGS] - [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]; + s->id = (uint32_t)(uintptr_t)server_data; + s->outgoing_window = t->settings[GRPC_PEER_SETTINGS] + [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]; + s->incoming_window = s->max_recv_bytes = + t->settings[GRPC_SENT_SETTINGS] + [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]; *t->accepting_stream = s; - grpc_chttp2_stream_map_add(&t->stream_map, s->global.id, s); - s->global.in_stream_map = true; + grpc_chttp2_stream_map_add(&t->stream_map, s->id, s); + s->in_stream_map = true; } GPR_TIMER_END("init_stream", 0); @@ -507,42 +466,39 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp, GPR_TIMER_BEGIN("destroy_stream", 0); - GPR_ASSERT((s->global.write_closed && s->global.read_closed) || - s->global.id == 0); - GPR_ASSERT(!s->global.in_stream_map); - if (s->global.id != 0) { - GPR_ASSERT(grpc_chttp2_stream_map_find(&t->stream_map, s->global.id) == - NULL); + GPR_ASSERT((s->write_closed && s->read_closed) || s->id == 0); + GPR_ASSERT(!s->in_stream_map); + if (s->id != 0) { + GPR_ASSERT(grpc_chttp2_stream_map_find(&t->stream_map, s->id) == NULL); } - while ( - (bs = grpc_chttp2_incoming_frame_queue_pop(&s->global.incoming_frames))) { + while ((bs = grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames))) { incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE); } - grpc_chttp2_list_remove_stalled_by_transport(&t->global, &s->global); - grpc_chttp2_list_remove_check_read_ops(&t->global, &s->global); + grpc_chttp2_list_remove_stalled_by_transport(t, s); + grpc_chttp2_list_remove_check_read_ops(t, s); for (int i = 0; i < STREAM_LIST_COUNT; i++) { if (s->included[i]) { gpr_log(GPR_ERROR, "%s stream %d still included in list %d", - t->global.is_client ? "client" : "server", s->global.id, i); + t->is_client ? "client" : "server", s->id, i); abort(); } } - GPR_ASSERT(s->global.send_initial_metadata_finished == NULL); - GPR_ASSERT(s->global.send_message_finished == NULL); - GPR_ASSERT(s->global.send_trailing_metadata_finished == NULL); - GPR_ASSERT(s->global.recv_initial_metadata_ready == NULL); - GPR_ASSERT(s->global.recv_message_ready == NULL); - GPR_ASSERT(s->global.recv_trailing_metadata_finished == NULL); - grpc_chttp2_data_parser_destroy(exec_ctx, &s->global.data_parser); - grpc_chttp2_incoming_metadata_buffer_destroy(&s->global.metadata_buffer[0]); - grpc_chttp2_incoming_metadata_buffer_destroy(&s->global.metadata_buffer[1]); - gpr_slice_buffer_destroy(&s->writing.flow_controlled_buffer); - GRPC_ERROR_UNREF(s->global.read_closed_error); - GRPC_ERROR_UNREF(s->global.write_closed_error); + GPR_ASSERT(s->send_initial_metadata_finished == NULL); + GPR_ASSERT(s->send_message_finished == NULL); + GPR_ASSERT(s->send_trailing_metadata_finished == NULL); + GPR_ASSERT(s->recv_initial_metadata_ready == NULL); + GPR_ASSERT(s->recv_message_ready == NULL); + GPR_ASSERT(s->recv_trailing_metadata_finished == NULL); + grpc_chttp2_data_parser_destroy(exec_ctx, &s->data_parser); + grpc_chttp2_incoming_metadata_buffer_destroy(&s->metadata_buffer[0]); + grpc_chttp2_incoming_metadata_buffer_destroy(&s->metadata_buffer[1]); + gpr_slice_buffer_destroy(&s->flow_controlled_buffer); + GRPC_ERROR_UNREF(s->read_closed_error); + GRPC_ERROR_UNREF(s->write_closed_error); GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "stream"); @@ -559,76 +515,47 @@ static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, s->destroy_stream_arg = and_free_memory; grpc_closure_init(&s->destroy_stream, destroy_stream_locked, s); - grpc_combiner_execute(exec_ctx, t->executor.combiner, &s->destroy_stream, + grpc_combiner_execute(exec_ctx, t->combiner, &s->destroy_stream, GRPC_ERROR_NONE); GPR_TIMER_END("destroy_stream", 0); } -grpc_chttp2_stream_global *grpc_chttp2_parsing_lookup_stream( - grpc_chttp2_transport_global *transport_global, uint32_t id) { - grpc_chttp2_transport *t = TRANSPORT_FROM_GLOBAL(transport_global); - grpc_chttp2_stream *s = grpc_chttp2_stream_map_find(&t->stream_map, id); - return s ? &s->global : NULL; +grpc_chttp2_stream *grpc_chttp2_parsing_lookup_stream(grpc_chttp2_transport *t, + uint32_t id) { + return grpc_chttp2_stream_map_find(&t->stream_map, id); } -grpc_chttp2_stream_global *grpc_chttp2_parsing_accept_stream( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - uint32_t id) { +grpc_chttp2_stream *grpc_chttp2_parsing_accept_stream(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + uint32_t id) { grpc_chttp2_stream *accepting; - grpc_chttp2_transport *t = TRANSPORT_FROM_GLOBAL(transport_global); GPR_ASSERT(t->accepting_stream == NULL); t->accepting_stream = &accepting; t->channel_callback.accept_stream(exec_ctx, t->channel_callback.accept_stream_user_data, &t->base, (void *)(uintptr_t)id); t->accepting_stream = NULL; - return &accepting->global; + return accepting; } /******************************************************************************* * LOCK MANAGEMENT */ -static const char *write_state_name(grpc_chttp2_write_state state) { - switch (state) { - case GRPC_CHTTP2_WRITES_CORKED: - return "CORKED"; - case GRPC_CHTTP2_WRITING_INACTIVE: - return "INACTIVE"; - case GRPC_CHTTP2_WRITE_SCHEDULED: - return "SCHEDULED"; - case GRPC_CHTTP2_WRITING: - return "WRITING"; - case GRPC_CHTTP2_WRITING_STALE_WITH_POLLER: - return "WRITING[p=1]"; - case GRPC_CHTTP2_WRITING_STALE_NO_POLLER: - return "WRITING[p=0]"; - } - GPR_UNREACHABLE_CODE(return "UNKNOWN"); -} - -static void set_write_state(grpc_chttp2_transport *t, - grpc_chttp2_write_state state, const char *reason) { - if (grpc_http_write_state_trace) { - gpr_log(GPR_DEBUG, "W:%p %s -> %s because %s", t, - write_state_name(t->executor.write_state), write_state_name(state), - reason); - } - t->executor.write_state = state; -} - +#if 0 static void initiate_writing_locked(grpc_exec_ctx *exec_ctx, void *tp, grpc_error *error) { grpc_chttp2_transport *t = tp; GPR_ASSERT(t->executor.write_state == GRPC_CHTTP2_WRITE_SCHEDULED); start_writing(exec_ctx, t); } +#endif static void initiate_read_flush_locked(grpc_exec_ctx *exec_ctx, void *tp, grpc_error *error) { grpc_chttp2_transport *t = tp; - t->executor.check_read_ops_scheduled = false; - check_read_ops(exec_ctx, &t->global); + t->check_read_ops_scheduled = false; + check_read_ops(exec_ctx, t); GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "initiate_read_flush_locked"); } @@ -637,98 +564,49 @@ static void initiate_read_flush_locked(grpc_exec_ctx *exec_ctx, void *tp, */ void grpc_chttp2_initiate_write(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_global *transport_global, + grpc_chttp2_transport *t, bool covered_by_poller, const char *reason) { GPR_TIMER_BEGIN("grpc_chttp2_initiate_write", 0); - /* Perform state checks, and transition to a scheduled state if appropriate. - If we are inactive, schedule a write chain to begin once the transport - combiner finishes any executions in its current batch (which may be - scheduled AFTER this code executes). The write chain will: - - call start_writing, which verifies (under the global lock) that there - are things that need to be written by calling - grpc_chttp2_unlocking_check_writes, and if so schedules writing_action - against the current exec_ctx, to be executed OUTSIDE of the global lock - - eventually writing_action results in grpc_chttp2_terminate_writing being - called, which re-takes the global lock, updates state, checks if we need - to do *another* write immediately, and if so loops back to - start_writing. - - Current problems: - - too much lock entry/exiting - - the writing thread can become stuck indefinitely (punt through the - workqueue periodically to fix) */ - - grpc_chttp2_transport *t = TRANSPORT_FROM_GLOBAL(transport_global); - switch (t->executor.write_state) { - case GRPC_CHTTP2_WRITES_CORKED: - break; - case GRPC_CHTTP2_WRITING_INACTIVE: - set_write_state(t, GRPC_CHTTP2_WRITE_SCHEDULED, reason); + switch (t->write_state) { + case GRPC_CHTTP2_WRITE_STATE_IDLE: + t->write_state = GRPC_CHTTP2_WRITE_STATE_WRITING; GRPC_CHTTP2_REF_TRANSPORT(t, "writing"); - grpc_combiner_execute_finally(exec_ctx, t->executor.combiner, - &t->initiate_writing, GRPC_ERROR_NONE, - covered_by_poller); - break; - case GRPC_CHTTP2_WRITE_SCHEDULED: - if (covered_by_poller) { - /* upgrade to note poller is available to cover the write */ - grpc_combiner_force_async_finally(t->executor.combiner); - } + grpc_combiner_execute_finally(exec_ctx, t->combiner, &t->writing_action, + GRPC_ERROR_NONE, false); break; - case GRPC_CHTTP2_WRITING: - set_write_state(t, - covered_by_poller ? GRPC_CHTTP2_WRITING_STALE_WITH_POLLER - : GRPC_CHTTP2_WRITING_STALE_NO_POLLER, - reason); + case GRPC_CHTTP2_WRITE_STATE_WRITING: + t->write_state = GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_TO_COME; break; - case GRPC_CHTTP2_WRITING_STALE_WITH_POLLER: - /* nothing to do: write already requested */ - break; - case GRPC_CHTTP2_WRITING_STALE_NO_POLLER: - if (covered_by_poller) { - /* upgrade to note poller is available to cover the write */ - set_write_state(t, GRPC_CHTTP2_WRITING_STALE_WITH_POLLER, reason); - } + case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_TO_COME: break; } GPR_TIMER_END("grpc_chttp2_initiate_write", 0); } +void grpc_chttp2_become_writable(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s, bool covered_by_poller, + const char *reason) { + if (!t->closed && grpc_chttp2_list_add_writable_stream(t, s)) { + GRPC_CHTTP2_STREAM_REF(s, "chttp2_writing"); + grpc_chttp2_initiate_write(exec_ctx, t, covered_by_poller, reason); + } +} + static void start_writing(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t) { GPR_TIMER_BEGIN("start_writing", 0); - GPR_ASSERT(t->executor.write_state == GRPC_CHTTP2_WRITE_SCHEDULED); - if (!t->closed && - grpc_chttp2_unlocking_check_writes(exec_ctx, &t->global, &t->writing)) { - set_write_state(t, GRPC_CHTTP2_WRITING, "start_writing"); + GPR_ASSERT(t->write_state != GRPC_CHTTP2_WRITE_STATE_IDLE); + if (!t->closed && grpc_chttp2_begin_write(exec_ctx, t)) { prevent_endpoint_shutdown(t); grpc_exec_ctx_sched(exec_ctx, &t->writing_action, GRPC_ERROR_NONE, NULL); } else { - if (t->closed) { - set_write_state(t, GRPC_CHTTP2_WRITING_INACTIVE, - "start_writing:transport_closed"); - } else { - set_write_state(t, GRPC_CHTTP2_WRITING_INACTIVE, - "start_writing:nothing_to_write"); - } - end_waiting_for_write(exec_ctx, t, GRPC_ERROR_NONE); + t->write_state = GRPC_CHTTP2_WRITE_STATE_IDLE; GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "writing"); } GPR_TIMER_END("start_writing", 0); } -void grpc_chttp2_become_writable(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, - bool covered_by_poller, const char *reason) { - if (!TRANSPORT_FROM_GLOBAL(transport_global)->closed && - grpc_chttp2_list_add_writable_stream(transport_global, stream_global)) { - GRPC_CHTTP2_STREAM_REF(stream_global, "chttp2_writing"); - grpc_chttp2_initiate_write(exec_ctx, transport_global, covered_by_poller, - reason); - } -} - static void push_setting(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_setting_id id, uint32_t value) { const grpc_chttp2_setting_parameters *sp = @@ -738,25 +616,11 @@ static void push_setting(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, gpr_log(GPR_INFO, "Requested parameter %s clamped from %d to %d", sp->name, value, use_value); } - if (use_value != t->global.settings[GRPC_LOCAL_SETTINGS][id]) { - t->global.settings[GRPC_LOCAL_SETTINGS][id] = use_value; - t->global.dirtied_local_settings = 1; - grpc_chttp2_initiate_write(exec_ctx, &t->global, false, "push_setting"); - } -} - -/* error may be GRPC_ERROR_NONE if there is no error allocated yet. - In that case, use "reason" as the text for a new error. */ -static void end_waiting_for_write(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport *t, grpc_error *error) { - grpc_chttp2_stream_global *stream_global; - while (grpc_chttp2_list_pop_closed_waiting_for_writing(&t->global, - &stream_global)) { - fail_pending_writes(exec_ctx, &t->global, stream_global, - GRPC_ERROR_REF(error)); - GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "finish_writes"); + if (use_value != t->settings[GRPC_LOCAL_SETTINGS][id]) { + t->settings[GRPC_LOCAL_SETTINGS][id] = use_value; + t->dirtied_local_settings = 1; + grpc_chttp2_initiate_write(exec_ctx, t, false, "push_setting"); } - GRPC_ERROR_UNREF(error); } static void terminate_writing_with_lock(grpc_exec_ctx *exec_ctx, void *tp, @@ -769,34 +633,21 @@ static void terminate_writing_with_lock(grpc_exec_ctx *exec_ctx, void *tp, drop_connection(exec_ctx, t, GRPC_ERROR_REF(error)); } - grpc_chttp2_cleanup_writing(exec_ctx, &t->global, &t->writing); - - end_waiting_for_write(exec_ctx, t, GRPC_ERROR_REF(error)); + grpc_chttp2_end_write(exec_ctx, t, GRPC_ERROR_REF(error)); - switch (t->executor.write_state) { - case GRPC_CHTTP2_WRITES_CORKED: - case GRPC_CHTTP2_WRITING_INACTIVE: - case GRPC_CHTTP2_WRITE_SCHEDULED: + switch (t->write_state) { + case GRPC_CHTTP2_WRITE_STATE_IDLE: GPR_UNREACHABLE_CODE(break); - case GRPC_CHTTP2_WRITING: + case GRPC_CHTTP2_WRITE_STATE_WRITING: GPR_TIMER_MARK("state=writing", 0); - set_write_state(t, GRPC_CHTTP2_WRITING_INACTIVE, "terminate_writing"); + t->write_state = GRPC_CHTTP2_WRITE_STATE_IDLE; break; - case GRPC_CHTTP2_WRITING_STALE_WITH_POLLER: + case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_TO_COME: GPR_TIMER_MARK("state=writing_stale_with_poller", 0); - set_write_state(t, GRPC_CHTTP2_WRITE_SCHEDULED, "terminate_writing"); - GRPC_CHTTP2_REF_TRANSPORT(t, "writing"); - grpc_combiner_execute_finally(exec_ctx, t->executor.combiner, - &t->initiate_writing, GRPC_ERROR_NONE, - true); - break; - case GRPC_CHTTP2_WRITING_STALE_NO_POLLER: - GPR_TIMER_MARK("state=writing_stale_no_poller", 0); - set_write_state(t, GRPC_CHTTP2_WRITE_SCHEDULED, "terminate_writing"); + t->write_state = GRPC_CHTTP2_WRITE_STATE_WRITING; GRPC_CHTTP2_REF_TRANSPORT(t, "writing"); - grpc_combiner_execute_finally(exec_ctx, t->executor.combiner, - &t->initiate_writing, GRPC_ERROR_NONE, - false); + grpc_combiner_execute_finally(exec_ctx, t->combiner, &t->writing_action, + GRPC_ERROR_NONE, false); break; } @@ -804,11 +655,11 @@ static void terminate_writing_with_lock(grpc_exec_ctx *exec_ctx, void *tp, GPR_TIMER_END("terminate_writing_with_lock", 0); } -void grpc_chttp2_terminate_writing(grpc_exec_ctx *exec_ctx, - void *transport_writing, grpc_error *error) { +static void grpc_chttp2_terminate_writing(grpc_exec_ctx *exec_ctx, void *gt, + grpc_error *error) { GPR_TIMER_BEGIN("grpc_chttp2_terminate_writing", 0); - grpc_chttp2_transport *t = TRANSPORT_FROM_WRITING(transport_writing); - grpc_combiner_execute(exec_ctx, t->executor.combiner, &t->terminate_writing, + grpc_chttp2_transport *t = gt; + grpc_combiner_execute(exec_ctx, t->combiner, &t->terminate_writing, GRPC_ERROR_REF(error)); GPR_TIMER_END("grpc_chttp2_terminate_writing", 0); } @@ -817,22 +668,23 @@ static void writing_action(grpc_exec_ctx *exec_ctx, void *gt, grpc_error *error) { grpc_chttp2_transport *t = gt; GPR_TIMER_BEGIN("writing_action", 0); - grpc_chttp2_perform_writes(exec_ctx, &t->writing, t->ep); + grpc_endpoint_write(exec_ctx, t->ep, &t->outbuf, &t->writing_done_action); GPR_TIMER_END("writing_action", 0); } -void grpc_chttp2_add_incoming_goaway( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - uint32_t goaway_error, gpr_slice goaway_text) { +void grpc_chttp2_add_incoming_goaway(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + uint32_t goaway_error, + gpr_slice goaway_text) { char *msg = gpr_dump_slice(goaway_text, GPR_DUMP_HEX | GPR_DUMP_ASCII); GRPC_CHTTP2_IF_TRACING( gpr_log(GPR_DEBUG, "got goaway [%d]: %s", goaway_error, msg)); gpr_slice_unref(goaway_text); - transport_global->seen_goaway = 1; + t->seen_goaway = 1; /* lie: use transient failure from the transport to indicate goaway has been * received */ connectivity_state_set( - exec_ctx, transport_global, GRPC_CHANNEL_TRANSIENT_FAILURE, + exec_ctx, t, GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_set_str( grpc_error_set_int(GRPC_ERROR_CREATE("GOAWAY received"), GRPC_ERROR_INT_HTTP2_ERROR, @@ -842,57 +694,47 @@ void grpc_chttp2_add_incoming_goaway( gpr_free(msg); } -static void maybe_start_some_streams( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global) { - grpc_chttp2_stream_global *stream_global; +static void maybe_start_some_streams(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t) { + grpc_chttp2_stream *s; uint32_t stream_incoming_window; /* start streams where we have free grpc_chttp2_stream ids and free * concurrency */ - while (transport_global->next_stream_id <= MAX_CLIENT_STREAM_ID && - grpc_chttp2_stream_map_size( - &TRANSPORT_FROM_GLOBAL(transport_global)->stream_map) < - transport_global - ->settings[GRPC_PEER_SETTINGS] - [GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS] && - grpc_chttp2_list_pop_waiting_for_concurrency(transport_global, - &stream_global)) { + while (t->next_stream_id <= MAX_CLIENT_STREAM_ID && + grpc_chttp2_stream_map_size(&t->stream_map) < + t->settings[GRPC_PEER_SETTINGS] + [GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS] && + grpc_chttp2_list_pop_waiting_for_concurrency(t, &s)) { /* safe since we can't (legally) be parsing this stream yet */ GRPC_CHTTP2_IF_TRACING(gpr_log( GPR_DEBUG, "HTTP:%s: Allocating new grpc_chttp2_stream %p to id %d", - transport_global->is_client ? "CLI" : "SVR", stream_global, - transport_global->next_stream_id)); + t->is_client ? "CLI" : "SVR", s, t->next_stream_id)); - GPR_ASSERT(stream_global->id == 0); - stream_global->id = transport_global->next_stream_id; - transport_global->next_stream_id += 2; + GPR_ASSERT(s->id == 0); + s->id = t->next_stream_id; + t->next_stream_id += 2; - if (transport_global->next_stream_id >= MAX_CLIENT_STREAM_ID) { - connectivity_state_set( - exec_ctx, transport_global, GRPC_CHANNEL_TRANSIENT_FAILURE, - GRPC_ERROR_CREATE("Stream IDs exhausted"), "no_more_stream_ids"); + if (t->next_stream_id >= MAX_CLIENT_STREAM_ID) { + connectivity_state_set(exec_ctx, t, GRPC_CHANNEL_TRANSIENT_FAILURE, + GRPC_ERROR_CREATE("Stream IDs exhausted"), + "no_more_stream_ids"); } - stream_global->outgoing_window = - transport_global->settings[GRPC_PEER_SETTINGS] - [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]; - stream_global->incoming_window = stream_incoming_window = - transport_global->settings[GRPC_SENT_SETTINGS] - [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]; - stream_global->max_recv_bytes = - GPR_MAX(stream_incoming_window, stream_global->max_recv_bytes); - grpc_chttp2_stream_map_add( - &TRANSPORT_FROM_GLOBAL(transport_global)->stream_map, stream_global->id, - STREAM_FROM_GLOBAL(stream_global)); - stream_global->in_stream_map = true; - grpc_chttp2_become_writable(exec_ctx, transport_global, stream_global, true, - "new_stream"); + s->outgoing_window = t->settings[GRPC_PEER_SETTINGS] + [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]; + s->incoming_window = stream_incoming_window = + t->settings[GRPC_SENT_SETTINGS] + [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]; + s->max_recv_bytes = GPR_MAX(stream_incoming_window, s->max_recv_bytes); + grpc_chttp2_stream_map_add(&t->stream_map, s->id, s); + s->in_stream_map = true; + grpc_chttp2_become_writable(exec_ctx, t, s, true, "new_stream"); } /* cancel out streams that will never be started */ - while (transport_global->next_stream_id >= MAX_CLIENT_STREAM_ID && - grpc_chttp2_list_pop_waiting_for_concurrency(transport_global, - &stream_global)) { + while (t->next_stream_id >= MAX_CLIENT_STREAM_ID && + grpc_chttp2_list_pop_waiting_for_concurrency(t, &s)) { grpc_chttp2_cancel_stream( - exec_ctx, transport_global, stream_global, + exec_ctx, t, s, grpc_error_set_int(GRPC_ERROR_CREATE("Stream IDs exhausted"), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE)); @@ -907,10 +749,11 @@ static grpc_closure *add_closure_barrier(grpc_closure *closure) { return closure; } -void grpc_chttp2_complete_closure_step( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, grpc_closure **pclosure, - grpc_error *error) { +void grpc_chttp2_complete_closure_step(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s, + grpc_closure **pclosure, + grpc_error *error) { grpc_closure *closure = *pclosure; if (closure == NULL) { GRPC_ERROR_UNREF(error); @@ -922,33 +765,29 @@ void grpc_chttp2_complete_closure_step( closure->error = GRPC_ERROR_CREATE("Error in HTTP transport completing operation"); closure->error = grpc_error_set_str( - closure->error, GRPC_ERROR_STR_TARGET_ADDRESS, - TRANSPORT_FROM_GLOBAL(transport_global)->peer_string); + closure->error, GRPC_ERROR_STR_TARGET_ADDRESS, t->peer_string); } closure->error = grpc_error_add_child(closure->error, error); } if (closure->next_data.scratch < CLOSURE_BARRIER_FIRST_REF_BIT) { if (closure->next_data.scratch & CLOSURE_BARRIER_STATS_BIT) { - grpc_transport_move_stats(&stream_global->stats, - stream_global->collecting_stats); - stream_global->collecting_stats = NULL; + grpc_transport_move_stats(&s->stats, s->collecting_stats); + s->collecting_stats = NULL; } grpc_exec_ctx_sched(exec_ctx, closure, closure->error, NULL); } *pclosure = NULL; } -static int contains_non_ok_status( - grpc_chttp2_transport_global *transport_global, - grpc_metadata_batch *batch) { +static bool contains_non_ok_status(grpc_metadata_batch *batch) { grpc_linked_mdelem *l; for (l = batch->list.head; l; l = l->next) { if (l->md->key == GRPC_MDSTR_GRPC_STATUS && l->md != GRPC_MDELEM_GRPC_STATUS_0) { - return 1; + return true; } } - return 0; + return false; } static void do_nothing(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {} @@ -960,8 +799,6 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, grpc_transport_stream_op *op = stream_op; grpc_chttp2_transport *t = op->transport_private.args[0]; grpc_chttp2_stream *s = op->transport_private.args[1]; - grpc_chttp2_transport_global *transport_global = &t->global; - grpc_chttp2_stream_global *stream_global = &s->global; if (grpc_http_trace) { char *str = grpc_transport_stream_op_string(op); @@ -979,39 +816,35 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, on_complete->error = GRPC_ERROR_NONE; if (op->collect_stats != NULL) { - GPR_ASSERT(stream_global->collecting_stats == NULL); - stream_global->collecting_stats = op->collect_stats; + GPR_ASSERT(s->collecting_stats == NULL); + s->collecting_stats = op->collect_stats; on_complete->next_data.scratch |= CLOSURE_BARRIER_STATS_BIT; } if (op->cancel_error != GRPC_ERROR_NONE) { - grpc_chttp2_cancel_stream(exec_ctx, transport_global, stream_global, - GRPC_ERROR_REF(op->cancel_error)); + grpc_chttp2_cancel_stream(exec_ctx, t, s, GRPC_ERROR_REF(op->cancel_error)); } if (op->close_error != GRPC_ERROR_NONE) { - close_from_api(exec_ctx, transport_global, stream_global, - GRPC_ERROR_REF(op->close_error)); + close_from_api(exec_ctx, t, s, GRPC_ERROR_REF(op->close_error)); } if (op->send_initial_metadata != NULL) { - GPR_ASSERT(stream_global->send_initial_metadata_finished == NULL); - stream_global->send_initial_metadata_finished = - add_closure_barrier(on_complete); - stream_global->send_initial_metadata = op->send_initial_metadata; + GPR_ASSERT(s->send_initial_metadata_finished == NULL); + s->send_initial_metadata_finished = add_closure_barrier(on_complete); + s->send_initial_metadata = op->send_initial_metadata; const size_t metadata_size = grpc_metadata_batch_size(op->send_initial_metadata); const size_t metadata_peer_limit = - transport_global->settings[GRPC_PEER_SETTINGS] - [GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE]; - if (transport_global->is_client) { - stream_global->deadline = - gpr_time_min(stream_global->deadline, - stream_global->send_initial_metadata->deadline); + t->settings[GRPC_PEER_SETTINGS] + [GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE]; + if (t->is_client) { + s->deadline = + gpr_time_min(s->deadline, s->send_initial_metadata->deadline); } if (metadata_size > metadata_peer_limit) { grpc_chttp2_cancel_stream( - exec_ctx, transport_global, stream_global, + exec_ctx, t, s, grpc_error_set_int( grpc_error_set_int( grpc_error_set_int( @@ -1021,27 +854,24 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, GRPC_ERROR_INT_LIMIT, (intptr_t)metadata_peer_limit), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED)); } else { - if (contains_non_ok_status(transport_global, op->send_initial_metadata)) { - stream_global->seen_error = true; - grpc_chttp2_list_add_check_read_ops(exec_ctx, transport_global, - stream_global); + if (contains_non_ok_status(op->send_initial_metadata)) { + s->seen_error = true; + grpc_chttp2_list_add_check_read_ops(exec_ctx, t, s); } - if (!stream_global->write_closed) { - if (transport_global->is_client) { - GPR_ASSERT(stream_global->id == 0); - grpc_chttp2_list_add_waiting_for_concurrency(transport_global, - stream_global); - maybe_start_some_streams(exec_ctx, transport_global); + if (!s->write_closed) { + if (t->is_client) { + GPR_ASSERT(s->id == 0); + grpc_chttp2_list_add_waiting_for_concurrency(t, s); + maybe_start_some_streams(exec_ctx, t); } else { - GPR_ASSERT(stream_global->id != 0); - grpc_chttp2_become_writable(exec_ctx, transport_global, stream_global, - true, "op.send_initial_metadata"); + GPR_ASSERT(s->id != 0); + grpc_chttp2_become_writable(exec_ctx, t, s, true, + "op.send_initial_metadata"); } } else { - stream_global->send_trailing_metadata = NULL; + s->send_trailing_metadata = NULL; grpc_chttp2_complete_closure_step( - exec_ctx, transport_global, stream_global, - &stream_global->send_initial_metadata_finished, + exec_ctx, t, s, &s->send_initial_metadata_finished, GRPC_ERROR_CREATE( "Attempt to send initial metadata after stream was closed")); } @@ -1049,36 +879,33 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, } if (op->send_message != NULL) { - GPR_ASSERT(stream_global->send_message_finished == NULL); - GPR_ASSERT(stream_global->send_message == NULL); - stream_global->send_message_finished = add_closure_barrier(on_complete); - if (stream_global->write_closed) { + GPR_ASSERT(s->send_message_finished == NULL); + GPR_ASSERT(s->send_message == NULL); + s->send_message_finished = add_closure_barrier(on_complete); + if (s->write_closed) { grpc_chttp2_complete_closure_step( - exec_ctx, transport_global, stream_global, - &stream_global->send_message_finished, + exec_ctx, t, s, &s->send_message_finished, GRPC_ERROR_CREATE("Attempt to send message after stream was closed")); } else { - stream_global->send_message = op->send_message; - if (stream_global->id != 0) { - grpc_chttp2_become_writable(exec_ctx, transport_global, stream_global, - true, "op.send_message"); + s->send_message = op->send_message; + if (s->id != 0) { + grpc_chttp2_become_writable(exec_ctx, t, s, true, "op.send_message"); } } } if (op->send_trailing_metadata != NULL) { - GPR_ASSERT(stream_global->send_trailing_metadata_finished == NULL); - stream_global->send_trailing_metadata_finished = - add_closure_barrier(on_complete); - stream_global->send_trailing_metadata = op->send_trailing_metadata; + GPR_ASSERT(s->send_trailing_metadata_finished == NULL); + s->send_trailing_metadata_finished = add_closure_barrier(on_complete); + s->send_trailing_metadata = op->send_trailing_metadata; const size_t metadata_size = grpc_metadata_batch_size(op->send_trailing_metadata); const size_t metadata_peer_limit = - transport_global->settings[GRPC_PEER_SETTINGS] - [GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE]; + t->settings[GRPC_PEER_SETTINGS] + [GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE]; if (metadata_size > metadata_peer_limit) { grpc_chttp2_cancel_stream( - exec_ctx, transport_global, stream_global, + exec_ctx, t, s, grpc_error_set_int( grpc_error_set_int( grpc_error_set_int( @@ -1088,69 +915,59 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, GRPC_ERROR_INT_LIMIT, (intptr_t)metadata_peer_limit), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED)); } else { - if (contains_non_ok_status(transport_global, - op->send_trailing_metadata)) { - stream_global->seen_error = true; - grpc_chttp2_list_add_check_read_ops(exec_ctx, transport_global, - stream_global); + if (contains_non_ok_status(op->send_trailing_metadata)) { + s->seen_error = true; + grpc_chttp2_list_add_check_read_ops(exec_ctx, t, s); } - if (stream_global->write_closed) { - stream_global->send_trailing_metadata = NULL; + if (s->write_closed) { + s->send_trailing_metadata = NULL; grpc_chttp2_complete_closure_step( - exec_ctx, transport_global, stream_global, - &stream_global->send_trailing_metadata_finished, + exec_ctx, t, s, &s->send_trailing_metadata_finished, grpc_metadata_batch_is_empty(op->send_trailing_metadata) ? GRPC_ERROR_NONE : GRPC_ERROR_CREATE("Attempt to send trailing metadata after " "stream was closed")); - } else if (stream_global->id != 0) { + } else if (s->id != 0) { /* TODO(ctiller): check if there's flow control for any outstanding bytes before going writable */ - grpc_chttp2_become_writable(exec_ctx, transport_global, stream_global, - true, "op.send_trailing_metadata"); + grpc_chttp2_become_writable(exec_ctx, t, s, true, + "op.send_trailing_metadata"); } } } if (op->recv_initial_metadata != NULL) { - GPR_ASSERT(stream_global->recv_initial_metadata_ready == NULL); - stream_global->recv_initial_metadata_ready = - op->recv_initial_metadata_ready; - stream_global->recv_initial_metadata = op->recv_initial_metadata; - grpc_chttp2_list_add_check_read_ops(exec_ctx, transport_global, - stream_global); + GPR_ASSERT(s->recv_initial_metadata_ready == NULL); + s->recv_initial_metadata_ready = op->recv_initial_metadata_ready; + s->recv_initial_metadata = op->recv_initial_metadata; + grpc_chttp2_list_add_check_read_ops(exec_ctx, t, s); } if (op->recv_message != NULL) { - GPR_ASSERT(stream_global->recv_message_ready == NULL); - stream_global->recv_message_ready = op->recv_message_ready; - stream_global->recv_message = op->recv_message; - if (stream_global->id != 0 && - (stream_global->incoming_frames.head == NULL || - stream_global->incoming_frames.head->is_tail)) { - incoming_byte_stream_update_flow_control( - exec_ctx, transport_global, stream_global, - transport_global->stream_lookahead, 0); + GPR_ASSERT(s->recv_message_ready == NULL); + s->recv_message_ready = op->recv_message_ready; + s->recv_message = op->recv_message; + if (s->id != 0 && + (s->incoming_frames.head == NULL || s->incoming_frames.head->is_tail)) { + incoming_byte_stream_update_flow_control(exec_ctx, t, s, + t->stream_lookahead, 0); } - grpc_chttp2_list_add_check_read_ops(exec_ctx, transport_global, - stream_global); + grpc_chttp2_list_add_check_read_ops(exec_ctx, t, s); } if (op->recv_trailing_metadata != NULL) { - GPR_ASSERT(stream_global->recv_trailing_metadata_finished == NULL); - stream_global->recv_trailing_metadata_finished = - add_closure_barrier(on_complete); - stream_global->recv_trailing_metadata = op->recv_trailing_metadata; - stream_global->final_metadata_requested = true; - grpc_chttp2_list_add_check_read_ops(exec_ctx, transport_global, - stream_global); + GPR_ASSERT(s->recv_trailing_metadata_finished == NULL); + s->recv_trailing_metadata_finished = add_closure_barrier(on_complete); + s->recv_trailing_metadata = op->recv_trailing_metadata; + s->final_metadata_requested = true; + grpc_chttp2_list_add_check_read_ops(exec_ctx, t, s); } - grpc_chttp2_complete_closure_step(exec_ctx, transport_global, stream_global, - &on_complete, GRPC_ERROR_NONE); + grpc_chttp2_complete_closure_step(exec_ctx, t, s, &on_complete, + GRPC_ERROR_NONE); GPR_TIMER_END("perform_stream_op_locked", 0); - GRPC_CHTTP2_STREAM_UNREF(exec_ctx, &s->global, "perform_stream_op"); + GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "perform_stream_op"); } static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, @@ -1162,38 +979,36 @@ static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, op); op->transport_private.args[0] = gt; op->transport_private.args[1] = gs; - GRPC_CHTTP2_STREAM_REF(&s->global, "perform_stream_op"); - grpc_combiner_execute(exec_ctx, t->executor.combiner, - &op->transport_private.closure, GRPC_ERROR_NONE); + GRPC_CHTTP2_STREAM_REF(s, "perform_stream_op"); + grpc_combiner_execute(exec_ctx, t->combiner, &op->transport_private.closure, + GRPC_ERROR_NONE); GPR_TIMER_END("perform_stream_op", 0); } static void send_ping_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_closure *on_recv) { grpc_chttp2_outstanding_ping *p = gpr_malloc(sizeof(*p)); - p->next = &t->global.pings; + p->next = &t->pings; p->prev = p->next->prev; p->prev->next = p->next->prev = p; - p->id[0] = (uint8_t)((t->global.ping_counter >> 56) & 0xff); - p->id[1] = (uint8_t)((t->global.ping_counter >> 48) & 0xff); - p->id[2] = (uint8_t)((t->global.ping_counter >> 40) & 0xff); - p->id[3] = (uint8_t)((t->global.ping_counter >> 32) & 0xff); - p->id[4] = (uint8_t)((t->global.ping_counter >> 24) & 0xff); - p->id[5] = (uint8_t)((t->global.ping_counter >> 16) & 0xff); - p->id[6] = (uint8_t)((t->global.ping_counter >> 8) & 0xff); - p->id[7] = (uint8_t)(t->global.ping_counter & 0xff); - t->global.ping_counter++; + p->id[0] = (uint8_t)((t->ping_counter >> 56) & 0xff); + p->id[1] = (uint8_t)((t->ping_counter >> 48) & 0xff); + p->id[2] = (uint8_t)((t->ping_counter >> 40) & 0xff); + p->id[3] = (uint8_t)((t->ping_counter >> 32) & 0xff); + p->id[4] = (uint8_t)((t->ping_counter >> 24) & 0xff); + p->id[5] = (uint8_t)((t->ping_counter >> 16) & 0xff); + p->id[6] = (uint8_t)((t->ping_counter >> 8) & 0xff); + p->id[7] = (uint8_t)(t->ping_counter & 0xff); + t->ping_counter++; p->on_recv = on_recv; - gpr_slice_buffer_add(&t->global.qbuf, grpc_chttp2_ping_create(0, p->id)); - grpc_chttp2_initiate_write(exec_ctx, &t->global, true, "send_ping"); + gpr_slice_buffer_add(&t->qbuf, grpc_chttp2_ping_create(0, p->id)); + grpc_chttp2_initiate_write(exec_ctx, t, true, "send_ping"); } -void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_global *transport_global, +void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, const uint8_t *opaque_8bytes) { grpc_chttp2_outstanding_ping *ping; - for (ping = transport_global->pings.next; ping != &transport_global->pings; - ping = ping->next) { + for (ping = t->pings.next; ping != &t->pings; ping = ping->next) { if (0 == memcmp(opaque_8bytes, ping->id, 8)) { grpc_exec_ctx_sched(exec_ctx, ping->on_recv, GRPC_ERROR_NONE, NULL); ping->next->prev = ping->prev; @@ -1203,8 +1018,7 @@ void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, } } char *msg = gpr_dump((const char *)opaque_8bytes, 8, GPR_DUMP_HEX); - char *from = - grpc_endpoint_get_peer(TRANSPORT_FROM_GLOBAL(transport_global)->ep); + char *from = grpc_endpoint_get_peer(t->ep); gpr_log(GPR_DEBUG, "Unknown ping response from %s: %s", from, msg); gpr_free(from); gpr_free(msg); @@ -1224,15 +1038,15 @@ static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx, } if (op->send_goaway) { - t->global.sent_goaway = 1; + t->sent_goaway = 1; grpc_chttp2_goaway_append( - t->global.last_incoming_stream_id, + t->last_incoming_stream_id, (uint32_t)grpc_chttp2_grpc_status_to_http2_error(op->goaway_status), - gpr_slice_ref(*op->goaway_message), &t->global.qbuf); + gpr_slice_ref(*op->goaway_message), &t->qbuf); close_transport = grpc_chttp2_stream_map_size(&t->stream_map) == 0 ? GRPC_ERROR_CREATE("GOAWAY sent") : GRPC_ERROR_NONE; - grpc_chttp2_initiate_write(exec_ctx, &t->global, false, "goaway_sent"); + grpc_chttp2_initiate_write(exec_ctx, t, false, "goaway_sent"); } if (op->set_accept_stream) { @@ -1269,85 +1083,77 @@ static void perform_transport_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, grpc_closure_init(&op->transport_private.closure, perform_transport_op_locked, op); GRPC_CHTTP2_REF_TRANSPORT(t, "transport_op"); - grpc_combiner_execute(exec_ctx, t->executor.combiner, - &op->transport_private.closure, GRPC_ERROR_NONE); + grpc_combiner_execute(exec_ctx, t->combiner, &op->transport_private.closure, + GRPC_ERROR_NONE); } /******************************************************************************* * INPUT PROCESSING - GENERAL */ -static void check_read_ops(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_global *transport_global) { +static void check_read_ops(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t) { GPR_TIMER_BEGIN("check_read_ops", 0); - grpc_chttp2_stream_global *stream_global; + grpc_chttp2_stream *s; grpc_byte_stream *bs; - while ( - grpc_chttp2_list_pop_check_read_ops(transport_global, &stream_global)) { - if (stream_global->recv_initial_metadata_ready != NULL && - stream_global->published_metadata[0]) { - if (stream_global->seen_error) { + while (grpc_chttp2_list_pop_check_read_ops(t, &s)) { + if (s->recv_initial_metadata_ready != NULL && s->published_metadata[0]) { + if (s->seen_error) { while ((bs = grpc_chttp2_incoming_frame_queue_pop( - &stream_global->incoming_frames)) != NULL) { + &s->incoming_frames)) != NULL) { incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE); } } - grpc_chttp2_incoming_metadata_buffer_publish( - &stream_global->metadata_buffer[0], - stream_global->recv_initial_metadata); - grpc_exec_ctx_sched(exec_ctx, stream_global->recv_initial_metadata_ready, + grpc_chttp2_incoming_metadata_buffer_publish(&s->metadata_buffer[0], + s->recv_initial_metadata); + grpc_exec_ctx_sched(exec_ctx, s->recv_initial_metadata_ready, GRPC_ERROR_NONE, NULL); - stream_global->recv_initial_metadata_ready = NULL; + s->recv_initial_metadata_ready = NULL; } - if (stream_global->recv_message_ready != NULL) { - while (stream_global->final_metadata_requested && - stream_global->seen_error && - (bs = grpc_chttp2_incoming_frame_queue_pop( - &stream_global->incoming_frames)) != NULL) { + if (s->recv_message_ready != NULL) { + while (s->final_metadata_requested && s->seen_error && + (bs = grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames)) != + NULL) { incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE); } - if (stream_global->incoming_frames.head != NULL) { - *stream_global->recv_message = grpc_chttp2_incoming_frame_queue_pop( - &stream_global->incoming_frames); - GPR_ASSERT(*stream_global->recv_message != NULL); - grpc_exec_ctx_sched(exec_ctx, stream_global->recv_message_ready, - GRPC_ERROR_NONE, NULL); - stream_global->recv_message_ready = NULL; - } else if (stream_global->published_metadata[1]) { - *stream_global->recv_message = NULL; - grpc_exec_ctx_sched(exec_ctx, stream_global->recv_message_ready, - GRPC_ERROR_NONE, NULL); - stream_global->recv_message_ready = NULL; + if (s->incoming_frames.head != NULL) { + *s->recv_message = + grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames); + GPR_ASSERT(*s->recv_message != NULL); + grpc_exec_ctx_sched(exec_ctx, s->recv_message_ready, GRPC_ERROR_NONE, + NULL); + s->recv_message_ready = NULL; + } else if (s->published_metadata[1]) { + *s->recv_message = NULL; + grpc_exec_ctx_sched(exec_ctx, s->recv_message_ready, GRPC_ERROR_NONE, + NULL); + s->recv_message_ready = NULL; } } - if (stream_global->recv_trailing_metadata_finished != NULL && - stream_global->read_closed && stream_global->write_closed) { - if (stream_global->seen_error) { + if (s->recv_trailing_metadata_finished != NULL && s->read_closed && + s->write_closed) { + if (s->seen_error) { while ((bs = grpc_chttp2_incoming_frame_queue_pop( - &stream_global->incoming_frames)) != NULL) { + &s->incoming_frames)) != NULL) { incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE); } } - if (stream_global->all_incoming_byte_streams_finished) { - grpc_chttp2_incoming_metadata_buffer_publish( - &stream_global->metadata_buffer[1], - stream_global->recv_trailing_metadata); - grpc_chttp2_complete_closure_step( - exec_ctx, transport_global, stream_global, - &stream_global->recv_trailing_metadata_finished, GRPC_ERROR_NONE); + if (s->all_incoming_byte_streams_finished) { + grpc_chttp2_incoming_metadata_buffer_publish(&s->metadata_buffer[1], + s->recv_trailing_metadata); + grpc_chttp2_complete_closure_step(exec_ctx, t, s, + &s->recv_trailing_metadata_finished, + GRPC_ERROR_NONE); } } } GPR_TIMER_END("check_read_ops", 0); } -static void decrement_active_streams_locked( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global) { - if ((stream_global->all_incoming_byte_streams_finished = - gpr_unref(&stream_global->active_streams))) { - grpc_chttp2_list_add_check_read_ops(exec_ctx, transport_global, - stream_global); +static void decrement_active_streams_locked(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s) { + if ((s->all_incoming_byte_streams_finished = gpr_unref(&s->active_streams))) { + grpc_chttp2_list_add_check_read_ops(exec_ctx, t, s); } } @@ -1355,31 +1161,29 @@ static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, uint32_t id, grpc_error *error) { grpc_chttp2_stream *s = grpc_chttp2_stream_map_delete(&t->stream_map, id); GPR_ASSERT(s); - s->global.in_stream_map = false; - if (t->global.incoming_stream == &s->global) { - t->global.incoming_stream = NULL; - grpc_chttp2_parsing_become_skip_parser(exec_ctx, &t->global); + s->in_stream_map = false; + if (t->incoming_stream == s) { + t->incoming_stream = NULL; + grpc_chttp2_parsing_become_skip_parser(exec_ctx, t); } - if (s->global.data_parser.parsing_frame != NULL) { + if (s->data_parser.parsing_frame != NULL) { grpc_chttp2_incoming_byte_stream_finished( - exec_ctx, s->global.data_parser.parsing_frame, GRPC_ERROR_REF(error), - 0); - s->global.data_parser.parsing_frame = NULL; + exec_ctx, s->data_parser.parsing_frame, GRPC_ERROR_REF(error), 0); + s->data_parser.parsing_frame = NULL; } - if (grpc_chttp2_stream_map_size(&t->stream_map) == 0 && - t->global.sent_goaway) { + if (grpc_chttp2_stream_map_size(&t->stream_map) == 0 && t->sent_goaway) { close_transport_locked( exec_ctx, t, GRPC_ERROR_CREATE_REFERENCING( "Last stream closed after sending GOAWAY", &error, 1)); } - if (grpc_chttp2_list_remove_writable_stream(&t->global, &s->global)) { - GRPC_CHTTP2_STREAM_UNREF(exec_ctx, &s->global, "chttp2_writing"); + if (grpc_chttp2_list_remove_writable_stream(t, s)) { + GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing"); } GRPC_ERROR_UNREF(error); - maybe_start_some_streams(exec_ctx, &t->global); + maybe_start_some_streams(exec_ctx, t); } static void status_codes_from_error(grpc_error *error, gpr_timespec deadline, @@ -1410,22 +1214,19 @@ static void status_codes_from_error(grpc_error *error, gpr_timespec deadline, } void grpc_chttp2_cancel_stream(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, + grpc_chttp2_transport *t, grpc_chttp2_stream *s, grpc_error *due_to_error) { - if (!stream_global->read_closed || !stream_global->write_closed) { + if (!s->read_closed || !s->write_closed) { grpc_status_code grpc_status; grpc_chttp2_error_code http_error; - status_codes_from_error(due_to_error, stream_global->deadline, &http_error, + status_codes_from_error(due_to_error, s->deadline, &http_error, &grpc_status); - if (stream_global->id != 0) { + if (s->id != 0) { gpr_slice_buffer_add( - &transport_global->qbuf, - grpc_chttp2_rst_stream_create(stream_global->id, (uint32_t)http_error, - &stream_global->stats.outgoing)); - grpc_chttp2_initiate_write(exec_ctx, transport_global, false, - "rst_stream"); + &t->qbuf, grpc_chttp2_rst_stream_create(s->id, (uint32_t)http_error, + &s->stats.outgoing)); + grpc_chttp2_initiate_write(exec_ctx, t, false, "rst_stream"); } const char *msg = @@ -1436,27 +1237,22 @@ void grpc_chttp2_cancel_stream(grpc_exec_ctx *exec_ctx, msg = grpc_error_string(due_to_error); } gpr_slice msg_slice = gpr_slice_from_copied_string(msg); - grpc_chttp2_fake_status(exec_ctx, transport_global, stream_global, - grpc_status, &msg_slice); + grpc_chttp2_fake_status(exec_ctx, t, s, grpc_status, &msg_slice); if (free_msg) grpc_error_free_string(msg); } - if (due_to_error != GRPC_ERROR_NONE && !stream_global->seen_error) { - stream_global->seen_error = true; - grpc_chttp2_list_add_check_read_ops(exec_ctx, transport_global, - stream_global); + if (due_to_error != GRPC_ERROR_NONE && !s->seen_error) { + s->seen_error = true; + grpc_chttp2_list_add_check_read_ops(exec_ctx, t, s); } - grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global, 1, - 1, due_to_error); + grpc_chttp2_mark_stream_closed(exec_ctx, t, s, 1, 1, due_to_error); } -void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, - grpc_status_code status, gpr_slice *slice) { +void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, + grpc_chttp2_stream *s, grpc_status_code status, + gpr_slice *slice) { if (status != GRPC_STATUS_OK) { - stream_global->seen_error = true; - grpc_chttp2_list_add_check_read_ops(exec_ctx, transport_global, - stream_global); + s->seen_error = true; + grpc_chttp2_list_add_check_read_ops(exec_ctx, t, s); } /* stream_global->recv_trailing_metadata_finished gives us a last chance replacement: we've received trailing metadata, @@ -1464,24 +1260,22 @@ void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx, to the upper layers - drop what we've got, and then publish what we want - which is safe because we haven't told anyone about the metadata yet */ - if (!stream_global->published_metadata[1] || - stream_global->recv_trailing_metadata_finished != NULL) { + if (!s->published_metadata[1] || s->recv_trailing_metadata_finished != NULL) { char status_string[GPR_LTOA_MIN_BUFSIZE]; gpr_ltoa(status, status_string); grpc_chttp2_incoming_metadata_buffer_add( - &stream_global->metadata_buffer[1], + &s->metadata_buffer[1], grpc_mdelem_from_metadata_strings( GRPC_MDSTR_GRPC_STATUS, grpc_mdstr_from_string(status_string))); if (slice) { grpc_chttp2_incoming_metadata_buffer_add( - &stream_global->metadata_buffer[1], + &s->metadata_buffer[1], grpc_mdelem_from_metadata_strings( GRPC_MDSTR_GRPC_MESSAGE, grpc_mdstr_from_slice(gpr_slice_ref(*slice)))); } - stream_global->published_metadata[1] = true; - grpc_chttp2_list_add_check_read_ops(exec_ctx, transport_global, - stream_global); + s->published_metadata[1] = true; + grpc_chttp2_list_add_check_read_ops(exec_ctx, t, s); } if (slice) { gpr_slice_unref(*slice); @@ -1500,11 +1294,11 @@ static void add_error(grpc_error *error, grpc_error **refs, size_t *nrefs) { } static grpc_error *removal_error(grpc_error *extra_error, - grpc_chttp2_stream_global *stream_global) { + grpc_chttp2_stream *s) { grpc_error *refs[3]; size_t nrefs = 0; - add_error(stream_global->read_closed_error, refs, &nrefs); - add_error(stream_global->write_closed_error, refs, &nrefs); + add_error(s->read_closed_error, refs, &nrefs); + add_error(s->write_closed_error, refs, &nrefs); add_error(extra_error, refs, &nrefs); grpc_error *error = GRPC_ERROR_NONE; if (nrefs > 0) { @@ -1516,68 +1310,54 @@ static grpc_error *removal_error(grpc_error *extra_error, } static void fail_pending_writes(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, + grpc_chttp2_transport *t, grpc_chttp2_stream *s, grpc_error *error) { - error = removal_error(error, stream_global); - stream_global->send_message = NULL; - grpc_chttp2_complete_closure_step( - exec_ctx, transport_global, stream_global, - &stream_global->send_initial_metadata_finished, GRPC_ERROR_REF(error)); - grpc_chttp2_complete_closure_step( - exec_ctx, transport_global, stream_global, - &stream_global->send_trailing_metadata_finished, GRPC_ERROR_REF(error)); - grpc_chttp2_complete_closure_step(exec_ctx, transport_global, stream_global, - &stream_global->send_message_finished, + error = removal_error(error, s); + s->send_message = NULL; + grpc_chttp2_complete_closure_step(exec_ctx, t, s, + &s->send_initial_metadata_finished, + GRPC_ERROR_REF(error)); + grpc_chttp2_complete_closure_step(exec_ctx, t, s, + &s->send_trailing_metadata_finished, + GRPC_ERROR_REF(error)); + grpc_chttp2_complete_closure_step(exec_ctx, t, s, &s->send_message_finished, error); } -void grpc_chttp2_mark_stream_closed( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, int close_reads, int close_writes, - grpc_error *error) { - if (stream_global->read_closed && stream_global->write_closed) { +void grpc_chttp2_mark_stream_closed(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s, int close_reads, + int close_writes, grpc_error *error) { + if (s->read_closed && s->write_closed) { /* already closed */ GRPC_ERROR_UNREF(error); return; } - grpc_chttp2_list_add_check_read_ops(exec_ctx, transport_global, - stream_global); - if (close_reads && !stream_global->read_closed) { - stream_global->read_closed_error = GRPC_ERROR_REF(error); - stream_global->read_closed = true; - stream_global->published_metadata[0] = true; - stream_global->published_metadata[1] = true; - decrement_active_streams_locked(exec_ctx, transport_global, stream_global); - } - if (close_writes && !stream_global->write_closed) { - stream_global->write_closed_error = GRPC_ERROR_REF(error); - stream_global->write_closed = true; - if (TRANSPORT_FROM_GLOBAL(transport_global)->executor.write_state != - GRPC_CHTTP2_WRITING_INACTIVE) { - GRPC_CHTTP2_STREAM_REF(stream_global, "finish_writes"); - grpc_chttp2_list_add_closed_waiting_for_writing(transport_global, - stream_global); - } else { - fail_pending_writes(exec_ctx, transport_global, stream_global, - GRPC_ERROR_REF(error)); + grpc_chttp2_list_add_check_read_ops(exec_ctx, t, s); + if (close_reads && !s->read_closed) { + s->read_closed_error = GRPC_ERROR_REF(error); + s->read_closed = true; + s->published_metadata[0] = true; + s->published_metadata[1] = true; + decrement_active_streams_locked(exec_ctx, t, s); + } + if (close_writes && !s->write_closed) { + s->write_closed_error = GRPC_ERROR_REF(error); + s->write_closed = true; + fail_pending_writes(exec_ctx, t, s, GRPC_ERROR_REF(error)); + } + if (s->read_closed && s->write_closed) { + if (s->id != 0) { + remove_stream(exec_ctx, t, s->id, + removal_error(GRPC_ERROR_REF(error), s)); } - } - if (stream_global->read_closed && stream_global->write_closed) { - if (stream_global->id != 0) { - remove_stream(exec_ctx, TRANSPORT_FROM_GLOBAL(transport_global), - stream_global->id, - removal_error(GRPC_ERROR_REF(error), stream_global)); - } - GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2"); + GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2"); } GRPC_ERROR_UNREF(error); } -static void close_from_api(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, - grpc_error *error) { +static void close_from_api(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, + grpc_chttp2_stream *s, grpc_error *error) { gpr_slice hdr; gpr_slice status_hdr; gpr_slice message_pfx; @@ -1585,12 +1365,11 @@ static void close_from_api(grpc_exec_ctx *exec_ctx, uint32_t len = 0; grpc_status_code grpc_status; grpc_chttp2_error_code http_error; - status_codes_from_error(error, stream_global->deadline, &http_error, - &grpc_status); + status_codes_from_error(error, s->deadline, &http_error, &grpc_status); GPR_ASSERT(grpc_status >= 0 && (int)grpc_status < 100); - if (stream_global->id != 0 && !transport_global->is_client) { + if (s->id != 0 && !t->is_client) { /* Hand roll a header block. This is unnecessarily ugly - at some point we should find a more elegant solution. @@ -1659,23 +1438,22 @@ static void close_from_api(grpc_exec_ctx *exec_ctx, *p++ = (uint8_t)(len); *p++ = GRPC_CHTTP2_FRAME_HEADER; *p++ = GRPC_CHTTP2_DATA_FLAG_END_STREAM | GRPC_CHTTP2_DATA_FLAG_END_HEADERS; - *p++ = (uint8_t)(stream_global->id >> 24); - *p++ = (uint8_t)(stream_global->id >> 16); - *p++ = (uint8_t)(stream_global->id >> 8); - *p++ = (uint8_t)(stream_global->id); + *p++ = (uint8_t)(s->id >> 24); + *p++ = (uint8_t)(s->id >> 16); + *p++ = (uint8_t)(s->id >> 8); + *p++ = (uint8_t)(s->id); GPR_ASSERT(p == GPR_SLICE_END_PTR(hdr)); - gpr_slice_buffer_add(&transport_global->qbuf, hdr); - gpr_slice_buffer_add(&transport_global->qbuf, status_hdr); + gpr_slice_buffer_add(&t->qbuf, hdr); + gpr_slice_buffer_add(&t->qbuf, status_hdr); if (optional_message) { - gpr_slice_buffer_add(&transport_global->qbuf, message_pfx); - gpr_slice_buffer_add(&transport_global->qbuf, + gpr_slice_buffer_add(&t->qbuf, message_pfx); + gpr_slice_buffer_add(&t->qbuf, gpr_slice_from_copied_string(optional_message)); } gpr_slice_buffer_add( - &transport_global->qbuf, - grpc_chttp2_rst_stream_create(stream_global->id, GRPC_CHTTP2_NO_ERROR, - &stream_global->stats.outgoing)); + &t->qbuf, grpc_chttp2_rst_stream_create(s->id, GRPC_CHTTP2_NO_ERROR, + &s->stats.outgoing)); } const char *msg = grpc_error_get_str(error, GRPC_ERROR_STR_GRPC_MESSAGE); @@ -1685,14 +1463,11 @@ static void close_from_api(grpc_exec_ctx *exec_ctx, msg = grpc_error_string(error); } gpr_slice msg_slice = gpr_slice_from_copied_string(msg); - grpc_chttp2_fake_status(exec_ctx, transport_global, stream_global, - grpc_status, &msg_slice); + grpc_chttp2_fake_status(exec_ctx, t, s, grpc_status, &msg_slice); if (free_msg) grpc_error_free_string(msg); - grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global, 1, - 1, error); - grpc_chttp2_initiate_write(exec_ctx, transport_global, false, - "close_from_api"); + grpc_chttp2_mark_stream_closed(exec_ctx, t, s, 1, 1, error); + grpc_chttp2_initiate_write(exec_ctx, t, false, "close_from_api"); } typedef struct { @@ -1704,7 +1479,7 @@ typedef struct { static void cancel_stream_cb(void *user_data, uint32_t key, void *stream) { cancel_stream_cb_args *args = user_data; grpc_chttp2_stream *s = stream; - grpc_chttp2_cancel_stream(args->exec_ctx, &args->t->global, &s->global, + grpc_chttp2_cancel_stream(args->exec_ctx, args->t, s, GRPC_ERROR_REF(args->error)); } @@ -1735,20 +1510,18 @@ static void update_global_window(void *args, uint32_t id, void *stream) { update_global_window_args *a = args; grpc_chttp2_transport *t = a->t; grpc_chttp2_stream *s = stream; - grpc_chttp2_transport_global *transport_global = &t->global; - grpc_chttp2_stream_global *stream_global = &s->global; int was_zero; int is_zero; - int64_t initial_window_update = t->global.initial_window_update; + int64_t initial_window_update = t->initial_window_update; - was_zero = stream_global->outgoing_window <= 0; - GRPC_CHTTP2_FLOW_CREDIT_STREAM("settings", transport_global, stream_global, - outgoing_window, initial_window_update); - is_zero = stream_global->outgoing_window <= 0; + was_zero = s->outgoing_window <= 0; + GRPC_CHTTP2_FLOW_CREDIT_STREAM("settings", t, s, outgoing_window, + initial_window_update); + is_zero = s->outgoing_window <= 0; if (was_zero && !is_zero) { - grpc_chttp2_become_writable(a->exec_ctx, transport_global, stream_global, - true, "update_global_window"); + grpc_chttp2_become_writable(a->exec_ctx, t, s, true, + "update_global_window"); } } @@ -1764,8 +1537,8 @@ static void reading_action(grpc_exec_ctx *exec_ctx, void *tp, post_reading_action_locked */ GPR_TIMER_BEGIN("reading_action", 0); grpc_chttp2_transport *t = tp; - grpc_combiner_execute(exec_ctx, t->executor.combiner, - &t->reading_action_locked, GRPC_ERROR_REF(error)); + grpc_combiner_execute(exec_ctx, t->combiner, &t->reading_action_locked, + GRPC_ERROR_REF(error)); GPR_TIMER_END("reading_action", 0); } @@ -1801,7 +1574,6 @@ static void reading_action_locked(grpc_exec_ctx *exec_ctx, void *tp, GPR_TIMER_BEGIN("reading_action_locked", 0); grpc_chttp2_transport *t = tp; - grpc_chttp2_transport_global *transport_global = &t->global; GRPC_ERROR_REF(error); @@ -1811,8 +1583,8 @@ static void reading_action_locked(grpc_exec_ctx *exec_ctx, void *tp, grpc_error *errors[3] = {GRPC_ERROR_REF(error), GRPC_ERROR_NONE, GRPC_ERROR_NONE}; for (; i < t->read_buffer.count && errors[1] == GRPC_ERROR_NONE; i++) { - errors[1] = grpc_chttp2_perform_read(exec_ctx, &t->global, - t->read_buffer.slices[i]); + errors[1] = + grpc_chttp2_perform_read(exec_ctx, t, t->read_buffer.slices[i]); }; if (errors[1] != GRPC_ERROR_NONE) { errors[2] = try_http_parsing(exec_ctx, t); @@ -1826,23 +1598,20 @@ static void reading_action_locked(grpc_exec_ctx *exec_ctx, void *tp, GPR_TIMER_END("reading_action.parse", 0); GPR_TIMER_BEGIN("post_parse_locked", 0); - if (transport_global->initial_window_update != 0) { + if (t->initial_window_update != 0) { update_global_window_args args = {t, exec_ctx}; grpc_chttp2_stream_map_for_each(&t->stream_map, update_global_window, &args); - transport_global->initial_window_update = 0; + t->initial_window_update = 0; } /* handle higher level things */ - if (transport_global->incoming_window < - transport_global->connection_window_target * 3 / 4) { - int64_t announce_bytes = transport_global->connection_window_target - - transport_global->incoming_window; - GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT( - "parsed", transport_global, announce_incoming_window, announce_bytes); - GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT("parsed", transport_global, - incoming_window, announce_bytes); - grpc_chttp2_initiate_write(exec_ctx, transport_global, false, - "global incoming window"); + if (t->incoming_window < t->connection_window_target * 3 / 4) { + int64_t announce_bytes = t->connection_window_target - t->incoming_window; + GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT("parsed", t, announce_incoming_window, + announce_bytes); + GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT("parsed", t, incoming_window, + announce_bytes); + grpc_chttp2_initiate_write(exec_ctx, t, false, "global incoming window"); } GPR_TIMER_END("post_parse_locked", 0); @@ -1856,10 +1625,6 @@ static void reading_action_locked(grpc_exec_ctx *exec_ctx, void *tp, if (error != GRPC_ERROR_NONE) { drop_connection(exec_ctx, t, GRPC_ERROR_REF(error)); t->endpoint_reading = 0; - if (grpc_http_write_state_trace) { - gpr_log(GPR_DEBUG, "R:%p -> 0 ws=%s", t, - write_state_name(t->executor.write_state)); - } } else if (!t->closed) { keep_reading = true; GRPC_CHTTP2_REF_TRANSPORT(t, "keep_reading"); @@ -1886,15 +1651,14 @@ static void reading_action_locked(grpc_exec_ctx *exec_ctx, void *tp, * CALLBACK LOOP */ -static void connectivity_state_set( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - grpc_connectivity_state state, grpc_error *error, const char *reason) { +static void connectivity_state_set(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + grpc_connectivity_state state, + grpc_error *error, const char *reason) { GRPC_CHTTP2_IF_TRACING( gpr_log(GPR_DEBUG, "set connectivity_state=%d", state)); - grpc_connectivity_state_set( - exec_ctx, - &TRANSPORT_FROM_GLOBAL(transport_global)->channel_callback.state_tracker, - state, error, reason); + grpc_connectivity_state_set(exec_ctx, &t->channel_callback.state_tracker, + state, error, reason); } /******************************************************************************* @@ -1927,15 +1691,16 @@ static void incoming_byte_stream_unref(grpc_exec_ctx *exec_ctx, } } -static void incoming_byte_stream_update_flow_control( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, size_t max_size_hint, - size_t have_already) { +static void incoming_byte_stream_update_flow_control(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s, + size_t max_size_hint, + size_t have_already) { uint32_t max_recv_bytes; /* clamp max recv hint to an allowable size */ - if (max_size_hint >= UINT32_MAX - transport_global->stream_lookahead) { - max_recv_bytes = UINT32_MAX - transport_global->stream_lookahead; + if (max_size_hint >= UINT32_MAX - t->stream_lookahead) { + max_recv_bytes = UINT32_MAX - t->stream_lookahead; } else { max_recv_bytes = (uint32_t)max_size_hint; } @@ -1948,20 +1713,18 @@ static void incoming_byte_stream_update_flow_control( } /* add some small lookahead to keep pipelines flowing */ - GPR_ASSERT(max_recv_bytes <= UINT32_MAX - transport_global->stream_lookahead); - max_recv_bytes += transport_global->stream_lookahead; - if (stream_global->max_recv_bytes < max_recv_bytes) { - uint32_t add_max_recv_bytes = - max_recv_bytes - stream_global->max_recv_bytes; - GRPC_CHTTP2_FLOW_CREDIT_STREAM("op", transport_global, stream_global, - max_recv_bytes, add_max_recv_bytes); - GRPC_CHTTP2_FLOW_CREDIT_STREAM("op", transport_global, stream_global, - incoming_window, add_max_recv_bytes); - GRPC_CHTTP2_FLOW_CREDIT_STREAM("op", transport_global, stream_global, + GPR_ASSERT(max_recv_bytes <= UINT32_MAX - t->stream_lookahead); + max_recv_bytes += t->stream_lookahead; + if (s->max_recv_bytes < max_recv_bytes) { + uint32_t add_max_recv_bytes = max_recv_bytes - s->max_recv_bytes; + GRPC_CHTTP2_FLOW_CREDIT_STREAM("op", t, s, max_recv_bytes, + add_max_recv_bytes); + GRPC_CHTTP2_FLOW_CREDIT_STREAM("op", t, s, incoming_window, + add_max_recv_bytes); + GRPC_CHTTP2_FLOW_CREDIT_STREAM("op", t, s, unannounced_incoming_window_for_writing, add_max_recv_bytes); - grpc_chttp2_become_writable(exec_ctx, transport_global, stream_global, - false, "read_incoming_stream"); + grpc_chttp2_become_writable(exec_ctx, t, s, false, "read_incoming_stream"); } } @@ -1969,16 +1732,15 @@ static void incoming_byte_stream_next_locked(grpc_exec_ctx *exec_ctx, void *argp, grpc_error *error_ignored) { grpc_chttp2_incoming_byte_stream *bs = argp; - grpc_chttp2_transport_global *transport_global = &bs->transport->global; - grpc_chttp2_stream_global *stream_global = &bs->stream->global; + grpc_chttp2_transport *t = bs->transport; + grpc_chttp2_stream *s = bs->stream; if (bs->is_tail) { gpr_mu_lock(&bs->slice_mu); size_t cur_length = bs->slices.length; gpr_mu_unlock(&bs->slice_mu); incoming_byte_stream_update_flow_control( - exec_ctx, transport_global, stream_global, - bs->next_action.max_size_hint, cur_length); + exec_ctx, t, s, bs->next_action.max_size_hint, cur_length); } gpr_mu_lock(&bs->slice_mu); if (bs->slices.count > 0) { @@ -2009,7 +1771,7 @@ static int incoming_byte_stream_next(grpc_exec_ctx *exec_ctx, bs->next_action.on_complete = on_complete; grpc_closure_init(&bs->next_action.closure, incoming_byte_stream_next_locked, bs); - grpc_combiner_execute(exec_ctx, bs->transport->executor.combiner, + grpc_combiner_execute(exec_ctx, bs->transport->combiner, &bs->next_action.closure, GRPC_ERROR_NONE); GPR_TIMER_END("incoming_byte_stream_next", 0); return 0; @@ -2023,8 +1785,7 @@ static void incoming_byte_stream_destroy_locked(grpc_exec_ctx *exec_ctx, grpc_error *error_ignored) { grpc_chttp2_incoming_byte_stream *bs = byte_stream; GPR_ASSERT(bs->base.destroy == incoming_byte_stream_destroy); - decrement_active_streams_locked(exec_ctx, &bs->transport->global, - &bs->stream->global); + decrement_active_streams_locked(exec_ctx, bs->transport, bs->stream); incoming_byte_stream_unref(exec_ctx, bs); } @@ -2035,8 +1796,8 @@ static void incoming_byte_stream_destroy(grpc_exec_ctx *exec_ctx, (grpc_chttp2_incoming_byte_stream *)byte_stream; grpc_closure_init(&bs->destroy_action, incoming_byte_stream_destroy_locked, bs); - grpc_combiner_execute(exec_ctx, bs->transport->executor.combiner, - &bs->destroy_action, GRPC_ERROR_NONE); + grpc_combiner_execute(exec_ctx, bs->transport->combiner, &bs->destroy_action, + GRPC_ERROR_NONE); GPR_TIMER_END("incoming_byte_stream_destroy", 0); } @@ -2078,7 +1839,7 @@ void grpc_chttp2_incoming_byte_stream_finished( if (from_parsing_thread) { grpc_closure_init(&bs->finished_action, incoming_byte_stream_finished_locked, bs); - grpc_combiner_execute(exec_ctx, bs->transport->executor.combiner, + grpc_combiner_execute(exec_ctx, bs->transport->combiner, &bs->finished_action, GRPC_ERROR_REF(error)); } else { incoming_byte_stream_finished_locked(exec_ctx, bs, error); @@ -2087,9 +1848,8 @@ void grpc_chttp2_incoming_byte_stream_finished( } grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, uint32_t frame_size, - uint32_t flags) { + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s, + uint32_t frame_size, uint32_t flags) { grpc_chttp2_incoming_byte_stream *incoming_byte_stream = gpr_malloc(sizeof(*incoming_byte_stream)); incoming_byte_stream->base.length = frame_size; @@ -2099,14 +1859,14 @@ grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( gpr_mu_init(&incoming_byte_stream->slice_mu); gpr_ref_init(&incoming_byte_stream->refs, 2); incoming_byte_stream->next_message = NULL; - incoming_byte_stream->transport = TRANSPORT_FROM_GLOBAL(transport_global); - incoming_byte_stream->stream = STREAM_FROM_GLOBAL(stream_global); - gpr_ref(&incoming_byte_stream->stream->global.active_streams); + incoming_byte_stream->transport = t; + incoming_byte_stream->stream = s; + gpr_ref(&incoming_byte_stream->stream->active_streams); gpr_slice_buffer_init(&incoming_byte_stream->slices); incoming_byte_stream->on_next = NULL; incoming_byte_stream->is_tail = 1; incoming_byte_stream->error = GRPC_ERROR_NONE; - grpc_chttp2_incoming_frame_queue *q = &stream_global->incoming_frames; + grpc_chttp2_incoming_frame_queue *q = &s->incoming_frames; if (q->head == NULL) { q->head = incoming_byte_stream; } else { diff --git a/src/core/ext/transport/chttp2/transport/frame.h b/src/core/ext/transport/chttp2/transport/frame.h index 48e3ac6482..0f1e128b3d 100644 --- a/src/core/ext/transport/chttp2/transport/frame.h +++ b/src/core/ext/transport/chttp2/transport/frame.h @@ -40,8 +40,8 @@ #include "src/core/lib/iomgr/error.h" /* defined in internal.h */ -typedef struct grpc_chttp2_stream_global grpc_chttp2_stream_global; -typedef struct grpc_chttp2_transport_global grpc_chttp2_transport_global; +typedef struct grpc_chttp2_stream grpc_chttp2_stream; +typedef struct grpc_chttp2_transport grpc_chttp2_transport; #define GRPC_CHTTP2_FRAME_DATA 0 #define GRPC_CHTTP2_FRAME_HEADER 1 diff --git a/src/core/ext/transport/chttp2/transport/frame_data.h b/src/core/ext/transport/chttp2/transport/frame_data.h index c8ff7fe6bc..eb2d97d898 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.h +++ b/src/core/ext/transport/chttp2/transport/frame_data.h @@ -91,10 +91,10 @@ grpc_error *grpc_chttp2_data_parser_begin_frame(grpc_chttp2_data_parser *parser, /* handle a slice of a data frame - is_last indicates the last slice of a frame */ -grpc_error *grpc_chttp2_data_parser_parse( - grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, gpr_slice slice, int is_last); +grpc_error *grpc_chttp2_data_parser_parse(grpc_exec_ctx *exec_ctx, void *parser, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s, + gpr_slice slice, int is_last); void grpc_chttp2_encode_data(uint32_t id, gpr_slice_buffer *inbuf, uint32_t write_bytes, int is_eof, diff --git a/src/core/ext/transport/chttp2/transport/frame_goaway.h b/src/core/ext/transport/chttp2/transport/frame_goaway.h index f821229931..355104a5a7 100644 --- a/src/core/ext/transport/chttp2/transport/frame_goaway.h +++ b/src/core/ext/transport/chttp2/transport/frame_goaway.h @@ -65,10 +65,11 @@ void grpc_chttp2_goaway_parser_init(grpc_chttp2_goaway_parser *p); void grpc_chttp2_goaway_parser_destroy(grpc_chttp2_goaway_parser *p); grpc_error *grpc_chttp2_goaway_parser_begin_frame( grpc_chttp2_goaway_parser *parser, uint32_t length, uint8_t flags); -grpc_error *grpc_chttp2_goaway_parser_parse( - grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, gpr_slice slice, int is_last); +grpc_error *grpc_chttp2_goaway_parser_parse(grpc_exec_ctx *exec_ctx, + void *parser, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s, + gpr_slice slice, int is_last); void grpc_chttp2_goaway_append(uint32_t last_stream_id, uint32_t error_code, gpr_slice debug_data, diff --git a/src/core/ext/transport/chttp2/transport/frame_ping.h b/src/core/ext/transport/chttp2/transport/frame_ping.h index c2c4fb2ee5..2071f647fb 100644 --- a/src/core/ext/transport/chttp2/transport/frame_ping.h +++ b/src/core/ext/transport/chttp2/transport/frame_ping.h @@ -48,9 +48,9 @@ gpr_slice grpc_chttp2_ping_create(uint8_t ack, uint8_t *opaque_8bytes); grpc_error *grpc_chttp2_ping_parser_begin_frame(grpc_chttp2_ping_parser *parser, uint32_t length, uint8_t flags); -grpc_error *grpc_chttp2_ping_parser_parse( - grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, gpr_slice slice, int is_last); +grpc_error *grpc_chttp2_ping_parser_parse(grpc_exec_ctx *exec_ctx, void *parser, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s, + gpr_slice slice, int is_last); #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FRAME_PING_H */ diff --git a/src/core/ext/transport/chttp2/transport/frame_rst_stream.h b/src/core/ext/transport/chttp2/transport/frame_rst_stream.h index 64a6a27341..5a1f578a29 100644 --- a/src/core/ext/transport/chttp2/transport/frame_rst_stream.h +++ b/src/core/ext/transport/chttp2/transport/frame_rst_stream.h @@ -49,9 +49,10 @@ gpr_slice grpc_chttp2_rst_stream_create(uint32_t stream_id, uint32_t code, grpc_error *grpc_chttp2_rst_stream_parser_begin_frame( grpc_chttp2_rst_stream_parser *parser, uint32_t length, uint8_t flags); -grpc_error *grpc_chttp2_rst_stream_parser_parse( - grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, gpr_slice slice, int is_last); +grpc_error *grpc_chttp2_rst_stream_parser_parse(grpc_exec_ctx *exec_ctx, + void *parser, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s, + gpr_slice slice, int is_last); #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FRAME_RST_STREAM_H */ diff --git a/src/core/ext/transport/chttp2/transport/frame_settings.h b/src/core/ext/transport/chttp2/transport/frame_settings.h index c19f8067cc..4bfa944cf1 100644 --- a/src/core/ext/transport/chttp2/transport/frame_settings.h +++ b/src/core/ext/transport/chttp2/transport/frame_settings.h @@ -95,9 +95,10 @@ gpr_slice grpc_chttp2_settings_ack_create(void); grpc_error *grpc_chttp2_settings_parser_begin_frame( grpc_chttp2_settings_parser *parser, uint32_t length, uint8_t flags, uint32_t *settings); -grpc_error *grpc_chttp2_settings_parser_parse( - grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, gpr_slice slice, int is_last); +grpc_error *grpc_chttp2_settings_parser_parse(grpc_exec_ctx *exec_ctx, + void *parser, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s, + gpr_slice slice, int is_last); #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FRAME_SETTINGS_H */ diff --git a/src/core/ext/transport/chttp2/transport/frame_window_update.h b/src/core/ext/transport/chttp2/transport/frame_window_update.h index 36ae6bd0b1..6e62f31872 100644 --- a/src/core/ext/transport/chttp2/transport/frame_window_update.h +++ b/src/core/ext/transport/chttp2/transport/frame_window_update.h @@ -51,8 +51,7 @@ gpr_slice grpc_chttp2_window_update_create(uint32_t id, uint32_t window_delta, grpc_error *grpc_chttp2_window_update_parser_begin_frame( grpc_chttp2_window_update_parser *parser, uint32_t length, uint8_t flags); grpc_error *grpc_chttp2_window_update_parser_parse( - grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, gpr_slice slice, int is_last); + grpc_exec_ctx *exec_ctx, void *parser, grpc_chttp2_transport *t, + grpc_chttp2_stream *s, gpr_slice slice, int is_last); #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FRAME_WINDOW_UPDATE_H */ diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.h b/src/core/ext/transport/chttp2/transport/hpack_parser.h index 314bd55965..0290c78d5a 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_parser.h +++ b/src/core/ext/transport/chttp2/transport/hpack_parser.h @@ -112,9 +112,10 @@ grpc_error *grpc_chttp2_hpack_parser_parse(grpc_exec_ctx *exec_ctx, /* wraps grpc_chttp2_hpack_parser_parse to provide a frame level parser for the transport */ -grpc_error *grpc_chttp2_header_parser_parse( - grpc_exec_ctx *exec_ctx, void *hpack_parser, - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, gpr_slice slice, int is_last); +grpc_error *grpc_chttp2_header_parser_parse(grpc_exec_ctx *exec_ctx, + void *hpack_parser, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s, + gpr_slice slice, int is_last); #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_PARSER_H */ diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 761ed2dad1..1ada0a6a80 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -53,9 +53,6 @@ #include "src/core/lib/transport/connectivity_state.h" #include "src/core/lib/transport/transport_impl.h" -typedef struct grpc_chttp2_transport grpc_chttp2_transport; -typedef struct grpc_chttp2_stream grpc_chttp2_stream; - /* streams are kept in various linked lists depending on what things need to happen to them... this enum labels each list */ typedef enum { @@ -63,7 +60,6 @@ typedef enum { GRPC_CHTTP2_LIST_WRITABLE, GRPC_CHTTP2_LIST_WRITING, GRPC_CHTTP2_LIST_WRITTEN, - GRPC_CHTTP2_LIST_CLOSED_WAITING_FOR_WRITING, GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT, /* streams waiting for the outgoing window in the writing path, they will be * merged to the stalled list or writable list under transport lock. */ @@ -74,6 +70,12 @@ typedef enum { STREAM_LIST_COUNT /* must be last */ } grpc_chttp2_stream_list_id; +typedef enum { + GRPC_CHTTP2_WRITE_STATE_IDLE, + GRPC_CHTTP2_WRITE_STATE_WRITING, + GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_TO_COME, +} grpc_chttp2_write_state; + /* deframer state for the overall http2 stream of bytes */ typedef enum { /* prefix: one entry per http2 connection prefix byte */ @@ -174,12 +176,76 @@ struct grpc_chttp2_incoming_byte_stream { grpc_closure finished_action; }; -struct grpc_chttp2_transport_global { +struct grpc_chttp2_transport { + grpc_transport base; /* must be first */ + gpr_refcount refs; + grpc_endpoint *ep; + char *peer_string; + + /** when this drops to zero it's safe to shutdown the endpoint */ + gpr_refcount shutdown_ep_refs; + + grpc_combiner *combiner; + + /** write execution state of the transport */ + grpc_chttp2_write_state write_state; + /** has a check_read_ops been scheduled */ + bool check_read_ops_scheduled; + + /** is the transport destroying itself? */ + uint8_t destroying; + /** has the upper layer closed the transport? */ + uint8_t closed; + + /** is there a read request to the endpoint outstanding? */ + uint8_t endpoint_reading; + + /** various lists of streams */ + grpc_chttp2_stream_list lists[STREAM_LIST_COUNT]; + + /** maps stream id to grpc_chttp2_stream objects */ + grpc_chttp2_stream_map stream_map; + + /** closure to execute writing */ + grpc_closure writing_action; + grpc_closure writing_done_action; + /** closure to finish writing */ + grpc_closure terminate_writing; + /** closure to start reading from the endpoint */ + grpc_closure reading_action; + grpc_closure reading_action_locked; + /** closure to flush read state up the stack */ + grpc_closure initiate_read_flush_locked; + + /** incoming read bytes */ + gpr_slice_buffer read_buffer; + + /** address to place a newly accepted stream - set and unset by + grpc_chttp2_parsing_accept_stream; used by init_stream to + publish the accepted server stream */ + grpc_chttp2_stream **accepting_stream; + + struct { + /* accept stream callback */ + void (*accept_stream)(grpc_exec_ctx *exec_ctx, void *user_data, + grpc_transport *transport, const void *server_data); + void *accept_stream_user_data; + + /** connectivity tracking */ + grpc_connectivity_state_tracker state_tracker; + } channel_callback; + + /** data to write now */ + gpr_slice_buffer outbuf; + /** hpack encoding */ + grpc_chttp2_hpack_compressor hpack_compressor; + int64_t outgoing_window; + /** is this a client? */ + uint8_t is_client; + /** data to write next write */ gpr_slice_buffer qbuf; - /** window available for us to send to peer */ - int64_t outgoing_window; /** window available to announce to peer */ int64_t announce_incoming_window; /** how much window would we like to have for incoming_window */ @@ -190,8 +256,6 @@ struct grpc_chttp2_transport_global { /** have we sent a goaway */ uint8_t sent_goaway; - /** is this transport a client? */ - uint8_t is_client; /** are the local settings dirty and need to be sent? */ uint8_t dirtied_local_settings; /** have local settings been sent? */ @@ -246,10 +310,9 @@ struct grpc_chttp2_transport_global { /* active parser */ void *parser_data; - grpc_chttp2_stream_global *incoming_stream; + grpc_chttp2_stream *incoming_stream; grpc_error *(*parser)(grpc_exec_ctx *exec_ctx, void *parser_user_data, - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, + grpc_chttp2_transport *t, grpc_chttp2_stream *s, gpr_slice slice, int is_last); /* goaway data */ @@ -258,109 +321,16 @@ struct grpc_chttp2_transport_global { gpr_slice goaway_text; }; -typedef struct { - /** data to write now */ - gpr_slice_buffer outbuf; - /** hpack encoding */ - grpc_chttp2_hpack_compressor hpack_compressor; - int64_t outgoing_window; - /** is this a client? */ - uint8_t is_client; - /** callback for when writing is done */ - grpc_closure done_cb; -} grpc_chttp2_transport_writing; - -#if 0 -struct grpc_chttp2_transport_parsing { -}; -#endif - -typedef enum { - /** no writing activity allowed */ - GRPC_CHTTP2_WRITES_CORKED, - /** no writing activity */ - GRPC_CHTTP2_WRITING_INACTIVE, - /** write has been requested and scheduled against the workqueue */ - GRPC_CHTTP2_WRITE_SCHEDULED, - /** write has been initiated after being reaped from the workqueue */ - GRPC_CHTTP2_WRITING, - /** write has been initiated, AND another write needs to be started once it's - done */ - GRPC_CHTTP2_WRITING_STALE_WITH_POLLER, - GRPC_CHTTP2_WRITING_STALE_NO_POLLER, -} grpc_chttp2_write_state; - -struct grpc_chttp2_transport { - grpc_transport base; /* must be first */ - gpr_refcount refs; - grpc_endpoint *ep; - char *peer_string; - - /** when this drops to zero it's safe to shutdown the endpoint */ - gpr_refcount shutdown_ep_refs; - - struct { - grpc_combiner *combiner; - - /** write execution state of the transport */ - grpc_chttp2_write_state write_state; - /** has a check_read_ops been scheduled */ - bool check_read_ops_scheduled; - } executor; - - /** is the transport destroying itself? */ - uint8_t destroying; - /** has the upper layer closed the transport? */ - uint8_t closed; - - /** is there a read request to the endpoint outstanding? */ - uint8_t endpoint_reading; - - /** various lists of streams */ - grpc_chttp2_stream_list lists[STREAM_LIST_COUNT]; - - /** global state for reading/writing */ - grpc_chttp2_transport_global global; - /** state only accessible by the chain of execution that - set writing_state >= GRPC_WRITING, and only by the writing closure - chain. */ - grpc_chttp2_transport_writing writing; - - /** maps stream id to grpc_chttp2_stream objects */ - grpc_chttp2_stream_map stream_map; - - /** closure to execute writing */ - grpc_closure writing_action; - /** closure to start reading from the endpoint */ - grpc_closure reading_action; - grpc_closure reading_action_locked; - /** closure to initiate writing */ - grpc_closure initiate_writing; - /** closure to finish writing */ - grpc_closure terminate_writing; - /** closure to flush read state up the stack */ - grpc_closure initiate_read_flush_locked; - - /** incoming read bytes */ - gpr_slice_buffer read_buffer; - - /** address to place a newly accepted stream - set and unset by - grpc_chttp2_parsing_accept_stream; used by init_stream to - publish the accepted server stream */ - grpc_chttp2_stream **accepting_stream; +struct grpc_chttp2_stream { + grpc_chttp2_transport *t; + grpc_stream_refcount *refcount; - struct { - /* accept stream callback */ - void (*accept_stream)(grpc_exec_ctx *exec_ctx, void *user_data, - grpc_transport *transport, const void *server_data); - void *accept_stream_user_data; + grpc_closure destroy_stream; + void *destroy_stream_arg; - /** connectivity tracking */ - grpc_connectivity_state_tracker state_tracker; - } channel_callback; -}; + grpc_chttp2_stream_link links[STREAM_LIST_COUNT]; + uint8_t included[STREAM_LIST_COUNT]; -struct grpc_chttp2_stream_global { /** HTTP2 stream id for this stream, or zero if one has not been assigned */ uint32_t id; @@ -434,50 +404,18 @@ struct grpc_chttp2_stream_global { grpc_chttp2_data_parser data_parser; /** number of bytes received - reset at end of parse thread execution */ int64_t received_bytes; -}; -typedef struct { /** HTTP2 stream id for this stream, or zero if one has not been assigned */ - uint32_t id; uint8_t fetching; bool sent_initial_metadata; uint8_t sent_message; uint8_t sent_trailing_metadata; - uint8_t read_closed; - /** send this initial metadata */ - grpc_metadata_batch *send_initial_metadata; - grpc_byte_stream *send_message; - grpc_metadata_batch *send_trailing_metadata; - int64_t outgoing_window; /** how much window should we announce? */ uint32_t announce_window; gpr_slice_buffer flow_controlled_buffer; gpr_slice fetching_slice; size_t stream_fetched; grpc_closure finished_fetch; - /** stats gathered during the write */ - grpc_transport_one_way_stats stats; -} grpc_chttp2_stream_writing; - -#if 0 -struct grpc_chttp2_stream_parsing { - - /** incoming metadata */ - grpc_chttp2_incoming_metadata_buffer metadata_buffer[2]; -}; -#endif - -struct grpc_chttp2_stream { - grpc_chttp2_transport *t; - grpc_stream_refcount *refcount; - grpc_chttp2_stream_global global; - grpc_chttp2_stream_writing writing; - - grpc_closure destroy_stream; - void *destroy_stream_arg; - - grpc_chttp2_stream_link links[STREAM_LIST_COUNT]; - uint8_t included[STREAM_LIST_COUNT]; }; /** Transport writing call flow: @@ -493,118 +431,84 @@ struct grpc_chttp2_stream { The actual call chain is documented in the implementation of this function. */ void grpc_chttp2_initiate_write(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_global *transport_global, + grpc_chttp2_transport *t, bool covered_by_poller, const char *reason); /** Someone is unlocking the transport mutex: check to see if writes - are required, and schedule them if so */ -int grpc_chttp2_unlocking_check_writes(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_global *global, - grpc_chttp2_transport_writing *writing); -void grpc_chttp2_perform_writes( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_writing *transport_writing, - grpc_endpoint *endpoint); -void grpc_chttp2_terminate_writing(grpc_exec_ctx *exec_ctx, - void *transport_writing, grpc_error *error); -void grpc_chttp2_cleanup_writing(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_global *global, - grpc_chttp2_transport_writing *writing); + are required, and frame them if so */ +bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t); +void grpc_chttp2_end_write(grpc_exec_ctx *exec_ctx, void *transport_writing, + grpc_error *error); /** Process one slice of incoming data; return 1 if the connection is still viable after reading, or 0 if the connection should be torn down */ -grpc_error *grpc_chttp2_perform_read( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - gpr_slice slice); +grpc_error *grpc_chttp2_perform_read(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, gpr_slice slice); -bool grpc_chttp2_list_add_writable_stream( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global); +bool grpc_chttp2_list_add_writable_stream(grpc_chttp2_transport *t, + grpc_chttp2_stream *s); /** Get a writable stream returns non-zero if there was a stream available */ -int grpc_chttp2_list_pop_writable_stream( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_transport_writing *transport_writing, - grpc_chttp2_stream_global **stream_global, - grpc_chttp2_stream_writing **stream_writing); +int grpc_chttp2_list_pop_writable_stream(grpc_chttp2_transport *t, + grpc_chttp2_stream **s); bool grpc_chttp2_list_remove_writable_stream( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global) GRPC_MUST_USE_RESULT; - -void grpc_chttp2_list_add_writing_stream( - grpc_chttp2_transport_writing *transport_writing, - grpc_chttp2_stream_writing *stream_writing); -int grpc_chttp2_list_have_writing_streams( - grpc_chttp2_transport_writing *transport_writing); -int grpc_chttp2_list_pop_writing_stream( - grpc_chttp2_transport_writing *transport_writing, - grpc_chttp2_stream_writing **stream_writing); - -void grpc_chttp2_list_add_written_stream( - grpc_chttp2_transport_writing *transport_writing, - grpc_chttp2_stream_writing *stream_writing); -int grpc_chttp2_list_pop_written_stream( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_transport_writing *transport_writing, - grpc_chttp2_stream_global **stream_global, - grpc_chttp2_stream_writing **stream_writing); - -void grpc_chttp2_list_add_waiting_for_concurrency( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global); -int grpc_chttp2_list_pop_waiting_for_concurrency( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global **stream_global); - -void grpc_chttp2_list_add_check_read_ops( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global); -bool grpc_chttp2_list_remove_check_read_ops( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global); -int grpc_chttp2_list_pop_check_read_ops( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global **stream_global); - -void grpc_chttp2_list_add_writing_stalled_by_transport( - grpc_chttp2_transport_writing *transport_writing, - grpc_chttp2_stream_writing *stream_writing); + grpc_chttp2_transport *t, grpc_chttp2_stream *s) GRPC_MUST_USE_RESULT; + +void grpc_chttp2_list_add_writing_stream(grpc_chttp2_transport *t, + grpc_chttp2_stream *s); +int grpc_chttp2_list_have_writing_streams(grpc_chttp2_transport *t); +int grpc_chttp2_list_pop_writing_stream(grpc_chttp2_transport *t, + grpc_chttp2_stream **s); + +void grpc_chttp2_list_add_written_stream(grpc_chttp2_transport *t, + grpc_chttp2_stream *s); +int grpc_chttp2_list_pop_written_stream(grpc_chttp2_transport *t, + grpc_chttp2_stream **s); + +void grpc_chttp2_list_add_waiting_for_concurrency(grpc_chttp2_transport *t, + grpc_chttp2_stream *s); +int grpc_chttp2_list_pop_waiting_for_concurrency(grpc_chttp2_transport *t, + grpc_chttp2_stream **s); + +void grpc_chttp2_list_add_check_read_ops(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s); +bool grpc_chttp2_list_remove_check_read_ops(grpc_chttp2_transport *t, + grpc_chttp2_stream *s); +int grpc_chttp2_list_pop_check_read_ops(grpc_chttp2_transport *t, + grpc_chttp2_stream **s); + +void grpc_chttp2_list_add_writing_stalled_by_transport(grpc_chttp2_transport *t, + grpc_chttp2_stream *s); bool grpc_chttp2_list_flush_writing_stalled_by_transport( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_writing *transport_writing); - -void grpc_chttp2_list_add_stalled_by_transport( - grpc_chttp2_transport_writing *transport_writing, - grpc_chttp2_stream_writing *stream_writing); -int grpc_chttp2_list_pop_stalled_by_transport( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global **stream_global); -void grpc_chttp2_list_remove_stalled_by_transport( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global); - -void grpc_chttp2_list_add_closed_waiting_for_writing( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global); -int grpc_chttp2_list_pop_closed_waiting_for_writing( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global **stream_global); - -grpc_chttp2_stream_global *grpc_chttp2_parsing_lookup_stream( - grpc_chttp2_transport_global *transport_global, uint32_t id); -grpc_chttp2_stream_global *grpc_chttp2_parsing_accept_stream( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - uint32_t id); - -void grpc_chttp2_add_incoming_goaway( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - uint32_t goaway_error, gpr_slice goaway_text); - -void grpc_chttp2_parsing_become_skip_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global); - -void grpc_chttp2_complete_closure_step( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, grpc_closure **pclosure, - grpc_error *error); + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t); + +void grpc_chttp2_list_add_stalled_by_transport(grpc_chttp2_transport *t, + grpc_chttp2_stream *s); +int grpc_chttp2_list_pop_stalled_by_transport(grpc_chttp2_transport *t, + grpc_chttp2_stream **s); +void grpc_chttp2_list_remove_stalled_by_transport(grpc_chttp2_transport *t, + grpc_chttp2_stream *s); + +grpc_chttp2_stream *grpc_chttp2_parsing_lookup_stream(grpc_chttp2_transport *t, + uint32_t id); +grpc_chttp2_stream *grpc_chttp2_parsing_accept_stream(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + uint32_t id); + +void grpc_chttp2_add_incoming_goaway(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + uint32_t goaway_error, + gpr_slice goaway_text); + +void grpc_chttp2_parsing_become_skip_parser(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t); + +void grpc_chttp2_complete_closure_step(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s, + grpc_closure **pclosure, + grpc_error *error); #define GRPC_CHTTP2_CLIENT_CONNECT_STRING "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" #define GRPC_CHTTP2_CLIENT_CONNECT_STRLEN \ @@ -695,35 +599,30 @@ void grpc_chttp2_flowctl_trace(const char *file, int line, const char *phase, const char *var2, int is_client, uint32_t stream_id, int64_t val1, int64_t val2); -void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream, +void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, + grpc_chttp2_stream *stream, grpc_status_code status, gpr_slice *details); -void grpc_chttp2_mark_stream_closed( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, int close_reads, int close_writes, - grpc_error *error); +void grpc_chttp2_mark_stream_closed(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s, int close_reads, + int close_writes, grpc_error *error); void grpc_chttp2_start_writing(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_global *transport_global); + grpc_chttp2_transport *t); #ifdef GRPC_STREAM_REFCOUNT_DEBUG -#define GRPC_CHTTP2_STREAM_REF(stream_global, reason) \ - grpc_chttp2_stream_ref(stream_global, reason) -#define GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, reason) \ - grpc_chttp2_stream_unref(exec_ctx, stream_global, reason) -void grpc_chttp2_stream_ref(grpc_chttp2_stream_global *stream_global, - const char *reason); -void grpc_chttp2_stream_unref(grpc_exec_ctx *exec_ctx, - grpc_chttp2_stream_global *stream_global, +#define GRPC_CHTTP2_STREAM_REF(stream, reason) \ + grpc_chttp2_stream_ref(stream, reason) +#define GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream, reason) \ + grpc_chttp2_stream_unref(exec_ctx, stream, reason) +void grpc_chttp2_stream_ref(grpc_chttp2_stream *s, const char *reason); +void grpc_chttp2_stream_unref(grpc_exec_ctx *exec_ctx, grpc_chttp2_stream *s, const char *reason); #else -#define GRPC_CHTTP2_STREAM_REF(stream_global, reason) \ - grpc_chttp2_stream_ref(stream_global) -#define GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, reason) \ - grpc_chttp2_stream_unref(exec_ctx, stream_global) -void grpc_chttp2_stream_ref(grpc_chttp2_stream_global *stream_global); -void grpc_chttp2_stream_unref(grpc_exec_ctx *exec_ctx, - grpc_chttp2_stream_global *stream_global); +#define GRPC_CHTTP2_STREAM_REF(stream, reason) grpc_chttp2_stream_ref(stream) +#define GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream, reason) \ + grpc_chttp2_stream_unref(exec_ctx, stream) +void grpc_chttp2_stream_ref(grpc_chttp2_stream *s); +void grpc_chttp2_stream_unref(grpc_exec_ctx *exec_ctx, grpc_chttp2_stream *s); #endif //#define GRPC_CHTTP2_REFCOUNTING_DEBUG 1 @@ -746,9 +645,8 @@ void grpc_chttp2_ref_transport(grpc_chttp2_transport *t); #endif grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, uint32_t frame_size, - uint32_t flags); + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s, + uint32_t frame_size, uint32_t flags); void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, gpr_slice slice); @@ -756,20 +654,18 @@ void grpc_chttp2_incoming_byte_stream_finished( grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, grpc_error *error, int from_parsing_thread); -void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_global *parsing, +void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, const uint8_t *opaque_8bytes); /** add a ref to the stream and add it to the writable list; ref will be dropped in writing.c */ void grpc_chttp2_become_writable(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, - bool covered_by_poller, const char *reason); + grpc_chttp2_transport *t, + grpc_chttp2_stream *s, bool covered_by_poller, + const char *reason); void grpc_chttp2_cancel_stream(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, + grpc_chttp2_transport *t, grpc_chttp2_stream *s, grpc_error *due_to_error); #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_INTERNAL_H */ -- cgit v1.2.3 From 4e5b4521478cf817dae0c646232b7ec184f0ebe6 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 26 Aug 2016 16:31:34 -0700 Subject: Compiling, writing work --- .../transport/chttp2/transport/chttp2_transport.c | 154 +++--- .../ext/transport/chttp2/transport/frame_data.c | 33 +- .../ext/transport/chttp2/transport/frame_goaway.c | 11 +- .../ext/transport/chttp2/transport/frame_ping.c | 15 +- .../transport/chttp2/transport/frame_rst_stream.c | 19 +- .../transport/chttp2/transport/frame_settings.c | 22 +- .../chttp2/transport/frame_window_update.c | 35 +- .../ext/transport/chttp2/transport/hpack_parser.c | 29 +- src/core/ext/transport/chttp2/transport/internal.h | 42 +- src/core/ext/transport/chttp2/transport/parsing.c | 610 ++++++++++----------- .../ext/transport/chttp2/transport/stream_lists.c | 262 +++------ src/core/ext/transport/chttp2/transport/writing.c | 557 ++++++++++--------- 12 files changed, 817 insertions(+), 972 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 7a70744e5c..f2c68df068 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -67,18 +67,20 @@ int grpc_flowctl_trace = 0; static const grpc_transport_vtable vtable; /* forward declarations of various callbacks that we'll build closures around */ -static void writing_action(grpc_exec_ctx *exec_ctx, void *t, grpc_error *error); -static void reading_action(grpc_exec_ctx *exec_ctx, void *t, grpc_error *error); -static void reading_action_locked(grpc_exec_ctx *exec_ctx, void *arg, - grpc_error *error); -static void initiate_writing_locked(grpc_exec_ctx *exec_ctx, void *t, +static void write_action_begin_locked(grpc_exec_ctx *exec_ctx, void *t, + grpc_error *error); +static void write_action(grpc_exec_ctx *exec_ctx, void *t, grpc_error *error); +static void write_action_end(grpc_exec_ctx *exec_ctx, void *t, + grpc_error *error); +static void write_action_end_locked(grpc_exec_ctx *exec_ctx, void *t, grpc_error *error); -static void initiate_read_flush_locked(grpc_exec_ctx *exec_ctx, void *t, - grpc_error *error); -static void terminate_writing_with_lock(grpc_exec_ctx *exec_ctx, void *t, - grpc_error *error); -static void start_writing(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t); +static void read_action_begin(grpc_exec_ctx *exec_ctx, void *t, + grpc_error *error); +static void read_action_locked(grpc_exec_ctx *exec_ctx, void *t, + grpc_error *error); +static void read_action_flush_locked(grpc_exec_ctx *exec_ctx, void *t, + grpc_error *error); /** Set a transport level setting, and push it to our peer */ static void push_setting(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, @@ -224,12 +226,15 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, gpr_slice_buffer_init(&t->outbuf); grpc_chttp2_hpack_compressor_init(&t->hpack_compressor); - grpc_closure_init(&t->writing_action, writing_action, t); - grpc_closure_init(&t->reading_action, reading_action, t); - grpc_closure_init(&t->reading_action_locked, reading_action_locked, t); - grpc_closure_init(&t->terminate_writing, terminate_writing_with_lock, t); - grpc_closure_init(&t->initiate_read_flush_locked, initiate_read_flush_locked, + + grpc_closure_init(&t->write_action_begin_locked, write_action_begin_locked, t); + grpc_closure_init(&t->write_action, write_action, t); + grpc_closure_init(&t->write_action_end, write_action_end, t); + grpc_closure_init(&t->write_action_end_locked, write_action_end_locked, t); + grpc_closure_init(&t->read_action_begin, read_action_begin, t); + grpc_closure_init(&t->read_action_locked, read_action_locked, t); + grpc_closure_init(&t->read_action_flush_locked, read_action_flush_locked, t); grpc_chttp2_goaway_parser_init(&t->goaway_parser); grpc_chttp2_hpack_parser_init(&t->hpack_parser); @@ -538,27 +543,6 @@ grpc_chttp2_stream *grpc_chttp2_parsing_accept_stream(grpc_exec_ctx *exec_ctx, return accepting; } -/******************************************************************************* - * LOCK MANAGEMENT - */ - -#if 0 -static void initiate_writing_locked(grpc_exec_ctx *exec_ctx, void *tp, - grpc_error *error) { - grpc_chttp2_transport *t = tp; - GPR_ASSERT(t->executor.write_state == GRPC_CHTTP2_WRITE_SCHEDULED); - start_writing(exec_ctx, t); -} -#endif - -static void initiate_read_flush_locked(grpc_exec_ctx *exec_ctx, void *tp, - grpc_error *error) { - grpc_chttp2_transport *t = tp; - t->check_read_ops_scheduled = false; - check_read_ops(exec_ctx, t); - GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "initiate_read_flush_locked"); -} - /******************************************************************************* * OUTPUT PROCESSING */ @@ -572,7 +556,8 @@ void grpc_chttp2_initiate_write(grpc_exec_ctx *exec_ctx, case GRPC_CHTTP2_WRITE_STATE_IDLE: t->write_state = GRPC_CHTTP2_WRITE_STATE_WRITING; GRPC_CHTTP2_REF_TRANSPORT(t, "writing"); - grpc_combiner_execute_finally(exec_ctx, t->combiner, &t->writing_action, + grpc_combiner_execute_finally(exec_ctx, t->combiner, + &t->write_action_begin_locked, GRPC_ERROR_NONE, false); break; case GRPC_CHTTP2_WRITE_STATE_WRITING: @@ -594,37 +579,39 @@ void grpc_chttp2_become_writable(grpc_exec_ctx *exec_ctx, } } -static void start_writing(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t) { - GPR_TIMER_BEGIN("start_writing", 0); +static void write_action_begin_locked(grpc_exec_ctx *exec_ctx, void *gt, + grpc_error *error_ignored) { + GPR_TIMER_BEGIN("write_action_begin_locked", 0); + grpc_chttp2_transport *t = gt; GPR_ASSERT(t->write_state != GRPC_CHTTP2_WRITE_STATE_IDLE); if (!t->closed && grpc_chttp2_begin_write(exec_ctx, t)) { prevent_endpoint_shutdown(t); - grpc_exec_ctx_sched(exec_ctx, &t->writing_action, GRPC_ERROR_NONE, NULL); + grpc_exec_ctx_sched(exec_ctx, &t->write_action, GRPC_ERROR_NONE, NULL); } else { t->write_state = GRPC_CHTTP2_WRITE_STATE_IDLE; GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "writing"); } - GPR_TIMER_END("start_writing", 0); + GPR_TIMER_END("write_action_begin_locked", 0); } -static void push_setting(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, - grpc_chttp2_setting_id id, uint32_t value) { - const grpc_chttp2_setting_parameters *sp = - &grpc_chttp2_settings_parameters[id]; - uint32_t use_value = GPR_CLAMP(value, sp->min_value, sp->max_value); - if (use_value != value) { - gpr_log(GPR_INFO, "Requested parameter %s clamped from %d to %d", sp->name, - value, use_value); - } - if (use_value != t->settings[GRPC_LOCAL_SETTINGS][id]) { - t->settings[GRPC_LOCAL_SETTINGS][id] = use_value; - t->dirtied_local_settings = 1; - grpc_chttp2_initiate_write(exec_ctx, t, false, "push_setting"); - } +static void write_action(grpc_exec_ctx *exec_ctx, void *gt, grpc_error *error) { + grpc_chttp2_transport *t = gt; + GPR_TIMER_BEGIN("write_action", 0); + grpc_endpoint_write(exec_ctx, t->ep, &t->outbuf, &t->write_action_end); + GPR_TIMER_END("write_action", 0); } -static void terminate_writing_with_lock(grpc_exec_ctx *exec_ctx, void *tp, - grpc_error *error) { +static void write_action_end(grpc_exec_ctx *exec_ctx, void *gt, + grpc_error *error) { + grpc_chttp2_transport *t = gt; + GPR_TIMER_BEGIN("write_action_end", 0); + grpc_combiner_execute(exec_ctx, t->combiner, &t->write_action_end_locked, + GRPC_ERROR_REF(error)); + GPR_TIMER_END("write_action_end", 0); +} + +static void write_action_end_locked(grpc_exec_ctx *exec_ctx, void *tp, + grpc_error *error) { GPR_TIMER_BEGIN("terminate_writing_with_lock", 0); grpc_chttp2_transport *t = tp; allow_endpoint_shutdown_locked(exec_ctx, t); @@ -646,7 +633,7 @@ static void terminate_writing_with_lock(grpc_exec_ctx *exec_ctx, void *tp, GPR_TIMER_MARK("state=writing_stale_with_poller", 0); t->write_state = GRPC_CHTTP2_WRITE_STATE_WRITING; GRPC_CHTTP2_REF_TRANSPORT(t, "writing"); - grpc_combiner_execute_finally(exec_ctx, t->combiner, &t->writing_action, + grpc_combiner_execute_finally(exec_ctx, t->combiner, &t->write_action, GRPC_ERROR_NONE, false); break; } @@ -655,21 +642,20 @@ static void terminate_writing_with_lock(grpc_exec_ctx *exec_ctx, void *tp, GPR_TIMER_END("terminate_writing_with_lock", 0); } -static void grpc_chttp2_terminate_writing(grpc_exec_ctx *exec_ctx, void *gt, - grpc_error *error) { - GPR_TIMER_BEGIN("grpc_chttp2_terminate_writing", 0); - grpc_chttp2_transport *t = gt; - grpc_combiner_execute(exec_ctx, t->combiner, &t->terminate_writing, - GRPC_ERROR_REF(error)); - GPR_TIMER_END("grpc_chttp2_terminate_writing", 0); -} - -static void writing_action(grpc_exec_ctx *exec_ctx, void *gt, - grpc_error *error) { - grpc_chttp2_transport *t = gt; - GPR_TIMER_BEGIN("writing_action", 0); - grpc_endpoint_write(exec_ctx, t->ep, &t->outbuf, &t->writing_done_action); - GPR_TIMER_END("writing_action", 0); +static void push_setting(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, + grpc_chttp2_setting_id id, uint32_t value) { + const grpc_chttp2_setting_parameters *sp = + &grpc_chttp2_settings_parameters[id]; + uint32_t use_value = GPR_CLAMP(value, sp->min_value, sp->max_value); + if (use_value != value) { + gpr_log(GPR_INFO, "Requested parameter %s clamped from %d to %d", sp->name, + value, use_value); + } + if (use_value != t->settings[GRPC_LOCAL_SETTINGS][id]) { + t->settings[GRPC_LOCAL_SETTINGS][id] = use_value; + t->dirtied_local_settings = 1; + grpc_chttp2_initiate_write(exec_ctx, t, false, "push_setting"); + } } void grpc_chttp2_add_incoming_goaway(grpc_exec_ctx *exec_ctx, @@ -1091,6 +1077,14 @@ static void perform_transport_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, * INPUT PROCESSING - GENERAL */ +static void read_action_flush_locked(grpc_exec_ctx *exec_ctx, void *tp, + grpc_error *error) { + grpc_chttp2_transport *t = tp; + t->check_read_ops_scheduled = false; + check_read_ops(exec_ctx, t); + GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "initiate_read_flush_locked"); +} + static void check_read_ops(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t) { GPR_TIMER_BEGIN("check_read_ops", 0); grpc_chttp2_stream *s; @@ -1529,15 +1523,15 @@ static void update_global_window(void *args, uint32_t id, void *stream) { * INPUT PROCESSING - PARSING */ -static void reading_action(grpc_exec_ctx *exec_ctx, void *tp, - grpc_error *error) { +static void read_action_begin(grpc_exec_ctx *exec_ctx, void *tp, + grpc_error *error) { /* Control flow: reading_action_locked -> (parse_unlocked -> post_parse_locked)? -> post_reading_action_locked */ GPR_TIMER_BEGIN("reading_action", 0); grpc_chttp2_transport *t = tp; - grpc_combiner_execute(exec_ctx, t->combiner, &t->reading_action_locked, + grpc_combiner_execute(exec_ctx, t->combiner, &t->read_action_locked, GRPC_ERROR_REF(error)); GPR_TIMER_END("reading_action", 0); } @@ -1569,8 +1563,8 @@ static grpc_error *try_http_parsing(grpc_exec_ctx *exec_ctx, return error; } -static void reading_action_locked(grpc_exec_ctx *exec_ctx, void *tp, - grpc_error *error) { +static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp, + grpc_error *error) { GPR_TIMER_BEGIN("reading_action_locked", 0); grpc_chttp2_transport *t = tp; @@ -1633,7 +1627,7 @@ static void reading_action_locked(grpc_exec_ctx *exec_ctx, void *tp, gpr_slice_buffer_reset_and_unref(&t->read_buffer); if (keep_reading) { - grpc_endpoint_read(exec_ctx, t->ep, &t->read_buffer, &t->reading_action); + grpc_endpoint_read(exec_ctx, t->ep, &t->read_buffer, &t->read_action_begin); allow_endpoint_shutdown_locked(exec_ctx, t); GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "keep_reading"); } else { @@ -2011,5 +2005,5 @@ void grpc_chttp2_transport_start_reading(grpc_exec_ctx *exec_ctx, gpr_slice_buffer_move_into(read_buffer, &t->read_buffer); gpr_free(read_buffer); } - reading_action(exec_ctx, t, GRPC_ERROR_NONE); + read_action_begin(exec_ctx, t, GRPC_ERROR_NONE); } diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c index 388a5aba2b..e340b2fb06 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.c +++ b/src/core/ext/transport/chttp2/transport/frame_data.c @@ -141,10 +141,10 @@ void grpc_chttp2_encode_data(uint32_t id, gpr_slice_buffer *inbuf, stats->data_bytes += write_bytes; } -grpc_error *grpc_chttp2_data_parser_parse( - grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, gpr_slice slice, int is_last) { +grpc_error *grpc_chttp2_data_parser_parse(grpc_exec_ctx *exec_ctx, void *parser, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s, + gpr_slice slice, int is_last) { uint8_t *const beg = GPR_SLICE_START_PTR(slice); uint8_t *const end = GPR_SLICE_END_PTR(slice); uint8_t *cur = beg; @@ -154,8 +154,8 @@ grpc_error *grpc_chttp2_data_parser_parse( char *msg; if (is_last && p->is_last_frame) { - grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global, - true, false, GRPC_ERROR_NONE); + grpc_chttp2_mark_stream_closed(exec_ctx, t, s, true, false, + GRPC_ERROR_NONE); } if (cur == end) { @@ -168,7 +168,7 @@ grpc_error *grpc_chttp2_data_parser_parse( return GRPC_ERROR_REF(p->error); fh_0: case GRPC_CHTTP2_DATA_FH_0: - stream_global->stats.incoming.framing_bytes++; + s->stats.incoming.framing_bytes++; p->frame_type = *cur; switch (p->frame_type) { case 0: @@ -181,7 +181,7 @@ grpc_error *grpc_chttp2_data_parser_parse( gpr_asprintf(&msg, "Bad GRPC frame type 0x%02x", p->frame_type); p->error = GRPC_ERROR_CREATE(msg); p->error = grpc_error_set_int(p->error, GRPC_ERROR_INT_STREAM_ID, - (intptr_t)stream_global->id); + (intptr_t)s->id); gpr_free(msg); msg = gpr_dump_slice(slice, GPR_DUMP_HEX | GPR_DUMP_ASCII); p->error = @@ -198,7 +198,7 @@ grpc_error *grpc_chttp2_data_parser_parse( } /* fallthrough */ case GRPC_CHTTP2_DATA_FH_1: - stream_global->stats.incoming.framing_bytes++; + s->stats.incoming.framing_bytes++; p->frame_size = ((uint32_t)*cur) << 24; if (++cur == end) { p->state = GRPC_CHTTP2_DATA_FH_2; @@ -206,7 +206,7 @@ grpc_error *grpc_chttp2_data_parser_parse( } /* fallthrough */ case GRPC_CHTTP2_DATA_FH_2: - stream_global->stats.incoming.framing_bytes++; + s->stats.incoming.framing_bytes++; p->frame_size |= ((uint32_t)*cur) << 16; if (++cur == end) { p->state = GRPC_CHTTP2_DATA_FH_3; @@ -214,7 +214,7 @@ grpc_error *grpc_chttp2_data_parser_parse( } /* fallthrough */ case GRPC_CHTTP2_DATA_FH_3: - stream_global->stats.incoming.framing_bytes++; + s->stats.incoming.framing_bytes++; p->frame_size |= ((uint32_t)*cur) << 8; if (++cur == end) { p->state = GRPC_CHTTP2_DATA_FH_4; @@ -222,7 +222,7 @@ grpc_error *grpc_chttp2_data_parser_parse( } /* fallthrough */ case GRPC_CHTTP2_DATA_FH_4: - stream_global->stats.incoming.framing_bytes++; + s->stats.incoming.framing_bytes++; p->frame_size |= ((uint32_t)*cur); p->state = GRPC_CHTTP2_DATA_FRAME; ++cur; @@ -231,8 +231,7 @@ grpc_error *grpc_chttp2_data_parser_parse( message_flags |= GRPC_WRITE_INTERNAL_COMPRESS; } p->parsing_frame = incoming_byte_stream = - grpc_chttp2_incoming_byte_stream_create(exec_ctx, transport_global, - stream_global, p->frame_size, + grpc_chttp2_incoming_byte_stream_create(exec_ctx, t, s, p->frame_size, message_flags); /* fallthrough */ case GRPC_CHTTP2_DATA_FRAME: @@ -241,7 +240,7 @@ grpc_error *grpc_chttp2_data_parser_parse( } uint32_t remaining = (uint32_t)(end - cur); if (remaining == p->frame_size) { - stream_global->stats.incoming.data_bytes += p->frame_size; + s->stats.incoming.data_bytes += p->frame_size; grpc_chttp2_incoming_byte_stream_push( exec_ctx, p->parsing_frame, gpr_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); @@ -251,7 +250,7 @@ grpc_error *grpc_chttp2_data_parser_parse( p->state = GRPC_CHTTP2_DATA_FH_0; return GRPC_ERROR_NONE; } else if (remaining > p->frame_size) { - stream_global->stats.incoming.data_bytes += p->frame_size; + s->stats.incoming.data_bytes += p->frame_size; grpc_chttp2_incoming_byte_stream_push( exec_ctx, p->parsing_frame, gpr_slice_sub(slice, (size_t)(cur - beg), @@ -267,7 +266,7 @@ grpc_error *grpc_chttp2_data_parser_parse( exec_ctx, p->parsing_frame, gpr_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); p->frame_size -= remaining; - stream_global->stats.incoming.data_bytes += remaining; + s->stats.incoming.data_bytes += remaining; return GRPC_ERROR_NONE; } } diff --git a/src/core/ext/transport/chttp2/transport/frame_goaway.c b/src/core/ext/transport/chttp2/transport/frame_goaway.c index e40c5e393b..33d2269169 100644 --- a/src/core/ext/transport/chttp2/transport/frame_goaway.c +++ b/src/core/ext/transport/chttp2/transport/frame_goaway.c @@ -67,10 +67,11 @@ grpc_error *grpc_chttp2_goaway_parser_begin_frame(grpc_chttp2_goaway_parser *p, return GRPC_ERROR_NONE; } -grpc_error *grpc_chttp2_goaway_parser_parse( - grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, gpr_slice slice, int is_last) { +grpc_error *grpc_chttp2_goaway_parser_parse(grpc_exec_ctx *exec_ctx, + void *parser, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s, + gpr_slice slice, int is_last) { uint8_t *const beg = GPR_SLICE_START_PTR(slice); uint8_t *const end = GPR_SLICE_END_PTR(slice); uint8_t *cur = beg; @@ -149,7 +150,7 @@ grpc_error *grpc_chttp2_goaway_parser_parse( p->state = GRPC_CHTTP2_GOAWAY_DEBUG; if (is_last) { grpc_chttp2_add_incoming_goaway( - exec_ctx, transport_global, (uint32_t)p->error_code, + exec_ctx, t, (uint32_t)p->error_code, gpr_slice_new(p->debug_data, p->debug_length, gpr_free)); p->debug_data = NULL; } diff --git a/src/core/ext/transport/chttp2/transport/frame_ping.c b/src/core/ext/transport/chttp2/transport/frame_ping.c index 9a56e66788..624f42649d 100644 --- a/src/core/ext/transport/chttp2/transport/frame_ping.c +++ b/src/core/ext/transport/chttp2/transport/frame_ping.c @@ -73,10 +73,10 @@ grpc_error *grpc_chttp2_ping_parser_begin_frame(grpc_chttp2_ping_parser *parser, return GRPC_ERROR_NONE; } -grpc_error *grpc_chttp2_ping_parser_parse( - grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, gpr_slice slice, int is_last) { +grpc_error *grpc_chttp2_ping_parser_parse(grpc_exec_ctx *exec_ctx, void *parser, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s, + gpr_slice slice, int is_last) { uint8_t *const beg = GPR_SLICE_START_PTR(slice); uint8_t *const end = GPR_SLICE_END_PTR(slice); uint8_t *cur = beg; @@ -91,12 +91,11 @@ grpc_error *grpc_chttp2_ping_parser_parse( if (p->byte == 8) { GPR_ASSERT(is_last); if (p->is_ack) { - grpc_chttp2_ack_ping(exec_ctx, transport_global, p->opaque_8bytes); + grpc_chttp2_ack_ping(exec_ctx, t, p->opaque_8bytes); } else { - gpr_slice_buffer_add(&transport_global->qbuf, + gpr_slice_buffer_add(&t->qbuf, grpc_chttp2_ping_create(1, p->opaque_8bytes)); - grpc_chttp2_initiate_write(exec_ctx, transport_global, false, - "ping response"); + grpc_chttp2_initiate_write(exec_ctx, t, false, "ping response"); } } diff --git a/src/core/ext/transport/chttp2/transport/frame_rst_stream.c b/src/core/ext/transport/chttp2/transport/frame_rst_stream.c index 7be664ced4..1bb6ed82b1 100644 --- a/src/core/ext/transport/chttp2/transport/frame_rst_stream.c +++ b/src/core/ext/transport/chttp2/transport/frame_rst_stream.c @@ -85,10 +85,11 @@ grpc_error *grpc_chttp2_rst_stream_parser_begin_frame( return GRPC_ERROR_NONE; } -grpc_error *grpc_chttp2_rst_stream_parser_parse( - grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, gpr_slice slice, int is_last) { +grpc_error *grpc_chttp2_rst_stream_parser_parse(grpc_exec_ctx *exec_ctx, + void *parser, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s, + gpr_slice slice, int is_last) { uint8_t *const beg = GPR_SLICE_START_PTR(slice); uint8_t *const end = GPR_SLICE_END_PTR(slice); uint8_t *cur = beg; @@ -99,7 +100,7 @@ grpc_error *grpc_chttp2_rst_stream_parser_parse( cur++; p->byte++; } - stream_global->stats.incoming.framing_bytes += (uint64_t)(end - cur); + s->stats.incoming.framing_bytes += (uint64_t)(end - cur); if (p->byte == 4) { GPR_ASSERT(is_last); @@ -112,17 +113,15 @@ grpc_error *grpc_chttp2_rst_stream_parser_parse( error = grpc_error_set_int(GRPC_ERROR_CREATE("RST_STREAM"), GRPC_ERROR_INT_HTTP2_ERROR, reason); grpc_status_code status_code = grpc_chttp2_http2_error_to_grpc_status( - (grpc_chttp2_error_code)reason, stream_global->deadline); + (grpc_chttp2_error_code)reason, s->deadline); char *status_details; gpr_asprintf(&status_details, "Received RST_STREAM with error code %d", reason); gpr_slice slice_details = gpr_slice_from_copied_string(status_details); gpr_free(status_details); - grpc_chttp2_fake_status(exec_ctx, transport_global, stream_global, - status_code, &slice_details); + grpc_chttp2_fake_status(exec_ctx, t, s, status_code, &slice_details); } - grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global, - true, true, error); + grpc_chttp2_mark_stream_closed(exec_ctx, t, s, true, true, error); } return GRPC_ERROR_NONE; diff --git a/src/core/ext/transport/chttp2/transport/frame_settings.c b/src/core/ext/transport/chttp2/transport/frame_settings.c index 32e6aa545f..fc0383d2e0 100644 --- a/src/core/ext/transport/chttp2/transport/frame_settings.c +++ b/src/core/ext/transport/chttp2/transport/frame_settings.c @@ -143,10 +143,10 @@ grpc_error *grpc_chttp2_settings_parser_begin_frame( } } -grpc_error *grpc_chttp2_settings_parser_parse( - grpc_exec_ctx *exec_ctx, void *p, - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, gpr_slice slice, int is_last) { +grpc_error *grpc_chttp2_settings_parser_parse(grpc_exec_ctx *exec_ctx, void *p, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s, + gpr_slice slice, int is_last) { grpc_chttp2_settings_parser *parser = p; const uint8_t *cur = GPR_SLICE_START_PTR(slice); const uint8_t *end = GPR_SLICE_END_PTR(slice); @@ -164,8 +164,7 @@ grpc_error *grpc_chttp2_settings_parser_parse( if (is_last) { memcpy(parser->target_settings, parser->incoming_settings, GRPC_CHTTP2_NUM_SETTINGS * sizeof(uint32_t)); - gpr_slice_buffer_add(&transport_global->qbuf, - grpc_chttp2_settings_ack_create()); + gpr_slice_buffer_add(&t->qbuf, grpc_chttp2_settings_ack_create()); } return GRPC_ERROR_NONE; } @@ -225,9 +224,9 @@ grpc_error *grpc_chttp2_settings_parser_parse( break; case GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE: grpc_chttp2_goaway_append( - transport_global->last_incoming_stream_id, sp->error_value, + t->last_incoming_stream_id, sp->error_value, gpr_slice_from_static_string("HTTP2 settings error"), - &transport_global->qbuf); + &t->qbuf); gpr_asprintf(&msg, "invalid value %u passed for %s", parser->value, sp->name); grpc_error *err = GRPC_ERROR_CREATE(msg); @@ -237,18 +236,17 @@ grpc_error *grpc_chttp2_settings_parser_parse( } if (parser->id == GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE && parser->incoming_settings[parser->id] != parser->value) { - transport_global->initial_window_update = + t->initial_window_update = (int64_t)parser->value - parser->incoming_settings[parser->id]; if (grpc_http_trace) { gpr_log(GPR_DEBUG, "adding %d for initial_window change", - (int)transport_global->initial_window_update); + (int)t->initial_window_update); } } parser->incoming_settings[parser->id] = parser->value; if (grpc_http_trace) { gpr_log(GPR_DEBUG, "CHTTP2:%s: got setting %d = %d", - transport_global->is_client ? "CLI" : "SVR", parser->id, - parser->value); + t->is_client ? "CLI" : "SVR", parser->id, parser->value); } } else if (grpc_http_trace) { gpr_log(GPR_ERROR, "CHTTP2: Ignoring unknown setting %d (value %d)", diff --git a/src/core/ext/transport/chttp2/transport/frame_window_update.c b/src/core/ext/transport/chttp2/transport/frame_window_update.c index 26bd73f0af..418166a6df 100644 --- a/src/core/ext/transport/chttp2/transport/frame_window_update.c +++ b/src/core/ext/transport/chttp2/transport/frame_window_update.c @@ -80,9 +80,8 @@ grpc_error *grpc_chttp2_window_update_parser_begin_frame( } grpc_error *grpc_chttp2_window_update_parser_parse( - grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, gpr_slice slice, int is_last) { + grpc_exec_ctx *exec_ctx, void *parser, grpc_chttp2_transport *t, + grpc_chttp2_stream *s, gpr_slice slice, int is_last) { uint8_t *const beg = GPR_SLICE_START_PTR(slice); uint8_t *const end = GPR_SLICE_END_PTR(slice); uint8_t *cur = beg; @@ -94,8 +93,8 @@ grpc_error *grpc_chttp2_window_update_parser_parse( p->byte++; } - if (stream_global != NULL) { - stream_global->stats.incoming.framing_bytes += (uint32_t)(end - cur); + if (s != NULL) { + s->stats.incoming.framing_bytes += (uint32_t)(end - cur); } if (p->byte == 4) { @@ -109,24 +108,24 @@ grpc_error *grpc_chttp2_window_update_parser_parse( } GPR_ASSERT(is_last); - if (transport_global->incoming_stream_id != 0) { - if (stream_global != NULL) { - bool was_zero = stream_global->outgoing_window <= 0; - GRPC_CHTTP2_FLOW_CREDIT_STREAM("parse", transport_global, stream_global, - outgoing_window, received_update); - bool is_zero = stream_global->outgoing_window <= 0; + if (t->incoming_stream_id != 0) { + if (s != NULL) { + bool was_zero = s->outgoing_window <= 0; + GRPC_CHTTP2_FLOW_CREDIT_STREAM("parse", t, s, outgoing_window, + received_update); + bool is_zero = s->outgoing_window <= 0; if (was_zero && !is_zero) { - grpc_chttp2_become_writable(exec_ctx, transport_global, stream_global, - false, "stream.read_flow_control"); + grpc_chttp2_become_writable(exec_ctx, t, s, false, + "stream.read_flow_control"); } } } else { - bool was_zero = transport_global->outgoing_window <= 0; - GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT("parse", transport_global, - outgoing_window, received_update); - bool is_zero = transport_global->outgoing_window <= 0; + bool was_zero = t->outgoing_window <= 0; + GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT("parse", t, outgoing_window, + received_update); + bool is_zero = t->outgoing_window <= 0; if (was_zero && !is_zero) { - grpc_chttp2_initiate_write(exec_ctx, transport_global, false, + grpc_chttp2_initiate_write(exec_ctx, t, false, "new_global_flow_control"); } } diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.c b/src/core/ext/transport/chttp2/transport/hpack_parser.c index 931be375d7..0ff5499919 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_parser.c +++ b/src/core/ext/transport/chttp2/transport/hpack_parser.c @@ -1571,14 +1571,15 @@ grpc_error *grpc_chttp2_hpack_parser_parse(grpc_exec_ctx *exec_ctx, return p->state(exec_ctx, p, beg, end); } -grpc_error *grpc_chttp2_header_parser_parse( - grpc_exec_ctx *exec_ctx, void *hpack_parser, - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, gpr_slice slice, int is_last) { +grpc_error *grpc_chttp2_header_parser_parse(grpc_exec_ctx *exec_ctx, + void *hpack_parser, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s, + gpr_slice slice, int is_last) { grpc_chttp2_hpack_parser *parser = hpack_parser; GPR_TIMER_BEGIN("grpc_chttp2_hpack_parser_parse", 0); - if (stream_global != NULL) { - stream_global->stats.incoming.header_bytes += GPR_SLICE_LENGTH(slice); + if (s != NULL) { + s->stats.incoming.header_bytes += GPR_SLICE_LENGTH(slice); } grpc_error *error = grpc_chttp2_hpack_parser_parse( exec_ctx, parser, GPR_SLICE_START_PTR(slice), GPR_SLICE_END_PTR(slice)); @@ -1594,21 +1595,17 @@ grpc_error *grpc_chttp2_header_parser_parse( } /* need to check for null stream: this can occur if we receive an invalid stream id on a header */ - if (stream_global != NULL) { + if (s != NULL) { if (parser->is_boundary) { - if (stream_global->header_frames_received == - GPR_ARRAY_SIZE(stream_global->metadata_buffer)) { + if (s->header_frames_received == GPR_ARRAY_SIZE(s->metadata_buffer)) { return GRPC_ERROR_CREATE("Too many trailer frames"); } - stream_global - ->published_metadata[stream_global->header_frames_received] = true; - stream_global->header_frames_received++; - grpc_chttp2_list_add_check_read_ops(exec_ctx, transport_global, - stream_global); + s->published_metadata[s->header_frames_received] = true; + s->header_frames_received++; + grpc_chttp2_list_add_check_read_ops(exec_ctx, t, s); } if (parser->is_eof) { - grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, - stream_global, true, false, + grpc_chttp2_mark_stream_closed(exec_ctx, t, s, true, false, GRPC_ERROR_NONE); } } diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 1ada0a6a80..ee905369a4 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -206,16 +206,14 @@ struct grpc_chttp2_transport { /** maps stream id to grpc_chttp2_stream objects */ grpc_chttp2_stream_map stream_map; - /** closure to execute writing */ - grpc_closure writing_action; - grpc_closure writing_done_action; - /** closure to finish writing */ - grpc_closure terminate_writing; - /** closure to start reading from the endpoint */ - grpc_closure reading_action; - grpc_closure reading_action_locked; - /** closure to flush read state up the stack */ - grpc_closure initiate_read_flush_locked; + grpc_closure write_action_begin_locked; + grpc_closure write_action; + grpc_closure write_action_end; + grpc_closure write_action_end_locked; + + grpc_closure read_action_begin; + grpc_closure read_action_locked; + grpc_closure read_action_flush_locked; /** incoming read bytes */ gpr_slice_buffer read_buffer; @@ -319,8 +317,24 @@ struct grpc_chttp2_transport { grpc_status_code goaway_error; uint32_t goaway_last_stream_index; gpr_slice goaway_text; + + /* closures to finish after writing */ + grpc_closure **finish_after_writing; + size_t finish_after_writing_count; + size_t finish_after_writing_capacity; }; +typedef enum { + GRPC_CHTTP2_CALL_WHEN_SCHEDULED, + GRPC_CHTTP2_CALL_WHEN_WRITTEN, +} grpc_chttp2_call_write_cb_when; + +typedef struct grpc_chttp2_write_cb { + size_t call_at_byte; + grpc_closure *closure; + grpc_chttp2_call_write_cb_when when; +} grpc_chttp2_write_cb; + struct grpc_chttp2_stream { grpc_chttp2_transport *t; grpc_stream_refcount *refcount; @@ -350,11 +364,11 @@ struct grpc_chttp2_stream { /** things the upper layers would like to send */ grpc_metadata_batch *send_initial_metadata; grpc_closure *send_initial_metadata_finished; - grpc_byte_stream *send_message; - grpc_closure *send_message_finished; grpc_metadata_batch *send_trailing_metadata; grpc_closure *send_trailing_metadata_finished; + grpc_byte_stream *fetching_send_message; + grpc_metadata_batch *recv_initial_metadata; grpc_closure *recv_initial_metadata_ready; grpc_byte_stream **recv_message; @@ -416,6 +430,10 @@ struct grpc_chttp2_stream { gpr_slice fetching_slice; size_t stream_fetched; grpc_closure finished_fetch; + + grpc_chttp2_write_cb *write_cbs; + size_t write_cb_count; + size_t write_cb_capacity; }; /** Transport writing call flow: diff --git a/src/core/ext/transport/chttp2/transport/parsing.c b/src/core/ext/transport/chttp2/transport/parsing.c index 983382ceef..7728cd4b81 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.c +++ b/src/core/ext/transport/chttp2/transport/parsing.c @@ -45,34 +45,34 @@ #include "src/core/lib/transport/static_metadata.h" #include "src/core/lib/transport/timeout_encoding.h" -static grpc_error *init_frame_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global); -static grpc_error *init_header_frame_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - int is_continuation); -static grpc_error *init_data_frame_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global); -static grpc_error *init_rst_stream_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global); -static grpc_error *init_settings_frame_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global); -static grpc_error *init_window_update_frame_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global); -static grpc_error *init_ping_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global); -static grpc_error *init_goaway_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global); -static grpc_error *init_skip_frame_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - int is_header); - -static grpc_error *parse_frame_slice( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - gpr_slice slice, int is_last); - -grpc_error *grpc_chttp2_perform_read( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - gpr_slice slice) { +static grpc_error *init_frame_parser(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t); +static grpc_error *init_header_frame_parser(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + int is_continuation); +static grpc_error *init_data_frame_parser(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t); +static grpc_error *init_rst_stream_parser(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t); +static grpc_error *init_settings_frame_parser(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t); +static grpc_error *init_window_update_frame_parser(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t); +static grpc_error *init_ping_parser(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t); +static grpc_error *init_goaway_parser(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t); +static grpc_error *init_skip_frame_parser(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + int is_header); + +static grpc_error *parse_frame_slice(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, gpr_slice slice, + int is_last); + +grpc_error *grpc_chttp2_perform_read(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + gpr_slice slice) { uint8_t *beg = GPR_SLICE_START_PTR(slice); uint8_t *end = GPR_SLICE_END_PTR(slice); uint8_t *cur = beg; @@ -80,7 +80,7 @@ grpc_error *grpc_chttp2_perform_read( if (cur == end) return GRPC_ERROR_NONE; - switch (transport_global->deframe_state) { + switch (t->deframe_state) { case GRPC_DTS_CLIENT_PREFIX_0: case GRPC_DTS_CLIENT_PREFIX_1: case GRPC_DTS_CLIENT_PREFIX_2: @@ -105,25 +105,22 @@ grpc_error *grpc_chttp2_perform_read( case GRPC_DTS_CLIENT_PREFIX_21: case GRPC_DTS_CLIENT_PREFIX_22: case GRPC_DTS_CLIENT_PREFIX_23: - while (cur != end && transport_global->deframe_state != GRPC_DTS_FH_0) { - if (*cur != GRPC_CHTTP2_CLIENT_CONNECT_STRING[transport_global - ->deframe_state]) { + while (cur != end && t->deframe_state != GRPC_DTS_FH_0) { + if (*cur != GRPC_CHTTP2_CLIENT_CONNECT_STRING[t->deframe_state]) { char *msg; gpr_asprintf( &msg, "Connect string mismatch: expected '%c' (%d) got '%c' (%d) " "at byte %d", - GRPC_CHTTP2_CLIENT_CONNECT_STRING[transport_global - ->deframe_state], - (int)(uint8_t)GRPC_CHTTP2_CLIENT_CONNECT_STRING - [transport_global->deframe_state], - *cur, (int)*cur, transport_global->deframe_state); + GRPC_CHTTP2_CLIENT_CONNECT_STRING[t->deframe_state], + (int)(uint8_t)GRPC_CHTTP2_CLIENT_CONNECT_STRING[t->deframe_state], + *cur, (int)*cur, t->deframe_state); err = GRPC_ERROR_CREATE(msg); gpr_free(msg); return err; } ++cur; - ++transport_global->deframe_state; + ++t->deframe_state; } if (cur == end) { return GRPC_ERROR_NONE; @@ -132,104 +129,99 @@ grpc_error *grpc_chttp2_perform_read( dts_fh_0: case GRPC_DTS_FH_0: GPR_ASSERT(cur < end); - transport_global->incoming_frame_size = ((uint32_t)*cur) << 16; + t->incoming_frame_size = ((uint32_t)*cur) << 16; if (++cur == end) { - transport_global->deframe_state = GRPC_DTS_FH_1; + t->deframe_state = GRPC_DTS_FH_1; return GRPC_ERROR_NONE; } /* fallthrough */ case GRPC_DTS_FH_1: GPR_ASSERT(cur < end); - transport_global->incoming_frame_size |= ((uint32_t)*cur) << 8; + t->incoming_frame_size |= ((uint32_t)*cur) << 8; if (++cur == end) { - transport_global->deframe_state = GRPC_DTS_FH_2; + t->deframe_state = GRPC_DTS_FH_2; return GRPC_ERROR_NONE; } /* fallthrough */ case GRPC_DTS_FH_2: GPR_ASSERT(cur < end); - transport_global->incoming_frame_size |= *cur; + t->incoming_frame_size |= *cur; if (++cur == end) { - transport_global->deframe_state = GRPC_DTS_FH_3; + t->deframe_state = GRPC_DTS_FH_3; return GRPC_ERROR_NONE; } /* fallthrough */ case GRPC_DTS_FH_3: GPR_ASSERT(cur < end); - transport_global->incoming_frame_type = *cur; + t->incoming_frame_type = *cur; if (++cur == end) { - transport_global->deframe_state = GRPC_DTS_FH_4; + t->deframe_state = GRPC_DTS_FH_4; return GRPC_ERROR_NONE; } /* fallthrough */ case GRPC_DTS_FH_4: GPR_ASSERT(cur < end); - transport_global->incoming_frame_flags = *cur; + t->incoming_frame_flags = *cur; if (++cur == end) { - transport_global->deframe_state = GRPC_DTS_FH_5; + t->deframe_state = GRPC_DTS_FH_5; return GRPC_ERROR_NONE; } /* fallthrough */ case GRPC_DTS_FH_5: GPR_ASSERT(cur < end); - transport_global->incoming_stream_id = (((uint32_t)*cur) & 0x7f) << 24; + t->incoming_stream_id = (((uint32_t)*cur) & 0x7f) << 24; if (++cur == end) { - transport_global->deframe_state = GRPC_DTS_FH_6; + t->deframe_state = GRPC_DTS_FH_6; return GRPC_ERROR_NONE; } /* fallthrough */ case GRPC_DTS_FH_6: GPR_ASSERT(cur < end); - transport_global->incoming_stream_id |= ((uint32_t)*cur) << 16; + t->incoming_stream_id |= ((uint32_t)*cur) << 16; if (++cur == end) { - transport_global->deframe_state = GRPC_DTS_FH_7; + t->deframe_state = GRPC_DTS_FH_7; return GRPC_ERROR_NONE; } /* fallthrough */ case GRPC_DTS_FH_7: GPR_ASSERT(cur < end); - transport_global->incoming_stream_id |= ((uint32_t)*cur) << 8; + t->incoming_stream_id |= ((uint32_t)*cur) << 8; if (++cur == end) { - transport_global->deframe_state = GRPC_DTS_FH_8; + t->deframe_state = GRPC_DTS_FH_8; return GRPC_ERROR_NONE; } /* fallthrough */ case GRPC_DTS_FH_8: GPR_ASSERT(cur < end); - transport_global->incoming_stream_id |= ((uint32_t)*cur); - transport_global->deframe_state = GRPC_DTS_FRAME; - err = init_frame_parser(exec_ctx, transport_global); + t->incoming_stream_id |= ((uint32_t)*cur); + t->deframe_state = GRPC_DTS_FRAME; + err = init_frame_parser(exec_ctx, t); if (err != GRPC_ERROR_NONE) { return err; } - if (transport_global->incoming_stream_id != 0 && - transport_global->incoming_stream_id > - transport_global->last_incoming_stream_id) { - transport_global->last_incoming_stream_id = - transport_global->incoming_stream_id; + if (t->incoming_stream_id != 0 && + t->incoming_stream_id > t->last_incoming_stream_id) { + t->last_incoming_stream_id = t->incoming_stream_id; } - if (transport_global->incoming_frame_size == 0) { - err = - parse_frame_slice(exec_ctx, transport_global, gpr_empty_slice(), 1); + if (t->incoming_frame_size == 0) { + err = parse_frame_slice(exec_ctx, t, gpr_empty_slice(), 1); if (err != GRPC_ERROR_NONE) { return err; } - transport_global->incoming_stream = NULL; + t->incoming_stream = NULL; if (++cur == end) { - transport_global->deframe_state = GRPC_DTS_FH_0; + t->deframe_state = GRPC_DTS_FH_0; return GRPC_ERROR_NONE; } goto dts_fh_0; /* loop */ - } else if (transport_global->incoming_frame_size > - transport_global - ->settings[GRPC_ACKED_SETTINGS] - [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE]) { + } else if (t->incoming_frame_size > + t->settings[GRPC_ACKED_SETTINGS] + [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE]) { char *msg; - gpr_asprintf( - &msg, "Frame size %d is larger than max frame size %d", - transport_global->incoming_frame_size, - transport_global->settings[GRPC_ACKED_SETTINGS] - [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE]); + gpr_asprintf(&msg, "Frame size %d is larger than max frame size %d", + t->incoming_frame_size, + t->settings[GRPC_ACKED_SETTINGS] + [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE]); err = GRPC_ERROR_CREATE(msg); gpr_free(msg); return err; @@ -240,41 +232,39 @@ grpc_error *grpc_chttp2_perform_read( /* fallthrough */ case GRPC_DTS_FRAME: GPR_ASSERT(cur < end); - if ((uint32_t)(end - cur) == transport_global->incoming_frame_size) { - err = parse_frame_slice(exec_ctx, transport_global, + if ((uint32_t)(end - cur) == t->incoming_frame_size) { + err = parse_frame_slice(exec_ctx, t, gpr_slice_sub_no_ref(slice, (size_t)(cur - beg), (size_t)(end - beg)), 1); if (err != GRPC_ERROR_NONE) { return err; } - transport_global->deframe_state = GRPC_DTS_FH_0; - transport_global->incoming_stream = NULL; + t->deframe_state = GRPC_DTS_FH_0; + t->incoming_stream = NULL; return GRPC_ERROR_NONE; - } else if ((uint32_t)(end - cur) > - transport_global->incoming_frame_size) { + } else if ((uint32_t)(end - cur) > t->incoming_frame_size) { size_t cur_offset = (size_t)(cur - beg); err = parse_frame_slice( - exec_ctx, transport_global, - gpr_slice_sub_no_ref( - slice, cur_offset, - cur_offset + transport_global->incoming_frame_size), + exec_ctx, t, + gpr_slice_sub_no_ref(slice, cur_offset, + cur_offset + t->incoming_frame_size), 1); if (err != GRPC_ERROR_NONE) { return err; } - cur += transport_global->incoming_frame_size; - transport_global->incoming_stream = NULL; + cur += t->incoming_frame_size; + t->incoming_stream = NULL; goto dts_fh_0; /* loop */ } else { - err = parse_frame_slice(exec_ctx, transport_global, + err = parse_frame_slice(exec_ctx, t, gpr_slice_sub_no_ref(slice, (size_t)(cur - beg), (size_t)(end - beg)), 0); if (err != GRPC_ERROR_NONE) { return err; } - transport_global->incoming_frame_size -= (uint32_t)(end - cur); + t->incoming_frame_size -= (uint32_t)(end - cur); return GRPC_ERROR_NONE; } GPR_UNREACHABLE_CODE(return 0); @@ -283,73 +273,68 @@ grpc_error *grpc_chttp2_perform_read( GPR_UNREACHABLE_CODE(return 0); } -static grpc_error *init_frame_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global) { - if (transport_global->is_first_frame && - transport_global->incoming_frame_type != GRPC_CHTTP2_FRAME_SETTINGS) { +static grpc_error *init_frame_parser(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t) { + if (t->is_first_frame && + t->incoming_frame_type != GRPC_CHTTP2_FRAME_SETTINGS) { char *msg; gpr_asprintf( &msg, "Expected SETTINGS frame as the first frame, got frame type %d", - transport_global->incoming_frame_type); + t->incoming_frame_type); grpc_error *err = GRPC_ERROR_CREATE(msg); gpr_free(msg); return err; } - transport_global->is_first_frame = false; - if (transport_global->expect_continuation_stream_id != 0) { - if (transport_global->incoming_frame_type != - GRPC_CHTTP2_FRAME_CONTINUATION) { + t->is_first_frame = false; + if (t->expect_continuation_stream_id != 0) { + if (t->incoming_frame_type != GRPC_CHTTP2_FRAME_CONTINUATION) { char *msg; gpr_asprintf(&msg, "Expected CONTINUATION frame, got frame type %02x", - transport_global->incoming_frame_type); + t->incoming_frame_type); grpc_error *err = GRPC_ERROR_CREATE(msg); gpr_free(msg); return err; } - if (transport_global->expect_continuation_stream_id != - transport_global->incoming_stream_id) { + if (t->expect_continuation_stream_id != t->incoming_stream_id) { char *msg; gpr_asprintf( &msg, "Expected CONTINUATION frame for grpc_chttp2_stream %08x, got " "grpc_chttp2_stream %08x", - transport_global->expect_continuation_stream_id, - transport_global->incoming_stream_id); + t->expect_continuation_stream_id, t->incoming_stream_id); grpc_error *err = GRPC_ERROR_CREATE(msg); gpr_free(msg); return err; } - return init_header_frame_parser(exec_ctx, transport_global, 1); + return init_header_frame_parser(exec_ctx, t, 1); } - switch (transport_global->incoming_frame_type) { + switch (t->incoming_frame_type) { case GRPC_CHTTP2_FRAME_DATA: - return init_data_frame_parser(exec_ctx, transport_global); + return init_data_frame_parser(exec_ctx, t); case GRPC_CHTTP2_FRAME_HEADER: - return init_header_frame_parser(exec_ctx, transport_global, 0); + return init_header_frame_parser(exec_ctx, t, 0); case GRPC_CHTTP2_FRAME_CONTINUATION: return GRPC_ERROR_CREATE("Unexpected CONTINUATION frame"); case GRPC_CHTTP2_FRAME_RST_STREAM: - return init_rst_stream_parser(exec_ctx, transport_global); + return init_rst_stream_parser(exec_ctx, t); case GRPC_CHTTP2_FRAME_SETTINGS: - return init_settings_frame_parser(exec_ctx, transport_global); + return init_settings_frame_parser(exec_ctx, t); case GRPC_CHTTP2_FRAME_WINDOW_UPDATE: - return init_window_update_frame_parser(exec_ctx, transport_global); + return init_window_update_frame_parser(exec_ctx, t); case GRPC_CHTTP2_FRAME_PING: - return init_ping_parser(exec_ctx, transport_global); + return init_ping_parser(exec_ctx, t); case GRPC_CHTTP2_FRAME_GOAWAY: - return init_goaway_parser(exec_ctx, transport_global); + return init_goaway_parser(exec_ctx, t); default: if (grpc_http_trace) { - gpr_log(GPR_ERROR, "Unknown frame type %02x", - transport_global->incoming_frame_type); + gpr_log(GPR_ERROR, "Unknown frame type %02x", t->incoming_frame_type); } - return init_skip_frame_parser(exec_ctx, transport_global, 0); + return init_skip_frame_parser(exec_ctx, t, 0); } } static grpc_error *skip_parser(grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, + grpc_chttp2_transport *t, grpc_chttp2_stream *s, gpr_slice slice, int is_last) { return GRPC_ERROR_NONE; } @@ -358,101 +343,94 @@ static void skip_header(grpc_exec_ctx *exec_ctx, void *tp, grpc_mdelem *md) { GRPC_MDELEM_UNREF(md); } -static grpc_error *init_skip_frame_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - int is_header) { +static grpc_error *init_skip_frame_parser(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + int is_header) { if (is_header) { - uint8_t is_eoh = transport_global->expect_continuation_stream_id != 0; - transport_global->parser = grpc_chttp2_header_parser_parse; - transport_global->parser_data = &transport_global->hpack_parser; - transport_global->hpack_parser.on_header = skip_header; - transport_global->hpack_parser.on_header_user_data = NULL; - transport_global->hpack_parser.is_boundary = is_eoh; - transport_global->hpack_parser.is_eof = - (uint8_t)(is_eoh ? transport_global->header_eof : 0); + uint8_t is_eoh = t->expect_continuation_stream_id != 0; + t->parser = grpc_chttp2_header_parser_parse; + t->parser_data = &t->hpack_parser; + t->hpack_parser.on_header = skip_header; + t->hpack_parser.on_header_user_data = NULL; + t->hpack_parser.is_boundary = is_eoh; + t->hpack_parser.is_eof = (uint8_t)(is_eoh ? t->header_eof : 0); } else { - transport_global->parser = skip_parser; + t->parser = skip_parser; } return GRPC_ERROR_NONE; } -void grpc_chttp2_parsing_become_skip_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global) { - init_skip_frame_parser( - exec_ctx, transport_global, - transport_global->parser == grpc_chttp2_header_parser_parse); +void grpc_chttp2_parsing_become_skip_parser(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t) { + init_skip_frame_parser(exec_ctx, t, + t->parser == grpc_chttp2_header_parser_parse); } -static grpc_error *update_incoming_window( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global) { - uint32_t incoming_frame_size = transport_global->incoming_frame_size; - if (incoming_frame_size > transport_global->incoming_window) { +static grpc_error *update_incoming_window(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s) { + uint32_t incoming_frame_size = t->incoming_frame_size; + if (incoming_frame_size > t->incoming_window) { char *msg; gpr_asprintf(&msg, "frame of size %d overflows incoming window of %" PRId64, - transport_global->incoming_frame_size, - transport_global->incoming_window); + t->incoming_frame_size, t->incoming_window); grpc_error *err = GRPC_ERROR_CREATE(msg); gpr_free(msg); return err; } - if (incoming_frame_size > stream_global->incoming_window) { + if (incoming_frame_size > s->incoming_window) { char *msg; gpr_asprintf(&msg, "frame of size %d overflows incoming window of %" PRId64, - transport_global->incoming_frame_size, - stream_global->incoming_window); + t->incoming_frame_size, s->incoming_window); grpc_error *err = GRPC_ERROR_CREATE(msg); gpr_free(msg); return err; } - GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("parse", transport_global, incoming_window, + GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("parse", t, incoming_window, incoming_frame_size); - GRPC_CHTTP2_FLOW_DEBIT_STREAM("parse", transport_global, stream_global, - incoming_window, incoming_frame_size); - stream_global->received_bytes += incoming_frame_size; - stream_global->max_recv_bytes -= - (uint32_t)GPR_MIN(stream_global->max_recv_bytes, incoming_frame_size); + GRPC_CHTTP2_FLOW_DEBIT_STREAM("parse", t, s, incoming_window, + incoming_frame_size); + s->received_bytes += incoming_frame_size; + s->max_recv_bytes -= + (uint32_t)GPR_MIN(s->max_recv_bytes, incoming_frame_size); return GRPC_ERROR_NONE; } -static grpc_error *init_data_frame_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global) { - grpc_chttp2_stream_global *stream_global = grpc_chttp2_parsing_lookup_stream( - transport_global, transport_global->incoming_stream_id); +static grpc_error *init_data_frame_parser(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t) { + grpc_chttp2_stream *s = + grpc_chttp2_parsing_lookup_stream(t, t->incoming_stream_id); grpc_error *err = GRPC_ERROR_NONE; - if (stream_global == NULL) { - return init_skip_frame_parser(exec_ctx, transport_global, 0); + if (s == NULL) { + return init_skip_frame_parser(exec_ctx, t, 0); } - stream_global->stats.incoming.framing_bytes += 9; - if (stream_global->read_closed) { - return init_skip_frame_parser(exec_ctx, transport_global, 0); + s->stats.incoming.framing_bytes += 9; + if (s->read_closed) { + return init_skip_frame_parser(exec_ctx, t, 0); } if (err == GRPC_ERROR_NONE) { - err = update_incoming_window(exec_ctx, transport_global, stream_global); + err = update_incoming_window(exec_ctx, t, s); } if (err == GRPC_ERROR_NONE) { - err = grpc_chttp2_data_parser_begin_frame( - &stream_global->data_parser, transport_global->incoming_frame_flags, - stream_global->id); + err = grpc_chttp2_data_parser_begin_frame(&s->data_parser, + t->incoming_frame_flags, s->id); } if (err == GRPC_ERROR_NONE) { - transport_global->incoming_stream = stream_global; - transport_global->parser = grpc_chttp2_data_parser_parse; - transport_global->parser_data = &stream_global->data_parser; + t->incoming_stream = s; + t->parser = grpc_chttp2_data_parser_parse; + t->parser_data = &s->data_parser; return GRPC_ERROR_NONE; } else if (grpc_error_get_int(err, GRPC_ERROR_INT_STREAM_ID, NULL)) { /* handle stream errors by closing the stream */ - grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global, - true, false, err); + grpc_chttp2_mark_stream_closed(exec_ctx, t, s, true, false, err); gpr_slice_buffer_add( - &transport_global->qbuf, - grpc_chttp2_rst_stream_create(transport_global->incoming_stream_id, - GRPC_CHTTP2_PROTOCOL_ERROR, - &stream_global->stats.outgoing)); - return init_skip_frame_parser(exec_ctx, transport_global, 0); + &t->qbuf, grpc_chttp2_rst_stream_create(t->incoming_stream_id, + GRPC_CHTTP2_PROTOCOL_ERROR, + &s->stats.outgoing)); + return init_skip_frame_parser(exec_ctx, t, 0); } else { return err; } @@ -462,21 +440,20 @@ static void free_timeout(void *p) { gpr_free(p); } static void on_initial_header(grpc_exec_ctx *exec_ctx, void *tp, grpc_mdelem *md) { - grpc_chttp2_transport_global *transport_global = tp; - grpc_chttp2_stream_global *stream_global = transport_global->incoming_stream; + grpc_chttp2_transport *t = tp; + grpc_chttp2_stream *s = t->incoming_stream; GPR_TIMER_BEGIN("on_initial_header", 0); - GPR_ASSERT(stream_global); + GPR_ASSERT(s != NULL); GRPC_CHTTP2_IF_TRACING(gpr_log( - GPR_INFO, "HTTP:%d:HDR:%s: %s: %s", stream_global->id, - transport_global->is_client ? "CLI" : "SVR", + GPR_INFO, "HTTP:%d:HDR:%s: %s: %s", s->id, t->is_client ? "CLI" : "SVR", grpc_mdstr_as_c_string(md->key), grpc_mdstr_as_c_string(md->value))); if (md->key == GRPC_MDSTR_GRPC_STATUS && md != GRPC_MDELEM_GRPC_STATUS_0) { /* TODO(ctiller): check for a status like " 0" */ - stream_global->seen_error = true; + s->seen_error = true; } if (md->key == GRPC_MDSTR_GRPC_TIMEOUT) { @@ -493,31 +470,29 @@ static void on_initial_header(grpc_exec_ctx *exec_ctx, void *tp, grpc_mdelem_set_user_data(md, free_timeout, cached_timeout); } grpc_chttp2_incoming_metadata_buffer_set_deadline( - &stream_global->metadata_buffer[0], + &s->metadata_buffer[0], gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), *cached_timeout)); GRPC_MDELEM_UNREF(md); } else { - const size_t new_size = - stream_global->metadata_buffer[0].size + GRPC_MDELEM_LENGTH(md); + const size_t new_size = s->metadata_buffer[0].size + GRPC_MDELEM_LENGTH(md); const size_t metadata_size_limit = - transport_global->settings[GRPC_ACKED_SETTINGS] - [GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE]; + t->settings[GRPC_ACKED_SETTINGS] + [GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE]; if (new_size > metadata_size_limit) { gpr_log(GPR_DEBUG, "received initial metadata size exceeds limit (%" PRIuPTR " vs. %" PRIuPTR ")", new_size, metadata_size_limit); grpc_chttp2_cancel_stream( - exec_ctx, transport_global, stream_global, + exec_ctx, t, s, grpc_error_set_int( GRPC_ERROR_CREATE("received initial metadata size exceeds limit"), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED)); - grpc_chttp2_parsing_become_skip_parser(exec_ctx, transport_global); - stream_global->seen_error = true; + grpc_chttp2_parsing_become_skip_parser(exec_ctx, t); + s->seen_error = true; GRPC_MDELEM_UNREF(md); } else { - grpc_chttp2_incoming_metadata_buffer_add( - &stream_global->metadata_buffer[0], md); + grpc_chttp2_incoming_metadata_buffer_add(&s->metadata_buffer[0], md); } } @@ -526,234 +501,213 @@ static void on_initial_header(grpc_exec_ctx *exec_ctx, void *tp, static void on_trailing_header(grpc_exec_ctx *exec_ctx, void *tp, grpc_mdelem *md) { - grpc_chttp2_transport_global *transport_global = tp; - grpc_chttp2_stream_global *stream_global = transport_global->incoming_stream; + grpc_chttp2_transport *t = tp; + grpc_chttp2_stream *s = t->incoming_stream; GPR_TIMER_BEGIN("on_trailing_header", 0); - GPR_ASSERT(stream_global); + GPR_ASSERT(s != NULL); GRPC_CHTTP2_IF_TRACING(gpr_log( - GPR_INFO, "HTTP:%d:TRL:%s: %s: %s", stream_global->id, - transport_global->is_client ? "CLI" : "SVR", + GPR_INFO, "HTTP:%d:TRL:%s: %s: %s", s->id, t->is_client ? "CLI" : "SVR", grpc_mdstr_as_c_string(md->key), grpc_mdstr_as_c_string(md->value))); if (md->key == GRPC_MDSTR_GRPC_STATUS && md != GRPC_MDELEM_GRPC_STATUS_0) { /* TODO(ctiller): check for a status like " 0" */ - stream_global->seen_error = true; + s->seen_error = true; } - const size_t new_size = - stream_global->metadata_buffer[1].size + GRPC_MDELEM_LENGTH(md); + const size_t new_size = s->metadata_buffer[1].size + GRPC_MDELEM_LENGTH(md); const size_t metadata_size_limit = - transport_global->settings[GRPC_ACKED_SETTINGS] - [GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE]; + t->settings[GRPC_ACKED_SETTINGS] + [GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE]; if (new_size > metadata_size_limit) { gpr_log(GPR_DEBUG, "received trailing metadata size exceeds limit (%" PRIuPTR " vs. %" PRIuPTR ")", new_size, metadata_size_limit); grpc_chttp2_cancel_stream( - exec_ctx, transport_global, stream_global, + exec_ctx, t, s, grpc_error_set_int( GRPC_ERROR_CREATE("received trailing metadata size exceeds limit"), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED)); - grpc_chttp2_parsing_become_skip_parser(exec_ctx, transport_global); - stream_global->seen_error = true; + grpc_chttp2_parsing_become_skip_parser(exec_ctx, t); + s->seen_error = true; GRPC_MDELEM_UNREF(md); } else { - grpc_chttp2_incoming_metadata_buffer_add(&stream_global->metadata_buffer[1], - md); + grpc_chttp2_incoming_metadata_buffer_add(&s->metadata_buffer[1], md); } GPR_TIMER_END("on_trailing_header", 0); } -static grpc_error *init_header_frame_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - int is_continuation) { - uint8_t is_eoh = (transport_global->incoming_frame_flags & - GRPC_CHTTP2_DATA_FLAG_END_HEADERS) != 0; - int via_accept = 0; - grpc_chttp2_stream_global *stream_global; +static grpc_error *init_header_frame_parser(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + int is_continuation) { + uint8_t is_eoh = + (t->incoming_frame_flags & GRPC_CHTTP2_DATA_FLAG_END_HEADERS) != 0; + grpc_chttp2_stream *s; /* TODO(ctiller): when to increment header_frames_received? */ if (is_eoh) { - transport_global->expect_continuation_stream_id = 0; + t->expect_continuation_stream_id = 0; } else { - transport_global->expect_continuation_stream_id = - transport_global->incoming_stream_id; + t->expect_continuation_stream_id = t->incoming_stream_id; } if (!is_continuation) { - transport_global->header_eof = (transport_global->incoming_frame_flags & - GRPC_CHTTP2_DATA_FLAG_END_STREAM) != 0; + t->header_eof = + (t->incoming_frame_flags & GRPC_CHTTP2_DATA_FLAG_END_STREAM) != 0; } /* could be a new grpc_chttp2_stream or an existing grpc_chttp2_stream */ - stream_global = grpc_chttp2_parsing_lookup_stream( - transport_global, transport_global->incoming_stream_id); - if (stream_global == NULL) { + s = grpc_chttp2_parsing_lookup_stream(t, t->incoming_stream_id); + if (s == NULL) { if (is_continuation) { gpr_log(GPR_ERROR, "grpc_chttp2_stream disbanded before CONTINUATION received"); - return init_skip_frame_parser(exec_ctx, transport_global, 1); + return init_skip_frame_parser(exec_ctx, t, 1); } - if (transport_global->is_client) { - if ((transport_global->incoming_stream_id & 1) && - transport_global->incoming_stream_id < - transport_global->next_stream_id) { + if (t->is_client) { + if ((t->incoming_stream_id & 1) && + t->incoming_stream_id < t->next_stream_id) { /* this is an old (probably cancelled) grpc_chttp2_stream */ } else { gpr_log(GPR_ERROR, "ignoring new grpc_chttp2_stream creation on client"); } - return init_skip_frame_parser(exec_ctx, transport_global, 1); - } else if (transport_global->last_incoming_stream_id > - transport_global->incoming_stream_id) { + return init_skip_frame_parser(exec_ctx, t, 1); + } else if (t->last_incoming_stream_id > t->incoming_stream_id) { gpr_log(GPR_ERROR, "ignoring out of order new grpc_chttp2_stream request on server; " "last grpc_chttp2_stream " "id=%d, new grpc_chttp2_stream id=%d", - transport_global->last_incoming_stream_id, - transport_global->incoming_stream_id); - return init_skip_frame_parser(exec_ctx, transport_global, 1); - } else if ((transport_global->incoming_stream_id & 1) == 0) { + t->last_incoming_stream_id, t->incoming_stream_id); + return init_skip_frame_parser(exec_ctx, t, 1); + } else if ((t->incoming_stream_id & 1) == 0) { gpr_log(GPR_ERROR, "ignoring grpc_chttp2_stream with non-client generated index %d", - transport_global->incoming_stream_id); - return init_skip_frame_parser(exec_ctx, transport_global, 1); + t->incoming_stream_id); + return init_skip_frame_parser(exec_ctx, t, 1); } - stream_global = transport_global->incoming_stream = - grpc_chttp2_parsing_accept_stream(exec_ctx, transport_global, - transport_global->incoming_stream_id); - if (stream_global == NULL) { + s = t->incoming_stream = + grpc_chttp2_parsing_accept_stream(exec_ctx, t, t->incoming_stream_id); + if (s == NULL) { gpr_log(GPR_ERROR, "grpc_chttp2_stream not accepted"); - return init_skip_frame_parser(exec_ctx, transport_global, 1); + return init_skip_frame_parser(exec_ctx, t, 1); } - via_accept = 1; } else { - transport_global->incoming_stream = stream_global; + t->incoming_stream = s; } - GPR_ASSERT(stream_global != NULL && (via_accept == 0 || via_accept == 1)); - stream_global->stats.incoming.framing_bytes += 9; - if (stream_global->read_closed) { + GPR_ASSERT(s != NULL); + s->stats.incoming.framing_bytes += 9; + if (s->read_closed) { gpr_log(GPR_ERROR, "skipping already closed grpc_chttp2_stream header"); - transport_global->incoming_stream = NULL; - return init_skip_frame_parser(exec_ctx, transport_global, 1); + t->incoming_stream = NULL; + return init_skip_frame_parser(exec_ctx, t, 1); } - transport_global->parser = grpc_chttp2_header_parser_parse; - transport_global->parser_data = &transport_global->hpack_parser; - switch (stream_global->header_frames_received) { + t->parser = grpc_chttp2_header_parser_parse; + t->parser_data = &t->hpack_parser; + switch (s->header_frames_received) { case 0: - transport_global->hpack_parser.on_header = on_initial_header; + t->hpack_parser.on_header = on_initial_header; break; case 1: - transport_global->hpack_parser.on_header = on_trailing_header; + t->hpack_parser.on_header = on_trailing_header; break; case 2: gpr_log(GPR_ERROR, "too many header frames received"); - return init_skip_frame_parser(exec_ctx, transport_global, 1); + return init_skip_frame_parser(exec_ctx, t, 1); } - transport_global->hpack_parser.on_header_user_data = transport_global; - transport_global->hpack_parser.is_boundary = is_eoh; - transport_global->hpack_parser.is_eof = - (uint8_t)(is_eoh ? transport_global->header_eof : 0); - if (!is_continuation && (transport_global->incoming_frame_flags & - GRPC_CHTTP2_FLAG_HAS_PRIORITY)) { - grpc_chttp2_hpack_parser_set_has_priority(&transport_global->hpack_parser); + t->hpack_parser.on_header_user_data = t; + t->hpack_parser.is_boundary = is_eoh; + t->hpack_parser.is_eof = (uint8_t)(is_eoh ? t->header_eof : 0); + if (!is_continuation && + (t->incoming_frame_flags & GRPC_CHTTP2_FLAG_HAS_PRIORITY)) { + grpc_chttp2_hpack_parser_set_has_priority(&t->hpack_parser); } return GRPC_ERROR_NONE; } -static grpc_error *init_window_update_frame_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global) { +static grpc_error *init_window_update_frame_parser(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t) { grpc_error *err = grpc_chttp2_window_update_parser_begin_frame( - &transport_global->simple.window_update, - transport_global->incoming_frame_size, - transport_global->incoming_frame_flags); + &t->simple.window_update, t->incoming_frame_size, + t->incoming_frame_flags); if (err != GRPC_ERROR_NONE) return err; - if (transport_global->incoming_stream_id != 0) { - grpc_chttp2_stream_global *stream_global = - transport_global->incoming_stream = grpc_chttp2_parsing_lookup_stream( - transport_global, transport_global->incoming_stream_id); - if (stream_global == NULL) { - return init_skip_frame_parser(exec_ctx, transport_global, 0); + if (t->incoming_stream_id != 0) { + grpc_chttp2_stream *s = t->incoming_stream = + grpc_chttp2_parsing_lookup_stream(t, t->incoming_stream_id); + if (s == NULL) { + return init_skip_frame_parser(exec_ctx, t, 0); } - stream_global->stats.incoming.framing_bytes += 9; + s->stats.incoming.framing_bytes += 9; } - transport_global->parser = grpc_chttp2_window_update_parser_parse; - transport_global->parser_data = &transport_global->simple.window_update; + t->parser = grpc_chttp2_window_update_parser_parse; + t->parser_data = &t->simple.window_update; return GRPC_ERROR_NONE; } -static grpc_error *init_ping_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global) { +static grpc_error *init_ping_parser(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t) { grpc_error *err = grpc_chttp2_ping_parser_begin_frame( - &transport_global->simple.ping, transport_global->incoming_frame_size, - transport_global->incoming_frame_flags); + &t->simple.ping, t->incoming_frame_size, t->incoming_frame_flags); if (err != GRPC_ERROR_NONE) return err; - transport_global->parser = grpc_chttp2_ping_parser_parse; - transport_global->parser_data = &transport_global->simple.ping; + t->parser = grpc_chttp2_ping_parser_parse; + t->parser_data = &t->simple.ping; return GRPC_ERROR_NONE; } -static grpc_error *init_rst_stream_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global) { +static grpc_error *init_rst_stream_parser(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t) { grpc_error *err = grpc_chttp2_rst_stream_parser_begin_frame( - &transport_global->simple.rst_stream, - transport_global->incoming_frame_size, - transport_global->incoming_frame_flags); + &t->simple.rst_stream, t->incoming_frame_size, t->incoming_frame_flags); if (err != GRPC_ERROR_NONE) return err; - grpc_chttp2_stream_global *stream_global = transport_global->incoming_stream = - grpc_chttp2_parsing_lookup_stream(transport_global, - transport_global->incoming_stream_id); - if (!transport_global->incoming_stream) { - return init_skip_frame_parser(exec_ctx, transport_global, 0); + grpc_chttp2_stream *s = t->incoming_stream = + grpc_chttp2_parsing_lookup_stream(t, t->incoming_stream_id); + if (!t->incoming_stream) { + return init_skip_frame_parser(exec_ctx, t, 0); } - stream_global->stats.incoming.framing_bytes += 9; - transport_global->parser = grpc_chttp2_rst_stream_parser_parse; - transport_global->parser_data = &transport_global->simple.rst_stream; + s->stats.incoming.framing_bytes += 9; + t->parser = grpc_chttp2_rst_stream_parser_parse; + t->parser_data = &t->simple.rst_stream; return GRPC_ERROR_NONE; } -static grpc_error *init_goaway_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global) { +static grpc_error *init_goaway_parser(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t) { grpc_error *err = grpc_chttp2_goaway_parser_begin_frame( - &transport_global->goaway_parser, transport_global->incoming_frame_size, - transport_global->incoming_frame_flags); + &t->goaway_parser, t->incoming_frame_size, t->incoming_frame_flags); if (err != GRPC_ERROR_NONE) return err; - transport_global->parser = grpc_chttp2_goaway_parser_parse; - transport_global->parser_data = &transport_global->goaway_parser; + t->parser = grpc_chttp2_goaway_parser_parse; + t->parser_data = &t->goaway_parser; return GRPC_ERROR_NONE; } -static grpc_error *init_settings_frame_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global) { - if (transport_global->incoming_stream_id != 0) { +static grpc_error *init_settings_frame_parser(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t) { + if (t->incoming_stream_id != 0) { return GRPC_ERROR_CREATE("Settings frame received for grpc_chttp2_stream"); } grpc_error *err = grpc_chttp2_settings_parser_begin_frame( - &transport_global->simple.settings, transport_global->incoming_frame_size, - transport_global->incoming_frame_flags, - transport_global->settings[GRPC_PEER_SETTINGS]); + &t->simple.settings, t->incoming_frame_size, t->incoming_frame_flags, + t->settings[GRPC_PEER_SETTINGS]); if (err != GRPC_ERROR_NONE) { return err; } - if (transport_global->incoming_frame_flags & GRPC_CHTTP2_FLAG_ACK) { - memcpy(transport_global->settings[GRPC_ACKED_SETTINGS], - transport_global->settings[GRPC_SENT_SETTINGS], + if (t->incoming_frame_flags & GRPC_CHTTP2_FLAG_ACK) { + memcpy(t->settings[GRPC_ACKED_SETTINGS], t->settings[GRPC_SENT_SETTINGS], GRPC_CHTTP2_NUM_SETTINGS * sizeof(uint32_t)); grpc_chttp2_hptbl_set_max_bytes( - &transport_global->hpack_parser.table, - transport_global->settings[GRPC_ACKED_SETTINGS] - [GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE]); - transport_global->sent_local_settings = 0; + &t->hpack_parser.table, + t->settings[GRPC_ACKED_SETTINGS] + [GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE]); + t->sent_local_settings = 0; } - transport_global->parser = grpc_chttp2_settings_parser_parse; - transport_global->parser_data = &transport_global->simple.settings; + t->parser = grpc_chttp2_settings_parser_parse; + t->parser_data = &t->simple.settings; return GRPC_ERROR_NONE; } @@ -763,17 +717,14 @@ static int is_window_update_legal(int64_t window_update, int64_t window) { } */ -static grpc_error *parse_frame_slice( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - gpr_slice slice, int is_last) { - grpc_chttp2_stream_global *stream_global = transport_global->incoming_stream; - grpc_error *err = - transport_global->parser(exec_ctx, transport_global->parser_data, - transport_global, stream_global, slice, is_last); +static grpc_error *parse_frame_slice(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, gpr_slice slice, + int is_last) { + grpc_chttp2_stream *s = t->incoming_stream; + grpc_error *err = t->parser(exec_ctx, t->parser_data, t, s, slice, is_last); if (err == GRPC_ERROR_NONE) { - if (stream_global != NULL) { - grpc_chttp2_list_add_check_read_ops(exec_ctx, transport_global, - stream_global); + if (s != NULL) { + grpc_chttp2_list_add_check_read_ops(exec_ctx, t, s); } return err; } else if (grpc_error_get_int(err, GRPC_ERROR_INT_STREAM_ID, NULL)) { @@ -782,14 +733,13 @@ static grpc_error *parse_frame_slice( gpr_log(GPR_ERROR, "%s", msg); grpc_error_free_string(msg); } - grpc_chttp2_parsing_become_skip_parser(exec_ctx, transport_global); - if (stream_global) { - stream_global->forced_close_error = err; + grpc_chttp2_parsing_become_skip_parser(exec_ctx, t); + if (s) { + s->forced_close_error = err; gpr_slice_buffer_add( - &transport_global->qbuf, - grpc_chttp2_rst_stream_create(transport_global->incoming_stream_id, - GRPC_CHTTP2_PROTOCOL_ERROR, - &stream_global->stats.outgoing)); + &t->qbuf, grpc_chttp2_rst_stream_create(t->incoming_stream_id, + GRPC_CHTTP2_PROTOCOL_ERROR, + &s->stats.outgoing)); } else { GRPC_ERROR_UNREF(err); } diff --git a/src/core/ext/transport/chttp2/transport/stream_lists.c b/src/core/ext/transport/chttp2/transport/stream_lists.c index 6d4863c4aa..2d1b242612 100644 --- a/src/core/ext/transport/chttp2/transport/stream_lists.c +++ b/src/core/ext/transport/chttp2/transport/stream_lists.c @@ -35,27 +35,6 @@ #include -#define TRANSPORT_FROM_GLOBAL(tg) \ - ((grpc_chttp2_transport *)((char *)(tg)-offsetof(grpc_chttp2_transport, \ - global))) - -#define STREAM_FROM_GLOBAL(sg) \ - ((grpc_chttp2_stream *)((char *)(sg)-offsetof(grpc_chttp2_stream, global))) - -#define TRANSPORT_FROM_WRITING(tw) \ - ((grpc_chttp2_transport *)((char *)(tw)-offsetof(grpc_chttp2_transport, \ - writing))) - -#define STREAM_FROM_WRITING(sw) \ - ((grpc_chttp2_stream *)((char *)(sw)-offsetof(grpc_chttp2_stream, writing))) - -#define TRANSPORT_FROM_PARSING(tp) \ - ((grpc_chttp2_transport *)((char *)(tp)-offsetof(grpc_chttp2_transport, \ - parsing))) - -#define STREAM_FROM_PARSING(sp) \ - ((grpc_chttp2_stream *)((char *)(sp)-offsetof(grpc_chttp2_stream, parsing))) - /* core list management */ static int stream_list_empty(grpc_chttp2_transport *t, @@ -139,219 +118,114 @@ static bool stream_list_add(grpc_chttp2_transport *t, grpc_chttp2_stream *s, /* wrappers for specializations */ -bool grpc_chttp2_list_add_writable_stream( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global) { - GPR_ASSERT(stream_global->id != 0); - return stream_list_add(TRANSPORT_FROM_GLOBAL(transport_global), - STREAM_FROM_GLOBAL(stream_global), - GRPC_CHTTP2_LIST_WRITABLE); +bool grpc_chttp2_list_add_writable_stream(grpc_chttp2_transport *t, + grpc_chttp2_stream *s) { + GPR_ASSERT(s->id != 0); + return stream_list_add(t, s, GRPC_CHTTP2_LIST_WRITABLE); } -int grpc_chttp2_list_pop_writable_stream( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_transport_writing *transport_writing, - grpc_chttp2_stream_global **stream_global, - grpc_chttp2_stream_writing **stream_writing) { - grpc_chttp2_stream *stream; - int r = stream_list_pop(TRANSPORT_FROM_GLOBAL(transport_global), &stream, - GRPC_CHTTP2_LIST_WRITABLE); - if (r != 0) { - *stream_global = &stream->global; - *stream_writing = &stream->writing; - } - return r; +int grpc_chttp2_list_pop_writable_stream(grpc_chttp2_transport *t, + grpc_chttp2_stream **s) { + return stream_list_pop(t, s, GRPC_CHTTP2_LIST_WRITABLE); } -bool grpc_chttp2_list_remove_writable_stream( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global) { - return stream_list_maybe_remove(TRANSPORT_FROM_GLOBAL(transport_global), - STREAM_FROM_GLOBAL(stream_global), - GRPC_CHTTP2_LIST_WRITABLE); +bool grpc_chttp2_list_remove_writable_stream(grpc_chttp2_transport *t, + grpc_chttp2_stream *s) { + return stream_list_maybe_remove(t, s, GRPC_CHTTP2_LIST_WRITABLE); } -void grpc_chttp2_list_add_writing_stream( - grpc_chttp2_transport_writing *transport_writing, - grpc_chttp2_stream_writing *stream_writing) { - GPR_ASSERT(stream_list_add(TRANSPORT_FROM_WRITING(transport_writing), - STREAM_FROM_WRITING(stream_writing), - GRPC_CHTTP2_LIST_WRITING)); +void grpc_chttp2_list_add_writing_stream(grpc_chttp2_transport *t, + grpc_chttp2_stream *s) { + GPR_ASSERT(stream_list_add(t, s, GRPC_CHTTP2_LIST_WRITING)); } -int grpc_chttp2_list_have_writing_streams( - grpc_chttp2_transport_writing *transport_writing) { - return !stream_list_empty(TRANSPORT_FROM_WRITING(transport_writing), - GRPC_CHTTP2_LIST_WRITING); +int grpc_chttp2_list_have_writing_streams(grpc_chttp2_transport *t) { + return !stream_list_empty(t, GRPC_CHTTP2_LIST_WRITING); } -int grpc_chttp2_list_pop_writing_stream( - grpc_chttp2_transport_writing *transport_writing, - grpc_chttp2_stream_writing **stream_writing) { - grpc_chttp2_stream *stream; - int r = stream_list_pop(TRANSPORT_FROM_WRITING(transport_writing), &stream, - GRPC_CHTTP2_LIST_WRITING); - if (r != 0) { - *stream_writing = &stream->writing; - } - return r; +int grpc_chttp2_list_pop_writing_stream(grpc_chttp2_transport *t, + grpc_chttp2_stream **s) { + return stream_list_pop(t, s, GRPC_CHTTP2_LIST_WRITING); } -void grpc_chttp2_list_add_written_stream( - grpc_chttp2_transport_writing *transport_writing, - grpc_chttp2_stream_writing *stream_writing) { - stream_list_add(TRANSPORT_FROM_WRITING(transport_writing), - STREAM_FROM_WRITING(stream_writing), - GRPC_CHTTP2_LIST_WRITTEN); +void grpc_chttp2_list_add_written_stream(grpc_chttp2_transport *t, + grpc_chttp2_stream *s) { + stream_list_add(t, s, GRPC_CHTTP2_LIST_WRITTEN); } -int grpc_chttp2_list_pop_written_stream( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_transport_writing *transport_writing, - grpc_chttp2_stream_global **stream_global, - grpc_chttp2_stream_writing **stream_writing) { - grpc_chttp2_stream *stream; - int r = stream_list_pop(TRANSPORT_FROM_WRITING(transport_writing), &stream, - GRPC_CHTTP2_LIST_WRITTEN); - if (r != 0) { - *stream_global = &stream->global; - *stream_writing = &stream->writing; - } - return r; +int grpc_chttp2_list_pop_written_stream(grpc_chttp2_transport *t, + grpc_chttp2_stream **s) { + return stream_list_pop(t, s, GRPC_CHTTP2_LIST_WRITTEN); } -void grpc_chttp2_list_add_waiting_for_concurrency( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global) { - stream_list_add(TRANSPORT_FROM_GLOBAL(transport_global), - STREAM_FROM_GLOBAL(stream_global), - GRPC_CHTTP2_LIST_WAITING_FOR_CONCURRENCY); +void grpc_chttp2_list_add_waiting_for_concurrency(grpc_chttp2_transport *t, + grpc_chttp2_stream *s) { + stream_list_add(t, s, GRPC_CHTTP2_LIST_WAITING_FOR_CONCURRENCY); } -int grpc_chttp2_list_pop_waiting_for_concurrency( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global **stream_global) { - grpc_chttp2_stream *stream; - int r = stream_list_pop(TRANSPORT_FROM_GLOBAL(transport_global), &stream, - GRPC_CHTTP2_LIST_WAITING_FOR_CONCURRENCY); - if (r != 0) { - *stream_global = &stream->global; - } - return r; +int grpc_chttp2_list_pop_waiting_for_concurrency(grpc_chttp2_transport *t, + grpc_chttp2_stream **s) { + return stream_list_pop(t, s, GRPC_CHTTP2_LIST_WAITING_FOR_CONCURRENCY); } -void grpc_chttp2_list_add_check_read_ops( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global) { - grpc_chttp2_transport *t = TRANSPORT_FROM_GLOBAL(transport_global); - if (!t->executor.check_read_ops_scheduled) { - GRPC_CHTTP2_REF_TRANSPORT(TRANSPORT_FROM_GLOBAL(transport_global), - "initiate_read_flush_locked"); - grpc_combiner_execute_finally(exec_ctx, t->executor.combiner, - &t->initiate_read_flush_locked, - GRPC_ERROR_NONE, false); - t->executor.check_read_ops_scheduled = true; +void grpc_chttp2_list_add_check_read_ops(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s) { + if (!t->check_read_ops_scheduled) { + GRPC_CHTTP2_REF_TRANSPORT(t, "initiate_read_flush_locked"); + grpc_combiner_execute_finally(exec_ctx, t->combiner, + &t->read_action_flush_locked, GRPC_ERROR_NONE, + false); + t->check_read_ops_scheduled = true; } - stream_list_add(TRANSPORT_FROM_GLOBAL(transport_global), - STREAM_FROM_GLOBAL(stream_global), - GRPC_CHTTP2_LIST_CHECK_READ_OPS); + stream_list_add(t, s, GRPC_CHTTP2_LIST_CHECK_READ_OPS); } -bool grpc_chttp2_list_remove_check_read_ops( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global) { - return stream_list_maybe_remove(TRANSPORT_FROM_GLOBAL(transport_global), - STREAM_FROM_GLOBAL(stream_global), - GRPC_CHTTP2_LIST_CHECK_READ_OPS); +bool grpc_chttp2_list_remove_check_read_ops(grpc_chttp2_transport *t, + grpc_chttp2_stream *s) { + return stream_list_maybe_remove(t, s, GRPC_CHTTP2_LIST_CHECK_READ_OPS); } -int grpc_chttp2_list_pop_check_read_ops( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global **stream_global) { - grpc_chttp2_stream *stream; - int r = stream_list_pop(TRANSPORT_FROM_GLOBAL(transport_global), &stream, - GRPC_CHTTP2_LIST_CHECK_READ_OPS); - if (r != 0) { - *stream_global = &stream->global; - } - return r; +int grpc_chttp2_list_pop_check_read_ops(grpc_chttp2_transport *t, + grpc_chttp2_stream **s) { + return stream_list_pop(t, s, GRPC_CHTTP2_LIST_CHECK_READ_OPS); } -void grpc_chttp2_list_add_writing_stalled_by_transport( - grpc_chttp2_transport_writing *transport_writing, - grpc_chttp2_stream_writing *stream_writing) { - grpc_chttp2_stream *stream = STREAM_FROM_WRITING(stream_writing); - gpr_log(GPR_DEBUG, "writing stalled %d", stream->global.id); +void grpc_chttp2_list_add_writing_stalled_by_transport(grpc_chttp2_transport *t, + grpc_chttp2_stream *s) { + grpc_chttp2_stream *stream = s; + gpr_log(GPR_DEBUG, "writing stalled %d", s->id); if (!stream->included[GRPC_CHTTP2_LIST_WRITING_STALLED_BY_TRANSPORT]) { - GRPC_CHTTP2_STREAM_REF(&stream->global, "chttp2_writing_stalled"); + GRPC_CHTTP2_STREAM_REF(s, "chttp2_writing_stalled"); } - stream_list_add(TRANSPORT_FROM_WRITING(transport_writing), stream, - GRPC_CHTTP2_LIST_WRITING_STALLED_BY_TRANSPORT); + stream_list_add(t, stream, GRPC_CHTTP2_LIST_WRITING_STALLED_BY_TRANSPORT); } bool grpc_chttp2_list_flush_writing_stalled_by_transport( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_writing *transport_writing) { - grpc_chttp2_stream *stream; + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t) { + grpc_chttp2_stream *s; bool out = false; - grpc_chttp2_transport *transport = TRANSPORT_FROM_WRITING(transport_writing); - while (stream_list_pop(transport, &stream, - GRPC_CHTTP2_LIST_WRITING_STALLED_BY_TRANSPORT)) { - gpr_log(GPR_DEBUG, "move %d from writing stalled to just stalled", - stream->global.id); - grpc_chttp2_list_add_stalled_by_transport(transport_writing, - &stream->writing); - GRPC_CHTTP2_STREAM_UNREF(exec_ctx, &stream->global, - "chttp2_writing_stalled"); + while ( + stream_list_pop(t, &s, GRPC_CHTTP2_LIST_WRITING_STALLED_BY_TRANSPORT)) { + gpr_log(GPR_DEBUG, "move %d from writing stalled to just stalled", s->id); + grpc_chttp2_list_add_stalled_by_transport(t, s); + GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing_stalled"); out = true; } return out; } -void grpc_chttp2_list_add_stalled_by_transport( - grpc_chttp2_transport_writing *transport_writing, - grpc_chttp2_stream_writing *stream_writing) { - gpr_log(GPR_DEBUG, "stalled %d", stream_writing->id); - stream_list_add(TRANSPORT_FROM_WRITING(transport_writing), - STREAM_FROM_WRITING(stream_writing), - GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT); -} - -int grpc_chttp2_list_pop_stalled_by_transport( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global **stream_global) { - grpc_chttp2_stream *stream; - int r = stream_list_pop(TRANSPORT_FROM_GLOBAL(transport_global), &stream, - GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT); - if (r != 0) { - *stream_global = &stream->global; - } - return r; -} - -void grpc_chttp2_list_remove_stalled_by_transport( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global) { - stream_list_maybe_remove(TRANSPORT_FROM_GLOBAL(transport_global), - STREAM_FROM_GLOBAL(stream_global), - GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT); +void grpc_chttp2_list_add_stalled_by_transport(grpc_chttp2_transport *t, + grpc_chttp2_stream *s) { + stream_list_add(t, s, GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT); } -void grpc_chttp2_list_add_closed_waiting_for_writing( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global) { - stream_list_add(TRANSPORT_FROM_GLOBAL(transport_global), - STREAM_FROM_GLOBAL(stream_global), - GRPC_CHTTP2_LIST_CLOSED_WAITING_FOR_WRITING); +int grpc_chttp2_list_pop_stalled_by_transport(grpc_chttp2_transport *t, + grpc_chttp2_stream **s) { + return stream_list_pop(t, s, GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT); } -int grpc_chttp2_list_pop_closed_waiting_for_writing( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global **stream_global) { - grpc_chttp2_stream *stream; - int r = stream_list_pop(TRANSPORT_FROM_GLOBAL(transport_global), &stream, - GRPC_CHTTP2_LIST_CLOSED_WAITING_FOR_WRITING); - if (r != 0) { - *stream_global = &stream->global; - } - return r; +void grpc_chttp2_list_remove_stalled_by_transport(grpc_chttp2_transport *t, + grpc_chttp2_stream *s) { + stream_list_maybe_remove(t, s, GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT); } diff --git a/src/core/ext/transport/chttp2/transport/writing.c b/src/core/ext/transport/chttp2/transport/writing.c index 4da9aa4f49..def79cd2a5 100644 --- a/src/core/ext/transport/chttp2/transport/writing.c +++ b/src/core/ext/transport/chttp2/transport/writing.c @@ -40,343 +40,360 @@ #include "src/core/ext/transport/chttp2/transport/http2_errors.h" #include "src/core/lib/profiling/timers.h" -static void finalize_outbuf(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_writing *transport_writing); +static void queue_write_callback(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s, grpc_closure **c, + grpc_error *error, + grpc_chttp2_call_write_cb_when when) { + switch (when) { + case GRPC_CHTTP2_CALL_WHEN_SCHEDULED: + grpc_chttp2_complete_closure_step(exec_ctx, t, s, c, error); + break; + case GRPC_CHTTP2_CALL_WHEN_WRITTEN: -int grpc_chttp2_unlocking_check_writes( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - grpc_chttp2_transport_writing *transport_writing) { - grpc_chttp2_stream_global *stream_global; - grpc_chttp2_stream_writing *stream_writing; + break; + } +} + +bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t) { + grpc_chttp2_stream *s; - GPR_TIMER_BEGIN("grpc_chttp2_unlocking_check_writes", 0); + GPR_TIMER_BEGIN("grpc_chttp2_begin_write", 0); - if (transport_global->dirtied_local_settings && - !transport_global->sent_local_settings) { + if (t->dirtied_local_settings && !t->sent_local_settings) { gpr_slice_buffer_add( - &transport_writing->outbuf, + &t->outbuf, grpc_chttp2_settings_create( - transport_global->settings[GRPC_SENT_SETTINGS], - transport_global->settings[GRPC_LOCAL_SETTINGS], - transport_global->force_send_settings, GRPC_CHTTP2_NUM_SETTINGS)); - transport_global->force_send_settings = 0; - transport_global->dirtied_local_settings = 0; - transport_global->sent_local_settings = 1; + t->settings[GRPC_SENT_SETTINGS], t->settings[GRPC_LOCAL_SETTINGS], + t->force_send_settings, GRPC_CHTTP2_NUM_SETTINGS)); + t->force_send_settings = 0; + t->dirtied_local_settings = 0; + t->sent_local_settings = 1; } /* simple writes are queued to qbuf, and flushed here */ - gpr_slice_buffer_move_into(&transport_global->qbuf, - &transport_writing->outbuf); - GPR_ASSERT(transport_global->qbuf.count == 0); + gpr_slice_buffer_move_into(&t->qbuf, &t->outbuf); + GPR_ASSERT(t->qbuf.count == 0); grpc_chttp2_hpack_compressor_set_max_table_size( - &transport_writing->hpack_compressor, - transport_global->settings[GRPC_PEER_SETTINGS] - [GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE]); - - GRPC_CHTTP2_FLOW_MOVE_TRANSPORT("write", transport_writing, outgoing_window, - transport_global, outgoing_window); - if (transport_writing->outgoing_window > 0) { - while (grpc_chttp2_list_pop_stalled_by_transport(transport_global, - &stream_global)) { - grpc_chttp2_become_writable(exec_ctx, transport_global, stream_global, - false, "transport.read_flow_control"); + &t->hpack_compressor, + t->settings[GRPC_PEER_SETTINGS][GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE]); + + if (t->outgoing_window > 0) { + while (grpc_chttp2_list_pop_stalled_by_transport(t, &s)) { + grpc_chttp2_become_writable(exec_ctx, t, s, false, + "transport.read_flow_control"); } } /* for each grpc_chttp2_stream that's become writable, frame it's data (according to available window sizes) and add to the output buffer */ - while (grpc_chttp2_list_pop_writable_stream( - transport_global, transport_writing, &stream_global, &stream_writing)) { - bool sent_initial_metadata = stream_writing->sent_initial_metadata; + while (grpc_chttp2_list_pop_writable_stream(t, &s)) { + bool sent_initial_metadata = s->sent_initial_metadata; bool become_writable = false; - stream_writing->id = stream_global->id; - stream_writing->read_closed = stream_global->read_closed; - - GRPC_CHTTP2_FLOW_MOVE_STREAM("write", transport_writing, stream_writing, - outgoing_window, stream_global, + GRPC_CHTTP2_FLOW_MOVE_STREAM("write", t, s, outgoing_window, s, outgoing_window); - if (!sent_initial_metadata && stream_global->send_initial_metadata) { - stream_writing->send_initial_metadata = - stream_global->send_initial_metadata; - stream_global->send_initial_metadata = NULL; + /* send initial metadata if it's available */ + if (!sent_initial_metadata && s->send_initial_metadata) { + grpc_chttp2_encode_header(&t->hpack_compressor, s->id, + s->send_initial_metadata, 0, &s->stats.outgoing, + &t->outbuf); + + s->send_initial_metadata = NULL; become_writable = true; sent_initial_metadata = true; } + /* send any window updates */ + if (s->announce_window > 0 && s->send_initial_metadata == NULL) { + uint32_t announce = s->announce_window; + gpr_slice_buffer_add(&t->outbuf, + grpc_chttp2_window_update_create( + s->id, s->announce_window, &s->stats.outgoing)); + GRPC_CHTTP2_FLOW_DEBIT_STREAM("write", t, s, announce_window, announce); + /* TODO(ctiller): why? */ + s->announce_window = 0; + } if (sent_initial_metadata) { - if (stream_global->send_message != NULL) { + /* send any body bytes, if allowed by flow control */ + if (s->flow_controlled_buffer.length > 0) { + uint32_t max_outgoing = + (uint32_t)GPR_MIN(GRPC_CHTTP2_MAX_PAYLOAD_LENGTH, + GPR_MIN(s->outgoing_window, t->outgoing_window)); + uint32_t send_bytes = + (uint32_t)GPR_MIN(max_outgoing, s->flow_controlled_buffer.length); + bool is_last_data_frame = + s->fetching_send_message == NULL && + send_bytes == s->flow_controlled_buffer.length; + bool is_last_frame = + is_last_data_frame && s->send_trailing_metadata != NULL && + grpc_metadata_batch_is_empty(s->send_trailing_metadata); + grpc_chttp2_encode_data(s->id, &s->flow_controlled_buffer, send_bytes, + is_last_frame, &s->stats.outgoing, &t->outbuf); + GRPC_CHTTP2_FLOW_DEBIT_STREAM("write", t, s, outgoing_window, + send_bytes); + GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("write", t, outgoing_window, + send_bytes); + if (is_last_frame) { + s->send_trailing_metadata = NULL; + s->sent_trailing_metadata = 1; + } +#if 0 + if (s->send_message != NULL) { gpr_slice hdr = gpr_slice_malloc(5); uint8_t *p = GPR_SLICE_START_PTR(hdr); - uint32_t len = stream_global->send_message->length; - GPR_ASSERT(stream_writing->send_message == NULL); - p[0] = (stream_global->send_message->flags & - GRPC_WRITE_INTERNAL_COMPRESS) != 0; + uint32_t len = s->send_message->length; + GPR_ASSERT(s->send_message == NULL); + p[0] = (s->send_message->flags & GRPC_WRITE_INTERNAL_COMPRESS) != 0; p[1] = (uint8_t)(len >> 24); p[2] = (uint8_t)(len >> 16); p[3] = (uint8_t)(len >> 8); p[4] = (uint8_t)(len); - gpr_slice_buffer_add(&stream_writing->flow_controlled_buffer, hdr); + gpr_slice_buffer_add(&s->flow_controlled_buffer, hdr); if (stream_global->send_message->length > 0) { - stream_writing->send_message = stream_global->send_message; + s->send_message = stream_global->send_message; } else { - stream_writing->send_message = NULL; + s->send_message = NULL; } - stream_writing->stream_fetched = 0; - stream_global->send_message = NULL; + s->stream_fetched = 0; + s->send_message = NULL; } - if ((stream_writing->send_message != NULL || - stream_writing->flow_controlled_buffer.length > 0) && - stream_writing->outgoing_window > 0) { + if ((s->send_message != NULL || s->flow_controlled_buffer.length > 0) && + s->outgoing_window > 0) { if (transport_writing->outgoing_window > 0) { become_writable = true; } else { - grpc_chttp2_list_add_stalled_by_transport(transport_writing, - stream_writing); + grpc_chttp2_list_add_stalled_by_transport(t, s); } } - if (stream_global->send_trailing_metadata) { - stream_writing->send_trailing_metadata = - stream_global->send_trailing_metadata; - stream_global->send_trailing_metadata = NULL; +#endif + if (stream_global->send_trailing_metadata) { + stream_writing->send_trailing_metadata = + stream_global->send_trailing_metadata; + stream_global->send_trailing_metadata = NULL; + become_writable = true; + } + } + + if (!stream_global->read_closed && + stream_global->unannounced_incoming_window_for_writing > 1024) { + GRPC_CHTTP2_FLOW_MOVE_STREAM("write", transport_global, stream_writing, + announce_window, stream_global, + unannounced_incoming_window_for_writing); become_writable = true; } - } - if (!stream_global->read_closed && - stream_global->unannounced_incoming_window_for_writing > 1024) { - GRPC_CHTTP2_FLOW_MOVE_STREAM("write", transport_global, stream_writing, - announce_window, stream_global, - unannounced_incoming_window_for_writing); - become_writable = true; + if (become_writable) { + grpc_chttp2_list_add_writing_stream(transport_writing, stream_writing); + } else { + GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2_writing"); + } } - if (become_writable) { - grpc_chttp2_list_add_writing_stream(transport_writing, stream_writing); - } else { - GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2_writing"); + /* if the grpc_chttp2_transport is ready to send a window update, do so here + also; 3/4 is a magic number that will likely get tuned soon */ + if (transport_global->announce_incoming_window > 0) { + uint32_t announced = (uint32_t)GPR_MIN( + transport_global->announce_incoming_window, UINT32_MAX); + GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("write", transport_global, + announce_incoming_window, announced); + grpc_transport_one_way_stats throwaway_stats; + gpr_slice_buffer_add( + &transport_writing->outbuf, + grpc_chttp2_window_update_create(0, announced, &throwaway_stats)); } - } - /* if the grpc_chttp2_transport is ready to send a window update, do so here - also; 3/4 is a magic number that will likely get tuned soon */ - if (transport_global->announce_incoming_window > 0) { - uint32_t announced = (uint32_t)GPR_MIN( - transport_global->announce_incoming_window, UINT32_MAX); - GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("write", transport_global, - announce_incoming_window, announced); - grpc_transport_one_way_stats throwaway_stats; - gpr_slice_buffer_add( - &transport_writing->outbuf, - grpc_chttp2_window_update_create(0, announced, &throwaway_stats)); - } - - GPR_TIMER_END("grpc_chttp2_unlocking_check_writes", 0); + GPR_TIMER_END("grpc_chttp2_unlocking_check_writes", 0); - return transport_writing->outbuf.count > 0 || - grpc_chttp2_list_have_writing_streams(transport_writing); -} + return transport_writing->outbuf.count > 0 || + grpc_chttp2_list_have_writing_streams(transport_writing); + } -void grpc_chttp2_perform_writes( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_writing *transport_writing, - grpc_endpoint *endpoint) { - GPR_ASSERT(transport_writing->outbuf.count > 0 || - grpc_chttp2_list_have_writing_streams(transport_writing)); + void grpc_chttp2_perform_writes( + grpc_exec_ctx * exec_ctx, + grpc_chttp2_transport_writing * transport_writing, + grpc_endpoint * endpoint) { + GPR_ASSERT(transport_writing->outbuf.count > 0 || + grpc_chttp2_list_have_writing_streams(transport_writing)); - finalize_outbuf(exec_ctx, transport_writing); + finalize_outbuf(exec_ctx, transport_writing); - GPR_ASSERT(endpoint); + GPR_ASSERT(endpoint); - if (transport_writing->outbuf.count > 0) { - grpc_endpoint_write(exec_ctx, endpoint, &transport_writing->outbuf, - &transport_writing->done_cb); - } else { - grpc_exec_ctx_sched(exec_ctx, &transport_writing->done_cb, GRPC_ERROR_NONE, - NULL); + if (transport_writing->outbuf.count > 0) { + grpc_endpoint_write(exec_ctx, endpoint, &transport_writing->outbuf, + &transport_writing->done_cb); + } else { + grpc_exec_ctx_sched(exec_ctx, &transport_writing->done_cb, + GRPC_ERROR_NONE, NULL); + } } -} -static void finalize_outbuf(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_writing *transport_writing) { - grpc_chttp2_stream_writing *stream_writing; + static void finalize_outbuf( + grpc_exec_ctx * exec_ctx, + grpc_chttp2_transport_writing * transport_writing) { + grpc_chttp2_stream_writing *stream_writing; - GPR_TIMER_BEGIN("finalize_outbuf", 0); + GPR_TIMER_BEGIN("finalize_outbuf", 0); - bool is_first_data_frame = true; - while ( - grpc_chttp2_list_pop_writing_stream(transport_writing, &stream_writing)) { - uint32_t max_outgoing = - (uint32_t)GPR_MIN(GRPC_CHTTP2_MAX_PAYLOAD_LENGTH, - GPR_MIN(stream_writing->outgoing_window, - transport_writing->outgoing_window)); - /* send initial metadata if it's available */ - if (stream_writing->send_initial_metadata != NULL) { - grpc_chttp2_encode_header( - &transport_writing->hpack_compressor, stream_writing->id, - stream_writing->send_initial_metadata, 0, &stream_writing->stats, - &transport_writing->outbuf); - stream_writing->send_initial_metadata = NULL; - stream_writing->sent_initial_metadata = 1; - } - /* send any window updates */ - if (stream_writing->announce_window > 0 && - stream_writing->send_initial_metadata == NULL) { - uint32_t announce = stream_writing->announce_window; - gpr_slice_buffer_add( - &transport_writing->outbuf, - grpc_chttp2_window_update_create(stream_writing->id, - stream_writing->announce_window, - &stream_writing->stats)); - GRPC_CHTTP2_FLOW_DEBIT_STREAM("write", transport_writing, stream_writing, - announce_window, announce); - stream_writing->announce_window = 0; - } - /* fetch any body bytes */ - while (!stream_writing->fetching && stream_writing->send_message && - stream_writing->flow_controlled_buffer.length < max_outgoing && - stream_writing->stream_fetched < - stream_writing->send_message->length) { - if (grpc_byte_stream_next(exec_ctx, stream_writing->send_message, - &stream_writing->fetching_slice, max_outgoing, - &stream_writing->finished_fetch)) { - stream_writing->stream_fetched += - GPR_SLICE_LENGTH(stream_writing->fetching_slice); - if (stream_writing->stream_fetched == - stream_writing->send_message->length) { - stream_writing->send_message = NULL; + bool is_first_data_frame = true; + while (grpc_chttp2_list_pop_writing_stream(transport_writing, + &stream_writing)) { + uint32_t max_outgoing = + (uint32_t)GPR_MIN(GRPC_CHTTP2_MAX_PAYLOAD_LENGTH, + GPR_MIN(stream_writing->outgoing_window, + transport_writing->outgoing_window)); + /* fetch any body bytes */ + while (!stream_writing->fetching && stream_writing->send_message && + stream_writing->flow_controlled_buffer.length < max_outgoing && + stream_writing->stream_fetched < + stream_writing->send_message->length) { + if (grpc_byte_stream_next(exec_ctx, stream_writing->send_message, + &stream_writing->fetching_slice, max_outgoing, + &stream_writing->finished_fetch)) { + stream_writing->stream_fetched += + GPR_SLICE_LENGTH(stream_writing->fetching_slice); + if (stream_writing->stream_fetched == + stream_writing->send_message->length) { + stream_writing->send_message = NULL; + } + gpr_slice_buffer_add(&stream_writing->flow_controlled_buffer, + stream_writing->fetching_slice); + } else { + stream_writing->fetching = 1; } - gpr_slice_buffer_add(&stream_writing->flow_controlled_buffer, - stream_writing->fetching_slice); - } else { - stream_writing->fetching = 1; } - } - /* send any body bytes */ - if (stream_writing->flow_controlled_buffer.length > 0) { - if (max_outgoing > 0) { - uint32_t send_bytes = (uint32_t)GPR_MIN( - max_outgoing, stream_writing->flow_controlled_buffer.length); - int is_last_data_frame = - stream_writing->send_message == NULL && - send_bytes == stream_writing->flow_controlled_buffer.length; - int is_last_frame = is_last_data_frame && - stream_writing->send_trailing_metadata != NULL && - grpc_metadata_batch_is_empty( - stream_writing->send_trailing_metadata); - grpc_chttp2_encode_data( - stream_writing->id, &stream_writing->flow_controlled_buffer, - send_bytes, is_last_frame, &stream_writing->stats, - &transport_writing->outbuf); - if (is_first_data_frame) { - /* TODO(dgq): this is a hack. It'll be fix in a future refactoring */ - stream_writing->stats.data_bytes -= 5; /* discount grpc framing */ - is_first_data_frame = false; + /* send any body bytes */ + if (stream_writing->flow_controlled_buffer.length > 0) { + if (max_outgoing > 0) { + uint32_t send_bytes = (uint32_t)GPR_MIN( + max_outgoing, stream_writing->flow_controlled_buffer.length); + int is_last_data_frame = + stream_writing->send_message == NULL && + send_bytes == stream_writing->flow_controlled_buffer.length; + int is_last_frame = is_last_data_frame && + stream_writing->send_trailing_metadata != NULL && + grpc_metadata_batch_is_empty( + stream_writing->send_trailing_metadata); + grpc_chttp2_encode_data( + stream_writing->id, &stream_writing->flow_controlled_buffer, + send_bytes, is_last_frame, &stream_writing->stats, + &transport_writing->outbuf); + if (is_first_data_frame) { + /* TODO(dgq): this is a hack. It'll be fix in a future refactoring + */ + stream_writing->stats.data_bytes -= 5; /* discount grpc framing */ + is_first_data_frame = false; + } + GRPC_CHTTP2_FLOW_DEBIT_STREAM("write", transport_writing, + stream_writing, outgoing_window, + send_bytes); + GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("write", transport_writing, + outgoing_window, send_bytes); + if (is_last_frame) { + stream_writing->send_trailing_metadata = NULL; + stream_writing->sent_trailing_metadata = 1; + } + if (is_last_data_frame) { + GPR_ASSERT(stream_writing->send_message == NULL); + stream_writing->sent_message = 1; + } + } else if (transport_writing->outgoing_window == 0) { + grpc_chttp2_list_add_writing_stalled_by_transport(transport_writing, + stream_writing); + grpc_chttp2_list_add_written_stream(transport_writing, + stream_writing); } - GRPC_CHTTP2_FLOW_DEBIT_STREAM("write", transport_writing, - stream_writing, outgoing_window, - send_bytes); - GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("write", transport_writing, - outgoing_window, send_bytes); - if (is_last_frame) { - stream_writing->send_trailing_metadata = NULL; - stream_writing->sent_trailing_metadata = 1; + } + /* send trailing metadata if it's available and we're ready for it */ + if (stream_writing->send_message == NULL && + stream_writing->flow_controlled_buffer.length == 0 && + stream_writing->send_trailing_metadata != NULL) { + if (grpc_metadata_batch_is_empty( + stream_writing->send_trailing_metadata)) { + grpc_chttp2_encode_data( + stream_writing->id, &stream_writing->flow_controlled_buffer, 0, 1, + &stream_writing->stats, &transport_writing->outbuf); + } else { + grpc_chttp2_encode_header( + &transport_writing->hpack_compressor, stream_writing->id, + stream_writing->send_trailing_metadata, 1, &stream_writing->stats, + &transport_writing->outbuf); } - if (is_last_data_frame) { - GPR_ASSERT(stream_writing->send_message == NULL); - stream_writing->sent_message = 1; + if (!transport_writing->is_client && !stream_writing->read_closed) { + gpr_slice_buffer_add(&transport_writing->outbuf, + grpc_chttp2_rst_stream_create( + stream_writing->id, GRPC_CHTTP2_NO_ERROR, + &stream_writing->stats)); } - } else if (transport_writing->outgoing_window == 0) { - grpc_chttp2_list_add_writing_stalled_by_transport(transport_writing, - stream_writing); - grpc_chttp2_list_add_written_stream(transport_writing, stream_writing); - } - } - /* send trailing metadata if it's available and we're ready for it */ - if (stream_writing->send_message == NULL && - stream_writing->flow_controlled_buffer.length == 0 && - stream_writing->send_trailing_metadata != NULL) { - if (grpc_metadata_batch_is_empty( - stream_writing->send_trailing_metadata)) { - grpc_chttp2_encode_data( - stream_writing->id, &stream_writing->flow_controlled_buffer, 0, 1, - &stream_writing->stats, &transport_writing->outbuf); - } else { - grpc_chttp2_encode_header( - &transport_writing->hpack_compressor, stream_writing->id, - stream_writing->send_trailing_metadata, 1, &stream_writing->stats, - &transport_writing->outbuf); + stream_writing->send_trailing_metadata = NULL; + stream_writing->sent_trailing_metadata = 1; } - if (!transport_writing->is_client && !stream_writing->read_closed) { - gpr_slice_buffer_add(&transport_writing->outbuf, - grpc_chttp2_rst_stream_create( - stream_writing->id, GRPC_CHTTP2_NO_ERROR, - &stream_writing->stats)); - } - stream_writing->send_trailing_metadata = NULL; - stream_writing->sent_trailing_metadata = 1; - } - /* if there's more to write, then loop, otherwise prepare to finish the - * write */ - if ((stream_writing->flow_controlled_buffer.length > 0 || - (stream_writing->send_message && !stream_writing->fetching)) && - stream_writing->outgoing_window > 0) { - if (transport_writing->outgoing_window > 0) { - grpc_chttp2_list_add_writing_stream(transport_writing, stream_writing); + /* if there's more to write, then loop, otherwise prepare to finish the + * write */ + if ((stream_writing->flow_controlled_buffer.length > 0 || + (stream_writing->send_message && !stream_writing->fetching)) && + stream_writing->outgoing_window > 0) { + if (transport_writing->outgoing_window > 0) { + grpc_chttp2_list_add_writing_stream(transport_writing, + stream_writing); + } else { + grpc_chttp2_list_add_writing_stalled_by_transport(transport_writing, + stream_writing); + grpc_chttp2_list_add_written_stream(transport_writing, + stream_writing); + } } else { - grpc_chttp2_list_add_writing_stalled_by_transport(transport_writing, - stream_writing); grpc_chttp2_list_add_written_stream(transport_writing, stream_writing); } - } else { - grpc_chttp2_list_add_written_stream(transport_writing, stream_writing); } - } - GPR_TIMER_END("finalize_outbuf", 0); -} - -void grpc_chttp2_cleanup_writing( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - grpc_chttp2_transport_writing *transport_writing) { - GPR_TIMER_BEGIN("grpc_chttp2_cleanup_writing", 0); - grpc_chttp2_stream_writing *stream_writing; - grpc_chttp2_stream_global *stream_global; - - if (grpc_chttp2_list_flush_writing_stalled_by_transport(exec_ctx, - transport_writing)) { - grpc_chttp2_initiate_write(exec_ctx, transport_global, false, - "resume_stalled_stream"); + GPR_TIMER_END("finalize_outbuf", 0); } - while (grpc_chttp2_list_pop_written_stream( - transport_global, transport_writing, &stream_global, &stream_writing)) { - if (stream_writing->sent_initial_metadata) { - grpc_chttp2_complete_closure_step( - exec_ctx, transport_global, stream_global, - &stream_global->send_initial_metadata_finished, GRPC_ERROR_NONE); - } - grpc_transport_move_one_way_stats(&stream_writing->stats, - &stream_global->stats.outgoing); - if (stream_writing->sent_message) { - GPR_ASSERT(stream_writing->send_message == NULL); - grpc_chttp2_complete_closure_step( - exec_ctx, transport_global, stream_global, - &stream_global->send_message_finished, GRPC_ERROR_NONE); - stream_writing->sent_message = 0; - } - if (stream_writing->sent_trailing_metadata) { - grpc_chttp2_complete_closure_step( - exec_ctx, transport_global, stream_global, - &stream_global->send_trailing_metadata_finished, GRPC_ERROR_NONE); + void grpc_chttp2_cleanup_writing( + grpc_exec_ctx * exec_ctx, grpc_chttp2_transport_global * transport_global, + grpc_chttp2_transport_writing * transport_writing) { + GPR_TIMER_BEGIN("grpc_chttp2_cleanup_writing", 0); + grpc_chttp2_stream_writing *stream_writing; + grpc_chttp2_stream_global *stream_global; + + if (grpc_chttp2_list_flush_writing_stalled_by_transport( + exec_ctx, transport_writing)) { + grpc_chttp2_initiate_write(exec_ctx, transport_global, false, + "resume_stalled_stream"); } - if (stream_writing->sent_trailing_metadata) { - grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global, - !transport_global->is_client, 1, - GRPC_ERROR_NONE); + + while (grpc_chttp2_list_pop_written_stream( + transport_global, transport_writing, &stream_global, &stream_writing)) { + if (stream_writing->sent_initial_metadata) { + grpc_chttp2_complete_closure_step( + exec_ctx, transport_global, stream_global, + &stream_global->send_initial_metadata_finished, GRPC_ERROR_NONE); + } + grpc_transport_move_one_way_stats(&stream_writing->stats, + &stream_global->stats.outgoing); + if (stream_writing->sent_message) { + GPR_ASSERT(stream_writing->send_message == NULL); + grpc_chttp2_complete_closure_step( + exec_ctx, transport_global, stream_global, + &stream_global->send_message_finished, GRPC_ERROR_NONE); + stream_writing->sent_message = 0; + } + if (stream_writing->sent_trailing_metadata) { + grpc_chttp2_complete_closure_step( + exec_ctx, transport_global, stream_global, + &stream_global->send_trailing_metadata_finished, GRPC_ERROR_NONE); + } + if (stream_writing->sent_trailing_metadata) { + grpc_chttp2_mark_stream_closed( + exec_ctx, transport_global, stream_global, + !transport_global->is_client, 1, GRPC_ERROR_NONE); + } + GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2_writing"); } - GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2_writing"); + gpr_slice_buffer_reset_and_unref(&transport_writing->outbuf); + GPR_TIMER_END("grpc_chttp2_cleanup_writing", 0); } - gpr_slice_buffer_reset_and_unref(&transport_writing->outbuf); - GPR_TIMER_END("grpc_chttp2_cleanup_writing", 0); -} -- cgit v1.2.3 From 0b8e0d5071bc135380e7e855ba33c92b082d49ff Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 29 Aug 2016 08:52:42 -0700 Subject: Write work --- .../transport/chttp2/transport/chttp2_transport.c | 29 +- src/core/ext/transport/chttp2/transport/internal.h | 36 +- src/core/ext/transport/chttp2/transport/writing.c | 503 +++++++++++---------- 3 files changed, 314 insertions(+), 254 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index f2c68df068..d177ce4281 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -865,13 +865,34 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, } if (op->send_message != NULL) { - GPR_ASSERT(s->send_message_finished == NULL); - GPR_ASSERT(s->send_message == NULL); - s->send_message_finished = add_closure_barrier(on_complete); if (s->write_closed) { + grpc_closure *temp_barrier = add_closure_barrier(op->send_message); grpc_chttp2_complete_closure_step( - exec_ctx, t, s, &s->send_message_finished, + exec_ctx, t, s, &temp_barrier, GRPC_ERROR_CREATE("Attempt to send message after stream was closed")); + } else { + uint8_t *frame_hdr = + gpr_slice_buffer_tiny_add(&s->flow_controlled_buffer, 5); + uint32_t flags = op->send_message->flags; + frame_hdr[0] = (flags & GRPC_WRITE_INTERNAL_COMPRESS) != 0; + size_t len = op->send_message->length; + frame_hdr[1] = (uint8_t)(len >> 24); + frame_hdr[2] = (uint8_t)(len >> 16); + frame_hdr[3] = (uint8_t)(len >> 8); + frame_hdr[4] = (uint8_t)(len); + grpc_chttp2_write_cb *write_cb = t->write_cb_pool; + if (write_cb != NULL) { + t->write_cb_pool = write_cb->next; + } else { + write_cb = gpr_malloc(sizeof(*write_cb)); + } + write_cb->next = &s->on_write_finished_cbs; + write_cb->call_at_byte = + add_send_completion(t, s, (ssize_t)() - backup, true); + } + + s->send_message_finished = add_closure_barrier(on_complete); + if (s->write_closed) { } else { s->send_message = op->send_message; if (s->id != 0) { diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index ee905369a4..1fef2c8f72 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -150,6 +150,17 @@ typedef struct grpc_chttp2_outstanding_ping { struct grpc_chttp2_outstanding_ping *prev; } grpc_chttp2_outstanding_ping; +typedef struct grpc_chttp2_write_cb { + size_t call_at_byte; + grpc_closure *closure; + struct grpc_chttp2_write_cb *next; +} grpc_chttp2_write_cb; + +typedef struct grpc_chttp2_write_cb_list { + grpc_chttp2_write_cb *head; + grpc_chttp2_write_cb *tail; +} grpc_chttp2_write_cb_list; + /* forward declared in frame_data.h */ struct grpc_chttp2_incoming_byte_stream { grpc_byte_stream base; @@ -318,23 +329,9 @@ struct grpc_chttp2_transport { uint32_t goaway_last_stream_index; gpr_slice goaway_text; - /* closures to finish after writing */ - grpc_closure **finish_after_writing; - size_t finish_after_writing_count; - size_t finish_after_writing_capacity; + grpc_chttp2_write_cb *write_cb_pool; }; -typedef enum { - GRPC_CHTTP2_CALL_WHEN_SCHEDULED, - GRPC_CHTTP2_CALL_WHEN_WRITTEN, -} grpc_chttp2_call_write_cb_when; - -typedef struct grpc_chttp2_write_cb { - size_t call_at_byte; - grpc_closure *closure; - grpc_chttp2_call_write_cb_when when; -} grpc_chttp2_write_cb; - struct grpc_chttp2_stream { grpc_chttp2_transport *t; grpc_stream_refcount *refcount; @@ -422,8 +419,7 @@ struct grpc_chttp2_stream { /** HTTP2 stream id for this stream, or zero if one has not been assigned */ uint8_t fetching; bool sent_initial_metadata; - uint8_t sent_message; - uint8_t sent_trailing_metadata; + bool sent_trailing_metadata; /** how much window should we announce? */ uint32_t announce_window; gpr_slice_buffer flow_controlled_buffer; @@ -431,9 +427,9 @@ struct grpc_chttp2_stream { size_t stream_fetched; grpc_closure finished_fetch; - grpc_chttp2_write_cb *write_cbs; - size_t write_cb_count; - size_t write_cb_capacity; + grpc_chttp2_write_cb_list on_write_scheduled_cbs; + grpc_chttp2_write_cb_list on_write_finished_cbs; + grpc_chttp2_write_cb_list finish_after_write; }; /** Transport writing call flow: diff --git a/src/core/ext/transport/chttp2/transport/writing.c b/src/core/ext/transport/chttp2/transport/writing.c index def79cd2a5..b75f5f4392 100644 --- a/src/core/ext/transport/chttp2/transport/writing.c +++ b/src/core/ext/transport/chttp2/transport/writing.c @@ -40,18 +40,44 @@ #include "src/core/ext/transport/chttp2/transport/http2_errors.h" #include "src/core/lib/profiling/timers.h" -static void queue_write_callback(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport *t, - grpc_chttp2_stream *s, grpc_closure **c, - grpc_error *error, - grpc_chttp2_call_write_cb_when when) { - switch (when) { - case GRPC_CHTTP2_CALL_WHEN_SCHEDULED: - grpc_chttp2_complete_closure_step(exec_ctx, t, s, c, error); - break; - case GRPC_CHTTP2_CALL_WHEN_WRITTEN: - - break; +static void add_to_write_list(grpc_chttp2_write_cb_list *list, + grpc_chttp2_write_cb *cb) { + if (list->head == NULL) { + list->head = list->tail = cb; + } else { + list->tail->next = cb; + list->tail = cb; + } + cb->next = NULL; +} + +static void finish_write_cb(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, + grpc_chttp2_stream *s, grpc_chttp2_write_cb *cb, + grpc_error *error) { + grpc_chttp2_complete_closure_step(exec_ctx, t, s, &cb->closure, error); + cb->next = t->write_cb_pool; + t->write_cb_pool = cb; +} + +static void update_list(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, + grpc_chttp2_stream *s, uint32_t send_bytes, + grpc_chttp2_write_cb_list *list, + grpc_chttp2_write_cb_list *done_target_or_null, + grpc_error *error) { + grpc_chttp2_write_cb *cb = list->head; + list->head = list->tail = NULL; + while (cb) { + grpc_chttp2_write_cb *next = cb->next; + if (cb->call_at_byte <= send_bytes) { + if (done_target_or_null != NULL) { + add_to_write_list(done_target_or_null, cb); + } else { + finish_write_cb(exec_ctx, t, s, cb, GRPC_ERROR_REF(error)); + } + } else { + cb->call_at_byte -= send_bytes; + add_to_write_list(list, cb); + } } } @@ -91,7 +117,6 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, (according to available window sizes) and add to the output buffer */ while (grpc_chttp2_list_pop_writable_stream(t, &s)) { bool sent_initial_metadata = s->sent_initial_metadata; - bool become_writable = false; GRPC_CHTTP2_FLOW_MOVE_STREAM("write", t, s, outgoing_window, s, outgoing_window); @@ -101,10 +126,10 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, grpc_chttp2_encode_header(&t->hpack_compressor, s->id, s->send_initial_metadata, 0, &s->stats.outgoing, &t->outbuf); - s->send_initial_metadata = NULL; - become_writable = true; + s->sent_initial_metadata = true; sent_initial_metadata = true; + grpc_chttp2_list_add_writing_stream(t, s); } /* send any window updates */ if (s->announce_window > 0 && s->send_initial_metadata == NULL) { @@ -122,24 +147,47 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, uint32_t max_outgoing = (uint32_t)GPR_MIN(GRPC_CHTTP2_MAX_PAYLOAD_LENGTH, GPR_MIN(s->outgoing_window, t->outgoing_window)); - uint32_t send_bytes = - (uint32_t)GPR_MIN(max_outgoing, s->flow_controlled_buffer.length); - bool is_last_data_frame = - s->fetching_send_message == NULL && - send_bytes == s->flow_controlled_buffer.length; - bool is_last_frame = - is_last_data_frame && s->send_trailing_metadata != NULL && - grpc_metadata_batch_is_empty(s->send_trailing_metadata); - grpc_chttp2_encode_data(s->id, &s->flow_controlled_buffer, send_bytes, - is_last_frame, &s->stats.outgoing, &t->outbuf); - GRPC_CHTTP2_FLOW_DEBIT_STREAM("write", t, s, outgoing_window, - send_bytes); - GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("write", t, outgoing_window, - send_bytes); - if (is_last_frame) { - s->send_trailing_metadata = NULL; - s->sent_trailing_metadata = 1; + if (max_outgoing > 0) { + uint32_t send_bytes = + (uint32_t)GPR_MIN(max_outgoing, s->flow_controlled_buffer.length); + bool is_last_data_frame = + s->fetching_send_message == NULL && + send_bytes == s->flow_controlled_buffer.length; + bool is_last_frame = + is_last_data_frame && s->send_trailing_metadata != NULL && + grpc_metadata_batch_is_empty(s->send_trailing_metadata); + grpc_chttp2_encode_data(s->id, &s->flow_controlled_buffer, send_bytes, + is_last_frame, &s->stats.outgoing, + &t->outbuf); + GRPC_CHTTP2_FLOW_DEBIT_STREAM("write", t, s, outgoing_window, + send_bytes); + GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("write", t, outgoing_window, + send_bytes); + if (is_last_frame) { + s->send_trailing_metadata = NULL; + s->sent_trailing_metadata = 1; + } + update_list(exec_ctx, t, s, send_bytes, &s->on_write_finished_cbs, + &s->finish_after_write, GRPC_ERROR_NONE); + update_list(exec_ctx, t, s, send_bytes, &s->on_write_scheduled_cbs, + NULL, GRPC_ERROR_NONE); + grpc_chttp2_list_add_writing_stream(t, s); + } else if (transport->outgoing_window == 0) { + grpc_chttp2_list_add_writing_stalled_by_transport(t, s); + grpc_chttp2_list_add_writing_stream(t, s); } + } + if (s->send_trailing_metadata && s->fetching_send_message == NULL && + s->flow_controlled_buffer.length == 0) { + grpc_chttp2_encode_header(&t->hpack_compressor, s->id, + s->send_trailing_metadata, 0, + &s->stats.outgoing, &t->outbuf); + s->send_trailing_metadata = NULL; + s->sent_trailing_metadata = true; + become_writable = true; + sent_initial_metadata = true; + grpc_chttp2_list_add_writing_stream(t, s); + } #if 0 if (s->send_message != NULL) { gpr_slice hdr = gpr_slice_malloc(5); @@ -169,231 +217,226 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, } } #endif - if (stream_global->send_trailing_metadata) { - stream_writing->send_trailing_metadata = - stream_global->send_trailing_metadata; - stream_global->send_trailing_metadata = NULL; - become_writable = true; - } - } - - if (!stream_global->read_closed && - stream_global->unannounced_incoming_window_for_writing > 1024) { - GRPC_CHTTP2_FLOW_MOVE_STREAM("write", transport_global, stream_writing, - announce_window, stream_global, - unannounced_incoming_window_for_writing); + if (stream_global->send_trailing_metadata) { + stream_writing->send_trailing_metadata = + stream_global->send_trailing_metadata; + stream_global->send_trailing_metadata = NULL; become_writable = true; } - - if (become_writable) { - grpc_chttp2_list_add_writing_stream(transport_writing, stream_writing); - } else { - GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2_writing"); - } } - /* if the grpc_chttp2_transport is ready to send a window update, do so here - also; 3/4 is a magic number that will likely get tuned soon */ - if (transport_global->announce_incoming_window > 0) { - uint32_t announced = (uint32_t)GPR_MIN( - transport_global->announce_incoming_window, UINT32_MAX); - GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("write", transport_global, - announce_incoming_window, announced); - grpc_transport_one_way_stats throwaway_stats; - gpr_slice_buffer_add( - &transport_writing->outbuf, - grpc_chttp2_window_update_create(0, announced, &throwaway_stats)); + if (!stream_global->read_closed && + stream_global->unannounced_incoming_window_for_writing > 1024) { + GRPC_CHTTP2_FLOW_MOVE_STREAM("write", transport_global, stream_writing, + announce_window, stream_global, + unannounced_incoming_window_for_writing); + become_writable = true; } - GPR_TIMER_END("grpc_chttp2_unlocking_check_writes", 0); + if (become_writable) { + grpc_chttp2_list_add_writing_stream(transport_writing, stream_writing); + } else { + GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2_writing"); + } + } - return transport_writing->outbuf.count > 0 || - grpc_chttp2_list_have_writing_streams(transport_writing); + /* if the grpc_chttp2_transport is ready to send a window update, do so here + also; 3/4 is a magic number that will likely get tuned soon */ + if (transport_global->announce_incoming_window > 0) { + uint32_t announced = (uint32_t)GPR_MIN( + transport_global->announce_incoming_window, UINT32_MAX); + GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("write", transport_global, + announce_incoming_window, announced); + grpc_transport_one_way_stats throwaway_stats; + gpr_slice_buffer_add( + &transport_writing->outbuf, + grpc_chttp2_window_update_create(0, announced, &throwaway_stats)); } - void grpc_chttp2_perform_writes( - grpc_exec_ctx * exec_ctx, - grpc_chttp2_transport_writing * transport_writing, - grpc_endpoint * endpoint) { - GPR_ASSERT(transport_writing->outbuf.count > 0 || - grpc_chttp2_list_have_writing_streams(transport_writing)); + GPR_TIMER_END("grpc_chttp2_unlocking_check_writes", 0); - finalize_outbuf(exec_ctx, transport_writing); + return transport_writing->outbuf.count > 0 || + grpc_chttp2_list_have_writing_streams(transport_writing); +} - GPR_ASSERT(endpoint); +void grpc_chttp2_perform_writes( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_writing *transport_writing, + grpc_endpoint *endpoint) { + GPR_ASSERT(transport_writing->outbuf.count > 0 || + grpc_chttp2_list_have_writing_streams(transport_writing)); - if (transport_writing->outbuf.count > 0) { - grpc_endpoint_write(exec_ctx, endpoint, &transport_writing->outbuf, - &transport_writing->done_cb); - } else { - grpc_exec_ctx_sched(exec_ctx, &transport_writing->done_cb, - GRPC_ERROR_NONE, NULL); - } + finalize_outbuf(exec_ctx, transport_writing); + + GPR_ASSERT(endpoint); + + if (transport_writing->outbuf.count > 0) { + grpc_endpoint_write(exec_ctx, endpoint, &transport_writing->outbuf, + &transport_writing->done_cb); + } else { + grpc_exec_ctx_sched(exec_ctx, &transport_writing->done_cb, GRPC_ERROR_NONE, + NULL); } +} - static void finalize_outbuf( - grpc_exec_ctx * exec_ctx, - grpc_chttp2_transport_writing * transport_writing) { - grpc_chttp2_stream_writing *stream_writing; - - GPR_TIMER_BEGIN("finalize_outbuf", 0); - - bool is_first_data_frame = true; - while (grpc_chttp2_list_pop_writing_stream(transport_writing, - &stream_writing)) { - uint32_t max_outgoing = - (uint32_t)GPR_MIN(GRPC_CHTTP2_MAX_PAYLOAD_LENGTH, - GPR_MIN(stream_writing->outgoing_window, - transport_writing->outgoing_window)); - /* fetch any body bytes */ - while (!stream_writing->fetching && stream_writing->send_message && - stream_writing->flow_controlled_buffer.length < max_outgoing && - stream_writing->stream_fetched < - stream_writing->send_message->length) { - if (grpc_byte_stream_next(exec_ctx, stream_writing->send_message, - &stream_writing->fetching_slice, max_outgoing, - &stream_writing->finished_fetch)) { - stream_writing->stream_fetched += - GPR_SLICE_LENGTH(stream_writing->fetching_slice); - if (stream_writing->stream_fetched == - stream_writing->send_message->length) { - stream_writing->send_message = NULL; - } - gpr_slice_buffer_add(&stream_writing->flow_controlled_buffer, - stream_writing->fetching_slice); - } else { - stream_writing->fetching = 1; +static void finalize_outbuf(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_writing *transport_writing) { + grpc_chttp2_stream_writing *stream_writing; + + GPR_TIMER_BEGIN("finalize_outbuf", 0); + + bool is_first_data_frame = true; + while ( + grpc_chttp2_list_pop_writing_stream(transport_writing, &stream_writing)) { + uint32_t max_outgoing = + (uint32_t)GPR_MIN(GRPC_CHTTP2_MAX_PAYLOAD_LENGTH, + GPR_MIN(stream_writing->outgoing_window, + transport_writing->outgoing_window)); + /* fetch any body bytes */ + while (!stream_writing->fetching && stream_writing->send_message && + stream_writing->flow_controlled_buffer.length < max_outgoing && + stream_writing->stream_fetched < + stream_writing->send_message->length) { + if (grpc_byte_stream_next(exec_ctx, stream_writing->send_message, + &stream_writing->fetching_slice, max_outgoing, + &stream_writing->finished_fetch)) { + stream_writing->stream_fetched += + GPR_SLICE_LENGTH(stream_writing->fetching_slice); + if (stream_writing->stream_fetched == + stream_writing->send_message->length) { + stream_writing->send_message = NULL; } + gpr_slice_buffer_add(&stream_writing->flow_controlled_buffer, + stream_writing->fetching_slice); + } else { + stream_writing->fetching = 1; } - /* send any body bytes */ - if (stream_writing->flow_controlled_buffer.length > 0) { - if (max_outgoing > 0) { - uint32_t send_bytes = (uint32_t)GPR_MIN( - max_outgoing, stream_writing->flow_controlled_buffer.length); - int is_last_data_frame = - stream_writing->send_message == NULL && - send_bytes == stream_writing->flow_controlled_buffer.length; - int is_last_frame = is_last_data_frame && - stream_writing->send_trailing_metadata != NULL && - grpc_metadata_batch_is_empty( - stream_writing->send_trailing_metadata); - grpc_chttp2_encode_data( - stream_writing->id, &stream_writing->flow_controlled_buffer, - send_bytes, is_last_frame, &stream_writing->stats, - &transport_writing->outbuf); - if (is_first_data_frame) { - /* TODO(dgq): this is a hack. It'll be fix in a future refactoring - */ - stream_writing->stats.data_bytes -= 5; /* discount grpc framing */ - is_first_data_frame = false; - } - GRPC_CHTTP2_FLOW_DEBIT_STREAM("write", transport_writing, - stream_writing, outgoing_window, - send_bytes); - GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("write", transport_writing, - outgoing_window, send_bytes); - if (is_last_frame) { - stream_writing->send_trailing_metadata = NULL; - stream_writing->sent_trailing_metadata = 1; - } - if (is_last_data_frame) { - GPR_ASSERT(stream_writing->send_message == NULL); - stream_writing->sent_message = 1; - } - } else if (transport_writing->outgoing_window == 0) { - grpc_chttp2_list_add_writing_stalled_by_transport(transport_writing, - stream_writing); - grpc_chttp2_list_add_written_stream(transport_writing, - stream_writing); + } + /* send any body bytes */ + if (stream_writing->flow_controlled_buffer.length > 0) { + if (max_outgoing > 0) { + uint32_t send_bytes = (uint32_t)GPR_MIN( + max_outgoing, stream_writing->flow_controlled_buffer.length); + int is_last_data_frame = + stream_writing->send_message == NULL && + send_bytes == stream_writing->flow_controlled_buffer.length; + int is_last_frame = is_last_data_frame && + stream_writing->send_trailing_metadata != NULL && + grpc_metadata_batch_is_empty( + stream_writing->send_trailing_metadata); + grpc_chttp2_encode_data( + stream_writing->id, &stream_writing->flow_controlled_buffer, + send_bytes, is_last_frame, &stream_writing->stats, + &transport_writing->outbuf); + if (is_first_data_frame) { + /* TODO(dgq): this is a hack. It'll be fix in a future refactoring + */ + stream_writing->stats.data_bytes -= 5; /* discount grpc framing */ + is_first_data_frame = false; } - } - /* send trailing metadata if it's available and we're ready for it */ - if (stream_writing->send_message == NULL && - stream_writing->flow_controlled_buffer.length == 0 && - stream_writing->send_trailing_metadata != NULL) { - if (grpc_metadata_batch_is_empty( - stream_writing->send_trailing_metadata)) { - grpc_chttp2_encode_data( - stream_writing->id, &stream_writing->flow_controlled_buffer, 0, 1, - &stream_writing->stats, &transport_writing->outbuf); - } else { - grpc_chttp2_encode_header( - &transport_writing->hpack_compressor, stream_writing->id, - stream_writing->send_trailing_metadata, 1, &stream_writing->stats, - &transport_writing->outbuf); + GRPC_CHTTP2_FLOW_DEBIT_STREAM("write", transport_writing, + stream_writing, outgoing_window, + send_bytes); + GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("write", transport_writing, + outgoing_window, send_bytes); + if (is_last_frame) { + stream_writing->send_trailing_metadata = NULL; + stream_writing->sent_trailing_metadata = 1; } - if (!transport_writing->is_client && !stream_writing->read_closed) { - gpr_slice_buffer_add(&transport_writing->outbuf, - grpc_chttp2_rst_stream_create( - stream_writing->id, GRPC_CHTTP2_NO_ERROR, - &stream_writing->stats)); + if (is_last_data_frame) { + GPR_ASSERT(stream_writing->send_message == NULL); + stream_writing->sent_message = 1; } - stream_writing->send_trailing_metadata = NULL; - stream_writing->sent_trailing_metadata = 1; + } else if (transport_writing->outgoing_window == 0) { + grpc_chttp2_list_add_writing_stalled_by_transport(transport_writing, + stream_writing); + grpc_chttp2_list_add_written_stream(transport_writing, stream_writing); } - /* if there's more to write, then loop, otherwise prepare to finish the - * write */ - if ((stream_writing->flow_controlled_buffer.length > 0 || - (stream_writing->send_message && !stream_writing->fetching)) && - stream_writing->outgoing_window > 0) { - if (transport_writing->outgoing_window > 0) { - grpc_chttp2_list_add_writing_stream(transport_writing, - stream_writing); - } else { - grpc_chttp2_list_add_writing_stalled_by_transport(transport_writing, - stream_writing); - grpc_chttp2_list_add_written_stream(transport_writing, - stream_writing); - } + } + /* send trailing metadata if it's available and we're ready for it */ + if (stream_writing->send_message == NULL && + stream_writing->flow_controlled_buffer.length == 0 && + stream_writing->send_trailing_metadata != NULL) { + if (grpc_metadata_batch_is_empty( + stream_writing->send_trailing_metadata)) { + grpc_chttp2_encode_data( + stream_writing->id, &stream_writing->flow_controlled_buffer, 0, 1, + &stream_writing->stats, &transport_writing->outbuf); + } else { + grpc_chttp2_encode_header( + &transport_writing->hpack_compressor, stream_writing->id, + stream_writing->send_trailing_metadata, 1, &stream_writing->stats, + &transport_writing->outbuf); + } + if (!transport_writing->is_client && !stream_writing->read_closed) { + gpr_slice_buffer_add(&transport_writing->outbuf, + grpc_chttp2_rst_stream_create( + stream_writing->id, GRPC_CHTTP2_NO_ERROR, + &stream_writing->stats)); + } + stream_writing->send_trailing_metadata = NULL; + stream_writing->sent_trailing_metadata = 1; + } + /* if there's more to write, then loop, otherwise prepare to finish the + * write */ + if ((stream_writing->flow_controlled_buffer.length > 0 || + (stream_writing->send_message && !stream_writing->fetching)) && + stream_writing->outgoing_window > 0) { + if (transport_writing->outgoing_window > 0) { + grpc_chttp2_list_add_writing_stream(transport_writing, stream_writing); } else { + grpc_chttp2_list_add_writing_stalled_by_transport(transport_writing, + stream_writing); grpc_chttp2_list_add_written_stream(transport_writing, stream_writing); } + } else { + grpc_chttp2_list_add_written_stream(transport_writing, stream_writing); } + } + + GPR_TIMER_END("finalize_outbuf", 0); +} - GPR_TIMER_END("finalize_outbuf", 0); +void grpc_chttp2_cleanup_writing( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, + grpc_chttp2_transport_writing *transport_writing) { + GPR_TIMER_BEGIN("grpc_chttp2_cleanup_writing", 0); + grpc_chttp2_stream_writing *stream_writing; + grpc_chttp2_stream_global *stream_global; + + if (grpc_chttp2_list_flush_writing_stalled_by_transport(exec_ctx, + transport_writing)) { + grpc_chttp2_initiate_write(exec_ctx, transport_global, false, + "resume_stalled_stream"); } - void grpc_chttp2_cleanup_writing( - grpc_exec_ctx * exec_ctx, grpc_chttp2_transport_global * transport_global, - grpc_chttp2_transport_writing * transport_writing) { - GPR_TIMER_BEGIN("grpc_chttp2_cleanup_writing", 0); - grpc_chttp2_stream_writing *stream_writing; - grpc_chttp2_stream_global *stream_global; - - if (grpc_chttp2_list_flush_writing_stalled_by_transport( - exec_ctx, transport_writing)) { - grpc_chttp2_initiate_write(exec_ctx, transport_global, false, - "resume_stalled_stream"); + while (grpc_chttp2_list_pop_written_stream( + transport_global, transport_writing, &stream_global, &stream_writing)) { + if (stream_writing->sent_initial_metadata) { + grpc_chttp2_complete_closure_step( + exec_ctx, transport_global, stream_global, + &stream_global->send_initial_metadata_finished, GRPC_ERROR_NONE); } - - while (grpc_chttp2_list_pop_written_stream( - transport_global, transport_writing, &stream_global, &stream_writing)) { - if (stream_writing->sent_initial_metadata) { - grpc_chttp2_complete_closure_step( - exec_ctx, transport_global, stream_global, - &stream_global->send_initial_metadata_finished, GRPC_ERROR_NONE); - } - grpc_transport_move_one_way_stats(&stream_writing->stats, - &stream_global->stats.outgoing); - if (stream_writing->sent_message) { - GPR_ASSERT(stream_writing->send_message == NULL); - grpc_chttp2_complete_closure_step( - exec_ctx, transport_global, stream_global, - &stream_global->send_message_finished, GRPC_ERROR_NONE); - stream_writing->sent_message = 0; - } - if (stream_writing->sent_trailing_metadata) { - grpc_chttp2_complete_closure_step( - exec_ctx, transport_global, stream_global, - &stream_global->send_trailing_metadata_finished, GRPC_ERROR_NONE); - } - if (stream_writing->sent_trailing_metadata) { - grpc_chttp2_mark_stream_closed( - exec_ctx, transport_global, stream_global, - !transport_global->is_client, 1, GRPC_ERROR_NONE); - } - GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2_writing"); + grpc_transport_move_one_way_stats(&stream_writing->stats, + &stream_global->stats.outgoing); + if (stream_writing->sent_message) { + GPR_ASSERT(stream_writing->send_message == NULL); + grpc_chttp2_complete_closure_step( + exec_ctx, transport_global, stream_global, + &stream_global->send_message_finished, GRPC_ERROR_NONE); + stream_writing->sent_message = 0; + } + if (stream_writing->sent_trailing_metadata) { + grpc_chttp2_complete_closure_step( + exec_ctx, transport_global, stream_global, + &stream_global->send_trailing_metadata_finished, GRPC_ERROR_NONE); } - gpr_slice_buffer_reset_and_unref(&transport_writing->outbuf); - GPR_TIMER_END("grpc_chttp2_cleanup_writing", 0); + if (stream_writing->sent_trailing_metadata) { + grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global, + !transport_global->is_client, 1, + GRPC_ERROR_NONE); + } + GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2_writing"); } + gpr_slice_buffer_reset_and_unref(&transport_writing->outbuf); + GPR_TIMER_END("grpc_chttp2_cleanup_writing", 0); +} -- cgit v1.2.3 From 16966845007f0a7264795855a8736abda1410ce0 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 29 Aug 2016 10:34:57 -0700 Subject: New write path compiles --- .../ext/transport/chttp2/transport/chttp2_plugin.c | 3 - .../transport/chttp2/transport/chttp2_transport.c | 116 ++++++-- src/core/ext/transport/chttp2/transport/internal.h | 33 +-- .../ext/transport/chttp2/transport/stream_lists.c | 34 --- src/core/ext/transport/chttp2/transport/writing.c | 316 ++++----------------- 5 files changed, 159 insertions(+), 343 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_plugin.c b/src/core/ext/transport/chttp2/transport/chttp2_plugin.c index 7d5279b9da..bd87253ed3 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_plugin.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_plugin.c @@ -36,14 +36,11 @@ #include "src/core/lib/debug/trace.h" #include "src/core/lib/transport/metadata.h" -extern int grpc_http_write_state_trace; - void grpc_chttp2_plugin_init(void) { grpc_chttp2_base64_encode_and_huffman_compress = grpc_chttp2_base64_encode_and_huffman_compress_impl; grpc_register_tracer("http", &grpc_http_trace); grpc_register_tracer("flowctl", &grpc_flowctl_trace); - grpc_register_tracer("http_write_state", &grpc_http_write_state_trace); } void grpc_chttp2_plugin_shutdown(void) {} diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index d177ce4281..c8553c4c47 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -82,6 +82,10 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *t, static void read_action_flush_locked(grpc_exec_ctx *exec_ctx, void *t, grpc_error *error); +static void complete_fetch_locked(grpc_exec_ctx *exec_ctx, void *gs, + grpc_error *error); +static void complete_fetch(grpc_exec_ctx *exec_ctx, void *gs, + grpc_error *error); /** Set a transport level setting, and push it to our peer */ static void push_setting(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_setting_id id, uint32_t value); @@ -443,6 +447,8 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, grpc_chttp2_data_parser_init(&s->data_parser); gpr_slice_buffer_init(&s->flow_controlled_buffer); s->deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC); + grpc_closure_init(&s->complete_fetch, complete_fetch, s); + grpc_closure_init(&s->complete_fetch_locked, complete_fetch_locked, s); GRPC_CHTTP2_REF_TRANSPORT(t, "stream"); @@ -493,7 +499,7 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp, } GPR_ASSERT(s->send_initial_metadata_finished == NULL); - GPR_ASSERT(s->send_message_finished == NULL); + GPR_ASSERT(s->fetching_send_message == NULL); GPR_ASSERT(s->send_trailing_metadata_finished == NULL); GPR_ASSERT(s->recv_initial_metadata_ready == NULL); GPR_ASSERT(s->recv_message_ready == NULL); @@ -776,6 +782,76 @@ static bool contains_non_ok_status(grpc_metadata_batch *batch) { return false; } +static void add_fetched_slice_locked(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s); + +static void continue_fetching_send_locked(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s) { + if (s->fetching_send_message == NULL) { + /* Stream was cancelled before message fetch completed */ + abort(); /* TODO(ctiller): what cleanup here? */ + return; + } + if (s->fetched_send_message_length == s->fetching_send_message->length) { + ssize_t notify_offset = s->fetching_slice_end_offset; + if (notify_offset <= 0) { + grpc_chttp2_complete_closure_step( + exec_ctx, t, s, &s->fetching_send_message_finished, GRPC_ERROR_NONE); + } else { + grpc_chttp2_write_cb *cb = t->write_cb_pool; + if (cb == NULL) { + cb = gpr_malloc(sizeof(*cb)); + } else { + t->write_cb_pool = cb->next; + } + cb->call_at_byte = (size_t)notify_offset; + cb->closure = s->fetching_send_message_finished; + s->fetching_send_message_finished = NULL; + cb->next = s->on_write_finished_cbs; + s->on_write_finished_cbs = cb; + } + s->fetching_send_message = NULL; + } else if (grpc_byte_stream_next(exec_ctx, s->fetching_send_message, + &s->fetching_slice, UINT32_MAX, + &s->complete_fetch)) { + add_fetched_slice_locked(exec_ctx, t, s); + } +} + +static void add_fetched_slice_locked(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s) { + s->fetched_send_message_length += + (uint32_t)GPR_SLICE_LENGTH(s->fetching_slice); + gpr_slice_buffer_add(&s->flow_controlled_buffer, s->fetching_slice); + if (s->id != 0) { + grpc_chttp2_become_writable(exec_ctx, t, s, true, "op.send_message"); + } + continue_fetching_send_locked(exec_ctx, t, s); +} + +static void complete_fetch_locked(grpc_exec_ctx *exec_ctx, void *gs, + grpc_error *error) { + grpc_chttp2_stream *s = gs; + grpc_chttp2_transport *t = s->t; + if (error == GRPC_ERROR_NONE) { + add_fetched_slice_locked(exec_ctx, t, s); + } else { + /* TODO(ctiller): what to do here */ + abort(); + } +} + +static void complete_fetch(grpc_exec_ctx *exec_ctx, void *gs, + grpc_error *error) { + grpc_chttp2_stream *s = gs; + grpc_chttp2_transport *t = s->t; + grpc_combiner_execute(exec_ctx, t->combiner, &s->complete_fetch_locked, + GRPC_ERROR_REF(error)); +} + static void do_nothing(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {} static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, @@ -865,12 +941,13 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, } if (op->send_message != NULL) { + s->fetching_send_message_finished = add_closure_barrier(op->on_complete); if (s->write_closed) { - grpc_closure *temp_barrier = add_closure_barrier(op->send_message); grpc_chttp2_complete_closure_step( - exec_ctx, t, s, &temp_barrier, + exec_ctx, t, s, &s->fetching_send_message_finished, GRPC_ERROR_CREATE("Attempt to send message after stream was closed")); } else { + GPR_ASSERT(s->fetching_send_message == NULL); uint8_t *frame_hdr = gpr_slice_buffer_tiny_add(&s->flow_controlled_buffer, 5); uint32_t flags = op->send_message->flags; @@ -880,21 +957,14 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, frame_hdr[2] = (uint8_t)(len >> 16); frame_hdr[3] = (uint8_t)(len >> 8); frame_hdr[4] = (uint8_t)(len); - grpc_chttp2_write_cb *write_cb = t->write_cb_pool; - if (write_cb != NULL) { - t->write_cb_pool = write_cb->next; - } else { - write_cb = gpr_malloc(sizeof(*write_cb)); + s->fetching_send_message = op->send_message; + s->fetched_send_message_length = 0; + s->fetching_slice_end_offset = + (ssize_t)s->flow_controlled_buffer.length + (ssize_t)len; + if (flags & GRPC_WRITE_BUFFER_HINT) { + s->fetched_send_message_length -= 65536; } - write_cb->next = &s->on_write_finished_cbs; - write_cb->call_at_byte = - add_send_completion(t, s, (ssize_t)() - backup, true); - } - - s->send_message_finished = add_closure_barrier(on_complete); - if (s->write_closed) { - } else { - s->send_message = op->send_message; + continue_fetching_send_locked(exec_ctx, t, s); if (s->id != 0) { grpc_chttp2_become_writable(exec_ctx, t, s, true, "op.send_message"); } @@ -1328,15 +1398,15 @@ static void fail_pending_writes(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s, grpc_error *error) { error = removal_error(error, s); - s->send_message = NULL; + s->fetching_send_message = NULL; grpc_chttp2_complete_closure_step(exec_ctx, t, s, &s->send_initial_metadata_finished, GRPC_ERROR_REF(error)); grpc_chttp2_complete_closure_step(exec_ctx, t, s, &s->send_trailing_metadata_finished, GRPC_ERROR_REF(error)); - grpc_chttp2_complete_closure_step(exec_ctx, t, s, &s->send_message_finished, - error); + grpc_chttp2_complete_closure_step(exec_ctx, t, s, + &s->fetching_send_message_finished, error); } void grpc_chttp2_mark_stream_closed(grpc_exec_ctx *exec_ctx, @@ -1386,9 +1456,11 @@ static void close_from_api(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, if (s->id != 0 && !t->is_client) { /* Hand roll a header block. - This is unnecessarily ugly - at some point we should find a more elegant + This is unnecessarily ugly - at some point we should find a more + elegant solution. - It's complicated by the fact that our send machinery would be dead by the + It's complicated by the fact that our send machinery would be dead by + the time we got around to sending this, so instead we ignore HPACK compression and just write the uncompressed bytes onto the wire. */ diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 1fef2c8f72..f90e6670a5 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -59,11 +59,7 @@ typedef enum { GRPC_CHTTP2_LIST_CHECK_READ_OPS, GRPC_CHTTP2_LIST_WRITABLE, GRPC_CHTTP2_LIST_WRITING, - GRPC_CHTTP2_LIST_WRITTEN, GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT, - /* streams waiting for the outgoing window in the writing path, they will be - * merged to the stalled list or writable list under transport lock. */ - GRPC_CHTTP2_LIST_WRITING_STALLED_BY_TRANSPORT, /** streams that are waiting to start because there are too many concurrent streams on the connection */ GRPC_CHTTP2_LIST_WAITING_FOR_CONCURRENCY, @@ -156,11 +152,6 @@ typedef struct grpc_chttp2_write_cb { struct grpc_chttp2_write_cb *next; } grpc_chttp2_write_cb; -typedef struct grpc_chttp2_write_cb_list { - grpc_chttp2_write_cb *head; - grpc_chttp2_write_cb *tail; -} grpc_chttp2_write_cb_list; - /* forward declared in frame_data.h */ struct grpc_chttp2_incoming_byte_stream { grpc_byte_stream base; @@ -365,6 +356,12 @@ struct grpc_chttp2_stream { grpc_closure *send_trailing_metadata_finished; grpc_byte_stream *fetching_send_message; + uint32_t fetched_send_message_length; + gpr_slice fetching_slice; + int64_t fetching_slice_end_offset; + grpc_closure complete_fetch; + grpc_closure complete_fetch_locked; + grpc_closure *fetching_send_message_finished; grpc_metadata_batch *recv_initial_metadata; grpc_closure *recv_initial_metadata_ready; @@ -416,20 +413,15 @@ struct grpc_chttp2_stream { /** number of bytes received - reset at end of parse thread execution */ int64_t received_bytes; - /** HTTP2 stream id for this stream, or zero if one has not been assigned */ - uint8_t fetching; bool sent_initial_metadata; bool sent_trailing_metadata; /** how much window should we announce? */ uint32_t announce_window; gpr_slice_buffer flow_controlled_buffer; - gpr_slice fetching_slice; - size_t stream_fetched; - grpc_closure finished_fetch; - grpc_chttp2_write_cb_list on_write_scheduled_cbs; - grpc_chttp2_write_cb_list on_write_finished_cbs; - grpc_chttp2_write_cb_list finish_after_write; + grpc_chttp2_write_cb *on_write_finished_cbs; + grpc_chttp2_write_cb *finish_after_write; + size_t sending_bytes; }; /** Transport writing call flow: @@ -451,7 +443,7 @@ void grpc_chttp2_initiate_write(grpc_exec_ctx *exec_ctx, /** Someone is unlocking the transport mutex: check to see if writes are required, and frame them if so */ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t); -void grpc_chttp2_end_write(grpc_exec_ctx *exec_ctx, void *transport_writing, +void grpc_chttp2_end_write(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_error *error); /** Process one slice of incoming data; return 1 if the connection is still @@ -492,11 +484,6 @@ bool grpc_chttp2_list_remove_check_read_ops(grpc_chttp2_transport *t, int grpc_chttp2_list_pop_check_read_ops(grpc_chttp2_transport *t, grpc_chttp2_stream **s); -void grpc_chttp2_list_add_writing_stalled_by_transport(grpc_chttp2_transport *t, - grpc_chttp2_stream *s); -bool grpc_chttp2_list_flush_writing_stalled_by_transport( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t); - void grpc_chttp2_list_add_stalled_by_transport(grpc_chttp2_transport *t, grpc_chttp2_stream *s); int grpc_chttp2_list_pop_stalled_by_transport(grpc_chttp2_transport *t, diff --git a/src/core/ext/transport/chttp2/transport/stream_lists.c b/src/core/ext/transport/chttp2/transport/stream_lists.c index 2d1b242612..a6b4a4e1d9 100644 --- a/src/core/ext/transport/chttp2/transport/stream_lists.c +++ b/src/core/ext/transport/chttp2/transport/stream_lists.c @@ -148,16 +148,6 @@ int grpc_chttp2_list_pop_writing_stream(grpc_chttp2_transport *t, return stream_list_pop(t, s, GRPC_CHTTP2_LIST_WRITING); } -void grpc_chttp2_list_add_written_stream(grpc_chttp2_transport *t, - grpc_chttp2_stream *s) { - stream_list_add(t, s, GRPC_CHTTP2_LIST_WRITTEN); -} - -int grpc_chttp2_list_pop_written_stream(grpc_chttp2_transport *t, - grpc_chttp2_stream **s) { - return stream_list_pop(t, s, GRPC_CHTTP2_LIST_WRITTEN); -} - void grpc_chttp2_list_add_waiting_for_concurrency(grpc_chttp2_transport *t, grpc_chttp2_stream *s) { stream_list_add(t, s, GRPC_CHTTP2_LIST_WAITING_FOR_CONCURRENCY); @@ -191,30 +181,6 @@ int grpc_chttp2_list_pop_check_read_ops(grpc_chttp2_transport *t, return stream_list_pop(t, s, GRPC_CHTTP2_LIST_CHECK_READ_OPS); } -void grpc_chttp2_list_add_writing_stalled_by_transport(grpc_chttp2_transport *t, - grpc_chttp2_stream *s) { - grpc_chttp2_stream *stream = s; - gpr_log(GPR_DEBUG, "writing stalled %d", s->id); - if (!stream->included[GRPC_CHTTP2_LIST_WRITING_STALLED_BY_TRANSPORT]) { - GRPC_CHTTP2_STREAM_REF(s, "chttp2_writing_stalled"); - } - stream_list_add(t, stream, GRPC_CHTTP2_LIST_WRITING_STALLED_BY_TRANSPORT); -} - -bool grpc_chttp2_list_flush_writing_stalled_by_transport( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t) { - grpc_chttp2_stream *s; - bool out = false; - while ( - stream_list_pop(t, &s, GRPC_CHTTP2_LIST_WRITING_STALLED_BY_TRANSPORT)) { - gpr_log(GPR_DEBUG, "move %d from writing stalled to just stalled", s->id); - grpc_chttp2_list_add_stalled_by_transport(t, s); - GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing_stalled"); - out = true; - } - return out; -} - void grpc_chttp2_list_add_stalled_by_transport(grpc_chttp2_transport *t, grpc_chttp2_stream *s) { stream_list_add(t, s, GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT); diff --git a/src/core/ext/transport/chttp2/transport/writing.c b/src/core/ext/transport/chttp2/transport/writing.c index b75f5f4392..e513bd9f5a 100644 --- a/src/core/ext/transport/chttp2/transport/writing.c +++ b/src/core/ext/transport/chttp2/transport/writing.c @@ -40,15 +40,10 @@ #include "src/core/ext/transport/chttp2/transport/http2_errors.h" #include "src/core/lib/profiling/timers.h" -static void add_to_write_list(grpc_chttp2_write_cb_list *list, +static void add_to_write_list(grpc_chttp2_write_cb **list, grpc_chttp2_write_cb *cb) { - if (list->head == NULL) { - list->head = list->tail = cb; - } else { - list->tail->next = cb; - list->tail = cb; - } - cb->next = NULL; + cb->next = *list; + *list = cb; } static void finish_write_cb(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, @@ -60,24 +55,19 @@ static void finish_write_cb(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, } static void update_list(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, - grpc_chttp2_stream *s, uint32_t send_bytes, - grpc_chttp2_write_cb_list *list, - grpc_chttp2_write_cb_list *done_target_or_null, - grpc_error *error) { - grpc_chttp2_write_cb *cb = list->head; - list->head = list->tail = NULL; + grpc_chttp2_stream *s, size_t send_bytes, + grpc_chttp2_write_cb **list, grpc_error *error) { + grpc_chttp2_write_cb *cb = *list; + *list = NULL; while (cb) { grpc_chttp2_write_cb *next = cb->next; if (cb->call_at_byte <= send_bytes) { - if (done_target_or_null != NULL) { - add_to_write_list(done_target_or_null, cb); - } else { - finish_write_cb(exec_ctx, t, s, cb, GRPC_ERROR_REF(error)); - } + finish_write_cb(exec_ctx, t, s, cb, GRPC_ERROR_REF(error)); } else { cb->call_at_byte -= send_bytes; add_to_write_list(list, cb); } + cb = next; } } @@ -117,6 +107,7 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, (according to available window sizes) and add to the output buffer */ while (grpc_chttp2_list_pop_writable_stream(t, &s)) { bool sent_initial_metadata = s->sent_initial_metadata; + bool now_writing = false; GRPC_CHTTP2_FLOW_MOVE_STREAM("write", t, s, outgoing_window, s, outgoing_window); @@ -129,7 +120,7 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, s->send_initial_metadata = NULL; s->sent_initial_metadata = true; sent_initial_metadata = true; - grpc_chttp2_list_add_writing_stream(t, s); + now_writing = true; } /* send any window updates */ if (s->announce_window > 0 && s->send_initial_metadata == NULL) { @@ -167,276 +158,79 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, s->send_trailing_metadata = NULL; s->sent_trailing_metadata = 1; } - update_list(exec_ctx, t, s, send_bytes, &s->on_write_finished_cbs, - &s->finish_after_write, GRPC_ERROR_NONE); - update_list(exec_ctx, t, s, send_bytes, &s->on_write_scheduled_cbs, - NULL, GRPC_ERROR_NONE); - grpc_chttp2_list_add_writing_stream(t, s); - } else if (transport->outgoing_window == 0) { - grpc_chttp2_list_add_writing_stalled_by_transport(t, s); - grpc_chttp2_list_add_writing_stream(t, s); + s->sending_bytes += send_bytes; + now_writing = true; + if (s->flow_controlled_buffer.length > 0) { + GRPC_CHTTP2_STREAM_REF(s, "chttp2_writing"); + grpc_chttp2_list_add_writing_stream(t, s); + } + } else if (t->outgoing_window == 0) { + grpc_chttp2_list_add_stalled_by_transport(t, s); + now_writing = true; } } - if (s->send_trailing_metadata && s->fetching_send_message == NULL && + if (s->send_trailing_metadata != NULL && + s->fetching_send_message == NULL && s->flow_controlled_buffer.length == 0) { grpc_chttp2_encode_header(&t->hpack_compressor, s->id, s->send_trailing_metadata, 0, &s->stats.outgoing, &t->outbuf); s->send_trailing_metadata = NULL; s->sent_trailing_metadata = true; - become_writable = true; - sent_initial_metadata = true; - grpc_chttp2_list_add_writing_stream(t, s); - } -#if 0 - if (s->send_message != NULL) { - gpr_slice hdr = gpr_slice_malloc(5); - uint8_t *p = GPR_SLICE_START_PTR(hdr); - uint32_t len = s->send_message->length; - GPR_ASSERT(s->send_message == NULL); - p[0] = (s->send_message->flags & GRPC_WRITE_INTERNAL_COMPRESS) != 0; - p[1] = (uint8_t)(len >> 24); - p[2] = (uint8_t)(len >> 16); - p[3] = (uint8_t)(len >> 8); - p[4] = (uint8_t)(len); - gpr_slice_buffer_add(&s->flow_controlled_buffer, hdr); - if (stream_global->send_message->length > 0) { - s->send_message = stream_global->send_message; - } else { - s->send_message = NULL; - } - s->stream_fetched = 0; - s->send_message = NULL; - } - if ((s->send_message != NULL || s->flow_controlled_buffer.length > 0) && - s->outgoing_window > 0) { - if (transport_writing->outgoing_window > 0) { - become_writable = true; - } else { - grpc_chttp2_list_add_stalled_by_transport(t, s); - } - } -#endif - if (stream_global->send_trailing_metadata) { - stream_writing->send_trailing_metadata = - stream_global->send_trailing_metadata; - stream_global->send_trailing_metadata = NULL; - become_writable = true; + now_writing = true; } } - if (!stream_global->read_closed && - stream_global->unannounced_incoming_window_for_writing > 1024) { - GRPC_CHTTP2_FLOW_MOVE_STREAM("write", transport_global, stream_writing, - announce_window, stream_global, - unannounced_incoming_window_for_writing); - become_writable = true; - } - - if (become_writable) { - grpc_chttp2_list_add_writing_stream(transport_writing, stream_writing); + if (now_writing) { + grpc_chttp2_list_add_writing_stream(t, s); } else { - GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2_writing"); + GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing"); } } /* if the grpc_chttp2_transport is ready to send a window update, do so here also; 3/4 is a magic number that will likely get tuned soon */ - if (transport_global->announce_incoming_window > 0) { - uint32_t announced = (uint32_t)GPR_MIN( - transport_global->announce_incoming_window, UINT32_MAX); - GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("write", transport_global, - announce_incoming_window, announced); + if (t->announce_incoming_window > 0) { + uint32_t announced = + (uint32_t)GPR_MIN(t->announce_incoming_window, UINT32_MAX); + GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("write", t, announce_incoming_window, + announced); grpc_transport_one_way_stats throwaway_stats; - gpr_slice_buffer_add( - &transport_writing->outbuf, - grpc_chttp2_window_update_create(0, announced, &throwaway_stats)); + gpr_slice_buffer_add(&t->outbuf, grpc_chttp2_window_update_create( + 0, announced, &throwaway_stats)); } GPR_TIMER_END("grpc_chttp2_unlocking_check_writes", 0); - return transport_writing->outbuf.count > 0 || - grpc_chttp2_list_have_writing_streams(transport_writing); + return t->outbuf.count > 0; } -void grpc_chttp2_perform_writes( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_writing *transport_writing, - grpc_endpoint *endpoint) { - GPR_ASSERT(transport_writing->outbuf.count > 0 || - grpc_chttp2_list_have_writing_streams(transport_writing)); - - finalize_outbuf(exec_ctx, transport_writing); - - GPR_ASSERT(endpoint); - - if (transport_writing->outbuf.count > 0) { - grpc_endpoint_write(exec_ctx, endpoint, &transport_writing->outbuf, - &transport_writing->done_cb); - } else { - grpc_exec_ctx_sched(exec_ctx, &transport_writing->done_cb, GRPC_ERROR_NONE, - NULL); - } -} - -static void finalize_outbuf(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_writing *transport_writing) { - grpc_chttp2_stream_writing *stream_writing; - - GPR_TIMER_BEGIN("finalize_outbuf", 0); - - bool is_first_data_frame = true; - while ( - grpc_chttp2_list_pop_writing_stream(transport_writing, &stream_writing)) { - uint32_t max_outgoing = - (uint32_t)GPR_MIN(GRPC_CHTTP2_MAX_PAYLOAD_LENGTH, - GPR_MIN(stream_writing->outgoing_window, - transport_writing->outgoing_window)); - /* fetch any body bytes */ - while (!stream_writing->fetching && stream_writing->send_message && - stream_writing->flow_controlled_buffer.length < max_outgoing && - stream_writing->stream_fetched < - stream_writing->send_message->length) { - if (grpc_byte_stream_next(exec_ctx, stream_writing->send_message, - &stream_writing->fetching_slice, max_outgoing, - &stream_writing->finished_fetch)) { - stream_writing->stream_fetched += - GPR_SLICE_LENGTH(stream_writing->fetching_slice); - if (stream_writing->stream_fetched == - stream_writing->send_message->length) { - stream_writing->send_message = NULL; - } - gpr_slice_buffer_add(&stream_writing->flow_controlled_buffer, - stream_writing->fetching_slice); - } else { - stream_writing->fetching = 1; - } - } - /* send any body bytes */ - if (stream_writing->flow_controlled_buffer.length > 0) { - if (max_outgoing > 0) { - uint32_t send_bytes = (uint32_t)GPR_MIN( - max_outgoing, stream_writing->flow_controlled_buffer.length); - int is_last_data_frame = - stream_writing->send_message == NULL && - send_bytes == stream_writing->flow_controlled_buffer.length; - int is_last_frame = is_last_data_frame && - stream_writing->send_trailing_metadata != NULL && - grpc_metadata_batch_is_empty( - stream_writing->send_trailing_metadata); - grpc_chttp2_encode_data( - stream_writing->id, &stream_writing->flow_controlled_buffer, - send_bytes, is_last_frame, &stream_writing->stats, - &transport_writing->outbuf); - if (is_first_data_frame) { - /* TODO(dgq): this is a hack. It'll be fix in a future refactoring - */ - stream_writing->stats.data_bytes -= 5; /* discount grpc framing */ - is_first_data_frame = false; - } - GRPC_CHTTP2_FLOW_DEBIT_STREAM("write", transport_writing, - stream_writing, outgoing_window, - send_bytes); - GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("write", transport_writing, - outgoing_window, send_bytes); - if (is_last_frame) { - stream_writing->send_trailing_metadata = NULL; - stream_writing->sent_trailing_metadata = 1; - } - if (is_last_data_frame) { - GPR_ASSERT(stream_writing->send_message == NULL); - stream_writing->sent_message = 1; - } - } else if (transport_writing->outgoing_window == 0) { - grpc_chttp2_list_add_writing_stalled_by_transport(transport_writing, - stream_writing); - grpc_chttp2_list_add_written_stream(transport_writing, stream_writing); - } - } - /* send trailing metadata if it's available and we're ready for it */ - if (stream_writing->send_message == NULL && - stream_writing->flow_controlled_buffer.length == 0 && - stream_writing->send_trailing_metadata != NULL) { - if (grpc_metadata_batch_is_empty( - stream_writing->send_trailing_metadata)) { - grpc_chttp2_encode_data( - stream_writing->id, &stream_writing->flow_controlled_buffer, 0, 1, - &stream_writing->stats, &transport_writing->outbuf); - } else { - grpc_chttp2_encode_header( - &transport_writing->hpack_compressor, stream_writing->id, - stream_writing->send_trailing_metadata, 1, &stream_writing->stats, - &transport_writing->outbuf); - } - if (!transport_writing->is_client && !stream_writing->read_closed) { - gpr_slice_buffer_add(&transport_writing->outbuf, - grpc_chttp2_rst_stream_create( - stream_writing->id, GRPC_CHTTP2_NO_ERROR, - &stream_writing->stats)); - } - stream_writing->send_trailing_metadata = NULL; - stream_writing->sent_trailing_metadata = 1; - } - /* if there's more to write, then loop, otherwise prepare to finish the - * write */ - if ((stream_writing->flow_controlled_buffer.length > 0 || - (stream_writing->send_message && !stream_writing->fetching)) && - stream_writing->outgoing_window > 0) { - if (transport_writing->outgoing_window > 0) { - grpc_chttp2_list_add_writing_stream(transport_writing, stream_writing); - } else { - grpc_chttp2_list_add_writing_stalled_by_transport(transport_writing, - stream_writing); - grpc_chttp2_list_add_written_stream(transport_writing, stream_writing); - } - } else { - grpc_chttp2_list_add_written_stream(transport_writing, stream_writing); - } - } - - GPR_TIMER_END("finalize_outbuf", 0); -} - -void grpc_chttp2_cleanup_writing( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - grpc_chttp2_transport_writing *transport_writing) { +void grpc_chttp2_end_write(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, + grpc_error *error) { GPR_TIMER_BEGIN("grpc_chttp2_cleanup_writing", 0); - grpc_chttp2_stream_writing *stream_writing; - grpc_chttp2_stream_global *stream_global; - - if (grpc_chttp2_list_flush_writing_stalled_by_transport(exec_ctx, - transport_writing)) { - grpc_chttp2_initiate_write(exec_ctx, transport_global, false, - "resume_stalled_stream"); - } + grpc_chttp2_stream *s; - while (grpc_chttp2_list_pop_written_stream( - transport_global, transport_writing, &stream_global, &stream_writing)) { - if (stream_writing->sent_initial_metadata) { - grpc_chttp2_complete_closure_step( - exec_ctx, transport_global, stream_global, - &stream_global->send_initial_metadata_finished, GRPC_ERROR_NONE); - } - grpc_transport_move_one_way_stats(&stream_writing->stats, - &stream_global->stats.outgoing); - if (stream_writing->sent_message) { - GPR_ASSERT(stream_writing->send_message == NULL); - grpc_chttp2_complete_closure_step( - exec_ctx, transport_global, stream_global, - &stream_global->send_message_finished, GRPC_ERROR_NONE); - stream_writing->sent_message = 0; + while (grpc_chttp2_list_pop_writing_stream(t, &s)) { + if (s->sent_initial_metadata) { + grpc_chttp2_complete_closure_step(exec_ctx, t, s, + &s->send_initial_metadata_finished, + GRPC_ERROR_REF(error)); } - if (stream_writing->sent_trailing_metadata) { - grpc_chttp2_complete_closure_step( - exec_ctx, transport_global, stream_global, - &stream_global->send_trailing_metadata_finished, GRPC_ERROR_NONE); + if (s->sending_bytes != 0) { + update_list(exec_ctx, t, s, s->sending_bytes, &s->on_write_finished_cbs, + GRPC_ERROR_REF(error)); + s->sending_bytes = 0; } - if (stream_writing->sent_trailing_metadata) { - grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global, - !transport_global->is_client, 1, - GRPC_ERROR_NONE); + if (s->sent_trailing_metadata) { + grpc_chttp2_complete_closure_step(exec_ctx, t, s, + &s->send_trailing_metadata_finished, + GRPC_ERROR_REF(error)); + grpc_chttp2_mark_stream_closed(exec_ctx, t, s, !t->is_client, 1, + GRPC_ERROR_REF(error)); } - GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2_writing"); + GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing"); } - gpr_slice_buffer_reset_and_unref(&transport_writing->outbuf); + gpr_slice_buffer_reset_and_unref(&t->outbuf); + GRPC_ERROR_UNREF(error); GPR_TIMER_END("grpc_chttp2_cleanup_writing", 0); } -- cgit v1.2.3 From 419c9d7a7d9a3b2eaea94c803c8559f5d2189db0 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 29 Aug 2016 10:40:06 -0700 Subject: Remove unnecessary endpoint shutdown protection (now that endpoint shutdown is idempotent) --- .../transport/chttp2/transport/chttp2_transport.c | 21 +-------------------- src/core/ext/transport/chttp2/transport/internal.h | 3 --- src/core/ext/transport/chttp2/transport/parsing.c | 6 ------ 3 files changed, 1 insertion(+), 29 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index c8553c4c47..310bca0b1f 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -207,8 +207,6 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, t->ep = ep; /* one ref is for destroy */ gpr_ref_init(&t->refs, 1); - /* ref is dropped at transport close() */ - gpr_ref_init(&t->shutdown_ep_refs, 1); t->combiner = grpc_combiner_create(grpc_endpoint_get_workqueue(ep)); t->peer_string = grpc_endpoint_get_peer(ep); t->endpoint_reading = 1; @@ -377,19 +375,6 @@ static void destroy_transport(grpc_exec_ctx *exec_ctx, grpc_transport *gt) { GRPC_ERROR_NONE); } -/** block grpc_endpoint_shutdown being called until a paired - allow_endpoint_shutdown is made */ -static void prevent_endpoint_shutdown(grpc_chttp2_transport *t) { - gpr_ref(&t->shutdown_ep_refs); -} - -static void allow_endpoint_shutdown_locked(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport *t) { - if (gpr_unref(&t->shutdown_ep_refs)) { - grpc_endpoint_shutdown(exec_ctx, t->ep); - } -} - static void close_transport_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_error *error) { @@ -397,7 +382,7 @@ static void close_transport_locked(grpc_exec_ctx *exec_ctx, t->closed = 1; connectivity_state_set(exec_ctx, t, GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_REF(error), "close_transport"); - allow_endpoint_shutdown_locked(exec_ctx, t); + grpc_endpoint_shutdown(exec_ctx, t->ep); /* flush writable stream list to avoid dangling references */ grpc_chttp2_stream *s; @@ -591,7 +576,6 @@ static void write_action_begin_locked(grpc_exec_ctx *exec_ctx, void *gt, grpc_chttp2_transport *t = gt; GPR_ASSERT(t->write_state != GRPC_CHTTP2_WRITE_STATE_IDLE); if (!t->closed && grpc_chttp2_begin_write(exec_ctx, t)) { - prevent_endpoint_shutdown(t); grpc_exec_ctx_sched(exec_ctx, &t->write_action, GRPC_ERROR_NONE, NULL); } else { t->write_state = GRPC_CHTTP2_WRITE_STATE_IDLE; @@ -620,7 +604,6 @@ static void write_action_end_locked(grpc_exec_ctx *exec_ctx, void *tp, grpc_error *error) { GPR_TIMER_BEGIN("terminate_writing_with_lock", 0); grpc_chttp2_transport *t = tp; - allow_endpoint_shutdown_locked(exec_ctx, t); if (error != GRPC_ERROR_NONE) { drop_connection(exec_ctx, t, GRPC_ERROR_REF(error)); @@ -1715,13 +1698,11 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp, } else if (!t->closed) { keep_reading = true; GRPC_CHTTP2_REF_TRANSPORT(t, "keep_reading"); - prevent_endpoint_shutdown(t); } gpr_slice_buffer_reset_and_unref(&t->read_buffer); if (keep_reading) { grpc_endpoint_read(exec_ctx, t->ep, &t->read_buffer, &t->read_action_begin); - allow_endpoint_shutdown_locked(exec_ctx, t); GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "keep_reading"); } else { GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "reading_action"); diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index f90e6670a5..c599c31162 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -184,9 +184,6 @@ struct grpc_chttp2_transport { grpc_endpoint *ep; char *peer_string; - /** when this drops to zero it's safe to shutdown the endpoint */ - gpr_refcount shutdown_ep_refs; - grpc_combiner *combiner; /** write execution state of the transport */ diff --git a/src/core/ext/transport/chttp2/transport/parsing.c b/src/core/ext/transport/chttp2/transport/parsing.c index 7728cd4b81..2ff1e4c620 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.c +++ b/src/core/ext/transport/chttp2/transport/parsing.c @@ -711,12 +711,6 @@ static grpc_error *init_settings_frame_parser(grpc_exec_ctx *exec_ctx, return GRPC_ERROR_NONE; } -/* -static int is_window_update_legal(int64_t window_update, int64_t window) { - return window + window_update < MAX_WINDOW; -} -*/ - static grpc_error *parse_frame_slice(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, gpr_slice slice, int is_last) { -- cgit v1.2.3 From 797d8dbf60bbe4b2d6b554ed3d11f5650041e9b9 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 29 Aug 2016 11:21:42 -0700 Subject: cleanup,debug --- .../transport/chttp2/transport/chttp2_transport.c | 8 ++++++++ src/core/ext/transport/chttp2/transport/writing.c | 20 ++++++++++++++++---- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 310bca0b1f..cf2c38f287 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -720,6 +720,8 @@ static void maybe_start_some_streams(grpc_exec_ctx *exec_ctx, #define CLOSURE_BARRIER_FIRST_REF_BIT (1 << 16) static grpc_closure *add_closure_barrier(grpc_closure *closure) { + gpr_log(GPR_DEBUG, "add_closure_barrier[%p]: scratch=%" PRIdPTR, closure, + closure->next_data.scratch); closure->next_data.scratch += CLOSURE_BARRIER_FIRST_REF_BIT; return closure; } @@ -734,6 +736,8 @@ void grpc_chttp2_complete_closure_step(grpc_exec_ctx *exec_ctx, GRPC_ERROR_UNREF(error); return; } + gpr_log(GPR_DEBUG, "complete_closure_step[%p]: scratch=%" PRIdPTR, closure, + closure->next_data.scratch); closure->next_data.scratch -= CLOSURE_BARRIER_FIRST_REF_BIT; if (error != GRPC_ERROR_NONE) { if (closure->error == GRPC_ERROR_NONE) { @@ -772,6 +776,10 @@ static void add_fetched_slice_locked(grpc_exec_ctx *exec_ctx, static void continue_fetching_send_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s) { + gpr_log(GPR_DEBUG, + "continue_fetching_send_locked[%d]: fsm=%p fetched=%d tgt=%d", s->id, + s->fetching_send_message, s->fetched_send_message_length, + s->fetching_send_message->length); if (s->fetching_send_message == NULL) { /* Stream was cancelled before message fetch completed */ abort(); /* TODO(ctiller): what cleanup here? */ diff --git a/src/core/ext/transport/chttp2/transport/writing.c b/src/core/ext/transport/chttp2/transport/writing.c index e513bd9f5a..98c0781ac2 100644 --- a/src/core/ext/transport/chttp2/transport/writing.c +++ b/src/core/ext/transport/chttp2/transport/writing.c @@ -77,6 +77,13 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, GPR_TIMER_BEGIN("grpc_chttp2_begin_write", 0); + gpr_log( + GPR_DEBUG, + "grpc_chttp2_begin_write: outbuf_len0=%" PRIdPTR + " dirtied_local_settings=%d sent_local_settings=%d qbuf_len=%" PRIdPTR, + t->outbuf.length, t->dirtied_local_settings, t->sent_local_settings, + t->qbuf.length); + if (t->dirtied_local_settings && !t->sent_local_settings) { gpr_slice_buffer_add( &t->outbuf, @@ -109,8 +116,13 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, bool sent_initial_metadata = s->sent_initial_metadata; bool now_writing = false; - GRPC_CHTTP2_FLOW_MOVE_STREAM("write", t, s, outgoing_window, s, - outgoing_window); + gpr_log(GPR_DEBUG, + "grpc_chttp2_begin_write[%d]: sent_initial_metadata=%d " + "send_initial_metadata=%p announce_window=%d fcbuf_len=%" PRIdPTR + " s_win=%" PRId64 " t_win=%" PRId64 " send_trailing_metadata=%p", + s->id, sent_initial_metadata, s->send_initial_metadata, + s->announce_window, s->flow_controlled_buffer.length, + s->outgoing_window, t->outgoing_window, s->send_trailing_metadata); /* send initial metadata if it's available */ if (!sent_initial_metadata && s->send_initial_metadata) { @@ -123,7 +135,7 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, now_writing = true; } /* send any window updates */ - if (s->announce_window > 0 && s->send_initial_metadata == NULL) { + if (s->announce_window > 0 && s->sent_initial_metadata) { uint32_t announce = s->announce_window; gpr_slice_buffer_add(&t->outbuf, grpc_chttp2_window_update_create( @@ -156,7 +168,7 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, send_bytes); if (is_last_frame) { s->send_trailing_metadata = NULL; - s->sent_trailing_metadata = 1; + s->sent_trailing_metadata = true; } s->sending_bytes += send_bytes; now_writing = true; -- cgit v1.2.3 From b38f6d618c29d00514de3cd652c1655e65fdb4be Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 29 Aug 2016 12:31:25 -0700 Subject: Get trailing metadata working again, remove debug spam --- .../ext/transport/chttp2/transport/chttp2_transport.c | 4 ---- src/core/ext/transport/chttp2/transport/writing.c | 17 +---------------- 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index cf2c38f287..3fbfc277e0 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -720,8 +720,6 @@ static void maybe_start_some_streams(grpc_exec_ctx *exec_ctx, #define CLOSURE_BARRIER_FIRST_REF_BIT (1 << 16) static grpc_closure *add_closure_barrier(grpc_closure *closure) { - gpr_log(GPR_DEBUG, "add_closure_barrier[%p]: scratch=%" PRIdPTR, closure, - closure->next_data.scratch); closure->next_data.scratch += CLOSURE_BARRIER_FIRST_REF_BIT; return closure; } @@ -736,8 +734,6 @@ void grpc_chttp2_complete_closure_step(grpc_exec_ctx *exec_ctx, GRPC_ERROR_UNREF(error); return; } - gpr_log(GPR_DEBUG, "complete_closure_step[%p]: scratch=%" PRIdPTR, closure, - closure->next_data.scratch); closure->next_data.scratch -= CLOSURE_BARRIER_FIRST_REF_BIT; if (error != GRPC_ERROR_NONE) { if (closure->error == GRPC_ERROR_NONE) { diff --git a/src/core/ext/transport/chttp2/transport/writing.c b/src/core/ext/transport/chttp2/transport/writing.c index 98c0781ac2..e4cd14d6d5 100644 --- a/src/core/ext/transport/chttp2/transport/writing.c +++ b/src/core/ext/transport/chttp2/transport/writing.c @@ -77,13 +77,6 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, GPR_TIMER_BEGIN("grpc_chttp2_begin_write", 0); - gpr_log( - GPR_DEBUG, - "grpc_chttp2_begin_write: outbuf_len0=%" PRIdPTR - " dirtied_local_settings=%d sent_local_settings=%d qbuf_len=%" PRIdPTR, - t->outbuf.length, t->dirtied_local_settings, t->sent_local_settings, - t->qbuf.length); - if (t->dirtied_local_settings && !t->sent_local_settings) { gpr_slice_buffer_add( &t->outbuf, @@ -116,14 +109,6 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, bool sent_initial_metadata = s->sent_initial_metadata; bool now_writing = false; - gpr_log(GPR_DEBUG, - "grpc_chttp2_begin_write[%d]: sent_initial_metadata=%d " - "send_initial_metadata=%p announce_window=%d fcbuf_len=%" PRIdPTR - " s_win=%" PRId64 " t_win=%" PRId64 " send_trailing_metadata=%p", - s->id, sent_initial_metadata, s->send_initial_metadata, - s->announce_window, s->flow_controlled_buffer.length, - s->outgoing_window, t->outgoing_window, s->send_trailing_metadata); - /* send initial metadata if it's available */ if (!sent_initial_metadata && s->send_initial_metadata) { grpc_chttp2_encode_header(&t->hpack_compressor, s->id, @@ -185,7 +170,7 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, s->fetching_send_message == NULL && s->flow_controlled_buffer.length == 0) { grpc_chttp2_encode_header(&t->hpack_compressor, s->id, - s->send_trailing_metadata, 0, + s->send_trailing_metadata, true, &s->stats.outgoing, &t->outbuf); s->send_trailing_metadata = NULL; s->sent_trailing_metadata = true; -- cgit v1.2.3 From e194ff010691458bc300b59f957e38740bd188c3 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 29 Aug 2016 15:48:41 -0700 Subject: Add transport op debugging, coalesce set_accept_stream & send_goaway calls --- .../transport/chttp2/transport/chttp2_transport.c | 7 ++ src/core/lib/surface/server.c | 9 +-- src/core/lib/transport/transport.h | 1 + src/core/lib/transport/transport_op_string.c | 77 ++++++++++++++++++++++ 4 files changed, 86 insertions(+), 8 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 3fbfc277e0..03b313ff4c 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1095,6 +1095,10 @@ static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t = op->transport_private.args[0]; grpc_error *close_transport = op->disconnect_with_error; + char *msg = grpc_transport_op_string(op); + gpr_log(GPR_DEBUG, "run:%p: %s", t, msg); + gpr_free(msg); + if (op->on_connectivity_state_change != NULL) { grpc_connectivity_state_notify_on_state_change( exec_ctx, &t->channel_callback.state_tracker, op->connectivity_state, @@ -1143,6 +1147,9 @@ static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx, static void perform_transport_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, grpc_transport_op *op) { grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt; + char *msg = grpc_transport_op_string(op); + gpr_log(GPR_DEBUG, "scd:%p: %s", t, msg); + gpr_free(msg); op->transport_private.args[0] = gt; grpc_closure_init(&op->transport_private.closure, perform_transport_op_locked, op); diff --git a/src/core/lib/surface/server.c b/src/core/lib/surface/server.c index fa48764a1c..dbeda55435 100644 --- a/src/core/lib/surface/server.c +++ b/src/core/lib/surface/server.c @@ -279,6 +279,7 @@ static void send_shutdown(grpc_exec_ctx *exec_ctx, grpc_channel *channel, grpc_channel_element *elem; op->send_goaway = send_goaway; + op->set_accept_stream = true; sc->slice = gpr_slice_from_copied_string("Server shutdown"); op->goaway_message = &sc->slice; op->goaway_status = GRPC_STATUS_OK; @@ -438,14 +439,6 @@ static void destroy_channel(grpc_exec_ctx *exec_ctx, channel_data *chand, chand->finish_destroy_channel_closure.cb = finish_destroy_channel; chand->finish_destroy_channel_closure.cb_arg = chand; - grpc_transport_op *op = - grpc_make_transport_op(&chand->finish_destroy_channel_closure); - op->set_accept_stream = true; - grpc_channel_next_op(exec_ctx, - grpc_channel_stack_element( - grpc_channel_get_channel_stack(chand->channel), 0), - op); - if (error != GRPC_ERROR_NONE) { const char *msg = grpc_error_string(error); gpr_log(GPR_INFO, "Disconnected client: %s", msg); diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h index 2c1cc3ee42..fe47fea306 100644 --- a/src/core/lib/transport/transport.h +++ b/src/core/lib/transport/transport.h @@ -251,6 +251,7 @@ void grpc_transport_stream_op_add_close(grpc_transport_stream_op *op, gpr_slice *optional_message); char *grpc_transport_stream_op_string(grpc_transport_stream_op *op); +char *grpc_transport_op_string(grpc_transport_op *op); /* Send a batch of operations on a transport diff --git a/src/core/lib/transport/transport_op_string.c b/src/core/lib/transport/transport_op_string.c index 138591db2a..f4e758f83b 100644 --- a/src/core/lib/transport/transport_op_string.c +++ b/src/core/lib/transport/transport_op_string.c @@ -41,6 +41,7 @@ #include #include #include "src/core/lib/support/string.h" +#include "src/core/lib/transport/connectivity_state.h" /* These routines are here to facilitate debugging - they produce string representations of various transport data structures */ @@ -143,6 +144,82 @@ char *grpc_transport_stream_op_string(grpc_transport_stream_op *op) { return out; } +char *grpc_transport_op_string(grpc_transport_op *op) { + char *tmp; + char *out; + int first = 1; + + gpr_strvec b; + gpr_strvec_init(&b); + + if (op->on_connectivity_state_change != NULL) { + if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); + first = 0; + if (op->connectivity_state != NULL) { + gpr_asprintf(&tmp, "ON_CONNECTIVITY_STATE_CHANGE:p=%p:from=%s", + op->on_connectivity_state_change, + grpc_connectivity_state_name(*op->connectivity_state)); + gpr_strvec_add(&b, tmp); + } else { + gpr_asprintf(&tmp, "ON_CONNECTIVITY_STATE_CHANGE[p=%p]", + op->on_connectivity_state_change); + gpr_strvec_add(&b, tmp); + } + } + + if (op->disconnect_with_error != GRPC_ERROR_NONE) { + if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); + first = 0; + const char *err = grpc_error_string(op->disconnect_with_error); + gpr_asprintf(&tmp, "DISCONNECT:%s", err); + gpr_strvec_add(&b, tmp); + grpc_error_free_string(err); + } + + if (op->send_goaway) { + if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); + first = 0; + char *msg = op->goaway_message == NULL + ? "null" + : gpr_dump_slice(*op->goaway_message, + GPR_DUMP_ASCII | GPR_DUMP_HEX); + gpr_asprintf(&tmp, "SEND_GOAWAY:status=%d:msg=%s", op->goaway_status, msg); + if (op->goaway_message != NULL) gpr_free(msg); + gpr_strvec_add(&b, tmp); + } + + if (op->set_accept_stream) { + if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); + first = 0; + gpr_asprintf(&tmp, "SET_ACCEPT_STREAM:%p(%p,...)", op->set_accept_stream_fn, + op->set_accept_stream_user_data); + gpr_strvec_add(&b, tmp); + } + + if (op->bind_pollset != NULL) { + if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); + first = 0; + gpr_strvec_add(&b, gpr_strdup("BIND_POLLSET")); + } + + if (op->bind_pollset_set != NULL) { + if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); + first = 0; + gpr_strvec_add(&b, gpr_strdup("BIND_POLLSET_SET")); + } + + if (op->send_ping != NULL) { + if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); + first = 0; + gpr_strvec_add(&b, gpr_strdup("SEND_PING")); + } + + out = gpr_strvec_flatten(&b, NULL); + gpr_strvec_destroy(&b); + + return out; +} + void grpc_call_log_op(char *file, int line, gpr_log_severity severity, grpc_call_element *elem, grpc_transport_stream_op *op) { char *str = grpc_transport_stream_op_string(op); -- cgit v1.2.3 From c3e940177cfe8536d5a24fa0a00426c101af30f8 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 29 Aug 2016 16:34:03 -0700 Subject: Improve debug --- src/core/lib/transport/connectivity_state.c | 3 ++- src/core/lib/transport/transport_op_string.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/lib/transport/connectivity_state.c b/src/core/lib/transport/connectivity_state.c index 68d05e3a85..fdb5307814 100644 --- a/src/core/lib/transport/connectivity_state.c +++ b/src/core/lib/transport/connectivity_state.c @@ -180,7 +180,8 @@ void grpc_connectivity_state_set(grpc_exec_ctx *exec_ctx, *w->current = tracker->current_state; tracker->watchers = w->next; if (grpc_connectivity_state_trace) { - gpr_log(GPR_DEBUG, "NOTIFY: %p", w->notify); + gpr_log(GPR_DEBUG, "NOTIFY: %p %s: %p", tracker, tracker->name, + w->notify); } grpc_exec_ctx_sched(exec_ctx, w->notify, GRPC_ERROR_REF(tracker->current_error), NULL); diff --git a/src/core/lib/transport/transport_op_string.c b/src/core/lib/transport/transport_op_string.c index f4e758f83b..8a687d8cd3 100644 --- a/src/core/lib/transport/transport_op_string.c +++ b/src/core/lib/transport/transport_op_string.c @@ -161,7 +161,7 @@ char *grpc_transport_op_string(grpc_transport_op *op) { grpc_connectivity_state_name(*op->connectivity_state)); gpr_strvec_add(&b, tmp); } else { - gpr_asprintf(&tmp, "ON_CONNECTIVITY_STATE_CHANGE[p=%p]", + gpr_asprintf(&tmp, "ON_CONNECTIVITY_STATE_CHANGE:p=%p:unsubscribe", op->on_connectivity_state_change); gpr_strvec_add(&b, tmp); } -- cgit v1.2.3 From 6354286f79cd38f1143071d50d096d1c9263d747 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 30 Aug 2016 10:14:35 -0700 Subject: Fix write buffering --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 03b313ff4c..f375288577 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -949,7 +949,7 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, s->fetching_slice_end_offset = (ssize_t)s->flow_controlled_buffer.length + (ssize_t)len; if (flags & GRPC_WRITE_BUFFER_HINT) { - s->fetched_send_message_length -= 65536; + s->fetching_slice_end_offset -= 65536; } continue_fetching_send_locked(exec_ctx, t, s); if (s->id != 0) { -- cgit v1.2.3 From c8db73c419f61668aac6908835125b1ad0880c76 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 30 Aug 2016 14:00:48 -0700 Subject: expand debug --- .../transport/chttp2/transport/chttp2_transport.c | 88 +++++++++++----------- src/core/ext/transport/chttp2/transport/internal.h | 2 +- .../ext/transport/chttp2/transport/stream_lists.c | 4 +- src/core/ext/transport/chttp2/transport/writing.c | 6 +- src/core/lib/surface/call.c | 8 ++ 5 files changed, 58 insertions(+), 50 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index f375288577..239c2f8f2e 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -720,6 +720,9 @@ static void maybe_start_some_streams(grpc_exec_ctx *exec_ctx, #define CLOSURE_BARRIER_FIRST_REF_BIT (1 << 16) static grpc_closure *add_closure_barrier(grpc_closure *closure) { + gpr_log(GPR_DEBUG, "add_closure_barrier: %p | %" PRIdPTR " -> %" PRIdPTR, + closure, closure->next_data.scratch, + closure->next_data.scratch + CLOSURE_BARRIER_FIRST_REF_BIT); closure->next_data.scratch += CLOSURE_BARRIER_FIRST_REF_BIT; return closure; } @@ -734,6 +737,9 @@ void grpc_chttp2_complete_closure_step(grpc_exec_ctx *exec_ctx, GRPC_ERROR_UNREF(error); return; } + gpr_log(GPR_DEBUG, "complete_closure_step: %p | %" PRIdPTR " -> %" PRIdPTR, + closure, closure->next_data.scratch, + closure->next_data.scratch - CLOSURE_BARRIER_FIRST_REF_BIT); closure->next_data.scratch -= CLOSURE_BARRIER_FIRST_REF_BIT; if (error != GRPC_ERROR_NONE) { if (closure->error == GRPC_ERROR_NONE) { @@ -859,6 +865,11 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, if (on_complete == NULL) { on_complete = grpc_closure_create(do_nothing, NULL); } + + if (grpc_http_trace) { + gpr_log(GPR_DEBUG, " on_complete = %p", on_complete); + } + /* use final_data as a barrier until enqueue time; the inital counter is dropped at the end of this function */ on_complete->next_data.scratch = CLOSURE_BARRIER_FIRST_REF_BIT; @@ -1039,6 +1050,13 @@ static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, GPR_TIMER_BEGIN("perform_stream_op", 0); grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt; grpc_chttp2_stream *s = (grpc_chttp2_stream *)gs; + + if (grpc_http_trace) { + char *str = grpc_transport_stream_op_string(op); + gpr_log(GPR_DEBUG, "perform_stream_op: %s", str); + gpr_free(str); + } + grpc_closure_init(&op->transport_private.closure, perform_stream_op_locked, op); op->transport_private.args[0] = gt; @@ -1961,40 +1979,30 @@ grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( */ static char *format_flowctl_context_var(const char *context, const char *var, - int64_t val, uint32_t id, - char **scope) { - char *underscore_pos; - char *buf; - char *result; + int64_t val, uint32_t id) { + char *name; if (context == NULL) { - *scope = NULL; - gpr_asprintf(&buf, "%s(%" PRId64 ")", var, val); - result = gpr_leftpad(buf, ' ', 60); - gpr_free(buf); - return result; - } - underscore_pos = strchr(context, '_'); - *scope = gpr_strdup(context); - (*scope)[underscore_pos - context] = 0; - if (id != 0) { - char *tmp = *scope; - gpr_asprintf(scope, "%s[%d]", tmp, id); - gpr_free(tmp); - } - gpr_asprintf(&buf, "%s.%s(%" PRId64 ")", underscore_pos + 1, var, val); - result = gpr_leftpad(buf, ' ', 60); - gpr_free(buf); - return result; -} - -static int samestr(char *a, char *b) { - if (a == NULL) { - return b == NULL; - } - if (b == NULL) { - return 0; + name = gpr_strdup(var); + } else if (0 == strcmp(context, "t")) { + GPR_ASSERT(id == 0); + gpr_asprintf(&name, "TRANSPORT:%s", var); + } else if (0 == strcmp(context, "s")) { + GPR_ASSERT(id != 0); + gpr_asprintf(&name, "STREAM[%d]:%s", id, var); + } else { + gpr_asprintf(&name, "BAD_CONTEXT[%s][%d]:%s", context, id, var); } - return 0 == strcmp(a, b); + char *name_fld = gpr_leftpad(name, ' ', 64); + char *value; + gpr_asprintf(&value, "%" PRId64, val); + char *value_fld = gpr_leftpad(value, ' ', 8); + char *result; + gpr_asprintf(&result, "%s %s", name_fld, value_fld); + gpr_free(name); + gpr_free(name_fld); + gpr_free(value); + gpr_free(value_fld); + return result; } void grpc_chttp2_flowctl_trace(const char *file, int line, const char *phase, @@ -2002,26 +2010,18 @@ void grpc_chttp2_flowctl_trace(const char *file, int line, const char *phase, const char *var1, const char *context2, const char *var2, int is_client, uint32_t stream_id, int64_t val1, int64_t val2) { - char *scope1; - char *scope2; char *tmp_phase; - char *tmp_scope1; - char *label1 = - format_flowctl_context_var(context1, var1, val1, stream_id, &scope1); - char *label2 = - format_flowctl_context_var(context2, var2, val2, stream_id, &scope2); + char *label1 = format_flowctl_context_var(context1, var1, val1, stream_id); + char *label2 = format_flowctl_context_var(context2, var2, val2, stream_id); char *clisvr = is_client ? "client" : "server"; char *prefix; tmp_phase = gpr_leftpad(phase, ' ', 8); - tmp_scope1 = gpr_leftpad(scope1, ' ', 11); - gpr_asprintf(&prefix, "FLOW %s: %s %s ", tmp_phase, clisvr, scope1); + gpr_asprintf(&prefix, "FLOW %s: %s ", tmp_phase, clisvr); gpr_free(tmp_phase); - gpr_free(tmp_scope1); switch (op) { case GRPC_CHTTP2_FLOWCTL_MOVE: - GPR_ASSERT(samestr(scope1, scope2)); if (val2 != 0) { gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "%sMOVE %s <- %s giving %" PRId64, prefix, label1, label2, @@ -2046,8 +2046,6 @@ void grpc_chttp2_flowctl_trace(const char *file, int line, const char *phase, break; } - gpr_free(scope1); - gpr_free(scope2); gpr_free(label1); gpr_free(label2); gpr_free(prefix); diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index c599c31162..e684c424a2 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -457,7 +457,7 @@ int grpc_chttp2_list_pop_writable_stream(grpc_chttp2_transport *t, bool grpc_chttp2_list_remove_writable_stream( grpc_chttp2_transport *t, grpc_chttp2_stream *s) GRPC_MUST_USE_RESULT; -void grpc_chttp2_list_add_writing_stream(grpc_chttp2_transport *t, +bool grpc_chttp2_list_add_writing_stream(grpc_chttp2_transport *t, grpc_chttp2_stream *s); int grpc_chttp2_list_have_writing_streams(grpc_chttp2_transport *t); int grpc_chttp2_list_pop_writing_stream(grpc_chttp2_transport *t, diff --git a/src/core/ext/transport/chttp2/transport/stream_lists.c b/src/core/ext/transport/chttp2/transport/stream_lists.c index a6b4a4e1d9..7a42c2a58a 100644 --- a/src/core/ext/transport/chttp2/transport/stream_lists.c +++ b/src/core/ext/transport/chttp2/transport/stream_lists.c @@ -134,9 +134,9 @@ bool grpc_chttp2_list_remove_writable_stream(grpc_chttp2_transport *t, return stream_list_maybe_remove(t, s, GRPC_CHTTP2_LIST_WRITABLE); } -void grpc_chttp2_list_add_writing_stream(grpc_chttp2_transport *t, +bool grpc_chttp2_list_add_writing_stream(grpc_chttp2_transport *t, grpc_chttp2_stream *s) { - GPR_ASSERT(stream_list_add(t, s, GRPC_CHTTP2_LIST_WRITING)); + return stream_list_add(t, s, GRPC_CHTTP2_LIST_WRITING); } int grpc_chttp2_list_have_writing_streams(grpc_chttp2_transport *t) { diff --git a/src/core/ext/transport/chttp2/transport/writing.c b/src/core/ext/transport/chttp2/transport/writing.c index e4cd14d6d5..84e5f634c3 100644 --- a/src/core/ext/transport/chttp2/transport/writing.c +++ b/src/core/ext/transport/chttp2/transport/writing.c @@ -109,6 +109,8 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, bool sent_initial_metadata = s->sent_initial_metadata; bool now_writing = false; + gpr_log(GPR_DEBUG, "W:%d: sim=%d ann=%d fcb_len=%d (t,s)-win=%d,%d", (int)s->id,sent_initial_metadata, (int) s->announce_window, (int)s->flow_controlled_buffer.length, (int)t->outgoing_window,(int)s->outgoing_window); + /* send initial metadata if it's available */ if (!sent_initial_metadata && s->send_initial_metadata) { grpc_chttp2_encode_header(&t->hpack_compressor, s->id, @@ -120,7 +122,7 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, now_writing = true; } /* send any window updates */ - if (s->announce_window > 0 && s->sent_initial_metadata) { + if (s->announce_window > 0 && sent_initial_metadata) { uint32_t announce = s->announce_window; gpr_slice_buffer_add(&t->outbuf, grpc_chttp2_window_update_create( @@ -159,7 +161,7 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, now_writing = true; if (s->flow_controlled_buffer.length > 0) { GRPC_CHTTP2_STREAM_REF(s, "chttp2_writing"); - grpc_chttp2_list_add_writing_stream(t, s); + grpc_chttp2_list_add_writable_stream(t, s); } } else if (t->outgoing_window == 0) { grpc_chttp2_list_add_stalled_by_transport(t, s); diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c index ae9424256c..8ed33bee5f 100644 --- a/src/core/lib/surface/call.c +++ b/src/core/lib/surface/call.c @@ -1197,6 +1197,10 @@ static void receiving_stream_ready(grpc_exec_ctx *exec_ctx, void *bctlp, batch_control *bctl = bctlp; grpc_call *call = bctl->call; + char *msg = grpc_transport_stream_op_string(&bctl->op); + gpr_log(GPR_DEBUG, "receiving_stream_ready: %s", msg); + gpr_free(msg); + gpr_mu_lock(&bctl->call->mu); if (bctl->call->has_initial_md_been_received || error != GRPC_ERROR_NONE || call->receiving_stream == NULL) { @@ -1307,6 +1311,10 @@ static void finish_batch(grpc_exec_ctx *exec_ctx, void *bctlp, grpc_call *child_call; grpc_call *next_child_call; + char *msg = grpc_transport_stream_op_string(&bctl->op); + gpr_log(GPR_DEBUG, "finish_batch: %s", msg); + gpr_free(msg); + GRPC_ERROR_REF(error); gpr_mu_lock(&call->mu); -- cgit v1.2.3 From 8af29b684dcaa313611df12881abeba6aeba1b6b Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 30 Aug 2016 14:35:34 -0700 Subject: Fix flowctl announcements --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 3 +-- src/core/ext/transport/chttp2/transport/internal.h | 7 ------- src/core/ext/transport/chttp2/transport/writing.c | 7 ++++--- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 239c2f8f2e..f774cce690 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1818,8 +1818,7 @@ static void incoming_byte_stream_update_flow_control(grpc_exec_ctx *exec_ctx, add_max_recv_bytes); GRPC_CHTTP2_FLOW_CREDIT_STREAM("op", t, s, incoming_window, add_max_recv_bytes); - GRPC_CHTTP2_FLOW_CREDIT_STREAM("op", t, s, - unannounced_incoming_window_for_writing, + GRPC_CHTTP2_FLOW_CREDIT_STREAM("op", t, s, announce_window, add_max_recv_bytes); grpc_chttp2_become_writable(exec_ctx, t, s, false, "read_incoming_stream"); } diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index e684c424a2..0c218b79de 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -339,13 +339,6 @@ struct grpc_chttp2_stream { As the upper layer offers more bytes, this value increases. As bytes are read, this value decreases. */ uint32_t max_recv_bytes; - /** The number of bytes the upper layer has offered to read but we have - not yet announced to HTTP2 flow control. - As the upper layers offer to read more bytes, this value increases. - As we advertise incoming flow control window, this value decreases. */ - /* TODO(ctiller): remove this, it's equivalent to incoming_window now - uint32_t unannounced_incoming_window_for_parse; */ - uint32_t unannounced_incoming_window_for_writing; /** things the upper layers would like to send */ grpc_metadata_batch *send_initial_metadata; grpc_closure *send_initial_metadata_finished; diff --git a/src/core/ext/transport/chttp2/transport/writing.c b/src/core/ext/transport/chttp2/transport/writing.c index 84e5f634c3..798e668aed 100644 --- a/src/core/ext/transport/chttp2/transport/writing.c +++ b/src/core/ext/transport/chttp2/transport/writing.c @@ -109,7 +109,10 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, bool sent_initial_metadata = s->sent_initial_metadata; bool now_writing = false; - gpr_log(GPR_DEBUG, "W:%d: sim=%d ann=%d fcb_len=%d (t,s)-win=%d,%d", (int)s->id,sent_initial_metadata, (int) s->announce_window, (int)s->flow_controlled_buffer.length, (int)t->outgoing_window,(int)s->outgoing_window); + gpr_log(GPR_DEBUG, "W:%d: sim=%d ann=%d fcb_len=%d (t,s)-win=%d,%d", + (int)s->id, sent_initial_metadata, (int)s->announce_window, + (int)s->flow_controlled_buffer.length, (int)t->outgoing_window, + (int)s->outgoing_window); /* send initial metadata if it's available */ if (!sent_initial_metadata && s->send_initial_metadata) { @@ -128,8 +131,6 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, grpc_chttp2_window_update_create( s->id, s->announce_window, &s->stats.outgoing)); GRPC_CHTTP2_FLOW_DEBIT_STREAM("write", t, s, announce_window, announce); - /* TODO(ctiller): why? */ - s->announce_window = 0; } if (sent_initial_metadata) { /* send any body bytes, if allowed by flow control */ -- cgit v1.2.3 From 259f23c99ea4294fb6870958611582975da2ef2c Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 30 Aug 2016 15:52:49 -0700 Subject: More debug --- src/core/ext/transport/chttp2/transport/writing.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/writing.c b/src/core/ext/transport/chttp2/transport/writing.c index 798e668aed..ecb3e49c98 100644 --- a/src/core/ext/transport/chttp2/transport/writing.c +++ b/src/core/ext/transport/chttp2/transport/writing.c @@ -109,8 +109,9 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, bool sent_initial_metadata = s->sent_initial_metadata; bool now_writing = false; - gpr_log(GPR_DEBUG, "W:%d: sim=%d ann=%d fcb_len=%d (t,s)-win=%d,%d", - (int)s->id, sent_initial_metadata, (int)s->announce_window, + gpr_log(GPR_DEBUG, "W:%d:%s: sim=%d ann=%d fcb_len=%d (t,s)-win=%d,%d", + (int)s->id, t->is_client ? "client" : "server", + sent_initial_metadata, (int)s->announce_window, (int)s->flow_controlled_buffer.length, (int)t->outgoing_window, (int)s->outgoing_window); -- cgit v1.2.3 From b85448407ecfd4e633886fa04bb3f334b5064a47 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 31 Aug 2016 12:58:26 -0700 Subject: Fuzzer found crash --- .../0083d5addbeca55271ed7ef93c8016bf7ca76903 | Bin 0 -> 249 bytes .../07b0bed3226eefac4a84000ec584e4ce06ebf1bf | Bin 0 -> 524 bytes .../07cec5c8d9c856a910c6fb57da2ae954f44beed0 | Bin 0 -> 52 bytes .../0c27c9999302b39bf2256a90b0cdb767fb2b6fe3 | Bin 0 -> 224 bytes .../0d407f099f8418de3dd94bd2146c858a8c6575ad | Bin 0 -> 22 bytes .../0d4d486aa9fd6e9c10cc9ca8967e922cadddb2fe | Bin 0 -> 305 bytes .../0d9ba07b57eb0e076b187c4455f662db085e730b | Bin 0 -> 147 bytes .../0f6b989cec08ef9da603dc83704d85900bd22f1f | Bin 0 -> 326 bytes .../10b25b0726cb6d820165699e5a453691c7a9c343 | Bin 0 -> 51 bytes .../1231c6d007d9e43d169122348363e20d9f25ee93 | Bin 0 -> 136 bytes .../13a9b61e431c20734c19bb36d85883b6a501284e | Bin 0 -> 15 bytes .../1698ec182fad9d973b84615da3a683ecdf2d0b3b | Bin 0 -> 38 bytes .../1859e2ee759e20fe195f67615a1576ce2b7d5bbd | Bin 0 -> 74 bytes .../1a9017db5ad8a9dc6cfe72305da1683a87a73452 | Bin 0 -> 511 bytes .../1bd90335afc9e0a1e6a9296e3cc27c03c1201886 | Bin 0 -> 51 bytes .../1be157b0fc79f0e7e1e05dfa3cbbe1ad71528bc2 | Bin 0 -> 52 bytes .../2185f411bdb1edc610f16ffc86836ae366193e03 | Bin 0 -> 690 bytes .../22661803bd1c7198df4be6e08924ef6a48af9cd4 | Bin 0 -> 760 bytes .../2717067bbc0e9bfc1d90d15cddf6154800a25ec6 | Bin 0 -> 337 bytes .../2825cfc19c9371f4fe70851283c68d49470d4d55 | Bin 0 -> 440 bytes .../29303c16f3afa18c2c0b84e77e587535a705a74c | Bin 0 -> 52 bytes .../2b5eb5aac77af905877bd98ec2c4d746b247abb6 | Bin 0 -> 51 bytes .../2cc43573f271ecd332551c1fb34ebc8645eaefe8 | Bin 0 -> 735 bytes .../2feb41037f5dd34e9f3465a2fbf1a6d355c8ce9d | Bin 0 -> 328 bytes .../300998021c7f743ff49d9cc192343ffd43eb47f2 | Bin 0 -> 147 bytes .../310b2aff5e2ec78b6004630bed39d49f8d13bb21 | Bin 0 -> 37 bytes .../3bb052abecc1b916cc869b9aad29c9dd55a95068 | Bin 0 -> 759 bytes .../3c5fa483ebfabe6e684831ce7c413176bc998c33 | Bin 0 -> 254 bytes .../3c6444b64ace5cd6c145614ad4412382271a6120 | Bin 0 -> 360 bytes .../4045d25f065bb1d70a8b9c3751f7453d4b0625b9 | Bin 0 -> 307 bytes .../407cedf992b14edac6e19f7d440ab73c88e72465 | Bin 0 -> 115 bytes .../411966ea7d9164fc432eeab55a55248ad808bb01 | Bin 0 -> 108 bytes .../415dde26637ed3c0e803111c532a1a9ea9c49092 | Bin 0 -> 53 bytes .../4fc34239f220392581520aa8cebc659daa65a7a6 | Bin 0 -> 135 bytes .../52939682304314f04897deddfbc9c7afa8ee50a9 | Bin 0 -> 747 bytes .../5369926a559827d08bccf264876d592c7cae660d | Bin 0 -> 137 bytes .../53ef530f65b0cff2e338a51b469c224f53b628d7 | Bin 0 -> 51 bytes .../560c1057487e6b0d2d457748c3ad8434423eb263 | Bin 0 -> 222 bytes .../564f203f678fb333c7b1f8f4df79237589ce346d | Bin 0 -> 108 bytes .../56b0ac0636c57838f63415082b3ae2ec7a93f017 | Bin 0 -> 472 bytes .../58bcbd601894835bb3312d2a0bc56f2e0f65984c | Bin 0 -> 57 bytes .../598d346f284bcff26d1de997c4ba5c4794c90b68 | Bin 0 -> 37 bytes .../5c14b48da74ab06b3cc20c4fe355e24f7dd7852a | Bin 0 -> 332 bytes .../5de72e607205dc17a45df703ec4e9b63c36821ec | Bin 0 -> 83 bytes .../5e25cf639ba8ea37543d944f5efa94824c6272ff | Bin 0 -> 217 bytes .../5f247d7b6753f7a8798cf952f49f303c532e017c | Bin 0 -> 135 bytes .../63a1cb41d219394c9bab947202921506f3574ad0 | Bin 0 -> 690 bytes .../650f74738d3961af2d1fe85ad8fc8212ea13cbbf | Bin 0 -> 306 bytes .../65dff388749da6a44926b491cdc555f61d708171 | Bin 0 -> 265 bytes .../676adbb1e5b3f4f9e3cba51d3d4ef963ba4ea7e3 | Bin 0 -> 498 bytes .../67f160446ded73c408f4e5a0665731b642b6edd4 | Bin 0 -> 119 bytes .../6856c7cb02d2ba74a60fd47140f042701dda63b3 | Bin 0 -> 37 bytes .../69e14b73af03e8f2d998cfcf16215f65bf589efb | Bin 0 -> 658 bytes .../77cff7548cafe87410e4a0dde3ba6892b25594d3 | Bin 0 -> 753 bytes .../7beeb19272131701f3a0d1dd633f1b1969899366 | Bin 0 -> 329 bytes .../8b0cf53ac17015fe066002cb3814933df9ee96be | Bin 0 -> 694 bytes .../8b5c4543923da5e468aca1de1ab880aed2ac4451 | Bin 0 -> 119 bytes .../8d9784f85e9662734e180ca8bec2164425ae8a87 | Bin 0 -> 250 bytes .../8e3f138d163022d6e105ab595788f4cfdd9b9db3 | Bin 0 -> 411 bytes .../914464d372dcccf31ed5331293d84121e17616bb | Bin 0 -> 307 bytes .../934a41b5027d1c5cca27ebda57560c38cb9e09ea | Bin 0 -> 120 bytes .../9354652806d96b09c8e7082b1b7d22e7c3fb9f0b | Bin 0 -> 265 bytes .../9398ac1c2b4015792661266a9c84b6d7a68c3155 | Bin 0 -> 148 bytes .../99099024a3f3e389f57cb7b697eb34485846f316 | Bin 0 -> 360 bytes .../998a54dc94ab6e7d6a6066415fb0dd9b52356171 | Bin 0 -> 554 bytes .../a25b31398669b585ccab97bceadc31994de7ead7 | Bin 0 -> 520 bytes .../a39ac9e92b41d1889096ed415b4c2eb1aba6ed50 | Bin 0 -> 104 bytes .../a5c2fdae1a1c0487d00db0eec6e3429b12244b1f | Bin 0 -> 265 bytes .../a649093880c2a2f143f861893eaff5d30be95eb7 | Bin 0 -> 27 bytes .../a8249ebfe91327806446f14a6b2e7d9c8440257f | Bin 0 -> 645 bytes .../a8e306820fb76566b522c23ec68bdce0ad0536f2 | Bin 0 -> 108 bytes .../a97dbb159ef9bc6e39c9c25e04315752e871e739 | Bin 0 -> 401 bytes .../ae448bfe17f9a3a6eff074d4caa9f7261c94d2d5 | Bin 0 -> 110 bytes .../ae8cdc02275a1436bc131bee52a17ee797e2e6c9 | Bin 0 -> 306 bytes .../b10353c265bef989d8909055fd6cd52e49eef3e6 | Bin 0 -> 77 bytes .../b387e46c23912785e6c353ab49b8ea4a92c2c2e5 | Bin 0 -> 37 bytes .../b3cfcd55b0331ab0c931b8c61d4df41464587f10 | Bin 0 -> 120 bytes .../b758f5c019696f33c50895168219c0e6cb04e11d | Bin 0 -> 284 bytes .../b93fd0a15287dd035eac86e547e3ce42183bdb28 | Bin 0 -> 638 bytes .../ba3566735888b53712c6b2e6d52ff5f2197afd6a | Bin 0 -> 83 bytes .../bd275178fd473028a5cedf7d5780b27e809882ee | Bin 0 -> 594 bytes .../c4c53b4727e9e1f040c5d7870639dd3daa184ddb | Bin 0 -> 136 bytes .../c9e2cf8be8a4dc2294020026c62840ef1fb4853b | Bin 0 -> 255 bytes .../caaf9a7751c0eccc34f0fc00a048012ab5ed2f37 | Bin 0 -> 52 bytes .../cb49955601d171fd14c9ac21137b221392c7dab1 | Bin 0 -> 121 bytes .../cbaabef34763f2fd922e67ff5f2ea283347e9823 | Bin 0 -> 253 bytes .../cdd1a4e358ee2396ece54b32c1f0a8d0a2e3f3dc | Bin 0 -> 125 bytes .../cf922d44bf08d223d3ebcd37a7e77d3e43555d08 | Bin 0 -> 254 bytes .../crash-ff53a3d713e83ae945b8dd1782e21f5b51aa649a | Bin 0 -> 747 bytes .../d17e9507af1855fcf9eca78e2d25c8fb2c40a34c | Bin 0 -> 51 bytes .../d46c3dcede830286dd9f4a1ba02a20a0b1430664 | Bin 0 -> 231 bytes .../d4a744ef6dcef5cf08d5289e167b26270d39e9f2 | Bin 0 -> 456 bytes .../d5a85ad91cfde27a96960b2e783d2ee43c50dcb9 | Bin 0 -> 83 bytes .../d88bb0b7ff687af84f33e6af22d3516fcdac5534 | Bin 0 -> 121 bytes .../d895ece988ad4712b87de8aa9bc273eee315e8b8 | Bin 0 -> 222 bytes .../da424090e1b94c5d0e91e26f3f3dd6c4af18fcd5 | Bin 0 -> 159 bytes .../db3a30a6d8e605dd587e51b214c42f68bc43cf19 | Bin 0 -> 51 bytes .../e3d12a2385b75443fe38d989e77c252e1f3cdb6d | Bin 0 -> 257 bytes .../e4f55281c481484bd9edc28fd10df0c2e0f7d546 | Bin 0 -> 360 bytes .../e6c52f2f31db7595d1ecde2939a7390777f15182 | Bin 0 -> 136 bytes .../f09cd3e3a16658174717668e51e7382e491df1da | Bin 0 -> 123 bytes .../f11abb090bae8cdac1f7d9a2e344f2def0e50066 | Bin 0 -> 568 bytes .../f4ae2a2b692bfa83cdde75d007813426e14daef7 | Bin 0 -> 107 bytes .../f5a629c8fd5720236b66a875e96ea22e29c45965 | Bin 0 -> 212 bytes .../f6627c55881fe4f0c8e6999980fb226836e6f5ce | Bin 0 -> 456 bytes .../f7aeceaf0b6d971038a677994b5d080fa0e18011 | Bin 0 -> 134 bytes .../f803c87a92662898e2c8c847787b56d2c31f63b3 | Bin 0 -> 52 bytes .../f89ad475ff51a5a9fe18603df833453bed320f36 | Bin 0 -> 268 bytes .../f9583b3a39c1aecbba6e81d71e7fe9b9519c8b08 | Bin 0 -> 18 bytes .../ffd52d31f9c59a346aa195a683f077dda5ecef6b | Bin 0 -> 59 bytes tools/run_tests/tests.json | 3006 +++++++++++++++++--- 111 files changed, 2548 insertions(+), 458 deletions(-) create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/0083d5addbeca55271ed7ef93c8016bf7ca76903 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/07b0bed3226eefac4a84000ec584e4ce06ebf1bf create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/07cec5c8d9c856a910c6fb57da2ae954f44beed0 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/0c27c9999302b39bf2256a90b0cdb767fb2b6fe3 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/0d407f099f8418de3dd94bd2146c858a8c6575ad create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/0d4d486aa9fd6e9c10cc9ca8967e922cadddb2fe create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/0d9ba07b57eb0e076b187c4455f662db085e730b create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/0f6b989cec08ef9da603dc83704d85900bd22f1f create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/10b25b0726cb6d820165699e5a453691c7a9c343 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/1231c6d007d9e43d169122348363e20d9f25ee93 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/13a9b61e431c20734c19bb36d85883b6a501284e create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/1698ec182fad9d973b84615da3a683ecdf2d0b3b create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/1859e2ee759e20fe195f67615a1576ce2b7d5bbd create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/1a9017db5ad8a9dc6cfe72305da1683a87a73452 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/1bd90335afc9e0a1e6a9296e3cc27c03c1201886 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/1be157b0fc79f0e7e1e05dfa3cbbe1ad71528bc2 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/2185f411bdb1edc610f16ffc86836ae366193e03 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/22661803bd1c7198df4be6e08924ef6a48af9cd4 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/2717067bbc0e9bfc1d90d15cddf6154800a25ec6 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/2825cfc19c9371f4fe70851283c68d49470d4d55 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/29303c16f3afa18c2c0b84e77e587535a705a74c create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/2b5eb5aac77af905877bd98ec2c4d746b247abb6 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/2cc43573f271ecd332551c1fb34ebc8645eaefe8 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/2feb41037f5dd34e9f3465a2fbf1a6d355c8ce9d create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/300998021c7f743ff49d9cc192343ffd43eb47f2 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/310b2aff5e2ec78b6004630bed39d49f8d13bb21 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/3bb052abecc1b916cc869b9aad29c9dd55a95068 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/3c5fa483ebfabe6e684831ce7c413176bc998c33 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/3c6444b64ace5cd6c145614ad4412382271a6120 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/4045d25f065bb1d70a8b9c3751f7453d4b0625b9 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/407cedf992b14edac6e19f7d440ab73c88e72465 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/411966ea7d9164fc432eeab55a55248ad808bb01 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/415dde26637ed3c0e803111c532a1a9ea9c49092 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/4fc34239f220392581520aa8cebc659daa65a7a6 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/52939682304314f04897deddfbc9c7afa8ee50a9 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/5369926a559827d08bccf264876d592c7cae660d create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/53ef530f65b0cff2e338a51b469c224f53b628d7 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/560c1057487e6b0d2d457748c3ad8434423eb263 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/564f203f678fb333c7b1f8f4df79237589ce346d create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/56b0ac0636c57838f63415082b3ae2ec7a93f017 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/58bcbd601894835bb3312d2a0bc56f2e0f65984c create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/598d346f284bcff26d1de997c4ba5c4794c90b68 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/5c14b48da74ab06b3cc20c4fe355e24f7dd7852a create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/5de72e607205dc17a45df703ec4e9b63c36821ec create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/5e25cf639ba8ea37543d944f5efa94824c6272ff create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/5f247d7b6753f7a8798cf952f49f303c532e017c create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/63a1cb41d219394c9bab947202921506f3574ad0 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/650f74738d3961af2d1fe85ad8fc8212ea13cbbf create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/65dff388749da6a44926b491cdc555f61d708171 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/676adbb1e5b3f4f9e3cba51d3d4ef963ba4ea7e3 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/67f160446ded73c408f4e5a0665731b642b6edd4 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/6856c7cb02d2ba74a60fd47140f042701dda63b3 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/69e14b73af03e8f2d998cfcf16215f65bf589efb create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/77cff7548cafe87410e4a0dde3ba6892b25594d3 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/7beeb19272131701f3a0d1dd633f1b1969899366 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/8b0cf53ac17015fe066002cb3814933df9ee96be create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/8b5c4543923da5e468aca1de1ab880aed2ac4451 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/8d9784f85e9662734e180ca8bec2164425ae8a87 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/8e3f138d163022d6e105ab595788f4cfdd9b9db3 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/914464d372dcccf31ed5331293d84121e17616bb create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/934a41b5027d1c5cca27ebda57560c38cb9e09ea create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/9354652806d96b09c8e7082b1b7d22e7c3fb9f0b create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/9398ac1c2b4015792661266a9c84b6d7a68c3155 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/99099024a3f3e389f57cb7b697eb34485846f316 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/998a54dc94ab6e7d6a6066415fb0dd9b52356171 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/a25b31398669b585ccab97bceadc31994de7ead7 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/a39ac9e92b41d1889096ed415b4c2eb1aba6ed50 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/a5c2fdae1a1c0487d00db0eec6e3429b12244b1f create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/a649093880c2a2f143f861893eaff5d30be95eb7 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/a8249ebfe91327806446f14a6b2e7d9c8440257f create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/a8e306820fb76566b522c23ec68bdce0ad0536f2 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/a97dbb159ef9bc6e39c9c25e04315752e871e739 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/ae448bfe17f9a3a6eff074d4caa9f7261c94d2d5 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/ae8cdc02275a1436bc131bee52a17ee797e2e6c9 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/b10353c265bef989d8909055fd6cd52e49eef3e6 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/b387e46c23912785e6c353ab49b8ea4a92c2c2e5 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/b3cfcd55b0331ab0c931b8c61d4df41464587f10 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/b758f5c019696f33c50895168219c0e6cb04e11d create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/b93fd0a15287dd035eac86e547e3ce42183bdb28 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/ba3566735888b53712c6b2e6d52ff5f2197afd6a create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/bd275178fd473028a5cedf7d5780b27e809882ee create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/c4c53b4727e9e1f040c5d7870639dd3daa184ddb create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/c9e2cf8be8a4dc2294020026c62840ef1fb4853b create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/caaf9a7751c0eccc34f0fc00a048012ab5ed2f37 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/cb49955601d171fd14c9ac21137b221392c7dab1 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/cbaabef34763f2fd922e67ff5f2ea283347e9823 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/cdd1a4e358ee2396ece54b32c1f0a8d0a2e3f3dc create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/cf922d44bf08d223d3ebcd37a7e77d3e43555d08 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/crash-ff53a3d713e83ae945b8dd1782e21f5b51aa649a create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/d17e9507af1855fcf9eca78e2d25c8fb2c40a34c create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/d46c3dcede830286dd9f4a1ba02a20a0b1430664 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/d4a744ef6dcef5cf08d5289e167b26270d39e9f2 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/d5a85ad91cfde27a96960b2e783d2ee43c50dcb9 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/d88bb0b7ff687af84f33e6af22d3516fcdac5534 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/d895ece988ad4712b87de8aa9bc273eee315e8b8 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/da424090e1b94c5d0e91e26f3f3dd6c4af18fcd5 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/db3a30a6d8e605dd587e51b214c42f68bc43cf19 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/e3d12a2385b75443fe38d989e77c252e1f3cdb6d create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/e4f55281c481484bd9edc28fd10df0c2e0f7d546 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/e6c52f2f31db7595d1ecde2939a7390777f15182 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/f09cd3e3a16658174717668e51e7382e491df1da create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/f11abb090bae8cdac1f7d9a2e344f2def0e50066 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/f4ae2a2b692bfa83cdde75d007813426e14daef7 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/f5a629c8fd5720236b66a875e96ea22e29c45965 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/f6627c55881fe4f0c8e6999980fb226836e6f5ce create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/f7aeceaf0b6d971038a677994b5d080fa0e18011 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/f803c87a92662898e2c8c847787b56d2c31f63b3 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/f89ad475ff51a5a9fe18603df833453bed320f36 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/f9583b3a39c1aecbba6e81d71e7fe9b9519c8b08 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/ffd52d31f9c59a346aa195a683f077dda5ecef6b diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/0083d5addbeca55271ed7ef93c8016bf7ca76903 b/test/core/end2end/fuzzers/client_fuzzer_corpus/0083d5addbeca55271ed7ef93c8016bf7ca76903 new file mode 100644 index 0000000000..821d85dbab Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/0083d5addbeca55271ed7ef93c8016bf7ca76903 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/07b0bed3226eefac4a84000ec584e4ce06ebf1bf b/test/core/end2end/fuzzers/client_fuzzer_corpus/07b0bed3226eefac4a84000ec584e4ce06ebf1bf new file mode 100644 index 0000000000..8ba8dfa5b2 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/07b0bed3226eefac4a84000ec584e4ce06ebf1bf differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/07cec5c8d9c856a910c6fb57da2ae954f44beed0 b/test/core/end2end/fuzzers/client_fuzzer_corpus/07cec5c8d9c856a910c6fb57da2ae954f44beed0 new file mode 100644 index 0000000000..28c9554883 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/07cec5c8d9c856a910c6fb57da2ae954f44beed0 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/0c27c9999302b39bf2256a90b0cdb767fb2b6fe3 b/test/core/end2end/fuzzers/client_fuzzer_corpus/0c27c9999302b39bf2256a90b0cdb767fb2b6fe3 new file mode 100644 index 0000000000..a3ecb27778 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/0c27c9999302b39bf2256a90b0cdb767fb2b6fe3 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/0d407f099f8418de3dd94bd2146c858a8c6575ad b/test/core/end2end/fuzzers/client_fuzzer_corpus/0d407f099f8418de3dd94bd2146c858a8c6575ad new file mode 100644 index 0000000000..ad20f50c4d Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/0d407f099f8418de3dd94bd2146c858a8c6575ad differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/0d4d486aa9fd6e9c10cc9ca8967e922cadddb2fe b/test/core/end2end/fuzzers/client_fuzzer_corpus/0d4d486aa9fd6e9c10cc9ca8967e922cadddb2fe new file mode 100644 index 0000000000..fa6d96d68e Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/0d4d486aa9fd6e9c10cc9ca8967e922cadddb2fe differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/0d9ba07b57eb0e076b187c4455f662db085e730b b/test/core/end2end/fuzzers/client_fuzzer_corpus/0d9ba07b57eb0e076b187c4455f662db085e730b new file mode 100644 index 0000000000..bf6ec61c1f Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/0d9ba07b57eb0e076b187c4455f662db085e730b differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/0f6b989cec08ef9da603dc83704d85900bd22f1f b/test/core/end2end/fuzzers/client_fuzzer_corpus/0f6b989cec08ef9da603dc83704d85900bd22f1f new file mode 100644 index 0000000000..6469f3cff8 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/0f6b989cec08ef9da603dc83704d85900bd22f1f differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/10b25b0726cb6d820165699e5a453691c7a9c343 b/test/core/end2end/fuzzers/client_fuzzer_corpus/10b25b0726cb6d820165699e5a453691c7a9c343 new file mode 100644 index 0000000000..bda05de043 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/10b25b0726cb6d820165699e5a453691c7a9c343 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/1231c6d007d9e43d169122348363e20d9f25ee93 b/test/core/end2end/fuzzers/client_fuzzer_corpus/1231c6d007d9e43d169122348363e20d9f25ee93 new file mode 100644 index 0000000000..ed848cb1d9 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/1231c6d007d9e43d169122348363e20d9f25ee93 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/13a9b61e431c20734c19bb36d85883b6a501284e b/test/core/end2end/fuzzers/client_fuzzer_corpus/13a9b61e431c20734c19bb36d85883b6a501284e new file mode 100644 index 0000000000..462273d10c Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/13a9b61e431c20734c19bb36d85883b6a501284e differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/1698ec182fad9d973b84615da3a683ecdf2d0b3b b/test/core/end2end/fuzzers/client_fuzzer_corpus/1698ec182fad9d973b84615da3a683ecdf2d0b3b new file mode 100644 index 0000000000..0c2710f556 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/1698ec182fad9d973b84615da3a683ecdf2d0b3b differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/1859e2ee759e20fe195f67615a1576ce2b7d5bbd b/test/core/end2end/fuzzers/client_fuzzer_corpus/1859e2ee759e20fe195f67615a1576ce2b7d5bbd new file mode 100644 index 0000000000..ed91baf92c Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/1859e2ee759e20fe195f67615a1576ce2b7d5bbd differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/1a9017db5ad8a9dc6cfe72305da1683a87a73452 b/test/core/end2end/fuzzers/client_fuzzer_corpus/1a9017db5ad8a9dc6cfe72305da1683a87a73452 new file mode 100644 index 0000000000..85d4be1674 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/1a9017db5ad8a9dc6cfe72305da1683a87a73452 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/1bd90335afc9e0a1e6a9296e3cc27c03c1201886 b/test/core/end2end/fuzzers/client_fuzzer_corpus/1bd90335afc9e0a1e6a9296e3cc27c03c1201886 new file mode 100644 index 0000000000..f020c9bb6c Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/1bd90335afc9e0a1e6a9296e3cc27c03c1201886 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/1be157b0fc79f0e7e1e05dfa3cbbe1ad71528bc2 b/test/core/end2end/fuzzers/client_fuzzer_corpus/1be157b0fc79f0e7e1e05dfa3cbbe1ad71528bc2 new file mode 100644 index 0000000000..ce32d23274 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/1be157b0fc79f0e7e1e05dfa3cbbe1ad71528bc2 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/2185f411bdb1edc610f16ffc86836ae366193e03 b/test/core/end2end/fuzzers/client_fuzzer_corpus/2185f411bdb1edc610f16ffc86836ae366193e03 new file mode 100644 index 0000000000..0516cfab4b Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/2185f411bdb1edc610f16ffc86836ae366193e03 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/22661803bd1c7198df4be6e08924ef6a48af9cd4 b/test/core/end2end/fuzzers/client_fuzzer_corpus/22661803bd1c7198df4be6e08924ef6a48af9cd4 new file mode 100644 index 0000000000..2443c3b7bb Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/22661803bd1c7198df4be6e08924ef6a48af9cd4 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/2717067bbc0e9bfc1d90d15cddf6154800a25ec6 b/test/core/end2end/fuzzers/client_fuzzer_corpus/2717067bbc0e9bfc1d90d15cddf6154800a25ec6 new file mode 100644 index 0000000000..d0fe18dcd4 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/2717067bbc0e9bfc1d90d15cddf6154800a25ec6 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/2825cfc19c9371f4fe70851283c68d49470d4d55 b/test/core/end2end/fuzzers/client_fuzzer_corpus/2825cfc19c9371f4fe70851283c68d49470d4d55 new file mode 100644 index 0000000000..e1e52b966d Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/2825cfc19c9371f4fe70851283c68d49470d4d55 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/29303c16f3afa18c2c0b84e77e587535a705a74c b/test/core/end2end/fuzzers/client_fuzzer_corpus/29303c16f3afa18c2c0b84e77e587535a705a74c new file mode 100644 index 0000000000..b684106b43 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/29303c16f3afa18c2c0b84e77e587535a705a74c differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/2b5eb5aac77af905877bd98ec2c4d746b247abb6 b/test/core/end2end/fuzzers/client_fuzzer_corpus/2b5eb5aac77af905877bd98ec2c4d746b247abb6 new file mode 100644 index 0000000000..76655ead93 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/2b5eb5aac77af905877bd98ec2c4d746b247abb6 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/2cc43573f271ecd332551c1fb34ebc8645eaefe8 b/test/core/end2end/fuzzers/client_fuzzer_corpus/2cc43573f271ecd332551c1fb34ebc8645eaefe8 new file mode 100644 index 0000000000..25ead66466 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/2cc43573f271ecd332551c1fb34ebc8645eaefe8 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/2feb41037f5dd34e9f3465a2fbf1a6d355c8ce9d b/test/core/end2end/fuzzers/client_fuzzer_corpus/2feb41037f5dd34e9f3465a2fbf1a6d355c8ce9d new file mode 100644 index 0000000000..96146836d1 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/2feb41037f5dd34e9f3465a2fbf1a6d355c8ce9d differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/300998021c7f743ff49d9cc192343ffd43eb47f2 b/test/core/end2end/fuzzers/client_fuzzer_corpus/300998021c7f743ff49d9cc192343ffd43eb47f2 new file mode 100644 index 0000000000..a3276451d2 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/300998021c7f743ff49d9cc192343ffd43eb47f2 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/310b2aff5e2ec78b6004630bed39d49f8d13bb21 b/test/core/end2end/fuzzers/client_fuzzer_corpus/310b2aff5e2ec78b6004630bed39d49f8d13bb21 new file mode 100644 index 0000000000..e48ee019dd Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/310b2aff5e2ec78b6004630bed39d49f8d13bb21 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/3bb052abecc1b916cc869b9aad29c9dd55a95068 b/test/core/end2end/fuzzers/client_fuzzer_corpus/3bb052abecc1b916cc869b9aad29c9dd55a95068 new file mode 100644 index 0000000000..e256230eec Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/3bb052abecc1b916cc869b9aad29c9dd55a95068 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/3c5fa483ebfabe6e684831ce7c413176bc998c33 b/test/core/end2end/fuzzers/client_fuzzer_corpus/3c5fa483ebfabe6e684831ce7c413176bc998c33 new file mode 100644 index 0000000000..82c60ba2bd Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/3c5fa483ebfabe6e684831ce7c413176bc998c33 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/3c6444b64ace5cd6c145614ad4412382271a6120 b/test/core/end2end/fuzzers/client_fuzzer_corpus/3c6444b64ace5cd6c145614ad4412382271a6120 new file mode 100644 index 0000000000..a829aadd0f Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/3c6444b64ace5cd6c145614ad4412382271a6120 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/4045d25f065bb1d70a8b9c3751f7453d4b0625b9 b/test/core/end2end/fuzzers/client_fuzzer_corpus/4045d25f065bb1d70a8b9c3751f7453d4b0625b9 new file mode 100644 index 0000000000..d3d6384e2f Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/4045d25f065bb1d70a8b9c3751f7453d4b0625b9 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/407cedf992b14edac6e19f7d440ab73c88e72465 b/test/core/end2end/fuzzers/client_fuzzer_corpus/407cedf992b14edac6e19f7d440ab73c88e72465 new file mode 100644 index 0000000000..151a983cfc Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/407cedf992b14edac6e19f7d440ab73c88e72465 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/411966ea7d9164fc432eeab55a55248ad808bb01 b/test/core/end2end/fuzzers/client_fuzzer_corpus/411966ea7d9164fc432eeab55a55248ad808bb01 new file mode 100644 index 0000000000..b60637b01f Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/411966ea7d9164fc432eeab55a55248ad808bb01 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/415dde26637ed3c0e803111c532a1a9ea9c49092 b/test/core/end2end/fuzzers/client_fuzzer_corpus/415dde26637ed3c0e803111c532a1a9ea9c49092 new file mode 100644 index 0000000000..2d8b9cf0ae Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/415dde26637ed3c0e803111c532a1a9ea9c49092 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/4fc34239f220392581520aa8cebc659daa65a7a6 b/test/core/end2end/fuzzers/client_fuzzer_corpus/4fc34239f220392581520aa8cebc659daa65a7a6 new file mode 100644 index 0000000000..1ca1c28045 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/4fc34239f220392581520aa8cebc659daa65a7a6 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/52939682304314f04897deddfbc9c7afa8ee50a9 b/test/core/end2end/fuzzers/client_fuzzer_corpus/52939682304314f04897deddfbc9c7afa8ee50a9 new file mode 100644 index 0000000000..27c5ca48cf Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/52939682304314f04897deddfbc9c7afa8ee50a9 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/5369926a559827d08bccf264876d592c7cae660d b/test/core/end2end/fuzzers/client_fuzzer_corpus/5369926a559827d08bccf264876d592c7cae660d new file mode 100644 index 0000000000..9a2c59f5b2 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/5369926a559827d08bccf264876d592c7cae660d differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/53ef530f65b0cff2e338a51b469c224f53b628d7 b/test/core/end2end/fuzzers/client_fuzzer_corpus/53ef530f65b0cff2e338a51b469c224f53b628d7 new file mode 100644 index 0000000000..cd129010da Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/53ef530f65b0cff2e338a51b469c224f53b628d7 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/560c1057487e6b0d2d457748c3ad8434423eb263 b/test/core/end2end/fuzzers/client_fuzzer_corpus/560c1057487e6b0d2d457748c3ad8434423eb263 new file mode 100644 index 0000000000..889056f090 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/560c1057487e6b0d2d457748c3ad8434423eb263 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/564f203f678fb333c7b1f8f4df79237589ce346d b/test/core/end2end/fuzzers/client_fuzzer_corpus/564f203f678fb333c7b1f8f4df79237589ce346d new file mode 100644 index 0000000000..d64ca599df Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/564f203f678fb333c7b1f8f4df79237589ce346d differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/56b0ac0636c57838f63415082b3ae2ec7a93f017 b/test/core/end2end/fuzzers/client_fuzzer_corpus/56b0ac0636c57838f63415082b3ae2ec7a93f017 new file mode 100644 index 0000000000..f997cede3b Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/56b0ac0636c57838f63415082b3ae2ec7a93f017 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/58bcbd601894835bb3312d2a0bc56f2e0f65984c b/test/core/end2end/fuzzers/client_fuzzer_corpus/58bcbd601894835bb3312d2a0bc56f2e0f65984c new file mode 100644 index 0000000000..016a98e9a2 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/58bcbd601894835bb3312d2a0bc56f2e0f65984c differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/598d346f284bcff26d1de997c4ba5c4794c90b68 b/test/core/end2end/fuzzers/client_fuzzer_corpus/598d346f284bcff26d1de997c4ba5c4794c90b68 new file mode 100644 index 0000000000..1230998613 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/598d346f284bcff26d1de997c4ba5c4794c90b68 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/5c14b48da74ab06b3cc20c4fe355e24f7dd7852a b/test/core/end2end/fuzzers/client_fuzzer_corpus/5c14b48da74ab06b3cc20c4fe355e24f7dd7852a new file mode 100644 index 0000000000..c0223af570 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/5c14b48da74ab06b3cc20c4fe355e24f7dd7852a differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/5de72e607205dc17a45df703ec4e9b63c36821ec b/test/core/end2end/fuzzers/client_fuzzer_corpus/5de72e607205dc17a45df703ec4e9b63c36821ec new file mode 100644 index 0000000000..6f50853678 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/5de72e607205dc17a45df703ec4e9b63c36821ec differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/5e25cf639ba8ea37543d944f5efa94824c6272ff b/test/core/end2end/fuzzers/client_fuzzer_corpus/5e25cf639ba8ea37543d944f5efa94824c6272ff new file mode 100644 index 0000000000..33b465f0dc Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/5e25cf639ba8ea37543d944f5efa94824c6272ff differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/5f247d7b6753f7a8798cf952f49f303c532e017c b/test/core/end2end/fuzzers/client_fuzzer_corpus/5f247d7b6753f7a8798cf952f49f303c532e017c new file mode 100644 index 0000000000..922c3ccae1 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/5f247d7b6753f7a8798cf952f49f303c532e017c differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/63a1cb41d219394c9bab947202921506f3574ad0 b/test/core/end2end/fuzzers/client_fuzzer_corpus/63a1cb41d219394c9bab947202921506f3574ad0 new file mode 100644 index 0000000000..417548abdf Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/63a1cb41d219394c9bab947202921506f3574ad0 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/650f74738d3961af2d1fe85ad8fc8212ea13cbbf b/test/core/end2end/fuzzers/client_fuzzer_corpus/650f74738d3961af2d1fe85ad8fc8212ea13cbbf new file mode 100644 index 0000000000..382f3def10 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/650f74738d3961af2d1fe85ad8fc8212ea13cbbf differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/65dff388749da6a44926b491cdc555f61d708171 b/test/core/end2end/fuzzers/client_fuzzer_corpus/65dff388749da6a44926b491cdc555f61d708171 new file mode 100644 index 0000000000..8e35246ba1 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/65dff388749da6a44926b491cdc555f61d708171 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/676adbb1e5b3f4f9e3cba51d3d4ef963ba4ea7e3 b/test/core/end2end/fuzzers/client_fuzzer_corpus/676adbb1e5b3f4f9e3cba51d3d4ef963ba4ea7e3 new file mode 100644 index 0000000000..720dcdbee7 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/676adbb1e5b3f4f9e3cba51d3d4ef963ba4ea7e3 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/67f160446ded73c408f4e5a0665731b642b6edd4 b/test/core/end2end/fuzzers/client_fuzzer_corpus/67f160446ded73c408f4e5a0665731b642b6edd4 new file mode 100644 index 0000000000..cdbee59a60 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/67f160446ded73c408f4e5a0665731b642b6edd4 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/6856c7cb02d2ba74a60fd47140f042701dda63b3 b/test/core/end2end/fuzzers/client_fuzzer_corpus/6856c7cb02d2ba74a60fd47140f042701dda63b3 new file mode 100644 index 0000000000..f2dc196c12 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/6856c7cb02d2ba74a60fd47140f042701dda63b3 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/69e14b73af03e8f2d998cfcf16215f65bf589efb b/test/core/end2end/fuzzers/client_fuzzer_corpus/69e14b73af03e8f2d998cfcf16215f65bf589efb new file mode 100644 index 0000000000..ae23d16630 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/69e14b73af03e8f2d998cfcf16215f65bf589efb differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/77cff7548cafe87410e4a0dde3ba6892b25594d3 b/test/core/end2end/fuzzers/client_fuzzer_corpus/77cff7548cafe87410e4a0dde3ba6892b25594d3 new file mode 100644 index 0000000000..95defaa956 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/77cff7548cafe87410e4a0dde3ba6892b25594d3 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/7beeb19272131701f3a0d1dd633f1b1969899366 b/test/core/end2end/fuzzers/client_fuzzer_corpus/7beeb19272131701f3a0d1dd633f1b1969899366 new file mode 100644 index 0000000000..4293d0cae9 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/7beeb19272131701f3a0d1dd633f1b1969899366 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/8b0cf53ac17015fe066002cb3814933df9ee96be b/test/core/end2end/fuzzers/client_fuzzer_corpus/8b0cf53ac17015fe066002cb3814933df9ee96be new file mode 100644 index 0000000000..ba952ec94c Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/8b0cf53ac17015fe066002cb3814933df9ee96be differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/8b5c4543923da5e468aca1de1ab880aed2ac4451 b/test/core/end2end/fuzzers/client_fuzzer_corpus/8b5c4543923da5e468aca1de1ab880aed2ac4451 new file mode 100644 index 0000000000..7c5cd2b45e Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/8b5c4543923da5e468aca1de1ab880aed2ac4451 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/8d9784f85e9662734e180ca8bec2164425ae8a87 b/test/core/end2end/fuzzers/client_fuzzer_corpus/8d9784f85e9662734e180ca8bec2164425ae8a87 new file mode 100644 index 0000000000..b2ad2b0b59 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/8d9784f85e9662734e180ca8bec2164425ae8a87 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/8e3f138d163022d6e105ab595788f4cfdd9b9db3 b/test/core/end2end/fuzzers/client_fuzzer_corpus/8e3f138d163022d6e105ab595788f4cfdd9b9db3 new file mode 100644 index 0000000000..e10a35c3e1 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/8e3f138d163022d6e105ab595788f4cfdd9b9db3 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/914464d372dcccf31ed5331293d84121e17616bb b/test/core/end2end/fuzzers/client_fuzzer_corpus/914464d372dcccf31ed5331293d84121e17616bb new file mode 100644 index 0000000000..c67d9ded9a Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/914464d372dcccf31ed5331293d84121e17616bb differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/934a41b5027d1c5cca27ebda57560c38cb9e09ea b/test/core/end2end/fuzzers/client_fuzzer_corpus/934a41b5027d1c5cca27ebda57560c38cb9e09ea new file mode 100644 index 0000000000..8ca1a43cfc Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/934a41b5027d1c5cca27ebda57560c38cb9e09ea differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/9354652806d96b09c8e7082b1b7d22e7c3fb9f0b b/test/core/end2end/fuzzers/client_fuzzer_corpus/9354652806d96b09c8e7082b1b7d22e7c3fb9f0b new file mode 100644 index 0000000000..41461a1a6a Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/9354652806d96b09c8e7082b1b7d22e7c3fb9f0b differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/9398ac1c2b4015792661266a9c84b6d7a68c3155 b/test/core/end2end/fuzzers/client_fuzzer_corpus/9398ac1c2b4015792661266a9c84b6d7a68c3155 new file mode 100644 index 0000000000..f9b2aaffb5 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/9398ac1c2b4015792661266a9c84b6d7a68c3155 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/99099024a3f3e389f57cb7b697eb34485846f316 b/test/core/end2end/fuzzers/client_fuzzer_corpus/99099024a3f3e389f57cb7b697eb34485846f316 new file mode 100644 index 0000000000..1721f92dcb Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/99099024a3f3e389f57cb7b697eb34485846f316 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/998a54dc94ab6e7d6a6066415fb0dd9b52356171 b/test/core/end2end/fuzzers/client_fuzzer_corpus/998a54dc94ab6e7d6a6066415fb0dd9b52356171 new file mode 100644 index 0000000000..06ec60a441 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/998a54dc94ab6e7d6a6066415fb0dd9b52356171 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/a25b31398669b585ccab97bceadc31994de7ead7 b/test/core/end2end/fuzzers/client_fuzzer_corpus/a25b31398669b585ccab97bceadc31994de7ead7 new file mode 100644 index 0000000000..9d41026e50 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/a25b31398669b585ccab97bceadc31994de7ead7 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/a39ac9e92b41d1889096ed415b4c2eb1aba6ed50 b/test/core/end2end/fuzzers/client_fuzzer_corpus/a39ac9e92b41d1889096ed415b4c2eb1aba6ed50 new file mode 100644 index 0000000000..be4a64bf24 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/a39ac9e92b41d1889096ed415b4c2eb1aba6ed50 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/a5c2fdae1a1c0487d00db0eec6e3429b12244b1f b/test/core/end2end/fuzzers/client_fuzzer_corpus/a5c2fdae1a1c0487d00db0eec6e3429b12244b1f new file mode 100644 index 0000000000..1c323b71ee Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/a5c2fdae1a1c0487d00db0eec6e3429b12244b1f differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/a649093880c2a2f143f861893eaff5d30be95eb7 b/test/core/end2end/fuzzers/client_fuzzer_corpus/a649093880c2a2f143f861893eaff5d30be95eb7 new file mode 100644 index 0000000000..7b879ac201 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/a649093880c2a2f143f861893eaff5d30be95eb7 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/a8249ebfe91327806446f14a6b2e7d9c8440257f b/test/core/end2end/fuzzers/client_fuzzer_corpus/a8249ebfe91327806446f14a6b2e7d9c8440257f new file mode 100644 index 0000000000..2bdbe51df2 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/a8249ebfe91327806446f14a6b2e7d9c8440257f differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/a8e306820fb76566b522c23ec68bdce0ad0536f2 b/test/core/end2end/fuzzers/client_fuzzer_corpus/a8e306820fb76566b522c23ec68bdce0ad0536f2 new file mode 100644 index 0000000000..3c62087fe3 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/a8e306820fb76566b522c23ec68bdce0ad0536f2 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/a97dbb159ef9bc6e39c9c25e04315752e871e739 b/test/core/end2end/fuzzers/client_fuzzer_corpus/a97dbb159ef9bc6e39c9c25e04315752e871e739 new file mode 100644 index 0000000000..b43e55bde0 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/a97dbb159ef9bc6e39c9c25e04315752e871e739 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/ae448bfe17f9a3a6eff074d4caa9f7261c94d2d5 b/test/core/end2end/fuzzers/client_fuzzer_corpus/ae448bfe17f9a3a6eff074d4caa9f7261c94d2d5 new file mode 100644 index 0000000000..5d16743900 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/ae448bfe17f9a3a6eff074d4caa9f7261c94d2d5 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/ae8cdc02275a1436bc131bee52a17ee797e2e6c9 b/test/core/end2end/fuzzers/client_fuzzer_corpus/ae8cdc02275a1436bc131bee52a17ee797e2e6c9 new file mode 100644 index 0000000000..12c2446a31 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/ae8cdc02275a1436bc131bee52a17ee797e2e6c9 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/b10353c265bef989d8909055fd6cd52e49eef3e6 b/test/core/end2end/fuzzers/client_fuzzer_corpus/b10353c265bef989d8909055fd6cd52e49eef3e6 new file mode 100644 index 0000000000..4f6e5cc089 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/b10353c265bef989d8909055fd6cd52e49eef3e6 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/b387e46c23912785e6c353ab49b8ea4a92c2c2e5 b/test/core/end2end/fuzzers/client_fuzzer_corpus/b387e46c23912785e6c353ab49b8ea4a92c2c2e5 new file mode 100644 index 0000000000..32397f012c Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/b387e46c23912785e6c353ab49b8ea4a92c2c2e5 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/b3cfcd55b0331ab0c931b8c61d4df41464587f10 b/test/core/end2end/fuzzers/client_fuzzer_corpus/b3cfcd55b0331ab0c931b8c61d4df41464587f10 new file mode 100644 index 0000000000..fd118bc92b Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/b3cfcd55b0331ab0c931b8c61d4df41464587f10 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/b758f5c019696f33c50895168219c0e6cb04e11d b/test/core/end2end/fuzzers/client_fuzzer_corpus/b758f5c019696f33c50895168219c0e6cb04e11d new file mode 100644 index 0000000000..6b74b8ac0b Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/b758f5c019696f33c50895168219c0e6cb04e11d differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/b93fd0a15287dd035eac86e547e3ce42183bdb28 b/test/core/end2end/fuzzers/client_fuzzer_corpus/b93fd0a15287dd035eac86e547e3ce42183bdb28 new file mode 100644 index 0000000000..0bb57741bc Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/b93fd0a15287dd035eac86e547e3ce42183bdb28 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/ba3566735888b53712c6b2e6d52ff5f2197afd6a b/test/core/end2end/fuzzers/client_fuzzer_corpus/ba3566735888b53712c6b2e6d52ff5f2197afd6a new file mode 100644 index 0000000000..3d91afed06 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/ba3566735888b53712c6b2e6d52ff5f2197afd6a differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/bd275178fd473028a5cedf7d5780b27e809882ee b/test/core/end2end/fuzzers/client_fuzzer_corpus/bd275178fd473028a5cedf7d5780b27e809882ee new file mode 100644 index 0000000000..eb3276b19d Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/bd275178fd473028a5cedf7d5780b27e809882ee differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/c4c53b4727e9e1f040c5d7870639dd3daa184ddb b/test/core/end2end/fuzzers/client_fuzzer_corpus/c4c53b4727e9e1f040c5d7870639dd3daa184ddb new file mode 100644 index 0000000000..80e75c5c2f Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/c4c53b4727e9e1f040c5d7870639dd3daa184ddb differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/c9e2cf8be8a4dc2294020026c62840ef1fb4853b b/test/core/end2end/fuzzers/client_fuzzer_corpus/c9e2cf8be8a4dc2294020026c62840ef1fb4853b new file mode 100644 index 0000000000..e97dce0ca4 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/c9e2cf8be8a4dc2294020026c62840ef1fb4853b differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/caaf9a7751c0eccc34f0fc00a048012ab5ed2f37 b/test/core/end2end/fuzzers/client_fuzzer_corpus/caaf9a7751c0eccc34f0fc00a048012ab5ed2f37 new file mode 100644 index 0000000000..f2374b706b Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/caaf9a7751c0eccc34f0fc00a048012ab5ed2f37 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/cb49955601d171fd14c9ac21137b221392c7dab1 b/test/core/end2end/fuzzers/client_fuzzer_corpus/cb49955601d171fd14c9ac21137b221392c7dab1 new file mode 100644 index 0000000000..adfce802f7 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/cb49955601d171fd14c9ac21137b221392c7dab1 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/cbaabef34763f2fd922e67ff5f2ea283347e9823 b/test/core/end2end/fuzzers/client_fuzzer_corpus/cbaabef34763f2fd922e67ff5f2ea283347e9823 new file mode 100644 index 0000000000..3a937aee16 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/cbaabef34763f2fd922e67ff5f2ea283347e9823 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/cdd1a4e358ee2396ece54b32c1f0a8d0a2e3f3dc b/test/core/end2end/fuzzers/client_fuzzer_corpus/cdd1a4e358ee2396ece54b32c1f0a8d0a2e3f3dc new file mode 100644 index 0000000000..82466bfe70 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/cdd1a4e358ee2396ece54b32c1f0a8d0a2e3f3dc differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/cf922d44bf08d223d3ebcd37a7e77d3e43555d08 b/test/core/end2end/fuzzers/client_fuzzer_corpus/cf922d44bf08d223d3ebcd37a7e77d3e43555d08 new file mode 100644 index 0000000000..b9399a2c2e Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/cf922d44bf08d223d3ebcd37a7e77d3e43555d08 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/crash-ff53a3d713e83ae945b8dd1782e21f5b51aa649a b/test/core/end2end/fuzzers/client_fuzzer_corpus/crash-ff53a3d713e83ae945b8dd1782e21f5b51aa649a new file mode 100644 index 0000000000..28ad75eaf0 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/crash-ff53a3d713e83ae945b8dd1782e21f5b51aa649a differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/d17e9507af1855fcf9eca78e2d25c8fb2c40a34c b/test/core/end2end/fuzzers/client_fuzzer_corpus/d17e9507af1855fcf9eca78e2d25c8fb2c40a34c new file mode 100644 index 0000000000..b262a2314b Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/d17e9507af1855fcf9eca78e2d25c8fb2c40a34c differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/d46c3dcede830286dd9f4a1ba02a20a0b1430664 b/test/core/end2end/fuzzers/client_fuzzer_corpus/d46c3dcede830286dd9f4a1ba02a20a0b1430664 new file mode 100644 index 0000000000..a11ecbe97a Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/d46c3dcede830286dd9f4a1ba02a20a0b1430664 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/d4a744ef6dcef5cf08d5289e167b26270d39e9f2 b/test/core/end2end/fuzzers/client_fuzzer_corpus/d4a744ef6dcef5cf08d5289e167b26270d39e9f2 new file mode 100644 index 0000000000..462391f6a5 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/d4a744ef6dcef5cf08d5289e167b26270d39e9f2 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/d5a85ad91cfde27a96960b2e783d2ee43c50dcb9 b/test/core/end2end/fuzzers/client_fuzzer_corpus/d5a85ad91cfde27a96960b2e783d2ee43c50dcb9 new file mode 100644 index 0000000000..c187ee3f37 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/d5a85ad91cfde27a96960b2e783d2ee43c50dcb9 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/d88bb0b7ff687af84f33e6af22d3516fcdac5534 b/test/core/end2end/fuzzers/client_fuzzer_corpus/d88bb0b7ff687af84f33e6af22d3516fcdac5534 new file mode 100644 index 0000000000..a64fe176a4 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/d88bb0b7ff687af84f33e6af22d3516fcdac5534 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/d895ece988ad4712b87de8aa9bc273eee315e8b8 b/test/core/end2end/fuzzers/client_fuzzer_corpus/d895ece988ad4712b87de8aa9bc273eee315e8b8 new file mode 100644 index 0000000000..615ac35eb6 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/d895ece988ad4712b87de8aa9bc273eee315e8b8 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/da424090e1b94c5d0e91e26f3f3dd6c4af18fcd5 b/test/core/end2end/fuzzers/client_fuzzer_corpus/da424090e1b94c5d0e91e26f3f3dd6c4af18fcd5 new file mode 100644 index 0000000000..99ae12197c Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/da424090e1b94c5d0e91e26f3f3dd6c4af18fcd5 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/db3a30a6d8e605dd587e51b214c42f68bc43cf19 b/test/core/end2end/fuzzers/client_fuzzer_corpus/db3a30a6d8e605dd587e51b214c42f68bc43cf19 new file mode 100644 index 0000000000..cc05683443 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/db3a30a6d8e605dd587e51b214c42f68bc43cf19 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/e3d12a2385b75443fe38d989e77c252e1f3cdb6d b/test/core/end2end/fuzzers/client_fuzzer_corpus/e3d12a2385b75443fe38d989e77c252e1f3cdb6d new file mode 100644 index 0000000000..1878ff29d8 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/e3d12a2385b75443fe38d989e77c252e1f3cdb6d differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/e4f55281c481484bd9edc28fd10df0c2e0f7d546 b/test/core/end2end/fuzzers/client_fuzzer_corpus/e4f55281c481484bd9edc28fd10df0c2e0f7d546 new file mode 100644 index 0000000000..042b169620 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/e4f55281c481484bd9edc28fd10df0c2e0f7d546 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/e6c52f2f31db7595d1ecde2939a7390777f15182 b/test/core/end2end/fuzzers/client_fuzzer_corpus/e6c52f2f31db7595d1ecde2939a7390777f15182 new file mode 100644 index 0000000000..17fbabe5c6 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/e6c52f2f31db7595d1ecde2939a7390777f15182 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/f09cd3e3a16658174717668e51e7382e491df1da b/test/core/end2end/fuzzers/client_fuzzer_corpus/f09cd3e3a16658174717668e51e7382e491df1da new file mode 100644 index 0000000000..82c3e4f8ce Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/f09cd3e3a16658174717668e51e7382e491df1da differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/f11abb090bae8cdac1f7d9a2e344f2def0e50066 b/test/core/end2end/fuzzers/client_fuzzer_corpus/f11abb090bae8cdac1f7d9a2e344f2def0e50066 new file mode 100644 index 0000000000..2a12fb9270 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/f11abb090bae8cdac1f7d9a2e344f2def0e50066 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/f4ae2a2b692bfa83cdde75d007813426e14daef7 b/test/core/end2end/fuzzers/client_fuzzer_corpus/f4ae2a2b692bfa83cdde75d007813426e14daef7 new file mode 100644 index 0000000000..ea1c77e222 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/f4ae2a2b692bfa83cdde75d007813426e14daef7 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/f5a629c8fd5720236b66a875e96ea22e29c45965 b/test/core/end2end/fuzzers/client_fuzzer_corpus/f5a629c8fd5720236b66a875e96ea22e29c45965 new file mode 100644 index 0000000000..8b2a87709c Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/f5a629c8fd5720236b66a875e96ea22e29c45965 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/f6627c55881fe4f0c8e6999980fb226836e6f5ce b/test/core/end2end/fuzzers/client_fuzzer_corpus/f6627c55881fe4f0c8e6999980fb226836e6f5ce new file mode 100644 index 0000000000..60c8c7589a Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/f6627c55881fe4f0c8e6999980fb226836e6f5ce differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/f7aeceaf0b6d971038a677994b5d080fa0e18011 b/test/core/end2end/fuzzers/client_fuzzer_corpus/f7aeceaf0b6d971038a677994b5d080fa0e18011 new file mode 100644 index 0000000000..a80c5823c5 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/f7aeceaf0b6d971038a677994b5d080fa0e18011 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/f803c87a92662898e2c8c847787b56d2c31f63b3 b/test/core/end2end/fuzzers/client_fuzzer_corpus/f803c87a92662898e2c8c847787b56d2c31f63b3 new file mode 100644 index 0000000000..146a748d13 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/f803c87a92662898e2c8c847787b56d2c31f63b3 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/f89ad475ff51a5a9fe18603df833453bed320f36 b/test/core/end2end/fuzzers/client_fuzzer_corpus/f89ad475ff51a5a9fe18603df833453bed320f36 new file mode 100644 index 0000000000..ae4812d406 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/f89ad475ff51a5a9fe18603df833453bed320f36 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/f9583b3a39c1aecbba6e81d71e7fe9b9519c8b08 b/test/core/end2end/fuzzers/client_fuzzer_corpus/f9583b3a39c1aecbba6e81d71e7fe9b9519c8b08 new file mode 100644 index 0000000000..9018d4d09f Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/f9583b3a39c1aecbba6e81d71e7fe9b9519c8b08 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/ffd52d31f9c59a346aa195a683f077dda5ecef6b b/test/core/end2end/fuzzers/client_fuzzer_corpus/ffd52d31f9c59a346aa195a683f077dda5ecef6b new file mode 100644 index 0000000000..d7e73ad056 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/ffd52d31f9c59a346aa195a683f077dda5ecef6b differ diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json index b0c09ace5b..ef1286a79d 100644 --- a/tools/run_tests/tests.json +++ b/tools/run_tests/tests.json @@ -54858,6 +54858,25 @@ ], "uses_polling": false }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/0083d5addbeca55271ed7ef93c8016bf7ca76903" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, { "args": [ "test/core/end2end/fuzzers/client_fuzzer_corpus/00c8446b230bebbae2b473552b174a06b446337a" @@ -55088,7 +55107,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/08a8a647b6a8f47ae10852322d14832fc15021f1" + "test/core/end2end/fuzzers/client_fuzzer_corpus/07b0bed3226eefac4a84000ec584e4ce06ebf1bf" ], "ci_platforms": [ "linux" @@ -55107,7 +55126,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/0949f4ac376808482be6ab2dcb18a2ecb08d9a52" + "test/core/end2end/fuzzers/client_fuzzer_corpus/07cec5c8d9c856a910c6fb57da2ae954f44beed0" ], "ci_platforms": [ "linux" @@ -55126,7 +55145,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/0b6fa6330bce65dfe7f758bcbfca2a2844dd07a6" + "test/core/end2end/fuzzers/client_fuzzer_corpus/08a8a647b6a8f47ae10852322d14832fc15021f1" ], "ci_platforms": [ "linux" @@ -55145,7 +55164,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/0c30868720d5e1a19ff23c53740749c37a43540d" + "test/core/end2end/fuzzers/client_fuzzer_corpus/0949f4ac376808482be6ab2dcb18a2ecb08d9a52" ], "ci_platforms": [ "linux" @@ -55164,7 +55183,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/0c5e0660ddf5f14af8f3fbcc754a967506994c9b" + "test/core/end2end/fuzzers/client_fuzzer_corpus/0b6fa6330bce65dfe7f758bcbfca2a2844dd07a6" ], "ci_platforms": [ "linux" @@ -55183,7 +55202,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/0c6f2e0a2232788cb20c4f52ffa18d7ab8f0b938" + "test/core/end2end/fuzzers/client_fuzzer_corpus/0c27c9999302b39bf2256a90b0cdb767fb2b6fe3" ], "ci_platforms": [ "linux" @@ -55202,7 +55221,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/0d36da88698737ec1ca7b55b30fe2b2036de7e19" + "test/core/end2end/fuzzers/client_fuzzer_corpus/0c30868720d5e1a19ff23c53740749c37a43540d" ], "ci_platforms": [ "linux" @@ -55221,7 +55240,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/0d8c547f1d261ba07c2648bae009636c17709600" + "test/core/end2end/fuzzers/client_fuzzer_corpus/0c5e0660ddf5f14af8f3fbcc754a967506994c9b" ], "ci_platforms": [ "linux" @@ -55240,7 +55259,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/0dd33527db106a3e84172e8f2189734b00ced4ed" + "test/core/end2end/fuzzers/client_fuzzer_corpus/0c6f2e0a2232788cb20c4f52ffa18d7ab8f0b938" ], "ci_platforms": [ "linux" @@ -55259,7 +55278,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/0e354d89d02c6c5cbba2f140dab7b609bf00793e" + "test/core/end2end/fuzzers/client_fuzzer_corpus/0d36da88698737ec1ca7b55b30fe2b2036de7e19" ], "ci_platforms": [ "linux" @@ -55278,7 +55297,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/0e3a18f0f08dcb9dd174627bc997f74a5c7a1390" + "test/core/end2end/fuzzers/client_fuzzer_corpus/0d407f099f8418de3dd94bd2146c858a8c6575ad" ], "ci_platforms": [ "linux" @@ -55297,7 +55316,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/0f83cbec19c834f534f353f4fce20c0cd88231f5" + "test/core/end2end/fuzzers/client_fuzzer_corpus/0d4d486aa9fd6e9c10cc9ca8967e922cadddb2fe" ], "ci_platforms": [ "linux" @@ -55316,7 +55335,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/0f98d7d56e9a99b97e5dc7eb122ef22e9684077b" + "test/core/end2end/fuzzers/client_fuzzer_corpus/0d8c547f1d261ba07c2648bae009636c17709600" ], "ci_platforms": [ "linux" @@ -55335,7 +55354,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/0fd8859246740606c498755ab00d6147abcfec00" + "test/core/end2end/fuzzers/client_fuzzer_corpus/0d9ba07b57eb0e076b187c4455f662db085e730b" ], "ci_platforms": [ "linux" @@ -55354,7 +55373,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/100bb8f2e6a0b41da13f4edb5c15d4a04e564840" + "test/core/end2end/fuzzers/client_fuzzer_corpus/0dd33527db106a3e84172e8f2189734b00ced4ed" ], "ci_platforms": [ "linux" @@ -55373,7 +55392,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/101305ccd08c7a8bd0c2913c37d3dd0d39d4bb64" + "test/core/end2end/fuzzers/client_fuzzer_corpus/0e354d89d02c6c5cbba2f140dab7b609bf00793e" ], "ci_platforms": [ "linux" @@ -55392,7 +55411,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/10f5d1937cb068fee7f85e2654be2bfe77498bb9" + "test/core/end2end/fuzzers/client_fuzzer_corpus/0e3a18f0f08dcb9dd174627bc997f74a5c7a1390" ], "ci_platforms": [ "linux" @@ -55411,7 +55430,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/110074f658208166d52897c9266fc46cbaa8af36" + "test/core/end2end/fuzzers/client_fuzzer_corpus/0f6b989cec08ef9da603dc83704d85900bd22f1f" ], "ci_platforms": [ "linux" @@ -55430,7 +55449,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/1160214cdb23e8fc187078a8d6796656c1ade925" + "test/core/end2end/fuzzers/client_fuzzer_corpus/0f83cbec19c834f534f353f4fce20c0cd88231f5" ], "ci_platforms": [ "linux" @@ -55449,7 +55468,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/118ffddb43ccf9dae8bdb4702232d1dc39b021f7" + "test/core/end2end/fuzzers/client_fuzzer_corpus/0f98d7d56e9a99b97e5dc7eb122ef22e9684077b" ], "ci_platforms": [ "linux" @@ -55468,7 +55487,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/1306c4c6ea714d4db0e4d814c944d8d40335e0fa" + "test/core/end2end/fuzzers/client_fuzzer_corpus/0fd8859246740606c498755ab00d6147abcfec00" ], "ci_platforms": [ "linux" @@ -55487,7 +55506,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/1402bbcac6fa24eeb0475250e33f704096e2fb45" + "test/core/end2end/fuzzers/client_fuzzer_corpus/100bb8f2e6a0b41da13f4edb5c15d4a04e564840" ], "ci_platforms": [ "linux" @@ -55506,7 +55525,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/143e0d4f546bbb984a7c3ac1c60a37dcf85ea58d" + "test/core/end2end/fuzzers/client_fuzzer_corpus/101305ccd08c7a8bd0c2913c37d3dd0d39d4bb64" ], "ci_platforms": [ "linux" @@ -55525,7 +55544,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/1526ac4266e152b029b7c283255fe4fb6507f726" + "test/core/end2end/fuzzers/client_fuzzer_corpus/10b25b0726cb6d820165699e5a453691c7a9c343" ], "ci_platforms": [ "linux" @@ -55544,7 +55563,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/1576c915ee38f5bd19f285ed0ed47e36026518f2" + "test/core/end2end/fuzzers/client_fuzzer_corpus/10f5d1937cb068fee7f85e2654be2bfe77498bb9" ], "ci_platforms": [ "linux" @@ -55563,7 +55582,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/15c8bfec99ff18b11211d464c824fc139cc791fd" + "test/core/end2end/fuzzers/client_fuzzer_corpus/110074f658208166d52897c9266fc46cbaa8af36" ], "ci_platforms": [ "linux" @@ -55582,7 +55601,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/1602788cf33d0354d6d48ead549e5137cd211979" + "test/core/end2end/fuzzers/client_fuzzer_corpus/1160214cdb23e8fc187078a8d6796656c1ade925" ], "ci_platforms": [ "linux" @@ -55601,7 +55620,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/169f579e66b4b8ff423891a40380e648e8d45247" + "test/core/end2end/fuzzers/client_fuzzer_corpus/118ffddb43ccf9dae8bdb4702232d1dc39b021f7" ], "ci_platforms": [ "linux" @@ -55620,7 +55639,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/17b1758fc7cd69a00d140f113b1ac894023ff20b" + "test/core/end2end/fuzzers/client_fuzzer_corpus/1231c6d007d9e43d169122348363e20d9f25ee93" ], "ci_platforms": [ "linux" @@ -55639,7 +55658,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/18185cbf9e9cfc1fd28d27ed0d651d7cee6a2c06" + "test/core/end2end/fuzzers/client_fuzzer_corpus/1306c4c6ea714d4db0e4d814c944d8d40335e0fa" ], "ci_platforms": [ "linux" @@ -55658,7 +55677,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/1875a4acdcffe505ca92ea8af8d9d6b174736e80" + "test/core/end2end/fuzzers/client_fuzzer_corpus/13a9b61e431c20734c19bb36d85883b6a501284e" ], "ci_platforms": [ "linux" @@ -55677,7 +55696,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/18850965807039500c7f5450a907e86825cf823d" + "test/core/end2end/fuzzers/client_fuzzer_corpus/1402bbcac6fa24eeb0475250e33f704096e2fb45" ], "ci_platforms": [ "linux" @@ -55696,7 +55715,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/18926cdc608599e8df6b0f4df99d4ad856ef4373" + "test/core/end2end/fuzzers/client_fuzzer_corpus/143e0d4f546bbb984a7c3ac1c60a37dcf85ea58d" ], "ci_platforms": [ "linux" @@ -55715,7 +55734,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/1965cd58fc41578a837231c69075994da2e871d9" + "test/core/end2end/fuzzers/client_fuzzer_corpus/1526ac4266e152b029b7c283255fe4fb6507f726" ], "ci_platforms": [ "linux" @@ -55734,7 +55753,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/19e984af62c36fe982284c87421d8ee46173e9f0" + "test/core/end2end/fuzzers/client_fuzzer_corpus/1576c915ee38f5bd19f285ed0ed47e36026518f2" ], "ci_platforms": [ "linux" @@ -55753,7 +55772,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/1aee32faadffa3c2ec508e8fd30006423665488f" + "test/core/end2end/fuzzers/client_fuzzer_corpus/15c8bfec99ff18b11211d464c824fc139cc791fd" ], "ci_platforms": [ "linux" @@ -55772,7 +55791,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/1ba08b63181066ffab948eb301a6a2363a81872d" + "test/core/end2end/fuzzers/client_fuzzer_corpus/1602788cf33d0354d6d48ead549e5137cd211979" ], "ci_platforms": [ "linux" @@ -55791,7 +55810,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/1c222dae4e2cde1fca9f9bf6226200f70d625342" + "test/core/end2end/fuzzers/client_fuzzer_corpus/1698ec182fad9d973b84615da3a683ecdf2d0b3b" ], "ci_platforms": [ "linux" @@ -55810,7 +55829,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/1ca51ab2fefef4f549c4a8e7f4910c6b5a4b4b1d" + "test/core/end2end/fuzzers/client_fuzzer_corpus/169f579e66b4b8ff423891a40380e648e8d45247" ], "ci_platforms": [ "linux" @@ -55829,7 +55848,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/1cbcaad71950c62d41bab50f9c242d014cc0d904" + "test/core/end2end/fuzzers/client_fuzzer_corpus/17b1758fc7cd69a00d140f113b1ac894023ff20b" ], "ci_platforms": [ "linux" @@ -55848,7 +55867,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/1d19042e6db2a90c52fcc3cb0aa76f2fd335014e" + "test/core/end2end/fuzzers/client_fuzzer_corpus/18185cbf9e9cfc1fd28d27ed0d651d7cee6a2c06" ], "ci_platforms": [ "linux" @@ -55867,7 +55886,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/1d458954e8174bbb5dd4d0053df47d6b7adf290a" + "test/core/end2end/fuzzers/client_fuzzer_corpus/1859e2ee759e20fe195f67615a1576ce2b7d5bbd" ], "ci_platforms": [ "linux" @@ -55886,7 +55905,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/1dc86d0febe4adc5353230cea24b5f7cce829283" + "test/core/end2end/fuzzers/client_fuzzer_corpus/1875a4acdcffe505ca92ea8af8d9d6b174736e80" ], "ci_platforms": [ "linux" @@ -55905,7 +55924,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/1e64080289ea4168304417f3fbd86b01d7d6f431" + "test/core/end2end/fuzzers/client_fuzzer_corpus/18850965807039500c7f5450a907e86825cf823d" ], "ci_platforms": [ "linux" @@ -55924,7 +55943,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/1e84d42fcf18bbf81ef6e8a16a0c57abbf8d292a" + "test/core/end2end/fuzzers/client_fuzzer_corpus/18926cdc608599e8df6b0f4df99d4ad856ef4373" ], "ci_platforms": [ "linux" @@ -55943,7 +55962,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/1f040e756f76357979f317e0c6541f72fd93df06" + "test/core/end2end/fuzzers/client_fuzzer_corpus/1965cd58fc41578a837231c69075994da2e871d9" ], "ci_platforms": [ "linux" @@ -55962,7 +55981,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/1fe7d16ffc2084d5d3c5f23d16902ae8810a5393" + "test/core/end2end/fuzzers/client_fuzzer_corpus/19e984af62c36fe982284c87421d8ee46173e9f0" ], "ci_platforms": [ "linux" @@ -55981,7 +56000,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/1ffc4952225dda41de59603e487ff7fd3026b958" + "test/core/end2end/fuzzers/client_fuzzer_corpus/1a9017db5ad8a9dc6cfe72305da1683a87a73452" ], "ci_platforms": [ "linux" @@ -56000,7 +56019,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/20216d27af2b3dcc83d944e5f7a489ed2eff98fd" + "test/core/end2end/fuzzers/client_fuzzer_corpus/1aee32faadffa3c2ec508e8fd30006423665488f" ], "ci_platforms": [ "linux" @@ -56019,7 +56038,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/204093594b568ada9c7857a971f2a4b42123ee1c" + "test/core/end2end/fuzzers/client_fuzzer_corpus/1ba08b63181066ffab948eb301a6a2363a81872d" ], "ci_platforms": [ "linux" @@ -56038,7 +56057,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/20539e464ced1a0a63d74bae731ca0a75db05967" + "test/core/end2end/fuzzers/client_fuzzer_corpus/1bd90335afc9e0a1e6a9296e3cc27c03c1201886" ], "ci_platforms": [ "linux" @@ -56057,7 +56076,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/205cf2b6994f10b783aa0a06938a5e47cb581126" + "test/core/end2end/fuzzers/client_fuzzer_corpus/1be157b0fc79f0e7e1e05dfa3cbbe1ad71528bc2" ], "ci_platforms": [ "linux" @@ -56076,7 +56095,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/207e12d6a84dc8fa020b3a60b3f75932ca4f8fa5" + "test/core/end2end/fuzzers/client_fuzzer_corpus/1c222dae4e2cde1fca9f9bf6226200f70d625342" ], "ci_platforms": [ "linux" @@ -56095,7 +56114,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/20ea73876cc9cd5b3d3efa1bda21deb5eac2d61e" + "test/core/end2end/fuzzers/client_fuzzer_corpus/1ca51ab2fefef4f549c4a8e7f4910c6b5a4b4b1d" ], "ci_platforms": [ "linux" @@ -56114,7 +56133,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/20ee437b7f456ebb19d98d94d9feb1d5e9174c65" + "test/core/end2end/fuzzers/client_fuzzer_corpus/1cbcaad71950c62d41bab50f9c242d014cc0d904" ], "ci_platforms": [ "linux" @@ -56133,7 +56152,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/2166c7093c424a2136c4cb8b10d0b124047320d4" + "test/core/end2end/fuzzers/client_fuzzer_corpus/1d19042e6db2a90c52fcc3cb0aa76f2fd335014e" ], "ci_platforms": [ "linux" @@ -56152,7 +56171,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/21a6a133f3d1e06c077032ba56a7df4161f62efe" + "test/core/end2end/fuzzers/client_fuzzer_corpus/1d458954e8174bbb5dd4d0053df47d6b7adf290a" ], "ci_platforms": [ "linux" @@ -56171,7 +56190,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/224fa2e83fd8ecaa9059ad37a55238f74b8e0829" + "test/core/end2end/fuzzers/client_fuzzer_corpus/1dc86d0febe4adc5353230cea24b5f7cce829283" ], "ci_platforms": [ "linux" @@ -56190,7 +56209,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/230527b90b0179139c961aca426187893191fdf2" + "test/core/end2end/fuzzers/client_fuzzer_corpus/1e64080289ea4168304417f3fbd86b01d7d6f431" ], "ci_platforms": [ "linux" @@ -56209,7 +56228,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/23e8c1377addaf67019ea36a084e0b68ca7a33db" + "test/core/end2end/fuzzers/client_fuzzer_corpus/1e84d42fcf18bbf81ef6e8a16a0c57abbf8d292a" ], "ci_platforms": [ "linux" @@ -56228,7 +56247,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/2467fa0f8a9f4bd121f544892f0782498b2df533" + "test/core/end2end/fuzzers/client_fuzzer_corpus/1f040e756f76357979f317e0c6541f72fd93df06" ], "ci_platforms": [ "linux" @@ -56247,7 +56266,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/246dcf347eba7f4d4e04d97dabc002f0acf2164e" + "test/core/end2end/fuzzers/client_fuzzer_corpus/1fe7d16ffc2084d5d3c5f23d16902ae8810a5393" ], "ci_platforms": [ "linux" @@ -56266,7 +56285,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/252de25a5237c830ad8c5e4732c176e03785042b" + "test/core/end2end/fuzzers/client_fuzzer_corpus/1ffc4952225dda41de59603e487ff7fd3026b958" ], "ci_platforms": [ "linux" @@ -56285,7 +56304,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/25761748660a64111a8daa46f72ea1f336c2046a" + "test/core/end2end/fuzzers/client_fuzzer_corpus/20216d27af2b3dcc83d944e5f7a489ed2eff98fd" ], "ci_platforms": [ "linux" @@ -56304,7 +56323,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/2585dc7b6c095e978b56e0249fe9b5c61a4840af" + "test/core/end2end/fuzzers/client_fuzzer_corpus/204093594b568ada9c7857a971f2a4b42123ee1c" ], "ci_platforms": [ "linux" @@ -56323,7 +56342,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/25949b623930511f9d43fea4aa56a4389a28e11a" + "test/core/end2end/fuzzers/client_fuzzer_corpus/20539e464ced1a0a63d74bae731ca0a75db05967" ], "ci_platforms": [ "linux" @@ -56342,7 +56361,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/25d2969baf8bd256e15b2ab72707682b2d18b40a" + "test/core/end2end/fuzzers/client_fuzzer_corpus/205cf2b6994f10b783aa0a06938a5e47cb581126" ], "ci_platforms": [ "linux" @@ -56361,7 +56380,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/26110f21dcb0fde99942e631366ebbd9d895860d" + "test/core/end2end/fuzzers/client_fuzzer_corpus/207e12d6a84dc8fa020b3a60b3f75932ca4f8fa5" ], "ci_platforms": [ "linux" @@ -56380,7 +56399,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/2663ce44ca5832381cbbdf7b252e39d6df021a93" + "test/core/end2end/fuzzers/client_fuzzer_corpus/20ea73876cc9cd5b3d3efa1bda21deb5eac2d61e" ], "ci_platforms": [ "linux" @@ -56399,7 +56418,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/269afce3bfff993c05c2a3b28c6cf3dfb3f461d7" + "test/core/end2end/fuzzers/client_fuzzer_corpus/20ee437b7f456ebb19d98d94d9feb1d5e9174c65" ], "ci_platforms": [ "linux" @@ -56418,7 +56437,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/26b8a9d27cef1ce4c3c5aefa2dee50001aab4b13" + "test/core/end2end/fuzzers/client_fuzzer_corpus/2166c7093c424a2136c4cb8b10d0b124047320d4" ], "ci_platforms": [ "linux" @@ -56437,7 +56456,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/27f37037525aac7a41ffbadd6ce52e5a1851a2b7" + "test/core/end2end/fuzzers/client_fuzzer_corpus/2185f411bdb1edc610f16ffc86836ae366193e03" ], "ci_platforms": [ "linux" @@ -56456,7 +56475,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/2862adc802092f1a422416a1666a5142f71d5d7f" + "test/core/end2end/fuzzers/client_fuzzer_corpus/21a6a133f3d1e06c077032ba56a7df4161f62efe" ], "ci_platforms": [ "linux" @@ -56475,7 +56494,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/28680d04887f96a1167dd913573ec8daa2a39625" + "test/core/end2end/fuzzers/client_fuzzer_corpus/224fa2e83fd8ecaa9059ad37a55238f74b8e0829" ], "ci_platforms": [ "linux" @@ -56494,7 +56513,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/289cdf83f89f70a13e9078259f764a339617c827" + "test/core/end2end/fuzzers/client_fuzzer_corpus/22661803bd1c7198df4be6e08924ef6a48af9cd4" ], "ci_platforms": [ "linux" @@ -56513,7 +56532,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/28ee8cae75efa07da9649933a9482d00643b5395" + "test/core/end2end/fuzzers/client_fuzzer_corpus/230527b90b0179139c961aca426187893191fdf2" ], "ci_platforms": [ "linux" @@ -56532,7 +56551,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/28f54e558b181e294e101447c7a79d976fe36fcb" + "test/core/end2end/fuzzers/client_fuzzer_corpus/23e8c1377addaf67019ea36a084e0b68ca7a33db" ], "ci_platforms": [ "linux" @@ -56551,7 +56570,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/299034b9e0cc8d91c049c489dca6d1a2b8b08959" + "test/core/end2end/fuzzers/client_fuzzer_corpus/2467fa0f8a9f4bd121f544892f0782498b2df533" ], "ci_platforms": [ "linux" @@ -56570,7 +56589,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/29952a15459cce9c647255ab5d7486df0507eff4" + "test/core/end2end/fuzzers/client_fuzzer_corpus/246dcf347eba7f4d4e04d97dabc002f0acf2164e" ], "ci_platforms": [ "linux" @@ -56589,7 +56608,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/299faa82b90ef12421d160148dfb6cd0077b57c0" + "test/core/end2end/fuzzers/client_fuzzer_corpus/252de25a5237c830ad8c5e4732c176e03785042b" ], "ci_platforms": [ "linux" @@ -56608,7 +56627,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/29be7d33920998bae7329d77d4c81989eae91647" + "test/core/end2end/fuzzers/client_fuzzer_corpus/25761748660a64111a8daa46f72ea1f336c2046a" ], "ci_platforms": [ "linux" @@ -56627,7 +56646,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/2a8260b23460f90f770cedcafa14868d24db201e" + "test/core/end2end/fuzzers/client_fuzzer_corpus/2585dc7b6c095e978b56e0249fe9b5c61a4840af" ], "ci_platforms": [ "linux" @@ -56646,7 +56665,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/2b230a7b55b17f2f8e89c4be73a662d781f7fb3c" + "test/core/end2end/fuzzers/client_fuzzer_corpus/25949b623930511f9d43fea4aa56a4389a28e11a" ], "ci_platforms": [ "linux" @@ -56665,7 +56684,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/2b71439e9ebf611a92386b9f21ad44bde7926184" + "test/core/end2end/fuzzers/client_fuzzer_corpus/25d2969baf8bd256e15b2ab72707682b2d18b40a" ], "ci_platforms": [ "linux" @@ -56684,7 +56703,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/2c1ecf05c5dde692ed16502294e9570ac3b02600" + "test/core/end2end/fuzzers/client_fuzzer_corpus/26110f21dcb0fde99942e631366ebbd9d895860d" ], "ci_platforms": [ "linux" @@ -56703,7 +56722,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/2c342f8715556398d49bcf3343b5a249d968e19e" + "test/core/end2end/fuzzers/client_fuzzer_corpus/2663ce44ca5832381cbbdf7b252e39d6df021a93" ], "ci_platforms": [ "linux" @@ -56722,7 +56741,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/2c452818a10ddef09b90c89a53db14b9b56b21f3" + "test/core/end2end/fuzzers/client_fuzzer_corpus/269afce3bfff993c05c2a3b28c6cf3dfb3f461d7" ], "ci_platforms": [ "linux" @@ -56741,7 +56760,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/2c6e69067c68c145dc5d3a60b86d8081fdf95d0d" + "test/core/end2end/fuzzers/client_fuzzer_corpus/26b8a9d27cef1ce4c3c5aefa2dee50001aab4b13" ], "ci_platforms": [ "linux" @@ -56760,7 +56779,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/2c79128c697b53256c56b9c57c7259866e0e2347" + "test/core/end2end/fuzzers/client_fuzzer_corpus/2717067bbc0e9bfc1d90d15cddf6154800a25ec6" ], "ci_platforms": [ "linux" @@ -56779,7 +56798,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/2d83097b3cbd2245b085e749fe923fb590790e0c" + "test/core/end2end/fuzzers/client_fuzzer_corpus/27f37037525aac7a41ffbadd6ce52e5a1851a2b7" ], "ci_platforms": [ "linux" @@ -56798,7 +56817,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/2dce4a1fc4bb00bfcd43d549a3785913c9280369" + "test/core/end2end/fuzzers/client_fuzzer_corpus/2825cfc19c9371f4fe70851283c68d49470d4d55" ], "ci_platforms": [ "linux" @@ -56817,7 +56836,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/2deb1aeb93c2abca4177b1fe886eb354c83fe8af" + "test/core/end2end/fuzzers/client_fuzzer_corpus/2862adc802092f1a422416a1666a5142f71d5d7f" ], "ci_platforms": [ "linux" @@ -56836,7 +56855,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/2e9860242d55a74cec244bb5c5445eb2797a3157" + "test/core/end2end/fuzzers/client_fuzzer_corpus/28680d04887f96a1167dd913573ec8daa2a39625" ], "ci_platforms": [ "linux" @@ -56855,7 +56874,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/2f288409c5f3cf2a10b3e1970a9c3d037dabe080" + "test/core/end2end/fuzzers/client_fuzzer_corpus/289cdf83f89f70a13e9078259f764a339617c827" ], "ci_platforms": [ "linux" @@ -56874,7 +56893,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/2f5f6d281a3d0473a04a17cbcbc6fd06cb73fd8b" + "test/core/end2end/fuzzers/client_fuzzer_corpus/28ee8cae75efa07da9649933a9482d00643b5395" ], "ci_platforms": [ "linux" @@ -56893,7 +56912,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/301e10bb6d9f60d91efde4e0c48893203a5b8b88" + "test/core/end2end/fuzzers/client_fuzzer_corpus/28f54e558b181e294e101447c7a79d976fe36fcb" ], "ci_platforms": [ "linux" @@ -56912,7 +56931,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/302a11eb9b9687464b88c9a670da371f6a6c57e7" + "test/core/end2end/fuzzers/client_fuzzer_corpus/29303c16f3afa18c2c0b84e77e587535a705a74c" ], "ci_platforms": [ "linux" @@ -56931,7 +56950,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/3128887b8e02f1873ed6b36766a870543269ea00" + "test/core/end2end/fuzzers/client_fuzzer_corpus/299034b9e0cc8d91c049c489dca6d1a2b8b08959" ], "ci_platforms": [ "linux" @@ -56950,7 +56969,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/31545e9fe4c6aa43329dc0d4a735842574fcaaed" + "test/core/end2end/fuzzers/client_fuzzer_corpus/29952a15459cce9c647255ab5d7486df0507eff4" ], "ci_platforms": [ "linux" @@ -56969,7 +56988,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/31d12a2b1378120d15b4097371d792daa95de0a9" + "test/core/end2end/fuzzers/client_fuzzer_corpus/299faa82b90ef12421d160148dfb6cd0077b57c0" ], "ci_platforms": [ "linux" @@ -56988,7 +57007,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/320dc10f64b59b0eb0ae140912eded1ef9276556" + "test/core/end2end/fuzzers/client_fuzzer_corpus/29be7d33920998bae7329d77d4c81989eae91647" ], "ci_platforms": [ "linux" @@ -57007,7 +57026,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/3336748264594689041e4080b51bc56f716d0689" + "test/core/end2end/fuzzers/client_fuzzer_corpus/2a8260b23460f90f770cedcafa14868d24db201e" ], "ci_platforms": [ "linux" @@ -57026,7 +57045,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/333d0554d91872e693d118d6988132d95b7920ae" + "test/core/end2end/fuzzers/client_fuzzer_corpus/2b230a7b55b17f2f8e89c4be73a662d781f7fb3c" ], "ci_platforms": [ "linux" @@ -57045,7 +57064,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/337d579ab5eb157d7d58e9287d447976062cbd8d" + "test/core/end2end/fuzzers/client_fuzzer_corpus/2b5eb5aac77af905877bd98ec2c4d746b247abb6" ], "ci_platforms": [ "linux" @@ -57064,7 +57083,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/33c32a80db0ec311ee8744991c5b19345bfd8fe9" + "test/core/end2end/fuzzers/client_fuzzer_corpus/2b71439e9ebf611a92386b9f21ad44bde7926184" ], "ci_platforms": [ "linux" @@ -57083,7 +57102,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/35fbd748458e3fd6068957d46a9fbb2b0113d2b3" + "test/core/end2end/fuzzers/client_fuzzer_corpus/2c1ecf05c5dde692ed16502294e9570ac3b02600" ], "ci_platforms": [ "linux" @@ -57102,7 +57121,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/361c6f4374443671f039fd9659577e4460178020" + "test/core/end2end/fuzzers/client_fuzzer_corpus/2c342f8715556398d49bcf3343b5a249d968e19e" ], "ci_platforms": [ "linux" @@ -57121,7 +57140,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/368c75135a7341a96627d0dcfc4b2081003d8979" + "test/core/end2end/fuzzers/client_fuzzer_corpus/2c452818a10ddef09b90c89a53db14b9b56b21f3" ], "ci_platforms": [ "linux" @@ -57140,7 +57159,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/370b2c16cc353621091eda4964d4c4329205ffc3" + "test/core/end2end/fuzzers/client_fuzzer_corpus/2c6e69067c68c145dc5d3a60b86d8081fdf95d0d" ], "ci_platforms": [ "linux" @@ -57159,7 +57178,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/370f893353f792c99754ece93baed2105decd71e" + "test/core/end2end/fuzzers/client_fuzzer_corpus/2c79128c697b53256c56b9c57c7259866e0e2347" ], "ci_platforms": [ "linux" @@ -57178,7 +57197,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/375c2462d6ae891222686f9519294811fa5de010" + "test/core/end2end/fuzzers/client_fuzzer_corpus/2cc43573f271ecd332551c1fb34ebc8645eaefe8" ], "ci_platforms": [ "linux" @@ -57197,7 +57216,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/379b177d55b1eb86ddb66dc3a037fd8283ee07c0" + "test/core/end2end/fuzzers/client_fuzzer_corpus/2d83097b3cbd2245b085e749fe923fb590790e0c" ], "ci_platforms": [ "linux" @@ -57216,7 +57235,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/3a01c85934363bd2067f76d0d40c491f9f846c8a" + "test/core/end2end/fuzzers/client_fuzzer_corpus/2dce4a1fc4bb00bfcd43d549a3785913c9280369" ], "ci_platforms": [ "linux" @@ -57235,7 +57254,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/3a3eb65d51f30f4cd16cc6f8436a5b00702a5712" + "test/core/end2end/fuzzers/client_fuzzer_corpus/2deb1aeb93c2abca4177b1fe886eb354c83fe8af" ], "ci_platforms": [ "linux" @@ -57254,7 +57273,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/3ae87e3150628c422ada13002b08f2d9c5a9d78e" + "test/core/end2end/fuzzers/client_fuzzer_corpus/2e9860242d55a74cec244bb5c5445eb2797a3157" ], "ci_platforms": [ "linux" @@ -57273,7 +57292,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/3afbc4c35885b79c6e6628afce93ce852d7767de" + "test/core/end2end/fuzzers/client_fuzzer_corpus/2f288409c5f3cf2a10b3e1970a9c3d037dabe080" ], "ci_platforms": [ "linux" @@ -57292,7 +57311,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/3b3b4f9a985ec49f6c54bae798208625e5adb777" + "test/core/end2end/fuzzers/client_fuzzer_corpus/2f5f6d281a3d0473a04a17cbcbc6fd06cb73fd8b" ], "ci_platforms": [ "linux" @@ -57311,7 +57330,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/3c01b1f89d50fa37fcb3457cd3dd6502fe84e25b" + "test/core/end2end/fuzzers/client_fuzzer_corpus/2feb41037f5dd34e9f3465a2fbf1a6d355c8ce9d" ], "ci_platforms": [ "linux" @@ -57330,7 +57349,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/3c7b516e302ad3503a933b5dcfb8c58acaea07a0" + "test/core/end2end/fuzzers/client_fuzzer_corpus/300998021c7f743ff49d9cc192343ffd43eb47f2" ], "ci_platforms": [ "linux" @@ -57349,7 +57368,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/3d4d961511c1de95a81b129f2fe96390209de2e7" + "test/core/end2end/fuzzers/client_fuzzer_corpus/301e10bb6d9f60d91efde4e0c48893203a5b8b88" ], "ci_platforms": [ "linux" @@ -57368,7 +57387,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/3da7577acd806e1d92d48211b22fd9db352fd834" + "test/core/end2end/fuzzers/client_fuzzer_corpus/302a11eb9b9687464b88c9a670da371f6a6c57e7" ], "ci_platforms": [ "linux" @@ -57387,7 +57406,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/3e8f531043a07df2280bca73fe4a7987d82ce67e" + "test/core/end2end/fuzzers/client_fuzzer_corpus/310b2aff5e2ec78b6004630bed39d49f8d13bb21" ], "ci_platforms": [ "linux" @@ -57406,7 +57425,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/3fcc2da89f438b247cb5b4b41e15aceccfa75b36" + "test/core/end2end/fuzzers/client_fuzzer_corpus/3128887b8e02f1873ed6b36766a870543269ea00" ], "ci_platforms": [ "linux" @@ -57425,7 +57444,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/4040224f3df361afe45bce682d56d26f13829413" + "test/core/end2end/fuzzers/client_fuzzer_corpus/31545e9fe4c6aa43329dc0d4a735842574fcaaed" ], "ci_platforms": [ "linux" @@ -57444,7 +57463,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/4097094277bc09981f428280fc0cc0f590f20ded" + "test/core/end2end/fuzzers/client_fuzzer_corpus/31d12a2b1378120d15b4097371d792daa95de0a9" ], "ci_platforms": [ "linux" @@ -57463,7 +57482,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/41aad2f11a7ab418213352e84de872d9997db8d2" + "test/core/end2end/fuzzers/client_fuzzer_corpus/320dc10f64b59b0eb0ae140912eded1ef9276556" ], "ci_platforms": [ "linux" @@ -57482,7 +57501,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/41b499e86caed7b48c59aaaf51360c3c71029400" + "test/core/end2end/fuzzers/client_fuzzer_corpus/3336748264594689041e4080b51bc56f716d0689" ], "ci_platforms": [ "linux" @@ -57501,7 +57520,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/42554ddbe59429d30d718282ca606ed8b5a90eb3" + "test/core/end2end/fuzzers/client_fuzzer_corpus/333d0554d91872e693d118d6988132d95b7920ae" ], "ci_platforms": [ "linux" @@ -57520,7 +57539,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/42c395ab373346fb283ace021bdc1f6428f92f80" + "test/core/end2end/fuzzers/client_fuzzer_corpus/337d579ab5eb157d7d58e9287d447976062cbd8d" ], "ci_platforms": [ "linux" @@ -57539,7 +57558,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/42ead79c94eccdf8a8c3d8036be73e14fa260dd5" + "test/core/end2end/fuzzers/client_fuzzer_corpus/33c32a80db0ec311ee8744991c5b19345bfd8fe9" ], "ci_platforms": [ "linux" @@ -57558,7 +57577,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/43202ad9b1a689d919ab9ae91c2d0223394867bf" + "test/core/end2end/fuzzers/client_fuzzer_corpus/35fbd748458e3fd6068957d46a9fbb2b0113d2b3" ], "ci_platforms": [ "linux" @@ -57577,7 +57596,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/438789ebe8a5d676f6f03ef8329c3d77579aeba4" + "test/core/end2end/fuzzers/client_fuzzer_corpus/361c6f4374443671f039fd9659577e4460178020" ], "ci_platforms": [ "linux" @@ -57596,7 +57615,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/44153f8b7af5a3b27625a46af89e1712daa3ae8a" + "test/core/end2end/fuzzers/client_fuzzer_corpus/368c75135a7341a96627d0dcfc4b2081003d8979" ], "ci_platforms": [ "linux" @@ -57615,7 +57634,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/44b6be630161765a3de5872629602ca14789c3bd" + "test/core/end2end/fuzzers/client_fuzzer_corpus/370b2c16cc353621091eda4964d4c4329205ffc3" ], "ci_platforms": [ "linux" @@ -57634,7 +57653,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/44d64196fb2e8d9506734a81304f6ef17b9bc29d" + "test/core/end2end/fuzzers/client_fuzzer_corpus/370f893353f792c99754ece93baed2105decd71e" ], "ci_platforms": [ "linux" @@ -57653,7 +57672,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/44f0973ec77d6fb9eac931e84fa7ec6fdadccca6" + "test/core/end2end/fuzzers/client_fuzzer_corpus/375c2462d6ae891222686f9519294811fa5de010" ], "ci_platforms": [ "linux" @@ -57672,7 +57691,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/450f9f56c80c8b71e37302a254ba7c3f7298dfd7" + "test/core/end2end/fuzzers/client_fuzzer_corpus/379b177d55b1eb86ddb66dc3a037fd8283ee07c0" ], "ci_platforms": [ "linux" @@ -57691,7 +57710,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/451e69ab65e0fe0a5731622ed21ab2b5380df677" + "test/core/end2end/fuzzers/client_fuzzer_corpus/3a01c85934363bd2067f76d0d40c491f9f846c8a" ], "ci_platforms": [ "linux" @@ -57710,7 +57729,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/46dcb1c399e5a514267fbbd5a50939f34e0ad6be" + "test/core/end2end/fuzzers/client_fuzzer_corpus/3a3eb65d51f30f4cd16cc6f8436a5b00702a5712" ], "ci_platforms": [ "linux" @@ -57729,7 +57748,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/47e8aee44c2c7bd870f15b50fc085c5a8030edfc" + "test/core/end2end/fuzzers/client_fuzzer_corpus/3ae87e3150628c422ada13002b08f2d9c5a9d78e" ], "ci_platforms": [ "linux" @@ -57748,7 +57767,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/489e9830136adcc53f4b191199c33504685b3737" + "test/core/end2end/fuzzers/client_fuzzer_corpus/3afbc4c35885b79c6e6628afce93ce852d7767de" ], "ci_platforms": [ "linux" @@ -57767,7 +57786,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/49112bf1277d93601eb6526fe9ee9d45864d759e" + "test/core/end2end/fuzzers/client_fuzzer_corpus/3b3b4f9a985ec49f6c54bae798208625e5adb777" ], "ci_platforms": [ "linux" @@ -57786,7 +57805,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/49c5568cb0de363bc9f9298f1eacaace6c8a268a" + "test/core/end2end/fuzzers/client_fuzzer_corpus/3bb052abecc1b916cc869b9aad29c9dd55a95068" ], "ci_platforms": [ "linux" @@ -57805,7 +57824,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/4a11af9ef42aeb36691185520be281c4760ad27b" + "test/core/end2end/fuzzers/client_fuzzer_corpus/3c01b1f89d50fa37fcb3457cd3dd6502fe84e25b" ], "ci_platforms": [ "linux" @@ -57824,7 +57843,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/4a4553c2e939cd50981bc38e8ddb1f2109ddb3a4" + "test/core/end2end/fuzzers/client_fuzzer_corpus/3c5fa483ebfabe6e684831ce7c413176bc998c33" ], "ci_platforms": [ "linux" @@ -57843,7 +57862,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/4b2ce115b15082ed951f4dc0b432da6a9d37bf85" + "test/core/end2end/fuzzers/client_fuzzer_corpus/3c6444b64ace5cd6c145614ad4412382271a6120" ], "ci_platforms": [ "linux" @@ -57862,7 +57881,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/4b585eb75ebca2187c0aa5a6abe4c8125aa80127" + "test/core/end2end/fuzzers/client_fuzzer_corpus/3c7b516e302ad3503a933b5dcfb8c58acaea07a0" ], "ci_platforms": [ "linux" @@ -57881,7 +57900,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/4b611a3748757e2fa89fcd2fb22d34444fbf5b42" + "test/core/end2end/fuzzers/client_fuzzer_corpus/3d4d961511c1de95a81b129f2fe96390209de2e7" ], "ci_platforms": [ "linux" @@ -57900,7 +57919,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/4e05d6cf1c3f0c04f6ee92d09a53ee0fe35c085a" + "test/core/end2end/fuzzers/client_fuzzer_corpus/3da7577acd806e1d92d48211b22fd9db352fd834" ], "ci_platforms": [ "linux" @@ -57919,7 +57938,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/4e21c4b5c454df51c102f09ea1ba78c42133ee16" + "test/core/end2end/fuzzers/client_fuzzer_corpus/3e8f531043a07df2280bca73fe4a7987d82ce67e" ], "ci_platforms": [ "linux" @@ -57938,7 +57957,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/4eaff3c3515a1ca019d46b9be0b7318eaffb63d1" + "test/core/end2end/fuzzers/client_fuzzer_corpus/3fcc2da89f438b247cb5b4b41e15aceccfa75b36" ], "ci_platforms": [ "linux" @@ -57957,7 +57976,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/4ec113a0126fc5746fa3f955727d009040e8377f" + "test/core/end2end/fuzzers/client_fuzzer_corpus/4040224f3df361afe45bce682d56d26f13829413" ], "ci_platforms": [ "linux" @@ -57976,7 +57995,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/4f5b9d5c707a35084918c272efd1295d301ca0b5" + "test/core/end2end/fuzzers/client_fuzzer_corpus/4045d25f065bb1d70a8b9c3751f7453d4b0625b9" ], "ci_platforms": [ "linux" @@ -57995,7 +58014,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/4f8b5b7489cca36225acec0f9aa7f5c556d79d8d" + "test/core/end2end/fuzzers/client_fuzzer_corpus/407cedf992b14edac6e19f7d440ab73c88e72465" ], "ci_platforms": [ "linux" @@ -58014,7 +58033,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/50ece7ea16659b4e1a2284cea963fab662c19e6b" + "test/core/end2end/fuzzers/client_fuzzer_corpus/4097094277bc09981f428280fc0cc0f590f20ded" ], "ci_platforms": [ "linux" @@ -58033,7 +58052,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/514c9cd7b6519b596900d924ff2caa173d688f4b" + "test/core/end2end/fuzzers/client_fuzzer_corpus/411966ea7d9164fc432eeab55a55248ad808bb01" ], "ci_platforms": [ "linux" @@ -58052,7 +58071,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/51c6c5297acebf9d21a8a7d6261d0a17c2adfb56" + "test/core/end2end/fuzzers/client_fuzzer_corpus/415dde26637ed3c0e803111c532a1a9ea9c49092" ], "ci_platforms": [ "linux" @@ -58071,7 +58090,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/52c00bde7f4af95a86deb0a6717d1faf2828a939" + "test/core/end2end/fuzzers/client_fuzzer_corpus/41aad2f11a7ab418213352e84de872d9997db8d2" ], "ci_platforms": [ "linux" @@ -58090,7 +58109,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/534c900ade27c8f7fccb1f3b7e7703f77f13a8f5" + "test/core/end2end/fuzzers/client_fuzzer_corpus/41b499e86caed7b48c59aaaf51360c3c71029400" ], "ci_platforms": [ "linux" @@ -58109,7 +58128,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/5360327e8bc8969f31b364df3081b51a1e03900c" + "test/core/end2end/fuzzers/client_fuzzer_corpus/42554ddbe59429d30d718282ca606ed8b5a90eb3" ], "ci_platforms": [ "linux" @@ -58128,7 +58147,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/542c958c84d1e319b9ba23c52de2c4bca08a8dc7" + "test/core/end2end/fuzzers/client_fuzzer_corpus/42c395ab373346fb283ace021bdc1f6428f92f80" ], "ci_platforms": [ "linux" @@ -58147,7 +58166,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/54555ceac4403855f4cf20367f7be05714c46c51" + "test/core/end2end/fuzzers/client_fuzzer_corpus/42ead79c94eccdf8a8c3d8036be73e14fa260dd5" ], "ci_platforms": [ "linux" @@ -58166,7 +58185,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/5482dc4af170def9c183315efaa48f9c186926a1" + "test/core/end2end/fuzzers/client_fuzzer_corpus/43202ad9b1a689d919ab9ae91c2d0223394867bf" ], "ci_platforms": [ "linux" @@ -58185,7 +58204,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/54e67ed1036f3f5b315e0e3c02948c30eba900fd" + "test/core/end2end/fuzzers/client_fuzzer_corpus/438789ebe8a5d676f6f03ef8329c3d77579aeba4" ], "ci_platforms": [ "linux" @@ -58204,7 +58223,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/55ca8f6d9928c239a7abb32554463e6e1e1ee084" + "test/core/end2end/fuzzers/client_fuzzer_corpus/44153f8b7af5a3b27625a46af89e1712daa3ae8a" ], "ci_platforms": [ "linux" @@ -58223,7 +58242,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/570ca8d2555dde94aa3b3121e8f5256e83eabe5e" + "test/core/end2end/fuzzers/client_fuzzer_corpus/44b6be630161765a3de5872629602ca14789c3bd" ], "ci_platforms": [ "linux" @@ -58242,7 +58261,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/57ee6efc38f4c544a3ea3e5e73987e825bdf2980" + "test/core/end2end/fuzzers/client_fuzzer_corpus/44d64196fb2e8d9506734a81304f6ef17b9bc29d" ], "ci_platforms": [ "linux" @@ -58261,7 +58280,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/5821752bf8923fdaebc8484662624d8acd382716" + "test/core/end2end/fuzzers/client_fuzzer_corpus/44f0973ec77d6fb9eac931e84fa7ec6fdadccca6" ], "ci_platforms": [ "linux" @@ -58280,7 +58299,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/58a067ec6eda7191a5a910d8120633271d3af074" + "test/core/end2end/fuzzers/client_fuzzer_corpus/450f9f56c80c8b71e37302a254ba7c3f7298dfd7" ], "ci_platforms": [ "linux" @@ -58299,7 +58318,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/58d6dffb65a1fe1bc4e3fa970a15459587a32f77" + "test/core/end2end/fuzzers/client_fuzzer_corpus/451e69ab65e0fe0a5731622ed21ab2b5380df677" ], "ci_platforms": [ "linux" @@ -58318,7 +58337,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/591ef436ef8cc982b48fd827a4555b57cd9780e5" + "test/core/end2end/fuzzers/client_fuzzer_corpus/46dcb1c399e5a514267fbbd5a50939f34e0ad6be" ], "ci_platforms": [ "linux" @@ -58337,7 +58356,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/59d28886db21f371ac9d999b68b116bcf425d971" + "test/core/end2end/fuzzers/client_fuzzer_corpus/47e8aee44c2c7bd870f15b50fc085c5a8030edfc" ], "ci_platforms": [ "linux" @@ -58356,7 +58375,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/59d78f6397f0483d139f5bd0a9f264156f34acc4" + "test/core/end2end/fuzzers/client_fuzzer_corpus/489e9830136adcc53f4b191199c33504685b3737" ], "ci_platforms": [ "linux" @@ -58375,7 +58394,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/5a2447fdfdbf123f4592c1284007b7d50a01750b" + "test/core/end2end/fuzzers/client_fuzzer_corpus/49112bf1277d93601eb6526fe9ee9d45864d759e" ], "ci_platforms": [ "linux" @@ -58394,7 +58413,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/5ca233a53e3e425cc12e04b466a49789291eaa00" + "test/core/end2end/fuzzers/client_fuzzer_corpus/49c5568cb0de363bc9f9298f1eacaace6c8a268a" ], "ci_platforms": [ "linux" @@ -58413,7 +58432,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/5dc7b2086a39f56d8b9135f524d34a01fcabafd8" + "test/core/end2end/fuzzers/client_fuzzer_corpus/4a11af9ef42aeb36691185520be281c4760ad27b" ], "ci_platforms": [ "linux" @@ -58432,7 +58451,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/5e1659e7cd840ab3f958273ebffdd215f2c81da6" + "test/core/end2end/fuzzers/client_fuzzer_corpus/4a4553c2e939cd50981bc38e8ddb1f2109ddb3a4" ], "ci_platforms": [ "linux" @@ -58451,7 +58470,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/605e474e9d9436488dfe084d348908e4dfab81a3" + "test/core/end2end/fuzzers/client_fuzzer_corpus/4b2ce115b15082ed951f4dc0b432da6a9d37bf85" ], "ci_platforms": [ "linux" @@ -58470,7 +58489,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/6066fc9e28b4ce704230f0e8cf21e7c3195aa2a3" + "test/core/end2end/fuzzers/client_fuzzer_corpus/4b585eb75ebca2187c0aa5a6abe4c8125aa80127" ], "ci_platforms": [ "linux" @@ -58489,7 +58508,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/607dac8012f188cb035b189fc3637028137023e0" + "test/core/end2end/fuzzers/client_fuzzer_corpus/4b611a3748757e2fa89fcd2fb22d34444fbf5b42" ], "ci_platforms": [ "linux" @@ -58508,7 +58527,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/611343a6b8879b393ba2f38ed41c7f5355355920" + "test/core/end2end/fuzzers/client_fuzzer_corpus/4e05d6cf1c3f0c04f6ee92d09a53ee0fe35c085a" ], "ci_platforms": [ "linux" @@ -58527,7 +58546,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/62c843359941660da3fc9eea62a5732aaa3be283" + "test/core/end2end/fuzzers/client_fuzzer_corpus/4e21c4b5c454df51c102f09ea1ba78c42133ee16" ], "ci_platforms": [ "linux" @@ -58546,7 +58565,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/636a19b8f50c4efccccea83ab78a933d999e41fa" + "test/core/end2end/fuzzers/client_fuzzer_corpus/4eaff3c3515a1ca019d46b9be0b7318eaffb63d1" ], "ci_platforms": [ "linux" @@ -58565,7 +58584,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/64696e93ead18265cdac3fb37dae29ad3be6d764" + "test/core/end2end/fuzzers/client_fuzzer_corpus/4ec113a0126fc5746fa3f955727d009040e8377f" ], "ci_platforms": [ "linux" @@ -58584,7 +58603,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/64c0e0b4d9c2d25fdcb1e2bdcb999487fc096dad" + "test/core/end2end/fuzzers/client_fuzzer_corpus/4f5b9d5c707a35084918c272efd1295d301ca0b5" ], "ci_platforms": [ "linux" @@ -58603,7 +58622,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/64cad305e1858eae27cd723778fb9f4b7052eaa5" + "test/core/end2end/fuzzers/client_fuzzer_corpus/4f8b5b7489cca36225acec0f9aa7f5c556d79d8d" ], "ci_platforms": [ "linux" @@ -58622,7 +58641,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/64d27dc9f984c49d421a5b0cb0391992d5aac1a4" + "test/core/end2end/fuzzers/client_fuzzer_corpus/4fc34239f220392581520aa8cebc659daa65a7a6" ], "ci_platforms": [ "linux" @@ -58641,7 +58660,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/653ec14661c40ea25bdbab4a7cb9371c669d10d9" + "test/core/end2end/fuzzers/client_fuzzer_corpus/50ece7ea16659b4e1a2284cea963fab662c19e6b" ], "ci_platforms": [ "linux" @@ -58660,7 +58679,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/66145518601b1405361df12570f6e0b2b9a2e5b3" + "test/core/end2end/fuzzers/client_fuzzer_corpus/514c9cd7b6519b596900d924ff2caa173d688f4b" ], "ci_platforms": [ "linux" @@ -58679,7 +58698,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/662d81374a2c96f867ccd88a4295190827c45453" + "test/core/end2end/fuzzers/client_fuzzer_corpus/51c6c5297acebf9d21a8a7d6261d0a17c2adfb56" ], "ci_platforms": [ "linux" @@ -58698,7 +58717,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/669256f857011c32f5757ec19b2e5b9a372f6c23" + "test/core/end2end/fuzzers/client_fuzzer_corpus/52939682304314f04897deddfbc9c7afa8ee50a9" ], "ci_platforms": [ "linux" @@ -58717,7 +58736,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/6749752b02f7d14fff9ac35f6b68dd62f5b49fcd" + "test/core/end2end/fuzzers/client_fuzzer_corpus/52c00bde7f4af95a86deb0a6717d1faf2828a939" ], "ci_platforms": [ "linux" @@ -58736,7 +58755,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/67e72cea2b7042f08e8dfba5191d27bb390e4d00" + "test/core/end2end/fuzzers/client_fuzzer_corpus/534c900ade27c8f7fccb1f3b7e7703f77f13a8f5" ], "ci_platforms": [ "linux" @@ -58755,7 +58774,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/685fbddd9ea612b25e325a50bd659997b4d77da1" + "test/core/end2end/fuzzers/client_fuzzer_corpus/5360327e8bc8969f31b364df3081b51a1e03900c" ], "ci_platforms": [ "linux" @@ -58774,7 +58793,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/690158fb146f7f3b3ea820979307a8d8e6f38314" + "test/core/end2end/fuzzers/client_fuzzer_corpus/5369926a559827d08bccf264876d592c7cae660d" ], "ci_platforms": [ "linux" @@ -58793,7 +58812,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/69542ed81b00a5ec8daaf4e8d509201eecd502c5" + "test/core/end2end/fuzzers/client_fuzzer_corpus/53ef530f65b0cff2e338a51b469c224f53b628d7" ], "ci_platforms": [ "linux" @@ -58812,7 +58831,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/69be4179b28e408a0574935e893c6986bbca0de9" + "test/core/end2end/fuzzers/client_fuzzer_corpus/542c958c84d1e319b9ba23c52de2c4bca08a8dc7" ], "ci_platforms": [ "linux" @@ -58831,7 +58850,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/69e52eef5dd0c51012b5c974cf70f4074ba814a9" + "test/core/end2end/fuzzers/client_fuzzer_corpus/54555ceac4403855f4cf20367f7be05714c46c51" ], "ci_platforms": [ "linux" @@ -58850,7 +58869,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/6b1698d096095d4035ce67a8680b52eada00cce2" + "test/core/end2end/fuzzers/client_fuzzer_corpus/5482dc4af170def9c183315efaa48f9c186926a1" ], "ci_platforms": [ "linux" @@ -58869,7 +58888,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/6bfd3679f4e30aaaa1808e96c980edcfa9cac1c0" + "test/core/end2end/fuzzers/client_fuzzer_corpus/54e67ed1036f3f5b315e0e3c02948c30eba900fd" ], "ci_platforms": [ "linux" @@ -58888,7 +58907,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/6ca3910d5f4f7967311853724b072750716dcb48" + "test/core/end2end/fuzzers/client_fuzzer_corpus/55ca8f6d9928c239a7abb32554463e6e1e1ee084" ], "ci_platforms": [ "linux" @@ -58907,7 +58926,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/6e2796549e29e5066f780a5e926fd6e3bb362450" + "test/core/end2end/fuzzers/client_fuzzer_corpus/560c1057487e6b0d2d457748c3ad8434423eb263" ], "ci_platforms": [ "linux" @@ -58926,7 +58945,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/6e71553967212dfea2c9995f3641e582d8c2105b" + "test/core/end2end/fuzzers/client_fuzzer_corpus/564f203f678fb333c7b1f8f4df79237589ce346d" ], "ci_platforms": [ "linux" @@ -58945,7 +58964,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/6f30de3096eb71f697885fdd9cbddd9ee6ce46c4" + "test/core/end2end/fuzzers/client_fuzzer_corpus/56b0ac0636c57838f63415082b3ae2ec7a93f017" ], "ci_platforms": [ "linux" @@ -58964,7 +58983,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/71106770243ccca03f5025aadb298ee3a825824b" + "test/core/end2end/fuzzers/client_fuzzer_corpus/570ca8d2555dde94aa3b3121e8f5256e83eabe5e" ], "ci_platforms": [ "linux" @@ -58983,7 +59002,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/717695057d76b81c344ed8c23cc024195caa9405" + "test/core/end2end/fuzzers/client_fuzzer_corpus/57ee6efc38f4c544a3ea3e5e73987e825bdf2980" ], "ci_platforms": [ "linux" @@ -59002,7 +59021,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/7353a7b2ea9f61325728b2f118416549e89dd79b" + "test/core/end2end/fuzzers/client_fuzzer_corpus/5821752bf8923fdaebc8484662624d8acd382716" ], "ci_platforms": [ "linux" @@ -59021,7 +59040,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/739228a1400cd69c47f110002c34dbe1661e8c41" + "test/core/end2end/fuzzers/client_fuzzer_corpus/58a067ec6eda7191a5a910d8120633271d3af074" ], "ci_platforms": [ "linux" @@ -59040,7 +59059,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/7465a4955a064e8f1bb777d4b0de5b3df8469831" + "test/core/end2end/fuzzers/client_fuzzer_corpus/58bcbd601894835bb3312d2a0bc56f2e0f65984c" ], "ci_platforms": [ "linux" @@ -59059,7 +59078,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/74e6831be67485fb59b8e226fb8a48d88faf57d6" + "test/core/end2end/fuzzers/client_fuzzer_corpus/58d6dffb65a1fe1bc4e3fa970a15459587a32f77" ], "ci_platforms": [ "linux" @@ -59078,7 +59097,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/753efc088d6023ca113a12acc54015a22f7daf9f" + "test/core/end2end/fuzzers/client_fuzzer_corpus/591ef436ef8cc982b48fd827a4555b57cd9780e5" ], "ci_platforms": [ "linux" @@ -59097,7 +59116,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/759a1e2e34cad14321a5e5790b1e6a783312fea1" + "test/core/end2end/fuzzers/client_fuzzer_corpus/598d346f284bcff26d1de997c4ba5c4794c90b68" ], "ci_platforms": [ "linux" @@ -59116,7 +59135,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/77ea9180617391d8503427a1c060538182f7729f" + "test/core/end2end/fuzzers/client_fuzzer_corpus/59d28886db21f371ac9d999b68b116bcf425d971" ], "ci_platforms": [ "linux" @@ -59135,7 +59154,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/7885df741c88ca4b539798d9985c445f41cc2929" + "test/core/end2end/fuzzers/client_fuzzer_corpus/59d78f6397f0483d139f5bd0a9f264156f34acc4" ], "ci_platforms": [ "linux" @@ -59154,7 +59173,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/7af3156d286a32a6a6fede46d93ec12ded1ac138" + "test/core/end2end/fuzzers/client_fuzzer_corpus/5a2447fdfdbf123f4592c1284007b7d50a01750b" ], "ci_platforms": [ "linux" @@ -59173,7 +59192,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/7af41e5391204f4596cb1461792e2e23f9390b7b" + "test/core/end2end/fuzzers/client_fuzzer_corpus/5c14b48da74ab06b3cc20c4fe355e24f7dd7852a" ], "ci_platforms": [ "linux" @@ -59192,7 +59211,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/7c2e48b0d08aaeb95b5ca26036384aa2cec9de77" + "test/core/end2end/fuzzers/client_fuzzer_corpus/5ca233a53e3e425cc12e04b466a49789291eaa00" ], "ci_platforms": [ "linux" @@ -59211,7 +59230,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/7c73c0671308e37a8075a20863e70e180ef8b6ea" + "test/core/end2end/fuzzers/client_fuzzer_corpus/5dc7b2086a39f56d8b9135f524d34a01fcabafd8" ], "ci_platforms": [ "linux" @@ -59230,7 +59249,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/7e18989175bba8d9aea34413d6f328549e1c6825" + "test/core/end2end/fuzzers/client_fuzzer_corpus/5de72e607205dc17a45df703ec4e9b63c36821ec" ], "ci_platforms": [ "linux" @@ -59249,7 +59268,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/7f1530d4b702e68d043f89d9e63d314319dcd803" + "test/core/end2end/fuzzers/client_fuzzer_corpus/5e1659e7cd840ab3f958273ebffdd215f2c81da6" ], "ci_platforms": [ "linux" @@ -59268,7 +59287,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/8021c689f0078c5c59419c9959f5c58472245bc7" + "test/core/end2end/fuzzers/client_fuzzer_corpus/5e25cf639ba8ea37543d944f5efa94824c6272ff" ], "ci_platforms": [ "linux" @@ -59287,7 +59306,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/807b8c4ca068cff4bc0fc8e854c1215a2fe65960" + "test/core/end2end/fuzzers/client_fuzzer_corpus/5f247d7b6753f7a8798cf952f49f303c532e017c" ], "ci_platforms": [ "linux" @@ -59306,7 +59325,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/80bd4827db81a1da28fae8c150f5e2d46651c598" + "test/core/end2end/fuzzers/client_fuzzer_corpus/605e474e9d9436488dfe084d348908e4dfab81a3" ], "ci_platforms": [ "linux" @@ -59325,7 +59344,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/813d2c34c0df8d4a918e68e58cf0ae3703d0d46f" + "test/core/end2end/fuzzers/client_fuzzer_corpus/6066fc9e28b4ce704230f0e8cf21e7c3195aa2a3" ], "ci_platforms": [ "linux" @@ -59344,7 +59363,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/824152f7bd022996b41327002f6971cd9900b265" + "test/core/end2end/fuzzers/client_fuzzer_corpus/607dac8012f188cb035b189fc3637028137023e0" ], "ci_platforms": [ "linux" @@ -59363,7 +59382,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/829a1dc2bcb22a230df8aa20540def0e16864983" + "test/core/end2end/fuzzers/client_fuzzer_corpus/611343a6b8879b393ba2f38ed41c7f5355355920" ], "ci_platforms": [ "linux" @@ -59382,7 +59401,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/82c0e02a867a5fdfb805e01ebf1a008220311e27" + "test/core/end2end/fuzzers/client_fuzzer_corpus/62c843359941660da3fc9eea62a5732aaa3be283" ], "ci_platforms": [ "linux" @@ -59401,7 +59420,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/831248cea079b629bf0ef6d9d02c159d6f8ed41b" + "test/core/end2end/fuzzers/client_fuzzer_corpus/636a19b8f50c4efccccea83ab78a933d999e41fa" ], "ci_platforms": [ "linux" @@ -59420,7 +59439,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/834527ef0bc1572c584938ca7fe5336961754708" + "test/core/end2end/fuzzers/client_fuzzer_corpus/63a1cb41d219394c9bab947202921506f3574ad0" ], "ci_platforms": [ "linux" @@ -59439,7 +59458,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/8382c249fc9c7a248833d89de554e63807c475f7" + "test/core/end2end/fuzzers/client_fuzzer_corpus/64696e93ead18265cdac3fb37dae29ad3be6d764" ], "ci_platforms": [ "linux" @@ -59458,7 +59477,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/83baaee9b46770d9eef0e161a6e52cda76e3b043" + "test/core/end2end/fuzzers/client_fuzzer_corpus/64c0e0b4d9c2d25fdcb1e2bdcb999487fc096dad" ], "ci_platforms": [ "linux" @@ -59477,7 +59496,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/842cea88bccc41d7e2625dae8ff7268ee79e9f57" + "test/core/end2end/fuzzers/client_fuzzer_corpus/64cad305e1858eae27cd723778fb9f4b7052eaa5" ], "ci_platforms": [ "linux" @@ -59496,7 +59515,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/850c639595eae3cc9c2cfef473e28fd4e8174dc8" + "test/core/end2end/fuzzers/client_fuzzer_corpus/64d27dc9f984c49d421a5b0cb0391992d5aac1a4" ], "ci_platforms": [ "linux" @@ -59515,7 +59534,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/857ce08213a5106c746767352c6863d7bd134208" + "test/core/end2end/fuzzers/client_fuzzer_corpus/650f74738d3961af2d1fe85ad8fc8212ea13cbbf" ], "ci_platforms": [ "linux" @@ -59534,7 +59553,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/85a7e47ef707d3b31cad924ed6c697c3678ab569" + "test/core/end2end/fuzzers/client_fuzzer_corpus/653ec14661c40ea25bdbab4a7cb9371c669d10d9" ], "ci_platforms": [ "linux" @@ -59553,7 +59572,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/86eb156ff8ddd7edc535840d412342ada6f3b184" + "test/core/end2end/fuzzers/client_fuzzer_corpus/65dff388749da6a44926b491cdc555f61d708171" ], "ci_platforms": [ "linux" @@ -59572,7 +59591,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/871a2e4d73a7fbb50f71558517a2f704b7fdb868" + "test/core/end2end/fuzzers/client_fuzzer_corpus/66145518601b1405361df12570f6e0b2b9a2e5b3" ], "ci_platforms": [ "linux" @@ -59591,7 +59610,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/8795e24f23db36e4f9ab609c9faff601b984eb6f" + "test/core/end2end/fuzzers/client_fuzzer_corpus/662d81374a2c96f867ccd88a4295190827c45453" ], "ci_platforms": [ "linux" @@ -59610,7 +59629,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/87e97b460042d045629263ad10ff3de7b000f0a1" + "test/core/end2end/fuzzers/client_fuzzer_corpus/669256f857011c32f5757ec19b2e5b9a372f6c23" ], "ci_platforms": [ "linux" @@ -59629,7 +59648,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/89cf42c02d7135afa6c81d8a0c2bc4c3df557769" + "test/core/end2end/fuzzers/client_fuzzer_corpus/6749752b02f7d14fff9ac35f6b68dd62f5b49fcd" ], "ci_platforms": [ "linux" @@ -59648,7 +59667,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/8b7b914723bfc23ec650cb91d209141641fba09f" + "test/core/end2end/fuzzers/client_fuzzer_corpus/676adbb1e5b3f4f9e3cba51d3d4ef963ba4ea7e3" ], "ci_platforms": [ "linux" @@ -59667,7 +59686,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/8b8b9fcdfff1f891b1694614b7309cb4a2098f4b" + "test/core/end2end/fuzzers/client_fuzzer_corpus/67e72cea2b7042f08e8dfba5191d27bb390e4d00" ], "ci_platforms": [ "linux" @@ -59686,7 +59705,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/8b8f6d58dff9ab0c37183ec93c9a600d5ba5d9e6" + "test/core/end2end/fuzzers/client_fuzzer_corpus/67f160446ded73c408f4e5a0665731b642b6edd4" ], "ci_platforms": [ "linux" @@ -59705,7 +59724,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/8ba00963037c9ff548b7a702497441799075f14b" + "test/core/end2end/fuzzers/client_fuzzer_corpus/6856c7cb02d2ba74a60fd47140f042701dda63b3" ], "ci_platforms": [ "linux" @@ -59724,7 +59743,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/8bacacba71bfa5c74fd74cb6577a49a7aec9cf1f" + "test/core/end2end/fuzzers/client_fuzzer_corpus/685fbddd9ea612b25e325a50bd659997b4d77da1" ], "ci_platforms": [ "linux" @@ -59743,7 +59762,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/8c527bdf0f304a31866f71cdb298511041ecd320" + "test/core/end2end/fuzzers/client_fuzzer_corpus/690158fb146f7f3b3ea820979307a8d8e6f38314" ], "ci_platforms": [ "linux" @@ -59762,7 +59781,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/8d352ea63259e26e1bb61f5a8f78254be4e3e7b1" + "test/core/end2end/fuzzers/client_fuzzer_corpus/69542ed81b00a5ec8daaf4e8d509201eecd502c5" ], "ci_platforms": [ "linux" @@ -59781,7 +59800,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/8dfc4e78007040009f37109f9ca928c31b3ebb49" + "test/core/end2end/fuzzers/client_fuzzer_corpus/69be4179b28e408a0574935e893c6986bbca0de9" ], "ci_platforms": [ "linux" @@ -59800,7 +59819,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/8ea624983d766ed45780378a3eec24eb2faeb229" + "test/core/end2end/fuzzers/client_fuzzer_corpus/69e14b73af03e8f2d998cfcf16215f65bf589efb" ], "ci_platforms": [ "linux" @@ -59819,7 +59838,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/8eeb8cf054ebd546ca0555ef1cd4ac6a08628917" + "test/core/end2end/fuzzers/client_fuzzer_corpus/69e52eef5dd0c51012b5c974cf70f4074ba814a9" ], "ci_platforms": [ "linux" @@ -59838,7 +59857,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/8f980dd25f1c77e3536131c2c620aa32e8c13180" + "test/core/end2end/fuzzers/client_fuzzer_corpus/6b1698d096095d4035ce67a8680b52eada00cce2" ], "ci_platforms": [ "linux" @@ -59857,7 +59876,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/90a9c3390752b94ca19a58cb2fe6267bc818f718" + "test/core/end2end/fuzzers/client_fuzzer_corpus/6bfd3679f4e30aaaa1808e96c980edcfa9cac1c0" ], "ci_platforms": [ "linux" @@ -59876,7 +59895,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/911e2ea20b6c10431e48f70d9933987815926a9d" + "test/core/end2end/fuzzers/client_fuzzer_corpus/6ca3910d5f4f7967311853724b072750716dcb48" ], "ci_platforms": [ "linux" @@ -59895,7 +59914,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/9125277ed9ec5d59e51f3e1a8d97d25ef88a5d4f" + "test/core/end2end/fuzzers/client_fuzzer_corpus/6e2796549e29e5066f780a5e926fd6e3bb362450" ], "ci_platforms": [ "linux" @@ -59914,7 +59933,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/91916df7c8f04d8c2b6b8f4aeaeee6972ce0de74" + "test/core/end2end/fuzzers/client_fuzzer_corpus/6e71553967212dfea2c9995f3641e582d8c2105b" ], "ci_platforms": [ "linux" @@ -59933,7 +59952,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/92cce6dc5c31acd62347b15d89d52ab94b507e0f" + "test/core/end2end/fuzzers/client_fuzzer_corpus/6f30de3096eb71f697885fdd9cbddd9ee6ce46c4" ], "ci_platforms": [ "linux" @@ -59952,7 +59971,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/92ea0d3200665e1836ac12bed0837425cb9f43de" + "test/core/end2end/fuzzers/client_fuzzer_corpus/71106770243ccca03f5025aadb298ee3a825824b" ], "ci_platforms": [ "linux" @@ -59971,7 +59990,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/9329b80d0125cc994d7ad36540c7a8265d76983c" + "test/core/end2end/fuzzers/client_fuzzer_corpus/717695057d76b81c344ed8c23cc024195caa9405" ], "ci_platforms": [ "linux" @@ -59990,7 +60009,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/93ac93b7deabdfb4f86eb37a1e9f6669957d14a6" + "test/core/end2end/fuzzers/client_fuzzer_corpus/7353a7b2ea9f61325728b2f118416549e89dd79b" ], "ci_platforms": [ "linux" @@ -60009,7 +60028,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/94108ac8420347598c7cee743b2a158b1270fb8f" + "test/core/end2end/fuzzers/client_fuzzer_corpus/739228a1400cd69c47f110002c34dbe1661e8c41" ], "ci_platforms": [ "linux" @@ -60028,7 +60047,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/954ea72fdbeaf5b46d18c6d5bb77fc1a0f97569d" + "test/core/end2end/fuzzers/client_fuzzer_corpus/7465a4955a064e8f1bb777d4b0de5b3df8469831" ], "ci_platforms": [ "linux" @@ -60047,7 +60066,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/9552c3f6304af40224b800f3a3a5df3887a530f6" + "test/core/end2end/fuzzers/client_fuzzer_corpus/74e6831be67485fb59b8e226fb8a48d88faf57d6" ], "ci_platforms": [ "linux" @@ -60066,7 +60085,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/96e5126447131d3d59cc6547f6b91d3433ce37c8" + "test/core/end2end/fuzzers/client_fuzzer_corpus/753efc088d6023ca113a12acc54015a22f7daf9f" ], "ci_platforms": [ "linux" @@ -60085,7 +60104,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/970fccda0b34b59ade44d52e1212699b4d2419a8" + "test/core/end2end/fuzzers/client_fuzzer_corpus/759a1e2e34cad14321a5e5790b1e6a783312fea1" ], "ci_platforms": [ "linux" @@ -60104,7 +60123,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/97c4b73f72b248b4ebf4bf30892d0db828a85297" + "test/core/end2end/fuzzers/client_fuzzer_corpus/77cff7548cafe87410e4a0dde3ba6892b25594d3" ], "ci_platforms": [ "linux" @@ -60123,7 +60142,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/98c0c0a3c8c05aec3082755a4635e65baecf4752" + "test/core/end2end/fuzzers/client_fuzzer_corpus/77ea9180617391d8503427a1c060538182f7729f" ], "ci_platforms": [ "linux" @@ -60142,7 +60161,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/98da5edafac67704810f093b38c86e4c77b75349" + "test/core/end2end/fuzzers/client_fuzzer_corpus/7885df741c88ca4b539798d9985c445f41cc2929" ], "ci_platforms": [ "linux" @@ -60161,7 +60180,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/98dddd3f679af150e9933bd864ae20e20b7aa25a" + "test/core/end2end/fuzzers/client_fuzzer_corpus/7af3156d286a32a6a6fede46d93ec12ded1ac138" ], "ci_platforms": [ "linux" @@ -60180,7 +60199,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/999d0995c2f09beda8783eac95d7643a11d5c89a" + "test/core/end2end/fuzzers/client_fuzzer_corpus/7af41e5391204f4596cb1461792e2e23f9390b7b" ], "ci_platforms": [ "linux" @@ -60199,7 +60218,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/9a43f48d4f6219618f8cc9e876880fe81109ad72" + "test/core/end2end/fuzzers/client_fuzzer_corpus/7beeb19272131701f3a0d1dd633f1b1969899366" ], "ci_platforms": [ "linux" @@ -60218,7 +60237,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/9a4da2a37a26c114e1226bfbe1cf80ec5ca99a66" + "test/core/end2end/fuzzers/client_fuzzer_corpus/7c2e48b0d08aaeb95b5ca26036384aa2cec9de77" ], "ci_platforms": [ "linux" @@ -60237,7 +60256,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/9abf980e8909aeb31936553ca22ccfd8680c4dab" + "test/core/end2end/fuzzers/client_fuzzer_corpus/7c73c0671308e37a8075a20863e70e180ef8b6ea" ], "ci_platforms": [ "linux" @@ -60256,7 +60275,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/9b1355c6e2c43ce83001bbead09a79852e04feef" + "test/core/end2end/fuzzers/client_fuzzer_corpus/7e18989175bba8d9aea34413d6f328549e1c6825" ], "ci_platforms": [ "linux" @@ -60275,7 +60294,1223 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/9b4d4ce0457f5300d6b4b309762acfdbc41e3965" + "test/core/end2end/fuzzers/client_fuzzer_corpus/7f1530d4b702e68d043f89d9e63d314319dcd803" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/8021c689f0078c5c59419c9959f5c58472245bc7" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/807b8c4ca068cff4bc0fc8e854c1215a2fe65960" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/80bd4827db81a1da28fae8c150f5e2d46651c598" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/813d2c34c0df8d4a918e68e58cf0ae3703d0d46f" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/824152f7bd022996b41327002f6971cd9900b265" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/829a1dc2bcb22a230df8aa20540def0e16864983" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/82c0e02a867a5fdfb805e01ebf1a008220311e27" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/831248cea079b629bf0ef6d9d02c159d6f8ed41b" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/834527ef0bc1572c584938ca7fe5336961754708" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/8382c249fc9c7a248833d89de554e63807c475f7" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/83baaee9b46770d9eef0e161a6e52cda76e3b043" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/842cea88bccc41d7e2625dae8ff7268ee79e9f57" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/850c639595eae3cc9c2cfef473e28fd4e8174dc8" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/857ce08213a5106c746767352c6863d7bd134208" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/85a7e47ef707d3b31cad924ed6c697c3678ab569" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/86eb156ff8ddd7edc535840d412342ada6f3b184" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/871a2e4d73a7fbb50f71558517a2f704b7fdb868" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/8795e24f23db36e4f9ab609c9faff601b984eb6f" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/87e97b460042d045629263ad10ff3de7b000f0a1" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/89cf42c02d7135afa6c81d8a0c2bc4c3df557769" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/8b0cf53ac17015fe066002cb3814933df9ee96be" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/8b5c4543923da5e468aca1de1ab880aed2ac4451" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/8b7b914723bfc23ec650cb91d209141641fba09f" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/8b8b9fcdfff1f891b1694614b7309cb4a2098f4b" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/8b8f6d58dff9ab0c37183ec93c9a600d5ba5d9e6" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/8ba00963037c9ff548b7a702497441799075f14b" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/8bacacba71bfa5c74fd74cb6577a49a7aec9cf1f" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/8c527bdf0f304a31866f71cdb298511041ecd320" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/8d352ea63259e26e1bb61f5a8f78254be4e3e7b1" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/8d9784f85e9662734e180ca8bec2164425ae8a87" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/8dfc4e78007040009f37109f9ca928c31b3ebb49" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/8e3f138d163022d6e105ab595788f4cfdd9b9db3" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/8ea624983d766ed45780378a3eec24eb2faeb229" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/8eeb8cf054ebd546ca0555ef1cd4ac6a08628917" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/8f980dd25f1c77e3536131c2c620aa32e8c13180" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/90a9c3390752b94ca19a58cb2fe6267bc818f718" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/911e2ea20b6c10431e48f70d9933987815926a9d" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/9125277ed9ec5d59e51f3e1a8d97d25ef88a5d4f" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/914464d372dcccf31ed5331293d84121e17616bb" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/91916df7c8f04d8c2b6b8f4aeaeee6972ce0de74" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/92cce6dc5c31acd62347b15d89d52ab94b507e0f" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/92ea0d3200665e1836ac12bed0837425cb9f43de" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/9329b80d0125cc994d7ad36540c7a8265d76983c" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/934a41b5027d1c5cca27ebda57560c38cb9e09ea" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/9354652806d96b09c8e7082b1b7d22e7c3fb9f0b" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/9398ac1c2b4015792661266a9c84b6d7a68c3155" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/93ac93b7deabdfb4f86eb37a1e9f6669957d14a6" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/94108ac8420347598c7cee743b2a158b1270fb8f" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/954ea72fdbeaf5b46d18c6d5bb77fc1a0f97569d" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/9552c3f6304af40224b800f3a3a5df3887a530f6" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/96e5126447131d3d59cc6547f6b91d3433ce37c8" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/970fccda0b34b59ade44d52e1212699b4d2419a8" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/97c4b73f72b248b4ebf4bf30892d0db828a85297" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/98c0c0a3c8c05aec3082755a4635e65baecf4752" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/98da5edafac67704810f093b38c86e4c77b75349" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/98dddd3f679af150e9933bd864ae20e20b7aa25a" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/99099024a3f3e389f57cb7b697eb34485846f316" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/998a54dc94ab6e7d6a6066415fb0dd9b52356171" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/999d0995c2f09beda8783eac95d7643a11d5c89a" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/9a43f48d4f6219618f8cc9e876880fe81109ad72" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/9a4da2a37a26c114e1226bfbe1cf80ec5ca99a66" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/9abf980e8909aeb31936553ca22ccfd8680c4dab" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/9b1355c6e2c43ce83001bbead09a79852e04feef" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/9b4d4ce0457f5300d6b4b309762acfdbc41e3965" ], "ci_platforms": [ "linux" @@ -60313,7 +61548,691 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/9c4eac3dd734a74673c76e6b21fd9c18cdfa831c" + "test/core/end2end/fuzzers/client_fuzzer_corpus/9c4eac3dd734a74673c76e6b21fd9c18cdfa831c" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/9d2dd744ba59c1e8ec091e23938e46d1bb5ee519" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/9d362d2aaeee243a5b54621d8187c4b16f87c9f5" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/9d6947df24c9ebcbec72c568d9708d7b1ecae63c" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/9dfdce1b090a559a14f9a5852f78547413b1d1ed" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/9e2ab07030bd35a4c31df32c79aca5e76c1d04f8" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/9eaf2ad607a943141c29f334b2c66c2e59e99980" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/9f0ab521c728be21e93112b2730c52bc1d6c0021" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/9f2316ddcea948c947fbbf35ae87b767b8c1dc55" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/9f9ed47f98b4905f1f6ef2b552a66905bdf79b1b" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/9fee3212240d4bccfdab3696dbbc579b06d39982" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/a09ef34c93fe0ffc13045f67b7ecec683fb72e98" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/a210d629c305b89a34b7ff3c41ae4566cd22186b" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/a25b31398669b585ccab97bceadc31994de7ead7" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/a29a547671badd3154789e1a02bdb87332fcd6a4" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/a30fc2605f4e74f7003f902ea4a4c994e3ce9bfd" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/a33e1b28074a41fc5c2611a67161ae5638a47dd5" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/a39ac9e92b41d1889096ed415b4c2eb1aba6ed50" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/a3cd54d43d3b3bdfcf224d636dc11ce1b5ee4d30" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/a4874327383ca168f9d9d59cffe327f61e9a6610" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/a4e4a0473ac1f2b8de86efdf00fcb382a343126d" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/a502dbaf3c842bd86e9ae513e8782eb23c70ad7a" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/a5592f15d5424ab7e16a18e77027ab91c846d90a" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/a5c2fdae1a1c0487d00db0eec6e3429b12244b1f" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/a5cf80b996b2ba8c9580f8ecd22720c48de41044" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/a60ae4e21a913e84405814f18555f0c179c24167" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/a649093880c2a2f143f861893eaff5d30be95eb7" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/a6603e797695274d10bce000f66ca0a715f7d8c0" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/a6d4b6043d86c376e9b166d5ca395f3e099ae229" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/a6f0d1ed80393ec0a884718b44fe2dc9f852d38a" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/a706f2067bfbda7837eaad68972d60547e2957c3" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/a814c5743d492b96d2b402f9e819bf8406262224" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/a8249ebfe91327806446f14a6b2e7d9c8440257f" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/a8e306820fb76566b522c23ec68bdce0ad0536f2" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/a8e67676784506d2e6eab3a0dfa25e53a80b40a0" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/a97dbb159ef9bc6e39c9c25e04315752e871e739" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/a9d71e1ff2912d8874e38fc61cbd9a8ef28af4a9" ], "ci_platforms": [ "linux" @@ -60332,7 +62251,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/9d2dd744ba59c1e8ec091e23938e46d1bb5ee519" + "test/core/end2end/fuzzers/client_fuzzer_corpus/aa878edb0100e876e00e310ae221b220fdb5e028" ], "ci_platforms": [ "linux" @@ -60351,7 +62270,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/9d362d2aaeee243a5b54621d8187c4b16f87c9f5" + "test/core/end2end/fuzzers/client_fuzzer_corpus/aaada46c7f3bff58c2dd6f4a8394135ed5f253ee" ], "ci_platforms": [ "linux" @@ -60370,7 +62289,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/9d6947df24c9ebcbec72c568d9708d7b1ecae63c" + "test/core/end2end/fuzzers/client_fuzzer_corpus/ab27fb527771c7d86f74afb6864e95402328ec0e" ], "ci_platforms": [ "linux" @@ -60389,7 +62308,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/9dfdce1b090a559a14f9a5852f78547413b1d1ed" + "test/core/end2end/fuzzers/client_fuzzer_corpus/ab8d6e1ecbd80c6223b8623a386c61023502a57c" ], "ci_platforms": [ "linux" @@ -60408,7 +62327,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/9e2ab07030bd35a4c31df32c79aca5e76c1d04f8" + "test/core/end2end/fuzzers/client_fuzzer_corpus/abd52da5882855a63632a6917df3639538928cd3" ], "ci_platforms": [ "linux" @@ -60427,7 +62346,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/9eaf2ad607a943141c29f334b2c66c2e59e99980" + "test/core/end2end/fuzzers/client_fuzzer_corpus/ac38a6572f8420b4df37d9e39088d1905fced71d" ], "ci_platforms": [ "linux" @@ -60446,7 +62365,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/9f0ab521c728be21e93112b2730c52bc1d6c0021" + "test/core/end2end/fuzzers/client_fuzzer_corpus/ac727124e46a249419f088c8665324a11b357b84" ], "ci_platforms": [ "linux" @@ -60465,7 +62384,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/9f2316ddcea948c947fbbf35ae87b767b8c1dc55" + "test/core/end2end/fuzzers/client_fuzzer_corpus/adb9bf315315338bcad85929917b9def2aa098cb" ], "ci_platforms": [ "linux" @@ -60484,7 +62403,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/9f9ed47f98b4905f1f6ef2b552a66905bdf79b1b" + "test/core/end2end/fuzzers/client_fuzzer_corpus/ade2d2f0e120a9527487e9b92458ee6844800e4e" ], "ci_platforms": [ "linux" @@ -60503,7 +62422,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/9fee3212240d4bccfdab3696dbbc579b06d39982" + "test/core/end2end/fuzzers/client_fuzzer_corpus/ae448bfe17f9a3a6eff074d4caa9f7261c94d2d5" ], "ci_platforms": [ "linux" @@ -60522,7 +62441,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/a09ef34c93fe0ffc13045f67b7ecec683fb72e98" + "test/core/end2end/fuzzers/client_fuzzer_corpus/ae8c538d4ad7f2996ac724bad7a075e1aea32556" ], "ci_platforms": [ "linux" @@ -60541,7 +62460,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/a210d629c305b89a34b7ff3c41ae4566cd22186b" + "test/core/end2end/fuzzers/client_fuzzer_corpus/ae8cdc02275a1436bc131bee52a17ee797e2e6c9" ], "ci_platforms": [ "linux" @@ -60560,7 +62479,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/a29a547671badd3154789e1a02bdb87332fcd6a4" + "test/core/end2end/fuzzers/client_fuzzer_corpus/aef36c49d7dec0dcf8cdc224d9e9221fa2cb1db0" ], "ci_platforms": [ "linux" @@ -60579,7 +62498,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/a30fc2605f4e74f7003f902ea4a4c994e3ce9bfd" + "test/core/end2end/fuzzers/client_fuzzer_corpus/af8b24ffaecdfaf96c0cd7c76f31dc9e1b4d0935" ], "ci_platforms": [ "linux" @@ -60598,7 +62517,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/a33e1b28074a41fc5c2611a67161ae5638a47dd5" + "test/core/end2end/fuzzers/client_fuzzer_corpus/afcce9e02e0696a2af073855a386f589cc12c94d" ], "ci_platforms": [ "linux" @@ -60617,7 +62536,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/a3cd54d43d3b3bdfcf224d636dc11ce1b5ee4d30" + "test/core/end2end/fuzzers/client_fuzzer_corpus/b00a32e8bfb75e75f31410dfe3592da6248275c6" ], "ci_platforms": [ "linux" @@ -60636,7 +62555,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/a4874327383ca168f9d9d59cffe327f61e9a6610" + "test/core/end2end/fuzzers/client_fuzzer_corpus/b09f98e13e5b67a4dd7f74eff00bb247b9967844" ], "ci_platforms": [ "linux" @@ -60655,7 +62574,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/a4e4a0473ac1f2b8de86efdf00fcb382a343126d" + "test/core/end2end/fuzzers/client_fuzzer_corpus/b10353c265bef989d8909055fd6cd52e49eef3e6" ], "ci_platforms": [ "linux" @@ -60674,7 +62593,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/a502dbaf3c842bd86e9ae513e8782eb23c70ad7a" + "test/core/end2end/fuzzers/client_fuzzer_corpus/b24a0dd1bc0bfabb832f0d1c8410c018c4ddaf4e" ], "ci_platforms": [ "linux" @@ -60693,7 +62612,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/a5592f15d5424ab7e16a18e77027ab91c846d90a" + "test/core/end2end/fuzzers/client_fuzzer_corpus/b24c25c6d4b57a5f3d64a0adb205bf4f150c9138" ], "ci_platforms": [ "linux" @@ -60712,7 +62631,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/a5cf80b996b2ba8c9580f8ecd22720c48de41044" + "test/core/end2end/fuzzers/client_fuzzer_corpus/b283eb8884c98dd50523995ce221aa1ecb3ca182" ], "ci_platforms": [ "linux" @@ -60731,7 +62650,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/a60ae4e21a913e84405814f18555f0c179c24167" + "test/core/end2end/fuzzers/client_fuzzer_corpus/b2a79b262ee3966c5ce7c7b42dcffd55d7d0956b" ], "ci_platforms": [ "linux" @@ -60750,7 +62669,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/a6603e797695274d10bce000f66ca0a715f7d8c0" + "test/core/end2end/fuzzers/client_fuzzer_corpus/b2aa4861b5104e8bb8bb173f4b023a2172a7b9a2" ], "ci_platforms": [ "linux" @@ -60769,7 +62688,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/a6d4b6043d86c376e9b166d5ca395f3e099ae229" + "test/core/end2end/fuzzers/client_fuzzer_corpus/b33eb7e1bde4c69671dbbf9489b4d4b87c5d23fd" ], "ci_platforms": [ "linux" @@ -60788,7 +62707,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/a6f0d1ed80393ec0a884718b44fe2dc9f852d38a" + "test/core/end2end/fuzzers/client_fuzzer_corpus/b387e46c23912785e6c353ab49b8ea4a92c2c2e5" ], "ci_platforms": [ "linux" @@ -60807,7 +62726,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/a706f2067bfbda7837eaad68972d60547e2957c3" + "test/core/end2end/fuzzers/client_fuzzer_corpus/b39bfaf6a3072d8a50984dcc54967e9246f8d3e5" ], "ci_platforms": [ "linux" @@ -60826,7 +62745,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/a814c5743d492b96d2b402f9e819bf8406262224" + "test/core/end2end/fuzzers/client_fuzzer_corpus/b3cfcd55b0331ab0c931b8c61d4df41464587f10" ], "ci_platforms": [ "linux" @@ -60845,7 +62764,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/a8e67676784506d2e6eab3a0dfa25e53a80b40a0" + "test/core/end2end/fuzzers/client_fuzzer_corpus/b3f33b78433af7f607bc99b569b0cef95a1a6ca0" ], "ci_platforms": [ "linux" @@ -60864,7 +62783,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/a9d71e1ff2912d8874e38fc61cbd9a8ef28af4a9" + "test/core/end2end/fuzzers/client_fuzzer_corpus/b46e762671a5e28c7061da3baee6fc41dcc0122b" ], "ci_platforms": [ "linux" @@ -60883,7 +62802,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/aa878edb0100e876e00e310ae221b220fdb5e028" + "test/core/end2end/fuzzers/client_fuzzer_corpus/b6d86bedf3cf19441114e463458a454709e627b4" ], "ci_platforms": [ "linux" @@ -60902,7 +62821,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/aaada46c7f3bff58c2dd6f4a8394135ed5f253ee" + "test/core/end2end/fuzzers/client_fuzzer_corpus/b755933ad6e318ee9e0c430ff69be7a515d44def" ], "ci_platforms": [ "linux" @@ -60921,7 +62840,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/ab27fb527771c7d86f74afb6864e95402328ec0e" + "test/core/end2end/fuzzers/client_fuzzer_corpus/b758f5c019696f33c50895168219c0e6cb04e11d" ], "ci_platforms": [ "linux" @@ -60940,7 +62859,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/ab8d6e1ecbd80c6223b8623a386c61023502a57c" + "test/core/end2end/fuzzers/client_fuzzer_corpus/b7b664a39372dd6142b8ef7906857e4ab3f1fc84" ], "ci_platforms": [ "linux" @@ -60959,7 +62878,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/abd52da5882855a63632a6917df3639538928cd3" + "test/core/end2end/fuzzers/client_fuzzer_corpus/b7c31bb5f6acc65b88e31400dcae71f7be392c86" ], "ci_platforms": [ "linux" @@ -60978,7 +62897,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/ac38a6572f8420b4df37d9e39088d1905fced71d" + "test/core/end2end/fuzzers/client_fuzzer_corpus/b93fd0a15287dd035eac86e547e3ce42183bdb28" ], "ci_platforms": [ "linux" @@ -60997,7 +62916,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/ac727124e46a249419f088c8665324a11b357b84" + "test/core/end2end/fuzzers/client_fuzzer_corpus/ba3566735888b53712c6b2e6d52ff5f2197afd6a" ], "ci_platforms": [ "linux" @@ -61016,7 +62935,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/adb9bf315315338bcad85929917b9def2aa098cb" + "test/core/end2end/fuzzers/client_fuzzer_corpus/ba942f8fb244b60561a067129c242c4bc4fdd5e1" ], "ci_platforms": [ "linux" @@ -61035,7 +62954,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/ade2d2f0e120a9527487e9b92458ee6844800e4e" + "test/core/end2end/fuzzers/client_fuzzer_corpus/baa28a5baedb645f4430940a4b4b1142f4b03e0f" ], "ci_platforms": [ "linux" @@ -61054,7 +62973,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/ae8c538d4ad7f2996ac724bad7a075e1aea32556" + "test/core/end2end/fuzzers/client_fuzzer_corpus/baf7839388e10ff0c410a58797482cb83693b309" ], "ci_platforms": [ "linux" @@ -61073,7 +62992,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/aef36c49d7dec0dcf8cdc224d9e9221fa2cb1db0" + "test/core/end2end/fuzzers/client_fuzzer_corpus/bbc03bf6274a79528d43e200e8f1aaa770a155d6" ], "ci_platforms": [ "linux" @@ -61092,7 +63011,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/af8b24ffaecdfaf96c0cd7c76f31dc9e1b4d0935" + "test/core/end2end/fuzzers/client_fuzzer_corpus/bc9e17fed43c5d0668a87e8d6354c344c5b4d00b" ], "ci_platforms": [ "linux" @@ -61111,7 +63030,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/afcce9e02e0696a2af073855a386f589cc12c94d" + "test/core/end2end/fuzzers/client_fuzzer_corpus/bcc7340f8876a7dff381ca676efc39d30eed9f48" ], "ci_platforms": [ "linux" @@ -61130,7 +63049,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/b00a32e8bfb75e75f31410dfe3592da6248275c6" + "test/core/end2end/fuzzers/client_fuzzer_corpus/bd0bef14e73aa1073eb5acb6e4cc901c976335f5" ], "ci_platforms": [ "linux" @@ -61149,7 +63068,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/b09f98e13e5b67a4dd7f74eff00bb247b9967844" + "test/core/end2end/fuzzers/client_fuzzer_corpus/bd275178fd473028a5cedf7d5780b27e809882ee" ], "ci_platforms": [ "linux" @@ -61168,7 +63087,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/b24a0dd1bc0bfabb832f0d1c8410c018c4ddaf4e" + "test/core/end2end/fuzzers/client_fuzzer_corpus/be3237e72b3d8d56eec0520145dd7d1a5064eede" ], "ci_platforms": [ "linux" @@ -61187,7 +63106,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/b24c25c6d4b57a5f3d64a0adb205bf4f150c9138" + "test/core/end2end/fuzzers/client_fuzzer_corpus/be8cc5bab95e0ea7af538ca11175d710da6207d9" ], "ci_platforms": [ "linux" @@ -61206,7 +63125,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/b283eb8884c98dd50523995ce221aa1ecb3ca182" + "test/core/end2end/fuzzers/client_fuzzer_corpus/be988fc0c00a8422020dea3dc72451b09e25e1ad" ], "ci_platforms": [ "linux" @@ -61225,7 +63144,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/b2a79b262ee3966c5ce7c7b42dcffd55d7d0956b" + "test/core/end2end/fuzzers/client_fuzzer_corpus/beabbe93f1e9b2e56f729af30559ec03a00f53fa" ], "ci_platforms": [ "linux" @@ -61244,7 +63163,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/b2aa4861b5104e8bb8bb173f4b023a2172a7b9a2" + "test/core/end2end/fuzzers/client_fuzzer_corpus/c0deaead93c9b3f2fc211fb7f0711ac192715a40" ], "ci_platforms": [ "linux" @@ -61263,7 +63182,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/b33eb7e1bde4c69671dbbf9489b4d4b87c5d23fd" + "test/core/end2end/fuzzers/client_fuzzer_corpus/c24143cf5f6f77f002e0ab82e3060906e2e7d062" ], "ci_platforms": [ "linux" @@ -61282,7 +63201,159 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/b39bfaf6a3072d8a50984dcc54967e9246f8d3e5" + "test/core/end2end/fuzzers/client_fuzzer_corpus/c3afa705dab02fea4d892134e7c01c3af270cb6e" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/c3de41124a14ea562360aabc9e12666851bff2fe" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/c4c53b4727e9e1f040c5d7870639dd3daa184ddb" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/c4e60ae7c05b12a90dd7c43fbc85ae4be7540f18" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/c5d0c169d326d79fc4ee8521b282dbcbf33c1d5c" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/c5dfb4a82f91d07041d4b0ca6cc34cfa1e9c7199" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/c685689a9d5b259afe237d857b7c6551dc95c176" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/c77087b4651f4c62a780d77a3b4c233490244e8a" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/c784ad2e205ba49b5bb1302746723dbc57320981" ], "ci_platforms": [ "linux" @@ -61301,7 +63372,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/b3f33b78433af7f607bc99b569b0cef95a1a6ca0" + "test/core/end2end/fuzzers/client_fuzzer_corpus/c84da54dacf04445b50448a70fb0ecdd08e9234a" ], "ci_platforms": [ "linux" @@ -61320,7 +63391,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/b46e762671a5e28c7061da3baee6fc41dcc0122b" + "test/core/end2end/fuzzers/client_fuzzer_corpus/c8cb20176e427d2e108187924f570ef1df6d440c" ], "ci_platforms": [ "linux" @@ -61339,7 +63410,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/b6d86bedf3cf19441114e463458a454709e627b4" + "test/core/end2end/fuzzers/client_fuzzer_corpus/c916ea9c6901c1e77af764773bd2843baa2ebdc6" ], "ci_platforms": [ "linux" @@ -61358,7 +63429,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/b755933ad6e318ee9e0c430ff69be7a515d44def" + "test/core/end2end/fuzzers/client_fuzzer_corpus/c97ebf43d8a5ce5cdb8e93a5d0362239c284ab4d" ], "ci_platforms": [ "linux" @@ -61377,7 +63448,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/b7b664a39372dd6142b8ef7906857e4ab3f1fc84" + "test/core/end2end/fuzzers/client_fuzzer_corpus/c9e2cf8be8a4dc2294020026c62840ef1fb4853b" ], "ci_platforms": [ "linux" @@ -61396,7 +63467,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/b7c31bb5f6acc65b88e31400dcae71f7be392c86" + "test/core/end2end/fuzzers/client_fuzzer_corpus/ca0db313bf949ba3f87a5254646a7a7dc8a7f89d" ], "ci_platforms": [ "linux" @@ -61415,7 +63486,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/ba942f8fb244b60561a067129c242c4bc4fdd5e1" + "test/core/end2end/fuzzers/client_fuzzer_corpus/caaf9a7751c0eccc34f0fc00a048012ab5ed2f37" ], "ci_platforms": [ "linux" @@ -61434,7 +63505,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/baa28a5baedb645f4430940a4b4b1142f4b03e0f" + "test/core/end2end/fuzzers/client_fuzzer_corpus/cb49955601d171fd14c9ac21137b221392c7dab1" ], "ci_platforms": [ "linux" @@ -61453,7 +63524,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/baf7839388e10ff0c410a58797482cb83693b309" + "test/core/end2end/fuzzers/client_fuzzer_corpus/cbaabef34763f2fd922e67ff5f2ea283347e9823" ], "ci_platforms": [ "linux" @@ -61472,7 +63543,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/bbc03bf6274a79528d43e200e8f1aaa770a155d6" + "test/core/end2end/fuzzers/client_fuzzer_corpus/cbe59c62c6d36c7307c438159327e320cd2fcf57" ], "ci_platforms": [ "linux" @@ -61491,7 +63562,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/bc9e17fed43c5d0668a87e8d6354c344c5b4d00b" + "test/core/end2end/fuzzers/client_fuzzer_corpus/cc4197d2381a75b674fe4944b8c690fe69a0b3b1" ], "ci_platforms": [ "linux" @@ -61510,7 +63581,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/bcc7340f8876a7dff381ca676efc39d30eed9f48" + "test/core/end2end/fuzzers/client_fuzzer_corpus/cceb4c620c02337138e489383db0d4f4e2c7a722" ], "ci_platforms": [ "linux" @@ -61529,7 +63600,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/bd0bef14e73aa1073eb5acb6e4cc901c976335f5" + "test/core/end2end/fuzzers/client_fuzzer_corpus/cd4be18b1ae872c40580edc4fe8cbdf1fe2a3881" ], "ci_platforms": [ "linux" @@ -61548,7 +63619,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/be3237e72b3d8d56eec0520145dd7d1a5064eede" + "test/core/end2end/fuzzers/client_fuzzer_corpus/cd76ed6aff7e074b0cfdcc6305ec4e453d8304bb" ], "ci_platforms": [ "linux" @@ -61567,7 +63638,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/be8cc5bab95e0ea7af538ca11175d710da6207d9" + "test/core/end2end/fuzzers/client_fuzzer_corpus/cdd1a4e358ee2396ece54b32c1f0a8d0a2e3f3dc" ], "ci_platforms": [ "linux" @@ -61586,7 +63657,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/be988fc0c00a8422020dea3dc72451b09e25e1ad" + "test/core/end2end/fuzzers/client_fuzzer_corpus/ce1c326f3b0147841550ce3b5126390764bae8e8" ], "ci_platforms": [ "linux" @@ -61605,7 +63676,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/beabbe93f1e9b2e56f729af30559ec03a00f53fa" + "test/core/end2end/fuzzers/client_fuzzer_corpus/ce990633c0f2b2a2ddb66144ed942d4bc9bcd8fb" ], "ci_platforms": [ "linux" @@ -61624,7 +63695,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/c0deaead93c9b3f2fc211fb7f0711ac192715a40" + "test/core/end2end/fuzzers/client_fuzzer_corpus/ceb297908903ba0fc24982ad4e6010e79dfbdd5e" ], "ci_platforms": [ "linux" @@ -61643,7 +63714,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/c24143cf5f6f77f002e0ab82e3060906e2e7d062" + "test/core/end2end/fuzzers/client_fuzzer_corpus/cedd54df6d34491dbf7843c2621d6818418aca02" ], "ci_platforms": [ "linux" @@ -61662,7 +63733,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/c3afa705dab02fea4d892134e7c01c3af270cb6e" + "test/core/end2end/fuzzers/client_fuzzer_corpus/cf75632ee185df2cbbbe148e2e1ad5410f11d361" ], "ci_platforms": [ "linux" @@ -61681,7 +63752,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/c3de41124a14ea562360aabc9e12666851bff2fe" + "test/core/end2end/fuzzers/client_fuzzer_corpus/cf922d44bf08d223d3ebcd37a7e77d3e43555d08" ], "ci_platforms": [ "linux" @@ -61700,7 +63771,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/c4e60ae7c05b12a90dd7c43fbc85ae4be7540f18" + "test/core/end2end/fuzzers/client_fuzzer_corpus/cfa40fccc5ea4304e83ca26f4e567765c2c08627" ], "ci_platforms": [ "linux" @@ -61719,7 +63790,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/c5d0c169d326d79fc4ee8521b282dbcbf33c1d5c" + "test/core/end2end/fuzzers/client_fuzzer_corpus/crash-12b69708d452b3cefe2da4a708a1030a661d37fc" ], "ci_platforms": [ "linux" @@ -61738,7 +63809,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/c5dfb4a82f91d07041d4b0ca6cc34cfa1e9c7199" + "test/core/end2end/fuzzers/client_fuzzer_corpus/crash-14ed70cd9ea7987cdd0c8f6e39398ee7c60ee2ff" ], "ci_platforms": [ "linux" @@ -61757,7 +63828,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/c685689a9d5b259afe237d857b7c6551dc95c176" + "test/core/end2end/fuzzers/client_fuzzer_corpus/crash-3bd02c98286bfa7be8e13c5500ddb587bba74fbb" ], "ci_platforms": [ "linux" @@ -61776,7 +63847,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/c77087b4651f4c62a780d77a3b4c233490244e8a" + "test/core/end2end/fuzzers/client_fuzzer_corpus/crash-53e93a1906d8442d058500e7107929cdd3e84ff8" ], "ci_platforms": [ "linux" @@ -61795,7 +63866,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/c784ad2e205ba49b5bb1302746723dbc57320981" + "test/core/end2end/fuzzers/client_fuzzer_corpus/crash-570c79624a2e4d36be107745d2b25e74464553af" ], "ci_platforms": [ "linux" @@ -61814,7 +63885,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/c84da54dacf04445b50448a70fb0ecdd08e9234a" + "test/core/end2end/fuzzers/client_fuzzer_corpus/crash-8e546795782dffa5d5f5e94c9510aac178fcee39" ], "ci_platforms": [ "linux" @@ -61833,7 +63904,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/c8cb20176e427d2e108187924f570ef1df6d440c" + "test/core/end2end/fuzzers/client_fuzzer_corpus/crash-d5af12c391b7bf0ce63ee3dc656ee4410fe496eb" ], "ci_platforms": [ "linux" @@ -61852,7 +63923,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/c916ea9c6901c1e77af764773bd2843baa2ebdc6" + "test/core/end2end/fuzzers/client_fuzzer_corpus/crash-d92bb454bbbd415175df541661e3696453ce3e43" ], "ci_platforms": [ "linux" @@ -61871,7 +63942,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/c97ebf43d8a5ce5cdb8e93a5d0362239c284ab4d" + "test/core/end2end/fuzzers/client_fuzzer_corpus/crash-e470e9fd09a5c9ef303813a40361c897650289fd" ], "ci_platforms": [ "linux" @@ -61890,7 +63961,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/ca0db313bf949ba3f87a5254646a7a7dc8a7f89d" + "test/core/end2end/fuzzers/client_fuzzer_corpus/crash-ff53a3d713e83ae945b8dd1782e21f5b51aa649a" ], "ci_platforms": [ "linux" @@ -61909,7 +63980,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/cbe59c62c6d36c7307c438159327e320cd2fcf57" + "test/core/end2end/fuzzers/client_fuzzer_corpus/d17e9507af1855fcf9eca78e2d25c8fb2c40a34c" ], "ci_platforms": [ "linux" @@ -61928,7 +63999,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/cc4197d2381a75b674fe4944b8c690fe69a0b3b1" + "test/core/end2end/fuzzers/client_fuzzer_corpus/d194592e6f471dd487ca2625e6c3da7802ea372f" ], "ci_platforms": [ "linux" @@ -61947,7 +64018,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/cceb4c620c02337138e489383db0d4f4e2c7a722" + "test/core/end2end/fuzzers/client_fuzzer_corpus/d1b1863b478e1ea71eafac9e03256080c8f0d1c5" ], "ci_platforms": [ "linux" @@ -61966,7 +64037,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/cd4be18b1ae872c40580edc4fe8cbdf1fe2a3881" + "test/core/end2end/fuzzers/client_fuzzer_corpus/d21ca2b01baa21a666257d1a1e0275587eeb565d" ], "ci_platforms": [ "linux" @@ -61985,7 +64056,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/cd76ed6aff7e074b0cfdcc6305ec4e453d8304bb" + "test/core/end2end/fuzzers/client_fuzzer_corpus/d24d1b9d754391fd0b11b0456a2e8c6050cadee6" ], "ci_platforms": [ "linux" @@ -62004,7 +64075,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/ce1c326f3b0147841550ce3b5126390764bae8e8" + "test/core/end2end/fuzzers/client_fuzzer_corpus/d250e525e8ff2ae4a9bddb2e478a90a1242155f0" ], "ci_platforms": [ "linux" @@ -62023,7 +64094,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/ce990633c0f2b2a2ddb66144ed942d4bc9bcd8fb" + "test/core/end2end/fuzzers/client_fuzzer_corpus/d257c41db22b60cd937de16b9d90a44b9fa8e426" ], "ci_platforms": [ "linux" @@ -62042,7 +64113,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/ceb297908903ba0fc24982ad4e6010e79dfbdd5e" + "test/core/end2end/fuzzers/client_fuzzer_corpus/d2df8e95436cf98ef2189191a75a3d9c78b1be6c" ], "ci_platforms": [ "linux" @@ -62061,7 +64132,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/cedd54df6d34491dbf7843c2621d6818418aca02" + "test/core/end2end/fuzzers/client_fuzzer_corpus/d2f71a800612876010558ce804c9a72ad0a1b9fc" ], "ci_platforms": [ "linux" @@ -62080,7 +64151,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/cf75632ee185df2cbbbe148e2e1ad5410f11d361" + "test/core/end2end/fuzzers/client_fuzzer_corpus/d3386702918881101368cdba2c4967e86ff3a7b9" ], "ci_platforms": [ "linux" @@ -62099,7 +64170,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/cfa40fccc5ea4304e83ca26f4e567765c2c08627" + "test/core/end2end/fuzzers/client_fuzzer_corpus/d363f288f48fba8fde401978b7e764295735645e" ], "ci_platforms": [ "linux" @@ -62118,7 +64189,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/crash-12b69708d452b3cefe2da4a708a1030a661d37fc" + "test/core/end2end/fuzzers/client_fuzzer_corpus/d36e015b1e14ecb9559d67bb09c2851699f0aa35" ], "ci_platforms": [ "linux" @@ -62137,7 +64208,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/crash-14ed70cd9ea7987cdd0c8f6e39398ee7c60ee2ff" + "test/core/end2end/fuzzers/client_fuzzer_corpus/d46c3dcede830286dd9f4a1ba02a20a0b1430664" ], "ci_platforms": [ "linux" @@ -62156,7 +64227,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/crash-3bd02c98286bfa7be8e13c5500ddb587bba74fbb" + "test/core/end2end/fuzzers/client_fuzzer_corpus/d49450b97f489f0dea74a9f83c71abeba1066d3c" ], "ci_platforms": [ "linux" @@ -62175,7 +64246,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/crash-53e93a1906d8442d058500e7107929cdd3e84ff8" + "test/core/end2end/fuzzers/client_fuzzer_corpus/d4a72650e8218ec551fef6560ddd136d52828a4e" ], "ci_platforms": [ "linux" @@ -62194,7 +64265,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/crash-570c79624a2e4d36be107745d2b25e74464553af" + "test/core/end2end/fuzzers/client_fuzzer_corpus/d4a744ef6dcef5cf08d5289e167b26270d39e9f2" ], "ci_platforms": [ "linux" @@ -62213,7 +64284,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/crash-8e546795782dffa5d5f5e94c9510aac178fcee39" + "test/core/end2end/fuzzers/client_fuzzer_corpus/d5a85ad91cfde27a96960b2e783d2ee43c50dcb9" ], "ci_platforms": [ "linux" @@ -62232,7 +64303,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/crash-d5af12c391b7bf0ce63ee3dc656ee4410fe496eb" + "test/core/end2end/fuzzers/client_fuzzer_corpus/d60469c0b5b385f20d55aa5cca55bc2c801f3b95" ], "ci_platforms": [ "linux" @@ -62251,7 +64322,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/crash-d92bb454bbbd415175df541661e3696453ce3e43" + "test/core/end2end/fuzzers/client_fuzzer_corpus/d637cc9387087de633b9db535d19f64795c43be1" ], "ci_platforms": [ "linux" @@ -62270,7 +64341,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/crash-e470e9fd09a5c9ef303813a40361c897650289fd" + "test/core/end2end/fuzzers/client_fuzzer_corpus/d70b2046ee62676b525490b70812c2157e5a3585" ], "ci_platforms": [ "linux" @@ -62289,7 +64360,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/d194592e6f471dd487ca2625e6c3da7802ea372f" + "test/core/end2end/fuzzers/client_fuzzer_corpus/d727b7edb460c549d7b12b90f581048c9f4747e5" ], "ci_platforms": [ "linux" @@ -62308,7 +64379,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/d1b1863b478e1ea71eafac9e03256080c8f0d1c5" + "test/core/end2end/fuzzers/client_fuzzer_corpus/d88bb0b7ff687af84f33e6af22d3516fcdac5534" ], "ci_platforms": [ "linux" @@ -62327,7 +64398,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/d21ca2b01baa21a666257d1a1e0275587eeb565d" + "test/core/end2end/fuzzers/client_fuzzer_corpus/d89026894e6c5f8b5c88dec12950f56c4b6924ba" ], "ci_platforms": [ "linux" @@ -62346,7 +64417,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/d24d1b9d754391fd0b11b0456a2e8c6050cadee6" + "test/core/end2end/fuzzers/client_fuzzer_corpus/d895ece988ad4712b87de8aa9bc273eee315e8b8" ], "ci_platforms": [ "linux" @@ -62365,7 +64436,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/d250e525e8ff2ae4a9bddb2e478a90a1242155f0" + "test/core/end2end/fuzzers/client_fuzzer_corpus/d90c312791129dee8c5f85cb3308323d0c39b70d" ], "ci_platforms": [ "linux" @@ -62384,7 +64455,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/d257c41db22b60cd937de16b9d90a44b9fa8e426" + "test/core/end2end/fuzzers/client_fuzzer_corpus/d91281daad9b821294db204dfc244b2d0d5496e4" ], "ci_platforms": [ "linux" @@ -62403,7 +64474,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/d2df8e95436cf98ef2189191a75a3d9c78b1be6c" + "test/core/end2end/fuzzers/client_fuzzer_corpus/da322a6b88da87babb52d1527fe54cb4ac214b32" ], "ci_platforms": [ "linux" @@ -62422,7 +64493,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/d2f71a800612876010558ce804c9a72ad0a1b9fc" + "test/core/end2end/fuzzers/client_fuzzer_corpus/da424090e1b94c5d0e91e26f3f3dd6c4af18fcd5" ], "ci_platforms": [ "linux" @@ -62441,7 +64512,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/d3386702918881101368cdba2c4967e86ff3a7b9" + "test/core/end2end/fuzzers/client_fuzzer_corpus/da4d300d0a8e6f803ec053e3e7689c4b91eaef90" ], "ci_platforms": [ "linux" @@ -62460,7 +64531,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/d363f288f48fba8fde401978b7e764295735645e" + "test/core/end2end/fuzzers/client_fuzzer_corpus/da538941f1613c627523cb1be71eb220d1ca2579" ], "ci_platforms": [ "linux" @@ -62479,7 +64550,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/d36e015b1e14ecb9559d67bb09c2851699f0aa35" + "test/core/end2end/fuzzers/client_fuzzer_corpus/da8d4c7f02dbeaa543c159b3a4e527059978a429" ], "ci_platforms": [ "linux" @@ -62498,7 +64569,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/d49450b97f489f0dea74a9f83c71abeba1066d3c" + "test/core/end2end/fuzzers/client_fuzzer_corpus/data_frame.bin" ], "ci_platforms": [ "linux" @@ -62517,7 +64588,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/d4a72650e8218ec551fef6560ddd136d52828a4e" + "test/core/end2end/fuzzers/client_fuzzer_corpus/db3a30a6d8e605dd587e51b214c42f68bc43cf19" ], "ci_platforms": [ "linux" @@ -62536,7 +64607,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/d60469c0b5b385f20d55aa5cca55bc2c801f3b95" + "test/core/end2end/fuzzers/client_fuzzer_corpus/dc4a248fa4c903ce3a571dd18aea575019445740" ], "ci_platforms": [ "linux" @@ -62555,7 +64626,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/d637cc9387087de633b9db535d19f64795c43be1" + "test/core/end2end/fuzzers/client_fuzzer_corpus/dc7ebba06558484af10b5aafd01ec4fd59276b12" ], "ci_platforms": [ "linux" @@ -62574,7 +64645,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/d70b2046ee62676b525490b70812c2157e5a3585" + "test/core/end2end/fuzzers/client_fuzzer_corpus/dc815fd6d5e817898238481472f359bc50b510c4" ], "ci_platforms": [ "linux" @@ -62593,7 +64664,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/d727b7edb460c549d7b12b90f581048c9f4747e5" + "test/core/end2end/fuzzers/client_fuzzer_corpus/dcb06a6e34cbed15515e5b3581ca666f704777bd" ], "ci_platforms": [ "linux" @@ -62612,7 +64683,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/d89026894e6c5f8b5c88dec12950f56c4b6924ba" + "test/core/end2end/fuzzers/client_fuzzer_corpus/dccd1fd6d3394f5f68c87950ed7356a2e9ef0f6f" ], "ci_platforms": [ "linux" @@ -62631,7 +64702,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/d90c312791129dee8c5f85cb3308323d0c39b70d" + "test/core/end2end/fuzzers/client_fuzzer_corpus/dd5ac34f5b220970447b2733848de78570c47883" ], "ci_platforms": [ "linux" @@ -62650,7 +64721,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/d91281daad9b821294db204dfc244b2d0d5496e4" + "test/core/end2end/fuzzers/client_fuzzer_corpus/dd662353bad317cee7d16191a39e094bfa4898f2" ], "ci_platforms": [ "linux" @@ -62669,7 +64740,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/da322a6b88da87babb52d1527fe54cb4ac214b32" + "test/core/end2end/fuzzers/client_fuzzer_corpus/df684493457bc8d87dec2ca0825f7b43978fecfd" ], "ci_platforms": [ "linux" @@ -62688,7 +64759,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/da4d300d0a8e6f803ec053e3e7689c4b91eaef90" + "test/core/end2end/fuzzers/client_fuzzer_corpus/e0d1ee5e2e169dcae87f790f5c27e84a3453cedb" ], "ci_platforms": [ "linux" @@ -62707,7 +64778,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/da538941f1613c627523cb1be71eb220d1ca2579" + "test/core/end2end/fuzzers/client_fuzzer_corpus/e18cab69ad5cc17c88f8b56ca9929ca8af3eed30" ], "ci_platforms": [ "linux" @@ -62726,7 +64797,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/da8d4c7f02dbeaa543c159b3a4e527059978a429" + "test/core/end2end/fuzzers/client_fuzzer_corpus/e1bd70aa5c802cd4462ff4833c09ed432ce4c9fa" ], "ci_platforms": [ "linux" @@ -62745,7 +64816,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/data_frame.bin" + "test/core/end2end/fuzzers/client_fuzzer_corpus/e1f2e203d39ab2509d4a67f7a44265b1e6364334" ], "ci_platforms": [ "linux" @@ -62764,7 +64835,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/dc4a248fa4c903ce3a571dd18aea575019445740" + "test/core/end2end/fuzzers/client_fuzzer_corpus/e262f378a3d27bc519d472ce3650bdffcd48a055" ], "ci_platforms": [ "linux" @@ -62783,7 +64854,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/dc7ebba06558484af10b5aafd01ec4fd59276b12" + "test/core/end2end/fuzzers/client_fuzzer_corpus/e309e21c69e4b96ab37f675f4e87a52453512ef8" ], "ci_platforms": [ "linux" @@ -62802,7 +64873,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/dc815fd6d5e817898238481472f359bc50b510c4" + "test/core/end2end/fuzzers/client_fuzzer_corpus/e30c4ef6423bd4d872792fbd6954ff8e47d31a97" ], "ci_platforms": [ "linux" @@ -62821,7 +64892,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/dcb06a6e34cbed15515e5b3581ca666f704777bd" + "test/core/end2end/fuzzers/client_fuzzer_corpus/e3422e8f5d63a9ef180aab552353955c7aba90b0" ], "ci_platforms": [ "linux" @@ -62840,7 +64911,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/dccd1fd6d3394f5f68c87950ed7356a2e9ef0f6f" + "test/core/end2end/fuzzers/client_fuzzer_corpus/e3d12a2385b75443fe38d989e77c252e1f3cdb6d" ], "ci_platforms": [ "linux" @@ -62859,7 +64930,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/dd5ac34f5b220970447b2733848de78570c47883" + "test/core/end2end/fuzzers/client_fuzzer_corpus/e40b0fa5d814be8f2081ca2c8e0a4090d4893831" ], "ci_platforms": [ "linux" @@ -62878,7 +64949,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/dd662353bad317cee7d16191a39e094bfa4898f2" + "test/core/end2end/fuzzers/client_fuzzer_corpus/e442f9fd63bc5345de1c14803d4ca4bb6f1152cf" ], "ci_platforms": [ "linux" @@ -62897,7 +64968,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/df684493457bc8d87dec2ca0825f7b43978fecfd" + "test/core/end2end/fuzzers/client_fuzzer_corpus/e4c0e27cfd3690b8255a8214d6dd055385d1d24e" ], "ci_platforms": [ "linux" @@ -62916,7 +64987,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/e0d1ee5e2e169dcae87f790f5c27e84a3453cedb" + "test/core/end2end/fuzzers/client_fuzzer_corpus/e4dc0a111e77dc495c5db07df5e2917adb674697" ], "ci_platforms": [ "linux" @@ -62935,7 +65006,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/e18cab69ad5cc17c88f8b56ca9929ca8af3eed30" + "test/core/end2end/fuzzers/client_fuzzer_corpus/e4f55281c481484bd9edc28fd10df0c2e0f7d546" ], "ci_platforms": [ "linux" @@ -62954,7 +65025,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/e1bd70aa5c802cd4462ff4833c09ed432ce4c9fa" + "test/core/end2end/fuzzers/client_fuzzer_corpus/e5a7c086208248a15ee6fa5195fc4ce22469de15" ], "ci_platforms": [ "linux" @@ -62973,7 +65044,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/e1f2e203d39ab2509d4a67f7a44265b1e6364334" + "test/core/end2end/fuzzers/client_fuzzer_corpus/e5ac3394971400b6636d029aec7ec665a94ecf29" ], "ci_platforms": [ "linux" @@ -62992,7 +65063,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/e262f378a3d27bc519d472ce3650bdffcd48a055" + "test/core/end2end/fuzzers/client_fuzzer_corpus/e61f728210ce72ed8b2c066bd1b1ecf9e6824b77" ], "ci_platforms": [ "linux" @@ -63011,7 +65082,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/e309e21c69e4b96ab37f675f4e87a52453512ef8" + "test/core/end2end/fuzzers/client_fuzzer_corpus/e6a08259a7d47601eab5c0249cb6547024e002c7" ], "ci_platforms": [ "linux" @@ -63030,7 +65101,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/e30c4ef6423bd4d872792fbd6954ff8e47d31a97" + "test/core/end2end/fuzzers/client_fuzzer_corpus/e6b3c920b47e00055226d49b9f715c5d4353e3e5" ], "ci_platforms": [ "linux" @@ -63049,7 +65120,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/e3422e8f5d63a9ef180aab552353955c7aba90b0" + "test/core/end2end/fuzzers/client_fuzzer_corpus/e6c52f2f31db7595d1ecde2939a7390777f15182" ], "ci_platforms": [ "linux" @@ -63068,7 +65139,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/e40b0fa5d814be8f2081ca2c8e0a4090d4893831" + "test/core/end2end/fuzzers/client_fuzzer_corpus/e6f5cc0702a5f38b9e7339849e1dd2e4001e547d" ], "ci_platforms": [ "linux" @@ -63087,7 +65158,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/e442f9fd63bc5345de1c14803d4ca4bb6f1152cf" + "test/core/end2end/fuzzers/client_fuzzer_corpus/e7c26599fb2e2b031346ff1ba09294fd758f7abe" ], "ci_platforms": [ "linux" @@ -63106,7 +65177,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/e4c0e27cfd3690b8255a8214d6dd055385d1d24e" + "test/core/end2end/fuzzers/client_fuzzer_corpus/e8323c817d18f0c920d3cf53be41a9bc0fd64b76" ], "ci_platforms": [ "linux" @@ -63125,7 +65196,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/e4dc0a111e77dc495c5db07df5e2917adb674697" + "test/core/end2end/fuzzers/client_fuzzer_corpus/e969affd8af10a1b87dc63afd3b29cce3e58fbb2" ], "ci_platforms": [ "linux" @@ -63144,7 +65215,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/e5a7c086208248a15ee6fa5195fc4ce22469de15" + "test/core/end2end/fuzzers/client_fuzzer_corpus/e9f7f7f258c72222397a960652c01d2a37e2afe3" ], "ci_platforms": [ "linux" @@ -63163,7 +65234,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/e5ac3394971400b6636d029aec7ec665a94ecf29" + "test/core/end2end/fuzzers/client_fuzzer_corpus/ea46b684f1e67a27c231f2d536c41da631189b9c" ], "ci_platforms": [ "linux" @@ -63182,7 +65253,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/e61f728210ce72ed8b2c066bd1b1ecf9e6824b77" + "test/core/end2end/fuzzers/client_fuzzer_corpus/eb969b9ab1b0d6b5d197795223ba7a091ebd8460" ], "ci_platforms": [ "linux" @@ -63201,7 +65272,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/e6a08259a7d47601eab5c0249cb6547024e002c7" + "test/core/end2end/fuzzers/client_fuzzer_corpus/ebb0786acc21c6185356eae9a62490a03fddd1f2" ], "ci_platforms": [ "linux" @@ -63220,7 +65291,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/e6b3c920b47e00055226d49b9f715c5d4353e3e5" + "test/core/end2end/fuzzers/client_fuzzer_corpus/ec180175f0edea0a6c3eea2ae719b006bc029ff8" ], "ci_platforms": [ "linux" @@ -63239,7 +65310,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/e6f5cc0702a5f38b9e7339849e1dd2e4001e547d" + "test/core/end2end/fuzzers/client_fuzzer_corpus/ed6358fbe6721c9ac01a6f4cab4d2df377eb1f11" ], "ci_platforms": [ "linux" @@ -63258,7 +65329,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/e7c26599fb2e2b031346ff1ba09294fd758f7abe" + "test/core/end2end/fuzzers/client_fuzzer_corpus/ee436743977b8e31feec22a91b1ce23dee96665e" ], "ci_platforms": [ "linux" @@ -63277,7 +65348,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/e8323c817d18f0c920d3cf53be41a9bc0fd64b76" + "test/core/end2end/fuzzers/client_fuzzer_corpus/ef1984d6146670122c7a7246374bca460e7284e5" ], "ci_platforms": [ "linux" @@ -63296,7 +65367,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/e969affd8af10a1b87dc63afd3b29cce3e58fbb2" + "test/core/end2end/fuzzers/client_fuzzer_corpus/eff9ad9144a2953fadc019fe72eb1cc3447c33fb" ], "ci_platforms": [ "linux" @@ -63315,7 +65386,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/e9f7f7f258c72222397a960652c01d2a37e2afe3" + "test/core/end2end/fuzzers/client_fuzzer_corpus/empty" ], "ci_platforms": [ "linux" @@ -63334,7 +65405,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/ea46b684f1e67a27c231f2d536c41da631189b9c" + "test/core/end2end/fuzzers/client_fuzzer_corpus/f03120d1a8376638e071735bf4746454b6ede389" ], "ci_platforms": [ "linux" @@ -63353,7 +65424,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/eb969b9ab1b0d6b5d197795223ba7a091ebd8460" + "test/core/end2end/fuzzers/client_fuzzer_corpus/f09410ab7bc19ee1ff206f94e8eec2931faef15f" ], "ci_platforms": [ "linux" @@ -63372,7 +65443,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/ebb0786acc21c6185356eae9a62490a03fddd1f2" + "test/core/end2end/fuzzers/client_fuzzer_corpus/f09cd3e3a16658174717668e51e7382e491df1da" ], "ci_platforms": [ "linux" @@ -63391,7 +65462,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/ec180175f0edea0a6c3eea2ae719b006bc029ff8" + "test/core/end2end/fuzzers/client_fuzzer_corpus/f11abb090bae8cdac1f7d9a2e344f2def0e50066" ], "ci_platforms": [ "linux" @@ -63410,7 +65481,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/ed6358fbe6721c9ac01a6f4cab4d2df377eb1f11" + "test/core/end2end/fuzzers/client_fuzzer_corpus/f1b9b6803e41beabb1a762d511fc148116e09e78" ], "ci_platforms": [ "linux" @@ -63429,7 +65500,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/ee436743977b8e31feec22a91b1ce23dee96665e" + "test/core/end2end/fuzzers/client_fuzzer_corpus/f24f925945aaf5e8b5ee470935e5aa7f847e7a72" ], "ci_platforms": [ "linux" @@ -63448,7 +65519,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/ef1984d6146670122c7a7246374bca460e7284e5" + "test/core/end2end/fuzzers/client_fuzzer_corpus/f2a6bb4e0137541e2b140b976764377d07d822d6" ], "ci_platforms": [ "linux" @@ -63467,7 +65538,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/eff9ad9144a2953fadc019fe72eb1cc3447c33fb" + "test/core/end2end/fuzzers/client_fuzzer_corpus/f41f9319bda14ef21b925c46945b30728503dfaf" ], "ci_platforms": [ "linux" @@ -63486,7 +65557,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/empty" + "test/core/end2end/fuzzers/client_fuzzer_corpus/f4499e3d4bf60ae3ae929c485a13ea4dc2713369" ], "ci_platforms": [ "linux" @@ -63505,7 +65576,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/f03120d1a8376638e071735bf4746454b6ede389" + "test/core/end2end/fuzzers/client_fuzzer_corpus/f4ae2a2b692bfa83cdde75d007813426e14daef7" ], "ci_platforms": [ "linux" @@ -63524,7 +65595,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/f09410ab7bc19ee1ff206f94e8eec2931faef15f" + "test/core/end2end/fuzzers/client_fuzzer_corpus/f5a629c8fd5720236b66a875e96ea22e29c45965" ], "ci_platforms": [ "linux" @@ -63543,7 +65614,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/f1b9b6803e41beabb1a762d511fc148116e09e78" + "test/core/end2end/fuzzers/client_fuzzer_corpus/f5b1eab444efb2664a295d4e6d087eb209c0c480" ], "ci_platforms": [ "linux" @@ -63562,7 +65633,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/f24f925945aaf5e8b5ee470935e5aa7f847e7a72" + "test/core/end2end/fuzzers/client_fuzzer_corpus/f6627c55881fe4f0c8e6999980fb226836e6f5ce" ], "ci_platforms": [ "linux" @@ -63581,7 +65652,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/f2a6bb4e0137541e2b140b976764377d07d822d6" + "test/core/end2end/fuzzers/client_fuzzer_corpus/f66305230042fa83fcd1b98c469d90ffef3ff6da" ], "ci_platforms": [ "linux" @@ -63600,7 +65671,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/f41f9319bda14ef21b925c46945b30728503dfaf" + "test/core/end2end/fuzzers/client_fuzzer_corpus/f6af3f46aacee395877d7f7909f8e412a6538efb" ], "ci_platforms": [ "linux" @@ -63619,7 +65690,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/f4499e3d4bf60ae3ae929c485a13ea4dc2713369" + "test/core/end2end/fuzzers/client_fuzzer_corpus/f74143e8160754e40eb4d21a182c970210707979" ], "ci_platforms": [ "linux" @@ -63638,7 +65709,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/f5b1eab444efb2664a295d4e6d087eb209c0c480" + "test/core/end2end/fuzzers/client_fuzzer_corpus/f7812b2aca4d12ffbdac67bcacc41b34524de6cb" ], "ci_platforms": [ "linux" @@ -63657,7 +65728,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/f66305230042fa83fcd1b98c469d90ffef3ff6da" + "test/core/end2end/fuzzers/client_fuzzer_corpus/f7aeceaf0b6d971038a677994b5d080fa0e18011" ], "ci_platforms": [ "linux" @@ -63676,7 +65747,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/f6af3f46aacee395877d7f7909f8e412a6538efb" + "test/core/end2end/fuzzers/client_fuzzer_corpus/f803c87a92662898e2c8c847787b56d2c31f63b3" ], "ci_platforms": [ "linux" @@ -63695,7 +65766,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/f74143e8160754e40eb4d21a182c970210707979" + "test/core/end2end/fuzzers/client_fuzzer_corpus/f8467d9574de94b9bb904f75a6a7e2405c36f105" ], "ci_platforms": [ "linux" @@ -63714,7 +65785,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/f7812b2aca4d12ffbdac67bcacc41b34524de6cb" + "test/core/end2end/fuzzers/client_fuzzer_corpus/f84f5d6188cf099465f0b70337b87ad8aa8efb78" ], "ci_platforms": [ "linux" @@ -63733,7 +65804,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/f8467d9574de94b9bb904f75a6a7e2405c36f105" + "test/core/end2end/fuzzers/client_fuzzer_corpus/f89ad475ff51a5a9fe18603df833453bed320f36" ], "ci_platforms": [ "linux" @@ -63752,7 +65823,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/f84f5d6188cf099465f0b70337b87ad8aa8efb78" + "test/core/end2end/fuzzers/client_fuzzer_corpus/f8fb1348ec3ceeb75c2a03df6a2ead0de6f4127a" ], "ci_platforms": [ "linux" @@ -63771,7 +65842,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/f8fb1348ec3ceeb75c2a03df6a2ead0de6f4127a" + "test/core/end2end/fuzzers/client_fuzzer_corpus/f91f76fa45a23adfed48a10ec9512cf16bfb6636" ], "ci_platforms": [ "linux" @@ -63790,7 +65861,7 @@ }, { "args": [ - "test/core/end2end/fuzzers/client_fuzzer_corpus/f91f76fa45a23adfed48a10ec9512cf16bfb6636" + "test/core/end2end/fuzzers/client_fuzzer_corpus/f9583b3a39c1aecbba6e81d71e7fe9b9519c8b08" ], "ci_platforms": [ "linux" @@ -64016,6 +66087,25 @@ ], "uses_polling": false }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/ffd52d31f9c59a346aa195a683f077dda5ecef6b" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, { "args": [ "test/core/end2end/fuzzers/client_fuzzer_corpus/hdr_frame.bin" -- cgit v1.2.3 From a7cd41cc46bf60aed17dea8ea2d3787814c45475 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 31 Aug 2016 12:59:24 -0700 Subject: Note polling coverage when taking combiner locks: resolves offload issues --- .../transport/chttp2/transport/chttp2_transport.c | 72 +++++++------ .../ext/transport/chttp2/transport/frame_data.c | 7 +- src/core/ext/transport/chttp2/transport/internal.h | 3 +- .../ext/transport/chttp2/transport/stream_lists.c | 5 +- src/core/lib/iomgr/closure.c | 6 +- src/core/lib/iomgr/closure.h | 5 +- src/core/lib/iomgr/combiner.c | 112 +++++++++++---------- src/core/lib/iomgr/combiner.h | 7 +- src/core/lib/iomgr/exec_ctx.c | 12 +-- src/core/lib/iomgr/workqueue_posix.c | 4 +- src/core/lib/surface/call.c | 1 + src/core/lib/transport/transport.h | 4 + test/core/iomgr/combiner_test.c | 12 +-- 13 files changed, 128 insertions(+), 122 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index f774cce690..fb72fd693a 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -372,7 +372,7 @@ static void destroy_transport(grpc_exec_ctx *exec_ctx, grpc_transport *gt) { grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt; grpc_combiner_execute(exec_ctx, t->combiner, grpc_closure_create(destroy_transport_locked, t), - GRPC_ERROR_NONE); + GRPC_ERROR_NONE, false); } static void close_transport_locked(grpc_exec_ctx *exec_ctx, @@ -512,7 +512,7 @@ static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, s->destroy_stream_arg = and_free_memory; grpc_closure_init(&s->destroy_stream, destroy_stream_locked, s); grpc_combiner_execute(exec_ctx, t->combiner, &s->destroy_stream, - GRPC_ERROR_NONE); + GRPC_ERROR_NONE, false); GPR_TIMER_END("destroy_stream", 0); } @@ -546,13 +546,15 @@ void grpc_chttp2_initiate_write(grpc_exec_ctx *exec_ctx, switch (t->write_state) { case GRPC_CHTTP2_WRITE_STATE_IDLE: t->write_state = GRPC_CHTTP2_WRITE_STATE_WRITING; + gpr_log(GPR_DEBUG, "W:%s:%p: IDLE -> WRITING", t->is_client ? "CLIENT" : "SERVER", t); GRPC_CHTTP2_REF_TRANSPORT(t, "writing"); grpc_combiner_execute_finally(exec_ctx, t->combiner, &t->write_action_begin_locked, - GRPC_ERROR_NONE, false); + GRPC_ERROR_NONE); break; case GRPC_CHTTP2_WRITE_STATE_WRITING: t->write_state = GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_TO_COME; + gpr_log(GPR_DEBUG, "W:%s:%p: WRITING -> WRITING_MORE", t->is_client ? "CLIENT" : "SERVER", t); break; case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_TO_COME: break; @@ -576,8 +578,11 @@ static void write_action_begin_locked(grpc_exec_ctx *exec_ctx, void *gt, grpc_chttp2_transport *t = gt; GPR_ASSERT(t->write_state != GRPC_CHTTP2_WRITE_STATE_IDLE); if (!t->closed && grpc_chttp2_begin_write(exec_ctx, t)) { + t->write_state = GRPC_CHTTP2_WRITE_STATE_WRITING; + gpr_log(GPR_DEBUG, "W:%s:%p: WRITING|WRITING_MORE -> WRITING", t->is_client ? "CLIENT" : "SERVER", t); grpc_exec_ctx_sched(exec_ctx, &t->write_action, GRPC_ERROR_NONE, NULL); } else { + gpr_log(GPR_DEBUG, "W:%s:%p: WRITING|WRITING_MORE -> IDLE", t->is_client ? "CLIENT" : "SERVER", t); t->write_state = GRPC_CHTTP2_WRITE_STATE_IDLE; GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "writing"); } @@ -596,7 +601,7 @@ static void write_action_end(grpc_exec_ctx *exec_ctx, void *gt, grpc_chttp2_transport *t = gt; GPR_TIMER_BEGIN("write_action_end", 0); grpc_combiner_execute(exec_ctx, t->combiner, &t->write_action_end_locked, - GRPC_ERROR_REF(error)); + GRPC_ERROR_REF(error), false); GPR_TIMER_END("write_action_end", 0); } @@ -617,13 +622,15 @@ static void write_action_end_locked(grpc_exec_ctx *exec_ctx, void *tp, case GRPC_CHTTP2_WRITE_STATE_WRITING: GPR_TIMER_MARK("state=writing", 0); t->write_state = GRPC_CHTTP2_WRITE_STATE_IDLE; + gpr_log(GPR_DEBUG, "W:%s:%p: WRITING -> IDLE", t->is_client ? "CLIENT" : "SERVER", t); break; case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_TO_COME: GPR_TIMER_MARK("state=writing_stale_with_poller", 0); t->write_state = GRPC_CHTTP2_WRITE_STATE_WRITING; + gpr_log(GPR_DEBUG, "W:%s:%p: WRITING_MORE -> WRITING", t->is_client ? "CLIENT" : "SERVER", t); GRPC_CHTTP2_REF_TRANSPORT(t, "writing"); - grpc_combiner_execute_finally(exec_ctx, t->combiner, &t->write_action, - GRPC_ERROR_NONE, false); + grpc_combiner_execute_finally(exec_ctx, t->combiner, &t->write_action_begin_locked, + GRPC_ERROR_NONE); break; } @@ -742,20 +749,22 @@ void grpc_chttp2_complete_closure_step(grpc_exec_ctx *exec_ctx, closure->next_data.scratch - CLOSURE_BARRIER_FIRST_REF_BIT); closure->next_data.scratch -= CLOSURE_BARRIER_FIRST_REF_BIT; if (error != GRPC_ERROR_NONE) { - if (closure->error == GRPC_ERROR_NONE) { - closure->error = + if (closure->error_data.error == GRPC_ERROR_NONE) { + closure->error_data.error = GRPC_ERROR_CREATE("Error in HTTP transport completing operation"); - closure->error = grpc_error_set_str( - closure->error, GRPC_ERROR_STR_TARGET_ADDRESS, t->peer_string); + closure->error_data.error = + grpc_error_set_str(closure->error_data.error, + GRPC_ERROR_STR_TARGET_ADDRESS, t->peer_string); } - closure->error = grpc_error_add_child(closure->error, error); + closure->error_data.error = + grpc_error_add_child(closure->error_data.error, error); } if (closure->next_data.scratch < CLOSURE_BARRIER_FIRST_REF_BIT) { if (closure->next_data.scratch & CLOSURE_BARRIER_STATS_BIT) { grpc_transport_move_stats(&s->stats, s->collecting_stats); s->collecting_stats = NULL; } - grpc_exec_ctx_sched(exec_ctx, closure, closure->error, NULL); + grpc_exec_ctx_sched(exec_ctx, closure, closure->error_data.error, NULL); } *pclosure = NULL; } @@ -842,7 +851,8 @@ static void complete_fetch(grpc_exec_ctx *exec_ctx, void *gs, grpc_chttp2_stream *s = gs; grpc_chttp2_transport *t = s->t; grpc_combiner_execute(exec_ctx, t->combiner, &s->complete_fetch_locked, - GRPC_ERROR_REF(error)); + GRPC_ERROR_REF(error), + s->complete_fetch_covered_by_poller); } static void do_nothing(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {} @@ -873,7 +883,7 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, /* use final_data as a barrier until enqueue time; the inital counter is dropped at the end of this function */ on_complete->next_data.scratch = CLOSURE_BARRIER_FIRST_REF_BIT; - on_complete->error = GRPC_ERROR_NONE; + on_complete->error_data.error = GRPC_ERROR_NONE; if (op->collect_stats != NULL) { GPR_ASSERT(s->collecting_stats == NULL); @@ -959,6 +969,7 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, s->fetched_send_message_length = 0; s->fetching_slice_end_offset = (ssize_t)s->flow_controlled_buffer.length + (ssize_t)len; + s->complete_fetch_covered_by_poller = op->covered_by_poller; if (flags & GRPC_WRITE_BUFFER_HINT) { s->fetching_slice_end_offset -= 65536; } @@ -1063,7 +1074,7 @@ static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, op->transport_private.args[1] = gs; GRPC_CHTTP2_STREAM_REF(s, "perform_stream_op"); grpc_combiner_execute(exec_ctx, t->combiner, &op->transport_private.closure, - GRPC_ERROR_NONE); + GRPC_ERROR_NONE, op->covered_by_poller); GPR_TIMER_END("perform_stream_op", 0); } @@ -1173,7 +1184,7 @@ static void perform_transport_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, op); GRPC_CHTTP2_REF_TRANSPORT(t, "transport_op"); grpc_combiner_execute(exec_ctx, t->combiner, &op->transport_private.closure, - GRPC_ERROR_NONE); + GRPC_ERROR_NONE, false); } /******************************************************************************* @@ -1265,7 +1276,7 @@ static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, } if (s->data_parser.parsing_frame != NULL) { grpc_chttp2_incoming_byte_stream_finished( - exec_ctx, s->data_parser.parsing_frame, GRPC_ERROR_REF(error), 0); + exec_ctx, s->data_parser.parsing_frame, GRPC_ERROR_REF(error)); s->data_parser.parsing_frame = NULL; } @@ -1637,7 +1648,7 @@ static void read_action_begin(grpc_exec_ctx *exec_ctx, void *tp, GPR_TIMER_BEGIN("reading_action", 0); grpc_chttp2_transport *t = tp; grpc_combiner_execute(exec_ctx, t->combiner, &t->read_action_locked, - GRPC_ERROR_REF(error)); + GRPC_ERROR_REF(error), false); GPR_TIMER_END("reading_action", 0); } @@ -1868,7 +1879,7 @@ static int incoming_byte_stream_next(grpc_exec_ctx *exec_ctx, grpc_closure_init(&bs->next_action.closure, incoming_byte_stream_next_locked, bs); grpc_combiner_execute(exec_ctx, bs->transport->combiner, - &bs->next_action.closure, GRPC_ERROR_NONE); + &bs->next_action.closure, GRPC_ERROR_NONE, false); GPR_TIMER_END("incoming_byte_stream_next", 0); return 0; } @@ -1893,7 +1904,7 @@ static void incoming_byte_stream_destroy(grpc_exec_ctx *exec_ctx, grpc_closure_init(&bs->destroy_action, incoming_byte_stream_destroy_locked, bs); grpc_combiner_execute(exec_ctx, bs->transport->combiner, &bs->destroy_action, - GRPC_ERROR_NONE); + GRPC_ERROR_NONE, false); GPR_TIMER_END("incoming_byte_stream_destroy", 0); } @@ -1916,9 +1927,9 @@ void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, gpr_mu_unlock(&bs->slice_mu); } -static void incoming_byte_stream_finished_locked(grpc_exec_ctx *exec_ctx, - void *bsp, grpc_error *error) { - grpc_chttp2_incoming_byte_stream *bs = bsp; +void grpc_chttp2_incoming_byte_stream_finished( + grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, + grpc_error *error) { if (error != GRPC_ERROR_NONE) { grpc_exec_ctx_sched(exec_ctx, bs->on_next, GRPC_ERROR_REF(error), NULL); bs->on_next = NULL; @@ -1928,21 +1939,6 @@ static void incoming_byte_stream_finished_locked(grpc_exec_ctx *exec_ctx, incoming_byte_stream_unref(exec_ctx, bs); } -void grpc_chttp2_incoming_byte_stream_finished( - grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, - grpc_error *error, int from_parsing_thread) { - GPR_TIMER_BEGIN("grpc_chttp2_incoming_byte_stream_finished", 0); - if (from_parsing_thread) { - grpc_closure_init(&bs->finished_action, - incoming_byte_stream_finished_locked, bs); - grpc_combiner_execute(exec_ctx, bs->transport->combiner, - &bs->finished_action, GRPC_ERROR_REF(error)); - } else { - incoming_byte_stream_finished_locked(exec_ctx, bs, error); - } - GPR_TIMER_END("grpc_chttp2_incoming_byte_stream_finished", 0); -} - grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s, uint32_t frame_size, uint32_t flags) { diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c index e340b2fb06..bcb0ab0f99 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.c +++ b/src/core/ext/transport/chttp2/transport/frame_data.c @@ -53,8 +53,7 @@ void grpc_chttp2_data_parser_destroy(grpc_exec_ctx *exec_ctx, grpc_chttp2_data_parser *parser) { if (parser->parsing_frame != NULL) { grpc_chttp2_incoming_byte_stream_finished( - exec_ctx, parser->parsing_frame, GRPC_ERROR_CREATE("Parser destroyed"), - 1); + exec_ctx, parser->parsing_frame, GRPC_ERROR_CREATE("Parser destroyed")); } GRPC_ERROR_UNREF(parser->error); } @@ -245,7 +244,7 @@ grpc_error *grpc_chttp2_data_parser_parse(grpc_exec_ctx *exec_ctx, void *parser, exec_ctx, p->parsing_frame, gpr_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, - GRPC_ERROR_NONE, 1); + GRPC_ERROR_NONE); p->parsing_frame = NULL; p->state = GRPC_CHTTP2_DATA_FH_0; return GRPC_ERROR_NONE; @@ -256,7 +255,7 @@ grpc_error *grpc_chttp2_data_parser_parse(grpc_exec_ctx *exec_ctx, void *parser, gpr_slice_sub(slice, (size_t)(cur - beg), (size_t)(cur + p->frame_size - beg))); grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, - GRPC_ERROR_NONE, 1); + GRPC_ERROR_NONE); p->parsing_frame = NULL; cur += p->frame_size; goto fh_0; /* loop */ diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 0c218b79de..0d15a56951 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -349,6 +349,7 @@ struct grpc_chttp2_stream { uint32_t fetched_send_message_length; gpr_slice fetching_slice; int64_t fetching_slice_end_offset; + bool complete_fetch_covered_by_poller; grpc_closure complete_fetch; grpc_closure complete_fetch_locked; grpc_closure *fetching_send_message_finished; @@ -643,7 +644,7 @@ void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, gpr_slice slice); void grpc_chttp2_incoming_byte_stream_finished( grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, - grpc_error *error, int from_parsing_thread); + grpc_error *error); void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, const uint8_t *opaque_8bytes); diff --git a/src/core/ext/transport/chttp2/transport/stream_lists.c b/src/core/ext/transport/chttp2/transport/stream_lists.c index 7a42c2a58a..9d09e0c7c2 100644 --- a/src/core/ext/transport/chttp2/transport/stream_lists.c +++ b/src/core/ext/transport/chttp2/transport/stream_lists.c @@ -163,9 +163,8 @@ void grpc_chttp2_list_add_check_read_ops(grpc_exec_ctx *exec_ctx, grpc_chttp2_stream *s) { if (!t->check_read_ops_scheduled) { GRPC_CHTTP2_REF_TRANSPORT(t, "initiate_read_flush_locked"); - grpc_combiner_execute_finally(exec_ctx, t->combiner, - &t->read_action_flush_locked, GRPC_ERROR_NONE, - false); + grpc_combiner_execute_finally( + exec_ctx, t->combiner, &t->read_action_flush_locked, GRPC_ERROR_NONE); t->check_read_ops_scheduled = true; } stream_list_add(t, s, GRPC_CHTTP2_LIST_CHECK_READ_OPS); diff --git a/src/core/lib/iomgr/closure.c b/src/core/lib/iomgr/closure.c index 1ba0a5c141..6200cda5dc 100644 --- a/src/core/lib/iomgr/closure.c +++ b/src/core/lib/iomgr/closure.c @@ -51,7 +51,7 @@ void grpc_closure_list_append(grpc_closure_list *closure_list, GRPC_ERROR_UNREF(error); return; } - closure->error = error; + closure->error_data.error = error; closure->next_data.next = NULL; if (closure_list->head == NULL) { closure_list->head = closure; @@ -64,8 +64,8 @@ void grpc_closure_list_append(grpc_closure_list *closure_list, void grpc_closure_list_fail_all(grpc_closure_list *list, grpc_error *forced_failure) { for (grpc_closure *c = list->head; c != NULL; c = c->next_data.next) { - if (c->error == GRPC_ERROR_NONE) { - c->error = GRPC_ERROR_REF(forced_failure); + if (c->error_data.error == GRPC_ERROR_NONE) { + c->error_data.error = GRPC_ERROR_REF(forced_failure); } } GRPC_ERROR_UNREF(forced_failure); diff --git a/src/core/lib/iomgr/closure.h b/src/core/lib/iomgr/closure.h index c1a22b6021..bf7c006097 100644 --- a/src/core/lib/iomgr/closure.h +++ b/src/core/lib/iomgr/closure.h @@ -76,7 +76,10 @@ struct grpc_closure { void *cb_arg; /** Once queued, the result of the closure. Before then: scratch space */ - grpc_error *error; + union { + grpc_error *error; + uintptr_t scratch; + } error_data; }; /** Initializes \a closure with \a cb and \a cb_arg. */ diff --git a/src/core/lib/iomgr/combiner.c b/src/core/lib/iomgr/combiner.c index f1a2b29519..40be4dea7b 100644 --- a/src/core/lib/iomgr/combiner.c +++ b/src/core/lib/iomgr/combiner.c @@ -58,7 +58,9 @@ struct grpc_combiner { // lower bit - zero if orphaned // other bits - number of items queued on the lock gpr_atm state; - bool take_async_break_before_final_list; + // number of elements in the list that are covered by a poller: if >0, we can + // offload safely + gpr_atm covered_by_poller; bool time_to_execute_final_list; grpc_closure_list final_list; grpc_closure offload; @@ -66,14 +68,27 @@ struct grpc_combiner { static void offload(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error); +typedef struct { + grpc_error *error; + bool covered_by_poller; +} error_data; + +static uintptr_t pack_error_data(error_data d) { + return ((uintptr_t)d.error) | (d.covered_by_poller ? 1 : 0); +} + +static error_data unpack_error_data(uintptr_t p) { + return (error_data){(grpc_error *)(p & ~(uintptr_t)1), p & 1}; +} + grpc_combiner *grpc_combiner_create(grpc_workqueue *optional_workqueue) { grpc_combiner *lock = gpr_malloc(sizeof(*lock)); lock->next_combiner_on_this_exec_ctx = NULL; lock->time_to_execute_final_list = false; lock->optional_workqueue = optional_workqueue; gpr_atm_no_barrier_store(&lock->state, 1); + gpr_atm_no_barrier_store(&lock->covered_by_poller, 0); gpr_mpscq_init(&lock->queue); - lock->take_async_break_before_final_list = false; grpc_closure_list_init(&lock->final_list); grpc_closure_init(&lock->offload, offload, lock); GRPC_COMBINER_TRACE(gpr_log(GPR_DEBUG, "C:%p create", lock)); @@ -108,13 +123,18 @@ static void queue_on_exec_ctx(grpc_exec_ctx *exec_ctx, grpc_combiner *lock) { } void grpc_combiner_execute(grpc_exec_ctx *exec_ctx, grpc_combiner *lock, - grpc_closure *cl, grpc_error *error) { + grpc_closure *cl, grpc_error *error, + bool covered_by_poller) { GRPC_COMBINER_TRACE( - gpr_log(GPR_DEBUG, "C:%p grpc_combiner_execute c=%p", lock, cl)); + gpr_log(GPR_DEBUG, "C:%p grpc_combiner_execute c=%p cov=%d", lock, cl, covered_by_poller)); GPR_TIMER_BEGIN("combiner.execute", 0); gpr_atm last = gpr_atm_full_fetch_add(&lock->state, 2); GPR_ASSERT(last & 1); // ensure lock has not been destroyed - cl->error = error; + cl->error_data.scratch = + pack_error_data((error_data){error, covered_by_poller}); + if (covered_by_poller) { + gpr_atm_no_barrier_fetch_add(&lock->covered_by_poller, 1); + } gpr_mpscq_push(&lock->queue, &cl->next_data.atm_next); if (last == 1) { // code will be written when the exec_ctx calls @@ -152,11 +172,12 @@ bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) { } if (lock->optional_workqueue != NULL && - grpc_exec_ctx_ready_to_finish(exec_ctx)) { + grpc_exec_ctx_ready_to_finish(exec_ctx) && + gpr_atm_acq_load(&lock->covered_by_poller) > 0) { GPR_TIMER_MARK("offload_from_finished_exec_ctx", 0); - // this execution context wants to move on, and we have a workqueue (and so - // can help the execution context out): schedule remaining work to be picked - // up on the workqueue + // this execution context wants to move on, and we have a workqueue (and + // so can help the execution context out): schedule remaining work to be + // picked up on the workqueue queue_offload(exec_ctx, lock); GPR_TIMER_END("combiner.continue_exec_ctx", 0); return true; @@ -173,7 +194,7 @@ bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) { // queue is in an inconsistant state: use this as a cue that we should // go off and do something else for a while (and come back later) GPR_TIMER_MARK("delay_busy", 0); - if (lock->optional_workqueue != NULL) { + if (lock->optional_workqueue != NULL && gpr_atm_acq_load(&lock->covered_by_poller) > 0) { queue_offload(exec_ctx, lock); } GPR_TIMER_END("combiner.continue_exec_ctx", 0); @@ -181,37 +202,28 @@ bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) { } GPR_TIMER_BEGIN("combiner.exec1", 0); grpc_closure *cl = (grpc_closure *)n; - grpc_error *error = cl->error; - cl->cb(exec_ctx, cl->cb_arg, error); - GRPC_ERROR_UNREF(error); + error_data err = unpack_error_data(cl->error_data.scratch); + cl->cb(exec_ctx, cl->cb_arg, err.error); + if (err.covered_by_poller) { + gpr_atm_no_barrier_fetch_add(&lock->covered_by_poller, -1); + } + GRPC_ERROR_UNREF(err.error); GPR_TIMER_END("combiner.exec1", 0); } else { - if (lock->take_async_break_before_final_list) { - GPR_TIMER_MARK("async_break", 0); - GRPC_COMBINER_TRACE(gpr_log(GPR_DEBUG, "C:%p take async break", lock)); - lock->take_async_break_before_final_list = false; - if (lock->optional_workqueue != NULL) { - queue_offload(exec_ctx, lock); - } - GPR_TIMER_END("combiner.continue_exec_ctx", 0); - return true; - } else { - grpc_closure *c = lock->final_list.head; - GPR_ASSERT(c != NULL); - grpc_closure_list_init(&lock->final_list); - lock->take_async_break_before_final_list = false; - int loops = 0; - while (c != NULL) { - GPR_TIMER_BEGIN("combiner.exec_1final", 0); - GRPC_COMBINER_TRACE( - gpr_log(GPR_DEBUG, "C:%p execute_final[%d] c=%p", lock, loops, c)); - grpc_closure *next = c->next_data.next; - grpc_error *error = c->error; - c->cb(exec_ctx, c->cb_arg, error); - GRPC_ERROR_UNREF(error); - c = next; - GPR_TIMER_END("combiner.exec_1final", 0); - } + grpc_closure *c = lock->final_list.head; + GPR_ASSERT(c != NULL); + grpc_closure_list_init(&lock->final_list); + int loops = 0; + while (c != NULL) { + GPR_TIMER_BEGIN("combiner.exec_1final", 0); + GRPC_COMBINER_TRACE( + gpr_log(GPR_DEBUG, "C:%p execute_final[%d] c=%p", lock, loops, c)); + grpc_closure *next = c->next_data.next; + grpc_error *error = c->error_data.error; + c->cb(exec_ctx, c->cb_arg, error); + GRPC_ERROR_UNREF(error); + c = next; + GPR_TIMER_END("combiner.exec_1final", 0); } } @@ -250,35 +262,27 @@ bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) { static void enqueue_finally(grpc_exec_ctx *exec_ctx, void *closure, grpc_error *error) { grpc_combiner_execute_finally(exec_ctx, exec_ctx->active_combiner, closure, - GRPC_ERROR_REF(error), false); + GRPC_ERROR_REF(error)); } void grpc_combiner_execute_finally(grpc_exec_ctx *exec_ctx, grpc_combiner *lock, - grpc_closure *closure, grpc_error *error, - bool force_async_break) { - GRPC_COMBINER_TRACE(gpr_log( - GPR_DEBUG, - "C:%p grpc_combiner_execute_finally c=%p force_async_break=%d; ac=%p", - lock, closure, force_async_break, exec_ctx->active_combiner)); + grpc_closure *closure, grpc_error *error) { + GRPC_COMBINER_TRACE(gpr_log(GPR_DEBUG, + "C:%p grpc_combiner_execute_finally c=%p; ac=%p", + lock, closure, exec_ctx->active_combiner)); GPR_TIMER_BEGIN("combiner.execute_finally", 0); if (exec_ctx->active_combiner != lock) { GPR_TIMER_MARK("slowpath", 0); grpc_combiner_execute(exec_ctx, lock, - grpc_closure_create(enqueue_finally, closure), error); + grpc_closure_create(enqueue_finally, closure), error, + false); GPR_TIMER_END("combiner.execute_finally", 0); return; } - if (force_async_break) { - lock->take_async_break_before_final_list = true; - } if (grpc_closure_list_empty(lock->final_list)) { gpr_atm_full_fetch_add(&lock->state, 2); } grpc_closure_list_append(&lock->final_list, closure, error); GPR_TIMER_END("combiner.execute_finally", 0); } - -void grpc_combiner_force_async_finally(grpc_combiner *lock) { - lock->take_async_break_before_final_list = true; -} diff --git a/src/core/lib/iomgr/combiner.h b/src/core/lib/iomgr/combiner.h index 28f548b2f5..80ed33c2a7 100644 --- a/src/core/lib/iomgr/combiner.h +++ b/src/core/lib/iomgr/combiner.h @@ -52,7 +52,8 @@ grpc_combiner *grpc_combiner_create(grpc_workqueue *optional_workqueue); void grpc_combiner_destroy(grpc_exec_ctx *exec_ctx, grpc_combiner *lock); // Execute \a action within the lock. void grpc_combiner_execute(grpc_exec_ctx *exec_ctx, grpc_combiner *lock, - grpc_closure *closure, grpc_error *error); + grpc_closure *closure, grpc_error *error, + bool covered_by_poller); // Execute \a action within the lock just prior to unlocking. // if \a hint_async_break is additionally set, the combiner is tries to trip // through the workqueue between finishing the primary queue of combined @@ -60,9 +61,7 @@ void grpc_combiner_execute(grpc_exec_ctx *exec_ctx, grpc_combiner *lock, // Takes a very slow and round-about path if not called from a // grpc_combiner_execute closure void grpc_combiner_execute_finally(grpc_exec_ctx *exec_ctx, grpc_combiner *lock, - grpc_closure *closure, grpc_error *error, - bool hint_async_break); -void grpc_combiner_force_async_finally(grpc_combiner *lock); + grpc_closure *closure, grpc_error *error); bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx); diff --git a/src/core/lib/iomgr/exec_ctx.c b/src/core/lib/iomgr/exec_ctx.c index 747b462a6e..eec32a4f26 100644 --- a/src/core/lib/iomgr/exec_ctx.c +++ b/src/core/lib/iomgr/exec_ctx.c @@ -67,7 +67,7 @@ bool grpc_exec_ctx_flush(grpc_exec_ctx *exec_ctx) { exec_ctx->closure_list.head = exec_ctx->closure_list.tail = NULL; while (c != NULL) { grpc_closure *next = c->next_data.next; - grpc_error *error = c->error; + grpc_error *error = c->error_data.error; did_something = true; GPR_TIMER_BEGIN("grpc_exec_ctx_flush.cb", 0); c->cb(exec_ctx, c->cb_arg, error); @@ -87,7 +87,7 @@ bool grpc_exec_ctx_flush(grpc_exec_ctx *exec_ctx) { if (grpc_exec_ctx_ready_to_finish(exec_ctx)) { grpc_workqueue_enqueue(exec_ctx, exec_ctx->stealing_from_workqueue, exec_ctx->stolen_closure, - exec_ctx->stolen_closure->error); + exec_ctx->stolen_closure->error_data.error); GRPC_WORKQUEUE_UNREF(exec_ctx, exec_ctx->stealing_from_workqueue, "exec_ctx_sched"); exec_ctx->stealing_from_workqueue = NULL; @@ -98,7 +98,7 @@ bool grpc_exec_ctx_flush(grpc_exec_ctx *exec_ctx) { "exec_ctx_sched"); exec_ctx->stealing_from_workqueue = NULL; exec_ctx->stolen_closure = NULL; - grpc_error *error = c->error; + grpc_error *error = c->error_data.error; GPR_TIMER_BEGIN("grpc_exec_ctx_flush.stolen_cb", 0); c->cb(exec_ctx, c->cb_arg, error); GRPC_ERROR_UNREF(error); @@ -125,7 +125,7 @@ void grpc_exec_ctx_sched(grpc_exec_ctx *exec_ctx, grpc_closure *closure, grpc_closure_list_append(&exec_ctx->closure_list, closure, error); } else if (exec_ctx->stealing_from_workqueue == NULL) { exec_ctx->stealing_from_workqueue = offload_target_or_null; - closure->error = error; + closure->error_data.error = error; exec_ctx->stolen_closure = closure; } else if (exec_ctx->stealing_from_workqueue != offload_target_or_null) { grpc_workqueue_enqueue(exec_ctx, offload_target_or_null, closure, error); @@ -133,8 +133,8 @@ void grpc_exec_ctx_sched(grpc_exec_ctx *exec_ctx, grpc_closure *closure, } else { /* stealing_from_workqueue == offload_target_or_null */ grpc_workqueue_enqueue(exec_ctx, offload_target_or_null, exec_ctx->stolen_closure, - exec_ctx->stolen_closure->error); - closure->error = error; + exec_ctx->stolen_closure->error_data.error); + closure->error_data.error = error; exec_ctx->stolen_closure = closure; GRPC_WORKQUEUE_UNREF(exec_ctx, offload_target_or_null, "exec_ctx_sched"); } diff --git a/src/core/lib/iomgr/workqueue_posix.c b/src/core/lib/iomgr/workqueue_posix.c index ecfea68f56..6c27c3b41e 100644 --- a/src/core/lib/iomgr/workqueue_posix.c +++ b/src/core/lib/iomgr/workqueue_posix.c @@ -171,7 +171,7 @@ static void on_readable(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { wakeup(exec_ctx, workqueue); } grpc_closure *cl = (grpc_closure *)n; - grpc_error *clerr = cl->error; + grpc_error *clerr = cl->error_data.error; cl->cb(exec_ctx, cl->cb_arg, clerr); GRPC_ERROR_UNREF(clerr); } @@ -185,7 +185,7 @@ void grpc_workqueue_enqueue(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue, GPR_TIMER_BEGIN("workqueue.enqueue", 0); gpr_atm last = gpr_atm_full_fetch_add(&workqueue->state, 2); GPR_ASSERT(last & 1); - closure->error = error; + closure->error_data.error = error; gpr_mpscq_push(&workqueue->queue, &closure->next_data.atm_next); if (last == 1) { wakeup(exec_ctx, workqueue); diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c index 8ed33bee5f..5f120a69c3 100644 --- a/src/core/lib/surface/call.c +++ b/src/core/lib/surface/call.c @@ -1405,6 +1405,7 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx, grpc_transport_stream_op *stream_op = &bctl->op; memset(stream_op, 0, sizeof(*stream_op)); + stream_op->covered_by_poller = true; if (nops == 0) { GRPC_CALL_INTERNAL_REF(call, "completion"); diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h index fe47fea306..42f51c9ce4 100644 --- a/src/core/lib/transport/transport.h +++ b/src/core/lib/transport/transport.h @@ -113,6 +113,10 @@ typedef struct grpc_transport_stream_op { have been completed. */ grpc_closure *on_complete; + /** Is the completion of this op covered by a poller (if false: the op should + complete independently of some pollset being polled) */ + bool covered_by_poller; + /** Send initial metadata to the peer, from the provided metadata batch. idempotent_request MUST be set if this is non-null */ grpc_metadata_batch *send_initial_metadata; diff --git a/test/core/iomgr/combiner_test.c b/test/core/iomgr/combiner_test.c index 7cf016d82c..cfb6159b17 100644 --- a/test/core/iomgr/combiner_test.c +++ b/test/core/iomgr/combiner_test.c @@ -61,7 +61,7 @@ static void test_execute_one(void) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_combiner_execute(&exec_ctx, lock, grpc_closure_create(set_bool_to_true, &done), - GRPC_ERROR_NONE); + GRPC_ERROR_NONE, false); grpc_exec_ctx_flush(&exec_ctx); GPR_ASSERT(done); grpc_combiner_destroy(&exec_ctx, lock); @@ -96,7 +96,8 @@ static void execute_many_loop(void *a) { c->ctr = &args->ctr; c->value = n++; grpc_combiner_execute(&exec_ctx, args->lock, - grpc_closure_create(check_one, c), GRPC_ERROR_NONE); + grpc_closure_create(check_one, c), GRPC_ERROR_NONE, + false); grpc_exec_ctx_flush(&exec_ctx); } gpr_sleep_until(GRPC_TIMEOUT_MILLIS_TO_DEADLINE(100)); @@ -132,9 +133,8 @@ static void in_finally(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { } static void add_finally(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { - grpc_combiner_execute_finally(exec_ctx, arg, - grpc_closure_create(in_finally, NULL), - GRPC_ERROR_NONE, false); + grpc_combiner_execute_finally( + exec_ctx, arg, grpc_closure_create(in_finally, NULL), GRPC_ERROR_NONE); } static void test_execute_finally(void) { @@ -143,7 +143,7 @@ static void test_execute_finally(void) { grpc_combiner *lock = grpc_combiner_create(NULL); grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_combiner_execute(&exec_ctx, lock, grpc_closure_create(add_finally, lock), - GRPC_ERROR_NONE); + GRPC_ERROR_NONE, false); grpc_exec_ctx_flush(&exec_ctx); GPR_ASSERT(got_in_finally); grpc_combiner_destroy(&exec_ctx, lock); -- cgit v1.2.3 From 83b4d3ef4e34bb45cfd9998716d3a21cc003e1ea Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 31 Aug 2016 17:12:39 -0700 Subject: Fix error cases --- .../transport/chttp2/transport/chttp2_transport.c | 52 +++++++++++++++------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index fb72fd693a..55688e36bb 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -546,7 +546,8 @@ void grpc_chttp2_initiate_write(grpc_exec_ctx *exec_ctx, switch (t->write_state) { case GRPC_CHTTP2_WRITE_STATE_IDLE: t->write_state = GRPC_CHTTP2_WRITE_STATE_WRITING; - gpr_log(GPR_DEBUG, "W:%s:%p: IDLE -> WRITING", t->is_client ? "CLIENT" : "SERVER", t); + gpr_log(GPR_DEBUG, "W:%s:%p: IDLE -> WRITING", + t->is_client ? "CLIENT" : "SERVER", t); GRPC_CHTTP2_REF_TRANSPORT(t, "writing"); grpc_combiner_execute_finally(exec_ctx, t->combiner, &t->write_action_begin_locked, @@ -554,7 +555,8 @@ void grpc_chttp2_initiate_write(grpc_exec_ctx *exec_ctx, break; case GRPC_CHTTP2_WRITE_STATE_WRITING: t->write_state = GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_TO_COME; - gpr_log(GPR_DEBUG, "W:%s:%p: WRITING -> WRITING_MORE", t->is_client ? "CLIENT" : "SERVER", t); + gpr_log(GPR_DEBUG, "W:%s:%p: WRITING -> WRITING_MORE", + t->is_client ? "CLIENT" : "SERVER", t); break; case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_TO_COME: break; @@ -579,10 +581,12 @@ static void write_action_begin_locked(grpc_exec_ctx *exec_ctx, void *gt, GPR_ASSERT(t->write_state != GRPC_CHTTP2_WRITE_STATE_IDLE); if (!t->closed && grpc_chttp2_begin_write(exec_ctx, t)) { t->write_state = GRPC_CHTTP2_WRITE_STATE_WRITING; - gpr_log(GPR_DEBUG, "W:%s:%p: WRITING|WRITING_MORE -> WRITING", t->is_client ? "CLIENT" : "SERVER", t); + gpr_log(GPR_DEBUG, "W:%s:%p: WRITING|WRITING_MORE -> WRITING", + t->is_client ? "CLIENT" : "SERVER", t); grpc_exec_ctx_sched(exec_ctx, &t->write_action, GRPC_ERROR_NONE, NULL); } else { - gpr_log(GPR_DEBUG, "W:%s:%p: WRITING|WRITING_MORE -> IDLE", t->is_client ? "CLIENT" : "SERVER", t); + gpr_log(GPR_DEBUG, "W:%s:%p: WRITING|WRITING_MORE -> IDLE", + t->is_client ? "CLIENT" : "SERVER", t); t->write_state = GRPC_CHTTP2_WRITE_STATE_IDLE; GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "writing"); } @@ -622,14 +626,17 @@ static void write_action_end_locked(grpc_exec_ctx *exec_ctx, void *tp, case GRPC_CHTTP2_WRITE_STATE_WRITING: GPR_TIMER_MARK("state=writing", 0); t->write_state = GRPC_CHTTP2_WRITE_STATE_IDLE; - gpr_log(GPR_DEBUG, "W:%s:%p: WRITING -> IDLE", t->is_client ? "CLIENT" : "SERVER", t); + gpr_log(GPR_DEBUG, "W:%s:%p: WRITING -> IDLE", + t->is_client ? "CLIENT" : "SERVER", t); break; case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_TO_COME: GPR_TIMER_MARK("state=writing_stale_with_poller", 0); t->write_state = GRPC_CHTTP2_WRITE_STATE_WRITING; - gpr_log(GPR_DEBUG, "W:%s:%p: WRITING_MORE -> WRITING", t->is_client ? "CLIENT" : "SERVER", t); + gpr_log(GPR_DEBUG, "W:%s:%p: WRITING_MORE -> WRITING", + t->is_client ? "CLIENT" : "SERVER", t); GRPC_CHTTP2_REF_TRANSPORT(t, "writing"); - grpc_combiner_execute_finally(exec_ctx, t->combiner, &t->write_action_begin_locked, + grpc_combiner_execute_finally(exec_ctx, t->combiner, + &t->write_action_begin_locked, GRPC_ERROR_NONE); break; } @@ -1429,7 +1436,17 @@ static void fail_pending_writes(grpc_exec_ctx *exec_ctx, &s->send_trailing_metadata_finished, GRPC_ERROR_REF(error)); grpc_chttp2_complete_closure_step(exec_ctx, t, s, - &s->fetching_send_message_finished, error); + &s->fetching_send_message_finished, + GRPC_ERROR_REF(error)); + while (s->on_write_finished_cbs) { + grpc_chttp2_write_cb *cb = s->on_write_finished_cbs; + s->on_write_finished_cbs = cb->next; + grpc_chttp2_complete_closure_step(exec_ctx, t, s, &cb->closure, + GRPC_ERROR_REF(error)); + cb->next = t->write_cb_pool; + t->write_cb_pool = cb; + } + GRPC_ERROR_UNREF(error); } void grpc_chttp2_mark_stream_closed(grpc_exec_ctx *exec_ctx, @@ -1624,14 +1641,19 @@ static void update_global_window(void *args, uint32_t id, void *stream) { int is_zero; int64_t initial_window_update = t->initial_window_update; - was_zero = s->outgoing_window <= 0; - GRPC_CHTTP2_FLOW_CREDIT_STREAM("settings", t, s, outgoing_window, - initial_window_update); - is_zero = s->outgoing_window <= 0; + if (initial_window_update > 0) { + was_zero = s->outgoing_window <= 0; + GRPC_CHTTP2_FLOW_CREDIT_STREAM("settings", t, s, outgoing_window, + initial_window_update); + is_zero = s->outgoing_window <= 0; - if (was_zero && !is_zero) { - grpc_chttp2_become_writable(a->exec_ctx, t, s, true, - "update_global_window"); + if (was_zero && !is_zero) { + grpc_chttp2_become_writable(a->exec_ctx, t, s, true, + "update_global_window"); + } + } else { + GRPC_CHTTP2_FLOW_DEBIT_STREAM("settings", t, s, outgoing_window, + -initial_window_update); } } -- cgit v1.2.3 From a96f8cb1798034884ebcfcc473d755c9d680415b Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 1 Sep 2016 09:17:11 -0700 Subject: Fix fuzzing detected error --- .../transport/chttp2/transport/chttp2_transport.c | 42 +++++++++++++++------- src/core/ext/transport/chttp2/transport/internal.h | 1 + 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 55688e36bb..ecb2b12eb0 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1930,21 +1930,32 @@ static void incoming_byte_stream_destroy(grpc_exec_ctx *exec_ctx, GPR_TIMER_END("incoming_byte_stream_destroy", 0); } -typedef struct { - grpc_chttp2_incoming_byte_stream *byte_stream; - gpr_slice slice; -} incoming_byte_stream_push_arg; +static void incoming_byte_stream_publish_error( + grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, + grpc_error *error) { + GPR_ASSERT(error != GRPC_ERROR_NONE); + grpc_exec_ctx_sched(exec_ctx, bs->on_next, GRPC_ERROR_REF(error), NULL); + bs->on_next = NULL; + GRPC_ERROR_UNREF(bs->error); + bs->error = error; +} void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, gpr_slice slice) { gpr_mu_lock(&bs->slice_mu); - if (bs->on_next != NULL) { - *bs->next = slice; - grpc_exec_ctx_sched(exec_ctx, bs->on_next, GRPC_ERROR_NONE, NULL); - bs->on_next = NULL; + if (bs->remaining_bytes < GPR_SLICE_LENGTH(slice)) { + incoming_byte_stream_publish_error( + exec_ctx, bs, GRPC_ERROR_CREATE("Too many bytes in stream")); } else { - gpr_slice_buffer_add(&bs->slices, slice); + bs->remaining_bytes -= GPR_SLICE_LENGTH(slice); + if (bs->on_next != NULL) { + *bs->next = slice; + grpc_exec_ctx_sched(exec_ctx, bs->on_next, GRPC_ERROR_NONE, NULL); + bs->on_next = NULL; + } else { + gpr_slice_buffer_add(&bs->slices, slice); + } } gpr_mu_unlock(&bs->slice_mu); } @@ -1952,11 +1963,15 @@ void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, void grpc_chttp2_incoming_byte_stream_finished( grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, grpc_error *error) { + if (error == GRPC_ERROR_NONE) { + gpr_mu_lock(&bs->slice_mu); + if (bs->remaining_bytes != 0) { + error = GRPC_ERROR_CREATE("Truncated message"); + } + gpr_mu_unlock(&bs->slice_mu); + } if (error != GRPC_ERROR_NONE) { - grpc_exec_ctx_sched(exec_ctx, bs->on_next, GRPC_ERROR_REF(error), NULL); - bs->on_next = NULL; - GRPC_ERROR_UNREF(bs->error); - bs->error = error; + incoming_byte_stream_publish_error(exec_ctx, bs, error); } incoming_byte_stream_unref(exec_ctx, bs); } @@ -1967,6 +1982,7 @@ grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( grpc_chttp2_incoming_byte_stream *incoming_byte_stream = gpr_malloc(sizeof(*incoming_byte_stream)); incoming_byte_stream->base.length = frame_size; + incoming_byte_stream->remaining_bytes = frame_size; incoming_byte_stream->base.flags = flags; incoming_byte_stream->base.next = incoming_byte_stream_next; incoming_byte_stream->base.destroy = incoming_byte_stream_destroy; diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 0d15a56951..bffd58a9d2 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -167,6 +167,7 @@ struct grpc_chttp2_incoming_byte_stream { gpr_slice_buffer slices; grpc_closure *on_next; gpr_slice *next; + uint32_t remaining_bytes; struct { grpc_closure closure; -- cgit v1.2.3 From eae090a67a02c81487e601e86fb9ef957de9407b Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 1 Sep 2016 10:16:51 -0700 Subject: Reinstate RST_STREAM at EOS --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 2 +- src/core/ext/transport/chttp2/transport/writing.c | 10 ++++++++++ src/core/lib/iomgr/combiner.c | 8 +++++--- src/core/lib/support/log.c | 6 +++--- src/core/lib/support/string.c | 11 +++++++++++ src/core/lib/support/string.h | 2 ++ test/core/support/string_test.c | 8 ++++++++ 7 files changed, 40 insertions(+), 7 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index ecb2b12eb0..b7dc91fda7 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1948,7 +1948,7 @@ void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, incoming_byte_stream_publish_error( exec_ctx, bs, GRPC_ERROR_CREATE("Too many bytes in stream")); } else { - bs->remaining_bytes -= GPR_SLICE_LENGTH(slice); + bs->remaining_bytes -= (uint32_t)GPR_SLICE_LENGTH(slice); if (bs->on_next != NULL) { *bs->next = slice; grpc_exec_ctx_sched(exec_ctx, bs->on_next, GRPC_ERROR_NONE, NULL); diff --git a/src/core/ext/transport/chttp2/transport/writing.c b/src/core/ext/transport/chttp2/transport/writing.c index ecb3e49c98..805a66a003 100644 --- a/src/core/ext/transport/chttp2/transport/writing.c +++ b/src/core/ext/transport/chttp2/transport/writing.c @@ -158,6 +158,11 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, if (is_last_frame) { s->send_trailing_metadata = NULL; s->sent_trailing_metadata = true; + if (!t->is_client && !s->read_closed) { + gpr_slice_buffer_add(&t->outbuf, grpc_chttp2_rst_stream_create( + s->id, GRPC_CHTTP2_NO_ERROR, + &s->stats.outgoing)); + } } s->sending_bytes += send_bytes; now_writing = true; @@ -178,6 +183,11 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, &s->stats.outgoing, &t->outbuf); s->send_trailing_metadata = NULL; s->sent_trailing_metadata = true; + if (!t->is_client && !s->read_closed) { + gpr_slice_buffer_add( + &t->outbuf, grpc_chttp2_rst_stream_create( + s->id, GRPC_CHTTP2_NO_ERROR, &s->stats.outgoing)); + } now_writing = true; } } diff --git a/src/core/lib/iomgr/combiner.c b/src/core/lib/iomgr/combiner.c index 40be4dea7b..a3def8affb 100644 --- a/src/core/lib/iomgr/combiner.c +++ b/src/core/lib/iomgr/combiner.c @@ -125,8 +125,9 @@ static void queue_on_exec_ctx(grpc_exec_ctx *exec_ctx, grpc_combiner *lock) { void grpc_combiner_execute(grpc_exec_ctx *exec_ctx, grpc_combiner *lock, grpc_closure *cl, grpc_error *error, bool covered_by_poller) { - GRPC_COMBINER_TRACE( - gpr_log(GPR_DEBUG, "C:%p grpc_combiner_execute c=%p cov=%d", lock, cl, covered_by_poller)); + GRPC_COMBINER_TRACE(gpr_log(GPR_DEBUG, + "C:%p grpc_combiner_execute c=%p cov=%d", lock, + cl, covered_by_poller)); GPR_TIMER_BEGIN("combiner.execute", 0); gpr_atm last = gpr_atm_full_fetch_add(&lock->state, 2); GPR_ASSERT(last & 1); // ensure lock has not been destroyed @@ -194,7 +195,8 @@ bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) { // queue is in an inconsistant state: use this as a cue that we should // go off and do something else for a while (and come back later) GPR_TIMER_MARK("delay_busy", 0); - if (lock->optional_workqueue != NULL && gpr_atm_acq_load(&lock->covered_by_poller) > 0) { + if (lock->optional_workqueue != NULL && + gpr_atm_acq_load(&lock->covered_by_poller) > 0) { queue_offload(exec_ctx, lock); } GPR_TIMER_END("combiner.continue_exec_ctx", 0); diff --git a/src/core/lib/support/log.c b/src/core/lib/support/log.c index 899f1218b6..6fbd947f4b 100644 --- a/src/core/lib/support/log.c +++ b/src/core/lib/support/log.c @@ -82,11 +82,11 @@ void gpr_log_verbosity_init() { gpr_atm min_severity_to_print = GPR_LOG_SEVERITY_ERROR; if (verbosity != NULL) { - if (strcmp(verbosity, "DEBUG") == 0) { + if (gpr_stricmp(verbosity, "DEBUG") == 0) { min_severity_to_print = (gpr_atm)GPR_LOG_SEVERITY_DEBUG; - } else if (strcmp(verbosity, "INFO") == 0) { + } else if (gpr_stricmp(verbosity, "INFO") == 0) { min_severity_to_print = (gpr_atm)GPR_LOG_SEVERITY_INFO; - } else if (strcmp(verbosity, "ERROR") == 0) { + } else if (gpr_stricmp(verbosity, "ERROR") == 0) { min_severity_to_print = (gpr_atm)GPR_LOG_SEVERITY_ERROR; } gpr_free(verbosity); diff --git a/src/core/lib/support/string.c b/src/core/lib/support/string.c index 30c1e67647..d17fb9da4b 100644 --- a/src/core/lib/support/string.c +++ b/src/core/lib/support/string.c @@ -304,3 +304,14 @@ void gpr_strvec_add(gpr_strvec *sv, char *str) { char *gpr_strvec_flatten(gpr_strvec *sv, size_t *final_length) { return gpr_strjoin((const char **)sv->strs, sv->count, final_length); } + +int gpr_stricmp(const char *a, const char *b) { + int ca, cb; + do { + ca = tolower(*a); + cb = tolower(*b); + ++a; + ++b; + } while (ca == cb && ca && cb); + return ca - cb; +} diff --git a/src/core/lib/support/string.h b/src/core/lib/support/string.h index 2b6bb3eec6..3aebc083ac 100644 --- a/src/core/lib/support/string.h +++ b/src/core/lib/support/string.h @@ -118,6 +118,8 @@ void gpr_strvec_add(gpr_strvec *strs, char *add); total_length as per gpr_strjoin */ char *gpr_strvec_flatten(gpr_strvec *strs, size_t *total_length); +int gpr_stricmp(const char *a, const char *b); + #ifdef __cplusplus } #endif diff --git a/test/core/support/string_test.c b/test/core/support/string_test.c index 553a824b3f..378e45a942 100644 --- a/test/core/support/string_test.c +++ b/test/core/support/string_test.c @@ -366,6 +366,13 @@ static void test_leftpad() { gpr_free(padded); } +static void test_stricmp(void) { + GPR_ASSERT(0 == gpr_stricmp("hello", "hello")); + GPR_ASSERT(0 == gpr_stricmp("HELLO", "hello")); + GPR_ASSERT(gpr_stricmp("a", "b") < 0); + GPR_ASSERT(gpr_stricmp("b", "a") > 0); +} + int main(int argc, char **argv) { grpc_test_init(argc, argv); test_strdup(); @@ -379,5 +386,6 @@ int main(int argc, char **argv) { test_ltoa(); test_int64toa(); test_leftpad(); + test_stricmp(); return 0; } -- cgit v1.2.3 From cd6add30221ba752a725a25abd755b330025121e Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 1 Sep 2016 10:56:01 -0700 Subject: Spam cleanup --- .../transport/chttp2/transport/chttp2_transport.c | 27 ---------------------- src/core/ext/transport/chttp2/transport/writing.c | 6 ----- src/core/lib/surface/call.c | 4 ---- test/core/end2end/tests/no_logging.c | 1 + 4 files changed, 1 insertion(+), 37 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index b7dc91fda7..ba2bf91b92 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -546,8 +546,6 @@ void grpc_chttp2_initiate_write(grpc_exec_ctx *exec_ctx, switch (t->write_state) { case GRPC_CHTTP2_WRITE_STATE_IDLE: t->write_state = GRPC_CHTTP2_WRITE_STATE_WRITING; - gpr_log(GPR_DEBUG, "W:%s:%p: IDLE -> WRITING", - t->is_client ? "CLIENT" : "SERVER", t); GRPC_CHTTP2_REF_TRANSPORT(t, "writing"); grpc_combiner_execute_finally(exec_ctx, t->combiner, &t->write_action_begin_locked, @@ -555,8 +553,6 @@ void grpc_chttp2_initiate_write(grpc_exec_ctx *exec_ctx, break; case GRPC_CHTTP2_WRITE_STATE_WRITING: t->write_state = GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_TO_COME; - gpr_log(GPR_DEBUG, "W:%s:%p: WRITING -> WRITING_MORE", - t->is_client ? "CLIENT" : "SERVER", t); break; case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_TO_COME: break; @@ -581,12 +577,8 @@ static void write_action_begin_locked(grpc_exec_ctx *exec_ctx, void *gt, GPR_ASSERT(t->write_state != GRPC_CHTTP2_WRITE_STATE_IDLE); if (!t->closed && grpc_chttp2_begin_write(exec_ctx, t)) { t->write_state = GRPC_CHTTP2_WRITE_STATE_WRITING; - gpr_log(GPR_DEBUG, "W:%s:%p: WRITING|WRITING_MORE -> WRITING", - t->is_client ? "CLIENT" : "SERVER", t); grpc_exec_ctx_sched(exec_ctx, &t->write_action, GRPC_ERROR_NONE, NULL); } else { - gpr_log(GPR_DEBUG, "W:%s:%p: WRITING|WRITING_MORE -> IDLE", - t->is_client ? "CLIENT" : "SERVER", t); t->write_state = GRPC_CHTTP2_WRITE_STATE_IDLE; GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "writing"); } @@ -626,14 +618,10 @@ static void write_action_end_locked(grpc_exec_ctx *exec_ctx, void *tp, case GRPC_CHTTP2_WRITE_STATE_WRITING: GPR_TIMER_MARK("state=writing", 0); t->write_state = GRPC_CHTTP2_WRITE_STATE_IDLE; - gpr_log(GPR_DEBUG, "W:%s:%p: WRITING -> IDLE", - t->is_client ? "CLIENT" : "SERVER", t); break; case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_TO_COME: GPR_TIMER_MARK("state=writing_stale_with_poller", 0); t->write_state = GRPC_CHTTP2_WRITE_STATE_WRITING; - gpr_log(GPR_DEBUG, "W:%s:%p: WRITING_MORE -> WRITING", - t->is_client ? "CLIENT" : "SERVER", t); GRPC_CHTTP2_REF_TRANSPORT(t, "writing"); grpc_combiner_execute_finally(exec_ctx, t->combiner, &t->write_action_begin_locked, @@ -734,9 +722,6 @@ static void maybe_start_some_streams(grpc_exec_ctx *exec_ctx, #define CLOSURE_BARRIER_FIRST_REF_BIT (1 << 16) static grpc_closure *add_closure_barrier(grpc_closure *closure) { - gpr_log(GPR_DEBUG, "add_closure_barrier: %p | %" PRIdPTR " -> %" PRIdPTR, - closure, closure->next_data.scratch, - closure->next_data.scratch + CLOSURE_BARRIER_FIRST_REF_BIT); closure->next_data.scratch += CLOSURE_BARRIER_FIRST_REF_BIT; return closure; } @@ -751,9 +736,6 @@ void grpc_chttp2_complete_closure_step(grpc_exec_ctx *exec_ctx, GRPC_ERROR_UNREF(error); return; } - gpr_log(GPR_DEBUG, "complete_closure_step: %p | %" PRIdPTR " -> %" PRIdPTR, - closure, closure->next_data.scratch, - closure->next_data.scratch - CLOSURE_BARRIER_FIRST_REF_BIT); closure->next_data.scratch -= CLOSURE_BARRIER_FIRST_REF_BIT; if (error != GRPC_ERROR_NONE) { if (closure->error_data.error == GRPC_ERROR_NONE) { @@ -794,10 +776,6 @@ static void add_fetched_slice_locked(grpc_exec_ctx *exec_ctx, static void continue_fetching_send_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s) { - gpr_log(GPR_DEBUG, - "continue_fetching_send_locked[%d]: fsm=%p fetched=%d tgt=%d", s->id, - s->fetching_send_message, s->fetched_send_message_length, - s->fetching_send_message->length); if (s->fetching_send_message == NULL) { /* Stream was cancelled before message fetch completed */ abort(); /* TODO(ctiller): what cleanup here? */ @@ -1131,10 +1109,6 @@ static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t = op->transport_private.args[0]; grpc_error *close_transport = op->disconnect_with_error; - char *msg = grpc_transport_op_string(op); - gpr_log(GPR_DEBUG, "run:%p: %s", t, msg); - gpr_free(msg); - if (op->on_connectivity_state_change != NULL) { grpc_connectivity_state_notify_on_state_change( exec_ctx, &t->channel_callback.state_tracker, op->connectivity_state, @@ -1184,7 +1158,6 @@ static void perform_transport_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, grpc_transport_op *op) { grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt; char *msg = grpc_transport_op_string(op); - gpr_log(GPR_DEBUG, "scd:%p: %s", t, msg); gpr_free(msg); op->transport_private.args[0] = gt; grpc_closure_init(&op->transport_private.closure, perform_transport_op_locked, diff --git a/src/core/ext/transport/chttp2/transport/writing.c b/src/core/ext/transport/chttp2/transport/writing.c index 805a66a003..6f14e7226b 100644 --- a/src/core/ext/transport/chttp2/transport/writing.c +++ b/src/core/ext/transport/chttp2/transport/writing.c @@ -109,12 +109,6 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, bool sent_initial_metadata = s->sent_initial_metadata; bool now_writing = false; - gpr_log(GPR_DEBUG, "W:%d:%s: sim=%d ann=%d fcb_len=%d (t,s)-win=%d,%d", - (int)s->id, t->is_client ? "client" : "server", - sent_initial_metadata, (int)s->announce_window, - (int)s->flow_controlled_buffer.length, (int)t->outgoing_window, - (int)s->outgoing_window); - /* send initial metadata if it's available */ if (!sent_initial_metadata && s->send_initial_metadata) { grpc_chttp2_encode_header(&t->hpack_compressor, s->id, diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c index 5f120a69c3..814baf3fc9 100644 --- a/src/core/lib/surface/call.c +++ b/src/core/lib/surface/call.c @@ -1311,10 +1311,6 @@ static void finish_batch(grpc_exec_ctx *exec_ctx, void *bctlp, grpc_call *child_call; grpc_call *next_child_call; - char *msg = grpc_transport_stream_op_string(&bctl->op); - gpr_log(GPR_DEBUG, "finish_batch: %s", msg); - gpr_free(msg); - GRPC_ERROR_REF(error); gpr_mu_lock(&call->mu); diff --git a/test/core/end2end/tests/no_logging.c b/test/core/end2end/tests/no_logging.c index 3c40e5dbac..afa98decc5 100644 --- a/test/core/end2end/tests/no_logging.c +++ b/test/core/end2end/tests/no_logging.c @@ -286,6 +286,7 @@ static void test_no_logging_in_one_request(grpc_end2end_test_config config) { } void no_logging(grpc_end2end_test_config config) { + gpr_set_log_verbosity(GPR_LOG_SEVERITY_DEBUG); test_no_logging_in_one_request(config); test_no_error_logging_in_entire_process(config); } -- cgit v1.2.3 From e0f25604562754f0290f92e34892ee5000f3da43 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 1 Sep 2016 11:40:07 -0700 Subject: Remove spam --- src/core/lib/surface/call.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c index 814baf3fc9..858c7f5b88 100644 --- a/src/core/lib/surface/call.c +++ b/src/core/lib/surface/call.c @@ -1197,10 +1197,6 @@ static void receiving_stream_ready(grpc_exec_ctx *exec_ctx, void *bctlp, batch_control *bctl = bctlp; grpc_call *call = bctl->call; - char *msg = grpc_transport_stream_op_string(&bctl->op); - gpr_log(GPR_DEBUG, "receiving_stream_ready: %s", msg); - gpr_free(msg); - gpr_mu_lock(&bctl->call->mu); if (bctl->call->has_initial_md_been_received || error != GRPC_ERROR_NONE || call->receiving_stream == NULL) { -- cgit v1.2.3 From 92e0257840ed4c15be7c67669676472eb4ae56d8 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 1 Sep 2016 11:54:18 -0700 Subject: Correct timer annotations --- src/core/ext/transport/chttp2/transport/writing.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/writing.c b/src/core/ext/transport/chttp2/transport/writing.c index 6f14e7226b..f08ecd8b7d 100644 --- a/src/core/ext/transport/chttp2/transport/writing.c +++ b/src/core/ext/transport/chttp2/transport/writing.c @@ -205,14 +205,14 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, 0, announced, &throwaway_stats)); } - GPR_TIMER_END("grpc_chttp2_unlocking_check_writes", 0); + GPR_TIMER_END("grpc_chttp2_begin_write", 0); return t->outbuf.count > 0; } void grpc_chttp2_end_write(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_error *error) { - GPR_TIMER_BEGIN("grpc_chttp2_cleanup_writing", 0); + GPR_TIMER_BEGIN("grpc_chttp2_end_write", 0); grpc_chttp2_stream *s; while (grpc_chttp2_list_pop_writing_stream(t, &s)) { @@ -237,5 +237,5 @@ void grpc_chttp2_end_write(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, } gpr_slice_buffer_reset_and_unref(&t->outbuf); GRPC_ERROR_UNREF(error); - GPR_TIMER_END("grpc_chttp2_cleanup_writing", 0); + GPR_TIMER_END("grpc_chttp2_end_write", 0); } -- cgit v1.2.3 From df1d3da924a746cebce263ce3aa37027a13f55ce Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 1 Sep 2016 13:51:42 -0700 Subject: Fix leaks --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 6 ++++++ src/core/lib/surface/server.c | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index ba2bf91b92..94440a9539 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -162,6 +162,12 @@ static void destruct_transport(grpc_exec_ctx *exec_ctx, gpr_free(ping); } + while (t->write_cb_pool) { + grpc_chttp2_write_cb *next = t->write_cb_pool->next; + gpr_free(t->write_cb_pool); + t->write_cb_pool = next; + } + gpr_free(t->peer_string); gpr_free(t); } diff --git a/src/core/lib/surface/server.c b/src/core/lib/surface/server.c index 041fd234ba..9a517b0a7a 100644 --- a/src/core/lib/surface/server.c +++ b/src/core/lib/surface/server.c @@ -446,6 +446,13 @@ static void destroy_channel(grpc_exec_ctx *exec_ctx, channel_data *chand, grpc_error_free_string(msg); } GRPC_ERROR_UNREF(error); + + grpc_transport_op *op = grpc_make_transport_op(&chand->finish_destroy_channel_closure); + op->set_accept_stream = true; + grpc_channel_next_op(exec_ctx, + grpc_channel_stack_element( + grpc_channel_get_channel_stack(chand->channel), 0), + op); } static void cpstr(char **dest, size_t *capacity, grpc_mdstr *value) { -- cgit v1.2.3 From de2c41c394770fd87f5e406af5dfe70ba6656b4c Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 1 Sep 2016 15:08:08 -0700 Subject: Call closures directly where safe --- .../ext/transport/chttp2/transport/chttp2_transport.c | 19 +++++++------------ src/core/lib/iomgr/closure.c | 10 ++++++++++ src/core/lib/iomgr/closure.h | 5 +++++ src/core/lib/iomgr/exec_ctx.c | 6 +----- src/core/lib/iomgr/tcp_posix.c | 9 +++------ src/core/lib/surface/server.c | 3 +-- 6 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 94440a9539..13fc8ab374 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -759,7 +759,7 @@ void grpc_chttp2_complete_closure_step(grpc_exec_ctx *exec_ctx, grpc_transport_move_stats(&s->stats, s->collecting_stats); s->collecting_stats = NULL; } - grpc_exec_ctx_sched(exec_ctx, closure, closure->error_data.error, NULL); + grpc_closure_run(exec_ctx, closure, closure->error_data.error); } *pclosure = NULL; } @@ -1155,7 +1155,7 @@ static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx, close_transport_locked(exec_ctx, t, close_transport); } - grpc_exec_ctx_sched(exec_ctx, op->on_consumed, GRPC_ERROR_NONE, NULL); + grpc_closure_run(exec_ctx, op->on_consumed, GRPC_ERROR_NONE); GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "transport_op"); } @@ -1199,8 +1199,7 @@ static void check_read_ops(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t) { } grpc_chttp2_incoming_metadata_buffer_publish(&s->metadata_buffer[0], s->recv_initial_metadata); - grpc_exec_ctx_sched(exec_ctx, s->recv_initial_metadata_ready, - GRPC_ERROR_NONE, NULL); + grpc_closure_run(exec_ctx, s->recv_initial_metadata_ready, GRPC_ERROR_NONE); s->recv_initial_metadata_ready = NULL; } if (s->recv_message_ready != NULL) { @@ -1213,13 +1212,11 @@ static void check_read_ops(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t) { *s->recv_message = grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames); GPR_ASSERT(*s->recv_message != NULL); - grpc_exec_ctx_sched(exec_ctx, s->recv_message_ready, GRPC_ERROR_NONE, - NULL); + grpc_closure_run(exec_ctx, s->recv_message_ready, GRPC_ERROR_NONE); s->recv_message_ready = NULL; } else if (s->published_metadata[1]) { *s->recv_message = NULL; - grpc_exec_ctx_sched(exec_ctx, s->recv_message_ready, GRPC_ERROR_NONE, - NULL); + grpc_closure_run(exec_ctx, s->recv_message_ready, GRPC_ERROR_NONE); s->recv_message_ready = NULL; } } @@ -1853,11 +1850,9 @@ static void incoming_byte_stream_next_locked(grpc_exec_ctx *exec_ctx, gpr_mu_lock(&bs->slice_mu); if (bs->slices.count > 0) { *bs->next_action.slice = gpr_slice_buffer_take_first(&bs->slices); - grpc_exec_ctx_sched(exec_ctx, bs->next_action.on_complete, GRPC_ERROR_NONE, - NULL); + grpc_closure_run(exec_ctx, bs->next_action.on_complete, GRPC_ERROR_NONE); } else if (bs->error != GRPC_ERROR_NONE) { - grpc_exec_ctx_sched(exec_ctx, bs->next_action.on_complete, - GRPC_ERROR_REF(bs->error), NULL); + grpc_closure_run(exec_ctx, bs->next_action.on_complete, GRPC_ERROR_REF(bs->error)); } else { bs->on_next = bs->next_action.on_complete; bs->next = bs->next_action.slice; diff --git a/src/core/lib/iomgr/closure.c b/src/core/lib/iomgr/closure.c index 6200cda5dc..5cbd6bd7a5 100644 --- a/src/core/lib/iomgr/closure.c +++ b/src/core/lib/iomgr/closure.c @@ -35,6 +35,8 @@ #include +#include "src/core/lib/profiling/timers.h" + void grpc_closure_init(grpc_closure *closure, grpc_iomgr_cb_func cb, void *cb_arg) { closure->cb = cb; @@ -110,3 +112,11 @@ grpc_closure *grpc_closure_create(grpc_iomgr_cb_func cb, void *cb_arg) { grpc_closure_init(&wc->wrapper, closure_wrapper, wc); return &wc->wrapper; } + +void grpc_closure_run(grpc_exec_ctx *exec_ctx, grpc_closure *c, grpc_error *error) { + GPR_TIMER_BEGIN("grpc_closure_run", 0); + c->cb(exec_ctx, c->cb_arg, error); + GRPC_ERROR_UNREF(error); + GPR_TIMER_END("grpc_closure_run", 0); +} + diff --git a/src/core/lib/iomgr/closure.h b/src/core/lib/iomgr/closure.h index bf7c006097..29ed19cb4f 100644 --- a/src/core/lib/iomgr/closure.h +++ b/src/core/lib/iomgr/closure.h @@ -109,4 +109,9 @@ void grpc_closure_list_move(grpc_closure_list *src, grpc_closure_list *dst); /** return whether \a list is empty. */ bool grpc_closure_list_empty(grpc_closure_list list); +/** Run a closure directly. Caller ensures that no locks are being held above. + * Note that calling this at the end of a closure callback function itself is + * by definition safe. */ +void grpc_closure_run(grpc_exec_ctx *exec_ctx, grpc_closure *closure, grpc_error *error); + #endif /* GRPC_CORE_LIB_IOMGR_CLOSURE_H */ diff --git a/src/core/lib/iomgr/exec_ctx.c b/src/core/lib/iomgr/exec_ctx.c index eec32a4f26..a3c40e8092 100644 --- a/src/core/lib/iomgr/exec_ctx.c +++ b/src/core/lib/iomgr/exec_ctx.c @@ -67,12 +67,8 @@ bool grpc_exec_ctx_flush(grpc_exec_ctx *exec_ctx) { exec_ctx->closure_list.head = exec_ctx->closure_list.tail = NULL; while (c != NULL) { grpc_closure *next = c->next_data.next; - grpc_error *error = c->error_data.error; did_something = true; - GPR_TIMER_BEGIN("grpc_exec_ctx_flush.cb", 0); - c->cb(exec_ctx, c->cb_arg, error); - GRPC_ERROR_UNREF(error); - GPR_TIMER_END("grpc_exec_ctx_flush.cb", 0); + grpc_closure_run(exec_ctx, c, c->error_data.error); c = next; } continue; diff --git a/src/core/lib/iomgr/tcp_posix.c b/src/core/lib/iomgr/tcp_posix.c index caaed23212..ffdc7c7b42 100644 --- a/src/core/lib/iomgr/tcp_posix.c +++ b/src/core/lib/iomgr/tcp_posix.c @@ -177,7 +177,7 @@ static void call_read_cb(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp, tcp->read_cb = NULL; tcp->incoming_buffer = NULL; - grpc_exec_ctx_sched(exec_ctx, cb, error, NULL); + grpc_closure_run(exec_ctx, cb, error); } #define MAX_READ_IOVEC 4 @@ -279,7 +279,7 @@ static void tcp_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, tcp->finished_edge = false; grpc_fd_notify_on_read(exec_ctx, tcp->em_fd, &tcp->read_closure); } else { - grpc_exec_ctx_sched(exec_ctx, &tcp->read_closure, GRPC_ERROR_NONE, NULL); + grpc_exec_ctx_sched(exec_ctx, &tcp->read_closure, GRPC_ERROR_NONE, grpc_fd_get_workqueue(tcp->em_fd)); } } @@ -392,11 +392,8 @@ static void tcp_handle_write(grpc_exec_ctx *exec_ctx, void *arg /* grpc_tcp */, grpc_error_free_string(str); } - GPR_TIMER_BEGIN("tcp_handle_write.cb", 0); - cb->cb(exec_ctx, cb->cb_arg, error); - GPR_TIMER_END("tcp_handle_write.cb", 0); + grpc_closure_run(exec_ctx, cb, error); TCP_UNREF(exec_ctx, tcp, "write"); - GRPC_ERROR_UNREF(error); } } diff --git a/src/core/lib/surface/server.c b/src/core/lib/surface/server.c index 9a517b0a7a..8f9b995265 100644 --- a/src/core/lib/surface/server.c +++ b/src/core/lib/surface/server.c @@ -773,8 +773,7 @@ static void server_on_recv_initial_metadata(grpc_exec_ctx *exec_ctx, void *ptr, GRPC_ERROR_CREATE_REFERENCING("Missing :authority or :path", &error, 1); } - grpc_exec_ctx_sched(exec_ctx, calld->on_done_recv_initial_metadata, error, - NULL); + grpc_closure_run(exec_ctx, calld->on_done_recv_initial_metadata, error); } static void server_mutate_op(grpc_call_element *elem, -- cgit v1.2.3 From eccf51004aa24784f1b5dcd29a105200dca2bb8e Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 1 Sep 2016 15:31:58 -0700 Subject: Eliminate check_read_ops list --- .../transport/chttp2/transport/chttp2_transport.c | 134 ++++++++++----------- .../ext/transport/chttp2/transport/hpack_parser.c | 9 +- src/core/ext/transport/chttp2/transport/internal.h | 24 ++-- src/core/ext/transport/chttp2/transport/parsing.c | 3 - .../ext/transport/chttp2/transport/stream_lists.c | 22 ---- 5 files changed, 82 insertions(+), 110 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 13fc8ab374..e7d1a84420 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -79,8 +79,6 @@ static void read_action_begin(grpc_exec_ctx *exec_ctx, void *t, grpc_error *error); static void read_action_locked(grpc_exec_ctx *exec_ctx, void *t, grpc_error *error); -static void read_action_flush_locked(grpc_exec_ctx *exec_ctx, void *t, - grpc_error *error); static void complete_fetch_locked(grpc_exec_ctx *exec_ctx, void *gs, grpc_error *error); @@ -106,8 +104,6 @@ static void connectivity_state_set(grpc_exec_ctx *exec_ctx, grpc_connectivity_state state, grpc_error *error, const char *reason); -static void check_read_ops(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t); - static void incoming_byte_stream_update_flow_control(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s, @@ -242,7 +238,6 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_closure_init(&t->write_action_end_locked, write_action_end_locked, t); grpc_closure_init(&t->read_action_begin, read_action_begin, t); grpc_closure_init(&t->read_action_locked, read_action_locked, t); - grpc_closure_init(&t->read_action_flush_locked, read_action_flush_locked, t); grpc_chttp2_goaway_parser_init(&t->goaway_parser); grpc_chttp2_hpack_parser_init(&t->hpack_parser); @@ -479,7 +474,6 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp, } grpc_chttp2_list_remove_stalled_by_transport(t, s); - grpc_chttp2_list_remove_check_read_ops(t, s); for (int i = 0; i < STREAM_LIST_COUNT; i++) { if (s->included[i]) { @@ -917,7 +911,6 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, } else { if (contains_non_ok_status(op->send_initial_metadata)) { s->seen_error = true; - grpc_chttp2_list_add_check_read_ops(exec_ctx, t, s); } if (!s->write_closed) { if (t->is_client) { @@ -994,7 +987,6 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, } else { if (contains_non_ok_status(op->send_trailing_metadata)) { s->seen_error = true; - grpc_chttp2_list_add_check_read_ops(exec_ctx, t, s); } if (s->write_closed) { s->send_trailing_metadata = NULL; @@ -1017,7 +1009,7 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, GPR_ASSERT(s->recv_initial_metadata_ready == NULL); s->recv_initial_metadata_ready = op->recv_initial_metadata_ready; s->recv_initial_metadata = op->recv_initial_metadata; - grpc_chttp2_list_add_check_read_ops(exec_ctx, t, s); + grpc_chttp2_maybe_complete_recv_initial_metadata(exec_ctx, t, s); } if (op->recv_message != NULL) { @@ -1029,7 +1021,7 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, incoming_byte_stream_update_flow_control(exec_ctx, t, s, t->stream_lookahead, 0); } - grpc_chttp2_list_add_check_read_ops(exec_ctx, t, s); + grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s); } if (op->recv_trailing_metadata != NULL) { @@ -1037,7 +1029,7 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, s->recv_trailing_metadata_finished = add_closure_barrier(on_complete); s->recv_trailing_metadata = op->recv_trailing_metadata; s->final_metadata_requested = true; - grpc_chttp2_list_add_check_read_ops(exec_ctx, t, s); + grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s); } grpc_chttp2_complete_closure_step(exec_ctx, t, s, &on_complete, @@ -1177,75 +1169,73 @@ static void perform_transport_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, * INPUT PROCESSING - GENERAL */ -static void read_action_flush_locked(grpc_exec_ctx *exec_ctx, void *tp, - grpc_error *error) { - grpc_chttp2_transport *t = tp; - t->check_read_ops_scheduled = false; - check_read_ops(exec_ctx, t); - GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "initiate_read_flush_locked"); +void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s) { + grpc_byte_stream *bs; + if (s->recv_initial_metadata_ready != NULL && s->published_metadata[0]) { + if (s->seen_error) { + while ((bs = grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames)) != + NULL) { + incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE); + } + } + grpc_chttp2_incoming_metadata_buffer_publish(&s->metadata_buffer[0], + s->recv_initial_metadata); + grpc_closure_run(exec_ctx, s->recv_initial_metadata_ready, GRPC_ERROR_NONE); + s->recv_initial_metadata_ready = NULL; + } } -static void check_read_ops(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t) { - GPR_TIMER_BEGIN("check_read_ops", 0); - grpc_chttp2_stream *s; +void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s) { grpc_byte_stream *bs; - while (grpc_chttp2_list_pop_check_read_ops(t, &s)) { - if (s->recv_initial_metadata_ready != NULL && s->published_metadata[0]) { - if (s->seen_error) { - while ((bs = grpc_chttp2_incoming_frame_queue_pop( - &s->incoming_frames)) != NULL) { - incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE); - } - } - grpc_chttp2_incoming_metadata_buffer_publish(&s->metadata_buffer[0], - s->recv_initial_metadata); - grpc_closure_run(exec_ctx, s->recv_initial_metadata_ready, GRPC_ERROR_NONE); - s->recv_initial_metadata_ready = NULL; + if (s->recv_message_ready != NULL) { + while (s->final_metadata_requested && s->seen_error && + (bs = grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames)) != + NULL) { + incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE); } - if (s->recv_message_ready != NULL) { - while (s->final_metadata_requested && s->seen_error && - (bs = grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames)) != - NULL) { + if (s->incoming_frames.head != NULL) { + *s->recv_message = + grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames); + GPR_ASSERT(*s->recv_message != NULL); + grpc_closure_run(exec_ctx, s->recv_message_ready, GRPC_ERROR_NONE); + s->recv_message_ready = NULL; + } else if (s->published_metadata[1]) { + *s->recv_message = NULL; + grpc_closure_run(exec_ctx, s->recv_message_ready, GRPC_ERROR_NONE); + s->recv_message_ready = NULL; + } + } +} + +void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s) { + grpc_byte_stream *bs; + if (s->recv_trailing_metadata_finished != NULL && s->read_closed && + s->write_closed) { + if (s->seen_error) { + while ((bs = grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames)) != + NULL) { incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE); } - if (s->incoming_frames.head != NULL) { - *s->recv_message = - grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames); - GPR_ASSERT(*s->recv_message != NULL); - grpc_closure_run(exec_ctx, s->recv_message_ready, GRPC_ERROR_NONE); - s->recv_message_ready = NULL; - } else if (s->published_metadata[1]) { - *s->recv_message = NULL; - grpc_closure_run(exec_ctx, s->recv_message_ready, GRPC_ERROR_NONE); - s->recv_message_ready = NULL; - } } - if (s->recv_trailing_metadata_finished != NULL && s->read_closed && - s->write_closed) { - if (s->seen_error) { - while ((bs = grpc_chttp2_incoming_frame_queue_pop( - &s->incoming_frames)) != NULL) { - incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE); - } - } - if (s->all_incoming_byte_streams_finished) { - grpc_chttp2_incoming_metadata_buffer_publish(&s->metadata_buffer[1], - s->recv_trailing_metadata); - grpc_chttp2_complete_closure_step(exec_ctx, t, s, - &s->recv_trailing_metadata_finished, - GRPC_ERROR_NONE); - } + if (s->all_incoming_byte_streams_finished) { + grpc_chttp2_incoming_metadata_buffer_publish(&s->metadata_buffer[1], + s->recv_trailing_metadata); + grpc_chttp2_complete_closure_step( + exec_ctx, t, s, &s->recv_trailing_metadata_finished, GRPC_ERROR_NONE); } } - GPR_TIMER_END("check_read_ops", 0); } static void decrement_active_streams_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s) { - if ((s->all_incoming_byte_streams_finished = gpr_unref(&s->active_streams))) { - grpc_chttp2_list_add_check_read_ops(exec_ctx, t, s); - } + s->all_incoming_byte_streams_finished = gpr_unref(&s->active_streams); } static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, @@ -1333,7 +1323,6 @@ void grpc_chttp2_cancel_stream(grpc_exec_ctx *exec_ctx, } if (due_to_error != GRPC_ERROR_NONE && !s->seen_error) { s->seen_error = true; - grpc_chttp2_list_add_check_read_ops(exec_ctx, t, s); } grpc_chttp2_mark_stream_closed(exec_ctx, t, s, 1, 1, due_to_error); } @@ -1343,7 +1332,6 @@ void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, gpr_slice *slice) { if (status != GRPC_STATUS_OK) { s->seen_error = true; - grpc_chttp2_list_add_check_read_ops(exec_ctx, t, s); } /* stream_global->recv_trailing_metadata_finished gives us a last chance replacement: we've received trailing metadata, @@ -1366,7 +1354,7 @@ void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_mdstr_from_slice(gpr_slice_ref(*slice)))); } s->published_metadata[1] = true; - grpc_chttp2_list_add_check_read_ops(exec_ctx, t, s); + grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s); } if (slice) { gpr_slice_unref(*slice); @@ -1434,18 +1422,21 @@ void grpc_chttp2_mark_stream_closed(grpc_exec_ctx *exec_ctx, GRPC_ERROR_UNREF(error); return; } - grpc_chttp2_list_add_check_read_ops(exec_ctx, t, s); if (close_reads && !s->read_closed) { s->read_closed_error = GRPC_ERROR_REF(error); s->read_closed = true; s->published_metadata[0] = true; s->published_metadata[1] = true; decrement_active_streams_locked(exec_ctx, t, s); + grpc_chttp2_maybe_complete_recv_initial_metadata(exec_ctx, t, s); + grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s); + grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s); } if (close_writes && !s->write_closed) { s->write_closed_error = GRPC_ERROR_REF(error); s->write_closed = true; fail_pending_writes(exec_ctx, t, s, GRPC_ERROR_REF(error)); + grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s); } if (s->read_closed && s->write_closed) { if (s->id != 0) { @@ -1852,7 +1843,8 @@ static void incoming_byte_stream_next_locked(grpc_exec_ctx *exec_ctx, *bs->next_action.slice = gpr_slice_buffer_take_first(&bs->slices); grpc_closure_run(exec_ctx, bs->next_action.on_complete, GRPC_ERROR_NONE); } else if (bs->error != GRPC_ERROR_NONE) { - grpc_closure_run(exec_ctx, bs->next_action.on_complete, GRPC_ERROR_REF(bs->error)); + grpc_closure_run(exec_ctx, bs->next_action.on_complete, + GRPC_ERROR_REF(bs->error)); } else { bs->on_next = bs->next_action.on_complete; bs->next = bs->next_action.slice; diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.c b/src/core/ext/transport/chttp2/transport/hpack_parser.c index 0ff5499919..bd26b81622 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_parser.c +++ b/src/core/ext/transport/chttp2/transport/hpack_parser.c @@ -1571,6 +1571,13 @@ grpc_error *grpc_chttp2_hpack_parser_parse(grpc_exec_ctx *exec_ctx, return p->state(exec_ctx, p, beg, end); } +typedef void (*maybe_complete_func_type)(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s); +static const maybe_complete_func_type maybe_complete_funcs[] = { + grpc_chttp2_maybe_complete_recv_initial_metadata, + grpc_chttp2_maybe_complete_recv_trailing_metadata}; + grpc_error *grpc_chttp2_header_parser_parse(grpc_exec_ctx *exec_ctx, void *hpack_parser, grpc_chttp2_transport *t, @@ -1601,8 +1608,8 @@ grpc_error *grpc_chttp2_header_parser_parse(grpc_exec_ctx *exec_ctx, return GRPC_ERROR_CREATE("Too many trailer frames"); } s->published_metadata[s->header_frames_received] = true; + maybe_complete_funcs[s->header_frames_received](exec_ctx, t, s); s->header_frames_received++; - grpc_chttp2_list_add_check_read_ops(exec_ctx, t, s); } if (parser->is_eof) { grpc_chttp2_mark_stream_closed(exec_ctx, t, s, true, false, diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index bffd58a9d2..43639139d5 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -56,7 +56,6 @@ /* streams are kept in various linked lists depending on what things need to happen to them... this enum labels each list */ typedef enum { - GRPC_CHTTP2_LIST_CHECK_READ_OPS, GRPC_CHTTP2_LIST_WRITABLE, GRPC_CHTTP2_LIST_WRITING, GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT, @@ -161,7 +160,7 @@ struct grpc_chttp2_incoming_byte_stream { grpc_chttp2_transport *transport; grpc_chttp2_stream *stream; - int is_tail; + bool is_tail; gpr_mu slice_mu; // protects slices, on_next gpr_slice_buffer slices; @@ -189,8 +188,6 @@ struct grpc_chttp2_transport { /** write execution state of the transport */ grpc_chttp2_write_state write_state; - /** has a check_read_ops been scheduled */ - bool check_read_ops_scheduled; /** is the transport destroying itself? */ uint8_t destroying; @@ -213,7 +210,6 @@ struct grpc_chttp2_transport { grpc_closure read_action_begin; grpc_closure read_action_locked; - grpc_closure read_action_flush_locked; /** incoming read bytes */ gpr_slice_buffer read_buffer; @@ -468,14 +464,6 @@ void grpc_chttp2_list_add_waiting_for_concurrency(grpc_chttp2_transport *t, int grpc_chttp2_list_pop_waiting_for_concurrency(grpc_chttp2_transport *t, grpc_chttp2_stream **s); -void grpc_chttp2_list_add_check_read_ops(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport *t, - grpc_chttp2_stream *s); -bool grpc_chttp2_list_remove_check_read_ops(grpc_chttp2_transport *t, - grpc_chttp2_stream *s); -int grpc_chttp2_list_pop_check_read_ops(grpc_chttp2_transport *t, - grpc_chttp2_stream **s); - void grpc_chttp2_list_add_stalled_by_transport(grpc_chttp2_transport *t, grpc_chttp2_stream *s); int grpc_chttp2_list_pop_stalled_by_transport(grpc_chttp2_transport *t, @@ -661,4 +649,14 @@ void grpc_chttp2_cancel_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s, grpc_error *due_to_error); +void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s); +void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s); +void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s); + #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_INTERNAL_H */ diff --git a/src/core/ext/transport/chttp2/transport/parsing.c b/src/core/ext/transport/chttp2/transport/parsing.c index 2ff1e4c620..aa36f90cae 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.c +++ b/src/core/ext/transport/chttp2/transport/parsing.c @@ -717,9 +717,6 @@ static grpc_error *parse_frame_slice(grpc_exec_ctx *exec_ctx, grpc_chttp2_stream *s = t->incoming_stream; grpc_error *err = t->parser(exec_ctx, t->parser_data, t, s, slice, is_last); if (err == GRPC_ERROR_NONE) { - if (s != NULL) { - grpc_chttp2_list_add_check_read_ops(exec_ctx, t, s); - } return err; } else if (grpc_error_get_int(err, GRPC_ERROR_INT_STREAM_ID, NULL)) { if (grpc_http_trace) { diff --git a/src/core/ext/transport/chttp2/transport/stream_lists.c b/src/core/ext/transport/chttp2/transport/stream_lists.c index 9d09e0c7c2..6d25b3ae57 100644 --- a/src/core/ext/transport/chttp2/transport/stream_lists.c +++ b/src/core/ext/transport/chttp2/transport/stream_lists.c @@ -158,28 +158,6 @@ int grpc_chttp2_list_pop_waiting_for_concurrency(grpc_chttp2_transport *t, return stream_list_pop(t, s, GRPC_CHTTP2_LIST_WAITING_FOR_CONCURRENCY); } -void grpc_chttp2_list_add_check_read_ops(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport *t, - grpc_chttp2_stream *s) { - if (!t->check_read_ops_scheduled) { - GRPC_CHTTP2_REF_TRANSPORT(t, "initiate_read_flush_locked"); - grpc_combiner_execute_finally( - exec_ctx, t->combiner, &t->read_action_flush_locked, GRPC_ERROR_NONE); - t->check_read_ops_scheduled = true; - } - stream_list_add(t, s, GRPC_CHTTP2_LIST_CHECK_READ_OPS); -} - -bool grpc_chttp2_list_remove_check_read_ops(grpc_chttp2_transport *t, - grpc_chttp2_stream *s) { - return stream_list_maybe_remove(t, s, GRPC_CHTTP2_LIST_CHECK_READ_OPS); -} - -int grpc_chttp2_list_pop_check_read_ops(grpc_chttp2_transport *t, - grpc_chttp2_stream **s) { - return stream_list_pop(t, s, GRPC_CHTTP2_LIST_CHECK_READ_OPS); -} - void grpc_chttp2_list_add_stalled_by_transport(grpc_chttp2_transport *t, grpc_chttp2_stream *s) { stream_list_add(t, s, GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT); -- cgit v1.2.3 From 452422e09ffd40dda56d672bd4a23cb8efdb4b31 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 1 Sep 2016 15:54:56 -0700 Subject: Fix some tests --- .../ext/transport/chttp2/transport/chttp2_transport.c | 15 +++++++++------ src/core/lib/surface/call.c | 18 ++++++++++++------ 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index e7d1a84420..a1e1e55f98 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1169,6 +1169,12 @@ static void perform_transport_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, * INPUT PROCESSING - GENERAL */ +static void run_closure_and_null(grpc_exec_ctx *exec_ctx, grpc_closure **closure, grpc_error *error) { + grpc_closure *c = *closure; + *closure = NULL; + grpc_closure_run(exec_ctx, c, error); +} + void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s) { @@ -1182,8 +1188,7 @@ void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_exec_ctx *exec_ctx, } grpc_chttp2_incoming_metadata_buffer_publish(&s->metadata_buffer[0], s->recv_initial_metadata); - grpc_closure_run(exec_ctx, s->recv_initial_metadata_ready, GRPC_ERROR_NONE); - s->recv_initial_metadata_ready = NULL; + run_closure_and_null(exec_ctx, &s->recv_initial_metadata_ready, GRPC_ERROR_NONE); } } @@ -1201,12 +1206,10 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx, *s->recv_message = grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames); GPR_ASSERT(*s->recv_message != NULL); - grpc_closure_run(exec_ctx, s->recv_message_ready, GRPC_ERROR_NONE); - s->recv_message_ready = NULL; + run_closure_and_null(exec_ctx, &s->recv_message_ready, GRPC_ERROR_NONE); } else if (s->published_metadata[1]) { *s->recv_message = NULL; - grpc_closure_run(exec_ctx, s->recv_message_ready, GRPC_ERROR_NONE); - s->recv_message_ready = NULL; + run_closure_and_null(exec_ctx, &s->recv_message_ready, GRPC_ERROR_NONE); } } } diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c index 858c7f5b88..df07b96f28 100644 --- a/src/core/lib/surface/call.c +++ b/src/core/lib/surface/call.c @@ -1092,7 +1092,7 @@ static void post_batch_completion(grpc_exec_ctx *exec_ctx, grpc_call *call = bctl->call; if (bctl->is_notify_tag_closure) { /* unrefs bctl->error */ - grpc_exec_ctx_sched(exec_ctx, bctl->notify_tag, bctl->error, NULL); + grpc_closure_run(exec_ctx, bctl->notify_tag, bctl->error); gpr_mu_lock(&call->mu); bctl->call->used_batches = (uint8_t)(bctl->call->used_batches & @@ -1258,6 +1258,14 @@ static void validate_filtered_metadata(grpc_exec_ctx *exec_ctx, } } +static void add_batch_error(batch_control *bctl, grpc_error *error) { + if (error == GRPC_ERROR_NONE) return; + if (bctl->error == GRPC_ERROR_NONE) { + bctl->error = GRPC_ERROR_CREATE("Call batch operation failed"); + } + bctl->error = grpc_error_add_child(bctl->error, error); +} + static void receiving_initial_metadata_ready(grpc_exec_ctx *exec_ctx, void *bctlp, grpc_error *error) { batch_control *bctl = bctlp; @@ -1265,9 +1273,8 @@ static void receiving_initial_metadata_ready(grpc_exec_ctx *exec_ctx, gpr_mu_lock(&call->mu); - if (error != GRPC_ERROR_NONE) { - bctl->error = GRPC_ERROR_REF(error); - } else { + add_batch_error(bctl, GRPC_ERROR_REF(error)); + if (error == GRPC_ERROR_NONE) { grpc_metadata_batch *md = &call->metadata_batch[1 /* is_receiving */][0 /* is_trailing */]; grpc_metadata_batch_filter(md, recv_initial_filter, call); @@ -1360,8 +1367,7 @@ static void finish_batch(grpc_exec_ctx *exec_ctx, void *bctlp, GRPC_ERROR_UNREF(error); error = GRPC_ERROR_NONE; } - GRPC_ERROR_UNREF(bctl->error); - bctl->error = GRPC_ERROR_REF(error); + add_batch_error(bctl, GRPC_ERROR_REF(error)); gpr_mu_unlock(&call->mu); if (gpr_unref(&bctl->steps_to_complete)) { post_batch_completion(exec_ctx, bctl); -- cgit v1.2.3 From 15b0ac03bb9563a7d3d929be946d088575c867fd Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 1 Sep 2016 17:14:00 -0700 Subject: Debug, fix some bugs --- .../transport/chttp2/transport/chttp2_transport.c | 44 ++++++++++++---------- src/core/ext/transport/chttp2/transport/internal.h | 2 +- src/core/ext/transport/chttp2/transport/writing.c | 6 +-- 3 files changed, 28 insertions(+), 24 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index a1e1e55f98..49fff80370 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -726,12 +726,19 @@ static grpc_closure *add_closure_barrier(grpc_closure *closure) { return closure; } +static void run_closure_and_null(grpc_exec_ctx *exec_ctx, grpc_closure **closure, grpc_error *error) { + grpc_closure *c = *closure; + *closure = NULL; + grpc_closure_run(exec_ctx, c, error); +} + void grpc_chttp2_complete_closure_step(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s, grpc_closure **pclosure, - grpc_error *error) { + grpc_error *error, const char *desc) { grpc_closure *closure = *pclosure; + *pclosure = NULL; if (closure == NULL) { GRPC_ERROR_UNREF(error); return; @@ -755,7 +762,6 @@ void grpc_chttp2_complete_closure_step(grpc_exec_ctx *exec_ctx, } grpc_closure_run(exec_ctx, closure, closure->error_data.error); } - *pclosure = NULL; } static bool contains_non_ok_status(grpc_metadata_batch *batch) { @@ -785,7 +791,7 @@ static void continue_fetching_send_locked(grpc_exec_ctx *exec_ctx, ssize_t notify_offset = s->fetching_slice_end_offset; if (notify_offset <= 0) { grpc_chttp2_complete_closure_step( - exec_ctx, t, s, &s->fetching_send_message_finished, GRPC_ERROR_NONE); + exec_ctx, t, s, &s->fetching_send_message_finished, GRPC_ERROR_NONE, "fetching_send_message_finished"); } else { grpc_chttp2_write_cb *cb = t->write_cb_pool; if (cb == NULL) { @@ -927,7 +933,7 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, grpc_chttp2_complete_closure_step( exec_ctx, t, s, &s->send_initial_metadata_finished, GRPC_ERROR_CREATE( - "Attempt to send initial metadata after stream was closed")); + "Attempt to send initial metadata after stream was closed"), "send_initial_metadata_finished"); } } } @@ -937,7 +943,7 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, if (s->write_closed) { grpc_chttp2_complete_closure_step( exec_ctx, t, s, &s->fetching_send_message_finished, - GRPC_ERROR_CREATE("Attempt to send message after stream was closed")); + GRPC_ERROR_CREATE("Attempt to send message after stream was closed"), "fetching_send_message_finished"); } else { GPR_ASSERT(s->fetching_send_message == NULL); uint8_t *frame_hdr = @@ -995,7 +1001,7 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, grpc_metadata_batch_is_empty(op->send_trailing_metadata) ? GRPC_ERROR_NONE : GRPC_ERROR_CREATE("Attempt to send trailing metadata after " - "stream was closed")); + "stream was closed"), "send_trailing_metadata_finished"); } else if (s->id != 0) { /* TODO(ctiller): check if there's flow control for any outstanding bytes before going writable */ @@ -1033,7 +1039,7 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, } grpc_chttp2_complete_closure_step(exec_ctx, t, s, &on_complete, - GRPC_ERROR_NONE); + GRPC_ERROR_NONE, "op->on_complete"); GPR_TIMER_END("perform_stream_op_locked", 0); GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "perform_stream_op"); @@ -1169,12 +1175,6 @@ static void perform_transport_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, * INPUT PROCESSING - GENERAL */ -static void run_closure_and_null(grpc_exec_ctx *exec_ctx, grpc_closure **closure, grpc_error *error) { - grpc_closure *c = *closure; - *closure = NULL; - grpc_closure_run(exec_ctx, c, error); -} - void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s) { @@ -1218,6 +1218,7 @@ void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s) { grpc_byte_stream *bs; + grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s); if (s->recv_trailing_metadata_finished != NULL && s->read_closed && s->write_closed) { if (s->seen_error) { @@ -1226,11 +1227,11 @@ void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_exec_ctx *exec_ctx, incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE); } } - if (s->all_incoming_byte_streams_finished) { + if (s->all_incoming_byte_streams_finished && s->recv_trailing_metadata_finished != NULL) { grpc_chttp2_incoming_metadata_buffer_publish(&s->metadata_buffer[1], s->recv_trailing_metadata); grpc_chttp2_complete_closure_step( - exec_ctx, t, s, &s->recv_trailing_metadata_finished, GRPC_ERROR_NONE); + exec_ctx, t, s, &s->recv_trailing_metadata_finished, GRPC_ERROR_NONE, "recv_trailing_metadata_finished"); } } } @@ -1238,7 +1239,9 @@ void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_exec_ctx *exec_ctx, static void decrement_active_streams_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s) { - s->all_incoming_byte_streams_finished = gpr_unref(&s->active_streams); + if ((s->all_incoming_byte_streams_finished = gpr_unref(&s->active_streams))) { + grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s); + } } static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, @@ -1398,18 +1401,18 @@ static void fail_pending_writes(grpc_exec_ctx *exec_ctx, s->fetching_send_message = NULL; grpc_chttp2_complete_closure_step(exec_ctx, t, s, &s->send_initial_metadata_finished, - GRPC_ERROR_REF(error)); + GRPC_ERROR_REF(error), "send_initial_metadata_finished"); grpc_chttp2_complete_closure_step(exec_ctx, t, s, &s->send_trailing_metadata_finished, - GRPC_ERROR_REF(error)); + GRPC_ERROR_REF(error), "send_trailing_metadata_finished"); grpc_chttp2_complete_closure_step(exec_ctx, t, s, &s->fetching_send_message_finished, - GRPC_ERROR_REF(error)); + GRPC_ERROR_REF(error), "fetching_send_message_finished"); while (s->on_write_finished_cbs) { grpc_chttp2_write_cb *cb = s->on_write_finished_cbs; s->on_write_finished_cbs = cb->next; grpc_chttp2_complete_closure_step(exec_ctx, t, s, &cb->closure, - GRPC_ERROR_REF(error)); + GRPC_ERROR_REF(error), "on_write_finished_cb"); cb->next = t->write_cb_pool; t->write_cb_pool = cb; } @@ -1973,6 +1976,7 @@ grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( q->tail->next_message = incoming_byte_stream; } q->tail = incoming_byte_stream; + grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s); return incoming_byte_stream; } diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 43639139d5..1ca2f7a70a 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -489,7 +489,7 @@ void grpc_chttp2_complete_closure_step(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s, grpc_closure **pclosure, - grpc_error *error); + grpc_error *error, const char *desc); #define GRPC_CHTTP2_CLIENT_CONNECT_STRING "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" #define GRPC_CHTTP2_CLIENT_CONNECT_STRLEN \ diff --git a/src/core/ext/transport/chttp2/transport/writing.c b/src/core/ext/transport/chttp2/transport/writing.c index f08ecd8b7d..c73360ec9c 100644 --- a/src/core/ext/transport/chttp2/transport/writing.c +++ b/src/core/ext/transport/chttp2/transport/writing.c @@ -49,7 +49,7 @@ static void add_to_write_list(grpc_chttp2_write_cb **list, static void finish_write_cb(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s, grpc_chttp2_write_cb *cb, grpc_error *error) { - grpc_chttp2_complete_closure_step(exec_ctx, t, s, &cb->closure, error); + grpc_chttp2_complete_closure_step(exec_ctx, t, s, &cb->closure, error, "finish_write_cb"); cb->next = t->write_cb_pool; t->write_cb_pool = cb; } @@ -219,7 +219,7 @@ void grpc_chttp2_end_write(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, if (s->sent_initial_metadata) { grpc_chttp2_complete_closure_step(exec_ctx, t, s, &s->send_initial_metadata_finished, - GRPC_ERROR_REF(error)); + GRPC_ERROR_REF(error), "send_initial_metadata_finished"); } if (s->sending_bytes != 0) { update_list(exec_ctx, t, s, s->sending_bytes, &s->on_write_finished_cbs, @@ -229,7 +229,7 @@ void grpc_chttp2_end_write(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, if (s->sent_trailing_metadata) { grpc_chttp2_complete_closure_step(exec_ctx, t, s, &s->send_trailing_metadata_finished, - GRPC_ERROR_REF(error)); + GRPC_ERROR_REF(error), "send_trailing_metadata_finished"); grpc_chttp2_mark_stream_closed(exec_ctx, t, s, !t->is_client, 1, GRPC_ERROR_REF(error)); } -- cgit v1.2.3 From 19656b1d5923809a46f3e0075fdcd694607d07ca Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Thu, 1 Sep 2016 18:00:45 -0700 Subject: Add call_data's pollent to channel_data's interested_parties --- src/core/ext/client_config/client_channel.c | 27 ++++++++++++++++++------ src/core/ext/client_config/lb_policy.c | 3 +-- src/core/ext/client_config/lb_policy.h | 6 ++---- src/core/ext/lb_policy/grpclb/grpclb.c | 27 +++++++----------------- src/core/ext/lb_policy/pick_first/pick_first.c | 13 ------------ src/core/ext/lb_policy/round_robin/round_robin.c | 11 ---------- 6 files changed, 32 insertions(+), 55 deletions(-) diff --git a/src/core/ext/client_config/client_channel.c b/src/core/ext/client_config/client_channel.c index 61e012578e..b5b6cc4df0 100644 --- a/src/core/ext/client_config/client_channel.c +++ b/src/core/ext/client_config/client_channel.c @@ -456,10 +456,16 @@ static void retry_waiting_locked(grpc_exec_ctx *exec_ctx, call_data *calld) { static void subchannel_ready(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { - call_data *calld = arg; + grpc_call_element *elem = arg; + call_data *calld = elem->call_data; + channel_data *chand = elem->channel_data; gpr_mu_lock(&calld->mu); GPR_ASSERT(calld->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL); + // gpr_mu_lock(&chand->mu); + grpc_polling_entity_del_from_pollset_set(exec_ctx, calld->pollent, + chand->interested_parties); + // gpr_mu_unlock(&chand->mu); calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING; if (calld->connected_subchannel == NULL) { gpr_atm_no_barrier_store(&calld->subchannel_call, 1); @@ -536,7 +542,6 @@ static bool pick_subchannel(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, GPR_TIMER_BEGIN("pick_subchannel", 0); channel_data *chand = elem->channel_data; - call_data *calld = elem->call_data; continue_picking_args *cpa; grpc_closure *closure; @@ -566,9 +571,9 @@ static bool pick_subchannel(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, int r; GRPC_LB_POLICY_REF(lb_policy, "pick_subchannel"); gpr_mu_unlock(&chand->mu); - r = grpc_lb_policy_pick(exec_ctx, lb_policy, calld->pollent, - initial_metadata, initial_metadata_flags, - connected_subchannel, on_ready); + r = grpc_lb_policy_pick(exec_ctx, lb_policy, initial_metadata, + initial_metadata_flags, connected_subchannel, + on_ready); GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "pick_subchannel"); GPR_TIMER_END("pick_subchannel", 0); return r; @@ -608,6 +613,7 @@ static void cc_start_transport_stream_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_transport_stream_op *op) { call_data *calld = elem->call_data; + channel_data *chand = elem->channel_data; GRPC_CALL_LOG_OP(GPR_INFO, elem, op); /* try to (atomically) get the call */ grpc_subchannel_call *call = GET_CALL(calld); @@ -668,13 +674,22 @@ retry: calld->connected_subchannel == NULL && op->send_initial_metadata != NULL) { calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL; - grpc_closure_init(&calld->next_step, subchannel_ready, calld); + grpc_closure_init(&calld->next_step, subchannel_ready, elem); GRPC_CALL_STACK_REF(calld->owning_call, "pick_subchannel"); + // grpc_polling_entity_add_to_pollset_set(exec_ctx, calld->pollent, + // chand->interested_parties); if (pick_subchannel(exec_ctx, elem, op->send_initial_metadata, op->send_initial_metadata_flags, &calld->connected_subchannel, &calld->next_step)) { calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING; + // grpc_polling_entity_del_from_pollset_set(exec_ctx, calld->pollent, + // chand->interested_parties); GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "pick_subchannel"); + } else { + // gpr_mu_lock(&chand->mu); + grpc_polling_entity_add_to_pollset_set(exec_ctx, calld->pollent, + chand->interested_parties); + // gpr_mu_unlock(&chand->mu); } } /* if we've got a subchannel, then let's ask it to create a call */ diff --git a/src/core/ext/client_config/lb_policy.c b/src/core/ext/client_config/lb_policy.c index 8b980b2cca..0e02de04ed 100644 --- a/src/core/ext/client_config/lb_policy.c +++ b/src/core/ext/client_config/lb_policy.c @@ -100,12 +100,11 @@ void grpc_lb_policy_weak_unref(grpc_exec_ctx *exec_ctx, } int grpc_lb_policy_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, - grpc_polling_entity *pollent, grpc_metadata_batch *initial_metadata, uint32_t initial_metadata_flags, grpc_connected_subchannel **target, grpc_closure *on_complete) { - return policy->vtable->pick(exec_ctx, policy, pollent, initial_metadata, + return policy->vtable->pick(exec_ctx, policy, initial_metadata, initial_metadata_flags, target, on_complete); } diff --git a/src/core/ext/client_config/lb_policy.h b/src/core/ext/client_config/lb_policy.h index a2f5446fc6..b92a73c09a 100644 --- a/src/core/ext/client_config/lb_policy.h +++ b/src/core/ext/client_config/lb_policy.h @@ -35,7 +35,6 @@ #define GRPC_CORE_EXT_CLIENT_CONFIG_LB_POLICY_H #include "src/core/ext/client_config/subchannel.h" -#include "src/core/lib/iomgr/polling_entity.h" #include "src/core/lib/transport/connectivity_state.h" /** A load balancing policy: specified by a vtable and a struct (which @@ -60,7 +59,6 @@ struct grpc_lb_policy_vtable { /** implement grpc_lb_policy_pick */ int (*pick)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, - grpc_polling_entity *pollent, grpc_metadata_batch *initial_metadata, uint32_t initial_metadata_flags, grpc_connected_subchannel **target, grpc_closure *on_complete); @@ -127,9 +125,9 @@ void grpc_lb_policy_init(grpc_lb_policy *policy, /** Given initial metadata in \a initial_metadata, find an appropriate target for this rpc, and 'return' it by calling \a on_complete after setting \a target. - Picking can be asynchronous. Any IO should be done under \a pollent. */ + Picking can be asynchronous. Any IO should be done under the pollset_set + interested_parties. */ int grpc_lb_policy_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, - grpc_polling_entity *pollent, grpc_metadata_batch *initial_metadata, uint32_t initial_metadata_flags, grpc_connected_subchannel **target, diff --git a/src/core/ext/lb_policy/grpclb/grpclb.c b/src/core/ext/lb_policy/grpclb/grpclb.c index af913d8a9d..515d379dbb 100644 --- a/src/core/ext/lb_policy/grpclb/grpclb.c +++ b/src/core/ext/lb_policy/grpclb/grpclb.c @@ -158,9 +158,6 @@ static void wrapped_rr_closure(grpc_exec_ctx *exec_ctx, void *arg, typedef struct pending_pick { struct pending_pick *next; - /* polling entity for the pick()'s async notification */ - grpc_polling_entity *pollent; - /* the initial metadata for the pick. See grpc_lb_policy_pick() */ grpc_metadata_batch *initial_metadata; @@ -180,7 +177,7 @@ typedef struct pending_pick { wrapped_rr_closure_arg wrapped_on_complete_arg; } pending_pick; -static void add_pending_pick(pending_pick **root, grpc_polling_entity *pollent, +static void add_pending_pick(pending_pick **root, grpc_metadata_batch *initial_metadata, uint32_t initial_metadata_flags, grpc_connected_subchannel **target, @@ -189,7 +186,6 @@ static void add_pending_pick(pending_pick **root, grpc_polling_entity *pollent, memset(pp, 0, sizeof(pending_pick)); memset(&pp->wrapped_on_complete_arg, 0, sizeof(wrapped_rr_closure_arg)); pp->next = *root; - pp->pollent = pollent; pp->target = target; pp->initial_metadata = initial_metadata; pp->initial_metadata_flags = initial_metadata_flags; @@ -359,9 +355,9 @@ static void rr_handover(grpc_exec_ctx *exec_ctx, glb_lb_policy *glb_policy, gpr_log(GPR_INFO, "Pending pick about to PICK from 0x%" PRIxPTR "", (intptr_t)glb_policy->rr_policy); } - grpc_lb_policy_pick(exec_ctx, glb_policy->rr_policy, pp->pollent, - pp->initial_metadata, pp->initial_metadata_flags, - pp->target, &pp->wrapped_on_complete); + grpc_lb_policy_pick(exec_ctx, glb_policy->rr_policy, pp->initial_metadata, + pp->initial_metadata_flags, pp->target, + &pp->wrapped_on_complete); pp->wrapped_on_complete_arg.owning_pending_node = pp; } @@ -541,8 +537,6 @@ static void glb_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, while (pp != NULL) { pending_pick *next = pp->next; if (pp->target == target) { - grpc_polling_entity_del_from_pollset_set( - exec_ctx, pp->pollent, glb_policy->base.interested_parties); *target = NULL; grpc_exec_ctx_sched(exec_ctx, &pp->wrapped_on_complete, GRPC_ERROR_CANCELLED, NULL); @@ -572,8 +566,6 @@ static void glb_cancel_picks(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, pending_pick *next = pp->next; if ((pp->initial_metadata_flags & initial_metadata_flags_mask) == initial_metadata_flags_eq) { - grpc_polling_entity_del_from_pollset_set( - exec_ctx, pp->pollent, glb_policy->base.interested_parties); grpc_exec_ctx_sched(exec_ctx, &pp->wrapped_on_complete, GRPC_ERROR_CANCELLED, NULL); gpr_free(pp); @@ -603,7 +595,6 @@ static void glb_exit_idle(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) { } static int glb_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, - grpc_polling_entity *pollent, grpc_metadata_batch *initial_metadata, uint32_t initial_metadata_flags, grpc_connected_subchannel **target, @@ -623,8 +614,8 @@ static int glb_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, glb_policy->wc_arg.wrapped_closure = on_complete; grpc_closure_init(&glb_policy->wrapped_on_complete, wrapped_rr_closure, &glb_policy->wc_arg); - r = grpc_lb_policy_pick(exec_ctx, glb_policy->rr_policy, pollent, - initial_metadata, initial_metadata_flags, target, + r = grpc_lb_policy_pick(exec_ctx, glb_policy->rr_policy, initial_metadata, + initial_metadata_flags, target, &glb_policy->wrapped_on_complete); if (r != 0) { /* the call to grpc_lb_policy_pick has been sychronous. Unreffing the RR @@ -639,9 +630,7 @@ static int glb_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, GRPC_ERROR_NONE, NULL); } } else { - grpc_polling_entity_add_to_pollset_set(exec_ctx, pollent, - glb_policy->base.interested_parties); - add_pending_pick(&glb_policy->pending_picks, pollent, initial_metadata, + add_pending_pick(&glb_policy->pending_picks, initial_metadata, initial_metadata_flags, target, on_complete); if (!glb_policy->started_picking) { @@ -769,7 +758,7 @@ static lb_client_data *lb_client_data_create(glb_lb_policy *glb_policy) { /* Note the following LB call progresses every time there's activity in \a * glb_policy->base.interested_parties, which is comprised of the polling - * entities passed to glb_pick(). */ + * entities from client_channel. */ lb_client->lb_call = grpc_channel_create_pollset_set_call( glb_policy->lb_channel, NULL, GRPC_PROPAGATE_DEFAULTS, glb_policy->base.interested_parties, "/BalanceLoad", diff --git a/src/core/ext/lb_policy/pick_first/pick_first.c b/src/core/ext/lb_policy/pick_first/pick_first.c index 9decf70692..a1a438c1df 100644 --- a/src/core/ext/lb_policy/pick_first/pick_first.c +++ b/src/core/ext/lb_policy/pick_first/pick_first.c @@ -39,7 +39,6 @@ typedef struct pending_pick { struct pending_pick *next; - grpc_polling_entity *pollent; uint32_t initial_metadata_flags; grpc_connected_subchannel **target; grpc_closure *on_complete; @@ -119,8 +118,6 @@ static void pf_shutdown(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) { while (pp != NULL) { pending_pick *next = pp->next; *pp->target = NULL; - grpc_polling_entity_del_from_pollset_set(exec_ctx, pp->pollent, - p->base.interested_parties); grpc_exec_ctx_sched(exec_ctx, pp->on_complete, GRPC_ERROR_NONE, NULL); gpr_free(pp); pp = next; @@ -137,8 +134,6 @@ static void pf_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, while (pp != NULL) { pending_pick *next = pp->next; if (pp->target == target) { - grpc_polling_entity_del_from_pollset_set(exec_ctx, pp->pollent, - p->base.interested_parties); *target = NULL; grpc_exec_ctx_sched(exec_ctx, pp->on_complete, GRPC_ERROR_CREATE("Pick Cancelled"), NULL); @@ -164,8 +159,6 @@ static void pf_cancel_picks(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, pending_pick *next = pp->next; if ((pp->initial_metadata_flags & initial_metadata_flags_mask) == initial_metadata_flags_eq) { - grpc_polling_entity_del_from_pollset_set(exec_ctx, pp->pollent, - p->base.interested_parties); grpc_exec_ctx_sched(exec_ctx, pp->on_complete, GRPC_ERROR_CREATE("Pick Cancelled"), NULL); gpr_free(pp); @@ -199,7 +192,6 @@ static void pf_exit_idle(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) { } static int pf_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, - grpc_polling_entity *pollent, grpc_metadata_batch *initial_metadata, uint32_t initial_metadata_flags, grpc_connected_subchannel **target, @@ -225,11 +217,8 @@ static int pf_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, if (!p->started_picking) { start_picking(exec_ctx, p); } - grpc_polling_entity_add_to_pollset_set(exec_ctx, pollent, - p->base.interested_parties); pp = gpr_malloc(sizeof(*pp)); pp->next = p->pending_picks; - pp->pollent = pollent; pp->target = target; pp->initial_metadata_flags = initial_metadata_flags; pp->on_complete = on_complete; @@ -315,8 +304,6 @@ static void pf_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg, while ((pp = p->pending_picks)) { p->pending_picks = pp->next; *pp->target = selected; - grpc_polling_entity_del_from_pollset_set(exec_ctx, pp->pollent, - p->base.interested_parties); grpc_exec_ctx_sched(exec_ctx, pp->on_complete, GRPC_ERROR_NONE, NULL); gpr_free(pp); } diff --git a/src/core/ext/lb_policy/round_robin/round_robin.c b/src/core/ext/lb_policy/round_robin/round_robin.c index 7bcf608ab9..9b557f423e 100644 --- a/src/core/ext/lb_policy/round_robin/round_robin.c +++ b/src/core/ext/lb_policy/round_robin/round_robin.c @@ -76,7 +76,6 @@ int grpc_lb_round_robin_trace = 0; * Once a pick is available, \a target is updated and \a on_complete called. */ typedef struct pending_pick { struct pending_pick *next; - grpc_polling_entity *pollent; uint32_t initial_metadata_flags; grpc_connected_subchannel **target; grpc_closure *on_complete; @@ -290,8 +289,6 @@ static void rr_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, while (pp != NULL) { pending_pick *next = pp->next; if (pp->target == target) { - grpc_polling_entity_del_from_pollset_set(exec_ctx, pp->pollent, - p->base.interested_parties); *target = NULL; grpc_exec_ctx_sched(exec_ctx, pp->on_complete, GRPC_ERROR_CANCELLED, NULL); @@ -317,8 +314,6 @@ static void rr_cancel_picks(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, pending_pick *next = pp->next; if ((pp->initial_metadata_flags & initial_metadata_flags_mask) == initial_metadata_flags_eq) { - grpc_polling_entity_del_from_pollset_set(exec_ctx, pp->pollent, - p->base.interested_parties); *pp->target = NULL; grpc_exec_ctx_sched(exec_ctx, pp->on_complete, GRPC_ERROR_CANCELLED, NULL); @@ -361,7 +356,6 @@ static void rr_exit_idle(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) { } static int rr_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, - grpc_polling_entity *pollent, grpc_metadata_batch *initial_metadata, uint32_t initial_metadata_flags, grpc_connected_subchannel **target, @@ -385,11 +379,8 @@ static int rr_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, if (!p->started_picking) { start_picking(exec_ctx, p); } - grpc_polling_entity_add_to_pollset_set(exec_ctx, pollent, - p->base.interested_parties); pp = gpr_malloc(sizeof(*pp)); pp->next = p->pending_picks; - pp->pollent = pollent; pp->target = target; pp->on_complete = on_complete; pp->initial_metadata_flags = initial_metadata_flags; @@ -440,8 +431,6 @@ static void rr_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg, "[RR CONN CHANGED] TARGET <-- SUBCHANNEL %p (NODE %p)", selected->subchannel, selected); } - grpc_polling_entity_del_from_pollset_set(exec_ctx, pp->pollent, - p->base.interested_parties); grpc_exec_ctx_sched(exec_ctx, pp->on_complete, GRPC_ERROR_NONE, NULL); gpr_free(pp); } -- cgit v1.2.3 From 9a0e63c1345711acb28288bd68ccd87cd032960b Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Thu, 1 Sep 2016 18:04:32 -0700 Subject: Remove unnecessary locks on channel_data's mutex --- src/core/ext/client_config/client_channel.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/core/ext/client_config/client_channel.c b/src/core/ext/client_config/client_channel.c index b5b6cc4df0..8f2311a6a8 100644 --- a/src/core/ext/client_config/client_channel.c +++ b/src/core/ext/client_config/client_channel.c @@ -462,10 +462,8 @@ static void subchannel_ready(grpc_exec_ctx *exec_ctx, void *arg, gpr_mu_lock(&calld->mu); GPR_ASSERT(calld->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL); - // gpr_mu_lock(&chand->mu); grpc_polling_entity_del_from_pollset_set(exec_ctx, calld->pollent, chand->interested_parties); - // gpr_mu_unlock(&chand->mu); calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING; if (calld->connected_subchannel == NULL) { gpr_atm_no_barrier_store(&calld->subchannel_call, 1); @@ -676,20 +674,14 @@ retry: calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL; grpc_closure_init(&calld->next_step, subchannel_ready, elem); GRPC_CALL_STACK_REF(calld->owning_call, "pick_subchannel"); - // grpc_polling_entity_add_to_pollset_set(exec_ctx, calld->pollent, - // chand->interested_parties); if (pick_subchannel(exec_ctx, elem, op->send_initial_metadata, op->send_initial_metadata_flags, &calld->connected_subchannel, &calld->next_step)) { calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING; - // grpc_polling_entity_del_from_pollset_set(exec_ctx, calld->pollent, - // chand->interested_parties); GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "pick_subchannel"); } else { - // gpr_mu_lock(&chand->mu); grpc_polling_entity_add_to_pollset_set(exec_ctx, calld->pollent, chand->interested_parties); - // gpr_mu_unlock(&chand->mu); } } /* if we've got a subchannel, then let's ask it to create a call */ -- cgit v1.2.3 From 144ce657c6a2cc81104007509226c54817003b7c Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Thu, 1 Sep 2016 18:19:34 -0700 Subject: Add comments for pick_subchannel --- src/core/ext/client_config/client_channel.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/core/ext/client_config/client_channel.c b/src/core/ext/client_config/client_channel.c index 8f2311a6a8..dfa9746004 100644 --- a/src/core/ext/client_config/client_channel.c +++ b/src/core/ext/client_config/client_channel.c @@ -511,6 +511,9 @@ typedef struct { grpc_closure closure; } continue_picking_args; +/** Return true if subchannel is available immediately (in which case on_ready + should not be called), or false otherwise (in which case on_ready should be + called when the subchannel is available). */ static bool pick_subchannel(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_metadata_batch *initial_metadata, uint32_t initial_metadata_flags, @@ -674,6 +677,9 @@ retry: calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL; grpc_closure_init(&calld->next_step, subchannel_ready, elem); GRPC_CALL_STACK_REF(calld->owning_call, "pick_subchannel"); + /* If a subchannel is not available immediately, the polling entity from + call_data should be provided to channel_data's interested_parties, so + that IO of the lb_policy and resolver could be done under it. */ if (pick_subchannel(exec_ctx, elem, op->send_initial_metadata, op->send_initial_metadata_flags, &calld->connected_subchannel, &calld->next_step)) { -- cgit v1.2.3 From b4291642758342a596a11146bef88b4aaf059a76 Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Thu, 1 Sep 2016 19:17:14 -0700 Subject: Fix grpclb --- src/core/ext/lb_policy/grpclb/grpclb.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/ext/lb_policy/grpclb/grpclb.c b/src/core/ext/lb_policy/grpclb/grpclb.c index 515d379dbb..2a23011e81 100644 --- a/src/core/ext/lb_policy/grpclb/grpclb.c +++ b/src/core/ext/lb_policy/grpclb/grpclb.c @@ -335,6 +335,9 @@ static void rr_handover(grpc_exec_ctx *exec_ctx, glb_lb_policy *glb_policy, (intptr_t)glb_policy->rr_policy); } GPR_ASSERT(glb_policy->rr_policy != NULL); + grpc_pollset_set_add_pollset_set(exec_ctx, + glb_policy->rr_policy->interested_parties, + glb_policy->base.interested_parties); glb_policy->rr_connectivity->state = grpc_lb_policy_check_connectivity( exec_ctx, glb_policy->rr_policy, &error); grpc_lb_policy_notify_on_state_change( -- cgit v1.2.3 From 02b87cdacb68bdda78df345d7cfdecceaf13a1ec Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 2 Sep 2016 09:50:08 -0700 Subject: Small fixes --- src/core/lib/surface/call.c | 13 +++++++++---- test/core/end2end/tests/no_logging.c | 1 + 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c index df07b96f28..97bfd587d2 100644 --- a/src/core/lib/surface/call.c +++ b/src/core/lib/surface/call.c @@ -1090,9 +1090,14 @@ static void finish_batch_completion(grpc_exec_ctx *exec_ctx, void *user_data, static void post_batch_completion(grpc_exec_ctx *exec_ctx, batch_control *bctl) { grpc_call *call = bctl->call; + grpc_error *error = bctl->error; + if (bctl->recv_final_op) { + GRPC_ERROR_UNREF(error); + error = GRPC_ERROR_NONE; + } if (bctl->is_notify_tag_closure) { /* unrefs bctl->error */ - grpc_closure_run(exec_ctx, bctl->notify_tag, bctl->error); + grpc_closure_run(exec_ctx, bctl->notify_tag, error); gpr_mu_lock(&call->mu); bctl->call->used_batches = (uint8_t)(bctl->call->used_batches & @@ -1101,7 +1106,7 @@ static void post_batch_completion(grpc_exec_ctx *exec_ctx, GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, "completion"); } else { /* unrefs bctl->error */ - grpc_cq_end_op(exec_ctx, bctl->call->cq, bctl->notify_tag, bctl->error, + grpc_cq_end_op(exec_ctx, bctl->call->cq, bctl->notify_tag, error, finish_batch_completion, bctl, &bctl->cq_completion); } } @@ -1273,7 +1278,7 @@ static void receiving_initial_metadata_ready(grpc_exec_ctx *exec_ctx, gpr_mu_lock(&call->mu); - add_batch_error(bctl, GRPC_ERROR_REF(error)); + add_batch_error(bctl, GRPC_ERROR_REF(error)); if (error == GRPC_ERROR_NONE) { grpc_metadata_batch *md = &call->metadata_batch[1 /* is_receiving */][0 /* is_trailing */]; @@ -1367,7 +1372,7 @@ static void finish_batch(grpc_exec_ctx *exec_ctx, void *bctlp, GRPC_ERROR_UNREF(error); error = GRPC_ERROR_NONE; } - add_batch_error(bctl, GRPC_ERROR_REF(error)); + add_batch_error(bctl, GRPC_ERROR_REF(error)); gpr_mu_unlock(&call->mu); if (gpr_unref(&bctl->steps_to_complete)) { post_batch_completion(exec_ctx, bctl); diff --git a/test/core/end2end/tests/no_logging.c b/test/core/end2end/tests/no_logging.c index afa98decc5..d03d336329 100644 --- a/test/core/end2end/tests/no_logging.c +++ b/test/core/end2end/tests/no_logging.c @@ -287,6 +287,7 @@ static void test_no_logging_in_one_request(grpc_end2end_test_config config) { void no_logging(grpc_end2end_test_config config) { gpr_set_log_verbosity(GPR_LOG_SEVERITY_DEBUG); + grpc_tracer_set_enabled("all", 0); test_no_logging_in_one_request(config); test_no_error_logging_in_entire_process(config); } -- cgit v1.2.3 From 86037cd0e7a1e26d77be46bedc45d6d6167d98a7 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 2 Sep 2016 19:58:43 -0700 Subject: fixes --- src/core/lib/iomgr/combiner.c | 22 +++++++++---- src/core/lib/iomgr/error.h | 8 +++-- src/core/lib/iomgr/tcp_posix.c | 2 +- src/core/lib/iomgr/workqueue_posix.c | 62 ++++++++++++++++++++---------------- 4 files changed, 57 insertions(+), 37 deletions(-) diff --git a/src/core/lib/iomgr/combiner.c b/src/core/lib/iomgr/combiner.c index 981d3348ce..721db6337e 100644 --- a/src/core/lib/iomgr/combiner.c +++ b/src/core/lib/iomgr/combiner.c @@ -112,7 +112,8 @@ void grpc_combiner_destroy(grpc_exec_ctx *exec_ctx, grpc_combiner *lock) { } } -static void queue_on_exec_ctx(grpc_exec_ctx *exec_ctx, grpc_combiner *lock) { +static void push_last_on_exec_ctx(grpc_exec_ctx *exec_ctx, + grpc_combiner *lock) { lock->next_combiner_on_this_exec_ctx = NULL; if (exec_ctx->active_combiner == NULL) { exec_ctx->active_combiner = exec_ctx->last_combiner = lock; @@ -122,6 +123,15 @@ static void queue_on_exec_ctx(grpc_exec_ctx *exec_ctx, grpc_combiner *lock) { } } +static void push_first_on_exec_ctx(grpc_exec_ctx *exec_ctx, + grpc_combiner *lock) { + lock->next_combiner_on_this_exec_ctx = exec_ctx->active_combiner; + exec_ctx->active_combiner = lock; + if (lock->next_combiner_on_this_exec_ctx == NULL) { + exec_ctx->last_combiner = lock; + } +} + void grpc_combiner_execute(grpc_exec_ctx *exec_ctx, grpc_combiner *lock, grpc_closure *cl, grpc_error *error, bool covered_by_poller) { @@ -140,7 +150,7 @@ void grpc_combiner_execute(grpc_exec_ctx *exec_ctx, grpc_combiner *lock, if (last == 1) { // code will be written when the exec_ctx calls // grpc_combiner_continue_exec_ctx - queue_on_exec_ctx(exec_ctx, lock); + push_last_on_exec_ctx(exec_ctx, lock); } GPR_TIMER_END("combiner.execute", 0); } @@ -155,7 +165,7 @@ static void move_next(grpc_exec_ctx *exec_ctx) { static void offload(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { grpc_combiner *lock = arg; - queue_on_exec_ctx(exec_ctx, lock); + push_last_on_exec_ctx(exec_ctx, lock); } static void queue_offload(grpc_exec_ctx *exec_ctx, grpc_combiner *lock) { @@ -230,10 +240,11 @@ bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) { } GPR_TIMER_MARK("unref", 0); + move_next(exec_ctx); + lock->time_to_execute_final_list = false; gpr_atm old_state = gpr_atm_full_fetch_add(&lock->state, -2); GRPC_COMBINER_TRACE( gpr_log(GPR_DEBUG, "C:%p finish old_state=%" PRIdPTR, lock, old_state)); - lock->time_to_execute_final_list = false; switch (old_state) { default: // we have multiple queued work items: just continue executing them @@ -245,11 +256,9 @@ bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) { } break; case 3: // had one count, one unorphaned --> unlocked unorphaned - move_next(exec_ctx); GPR_TIMER_END("combiner.continue_exec_ctx", 0); return true; case 2: // and one count, one orphaned --> unlocked and orphaned - move_next(exec_ctx); really_destroy(exec_ctx, lock); GPR_TIMER_END("combiner.continue_exec_ctx", 0); return true; @@ -260,6 +269,7 @@ bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) { GPR_TIMER_END("combiner.continue_exec_ctx", 0); GPR_UNREACHABLE_CODE(return true); } + push_first_on_exec_ctx(exec_ctx, lock); GPR_TIMER_END("combiner.continue_exec_ctx", 0); return true; } diff --git a/src/core/lib/iomgr/error.h b/src/core/lib/iomgr/error.h index 6c769accdb..2ab3ef9f40 100644 --- a/src/core/lib/iomgr/error.h +++ b/src/core/lib/iomgr/error.h @@ -123,9 +123,13 @@ typedef enum { GRPC_ERROR_TIME_CREATED, } grpc_error_times; +/// The following "special" errors can be propagated without allocating memory. +/// They are always even so that other code (particularly combiner locks) can +/// safely use the lower bit for themselves. + #define GRPC_ERROR_NONE ((grpc_error *)NULL) -#define GRPC_ERROR_OOM ((grpc_error *)1) -#define GRPC_ERROR_CANCELLED ((grpc_error *)2) +#define GRPC_ERROR_OOM ((grpc_error *)2) +#define GRPC_ERROR_CANCELLED ((grpc_error *)4) const char *grpc_error_string(grpc_error *error); void grpc_error_free_string(const char *str); diff --git a/src/core/lib/iomgr/tcp_posix.c b/src/core/lib/iomgr/tcp_posix.c index ffdc7c7b42..00fd77679a 100644 --- a/src/core/lib/iomgr/tcp_posix.c +++ b/src/core/lib/iomgr/tcp_posix.c @@ -279,7 +279,7 @@ static void tcp_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, tcp->finished_edge = false; grpc_fd_notify_on_read(exec_ctx, tcp->em_fd, &tcp->read_closure); } else { - grpc_exec_ctx_sched(exec_ctx, &tcp->read_closure, GRPC_ERROR_NONE, grpc_fd_get_workqueue(tcp->em_fd)); + grpc_exec_ctx_sched(exec_ctx, &tcp->read_closure, GRPC_ERROR_NONE, NULL); } } diff --git a/src/core/lib/iomgr/workqueue_posix.c b/src/core/lib/iomgr/workqueue_posix.c index 6c27c3b41e..c7d4fc6423 100644 --- a/src/core/lib/iomgr/workqueue_posix.c +++ b/src/core/lib/iomgr/workqueue_posix.c @@ -76,7 +76,8 @@ static void workqueue_destroy(grpc_exec_ctx *exec_ctx, static void workqueue_orphan(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue) { - if (gpr_atm_full_fetch_add(&workqueue->state, -1) == 1) { + gpr_atm last = gpr_atm_full_fetch_add(&workqueue->state, -1); + if (last == 1) { workqueue_destroy(exec_ctx, workqueue); } } @@ -143,37 +144,40 @@ static void on_readable(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { gpr_free(workqueue); } else { error = grpc_wakeup_fd_consume_wakeup(&workqueue->wakeup_fd); - gpr_mpscq_node *n = gpr_mpscq_pop(&workqueue->queue); - if (error == GRPC_ERROR_NONE) { - grpc_fd_notify_on_read(exec_ctx, workqueue->wakeup_read_fd, - &workqueue->read_closure); - } else { + if (error != GRPC_ERROR_NONE) { /* recurse to get error handling */ on_readable(exec_ctx, arg, error); - } - if (n == NULL) { - /* try again - queue in an inconsistant state */ - wakeup(exec_ctx, workqueue); } else { - switch (gpr_atm_full_fetch_add(&workqueue->state, -2)) { - case 3: // had one count, one unorphaned --> done, unorphaned - break; - case 2: // had one count, one orphaned --> done, orphaned - workqueue_destroy(exec_ctx, workqueue); - break; - case 1: - case 0: - // these values are illegal - representing an already done or - // deleted workqueue - GPR_UNREACHABLE_CODE(break); - default: - // schedule a wakeup since there's more to do - wakeup(exec_ctx, workqueue); + gpr_mpscq_node *n = gpr_mpscq_pop(&workqueue->queue); + if (n == NULL) { + /* try again - queue in an ephemerally inconsistent state */ + wakeup(exec_ctx, workqueue); + grpc_fd_notify_on_read(exec_ctx, workqueue->wakeup_read_fd, + &workqueue->read_closure); + } else { + gpr_atm last = gpr_atm_full_fetch_add(&workqueue->state, -2); + switch (last) { + default: + // schedule a wakeup since there's more to do + wakeup(exec_ctx, workqueue); + break; + case 3: // had one count, one unorphaned --> done, unorphaned + break; + case 2: // had one count, one orphaned --> done, orphaned + workqueue_destroy(exec_ctx, workqueue); + break; + case 1: + case 0: + // these values are illegal - representing an already done or + // deleted workqueue + GPR_UNREACHABLE_CODE(break); + } + grpc_fd_notify_on_read(exec_ctx, workqueue->wakeup_read_fd, + &workqueue->read_closure); + grpc_closure *cl = (grpc_closure *)n; + grpc_error *clerr = cl->error_data.error; + grpc_closure_run(exec_ctx, cl, clerr); } - grpc_closure *cl = (grpc_closure *)n; - grpc_error *clerr = cl->error_data.error; - cl->cb(exec_ctx, cl->cb_arg, clerr); - GRPC_ERROR_UNREF(clerr); } } @@ -183,6 +187,7 @@ static void on_readable(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { void grpc_workqueue_enqueue(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue, grpc_closure *closure, grpc_error *error) { GPR_TIMER_BEGIN("workqueue.enqueue", 0); + GRPC_WORKQUEUE_REF(workqueue, "enqueue"); gpr_atm last = gpr_atm_full_fetch_add(&workqueue->state, 2); GPR_ASSERT(last & 1); closure->error_data.error = error; @@ -190,6 +195,7 @@ void grpc_workqueue_enqueue(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue, if (last == 1) { wakeup(exec_ctx, workqueue); } + GRPC_WORKQUEUE_UNREF(exec_ctx, workqueue, "enqueue"); GPR_TIMER_END("workqueue.enqueue", 0); } -- cgit v1.2.3 From 2c4043bd8a822beb07b9cd2feff759302237966f Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 5 Sep 2016 14:50:16 -0700 Subject: fixes --- .../transport/chttp2/transport/chttp2_transport.c | 26 ++++++++++++---- src/core/ext/transport/chttp2/transport/writing.c | 4 ++- src/core/lib/surface/completion_queue.c | 35 ++++++++++++++-------- 3 files changed, 46 insertions(+), 19 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 49fff80370..03e1ce0ab7 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -538,6 +538,20 @@ grpc_chttp2_stream *grpc_chttp2_parsing_accept_stream(grpc_exec_ctx *exec_ctx, * OUTPUT PROCESSING */ +static const char *write_state_name(grpc_chttp2_write_state st) { + switch (st) { + case GRPC_CHTTP2_WRITE_STATE_IDLE: return "IDLE"; + case GRPC_CHTTP2_WRITE_STATE_WRITING: return "WRITING"; + case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_TO_COME: return "WRITING+MORE"; + } + GPR_UNREACHABLE_CODE(return "UNKNOWN"); +} + +static void set_write_state(grpc_chttp2_transport *t, grpc_chttp2_write_state st) { + GRPC_CHTTP2_IF_TRACING(gpr_log(GPR_DEBUG, "W:%p %s state %s -> %s", t, t->is_client ? "CLIENT" : "SERVER", write_state_name(t->write_state), write_state_name(st))); + t->write_state = st; +} + void grpc_chttp2_initiate_write(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, bool covered_by_poller, const char *reason) { @@ -545,14 +559,14 @@ void grpc_chttp2_initiate_write(grpc_exec_ctx *exec_ctx, switch (t->write_state) { case GRPC_CHTTP2_WRITE_STATE_IDLE: - t->write_state = GRPC_CHTTP2_WRITE_STATE_WRITING; + set_write_state(t, GRPC_CHTTP2_WRITE_STATE_WRITING); GRPC_CHTTP2_REF_TRANSPORT(t, "writing"); grpc_combiner_execute_finally(exec_ctx, t->combiner, &t->write_action_begin_locked, GRPC_ERROR_NONE); break; case GRPC_CHTTP2_WRITE_STATE_WRITING: - t->write_state = GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_TO_COME; + set_write_state(t, GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_TO_COME); break; case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_TO_COME: break; @@ -576,10 +590,10 @@ static void write_action_begin_locked(grpc_exec_ctx *exec_ctx, void *gt, grpc_chttp2_transport *t = gt; GPR_ASSERT(t->write_state != GRPC_CHTTP2_WRITE_STATE_IDLE); if (!t->closed && grpc_chttp2_begin_write(exec_ctx, t)) { - t->write_state = GRPC_CHTTP2_WRITE_STATE_WRITING; + set_write_state(t, GRPC_CHTTP2_WRITE_STATE_WRITING); grpc_exec_ctx_sched(exec_ctx, &t->write_action, GRPC_ERROR_NONE, NULL); } else { - t->write_state = GRPC_CHTTP2_WRITE_STATE_IDLE; + set_write_state(t, GRPC_CHTTP2_WRITE_STATE_IDLE); GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "writing"); } GPR_TIMER_END("write_action_begin_locked", 0); @@ -617,11 +631,11 @@ static void write_action_end_locked(grpc_exec_ctx *exec_ctx, void *tp, GPR_UNREACHABLE_CODE(break); case GRPC_CHTTP2_WRITE_STATE_WRITING: GPR_TIMER_MARK("state=writing", 0); - t->write_state = GRPC_CHTTP2_WRITE_STATE_IDLE; + set_write_state(t, GRPC_CHTTP2_WRITE_STATE_IDLE); break; case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_TO_COME: GPR_TIMER_MARK("state=writing_stale_with_poller", 0); - t->write_state = GRPC_CHTTP2_WRITE_STATE_WRITING; + set_write_state(t, GRPC_CHTTP2_WRITE_STATE_WRITING); GRPC_CHTTP2_REF_TRANSPORT(t, "writing"); grpc_combiner_execute_finally(exec_ctx, t->combiner, &t->write_action_begin_locked, diff --git a/src/core/ext/transport/chttp2/transport/writing.c b/src/core/ext/transport/chttp2/transport/writing.c index c73360ec9c..e34d2991fb 100644 --- a/src/core/ext/transport/chttp2/transport/writing.c +++ b/src/core/ext/transport/chttp2/transport/writing.c @@ -109,6 +109,8 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, bool sent_initial_metadata = s->sent_initial_metadata; bool now_writing = false; + GRPC_CHTTP2_IF_TRACING(gpr_log(GPR_DEBUG, "W:%p %s[%d] im-(sent,send)=(%d,%d) announce=%d", t, t->is_client?"CLIENT":"SERVER", s->id, sent_initial_metadata, s->send_initial_metadata!=NULL, s->announce_window)); + /* send initial metadata if it's available */ if (!sent_initial_metadata && s->send_initial_metadata) { grpc_chttp2_encode_header(&t->hpack_compressor, s->id, @@ -120,7 +122,7 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, now_writing = true; } /* send any window updates */ - if (s->announce_window > 0 && sent_initial_metadata) { + if (s->announce_window > 0) { uint32_t announce = s->announce_window; gpr_slice_buffer_add(&t->outbuf, grpc_chttp2_window_update_create( diff --git a/src/core/lib/surface/completion_queue.c b/src/core/lib/surface/completion_queue.c index 1124290699..4e0feb56ac 100644 --- a/src/core/lib/surface/completion_queue.c +++ b/src/core/lib/surface/completion_queue.c @@ -319,6 +319,7 @@ typedef struct { gpr_timespec deadline; grpc_cq_completion *stolen_completion; void *tag; /* for pluck */ + bool first_loop; } cq_is_finished_arg; static bool cq_is_next_finished(grpc_exec_ctx *exec_ctx, void *arg) { @@ -342,7 +343,8 @@ static bool cq_is_next_finished(grpc_exec_ctx *exec_ctx, void *arg) { } gpr_mu_unlock(cq->mu); } - return gpr_time_cmp(a->deadline, gpr_now(a->deadline.clock_type)) < 0; + return !a->first_loop && + gpr_time_cmp(a->deadline, gpr_now(a->deadline.clock_type)) < 0; } #ifndef NDEBUG @@ -370,7 +372,6 @@ grpc_event grpc_completion_queue_next(grpc_completion_queue *cc, gpr_timespec deadline, void *reserved) { grpc_event ret; grpc_pollset_worker *worker = NULL; - int first_loop = 1; gpr_timespec now; GPR_TIMER_BEGIN("grpc_completion_queue_next", 0); @@ -392,8 +393,13 @@ grpc_event grpc_completion_queue_next(grpc_completion_queue *cc, GRPC_CQ_INTERNAL_REF(cc, "next"); gpr_mu_lock(cc->mu); cq_is_finished_arg is_finished_arg = { - gpr_atm_no_barrier_load(&cc->things_queued_ever), cc, deadline, NULL, - NULL}; + .last_seen_things_queued_ever = + gpr_atm_no_barrier_load(&cc->things_queued_ever), + .cq = cc, + .deadline = deadline, + .stolen_completion = NULL, + .tag = NULL, + .first_loop = true}; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT_WITH_FINISH_CHECK( cq_is_next_finished, &is_finished_arg); for (;;) { @@ -427,14 +433,13 @@ grpc_event grpc_completion_queue_next(grpc_completion_queue *cc, break; } now = gpr_now(GPR_CLOCK_MONOTONIC); - if (!first_loop && gpr_time_cmp(now, deadline) >= 0) { + if (!is_finished_arg.first_loop && gpr_time_cmp(now, deadline) >= 0) { gpr_mu_unlock(cc->mu); memset(&ret, 0, sizeof(ret)); ret.type = GRPC_QUEUE_TIMEOUT; dump_pending_tags(cc); break; } - first_loop = 0; /* Check alarms - these are a global resource so we just ping each time through on every pollset. May update deadline to ensure timely wakeups. @@ -461,6 +466,7 @@ grpc_event grpc_completion_queue_next(grpc_completion_queue *cc, break; } } + is_finished_arg.first_loop = false; } GRPC_SURFACE_TRACE_RETURNED_EVENT(cc, &ret); GRPC_CQ_INTERNAL_UNREF(cc, "next"); @@ -523,7 +529,8 @@ static bool cq_is_pluck_finished(grpc_exec_ctx *exec_ctx, void *arg) { } gpr_mu_unlock(cq->mu); } - return gpr_time_cmp(a->deadline, gpr_now(a->deadline.clock_type)) < 0; + return !a->first_loop && + gpr_time_cmp(a->deadline, gpr_now(a->deadline.clock_type)) < 0; } grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag, @@ -533,7 +540,6 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag, grpc_cq_completion *prev; grpc_pollset_worker *worker = NULL; gpr_timespec now; - int first_loop = 1; GPR_TIMER_BEGIN("grpc_completion_queue_pluck", 0); @@ -556,8 +562,13 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag, GRPC_CQ_INTERNAL_REF(cc, "pluck"); gpr_mu_lock(cc->mu); cq_is_finished_arg is_finished_arg = { - gpr_atm_no_barrier_load(&cc->things_queued_ever), cc, deadline, NULL, - tag}; + .last_seen_things_queued_ever = + gpr_atm_no_barrier_load(&cc->things_queued_ever), + .cq = cc, + .deadline = deadline, + .stolen_completion = NULL, + .tag = tag, + .first_loop = true}; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT_WITH_FINISH_CHECK( cq_is_pluck_finished, &is_finished_arg); for (;;) { @@ -607,7 +618,7 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag, break; } now = gpr_now(GPR_CLOCK_MONOTONIC); - if (!first_loop && gpr_time_cmp(now, deadline) >= 0) { + if (!is_finished_arg.first_loop && gpr_time_cmp(now, deadline) >= 0) { del_plucker(cc, tag, &worker); gpr_mu_unlock(cc->mu); memset(&ret, 0, sizeof(ret)); @@ -615,7 +626,6 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag, dump_pending_tags(cc); break; } - first_loop = 0; /* Check alarms - these are a global resource so we just ping each time through on every pollset. May update deadline to ensure timely wakeups. @@ -642,6 +652,7 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag, break; } } + is_finished_arg.first_loop = false; del_plucker(cc, tag, &worker); } done: -- cgit v1.2.3 From fd4c6471ce543f1185a1e46643943f551d675807 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 6 Sep 2016 20:03:06 -0700 Subject: Fix memory leak, make it easier to spot in future --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 6 +++--- src/core/ext/transport/chttp2/transport/writing.c | 11 +++++++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 03e1ce0ab7..ec9de47725 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -388,7 +388,7 @@ static void close_transport_locked(grpc_exec_ctx *exec_ctx, /* flush writable stream list to avoid dangling references */ grpc_chttp2_stream *s; while (grpc_chttp2_list_pop_writable_stream(t, &s)) { - GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing"); + GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing:close"); } } GRPC_ERROR_UNREF(error); @@ -579,7 +579,7 @@ void grpc_chttp2_become_writable(grpc_exec_ctx *exec_ctx, grpc_chttp2_stream *s, bool covered_by_poller, const char *reason) { if (!t->closed && grpc_chttp2_list_add_writable_stream(t, s)) { - GRPC_CHTTP2_STREAM_REF(s, "chttp2_writing"); + GRPC_CHTTP2_STREAM_REF(s, "chttp2_writing:become"); grpc_chttp2_initiate_write(exec_ctx, t, covered_by_poller, reason); } } @@ -1279,7 +1279,7 @@ static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, "Last stream closed after sending GOAWAY", &error, 1)); } if (grpc_chttp2_list_remove_writable_stream(t, s)) { - GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing"); + GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing:remove_stream"); } GRPC_ERROR_UNREF(error); diff --git a/src/core/ext/transport/chttp2/transport/writing.c b/src/core/ext/transport/chttp2/transport/writing.c index e34d2991fb..fbddb34c56 100644 --- a/src/core/ext/transport/chttp2/transport/writing.c +++ b/src/core/ext/transport/chttp2/transport/writing.c @@ -163,7 +163,7 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, s->sending_bytes += send_bytes; now_writing = true; if (s->flow_controlled_buffer.length > 0) { - GRPC_CHTTP2_STREAM_REF(s, "chttp2_writing"); + GRPC_CHTTP2_STREAM_REF(s, "chttp2_writing:fork"); grpc_chttp2_list_add_writable_stream(t, s); } } else if (t->outgoing_window == 0) { @@ -189,9 +189,12 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, } if (now_writing) { - grpc_chttp2_list_add_writing_stream(t, s); + if (!grpc_chttp2_list_add_writing_stream(t, s)) { + /* already in writing list: drop ref */ + GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing:already_writing"); + } } else { - GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing"); + GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing:no_write"); } } @@ -235,7 +238,7 @@ void grpc_chttp2_end_write(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_mark_stream_closed(exec_ctx, t, s, !t->is_client, 1, GRPC_ERROR_REF(error)); } - GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing"); + GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing:end"); } gpr_slice_buffer_reset_and_unref(&t->outbuf); GRPC_ERROR_UNREF(error); -- cgit v1.2.3 From bd37a21c2605abcd07f0aea2e4ddb258a88eda22 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 7 Sep 2016 11:28:56 -0700 Subject: Cleanup, debug support --- .../transport/chttp2/transport/chttp2_transport.c | 98 ++++++++++++++-------- .../ext/transport/chttp2/transport/frame_data.c | 29 ++++--- .../ext/transport/chttp2/transport/hpack_parser.c | 3 +- src/core/ext/transport/chttp2/transport/internal.h | 11 ++- .../ext/transport/chttp2/transport/stream_map.c | 2 + test/cpp/end2end/thread_stress_test.cc | 5 +- test/cpp/qps/client_sync.cc | 3 + 7 files changed, 100 insertions(+), 51 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index ec9de47725..5484d9a1ec 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -447,7 +447,6 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]; *t->accepting_stream = s; grpc_chttp2_stream_map_add(&t->stream_map, s->id, s); - s->in_stream_map = true; } GPR_TIMER_END("init_stream", 0); @@ -464,7 +463,6 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp, GPR_TIMER_BEGIN("destroy_stream", 0); GPR_ASSERT((s->write_closed && s->read_closed) || s->id == 0); - GPR_ASSERT(!s->in_stream_map); if (s->id != 0) { GPR_ASSERT(grpc_chttp2_stream_map_find(&t->stream_map, s->id) == NULL); } @@ -540,16 +538,23 @@ grpc_chttp2_stream *grpc_chttp2_parsing_accept_stream(grpc_exec_ctx *exec_ctx, static const char *write_state_name(grpc_chttp2_write_state st) { switch (st) { - case GRPC_CHTTP2_WRITE_STATE_IDLE: return "IDLE"; - case GRPC_CHTTP2_WRITE_STATE_WRITING: return "WRITING"; - case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_TO_COME: return "WRITING+MORE"; + case GRPC_CHTTP2_WRITE_STATE_IDLE: + return "IDLE"; + case GRPC_CHTTP2_WRITE_STATE_WRITING: + return "WRITING"; + case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_TO_COME: + return "WRITING+MORE"; } GPR_UNREACHABLE_CODE(return "UNKNOWN"); } -static void set_write_state(grpc_chttp2_transport *t, grpc_chttp2_write_state st) { - GRPC_CHTTP2_IF_TRACING(gpr_log(GPR_DEBUG, "W:%p %s state %s -> %s", t, t->is_client ? "CLIENT" : "SERVER", write_state_name(t->write_state), write_state_name(st))); - t->write_state = st; +static void set_write_state(grpc_chttp2_transport *t, + grpc_chttp2_write_state st) { + GRPC_CHTTP2_IF_TRACING(gpr_log(GPR_DEBUG, "W:%p %s state %s -> %s", t, + t->is_client ? "CLIENT" : "SERVER", + write_state_name(t->write_state), + write_state_name(st))); + t->write_state = st; } void grpc_chttp2_initiate_write(grpc_exec_ctx *exec_ctx, @@ -718,7 +723,6 @@ static void maybe_start_some_streams(grpc_exec_ctx *exec_ctx, [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]; s->max_recv_bytes = GPR_MAX(stream_incoming_window, s->max_recv_bytes); grpc_chttp2_stream_map_add(&t->stream_map, s->id, s); - s->in_stream_map = true; grpc_chttp2_become_writable(exec_ctx, t, s, true, "new_stream"); } /* cancel out streams that will never be started */ @@ -740,7 +744,8 @@ static grpc_closure *add_closure_barrier(grpc_closure *closure) { return closure; } -static void run_closure_and_null(grpc_exec_ctx *exec_ctx, grpc_closure **closure, grpc_error *error) { +static void null_then_run_closure(grpc_exec_ctx *exec_ctx, + grpc_closure **closure, grpc_error *error) { grpc_closure *c = *closure; *closure = NULL; grpc_closure_run(exec_ctx, c, error); @@ -805,7 +810,8 @@ static void continue_fetching_send_locked(grpc_exec_ctx *exec_ctx, ssize_t notify_offset = s->fetching_slice_end_offset; if (notify_offset <= 0) { grpc_chttp2_complete_closure_step( - exec_ctx, t, s, &s->fetching_send_message_finished, GRPC_ERROR_NONE, "fetching_send_message_finished"); + exec_ctx, t, s, &s->fetching_send_message_finished, GRPC_ERROR_NONE, + "fetching_send_message_finished"); } else { grpc_chttp2_write_cb *cb = t->write_cb_pool; if (cb == NULL) { @@ -947,7 +953,8 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, grpc_chttp2_complete_closure_step( exec_ctx, t, s, &s->send_initial_metadata_finished, GRPC_ERROR_CREATE( - "Attempt to send initial metadata after stream was closed"), "send_initial_metadata_finished"); + "Attempt to send initial metadata after stream was closed"), + "send_initial_metadata_finished"); } } } @@ -957,7 +964,8 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, if (s->write_closed) { grpc_chttp2_complete_closure_step( exec_ctx, t, s, &s->fetching_send_message_finished, - GRPC_ERROR_CREATE("Attempt to send message after stream was closed"), "fetching_send_message_finished"); + GRPC_ERROR_CREATE("Attempt to send message after stream was closed"), + "fetching_send_message_finished"); } else { GPR_ASSERT(s->fetching_send_message == NULL); uint8_t *frame_hdr = @@ -1015,7 +1023,8 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, grpc_metadata_batch_is_empty(op->send_trailing_metadata) ? GRPC_ERROR_NONE : GRPC_ERROR_CREATE("Attempt to send trailing metadata after " - "stream was closed"), "send_trailing_metadata_finished"); + "stream was closed"), + "send_trailing_metadata_finished"); } else if (s->id != 0) { /* TODO(ctiller): check if there's flow control for any outstanding bytes before going writable */ @@ -1193,16 +1202,19 @@ void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s) { grpc_byte_stream *bs; - if (s->recv_initial_metadata_ready != NULL && s->published_metadata[0]) { + if (s->recv_initial_metadata_ready != NULL && + s->published_metadata[0] != GRPC_METADATA_NOT_PUBLISHED) { if (s->seen_error) { while ((bs = grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames)) != NULL) { + gpr_log(GPR_DEBUG, "discard %p", bs); incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE); } } grpc_chttp2_incoming_metadata_buffer_publish(&s->metadata_buffer[0], s->recv_initial_metadata); - run_closure_and_null(exec_ctx, &s->recv_initial_metadata_ready, GRPC_ERROR_NONE); + null_then_run_closure(exec_ctx, &s->recv_initial_metadata_ready, + GRPC_ERROR_NONE); } } @@ -1214,16 +1226,22 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx, while (s->final_metadata_requested && s->seen_error && (bs = grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames)) != NULL) { + gpr_log(GPR_DEBUG, "discard %p", bs); incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE); } if (s->incoming_frames.head != NULL) { *s->recv_message = grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames); GPR_ASSERT(*s->recv_message != NULL); - run_closure_and_null(exec_ctx, &s->recv_message_ready, GRPC_ERROR_NONE); - } else if (s->published_metadata[1]) { + null_then_run_closure(exec_ctx, &s->recv_message_ready, GRPC_ERROR_NONE); + } else if (s->published_metadata[1] != GRPC_METADATA_NOT_PUBLISHED) { + const char *m = grpc_error_string(s->read_closed_error); + gpr_log(GPR_ERROR, "publish null :: %s", m); + abort(); + grpc_error_free_string(m); + *s->recv_message = NULL; - run_closure_and_null(exec_ctx, &s->recv_message_ready, GRPC_ERROR_NONE); + null_then_run_closure(exec_ctx, &s->recv_message_ready, GRPC_ERROR_NONE); } } } @@ -1238,14 +1256,17 @@ void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_exec_ctx *exec_ctx, if (s->seen_error) { while ((bs = grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames)) != NULL) { + gpr_log(GPR_DEBUG, "discard %p", bs); incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE); } } - if (s->all_incoming_byte_streams_finished && s->recv_trailing_metadata_finished != NULL) { + if (s->all_incoming_byte_streams_finished && + s->recv_trailing_metadata_finished != NULL) { grpc_chttp2_incoming_metadata_buffer_publish(&s->metadata_buffer[1], s->recv_trailing_metadata); grpc_chttp2_complete_closure_step( - exec_ctx, t, s, &s->recv_trailing_metadata_finished, GRPC_ERROR_NONE, "recv_trailing_metadata_finished"); + exec_ctx, t, s, &s->recv_trailing_metadata_finished, GRPC_ERROR_NONE, + "recv_trailing_metadata_finished"); } } } @@ -1262,7 +1283,6 @@ static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, uint32_t id, grpc_error *error) { grpc_chttp2_stream *s = grpc_chttp2_stream_map_delete(&t->stream_map, id); GPR_ASSERT(s); - s->in_stream_map = false; if (t->incoming_stream == s) { t->incoming_stream = NULL; grpc_chttp2_parsing_become_skip_parser(exec_ctx, t); @@ -1359,7 +1379,8 @@ void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, to the upper layers - drop what we've got, and then publish what we want - which is safe because we haven't told anyone about the metadata yet */ - if (!s->published_metadata[1] || s->recv_trailing_metadata_finished != NULL) { + if (s->published_metadata[1] == GRPC_METADATA_NOT_PUBLISHED || + s->recv_trailing_metadata_finished != NULL) { char status_string[GPR_LTOA_MIN_BUFSIZE]; gpr_ltoa(status, status_string); grpc_chttp2_incoming_metadata_buffer_add( @@ -1373,7 +1394,8 @@ void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, GRPC_MDSTR_GRPC_MESSAGE, grpc_mdstr_from_slice(gpr_slice_ref(*slice)))); } - s->published_metadata[1] = true; + gpr_log(GPR_DEBUG, "published_metadata from fake"); + s->published_metadata[1] = GRPC_METADATA_SYNTHESIZED_FROM_FAKE; grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s); } if (slice) { @@ -1413,20 +1435,21 @@ static void fail_pending_writes(grpc_exec_ctx *exec_ctx, grpc_error *error) { error = removal_error(error, s); s->fetching_send_message = NULL; - grpc_chttp2_complete_closure_step(exec_ctx, t, s, - &s->send_initial_metadata_finished, - GRPC_ERROR_REF(error), "send_initial_metadata_finished"); - grpc_chttp2_complete_closure_step(exec_ctx, t, s, - &s->send_trailing_metadata_finished, - GRPC_ERROR_REF(error), "send_trailing_metadata_finished"); - grpc_chttp2_complete_closure_step(exec_ctx, t, s, - &s->fetching_send_message_finished, - GRPC_ERROR_REF(error), "fetching_send_message_finished"); + grpc_chttp2_complete_closure_step( + exec_ctx, t, s, &s->send_initial_metadata_finished, GRPC_ERROR_REF(error), + "send_initial_metadata_finished"); + grpc_chttp2_complete_closure_step( + exec_ctx, t, s, &s->send_trailing_metadata_finished, + GRPC_ERROR_REF(error), "send_trailing_metadata_finished"); + grpc_chttp2_complete_closure_step( + exec_ctx, t, s, &s->fetching_send_message_finished, GRPC_ERROR_REF(error), + "fetching_send_message_finished"); while (s->on_write_finished_cbs) { grpc_chttp2_write_cb *cb = s->on_write_finished_cbs; s->on_write_finished_cbs = cb->next; grpc_chttp2_complete_closure_step(exec_ctx, t, s, &cb->closure, - GRPC_ERROR_REF(error), "on_write_finished_cb"); + GRPC_ERROR_REF(error), + "on_write_finished_cb"); cb->next = t->write_cb_pool; t->write_cb_pool = cb; } @@ -1445,8 +1468,11 @@ void grpc_chttp2_mark_stream_closed(grpc_exec_ctx *exec_ctx, if (close_reads && !s->read_closed) { s->read_closed_error = GRPC_ERROR_REF(error); s->read_closed = true; - s->published_metadata[0] = true; - s->published_metadata[1] = true; + for (int i = 0; i < 2; i++) { + if (s->published_metadata[i] == GRPC_METADATA_NOT_PUBLISHED) { + s->published_metadata[i] = GPRC_METADATA_PUBLISHED_AT_CLOSE; + } + } decrement_active_streams_locked(exec_ctx, t, s); grpc_chttp2_maybe_complete_recv_initial_metadata(exec_ctx, t, s); grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s); diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c index bcb0ab0f99..8668816930 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.c +++ b/src/core/ext/transport/chttp2/transport/frame_data.c @@ -140,23 +140,17 @@ void grpc_chttp2_encode_data(uint32_t id, gpr_slice_buffer *inbuf, stats->data_bytes += write_bytes; } -grpc_error *grpc_chttp2_data_parser_parse(grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport *t, - grpc_chttp2_stream *s, - gpr_slice slice, int is_last) { +static grpc_error *parse_inner(grpc_exec_ctx *exec_ctx, + grpc_chttp2_data_parser *p, + grpc_chttp2_transport *t, grpc_chttp2_stream *s, + gpr_slice slice) { uint8_t *const beg = GPR_SLICE_START_PTR(slice); uint8_t *const end = GPR_SLICE_END_PTR(slice); uint8_t *cur = beg; - grpc_chttp2_data_parser *p = parser; uint32_t message_flags; grpc_chttp2_incoming_byte_stream *incoming_byte_stream; char *msg; - if (is_last && p->is_last_frame) { - grpc_chttp2_mark_stream_closed(exec_ctx, t, s, true, false, - GRPC_ERROR_NONE); - } - if (cur == end) { return GRPC_ERROR_NONE; } @@ -272,3 +266,18 @@ grpc_error *grpc_chttp2_data_parser_parse(grpc_exec_ctx *exec_ctx, void *parser, GPR_UNREACHABLE_CODE(return GRPC_ERROR_CREATE("Should never reach here")); } + +grpc_error *grpc_chttp2_data_parser_parse(grpc_exec_ctx *exec_ctx, void *parser, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s, + gpr_slice slice, int is_last) { + grpc_chttp2_data_parser *p = parser; + grpc_error *error = parse_inner(exec_ctx, p, t, s, slice); + + if (is_last && p->is_last_frame) { + grpc_chttp2_mark_stream_closed(exec_ctx, t, s, true, false, + GRPC_ERROR_NONE); + } + + return error; +} diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.c b/src/core/ext/transport/chttp2/transport/hpack_parser.c index bd26b81622..8180f78fc0 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_parser.c +++ b/src/core/ext/transport/chttp2/transport/hpack_parser.c @@ -1607,7 +1607,8 @@ grpc_error *grpc_chttp2_header_parser_parse(grpc_exec_ctx *exec_ctx, if (s->header_frames_received == GPR_ARRAY_SIZE(s->metadata_buffer)) { return GRPC_ERROR_CREATE("Too many trailer frames"); } - s->published_metadata[s->header_frames_received] = true; + s->published_metadata[s->header_frames_received] = + GRPC_METADATA_PUBLISHED_FROM_WIRE; maybe_complete_funcs[s->header_frames_received](exec_ctx, t, s); s->header_frames_received++; } diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 1ca2f7a70a..27acf6321b 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -317,6 +317,13 @@ struct grpc_chttp2_transport { grpc_chttp2_write_cb *write_cb_pool; }; +typedef enum { + GRPC_METADATA_NOT_PUBLISHED, + GRPC_METADATA_SYNTHESIZED_FROM_FAKE, + GRPC_METADATA_PUBLISHED_FROM_WIRE, + GPRC_METADATA_PUBLISHED_AT_CLOSE +} grpc_published_metadata_method; + struct grpc_chttp2_stream { grpc_chttp2_transport *t; grpc_stream_refcount *refcount; @@ -370,8 +377,6 @@ struct grpc_chttp2_stream { bool read_closed; /** Are all published incoming byte streams closed. */ bool all_incoming_byte_streams_finished; - /** Is this stream in the stream map. */ - bool in_stream_map; /** Has this stream seen an error. If true, then pending incoming frames can be thrown away. */ bool seen_error; @@ -381,7 +386,7 @@ struct grpc_chttp2_stream { /** the error that resulted in this stream being write-closed */ grpc_error *write_closed_error; - bool published_metadata[2]; + grpc_published_metadata_method published_metadata[2]; bool final_metadata_requested; grpc_chttp2_incoming_metadata_buffer metadata_buffer[2]; diff --git a/src/core/ext/transport/chttp2/transport/stream_map.c b/src/core/ext/transport/chttp2/transport/stream_map.c index f70791c422..bd07412274 100644 --- a/src/core/ext/transport/chttp2/transport/stream_map.c +++ b/src/core/ext/transport/chttp2/transport/stream_map.c @@ -77,6 +77,7 @@ void grpc_chttp2_stream_map_add(grpc_chttp2_stream_map *map, uint32_t key, GPR_ASSERT(count == 0 || keys[count - 1] < key); GPR_ASSERT(value); + GPR_ASSERT(grpc_chttp2_stream_map_find(map, key) == NULL); if (count == capacity) { if (map->free > capacity / 4) { @@ -170,6 +171,7 @@ void *grpc_chttp2_stream_map_delete(grpc_chttp2_stream_map *map, uint32_t key) { if (map->free == map->count) { map->free = map->count = 0; } + GPR_ASSERT(grpc_chttp2_stream_map_find(map, key) == NULL); } return out; } diff --git a/test/cpp/end2end/thread_stress_test.cc b/test/cpp/end2end/thread_stress_test.cc index b021b34523..ebede19a7f 100644 --- a/test/cpp/end2end/thread_stress_test.cc +++ b/test/cpp/end2end/thread_stress_test.cc @@ -339,7 +339,10 @@ static void SendRpc(grpc::testing::EchoTestService::Stub* stub, int num_rpcs) { ClientContext context; Status s = stub->Echo(&context, request, &response); EXPECT_EQ(response.message(), request.message()); - EXPECT_TRUE(s.ok()); + if (!s.ok()) { + gpr_log(GPR_ERROR, "RPC error: %d: %s", s.error_code(), s.error_message().c_str()); + } + ASSERT_TRUE(s.ok()); } } diff --git a/test/cpp/qps/client_sync.cc b/test/cpp/qps/client_sync.cc index 8062424a1f..ef54b4b766 100644 --- a/test/cpp/qps/client_sync.cc +++ b/test/cpp/qps/client_sync.cc @@ -130,6 +130,9 @@ class SynchronousUnaryClient GRPC_FINAL : public SynchronousClient { grpc::Status s = stub->UnaryCall(&context, request_, &responses_[thread_idx]); entry->set_value((UsageTimer::Now() - start) * 1e9); + if (!s.ok()) { + gpr_log(GPR_ERROR, "RPC error: %d: %s", s.error_code(), s.error_message().c_str()); + } return s.ok(); } }; -- cgit v1.2.3 From a81dac2888d4cb7b766a976aa5084a4ca797d21e Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 7 Sep 2016 11:30:06 -0700 Subject: Remove bad debug lines --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 5484d9a1ec..7adbd66923 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1235,11 +1235,6 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx, GPR_ASSERT(*s->recv_message != NULL); null_then_run_closure(exec_ctx, &s->recv_message_ready, GRPC_ERROR_NONE); } else if (s->published_metadata[1] != GRPC_METADATA_NOT_PUBLISHED) { - const char *m = grpc_error_string(s->read_closed_error); - gpr_log(GPR_ERROR, "publish null :: %s", m); - abort(); - grpc_error_free_string(m); - *s->recv_message = NULL; null_then_run_closure(exec_ctx, &s->recv_message_ready, GRPC_ERROR_NONE); } -- cgit v1.2.3 From 09b05fd3fd91a473c42b99cc9636c1634eeb327e Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 7 Sep 2016 13:02:05 -0700 Subject: Get write batching working again --- .../transport/chttp2/transport/chttp2_transport.c | 34 +++++++++++++++++----- src/core/ext/transport/chttp2/transport/internal.h | 3 +- src/core/lib/iomgr/combiner.c | 21 +++++++++---- src/core/lib/iomgr/combiner.h | 9 ++---- test/core/iomgr/combiner_test.c | 5 ++-- 5 files changed, 49 insertions(+), 23 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 7adbd66923..986f089397 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -542,8 +542,10 @@ static const char *write_state_name(grpc_chttp2_write_state st) { return "IDLE"; case GRPC_CHTTP2_WRITE_STATE_WRITING: return "WRITING"; - case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_TO_COME: + case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE: return "WRITING+MORE"; + case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_AND_COVERED_BY_POLLER: + return "WRITING+MORE+COVERED"; } GPR_UNREACHABLE_CODE(return "UNKNOWN"); } @@ -568,12 +570,22 @@ void grpc_chttp2_initiate_write(grpc_exec_ctx *exec_ctx, GRPC_CHTTP2_REF_TRANSPORT(t, "writing"); grpc_combiner_execute_finally(exec_ctx, t->combiner, &t->write_action_begin_locked, - GRPC_ERROR_NONE); + GRPC_ERROR_NONE, covered_by_poller); break; case GRPC_CHTTP2_WRITE_STATE_WRITING: - set_write_state(t, GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_TO_COME); + set_write_state( + t, + covered_by_poller + ? GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_AND_COVERED_BY_POLLER + : GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE); break; - case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_TO_COME: + case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE: + if (covered_by_poller) { + set_write_state( + t, GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_AND_COVERED_BY_POLLER); + } + break; + case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_AND_COVERED_BY_POLLER: break; } GPR_TIMER_END("grpc_chttp2_initiate_write", 0); @@ -638,13 +650,21 @@ static void write_action_end_locked(grpc_exec_ctx *exec_ctx, void *tp, GPR_TIMER_MARK("state=writing", 0); set_write_state(t, GRPC_CHTTP2_WRITE_STATE_IDLE); break; - case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_TO_COME: + case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE: + GPR_TIMER_MARK("state=writing_stale_no_poller", 0); + set_write_state(t, GRPC_CHTTP2_WRITE_STATE_WRITING); + GRPC_CHTTP2_REF_TRANSPORT(t, "writing"); + grpc_combiner_execute_finally(exec_ctx, t->combiner, + &t->write_action_begin_locked, + GRPC_ERROR_NONE, false); + break; + case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_AND_COVERED_BY_POLLER: GPR_TIMER_MARK("state=writing_stale_with_poller", 0); set_write_state(t, GRPC_CHTTP2_WRITE_STATE_WRITING); GRPC_CHTTP2_REF_TRANSPORT(t, "writing"); grpc_combiner_execute_finally(exec_ctx, t->combiner, &t->write_action_begin_locked, - GRPC_ERROR_NONE); + GRPC_ERROR_NONE, true); break; } @@ -1861,7 +1881,7 @@ static void incoming_byte_stream_update_flow_control(grpc_exec_ctx *exec_ctx, add_max_recv_bytes); GRPC_CHTTP2_FLOW_CREDIT_STREAM("op", t, s, announce_window, add_max_recv_bytes); - grpc_chttp2_become_writable(exec_ctx, t, s, false, "read_incoming_stream"); + grpc_chttp2_become_writable(exec_ctx, t, s, true, "read_incoming_stream"); } } diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 27acf6321b..6b3e2edd54 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -68,7 +68,8 @@ typedef enum { typedef enum { GRPC_CHTTP2_WRITE_STATE_IDLE, GRPC_CHTTP2_WRITE_STATE_WRITING, - GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_TO_COME, + GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE, + GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_AND_COVERED_BY_POLLER, } grpc_chttp2_write_state; /* deframer state for the overall http2 stream of bytes */ diff --git a/src/core/lib/iomgr/combiner.c b/src/core/lib/iomgr/combiner.c index 721db6337e..b2d6559751 100644 --- a/src/core/lib/iomgr/combiner.c +++ b/src/core/lib/iomgr/combiner.c @@ -62,6 +62,7 @@ struct grpc_combiner { // offload safely gpr_atm covered_by_poller; bool time_to_execute_final_list; + bool final_list_covered_by_poller; grpc_closure_list final_list; grpc_closure offload; }; @@ -81,6 +82,11 @@ static error_data unpack_error_data(uintptr_t p) { return (error_data){(grpc_error *)(p & ~(uintptr_t)1), p & 1}; } +static bool is_covered_by_poller(grpc_combiner *lock) { + return lock->final_list_covered_by_poller || + gpr_atm_acq_load(&lock->covered_by_poller) > 0; +} + grpc_combiner *grpc_combiner_create(grpc_workqueue *optional_workqueue) { grpc_combiner *lock = gpr_malloc(sizeof(*lock)); lock->next_combiner_on_this_exec_ctx = NULL; @@ -183,8 +189,7 @@ bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) { } if (lock->optional_workqueue != NULL && - grpc_exec_ctx_ready_to_finish(exec_ctx) && - gpr_atm_acq_load(&lock->covered_by_poller) > 0) { + grpc_exec_ctx_ready_to_finish(exec_ctx) && is_covered_by_poller(lock)) { GPR_TIMER_MARK("offload_from_finished_exec_ctx", 0); // this execution context wants to move on, and we have a workqueue (and // so can help the execution context out): schedule remaining work to be @@ -205,8 +210,7 @@ bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) { // queue is in an inconsistant state: use this as a cue that we should // go off and do something else for a while (and come back later) GPR_TIMER_MARK("delay_busy", 0); - if (lock->optional_workqueue != NULL && - gpr_atm_acq_load(&lock->covered_by_poller) > 0) { + if (lock->optional_workqueue != NULL && is_covered_by_poller(lock)) { queue_offload(exec_ctx, lock); } GPR_TIMER_END("combiner.continue_exec_ctx", 0); @@ -225,6 +229,7 @@ bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) { grpc_closure *c = lock->final_list.head; GPR_ASSERT(c != NULL); grpc_closure_list_init(&lock->final_list); + lock->final_list_covered_by_poller = false; int loops = 0; while (c != NULL) { GPR_TIMER_BEGIN("combiner.exec_1final", 0); @@ -277,11 +282,12 @@ bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) { static void enqueue_finally(grpc_exec_ctx *exec_ctx, void *closure, grpc_error *error) { grpc_combiner_execute_finally(exec_ctx, exec_ctx->active_combiner, closure, - GRPC_ERROR_REF(error)); + GRPC_ERROR_REF(error), false); } void grpc_combiner_execute_finally(grpc_exec_ctx *exec_ctx, grpc_combiner *lock, - grpc_closure *closure, grpc_error *error) { + grpc_closure *closure, grpc_error *error, + bool covered_by_poller) { GRPC_COMBINER_TRACE(gpr_log(GPR_DEBUG, "C:%p grpc_combiner_execute_finally c=%p; ac=%p", lock, closure, exec_ctx->active_combiner)); @@ -298,6 +304,9 @@ void grpc_combiner_execute_finally(grpc_exec_ctx *exec_ctx, grpc_combiner *lock, if (grpc_closure_list_empty(lock->final_list)) { gpr_atm_full_fetch_add(&lock->state, 2); } + if (covered_by_poller) { + lock->final_list_covered_by_poller = true; + } grpc_closure_list_append(&lock->final_list, closure, error); GPR_TIMER_END("combiner.execute_finally", 0); } diff --git a/src/core/lib/iomgr/combiner.h b/src/core/lib/iomgr/combiner.h index fa9c143d3c..d04eeed83a 100644 --- a/src/core/lib/iomgr/combiner.h +++ b/src/core/lib/iomgr/combiner.h @@ -55,14 +55,9 @@ void grpc_combiner_execute(grpc_exec_ctx *exec_ctx, grpc_combiner *lock, grpc_closure *closure, grpc_error *error, bool covered_by_poller); // Execute \a action within the lock just prior to unlocking. -// if \a hint_async_break is true, the combiner tries to hand execution to -// another thread before finishing the primary queue of combined closures and -// executing the finally list. -// Deprecation warning: \a hint_async_break will be removed in a future version -// Takes a very slow and round-about path if not called from a -// grpc_combiner_execute closure. void grpc_combiner_execute_finally(grpc_exec_ctx *exec_ctx, grpc_combiner *lock, - grpc_closure *closure, grpc_error *error); + grpc_closure *closure, grpc_error *error, + bool covered_by_poller); bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx); diff --git a/test/core/iomgr/combiner_test.c b/test/core/iomgr/combiner_test.c index 2ea4e5dd14..f7d5809be7 100644 --- a/test/core/iomgr/combiner_test.c +++ b/test/core/iomgr/combiner_test.c @@ -134,8 +134,9 @@ static void in_finally(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { } static void add_finally(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { - grpc_combiner_execute_finally( - exec_ctx, arg, grpc_closure_create(in_finally, NULL), GRPC_ERROR_NONE); + grpc_combiner_execute_finally(exec_ctx, arg, + grpc_closure_create(in_finally, NULL), + GRPC_ERROR_NONE, false); } static void test_execute_finally(void) { -- cgit v1.2.3 From 0b834b3bd557ffac6991d3c283354f73d780c452 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 7 Sep 2016 14:03:29 -0700 Subject: Fix compiler warning --- src/core/lib/iomgr/workqueue.h | 10 +++++----- src/core/lib/iomgr/workqueue_posix.c | 15 +++++++++------ src/core/lib/iomgr/workqueue_windows.c | 10 +++++++--- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/core/lib/iomgr/workqueue.h b/src/core/lib/iomgr/workqueue.h index b2805dc66c..9f95562fab 100644 --- a/src/core/lib/iomgr/workqueue.h +++ b/src/core/lib/iomgr/workqueue.h @@ -61,17 +61,17 @@ //#define GRPC_WORKQUEUE_REFCOUNT_DEBUG #ifdef GRPC_WORKQUEUE_REFCOUNT_DEBUG #define GRPC_WORKQUEUE_REF(p, r) \ - (grpc_workqueue_ref((p), __FILE__, __LINE__, (r)), (p)) + grpc_workqueue_ref((p), __FILE__, __LINE__, (r)) #define GRPC_WORKQUEUE_UNREF(exec_ctx, p, r) \ grpc_workqueue_unref((exec_ctx), (p), __FILE__, __LINE__, (r)) -void grpc_workqueue_ref(grpc_workqueue *workqueue, const char *file, int line, - const char *reason); +grpc_workqueue *grpc_workqueue_ref(grpc_workqueue *workqueue, const char *file, + int line, const char *reason); void grpc_workqueue_unref(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue, const char *file, int line, const char *reason); #else -#define GRPC_WORKQUEUE_REF(p, r) (grpc_workqueue_ref((p)), (p)) +#define GRPC_WORKQUEUE_REF(p, r) grpc_workqueue_ref((p)) #define GRPC_WORKQUEUE_UNREF(cl, p, r) grpc_workqueue_unref((cl), (p)) -void grpc_workqueue_ref(grpc_workqueue *workqueue); +grpc_workqueue *grpc_workqueue_ref(grpc_workqueue *workqueue); void grpc_workqueue_unref(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue); #endif diff --git a/src/core/lib/iomgr/workqueue_posix.c b/src/core/lib/iomgr/workqueue_posix.c index c7d4fc6423..836bb8b6e0 100644 --- a/src/core/lib/iomgr/workqueue_posix.c +++ b/src/core/lib/iomgr/workqueue_posix.c @@ -83,18 +83,21 @@ static void workqueue_orphan(grpc_exec_ctx *exec_ctx, } #ifdef GRPC_WORKQUEUE_REFCOUNT_DEBUG -void grpc_workqueue_ref(grpc_workqueue *workqueue, const char *file, int line, - const char *reason) { - if (workqueue == NULL) return; +grpc_workqueue *grpc_workqueue_ref(grpc_workqueue *workqueue, const char *file, + int line, const char *reason) { + if (workqueue == NULL) return NULL; gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "WORKQUEUE:%p ref %d -> %d %s", workqueue, (int)workqueue->refs.count, (int)workqueue->refs.count + 1, reason); gpr_ref(&workqueue->refs); + return workqueue; } #else -void grpc_workqueue_ref(grpc_workqueue *workqueue) { - if (workqueue == NULL) return; - gpr_ref(&workqueue->refs); +grpc_workqueue *grpc_workqueue_ref(grpc_workqueue *workqueue) { + if (workqueue != NULL) { + gpr_ref(&workqueue->refs); + } + return workqueue; } #endif diff --git a/src/core/lib/iomgr/workqueue_windows.c b/src/core/lib/iomgr/workqueue_windows.c index ee81dc248e..5c93d3c59e 100644 --- a/src/core/lib/iomgr/workqueue_windows.c +++ b/src/core/lib/iomgr/workqueue_windows.c @@ -43,12 +43,16 @@ // workqueues. #ifdef GRPC_WORKQUEUE_REFCOUNT_DEBUG -void grpc_workqueue_ref(grpc_workqueue *workqueue, const char *file, int line, - const char *reason) {} +grpc_workqueue *grpc_workqueue_ref(grpc_workqueue *workqueue, const char *file, + int line, const char *reason) { + return workqueue; +} void grpc_workqueue_unref(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue, const char *file, int line, const char *reason) {} #else -void grpc_workqueue_ref(grpc_workqueue *workqueue) {} +grpc_workqueue *grpc_workqueue_ref(grpc_workqueue *workqueue) { + return workqueue; +} void grpc_workqueue_unref(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue) {} #endif -- cgit v1.2.3 From 44b12f9e23cbdb5f5f1be0681b81aeded481debf Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 8 Sep 2016 10:06:14 -0700 Subject: clang-format --- src/core/ext/transport/chttp2/transport/writing.c | 41 +++++++++++++---------- src/core/lib/iomgr/closure.c | 4 +-- src/core/lib/iomgr/closure.h | 3 +- src/core/lib/surface/server.c | 3 +- test/cpp/end2end/thread_stress_test.cc | 3 +- test/cpp/qps/client_sync.cc | 3 +- 6 files changed, 33 insertions(+), 24 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/writing.c b/src/core/ext/transport/chttp2/transport/writing.c index 87f4e1e836..bc490569b7 100644 --- a/src/core/ext/transport/chttp2/transport/writing.c +++ b/src/core/ext/transport/chttp2/transport/writing.c @@ -49,7 +49,8 @@ static void add_to_write_list(grpc_chttp2_write_cb **list, static void finish_write_cb(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s, grpc_chttp2_write_cb *cb, grpc_error *error) { - grpc_chttp2_complete_closure_step(exec_ctx, t, s, &cb->closure, error, "finish_write_cb"); + grpc_chttp2_complete_closure_step(exec_ctx, t, s, &cb->closure, error, + "finish_write_cb"); cb->next = t->write_cb_pool; t->write_cb_pool = cb; } @@ -109,15 +110,17 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, bool sent_initial_metadata = s->sent_initial_metadata; bool now_writing = false; - GRPC_CHTTP2_IF_TRACING(gpr_log(GPR_DEBUG, "W:%p %s[%d] im-(sent,send)=(%d,%d) announce=%d", t, t->is_client?"CLIENT":"SERVER", s->id, sent_initial_metadata, s->send_initial_metadata!=NULL, s->announce_window)); + GRPC_CHTTP2_IF_TRACING(gpr_log( + GPR_DEBUG, "W:%p %s[%d] im-(sent,send)=(%d,%d) announce=%d", t, + t->is_client ? "CLIENT" : "SERVER", s->id, sent_initial_metadata, + s->send_initial_metadata != NULL, s->announce_window)); /* send initial metadata if it's available */ if (!sent_initial_metadata && s->send_initial_metadata) { - grpc_chttp2_encode_header(&t->hpack_compressor, s->id, - s->send_initial_metadata, 0, -t->settings[GRPC_ACKED_SETTINGS][GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE], - &s->stats.outgoing, - &t->outbuf); + grpc_chttp2_encode_header( + &t->hpack_compressor, s->id, s->send_initial_metadata, 0, + t->settings[GRPC_ACKED_SETTINGS][GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE], + &s->stats.outgoing, &t->outbuf); s->send_initial_metadata = NULL; s->sent_initial_metadata = true; sent_initial_metadata = true; @@ -135,7 +138,8 @@ t->settings[GRPC_ACKED_SETTINGS][GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE], /* send any body bytes, if allowed by flow control */ if (s->flow_controlled_buffer.length > 0) { uint32_t max_outgoing = - (uint32_t)GPR_MIN(t->settings[GRPC_ACKED_SETTINGS][GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE], + (uint32_t)GPR_MIN(t->settings[GRPC_ACKED_SETTINGS] + [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE], GPR_MIN(s->outgoing_window, t->outgoing_window)); if (max_outgoing > 0) { uint32_t send_bytes = @@ -176,10 +180,11 @@ t->settings[GRPC_ACKED_SETTINGS][GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE], if (s->send_trailing_metadata != NULL && s->fetching_send_message == NULL && s->flow_controlled_buffer.length == 0) { - grpc_chttp2_encode_header(&t->hpack_compressor, s->id, - s->send_trailing_metadata, true, -t->settings[GRPC_ACKED_SETTINGS][GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE], - &s->stats.outgoing, &t->outbuf); + grpc_chttp2_encode_header( + &t->hpack_compressor, s->id, s->send_trailing_metadata, true, + t->settings[GRPC_ACKED_SETTINGS] + [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE], + &s->stats.outgoing, &t->outbuf); s->send_trailing_metadata = NULL; s->sent_trailing_metadata = true; if (!t->is_client && !s->read_closed) { @@ -225,9 +230,9 @@ void grpc_chttp2_end_write(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, while (grpc_chttp2_list_pop_writing_stream(t, &s)) { if (s->sent_initial_metadata) { - grpc_chttp2_complete_closure_step(exec_ctx, t, s, - &s->send_initial_metadata_finished, - GRPC_ERROR_REF(error), "send_initial_metadata_finished"); + grpc_chttp2_complete_closure_step( + exec_ctx, t, s, &s->send_initial_metadata_finished, + GRPC_ERROR_REF(error), "send_initial_metadata_finished"); } if (s->sending_bytes != 0) { update_list(exec_ctx, t, s, s->sending_bytes, &s->on_write_finished_cbs, @@ -235,9 +240,9 @@ void grpc_chttp2_end_write(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, s->sending_bytes = 0; } if (s->sent_trailing_metadata) { - grpc_chttp2_complete_closure_step(exec_ctx, t, s, - &s->send_trailing_metadata_finished, - GRPC_ERROR_REF(error), "send_trailing_metadata_finished"); + grpc_chttp2_complete_closure_step( + exec_ctx, t, s, &s->send_trailing_metadata_finished, + GRPC_ERROR_REF(error), "send_trailing_metadata_finished"); grpc_chttp2_mark_stream_closed(exec_ctx, t, s, !t->is_client, 1, GRPC_ERROR_REF(error)); } diff --git a/src/core/lib/iomgr/closure.c b/src/core/lib/iomgr/closure.c index 5cbd6bd7a5..2c84e82aca 100644 --- a/src/core/lib/iomgr/closure.c +++ b/src/core/lib/iomgr/closure.c @@ -113,10 +113,10 @@ grpc_closure *grpc_closure_create(grpc_iomgr_cb_func cb, void *cb_arg) { return &wc->wrapper; } -void grpc_closure_run(grpc_exec_ctx *exec_ctx, grpc_closure *c, grpc_error *error) { +void grpc_closure_run(grpc_exec_ctx *exec_ctx, grpc_closure *c, + grpc_error *error) { GPR_TIMER_BEGIN("grpc_closure_run", 0); c->cb(exec_ctx, c->cb_arg, error); GRPC_ERROR_UNREF(error); GPR_TIMER_END("grpc_closure_run", 0); } - diff --git a/src/core/lib/iomgr/closure.h b/src/core/lib/iomgr/closure.h index 29ed19cb4f..2b4b271eaa 100644 --- a/src/core/lib/iomgr/closure.h +++ b/src/core/lib/iomgr/closure.h @@ -112,6 +112,7 @@ bool grpc_closure_list_empty(grpc_closure_list list); /** Run a closure directly. Caller ensures that no locks are being held above. * Note that calling this at the end of a closure callback function itself is * by definition safe. */ -void grpc_closure_run(grpc_exec_ctx *exec_ctx, grpc_closure *closure, grpc_error *error); +void grpc_closure_run(grpc_exec_ctx *exec_ctx, grpc_closure *closure, + grpc_error *error); #endif /* GRPC_CORE_LIB_IOMGR_CLOSURE_H */ diff --git a/src/core/lib/surface/server.c b/src/core/lib/surface/server.c index 8f9b995265..9a9fcddb6e 100644 --- a/src/core/lib/surface/server.c +++ b/src/core/lib/surface/server.c @@ -447,7 +447,8 @@ static void destroy_channel(grpc_exec_ctx *exec_ctx, channel_data *chand, } GRPC_ERROR_UNREF(error); - grpc_transport_op *op = grpc_make_transport_op(&chand->finish_destroy_channel_closure); + grpc_transport_op *op = + grpc_make_transport_op(&chand->finish_destroy_channel_closure); op->set_accept_stream = true; grpc_channel_next_op(exec_ctx, grpc_channel_stack_element( diff --git a/test/cpp/end2end/thread_stress_test.cc b/test/cpp/end2end/thread_stress_test.cc index ebede19a7f..0b9d4cda9f 100644 --- a/test/cpp/end2end/thread_stress_test.cc +++ b/test/cpp/end2end/thread_stress_test.cc @@ -340,7 +340,8 @@ static void SendRpc(grpc::testing::EchoTestService::Stub* stub, int num_rpcs) { Status s = stub->Echo(&context, request, &response); EXPECT_EQ(response.message(), request.message()); if (!s.ok()) { - gpr_log(GPR_ERROR, "RPC error: %d: %s", s.error_code(), s.error_message().c_str()); + gpr_log(GPR_ERROR, "RPC error: %d: %s", s.error_code(), + s.error_message().c_str()); } ASSERT_TRUE(s.ok()); } diff --git a/test/cpp/qps/client_sync.cc b/test/cpp/qps/client_sync.cc index ef54b4b766..0ccf4e270b 100644 --- a/test/cpp/qps/client_sync.cc +++ b/test/cpp/qps/client_sync.cc @@ -131,7 +131,8 @@ class SynchronousUnaryClient GRPC_FINAL : public SynchronousClient { stub->UnaryCall(&context, request_, &responses_[thread_idx]); entry->set_value((UsageTimer::Now() - start) * 1e9); if (!s.ok()) { - gpr_log(GPR_ERROR, "RPC error: %d: %s", s.error_code(), s.error_message().c_str()); + gpr_log(GPR_ERROR, "RPC error: %d: %s", s.error_code(), + s.error_message().c_str()); } return s.ok(); } -- cgit v1.2.3 From 84ea341aa3c1435182d8f2e0a687fa45bd4a8d1c Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 8 Sep 2016 14:57:56 -0700 Subject: Minor perf improvements --- src/core/lib/iomgr/combiner.c | 2 +- src/core/lib/iomgr/ev_epoll_linux.c | 2 +- src/core/lib/iomgr/workqueue_posix.c | 71 ++++++++++++++++++++++++------------ 3 files changed, 50 insertions(+), 25 deletions(-) diff --git a/src/core/lib/iomgr/combiner.c b/src/core/lib/iomgr/combiner.c index b2d6559751..273505f8b8 100644 --- a/src/core/lib/iomgr/combiner.c +++ b/src/core/lib/iomgr/combiner.c @@ -189,7 +189,7 @@ bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) { } if (lock->optional_workqueue != NULL && - grpc_exec_ctx_ready_to_finish(exec_ctx) && is_covered_by_poller(lock)) { + is_covered_by_poller(lock) && grpc_exec_ctx_ready_to_finish(exec_ctx)) { GPR_TIMER_MARK("offload_from_finished_exec_ctx", 0); // this execution context wants to move on, and we have a workqueue (and // so can help the execution context out): schedule remaining work to be diff --git a/src/core/lib/iomgr/ev_epoll_linux.c b/src/core/lib/iomgr/ev_epoll_linux.c index 740920d760..f473e4765c 100644 --- a/src/core/lib/iomgr/ev_epoll_linux.c +++ b/src/core/lib/iomgr/ev_epoll_linux.c @@ -1299,7 +1299,7 @@ static void pollset_reset(grpc_pollset *pollset) { GPR_ASSERT(pollset->polling_island == NULL); } -#define GRPC_EPOLL_MAX_EVENTS 1000 +#define GRPC_EPOLL_MAX_EVENTS 100 /* Note: sig_mask contains the signal mask to use *during* epoll_wait() */ static void pollset_work_and_unlock(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, diff --git a/src/core/lib/iomgr/workqueue_posix.c b/src/core/lib/iomgr/workqueue_posix.c index 836bb8b6e0..6f8a26684a 100644 --- a/src/core/lib/iomgr/workqueue_posix.c +++ b/src/core/lib/iomgr/workqueue_posix.c @@ -146,42 +146,67 @@ static void on_readable(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { GPR_ASSERT(gpr_atm_no_barrier_load(&workqueue->state) == 0); gpr_free(workqueue); } else { - error = grpc_wakeup_fd_consume_wakeup(&workqueue->wakeup_fd); - if (error != GRPC_ERROR_NONE) { - /* recurse to get error handling */ - on_readable(exec_ctx, arg, error); - } else { - gpr_mpscq_node *n = gpr_mpscq_pop(&workqueue->queue); - if (n == NULL) { - /* try again - queue in an ephemerally inconsistent state */ - wakeup(exec_ctx, workqueue); - grpc_fd_notify_on_read(exec_ctx, workqueue->wakeup_read_fd, - &workqueue->read_closure); - } else { + gpr_mpscq_node *n = NULL; + for (int i = 0; i < 100; i++) { + n = gpr_mpscq_pop(&workqueue->queue); + if (n != NULL) { + grpc_closure *c = (grpc_closure *)n; + grpc_closure_run(exec_ctx, c, c->error_data.error); + grpc_exec_ctx_flush(exec_ctx); gpr_atm last = gpr_atm_full_fetch_add(&workqueue->state, -2); switch (last) { default: - // schedule a wakeup since there's more to do - wakeup(exec_ctx, workqueue); - break; + // there's more to do, keep going + goto keep_going; case 3: // had one count, one unorphaned --> done, unorphaned - break; + goto switch_to_idle; case 2: // had one count, one orphaned --> done, orphaned - workqueue_destroy(exec_ctx, workqueue); - break; + goto destroy; case 1: case 0: // these values are illegal - representing an already done or // deleted workqueue GPR_UNREACHABLE_CODE(break); } - grpc_fd_notify_on_read(exec_ctx, workqueue->wakeup_read_fd, - &workqueue->read_closure); - grpc_closure *cl = (grpc_closure *)n; - grpc_error *clerr = cl->error_data.error; - grpc_closure_run(exec_ctx, cl, clerr); } } + /* fall through to wakeup_next -- we tried a bunch of times to pull a node + * but failed */ +wakeup_next: + error = grpc_wakeup_fd_consume_wakeup(&workqueue->wakeup_fd); + if (error != GRPC_ERROR_NONE) { + /* recurse to get error handling */ + on_readable(exec_ctx, arg, error); + } else { + grpc_fd_notify_on_read(exec_ctx, workqueue->wakeup_read_fd, + &workqueue->read_closure); + wakeup(exec_ctx, workqueue); + } + return; + +keep_going: + if (grpc_exec_ctx_ready_to_finish(exec_ctx)) { + goto wakeup_next; + } else { + /* recurse to continue */ + on_readable(exec_ctx, arg, GRPC_ERROR_NONE); + } + return; + +switch_to_idle: + error = grpc_wakeup_fd_consume_wakeup(&workqueue->wakeup_fd); + if (error != GRPC_ERROR_NONE) { + /* recurse to get error handling */ + on_readable(exec_ctx, arg, error); + } else { + grpc_fd_notify_on_read(exec_ctx, workqueue->wakeup_read_fd, + &workqueue->read_closure); + } + return; + +destroy: + workqueue_destroy(exec_ctx, workqueue); + return; } GPR_TIMER_END("workqueue.on_readable", 0); -- cgit v1.2.3 From d8a3c048e25f141a19a60e7f2439d699a21cdcc7 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 9 Sep 2016 12:42:37 -0700 Subject: Tie workqueue implementation to event engine --- BUILD | 12 -- CMakeLists.txt | 5 - Makefile | 6 - binding.gyp | 1 - build.yaml | 2 - config.m4 | 1 - gRPC-Core.podspec | 3 - grpc.gemspec | 2 - package.xml | 2 - src/core/lib/iomgr/combiner.c | 5 +- src/core/lib/iomgr/ev_epoll_linux.c | 194 +++++++++++++---- src/core/lib/iomgr/ev_poll_and_epoll_posix.c | 30 +++ src/core/lib/iomgr/ev_poll_posix.c | 30 +++ src/core/lib/iomgr/ev_posix.c | 23 +++ src/core/lib/iomgr/ev_posix.h | 12 ++ src/core/lib/iomgr/workqueue.h | 4 - src/core/lib/iomgr/workqueue_posix.c | 230 --------------------- src/core/lib/iomgr/workqueue_posix.h | 61 ------ src/python/grpcio/grpc_core_dependencies.py | 1 - tools/doxygen/Doxyfile.c++.internal | 2 - tools/doxygen/Doxyfile.core.internal | 2 - tools/profiling/perf/run_perf_unconstrained.sh | 97 +++++++++ tools/run_tests/sources_and_headers.json | 3 - vsprojects/vcxproj/grpc++/grpc++.vcxproj | 3 - vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters | 6 - .../grpc++_unsecure/grpc++_unsecure.vcxproj | 3 - .../grpc++_unsecure.vcxproj.filters | 6 - vsprojects/vcxproj/grpc/grpc.vcxproj | 3 - vsprojects/vcxproj/grpc/grpc.vcxproj.filters | 6 - .../vcxproj/grpc_test_util/grpc_test_util.vcxproj | 3 - .../grpc_test_util/grpc_test_util.vcxproj.filters | 6 - .../vcxproj/grpc_unsecure/grpc_unsecure.vcxproj | 3 - .../grpc_unsecure/grpc_unsecure.vcxproj.filters | 6 - 33 files changed, 345 insertions(+), 428 deletions(-) delete mode 100644 src/core/lib/iomgr/workqueue_posix.c delete mode 100644 src/core/lib/iomgr/workqueue_posix.h create mode 100755 tools/profiling/perf/run_perf_unconstrained.sh diff --git a/BUILD b/BUILD index 7db1c1d2f6..e03bce72c6 100644 --- a/BUILD +++ b/BUILD @@ -221,7 +221,6 @@ cc_library( "src/core/lib/iomgr/wakeup_fd_pipe.h", "src/core/lib/iomgr/wakeup_fd_posix.h", "src/core/lib/iomgr/workqueue.h", - "src/core/lib/iomgr/workqueue_posix.h", "src/core/lib/iomgr/workqueue_windows.h", "src/core/lib/json/json.h", "src/core/lib/json/json_common.h", @@ -380,7 +379,6 @@ cc_library( "src/core/lib/iomgr/wakeup_fd_nospecial.c", "src/core/lib/iomgr/wakeup_fd_pipe.c", "src/core/lib/iomgr/wakeup_fd_posix.c", - "src/core/lib/iomgr/workqueue_posix.c", "src/core/lib/iomgr/workqueue_windows.c", "src/core/lib/json/json.c", "src/core/lib/json/json_reader.c", @@ -618,7 +616,6 @@ cc_library( "src/core/lib/iomgr/wakeup_fd_pipe.h", "src/core/lib/iomgr/wakeup_fd_posix.h", "src/core/lib/iomgr/workqueue.h", - "src/core/lib/iomgr/workqueue_posix.h", "src/core/lib/iomgr/workqueue_windows.h", "src/core/lib/json/json.h", "src/core/lib/json/json_common.h", @@ -763,7 +760,6 @@ cc_library( "src/core/lib/iomgr/wakeup_fd_nospecial.c", "src/core/lib/iomgr/wakeup_fd_pipe.c", "src/core/lib/iomgr/wakeup_fd_posix.c", - "src/core/lib/iomgr/workqueue_posix.c", "src/core/lib/iomgr/workqueue_windows.c", "src/core/lib/json/json.c", "src/core/lib/json/json_reader.c", @@ -972,7 +968,6 @@ cc_library( "src/core/lib/iomgr/wakeup_fd_pipe.h", "src/core/lib/iomgr/wakeup_fd_posix.h", "src/core/lib/iomgr/workqueue.h", - "src/core/lib/iomgr/workqueue_posix.h", "src/core/lib/iomgr/workqueue_windows.h", "src/core/lib/json/json.h", "src/core/lib/json/json_common.h", @@ -1108,7 +1103,6 @@ cc_library( "src/core/lib/iomgr/wakeup_fd_nospecial.c", "src/core/lib/iomgr/wakeup_fd_pipe.c", "src/core/lib/iomgr/wakeup_fd_posix.c", - "src/core/lib/iomgr/workqueue_posix.c", "src/core/lib/iomgr/workqueue_windows.c", "src/core/lib/json/json.c", "src/core/lib/json/json_reader.c", @@ -1321,7 +1315,6 @@ cc_library( "src/core/lib/iomgr/wakeup_fd_pipe.h", "src/core/lib/iomgr/wakeup_fd_posix.h", "src/core/lib/iomgr/workqueue.h", - "src/core/lib/iomgr/workqueue_posix.h", "src/core/lib/iomgr/workqueue_windows.h", "src/core/lib/json/json.h", "src/core/lib/json/json_common.h", @@ -1437,7 +1430,6 @@ cc_library( "src/core/lib/iomgr/wakeup_fd_nospecial.c", "src/core/lib/iomgr/wakeup_fd_pipe.c", "src/core/lib/iomgr/wakeup_fd_posix.c", - "src/core/lib/iomgr/workqueue_posix.c", "src/core/lib/iomgr/workqueue_windows.c", "src/core/lib/json/json.c", "src/core/lib/json/json_reader.c", @@ -1733,7 +1725,6 @@ cc_library( "src/core/lib/iomgr/wakeup_fd_pipe.h", "src/core/lib/iomgr/wakeup_fd_posix.h", "src/core/lib/iomgr/workqueue.h", - "src/core/lib/iomgr/workqueue_posix.h", "src/core/lib/iomgr/workqueue_windows.h", "src/core/lib/json/json.h", "src/core/lib/json/json_common.h", @@ -1844,7 +1835,6 @@ cc_library( "src/core/lib/iomgr/wakeup_fd_nospecial.c", "src/core/lib/iomgr/wakeup_fd_pipe.c", "src/core/lib/iomgr/wakeup_fd_posix.c", - "src/core/lib/iomgr/workqueue_posix.c", "src/core/lib/iomgr/workqueue_windows.c", "src/core/lib/json/json.c", "src/core/lib/json/json_reader.c", @@ -2237,7 +2227,6 @@ objc_library( "src/core/lib/iomgr/wakeup_fd_nospecial.c", "src/core/lib/iomgr/wakeup_fd_pipe.c", "src/core/lib/iomgr/wakeup_fd_posix.c", - "src/core/lib/iomgr/workqueue_posix.c", "src/core/lib/iomgr/workqueue_windows.c", "src/core/lib/json/json.c", "src/core/lib/json/json_reader.c", @@ -2454,7 +2443,6 @@ objc_library( "src/core/lib/iomgr/wakeup_fd_pipe.h", "src/core/lib/iomgr/wakeup_fd_posix.h", "src/core/lib/iomgr/workqueue.h", - "src/core/lib/iomgr/workqueue_posix.h", "src/core/lib/iomgr/workqueue_windows.h", "src/core/lib/json/json.h", "src/core/lib/json/json_common.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 915c406c9a..0495cafe54 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -351,7 +351,6 @@ add_library(grpc src/core/lib/iomgr/wakeup_fd_nospecial.c src/core/lib/iomgr/wakeup_fd_pipe.c src/core/lib/iomgr/wakeup_fd_posix.c - src/core/lib/iomgr/workqueue_posix.c src/core/lib/iomgr/workqueue_windows.c src/core/lib/json/json.c src/core/lib/json/json_reader.c @@ -610,7 +609,6 @@ add_library(grpc_cronet src/core/lib/iomgr/wakeup_fd_nospecial.c src/core/lib/iomgr/wakeup_fd_pipe.c src/core/lib/iomgr/wakeup_fd_posix.c - src/core/lib/iomgr/workqueue_posix.c src/core/lib/iomgr/workqueue_windows.c src/core/lib/json/json.c src/core/lib/json/json_reader.c @@ -842,7 +840,6 @@ add_library(grpc_unsecure src/core/lib/iomgr/wakeup_fd_nospecial.c src/core/lib/iomgr/wakeup_fd_pipe.c src/core/lib/iomgr/wakeup_fd_posix.c - src/core/lib/iomgr/workqueue_posix.c src/core/lib/iomgr/workqueue_windows.c src/core/lib/json/json.c src/core/lib/json/json_reader.c @@ -1100,7 +1097,6 @@ add_library(grpc++ src/core/lib/iomgr/wakeup_fd_nospecial.c src/core/lib/iomgr/wakeup_fd_pipe.c src/core/lib/iomgr/wakeup_fd_posix.c - src/core/lib/iomgr/workqueue_posix.c src/core/lib/iomgr/workqueue_windows.c src/core/lib/json/json.c src/core/lib/json/json_reader.c @@ -1458,7 +1454,6 @@ add_library(grpc++_unsecure src/core/lib/iomgr/wakeup_fd_nospecial.c src/core/lib/iomgr/wakeup_fd_pipe.c src/core/lib/iomgr/wakeup_fd_posix.c - src/core/lib/iomgr/workqueue_posix.c src/core/lib/iomgr/workqueue_windows.c src/core/lib/json/json.c src/core/lib/json/json_reader.c diff --git a/Makefile b/Makefile index 219c0e4a43..e2338e9b40 100644 --- a/Makefile +++ b/Makefile @@ -2580,7 +2580,6 @@ LIBGRPC_SRC = \ src/core/lib/iomgr/wakeup_fd_nospecial.c \ src/core/lib/iomgr/wakeup_fd_pipe.c \ src/core/lib/iomgr/wakeup_fd_posix.c \ - src/core/lib/iomgr/workqueue_posix.c \ src/core/lib/iomgr/workqueue_windows.c \ src/core/lib/json/json.c \ src/core/lib/json/json_reader.c \ @@ -2857,7 +2856,6 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/iomgr/wakeup_fd_nospecial.c \ src/core/lib/iomgr/wakeup_fd_pipe.c \ src/core/lib/iomgr/wakeup_fd_posix.c \ - src/core/lib/iomgr/workqueue_posix.c \ src/core/lib/iomgr/workqueue_windows.c \ src/core/lib/json/json.c \ src/core/lib/json/json_reader.c \ @@ -3123,7 +3121,6 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/lib/iomgr/wakeup_fd_nospecial.c \ src/core/lib/iomgr/wakeup_fd_pipe.c \ src/core/lib/iomgr/wakeup_fd_posix.c \ - src/core/lib/iomgr/workqueue_posix.c \ src/core/lib/iomgr/workqueue_windows.c \ src/core/lib/json/json.c \ src/core/lib/json/json_reader.c \ @@ -3317,7 +3314,6 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/iomgr/wakeup_fd_nospecial.c \ src/core/lib/iomgr/wakeup_fd_pipe.c \ src/core/lib/iomgr/wakeup_fd_posix.c \ - src/core/lib/iomgr/workqueue_posix.c \ src/core/lib/iomgr/workqueue_windows.c \ src/core/lib/json/json.c \ src/core/lib/json/json_reader.c \ @@ -3658,7 +3654,6 @@ LIBGRPC++_SRC = \ src/core/lib/iomgr/wakeup_fd_nospecial.c \ src/core/lib/iomgr/wakeup_fd_pipe.c \ src/core/lib/iomgr/wakeup_fd_posix.c \ - src/core/lib/iomgr/workqueue_posix.c \ src/core/lib/iomgr/workqueue_windows.c \ src/core/lib/json/json.c \ src/core/lib/json/json_reader.c \ @@ -4294,7 +4289,6 @@ LIBGRPC++_UNSECURE_SRC = \ src/core/lib/iomgr/wakeup_fd_nospecial.c \ src/core/lib/iomgr/wakeup_fd_pipe.c \ src/core/lib/iomgr/wakeup_fd_posix.c \ - src/core/lib/iomgr/workqueue_posix.c \ src/core/lib/iomgr/workqueue_windows.c \ src/core/lib/json/json.c \ src/core/lib/json/json_reader.c \ diff --git a/binding.gyp b/binding.gyp index b4f182c4b7..15ee99ae1c 100644 --- a/binding.gyp +++ b/binding.gyp @@ -623,7 +623,6 @@ 'src/core/lib/iomgr/wakeup_fd_nospecial.c', 'src/core/lib/iomgr/wakeup_fd_pipe.c', 'src/core/lib/iomgr/wakeup_fd_posix.c', - 'src/core/lib/iomgr/workqueue_posix.c', 'src/core/lib/iomgr/workqueue_windows.c', 'src/core/lib/json/json.c', 'src/core/lib/json/json_reader.c', diff --git a/build.yaml b/build.yaml index ee459ea3f5..1350af0b11 100644 --- a/build.yaml +++ b/build.yaml @@ -223,7 +223,6 @@ filegroups: - src/core/lib/iomgr/wakeup_fd_pipe.h - src/core/lib/iomgr/wakeup_fd_posix.h - src/core/lib/iomgr/workqueue.h - - src/core/lib/iomgr/workqueue_posix.h - src/core/lib/iomgr/workqueue_windows.h - src/core/lib/json/json.h - src/core/lib/json/json_common.h @@ -307,7 +306,6 @@ filegroups: - src/core/lib/iomgr/wakeup_fd_nospecial.c - src/core/lib/iomgr/wakeup_fd_pipe.c - src/core/lib/iomgr/wakeup_fd_posix.c - - src/core/lib/iomgr/workqueue_posix.c - src/core/lib/iomgr/workqueue_windows.c - src/core/lib/json/json.c - src/core/lib/json/json_reader.c diff --git a/config.m4 b/config.m4 index 5947306c39..01b448e593 100644 --- a/config.m4 +++ b/config.m4 @@ -142,7 +142,6 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/iomgr/wakeup_fd_nospecial.c \ src/core/lib/iomgr/wakeup_fd_pipe.c \ src/core/lib/iomgr/wakeup_fd_posix.c \ - src/core/lib/iomgr/workqueue_posix.c \ src/core/lib/iomgr/workqueue_windows.c \ src/core/lib/json/json.c \ src/core/lib/json/json_reader.c \ diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 895e39b2a7..3746e2d2ff 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -312,7 +312,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/wakeup_fd_pipe.h', 'src/core/lib/iomgr/wakeup_fd_posix.h', 'src/core/lib/iomgr/workqueue.h', - 'src/core/lib/iomgr/workqueue_posix.h', 'src/core/lib/iomgr/workqueue_windows.h', 'src/core/lib/json/json.h', 'src/core/lib/json/json_common.h', @@ -475,7 +474,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/wakeup_fd_nospecial.c', 'src/core/lib/iomgr/wakeup_fd_pipe.c', 'src/core/lib/iomgr/wakeup_fd_posix.c', - 'src/core/lib/iomgr/workqueue_posix.c', 'src/core/lib/iomgr/workqueue_windows.c', 'src/core/lib/json/json.c', 'src/core/lib/json/json_reader.c', @@ -677,7 +675,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/wakeup_fd_pipe.h', 'src/core/lib/iomgr/wakeup_fd_posix.h', 'src/core/lib/iomgr/workqueue.h', - 'src/core/lib/iomgr/workqueue_posix.h', 'src/core/lib/iomgr/workqueue_windows.h', 'src/core/lib/json/json.h', 'src/core/lib/json/json_common.h', diff --git a/grpc.gemspec b/grpc.gemspec index 2a27492cfe..b5bd5eb102 100755 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -232,7 +232,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/wakeup_fd_pipe.h ) s.files += %w( src/core/lib/iomgr/wakeup_fd_posix.h ) s.files += %w( src/core/lib/iomgr/workqueue.h ) - s.files += %w( src/core/lib/iomgr/workqueue_posix.h ) s.files += %w( src/core/lib/iomgr/workqueue_windows.h ) s.files += %w( src/core/lib/json/json.h ) s.files += %w( src/core/lib/json/json_common.h ) @@ -395,7 +394,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/wakeup_fd_nospecial.c ) s.files += %w( src/core/lib/iomgr/wakeup_fd_pipe.c ) s.files += %w( src/core/lib/iomgr/wakeup_fd_posix.c ) - s.files += %w( src/core/lib/iomgr/workqueue_posix.c ) s.files += %w( src/core/lib/iomgr/workqueue_windows.c ) s.files += %w( src/core/lib/json/json.c ) s.files += %w( src/core/lib/json/json_reader.c ) diff --git a/package.xml b/package.xml index 4f596e0e8f..2b2045a563 100644 --- a/package.xml +++ b/package.xml @@ -239,7 +239,6 @@ - @@ -402,7 +401,6 @@ - diff --git a/src/core/lib/iomgr/combiner.c b/src/core/lib/iomgr/combiner.c index 273505f8b8..2b68240a15 100644 --- a/src/core/lib/iomgr/combiner.c +++ b/src/core/lib/iomgr/combiner.c @@ -92,6 +92,7 @@ grpc_combiner *grpc_combiner_create(grpc_workqueue *optional_workqueue) { lock->next_combiner_on_this_exec_ctx = NULL; lock->time_to_execute_final_list = false; lock->optional_workqueue = optional_workqueue; + lock->final_list_covered_by_poller = false; gpr_atm_no_barrier_store(&lock->state, 1); gpr_atm_no_barrier_store(&lock->covered_by_poller, 0); gpr_mpscq_init(&lock->queue); @@ -188,8 +189,8 @@ bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) { return false; } - if (lock->optional_workqueue != NULL && - is_covered_by_poller(lock) && grpc_exec_ctx_ready_to_finish(exec_ctx)) { + if (lock->optional_workqueue != NULL && is_covered_by_poller(lock) && + grpc_exec_ctx_ready_to_finish(exec_ctx)) { GPR_TIMER_MARK("offload_from_finished_exec_ctx", 0); // this execution context wants to move on, and we have a workqueue (and // so can help the execution context out): schedule remaining work to be diff --git a/src/core/lib/iomgr/ev_epoll_linux.c b/src/core/lib/iomgr/ev_epoll_linux.c index f473e4765c..864fe62cb6 100644 --- a/src/core/lib/iomgr/ev_epoll_linux.c +++ b/src/core/lib/iomgr/ev_epoll_linux.c @@ -152,14 +152,13 @@ static void fd_global_shutdown(void); * Polling island Declarations */ -//#define GRPC_PI_REF_COUNT_DEBUG -#ifdef GRPC_PI_REF_COUNT_DEBUG +#ifdef GRPC_WORKQUEUE_REFCOUNT_DEBUG #define PI_ADD_REF(p, r) pi_add_ref_dbg((p), (r), __FILE__, __LINE__) #define PI_UNREF(exec_ctx, p, r) \ pi_unref_dbg((exec_ctx), (p), (r), __FILE__, __LINE__) -#else /* defined(GRPC_PI_REF_COUNT_DEBUG) */ +#else /* defined(GRPC_WORKQUEUE_REFCOUNT_DEBUG) */ #define PI_ADD_REF(p, r) pi_add_ref((p)) #define PI_UNREF(exec_ctx, p, r) pi_unref((exec_ctx), (p)) @@ -185,8 +184,11 @@ typedef struct polling_island { * (except mu and ref_count) are invalid and must be ignored. */ gpr_atm merged_to; - /* The workqueue associated with this polling island */ - grpc_workqueue *workqueue; + gpr_atm poller_count; + gpr_mu workqueue_read_mu; + gpr_mpscq workqueue_items; + gpr_atm workqueue_item_count; + grpc_wakeup_fd workqueue_wakeup_fd; /* The fd of the underlying epoll set */ int epoll_fd; @@ -275,6 +277,8 @@ static bool append_error(grpc_error **composite, grpc_error *error, threads that woke up MUST NOT call grpc_wakeup_fd_consume_wakeup() */ static grpc_wakeup_fd polling_island_wakeup_fd; +static __thread polling_island *g_current_thread_polling_island; + /* Forward declaration */ static void polling_island_delete(grpc_exec_ctx *exec_ctx, polling_island *pi); @@ -289,10 +293,10 @@ static void polling_island_delete(grpc_exec_ctx *exec_ctx, polling_island *pi); gpr_atm g_epoll_sync; #endif /* defined(GRPC_TSAN) */ -#ifdef GRPC_PI_REF_COUNT_DEBUG static void pi_add_ref(polling_island *pi); static void pi_unref(grpc_exec_ctx *exec_ctx, polling_island *pi); +#ifdef GRPC_WORKQUEUE_REFCOUNT_DEBUG static void pi_add_ref_dbg(polling_island *pi, char *reason, char *file, int line) { long old_cnt = gpr_atm_acq_load(&pi->ref_count); @@ -308,6 +312,36 @@ static void pi_unref_dbg(grpc_exec_ctx *exec_ctx, polling_island *pi, gpr_log(GPR_DEBUG, "Unref pi: %p, old:%ld -> new:%ld (%s) - (%s, %d)", (void *)pi, old_cnt, (old_cnt - 1), reason, file, line); } + +static grpc_workqueue *workqueue_ref(grpc_workqueue *workqueue, + const char *file, int line, + const char *reason) { + if (workqueue != NULL) { + pi_add_ref_debug((polling_island *)workqueue, reason, file, line); + } + return workqueue; +} + +static void workqueue_unref(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue, + const char *file, int line, const char *reason) { + if (workqueue != NULL) { + pi_unref_dbg((polling_island *)workqueue, reason, file, line); + } +} +#else +static grpc_workqueue *workqueue_ref(grpc_workqueue *workqueue) { + if (workqueue != NULL) { + pi_add_ref((polling_island *)workqueue); + } + return workqueue; +} + +static void workqueue_unref(grpc_exec_ctx *exec_ctx, + grpc_workqueue *workqueue) { + if (workqueue != NULL) { + pi_unref(exec_ctx, (polling_island *)workqueue); + } +} #endif static void pi_add_ref(polling_island *pi) { @@ -315,10 +349,7 @@ static void pi_add_ref(polling_island *pi) { } static void pi_unref(grpc_exec_ctx *exec_ctx, polling_island *pi) { - /* If ref count went to one, we're back to just the workqueue owning a ref. - Unref the workqueue to break the loop. - - If ref count went to zero, delete the polling island. + /* If ref count went to zero, delete the polling island. Note that this deletion not be done under a lock. Once the ref count goes to zero, we are guaranteed that no one else holds a reference to the polling island (and that there is no racing pi_add_ref() call either). @@ -326,20 +357,12 @@ static void pi_unref(grpc_exec_ctx *exec_ctx, polling_island *pi) { Also, if we are deleting the polling island and the merged_to field is non-empty, we should remove a ref to the merged_to polling island */ - switch (gpr_atm_full_fetch_add(&pi->ref_count, -1)) { - case 2: /* last external ref: the only one now owned is by the workqueue */ - GRPC_WORKQUEUE_UNREF(exec_ctx, pi->workqueue, "polling_island"); - break; - case 1: { - polling_island *next = (polling_island *)gpr_atm_acq_load(&pi->merged_to); - polling_island_delete(exec_ctx, pi); - if (next != NULL) { - PI_UNREF(exec_ctx, next, "pi_delete"); /* Recursive call */ - } - break; + if (1 == gpr_atm_full_fetch_add(&pi->ref_count, -1)) { + polling_island *next = (polling_island *)gpr_atm_acq_load(&pi->merged_to); + polling_island_delete(exec_ctx, pi); + if (next != NULL) { + PI_UNREF(exec_ctx, next, "pi_delete"); /* Recursive call */ } - case 0: - GPR_UNREACHABLE_CODE(return ); } } @@ -488,11 +511,20 @@ static polling_island *polling_island_create(grpc_exec_ctx *exec_ctx, pi->fd_capacity = 0; pi->fds = NULL; pi->epoll_fd = -1; - pi->workqueue = NULL; + + gpr_mu_init(&pi->workqueue_read_mu); + gpr_mpscq_init(&pi->workqueue_items); + gpr_atm_rel_store(&pi->workqueue_item_count, 0); gpr_atm_rel_store(&pi->ref_count, 0); + gpr_atm_rel_store(&pi->poller_count, 0); gpr_atm_rel_store(&pi->merged_to, (gpr_atm)NULL); + if (!append_error(error, grpc_wakeup_fd_init(&pi->workqueue_wakeup_fd), + err_desc)) { + goto done; + } + pi->epoll_fd = epoll_create1(EPOLL_CLOEXEC); if (pi->epoll_fd < 0) { @@ -501,26 +533,14 @@ static polling_island *polling_island_create(grpc_exec_ctx *exec_ctx, } polling_island_add_wakeup_fd_locked(pi, &grpc_global_wakeup_fd, error); + polling_island_add_wakeup_fd_locked(pi, &pi->workqueue_wakeup_fd, error); if (initial_fd != NULL) { polling_island_add_fds_locked(pi, &initial_fd, 1, true, error); } - if (append_error(error, grpc_workqueue_create(exec_ctx, &pi->workqueue), - err_desc) && - *error == GRPC_ERROR_NONE) { - polling_island_add_fds_locked(pi, &pi->workqueue->wakeup_read_fd, 1, true, - error); - GPR_ASSERT(pi->workqueue->wakeup_read_fd->polling_island == NULL); - pi->workqueue->wakeup_read_fd->polling_island = pi; - PI_ADD_REF(pi, "fd"); - } - done: if (*error != GRPC_ERROR_NONE) { - if (pi->workqueue != NULL) { - GRPC_WORKQUEUE_UNREF(exec_ctx, pi->workqueue, "polling_island"); - } polling_island_delete(exec_ctx, pi); pi = NULL; } @@ -533,7 +553,11 @@ static void polling_island_delete(grpc_exec_ctx *exec_ctx, polling_island *pi) { if (pi->epoll_fd >= 0) { close(pi->epoll_fd); } + GPR_ASSERT(gpr_atm_no_barrier_load(&pi->workqueue_item_count) == 0); + gpr_mu_destroy(&pi->workqueue_read_mu); + gpr_mpscq_destroy(&pi->workqueue_items); gpr_mu_destroy(&pi->mu); + grpc_wakeup_fd_destroy(&pi->workqueue_wakeup_fd); gpr_free(pi->fds); gpr_free(pi); } @@ -678,6 +702,40 @@ static void polling_island_unlock_pair(polling_island *p, polling_island *q) { } } +static void workqueue_maybe_wakeup(polling_island *pi) { + bool force_wakeup = false; + bool is_current_poller = (g_current_thread_polling_island == pi); + gpr_atm min_current_pollers_for_wakeup = is_current_poller ? 1 : 0; + gpr_atm current_pollers = gpr_atm_no_barrier_load(&pi->poller_count); + if (force_wakeup || current_pollers > min_current_pollers_for_wakeup) { + GRPC_LOG_IF_ERROR("workqueue_wakeup_fd", + grpc_wakeup_fd_wakeup(&pi->workqueue_wakeup_fd)); + } +} + +static void workqueue_move_items_to_parent(polling_island *q) { + polling_island *p = (polling_island *)gpr_atm_no_barrier_load(&q->merged_to); + if (p == NULL) { + return; + } + gpr_mu_lock(&q->workqueue_read_mu); + int num_added = 0; + while (gpr_atm_no_barrier_load(&q->workqueue_item_count) > 0) { + gpr_mpscq_node *n = gpr_mpscq_pop(&q->workqueue_items); + if (n != NULL) { + gpr_atm_no_barrier_fetch_add(&q->workqueue_item_count, -1); + gpr_atm_no_barrier_fetch_add(&p->workqueue_item_count, 1); + gpr_mpscq_push(&p->workqueue_items, n); + num_added++; + } + } + gpr_mu_unlock(&q->workqueue_read_mu); + if (num_added > 0) { + workqueue_maybe_wakeup(p); + } + workqueue_move_items_to_parent(p); +} + static polling_island *polling_island_merge(polling_island *p, polling_island *q, grpc_error **error) { @@ -702,6 +760,8 @@ static polling_island *polling_island_merge(polling_island *p, /* Add the 'merged_to' link from p --> q */ gpr_atm_rel_store(&p->merged_to, (gpr_atm)q); PI_ADD_REF(q, "pi_merge"); /* To account for the new incoming ref from p */ + + workqueue_move_items_to_parent(q); } /* else if p == q, nothing needs to be done */ @@ -712,6 +772,21 @@ static polling_island *polling_island_merge(polling_island *p, return q; } +static void workqueue_enqueue(grpc_exec_ctx *exec_ctx, + grpc_workqueue *workqueue, grpc_closure *closure, + grpc_error *error) { + polling_island *pi = (polling_island *)workqueue; + GPR_TIMER_BEGIN("workqueue.enqueue", 0); + gpr_atm last = gpr_atm_no_barrier_fetch_add(&pi->workqueue_item_count, 1); + closure->error_data.error = error; + gpr_mpscq_push(&pi->workqueue_items, &closure->next_data.atm_next); + if (last == 0) { + workqueue_maybe_wakeup(pi); + } + GPR_TIMER_END("workqueue.enqueue", 0); + workqueue_move_items_to_parent(pi); +} + static grpc_error *polling_island_global_init() { grpc_error *error = GRPC_ERROR_NONE; @@ -1042,11 +1117,8 @@ static void fd_notify_on_write(grpc_exec_ctx *exec_ctx, grpc_fd *fd, static grpc_workqueue *fd_get_workqueue(grpc_fd *fd) { gpr_mu_lock(&fd->mu); - grpc_workqueue *workqueue = NULL; - if (fd->polling_island != NULL) { - workqueue = - GRPC_WORKQUEUE_REF(fd->polling_island->workqueue, "get_workqueue"); - } + grpc_workqueue *workqueue = + grpc_workqueue_ref((grpc_workqueue *)fd->polling_island); gpr_mu_unlock(&fd->mu); return workqueue; } @@ -1299,6 +1371,25 @@ static void pollset_reset(grpc_pollset *pollset) { GPR_ASSERT(pollset->polling_island == NULL); } +static bool maybe_do_workqueue_work(grpc_exec_ctx *exec_ctx, + polling_island *pi) { + if (gpr_mu_trylock(&pi->workqueue_read_mu)) { + gpr_mpscq_node *n = gpr_mpscq_pop(&pi->workqueue_items); + gpr_mu_unlock(&pi->workqueue_read_mu); + if (n != NULL) { + if (gpr_atm_full_fetch_add(&pi->workqueue_item_count, -1) > 1) { + workqueue_maybe_wakeup(pi); + } + grpc_closure *c = (grpc_closure *)n; + grpc_closure_run(exec_ctx, c, c->error_data.error); + return true; + } else if (gpr_atm_no_barrier_load(&pi->workqueue_item_count) > 0) { + workqueue_maybe_wakeup(pi); + } + } + return false; +} + #define GRPC_EPOLL_MAX_EVENTS 100 /* Note: sig_mask contains the signal mask to use *during* epoll_wait() */ static void pollset_work_and_unlock(grpc_exec_ctx *exec_ctx, @@ -1354,7 +1445,10 @@ static void pollset_work_and_unlock(grpc_exec_ctx *exec_ctx, PI_ADD_REF(pi, "ps_work"); gpr_mu_unlock(&pollset->mu); - do { + if (!maybe_do_workqueue_work(exec_ctx, pi)) { + gpr_atm_no_barrier_fetch_add(&pi->poller_count, 1); + g_current_thread_polling_island = pi; + GRPC_SCHEDULING_START_BLOCKING_REGION; ep_rv = epoll_pwait(epoll_fd, ep_ev, GRPC_EPOLL_MAX_EVENTS, timeout_ms, sig_mask); @@ -1386,6 +1480,11 @@ static void pollset_work_and_unlock(grpc_exec_ctx *exec_ctx, append_error(error, grpc_wakeup_fd_consume_wakeup(&grpc_global_wakeup_fd), err_desc); + } else if (data_ptr == &pi->workqueue_wakeup_fd) { + append_error(error, + grpc_wakeup_fd_consume_wakeup(&grpc_global_wakeup_fd), + err_desc); + maybe_do_workqueue_work(exec_ctx, pi); } else if (data_ptr == &polling_island_wakeup_fd) { GRPC_POLLING_TRACE( "pollset_work: pollset: %p, worker: %p polling island (epoll_fd: " @@ -1408,7 +1507,10 @@ static void pollset_work_and_unlock(grpc_exec_ctx *exec_ctx, } } } - } while (ep_rv == GRPC_EPOLL_MAX_EVENTS); + + g_current_thread_polling_island = NULL; + gpr_atm_no_barrier_fetch_add(&pi->poller_count, -1); + } GPR_ASSERT(pi != NULL); @@ -1868,6 +1970,10 @@ static const grpc_event_engine_vtable vtable = { .kick_poller = kick_poller, + .workqueue_ref = workqueue_ref, + .workqueue_unref = workqueue_unref, + .workqueue_enqueue = workqueue_enqueue, + .shutdown_engine = shutdown_engine, }; diff --git a/src/core/lib/iomgr/ev_poll_and_epoll_posix.c b/src/core/lib/iomgr/ev_poll_and_epoll_posix.c index c2107e5e39..1829440a6e 100644 --- a/src/core/lib/iomgr/ev_poll_and_epoll_posix.c +++ b/src/core/lib/iomgr/ev_poll_and_epoll_posix.c @@ -1988,6 +1988,32 @@ static void pollset_set_del_fd(grpc_exec_ctx *exec_ctx, gpr_mu_unlock(&pollset_set->mu); } +/******************************************************************************* + * workqueue stubs + */ + +#ifdef GRPC_WORKQUEUE_REFCOUNT_DEBUG +static grpc_workqueue *workqueue_ref(grpc_workqueue *workqueue, + const char *file, int line, + const char *reason) { + return workqueue; +} +static void workqueue_unref(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue, + const char *file, int line, const char *reason) {} +#else +static grpc_workqueue *workqueue_ref(grpc_workqueue *workqueue) { + return workqueue; +} +static void workqueue_unref(grpc_exec_ctx *exec_ctx, + grpc_workqueue *workqueue) {} +#endif + +static void workqueue_enqueue(grpc_exec_ctx *exec_ctx, + grpc_workqueue *workqueue, grpc_closure *closure, + grpc_error *error) { + grpc_exec_ctx_sched(exec_ctx, closure, error, NULL); +} + /******************************************************************************* * event engine binding */ @@ -2029,6 +2055,10 @@ static const grpc_event_engine_vtable vtable = { .kick_poller = kick_poller, + .workqueue_ref = workqueue_ref, + .workqueue_unref = workqueue_unref, + .workqueue_enqueue = workqueue_enqueue, + .shutdown_engine = shutdown_engine, }; diff --git a/src/core/lib/iomgr/ev_poll_posix.c b/src/core/lib/iomgr/ev_poll_posix.c index 16a5e3083e..b84a56018f 100644 --- a/src/core/lib/iomgr/ev_poll_posix.c +++ b/src/core/lib/iomgr/ev_poll_posix.c @@ -1235,6 +1235,32 @@ static void pollset_set_del_fd(grpc_exec_ctx *exec_ctx, gpr_mu_unlock(&pollset_set->mu); } +/******************************************************************************* + * workqueue stubs + */ + +#ifdef GRPC_WORKQUEUE_REFCOUNT_DEBUG +static grpc_workqueue *workqueue_ref(grpc_workqueue *workqueue, + const char *file, int line, + const char *reason) { + return workqueue; +} +static void workqueue_unref(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue, + const char *file, int line, const char *reason) {} +#else +static grpc_workqueue *workqueue_ref(grpc_workqueue *workqueue) { + return workqueue; +} +static void workqueue_unref(grpc_exec_ctx *exec_ctx, + grpc_workqueue *workqueue) {} +#endif + +static void workqueue_enqueue(grpc_exec_ctx *exec_ctx, + grpc_workqueue *workqueue, grpc_closure *closure, + grpc_error *error) { + grpc_exec_ctx_sched(exec_ctx, closure, error, NULL); +} + /******************************************************************************* * event engine binding */ @@ -1273,6 +1299,10 @@ static const grpc_event_engine_vtable vtable = { .kick_poller = kick_poller, + .workqueue_ref = workqueue_ref, + .workqueue_unref = workqueue_unref, + .workqueue_enqueue = workqueue_enqueue, + .shutdown_engine = shutdown_engine, }; diff --git a/src/core/lib/iomgr/ev_posix.c b/src/core/lib/iomgr/ev_posix.c index 6536672685..26618f8d55 100644 --- a/src/core/lib/iomgr/ev_posix.c +++ b/src/core/lib/iomgr/ev_posix.c @@ -258,4 +258,27 @@ void grpc_pollset_set_del_fd(grpc_exec_ctx *exec_ctx, grpc_error *grpc_kick_poller(void) { return g_event_engine->kick_poller(); } +#ifdef GRPC_WORKQUEUE_REFCOUNT_DEBUG +grpc_workqueue *grpc_workqueue_ref(grpc_workqueue *workqueue, const char *file, + int line, const char *reason) { + return g_event_engine->workqueue_ref(workqueue, file, line, reason); +} +void grpc_workqueue_unref(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue, + const char *file, int line, const char *reason) { + g_event_engine->workqueue_unref(exec_ctx, workqueue, file, line, reason); +} +#else +grpc_workqueue *grpc_workqueue_ref(grpc_workqueue *workqueue) { + return g_event_engine->workqueue_ref(workqueue); +} +void grpc_workqueue_unref(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue) { + g_event_engine->workqueue_unref(exec_ctx, workqueue); +} +#endif + +void grpc_workqueue_enqueue(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue, + grpc_closure *closure, grpc_error *error) { + g_event_engine->workqueue_enqueue(exec_ctx, workqueue, closure, error); +} + #endif // GPR_POSIX_SOCKET diff --git a/src/core/lib/iomgr/ev_posix.h b/src/core/lib/iomgr/ev_posix.h index c2aa1756ea..9666fe5e86 100644 --- a/src/core/lib/iomgr/ev_posix.h +++ b/src/core/lib/iomgr/ev_posix.h @@ -95,6 +95,18 @@ typedef struct grpc_event_engine_vtable { grpc_error *(*kick_poller)(void); void (*shutdown_engine)(void); + +#ifdef GRPC_WORKQUEUE_REFCOUNT_DEBUG + grpc_workqueue *(*workqueue_ref)(grpc_workqueue *workqueue, const char *file, + int line, const char *reason); + void (*workqueue_unref)(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue, + const char *file, int line, const char *reason); +#else + grpc_workqueue *(*workqueue_ref)(grpc_workqueue *workqueue); + void (*workqueue_unref)(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue); +#endif + void (*workqueue_enqueue)(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue, + grpc_closure *closure, grpc_error *error); } grpc_event_engine_vtable; void grpc_event_engine_init(void); diff --git a/src/core/lib/iomgr/workqueue.h b/src/core/lib/iomgr/workqueue.h index 9f95562fab..e1902a36d2 100644 --- a/src/core/lib/iomgr/workqueue.h +++ b/src/core/lib/iomgr/workqueue.h @@ -40,10 +40,6 @@ #include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/iomgr/pollset_set.h" -#ifdef GPR_POSIX_SOCKET -#include "src/core/lib/iomgr/workqueue_posix.h" -#endif - #ifdef GPR_WINDOWS #include "src/core/lib/iomgr/workqueue_windows.h" #endif diff --git a/src/core/lib/iomgr/workqueue_posix.c b/src/core/lib/iomgr/workqueue_posix.c deleted file mode 100644 index 6f8a26684a..0000000000 --- a/src/core/lib/iomgr/workqueue_posix.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include - -#ifdef GPR_POSIX_SOCKET - -#include "src/core/lib/iomgr/workqueue.h" - -#include - -#include -#include -#include - -#include "src/core/lib/iomgr/ev_posix.h" -#include "src/core/lib/profiling/timers.h" - -static void on_readable(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error); - -grpc_error *grpc_workqueue_create(grpc_exec_ctx *exec_ctx, - grpc_workqueue **workqueue) { - char name[32]; - *workqueue = gpr_malloc(sizeof(grpc_workqueue)); - gpr_ref_init(&(*workqueue)->refs, 1); - gpr_atm_no_barrier_store(&(*workqueue)->state, 1); - grpc_error *err = grpc_wakeup_fd_init(&(*workqueue)->wakeup_fd); - if (err != GRPC_ERROR_NONE) { - gpr_free(*workqueue); - return err; - } - sprintf(name, "workqueue:%p", (void *)(*workqueue)); - (*workqueue)->wakeup_read_fd = grpc_fd_create( - GRPC_WAKEUP_FD_GET_READ_FD(&(*workqueue)->wakeup_fd), name); - gpr_mpscq_init(&(*workqueue)->queue); - grpc_closure_init(&(*workqueue)->read_closure, on_readable, *workqueue); - grpc_fd_notify_on_read(exec_ctx, (*workqueue)->wakeup_read_fd, - &(*workqueue)->read_closure); - return GRPC_ERROR_NONE; -} - -static void workqueue_destroy(grpc_exec_ctx *exec_ctx, - grpc_workqueue *workqueue) { - grpc_fd_shutdown(exec_ctx, workqueue->wakeup_read_fd); -} - -static void workqueue_orphan(grpc_exec_ctx *exec_ctx, - grpc_workqueue *workqueue) { - gpr_atm last = gpr_atm_full_fetch_add(&workqueue->state, -1); - if (last == 1) { - workqueue_destroy(exec_ctx, workqueue); - } -} - -#ifdef GRPC_WORKQUEUE_REFCOUNT_DEBUG -grpc_workqueue *grpc_workqueue_ref(grpc_workqueue *workqueue, const char *file, - int line, const char *reason) { - if (workqueue == NULL) return NULL; - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "WORKQUEUE:%p ref %d -> %d %s", - workqueue, (int)workqueue->refs.count, (int)workqueue->refs.count + 1, - reason); - gpr_ref(&workqueue->refs); - return workqueue; -} -#else -grpc_workqueue *grpc_workqueue_ref(grpc_workqueue *workqueue) { - if (workqueue != NULL) { - gpr_ref(&workqueue->refs); - } - return workqueue; -} -#endif - -#ifdef GRPC_WORKQUEUE_REFCOUNT_DEBUG -void grpc_workqueue_unref(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue, - const char *file, int line, const char *reason) { - if (workqueue == NULL) return; - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "WORKQUEUE:%p unref %d -> %d %s", - workqueue, (int)workqueue->refs.count, (int)workqueue->refs.count - 1, - reason); - if (gpr_unref(&workqueue->refs)) { - workqueue_orphan(exec_ctx, workqueue); - } -} -#else -void grpc_workqueue_unref(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue) { - if (workqueue == NULL) return; - if (gpr_unref(&workqueue->refs)) { - workqueue_orphan(exec_ctx, workqueue); - } -} -#endif - -static void drain(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue) { - abort(); -} - -static void wakeup(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue) { - GPR_TIMER_MARK("workqueue.wakeup", 0); - grpc_error *err = grpc_wakeup_fd_wakeup(&workqueue->wakeup_fd); - if (!GRPC_LOG_IF_ERROR("wakeupfd_wakeup", err)) { - drain(exec_ctx, workqueue); - } -} - -static void on_readable(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { - GPR_TIMER_BEGIN("workqueue.on_readable", 0); - - grpc_workqueue *workqueue = arg; - - if (error != GRPC_ERROR_NONE) { - /* HACK: let wakeup_fd code know that we stole the fd */ - workqueue->wakeup_fd.read_fd = 0; - grpc_wakeup_fd_destroy(&workqueue->wakeup_fd); - grpc_fd_orphan(exec_ctx, workqueue->wakeup_read_fd, NULL, NULL, "destroy"); - GPR_ASSERT(gpr_atm_no_barrier_load(&workqueue->state) == 0); - gpr_free(workqueue); - } else { - gpr_mpscq_node *n = NULL; - for (int i = 0; i < 100; i++) { - n = gpr_mpscq_pop(&workqueue->queue); - if (n != NULL) { - grpc_closure *c = (grpc_closure *)n; - grpc_closure_run(exec_ctx, c, c->error_data.error); - grpc_exec_ctx_flush(exec_ctx); - gpr_atm last = gpr_atm_full_fetch_add(&workqueue->state, -2); - switch (last) { - default: - // there's more to do, keep going - goto keep_going; - case 3: // had one count, one unorphaned --> done, unorphaned - goto switch_to_idle; - case 2: // had one count, one orphaned --> done, orphaned - goto destroy; - case 1: - case 0: - // these values are illegal - representing an already done or - // deleted workqueue - GPR_UNREACHABLE_CODE(break); - } - } - } - /* fall through to wakeup_next -- we tried a bunch of times to pull a node - * but failed */ -wakeup_next: - error = grpc_wakeup_fd_consume_wakeup(&workqueue->wakeup_fd); - if (error != GRPC_ERROR_NONE) { - /* recurse to get error handling */ - on_readable(exec_ctx, arg, error); - } else { - grpc_fd_notify_on_read(exec_ctx, workqueue->wakeup_read_fd, - &workqueue->read_closure); - wakeup(exec_ctx, workqueue); - } - return; - -keep_going: - if (grpc_exec_ctx_ready_to_finish(exec_ctx)) { - goto wakeup_next; - } else { - /* recurse to continue */ - on_readable(exec_ctx, arg, GRPC_ERROR_NONE); - } - return; - -switch_to_idle: - error = grpc_wakeup_fd_consume_wakeup(&workqueue->wakeup_fd); - if (error != GRPC_ERROR_NONE) { - /* recurse to get error handling */ - on_readable(exec_ctx, arg, error); - } else { - grpc_fd_notify_on_read(exec_ctx, workqueue->wakeup_read_fd, - &workqueue->read_closure); - } - return; - -destroy: - workqueue_destroy(exec_ctx, workqueue); - return; - } - - GPR_TIMER_END("workqueue.on_readable", 0); -} - -void grpc_workqueue_enqueue(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue, - grpc_closure *closure, grpc_error *error) { - GPR_TIMER_BEGIN("workqueue.enqueue", 0); - GRPC_WORKQUEUE_REF(workqueue, "enqueue"); - gpr_atm last = gpr_atm_full_fetch_add(&workqueue->state, 2); - GPR_ASSERT(last & 1); - closure->error_data.error = error; - gpr_mpscq_push(&workqueue->queue, &closure->next_data.atm_next); - if (last == 1) { - wakeup(exec_ctx, workqueue); - } - GRPC_WORKQUEUE_UNREF(exec_ctx, workqueue, "enqueue"); - GPR_TIMER_END("workqueue.enqueue", 0); -} - -#endif /* GPR_POSIX_SOCKET */ diff --git a/src/core/lib/iomgr/workqueue_posix.h b/src/core/lib/iomgr/workqueue_posix.h deleted file mode 100644 index 03ee21cef7..0000000000 --- a/src/core/lib/iomgr/workqueue_posix.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef GRPC_CORE_LIB_IOMGR_WORKQUEUE_POSIX_H -#define GRPC_CORE_LIB_IOMGR_WORKQUEUE_POSIX_H - -#include "src/core/lib/iomgr/wakeup_fd_posix.h" -#include "src/core/lib/support/mpscq.h" - -struct grpc_fd; - -struct grpc_workqueue { - gpr_refcount refs; - gpr_mpscq queue; - // state is: - // lower bit - zero if orphaned - // other bits - number of items enqueued - gpr_atm state; - - grpc_wakeup_fd wakeup_fd; - struct grpc_fd *wakeup_read_fd; - - grpc_closure read_closure; -}; - -/** Create a work queue. Returns an error if creation fails. If creation - succeeds, sets *workqueue to point to it. */ -grpc_error *grpc_workqueue_create(grpc_exec_ctx *exec_ctx, - grpc_workqueue **workqueue); - -#endif /* GRPC_CORE_LIB_IOMGR_WORKQUEUE_POSIX_H */ diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index d53f46b18b..15a8a10fca 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -136,7 +136,6 @@ CORE_SOURCE_FILES = [ 'src/core/lib/iomgr/wakeup_fd_nospecial.c', 'src/core/lib/iomgr/wakeup_fd_pipe.c', 'src/core/lib/iomgr/wakeup_fd_posix.c', - 'src/core/lib/iomgr/workqueue_posix.c', 'src/core/lib/iomgr/workqueue_windows.c', 'src/core/lib/json/json.c', 'src/core/lib/json/json_reader.c', diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 0a412dd706..e95f0de8c8 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -929,7 +929,6 @@ src/core/lib/iomgr/unix_sockets_posix.h \ src/core/lib/iomgr/wakeup_fd_pipe.h \ src/core/lib/iomgr/wakeup_fd_posix.h \ src/core/lib/iomgr/workqueue.h \ -src/core/lib/iomgr/workqueue_posix.h \ src/core/lib/iomgr/workqueue_windows.h \ src/core/lib/json/json.h \ src/core/lib/json/json_common.h \ @@ -1045,7 +1044,6 @@ src/core/lib/iomgr/wakeup_fd_eventfd.c \ src/core/lib/iomgr/wakeup_fd_nospecial.c \ src/core/lib/iomgr/wakeup_fd_pipe.c \ src/core/lib/iomgr/wakeup_fd_posix.c \ -src/core/lib/iomgr/workqueue_posix.c \ src/core/lib/iomgr/workqueue_windows.c \ src/core/lib/json/json.c \ src/core/lib/json/json_reader.c \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 1c55859d26..25b047b51f 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -846,7 +846,6 @@ src/core/lib/iomgr/unix_sockets_posix.h \ src/core/lib/iomgr/wakeup_fd_pipe.h \ src/core/lib/iomgr/wakeup_fd_posix.h \ src/core/lib/iomgr/workqueue.h \ -src/core/lib/iomgr/workqueue_posix.h \ src/core/lib/iomgr/workqueue_windows.h \ src/core/lib/json/json.h \ src/core/lib/json/json_common.h \ @@ -1009,7 +1008,6 @@ src/core/lib/iomgr/wakeup_fd_eventfd.c \ src/core/lib/iomgr/wakeup_fd_nospecial.c \ src/core/lib/iomgr/wakeup_fd_pipe.c \ src/core/lib/iomgr/wakeup_fd_posix.c \ -src/core/lib/iomgr/workqueue_posix.c \ src/core/lib/iomgr/workqueue_windows.c \ src/core/lib/json/json.c \ src/core/lib/json/json_reader.c \ diff --git a/tools/profiling/perf/run_perf_unconstrained.sh b/tools/profiling/perf/run_perf_unconstrained.sh new file mode 100755 index 0000000000..a4c2dfa7fd --- /dev/null +++ b/tools/profiling/perf/run_perf_unconstrained.sh @@ -0,0 +1,97 @@ +#!/bin/bash +# Copyright 2016, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# format argument via +# $ echo '{...}' | python -mjson.tool +read -r -d '' SCENARIOS_JSON_ARG <<'EOF' +{ + "scenarios": [ + { + "benchmark_seconds": 60, + "warmup_seconds": 5, + "client_config": { + "client_channels": 100, + "client_type": "ASYNC_CLIENT", + "histogram_params": { + "max_possible": 60000000000.0, + "resolution": 0.01 + }, + "load_params": { + "closed_loop": {} + }, + "outstanding_rpcs_per_channel": 100, + "payload_config": { + "simple_params": { + "req_size": 0, + "resp_size": 0 + } + }, + "rpc_type": "UNARY", + "security_params": null + }, + "name": "name_goes_here", + "num_clients": 1, + "num_servers": 1, + "server_config": { + "security_params": null, + "server_type": "ASYNC_SERVER" + }, + "spawn_local_worker_count": -2 + } + ] +} + +EOF + +set -ex + +cd $(dirname $0)/../../.. + +CPUS=`python -c 'import multiprocessing; print multiprocessing.cpu_count()'` + +# try to use pypy for generating reports +# each trace dumps 7-8gig of text to disk, and processing this into a report is +# heavyweight - so any speed boost is worthwhile +# TODO(ctiller): consider rewriting report generation in C++ for performance +if which pypy >/dev/null; then + PYTHON=pypy +else + PYTHON=python2.7 +fi + +export config=mutrace + +make CONFIG=$config -j$CPUS qps_json_driver + +bins/$config/qps_json_driver --scenarios_json="$SCENARIOS_JSON_ARG" + +#sudo perf record -F 997 -g bins/$config/qps_json_driver --scenarios_json="$SCENARIOS_JSON_ARG" +#sudo perf report + diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index 37355c7e11..980328c82a 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -5978,7 +5978,6 @@ "src/core/lib/iomgr/wakeup_fd_pipe.h", "src/core/lib/iomgr/wakeup_fd_posix.h", "src/core/lib/iomgr/workqueue.h", - "src/core/lib/iomgr/workqueue_posix.h", "src/core/lib/iomgr/workqueue_windows.h", "src/core/lib/json/json.h", "src/core/lib/json/json_common.h", @@ -6128,8 +6127,6 @@ "src/core/lib/iomgr/wakeup_fd_posix.c", "src/core/lib/iomgr/wakeup_fd_posix.h", "src/core/lib/iomgr/workqueue.h", - "src/core/lib/iomgr/workqueue_posix.c", - "src/core/lib/iomgr/workqueue_posix.h", "src/core/lib/iomgr/workqueue_windows.c", "src/core/lib/iomgr/workqueue_windows.h", "src/core/lib/json/json.c", diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj b/vsprojects/vcxproj/grpc++/grpc++.vcxproj index 354351364e..79139f6e51 100644 --- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj +++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj @@ -429,7 +429,6 @@ - @@ -638,8 +637,6 @@ - - diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters index e284e3f7f3..f78fe62fed 100644 --- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters +++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters @@ -274,9 +274,6 @@ src\core\lib\iomgr - - src\core\lib\iomgr - src\core\lib\iomgr @@ -884,9 +881,6 @@ src\core\lib\iomgr - - src\core\lib\iomgr - src\core\lib\iomgr diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj index ac1593464f..118b4ddf4b 100644 --- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj +++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj @@ -425,7 +425,6 @@ - @@ -624,8 +623,6 @@ - - diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters index 9352918fb0..be1ea64396 100644 --- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters +++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters @@ -259,9 +259,6 @@ src\core\lib\iomgr - - src\core\lib\iomgr - src\core\lib\iomgr @@ -857,9 +854,6 @@ src\core\lib\iomgr - - src\core\lib\iomgr - src\core\lib\iomgr diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj index 98873ca8d7..ff49d6c6b2 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj @@ -355,7 +355,6 @@ - @@ -579,8 +578,6 @@ - - diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters index f3d7958f7c..a7a9266a7d 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters @@ -178,9 +178,6 @@ src\core\lib\iomgr - - src\core\lib\iomgr - src\core\lib\iomgr @@ -836,9 +833,6 @@ src\core\lib\iomgr - - src\core\lib\iomgr - src\core\lib\iomgr diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj index b1bdde584d..6e15f249a6 100644 --- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj +++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj @@ -246,7 +246,6 @@ - @@ -423,8 +422,6 @@ - - diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters index b78c7bfb36..2cef219892 100644 --- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters +++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters @@ -226,9 +226,6 @@ src\core\lib\iomgr - - src\core\lib\iomgr - src\core\lib\iomgr @@ -617,9 +614,6 @@ src\core\lib\iomgr - - src\core\lib\iomgr - src\core\lib\iomgr diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj index 0ea880833a..2d8b04c7cd 100644 --- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj +++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj @@ -345,7 +345,6 @@ - @@ -547,8 +546,6 @@ - - diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters index 7549a9609d..a3429b351f 100644 --- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters +++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters @@ -181,9 +181,6 @@ src\core\lib\iomgr - - src\core\lib\iomgr - src\core\lib\iomgr @@ -746,9 +743,6 @@ src\core\lib\iomgr - - src\core\lib\iomgr - src\core\lib\iomgr -- cgit v1.2.3 From a980b9acc42da5afa691c7d5bfd3ae9fb2a24586 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 9 Sep 2016 12:58:55 -0700 Subject: Fix perf reporting --- tools/profiling/perf/run_perf_unconstrained.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tools/profiling/perf/run_perf_unconstrained.sh b/tools/profiling/perf/run_perf_unconstrained.sh index a4c2dfa7fd..dbfd2828a8 100755 --- a/tools/profiling/perf/run_perf_unconstrained.sh +++ b/tools/profiling/perf/run_perf_unconstrained.sh @@ -90,8 +90,6 @@ export config=mutrace make CONFIG=$config -j$CPUS qps_json_driver -bins/$config/qps_json_driver --scenarios_json="$SCENARIOS_JSON_ARG" - -#sudo perf record -F 997 -g bins/$config/qps_json_driver --scenarios_json="$SCENARIOS_JSON_ARG" -#sudo perf report +sudo perf record -F 997 -g bins/$config/qps_json_driver --scenarios_json="$SCENARIOS_JSON_ARG" +sudo perf report -- cgit v1.2.3 From a10b0b102012e11d43e1b6337accee4b6986bdf2 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 9 Sep 2016 16:20:07 -0700 Subject: Fix refcount debug --- src/core/lib/iomgr/ev_epoll_linux.c | 14 +++++++------- src/core/lib/iomgr/ev_posix.h | 1 + src/core/lib/iomgr/workqueue.h | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/core/lib/iomgr/ev_epoll_linux.c b/src/core/lib/iomgr/ev_epoll_linux.c index 864fe62cb6..5a69c088cd 100644 --- a/src/core/lib/iomgr/ev_epoll_linux.c +++ b/src/core/lib/iomgr/ev_epoll_linux.c @@ -297,8 +297,8 @@ static void pi_add_ref(polling_island *pi); static void pi_unref(grpc_exec_ctx *exec_ctx, polling_island *pi); #ifdef GRPC_WORKQUEUE_REFCOUNT_DEBUG -static void pi_add_ref_dbg(polling_island *pi, char *reason, char *file, - int line) { +static void pi_add_ref_dbg(polling_island *pi, const char *reason, + const char *file, int line) { long old_cnt = gpr_atm_acq_load(&pi->ref_count); pi_add_ref(pi); gpr_log(GPR_DEBUG, "Add ref pi: %p, old: %ld -> new:%ld (%s) - (%s, %d)", @@ -306,7 +306,7 @@ static void pi_add_ref_dbg(polling_island *pi, char *reason, char *file, } static void pi_unref_dbg(grpc_exec_ctx *exec_ctx, polling_island *pi, - char *reason, char *file, int line) { + const char *reason, const char *file, int line) { long old_cnt = gpr_atm_acq_load(&pi->ref_count); pi_unref(exec_ctx, pi); gpr_log(GPR_DEBUG, "Unref pi: %p, old:%ld -> new:%ld (%s) - (%s, %d)", @@ -317,7 +317,7 @@ static grpc_workqueue *workqueue_ref(grpc_workqueue *workqueue, const char *file, int line, const char *reason) { if (workqueue != NULL) { - pi_add_ref_debug((polling_island *)workqueue, reason, file, line); + pi_add_ref_dbg((polling_island *)workqueue, reason, file, line); } return workqueue; } @@ -325,7 +325,7 @@ static grpc_workqueue *workqueue_ref(grpc_workqueue *workqueue, static void workqueue_unref(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue, const char *file, int line, const char *reason) { if (workqueue != NULL) { - pi_unref_dbg((polling_island *)workqueue, reason, file, line); + pi_unref_dbg(exec_ctx, (polling_island *)workqueue, reason, file, line); } } #else @@ -1117,8 +1117,8 @@ static void fd_notify_on_write(grpc_exec_ctx *exec_ctx, grpc_fd *fd, static grpc_workqueue *fd_get_workqueue(grpc_fd *fd) { gpr_mu_lock(&fd->mu); - grpc_workqueue *workqueue = - grpc_workqueue_ref((grpc_workqueue *)fd->polling_island); + grpc_workqueue *workqueue = GRPC_WORKQUEUE_REF( + (grpc_workqueue *)fd->polling_island, "fd_get_workqueue"); gpr_mu_unlock(&fd->mu); return workqueue; } diff --git a/src/core/lib/iomgr/ev_posix.h b/src/core/lib/iomgr/ev_posix.h index 9666fe5e86..2fdef06838 100644 --- a/src/core/lib/iomgr/ev_posix.h +++ b/src/core/lib/iomgr/ev_posix.h @@ -40,6 +40,7 @@ #include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/iomgr/pollset_set.h" #include "src/core/lib/iomgr/wakeup_fd_posix.h" +#include "src/core/lib/iomgr/workqueue.h" typedef struct grpc_fd grpc_fd; diff --git a/src/core/lib/iomgr/workqueue.h b/src/core/lib/iomgr/workqueue.h index e1902a36d2..703ea7819e 100644 --- a/src/core/lib/iomgr/workqueue.h +++ b/src/core/lib/iomgr/workqueue.h @@ -54,7 +54,7 @@ string will be printed alongside the refcount. When it is not defined, the string will be discarded at compilation time. */ -//#define GRPC_WORKQUEUE_REFCOUNT_DEBUG +#define GRPC_WORKQUEUE_REFCOUNT_DEBUG #ifdef GRPC_WORKQUEUE_REFCOUNT_DEBUG #define GRPC_WORKQUEUE_REF(p, r) \ grpc_workqueue_ref((p), __FILE__, __LINE__, (r)) -- cgit v1.2.3 From 1dc5dbb78628dc95c125fd46319930db52191ffc Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 9 Sep 2016 17:09:39 -0700 Subject: Fix refcount bug --- src/core/lib/iomgr/ev_epoll_linux.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/ev_epoll_linux.c b/src/core/lib/iomgr/ev_epoll_linux.c index 5a69c088cd..42c0ae2dcd 100644 --- a/src/core/lib/iomgr/ev_epoll_linux.c +++ b/src/core/lib/iomgr/ev_epoll_linux.c @@ -775,16 +775,21 @@ static polling_island *polling_island_merge(polling_island *p, static void workqueue_enqueue(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue, grpc_closure *closure, grpc_error *error) { - polling_island *pi = (polling_island *)workqueue; GPR_TIMER_BEGIN("workqueue.enqueue", 0); + /* take a ref to the workqueue: otherwise it can happen that whatever events + * this kicks off ends up destroying the workqueue before this function + * completes */ + GRPC_WORKQUEUE_REF(workqueue, "enqueue"); + polling_island *pi = (polling_island *)workqueue; gpr_atm last = gpr_atm_no_barrier_fetch_add(&pi->workqueue_item_count, 1); closure->error_data.error = error; gpr_mpscq_push(&pi->workqueue_items, &closure->next_data.atm_next); if (last == 0) { workqueue_maybe_wakeup(pi); } - GPR_TIMER_END("workqueue.enqueue", 0); workqueue_move_items_to_parent(pi); + GRPC_WORKQUEUE_UNREF(exec_ctx, workqueue, "enqueue"); + GPR_TIMER_END("workqueue.enqueue", 0); } static grpc_error *polling_island_global_init() { -- cgit v1.2.3 From 39cfffaed42c30270e8a492d58377416f6ac697d Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Sat, 10 Sep 2016 10:00:17 -0700 Subject: Disable debug --- src/core/lib/iomgr/workqueue.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/workqueue.h b/src/core/lib/iomgr/workqueue.h index 703ea7819e..5b96d1d851 100644 --- a/src/core/lib/iomgr/workqueue.h +++ b/src/core/lib/iomgr/workqueue.h @@ -54,7 +54,7 @@ string will be printed alongside the refcount. When it is not defined, the string will be discarded at compilation time. */ -#define GRPC_WORKQUEUE_REFCOUNT_DEBUG +/*#define GRPC_WORKQUEUE_REFCOUNT_DEBUG*/ #ifdef GRPC_WORKQUEUE_REFCOUNT_DEBUG #define GRPC_WORKQUEUE_REF(p, r) \ grpc_workqueue_ref((p), __FILE__, __LINE__, (r)) -- cgit v1.2.3 From df844f8a5cffafec36fb319c8f41bc11c9702a69 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Sun, 11 Sep 2016 15:42:17 -0700 Subject: Fix spam --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 3760c8ea56..ff883dbd76 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1422,7 +1422,6 @@ void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, GRPC_MDSTR_GRPC_MESSAGE, grpc_mdstr_from_slice(gpr_slice_ref(*slice)))); } - gpr_log(GPR_DEBUG, "published_metadata from fake"); s->published_metadata[1] = GRPC_METADATA_SYNTHESIZED_FROM_FAKE; grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s); } -- cgit v1.2.3 From fc2636d7a66cc39596dbaebb1813adc93191290d Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 12 Sep 2016 09:57:07 -0700 Subject: Fix resource leak --- .../transport/chttp2/transport/chttp2_transport.c | 32 ++++++++++++++-------- src/core/lib/iomgr/combiner.c | 23 ++++++++++++---- src/core/lib/iomgr/iomgr.c | 11 ++++++-- src/core/lib/support/log.c | 3 +- test/core/end2end/tests/payload.c | 6 ++-- 5 files changed, 50 insertions(+), 25 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index ff883dbd76..88ae81a35d 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -564,11 +564,11 @@ static const char *write_state_name(grpc_chttp2_write_state st) { } static void set_write_state(grpc_chttp2_transport *t, - grpc_chttp2_write_state st) { - GRPC_CHTTP2_IF_TRACING(gpr_log(GPR_DEBUG, "W:%p %s state %s -> %s", t, + grpc_chttp2_write_state st, const char *reason) { + GRPC_CHTTP2_IF_TRACING(gpr_log(GPR_DEBUG, "W:%p %s state %s -> %s [%s]", t, t->is_client ? "CLIENT" : "SERVER", write_state_name(t->write_state), - write_state_name(st))); + write_state_name(st), reason)); t->write_state = st; } @@ -579,7 +579,7 @@ void grpc_chttp2_initiate_write(grpc_exec_ctx *exec_ctx, switch (t->write_state) { case GRPC_CHTTP2_WRITE_STATE_IDLE: - set_write_state(t, GRPC_CHTTP2_WRITE_STATE_WRITING); + set_write_state(t, GRPC_CHTTP2_WRITE_STATE_WRITING, reason); GRPC_CHTTP2_REF_TRANSPORT(t, "writing"); grpc_combiner_execute_finally(exec_ctx, t->combiner, &t->write_action_begin_locked, @@ -590,12 +590,14 @@ void grpc_chttp2_initiate_write(grpc_exec_ctx *exec_ctx, t, covered_by_poller ? GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_AND_COVERED_BY_POLLER - : GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE); + : GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE, + reason); break; case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE: if (covered_by_poller) { set_write_state( - t, GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_AND_COVERED_BY_POLLER); + t, GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_AND_COVERED_BY_POLLER, + reason); } break; case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_AND_COVERED_BY_POLLER: @@ -620,10 +622,10 @@ static void write_action_begin_locked(grpc_exec_ctx *exec_ctx, void *gt, grpc_chttp2_transport *t = gt; GPR_ASSERT(t->write_state != GRPC_CHTTP2_WRITE_STATE_IDLE); if (!t->closed && grpc_chttp2_begin_write(exec_ctx, t)) { - set_write_state(t, GRPC_CHTTP2_WRITE_STATE_WRITING); + set_write_state(t, GRPC_CHTTP2_WRITE_STATE_WRITING, "begin writing"); grpc_exec_ctx_sched(exec_ctx, &t->write_action, GRPC_ERROR_NONE, NULL); } else { - set_write_state(t, GRPC_CHTTP2_WRITE_STATE_IDLE); + set_write_state(t, GRPC_CHTTP2_WRITE_STATE_IDLE, "begin writing nothing"); GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "writing"); } GPR_TIMER_END("write_action_begin_locked", 0); @@ -661,11 +663,12 @@ static void write_action_end_locked(grpc_exec_ctx *exec_ctx, void *tp, GPR_UNREACHABLE_CODE(break); case GRPC_CHTTP2_WRITE_STATE_WRITING: GPR_TIMER_MARK("state=writing", 0); - set_write_state(t, GRPC_CHTTP2_WRITE_STATE_IDLE); + set_write_state(t, GRPC_CHTTP2_WRITE_STATE_IDLE, "finish writing"); break; case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE: GPR_TIMER_MARK("state=writing_stale_no_poller", 0); - set_write_state(t, GRPC_CHTTP2_WRITE_STATE_WRITING); + set_write_state(t, GRPC_CHTTP2_WRITE_STATE_WRITING, + "continue writing [!covered]"); GRPC_CHTTP2_REF_TRANSPORT(t, "writing"); grpc_combiner_execute_finally(exec_ctx, t->combiner, &t->write_action_begin_locked, @@ -673,7 +676,8 @@ static void write_action_end_locked(grpc_exec_ctx *exec_ctx, void *tp, break; case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_AND_COVERED_BY_POLLER: GPR_TIMER_MARK("state=writing_stale_with_poller", 0); - set_write_state(t, GRPC_CHTTP2_WRITE_STATE_WRITING); + set_write_state(t, GRPC_CHTTP2_WRITE_STATE_WRITING, + "continue writing [covered]"); GRPC_CHTTP2_REF_TRANSPORT(t, "writing"); grpc_combiner_execute_finally(exec_ctx, t->combiner, &t->write_action_begin_locked, @@ -1887,13 +1891,17 @@ static void incoming_byte_stream_update_flow_control(grpc_exec_ctx *exec_ctx, max_recv_bytes += t->stream_lookahead; if (s->max_recv_bytes < max_recv_bytes) { uint32_t add_max_recv_bytes = max_recv_bytes - s->max_recv_bytes; + bool new_window_write_is_covered_by_poller = + s->max_recv_bytes < have_already; GRPC_CHTTP2_FLOW_CREDIT_STREAM("op", t, s, max_recv_bytes, add_max_recv_bytes); GRPC_CHTTP2_FLOW_CREDIT_STREAM("op", t, s, incoming_window, add_max_recv_bytes); GRPC_CHTTP2_FLOW_CREDIT_STREAM("op", t, s, announce_window, add_max_recv_bytes); - grpc_chttp2_become_writable(exec_ctx, t, s, true, "read_incoming_stream"); + grpc_chttp2_become_writable(exec_ctx, t, s, + new_window_write_is_covered_by_poller, + "read_incoming_stream"); } } diff --git a/src/core/lib/iomgr/combiner.c b/src/core/lib/iomgr/combiner.c index 2b68240a15..48806abc38 100644 --- a/src/core/lib/iomgr/combiner.c +++ b/src/core/lib/iomgr/combiner.c @@ -142,11 +142,11 @@ static void push_first_on_exec_ctx(grpc_exec_ctx *exec_ctx, void grpc_combiner_execute(grpc_exec_ctx *exec_ctx, grpc_combiner *lock, grpc_closure *cl, grpc_error *error, bool covered_by_poller) { - GRPC_COMBINER_TRACE(gpr_log(GPR_DEBUG, - "C:%p grpc_combiner_execute c=%p cov=%d", lock, - cl, covered_by_poller)); GPR_TIMER_BEGIN("combiner.execute", 0); gpr_atm last = gpr_atm_full_fetch_add(&lock->state, 2); + GRPC_COMBINER_TRACE(gpr_log( + GPR_DEBUG, "C:%p grpc_combiner_execute c=%p cov=%d last=%" PRIdPTR, lock, + cl, covered_by_poller, last)); GPR_ASSERT(last & 1); // ensure lock has not been destroyed cl->error_data.scratch = pack_error_data((error_data){error, covered_by_poller}); @@ -177,6 +177,8 @@ static void offload(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { static void queue_offload(grpc_exec_ctx *exec_ctx, grpc_combiner *lock) { move_next(exec_ctx); + GRPC_COMBINER_TRACE(gpr_log(GPR_DEBUG, "C:%p queue_offload --> %p", lock, + lock->optional_workqueue)); grpc_workqueue_enqueue(exec_ctx, lock->optional_workqueue, &lock->offload, GRPC_ERROR_NONE); } @@ -189,6 +191,15 @@ bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) { return false; } + GRPC_COMBINER_TRACE( + gpr_log(GPR_DEBUG, + "C:%p grpc_combiner_continue_exec_ctx workqueue=%p " + "is_covered_by_poller=%d exec_ctx_ready_to_finish=%d " + "time_to_execute_final_list=%d", + lock, lock->optional_workqueue, is_covered_by_poller(lock), + grpc_exec_ctx_ready_to_finish(exec_ctx), + lock->time_to_execute_final_list)); + if (lock->optional_workqueue != NULL && is_covered_by_poller(lock) && grpc_exec_ctx_ready_to_finish(exec_ctx)) { GPR_TIMER_MARK("offload_from_finished_exec_ctx", 0); @@ -289,9 +300,9 @@ static void enqueue_finally(grpc_exec_ctx *exec_ctx, void *closure, void grpc_combiner_execute_finally(grpc_exec_ctx *exec_ctx, grpc_combiner *lock, grpc_closure *closure, grpc_error *error, bool covered_by_poller) { - GRPC_COMBINER_TRACE(gpr_log(GPR_DEBUG, - "C:%p grpc_combiner_execute_finally c=%p; ac=%p", - lock, closure, exec_ctx->active_combiner)); + GRPC_COMBINER_TRACE(gpr_log( + GPR_DEBUG, "C:%p grpc_combiner_execute_finally c=%p; ac=%p; cov=%d", lock, + closure, exec_ctx->active_combiner, covered_by_poller)); GPR_TIMER_BEGIN("combiner.execute_finally", 0); if (exec_ctx->active_combiner != lock) { GPR_TIMER_MARK("slowpath", 0); diff --git a/src/core/lib/iomgr/iomgr.c b/src/core/lib/iomgr/iomgr.c index d67d388b8c..4fd83e0b22 100644 --- a/src/core/lib/iomgr/iomgr.c +++ b/src/core/lib/iomgr/iomgr.c @@ -112,6 +112,14 @@ void grpc_iomgr_shutdown(void) { continue; } if (g_root_object.next != &g_root_object) { + if (grpc_iomgr_abort_on_leaks()) { + gpr_log(GPR_DEBUG, "Failed to free %" PRIuPTR + " iomgr objects before shutdown deadline: " + "memory leaks are likely", + count_objects()); + dump_objects("LEAKED"); + abort(); + } gpr_timespec short_deadline = gpr_time_add( gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(100, GPR_TIMESPAN)); if (gpr_cv_wait(&g_rcv, &g_mu, short_deadline)) { @@ -122,9 +130,6 @@ void grpc_iomgr_shutdown(void) { "memory leaks are likely", count_objects()); dump_objects("LEAKED"); - if (grpc_iomgr_abort_on_leaks()) { - abort(); - } } break; } diff --git a/src/core/lib/support/log.c b/src/core/lib/support/log.c index 6fbd947f4b..af1651dae5 100644 --- a/src/core/lib/support/log.c +++ b/src/core/lib/support/log.c @@ -60,8 +60,9 @@ const char *gpr_log_severity_string(gpr_log_severity severity) { void gpr_log_message(const char *file, int line, gpr_log_severity severity, const char *message) { - if ((gpr_atm)severity < gpr_atm_no_barrier_load(&g_min_severity_to_print)) + if ((gpr_atm)severity < gpr_atm_no_barrier_load(&g_min_severity_to_print)) { return; + } gpr_log_func_args lfargs; memset(&lfargs, 0, sizeof(lfargs)); diff --git a/test/core/end2end/tests/payload.c b/test/core/end2end/tests/payload.c index c37d7fe41a..ed1c719ef8 100644 --- a/test/core/end2end/tests/payload.c +++ b/test/core/end2end/tests/payload.c @@ -99,11 +99,11 @@ static void end_test(grpc_end2end_test_fixture *f) { static gpr_slice generate_random_slice() { size_t i; static const char chars[] = "abcdefghijklmnopqrstuvwxyz1234567890"; - char output[1024 * 1024]; /* 1 MB */ - for (i = 0; i < 1024 * 1024 - 1; ++i) { + char output[1024 * 1024]; + for (i = 0; i < GPR_ARRAY_SIZE(output) - 1; ++i) { output[i] = chars[rand() % (int)(sizeof(chars) - 1)]; } - output[1024 * 1024 - 1] = '\0'; + output[GPR_ARRAY_SIZE(output) - 1] = '\0'; return gpr_slice_from_copied_string(output); } -- cgit v1.2.3 From 31caabdead52000354c4fdd88b68bb3041ca8c4a Mon Sep 17 00:00:00 2001 From: Ken Payson Date: Sat, 6 Aug 2016 21:27:29 -0700 Subject: Add shim to support condition variable wakeup fds where pipe/eventfd is not available --- BUILD | 12 + CMakeLists.txt | 5 + Makefile | 42 +++ binding.gyp | 1 + build.yaml | 16 + config.m4 | 1 + gRPC-Core.podspec | 3 + grpc.gemspec | 2 + package.xml | 2 + src/core/lib/iomgr/wakeup_fd_cv.c | 328 +++++++++++++++++++++ src/core/lib/iomgr/wakeup_fd_cv.h | 58 ++++ src/core/lib/iomgr/wakeup_fd_pipe.c | 9 +- src/core/lib/iomgr/wakeup_fd_posix.c | 15 +- src/core/lib/iomgr/wakeup_fd_posix.h | 1 + src/python/grpcio/grpc_core_dependencies.py | 1 + test/core/iomgr/wakeup_fd_cv_test.c | 246 ++++++++++++++++ tools/doxygen/Doxyfile.c++.internal | 2 + tools/doxygen/Doxyfile.core.internal | 2 + tools/run_tests/sources_and_headers.json | 19 ++ tools/run_tests/tests.json | 19 ++ vsprojects/vcxproj/grpc++/grpc++.vcxproj | 3 + vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters | 6 + .../grpc++_unsecure/grpc++_unsecure.vcxproj | 3 + .../grpc++_unsecure.vcxproj.filters | 6 + vsprojects/vcxproj/grpc/grpc.vcxproj | 3 + vsprojects/vcxproj/grpc/grpc.vcxproj.filters | 6 + .../vcxproj/grpc_test_util/grpc_test_util.vcxproj | 3 + .../grpc_test_util/grpc_test_util.vcxproj.filters | 6 + .../vcxproj/grpc_unsecure/grpc_unsecure.vcxproj | 3 + .../grpc_unsecure/grpc_unsecure.vcxproj.filters | 6 + 30 files changed, 825 insertions(+), 4 deletions(-) create mode 100644 src/core/lib/iomgr/wakeup_fd_cv.c create mode 100644 src/core/lib/iomgr/wakeup_fd_cv.h create mode 100644 test/core/iomgr/wakeup_fd_cv_test.c diff --git a/BUILD b/BUILD index ee41d1ab21..67e481e0d2 100644 --- a/BUILD +++ b/BUILD @@ -215,6 +215,7 @@ cc_library( "src/core/lib/iomgr/timer_heap.h", "src/core/lib/iomgr/udp_server.h", "src/core/lib/iomgr/unix_sockets_posix.h", + "src/core/lib/iomgr/wakeup_fd_cv.h", "src/core/lib/iomgr/wakeup_fd_pipe.h", "src/core/lib/iomgr/wakeup_fd_posix.h", "src/core/lib/iomgr/workqueue.h", @@ -372,6 +373,7 @@ cc_library( "src/core/lib/iomgr/udp_server.c", "src/core/lib/iomgr/unix_sockets_posix.c", "src/core/lib/iomgr/unix_sockets_posix_noop.c", + "src/core/lib/iomgr/wakeup_fd_cv.c", "src/core/lib/iomgr/wakeup_fd_eventfd.c", "src/core/lib/iomgr/wakeup_fd_nospecial.c", "src/core/lib/iomgr/wakeup_fd_pipe.c", @@ -610,6 +612,7 @@ cc_library( "src/core/lib/iomgr/timer_heap.h", "src/core/lib/iomgr/udp_server.h", "src/core/lib/iomgr/unix_sockets_posix.h", + "src/core/lib/iomgr/wakeup_fd_cv.h", "src/core/lib/iomgr/wakeup_fd_pipe.h", "src/core/lib/iomgr/wakeup_fd_posix.h", "src/core/lib/iomgr/workqueue.h", @@ -753,6 +756,7 @@ cc_library( "src/core/lib/iomgr/udp_server.c", "src/core/lib/iomgr/unix_sockets_posix.c", "src/core/lib/iomgr/unix_sockets_posix_noop.c", + "src/core/lib/iomgr/wakeup_fd_cv.c", "src/core/lib/iomgr/wakeup_fd_eventfd.c", "src/core/lib/iomgr/wakeup_fd_nospecial.c", "src/core/lib/iomgr/wakeup_fd_pipe.c", @@ -962,6 +966,7 @@ cc_library( "src/core/lib/iomgr/timer_heap.h", "src/core/lib/iomgr/udp_server.h", "src/core/lib/iomgr/unix_sockets_posix.h", + "src/core/lib/iomgr/wakeup_fd_cv.h", "src/core/lib/iomgr/wakeup_fd_pipe.h", "src/core/lib/iomgr/wakeup_fd_posix.h", "src/core/lib/iomgr/workqueue.h", @@ -1096,6 +1101,7 @@ cc_library( "src/core/lib/iomgr/udp_server.c", "src/core/lib/iomgr/unix_sockets_posix.c", "src/core/lib/iomgr/unix_sockets_posix_noop.c", + "src/core/lib/iomgr/wakeup_fd_cv.c", "src/core/lib/iomgr/wakeup_fd_eventfd.c", "src/core/lib/iomgr/wakeup_fd_nospecial.c", "src/core/lib/iomgr/wakeup_fd_pipe.c", @@ -1309,6 +1315,7 @@ cc_library( "src/core/lib/iomgr/timer_heap.h", "src/core/lib/iomgr/udp_server.h", "src/core/lib/iomgr/unix_sockets_posix.h", + "src/core/lib/iomgr/wakeup_fd_cv.h", "src/core/lib/iomgr/wakeup_fd_pipe.h", "src/core/lib/iomgr/wakeup_fd_posix.h", "src/core/lib/iomgr/workqueue.h", @@ -1423,6 +1430,7 @@ cc_library( "src/core/lib/iomgr/udp_server.c", "src/core/lib/iomgr/unix_sockets_posix.c", "src/core/lib/iomgr/unix_sockets_posix_noop.c", + "src/core/lib/iomgr/wakeup_fd_cv.c", "src/core/lib/iomgr/wakeup_fd_eventfd.c", "src/core/lib/iomgr/wakeup_fd_nospecial.c", "src/core/lib/iomgr/wakeup_fd_pipe.c", @@ -1719,6 +1727,7 @@ cc_library( "src/core/lib/iomgr/timer_heap.h", "src/core/lib/iomgr/udp_server.h", "src/core/lib/iomgr/unix_sockets_posix.h", + "src/core/lib/iomgr/wakeup_fd_cv.h", "src/core/lib/iomgr/wakeup_fd_pipe.h", "src/core/lib/iomgr/wakeup_fd_posix.h", "src/core/lib/iomgr/workqueue.h", @@ -1828,6 +1837,7 @@ cc_library( "src/core/lib/iomgr/udp_server.c", "src/core/lib/iomgr/unix_sockets_posix.c", "src/core/lib/iomgr/unix_sockets_posix_noop.c", + "src/core/lib/iomgr/wakeup_fd_cv.c", "src/core/lib/iomgr/wakeup_fd_eventfd.c", "src/core/lib/iomgr/wakeup_fd_nospecial.c", "src/core/lib/iomgr/wakeup_fd_pipe.c", @@ -2218,6 +2228,7 @@ objc_library( "src/core/lib/iomgr/udp_server.c", "src/core/lib/iomgr/unix_sockets_posix.c", "src/core/lib/iomgr/unix_sockets_posix_noop.c", + "src/core/lib/iomgr/wakeup_fd_cv.c", "src/core/lib/iomgr/wakeup_fd_eventfd.c", "src/core/lib/iomgr/wakeup_fd_nospecial.c", "src/core/lib/iomgr/wakeup_fd_pipe.c", @@ -2435,6 +2446,7 @@ objc_library( "src/core/lib/iomgr/timer_heap.h", "src/core/lib/iomgr/udp_server.h", "src/core/lib/iomgr/unix_sockets_posix.h", + "src/core/lib/iomgr/wakeup_fd_cv.h", "src/core/lib/iomgr/wakeup_fd_pipe.h", "src/core/lib/iomgr/wakeup_fd_posix.h", "src/core/lib/iomgr/workqueue.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 05aa323ca9..f07fa26e63 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -345,6 +345,7 @@ add_library(grpc src/core/lib/iomgr/udp_server.c src/core/lib/iomgr/unix_sockets_posix.c src/core/lib/iomgr/unix_sockets_posix_noop.c + src/core/lib/iomgr/wakeup_fd_cv.c src/core/lib/iomgr/wakeup_fd_eventfd.c src/core/lib/iomgr/wakeup_fd_nospecial.c src/core/lib/iomgr/wakeup_fd_pipe.c @@ -603,6 +604,7 @@ add_library(grpc_cronet src/core/lib/iomgr/udp_server.c src/core/lib/iomgr/unix_sockets_posix.c src/core/lib/iomgr/unix_sockets_posix_noop.c + src/core/lib/iomgr/wakeup_fd_cv.c src/core/lib/iomgr/wakeup_fd_eventfd.c src/core/lib/iomgr/wakeup_fd_nospecial.c src/core/lib/iomgr/wakeup_fd_pipe.c @@ -834,6 +836,7 @@ add_library(grpc_unsecure src/core/lib/iomgr/udp_server.c src/core/lib/iomgr/unix_sockets_posix.c src/core/lib/iomgr/unix_sockets_posix_noop.c + src/core/lib/iomgr/wakeup_fd_cv.c src/core/lib/iomgr/wakeup_fd_eventfd.c src/core/lib/iomgr/wakeup_fd_nospecial.c src/core/lib/iomgr/wakeup_fd_pipe.c @@ -1091,6 +1094,7 @@ add_library(grpc++ src/core/lib/iomgr/udp_server.c src/core/lib/iomgr/unix_sockets_posix.c src/core/lib/iomgr/unix_sockets_posix_noop.c + src/core/lib/iomgr/wakeup_fd_cv.c src/core/lib/iomgr/wakeup_fd_eventfd.c src/core/lib/iomgr/wakeup_fd_nospecial.c src/core/lib/iomgr/wakeup_fd_pipe.c @@ -1448,6 +1452,7 @@ add_library(grpc++_unsecure src/core/lib/iomgr/udp_server.c src/core/lib/iomgr/unix_sockets_posix.c src/core/lib/iomgr/unix_sockets_posix_noop.c + src/core/lib/iomgr/wakeup_fd_cv.c src/core/lib/iomgr/wakeup_fd_eventfd.c src/core/lib/iomgr/wakeup_fd_nospecial.c src/core/lib/iomgr/wakeup_fd_pipe.c diff --git a/Makefile b/Makefile index e454ad6cd7..a23e12687d 100644 --- a/Makefile +++ b/Makefile @@ -1021,6 +1021,7 @@ transport_security_test: $(BINDIR)/$(CONFIG)/transport_security_test udp_server_test: $(BINDIR)/$(CONFIG)/udp_server_test uri_fuzzer_test: $(BINDIR)/$(CONFIG)/uri_fuzzer_test uri_parser_test: $(BINDIR)/$(CONFIG)/uri_parser_test +wakeup_fd_cv_test: $(BINDIR)/$(CONFIG)/wakeup_fd_cv_test alarm_cpp_test: $(BINDIR)/$(CONFIG)/alarm_cpp_test async_end2end_test: $(BINDIR)/$(CONFIG)/async_end2end_test auth_property_iterator_test: $(BINDIR)/$(CONFIG)/auth_property_iterator_test @@ -1329,6 +1330,7 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/transport_security_test \ $(BINDIR)/$(CONFIG)/udp_server_test \ $(BINDIR)/$(CONFIG)/uri_parser_test \ + $(BINDIR)/$(CONFIG)/wakeup_fd_cv_test \ $(BINDIR)/$(CONFIG)/public_headers_must_be_c89 \ $(BINDIR)/$(CONFIG)/badreq_bad_client_test \ $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test \ @@ -1717,6 +1719,8 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/udp_server_test || ( echo test udp_server_test failed ; exit 1 ) $(E) "[RUN] Testing uri_parser_test" $(Q) $(BINDIR)/$(CONFIG)/uri_parser_test || ( echo test uri_parser_test failed ; exit 1 ) + $(E) "[RUN] Testing wakeup_fd_cv_test" + $(Q) $(BINDIR)/$(CONFIG)/wakeup_fd_cv_test || ( echo test wakeup_fd_cv_test failed ; exit 1 ) $(E) "[RUN] Testing public_headers_must_be_c89" $(Q) $(BINDIR)/$(CONFIG)/public_headers_must_be_c89 || ( echo test public_headers_must_be_c89 failed ; exit 1 ) $(E) "[RUN] Testing badreq_bad_client_test" @@ -2566,6 +2570,7 @@ LIBGRPC_SRC = \ src/core/lib/iomgr/udp_server.c \ src/core/lib/iomgr/unix_sockets_posix.c \ src/core/lib/iomgr/unix_sockets_posix_noop.c \ + src/core/lib/iomgr/wakeup_fd_cv.c \ src/core/lib/iomgr/wakeup_fd_eventfd.c \ src/core/lib/iomgr/wakeup_fd_nospecial.c \ src/core/lib/iomgr/wakeup_fd_pipe.c \ @@ -2842,6 +2847,7 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/iomgr/udp_server.c \ src/core/lib/iomgr/unix_sockets_posix.c \ src/core/lib/iomgr/unix_sockets_posix_noop.c \ + src/core/lib/iomgr/wakeup_fd_cv.c \ src/core/lib/iomgr/wakeup_fd_eventfd.c \ src/core/lib/iomgr/wakeup_fd_nospecial.c \ src/core/lib/iomgr/wakeup_fd_pipe.c \ @@ -3107,6 +3113,7 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/lib/iomgr/udp_server.c \ src/core/lib/iomgr/unix_sockets_posix.c \ src/core/lib/iomgr/unix_sockets_posix_noop.c \ + src/core/lib/iomgr/wakeup_fd_cv.c \ src/core/lib/iomgr/wakeup_fd_eventfd.c \ src/core/lib/iomgr/wakeup_fd_nospecial.c \ src/core/lib/iomgr/wakeup_fd_pipe.c \ @@ -3300,6 +3307,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/iomgr/udp_server.c \ src/core/lib/iomgr/unix_sockets_posix.c \ src/core/lib/iomgr/unix_sockets_posix_noop.c \ + src/core/lib/iomgr/wakeup_fd_cv.c \ src/core/lib/iomgr/wakeup_fd_eventfd.c \ src/core/lib/iomgr/wakeup_fd_nospecial.c \ src/core/lib/iomgr/wakeup_fd_pipe.c \ @@ -3640,6 +3648,7 @@ LIBGRPC++_SRC = \ src/core/lib/iomgr/udp_server.c \ src/core/lib/iomgr/unix_sockets_posix.c \ src/core/lib/iomgr/unix_sockets_posix_noop.c \ + src/core/lib/iomgr/wakeup_fd_cv.c \ src/core/lib/iomgr/wakeup_fd_eventfd.c \ src/core/lib/iomgr/wakeup_fd_nospecial.c \ src/core/lib/iomgr/wakeup_fd_pipe.c \ @@ -4275,6 +4284,7 @@ LIBGRPC++_UNSECURE_SRC = \ src/core/lib/iomgr/udp_server.c \ src/core/lib/iomgr/unix_sockets_posix.c \ src/core/lib/iomgr/unix_sockets_posix_noop.c \ + src/core/lib/iomgr/wakeup_fd_cv.c \ src/core/lib/iomgr/wakeup_fd_eventfd.c \ src/core/lib/iomgr/wakeup_fd_nospecial.c \ src/core/lib/iomgr/wakeup_fd_pipe.c \ @@ -10805,6 +10815,38 @@ endif endif +WAKEUP_FD_CV_TEST_SRC = \ + test/core/iomgr/wakeup_fd_cv_test.c \ + +WAKEUP_FD_CV_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(WAKEUP_FD_CV_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/wakeup_fd_cv_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/wakeup_fd_cv_test: $(WAKEUP_FD_CV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LD) $(LDFLAGS) $(WAKEUP_FD_CV_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)/wakeup_fd_cv_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/iomgr/wakeup_fd_cv_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_wakeup_fd_cv_test: $(WAKEUP_FD_CV_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(WAKEUP_FD_CV_TEST_OBJS:.o=.dep) +endif +endif + + ALARM_CPP_TEST_SRC = \ test/cpp/common/alarm_cpp_test.cc \ diff --git a/binding.gyp b/binding.gyp index 7cc8a58c01..1b68b63d22 100644 --- a/binding.gyp +++ b/binding.gyp @@ -617,6 +617,7 @@ 'src/core/lib/iomgr/udp_server.c', 'src/core/lib/iomgr/unix_sockets_posix.c', 'src/core/lib/iomgr/unix_sockets_posix_noop.c', + 'src/core/lib/iomgr/wakeup_fd_cv.c', 'src/core/lib/iomgr/wakeup_fd_eventfd.c', 'src/core/lib/iomgr/wakeup_fd_nospecial.c', 'src/core/lib/iomgr/wakeup_fd_pipe.c', diff --git a/build.yaml b/build.yaml index 6eb23d6fb7..d4f731e85f 100644 --- a/build.yaml +++ b/build.yaml @@ -217,6 +217,7 @@ filegroups: - src/core/lib/iomgr/timer_heap.h - src/core/lib/iomgr/udp_server.h - src/core/lib/iomgr/unix_sockets_posix.h + - src/core/lib/iomgr/wakeup_fd_cv.h - src/core/lib/iomgr/wakeup_fd_pipe.h - src/core/lib/iomgr/wakeup_fd_posix.h - src/core/lib/iomgr/workqueue.h @@ -299,6 +300,7 @@ filegroups: - src/core/lib/iomgr/udp_server.c - src/core/lib/iomgr/unix_sockets_posix.c - src/core/lib/iomgr/unix_sockets_posix_noop.c + - src/core/lib/iomgr/wakeup_fd_cv.c - src/core/lib/iomgr/wakeup_fd_eventfd.c - src/core/lib/iomgr/wakeup_fd_nospecial.c - src/core/lib/iomgr/wakeup_fd_pipe.c @@ -2535,6 +2537,20 @@ targets: - grpc - gpr_test_util - gpr +- name: wakeup_fd_cv_test + build: test + language: c + src: + - test/core/iomgr/wakeup_fd_cv_test.c + deps: + - grpc_test_util + - grpc + - gpr_test_util + - gpr + platforms: + - mac + - linux + - posix - name: alarm_cpp_test gtest: true build: test diff --git a/config.m4 b/config.m4 index 5384585dd6..6b605fbcd6 100644 --- a/config.m4 +++ b/config.m4 @@ -136,6 +136,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/iomgr/udp_server.c \ src/core/lib/iomgr/unix_sockets_posix.c \ src/core/lib/iomgr/unix_sockets_posix_noop.c \ + src/core/lib/iomgr/wakeup_fd_cv.c \ src/core/lib/iomgr/wakeup_fd_eventfd.c \ src/core/lib/iomgr/wakeup_fd_nospecial.c \ src/core/lib/iomgr/wakeup_fd_pipe.c \ diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index deffa1653e..92b3022cf7 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -306,6 +306,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/timer_heap.h', 'src/core/lib/iomgr/udp_server.h', 'src/core/lib/iomgr/unix_sockets_posix.h', + 'src/core/lib/iomgr/wakeup_fd_cv.h', 'src/core/lib/iomgr/wakeup_fd_pipe.h', 'src/core/lib/iomgr/wakeup_fd_posix.h', 'src/core/lib/iomgr/workqueue.h', @@ -467,6 +468,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/udp_server.c', 'src/core/lib/iomgr/unix_sockets_posix.c', 'src/core/lib/iomgr/unix_sockets_posix_noop.c', + 'src/core/lib/iomgr/wakeup_fd_cv.c', 'src/core/lib/iomgr/wakeup_fd_eventfd.c', 'src/core/lib/iomgr/wakeup_fd_nospecial.c', 'src/core/lib/iomgr/wakeup_fd_pipe.c', @@ -668,6 +670,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/timer_heap.h', 'src/core/lib/iomgr/udp_server.h', 'src/core/lib/iomgr/unix_sockets_posix.h', + 'src/core/lib/iomgr/wakeup_fd_cv.h', 'src/core/lib/iomgr/wakeup_fd_pipe.h', 'src/core/lib/iomgr/wakeup_fd_posix.h', 'src/core/lib/iomgr/workqueue.h', diff --git a/grpc.gemspec b/grpc.gemspec index f249006065..d672bb1284 100755 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -226,6 +226,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/timer_heap.h ) s.files += %w( src/core/lib/iomgr/udp_server.h ) s.files += %w( src/core/lib/iomgr/unix_sockets_posix.h ) + s.files += %w( src/core/lib/iomgr/wakeup_fd_cv.h ) s.files += %w( src/core/lib/iomgr/wakeup_fd_pipe.h ) s.files += %w( src/core/lib/iomgr/wakeup_fd_posix.h ) s.files += %w( src/core/lib/iomgr/workqueue.h ) @@ -387,6 +388,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/udp_server.c ) s.files += %w( src/core/lib/iomgr/unix_sockets_posix.c ) s.files += %w( src/core/lib/iomgr/unix_sockets_posix_noop.c ) + s.files += %w( src/core/lib/iomgr/wakeup_fd_cv.c ) s.files += %w( src/core/lib/iomgr/wakeup_fd_eventfd.c ) s.files += %w( src/core/lib/iomgr/wakeup_fd_nospecial.c ) s.files += %w( src/core/lib/iomgr/wakeup_fd_pipe.c ) diff --git a/package.xml b/package.xml index 93210ee47b..02cc271fe5 100644 --- a/package.xml +++ b/package.xml @@ -233,6 +233,7 @@ + @@ -394,6 +395,7 @@ + diff --git a/src/core/lib/iomgr/wakeup_fd_cv.c b/src/core/lib/iomgr/wakeup_fd_cv.c new file mode 100644 index 0000000000..bfdc2cb422 --- /dev/null +++ b/src/core/lib/iomgr/wakeup_fd_cv.c @@ -0,0 +1,328 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include + +#ifdef GPR_POSIX_WAKEUP_FD + +#include "src/core/lib/iomgr/wakeup_fd_posix.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "src/core/lib/iomgr/ev_posix.h" + +#define MAX_TABLE_RESIZE 256 +#define DEFAULT_TABLE_SIZE 16 +#define POLL_PERIOD_MS 1000 + +#define FD_TO_IDX(fd) (-(fd)-1) +#define IDX_TO_FD(idx) (-(idx)-1) + +typedef struct cv_node { + gpr_cv* cv; + struct cv_node* next; +} cv_node; + +typedef struct fd_node { + int is_set; + cv_node* cvs; + struct fd_node* next_free; +} fd_node; + +typedef struct cv_fd_table { + fd_node* cvfds; + fd_node* free_fds; + unsigned int size; + grpc_poll_function_type poll; +} cv_fd_table; + +typedef struct poll_result { + struct pollfd* fds; + gpr_cv* cv; + int completed; + int res; + int err; +} poll_result; + +typedef struct poll_args { + struct pollfd* fds; + nfds_t nfds; + int timeout; + poll_result* result; +} poll_args; + +static gpr_mu g_mu = PTHREAD_MUTEX_INITIALIZER; +static cv_fd_table g_cvfds; + +// Some environments do not implement pthread_cancel(), so we run +// this poll in a detached thread, and wake up periodically and +// check if the calling thread is still waiting on a result +static void run_poll(void* arg) { + int result, timeout; + poll_args* pargs = (poll_args*)arg; + gpr_mu_lock(&g_mu); + if (pargs->result != NULL) { + while (pargs->result != NULL) { + if (pargs->timeout < 0) { + timeout = POLL_PERIOD_MS; + } else { + timeout = GPR_MIN(POLL_PERIOD_MS, pargs->timeout); + pargs->timeout -= timeout; + } + gpr_mu_unlock(&g_mu); + result = g_cvfds.poll(pargs->fds, pargs->nfds, timeout); + gpr_mu_lock(&g_mu); + if (pargs->result != NULL) { + if (result != 0 || pargs->timeout == 0) { + memcpy(pargs->result->fds, pargs->fds, + sizeof(struct pollfd) * pargs->nfds); + pargs->result->res = result; + pargs->result->err = errno; + pargs->result->completed = 1; + gpr_cv_signal(pargs->result->cv); + break; + } + } + } + } + gpr_free(pargs->fds); + gpr_free(pargs); + gpr_mu_unlock(&g_mu); +} + +int cvfd_poll(struct pollfd* fds, nfds_t nfds, int timeout) { + unsigned int i; + int res, idx; + cv_node *cvn, *prev; + struct pollfd* sockfds; + nfds_t nsockfds = 0; + gpr_cv pollcv; + gpr_thd_id t_id; + gpr_thd_options opt; + poll_args* pargs; + poll_result* pres; + gpr_mu_lock(&g_mu); + gpr_cv_init(&pollcv); + for (i = 0; i < nfds; i++) { + fds[i].revents = 0; + if (fds[i].fd < 0 && (fds[i].events & POLLIN)) { + idx = FD_TO_IDX(fds[i].fd); + cvn = gpr_malloc(sizeof(cv_node)); + cvn->cv = &pollcv; + cvn->next = g_cvfds.cvfds[idx].cvs; + g_cvfds.cvfds[idx].cvs = cvn; + // We should return immediately if there are pending events, + // but we still need to call poll() to check for socket events + if (g_cvfds.cvfds[idx].is_set) { + timeout = 0; + } + } else if (fds[i].fd >= 0) { + nsockfds++; + } + } + sockfds = gpr_malloc(sizeof(struct pollfd) * nsockfds); + idx = 0; + for (i = 0; i < nfds; i++) { + if (fds[i].fd >= 0) { + sockfds[idx].fd = fds[i].fd; + sockfds[idx].events = fds[i].events; + sockfds[idx].revents = 0; + idx++; + } + } + + errno = 0; + if (nsockfds > 0) { + pres = gpr_malloc(sizeof(struct poll_result)); + pargs = gpr_malloc(sizeof(struct poll_args)); + + pargs->fds = gpr_malloc(sizeof(struct pollfd) * nsockfds); + memcpy(pargs->fds, sockfds, sizeof(struct pollfd) * nsockfds); + pargs->nfds = nsockfds; + pargs->timeout = timeout; + pargs->result = pres; + + pres->fds = sockfds; + pres->cv = &pollcv; + pres->completed = 0; + pres->res = 0; + pres->err = 0; + + opt = gpr_thd_options_default(); + gpr_thd_options_set_detached(&opt); + gpr_thd_new(&t_id, &run_poll, pargs, &opt); + // We want the poll() thread to trigger the deadline, so wait forever here + gpr_cv_wait(&pollcv, &g_mu, gpr_inf_future(GPR_CLOCK_MONOTONIC)); + if (!pres->completed) { + pargs->result = NULL; + } + res = pres->res; + errno = pres->err; + gpr_free(pres); + } else { + gpr_timespec deadline = gpr_now(GPR_CLOCK_REALTIME); + deadline = + gpr_time_add(deadline, gpr_time_from_millis(timeout, GPR_TIMESPAN)); + gpr_cv_wait(&pollcv, &g_mu, deadline); + res = 0; + } + idx = 0; + for (i = 0; i < nfds; i++) { + if (fds[i].fd < 0 && (fds[i].events & POLLIN)) { + cvn = g_cvfds.cvfds[FD_TO_IDX(fds[i].fd)].cvs; + prev = NULL; + while (cvn->cv != &pollcv) { + prev = cvn; + cvn = cvn->next; + GPR_ASSERT(cvn); + } + if (!prev) { + g_cvfds.cvfds[FD_TO_IDX(fds[i].fd)].cvs = cvn->next; + } else { + prev->next = cvn->next; + } + gpr_free(cvn); + + if (g_cvfds.cvfds[FD_TO_IDX(fds[i].fd)].is_set) { + fds[i].revents = POLLIN; + if (res >= 0) res++; + } + } else if (fds[i].fd >= 0) { + fds[i].revents = sockfds[idx].revents; + idx++; + } + } + gpr_free(sockfds); + gpr_cv_destroy(&pollcv); + gpr_mu_unlock(&g_mu); + + return res; +} + +static grpc_error* cv_fd_init(grpc_wakeup_fd* fd_info) { + unsigned int i, newsize; + int idx; + gpr_mu_lock(&g_mu); + if (!g_cvfds.free_fds) { + newsize = GPR_MIN(g_cvfds.size * 2, g_cvfds.size + MAX_TABLE_RESIZE); + g_cvfds.cvfds = gpr_realloc(g_cvfds.cvfds, sizeof(fd_node) * newsize); + for (i = g_cvfds.size; i < newsize; i++) { + g_cvfds.cvfds[i].is_set = 0; + g_cvfds.cvfds[i].cvs = NULL; + g_cvfds.cvfds[i].next_free = g_cvfds.free_fds; + g_cvfds.free_fds = &g_cvfds.cvfds[i]; + } + g_cvfds.size = newsize; + } + + idx = (int)(g_cvfds.free_fds - g_cvfds.cvfds); + g_cvfds.free_fds = g_cvfds.free_fds->next_free; + g_cvfds.cvfds[idx].cvs = NULL; + g_cvfds.cvfds[idx].is_set = 0; + fd_info->read_fd = IDX_TO_FD(idx); + fd_info->write_fd = -1; + gpr_mu_unlock(&g_mu); + return GRPC_ERROR_NONE; +} + +void grpc_global_cv_fd_table_init() { + gpr_mu_lock(&g_mu); + g_cvfds.size = DEFAULT_TABLE_SIZE; + g_cvfds.cvfds = gpr_malloc(sizeof(fd_node) * DEFAULT_TABLE_SIZE); + g_cvfds.free_fds = NULL; + for (int i = 0; i < DEFAULT_TABLE_SIZE; i++) { + g_cvfds.cvfds[i].is_set = 0; + g_cvfds.cvfds[i].cvs = NULL; + g_cvfds.cvfds[i].next_free = g_cvfds.free_fds; + g_cvfds.free_fds = &g_cvfds.cvfds[i]; + } + // Override the poll function with one that supports cvfds + g_cvfds.poll = grpc_poll_function; + grpc_poll_function = &cvfd_poll; + gpr_mu_unlock(&g_mu); +} + +void grpc_global_cv_fd_table_shutdown() { + gpr_mu_lock(&g_mu); + grpc_poll_function = g_cvfds.poll; + gpr_free(g_cvfds.cvfds); + gpr_mu_unlock(&g_mu); +} + +static grpc_error* cv_fd_wakeup(grpc_wakeup_fd* fd_info) { + cv_node* cvn; + gpr_mu_lock(&g_mu); + g_cvfds.cvfds[FD_TO_IDX(fd_info->read_fd)].is_set = 1; + cvn = g_cvfds.cvfds[FD_TO_IDX(fd_info->read_fd)].cvs; + while (cvn) { + gpr_cv_signal(cvn->cv); + cvn = cvn->next; + } + gpr_mu_unlock(&g_mu); + return GRPC_ERROR_NONE; +} + +static grpc_error* cv_fd_consume(grpc_wakeup_fd* fd_info) { + gpr_mu_lock(&g_mu); + g_cvfds.cvfds[FD_TO_IDX(fd_info->read_fd)].is_set = 0; + gpr_mu_unlock(&g_mu); + return GRPC_ERROR_NONE; +} + +static void cv_fd_destroy(grpc_wakeup_fd* fd_info) { + if (fd_info->read_fd == 0) { + return; + } + gpr_mu_lock(&g_mu); + // Assert that there are no active pollers + GPR_ASSERT(!g_cvfds.cvfds[FD_TO_IDX(fd_info->read_fd)].cvs); + g_cvfds.cvfds[FD_TO_IDX(fd_info->read_fd)].next_free = g_cvfds.free_fds; + g_cvfds.free_fds = &g_cvfds.cvfds[FD_TO_IDX(fd_info->read_fd)]; + gpr_mu_unlock(&g_mu); +} + +static int cv_check_availability(void) { return 1; } + +const grpc_wakeup_fd_vtable grpc_cv_wakeup_fd_vtable = { + cv_fd_init, cv_fd_consume, cv_fd_wakeup, cv_fd_destroy, + cv_check_availability}; + +#endif /* GPR_POSIX_WAKUP_FD */ diff --git a/src/core/lib/iomgr/wakeup_fd_cv.h b/src/core/lib/iomgr/wakeup_fd_cv.h new file mode 100644 index 0000000000..22ee6c0bbe --- /dev/null +++ b/src/core/lib/iomgr/wakeup_fd_cv.h @@ -0,0 +1,58 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* + * wakeup_fd_cv uses condition variables to implement wakeup fds. + * + * It is intended for use only in cases when eventfd() and pipe() are not + * available. It can only be used with the "poll" engine. + * + * Implementation: + * A global table of cv wakeup fds is mantained. A cv wakeup fd is a negative + * file descriptor. poll() is then run in a background thread with only the + * real socket fds while we wait on a condition variable trigged by either the + * poll() called or a wakeup_fd() call. + * + */ + +#ifndef GRPC_CORE_LIB_IOMGR_WAKEUP_FD_CV_H +#define GRPC_CORE_LIB_IOMGR_WAKEUP_FD_CV_H + +#include "src/core/lib/iomgr/wakeup_fd_posix.h" + +void grpc_global_cv_fd_table_init(); +void grpc_global_cv_fd_table_shutdown(); + +extern grpc_wakeup_fd_vtable grpc_cv_wakeup_fd_vtable; + +#endif /* GRPC_CORE_LIB_IOMGR_WAKEUP_FD_CV_H */ diff --git a/src/core/lib/iomgr/wakeup_fd_pipe.c b/src/core/lib/iomgr/wakeup_fd_pipe.c index 4e5dbdcb73..3dc94c94ba 100644 --- a/src/core/lib/iomgr/wakeup_fd_pipe.c +++ b/src/core/lib/iomgr/wakeup_fd_pipe.c @@ -95,8 +95,13 @@ static void pipe_destroy(grpc_wakeup_fd* fd_info) { } static int pipe_check_availability(void) { - /* Assume that pipes are always available. */ - return 1; + grpc_wakeup_fd fd; + if (pipe_init(&fd) == GRPC_ERROR_NONE) { + pipe_destroy(&fd); + return 1; + } else { + return 0; + } } const grpc_wakeup_fd_vtable grpc_pipe_wakeup_fd_vtable = { diff --git a/src/core/lib/iomgr/wakeup_fd_posix.c b/src/core/lib/iomgr/wakeup_fd_posix.c index 046208abc8..564b836154 100644 --- a/src/core/lib/iomgr/wakeup_fd_posix.c +++ b/src/core/lib/iomgr/wakeup_fd_posix.c @@ -36,22 +36,33 @@ #ifdef GPR_POSIX_WAKEUP_FD #include +#include "src/core/lib/iomgr/wakeup_fd_cv.h" #include "src/core/lib/iomgr/wakeup_fd_pipe.h" #include "src/core/lib/iomgr/wakeup_fd_posix.h" static const grpc_wakeup_fd_vtable *wakeup_fd_vtable = NULL; int grpc_allow_specialized_wakeup_fd = 1; +int grpc_allow_pipe_wakeup_fd = 1; void grpc_wakeup_fd_global_init(void) { if (grpc_allow_specialized_wakeup_fd && grpc_specialized_wakeup_fd_vtable.check_availability()) { wakeup_fd_vtable = &grpc_specialized_wakeup_fd_vtable; - } else { + } else if (grpc_allow_pipe_wakeup_fd && + grpc_pipe_wakeup_fd_vtable.check_availability()) { wakeup_fd_vtable = &grpc_pipe_wakeup_fd_vtable; + } else { + wakeup_fd_vtable = &grpc_cv_wakeup_fd_vtable; + grpc_global_cv_fd_table_init(); } } -void grpc_wakeup_fd_global_destroy(void) { wakeup_fd_vtable = NULL; } +void grpc_wakeup_fd_global_destroy(void) { + if (wakeup_fd_vtable == &grpc_cv_wakeup_fd_vtable) { + grpc_global_cv_fd_table_shutdown(); + } + wakeup_fd_vtable = NULL; +} grpc_error *grpc_wakeup_fd_init(grpc_wakeup_fd *fd_info) { return wakeup_fd_vtable->init(fd_info); diff --git a/src/core/lib/iomgr/wakeup_fd_posix.h b/src/core/lib/iomgr/wakeup_fd_posix.h index e269f242d8..a9f902bc9f 100644 --- a/src/core/lib/iomgr/wakeup_fd_posix.h +++ b/src/core/lib/iomgr/wakeup_fd_posix.h @@ -88,6 +88,7 @@ struct grpc_wakeup_fd { }; extern int grpc_allow_specialized_wakeup_fd; +extern int grpc_allow_pipe_wakeup_fd; #define GRPC_WAKEUP_FD_GET_READ_FD(fd_info) ((fd_info)->read_fd) diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index be7f30c29b..dc2ce46979 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -130,6 +130,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/iomgr/udp_server.c', 'src/core/lib/iomgr/unix_sockets_posix.c', 'src/core/lib/iomgr/unix_sockets_posix_noop.c', + 'src/core/lib/iomgr/wakeup_fd_cv.c', 'src/core/lib/iomgr/wakeup_fd_eventfd.c', 'src/core/lib/iomgr/wakeup_fd_nospecial.c', 'src/core/lib/iomgr/wakeup_fd_pipe.c', diff --git a/test/core/iomgr/wakeup_fd_cv_test.c b/test/core/iomgr/wakeup_fd_cv_test.c new file mode 100644 index 0000000000..2cd777536d --- /dev/null +++ b/test/core/iomgr/wakeup_fd_cv_test.c @@ -0,0 +1,246 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include + +#include +#include +#include +#include + +#include "src/core/lib/iomgr/ev_posix.h" +#include "src/core/lib/iomgr/wakeup_fd_posix.h" +#include "src/core/lib/support/env.h" + +typedef struct poll_args { + struct pollfd *fds; + nfds_t nfds; + int timeout; + int result; +} poll_args; + +gpr_cv poll_cv; +gpr_mu poll_mu; +static int socket_event = 0; + +// Trigger a "socket" POLLIN in mock_poll() +void trigger_socket_event() { + gpr_mu_lock(&poll_mu); + socket_event = 1; + gpr_cv_broadcast(&poll_cv); + gpr_mu_unlock(&poll_mu); +} + +void reset_socket_event() { + gpr_mu_lock(&poll_mu); + socket_event = 0; + gpr_mu_unlock(&poll_mu); +} + +// Mocks posix poll() function +int mock_poll(struct pollfd *fds, nfds_t nfds, int timeout) { + int res = 0; + gpr_timespec poll_time; + gpr_mu_lock(&poll_mu); + GPR_ASSERT(nfds == 3); + GPR_ASSERT(fds[0].fd == 20); + GPR_ASSERT(fds[1].fd == 30); + GPR_ASSERT(fds[2].fd == 50); + GPR_ASSERT(fds[0].events == (POLLIN | POLLHUP)); + GPR_ASSERT(fds[1].events == (POLLIN | POLLHUP)); + GPR_ASSERT(fds[2].events == POLLIN); + + if (timeout < 0) { + poll_time = gpr_inf_future(GPR_CLOCK_REALTIME); + } else { + poll_time = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), + gpr_time_from_millis(timeout, GPR_TIMESPAN)); + } + + if (socket_event || !gpr_cv_wait(&poll_cv, &poll_mu, poll_time)) { + fds[0].revents = POLLIN; + res = 1; + } + gpr_mu_unlock(&poll_mu); + return res; +} + +void background_poll(void *args) { + poll_args *pargs = (poll_args *)args; + pargs->result = grpc_poll_function(pargs->fds, pargs->nfds, pargs->timeout); +} + +void test_many_fds(void) { + int i; + grpc_wakeup_fd_global_init(); + grpc_wakeup_fd fd[1000]; + for (i = 0; i < 1000; i++) { + GPR_ASSERT(grpc_wakeup_fd_init(&fd[i]) == GRPC_ERROR_NONE); + } + for (i = 0; i < 1000; i++) { + grpc_wakeup_fd_destroy(&fd[i]); + } + grpc_wakeup_fd_global_destroy(); +} + +void test_poll_cv_trigger(void) { + grpc_wakeup_fd cvfd1, cvfd2, cvfd3; + struct pollfd pfds[6]; + poll_args pargs; + gpr_thd_id t_id; + gpr_thd_options opt; + grpc_poll_function = &mock_poll; + grpc_wakeup_fd_global_init(); + + GPR_ASSERT(grpc_wakeup_fd_init(&cvfd1) == GRPC_ERROR_NONE); + GPR_ASSERT(grpc_wakeup_fd_init(&cvfd2) == GRPC_ERROR_NONE); + GPR_ASSERT(grpc_wakeup_fd_init(&cvfd3) == GRPC_ERROR_NONE); + GPR_ASSERT(cvfd1.read_fd < 0); + GPR_ASSERT(cvfd2.read_fd < 0); + GPR_ASSERT(cvfd3.read_fd < 0); + GPR_ASSERT(cvfd1.read_fd != cvfd2.read_fd); + GPR_ASSERT(cvfd2.read_fd != cvfd3.read_fd); + GPR_ASSERT(cvfd1.read_fd != cvfd3.read_fd); + + pfds[0].fd = cvfd1.read_fd; + pfds[1].fd = cvfd2.read_fd; + pfds[2].fd = 20; + pfds[3].fd = 30; + pfds[4].fd = cvfd3.read_fd; + pfds[5].fd = 50; + + pfds[0].events = 0; + pfds[1].events = POLLIN; + pfds[2].events = POLLIN | POLLHUP; + pfds[3].events = POLLIN | POLLHUP; + pfds[4].events = POLLIN; + pfds[5].events = POLLIN; + + pargs.fds = pfds; + pargs.nfds = 6; + pargs.timeout = 1000; + pargs.result = -2; + + opt = gpr_thd_options_default(); + gpr_thd_options_set_joinable(&opt); + gpr_thd_new(&t_id, &background_poll, &pargs, &opt); + + // Wakeup wakeup_fd not listening for events + GPR_ASSERT(grpc_wakeup_fd_wakeup(&cvfd1) == GRPC_ERROR_NONE); + gpr_thd_join(t_id); + GPR_ASSERT(pargs.result == 0); + GPR_ASSERT(pfds[0].revents == 0); + GPR_ASSERT(pfds[1].revents == 0); + GPR_ASSERT(pfds[2].revents == 0); + GPR_ASSERT(pfds[3].revents == 0); + GPR_ASSERT(pfds[4].revents == 0); + GPR_ASSERT(pfds[5].revents == 0); + + // Pollin on socket fd + pargs.timeout = -1; + pargs.result = -2; + gpr_thd_new(&t_id, &background_poll, &pargs, &opt); + trigger_socket_event(); + gpr_thd_join(t_id); + GPR_ASSERT(pargs.result == 1); + GPR_ASSERT(pfds[0].revents == 0); + GPR_ASSERT(pfds[1].revents == 0); + GPR_ASSERT(pfds[2].revents == POLLIN); + GPR_ASSERT(pfds[3].revents == 0); + GPR_ASSERT(pfds[4].revents == 0); + GPR_ASSERT(pfds[5].revents == 0); + + // Pollin on wakeup fd + reset_socket_event(); + pargs.result = -2; + gpr_thd_new(&t_id, &background_poll, &pargs, &opt); + GPR_ASSERT(grpc_wakeup_fd_wakeup(&cvfd2) == GRPC_ERROR_NONE); + gpr_thd_join(t_id); + + GPR_ASSERT(pargs.result == 1); + GPR_ASSERT(pfds[0].revents == 0); + GPR_ASSERT(pfds[1].revents == POLLIN); + GPR_ASSERT(pfds[2].revents == 0); + GPR_ASSERT(pfds[3].revents == 0); + GPR_ASSERT(pfds[4].revents == 0); + GPR_ASSERT(pfds[5].revents == 0); + + // Pollin on wakeup fd + socket fd + trigger_socket_event(); + pargs.result = -2; + gpr_thd_new(&t_id, &background_poll, &pargs, &opt); + gpr_thd_join(t_id); + + GPR_ASSERT(pargs.result == 2); + GPR_ASSERT(pfds[0].revents == 0); + GPR_ASSERT(pfds[1].revents == POLLIN); + GPR_ASSERT(pfds[2].revents == POLLIN); + GPR_ASSERT(pfds[3].revents == 0); + GPR_ASSERT(pfds[4].revents == 0); + GPR_ASSERT(pfds[5].revents == 0); + + // No Events + pargs.result = -2; + pargs.timeout = 1000; + reset_socket_event(); + GPR_ASSERT(grpc_wakeup_fd_consume_wakeup(&cvfd1) == GRPC_ERROR_NONE); + GPR_ASSERT(grpc_wakeup_fd_consume_wakeup(&cvfd2) == GRPC_ERROR_NONE); + gpr_thd_new(&t_id, &background_poll, &pargs, &opt); + gpr_thd_join(t_id); + + GPR_ASSERT(pargs.result == 0); + GPR_ASSERT(pfds[0].revents == 0); + GPR_ASSERT(pfds[1].revents == 0); + GPR_ASSERT(pfds[2].revents == 0); + GPR_ASSERT(pfds[3].revents == 0); + GPR_ASSERT(pfds[4].revents == 0); + GPR_ASSERT(pfds[5].revents == 0); + + grpc_wakeup_fd_global_destroy(); +} + +int main(int argc, char **argv) { + gpr_setenv("GRPC_POLL_STRATEGY", "poll"); + grpc_allow_specialized_wakeup_fd = 0; + grpc_allow_pipe_wakeup_fd = 0; + gpr_mu_init(&poll_mu); + gpr_cv_init(&poll_cv); + test_many_fds(); + test_poll_cv_trigger(); + // Make sure detached polling threads have chance + // to exit and clean up memory. pthread_exit() causes tsan/msan + // issues, so we just wait an ample amount of time + gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), + gpr_time_from_seconds(5, GPR_TIMESPAN))); + return 0; +} diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 06b68c3b74..6e08a1977c 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -925,6 +925,7 @@ src/core/lib/iomgr/timer.h \ src/core/lib/iomgr/timer_heap.h \ src/core/lib/iomgr/udp_server.h \ src/core/lib/iomgr/unix_sockets_posix.h \ +src/core/lib/iomgr/wakeup_fd_cv.h \ src/core/lib/iomgr/wakeup_fd_pipe.h \ src/core/lib/iomgr/wakeup_fd_posix.h \ src/core/lib/iomgr/workqueue.h \ @@ -1039,6 +1040,7 @@ src/core/lib/iomgr/timer_heap.c \ src/core/lib/iomgr/udp_server.c \ src/core/lib/iomgr/unix_sockets_posix.c \ src/core/lib/iomgr/unix_sockets_posix_noop.c \ +src/core/lib/iomgr/wakeup_fd_cv.c \ src/core/lib/iomgr/wakeup_fd_eventfd.c \ src/core/lib/iomgr/wakeup_fd_nospecial.c \ src/core/lib/iomgr/wakeup_fd_pipe.c \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 02590db421..2328194c3a 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -842,6 +842,7 @@ src/core/lib/iomgr/timer.h \ src/core/lib/iomgr/timer_heap.h \ src/core/lib/iomgr/udp_server.h \ src/core/lib/iomgr/unix_sockets_posix.h \ +src/core/lib/iomgr/wakeup_fd_cv.h \ src/core/lib/iomgr/wakeup_fd_pipe.h \ src/core/lib/iomgr/wakeup_fd_posix.h \ src/core/lib/iomgr/workqueue.h \ @@ -1003,6 +1004,7 @@ src/core/lib/iomgr/timer_heap.c \ src/core/lib/iomgr/udp_server.c \ src/core/lib/iomgr/unix_sockets_posix.c \ src/core/lib/iomgr/unix_sockets_posix_noop.c \ +src/core/lib/iomgr/wakeup_fd_cv.c \ src/core/lib/iomgr/wakeup_fd_eventfd.c \ src/core/lib/iomgr/wakeup_fd_nospecial.c \ src/core/lib/iomgr/wakeup_fd_pipe.c \ diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index db84f21968..2ce0e3b05c 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -1891,6 +1891,22 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "gpr_test_util", + "grpc", + "grpc_test_util" + ], + "headers": [], + "language": "c", + "name": "wakeup_fd_cv_test", + "src": [ + "test/core/iomgr/wakeup_fd_cv_test.c" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", @@ -5941,6 +5957,7 @@ "src/core/lib/iomgr/timer_heap.h", "src/core/lib/iomgr/udp_server.h", "src/core/lib/iomgr/unix_sockets_posix.h", + "src/core/lib/iomgr/wakeup_fd_cv.h", "src/core/lib/iomgr/wakeup_fd_pipe.h", "src/core/lib/iomgr/wakeup_fd_posix.h", "src/core/lib/iomgr/workqueue.h", @@ -6085,6 +6102,8 @@ "src/core/lib/iomgr/unix_sockets_posix.c", "src/core/lib/iomgr/unix_sockets_posix.h", "src/core/lib/iomgr/unix_sockets_posix_noop.c", + "src/core/lib/iomgr/wakeup_fd_cv.c", + "src/core/lib/iomgr/wakeup_fd_cv.h", "src/core/lib/iomgr/wakeup_fd_eventfd.c", "src/core/lib/iomgr/wakeup_fd_nospecial.c", "src/core/lib/iomgr/wakeup_fd_pipe.c", diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json index f97ee835c1..de9c3d1053 100644 --- a/tools/run_tests/tests.json +++ b/tools/run_tests/tests.json @@ -1977,6 +1977,25 @@ "windows" ] }, + { + "args": [], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "gtest": false, + "language": "c", + "name": "wakeup_fd_cv_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, { "args": [], "ci_platforms": [ diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj b/vsprojects/vcxproj/grpc++/grpc++.vcxproj index 1bcb263911..2afda35d34 100644 --- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj +++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj @@ -425,6 +425,7 @@ + @@ -627,6 +628,8 @@ + + diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters index 7343c80cc4..1f88ae0e93 100644 --- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters +++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters @@ -259,6 +259,9 @@ src\core\lib\iomgr + + src\core\lib\iomgr + src\core\lib\iomgr @@ -869,6 +872,9 @@ src\core\lib\iomgr + + src\core\lib\iomgr + src\core\lib\iomgr diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj index 3241bafa6b..be20aef6dc 100644 --- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj +++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj @@ -421,6 +421,7 @@ + @@ -613,6 +614,8 @@ + + diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters index 3df26646fc..628173dbbe 100644 --- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters +++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters @@ -244,6 +244,9 @@ src\core\lib\iomgr + + src\core\lib\iomgr + src\core\lib\iomgr @@ -842,6 +845,9 @@ src\core\lib\iomgr + + src\core\lib\iomgr + src\core\lib\iomgr diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj index 7c120bcf02..ae24e8f066 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj @@ -351,6 +351,7 @@ + @@ -568,6 +569,8 @@ + + diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters index 9cbb2ce45b..a849795dc9 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters @@ -163,6 +163,9 @@ src\core\lib\iomgr + + src\core\lib\iomgr + src\core\lib\iomgr @@ -821,6 +824,9 @@ src\core\lib\iomgr + + src\core\lib\iomgr + src\core\lib\iomgr diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj index 80dd6b2dcb..3c3fae370f 100644 --- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj +++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj @@ -242,6 +242,7 @@ + @@ -412,6 +413,8 @@ + + diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters index 8dc28d1cb9..b81431cafa 100644 --- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters +++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters @@ -211,6 +211,9 @@ src\core\lib\iomgr + + src\core\lib\iomgr + src\core\lib\iomgr @@ -602,6 +605,9 @@ src\core\lib\iomgr + + src\core\lib\iomgr + src\core\lib\iomgr diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj index d4a85768c3..69d631e452 100644 --- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj +++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj @@ -341,6 +341,7 @@ + @@ -536,6 +537,8 @@ + + diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters index fba5a02099..36e80b4a13 100644 --- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters +++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters @@ -166,6 +166,9 @@ src\core\lib\iomgr + + src\core\lib\iomgr + src\core\lib\iomgr @@ -731,6 +734,9 @@ src\core\lib\iomgr + + src\core\lib\iomgr + src\core\lib\iomgr -- cgit v1.2.3 From f7c45aea5367c1340b1c05b6011528f2f9e39d43 Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Thu, 15 Sep 2016 13:40:32 -0700 Subject: Address review comments --- src/core/ext/client_config/lb_policy.h | 4 ++-- src/core/ext/lb_policy/grpclb/grpclb.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/ext/client_config/lb_policy.h b/src/core/ext/client_config/lb_policy.h index b92a73c09a..a244b06ec6 100644 --- a/src/core/ext/client_config/lb_policy.h +++ b/src/core/ext/client_config/lb_policy.h @@ -125,8 +125,8 @@ void grpc_lb_policy_init(grpc_lb_policy *policy, /** Given initial metadata in \a initial_metadata, find an appropriate target for this rpc, and 'return' it by calling \a on_complete after setting \a target. - Picking can be asynchronous. Any IO should be done under the pollset_set - interested_parties. */ + Picking can be asynchronous. Any IO should be done under the \a + interested_parties \a grpc_pollset_set in the \a grpc_lb_policy struct. */ int grpc_lb_policy_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, grpc_metadata_batch *initial_metadata, uint32_t initial_metadata_flags, diff --git a/src/core/ext/lb_policy/grpclb/grpclb.c b/src/core/ext/lb_policy/grpclb/grpclb.c index 2a23011e81..a9e329ed6d 100644 --- a/src/core/ext/lb_policy/grpclb/grpclb.c +++ b/src/core/ext/lb_policy/grpclb/grpclb.c @@ -761,7 +761,7 @@ static lb_client_data *lb_client_data_create(glb_lb_policy *glb_policy) { /* Note the following LB call progresses every time there's activity in \a * glb_policy->base.interested_parties, which is comprised of the polling - * entities from client_channel. */ + * entities from \a client_channel. */ lb_client->lb_call = grpc_channel_create_pollset_set_call( glb_policy->lb_channel, NULL, GRPC_PROPAGATE_DEFAULTS, glb_policy->base.interested_parties, "/BalanceLoad", -- cgit v1.2.3 From 6222926d682600e840cc5f421a07eb56ce8d4f00 Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Thu, 15 Sep 2016 16:08:10 -0700 Subject: Remove pollent from grpc_lb_policy_pick_args --- src/core/ext/client_config/client_channel.c | 6 +++--- src/core/ext/client_config/lb_policy.h | 2 -- src/core/ext/lb_policy/grpclb/grpclb.c | 8 +++----- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/core/ext/client_config/client_channel.c b/src/core/ext/client_config/client_channel.c index 42050d7043..c16e9a6765 100644 --- a/src/core/ext/client_config/client_channel.c +++ b/src/core/ext/client_config/client_channel.c @@ -545,6 +545,7 @@ static bool pick_subchannel(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, GPR_TIMER_BEGIN("pick_subchannel", 0); channel_data *chand = elem->channel_data; + call_data *calld = elem->call_data; continue_picking_args *cpa; grpc_closure *closure; @@ -574,9 +575,8 @@ static bool pick_subchannel(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, int r; GRPC_LB_POLICY_REF(lb_policy, "pick_subchannel"); gpr_mu_unlock(&chand->mu); - const grpc_lb_policy_pick_args inputs = {calld->pollent, initial_metadata, - initial_metadata_flags, - &calld->lb_token_mdelem}; + const grpc_lb_policy_pick_args inputs = { + initial_metadata, initial_metadata_flags, &calld->lb_token_mdelem}; r = grpc_lb_policy_pick(exec_ctx, lb_policy, &inputs, connected_subchannel, NULL, on_ready); GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "pick_subchannel"); diff --git a/src/core/ext/client_config/lb_policy.h b/src/core/ext/client_config/lb_policy.h index ef412b7ca3..ac387e4b80 100644 --- a/src/core/ext/client_config/lb_policy.h +++ b/src/core/ext/client_config/lb_policy.h @@ -54,8 +54,6 @@ struct grpc_lb_policy { /** Extra arguments for an LB pick */ typedef struct grpc_lb_policy_pick_args { - /** Parties interested in the pick's progress */ - grpc_polling_entity *pollent; /** Initial metadata associated with the picking call. */ grpc_metadata_batch *initial_metadata; /** See \a GRPC_INITIAL_METADATA_* in grpc_types.h */ diff --git a/src/core/ext/lb_policy/grpclb/grpclb.c b/src/core/ext/lb_policy/grpclb/grpclb.c index b44ca1b6b2..f213342ecb 100644 --- a/src/core/ext/lb_policy/grpclb/grpclb.c +++ b/src/core/ext/lb_policy/grpclb/grpclb.c @@ -500,9 +500,9 @@ static void rr_handover(grpc_exec_ctx *exec_ctx, glb_lb_policy *glb_policy, gpr_log(GPR_INFO, "Pending pick about to PICK from 0x%" PRIxPTR "", (intptr_t)glb_policy->rr_policy); } - const grpc_lb_policy_pick_args pick_args = { - pp->pollent, pp->initial_metadata, pp->initial_metadata_flags, - pp->lb_token_mdelem_storage}; + const grpc_lb_policy_pick_args pick_args = {pp->initial_metadata, + pp->initial_metadata_flags, + pp->lb_token_mdelem_storage}; grpc_lb_policy_pick(exec_ctx, glb_policy->rr_policy, &pick_args, pp->target, (void **)&pp->wrapped_on_complete_arg.lb_token, &pp->wrapped_on_complete); @@ -806,8 +806,6 @@ static int glb_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, GRPC_MDELEM_REF(glb_policy->wc_arg.lb_token)); } } else { - grpc_polling_entity_add_to_pollset_set(exec_ctx, pick_args->pollent, - glb_policy->base.interested_parties); add_pending_pick(&glb_policy->pending_picks, pick_args, target, on_complete); -- cgit v1.2.3 From 1808bbd2590702ab5a0e067d9d4ab037d9b8e2bc Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 20 Sep 2016 11:29:34 -0700 Subject: Correct merge errors --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 3497d23a78..9b4c4f4220 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -319,12 +319,12 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, const char *channel_arg_name; grpc_chttp2_setting_id setting_id; grpc_integer_options integer_options; - bool availability[2] /* client, server */; + bool availability[2] /* server, client */; } settings_map[] = { {GRPC_ARG_MAX_CONCURRENT_STREAMS, GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, {-1, 0, INT_MAX}, - {false, true}}, + {true, false}}, {GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER, GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE, {-1, 0, INT_MAX}, @@ -338,7 +338,7 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, {-1, 16384, 16777215}, {true, true}}, }; - for (size_t j = 0; j < GPR_ARRAY_SIZE(settings_map); j++) { + for (j = 0; j < (int)GPR_ARRAY_SIZE(settings_map); j++) { if (0 == strcmp(channel_args->args[i].key, settings_map[j].channel_arg_name)) { if (!settings_map[j].availability[is_client]) { @@ -349,7 +349,8 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, int value = grpc_channel_arg_get_integer( &channel_args->args[i], settings_map[j].integer_options); if (value >= 0) { - push_setting(exec_ctx, t, settings_map[j].setting_id, value); + push_setting(exec_ctx, t, settings_map[j].setting_id, + (uint32_t)value); } } break; -- cgit v1.2.3 From f4e1c3e614ee0e0cb95bb7ee8dcf3e44236718cd Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 20 Sep 2016 21:36:09 -0700 Subject: Fix bug whereby receiving a trailer after a stream close could trigger an assert --- .../transport/chttp2/transport/chttp2_transport.c | 4 +-- .../transport/chttp2/transport/frame_settings.c | 2 +- src/core/ext/transport/chttp2/transport/internal.h | 4 +-- src/core/ext/transport/chttp2/transport/parsing.c | 9 ++---- .../ext/transport/chttp2/transport/stream_map.c | 34 ---------------------- .../ext/transport/chttp2/transport/stream_map.h | 4 --- 6 files changed, 8 insertions(+), 49 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 9b4c4f4220..d46656ce81 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1102,7 +1102,7 @@ static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, if (grpc_http_trace) { char *str = grpc_transport_stream_op_string(op); - gpr_log(GPR_DEBUG, "perform_stream_op: %s", str); + gpr_log(GPR_DEBUG, "perform_stream_op[s=%p/%d]: %s", s, s->id, str); gpr_free(str); } @@ -1171,7 +1171,7 @@ static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx, if (op->send_goaway) { t->sent_goaway = 1; grpc_chttp2_goaway_append( - t->last_incoming_stream_id, + t->last_new_stream_id, (uint32_t)grpc_chttp2_grpc_status_to_http2_error(op->goaway_status), gpr_slice_ref(*op->goaway_message), &t->qbuf); close_transport = grpc_chttp2_stream_map_size(&t->stream_map) == 0 diff --git a/src/core/ext/transport/chttp2/transport/frame_settings.c b/src/core/ext/transport/chttp2/transport/frame_settings.c index fc0383d2e0..92022f90c9 100644 --- a/src/core/ext/transport/chttp2/transport/frame_settings.c +++ b/src/core/ext/transport/chttp2/transport/frame_settings.c @@ -224,7 +224,7 @@ grpc_error *grpc_chttp2_settings_parser_parse(grpc_exec_ctx *exec_ctx, void *p, break; case GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE: grpc_chttp2_goaway_append( - t->last_incoming_stream_id, sp->error_value, + t->last_new_stream_id, sp->error_value, gpr_slice_from_static_string("HTTP2 settings error"), &t->qbuf); gpr_asprintf(&msg, "invalid value %u passed for %s", diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 6b3e2edd54..3263c99bde 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -267,8 +267,8 @@ struct grpc_chttp2_transport { /** how far to lookahead in a stream? */ uint32_t stream_lookahead; - /** last received stream id */ - uint32_t last_incoming_stream_id; + /** last new stream id */ + uint32_t last_new_stream_id; /** pings awaiting responses */ grpc_chttp2_outstanding_ping pings; diff --git a/src/core/ext/transport/chttp2/transport/parsing.c b/src/core/ext/transport/chttp2/transport/parsing.c index aa36f90cae..41bf10b50f 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.c +++ b/src/core/ext/transport/chttp2/transport/parsing.c @@ -199,10 +199,6 @@ grpc_error *grpc_chttp2_perform_read(grpc_exec_ctx *exec_ctx, if (err != GRPC_ERROR_NONE) { return err; } - if (t->incoming_stream_id != 0 && - t->incoming_stream_id > t->last_incoming_stream_id) { - t->last_incoming_stream_id = t->incoming_stream_id; - } if (t->incoming_frame_size == 0) { err = parse_frame_slice(exec_ctx, t, gpr_empty_slice(), 1); if (err != GRPC_ERROR_NONE) { @@ -578,12 +574,12 @@ static grpc_error *init_header_frame_parser(grpc_exec_ctx *exec_ctx, "ignoring new grpc_chttp2_stream creation on client"); } return init_skip_frame_parser(exec_ctx, t, 1); - } else if (t->last_incoming_stream_id > t->incoming_stream_id) { + } else if (t->last_new_stream_id >= t->incoming_stream_id) { gpr_log(GPR_ERROR, "ignoring out of order new grpc_chttp2_stream request on server; " "last grpc_chttp2_stream " "id=%d, new grpc_chttp2_stream id=%d", - t->last_incoming_stream_id, t->incoming_stream_id); + t->last_new_stream_id, t->incoming_stream_id); return init_skip_frame_parser(exec_ctx, t, 1); } else if ((t->incoming_stream_id & 1) == 0) { gpr_log(GPR_ERROR, @@ -591,6 +587,7 @@ static grpc_error *init_header_frame_parser(grpc_exec_ctx *exec_ctx, t->incoming_stream_id); return init_skip_frame_parser(exec_ctx, t, 1); } + t->last_new_stream_id = t->incoming_stream_id; s = t->incoming_stream = grpc_chttp2_parsing_accept_stream(exec_ctx, t, t->incoming_stream_id); if (s == NULL) { diff --git a/src/core/ext/transport/chttp2/transport/stream_map.c b/src/core/ext/transport/chttp2/transport/stream_map.c index bd07412274..59b3a14e0a 100644 --- a/src/core/ext/transport/chttp2/transport/stream_map.c +++ b/src/core/ext/transport/chttp2/transport/stream_map.c @@ -97,40 +97,6 @@ void grpc_chttp2_stream_map_add(grpc_chttp2_stream_map *map, uint32_t key, map->count = count + 1; } -void grpc_chttp2_stream_map_move_into(grpc_chttp2_stream_map *src, - grpc_chttp2_stream_map *dst) { - /* if src is empty we dont need to do anything */ - if (src->count == src->free) { - return; - } - /* if dst is empty we simply need to swap */ - if (dst->count == dst->free) { - GPR_SWAP(grpc_chttp2_stream_map, *src, *dst); - return; - } - /* the first element of src must be greater than the last of dst... - * however the maps may need compacting for this property to hold */ - if (src->keys[0] <= dst->keys[dst->count - 1]) { - src->count = compact(src->keys, src->values, src->count); - src->free = 0; - dst->count = compact(dst->keys, dst->values, dst->count); - dst->free = 0; - } - GPR_ASSERT(src->keys[0] > dst->keys[dst->count - 1]); - /* if dst doesn't have capacity, resize */ - if (dst->count + src->count > dst->capacity) { - dst->capacity = GPR_MAX(dst->capacity * 3 / 2, dst->count + src->count); - dst->keys = gpr_realloc(dst->keys, dst->capacity * sizeof(uint32_t)); - dst->values = gpr_realloc(dst->values, dst->capacity * sizeof(void *)); - } - memcpy(dst->keys + dst->count, src->keys, src->count * sizeof(uint32_t)); - memcpy(dst->values + dst->count, src->values, src->count * sizeof(void *)); - dst->count += src->count; - dst->free += src->free; - src->count = 0; - src->free = 0; -} - static void **find(grpc_chttp2_stream_map *map, uint32_t key) { size_t min_idx = 0; size_t max_idx = map->count; diff --git a/src/core/ext/transport/chttp2/transport/stream_map.h b/src/core/ext/transport/chttp2/transport/stream_map.h index b1d59ca6a3..e76312dd1a 100644 --- a/src/core/ext/transport/chttp2/transport/stream_map.h +++ b/src/core/ext/transport/chttp2/transport/stream_map.h @@ -65,10 +65,6 @@ void grpc_chttp2_stream_map_add(grpc_chttp2_stream_map *map, uint32_t key, or NULL otherwise */ void *grpc_chttp2_stream_map_delete(grpc_chttp2_stream_map *map, uint32_t key); -/* Move all elements of src into dst */ -void grpc_chttp2_stream_map_move_into(grpc_chttp2_stream_map *src, - grpc_chttp2_stream_map *dst); - /* Return an existing key, or NULL if it does not exist */ void *grpc_chttp2_stream_map_find(grpc_chttp2_stream_map *map, uint32_t key); -- cgit v1.2.3 From df71521247c449cf37618df59eab53adddacf0cf Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 21 Sep 2016 07:01:33 -0700 Subject: Cover some log lines with if_tracing --- src/core/ext/transport/chttp2/transport/parsing.c | 33 +++++++++++++---------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/parsing.c b/src/core/ext/transport/chttp2/transport/parsing.c index 41bf10b50f..bc12515b0c 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.c +++ b/src/core/ext/transport/chttp2/transport/parsing.c @@ -561,8 +561,9 @@ static grpc_error *init_header_frame_parser(grpc_exec_ctx *exec_ctx, s = grpc_chttp2_parsing_lookup_stream(t, t->incoming_stream_id); if (s == NULL) { if (is_continuation) { - gpr_log(GPR_ERROR, - "grpc_chttp2_stream disbanded before CONTINUATION received"); + GRPC_CHTTP2_IF_TRACING( + gpr_log(GPR_ERROR, + "grpc_chttp2_stream disbanded before CONTINUATION received")); return init_skip_frame_parser(exec_ctx, t, 1); } if (t->is_client) { @@ -570,28 +571,31 @@ static grpc_error *init_header_frame_parser(grpc_exec_ctx *exec_ctx, t->incoming_stream_id < t->next_stream_id) { /* this is an old (probably cancelled) grpc_chttp2_stream */ } else { - gpr_log(GPR_ERROR, - "ignoring new grpc_chttp2_stream creation on client"); + GRPC_CHTTP2_IF_TRACING(gpr_log( + GPR_ERROR, "ignoring new grpc_chttp2_stream creation on client")); } return init_skip_frame_parser(exec_ctx, t, 1); } else if (t->last_new_stream_id >= t->incoming_stream_id) { - gpr_log(GPR_ERROR, - "ignoring out of order new grpc_chttp2_stream request on server; " - "last grpc_chttp2_stream " - "id=%d, new grpc_chttp2_stream id=%d", - t->last_new_stream_id, t->incoming_stream_id); + GRPC_CHTTP2_IF_TRACING(gpr_log( + GPR_ERROR, + "ignoring out of order new grpc_chttp2_stream request on server; " + "last grpc_chttp2_stream " + "id=%d, new grpc_chttp2_stream id=%d", + t->last_new_stream_id, t->incoming_stream_id)); return init_skip_frame_parser(exec_ctx, t, 1); } else if ((t->incoming_stream_id & 1) == 0) { - gpr_log(GPR_ERROR, - "ignoring grpc_chttp2_stream with non-client generated index %d", - t->incoming_stream_id); + GRPC_CHTTP2_IF_TRACING(gpr_log( + GPR_ERROR, + "ignoring grpc_chttp2_stream with non-client generated index %d", + t->incoming_stream_id)); return init_skip_frame_parser(exec_ctx, t, 1); } t->last_new_stream_id = t->incoming_stream_id; s = t->incoming_stream = grpc_chttp2_parsing_accept_stream(exec_ctx, t, t->incoming_stream_id); if (s == NULL) { - gpr_log(GPR_ERROR, "grpc_chttp2_stream not accepted"); + GRPC_CHTTP2_IF_TRACING( + gpr_log(GPR_ERROR, "grpc_chttp2_stream not accepted")); return init_skip_frame_parser(exec_ctx, t, 1); } } else { @@ -600,7 +604,8 @@ static grpc_error *init_header_frame_parser(grpc_exec_ctx *exec_ctx, GPR_ASSERT(s != NULL); s->stats.incoming.framing_bytes += 9; if (s->read_closed) { - gpr_log(GPR_ERROR, "skipping already closed grpc_chttp2_stream header"); + GRPC_CHTTP2_IF_TRACING(gpr_log( + GPR_ERROR, "skipping already closed grpc_chttp2_stream header")); t->incoming_stream = NULL; return init_skip_frame_parser(exec_ctx, t, 1); } -- cgit v1.2.3 From 0786490eb4378876ea2b4e7b3500bcf9d1781abe Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 21 Sep 2016 10:40:45 -0700 Subject: Rollback changes to timer.h --- src/core/lib/profiling/timers.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/core/lib/profiling/timers.h b/src/core/lib/profiling/timers.h index ea0cbca977..621cdbf656 100644 --- a/src/core/lib/profiling/timers.h +++ b/src/core/lib/profiling/timers.h @@ -34,8 +34,6 @@ #ifndef GRPC_CORE_LIB_PROFILING_TIMERS_H #define GRPC_CORE_LIB_PROFILING_TIMERS_H -#include - #ifdef __cplusplus extern "C" { #endif @@ -58,17 +56,14 @@ void gpr_timer_set_enabled(int enabled); /* No profiling. No-op all the things. */ #define GPR_TIMER_MARK(tag, important) \ do { \ - /*printf("- %s\n", tag);*/ \ } while (0) #define GPR_TIMER_BEGIN(tag, important) \ do { \ - /*printf("%s {\n", tag);*/ \ } while (0) #define GPR_TIMER_END(tag, important) \ do { \ - /*printf("} // %s\n", tag);*/ \ } while (0) #else /* at least one profiler requested... */ -- cgit v1.2.3 From d533613a63431865e92ffa245fe463f072425196 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 21 Sep 2016 10:43:08 -0700 Subject: Add documentation --- src/core/lib/support/string.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/lib/support/string.h b/src/core/lib/support/string.h index 3aebc083ac..9a94e9471c 100644 --- a/src/core/lib/support/string.h +++ b/src/core/lib/support/string.h @@ -118,6 +118,8 @@ void gpr_strvec_add(gpr_strvec *strs, char *add); total_length as per gpr_strjoin */ char *gpr_strvec_flatten(gpr_strvec *strs, size_t *total_length); +/** Case insensitive string comparison... return <0 if lower(a)0 if lower(a)>lower(b) */ int gpr_stricmp(const char *a, const char *b); #ifdef __cplusplus -- cgit v1.2.3 From 47b5f0aeb598d588d651842ee4f30c7229898df6 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 21 Sep 2016 10:43:26 -0700 Subject: Use bool --- src/core/lib/transport/transport_op_string.c | 34 ++++++++++++++-------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/core/lib/transport/transport_op_string.c b/src/core/lib/transport/transport_op_string.c index 8a687d8cd3..f350e55b34 100644 --- a/src/core/lib/transport/transport_op_string.c +++ b/src/core/lib/transport/transport_op_string.c @@ -73,14 +73,14 @@ static void put_metadata_list(gpr_strvec *b, grpc_metadata_batch md) { char *grpc_transport_stream_op_string(grpc_transport_stream_op *op) { char *tmp; char *out; - int first = 1; + bool first = true; gpr_strvec b; gpr_strvec_init(&b); if (op->send_initial_metadata != NULL) { if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); - first = 0; + first = false; gpr_strvec_add(&b, gpr_strdup("SEND_INITIAL_METADATA{")); put_metadata_list(&b, *op->send_initial_metadata); gpr_strvec_add(&b, gpr_strdup("}")); @@ -88,7 +88,7 @@ char *grpc_transport_stream_op_string(grpc_transport_stream_op *op) { if (op->send_message != NULL) { if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); - first = 0; + first = false; gpr_asprintf(&tmp, "SEND_MESSAGE:flags=0x%08x:len=%d", op->send_message->flags, op->send_message->length); gpr_strvec_add(&b, tmp); @@ -96,7 +96,7 @@ char *grpc_transport_stream_op_string(grpc_transport_stream_op *op) { if (op->send_trailing_metadata != NULL) { if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); - first = 0; + first = false; gpr_strvec_add(&b, gpr_strdup("SEND_TRAILING_METADATA{")); put_metadata_list(&b, *op->send_trailing_metadata); gpr_strvec_add(&b, gpr_strdup("}")); @@ -104,25 +104,25 @@ char *grpc_transport_stream_op_string(grpc_transport_stream_op *op) { if (op->recv_initial_metadata != NULL) { if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); - first = 0; + first = false; gpr_strvec_add(&b, gpr_strdup("RECV_INITIAL_METADATA")); } if (op->recv_message != NULL) { if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); - first = 0; + first = false; gpr_strvec_add(&b, gpr_strdup("RECV_MESSAGE")); } if (op->recv_trailing_metadata != NULL) { if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); - first = 0; + first = false; gpr_strvec_add(&b, gpr_strdup("RECV_TRAILING_METADATA")); } if (op->cancel_error != GRPC_ERROR_NONE) { if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); - first = 0; + first = false; const char *msg = grpc_error_string(op->cancel_error); gpr_asprintf(&tmp, "CANCEL:%s", msg); grpc_error_free_string(msg); @@ -131,7 +131,7 @@ char *grpc_transport_stream_op_string(grpc_transport_stream_op *op) { if (op->close_error != GRPC_ERROR_NONE) { if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); - first = 0; + first = false; const char *msg = grpc_error_string(op->close_error); gpr_asprintf(&tmp, "CLOSE:%s", msg); grpc_error_free_string(msg); @@ -147,14 +147,14 @@ char *grpc_transport_stream_op_string(grpc_transport_stream_op *op) { char *grpc_transport_op_string(grpc_transport_op *op) { char *tmp; char *out; - int first = 1; + bool first = true; gpr_strvec b; gpr_strvec_init(&b); if (op->on_connectivity_state_change != NULL) { if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); - first = 0; + first = false; if (op->connectivity_state != NULL) { gpr_asprintf(&tmp, "ON_CONNECTIVITY_STATE_CHANGE:p=%p:from=%s", op->on_connectivity_state_change, @@ -169,7 +169,7 @@ char *grpc_transport_op_string(grpc_transport_op *op) { if (op->disconnect_with_error != GRPC_ERROR_NONE) { if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); - first = 0; + first = false; const char *err = grpc_error_string(op->disconnect_with_error); gpr_asprintf(&tmp, "DISCONNECT:%s", err); gpr_strvec_add(&b, tmp); @@ -178,7 +178,7 @@ char *grpc_transport_op_string(grpc_transport_op *op) { if (op->send_goaway) { if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); - first = 0; + first = false; char *msg = op->goaway_message == NULL ? "null" : gpr_dump_slice(*op->goaway_message, @@ -190,7 +190,7 @@ char *grpc_transport_op_string(grpc_transport_op *op) { if (op->set_accept_stream) { if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); - first = 0; + first = false; gpr_asprintf(&tmp, "SET_ACCEPT_STREAM:%p(%p,...)", op->set_accept_stream_fn, op->set_accept_stream_user_data); gpr_strvec_add(&b, tmp); @@ -198,19 +198,19 @@ char *grpc_transport_op_string(grpc_transport_op *op) { if (op->bind_pollset != NULL) { if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); - first = 0; + first = false; gpr_strvec_add(&b, gpr_strdup("BIND_POLLSET")); } if (op->bind_pollset_set != NULL) { if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); - first = 0; + first = false; gpr_strvec_add(&b, gpr_strdup("BIND_POLLSET_SET")); } if (op->send_ping != NULL) { if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); - first = 0; + first = false; gpr_strvec_add(&b, gpr_strdup("SEND_PING")); } -- cgit v1.2.3 From 0eaed7224dea18738950ef8135c76453ac91d4d7 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 21 Sep 2016 10:44:18 -0700 Subject: Readability fix --- src/core/lib/surface/call.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c index 2438885ae9..6b2badf71b 100644 --- a/src/core/lib/surface/call.c +++ b/src/core/lib/surface/call.c @@ -238,8 +238,8 @@ grpc_error *grpc_call_create(const grpc_call_create_args *args, grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_call *call; GPR_TIMER_BEGIN("grpc_call_create", 0); - *out_call = call = - gpr_malloc(sizeof(grpc_call) + channel_stack->call_stack_size); + call = gpr_malloc(sizeof(grpc_call) + channel_stack->call_stack_size); + *out_call = call; memset(call, 0, sizeof(grpc_call)); gpr_mu_init(&call->mu); call->channel = args->channel; -- cgit v1.2.3 From 687a0e641057d42394e1574629df6368cc6e5322 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 21 Sep 2016 10:48:59 -0700 Subject: Add trace for server channel events --- doc/environment_variables.md | 2 +- src/core/lib/surface/init.c | 1 + src/core/lib/surface/server.c | 4 +++- src/core/lib/surface/server.h | 3 +++ 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/doc/environment_variables.md b/doc/environment_variables.md index 578bfe7eb7..b790f627ea 100644 --- a/doc/environment_variables.md +++ b/doc/environment_variables.md @@ -48,6 +48,7 @@ some configuration as environment variables that can be set. - glb - traces the grpclb load balancer - queue_pluck - queue_timeout + - server_channel - lightweight trace of significant server channel events - secure_endpoint - traces bytes flowing through encrypted channels - transport_security - traces metadata about secure channel establishment - tcp - traces bytes in and out of a channel @@ -61,4 +62,3 @@ some configuration as environment variables that can be set. - DEBUG - log all gRPC messages - INFO - log INFO and ERROR message - ERROR - log only errors - diff --git a/src/core/lib/surface/init.c b/src/core/lib/surface/init.c index 2135507b7a..3cbbaa7b0c 100644 --- a/src/core/lib/surface/init.c +++ b/src/core/lib/surface/init.c @@ -177,6 +177,7 @@ void grpc_init(void) { grpc_register_tracer("compression", &grpc_compression_trace); grpc_register_tracer("queue_pluck", &grpc_cq_pluck_trace); grpc_register_tracer("combiner", &grpc_combiner_trace); + grpc_register_tracer("server_channel", &grpc_server_channel_trace); // Default pluck trace to 1 grpc_cq_pluck_trace = 1; grpc_register_tracer("queue_timeout", &grpc_cq_event_timeout_trace); diff --git a/src/core/lib/surface/server.c b/src/core/lib/surface/server.c index 9a9fcddb6e..cec3e3ce97 100644 --- a/src/core/lib/surface/server.c +++ b/src/core/lib/surface/server.c @@ -71,6 +71,8 @@ typedef struct registered_method registered_method; typedef enum { BATCH_CALL, REGISTERED_CALL } requested_call_type; +int grpc_server_channel_trace = 0; + typedef struct requested_call { requested_call_type type; size_t cq_idx; @@ -440,7 +442,7 @@ static void destroy_channel(grpc_exec_ctx *exec_ctx, channel_data *chand, chand->finish_destroy_channel_closure.cb = finish_destroy_channel; chand->finish_destroy_channel_closure.cb_arg = chand; - if (error != GRPC_ERROR_NONE) { + if (grpc_server_channel_trace && error != GRPC_ERROR_NONE) { const char *msg = grpc_error_string(error); gpr_log(GPR_INFO, "Disconnected client: %s", msg); grpc_error_free_string(msg); diff --git a/src/core/lib/surface/server.h b/src/core/lib/surface/server.h index fb6e4d60c5..2a4e65c7ce 100644 --- a/src/core/lib/surface/server.h +++ b/src/core/lib/surface/server.h @@ -40,6 +40,9 @@ extern const grpc_channel_filter grpc_server_top_filter; +/** Lightweight tracing of server channel state */ +extern int grpc_server_channel_trace; + /* Add a listener to the server: when the server starts, it will call start, and when it shuts down, it will call destroy */ void grpc_server_add_listener( -- cgit v1.2.3 From 3f665f5fefb4ec7687f44d8a60eb660bee1f3e6c Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 23 Sep 2016 09:52:26 -0700 Subject: Add fuzzer detected failure --- .../crash-3e52af52deb0ed5d6ef06487d7e475e8fb616972 | Bin 0 -> 37 bytes tools/run_tests/tests.json | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/crash-3e52af52deb0ed5d6ef06487d7e475e8fb616972 diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/crash-3e52af52deb0ed5d6ef06487d7e475e8fb616972 b/test/core/end2end/fuzzers/client_fuzzer_corpus/crash-3e52af52deb0ed5d6ef06487d7e475e8fb616972 new file mode 100644 index 0000000000..30614ec9a4 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/crash-3e52af52deb0ed5d6ef06487d7e475e8fb616972 differ diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json index 51e1dff96e..4c8dfee625 100644 --- a/tools/run_tests/tests.json +++ b/tools/run_tests/tests.json @@ -64282,6 +64282,25 @@ ], "uses_polling": false }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/crash-3e52af52deb0ed5d6ef06487d7e475e8fb616972" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, { "args": [ "test/core/end2end/fuzzers/client_fuzzer_corpus/crash-53e93a1906d8442d058500e7107929cdd3e84ff8" -- cgit v1.2.3 From 76b3e26d938a925532522fa276736bfcea442624 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 23 Sep 2016 09:59:30 -0700 Subject: Add fuzzer detected failure --- .../crash-17d5b79ce495f7d3f2e33d95588457281a5e8965 | Bin 0 -> 52 bytes tools/run_tests/tests.json | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/crash-17d5b79ce495f7d3f2e33d95588457281a5e8965 diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/crash-17d5b79ce495f7d3f2e33d95588457281a5e8965 b/test/core/end2end/fuzzers/client_fuzzer_corpus/crash-17d5b79ce495f7d3f2e33d95588457281a5e8965 new file mode 100644 index 0000000000..7b5b32cd37 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/crash-17d5b79ce495f7d3f2e33d95588457281a5e8965 differ diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json index 7e3d9e6090..f69a00d118 100644 --- a/tools/run_tests/tests.json +++ b/tools/run_tests/tests.json @@ -68806,6 +68806,25 @@ ], "uses_polling": false }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/crash-17d5b79ce495f7d3f2e33d95588457281a5e8965" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "linux" + ], + "uses_polling": false + }, { "args": [ "test/core/end2end/fuzzers/client_fuzzer_corpus/crash-3bd02c98286bfa7be8e13c5500ddb587bba74fbb" -- cgit v1.2.3 From 4288101a0bcb4c1caaa633522df87f2ab0abc57d Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 28 Sep 2016 09:21:35 -0700 Subject: Fix flow control of cancelled streams --- src/core/ext/transport/chttp2/transport/parsing.c | 46 +++++++++++++---------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/parsing.c b/src/core/ext/transport/chttp2/transport/parsing.c index bc12515b0c..8005350ae7 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.c +++ b/src/core/ext/transport/chttp2/transport/parsing.c @@ -375,22 +375,26 @@ static grpc_error *update_incoming_window(grpc_exec_ctx *exec_ctx, return err; } - if (incoming_frame_size > s->incoming_window) { - char *msg; - gpr_asprintf(&msg, "frame of size %d overflows incoming window of %" PRId64, - t->incoming_frame_size, s->incoming_window); - grpc_error *err = GRPC_ERROR_CREATE(msg); - gpr_free(msg); - return err; - } - GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("parse", t, incoming_window, incoming_frame_size); - GRPC_CHTTP2_FLOW_DEBIT_STREAM("parse", t, s, incoming_window, - incoming_frame_size); - s->received_bytes += incoming_frame_size; - s->max_recv_bytes -= - (uint32_t)GPR_MIN(s->max_recv_bytes, incoming_frame_size); + + if (s != NULL) { + if (incoming_frame_size > s->incoming_window) { + char *msg; + gpr_asprintf(&msg, + "frame of size %d overflows incoming window of %" PRId64, + t->incoming_frame_size, s->incoming_window); + grpc_error *err = GRPC_ERROR_CREATE(msg); + gpr_free(msg); + return err; + } + + GRPC_CHTTP2_FLOW_DEBIT_STREAM("parse", t, s, incoming_window, + incoming_frame_size); + s->received_bytes += incoming_frame_size; + s->max_recv_bytes -= + (uint32_t)GPR_MIN(s->max_recv_bytes, incoming_frame_size); + } return GRPC_ERROR_NONE; } @@ -400,20 +404,22 @@ static grpc_error *init_data_frame_parser(grpc_exec_ctx *exec_ctx, grpc_chttp2_stream *s = grpc_chttp2_parsing_lookup_stream(t, t->incoming_stream_id); grpc_error *err = GRPC_ERROR_NONE; + err = update_incoming_window(exec_ctx, t, s); + if (err != GRPC_ERROR_NONE) { + goto error_handler; + } if (s == NULL) { return init_skip_frame_parser(exec_ctx, t, 0); } s->stats.incoming.framing_bytes += 9; - if (s->read_closed) { + if (err == GRPC_ERROR_NONE && s->read_closed) { return init_skip_frame_parser(exec_ctx, t, 0); } - if (err == GRPC_ERROR_NONE) { - err = update_incoming_window(exec_ctx, t, s); - } if (err == GRPC_ERROR_NONE) { err = grpc_chttp2_data_parser_begin_frame(&s->data_parser, t->incoming_frame_flags, s->id); } +error_handler: if (err == GRPC_ERROR_NONE) { t->incoming_stream = s; t->parser = grpc_chttp2_data_parser_parse; @@ -421,7 +427,9 @@ static grpc_error *init_data_frame_parser(grpc_exec_ctx *exec_ctx, return GRPC_ERROR_NONE; } else if (grpc_error_get_int(err, GRPC_ERROR_INT_STREAM_ID, NULL)) { /* handle stream errors by closing the stream */ - grpc_chttp2_mark_stream_closed(exec_ctx, t, s, true, false, err); + if (s != NULL) { + grpc_chttp2_mark_stream_closed(exec_ctx, t, s, true, false, err); + } gpr_slice_buffer_add( &t->qbuf, grpc_chttp2_rst_stream_create(t->incoming_stream_id, GRPC_CHTTP2_PROTOCOL_ERROR, -- cgit v1.2.3 From 35e87838a7f58c640da1e8c2b6d77c81dce8364f Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 28 Sep 2016 10:53:41 -0700 Subject: Review feedback --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 77ae890c06..c25bf1718c 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -904,7 +904,8 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, if (grpc_http_trace) { char *str = grpc_transport_stream_op_string(op); - gpr_log(GPR_DEBUG, "perform_stream_op_locked: %s", str); + gpr_log(GPR_DEBUG, "perform_stream_op_locked: %s; on_complete = %p", str, + op->on_complete); gpr_free(str); } @@ -913,10 +914,6 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, on_complete = grpc_closure_create(do_nothing, NULL); } - if (grpc_http_trace) { - gpr_log(GPR_DEBUG, " on_complete = %p", on_complete); - } - /* use final_data as a barrier until enqueue time; the inital counter is dropped at the end of this function */ on_complete->next_data.scratch = CLOSURE_BARRIER_FIRST_REF_BIT; @@ -1009,6 +1006,8 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, (ssize_t)s->flow_controlled_buffer.length + (ssize_t)len; s->complete_fetch_covered_by_poller = op->covered_by_poller; if (flags & GRPC_WRITE_BUFFER_HINT) { + /* allow up to 64kb to be buffered */ + /* TODO(ctiller): make this configurable */ s->fetching_slice_end_offset -= 65536; } continue_fetching_send_locked(exec_ctx, t, s); @@ -1233,7 +1232,6 @@ void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_exec_ctx *exec_ctx, if (s->seen_error) { while ((bs = grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames)) != NULL) { - gpr_log(GPR_DEBUG, "discard %p", bs); incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE); } } @@ -1252,7 +1250,6 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx *exec_ctx, while (s->final_metadata_requested && s->seen_error && (bs = grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames)) != NULL) { - gpr_log(GPR_DEBUG, "discard %p", bs); incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE); } if (s->incoming_frames.head != NULL) { @@ -1277,7 +1274,6 @@ void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_exec_ctx *exec_ctx, if (s->seen_error) { while ((bs = grpc_chttp2_incoming_frame_queue_pop(&s->incoming_frames)) != NULL) { - gpr_log(GPR_DEBUG, "discard %p", bs); incoming_byte_stream_destroy_locked(exec_ctx, bs, GRPC_ERROR_NONE); } } -- cgit v1.2.3 From a22510cb945151227af4b2b0a17df04c3fe6c851 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 28 Sep 2016 11:37:24 -0700 Subject: Merge --- tools/run_tests/tests.json | 266 --------------------------------------------- 1 file changed, 266 deletions(-) diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json index f80458665a..85472c363c 100644 --- a/tools/run_tests/tests.json +++ b/tools/run_tests/tests.json @@ -82228,63 +82228,6 @@ ], "uses_polling": false }, - { - "args": [ - "test/core/nanopb/corpus_response/1b5e3e31c209db047776625d63dad60b99c4f8c4" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 0.1, - "exclude_configs": [ - "tsan" - ], - "flaky": false, - "language": "c", - "name": "nanopb_fuzzer_response_test_one_entry", - "platforms": [ - "linux" - ], - "uses_polling": false - }, - { - "args": [ - "test/core/nanopb/corpus_response/1feac2e01f6059e5c46b77174a2928e267af23a7" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 0.1, - "exclude_configs": [ - "tsan" - ], - "flaky": false, - "language": "c", - "name": "nanopb_fuzzer_response_test_one_entry", - "platforms": [ - "linux" - ], - "uses_polling": false - }, - { - "args": [ - "test/core/nanopb/corpus_response/215424c0703ac1beb18fca2991ab53cef780bdc8" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 0.1, - "exclude_configs": [ - "tsan" - ], - "flaky": false, - "language": "c", - "name": "nanopb_fuzzer_response_test_one_entry", - "platforms": [ - "linux" - ], - "uses_polling": false - }, { "args": [ "test/core/nanopb/corpus_response/23121c5f633db5d7c1a9f2225240754246fee513" @@ -82323,25 +82266,6 @@ ], "uses_polling": false }, - { - "args": [ - "test/core/nanopb/corpus_response/269795add2208946182ff8063b838409ae181147" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 0.1, - "exclude_configs": [ - "tsan" - ], - "flaky": false, - "language": "c", - "name": "nanopb_fuzzer_response_test_one_entry", - "platforms": [ - "linux" - ], - "uses_polling": false - }, { "args": [ "test/core/nanopb/corpus_response/28ed3a797da3c48c309a4ef792147f3c56cfec40" @@ -82475,25 +82399,6 @@ ], "uses_polling": false }, - { - "args": [ - "test/core/nanopb/corpus_response/4326c9dd45537b770f238d868b67ae7fa4dd4339" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 0.1, - "exclude_configs": [ - "tsan" - ], - "flaky": false, - "language": "c", - "name": "nanopb_fuzzer_response_test_one_entry", - "platforms": [ - "linux" - ], - "uses_polling": false - }, { "args": [ "test/core/nanopb/corpus_response/47879cc364be304754f6af15563ad6f9a538da41" @@ -82703,25 +82608,6 @@ ], "uses_polling": false }, - { - "args": [ - "test/core/nanopb/corpus_response/72f663484806227ace334de56e87749ada1b14bf" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 0.1, - "exclude_configs": [ - "tsan" - ], - "flaky": false, - "language": "c", - "name": "nanopb_fuzzer_response_test_one_entry", - "platforms": [ - "linux" - ], - "uses_polling": false - }, { "args": [ "test/core/nanopb/corpus_response/73285d7a70d73b517648067520d921e4477dbbfa" @@ -82931,25 +82817,6 @@ ], "uses_polling": false }, - { - "args": [ - "test/core/nanopb/corpus_response/938e80d928c7f03d1a7ed3d0b4ff4d21619c3b9f" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 0.1, - "exclude_configs": [ - "tsan" - ], - "flaky": false, - "language": "c", - "name": "nanopb_fuzzer_response_test_one_entry", - "platforms": [ - "linux" - ], - "uses_polling": false - }, { "args": [ "test/core/nanopb/corpus_response/95cd94c858e5e97f7df4a5eb7552e5e0d5ce1ec4" @@ -83064,25 +82931,6 @@ ], "uses_polling": false }, - { - "args": [ - "test/core/nanopb/corpus_response/a7e1da726cc81cfccb82d7ef608ee20614ead21d" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 0.1, - "exclude_configs": [ - "tsan" - ], - "flaky": false, - "language": "c", - "name": "nanopb_fuzzer_response_test_one_entry", - "platforms": [ - "linux" - ], - "uses_polling": false - }, { "args": [ "test/core/nanopb/corpus_response/a8a62a7ebb7d68b211ae319e082575935c07d188" @@ -83178,44 +83026,6 @@ ], "uses_polling": false }, - { - "args": [ - "test/core/nanopb/corpus_response/b7c2a1c12efc817db4365b0fb2335e42d5cc0c85" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 0.1, - "exclude_configs": [ - "tsan" - ], - "flaky": false, - "language": "c", - "name": "nanopb_fuzzer_response_test_one_entry", - "platforms": [ - "linux" - ], - "uses_polling": false - }, - { - "args": [ - "test/core/nanopb/corpus_response/be5555929bb0f93603b6c477c7a4be8abf61185e" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 0.1, - "exclude_configs": [ - "tsan" - ], - "flaky": false, - "language": "c", - "name": "nanopb_fuzzer_response_test_one_entry", - "platforms": [ - "linux" - ], - "uses_polling": false - }, { "args": [ "test/core/nanopb/corpus_response/c1eed32e1e353737987da851ad760312ea8e557c" @@ -83273,44 +83083,6 @@ ], "uses_polling": false }, - { - "args": [ - "test/core/nanopb/corpus_response/c732c562f3c10288fad0bf08c1bb3ab811eb1f17" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 0.1, - "exclude_configs": [ - "tsan" - ], - "flaky": false, - "language": "c", - "name": "nanopb_fuzzer_response_test_one_entry", - "platforms": [ - "linux" - ], - "uses_polling": false - }, - { - "args": [ - "test/core/nanopb/corpus_response/cf0bafaa2f3484da47779377f12630191303bbb9" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 0.1, - "exclude_configs": [ - "tsan" - ], - "flaky": false, - "language": "c", - "name": "nanopb_fuzzer_response_test_one_entry", - "platforms": [ - "linux" - ], - "uses_polling": false - }, { "args": [ "test/core/nanopb/corpus_response/d285d78d3ba966b4b199453d38ead1aa36a7484f" @@ -83368,25 +83140,6 @@ ], "uses_polling": false }, - { - "args": [ - "test/core/nanopb/corpus_response/e1c260578eaefc679b41f3bc84eac2aa9e4c805f" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 0.1, - "exclude_configs": [ - "tsan" - ], - "flaky": false, - "language": "c", - "name": "nanopb_fuzzer_response_test_one_entry", - "platforms": [ - "linux" - ], - "uses_polling": false - }, { "args": [ "test/core/nanopb/corpus_response/e53e789a4c175c6a2c468472f1047d0fe8db1177" @@ -83425,25 +83178,6 @@ ], "uses_polling": false }, - { - "args": [ - "test/core/nanopb/corpus_response/e94711da6ea4a9c8fed17ddc5597552f4f81b2fd" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 0.1, - "exclude_configs": [ - "tsan" - ], - "flaky": false, - "language": "c", - "name": "nanopb_fuzzer_response_test_one_entry", - "platforms": [ - "linux" - ], - "uses_polling": false - }, { "args": [ "test/core/nanopb/corpus_response/ead61e86fedf118df8e44ed70ce002be651cf291" -- cgit v1.2.3 From a27eb1d07a78ae5115b0251b1096811722a8174d Mon Sep 17 00:00:00 2001 From: Noah Eisen Date: Wed, 28 Sep 2016 12:19:52 -0700 Subject: added the unimplemented_call test to interop_client.cc. Next step is to call this from the driver program, run_interop_tests.py --- src/proto/grpc/testing/test.proto | 3 +++ test/cpp/interop/client.cc | 9 +++++++-- test/cpp/interop/interop_client.cc | 20 ++++++++++++++++++++ test/cpp/interop/interop_client.h | 1 + 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/proto/grpc/testing/test.proto b/src/proto/grpc/testing/test.proto index 84369db4b8..084d59f8aa 100644 --- a/src/proto/grpc/testing/test.proto +++ b/src/proto/grpc/testing/test.proto @@ -69,6 +69,9 @@ service TestService { // first request. rpc HalfDuplexCall(stream StreamingOutputCallRequest) returns (stream StreamingOutputCallResponse); + + // A call that no server should implement + rpc UnimplementedCall(grpc.testing.Empty) returns (grpc.testing.Empty); } // A simple service NOT implemented at servers so clients can test for diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc index 032b378b1a..51de7ac882 100644 --- a/test/cpp/interop/client.cc +++ b/test/cpp/interop/client.cc @@ -79,7 +79,8 @@ DEFINE_string(test_case, "large_unary", "slow_consumer : single request with response streaming with " "slow client consumer;\n" "status_code_and_message: verify status code & message;\n" - "timeout_on_sleeping_server: deadline exceeds on stream;\n"); + "timeout_on_sleeping_server: deadline exceeds on stream;\n" + "unimplemented_method: client calls an unimplemented_method;\n"); DEFINE_string(default_service_account, "", "Email of GCE default service account"); DEFINE_string(service_account_key_file, "", @@ -149,6 +150,8 @@ int main(int argc, char** argv) { client.DoStatusWithMessage(); } else if (FLAGS_test_case == "custom_metadata") { client.DoCustomMetadata(); + } else if (FLAGS_test_case == "unimplemented_method") { + client.DoUnimplementedMethod(); } else if (FLAGS_test_case == "all") { client.DoEmpty(); client.DoLargeUnary(); @@ -166,6 +169,7 @@ int main(int argc, char** argv) { client.DoEmptyStream(); client.DoStatusWithMessage(); client.DoCustomMetadata(); + client.DoUnimplementedMethod(); // service_account_creds and jwt_token_creds can only run with ssl. if (FLAGS_use_tls) { grpc::string json_key = GetServiceAccountJsonKey(); @@ -198,7 +202,8 @@ int main(int argc, char** argv) { "server_compressed_unary", "server_streaming", "status_code_and_message", - "timeout_on_sleeping_server"}; + "timeout_on_sleeping_server", + "unimplemented_method"}; char* joined_testcases = gpr_strjoin_sep(testcases, GPR_ARRAY_SIZE(testcases), "\n", NULL); diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc index 6117878a33..b43f166b96 100644 --- a/test/cpp/interop/interop_client.cc +++ b/test/cpp/interop/interop_client.cc @@ -937,5 +937,25 @@ bool InteropClient::DoCustomMetadata() { return true; } +bool InteropClient::DoUnimplementedMethod() { + gpr_log(GPR_DEBUG, "Sending a request for an unimplemented rpc..."); + + Empty request = Empty::default_instance(); + Empty response = Empty::default_instance(); + ClientContext context; + + gpr_log(GPR_DEBUG, "here"); + + Status s = serviceStub_.Get()->UnimplementedCall( + &context, request, &response); + + if (!AssertStatusCode(s, StatusCode::UNIMPLEMENTED)) { + return false; + } + + gpr_log(GPR_DEBUG, "unimplemented rpc done."); + return true; +} + } // namespace testing } // namespace grpc diff --git a/test/cpp/interop/interop_client.h b/test/cpp/interop/interop_client.h index eb886fcb7e..a535bf9a5a 100644 --- a/test/cpp/interop/interop_client.h +++ b/test/cpp/interop/interop_client.h @@ -79,6 +79,7 @@ class InteropClient { bool DoEmptyStream(); bool DoStatusWithMessage(); bool DoCustomMetadata(); + bool DoUnimplementedMethod(); // Auth tests. // username is a string containing the user email bool DoJwtTokenCreds(const grpc::string& username); -- cgit v1.2.3 From 02e70ed120120b95f35862d5af8988ec18812ca6 Mon Sep 17 00:00:00 2001 From: Noah Eisen Date: Wed, 28 Sep 2016 14:17:25 -0700 Subject: changed method name in test.proto to more accurately reflect how the calls will be used --- src/proto/grpc/testing/test.proto | 5 +++-- test/cpp/interop/interop_client.cc | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/proto/grpc/testing/test.proto b/src/proto/grpc/testing/test.proto index 084d59f8aa..801baf8b3b 100644 --- a/src/proto/grpc/testing/test.proto +++ b/src/proto/grpc/testing/test.proto @@ -70,8 +70,9 @@ service TestService { rpc HalfDuplexCall(stream StreamingOutputCallRequest) returns (stream StreamingOutputCallResponse); - // A call that no server should implement - rpc UnimplementedCall(grpc.testing.Empty) returns (grpc.testing.Empty); + // The test server will not implement this method. It will be used + // to test the behavior when clients call unimplemented methods. + rpc UnimplementedMethod(grpc.testing.Empty) returns (grpc.testing.Empty); } // A simple service NOT implemented at servers so clients can test for diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc index b43f166b96..65519a03a8 100644 --- a/test/cpp/interop/interop_client.cc +++ b/test/cpp/interop/interop_client.cc @@ -944,15 +944,15 @@ bool InteropClient::DoUnimplementedMethod() { Empty response = Empty::default_instance(); ClientContext context; - gpr_log(GPR_DEBUG, "here"); - - Status s = serviceStub_.Get()->UnimplementedCall( + Status s = serviceStub_.Get()->UnimplementedMethod( &context, request, &response); if (!AssertStatusCode(s, StatusCode::UNIMPLEMENTED)) { return false; } + GPR_ASSERT(s.error_message().empty()); + gpr_log(GPR_DEBUG, "unimplemented rpc done."); return true; } -- cgit v1.2.3 From 13a6008c55c1737262d55ee12c44393dcb419c08 Mon Sep 17 00:00:00 2001 From: Noah Eisen Date: Wed, 28 Sep 2016 15:28:22 -0700 Subject: updated interop test driver to run the advanced tests from a c++ client, since they are now all implemented --- tools/run_tests/run_interop_tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index 389d070d63..310cfe674e 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -89,7 +89,7 @@ class CXXLanguage: return {} def unimplemented_test_cases(self): - return _SKIP_ADVANCED + return [] def unimplemented_test_cases_server(self): return _SKIP_ADVANCED -- cgit v1.2.3 From 2e9661c67176d0bf8eca8b1405ff78b9aa6efb42 Mon Sep 17 00:00:00 2001 From: Noah Eisen Date: Wed, 28 Sep 2016 16:41:36 -0700 Subject: Update interop-test-descriptions.md --- doc/interop-test-descriptions.md | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/doc/interop-test-descriptions.md b/doc/interop-test-descriptions.md index 1e04966380..d9799c66c0 100644 --- a/doc/interop-test-descriptions.md +++ b/doc/interop-test-descriptions.md @@ -750,9 +750,29 @@ Client asserts: ### unimplemented_method -Status: Ready for implementation. Blocking beta. +This test verifies that calling an unimplemented RPC method returns the +UNIMPLEMENTED status code -This test verifies calling unimplemented RPC method returns the UNIMPLEMENTED status code. +Server features: +N/A + +Procedure: +* Client calls `grpc.testing.TestService/UnimplementedMethod` with an empty + request (defined as `grpc.testing.Empty`): + + ``` + { + } + ``` + +Client asserts: +* received status code is 12 (UNIMPLEMENTED) +* received status message is empty or null/unset + +### unimplemented_service + +This test verifies calling an unimplemented server returns the UNIMPLEMENTED +status code. Server features: N/A -- cgit v1.2.3 From 55cb2363c64f7ee8e8d5822276e939eb60ac0ecc Mon Sep 17 00:00:00 2001 From: Noah Eisen Date: Wed, 28 Sep 2016 17:01:54 -0700 Subject: fixed typo in the updated interop test description file --- doc/interop-test-descriptions.md | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/doc/interop-test-descriptions.md b/doc/interop-test-descriptions.md index d9799c66c0..6a3979d117 100644 --- a/doc/interop-test-descriptions.md +++ b/doc/interop-test-descriptions.md @@ -751,7 +751,7 @@ Client asserts: ### unimplemented_method This test verifies that calling an unimplemented RPC method returns the -UNIMPLEMENTED status code +UNIMPLEMENTED status code. Server features: N/A @@ -779,12 +779,7 @@ N/A Procedure: * Client calls `grpc.testing.UnimplementedService/UnimplementedCall` with an - empty request (defined as `grpc.testing.Empty`): - - ``` - { - } - ``` + empty request (defined as `grpc.testing.Empty`) Client asserts: * received status code is 12 (UNIMPLEMENTED) -- cgit v1.2.3 From e02c7ed37b1f98ed95b8f47e053d4a617fd7c530 Mon Sep 17 00:00:00 2001 From: Ken Payson Date: Thu, 29 Sep 2016 09:15:49 -0700 Subject: Broke cv polling into seperate engine --- BUILD | 12 + CMakeLists.txt | 5 + Makefile | 6 + binding.gyp | 1 + build.yaml | 2 + config.m4 | 1 + gRPC-Core.podspec | 3 + grpc.gemspec | 2 + package.xml | 2 + src/core/lib/iomgr/ev_poll_cv_posix.c | 282 +++++++++++++++++++++ src/core/lib/iomgr/ev_poll_cv_posix.h | 65 +++++ src/core/lib/iomgr/ev_posix.c | 2 + src/core/lib/iomgr/wakeup_fd_cv.c | 230 +---------------- src/core/lib/iomgr/wakeup_fd_cv.h | 5 +- src/core/lib/iomgr/wakeup_fd_posix.c | 9 +- src/core/lib/iomgr/wakeup_fd_posix.h | 1 + src/python/grpcio/grpc_core_dependencies.py | 1 + test/core/iomgr/wakeup_fd_cv_test.c | 19 +- tools/doxygen/Doxyfile.c++.internal | 2 + tools/doxygen/Doxyfile.core.internal | 2 + tools/run_tests/run_tests.py | 2 +- tools/run_tests/sources_and_headers.json | 3 + vsprojects/vcxproj/grpc++/grpc++.vcxproj | 3 + vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters | 6 + .../grpc++_unsecure/grpc++_unsecure.vcxproj | 3 + .../grpc++_unsecure.vcxproj.filters | 6 + vsprojects/vcxproj/grpc/grpc.vcxproj | 3 + vsprojects/vcxproj/grpc/grpc.vcxproj.filters | 6 + .../vcxproj/grpc_test_util/grpc_test_util.vcxproj | 3 + .../grpc_test_util/grpc_test_util.vcxproj.filters | 6 + .../vcxproj/grpc_unsecure/grpc_unsecure.vcxproj | 3 + .../grpc_unsecure/grpc_unsecure.vcxproj.filters | 6 + 32 files changed, 463 insertions(+), 239 deletions(-) create mode 100644 src/core/lib/iomgr/ev_poll_cv_posix.c create mode 100644 src/core/lib/iomgr/ev_poll_cv_posix.h diff --git a/BUILD b/BUILD index 67e481e0d2..a8d1b4a5b9 100644 --- a/BUILD +++ b/BUILD @@ -184,6 +184,7 @@ cc_library( "src/core/lib/iomgr/error.h", "src/core/lib/iomgr/ev_epoll_linux.h", "src/core/lib/iomgr/ev_poll_and_epoll_posix.h", + "src/core/lib/iomgr/ev_poll_cv_posix.h", "src/core/lib/iomgr/ev_poll_posix.h", "src/core/lib/iomgr/ev_posix.h", "src/core/lib/iomgr/exec_ctx.h", @@ -341,6 +342,7 @@ cc_library( "src/core/lib/iomgr/error.c", "src/core/lib/iomgr/ev_epoll_linux.c", "src/core/lib/iomgr/ev_poll_and_epoll_posix.c", + "src/core/lib/iomgr/ev_poll_cv_posix.c", "src/core/lib/iomgr/ev_poll_posix.c", "src/core/lib/iomgr/ev_posix.c", "src/core/lib/iomgr/exec_ctx.c", @@ -581,6 +583,7 @@ cc_library( "src/core/lib/iomgr/error.h", "src/core/lib/iomgr/ev_epoll_linux.h", "src/core/lib/iomgr/ev_poll_and_epoll_posix.h", + "src/core/lib/iomgr/ev_poll_cv_posix.h", "src/core/lib/iomgr/ev_poll_posix.h", "src/core/lib/iomgr/ev_posix.h", "src/core/lib/iomgr/exec_ctx.h", @@ -724,6 +727,7 @@ cc_library( "src/core/lib/iomgr/error.c", "src/core/lib/iomgr/ev_epoll_linux.c", "src/core/lib/iomgr/ev_poll_and_epoll_posix.c", + "src/core/lib/iomgr/ev_poll_cv_posix.c", "src/core/lib/iomgr/ev_poll_posix.c", "src/core/lib/iomgr/ev_posix.c", "src/core/lib/iomgr/exec_ctx.c", @@ -935,6 +939,7 @@ cc_library( "src/core/lib/iomgr/error.h", "src/core/lib/iomgr/ev_epoll_linux.h", "src/core/lib/iomgr/ev_poll_and_epoll_posix.h", + "src/core/lib/iomgr/ev_poll_cv_posix.h", "src/core/lib/iomgr/ev_poll_posix.h", "src/core/lib/iomgr/ev_posix.h", "src/core/lib/iomgr/exec_ctx.h", @@ -1069,6 +1074,7 @@ cc_library( "src/core/lib/iomgr/error.c", "src/core/lib/iomgr/ev_epoll_linux.c", "src/core/lib/iomgr/ev_poll_and_epoll_posix.c", + "src/core/lib/iomgr/ev_poll_cv_posix.c", "src/core/lib/iomgr/ev_poll_posix.c", "src/core/lib/iomgr/ev_posix.c", "src/core/lib/iomgr/exec_ctx.c", @@ -1284,6 +1290,7 @@ cc_library( "src/core/lib/iomgr/error.h", "src/core/lib/iomgr/ev_epoll_linux.h", "src/core/lib/iomgr/ev_poll_and_epoll_posix.h", + "src/core/lib/iomgr/ev_poll_cv_posix.h", "src/core/lib/iomgr/ev_poll_posix.h", "src/core/lib/iomgr/ev_posix.h", "src/core/lib/iomgr/exec_ctx.h", @@ -1398,6 +1405,7 @@ cc_library( "src/core/lib/iomgr/error.c", "src/core/lib/iomgr/ev_epoll_linux.c", "src/core/lib/iomgr/ev_poll_and_epoll_posix.c", + "src/core/lib/iomgr/ev_poll_cv_posix.c", "src/core/lib/iomgr/ev_poll_posix.c", "src/core/lib/iomgr/ev_posix.c", "src/core/lib/iomgr/exec_ctx.c", @@ -1696,6 +1704,7 @@ cc_library( "src/core/lib/iomgr/error.h", "src/core/lib/iomgr/ev_epoll_linux.h", "src/core/lib/iomgr/ev_poll_and_epoll_posix.h", + "src/core/lib/iomgr/ev_poll_cv_posix.h", "src/core/lib/iomgr/ev_poll_posix.h", "src/core/lib/iomgr/ev_posix.h", "src/core/lib/iomgr/exec_ctx.h", @@ -1805,6 +1814,7 @@ cc_library( "src/core/lib/iomgr/error.c", "src/core/lib/iomgr/ev_epoll_linux.c", "src/core/lib/iomgr/ev_poll_and_epoll_posix.c", + "src/core/lib/iomgr/ev_poll_cv_posix.c", "src/core/lib/iomgr/ev_poll_posix.c", "src/core/lib/iomgr/ev_posix.c", "src/core/lib/iomgr/exec_ctx.c", @@ -2196,6 +2206,7 @@ objc_library( "src/core/lib/iomgr/error.c", "src/core/lib/iomgr/ev_epoll_linux.c", "src/core/lib/iomgr/ev_poll_and_epoll_posix.c", + "src/core/lib/iomgr/ev_poll_cv_posix.c", "src/core/lib/iomgr/ev_poll_posix.c", "src/core/lib/iomgr/ev_posix.c", "src/core/lib/iomgr/exec_ctx.c", @@ -2415,6 +2426,7 @@ objc_library( "src/core/lib/iomgr/error.h", "src/core/lib/iomgr/ev_epoll_linux.h", "src/core/lib/iomgr/ev_poll_and_epoll_posix.h", + "src/core/lib/iomgr/ev_poll_cv_posix.h", "src/core/lib/iomgr/ev_poll_posix.h", "src/core/lib/iomgr/ev_posix.h", "src/core/lib/iomgr/exec_ctx.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index f07fa26e63..1f8c4ca0f0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -313,6 +313,7 @@ add_library(grpc src/core/lib/iomgr/error.c src/core/lib/iomgr/ev_epoll_linux.c src/core/lib/iomgr/ev_poll_and_epoll_posix.c + src/core/lib/iomgr/ev_poll_cv_posix.c src/core/lib/iomgr/ev_poll_posix.c src/core/lib/iomgr/ev_posix.c src/core/lib/iomgr/exec_ctx.c @@ -572,6 +573,7 @@ add_library(grpc_cronet src/core/lib/iomgr/error.c src/core/lib/iomgr/ev_epoll_linux.c src/core/lib/iomgr/ev_poll_and_epoll_posix.c + src/core/lib/iomgr/ev_poll_cv_posix.c src/core/lib/iomgr/ev_poll_posix.c src/core/lib/iomgr/ev_posix.c src/core/lib/iomgr/exec_ctx.c @@ -804,6 +806,7 @@ add_library(grpc_unsecure src/core/lib/iomgr/error.c src/core/lib/iomgr/ev_epoll_linux.c src/core/lib/iomgr/ev_poll_and_epoll_posix.c + src/core/lib/iomgr/ev_poll_cv_posix.c src/core/lib/iomgr/ev_poll_posix.c src/core/lib/iomgr/ev_posix.c src/core/lib/iomgr/exec_ctx.c @@ -1062,6 +1065,7 @@ add_library(grpc++ src/core/lib/iomgr/error.c src/core/lib/iomgr/ev_epoll_linux.c src/core/lib/iomgr/ev_poll_and_epoll_posix.c + src/core/lib/iomgr/ev_poll_cv_posix.c src/core/lib/iomgr/ev_poll_posix.c src/core/lib/iomgr/ev_posix.c src/core/lib/iomgr/exec_ctx.c @@ -1420,6 +1424,7 @@ add_library(grpc++_unsecure src/core/lib/iomgr/error.c src/core/lib/iomgr/ev_epoll_linux.c src/core/lib/iomgr/ev_poll_and_epoll_posix.c + src/core/lib/iomgr/ev_poll_cv_posix.c src/core/lib/iomgr/ev_poll_posix.c src/core/lib/iomgr/ev_posix.c src/core/lib/iomgr/exec_ctx.c diff --git a/Makefile b/Makefile index a23e12687d..0b23fc44bc 100644 --- a/Makefile +++ b/Makefile @@ -2538,6 +2538,7 @@ LIBGRPC_SRC = \ src/core/lib/iomgr/error.c \ src/core/lib/iomgr/ev_epoll_linux.c \ src/core/lib/iomgr/ev_poll_and_epoll_posix.c \ + src/core/lib/iomgr/ev_poll_cv_posix.c \ src/core/lib/iomgr/ev_poll_posix.c \ src/core/lib/iomgr/ev_posix.c \ src/core/lib/iomgr/exec_ctx.c \ @@ -2815,6 +2816,7 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/iomgr/error.c \ src/core/lib/iomgr/ev_epoll_linux.c \ src/core/lib/iomgr/ev_poll_and_epoll_posix.c \ + src/core/lib/iomgr/ev_poll_cv_posix.c \ src/core/lib/iomgr/ev_poll_posix.c \ src/core/lib/iomgr/ev_posix.c \ src/core/lib/iomgr/exec_ctx.c \ @@ -3081,6 +3083,7 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/lib/iomgr/error.c \ src/core/lib/iomgr/ev_epoll_linux.c \ src/core/lib/iomgr/ev_poll_and_epoll_posix.c \ + src/core/lib/iomgr/ev_poll_cv_posix.c \ src/core/lib/iomgr/ev_poll_posix.c \ src/core/lib/iomgr/ev_posix.c \ src/core/lib/iomgr/exec_ctx.c \ @@ -3275,6 +3278,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/iomgr/error.c \ src/core/lib/iomgr/ev_epoll_linux.c \ src/core/lib/iomgr/ev_poll_and_epoll_posix.c \ + src/core/lib/iomgr/ev_poll_cv_posix.c \ src/core/lib/iomgr/ev_poll_posix.c \ src/core/lib/iomgr/ev_posix.c \ src/core/lib/iomgr/exec_ctx.c \ @@ -3616,6 +3620,7 @@ LIBGRPC++_SRC = \ src/core/lib/iomgr/error.c \ src/core/lib/iomgr/ev_epoll_linux.c \ src/core/lib/iomgr/ev_poll_and_epoll_posix.c \ + src/core/lib/iomgr/ev_poll_cv_posix.c \ src/core/lib/iomgr/ev_poll_posix.c \ src/core/lib/iomgr/ev_posix.c \ src/core/lib/iomgr/exec_ctx.c \ @@ -4252,6 +4257,7 @@ LIBGRPC++_UNSECURE_SRC = \ src/core/lib/iomgr/error.c \ src/core/lib/iomgr/ev_epoll_linux.c \ src/core/lib/iomgr/ev_poll_and_epoll_posix.c \ + src/core/lib/iomgr/ev_poll_cv_posix.c \ src/core/lib/iomgr/ev_poll_posix.c \ src/core/lib/iomgr/ev_posix.c \ src/core/lib/iomgr/exec_ctx.c \ diff --git a/binding.gyp b/binding.gyp index 1b68b63d22..d97b1410e1 100644 --- a/binding.gyp +++ b/binding.gyp @@ -585,6 +585,7 @@ 'src/core/lib/iomgr/error.c', 'src/core/lib/iomgr/ev_epoll_linux.c', 'src/core/lib/iomgr/ev_poll_and_epoll_posix.c', + 'src/core/lib/iomgr/ev_poll_cv_posix.c', 'src/core/lib/iomgr/ev_poll_posix.c', 'src/core/lib/iomgr/ev_posix.c', 'src/core/lib/iomgr/exec_ctx.c', diff --git a/build.yaml b/build.yaml index d4f731e85f..7693c911f9 100644 --- a/build.yaml +++ b/build.yaml @@ -186,6 +186,7 @@ filegroups: - src/core/lib/iomgr/error.h - src/core/lib/iomgr/ev_epoll_linux.h - src/core/lib/iomgr/ev_poll_and_epoll_posix.h + - src/core/lib/iomgr/ev_poll_cv_posix.h - src/core/lib/iomgr/ev_poll_posix.h - src/core/lib/iomgr/ev_posix.h - src/core/lib/iomgr/exec_ctx.h @@ -268,6 +269,7 @@ filegroups: - src/core/lib/iomgr/error.c - src/core/lib/iomgr/ev_epoll_linux.c - src/core/lib/iomgr/ev_poll_and_epoll_posix.c + - src/core/lib/iomgr/ev_poll_cv_posix.c - src/core/lib/iomgr/ev_poll_posix.c - src/core/lib/iomgr/ev_posix.c - src/core/lib/iomgr/exec_ctx.c diff --git a/config.m4 b/config.m4 index 6b605fbcd6..bebcab601a 100644 --- a/config.m4 +++ b/config.m4 @@ -104,6 +104,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/iomgr/error.c \ src/core/lib/iomgr/ev_epoll_linux.c \ src/core/lib/iomgr/ev_poll_and_epoll_posix.c \ + src/core/lib/iomgr/ev_poll_cv_posix.c \ src/core/lib/iomgr/ev_poll_posix.c \ src/core/lib/iomgr/ev_posix.c \ src/core/lib/iomgr/exec_ctx.c \ diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 92b3022cf7..73953cc8bd 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -275,6 +275,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/error.h', 'src/core/lib/iomgr/ev_epoll_linux.h', 'src/core/lib/iomgr/ev_poll_and_epoll_posix.h', + 'src/core/lib/iomgr/ev_poll_cv_posix.h', 'src/core/lib/iomgr/ev_poll_posix.h', 'src/core/lib/iomgr/ev_posix.h', 'src/core/lib/iomgr/exec_ctx.h', @@ -436,6 +437,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/error.c', 'src/core/lib/iomgr/ev_epoll_linux.c', 'src/core/lib/iomgr/ev_poll_and_epoll_posix.c', + 'src/core/lib/iomgr/ev_poll_cv_posix.c', 'src/core/lib/iomgr/ev_poll_posix.c', 'src/core/lib/iomgr/ev_posix.c', 'src/core/lib/iomgr/exec_ctx.c', @@ -639,6 +641,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/error.h', 'src/core/lib/iomgr/ev_epoll_linux.h', 'src/core/lib/iomgr/ev_poll_and_epoll_posix.h', + 'src/core/lib/iomgr/ev_poll_cv_posix.h', 'src/core/lib/iomgr/ev_poll_posix.h', 'src/core/lib/iomgr/ev_posix.h', 'src/core/lib/iomgr/exec_ctx.h', diff --git a/grpc.gemspec b/grpc.gemspec index d672bb1284..64441ead59 100755 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -195,6 +195,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/error.h ) s.files += %w( src/core/lib/iomgr/ev_epoll_linux.h ) s.files += %w( src/core/lib/iomgr/ev_poll_and_epoll_posix.h ) + s.files += %w( src/core/lib/iomgr/ev_poll_cv_posix.h ) s.files += %w( src/core/lib/iomgr/ev_poll_posix.h ) s.files += %w( src/core/lib/iomgr/ev_posix.h ) s.files += %w( src/core/lib/iomgr/exec_ctx.h ) @@ -356,6 +357,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/error.c ) s.files += %w( src/core/lib/iomgr/ev_epoll_linux.c ) s.files += %w( src/core/lib/iomgr/ev_poll_and_epoll_posix.c ) + s.files += %w( src/core/lib/iomgr/ev_poll_cv_posix.c ) s.files += %w( src/core/lib/iomgr/ev_poll_posix.c ) s.files += %w( src/core/lib/iomgr/ev_posix.c ) s.files += %w( src/core/lib/iomgr/exec_ctx.c ) diff --git a/package.xml b/package.xml index 02cc271fe5..3e2d9d278c 100644 --- a/package.xml +++ b/package.xml @@ -202,6 +202,7 @@ + @@ -363,6 +364,7 @@ + diff --git a/src/core/lib/iomgr/ev_poll_cv_posix.c b/src/core/lib/iomgr/ev_poll_cv_posix.c new file mode 100644 index 0000000000..596a3025eb --- /dev/null +++ b/src/core/lib/iomgr/ev_poll_cv_posix.c @@ -0,0 +1,282 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include + +#ifdef GPR_POSIX_SOCKET + +#include "src/core/lib/iomgr/ev_poll_cv_posix.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "src/core/lib/iomgr/ev_poll_posix.h" +#include "src/core/lib/iomgr/wakeup_fd_posix.h" + +#define POLL_PERIOD_MS 1000 +#define DEFAULT_TABLE_SIZE 16 + +// poll_result is owned by parent thread +typedef struct poll_result { + struct pollfd* fds; + gpr_cv* cv; + int completed; + int res; + int err; +} poll_result; + +// poll_args is owned by spawned thread +typedef struct poll_args { + struct pollfd* fds; + nfds_t nfds; + int timeout; + poll_result* result; +} poll_args; + +cv_fd_table g_cvfds; + +// Poll in a background thread +static void run_poll(void* arg) { + int result, timeout; + poll_args* pargs = (poll_args*)arg; + gpr_mu_lock(&g_cvfds.mu); + if (pargs->result != NULL) { + while (pargs->result != NULL) { + if (pargs->timeout < 0) { + timeout = POLL_PERIOD_MS; + } else { + timeout = GPR_MIN(POLL_PERIOD_MS, pargs->timeout); + pargs->timeout -= timeout; + } + gpr_mu_unlock(&g_cvfds.mu); + result = g_cvfds.poll(pargs->fds, pargs->nfds, timeout); + gpr_mu_lock(&g_cvfds.mu); + if (pargs->result != NULL) { + if (result != 0 || pargs->timeout == 0) { + memcpy(pargs->result->fds, pargs->fds, + sizeof(struct pollfd) * pargs->nfds); + pargs->result->res = result; + pargs->result->err = errno; + pargs->result->completed = 1; + gpr_cv_signal(pargs->result->cv); + break; + } + } + } + } + gpr_free(pargs->fds); + gpr_free(pargs); + gpr_mu_unlock(&g_cvfds.mu); +} + +// This function overrides poll() to handle condition variable wakeup fds +static int cvfd_poll(struct pollfd* fds, nfds_t nfds, int timeout) { + unsigned int i; + int res, idx; + cv_node *cvn, *prev; + struct pollfd* sockfds; + nfds_t nsockfds = 0; + gpr_cv pollcv; + gpr_thd_id t_id; + gpr_thd_options opt; + poll_args* pargs; + poll_result* pres; + gpr_mu_lock(&g_cvfds.mu); + gpr_cv_init(&pollcv); + for (i = 0; i < nfds; i++) { + fds[i].revents = 0; + if (fds[i].fd < 0 && (fds[i].events & POLLIN)) { + idx = FD_TO_IDX(fds[i].fd); + cvn = gpr_malloc(sizeof(cv_node)); + cvn->cv = &pollcv; + cvn->next = g_cvfds.cvfds[idx].cvs; + g_cvfds.cvfds[idx].cvs = cvn; + // We should return immediately if there are pending events, + // but we still need to call poll() to check for socket events + if (g_cvfds.cvfds[idx].is_set) { + timeout = 0; + } + } else if (fds[i].fd >= 0) { + nsockfds++; + } + } + sockfds = gpr_malloc(sizeof(struct pollfd) * nsockfds); + idx = 0; + for (i = 0; i < nfds; i++) { + if (fds[i].fd >= 0) { + sockfds[idx].fd = fds[i].fd; + sockfds[idx].events = fds[i].events; + sockfds[idx].revents = 0; + idx++; + } + } + + errno = 0; + if (nsockfds > 0) { + pres = gpr_malloc(sizeof(struct poll_result)); + pargs = gpr_malloc(sizeof(struct poll_args)); + + pargs->fds = gpr_malloc(sizeof(struct pollfd) * nsockfds); + memcpy(pargs->fds, sockfds, sizeof(struct pollfd) * nsockfds); + pargs->nfds = nsockfds; + pargs->timeout = timeout; + pargs->result = pres; + + pres->fds = sockfds; + pres->cv = &pollcv; + pres->completed = 0; + pres->res = 0; + pres->err = 0; + + opt = gpr_thd_options_default(); + gpr_thd_options_set_detached(&opt); + gpr_thd_new(&t_id, &run_poll, pargs, &opt); + // We want the poll() thread to trigger the deadline, so wait forever here + gpr_cv_wait(&pollcv, &g_cvfds.mu, gpr_inf_future(GPR_CLOCK_MONOTONIC)); + if (!pres->completed) { + pargs->result = NULL; + } + res = pres->res; + errno = pres->err; + gpr_free(pres); + } else { + gpr_timespec deadline = gpr_now(GPR_CLOCK_REALTIME); + deadline = + gpr_time_add(deadline, gpr_time_from_millis(timeout, GPR_TIMESPAN)); + gpr_cv_wait(&pollcv, &g_cvfds.mu, deadline); + res = 0; + } + idx = 0; + for (i = 0; i < nfds; i++) { + if (fds[i].fd < 0 && (fds[i].events & POLLIN)) { + cvn = g_cvfds.cvfds[FD_TO_IDX(fds[i].fd)].cvs; + prev = NULL; + while (cvn->cv != &pollcv) { + prev = cvn; + cvn = cvn->next; + GPR_ASSERT(cvn); + } + if (!prev) { + g_cvfds.cvfds[FD_TO_IDX(fds[i].fd)].cvs = cvn->next; + } else { + prev->next = cvn->next; + } + gpr_free(cvn); + + if (g_cvfds.cvfds[FD_TO_IDX(fds[i].fd)].is_set) { + fds[i].revents = POLLIN; + if (res >= 0) res++; + } + } else if (fds[i].fd >= 0) { + fds[i].revents = sockfds[idx].revents; + idx++; + } + } + gpr_free(sockfds); + gpr_cv_destroy(&pollcv); + gpr_mu_unlock(&g_cvfds.mu); + + return res; +} + +static void grpc_global_cv_fd_table_init() { + gpr_mu_init(&g_cvfds.mu); + gpr_mu_lock(&g_cvfds.mu); + g_cvfds.size = DEFAULT_TABLE_SIZE; + g_cvfds.cvfds = gpr_malloc(sizeof(fd_node) * DEFAULT_TABLE_SIZE); + g_cvfds.free_fds = NULL; + for (int i = 0; i < DEFAULT_TABLE_SIZE; i++) { + g_cvfds.cvfds[i].is_set = 0; + g_cvfds.cvfds[i].cvs = NULL; + g_cvfds.cvfds[i].next_free = g_cvfds.free_fds; + g_cvfds.free_fds = &g_cvfds.cvfds[i]; + } + // Override the poll function with one that supports cvfds + g_cvfds.poll = grpc_poll_function; + grpc_poll_function = &cvfd_poll; + gpr_mu_unlock(&g_cvfds.mu); +} + +static void grpc_global_cv_fd_table_shutdown() { + gpr_mu_lock(&g_cvfds.mu); + grpc_poll_function = g_cvfds.poll; + gpr_free(g_cvfds.cvfds); + gpr_mu_unlock(&g_cvfds.mu); + gpr_mu_destroy(&g_cvfds.mu); +} + +/******************************************************************************* + * event engine binding + */ + +static const grpc_event_engine_vtable* ev_poll_vtable; +static grpc_event_engine_vtable vtable; + +static void shutdown_engine(void) { + ev_poll_vtable->shutdown_engine(); + grpc_global_cv_fd_table_shutdown(); +} + +const grpc_event_engine_vtable* grpc_init_poll_cv_posix(void) { + int has_wakeup_fd = grpc_has_wakeup_fd; + int allow_specialized_wakeup_fd = grpc_allow_specialized_wakeup_fd; + int allow_pipe_wakeup_fd = grpc_allow_pipe_wakeup_fd; + grpc_global_cv_fd_table_init(); + grpc_has_wakeup_fd = 1; + grpc_allow_specialized_wakeup_fd = 0; + grpc_allow_pipe_wakeup_fd = 0; + grpc_wakeup_fd_global_init(); + ev_poll_vtable = grpc_init_poll_posix(); + if (!ev_poll_vtable) { + grpc_global_cv_fd_table_shutdown(); + grpc_has_wakeup_fd = has_standard_wakeup_fd; + grpc_allow_specialized_wakeup_fd = allow_specialized_wakeup_fd; + grpc_allow_pipe_wakeup_fd = allow_pipe_wakeup_fd; + grpc_has_wakeup_fd = has_standard_wakeup_fd; + grpc_global_cv_fd_table_init(); + return NULL; + } + + vtable = *ev_poll_vtable; + vtable.shutdown_engine = shutdown_engine; + return &vtable; +} + +#endif /* GPR_POSIX_SOCKET */ diff --git a/src/core/lib/iomgr/ev_poll_cv_posix.h b/src/core/lib/iomgr/ev_poll_cv_posix.h new file mode 100644 index 0000000000..0fd3e5bbb4 --- /dev/null +++ b/src/core/lib/iomgr/ev_poll_cv_posix.h @@ -0,0 +1,65 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPC_CORE_LIB_IOMGR_EV_POLL_CV_POSIX_H +#define GRPC_CORE_LIB_IOMGR_EV_POLL_CV_POSIX_H + +#include + +#include "src/core/lib/iomgr/ev_posix.h" + +#define FD_TO_IDX(fd) (-(fd)-1) +#define IDX_TO_FD(idx) (-(idx)-1) + +typedef struct cv_node { + gpr_cv* cv; + struct cv_node* next; +} cv_node; + +typedef struct fd_node { + int is_set; + cv_node* cvs; + struct fd_node* next_free; +} fd_node; + +typedef struct cv_fd_table { + gpr_mu mu; + fd_node* cvfds; + fd_node* free_fds; + unsigned int size; + grpc_poll_function_type poll; +} cv_fd_table; + +const grpc_event_engine_vtable* grpc_init_poll_cv_posix(void); + +#endif /* GRPC_CORE_LIB_IOMGR_EV_POLL_POSIX_H */ diff --git a/src/core/lib/iomgr/ev_posix.c b/src/core/lib/iomgr/ev_posix.c index 6536672685..2fc8ccfa91 100644 --- a/src/core/lib/iomgr/ev_posix.c +++ b/src/core/lib/iomgr/ev_posix.c @@ -46,6 +46,7 @@ #include "src/core/lib/iomgr/ev_epoll_linux.h" #include "src/core/lib/iomgr/ev_poll_and_epoll_posix.h" +#include "src/core/lib/iomgr/ev_poll_cv_posix.h" #include "src/core/lib/iomgr/ev_poll_posix.h" #include "src/core/lib/support/env.h" @@ -66,6 +67,7 @@ typedef struct { static const event_engine_factory g_factories[] = { {"epoll", grpc_init_epoll_linux}, {"poll", grpc_init_poll_posix}, + {"poll-cv", grpc_init_poll_cv_posix}, {"legacy", grpc_init_poll_and_epoll_posix}, }; diff --git a/src/core/lib/iomgr/wakeup_fd_cv.c b/src/core/lib/iomgr/wakeup_fd_cv.c index bfdc2cb422..651e2f663d 100644 --- a/src/core/lib/iomgr/wakeup_fd_cv.c +++ b/src/core/lib/iomgr/wakeup_fd_cv.c @@ -35,8 +35,6 @@ #ifdef GPR_POSIX_WAKEUP_FD -#include "src/core/lib/iomgr/wakeup_fd_posix.h" - #include #include @@ -47,200 +45,16 @@ #include #include -#include "src/core/lib/iomgr/ev_posix.h" +#include "src/core/lib/iomgr/ev_poll_cv_posix.h" #define MAX_TABLE_RESIZE 256 -#define DEFAULT_TABLE_SIZE 16 -#define POLL_PERIOD_MS 1000 - -#define FD_TO_IDX(fd) (-(fd)-1) -#define IDX_TO_FD(idx) (-(idx)-1) - -typedef struct cv_node { - gpr_cv* cv; - struct cv_node* next; -} cv_node; - -typedef struct fd_node { - int is_set; - cv_node* cvs; - struct fd_node* next_free; -} fd_node; - -typedef struct cv_fd_table { - fd_node* cvfds; - fd_node* free_fds; - unsigned int size; - grpc_poll_function_type poll; -} cv_fd_table; - -typedef struct poll_result { - struct pollfd* fds; - gpr_cv* cv; - int completed; - int res; - int err; -} poll_result; - -typedef struct poll_args { - struct pollfd* fds; - nfds_t nfds; - int timeout; - poll_result* result; -} poll_args; - -static gpr_mu g_mu = PTHREAD_MUTEX_INITIALIZER; -static cv_fd_table g_cvfds; - -// Some environments do not implement pthread_cancel(), so we run -// this poll in a detached thread, and wake up periodically and -// check if the calling thread is still waiting on a result -static void run_poll(void* arg) { - int result, timeout; - poll_args* pargs = (poll_args*)arg; - gpr_mu_lock(&g_mu); - if (pargs->result != NULL) { - while (pargs->result != NULL) { - if (pargs->timeout < 0) { - timeout = POLL_PERIOD_MS; - } else { - timeout = GPR_MIN(POLL_PERIOD_MS, pargs->timeout); - pargs->timeout -= timeout; - } - gpr_mu_unlock(&g_mu); - result = g_cvfds.poll(pargs->fds, pargs->nfds, timeout); - gpr_mu_lock(&g_mu); - if (pargs->result != NULL) { - if (result != 0 || pargs->timeout == 0) { - memcpy(pargs->result->fds, pargs->fds, - sizeof(struct pollfd) * pargs->nfds); - pargs->result->res = result; - pargs->result->err = errno; - pargs->result->completed = 1; - gpr_cv_signal(pargs->result->cv); - break; - } - } - } - } - gpr_free(pargs->fds); - gpr_free(pargs); - gpr_mu_unlock(&g_mu); -} - -int cvfd_poll(struct pollfd* fds, nfds_t nfds, int timeout) { - unsigned int i; - int res, idx; - cv_node *cvn, *prev; - struct pollfd* sockfds; - nfds_t nsockfds = 0; - gpr_cv pollcv; - gpr_thd_id t_id; - gpr_thd_options opt; - poll_args* pargs; - poll_result* pres; - gpr_mu_lock(&g_mu); - gpr_cv_init(&pollcv); - for (i = 0; i < nfds; i++) { - fds[i].revents = 0; - if (fds[i].fd < 0 && (fds[i].events & POLLIN)) { - idx = FD_TO_IDX(fds[i].fd); - cvn = gpr_malloc(sizeof(cv_node)); - cvn->cv = &pollcv; - cvn->next = g_cvfds.cvfds[idx].cvs; - g_cvfds.cvfds[idx].cvs = cvn; - // We should return immediately if there are pending events, - // but we still need to call poll() to check for socket events - if (g_cvfds.cvfds[idx].is_set) { - timeout = 0; - } - } else if (fds[i].fd >= 0) { - nsockfds++; - } - } - sockfds = gpr_malloc(sizeof(struct pollfd) * nsockfds); - idx = 0; - for (i = 0; i < nfds; i++) { - if (fds[i].fd >= 0) { - sockfds[idx].fd = fds[i].fd; - sockfds[idx].events = fds[i].events; - sockfds[idx].revents = 0; - idx++; - } - } - - errno = 0; - if (nsockfds > 0) { - pres = gpr_malloc(sizeof(struct poll_result)); - pargs = gpr_malloc(sizeof(struct poll_args)); - - pargs->fds = gpr_malloc(sizeof(struct pollfd) * nsockfds); - memcpy(pargs->fds, sockfds, sizeof(struct pollfd) * nsockfds); - pargs->nfds = nsockfds; - pargs->timeout = timeout; - pargs->result = pres; - - pres->fds = sockfds; - pres->cv = &pollcv; - pres->completed = 0; - pres->res = 0; - pres->err = 0; - - opt = gpr_thd_options_default(); - gpr_thd_options_set_detached(&opt); - gpr_thd_new(&t_id, &run_poll, pargs, &opt); - // We want the poll() thread to trigger the deadline, so wait forever here - gpr_cv_wait(&pollcv, &g_mu, gpr_inf_future(GPR_CLOCK_MONOTONIC)); - if (!pres->completed) { - pargs->result = NULL; - } - res = pres->res; - errno = pres->err; - gpr_free(pres); - } else { - gpr_timespec deadline = gpr_now(GPR_CLOCK_REALTIME); - deadline = - gpr_time_add(deadline, gpr_time_from_millis(timeout, GPR_TIMESPAN)); - gpr_cv_wait(&pollcv, &g_mu, deadline); - res = 0; - } - idx = 0; - for (i = 0; i < nfds; i++) { - if (fds[i].fd < 0 && (fds[i].events & POLLIN)) { - cvn = g_cvfds.cvfds[FD_TO_IDX(fds[i].fd)].cvs; - prev = NULL; - while (cvn->cv != &pollcv) { - prev = cvn; - cvn = cvn->next; - GPR_ASSERT(cvn); - } - if (!prev) { - g_cvfds.cvfds[FD_TO_IDX(fds[i].fd)].cvs = cvn->next; - } else { - prev->next = cvn->next; - } - gpr_free(cvn); - - if (g_cvfds.cvfds[FD_TO_IDX(fds[i].fd)].is_set) { - fds[i].revents = POLLIN; - if (res >= 0) res++; - } - } else if (fds[i].fd >= 0) { - fds[i].revents = sockfds[idx].revents; - idx++; - } - } - gpr_free(sockfds); - gpr_cv_destroy(&pollcv); - gpr_mu_unlock(&g_mu); - return res; -} +extern cv_fd_table g_cvfds; static grpc_error* cv_fd_init(grpc_wakeup_fd* fd_info) { unsigned int i, newsize; int idx; - gpr_mu_lock(&g_mu); + gpr_mu_lock(&g_cvfds.mu); if (!g_cvfds.free_fds) { newsize = GPR_MIN(g_cvfds.size * 2, g_cvfds.size + MAX_TABLE_RESIZE); g_cvfds.cvfds = gpr_realloc(g_cvfds.cvfds, sizeof(fd_node) * newsize); @@ -259,51 +73,27 @@ static grpc_error* cv_fd_init(grpc_wakeup_fd* fd_info) { g_cvfds.cvfds[idx].is_set = 0; fd_info->read_fd = IDX_TO_FD(idx); fd_info->write_fd = -1; - gpr_mu_unlock(&g_mu); + gpr_mu_unlock(&g_cvfds.mu); return GRPC_ERROR_NONE; } -void grpc_global_cv_fd_table_init() { - gpr_mu_lock(&g_mu); - g_cvfds.size = DEFAULT_TABLE_SIZE; - g_cvfds.cvfds = gpr_malloc(sizeof(fd_node) * DEFAULT_TABLE_SIZE); - g_cvfds.free_fds = NULL; - for (int i = 0; i < DEFAULT_TABLE_SIZE; i++) { - g_cvfds.cvfds[i].is_set = 0; - g_cvfds.cvfds[i].cvs = NULL; - g_cvfds.cvfds[i].next_free = g_cvfds.free_fds; - g_cvfds.free_fds = &g_cvfds.cvfds[i]; - } - // Override the poll function with one that supports cvfds - g_cvfds.poll = grpc_poll_function; - grpc_poll_function = &cvfd_poll; - gpr_mu_unlock(&g_mu); -} - -void grpc_global_cv_fd_table_shutdown() { - gpr_mu_lock(&g_mu); - grpc_poll_function = g_cvfds.poll; - gpr_free(g_cvfds.cvfds); - gpr_mu_unlock(&g_mu); -} - static grpc_error* cv_fd_wakeup(grpc_wakeup_fd* fd_info) { cv_node* cvn; - gpr_mu_lock(&g_mu); + gpr_mu_lock(&g_cvfds.mu); g_cvfds.cvfds[FD_TO_IDX(fd_info->read_fd)].is_set = 1; cvn = g_cvfds.cvfds[FD_TO_IDX(fd_info->read_fd)].cvs; while (cvn) { gpr_cv_signal(cvn->cv); cvn = cvn->next; } - gpr_mu_unlock(&g_mu); + gpr_mu_unlock(&g_cvfds.mu); return GRPC_ERROR_NONE; } static grpc_error* cv_fd_consume(grpc_wakeup_fd* fd_info) { - gpr_mu_lock(&g_mu); + gpr_mu_lock(&g_cvfds.mu); g_cvfds.cvfds[FD_TO_IDX(fd_info->read_fd)].is_set = 0; - gpr_mu_unlock(&g_mu); + gpr_mu_unlock(&g_cvfds.mu); return GRPC_ERROR_NONE; } @@ -311,12 +101,12 @@ static void cv_fd_destroy(grpc_wakeup_fd* fd_info) { if (fd_info->read_fd == 0) { return; } - gpr_mu_lock(&g_mu); + gpr_mu_lock(&g_cvfds.mu); // Assert that there are no active pollers GPR_ASSERT(!g_cvfds.cvfds[FD_TO_IDX(fd_info->read_fd)].cvs); g_cvfds.cvfds[FD_TO_IDX(fd_info->read_fd)].next_free = g_cvfds.free_fds; g_cvfds.free_fds = &g_cvfds.cvfds[FD_TO_IDX(fd_info->read_fd)]; - gpr_mu_unlock(&g_mu); + gpr_mu_unlock(&g_cvfds.mu); } static int cv_check_availability(void) { return 1; } diff --git a/src/core/lib/iomgr/wakeup_fd_cv.h b/src/core/lib/iomgr/wakeup_fd_cv.h index 22ee6c0bbe..e57fc28363 100644 --- a/src/core/lib/iomgr/wakeup_fd_cv.h +++ b/src/core/lib/iomgr/wakeup_fd_cv.h @@ -41,7 +41,7 @@ * A global table of cv wakeup fds is mantained. A cv wakeup fd is a negative * file descriptor. poll() is then run in a background thread with only the * real socket fds while we wait on a condition variable trigged by either the - * poll() called or a wakeup_fd() call. + * poll() completion or a wakeup_fd() call. * */ @@ -50,9 +50,6 @@ #include "src/core/lib/iomgr/wakeup_fd_posix.h" -void grpc_global_cv_fd_table_init(); -void grpc_global_cv_fd_table_shutdown(); - extern grpc_wakeup_fd_vtable grpc_cv_wakeup_fd_vtable; #endif /* GRPC_CORE_LIB_IOMGR_WAKEUP_FD_CV_H */ diff --git a/src/core/lib/iomgr/wakeup_fd_posix.c b/src/core/lib/iomgr/wakeup_fd_posix.c index 564b836154..48ed92abe8 100644 --- a/src/core/lib/iomgr/wakeup_fd_posix.c +++ b/src/core/lib/iomgr/wakeup_fd_posix.c @@ -33,7 +33,7 @@ #include -#ifdef GPR_POSIX_WAKEUP_FD +#ifdef GPR_POSIX_SOCKET #include #include "src/core/lib/iomgr/wakeup_fd_cv.h" @@ -43,6 +43,8 @@ static const grpc_wakeup_fd_vtable *wakeup_fd_vtable = NULL; int grpc_allow_specialized_wakeup_fd = 1; int grpc_allow_pipe_wakeup_fd = 1; +int grpc_has_wakeup_fd = 1; + void grpc_wakeup_fd_global_init(void) { if (grpc_allow_specialized_wakeup_fd && @@ -52,15 +54,12 @@ void grpc_wakeup_fd_global_init(void) { grpc_pipe_wakeup_fd_vtable.check_availability()) { wakeup_fd_vtable = &grpc_pipe_wakeup_fd_vtable; } else { + grpc_has_wakeup_fd = 0; wakeup_fd_vtable = &grpc_cv_wakeup_fd_vtable; - grpc_global_cv_fd_table_init(); } } void grpc_wakeup_fd_global_destroy(void) { - if (wakeup_fd_vtable == &grpc_cv_wakeup_fd_vtable) { - grpc_global_cv_fd_table_shutdown(); - } wakeup_fd_vtable = NULL; } diff --git a/src/core/lib/iomgr/wakeup_fd_posix.h b/src/core/lib/iomgr/wakeup_fd_posix.h index a9f902bc9f..bd0fb46da1 100644 --- a/src/core/lib/iomgr/wakeup_fd_posix.h +++ b/src/core/lib/iomgr/wakeup_fd_posix.h @@ -89,6 +89,7 @@ struct grpc_wakeup_fd { extern int grpc_allow_specialized_wakeup_fd; extern int grpc_allow_pipe_wakeup_fd; +extern int grpc_has_wakeup_fd; #define GRPC_WAKEUP_FD_GET_READ_FD(fd_info) ((fd_info)->read_fd) diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index dc2ce46979..0d4c7d1c0e 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -98,6 +98,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/iomgr/error.c', 'src/core/lib/iomgr/ev_epoll_linux.c', 'src/core/lib/iomgr/ev_poll_and_epoll_posix.c', + 'src/core/lib/iomgr/ev_poll_cv_posix.c', 'src/core/lib/iomgr/ev_poll_posix.c', 'src/core/lib/iomgr/ev_posix.c', 'src/core/lib/iomgr/exec_ctx.c', diff --git a/test/core/iomgr/wakeup_fd_cv_test.c b/test/core/iomgr/wakeup_fd_cv_test.c index 2cd777536d..8ac78a2f41 100644 --- a/test/core/iomgr/wakeup_fd_cv_test.c +++ b/test/core/iomgr/wakeup_fd_cv_test.c @@ -39,7 +39,7 @@ #include #include "src/core/lib/iomgr/ev_posix.h" -#include "src/core/lib/iomgr/wakeup_fd_posix.h" +#include "src/core/lib/iomgr/iomgr_posix.h" #include "src/core/lib/support/env.h" typedef struct poll_args { @@ -102,7 +102,6 @@ void background_poll(void *args) { void test_many_fds(void) { int i; - grpc_wakeup_fd_global_init(); grpc_wakeup_fd fd[1000]; for (i = 0; i < 1000; i++) { GPR_ASSERT(grpc_wakeup_fd_init(&fd[i]) == GRPC_ERROR_NONE); @@ -110,7 +109,6 @@ void test_many_fds(void) { for (i = 0; i < 1000; i++) { grpc_wakeup_fd_destroy(&fd[i]); } - grpc_wakeup_fd_global_destroy(); } void test_poll_cv_trigger(void) { @@ -119,8 +117,6 @@ void test_poll_cv_trigger(void) { poll_args pargs; gpr_thd_id t_id; gpr_thd_options opt; - grpc_poll_function = &mock_poll; - grpc_wakeup_fd_global_init(); GPR_ASSERT(grpc_wakeup_fd_init(&cvfd1) == GRPC_ERROR_NONE); GPR_ASSERT(grpc_wakeup_fd_init(&cvfd2) == GRPC_ERROR_NONE); @@ -226,17 +222,22 @@ void test_poll_cv_trigger(void) { GPR_ASSERT(pfds[4].revents == 0); GPR_ASSERT(pfds[5].revents == 0); - grpc_wakeup_fd_global_destroy(); } int main(int argc, char **argv) { - gpr_setenv("GRPC_POLL_STRATEGY", "poll"); - grpc_allow_specialized_wakeup_fd = 0; - grpc_allow_pipe_wakeup_fd = 0; + gpr_setenv("GRPC_POLL_STRATEGY", "poll-cv"); + grpc_poll_function = &mock_poll; gpr_mu_init(&poll_mu); gpr_cv_init(&poll_cv); + + grpc_iomgr_platform_init(); test_many_fds(); + grpc_iomgr_platform_shutdown(); + + grpc_iomgr_platform_init(); test_poll_cv_trigger(); + grpc_iomgr_platform_shutdown(); + // Make sure detached polling threads have chance // to exit and clean up memory. pthread_exit() causes tsan/msan // issues, so we just wait an ample amount of time diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 6e08a1977c..2ea042a4f4 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -894,6 +894,7 @@ src/core/lib/iomgr/endpoint_pair.h \ src/core/lib/iomgr/error.h \ src/core/lib/iomgr/ev_epoll_linux.h \ src/core/lib/iomgr/ev_poll_and_epoll_posix.h \ +src/core/lib/iomgr/ev_poll_cv_posix.h \ src/core/lib/iomgr/ev_poll_posix.h \ src/core/lib/iomgr/ev_posix.h \ src/core/lib/iomgr/exec_ctx.h \ @@ -1008,6 +1009,7 @@ src/core/lib/iomgr/endpoint_pair_windows.c \ src/core/lib/iomgr/error.c \ src/core/lib/iomgr/ev_epoll_linux.c \ src/core/lib/iomgr/ev_poll_and_epoll_posix.c \ +src/core/lib/iomgr/ev_poll_cv_posix.c \ src/core/lib/iomgr/ev_poll_posix.c \ src/core/lib/iomgr/ev_posix.c \ src/core/lib/iomgr/exec_ctx.c \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 2328194c3a..a59ff043b1 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -811,6 +811,7 @@ src/core/lib/iomgr/endpoint_pair.h \ src/core/lib/iomgr/error.h \ src/core/lib/iomgr/ev_epoll_linux.h \ src/core/lib/iomgr/ev_poll_and_epoll_posix.h \ +src/core/lib/iomgr/ev_poll_cv_posix.h \ src/core/lib/iomgr/ev_poll_posix.h \ src/core/lib/iomgr/ev_posix.h \ src/core/lib/iomgr/exec_ctx.h \ @@ -972,6 +973,7 @@ src/core/lib/iomgr/endpoint_pair_windows.c \ src/core/lib/iomgr/error.c \ src/core/lib/iomgr/ev_epoll_linux.c \ src/core/lib/iomgr/ev_poll_and_epoll_posix.c \ +src/core/lib/iomgr/ev_poll_cv_posix.c \ src/core/lib/iomgr/ev_poll_posix.c \ src/core/lib/iomgr/ev_posix.c \ src/core/lib/iomgr/exec_ctx.c \ diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index 146018ba3a..7d8a18d8fe 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -69,7 +69,7 @@ _FORCE_ENVIRON_FOR_WRAPPERS = { _POLLING_STRATEGIES = { - 'linux': ['epoll', 'poll', 'legacy'] + 'linux': ['epoll', 'poll', 'poll-cv', 'legacy'] } diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index 2ce0e3b05c..f6abb4641f 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -5926,6 +5926,7 @@ "src/core/lib/iomgr/error.h", "src/core/lib/iomgr/ev_epoll_linux.h", "src/core/lib/iomgr/ev_poll_and_epoll_posix.h", + "src/core/lib/iomgr/ev_poll_cv_posix.h", "src/core/lib/iomgr/ev_poll_posix.h", "src/core/lib/iomgr/ev_posix.h", "src/core/lib/iomgr/exec_ctx.h", @@ -6039,6 +6040,8 @@ "src/core/lib/iomgr/ev_epoll_linux.h", "src/core/lib/iomgr/ev_poll_and_epoll_posix.c", "src/core/lib/iomgr/ev_poll_and_epoll_posix.h", + "src/core/lib/iomgr/ev_poll_cv_posix.c", + "src/core/lib/iomgr/ev_poll_cv_posix.h", "src/core/lib/iomgr/ev_poll_posix.c", "src/core/lib/iomgr/ev_poll_posix.h", "src/core/lib/iomgr/ev_posix.c", diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj b/vsprojects/vcxproj/grpc++/grpc++.vcxproj index 2afda35d34..eb830eb45d 100644 --- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj +++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj @@ -394,6 +394,7 @@ + @@ -564,6 +565,8 @@ + + diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters index 1f88ae0e93..acee5ed3c9 100644 --- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters +++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters @@ -163,6 +163,9 @@ src\core\lib\iomgr + + src\core\lib\iomgr + src\core\lib\iomgr @@ -779,6 +782,9 @@ src\core\lib\iomgr + + src\core\lib\iomgr + src\core\lib\iomgr diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj index be20aef6dc..fbdc6c3bdf 100644 --- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj +++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj @@ -390,6 +390,7 @@ + @@ -550,6 +551,8 @@ + + diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters index 628173dbbe..600e6475a4 100644 --- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters +++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters @@ -148,6 +148,9 @@ src\core\lib\iomgr + + src\core\lib\iomgr + src\core\lib\iomgr @@ -752,6 +755,9 @@ src\core\lib\iomgr + + src\core\lib\iomgr + src\core\lib\iomgr diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj index ae24e8f066..3ae2ade070 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj @@ -320,6 +320,7 @@ + @@ -505,6 +506,8 @@ + + diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters index a849795dc9..2a401e1695 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters @@ -67,6 +67,9 @@ src\core\lib\iomgr + + src\core\lib\iomgr + src\core\lib\iomgr @@ -731,6 +734,9 @@ src\core\lib\iomgr + + src\core\lib\iomgr + src\core\lib\iomgr diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj index 3c3fae370f..e54b369ec6 100644 --- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj +++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj @@ -211,6 +211,7 @@ + @@ -349,6 +350,8 @@ + + diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters index b81431cafa..f391f29729 100644 --- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters +++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters @@ -115,6 +115,9 @@ src\core\lib\iomgr + + src\core\lib\iomgr + src\core\lib\iomgr @@ -512,6 +515,9 @@ src\core\lib\iomgr + + src\core\lib\iomgr + src\core\lib\iomgr diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj index 69d631e452..3eaae7fe18 100644 --- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj +++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj @@ -310,6 +310,7 @@ + @@ -473,6 +474,8 @@ + + diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters index 36e80b4a13..31ba6e97bf 100644 --- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters +++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters @@ -70,6 +70,9 @@ src\core\lib\iomgr + + src\core\lib\iomgr + src\core\lib\iomgr @@ -641,6 +644,9 @@ src\core\lib\iomgr + + src\core\lib\iomgr + src\core\lib\iomgr -- cgit v1.2.3 From 84a4bdd5d8c0d20d6cdc93ce09167adc24431ada Mon Sep 17 00:00:00 2001 From: Ken Payson Date: Thu, 29 Sep 2016 09:24:09 -0700 Subject: Fix Typo --- src/core/lib/iomgr/ev_poll_cv_posix.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/ev_poll_cv_posix.c b/src/core/lib/iomgr/ev_poll_cv_posix.c index 596a3025eb..cb2c2ba824 100644 --- a/src/core/lib/iomgr/ev_poll_cv_posix.c +++ b/src/core/lib/iomgr/ev_poll_cv_posix.c @@ -266,10 +266,9 @@ const grpc_event_engine_vtable* grpc_init_poll_cv_posix(void) { ev_poll_vtable = grpc_init_poll_posix(); if (!ev_poll_vtable) { grpc_global_cv_fd_table_shutdown(); - grpc_has_wakeup_fd = has_standard_wakeup_fd; + grpc_has_wakeup_fd = has_wakeup_fd; grpc_allow_specialized_wakeup_fd = allow_specialized_wakeup_fd; grpc_allow_pipe_wakeup_fd = allow_pipe_wakeup_fd; - grpc_has_wakeup_fd = has_standard_wakeup_fd; grpc_global_cv_fd_table_init(); return NULL; } -- cgit v1.2.3 From c2fbddf19990aa0c6b609af8ff461a0c7946fe52 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 29 Sep 2016 09:44:51 -0700 Subject: Fix memory leak --- src/core/ext/transport/chttp2/transport/writing.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/ext/transport/chttp2/transport/writing.c b/src/core/ext/transport/chttp2/transport/writing.c index bc490569b7..ebdbce1bfd 100644 --- a/src/core/ext/transport/chttp2/transport/writing.c +++ b/src/core/ext/transport/chttp2/transport/writing.c @@ -70,6 +70,7 @@ static void update_list(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, } cb = next; } + GRPC_ERROR_UNREF(error); } bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, -- cgit v1.2.3 From 7f0bf534df61f8e0320ac3a69f6c0e75e58d3ccd Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 29 Sep 2016 10:19:28 -0700 Subject: Fix crash when accepting a stream after shutdown --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index c25bf1718c..023b7c2e95 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -524,6 +524,9 @@ grpc_chttp2_stream *grpc_chttp2_parsing_lookup_stream(grpc_chttp2_transport *t, grpc_chttp2_stream *grpc_chttp2_parsing_accept_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, uint32_t id) { + if (t->channel_callback.accept_stream == NULL) { + return NULL; + } grpc_chttp2_stream *accepting; GPR_ASSERT(t->accepting_stream == NULL); t->accepting_stream = &accepting; -- cgit v1.2.3 From 65818729dc871e991c452738c221bf3f0f28812b Mon Sep 17 00:00:00 2001 From: Ken Payson Date: Thu, 29 Sep 2016 11:28:23 -0700 Subject: Clang format --- src/core/lib/iomgr/ev_poll_cv_posix.h | 2 +- src/core/lib/iomgr/wakeup_fd_posix.c | 5 +---- tools/run_tests/run_tests.py | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/core/lib/iomgr/ev_poll_cv_posix.h b/src/core/lib/iomgr/ev_poll_cv_posix.h index 0fd3e5bbb4..89e4929fbb 100644 --- a/src/core/lib/iomgr/ev_poll_cv_posix.h +++ b/src/core/lib/iomgr/ev_poll_cv_posix.h @@ -62,4 +62,4 @@ typedef struct cv_fd_table { const grpc_event_engine_vtable* grpc_init_poll_cv_posix(void); -#endif /* GRPC_CORE_LIB_IOMGR_EV_POLL_POSIX_H */ +#endif /* GRPC_CORE_LIB_IOMGR_EV_POLL_CV_POSIX_H */ diff --git a/src/core/lib/iomgr/wakeup_fd_posix.c b/src/core/lib/iomgr/wakeup_fd_posix.c index 48ed92abe8..d8eafc4192 100644 --- a/src/core/lib/iomgr/wakeup_fd_posix.c +++ b/src/core/lib/iomgr/wakeup_fd_posix.c @@ -45,7 +45,6 @@ int grpc_allow_specialized_wakeup_fd = 1; int grpc_allow_pipe_wakeup_fd = 1; int grpc_has_wakeup_fd = 1; - void grpc_wakeup_fd_global_init(void) { if (grpc_allow_specialized_wakeup_fd && grpc_specialized_wakeup_fd_vtable.check_availability()) { @@ -59,9 +58,7 @@ void grpc_wakeup_fd_global_init(void) { } } -void grpc_wakeup_fd_global_destroy(void) { - wakeup_fd_vtable = NULL; -} +void grpc_wakeup_fd_global_destroy(void) { wakeup_fd_vtable = NULL; } grpc_error *grpc_wakeup_fd_init(grpc_wakeup_fd *fd_info) { return wakeup_fd_vtable->init(fd_info); diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index 7d8a18d8fe..0777274694 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -1027,7 +1027,7 @@ argp.add_argument('--force_default_poller', default=False, action='store_const', args = argp.parse_args() if args.force_default_poller: - _POLLING_STRATEGIES = {} + _POLLING_STRATEGIES = {'linux': ['poll-cv']} jobset.measure_cpu_costs = args.measure_cpu_costs -- cgit v1.2.3 From 0adb72808356704967d0478f56a862a3da2ee913 Mon Sep 17 00:00:00 2001 From: Noah Eisen Date: Thu, 29 Sep 2016 12:01:11 -0700 Subject: removed check for status error message. Investigating why node servers send messages back that are not empty --- test/cpp/interop/interop_client.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc index 65519a03a8..a54dd5a744 100644 --- a/test/cpp/interop/interop_client.cc +++ b/test/cpp/interop/interop_client.cc @@ -135,7 +135,7 @@ bool InteropClient::AssertStatusOk(const Status& s) { } // Note: At this point, s.error_code is definitely not StatusCode::OK (we - // already checked for s.ok() above). So, the following will call abort() + // already checked for s.ok() all call abort() // (unless s.error_code() corresponds to a transient failure and // 'do_not_abort_on_transient_failures' is true) return AssertStatusCode(s, StatusCode::OK); @@ -951,8 +951,6 @@ bool InteropClient::DoUnimplementedMethod() { return false; } - GPR_ASSERT(s.error_message().empty()); - gpr_log(GPR_DEBUG, "unimplemented rpc done."); return true; } -- cgit v1.2.3 From 98b3663f6cdb119f1199b9cac8a88a3f84f52664 Mon Sep 17 00:00:00 2001 From: Noah Eisen Date: Thu, 29 Sep 2016 14:00:47 -0700 Subject: Fixed type in comments --- test/cpp/interop/interop_client.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc index a54dd5a744..ea5a1fd861 100644 --- a/test/cpp/interop/interop_client.cc +++ b/test/cpp/interop/interop_client.cc @@ -135,7 +135,7 @@ bool InteropClient::AssertStatusOk(const Status& s) { } // Note: At this point, s.error_code is definitely not StatusCode::OK (we - // already checked for s.ok() all call abort() + // already checked for s.ok() above). So, the following will call abort() // (unless s.error_code() corresponds to a transient failure and // 'do_not_abort_on_transient_failures' is true) return AssertStatusCode(s, StatusCode::OK); -- cgit v1.2.3 From 3b630f7f204fb49814406a6173cea23e37a7a299 Mon Sep 17 00:00:00 2001 From: Noah Eisen Date: Thu, 29 Sep 2016 18:00:39 -0700 Subject: updated interop test doc. unimplemented test no longer checks error message, since some server languages set it to empty string, and some set it to a non empty message --- doc/interop-test-descriptions.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/doc/interop-test-descriptions.md b/doc/interop-test-descriptions.md index 6a3979d117..2e1650eaf1 100644 --- a/doc/interop-test-descriptions.md +++ b/doc/interop-test-descriptions.md @@ -767,7 +767,6 @@ Procedure: Client asserts: * received status code is 12 (UNIMPLEMENTED) -* received status message is empty or null/unset ### unimplemented_service @@ -783,7 +782,6 @@ Procedure: Client asserts: * received status code is 12 (UNIMPLEMENTED) -* received status message is empty or null/unset ### cancel_after_begin -- cgit v1.2.3 From 3299f81ea88b183396740bfdf602fb78270ea1a5 Mon Sep 17 00:00:00 2001 From: Ken Payson Date: Fri, 30 Sep 2016 08:49:50 -0700 Subject: Remove run_tests.py poll-cv shim --- test/core/iomgr/wakeup_fd_cv_test.c | 1 - tools/run_tests/run_tests.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/test/core/iomgr/wakeup_fd_cv_test.c b/test/core/iomgr/wakeup_fd_cv_test.c index 8ac78a2f41..a3f1d496df 100644 --- a/test/core/iomgr/wakeup_fd_cv_test.c +++ b/test/core/iomgr/wakeup_fd_cv_test.c @@ -221,7 +221,6 @@ void test_poll_cv_trigger(void) { GPR_ASSERT(pfds[3].revents == 0); GPR_ASSERT(pfds[4].revents == 0); GPR_ASSERT(pfds[5].revents == 0); - } int main(int argc, char **argv) { diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index 0777274694..7d8a18d8fe 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -1027,7 +1027,7 @@ argp.add_argument('--force_default_poller', default=False, action='store_const', args = argp.parse_args() if args.force_default_poller: - _POLLING_STRATEGIES = {'linux': ['poll-cv']} + _POLLING_STRATEGIES = {} jobset.measure_cpu_costs = args.measure_cpu_costs -- cgit v1.2.3 From c5b927abce05bb389be81d8e38c71a9144743653 Mon Sep 17 00:00:00 2001 From: Noah Eisen Date: Fri, 30 Sep 2016 18:20:37 -0700 Subject: commit so docker picks up on out changes. will be rolled back --- tools/run_tests/run_interop_tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index 310cfe674e..53c03f0bad 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -92,7 +92,7 @@ class CXXLanguage: return [] def unimplemented_test_cases_server(self): - return _SKIP_ADVANCED + return [] def __str__(self): return 'c++' -- cgit v1.2.3 From e9163f04c35b4ef29400c564a5be7b6cce6aeef2 Mon Sep 17 00:00:00 2001 From: Matt Kwong Date: Wed, 5 Oct 2016 11:42:55 -0700 Subject: Create filter for pull request tests --- tools/run_tests/filter_pull_request_tests.py | 95 ++++++++++++++++++++++++++++ tools/run_tests/run_tests_matrix.py | 18 ++++++ 2 files changed, 113 insertions(+) create mode 100644 tools/run_tests/filter_pull_request_tests.py diff --git a/tools/run_tests/filter_pull_request_tests.py b/tools/run_tests/filter_pull_request_tests.py new file mode 100644 index 0000000000..6cc06d9c40 --- /dev/null +++ b/tools/run_tests/filter_pull_request_tests.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python2.7 +# Copyright 2015, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Filter out tests based on file differences compared to grpc:master""" + +from subprocess import call, check_output + +# triggers to skip c++ tests +run_cpp_starts_with_triggers = ('src/core', + 'src/cpp', + 'test/core', + 'test/cpp') + + +def _get_changed_files(): + """ + Get list of changed files between current branch and gRPC master branch + """ + # git fetch might need to be called on Jenkins slave + # todo(mattkwong): remove or uncomment below after seeing if Jenkins needs this + # call(['git', 'fetch']) + # this also collects files that are changed in the repo but not updated in the branch + return check_output(["git", "diff", "--name-only", "..origin/master"]).split() + + +def _can_skip_tests(file_names, starts_with_triggers=(), ends_with_triggers=()): + """ + Determines if tests are skippable based on if all file names do not match + any begin or end triggers + :param file_names: list of changed files generated by _get_changed_files() + :param starts_with_triggers: tuple of strings to match with beginning of file names + :param ends_with_triggers: tuple of strings to match with end of file names + :return: safe to skip tests + """ + for file_name in file_names: + if starts_with_triggers and file_name.startswith(starts_with_triggers) or \ + ends_with_triggers and file_name.endswith(ends_with_triggers): + return False + return True + + +def _remove_irrelevant_tests(tests, tag): + """ + Filters out tests by config or language + :param tests: list of all tests generated by run_tests_matrix.py + :param tag: string representing language or config to filter - "_(language)_" or "_(config)" + :return: list of relevant tests + """ + return [test for test in tests if not tag in test.shortname] + + +def filter_tests(tests): + """ + Filters out tests that are safe to ignore + :param tests: list of all tests generated by run_tests_matrix.py + :return: list of relevant tests + """ + print("Finding file differences between grpc:master repo and pull request...") + changed_files = _get_changed_files() + for changed_file in changed_files: + print(changed_file) + # C++, tsan, msan, and asan have the same filter + if _can_skip_tests(changed_files, starts_with_triggers=run_cpp_starts_with_triggers): + tests = _remove_irrelevant_tests(tests, '_c++_') # filter out c++ tests + tests = _remove_irrelevant_tests(tests, '_tsan') # filter out tsan tests + tests = _remove_irrelevant_tests(tests, '_msan') # filter out msan tests + tests = _remove_irrelevant_tests(tests, '_asan') # filter out asan tests + return tests diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py index a94f9cfef5..00a2d65d3d 100755 --- a/tools/run_tests/run_tests_matrix.py +++ b/tools/run_tests/run_tests_matrix.py @@ -36,6 +36,7 @@ import multiprocessing import os import report_utils import sys +from filter_pull_request_tests import filter_tests _ROOT = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../..')) os.chdir(_ROOT) @@ -229,6 +230,11 @@ argp.add_argument('--dry_run', action='store_const', const=True, help='Only print what would be run.') +argp.add_argument('--filter_pr_tests', + default=False, + action='store_const', + const=True, + help='Filters out tests irrelavant to pull request changes.') args = argp.parse_args() extra_args = [] @@ -262,6 +268,18 @@ for job in jobs: print ' %s' % job.shortname print +if args.filter_pr_tests: + print 'IMPORTANT: Test filtering is not active; this is only for testing.' + relevant_jobs = filter_tests(jobs) + print + if len(relevant_jobs) == len(jobs): + print 'No tests were filtered.' + else: + print 'These tests were filtered:' + for job in list(set(jobs) - set(relevant_jobs)): + print ' %s' % job.shortname + print + if args.dry_run: print '--dry_run was used, exiting' sys.exit(1) -- cgit v1.2.3 From 037704d7143fba8710a3389761097d4a05781bfd Mon Sep 17 00:00:00 2001 From: Matt Kwong Date: Thu, 6 Oct 2016 18:18:11 -0700 Subject: Fixed some changes --- tools/run_tests/filter_pull_request_tests.py | 170 ++++++++++++++++++++++++--- 1 file changed, 153 insertions(+), 17 deletions(-) diff --git a/tools/run_tests/filter_pull_request_tests.py b/tools/run_tests/filter_pull_request_tests.py index 6cc06d9c40..fe8b8ed0f3 100644 --- a/tools/run_tests/filter_pull_request_tests.py +++ b/tools/run_tests/filter_pull_request_tests.py @@ -28,29 +28,101 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -"""Filter out tests based on file differences compared to grpc:master""" +"""Filter out tests based on file differences compared to merge target branch""" from subprocess import call, check_output -# triggers to skip c++ tests -run_cpp_starts_with_triggers = ('src/core', - 'src/cpp', - 'test/core', - 'test/cpp') +# Whitelist for all tests +# Update all instances in corresponding trigger lists when modifying this +starts_with_whitelist = ['templates/', + 'doc/', + 'examples/', + 'summerofcode/', + 'src/cpp', + 'src/csharp', + 'src/node', + 'src/objective-c', + 'src/php', + 'src/python', + 'src/ruby', + 'test/core', + 'test/cpp', + 'test/distrib/cpp', + 'test/distrib/csharp', + 'test/distrib/node', + 'test/distrib/php', + 'test/distrib/python', + 'test/distrib/ruby'] + +ends_with_whitelist = ['README.md', + 'LICENSE'] + +# Triggers for core tests +core_starts_with_triggers = ['test/core'] + +# Triggers for c++ tests +cpp_starts_with_triggers = ['src/cpp', + 'test/cpp', + 'test/distrib/cpp'] + +# Triggers for c# tests +csharp_starts_with_triggers = ['src/csharp', + 'test/distrib/csharp'] + +# Triggers for node tests +node_starts_with_triggers = ['src/node', + 'test/distrib/node'] + +# Triggers for objective-c tests +objc_starts_with_triggers = ['src/objective-c'] + +# Triggers for php tests +php_starts_with_triggers = ['src/php', + 'test/distrib/php'] + +# Triggers for python tests +python_starts_with_triggers = ['src/python', + 'test/distrib/python'] + +# Triggers for ruby tests +ruby_starts_with_triggers = ['src/ruby', + 'test/distrib/ruby'] + + +def _filter_whitelist(whitelist, triggers): + """ + Removes triggers from whitelist + :param whitelist: list to remove values from + :param triggers: list of values to remove from whitelist + :return: filtered whitelist + """ + filtered_whitelist = list(whitelist) + for trigger in triggers: + if trigger in filtered_whitelist: + filtered_whitelist.remove(trigger) + else: + """ + If the trigger is not found in the whitelist, then there is likely + a mistake in the whitelist or trigger list, which needs to be addressed + to not wrongly skip tests + """ + print("ERROR: '%s' trigger not in whitelist. Please fix this!" % trigger) + return filtered_whitelist def _get_changed_files(): """ - Get list of changed files between current branch and gRPC master branch + Get list of changed files between current branch and base of target merge branch """ # git fetch might need to be called on Jenkins slave # todo(mattkwong): remove or uncomment below after seeing if Jenkins needs this # call(['git', 'fetch']) # this also collects files that are changed in the repo but not updated in the branch - return check_output(["git", "diff", "--name-only", "..origin/master"]).split() + # todo(mattkwong): change this to only collect changes files compared to base and not hardcode branch + return check_output(["git", "diff", "--name-only", "..origin/master"]).splitlines() -def _can_skip_tests(file_names, starts_with_triggers=(), ends_with_triggers=()): +def _can_skip_tests(file_names, starts_with_whitelist=[], ends_with_whitelist=[]): """ Determines if tests are skippable based on if all file names do not match any begin or end triggers @@ -59,9 +131,13 @@ def _can_skip_tests(file_names, starts_with_triggers=(), ends_with_triggers=()): :param ends_with_triggers: tuple of strings to match with end of file names :return: safe to skip tests """ + # convert lists to tuple to pass into str.startswith() and str.endswith() + starts_with_whitelist = tuple(starts_with_whitelist) + ends_with_whitelist = tuple(ends_with_whitelist) + print (starts_with_whitelist) for file_name in file_names: - if starts_with_triggers and file_name.startswith(starts_with_triggers) or \ - ends_with_triggers and file_name.endswith(ends_with_triggers): + if starts_with_whitelist and not file_name.startswith(starts_with_whitelist) and \ + ends_with_whitelist and not file_name.endswith(ends_with_whitelist): return False return True @@ -73,6 +149,7 @@ def _remove_irrelevant_tests(tests, tag): :param tag: string representing language or config to filter - "_(language)_" or "_(config)" :return: list of relevant tests """ + # todo(mattkwong): find a more reliable way to filter tests - don't use shortname return [test for test in tests if not tag in test.shortname] @@ -86,10 +163,69 @@ def filter_tests(tests): changed_files = _get_changed_files() for changed_file in changed_files: print(changed_file) - # C++, tsan, msan, and asan have the same filter - if _can_skip_tests(changed_files, starts_with_triggers=run_cpp_starts_with_triggers): - tests = _remove_irrelevant_tests(tests, '_c++_') # filter out c++ tests - tests = _remove_irrelevant_tests(tests, '_tsan') # filter out tsan tests - tests = _remove_irrelevant_tests(tests, '_msan') # filter out msan tests - tests = _remove_irrelevant_tests(tests, '_asan') # filter out asan tests + + changed_files = ['src/ruby/dgf'] + + # Filter core tests + skip_core = _can_skip_tests(changed_files, + starts_with_whitelist=_filter_whitelist(starts_with_whitelist, core_starts_with_triggers), + ends_with_whitelist=ends_with_whitelist) + if skip_core: + tests = _remove_irrelevant_tests(tests, '_c_') + + # Filter c++ tests + skip_cpp = _can_skip_tests(changed_files, + starts_with_whitelist=_filter_whitelist(starts_with_whitelist, cpp_starts_with_triggers), + ends_with_whitelist=ends_with_whitelist) + if skip_cpp: + tests = _remove_irrelevant_tests(tests, '_cpp_') + + # Tsan, msan, and asan tests skipped if core and c++ are skipped + if skip_core and skip_cpp: + tests = _remove_irrelevant_tests(tests, '_tsan') + tests = _remove_irrelevant_tests(tests, '_msan') + tests = _remove_irrelevant_tests(tests, '_asan') + + # Filter c# tests + skip_csharp = _can_skip_tests(changed_files, + starts_with_whitelist=_filter_whitelist(starts_with_whitelist, csharp_starts_with_triggers), + ends_with_whitelist=ends_with_whitelist) + if skip_csharp: + tests = _remove_irrelevant_tests(tests, '_csharp_') + + # Filter node tests + skip_node = _can_skip_tests(changed_files, + starts_with_whitelist=_filter_whitelist(starts_with_whitelist, node_starts_with_triggers), + ends_with_whitelist=ends_with_whitelist) + if skip_node: + tests = _remove_irrelevant_tests(tests, '_node_') + + # Filter objc tests + skip_objc = _can_skip_tests(changed_files, + starts_with_whitelist=_filter_whitelist(starts_with_whitelist, objc_starts_with_triggers), + ends_with_whitelist=ends_with_whitelist) + if skip_objc: + tests = _remove_irrelevant_tests(tests, '_objc_') + + # Filter php tests + skip_php = _can_skip_tests(changed_files, + starts_with_whitelist=_filter_whitelist(starts_with_whitelist, php_starts_with_triggers), + ends_with_whitelist=ends_with_whitelist) + if skip_php: + tests = _remove_irrelevant_tests(tests, '_php_') + + # Filter python tests + skip_python = _can_skip_tests(changed_files, + starts_with_whitelist=_filter_whitelist(starts_with_whitelist, python_starts_with_triggers), + ends_with_whitelist=ends_with_whitelist) + if skip_python: + tests = _remove_irrelevant_tests(tests, '_python_') + + # Filter ruby tests + skip_ruby = _can_skip_tests(changed_files, + starts_with_whitelist=_filter_whitelist(starts_with_whitelist, ruby_starts_with_triggers), + ends_with_whitelist=ends_with_whitelist) + if skip_ruby: + tests = _remove_irrelevant_tests(tests, '_ruby_') + return tests -- cgit v1.2.3 From bc544be002b864e808cbca54ea64fa9b68262302 Mon Sep 17 00:00:00 2001 From: Ken Payson Date: Thu, 6 Oct 2016 19:23:47 -0700 Subject: Fix platform detection --- src/core/lib/iomgr/ev_epoll_linux.c | 4 ++++ src/core/lib/iomgr/ev_poll_posix.c | 3 +++ src/core/lib/iomgr/ev_posix.c | 1 + src/core/lib/iomgr/wakeup_fd_pipe.c | 3 +-- 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/ev_epoll_linux.c b/src/core/lib/iomgr/ev_epoll_linux.c index ab77ebc78b..249bc98735 100644 --- a/src/core/lib/iomgr/ev_epoll_linux.c +++ b/src/core/lib/iomgr/ev_epoll_linux.c @@ -1892,6 +1892,10 @@ const grpc_event_engine_vtable *grpc_init_epoll_linux(void) { return NULL; } + if (!grpc_has_wakeup_fd) { + return NULL; + } + if (!is_epoll_available()) { return NULL; } diff --git a/src/core/lib/iomgr/ev_poll_posix.c b/src/core/lib/iomgr/ev_poll_posix.c index 16a5e3083e..97e71d968e 100644 --- a/src/core/lib/iomgr/ev_poll_posix.c +++ b/src/core/lib/iomgr/ev_poll_posix.c @@ -1277,6 +1277,9 @@ static const grpc_event_engine_vtable vtable = { }; const grpc_event_engine_vtable *grpc_init_poll_posix(void) { + if (!grpc_has_wakeup_fd) { + return NULL; + } if (!GRPC_LOG_IF_ERROR("pollset_global_init", pollset_global_init())) { return NULL; } diff --git a/src/core/lib/iomgr/ev_posix.c b/src/core/lib/iomgr/ev_posix.c index 2fc8ccfa91..a4102b429f 100644 --- a/src/core/lib/iomgr/ev_posix.c +++ b/src/core/lib/iomgr/ev_posix.c @@ -65,6 +65,7 @@ typedef struct { } event_engine_factory; static const event_engine_factory g_factories[] = { + {"poll-cv", grpc_init_poll_cv_posix}, {"epoll", grpc_init_epoll_linux}, {"poll", grpc_init_poll_posix}, {"poll-cv", grpc_init_poll_cv_posix}, diff --git a/src/core/lib/iomgr/wakeup_fd_pipe.c b/src/core/lib/iomgr/wakeup_fd_pipe.c index 3dc94c94ba..d0ea216aa0 100644 --- a/src/core/lib/iomgr/wakeup_fd_pipe.c +++ b/src/core/lib/iomgr/wakeup_fd_pipe.c @@ -47,11 +47,10 @@ static grpc_error* pipe_init(grpc_wakeup_fd* fd_info) { int pipefd[2]; - /* TODO(klempner): Make this nonfatal */ int r = pipe(pipefd); if (0 != r) { gpr_log(GPR_ERROR, "pipe creation failed (%d): %s", errno, strerror(errno)); - abort(); + return GRPC_OS_ERROR(errno, "pipe"); } grpc_error* err; err = grpc_set_socket_nonblocking(pipefd[0], 1); -- cgit v1.2.3 From 46db0d29061d49d68c3a0e490e036d2a076d59f9 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 7 Oct 2016 07:27:05 -0700 Subject: Fix refcount bug --- src/core/lib/surface/call.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c index 601b0c8580..d723711c55 100644 --- a/src/core/lib/surface/call.c +++ b/src/core/lib/surface/call.c @@ -314,7 +314,6 @@ grpc_error *grpc_call_create(const grpc_call_create_args *args, const char *error_str; grpc_error_get_status(error, &status, &error_str); close_with_status(&exec_ctx, call, status, error_str); - GRPC_ERROR_UNREF(error); } if (args->cq != NULL) { GPR_ASSERT( -- cgit v1.2.3 From d526e82a8340c5ad169a6bbb770cee23e1c0a441 Mon Sep 17 00:00:00 2001 From: Ken Payson Date: Fri, 7 Oct 2016 10:17:01 -0700 Subject: fix small bug --- src/core/lib/iomgr/ev_poll_cv_posix.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/ev_poll_cv_posix.c b/src/core/lib/iomgr/ev_poll_cv_posix.c index cb2c2ba824..1ea811e445 100644 --- a/src/core/lib/iomgr/ev_poll_cv_posix.c +++ b/src/core/lib/iomgr/ev_poll_cv_posix.c @@ -259,10 +259,10 @@ const grpc_event_engine_vtable* grpc_init_poll_cv_posix(void) { int allow_specialized_wakeup_fd = grpc_allow_specialized_wakeup_fd; int allow_pipe_wakeup_fd = grpc_allow_pipe_wakeup_fd; grpc_global_cv_fd_table_init(); - grpc_has_wakeup_fd = 1; grpc_allow_specialized_wakeup_fd = 0; grpc_allow_pipe_wakeup_fd = 0; grpc_wakeup_fd_global_init(); + grpc_has_wakeup_fd = 1; ev_poll_vtable = grpc_init_poll_posix(); if (!ev_poll_vtable) { grpc_global_cv_fd_table_shutdown(); @@ -272,7 +272,6 @@ const grpc_event_engine_vtable* grpc_init_poll_cv_posix(void) { grpc_global_cv_fd_table_init(); return NULL; } - vtable = *ev_poll_vtable; vtable.shutdown_engine = shutdown_engine; return &vtable; -- cgit v1.2.3 From c4fb2e782d841df4e402c5c8825f01853c8d1b1b Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Fri, 7 Oct 2016 11:00:45 -0700 Subject: update go in linux perf worker init script --- tools/gce/linux_performance_worker_init.sh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tools/gce/linux_performance_worker_init.sh b/tools/gce/linux_performance_worker_init.sh index ea80d74bdf..6fc3035c10 100755 --- a/tools/gce/linux_performance_worker_init.sh +++ b/tools/gce/linux_performance_worker_init.sh @@ -128,4 +128,13 @@ gem install bundler # Java dependencies - nothing as we already have Java JDK 8 # Go dependencies -sudo apt-get install -y golang-go +# Currently, the golang package available via apt-get doesn't have the latest go. +# Following go install instructions from https://golang.org/doc/install +GO_VERSION=1.7.1 +OS=linux +ARCH=amd64 +curl -O https://storage.googleapis.com/golang/go${GO_VERSION}.${OS}-${ARCH}.tar.gz +sudo tar -C /usr/local -xzf go$GO_VERSION.$OS-$ARCH.tar.gz +# Put go on the PATH, keep the usual installation dir +sudo ln -s /usr/local/go/bin/go /usr/bin/go +rm go$GO_VERSION.$OS-$ARCH.tar.gz -- cgit v1.2.3 From 131a1065fb23d9fd4be60361dffb9f8a0042f0cc Mon Sep 17 00:00:00 2001 From: Ken Payson Date: Fri, 7 Oct 2016 14:03:30 -0700 Subject: Remove test-forcing hack --- src/core/lib/iomgr/ev_posix.c | 1 - src/core/lib/iomgr/wakeup_fd_posix.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/ev_posix.c b/src/core/lib/iomgr/ev_posix.c index a4102b429f..2fc8ccfa91 100644 --- a/src/core/lib/iomgr/ev_posix.c +++ b/src/core/lib/iomgr/ev_posix.c @@ -65,7 +65,6 @@ typedef struct { } event_engine_factory; static const event_engine_factory g_factories[] = { - {"poll-cv", grpc_init_poll_cv_posix}, {"epoll", grpc_init_epoll_linux}, {"poll", grpc_init_poll_posix}, {"poll-cv", grpc_init_poll_cv_posix}, diff --git a/src/core/lib/iomgr/wakeup_fd_posix.c b/src/core/lib/iomgr/wakeup_fd_posix.c index d8eafc4192..041c221de3 100644 --- a/src/core/lib/iomgr/wakeup_fd_posix.c +++ b/src/core/lib/iomgr/wakeup_fd_posix.c @@ -33,7 +33,7 @@ #include -#ifdef GPR_POSIX_SOCKET +#ifdef GPR_POSIX_WAKEUP_FD #include #include "src/core/lib/iomgr/wakeup_fd_cv.h" -- cgit v1.2.3 From f3f28724834683349e1c7e7aedd49524a226d6fa Mon Sep 17 00:00:00 2001 From: Matt Kwong Date: Fri, 7 Oct 2016 15:25:56 -0700 Subject: changed filter to be more conservative - any no-whitelisted file runs all tests --- tools/run_tests/filter_pull_request_tests.py | 58 +++++++++++++++++++--------- tools/run_tests/run_tests_matrix.py | 10 +++-- 2 files changed, 47 insertions(+), 21 deletions(-) diff --git a/tools/run_tests/filter_pull_request_tests.py b/tools/run_tests/filter_pull_request_tests.py index fe8b8ed0f3..29dbd97825 100644 --- a/tools/run_tests/filter_pull_request_tests.py +++ b/tools/run_tests/filter_pull_request_tests.py @@ -33,7 +33,8 @@ from subprocess import call, check_output # Whitelist for all tests -# Update all instances in corresponding trigger lists when modifying this +# If whitelist item should only trigger some tests, the item should be +# added to this list and the trigger list of tests that should be run starts_with_whitelist = ['templates/', 'doc/', 'examples/', @@ -110,16 +111,18 @@ def _filter_whitelist(whitelist, triggers): return filtered_whitelist -def _get_changed_files(): +def _get_changed_files(base_branch): """ Get list of changed files between current branch and base of target merge branch """ # git fetch might need to be called on Jenkins slave # todo(mattkwong): remove or uncomment below after seeing if Jenkins needs this # call(['git', 'fetch']) - # this also collects files that are changed in the repo but not updated in the branch - # todo(mattkwong): change this to only collect changes files compared to base and not hardcode branch - return check_output(["git", "diff", "--name-only", "..origin/master"]).splitlines() + + # get file changes between branch and merge-base of specified branch + # not combined to be Windows friendly + base_commit = check_output(["git", "merge-base", base_branch, "HEAD"]).rstrip() + return check_output(["git", "diff", base_commit, "--name-only"]).splitlines() def _can_skip_tests(file_names, starts_with_whitelist=[], ends_with_whitelist=[]): @@ -134,7 +137,6 @@ def _can_skip_tests(file_names, starts_with_whitelist=[], ends_with_whitelist=[] # convert lists to tuple to pass into str.startswith() and str.endswith() starts_with_whitelist = tuple(starts_with_whitelist) ends_with_whitelist = tuple(ends_with_whitelist) - print (starts_with_whitelist) for file_name in file_names: if starts_with_whitelist and not file_name.startswith(starts_with_whitelist) and \ ends_with_whitelist and not file_name.endswith(ends_with_whitelist): @@ -144,28 +146,48 @@ def _can_skip_tests(file_names, starts_with_whitelist=[], ends_with_whitelist=[] def _remove_irrelevant_tests(tests, tag): """ - Filters out tests by config or language + Filters out tests by config or language - will not remove sanitizer tests :param tests: list of all tests generated by run_tests_matrix.py :param tag: string representing language or config to filter - "_(language)_" or "_(config)" :return: list of relevant tests """ # todo(mattkwong): find a more reliable way to filter tests - don't use shortname - return [test for test in tests if not tag in test.shortname] + return [test for test in tests if + tag not in test.shortname or + '_msan' in test.shortname or + '_asan' in test.shortname or + '_tsan' in test.shortname] -def filter_tests(tests): +def _remove_irrelevant_sanitizer_tests(tests, language_tag=""): + """ + Filters out sanitizer tests - can specify a language to filter - this should be c++ only + :param tests: list of all tests generated by run_tests_matrix.py + :param language_tag: string specifying a language from which to filter sanitizer tests - "_(language)_" + :return: list of relevant tests + """ + if language_tag: + return [test for test in tests if not language_tag in test.shortname and + not '_asan' in test.shortname and + not '_msan' in test.shortname and + not '_tsan' in test.shortname] + else: + return [test for test in tests if + '_asan' not in test.shortname and + '_msan' not in test.shortname and + '_tsan' not in test.shortname] + +def filter_tests(tests, base_branch): """ Filters out tests that are safe to ignore :param tests: list of all tests generated by run_tests_matrix.py :return: list of relevant tests """ - print("Finding file differences between grpc:master repo and pull request...") - changed_files = _get_changed_files() + print("Finding file differences between %s repo and current branch..." % base_branch) + changed_files = _get_changed_files(base_branch) for changed_file in changed_files: print(changed_file) - changed_files = ['src/ruby/dgf'] - # Filter core tests skip_core = _can_skip_tests(changed_files, starts_with_whitelist=_filter_whitelist(starts_with_whitelist, core_starts_with_triggers), @@ -178,13 +200,12 @@ def filter_tests(tests): starts_with_whitelist=_filter_whitelist(starts_with_whitelist, cpp_starts_with_triggers), ends_with_whitelist=ends_with_whitelist) if skip_cpp: - tests = _remove_irrelevant_tests(tests, '_cpp_') + tests = _remove_irrelevant_tests(tests, '_c++_') + tests = _remove_irrelevant_sanitizer_tests(tests, language_tag='_c++_') - # Tsan, msan, and asan tests skipped if core and c++ are skipped + # Sanitizer tests skipped if core and c++ are skipped if skip_core and skip_cpp: - tests = _remove_irrelevant_tests(tests, '_tsan') - tests = _remove_irrelevant_tests(tests, '_msan') - tests = _remove_irrelevant_tests(tests, '_asan') + tests = _remove_irrelevant_sanitizer_tests(tests) # Filter c# tests skip_csharp = _can_skip_tests(changed_files, @@ -213,6 +234,7 @@ def filter_tests(tests): ends_with_whitelist=ends_with_whitelist) if skip_php: tests = _remove_irrelevant_tests(tests, '_php_') + tests = _remove_irrelevant_tests(tests, '_php7_') # Filter python tests skip_python = _can_skip_tests(changed_files, diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py index 00a2d65d3d..3cea0f5011 100755 --- a/tools/run_tests/run_tests_matrix.py +++ b/tools/run_tests/run_tests_matrix.py @@ -235,6 +235,10 @@ argp.add_argument('--filter_pr_tests', action='store_const', const=True, help='Filters out tests irrelavant to pull request changes.') +argp.add_argument('--base_branch', + default='origin/master', + type=str, + help='Branch that pull request is requesting to merge into') args = argp.parse_args() extra_args = [] @@ -270,12 +274,12 @@ print if args.filter_pr_tests: print 'IMPORTANT: Test filtering is not active; this is only for testing.' - relevant_jobs = filter_tests(jobs) + relevant_jobs = filter_tests(jobs, args.base_branch) print if len(relevant_jobs) == len(jobs): - print 'No tests were filtered.' + print '(TESTING) No tests will be skipped.' else: - print 'These tests were filtered:' + print '(TESTING) These tests will be skipped:' for job in list(set(jobs) - set(relevant_jobs)): print ' %s' % job.shortname print -- cgit v1.2.3 From 2cef11c6674e67aea8e7f63f7ac2869e5d44a7c5 Mon Sep 17 00:00:00 2001 From: Noah Eisen Date: Fri, 7 Oct 2016 15:35:48 -0700 Subject: added status request ability to the FullDuplexCall so that cpp server can pass the node client's status_code_and_message test --- test/cpp/interop/interop_server.cc | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/test/cpp/interop/interop_server.cc b/test/cpp/interop/interop_server.cc index c05eb5d146..0da37e1551 100644 --- a/test/cpp/interop/interop_server.cc +++ b/test/cpp/interop/interop_server.cc @@ -82,6 +82,8 @@ const char kEchoInitialMetadataKey[] = "x-grpc-test-echo-initial"; const char kEchoTrailingBinMetadataKey[] = "x-grpc-test-echo-trailing-bin"; const char kEchoUserAgentKey[] = "x-grpc-test-echo-useragent"; +namespace { + void MaybeEchoMetadata(ServerContext* context) { const auto& client_metadata = context->client_metadata(); GPR_ASSERT(client_metadata.count(kEchoInitialMetadataKey) <= 1); @@ -145,6 +147,28 @@ bool CheckExpectedCompression(const ServerContext& context, return true; } +Status RequestedStatusOrOk(const SimpleRequest* request) { + if (request->has_response_status()) { + return Status( + static_cast(request->response_status().code()), + request->response_status().message()); + } else { + return Status::OK; + } +} + +Status RequestedStatusOrOk(const StreamingOutputCallRequest* request) { + if (request->has_response_status()) { + return Status( + static_cast(request->response_status().code()), + request->response_status().message()); + } else { + return Status::OK; + } +} + +} // anonomous namespace + class TestServiceImpl : public TestService::Service { public: Status EmptyCall(ServerContext* context, const grpc::testing::Empty* request, @@ -179,13 +203,7 @@ class TestServiceImpl : public TestService::Service { } } - if (request->has_response_status()) { - return Status( - static_cast(request->response_status().code()), - request->response_status().message()); - } - - return Status::OK; + return RequestedStatusOrOk(request); } Status StreamingOutputCall( @@ -223,7 +241,7 @@ class TestServiceImpl : public TestService::Service { write_success = writer->Write(response, wopts); } if (write_success) { - return Status::OK; + return RequestedStatusOrOk(request); } else { return Status(grpc::StatusCode::INTERNAL, "Error writing response."); } @@ -273,7 +291,7 @@ class TestServiceImpl : public TestService::Service { } } if (write_success) { - return Status::OK; + return RequestedStatusOrOk(&request); } else { return Status(grpc::StatusCode::INTERNAL, "Error writing response."); } @@ -302,7 +320,7 @@ class TestServiceImpl : public TestService::Service { write_success = stream->Write(response); } if (write_success) { - return Status::OK; + return RequestedStatusOrOk(&request); } else { return Status(grpc::StatusCode::INTERNAL, "Error writing response."); } -- cgit v1.2.3 From d195cf589d3f03b4f08017f3e2885c2c2fff125b Mon Sep 17 00:00:00 2001 From: kpayson64 Date: Sun, 9 Oct 2016 18:04:00 -0700 Subject: Add condition variable polling engine --- BUILD | 16 ++ CMakeLists.txt | 6 + Makefile | 44 +++ binding.gyp | 2 + build.yaml | 18 ++ config.m4 | 2 + gRPC-Core.podspec | 6 + grpc.gemspec | 4 + package.xml | 4 + src/core/lib/iomgr/ev_epoll_linux.c | 4 + src/core/lib/iomgr/ev_poll_cv_posix.c | 297 +++++++++++++++++++++ src/core/lib/iomgr/ev_poll_cv_posix.h | 68 +++++ src/core/lib/iomgr/ev_poll_posix.c | 3 + src/core/lib/iomgr/ev_posix.c | 2 + src/core/lib/iomgr/wakeup_fd_cv.c | 118 ++++++++ src/core/lib/iomgr/wakeup_fd_cv.h | 55 ++++ src/core/lib/iomgr/wakeup_fd_pipe.c | 12 +- src/core/lib/iomgr/wakeup_fd_posix.c | 9 +- src/core/lib/iomgr/wakeup_fd_posix.h | 2 + src/python/grpcio/grpc_core_dependencies.py | 2 + test/core/iomgr/wakeup_fd_cv_test.c | 240 +++++++++++++++++ tools/doxygen/Doxyfile.core.internal | 4 + tools/run_tests/run_tests.py | 2 +- tools/run_tests/sources_and_headers.json | 23 ++ tools/run_tests/tests.json | 19 ++ vsprojects/vcxproj/grpc/grpc.vcxproj | 6 + vsprojects/vcxproj/grpc/grpc.vcxproj.filters | 12 + .../vcxproj/grpc_test_util/grpc_test_util.vcxproj | 6 + .../grpc_test_util/grpc_test_util.vcxproj.filters | 12 + .../vcxproj/grpc_unsecure/grpc_unsecure.vcxproj | 6 + .../grpc_unsecure/grpc_unsecure.vcxproj.filters | 12 + 31 files changed, 1010 insertions(+), 6 deletions(-) create mode 100644 src/core/lib/iomgr/ev_poll_cv_posix.c create mode 100644 src/core/lib/iomgr/ev_poll_cv_posix.h create mode 100644 src/core/lib/iomgr/wakeup_fd_cv.c create mode 100644 src/core/lib/iomgr/wakeup_fd_cv.h create mode 100644 test/core/iomgr/wakeup_fd_cv_test.c diff --git a/BUILD b/BUILD index bad6f3f075..ba44367dbb 100644 --- a/BUILD +++ b/BUILD @@ -186,6 +186,7 @@ cc_library( "src/core/lib/iomgr/error.h", "src/core/lib/iomgr/ev_epoll_linux.h", "src/core/lib/iomgr/ev_poll_and_epoll_posix.h", + "src/core/lib/iomgr/ev_poll_cv_posix.h", "src/core/lib/iomgr/ev_poll_posix.h", "src/core/lib/iomgr/ev_posix.h", "src/core/lib/iomgr/exec_ctx.h", @@ -217,6 +218,7 @@ cc_library( "src/core/lib/iomgr/timer_heap.h", "src/core/lib/iomgr/udp_server.h", "src/core/lib/iomgr/unix_sockets_posix.h", + "src/core/lib/iomgr/wakeup_fd_cv.h", "src/core/lib/iomgr/wakeup_fd_pipe.h", "src/core/lib/iomgr/wakeup_fd_posix.h", "src/core/lib/iomgr/workqueue.h", @@ -347,6 +349,7 @@ cc_library( "src/core/lib/iomgr/error.c", "src/core/lib/iomgr/ev_epoll_linux.c", "src/core/lib/iomgr/ev_poll_and_epoll_posix.c", + "src/core/lib/iomgr/ev_poll_cv_posix.c", "src/core/lib/iomgr/ev_poll_posix.c", "src/core/lib/iomgr/ev_posix.c", "src/core/lib/iomgr/exec_ctx.c", @@ -379,6 +382,7 @@ cc_library( "src/core/lib/iomgr/udp_server.c", "src/core/lib/iomgr/unix_sockets_posix.c", "src/core/lib/iomgr/unix_sockets_posix_noop.c", + "src/core/lib/iomgr/wakeup_fd_cv.c", "src/core/lib/iomgr/wakeup_fd_eventfd.c", "src/core/lib/iomgr/wakeup_fd_nospecial.c", "src/core/lib/iomgr/wakeup_fd_pipe.c", @@ -587,6 +591,7 @@ cc_library( "src/core/lib/iomgr/error.h", "src/core/lib/iomgr/ev_epoll_linux.h", "src/core/lib/iomgr/ev_poll_and_epoll_posix.h", + "src/core/lib/iomgr/ev_poll_cv_posix.h", "src/core/lib/iomgr/ev_poll_posix.h", "src/core/lib/iomgr/ev_posix.h", "src/core/lib/iomgr/exec_ctx.h", @@ -618,6 +623,7 @@ cc_library( "src/core/lib/iomgr/timer_heap.h", "src/core/lib/iomgr/udp_server.h", "src/core/lib/iomgr/unix_sockets_posix.h", + "src/core/lib/iomgr/wakeup_fd_cv.h", "src/core/lib/iomgr/wakeup_fd_pipe.h", "src/core/lib/iomgr/wakeup_fd_posix.h", "src/core/lib/iomgr/workqueue.h", @@ -733,6 +739,7 @@ cc_library( "src/core/lib/iomgr/error.c", "src/core/lib/iomgr/ev_epoll_linux.c", "src/core/lib/iomgr/ev_poll_and_epoll_posix.c", + "src/core/lib/iomgr/ev_poll_cv_posix.c", "src/core/lib/iomgr/ev_poll_posix.c", "src/core/lib/iomgr/ev_posix.c", "src/core/lib/iomgr/exec_ctx.c", @@ -765,6 +772,7 @@ cc_library( "src/core/lib/iomgr/udp_server.c", "src/core/lib/iomgr/unix_sockets_posix.c", "src/core/lib/iomgr/unix_sockets_posix_noop.c", + "src/core/lib/iomgr/wakeup_fd_cv.c", "src/core/lib/iomgr/wakeup_fd_eventfd.c", "src/core/lib/iomgr/wakeup_fd_nospecial.c", "src/core/lib/iomgr/wakeup_fd_pipe.c", @@ -943,6 +951,7 @@ cc_library( "src/core/lib/iomgr/error.h", "src/core/lib/iomgr/ev_epoll_linux.h", "src/core/lib/iomgr/ev_poll_and_epoll_posix.h", + "src/core/lib/iomgr/ev_poll_cv_posix.h", "src/core/lib/iomgr/ev_poll_posix.h", "src/core/lib/iomgr/ev_posix.h", "src/core/lib/iomgr/exec_ctx.h", @@ -974,6 +983,7 @@ cc_library( "src/core/lib/iomgr/timer_heap.h", "src/core/lib/iomgr/udp_server.h", "src/core/lib/iomgr/unix_sockets_posix.h", + "src/core/lib/iomgr/wakeup_fd_cv.h", "src/core/lib/iomgr/wakeup_fd_pipe.h", "src/core/lib/iomgr/wakeup_fd_posix.h", "src/core/lib/iomgr/workqueue.h", @@ -1081,6 +1091,7 @@ cc_library( "src/core/lib/iomgr/error.c", "src/core/lib/iomgr/ev_epoll_linux.c", "src/core/lib/iomgr/ev_poll_and_epoll_posix.c", + "src/core/lib/iomgr/ev_poll_cv_posix.c", "src/core/lib/iomgr/ev_poll_posix.c", "src/core/lib/iomgr/ev_posix.c", "src/core/lib/iomgr/exec_ctx.c", @@ -1113,6 +1124,7 @@ cc_library( "src/core/lib/iomgr/udp_server.c", "src/core/lib/iomgr/unix_sockets_posix.c", "src/core/lib/iomgr/unix_sockets_posix_noop.c", + "src/core/lib/iomgr/wakeup_fd_cv.c", "src/core/lib/iomgr/wakeup_fd_eventfd.c", "src/core/lib/iomgr/wakeup_fd_nospecial.c", "src/core/lib/iomgr/wakeup_fd_pipe.c", @@ -1844,6 +1856,7 @@ objc_library( "src/core/lib/iomgr/error.c", "src/core/lib/iomgr/ev_epoll_linux.c", "src/core/lib/iomgr/ev_poll_and_epoll_posix.c", + "src/core/lib/iomgr/ev_poll_cv_posix.c", "src/core/lib/iomgr/ev_poll_posix.c", "src/core/lib/iomgr/ev_posix.c", "src/core/lib/iomgr/exec_ctx.c", @@ -1876,6 +1889,7 @@ objc_library( "src/core/lib/iomgr/udp_server.c", "src/core/lib/iomgr/unix_sockets_posix.c", "src/core/lib/iomgr/unix_sockets_posix_noop.c", + "src/core/lib/iomgr/wakeup_fd_cv.c", "src/core/lib/iomgr/wakeup_fd_eventfd.c", "src/core/lib/iomgr/wakeup_fd_nospecial.c", "src/core/lib/iomgr/wakeup_fd_pipe.c", @@ -2063,6 +2077,7 @@ objc_library( "src/core/lib/iomgr/error.h", "src/core/lib/iomgr/ev_epoll_linux.h", "src/core/lib/iomgr/ev_poll_and_epoll_posix.h", + "src/core/lib/iomgr/ev_poll_cv_posix.h", "src/core/lib/iomgr/ev_poll_posix.h", "src/core/lib/iomgr/ev_posix.h", "src/core/lib/iomgr/exec_ctx.h", @@ -2094,6 +2109,7 @@ objc_library( "src/core/lib/iomgr/timer_heap.h", "src/core/lib/iomgr/udp_server.h", "src/core/lib/iomgr/unix_sockets_posix.h", + "src/core/lib/iomgr/wakeup_fd_cv.h", "src/core/lib/iomgr/wakeup_fd_pipe.h", "src/core/lib/iomgr/wakeup_fd_posix.h", "src/core/lib/iomgr/workqueue.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index c4191521bd..747d1fab4d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -314,6 +314,7 @@ add_library(grpc src/core/lib/iomgr/error.c src/core/lib/iomgr/ev_epoll_linux.c src/core/lib/iomgr/ev_poll_and_epoll_posix.c + src/core/lib/iomgr/ev_poll_cv_posix.c src/core/lib/iomgr/ev_poll_posix.c src/core/lib/iomgr/ev_posix.c src/core/lib/iomgr/exec_ctx.c @@ -346,6 +347,7 @@ add_library(grpc src/core/lib/iomgr/udp_server.c src/core/lib/iomgr/unix_sockets_posix.c src/core/lib/iomgr/unix_sockets_posix_noop.c + src/core/lib/iomgr/wakeup_fd_cv.c src/core/lib/iomgr/wakeup_fd_eventfd.c src/core/lib/iomgr/wakeup_fd_nospecial.c src/core/lib/iomgr/wakeup_fd_pipe.c @@ -573,6 +575,7 @@ add_library(grpc_cronet src/core/lib/iomgr/error.c src/core/lib/iomgr/ev_epoll_linux.c src/core/lib/iomgr/ev_poll_and_epoll_posix.c + src/core/lib/iomgr/ev_poll_cv_posix.c src/core/lib/iomgr/ev_poll_posix.c src/core/lib/iomgr/ev_posix.c src/core/lib/iomgr/exec_ctx.c @@ -605,6 +608,7 @@ add_library(grpc_cronet src/core/lib/iomgr/udp_server.c src/core/lib/iomgr/unix_sockets_posix.c src/core/lib/iomgr/unix_sockets_posix_noop.c + src/core/lib/iomgr/wakeup_fd_cv.c src/core/lib/iomgr/wakeup_fd_eventfd.c src/core/lib/iomgr/wakeup_fd_nospecial.c src/core/lib/iomgr/wakeup_fd_pipe.c @@ -804,6 +808,7 @@ add_library(grpc_unsecure src/core/lib/iomgr/error.c src/core/lib/iomgr/ev_epoll_linux.c src/core/lib/iomgr/ev_poll_and_epoll_posix.c + src/core/lib/iomgr/ev_poll_cv_posix.c src/core/lib/iomgr/ev_poll_posix.c src/core/lib/iomgr/ev_posix.c src/core/lib/iomgr/exec_ctx.c @@ -836,6 +841,7 @@ add_library(grpc_unsecure src/core/lib/iomgr/udp_server.c src/core/lib/iomgr/unix_sockets_posix.c src/core/lib/iomgr/unix_sockets_posix_noop.c + src/core/lib/iomgr/wakeup_fd_cv.c src/core/lib/iomgr/wakeup_fd_eventfd.c src/core/lib/iomgr/wakeup_fd_nospecial.c src/core/lib/iomgr/wakeup_fd_pipe.c diff --git a/Makefile b/Makefile index 62c65822b0..1f4c9b5c32 100644 --- a/Makefile +++ b/Makefile @@ -1025,6 +1025,7 @@ transport_security_test: $(BINDIR)/$(CONFIG)/transport_security_test udp_server_test: $(BINDIR)/$(CONFIG)/udp_server_test uri_fuzzer_test: $(BINDIR)/$(CONFIG)/uri_fuzzer_test uri_parser_test: $(BINDIR)/$(CONFIG)/uri_parser_test +wakeup_fd_cv_test: $(BINDIR)/$(CONFIG)/wakeup_fd_cv_test alarm_cpp_test: $(BINDIR)/$(CONFIG)/alarm_cpp_test async_end2end_test: $(BINDIR)/$(CONFIG)/async_end2end_test auth_property_iterator_test: $(BINDIR)/$(CONFIG)/auth_property_iterator_test @@ -1340,6 +1341,7 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/transport_security_test \ $(BINDIR)/$(CONFIG)/udp_server_test \ $(BINDIR)/$(CONFIG)/uri_parser_test \ + $(BINDIR)/$(CONFIG)/wakeup_fd_cv_test \ $(BINDIR)/$(CONFIG)/public_headers_must_be_c89 \ $(BINDIR)/$(CONFIG)/badreq_bad_client_test \ $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test \ @@ -1738,6 +1740,8 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/udp_server_test || ( echo test udp_server_test failed ; exit 1 ) $(E) "[RUN] Testing uri_parser_test" $(Q) $(BINDIR)/$(CONFIG)/uri_parser_test || ( echo test uri_parser_test failed ; exit 1 ) + $(E) "[RUN] Testing wakeup_fd_cv_test" + $(Q) $(BINDIR)/$(CONFIG)/wakeup_fd_cv_test || ( echo test wakeup_fd_cv_test failed ; exit 1 ) $(E) "[RUN] Testing public_headers_must_be_c89" $(Q) $(BINDIR)/$(CONFIG)/public_headers_must_be_c89 || ( echo test public_headers_must_be_c89 failed ; exit 1 ) $(E) "[RUN] Testing badreq_bad_client_test" @@ -2558,6 +2562,7 @@ LIBGRPC_SRC = \ src/core/lib/iomgr/error.c \ src/core/lib/iomgr/ev_epoll_linux.c \ src/core/lib/iomgr/ev_poll_and_epoll_posix.c \ + src/core/lib/iomgr/ev_poll_cv_posix.c \ src/core/lib/iomgr/ev_poll_posix.c \ src/core/lib/iomgr/ev_posix.c \ src/core/lib/iomgr/exec_ctx.c \ @@ -2590,6 +2595,7 @@ LIBGRPC_SRC = \ src/core/lib/iomgr/udp_server.c \ src/core/lib/iomgr/unix_sockets_posix.c \ src/core/lib/iomgr/unix_sockets_posix_noop.c \ + src/core/lib/iomgr/wakeup_fd_cv.c \ src/core/lib/iomgr/wakeup_fd_eventfd.c \ src/core/lib/iomgr/wakeup_fd_nospecial.c \ src/core/lib/iomgr/wakeup_fd_pipe.c \ @@ -2835,6 +2841,7 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/iomgr/error.c \ src/core/lib/iomgr/ev_epoll_linux.c \ src/core/lib/iomgr/ev_poll_and_epoll_posix.c \ + src/core/lib/iomgr/ev_poll_cv_posix.c \ src/core/lib/iomgr/ev_poll_posix.c \ src/core/lib/iomgr/ev_posix.c \ src/core/lib/iomgr/exec_ctx.c \ @@ -2867,6 +2874,7 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/iomgr/udp_server.c \ src/core/lib/iomgr/unix_sockets_posix.c \ src/core/lib/iomgr/unix_sockets_posix_noop.c \ + src/core/lib/iomgr/wakeup_fd_cv.c \ src/core/lib/iomgr/wakeup_fd_eventfd.c \ src/core/lib/iomgr/wakeup_fd_nospecial.c \ src/core/lib/iomgr/wakeup_fd_pipe.c \ @@ -3102,6 +3110,7 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/lib/iomgr/error.c \ src/core/lib/iomgr/ev_epoll_linux.c \ src/core/lib/iomgr/ev_poll_and_epoll_posix.c \ + src/core/lib/iomgr/ev_poll_cv_posix.c \ src/core/lib/iomgr/ev_poll_posix.c \ src/core/lib/iomgr/ev_posix.c \ src/core/lib/iomgr/exec_ctx.c \ @@ -3134,6 +3143,7 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/lib/iomgr/udp_server.c \ src/core/lib/iomgr/unix_sockets_posix.c \ src/core/lib/iomgr/unix_sockets_posix_noop.c \ + src/core/lib/iomgr/wakeup_fd_cv.c \ src/core/lib/iomgr/wakeup_fd_eventfd.c \ src/core/lib/iomgr/wakeup_fd_nospecial.c \ src/core/lib/iomgr/wakeup_fd_pipe.c \ @@ -3296,6 +3306,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/iomgr/error.c \ src/core/lib/iomgr/ev_epoll_linux.c \ src/core/lib/iomgr/ev_poll_and_epoll_posix.c \ + src/core/lib/iomgr/ev_poll_cv_posix.c \ src/core/lib/iomgr/ev_poll_posix.c \ src/core/lib/iomgr/ev_posix.c \ src/core/lib/iomgr/exec_ctx.c \ @@ -3328,6 +3339,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/iomgr/udp_server.c \ src/core/lib/iomgr/unix_sockets_posix.c \ src/core/lib/iomgr/unix_sockets_posix_noop.c \ + src/core/lib/iomgr/wakeup_fd_cv.c \ src/core/lib/iomgr/wakeup_fd_eventfd.c \ src/core/lib/iomgr/wakeup_fd_nospecial.c \ src/core/lib/iomgr/wakeup_fd_pipe.c \ @@ -10757,6 +10769,38 @@ endif endif +WAKEUP_FD_CV_TEST_SRC = \ + test/core/iomgr/wakeup_fd_cv_test.c \ + +WAKEUP_FD_CV_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(WAKEUP_FD_CV_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/wakeup_fd_cv_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/wakeup_fd_cv_test: $(WAKEUP_FD_CV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LD) $(LDFLAGS) $(WAKEUP_FD_CV_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)/wakeup_fd_cv_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/iomgr/wakeup_fd_cv_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_wakeup_fd_cv_test: $(WAKEUP_FD_CV_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(WAKEUP_FD_CV_TEST_OBJS:.o=.dep) +endif +endif + + ALARM_CPP_TEST_SRC = \ test/cpp/common/alarm_cpp_test.cc \ diff --git a/binding.gyp b/binding.gyp index 58edda2e63..85070e5cac 100644 --- a/binding.gyp +++ b/binding.gyp @@ -589,6 +589,7 @@ 'src/core/lib/iomgr/error.c', 'src/core/lib/iomgr/ev_epoll_linux.c', 'src/core/lib/iomgr/ev_poll_and_epoll_posix.c', + 'src/core/lib/iomgr/ev_poll_cv_posix.c', 'src/core/lib/iomgr/ev_poll_posix.c', 'src/core/lib/iomgr/ev_posix.c', 'src/core/lib/iomgr/exec_ctx.c', @@ -621,6 +622,7 @@ 'src/core/lib/iomgr/udp_server.c', 'src/core/lib/iomgr/unix_sockets_posix.c', 'src/core/lib/iomgr/unix_sockets_posix_noop.c', + 'src/core/lib/iomgr/wakeup_fd_cv.c', 'src/core/lib/iomgr/wakeup_fd_eventfd.c', 'src/core/lib/iomgr/wakeup_fd_nospecial.c', 'src/core/lib/iomgr/wakeup_fd_pipe.c', diff --git a/build.yaml b/build.yaml index 584084ff86..3e64ce8f37 100644 --- a/build.yaml +++ b/build.yaml @@ -190,6 +190,7 @@ filegroups: - src/core/lib/iomgr/error.h - src/core/lib/iomgr/ev_epoll_linux.h - src/core/lib/iomgr/ev_poll_and_epoll_posix.h + - src/core/lib/iomgr/ev_poll_cv_posix.h - src/core/lib/iomgr/ev_poll_posix.h - src/core/lib/iomgr/ev_posix.h - src/core/lib/iomgr/exec_ctx.h @@ -221,6 +222,7 @@ filegroups: - src/core/lib/iomgr/timer_heap.h - src/core/lib/iomgr/udp_server.h - src/core/lib/iomgr/unix_sockets_posix.h + - src/core/lib/iomgr/wakeup_fd_cv.h - src/core/lib/iomgr/wakeup_fd_pipe.h - src/core/lib/iomgr/wakeup_fd_posix.h - src/core/lib/iomgr/workqueue.h @@ -274,6 +276,7 @@ filegroups: - src/core/lib/iomgr/error.c - src/core/lib/iomgr/ev_epoll_linux.c - src/core/lib/iomgr/ev_poll_and_epoll_posix.c + - src/core/lib/iomgr/ev_poll_cv_posix.c - src/core/lib/iomgr/ev_poll_posix.c - src/core/lib/iomgr/ev_posix.c - src/core/lib/iomgr/exec_ctx.c @@ -306,6 +309,7 @@ filegroups: - src/core/lib/iomgr/udp_server.c - src/core/lib/iomgr/unix_sockets_posix.c - src/core/lib/iomgr/unix_sockets_posix_noop.c + - src/core/lib/iomgr/wakeup_fd_cv.c - src/core/lib/iomgr/wakeup_fd_eventfd.c - src/core/lib/iomgr/wakeup_fd_nospecial.c - src/core/lib/iomgr/wakeup_fd_pipe.c @@ -2592,6 +2596,20 @@ targets: - grpc - gpr_test_util - gpr +- name: wakeup_fd_cv_test + build: test + language: c + src: + - test/core/iomgr/wakeup_fd_cv_test.c + deps: + - grpc_test_util + - grpc + - gpr_test_util + - gpr + platforms: + - mac + - linux + - posix - name: alarm_cpp_test gtest: true build: test diff --git a/config.m4 b/config.m4 index 0f103655a8..1452798897 100644 --- a/config.m4 +++ b/config.m4 @@ -108,6 +108,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/iomgr/error.c \ src/core/lib/iomgr/ev_epoll_linux.c \ src/core/lib/iomgr/ev_poll_and_epoll_posix.c \ + src/core/lib/iomgr/ev_poll_cv_posix.c \ src/core/lib/iomgr/ev_poll_posix.c \ src/core/lib/iomgr/ev_posix.c \ src/core/lib/iomgr/exec_ctx.c \ @@ -140,6 +141,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/iomgr/udp_server.c \ src/core/lib/iomgr/unix_sockets_posix.c \ src/core/lib/iomgr/unix_sockets_posix_noop.c \ + src/core/lib/iomgr/wakeup_fd_cv.c \ src/core/lib/iomgr/wakeup_fd_eventfd.c \ src/core/lib/iomgr/wakeup_fd_nospecial.c \ src/core/lib/iomgr/wakeup_fd_pipe.c \ diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 6886bdfb5a..3ac0b841cf 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -273,6 +273,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/error.h', 'src/core/lib/iomgr/ev_epoll_linux.h', 'src/core/lib/iomgr/ev_poll_and_epoll_posix.h', + 'src/core/lib/iomgr/ev_poll_cv_posix.h', 'src/core/lib/iomgr/ev_poll_posix.h', 'src/core/lib/iomgr/ev_posix.h', 'src/core/lib/iomgr/exec_ctx.h', @@ -304,6 +305,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/timer_heap.h', 'src/core/lib/iomgr/udp_server.h', 'src/core/lib/iomgr/unix_sockets_posix.h', + 'src/core/lib/iomgr/wakeup_fd_cv.h', 'src/core/lib/iomgr/wakeup_fd_pipe.h', 'src/core/lib/iomgr/wakeup_fd_posix.h', 'src/core/lib/iomgr/workqueue.h', @@ -438,6 +440,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/error.c', 'src/core/lib/iomgr/ev_epoll_linux.c', 'src/core/lib/iomgr/ev_poll_and_epoll_posix.c', + 'src/core/lib/iomgr/ev_poll_cv_posix.c', 'src/core/lib/iomgr/ev_poll_posix.c', 'src/core/lib/iomgr/ev_posix.c', 'src/core/lib/iomgr/exec_ctx.c', @@ -470,6 +473,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/udp_server.c', 'src/core/lib/iomgr/unix_sockets_posix.c', 'src/core/lib/iomgr/unix_sockets_posix_noop.c', + 'src/core/lib/iomgr/wakeup_fd_cv.c', 'src/core/lib/iomgr/wakeup_fd_eventfd.c', 'src/core/lib/iomgr/wakeup_fd_nospecial.c', 'src/core/lib/iomgr/wakeup_fd_pipe.c', @@ -646,6 +650,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/error.h', 'src/core/lib/iomgr/ev_epoll_linux.h', 'src/core/lib/iomgr/ev_poll_and_epoll_posix.h', + 'src/core/lib/iomgr/ev_poll_cv_posix.h', 'src/core/lib/iomgr/ev_poll_posix.h', 'src/core/lib/iomgr/ev_posix.h', 'src/core/lib/iomgr/exec_ctx.h', @@ -677,6 +682,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/timer_heap.h', 'src/core/lib/iomgr/udp_server.h', 'src/core/lib/iomgr/unix_sockets_posix.h', + 'src/core/lib/iomgr/wakeup_fd_cv.h', 'src/core/lib/iomgr/wakeup_fd_pipe.h', 'src/core/lib/iomgr/wakeup_fd_posix.h', 'src/core/lib/iomgr/workqueue.h', diff --git a/grpc.gemspec b/grpc.gemspec index 6079ea2aef..85135a5327 100755 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -193,6 +193,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/error.h ) s.files += %w( src/core/lib/iomgr/ev_epoll_linux.h ) s.files += %w( src/core/lib/iomgr/ev_poll_and_epoll_posix.h ) + s.files += %w( src/core/lib/iomgr/ev_poll_cv_posix.h ) s.files += %w( src/core/lib/iomgr/ev_poll_posix.h ) s.files += %w( src/core/lib/iomgr/ev_posix.h ) s.files += %w( src/core/lib/iomgr/exec_ctx.h ) @@ -224,6 +225,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/timer_heap.h ) s.files += %w( src/core/lib/iomgr/udp_server.h ) s.files += %w( src/core/lib/iomgr/unix_sockets_posix.h ) + s.files += %w( src/core/lib/iomgr/wakeup_fd_cv.h ) s.files += %w( src/core/lib/iomgr/wakeup_fd_pipe.h ) s.files += %w( src/core/lib/iomgr/wakeup_fd_posix.h ) s.files += %w( src/core/lib/iomgr/workqueue.h ) @@ -358,6 +360,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/error.c ) s.files += %w( src/core/lib/iomgr/ev_epoll_linux.c ) s.files += %w( src/core/lib/iomgr/ev_poll_and_epoll_posix.c ) + s.files += %w( src/core/lib/iomgr/ev_poll_cv_posix.c ) s.files += %w( src/core/lib/iomgr/ev_poll_posix.c ) s.files += %w( src/core/lib/iomgr/ev_posix.c ) s.files += %w( src/core/lib/iomgr/exec_ctx.c ) @@ -390,6 +393,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/udp_server.c ) s.files += %w( src/core/lib/iomgr/unix_sockets_posix.c ) s.files += %w( src/core/lib/iomgr/unix_sockets_posix_noop.c ) + s.files += %w( src/core/lib/iomgr/wakeup_fd_cv.c ) s.files += %w( src/core/lib/iomgr/wakeup_fd_eventfd.c ) s.files += %w( src/core/lib/iomgr/wakeup_fd_nospecial.c ) s.files += %w( src/core/lib/iomgr/wakeup_fd_pipe.c ) diff --git a/package.xml b/package.xml index 7bac695787..4631fc1c39 100644 --- a/package.xml +++ b/package.xml @@ -200,6 +200,7 @@ + @@ -231,6 +232,7 @@ + @@ -365,6 +367,7 @@ + @@ -397,6 +400,7 @@ + diff --git a/src/core/lib/iomgr/ev_epoll_linux.c b/src/core/lib/iomgr/ev_epoll_linux.c index ab77ebc78b..249bc98735 100644 --- a/src/core/lib/iomgr/ev_epoll_linux.c +++ b/src/core/lib/iomgr/ev_epoll_linux.c @@ -1892,6 +1892,10 @@ const grpc_event_engine_vtable *grpc_init_epoll_linux(void) { return NULL; } + if (!grpc_has_wakeup_fd) { + return NULL; + } + if (!is_epoll_available()) { return NULL; } diff --git a/src/core/lib/iomgr/ev_poll_cv_posix.c b/src/core/lib/iomgr/ev_poll_cv_posix.c new file mode 100644 index 0000000000..dd1bbedcc1 --- /dev/null +++ b/src/core/lib/iomgr/ev_poll_cv_posix.c @@ -0,0 +1,297 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include + +#ifdef GPR_POSIX_SOCKET + +#include "src/core/lib/iomgr/ev_poll_cv_posix.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "src/core/lib/iomgr/ev_poll_posix.h" +#include "src/core/lib/iomgr/wakeup_fd_posix.h" + +#define POLL_PERIOD_MS 1000 +#define DEFAULT_TABLE_SIZE 16 + +typedef enum status_t { INPROGRESS, COMPLETED, CANCELLED } status_t; + +typedef struct poll_args { + gpr_refcount refcount; + gpr_cv* cv; + struct pollfd* fds; + nfds_t nfds; + int timeout; + int retval; + int err; + status_t status; +} poll_args; + +cv_fd_table g_cvfds; + +static void decref_poll_args(poll_args* args) { + if (gpr_unref(&args->refcount)) { + gpr_free(args->fds); + gpr_cv_destroy(args->cv); + gpr_free(args->cv); + gpr_free(args); + } +} + +// Poll in a background thread +static void run_poll(void* arg) { + int timeout, retval; + poll_args* pargs = (poll_args*)arg; + while (pargs->status == INPROGRESS) { + if (pargs->timeout < 0) { + timeout = POLL_PERIOD_MS; + } else { + timeout = GPR_MIN(POLL_PERIOD_MS, pargs->timeout); + pargs->timeout -= timeout; + } + retval = g_cvfds.poll(pargs->fds, pargs->nfds, timeout); + if (retval != 0 || pargs->timeout == 0) { + pargs->retval = retval; + pargs->err = errno; + break; + } + } + gpr_mu_lock(&g_cvfds.mu); + if (pargs->status == INPROGRESS) { + // Signal main thread that the poll completed + pargs->status = COMPLETED; + gpr_cv_signal(pargs->cv); + } + decref_poll_args(pargs); + g_cvfds.pollcount--; + if (g_cvfds.shutdown && g_cvfds.pollcount == 0) { + gpr_cv_signal(&g_cvfds.shutdown_complete); + } + gpr_mu_unlock(&g_cvfds.mu); +} + +// This function overrides poll() to handle condition variable wakeup fds +static int cvfd_poll(struct pollfd* fds, nfds_t nfds, int timeout) { + unsigned int i; + int res, idx; + gpr_cv* pollcv; + cv_node *cvn, *prev; + nfds_t nsockfds = 0; + gpr_thd_id t_id; + gpr_thd_options opt; + poll_args* pargs = NULL; + gpr_mu_lock(&g_cvfds.mu); + pollcv = gpr_malloc(sizeof(gpr_cv)); + gpr_cv_init(pollcv); + for (i = 0; i < nfds; i++) { + fds[i].revents = 0; + if (fds[i].fd < 0 && (fds[i].events & POLLIN)) { + idx = FD_TO_IDX(fds[i].fd); + cvn = gpr_malloc(sizeof(cv_node)); + cvn->cv = pollcv; + cvn->next = g_cvfds.cvfds[idx].cvs; + g_cvfds.cvfds[idx].cvs = cvn; + // We should return immediately if there are pending events, + // but we still need to call poll() to check for socket events + if (g_cvfds.cvfds[idx].is_set) { + timeout = 0; + } + } else if (fds[i].fd >= 0) { + nsockfds++; + } + } + + if (nsockfds > 0) { + pargs = gpr_malloc(sizeof(struct poll_args)); + // Both the main thread and calling thread get a reference + gpr_ref_init(&pargs->refcount, 2); + pargs->cv = pollcv; + pargs->fds = gpr_malloc(sizeof(struct pollfd) * nsockfds); + pargs->nfds = nsockfds; + pargs->timeout = timeout; + pargs->retval = 0; + pargs->err = 0; + pargs->status = INPROGRESS; + idx = 0; + for (i = 0; i < nfds; i++) { + if (fds[i].fd >= 0) { + pargs->fds[idx].fd = fds[i].fd; + pargs->fds[idx].events = fds[i].events; + pargs->fds[idx].revents = 0; + idx++; + } + } + g_cvfds.pollcount++; + opt = gpr_thd_options_default(); + gpr_thd_options_set_detached(&opt); + gpr_thd_new(&t_id, &run_poll, pargs, &opt); + // We want the poll() thread to trigger the deadline, so wait forever here + gpr_cv_wait(pollcv, &g_cvfds.mu, gpr_inf_future(GPR_CLOCK_MONOTONIC)); + if (pargs->status == COMPLETED) { + res = pargs->retval; + errno = pargs->err; + } else { + res = 0; + errno = 0; + pargs->status = CANCELLED; + } + } else { + gpr_timespec deadline = gpr_now(GPR_CLOCK_REALTIME); + deadline = + gpr_time_add(deadline, gpr_time_from_millis(timeout, GPR_TIMESPAN)); + gpr_cv_wait(pollcv, &g_cvfds.mu, deadline); + res = 0; + } + + idx = 0; + for (i = 0; i < nfds; i++) { + if (fds[i].fd < 0 && (fds[i].events & POLLIN)) { + cvn = g_cvfds.cvfds[FD_TO_IDX(fds[i].fd)].cvs; + prev = NULL; + while (cvn->cv != pollcv) { + prev = cvn; + cvn = cvn->next; + GPR_ASSERT(cvn); + } + if (!prev) { + g_cvfds.cvfds[FD_TO_IDX(fds[i].fd)].cvs = cvn->next; + } else { + prev->next = cvn->next; + } + gpr_free(cvn); + + if (g_cvfds.cvfds[FD_TO_IDX(fds[i].fd)].is_set) { + fds[i].revents = POLLIN; + if (res >= 0) res++; + } + } else if (fds[i].fd >= 0 && pargs->status == COMPLETED) { + fds[i].revents = pargs->fds[idx].revents; + idx++; + } + } + + if (pargs) { + decref_poll_args(pargs); + } else { + gpr_cv_destroy(pollcv); + gpr_free(pollcv); + } + gpr_mu_unlock(&g_cvfds.mu); + + return res; +} + +static void grpc_global_cv_fd_table_init() { + gpr_mu_init(&g_cvfds.mu); + gpr_mu_lock(&g_cvfds.mu); + gpr_cv_init(&g_cvfds.shutdown_complete); + g_cvfds.shutdown = 0; + g_cvfds.pollcount = 0; + g_cvfds.size = DEFAULT_TABLE_SIZE; + g_cvfds.cvfds = gpr_malloc(sizeof(fd_node) * DEFAULT_TABLE_SIZE); + g_cvfds.free_fds = NULL; + for (int i = 0; i < DEFAULT_TABLE_SIZE; i++) { + g_cvfds.cvfds[i].is_set = 0; + g_cvfds.cvfds[i].cvs = NULL; + g_cvfds.cvfds[i].next_free = g_cvfds.free_fds; + g_cvfds.free_fds = &g_cvfds.cvfds[i]; + } + // Override the poll function with one that supports cvfds + g_cvfds.poll = grpc_poll_function; + grpc_poll_function = &cvfd_poll; + gpr_mu_unlock(&g_cvfds.mu); +} + +static void grpc_global_cv_fd_table_shutdown() { + gpr_mu_lock(&g_cvfds.mu); + g_cvfds.shutdown = 1; + // Attempt to wait for all abandoned poll() threads to terminate + // Not doing so will result in reported memory leaks + if (g_cvfds.pollcount > 0) { + int res = gpr_cv_wait(&g_cvfds.shutdown_complete, &g_cvfds.mu, + gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), + gpr_time_from_seconds(3, GPR_TIMESPAN))); + GPR_ASSERT(res == 0); + } + gpr_cv_destroy(&g_cvfds.shutdown_complete); + grpc_poll_function = g_cvfds.poll; + gpr_free(g_cvfds.cvfds); + gpr_mu_unlock(&g_cvfds.mu); + gpr_mu_destroy(&g_cvfds.mu); +} + +/******************************************************************************* + * event engine binding + */ + +static const grpc_event_engine_vtable* ev_poll_vtable; +static grpc_event_engine_vtable vtable; + +static void shutdown_engine(void) { + ev_poll_vtable->shutdown_engine(); + grpc_global_cv_fd_table_shutdown(); +} + +const grpc_event_engine_vtable* grpc_init_poll_cv_posix(void) { + int has_wakeup_fd = grpc_has_wakeup_fd; + int allow_specialized_wakeup_fd = grpc_allow_specialized_wakeup_fd; + int allow_pipe_wakeup_fd = grpc_allow_pipe_wakeup_fd; + grpc_global_cv_fd_table_init(); + grpc_allow_specialized_wakeup_fd = 0; + grpc_allow_pipe_wakeup_fd = 0; + grpc_wakeup_fd_global_init(); + grpc_has_wakeup_fd = 1; + ev_poll_vtable = grpc_init_poll_posix(); + if (!ev_poll_vtable) { + grpc_global_cv_fd_table_shutdown(); + grpc_has_wakeup_fd = has_wakeup_fd; + grpc_allow_specialized_wakeup_fd = allow_specialized_wakeup_fd; + grpc_allow_pipe_wakeup_fd = allow_pipe_wakeup_fd; + grpc_global_cv_fd_table_init(); + return NULL; + } + vtable = *ev_poll_vtable; + vtable.shutdown_engine = shutdown_engine; + return &vtable; +} + +#endif /* GPR_POSIX_SOCKET */ diff --git a/src/core/lib/iomgr/ev_poll_cv_posix.h b/src/core/lib/iomgr/ev_poll_cv_posix.h new file mode 100644 index 0000000000..885711d1c5 --- /dev/null +++ b/src/core/lib/iomgr/ev_poll_cv_posix.h @@ -0,0 +1,68 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPC_CORE_LIB_IOMGR_EV_POLL_CV_POSIX_H +#define GRPC_CORE_LIB_IOMGR_EV_POLL_CV_POSIX_H + +#include + +#include "src/core/lib/iomgr/ev_posix.h" + +#define FD_TO_IDX(fd) (-(fd)-1) +#define IDX_TO_FD(idx) (-(idx)-1) + +typedef struct cv_node { + gpr_cv* cv; + struct cv_node* next; +} cv_node; + +typedef struct fd_node { + int is_set; + cv_node* cvs; + struct fd_node* next_free; +} fd_node; + +typedef struct cv_fd_table { + gpr_mu mu; + int pollcount; + int shutdown; + gpr_cv shutdown_complete; + fd_node* cvfds; + fd_node* free_fds; + unsigned int size; + grpc_poll_function_type poll; +} cv_fd_table; + +const grpc_event_engine_vtable* grpc_init_poll_cv_posix(void); + +#endif /* GRPC_CORE_LIB_IOMGR_EV_POLL_CV_POSIX_H */ diff --git a/src/core/lib/iomgr/ev_poll_posix.c b/src/core/lib/iomgr/ev_poll_posix.c index 16a5e3083e..97e71d968e 100644 --- a/src/core/lib/iomgr/ev_poll_posix.c +++ b/src/core/lib/iomgr/ev_poll_posix.c @@ -1277,6 +1277,9 @@ static const grpc_event_engine_vtable vtable = { }; const grpc_event_engine_vtable *grpc_init_poll_posix(void) { + if (!grpc_has_wakeup_fd) { + return NULL; + } if (!GRPC_LOG_IF_ERROR("pollset_global_init", pollset_global_init())) { return NULL; } diff --git a/src/core/lib/iomgr/ev_posix.c b/src/core/lib/iomgr/ev_posix.c index 6536672685..2fc8ccfa91 100644 --- a/src/core/lib/iomgr/ev_posix.c +++ b/src/core/lib/iomgr/ev_posix.c @@ -46,6 +46,7 @@ #include "src/core/lib/iomgr/ev_epoll_linux.h" #include "src/core/lib/iomgr/ev_poll_and_epoll_posix.h" +#include "src/core/lib/iomgr/ev_poll_cv_posix.h" #include "src/core/lib/iomgr/ev_poll_posix.h" #include "src/core/lib/support/env.h" @@ -66,6 +67,7 @@ typedef struct { static const event_engine_factory g_factories[] = { {"epoll", grpc_init_epoll_linux}, {"poll", grpc_init_poll_posix}, + {"poll-cv", grpc_init_poll_cv_posix}, {"legacy", grpc_init_poll_and_epoll_posix}, }; diff --git a/src/core/lib/iomgr/wakeup_fd_cv.c b/src/core/lib/iomgr/wakeup_fd_cv.c new file mode 100644 index 0000000000..651e2f663d --- /dev/null +++ b/src/core/lib/iomgr/wakeup_fd_cv.c @@ -0,0 +1,118 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include + +#ifdef GPR_POSIX_WAKEUP_FD + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "src/core/lib/iomgr/ev_poll_cv_posix.h" + +#define MAX_TABLE_RESIZE 256 + +extern cv_fd_table g_cvfds; + +static grpc_error* cv_fd_init(grpc_wakeup_fd* fd_info) { + unsigned int i, newsize; + int idx; + gpr_mu_lock(&g_cvfds.mu); + if (!g_cvfds.free_fds) { + newsize = GPR_MIN(g_cvfds.size * 2, g_cvfds.size + MAX_TABLE_RESIZE); + g_cvfds.cvfds = gpr_realloc(g_cvfds.cvfds, sizeof(fd_node) * newsize); + for (i = g_cvfds.size; i < newsize; i++) { + g_cvfds.cvfds[i].is_set = 0; + g_cvfds.cvfds[i].cvs = NULL; + g_cvfds.cvfds[i].next_free = g_cvfds.free_fds; + g_cvfds.free_fds = &g_cvfds.cvfds[i]; + } + g_cvfds.size = newsize; + } + + idx = (int)(g_cvfds.free_fds - g_cvfds.cvfds); + g_cvfds.free_fds = g_cvfds.free_fds->next_free; + g_cvfds.cvfds[idx].cvs = NULL; + g_cvfds.cvfds[idx].is_set = 0; + fd_info->read_fd = IDX_TO_FD(idx); + fd_info->write_fd = -1; + gpr_mu_unlock(&g_cvfds.mu); + return GRPC_ERROR_NONE; +} + +static grpc_error* cv_fd_wakeup(grpc_wakeup_fd* fd_info) { + cv_node* cvn; + gpr_mu_lock(&g_cvfds.mu); + g_cvfds.cvfds[FD_TO_IDX(fd_info->read_fd)].is_set = 1; + cvn = g_cvfds.cvfds[FD_TO_IDX(fd_info->read_fd)].cvs; + while (cvn) { + gpr_cv_signal(cvn->cv); + cvn = cvn->next; + } + gpr_mu_unlock(&g_cvfds.mu); + return GRPC_ERROR_NONE; +} + +static grpc_error* cv_fd_consume(grpc_wakeup_fd* fd_info) { + gpr_mu_lock(&g_cvfds.mu); + g_cvfds.cvfds[FD_TO_IDX(fd_info->read_fd)].is_set = 0; + gpr_mu_unlock(&g_cvfds.mu); + return GRPC_ERROR_NONE; +} + +static void cv_fd_destroy(grpc_wakeup_fd* fd_info) { + if (fd_info->read_fd == 0) { + return; + } + gpr_mu_lock(&g_cvfds.mu); + // Assert that there are no active pollers + GPR_ASSERT(!g_cvfds.cvfds[FD_TO_IDX(fd_info->read_fd)].cvs); + g_cvfds.cvfds[FD_TO_IDX(fd_info->read_fd)].next_free = g_cvfds.free_fds; + g_cvfds.free_fds = &g_cvfds.cvfds[FD_TO_IDX(fd_info->read_fd)]; + gpr_mu_unlock(&g_cvfds.mu); +} + +static int cv_check_availability(void) { return 1; } + +const grpc_wakeup_fd_vtable grpc_cv_wakeup_fd_vtable = { + cv_fd_init, cv_fd_consume, cv_fd_wakeup, cv_fd_destroy, + cv_check_availability}; + +#endif /* GPR_POSIX_WAKUP_FD */ diff --git a/src/core/lib/iomgr/wakeup_fd_cv.h b/src/core/lib/iomgr/wakeup_fd_cv.h new file mode 100644 index 0000000000..e57fc28363 --- /dev/null +++ b/src/core/lib/iomgr/wakeup_fd_cv.h @@ -0,0 +1,55 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* + * wakeup_fd_cv uses condition variables to implement wakeup fds. + * + * It is intended for use only in cases when eventfd() and pipe() are not + * available. It can only be used with the "poll" engine. + * + * Implementation: + * A global table of cv wakeup fds is mantained. A cv wakeup fd is a negative + * file descriptor. poll() is then run in a background thread with only the + * real socket fds while we wait on a condition variable trigged by either the + * poll() completion or a wakeup_fd() call. + * + */ + +#ifndef GRPC_CORE_LIB_IOMGR_WAKEUP_FD_CV_H +#define GRPC_CORE_LIB_IOMGR_WAKEUP_FD_CV_H + +#include "src/core/lib/iomgr/wakeup_fd_posix.h" + +extern grpc_wakeup_fd_vtable grpc_cv_wakeup_fd_vtable; + +#endif /* GRPC_CORE_LIB_IOMGR_WAKEUP_FD_CV_H */ diff --git a/src/core/lib/iomgr/wakeup_fd_pipe.c b/src/core/lib/iomgr/wakeup_fd_pipe.c index 4e5dbdcb73..d0ea216aa0 100644 --- a/src/core/lib/iomgr/wakeup_fd_pipe.c +++ b/src/core/lib/iomgr/wakeup_fd_pipe.c @@ -47,11 +47,10 @@ static grpc_error* pipe_init(grpc_wakeup_fd* fd_info) { int pipefd[2]; - /* TODO(klempner): Make this nonfatal */ int r = pipe(pipefd); if (0 != r) { gpr_log(GPR_ERROR, "pipe creation failed (%d): %s", errno, strerror(errno)); - abort(); + return GRPC_OS_ERROR(errno, "pipe"); } grpc_error* err; err = grpc_set_socket_nonblocking(pipefd[0], 1); @@ -95,8 +94,13 @@ static void pipe_destroy(grpc_wakeup_fd* fd_info) { } static int pipe_check_availability(void) { - /* Assume that pipes are always available. */ - return 1; + grpc_wakeup_fd fd; + if (pipe_init(&fd) == GRPC_ERROR_NONE) { + pipe_destroy(&fd); + return 1; + } else { + return 0; + } } const grpc_wakeup_fd_vtable grpc_pipe_wakeup_fd_vtable = { diff --git a/src/core/lib/iomgr/wakeup_fd_posix.c b/src/core/lib/iomgr/wakeup_fd_posix.c index 046208abc8..041c221de3 100644 --- a/src/core/lib/iomgr/wakeup_fd_posix.c +++ b/src/core/lib/iomgr/wakeup_fd_posix.c @@ -36,18 +36,25 @@ #ifdef GPR_POSIX_WAKEUP_FD #include +#include "src/core/lib/iomgr/wakeup_fd_cv.h" #include "src/core/lib/iomgr/wakeup_fd_pipe.h" #include "src/core/lib/iomgr/wakeup_fd_posix.h" static const grpc_wakeup_fd_vtable *wakeup_fd_vtable = NULL; int grpc_allow_specialized_wakeup_fd = 1; +int grpc_allow_pipe_wakeup_fd = 1; +int grpc_has_wakeup_fd = 1; void grpc_wakeup_fd_global_init(void) { if (grpc_allow_specialized_wakeup_fd && grpc_specialized_wakeup_fd_vtable.check_availability()) { wakeup_fd_vtable = &grpc_specialized_wakeup_fd_vtable; - } else { + } else if (grpc_allow_pipe_wakeup_fd && + grpc_pipe_wakeup_fd_vtable.check_availability()) { wakeup_fd_vtable = &grpc_pipe_wakeup_fd_vtable; + } else { + grpc_has_wakeup_fd = 0; + wakeup_fd_vtable = &grpc_cv_wakeup_fd_vtable; } } diff --git a/src/core/lib/iomgr/wakeup_fd_posix.h b/src/core/lib/iomgr/wakeup_fd_posix.h index e269f242d8..bd0fb46da1 100644 --- a/src/core/lib/iomgr/wakeup_fd_posix.h +++ b/src/core/lib/iomgr/wakeup_fd_posix.h @@ -88,6 +88,8 @@ struct grpc_wakeup_fd { }; extern int grpc_allow_specialized_wakeup_fd; +extern int grpc_allow_pipe_wakeup_fd; +extern int grpc_has_wakeup_fd; #define GRPC_WAKEUP_FD_GET_READ_FD(fd_info) ((fd_info)->read_fd) diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 2bebf48c70..62d9729e13 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -102,6 +102,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/iomgr/error.c', 'src/core/lib/iomgr/ev_epoll_linux.c', 'src/core/lib/iomgr/ev_poll_and_epoll_posix.c', + 'src/core/lib/iomgr/ev_poll_cv_posix.c', 'src/core/lib/iomgr/ev_poll_posix.c', 'src/core/lib/iomgr/ev_posix.c', 'src/core/lib/iomgr/exec_ctx.c', @@ -134,6 +135,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/iomgr/udp_server.c', 'src/core/lib/iomgr/unix_sockets_posix.c', 'src/core/lib/iomgr/unix_sockets_posix_noop.c', + 'src/core/lib/iomgr/wakeup_fd_cv.c', 'src/core/lib/iomgr/wakeup_fd_eventfd.c', 'src/core/lib/iomgr/wakeup_fd_nospecial.c', 'src/core/lib/iomgr/wakeup_fd_pipe.c', diff --git a/test/core/iomgr/wakeup_fd_cv_test.c b/test/core/iomgr/wakeup_fd_cv_test.c new file mode 100644 index 0000000000..952985ed7e --- /dev/null +++ b/test/core/iomgr/wakeup_fd_cv_test.c @@ -0,0 +1,240 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include + +#include +#include +#include +#include + +#include "src/core/lib/iomgr/ev_posix.h" +#include "src/core/lib/iomgr/iomgr_posix.h" +#include "src/core/lib/support/env.h" + +typedef struct poll_args { + struct pollfd *fds; + nfds_t nfds; + int timeout; + int result; +} poll_args; + +gpr_cv poll_cv; +gpr_mu poll_mu; +static int socket_event = 0; + +// Trigger a "socket" POLLIN in mock_poll() +void trigger_socket_event() { + gpr_mu_lock(&poll_mu); + socket_event = 1; + gpr_cv_broadcast(&poll_cv); + gpr_mu_unlock(&poll_mu); +} + +void reset_socket_event() { + gpr_mu_lock(&poll_mu); + socket_event = 0; + gpr_mu_unlock(&poll_mu); +} + +// Mocks posix poll() function +int mock_poll(struct pollfd *fds, nfds_t nfds, int timeout) { + int res = 0; + gpr_timespec poll_time; + gpr_mu_lock(&poll_mu); + GPR_ASSERT(nfds == 3); + GPR_ASSERT(fds[0].fd == 20); + GPR_ASSERT(fds[1].fd == 30); + GPR_ASSERT(fds[2].fd == 50); + GPR_ASSERT(fds[0].events == (POLLIN | POLLHUP)); + GPR_ASSERT(fds[1].events == (POLLIN | POLLHUP)); + GPR_ASSERT(fds[2].events == POLLIN); + + if (timeout < 0) { + poll_time = gpr_inf_future(GPR_CLOCK_REALTIME); + } else { + poll_time = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), + gpr_time_from_millis(timeout, GPR_TIMESPAN)); + } + + if (socket_event || !gpr_cv_wait(&poll_cv, &poll_mu, poll_time)) { + fds[0].revents = POLLIN; + res = 1; + } + gpr_mu_unlock(&poll_mu); + return res; +} + +void background_poll(void *args) { + poll_args *pargs = (poll_args *)args; + pargs->result = grpc_poll_function(pargs->fds, pargs->nfds, pargs->timeout); +} + +void test_many_fds(void) { + int i; + grpc_wakeup_fd fd[1000]; + for (i = 0; i < 1000; i++) { + GPR_ASSERT(grpc_wakeup_fd_init(&fd[i]) == GRPC_ERROR_NONE); + } + for (i = 0; i < 1000; i++) { + grpc_wakeup_fd_destroy(&fd[i]); + } +} + +void test_poll_cv_trigger(void) { + grpc_wakeup_fd cvfd1, cvfd2, cvfd3; + struct pollfd pfds[6]; + poll_args pargs; + gpr_thd_id t_id; + gpr_thd_options opt; + + GPR_ASSERT(grpc_wakeup_fd_init(&cvfd1) == GRPC_ERROR_NONE); + GPR_ASSERT(grpc_wakeup_fd_init(&cvfd2) == GRPC_ERROR_NONE); + GPR_ASSERT(grpc_wakeup_fd_init(&cvfd3) == GRPC_ERROR_NONE); + GPR_ASSERT(cvfd1.read_fd < 0); + GPR_ASSERT(cvfd2.read_fd < 0); + GPR_ASSERT(cvfd3.read_fd < 0); + GPR_ASSERT(cvfd1.read_fd != cvfd2.read_fd); + GPR_ASSERT(cvfd2.read_fd != cvfd3.read_fd); + GPR_ASSERT(cvfd1.read_fd != cvfd3.read_fd); + + pfds[0].fd = cvfd1.read_fd; + pfds[1].fd = cvfd2.read_fd; + pfds[2].fd = 20; + pfds[3].fd = 30; + pfds[4].fd = cvfd3.read_fd; + pfds[5].fd = 50; + + pfds[0].events = 0; + pfds[1].events = POLLIN; + pfds[2].events = POLLIN | POLLHUP; + pfds[3].events = POLLIN | POLLHUP; + pfds[4].events = POLLIN; + pfds[5].events = POLLIN; + + pargs.fds = pfds; + pargs.nfds = 6; + pargs.timeout = 1000; + pargs.result = -2; + + opt = gpr_thd_options_default(); + gpr_thd_options_set_joinable(&opt); + gpr_thd_new(&t_id, &background_poll, &pargs, &opt); + + // Wakeup wakeup_fd not listening for events + GPR_ASSERT(grpc_wakeup_fd_wakeup(&cvfd1) == GRPC_ERROR_NONE); + gpr_thd_join(t_id); + GPR_ASSERT(pargs.result == 0); + GPR_ASSERT(pfds[0].revents == 0); + GPR_ASSERT(pfds[1].revents == 0); + GPR_ASSERT(pfds[2].revents == 0); + GPR_ASSERT(pfds[3].revents == 0); + GPR_ASSERT(pfds[4].revents == 0); + GPR_ASSERT(pfds[5].revents == 0); + + // Pollin on socket fd + pargs.timeout = -1; + pargs.result = -2; + gpr_thd_new(&t_id, &background_poll, &pargs, &opt); + trigger_socket_event(); + gpr_thd_join(t_id); + GPR_ASSERT(pargs.result == 1); + GPR_ASSERT(pfds[0].revents == 0); + GPR_ASSERT(pfds[1].revents == 0); + GPR_ASSERT(pfds[2].revents == POLLIN); + GPR_ASSERT(pfds[3].revents == 0); + GPR_ASSERT(pfds[4].revents == 0); + GPR_ASSERT(pfds[5].revents == 0); + + // Pollin on wakeup fd + reset_socket_event(); + pargs.result = -2; + gpr_thd_new(&t_id, &background_poll, &pargs, &opt); + GPR_ASSERT(grpc_wakeup_fd_wakeup(&cvfd2) == GRPC_ERROR_NONE); + gpr_thd_join(t_id); + + GPR_ASSERT(pargs.result == 1); + GPR_ASSERT(pfds[0].revents == 0); + GPR_ASSERT(pfds[1].revents == POLLIN); + GPR_ASSERT(pfds[2].revents == 0); + GPR_ASSERT(pfds[3].revents == 0); + GPR_ASSERT(pfds[4].revents == 0); + GPR_ASSERT(pfds[5].revents == 0); + + // Pollin on wakeup fd + socket fd + trigger_socket_event(); + pargs.result = -2; + gpr_thd_new(&t_id, &background_poll, &pargs, &opt); + gpr_thd_join(t_id); + + GPR_ASSERT(pargs.result == 2); + GPR_ASSERT(pfds[0].revents == 0); + GPR_ASSERT(pfds[1].revents == POLLIN); + GPR_ASSERT(pfds[2].revents == POLLIN); + GPR_ASSERT(pfds[3].revents == 0); + GPR_ASSERT(pfds[4].revents == 0); + GPR_ASSERT(pfds[5].revents == 0); + + // No Events + pargs.result = -2; + pargs.timeout = 1000; + reset_socket_event(); + GPR_ASSERT(grpc_wakeup_fd_consume_wakeup(&cvfd1) == GRPC_ERROR_NONE); + GPR_ASSERT(grpc_wakeup_fd_consume_wakeup(&cvfd2) == GRPC_ERROR_NONE); + gpr_thd_new(&t_id, &background_poll, &pargs, &opt); + gpr_thd_join(t_id); + + GPR_ASSERT(pargs.result == 0); + GPR_ASSERT(pfds[0].revents == 0); + GPR_ASSERT(pfds[1].revents == 0); + GPR_ASSERT(pfds[2].revents == 0); + GPR_ASSERT(pfds[3].revents == 0); + GPR_ASSERT(pfds[4].revents == 0); + GPR_ASSERT(pfds[5].revents == 0); +} + +int main(int argc, char **argv) { + gpr_setenv("GRPC_POLL_STRATEGY", "poll-cv"); + grpc_poll_function = &mock_poll; + gpr_mu_init(&poll_mu); + gpr_cv_init(&poll_cv); + + grpc_iomgr_platform_init(); + test_many_fds(); + grpc_iomgr_platform_shutdown(); + + grpc_iomgr_platform_init(); + test_poll_cv_trigger(); + grpc_iomgr_platform_shutdown(); + return 0; +} diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 44f147aeb1..1ec177cdf3 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -810,6 +810,7 @@ src/core/lib/iomgr/endpoint_pair.h \ src/core/lib/iomgr/error.h \ src/core/lib/iomgr/ev_epoll_linux.h \ src/core/lib/iomgr/ev_poll_and_epoll_posix.h \ +src/core/lib/iomgr/ev_poll_cv_posix.h \ src/core/lib/iomgr/ev_poll_posix.h \ src/core/lib/iomgr/ev_posix.h \ src/core/lib/iomgr/exec_ctx.h \ @@ -841,6 +842,7 @@ src/core/lib/iomgr/timer.h \ src/core/lib/iomgr/timer_heap.h \ src/core/lib/iomgr/udp_server.h \ src/core/lib/iomgr/unix_sockets_posix.h \ +src/core/lib/iomgr/wakeup_fd_cv.h \ src/core/lib/iomgr/wakeup_fd_pipe.h \ src/core/lib/iomgr/wakeup_fd_posix.h \ src/core/lib/iomgr/workqueue.h \ @@ -975,6 +977,7 @@ src/core/lib/iomgr/endpoint_pair_windows.c \ src/core/lib/iomgr/error.c \ src/core/lib/iomgr/ev_epoll_linux.c \ src/core/lib/iomgr/ev_poll_and_epoll_posix.c \ +src/core/lib/iomgr/ev_poll_cv_posix.c \ src/core/lib/iomgr/ev_poll_posix.c \ src/core/lib/iomgr/ev_posix.c \ src/core/lib/iomgr/exec_ctx.c \ @@ -1007,6 +1010,7 @@ src/core/lib/iomgr/timer_heap.c \ src/core/lib/iomgr/udp_server.c \ src/core/lib/iomgr/unix_sockets_posix.c \ src/core/lib/iomgr/unix_sockets_posix_noop.c \ +src/core/lib/iomgr/wakeup_fd_cv.c \ src/core/lib/iomgr/wakeup_fd_eventfd.c \ src/core/lib/iomgr/wakeup_fd_nospecial.c \ src/core/lib/iomgr/wakeup_fd_pipe.c \ diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index a6f3d405dc..a9925ed976 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -69,7 +69,7 @@ _FORCE_ENVIRON_FOR_WRAPPERS = { _POLLING_STRATEGIES = { - 'linux': ['epoll', 'poll', 'legacy'] + 'linux': ['epoll', 'poll', 'poll-cv', 'legacy'] } diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index c05d194e19..35b21d4e20 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -2079,6 +2079,23 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "gpr_test_util", + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "wakeup_fd_cv_test", + "src": [ + "test/core/iomgr/wakeup_fd_cv_test.c" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", @@ -6374,6 +6391,7 @@ "src/core/lib/iomgr/error.h", "src/core/lib/iomgr/ev_epoll_linux.h", "src/core/lib/iomgr/ev_poll_and_epoll_posix.h", + "src/core/lib/iomgr/ev_poll_cv_posix.h", "src/core/lib/iomgr/ev_poll_posix.h", "src/core/lib/iomgr/ev_posix.h", "src/core/lib/iomgr/exec_ctx.h", @@ -6405,6 +6423,7 @@ "src/core/lib/iomgr/timer_heap.h", "src/core/lib/iomgr/udp_server.h", "src/core/lib/iomgr/unix_sockets_posix.h", + "src/core/lib/iomgr/wakeup_fd_cv.h", "src/core/lib/iomgr/wakeup_fd_pipe.h", "src/core/lib/iomgr/wakeup_fd_posix.h", "src/core/lib/iomgr/workqueue.h", @@ -6493,6 +6512,8 @@ "src/core/lib/iomgr/ev_epoll_linux.h", "src/core/lib/iomgr/ev_poll_and_epoll_posix.c", "src/core/lib/iomgr/ev_poll_and_epoll_posix.h", + "src/core/lib/iomgr/ev_poll_cv_posix.c", + "src/core/lib/iomgr/ev_poll_cv_posix.h", "src/core/lib/iomgr/ev_poll_posix.c", "src/core/lib/iomgr/ev_poll_posix.h", "src/core/lib/iomgr/ev_posix.c", @@ -6556,6 +6577,8 @@ "src/core/lib/iomgr/unix_sockets_posix.c", "src/core/lib/iomgr/unix_sockets_posix.h", "src/core/lib/iomgr/unix_sockets_posix_noop.c", + "src/core/lib/iomgr/wakeup_fd_cv.c", + "src/core/lib/iomgr/wakeup_fd_cv.h", "src/core/lib/iomgr/wakeup_fd_eventfd.c", "src/core/lib/iomgr/wakeup_fd_nospecial.c", "src/core/lib/iomgr/wakeup_fd_pipe.c", diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json index c3395067c9..323c09c77f 100644 --- a/tools/run_tests/tests.json +++ b/tools/run_tests/tests.json @@ -2061,6 +2061,25 @@ "windows" ] }, + { + "args": [], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "gtest": false, + "language": "c", + "name": "wakeup_fd_cv_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, { "args": [], "ci_platforms": [ diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj index 965d06d1d5..7d5e0ee56f 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj @@ -319,6 +319,7 @@ + @@ -350,6 +351,7 @@ + @@ -511,6 +513,8 @@ + + @@ -575,6 +579,8 @@ + + diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters index dddd4ecce5..72bf449c3e 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters @@ -76,6 +76,9 @@ src\core\lib\iomgr + + src\core\lib\iomgr + src\core\lib\iomgr @@ -172,6 +175,9 @@ src\core\lib\iomgr + + src\core\lib\iomgr + src\core\lib\iomgr @@ -740,6 +746,9 @@ src\core\lib\iomgr + + src\core\lib\iomgr + src\core\lib\iomgr @@ -833,6 +842,9 @@ src\core\lib\iomgr + + src\core\lib\iomgr + src\core\lib\iomgr diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj index b724c217ed..44cbe8bf0c 100644 --- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj +++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj @@ -212,6 +212,7 @@ + @@ -243,6 +244,7 @@ + @@ -359,6 +361,8 @@ + + @@ -423,6 +427,8 @@ + + diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters index 92806fa04a..57466022f4 100644 --- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters +++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters @@ -130,6 +130,9 @@ src\core\lib\iomgr + + src\core\lib\iomgr + src\core\lib\iomgr @@ -226,6 +229,9 @@ src\core\lib\iomgr + + src\core\lib\iomgr + src\core\lib\iomgr @@ -527,6 +533,9 @@ src\core\lib\iomgr + + src\core\lib\iomgr + src\core\lib\iomgr @@ -620,6 +629,9 @@ src\core\lib\iomgr + + src\core\lib\iomgr + src\core\lib\iomgr diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj index b46773632c..aa47cc800d 100644 --- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj +++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj @@ -309,6 +309,7 @@ + @@ -340,6 +341,7 @@ + @@ -479,6 +481,8 @@ + + @@ -543,6 +547,8 @@ + + diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters index 6ffc1eab70..4706c90af2 100644 --- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters +++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters @@ -79,6 +79,9 @@ src\core\lib\iomgr + + src\core\lib\iomgr + src\core\lib\iomgr @@ -175,6 +178,9 @@ src\core\lib\iomgr + + src\core\lib\iomgr + src\core\lib\iomgr @@ -650,6 +656,9 @@ src\core\lib\iomgr + + src\core\lib\iomgr + src\core\lib\iomgr @@ -743,6 +752,9 @@ src\core\lib\iomgr + + src\core\lib\iomgr + src\core\lib\iomgr -- cgit v1.2.3 From f0da36b8d8f24e537bfcd297be05e8eca9fa0e35 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 10 Oct 2016 13:07:37 -0700 Subject: Clarifying comment --- include/grpc/support/alloc.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/grpc/support/alloc.h b/include/grpc/support/alloc.h index 327a9ff9f0..7209bec014 100644 --- a/include/grpc/support/alloc.h +++ b/include/grpc/support/alloc.h @@ -48,7 +48,11 @@ typedef struct gpr_allocation_functions { void (*free_fn)(void *ptr); } gpr_allocation_functions; -/* malloc, never returns NULL */ +/* malloc. + * If size==0, always returns NULL. Otherwise this function never returns NULL. + * The pointer returned is suitably aligned for any kind of variable it could + * contain. + */ GPRAPI void *gpr_malloc(size_t size); /* free */ GPRAPI void gpr_free(void *ptr); -- cgit v1.2.3 From d80a8c947c3491ea1491bc16b4f0479add3461f5 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 10 Oct 2016 13:19:56 -0700 Subject: Cleanup --- src/core/lib/iomgr/combiner.c | 49 ++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/src/core/lib/iomgr/combiner.c b/src/core/lib/iomgr/combiner.c index 48806abc38..24ffe41d99 100644 --- a/src/core/lib/iomgr/combiner.c +++ b/src/core/lib/iomgr/combiner.c @@ -50,17 +50,20 @@ int grpc_combiner_trace = 0; } \ } while (0) +#define STATE_UNORPHANED 1 +#define STATE_ELEM_COUNT_LOW_BIT 2 + struct grpc_combiner { grpc_combiner *next_combiner_on_this_exec_ctx; grpc_workqueue *optional_workqueue; gpr_mpscq queue; // state is: - // lower bit - zero if orphaned - // other bits - number of items queued on the lock + // lower bit - zero if orphaned (STATE_UNORPHANED) + // other bits - number of items queued on the lock (STATE_ELEM_COUNT_LOW_BIT) gpr_atm state; // number of elements in the list that are covered by a poller: if >0, we can // offload safely - gpr_atm covered_by_poller; + gpr_atm elements_covered_by_poller; bool time_to_execute_final_list; bool final_list_covered_by_poller; grpc_closure_list final_list; @@ -84,7 +87,7 @@ static error_data unpack_error_data(uintptr_t p) { static bool is_covered_by_poller(grpc_combiner *lock) { return lock->final_list_covered_by_poller || - gpr_atm_acq_load(&lock->covered_by_poller) > 0; + gpr_atm_acq_load(&lock->elements_covered_by_poller) > 0; } grpc_combiner *grpc_combiner_create(grpc_workqueue *optional_workqueue) { @@ -93,8 +96,8 @@ grpc_combiner *grpc_combiner_create(grpc_workqueue *optional_workqueue) { lock->time_to_execute_final_list = false; lock->optional_workqueue = optional_workqueue; lock->final_list_covered_by_poller = false; - gpr_atm_no_barrier_store(&lock->state, 1); - gpr_atm_no_barrier_store(&lock->covered_by_poller, 0); + gpr_atm_no_barrier_store(&lock->state, STATE_UNORPHANED); + gpr_atm_no_barrier_store(&lock->elements_covered_by_poller, 0); gpr_mpscq_init(&lock->queue); grpc_closure_list_init(&lock->final_list); grpc_closure_init(&lock->offload, offload, lock); @@ -111,7 +114,7 @@ static void really_destroy(grpc_exec_ctx *exec_ctx, grpc_combiner *lock) { } void grpc_combiner_destroy(grpc_exec_ctx *exec_ctx, grpc_combiner *lock) { - gpr_atm old_state = gpr_atm_full_fetch_add(&lock->state, -1); + gpr_atm old_state = gpr_atm_full_fetch_add(&lock->state, -STATE_UNORPHANED); GRPC_COMBINER_TRACE(gpr_log( GPR_DEBUG, "C:%p really_destroy old_state=%" PRIdPTR, lock, old_state)); if (old_state == 1) { @@ -143,20 +146,20 @@ void grpc_combiner_execute(grpc_exec_ctx *exec_ctx, grpc_combiner *lock, grpc_closure *cl, grpc_error *error, bool covered_by_poller) { GPR_TIMER_BEGIN("combiner.execute", 0); - gpr_atm last = gpr_atm_full_fetch_add(&lock->state, 2); + gpr_atm last = gpr_atm_full_fetch_add(&lock->state, STATE_ELEM_COUNT_LOW_BIT); GRPC_COMBINER_TRACE(gpr_log( GPR_DEBUG, "C:%p grpc_combiner_execute c=%p cov=%d last=%" PRIdPTR, lock, cl, covered_by_poller, last)); - GPR_ASSERT(last & 1); // ensure lock has not been destroyed + GPR_ASSERT(last & STATE_UNORPHANED); // ensure lock has not been destroyed cl->error_data.scratch = pack_error_data((error_data){error, covered_by_poller}); if (covered_by_poller) { - gpr_atm_no_barrier_fetch_add(&lock->covered_by_poller, 1); + gpr_atm_no_barrier_fetch_add(&lock->elements_covered_by_poller, 1); } gpr_mpscq_push(&lock->queue, &cl->next_data.atm_next); if (last == 1) { - // code will be written when the exec_ctx calls - // grpc_combiner_continue_exec_ctx + // first element on this list: add it to the list of combiner locks + // executing within this exec_ctx push_last_on_exec_ctx(exec_ctx, lock); } GPR_TIMER_END("combiner.execute", 0); @@ -219,7 +222,7 @@ bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) { GRPC_COMBINER_TRACE( gpr_log(GPR_DEBUG, "C:%p maybe_finish_one n=%p", lock, n)); if (n == NULL) { - // queue is in an inconsistant state: use this as a cue that we should + // queue is in an inconsistent state: use this as a cue that we should // go off and do something else for a while (and come back later) GPR_TIMER_MARK("delay_busy", 0); if (lock->optional_workqueue != NULL && is_covered_by_poller(lock)) { @@ -233,7 +236,7 @@ bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) { error_data err = unpack_error_data(cl->error_data.scratch); cl->cb(exec_ctx, cl->cb_arg, err.error); if (err.covered_by_poller) { - gpr_atm_no_barrier_fetch_add(&lock->covered_by_poller, -1); + gpr_atm_no_barrier_fetch_add(&lock->elements_covered_by_poller, -1); } GRPC_ERROR_UNREF(err.error); GPR_TIMER_END("combiner.exec1", 0); @@ -259,27 +262,31 @@ bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) { GPR_TIMER_MARK("unref", 0); move_next(exec_ctx); lock->time_to_execute_final_list = false; - gpr_atm old_state = gpr_atm_full_fetch_add(&lock->state, -2); + gpr_atm old_state = + gpr_atm_full_fetch_add(&lock->state, -STATE_ELEM_COUNT_LOW_BIT); GRPC_COMBINER_TRACE( gpr_log(GPR_DEBUG, "C:%p finish old_state=%" PRIdPTR, lock, old_state)); switch (old_state) { default: // we have multiple queued work items: just continue executing them break; - case 5: // we're down to one queued item: if it's the final list we - case 4: // should do that + case STATE_UNORPHANED | (2 * STATE_ELEM_COUNT_LOW_BIT): + case 0 | (2 * STATE_ELEM_COUNT_LOW_BIT): + // we're down to one queued item: if it's the final list we should do that if (!grpc_closure_list_empty(lock->final_list)) { lock->time_to_execute_final_list = true; } break; - case 3: // had one count, one unorphaned --> unlocked unorphaned + case STATE_UNORPHANED | STATE_ELEM_COUNT_LOW_BIT: + // had one count, one unorphaned --> unlocked unorphaned GPR_TIMER_END("combiner.continue_exec_ctx", 0); return true; - case 2: // and one count, one orphaned --> unlocked and orphaned + case 0 | STATE_ELEM_COUNT_LOW_BIT: + // and one count, one orphaned --> unlocked and orphaned really_destroy(exec_ctx, lock); GPR_TIMER_END("combiner.continue_exec_ctx", 0); return true; - case 1: + case STATE_UNORPHANED: case 0: // these values are illegal - representing an already unlocked or // deleted lock @@ -314,7 +321,7 @@ void grpc_combiner_execute_finally(grpc_exec_ctx *exec_ctx, grpc_combiner *lock, } if (grpc_closure_list_empty(lock->final_list)) { - gpr_atm_full_fetch_add(&lock->state, 2); + gpr_atm_full_fetch_add(&lock->state, STATE_ELEM_COUNT_LOW_BIT); } if (covered_by_poller) { lock->final_list_covered_by_poller = true; -- cgit v1.2.3 From 686d7a7b7f22b08043414aa7651f89af06f176b8 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 10 Oct 2016 14:02:29 -0700 Subject: Simplifications --- src/core/lib/iomgr/exec_ctx.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/core/lib/iomgr/exec_ctx.c b/src/core/lib/iomgr/exec_ctx.c index a3c40e8092..604713e578 100644 --- a/src/core/lib/iomgr/exec_ctx.c +++ b/src/core/lib/iomgr/exec_ctx.c @@ -71,12 +71,9 @@ bool grpc_exec_ctx_flush(grpc_exec_ctx *exec_ctx) { grpc_closure_run(exec_ctx, c, c->error_data.error); c = next; } - continue; + } else if (!grpc_combiner_continue_exec_ctx(exec_ctx)) { + break; } - if (grpc_combiner_continue_exec_ctx(exec_ctx)) { - continue; - } - break; } GPR_ASSERT(exec_ctx->active_combiner == NULL); if (exec_ctx->stealing_from_workqueue != NULL) { @@ -100,8 +97,7 @@ bool grpc_exec_ctx_flush(grpc_exec_ctx *exec_ctx) { GRPC_ERROR_UNREF(error); GPR_TIMER_END("grpc_exec_ctx_flush.stolen_cb", 0); grpc_exec_ctx_flush(exec_ctx); - GPR_TIMER_END("grpc_exec_ctx_flush", 0); - return true; + did_something = true; } } GPR_TIMER_END("grpc_exec_ctx_flush", 0); -- cgit v1.2.3 From d3ee0d5c76626849756e1bff9ffb23de30706c7e Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 10 Oct 2016 14:09:18 -0700 Subject: Better readability --- src/core/lib/iomgr/combiner.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/core/lib/iomgr/combiner.c b/src/core/lib/iomgr/combiner.c index 24ffe41d99..60ee14eb23 100644 --- a/src/core/lib/iomgr/combiner.c +++ b/src/core/lib/iomgr/combiner.c @@ -266,28 +266,34 @@ bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) { gpr_atm_full_fetch_add(&lock->state, -STATE_ELEM_COUNT_LOW_BIT); GRPC_COMBINER_TRACE( gpr_log(GPR_DEBUG, "C:%p finish old_state=%" PRIdPTR, lock, old_state)); +// Define a macro to ease readability of the following switch statement. +#define OLD_STATE_WAS(orphaned, elem_count) \ + (((orphaned) ? 0 : STATE_UNORPHANED) | \ + ((elem_count)*STATE_ELEM_COUNT_LOW_BIT)) + // Depending on what the previous state was, we need to perform different + // actions. switch (old_state) { default: // we have multiple queued work items: just continue executing them break; - case STATE_UNORPHANED | (2 * STATE_ELEM_COUNT_LOW_BIT): - case 0 | (2 * STATE_ELEM_COUNT_LOW_BIT): + case OLD_STATE_WAS(false, 2): + case OLD_STATE_WAS(true, 2): // we're down to one queued item: if it's the final list we should do that if (!grpc_closure_list_empty(lock->final_list)) { lock->time_to_execute_final_list = true; } break; - case STATE_UNORPHANED | STATE_ELEM_COUNT_LOW_BIT: + case OLD_STATE_WAS(false, 1): // had one count, one unorphaned --> unlocked unorphaned GPR_TIMER_END("combiner.continue_exec_ctx", 0); return true; - case 0 | STATE_ELEM_COUNT_LOW_BIT: + case OLD_STATE_WAS(true, 1): // and one count, one orphaned --> unlocked and orphaned really_destroy(exec_ctx, lock); GPR_TIMER_END("combiner.continue_exec_ctx", 0); return true; - case STATE_UNORPHANED: - case 0: + case OLD_STATE_WAS(false, 0): + case OLD_STATE_WAS(true, 0): // these values are illegal - representing an already unlocked or // deleted lock GPR_TIMER_END("combiner.continue_exec_ctx", 0); -- cgit v1.2.3 From 2e62013f578e55ade82c5d93ac5598d307d97b21 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 10 Oct 2016 15:27:44 -0700 Subject: Add some comments --- src/core/lib/iomgr/ev_epoll_linux.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/ev_epoll_linux.c b/src/core/lib/iomgr/ev_epoll_linux.c index 496b2d9255..98fe2defea 100644 --- a/src/core/lib/iomgr/ev_epoll_linux.c +++ b/src/core/lib/iomgr/ev_epoll_linux.c @@ -277,6 +277,8 @@ static bool append_error(grpc_error **composite, grpc_error *error, threads that woke up MUST NOT call grpc_wakeup_fd_consume_wakeup() */ static grpc_wakeup_fd polling_island_wakeup_fd; +/* The polling island being polled right now. + See comments in workqueue_maybe_wakeup for why this is tracked. */ static __thread polling_island *g_current_thread_polling_island; /* Forward declaration */ @@ -703,11 +705,16 @@ static void polling_island_unlock_pair(polling_island *p, polling_island *q) { } static void workqueue_maybe_wakeup(polling_island *pi) { - bool force_wakeup = false; + /* If this thread is the current poller, then it may be that it's about to + decrement the current poller count, so we need to look past this thread */ bool is_current_poller = (g_current_thread_polling_island == pi); gpr_atm min_current_pollers_for_wakeup = is_current_poller ? 1 : 0; gpr_atm current_pollers = gpr_atm_no_barrier_load(&pi->poller_count); - if (force_wakeup || current_pollers > min_current_pollers_for_wakeup) { + /* Only issue a wakeup if it's likely that some poller could come in and take + it right now. Note that since we do an anticipatory mpscq_pop every poll + loop, it's ok if we miss the wakeup here, as we'll get the work item when + the next poller enters anyway. */ + if (current_pollers > min_current_pollers_for_wakeup) { GRPC_LOG_IF_ERROR("workqueue_wakeup_fd", grpc_wakeup_fd_wakeup(&pi->workqueue_wakeup_fd)); } -- cgit v1.2.3 From cd7d0479a2aa51166ca251ed0f460f1c2ea5d1e7 Mon Sep 17 00:00:00 2001 From: Ken Payson Date: Tue, 11 Oct 2016 12:24:20 -0700 Subject: Cleanup poll-cv setup --- src/core/lib/iomgr/ev_epoll_linux.c | 2 +- src/core/lib/iomgr/ev_poll_cv_posix.c | 13 ++----------- src/core/lib/iomgr/ev_poll_posix.c | 2 +- src/core/lib/iomgr/wakeup_fd_posix.c | 30 ++++++++++++++++++++++++++---- src/core/lib/iomgr/wakeup_fd_posix.h | 5 ++++- 5 files changed, 34 insertions(+), 18 deletions(-) diff --git a/src/core/lib/iomgr/ev_epoll_linux.c b/src/core/lib/iomgr/ev_epoll_linux.c index 249bc98735..ad1cfc2031 100644 --- a/src/core/lib/iomgr/ev_epoll_linux.c +++ b/src/core/lib/iomgr/ev_epoll_linux.c @@ -1892,7 +1892,7 @@ const grpc_event_engine_vtable *grpc_init_epoll_linux(void) { return NULL; } - if (!grpc_has_wakeup_fd) { + if (!grpc_has_wakeup_fd()) { return NULL; } diff --git a/src/core/lib/iomgr/ev_poll_cv_posix.c b/src/core/lib/iomgr/ev_poll_cv_posix.c index 1ea811e445..0cb414ba88 100644 --- a/src/core/lib/iomgr/ev_poll_cv_posix.c +++ b/src/core/lib/iomgr/ev_poll_cv_posix.c @@ -255,21 +255,12 @@ static void shutdown_engine(void) { } const grpc_event_engine_vtable* grpc_init_poll_cv_posix(void) { - int has_wakeup_fd = grpc_has_wakeup_fd; - int allow_specialized_wakeup_fd = grpc_allow_specialized_wakeup_fd; - int allow_pipe_wakeup_fd = grpc_allow_pipe_wakeup_fd; grpc_global_cv_fd_table_init(); - grpc_allow_specialized_wakeup_fd = 0; - grpc_allow_pipe_wakeup_fd = 0; - grpc_wakeup_fd_global_init(); - grpc_has_wakeup_fd = 1; + grpc_enable_cv_wakeup_fds(1); ev_poll_vtable = grpc_init_poll_posix(); if (!ev_poll_vtable) { grpc_global_cv_fd_table_shutdown(); - grpc_has_wakeup_fd = has_wakeup_fd; - grpc_allow_specialized_wakeup_fd = allow_specialized_wakeup_fd; - grpc_allow_pipe_wakeup_fd = allow_pipe_wakeup_fd; - grpc_global_cv_fd_table_init(); + grpc_enable_cv_wakeup_fds(0); return NULL; } vtable = *ev_poll_vtable; diff --git a/src/core/lib/iomgr/ev_poll_posix.c b/src/core/lib/iomgr/ev_poll_posix.c index 97e71d968e..0dca51bc78 100644 --- a/src/core/lib/iomgr/ev_poll_posix.c +++ b/src/core/lib/iomgr/ev_poll_posix.c @@ -1277,7 +1277,7 @@ static const grpc_event_engine_vtable vtable = { }; const grpc_event_engine_vtable *grpc_init_poll_posix(void) { - if (!grpc_has_wakeup_fd) { + if (!grpc_has_wakeup_fd()) { return NULL; } if (!GRPC_LOG_IF_ERROR("pollset_global_init", pollset_global_init())) { diff --git a/src/core/lib/iomgr/wakeup_fd_posix.c b/src/core/lib/iomgr/wakeup_fd_posix.c index 041c221de3..f75ae78c22 100644 --- a/src/core/lib/iomgr/wakeup_fd_posix.c +++ b/src/core/lib/iomgr/wakeup_fd_posix.c @@ -41,9 +41,11 @@ #include "src/core/lib/iomgr/wakeup_fd_posix.h" static const grpc_wakeup_fd_vtable *wakeup_fd_vtable = NULL; + int grpc_allow_specialized_wakeup_fd = 1; int grpc_allow_pipe_wakeup_fd = 1; -int grpc_has_wakeup_fd = 1; +int grpc_has_real_wakeup_fd = 1; +int grpc_cv_wakeup_fds_enabled = 0; void grpc_wakeup_fd_global_init(void) { if (grpc_allow_specialized_wakeup_fd && @@ -53,27 +55,47 @@ void grpc_wakeup_fd_global_init(void) { grpc_pipe_wakeup_fd_vtable.check_availability()) { wakeup_fd_vtable = &grpc_pipe_wakeup_fd_vtable; } else { - grpc_has_wakeup_fd = 0; - wakeup_fd_vtable = &grpc_cv_wakeup_fd_vtable; + grpc_has_real_wakeup_fd = 0; } } void grpc_wakeup_fd_global_destroy(void) { wakeup_fd_vtable = NULL; } +int grpc_has_wakeup_fd(void) { + return grpc_has_real_wakeup_fd || grpc_cv_wakeup_fds_enabled; +} + +void grpc_enable_cv_wakeup_fds(int enable) { + grpc_cv_wakeup_fds_enabled = enable; +} + grpc_error *grpc_wakeup_fd_init(grpc_wakeup_fd *fd_info) { + if (grpc_cv_wakeup_fds_enabled) { + return grpc_cv_wakeup_fd_vtable.init(fd_info); + } return wakeup_fd_vtable->init(fd_info); } grpc_error *grpc_wakeup_fd_consume_wakeup(grpc_wakeup_fd *fd_info) { + if (grpc_cv_wakeup_fds_enabled) { + return grpc_cv_wakeup_fd_vtable.consume(fd_info); + } return wakeup_fd_vtable->consume(fd_info); } grpc_error *grpc_wakeup_fd_wakeup(grpc_wakeup_fd *fd_info) { + if (grpc_cv_wakeup_fds_enabled) { + return grpc_cv_wakeup_fd_vtable.wakeup(fd_info); + } return wakeup_fd_vtable->wakeup(fd_info); } void grpc_wakeup_fd_destroy(grpc_wakeup_fd *fd_info) { - wakeup_fd_vtable->destroy(fd_info); + if (grpc_cv_wakeup_fds_enabled) { + grpc_cv_wakeup_fd_vtable.destroy(fd_info); + } else { + wakeup_fd_vtable->destroy(fd_info); + } } #endif /* GPR_POSIX_WAKEUP_FD */ diff --git a/src/core/lib/iomgr/wakeup_fd_posix.h b/src/core/lib/iomgr/wakeup_fd_posix.h index bd0fb46da1..243c452751 100644 --- a/src/core/lib/iomgr/wakeup_fd_posix.h +++ b/src/core/lib/iomgr/wakeup_fd_posix.h @@ -71,6 +71,9 @@ void grpc_wakeup_fd_global_destroy(void); * purposes only.*/ void grpc_wakeup_fd_global_init_force_fallback(void); +int grpc_has_wakeup_fd(void); +void grpc_enable_cv_wakeup_fds(int enable); + typedef struct grpc_wakeup_fd grpc_wakeup_fd; typedef struct grpc_wakeup_fd_vtable { @@ -89,7 +92,7 @@ struct grpc_wakeup_fd { extern int grpc_allow_specialized_wakeup_fd; extern int grpc_allow_pipe_wakeup_fd; -extern int grpc_has_wakeup_fd; +extern int grpc_has_real_wakeup_fd; #define GRPC_WAKEUP_FD_GET_READ_FD(fd_info) ((fd_info)->read_fd) -- cgit v1.2.3 From 7e73f8c2d8f46f9ea3491a897345047bed7a0ea0 Mon Sep 17 00:00:00 2001 From: Ken Payson Date: Tue, 11 Oct 2016 12:55:40 -0700 Subject: Changes --- src/core/lib/iomgr/ev_poll_cv_posix.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/core/lib/iomgr/ev_poll_cv_posix.h b/src/core/lib/iomgr/ev_poll_cv_posix.h index ff667a54c2..885711d1c5 100644 --- a/src/core/lib/iomgr/ev_poll_cv_posix.h +++ b/src/core/lib/iomgr/ev_poll_cv_posix.h @@ -54,12 +54,9 @@ typedef struct fd_node { typedef struct cv_fd_table { gpr_mu mu; -<<<<<<< HEAD -======= int pollcount; int shutdown; gpr_cv shutdown_complete; ->>>>>>> d195cf589d3f03b4f08017f3e2885c2c2fff125b fd_node* cvfds; fd_node* free_fds; unsigned int size; -- cgit v1.2.3 From a3654db631f02eb7f566ea775d78f3ff2b27830a Mon Sep 17 00:00:00 2001 From: David Garcia Quintas Date: Tue, 11 Oct 2016 15:52:39 -0700 Subject: Renamed LB-related metadata keys --- src/core/ext/lb_policy/grpclb/grpclb.c | 6 +++--- src/core/ext/load_reporting/load_reporting.h | 4 ++-- src/core/ext/load_reporting/load_reporting_filter.c | 4 ++-- src/core/lib/transport/static_metadata.c | 4 ++-- src/core/lib/transport/static_metadata.h | 21 ++++++++++----------- test/core/end2end/fuzzers/hpack.dictionary | 8 ++++---- test/core/end2end/tests/load_reporting_hook.c | 4 ++-- test/cpp/grpclb/grpclb_test.cc | 3 +-- tools/codegen/core/gen_static_metadata.py | 4 ++-- 9 files changed, 28 insertions(+), 30 deletions(-) diff --git a/src/core/ext/lb_policy/grpclb/grpclb.c b/src/core/ext/lb_policy/grpclb/grpclb.c index ae1f2a3b4c..0442c864f5 100644 --- a/src/core/ext/lb_policy/grpclb/grpclb.c +++ b/src/core/ext/lb_policy/grpclb/grpclb.c @@ -399,14 +399,14 @@ static grpc_lb_addresses *process_serverlist( GPR_ARRAY_SIZE(server->load_balance_token) - 1; grpc_mdstr *lb_token_mdstr = grpc_mdstr_from_buffer( (uint8_t *)server->load_balance_token, lb_token_size); - user_data = grpc_mdelem_from_metadata_strings( - GRPC_MDSTR_LOAD_REPORTING_INITIAL, lb_token_mdstr); + user_data = grpc_mdelem_from_metadata_strings(GRPC_MDSTR_LB_TOKEN, + lb_token_mdstr); } else { gpr_log(GPR_ERROR, "Missing LB token for backend address '%s'. The empty token will " "be used instead", grpc_sockaddr_to_uri((struct sockaddr *)&addr.addr)); - user_data = GRPC_MDELEM_LOAD_REPORTING_INITIAL_EMPTY; + user_data = GRPC_MDELEM_LB_TOKEN_EMPTY; } grpc_lb_addresses_set_address(lb_addresses, addr_idx, &addr.addr, addr.len, diff --git a/src/core/ext/load_reporting/load_reporting.h b/src/core/ext/load_reporting/load_reporting.h index e37817d8c2..a0db780c3a 100644 --- a/src/core/ext/load_reporting/load_reporting.h +++ b/src/core/ext/load_reporting/load_reporting.h @@ -39,11 +39,11 @@ /** Metadata key for initial metadata coming from clients */ /* TODO(dgq): change to the final value TBD */ -#define GRPC_LOAD_REPORTING_INITIAL_MD_KEY "load-reporting-initial" +#define GRPC_LB_TOKEN_MD_KEY "lb-token" /** Metadata key for trailing metadata from servers */ /* TODO(dgq): change to the final value TBD */ -#define GRPC_LOAD_REPORTING_TRAILING_MD_KEY "load-reporting-trailing" +#define GRPC_LB_COST_MD_KEY "lb-cost" /** Identifiers for the invocation point of the users LR callback */ typedef enum grpc_load_reporting_source { diff --git a/src/core/ext/load_reporting/load_reporting_filter.c b/src/core/ext/load_reporting/load_reporting_filter.c index 394f0cb832..22bf36367f 100644 --- a/src/core/ext/load_reporting/load_reporting_filter.c +++ b/src/core/ext/load_reporting/load_reporting_filter.c @@ -75,7 +75,7 @@ static grpc_mdelem *recv_md_filter(void *user_data, grpc_mdelem *md) { if (md->key == GRPC_MDSTR_PATH) { calld->service_method = grpc_mdstr_as_c_string(md->value); - } else if (md->key == GRPC_MDSTR_LOAD_REPORTING_INITIAL) { + } else if (md->key == GRPC_MDSTR_LB_TOKEN) { calld->initial_md_string = gpr_strdup(grpc_mdstr_as_c_string(md->value)); return NULL; } @@ -193,7 +193,7 @@ static grpc_mdelem *lr_trailing_md_filter(void *user_data, grpc_mdelem *md) { grpc_call_element *elem = user_data; call_data *calld = elem->call_data; - if (md->key == GRPC_MDSTR_LOAD_REPORTING_TRAILING) { + if (md->key == GRPC_MDSTR_LB_COST) { calld->trailing_md_string = gpr_strdup(grpc_mdstr_as_c_string(md->value)); return NULL; } diff --git a/src/core/lib/transport/static_metadata.c b/src/core/lib/transport/static_metadata.c index 5e0352a467..f019ef156a 100644 --- a/src/core/lib/transport/static_metadata.c +++ b/src/core/lib/transport/static_metadata.c @@ -126,9 +126,9 @@ const char *const grpc_static_metadata_strings[GRPC_STATIC_MDSTR_COUNT] = { "if-range", "if-unmodified-since", "last-modified", + "lb-cost", + "lb-token", "link", - "load-reporting-initial", - "load-reporting-trailing", "location", "max-forwards", ":method", diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h index 5b9ee1a60a..e0a8196419 100644 --- a/src/core/lib/transport/static_metadata.h +++ b/src/core/lib/transport/static_metadata.h @@ -175,12 +175,12 @@ extern grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT]; #define GRPC_MDSTR_IF_UNMODIFIED_SINCE (&grpc_static_mdstr_table[62]) /* "last-modified" */ #define GRPC_MDSTR_LAST_MODIFIED (&grpc_static_mdstr_table[63]) +/* "lb-cost" */ +#define GRPC_MDSTR_LB_COST (&grpc_static_mdstr_table[64]) +/* "lb-token" */ +#define GRPC_MDSTR_LB_TOKEN (&grpc_static_mdstr_table[65]) /* "link" */ -#define GRPC_MDSTR_LINK (&grpc_static_mdstr_table[64]) -/* "load-reporting-initial" */ -#define GRPC_MDSTR_LOAD_REPORTING_INITIAL (&grpc_static_mdstr_table[65]) -/* "load-reporting-trailing" */ -#define GRPC_MDSTR_LOAD_REPORTING_TRAILING (&grpc_static_mdstr_table[66]) +#define GRPC_MDSTR_LINK (&grpc_static_mdstr_table[66]) /* "location" */ #define GRPC_MDSTR_LOCATION (&grpc_static_mdstr_table[67]) /* "max-forwards" */ @@ -337,13 +337,12 @@ extern uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT]; #define GRPC_MDELEM_IF_UNMODIFIED_SINCE_EMPTY (&grpc_static_mdelem_table[44]) /* "last-modified": "" */ #define GRPC_MDELEM_LAST_MODIFIED_EMPTY (&grpc_static_mdelem_table[45]) +/* "lb-cost": "" */ +#define GRPC_MDELEM_LB_COST_EMPTY (&grpc_static_mdelem_table[46]) +/* "lb-token": "" */ +#define GRPC_MDELEM_LB_TOKEN_EMPTY (&grpc_static_mdelem_table[47]) /* "link": "" */ -#define GRPC_MDELEM_LINK_EMPTY (&grpc_static_mdelem_table[46]) -/* "load-reporting-initial": "" */ -#define GRPC_MDELEM_LOAD_REPORTING_INITIAL_EMPTY (&grpc_static_mdelem_table[47]) -/* "load-reporting-trailing": "" */ -#define GRPC_MDELEM_LOAD_REPORTING_TRAILING_EMPTY \ - (&grpc_static_mdelem_table[48]) +#define GRPC_MDELEM_LINK_EMPTY (&grpc_static_mdelem_table[48]) /* "location": "" */ #define GRPC_MDELEM_LOCATION_EMPTY (&grpc_static_mdelem_table[49]) /* "max-forwards": "" */ diff --git a/test/core/end2end/fuzzers/hpack.dictionary b/test/core/end2end/fuzzers/hpack.dictionary index a93bccfa0d..181bbe845e 100644 --- a/test/core/end2end/fuzzers/hpack.dictionary +++ b/test/core/end2end/fuzzers/hpack.dictionary @@ -63,9 +63,9 @@ "\x08if-range" "\x13if-unmodified-since" "\x0Dlast-modified" +"\x07lb-cost" +"\x08lb-token" "\x04link" -"\x16load-reporting-initial" -"\x17load-reporting-trailing" "\x08location" "\x0Cmax-forwards" "\x07:method" @@ -138,9 +138,9 @@ "\x00\x08if-range\x00" "\x00\x13if-unmodified-since\x00" "\x00\x0Dlast-modified\x00" +"\x00\x07lb-cost\x00" +"\x00\x08lb-token\x00" "\x00\x04link\x00" -"\x00\x16load-reporting-initial\x00" -"\x00\x17load-reporting-trailing\x00" "\x00\x08location\x00" "\x00\x0Cmax-forwards\x00" "\x00\x07:method\x03GET" diff --git a/test/core/end2end/tests/load_reporting_hook.c b/test/core/end2end/tests/load_reporting_hook.c index 59d054cf87..7f95dfd949 100644 --- a/test/core/end2end/tests/load_reporting_hook.c +++ b/test/core/end2end/tests/load_reporting_hook.c @@ -295,13 +295,13 @@ static void test_load_reporting_hook(grpc_end2end_test_config config) { grpc_metadata initial_lr_metadata; grpc_metadata trailing_lr_metadata; - initial_lr_metadata.key = GRPC_LOAD_REPORTING_INITIAL_MD_KEY; + initial_lr_metadata.key = GRPC_LB_TOKEN_MD_KEY; initial_lr_metadata.value = "client-token"; initial_lr_metadata.value_length = strlen(initial_lr_metadata.value); memset(&initial_lr_metadata.internal_data, 0, sizeof(initial_lr_metadata.internal_data)); - trailing_lr_metadata.key = GRPC_LOAD_REPORTING_TRAILING_MD_KEY; + trailing_lr_metadata.key = GRPC_LB_COST_MD_KEY; trailing_lr_metadata.value = "server-token"; trailing_lr_metadata.value_length = strlen(trailing_lr_metadata.value); memset(&trailing_lr_metadata.internal_data, 0, diff --git a/test/cpp/grpclb/grpclb_test.cc b/test/cpp/grpclb/grpclb_test.cc index 7666c4e60b..80f2fa4f4d 100644 --- a/test/cpp/grpclb/grpclb_test.cc +++ b/test/cpp/grpclb/grpclb_test.cc @@ -334,8 +334,7 @@ static void start_backend_server(server_fixture *sf) { // have a version for int but does have one for long long int. string expected_token = "token" + std::to_string((long long int)sf->port); expected_token.resize(64, '-'); - GPR_ASSERT(contains_metadata(&request_metadata_recv, - "load-reporting-initial", + GPR_ASSERT(contains_metadata(&request_metadata_recv, "lb-token", expected_token.c_str())); gpr_log(GPR_INFO, "Server[%s] after tag 100", sf->servers_hostport); diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py index 6f400102e4..6f8cad279c 100755 --- a/tools/codegen/core/gen_static_metadata.py +++ b/tools/codegen/core/gen_static_metadata.py @@ -109,8 +109,8 @@ CONFIG = [ ('if-range', ''), ('if-unmodified-since', ''), ('last-modified', ''), - ('load-reporting-initial', ''), - ('load-reporting-trailing', ''), + ('lb-token', ''), + ('lb-cost', ''), ('link', ''), ('location', ''), ('max-forwards', ''), -- cgit v1.2.3 From c5986021b98cf9bc95496f6d7af9b39864483c2c Mon Sep 17 00:00:00 2001 From: David Garcia Quintas Date: Tue, 11 Oct 2016 16:33:31 -0700 Subject: Removed outdated TODOs and improved docstrings --- src/core/ext/load_reporting/load_reporting.h | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/core/ext/load_reporting/load_reporting.h b/src/core/ext/load_reporting/load_reporting.h index a0db780c3a..e13097654d 100644 --- a/src/core/ext/load_reporting/load_reporting.h +++ b/src/core/ext/load_reporting/load_reporting.h @@ -37,12 +37,20 @@ #include #include "src/core/lib/channel/channel_stack.h" -/** Metadata key for initial metadata coming from clients */ -/* TODO(dgq): change to the final value TBD */ +/** Metadata key for the gRPC LB load balancer token. + * + * The value corresponding to this key is an opaque token that is given to the + * frontend as part of each pick; the frontend sends this token to the backend + * in each request it sends when using that pick. The token is used by the + * backend to verify the request and to allow the backend to report load to the + * gRPC LB system. */ #define GRPC_LB_TOKEN_MD_KEY "lb-token" -/** Metadata key for trailing metadata from servers */ -/* TODO(dgq): change to the final value TBD */ +/** Metadata key for gRPC LB cost reporting. + * + * The value corresponding to this key is an opaque binary blob reported by the + * backend as part of its trailing metadata containing cost information for the + * call. */ #define GRPC_LB_COST_MD_KEY "lb-cost" /** Identifiers for the invocation point of the users LR callback */ -- cgit v1.2.3 From cfcc0755a0c77180c3eaadea1c8d1103da2e8f36 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Sun, 9 Oct 2016 17:02:34 +0200 Subject: more flexible test naming in reports --- tools/run_tests/report_utils.py | 7 ++++--- tools/run_tests/run_tests.py | 8 ++++++-- tools/run_tests/run_tests_matrix.py | 9 ++++++--- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/tools/run_tests/report_utils.py b/tools/run_tests/report_utils.py index 5648a694cd..efe5dc999d 100644 --- a/tools/run_tests/report_utils.py +++ b/tools/run_tests/report_utils.py @@ -57,11 +57,12 @@ def _filter_msg(msg, output_format): return msg -def render_junit_xml_report(resultset, xml_report): +def render_junit_xml_report(resultset, xml_report, suite_package='grpc', + suite_name='tests'): """Generate JUnit-like XML report.""" root = ET.Element('testsuites') - testsuite = ET.SubElement(root, 'testsuite', id='1', package='grpc', - name='tests') + testsuite = ET.SubElement(root, 'testsuite', id='1', package=suite_package, + name=suite_name) for shortname, results in resultset.items(): for result in results: xml_test = ET.SubElement(testsuite, 'testcase', name=shortname) diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index a6f3d405dc..dd070b1fe0 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -1015,6 +1015,8 @@ argp.add_argument('--update_submodules', default=[], nargs='*', argp.add_argument('-a', '--antagonists', default=0, type=int) argp.add_argument('-x', '--xml_report', default=None, type=str, help='Generates a JUnit-compatible XML report') +argp.add_argument('--report_suite_name', default='tests', type=str, + help='Test suite name to use in generated JUnit XML report') argp.add_argument('--force_default_poller', default=False, action='store_const', const=True, help='Dont try to iterate over many polling strategies when they exist') args = argp.parse_args() @@ -1327,7 +1329,8 @@ def _build_and_run( if build_only: if xml_report: - report_utils.render_junit_xml_report(resultset, xml_report) + report_utils.render_junit_xml_report(resultset, xml_report, + suite_name=args.report_suite_name) return [] # start antagonists @@ -1379,7 +1382,8 @@ def _build_and_run( for antagonist in antagonists: antagonist.kill() if xml_report and resultset: - report_utils.render_junit_xml_report(resultset, xml_report) + report_utils.render_junit_xml_report(resultset, xml_report, + suite_name=args.report_suite_name) number_failures, _ = jobset.run( post_tests_steps, maxjobs=1, stop_on_failure=True, diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py index a94f9cfef5..60c21a1e21 100755 --- a/tools/run_tests/run_tests_matrix.py +++ b/tools/run_tests/run_tests_matrix.py @@ -55,7 +55,8 @@ def _docker_jobspec(name, runtests_args=[]): '--use_docker', '-t', '-j', str(_INNER_JOBS), - '-x', 'report_%s.xml' % name] + runtests_args, + '-x', 'report_%s.xml' % name, + '--report_suite_name', '%s' % name] + runtests_args, shortname='run_tests_%s' % name, timeout_seconds=_RUNTESTS_TIMEOUT) return test_job @@ -70,7 +71,8 @@ def _workspace_jobspec(name, runtests_args=[], workspace_name=None): cmdline=['tools/run_tests/run_tests_in_workspace.sh', '-t', '-j', str(_INNER_JOBS), - '-x', '../report_%s.xml' % name] + runtests_args, + '-x', '../report_%s.xml' % name, + '--report_suite_name', '%s' % name] + runtests_args, environ=env, shortname='run_tests_%s' % name, timeout_seconds=_RUNTESTS_TIMEOUT) @@ -271,7 +273,8 @@ num_failures, resultset = jobset.run(jobs, newline_on_success=True, travis=True, maxjobs=args.jobs) -report_utils.render_junit_xml_report(resultset, 'report.xml') +report_utils.render_junit_xml_report(resultset, 'report.xml', + suite_name='aggregate_tests') if num_failures == 0: jobset.message('SUCCESS', 'All run_tests.py instance finished successfully.', -- cgit v1.2.3 From 05cccba2f14648704725498439078766631f58f0 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 5 Oct 2016 21:22:06 +0200 Subject: add comment for NewInstance override --- src/compiler/csharp_generator.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc index 591e5ae3d4..48157033db 100644 --- a/src/compiler/csharp_generator.cc +++ b/src/compiler/csharp_generator.cc @@ -494,6 +494,9 @@ void GenerateClientStub(Printer *out, const ServiceDescriptor *service) { } // override NewInstance method + out->Print( + "/// Creates a new instance of client from given " + "ClientBaseConfiguration.\n"); out->Print( "protected override $name$ NewInstance(ClientBaseConfiguration " "configuration)\n", -- cgit v1.2.3 From 10098d1819c39a5083131b821adf86b738568362 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 6 Oct 2016 13:15:12 +0200 Subject: regenerate C# protos --- src/csharp/Grpc.Examples/Math.cs | 83 ++++- src/csharp/Grpc.Examples/MathGrpc.cs | 1 + src/csharp/Grpc.HealthCheck/Health.cs | 35 +- src/csharp/Grpc.HealthCheck/HealthGrpc.cs | 1 + src/csharp/Grpc.IntegrationTesting/Control.cs | 401 +++++++++++++++++++-- src/csharp/Grpc.IntegrationTesting/Empty.cs | 16 +- src/csharp/Grpc.IntegrationTesting/Messages.cs | 211 ++++++++++- src/csharp/Grpc.IntegrationTesting/Metrics.cs | 53 ++- src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs | 1 + src/csharp/Grpc.IntegrationTesting/Payloads.cs | 70 +++- src/csharp/Grpc.IntegrationTesting/Services.cs | 1 - src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs | 2 + src/csharp/Grpc.IntegrationTesting/Stats.cs | 76 +++- src/csharp/Grpc.IntegrationTesting/Test.cs | 1 - src/csharp/Grpc.IntegrationTesting/TestGrpc.cs | 3 + 15 files changed, 887 insertions(+), 68 deletions(-) diff --git a/src/csharp/Grpc.Examples/Math.cs b/src/csharp/Grpc.Examples/Math.cs index a17228c8c5..fae4fd3c26 100644 --- a/src/csharp/Grpc.Examples/Math.cs +++ b/src/csharp/Grpc.Examples/Math.cs @@ -10,7 +10,6 @@ using scg = global::System.Collections.Generic; namespace Math { /// Holder for reflection information generated from math.proto - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public static partial class MathReflection { #region Descriptor @@ -46,30 +45,35 @@ namespace Math { } #region Messages - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class DivArgs : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new DivArgs()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Math.MathReflection.Descriptor.MessageTypes[0]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public DivArgs() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public DivArgs(DivArgs other) : this() { dividend_ = other.dividend_; divisor_ = other.divisor_; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public DivArgs Clone() { return new DivArgs(this); } @@ -77,6 +81,7 @@ namespace Math { /// Field number for the "dividend" field. public const int DividendFieldNumber = 1; private long dividend_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public long Dividend { get { return dividend_; } set { @@ -87,6 +92,7 @@ namespace Math { /// Field number for the "divisor" field. public const int DivisorFieldNumber = 2; private long divisor_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public long Divisor { get { return divisor_; } set { @@ -94,10 +100,12 @@ namespace Math { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as DivArgs); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(DivArgs other) { if (ReferenceEquals(other, null)) { return false; @@ -110,6 +118,7 @@ namespace Math { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (Dividend != 0L) hash ^= Dividend.GetHashCode(); @@ -117,10 +126,12 @@ namespace Math { return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (Dividend != 0L) { output.WriteRawTag(8); @@ -132,6 +143,7 @@ namespace Math { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (Dividend != 0L) { @@ -143,6 +155,7 @@ namespace Math { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(DivArgs other) { if (other == null) { return; @@ -155,6 +168,7 @@ namespace Math { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -176,30 +190,35 @@ namespace Math { } - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class DivReply : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new DivReply()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Math.MathReflection.Descriptor.MessageTypes[1]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public DivReply() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public DivReply(DivReply other) : this() { quotient_ = other.quotient_; remainder_ = other.remainder_; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public DivReply Clone() { return new DivReply(this); } @@ -207,6 +226,7 @@ namespace Math { /// Field number for the "quotient" field. public const int QuotientFieldNumber = 1; private long quotient_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public long Quotient { get { return quotient_; } set { @@ -217,6 +237,7 @@ namespace Math { /// Field number for the "remainder" field. public const int RemainderFieldNumber = 2; private long remainder_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public long Remainder { get { return remainder_; } set { @@ -224,10 +245,12 @@ namespace Math { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as DivReply); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(DivReply other) { if (ReferenceEquals(other, null)) { return false; @@ -240,6 +263,7 @@ namespace Math { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (Quotient != 0L) hash ^= Quotient.GetHashCode(); @@ -247,10 +271,12 @@ namespace Math { return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (Quotient != 0L) { output.WriteRawTag(8); @@ -262,6 +288,7 @@ namespace Math { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (Quotient != 0L) { @@ -273,6 +300,7 @@ namespace Math { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(DivReply other) { if (other == null) { return; @@ -285,6 +313,7 @@ namespace Math { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -306,29 +335,34 @@ namespace Math { } - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class FibArgs : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FibArgs()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Math.MathReflection.Descriptor.MessageTypes[2]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public FibArgs() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public FibArgs(FibArgs other) : this() { limit_ = other.limit_; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public FibArgs Clone() { return new FibArgs(this); } @@ -336,6 +370,7 @@ namespace Math { /// Field number for the "limit" field. public const int LimitFieldNumber = 1; private long limit_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public long Limit { get { return limit_; } set { @@ -343,10 +378,12 @@ namespace Math { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as FibArgs); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(FibArgs other) { if (ReferenceEquals(other, null)) { return false; @@ -358,16 +395,19 @@ namespace Math { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (Limit != 0L) hash ^= Limit.GetHashCode(); return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (Limit != 0L) { output.WriteRawTag(8); @@ -375,6 +415,7 @@ namespace Math { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (Limit != 0L) { @@ -383,6 +424,7 @@ namespace Math { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(FibArgs other) { if (other == null) { return; @@ -392,6 +434,7 @@ namespace Math { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -409,29 +452,34 @@ namespace Math { } - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class Num : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Num()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Math.MathReflection.Descriptor.MessageTypes[3]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public Num() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public Num(Num other) : this() { num_ = other.num_; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public Num Clone() { return new Num(this); } @@ -439,6 +487,7 @@ namespace Math { /// Field number for the "num" field. public const int Num_FieldNumber = 1; private long num_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public long Num_ { get { return num_; } set { @@ -446,10 +495,12 @@ namespace Math { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as Num); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(Num other) { if (ReferenceEquals(other, null)) { return false; @@ -461,16 +512,19 @@ namespace Math { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (Num_ != 0L) hash ^= Num_.GetHashCode(); return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (Num_ != 0L) { output.WriteRawTag(8); @@ -478,6 +532,7 @@ namespace Math { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (Num_ != 0L) { @@ -486,6 +541,7 @@ namespace Math { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(Num other) { if (other == null) { return; @@ -495,6 +551,7 @@ namespace Math { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -512,29 +569,34 @@ namespace Math { } - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class FibReply : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FibReply()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Math.MathReflection.Descriptor.MessageTypes[4]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public FibReply() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public FibReply(FibReply other) : this() { count_ = other.count_; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public FibReply Clone() { return new FibReply(this); } @@ -542,6 +604,7 @@ namespace Math { /// Field number for the "count" field. public const int CountFieldNumber = 1; private long count_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public long Count { get { return count_; } set { @@ -549,10 +612,12 @@ namespace Math { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as FibReply); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(FibReply other) { if (ReferenceEquals(other, null)) { return false; @@ -564,16 +629,19 @@ namespace Math { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (Count != 0L) hash ^= Count.GetHashCode(); return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (Count != 0L) { output.WriteRawTag(8); @@ -581,6 +649,7 @@ namespace Math { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (Count != 0L) { @@ -589,6 +658,7 @@ namespace Math { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(FibReply other) { if (other == null) { return; @@ -598,6 +668,7 @@ namespace Math { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { diff --git a/src/csharp/Grpc.Examples/MathGrpc.cs b/src/csharp/Grpc.Examples/MathGrpc.cs index 25abc51419..d6ba61e7dc 100644 --- a/src/csharp/Grpc.Examples/MathGrpc.cs +++ b/src/csharp/Grpc.Examples/MathGrpc.cs @@ -234,6 +234,7 @@ namespace Math { { return CallInvoker.AsyncClientStreamingCall(__Method_Sum, null, options); } + /// Creates a new instance of client from given ClientBaseConfiguration. protected override MathClient NewInstance(ClientBaseConfiguration configuration) { return new MathClient(configuration); diff --git a/src/csharp/Grpc.HealthCheck/Health.cs b/src/csharp/Grpc.HealthCheck/Health.cs index 100ad187d7..b8e2e2274c 100644 --- a/src/csharp/Grpc.HealthCheck/Health.cs +++ b/src/csharp/Grpc.HealthCheck/Health.cs @@ -10,7 +10,6 @@ using scg = global::System.Collections.Generic; namespace Grpc.Health.V1 { /// Holder for reflection information generated from health.proto - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public static partial class HealthReflection { #region Descriptor @@ -42,29 +41,34 @@ namespace Grpc.Health.V1 { } #region Messages - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class HealthCheckRequest : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new HealthCheckRequest()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Health.V1.HealthReflection.Descriptor.MessageTypes[0]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public HealthCheckRequest() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public HealthCheckRequest(HealthCheckRequest other) : this() { service_ = other.service_; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public HealthCheckRequest Clone() { return new HealthCheckRequest(this); } @@ -72,6 +76,7 @@ namespace Grpc.Health.V1 { /// Field number for the "service" field. public const int ServiceFieldNumber = 1; private string service_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public string Service { get { return service_; } set { @@ -79,10 +84,12 @@ namespace Grpc.Health.V1 { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as HealthCheckRequest); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(HealthCheckRequest other) { if (ReferenceEquals(other, null)) { return false; @@ -94,16 +101,19 @@ namespace Grpc.Health.V1 { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (Service.Length != 0) hash ^= Service.GetHashCode(); return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (Service.Length != 0) { output.WriteRawTag(10); @@ -111,6 +121,7 @@ namespace Grpc.Health.V1 { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (Service.Length != 0) { @@ -119,6 +130,7 @@ namespace Grpc.Health.V1 { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(HealthCheckRequest other) { if (other == null) { return; @@ -128,6 +140,7 @@ namespace Grpc.Health.V1 { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -145,29 +158,34 @@ namespace Grpc.Health.V1 { } - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class HealthCheckResponse : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new HealthCheckResponse()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Health.V1.HealthReflection.Descriptor.MessageTypes[1]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public HealthCheckResponse() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public HealthCheckResponse(HealthCheckResponse other) : this() { status_ = other.status_; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public HealthCheckResponse Clone() { return new HealthCheckResponse(this); } @@ -175,6 +193,7 @@ namespace Grpc.Health.V1 { /// Field number for the "status" field. public const int StatusFieldNumber = 1; private global::Grpc.Health.V1.HealthCheckResponse.Types.ServingStatus status_ = 0; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Health.V1.HealthCheckResponse.Types.ServingStatus Status { get { return status_; } set { @@ -182,10 +201,12 @@ namespace Grpc.Health.V1 { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as HealthCheckResponse); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(HealthCheckResponse other) { if (ReferenceEquals(other, null)) { return false; @@ -197,16 +218,19 @@ namespace Grpc.Health.V1 { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (Status != 0) hash ^= Status.GetHashCode(); return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (Status != 0) { output.WriteRawTag(8); @@ -214,6 +238,7 @@ namespace Grpc.Health.V1 { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (Status != 0) { @@ -222,6 +247,7 @@ namespace Grpc.Health.V1 { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(HealthCheckResponse other) { if (other == null) { return; @@ -231,6 +257,7 @@ namespace Grpc.Health.V1 { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -248,7 +275,7 @@ namespace Grpc.Health.V1 { #region Nested types /// Container for nested types declared in the HealthCheckResponse message type. - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static partial class Types { public enum ServingStatus { [pbr::OriginalName("UNKNOWN")] Unknown = 0, diff --git a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs index 43eea0f22f..b2a35a79be 100644 --- a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs +++ b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs @@ -107,6 +107,7 @@ namespace Grpc.Health.V1 { { return CallInvoker.AsyncUnaryCall(__Method_Check, null, options, request); } + /// Creates a new instance of client from given ClientBaseConfiguration. protected override HealthClient NewInstance(ClientBaseConfiguration configuration) { return new HealthClient(configuration); diff --git a/src/csharp/Grpc.IntegrationTesting/Control.cs b/src/csharp/Grpc.IntegrationTesting/Control.cs index 412f800ff9..7928b51ba5 100644 --- a/src/csharp/Grpc.IntegrationTesting/Control.cs +++ b/src/csharp/Grpc.IntegrationTesting/Control.cs @@ -10,7 +10,6 @@ using scg = global::System.Collections.Generic; namespace Grpc.Testing { /// Holder for reflection information generated from src/proto/grpc/testing/control.proto - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public static partial class ControlReflection { #region Descriptor @@ -71,18 +70,19 @@ namespace Grpc.Testing { "ASgBEhoKEmNsaWVudF9zeXN0ZW1fdGltZRgFIAEoARIYChBjbGllbnRfdXNl", "cl90aW1lGAYgASgBEhIKCmxhdGVuY3lfNTAYByABKAESEgoKbGF0ZW5jeV85", "MBgIIAEoARISCgpsYXRlbmN5Xzk1GAkgASgBEhIKCmxhdGVuY3lfOTkYCiAB", - "KAESEwoLbGF0ZW5jeV85OTkYCyABKAEimAIKDlNjZW5hcmlvUmVzdWx0EigK", + "KAESEwoLbGF0ZW5jeV85OTkYCyABKAEiyAIKDlNjZW5hcmlvUmVzdWx0EigK", "CHNjZW5hcmlvGAEgASgLMhYuZ3JwYy50ZXN0aW5nLlNjZW5hcmlvEi4KCWxh", "dGVuY2llcxgCIAEoCzIbLmdycGMudGVzdGluZy5IaXN0b2dyYW1EYXRhEi8K", "DGNsaWVudF9zdGF0cxgDIAMoCzIZLmdycGMudGVzdGluZy5DbGllbnRTdGF0", "cxIvCgxzZXJ2ZXJfc3RhdHMYBCADKAsyGS5ncnBjLnRlc3RpbmcuU2VydmVy", "U3RhdHMSFAoMc2VydmVyX2NvcmVzGAUgAygFEjQKB3N1bW1hcnkYBiABKAsy", - "Iy5ncnBjLnRlc3RpbmcuU2NlbmFyaW9SZXN1bHRTdW1tYXJ5KkEKCkNsaWVu", - "dFR5cGUSDwoLU1lOQ19DTElFTlQQABIQCgxBU1lOQ19DTElFTlQQARIQCgxP", - "VEhFUl9DTElFTlQQAipbCgpTZXJ2ZXJUeXBlEg8KC1NZTkNfU0VSVkVSEAAS", - "EAoMQVNZTkNfU0VSVkVSEAESGAoUQVNZTkNfR0VORVJJQ19TRVJWRVIQAhIQ", - "CgxPVEhFUl9TRVJWRVIQAyojCgdScGNUeXBlEgkKBVVOQVJZEAASDQoJU1RS", - "RUFNSU5HEAFiBnByb3RvMw==")); + "Iy5ncnBjLnRlc3RpbmcuU2NlbmFyaW9SZXN1bHRTdW1tYXJ5EhYKDmNsaWVu", + "dF9zdWNjZXNzGAcgAygIEhYKDnNlcnZlcl9zdWNjZXNzGAggAygIKkEKCkNs", + "aWVudFR5cGUSDwoLU1lOQ19DTElFTlQQABIQCgxBU1lOQ19DTElFTlQQARIQ", + "CgxPVEhFUl9DTElFTlQQAipbCgpTZXJ2ZXJUeXBlEg8KC1NZTkNfU0VSVkVS", + "EAASEAoMQVNZTkNfU0VSVkVSEAESGAoUQVNZTkNfR0VORVJJQ19TRVJWRVIQ", + "AhIQCgxPVEhFUl9TRVJWRVIQAyojCgdScGNUeXBlEgkKBVVOQVJZEAASDQoJ", + "U1RSRUFNSU5HEAFiBnByb3RvMw==")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { global::Grpc.Testing.PayloadsReflection.Descriptor, global::Grpc.Testing.StatsReflection.Descriptor, }, new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Grpc.Testing.ClientType), typeof(global::Grpc.Testing.ServerType), typeof(global::Grpc.Testing.RpcType), }, new pbr::GeneratedClrTypeInfo[] { @@ -103,7 +103,7 @@ namespace Grpc.Testing { new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.Scenario), global::Grpc.Testing.Scenario.Parser, new[]{ "Name", "ClientConfig", "NumClients", "ServerConfig", "NumServers", "WarmupSeconds", "BenchmarkSeconds", "SpawnLocalWorkerCount" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.Scenarios), global::Grpc.Testing.Scenarios.Parser, new[]{ "Scenarios_" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ScenarioResultSummary), global::Grpc.Testing.ScenarioResultSummary.Parser, new[]{ "Qps", "QpsPerServerCore", "ServerSystemTime", "ServerUserTime", "ClientSystemTime", "ClientUserTime", "Latency50", "Latency90", "Latency95", "Latency99", "Latency999" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ScenarioResult), global::Grpc.Testing.ScenarioResult.Parser, new[]{ "Scenario", "Latencies", "ClientStats", "ServerStats", "ServerCores", "Summary" }, null, null, null) + new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ScenarioResult), global::Grpc.Testing.ScenarioResult.Parser, new[]{ "Scenario", "Latencies", "ClientStats", "ServerStats", "ServerCores", "Summary", "ClientSuccess", "ServerSuccess" }, null, null, null) })); } #endregion @@ -145,29 +145,34 @@ namespace Grpc.Testing { /// Parameters of poisson process distribution, which is a good representation /// of activity coming in from independent identical stationary sources. /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class PoissonParams : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new PoissonParams()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[0]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public PoissonParams() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public PoissonParams(PoissonParams other) : this() { offeredLoad_ = other.offeredLoad_; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public PoissonParams Clone() { return new PoissonParams(this); } @@ -178,6 +183,7 @@ namespace Grpc.Testing { /// /// The rate of arrivals (a.k.a. lambda parameter of the exp distribution). /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double OfferedLoad { get { return offeredLoad_; } set { @@ -185,10 +191,12 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as PoissonParams); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(PoissonParams other) { if (ReferenceEquals(other, null)) { return false; @@ -200,16 +208,19 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (OfferedLoad != 0D) hash ^= OfferedLoad.GetHashCode(); return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (OfferedLoad != 0D) { output.WriteRawTag(9); @@ -217,6 +228,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (OfferedLoad != 0D) { @@ -225,6 +237,7 @@ namespace Grpc.Testing { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(PoissonParams other) { if (other == null) { return; @@ -234,6 +247,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -255,36 +269,43 @@ namespace Grpc.Testing { /// Once an RPC finishes, immediately start a new one. /// No configuration parameters needed. /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class ClosedLoopParams : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ClosedLoopParams()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[1]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ClosedLoopParams() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ClosedLoopParams(ClosedLoopParams other) : this() { } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ClosedLoopParams Clone() { return new ClosedLoopParams(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as ClosedLoopParams); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(ClosedLoopParams other) { if (ReferenceEquals(other, null)) { return false; @@ -295,29 +316,35 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(ClosedLoopParams other) { if (other == null) { return; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -331,25 +358,29 @@ namespace Grpc.Testing { } - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class LoadParams : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new LoadParams()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[2]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public LoadParams() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public LoadParams(LoadParams other) : this() { switch (other.LoadCase) { case LoadOneofCase.ClosedLoop: @@ -362,12 +393,14 @@ namespace Grpc.Testing { } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public LoadParams Clone() { return new LoadParams(this); } /// Field number for the "closed_loop" field. public const int ClosedLoopFieldNumber = 1; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.ClosedLoopParams ClosedLoop { get { return loadCase_ == LoadOneofCase.ClosedLoop ? (global::Grpc.Testing.ClosedLoopParams) load_ : null; } set { @@ -378,6 +411,7 @@ namespace Grpc.Testing { /// Field number for the "poisson" field. public const int PoissonFieldNumber = 2; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.PoissonParams Poisson { get { return loadCase_ == LoadOneofCase.Poisson ? (global::Grpc.Testing.PoissonParams) load_ : null; } set { @@ -394,19 +428,23 @@ namespace Grpc.Testing { Poisson = 2, } private LoadOneofCase loadCase_ = LoadOneofCase.None; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public LoadOneofCase LoadCase { get { return loadCase_; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void ClearLoad() { loadCase_ = LoadOneofCase.None; load_ = null; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as LoadParams); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(LoadParams other) { if (ReferenceEquals(other, null)) { return false; @@ -420,6 +458,7 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (loadCase_ == LoadOneofCase.ClosedLoop) hash ^= ClosedLoop.GetHashCode(); @@ -428,10 +467,12 @@ namespace Grpc.Testing { return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (loadCase_ == LoadOneofCase.ClosedLoop) { output.WriteRawTag(10); @@ -443,6 +484,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (loadCase_ == LoadOneofCase.ClosedLoop) { @@ -454,6 +496,7 @@ namespace Grpc.Testing { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(LoadParams other) { if (other == null) { return; @@ -469,6 +512,7 @@ namespace Grpc.Testing { } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -503,30 +547,35 @@ namespace Grpc.Testing { /// /// presence of SecurityParams implies use of TLS /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class SecurityParams : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new SecurityParams()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[3]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public SecurityParams() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public SecurityParams(SecurityParams other) : this() { useTestCa_ = other.useTestCa_; serverHostOverride_ = other.serverHostOverride_; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public SecurityParams Clone() { return new SecurityParams(this); } @@ -534,6 +583,7 @@ namespace Grpc.Testing { /// Field number for the "use_test_ca" field. public const int UseTestCaFieldNumber = 1; private bool useTestCa_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool UseTestCa { get { return useTestCa_; } set { @@ -544,6 +594,7 @@ namespace Grpc.Testing { /// Field number for the "server_host_override" field. public const int ServerHostOverrideFieldNumber = 2; private string serverHostOverride_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public string ServerHostOverride { get { return serverHostOverride_; } set { @@ -551,10 +602,12 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as SecurityParams); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(SecurityParams other) { if (ReferenceEquals(other, null)) { return false; @@ -567,6 +620,7 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (UseTestCa != false) hash ^= UseTestCa.GetHashCode(); @@ -574,10 +628,12 @@ namespace Grpc.Testing { return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (UseTestCa != false) { output.WriteRawTag(8); @@ -589,6 +645,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (UseTestCa != false) { @@ -600,6 +657,7 @@ namespace Grpc.Testing { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(SecurityParams other) { if (other == null) { return; @@ -612,6 +670,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -633,25 +692,29 @@ namespace Grpc.Testing { } - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class ClientConfig : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ClientConfig()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[4]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ClientConfig() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ClientConfig(ClientConfig other) : this() { serverTargets_ = other.serverTargets_.Clone(); clientType_ = other.clientType_; @@ -668,6 +731,7 @@ namespace Grpc.Testing { otherClientApi_ = other.otherClientApi_; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ClientConfig Clone() { return new ClientConfig(this); } @@ -680,6 +744,7 @@ namespace Grpc.Testing { /// /// List of targets to connect to. At least one target needs to be specified. /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::RepeatedField ServerTargets { get { return serverTargets_; } } @@ -687,6 +752,7 @@ namespace Grpc.Testing { /// Field number for the "client_type" field. public const int ClientTypeFieldNumber = 2; private global::Grpc.Testing.ClientType clientType_ = 0; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.ClientType ClientType { get { return clientType_; } set { @@ -697,6 +763,7 @@ namespace Grpc.Testing { /// Field number for the "security_params" field. public const int SecurityParamsFieldNumber = 3; private global::Grpc.Testing.SecurityParams securityParams_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.SecurityParams SecurityParams { get { return securityParams_; } set { @@ -711,6 +778,7 @@ namespace Grpc.Testing { /// How many concurrent RPCs to start for each channel. /// For synchronous client, use a separate thread for each outstanding RPC. /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int OutstandingRpcsPerChannel { get { return outstandingRpcsPerChannel_; } set { @@ -725,6 +793,7 @@ namespace Grpc.Testing { /// Number of independent client channels to create. /// i-th channel will connect to server_target[i % server_targets.size()] /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int ClientChannels { get { return clientChannels_; } set { @@ -738,6 +807,7 @@ namespace Grpc.Testing { /// /// Only for async client. Number of threads to use to start/manage RPCs. /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int AsyncClientThreads { get { return asyncClientThreads_; } set { @@ -748,6 +818,7 @@ namespace Grpc.Testing { /// Field number for the "rpc_type" field. public const int RpcTypeFieldNumber = 8; private global::Grpc.Testing.RpcType rpcType_ = 0; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.RpcType RpcType { get { return rpcType_; } set { @@ -761,6 +832,7 @@ namespace Grpc.Testing { /// /// The requested load for the entire client (aggregated over all the threads). /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.LoadParams LoadParams { get { return loadParams_; } set { @@ -771,6 +843,7 @@ namespace Grpc.Testing { /// Field number for the "payload_config" field. public const int PayloadConfigFieldNumber = 11; private global::Grpc.Testing.PayloadConfig payloadConfig_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.PayloadConfig PayloadConfig { get { return payloadConfig_; } set { @@ -781,6 +854,7 @@ namespace Grpc.Testing { /// Field number for the "histogram_params" field. public const int HistogramParamsFieldNumber = 12; private global::Grpc.Testing.HistogramParams histogramParams_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.HistogramParams HistogramParams { get { return histogramParams_; } set { @@ -796,6 +870,7 @@ namespace Grpc.Testing { /// /// Specify the cores we should run the client on, if desired /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::RepeatedField CoreList { get { return coreList_; } } @@ -803,6 +878,7 @@ namespace Grpc.Testing { /// Field number for the "core_limit" field. public const int CoreLimitFieldNumber = 14; private int coreLimit_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CoreLimit { get { return coreLimit_; } set { @@ -816,6 +892,7 @@ namespace Grpc.Testing { /// /// If we use an OTHER_CLIENT client_type, this string gives more detail /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public string OtherClientApi { get { return otherClientApi_; } set { @@ -823,10 +900,12 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as ClientConfig); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(ClientConfig other) { if (ReferenceEquals(other, null)) { return false; @@ -850,6 +929,7 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; hash ^= serverTargets_.GetHashCode(); @@ -868,10 +948,12 @@ namespace Grpc.Testing { return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { serverTargets_.WriteTo(output, _repeated_serverTargets_codec); if (ClientType != 0) { @@ -921,6 +1003,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; size += serverTargets_.CalculateSize(_repeated_serverTargets_codec); @@ -961,6 +1044,7 @@ namespace Grpc.Testing { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(ClientConfig other) { if (other == null) { return; @@ -1014,6 +1098,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -1092,29 +1177,34 @@ namespace Grpc.Testing { } - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class ClientStatus : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ClientStatus()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[5]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ClientStatus() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ClientStatus(ClientStatus other) : this() { Stats = other.stats_ != null ? other.Stats.Clone() : null; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ClientStatus Clone() { return new ClientStatus(this); } @@ -1122,6 +1212,7 @@ namespace Grpc.Testing { /// Field number for the "stats" field. public const int StatsFieldNumber = 1; private global::Grpc.Testing.ClientStats stats_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.ClientStats Stats { get { return stats_; } set { @@ -1129,10 +1220,12 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as ClientStatus); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(ClientStatus other) { if (ReferenceEquals(other, null)) { return false; @@ -1144,16 +1237,19 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (stats_ != null) hash ^= Stats.GetHashCode(); return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (stats_ != null) { output.WriteRawTag(10); @@ -1161,6 +1257,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (stats_ != null) { @@ -1169,6 +1266,7 @@ namespace Grpc.Testing { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(ClientStatus other) { if (other == null) { return; @@ -1181,6 +1279,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -1204,29 +1303,34 @@ namespace Grpc.Testing { /// /// Request current stats /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class Mark : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Mark()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[6]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public Mark() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public Mark(Mark other) : this() { reset_ = other.reset_; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public Mark Clone() { return new Mark(this); } @@ -1237,6 +1341,7 @@ namespace Grpc.Testing { /// /// if true, the stats will be reset after taking their snapshot. /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Reset { get { return reset_; } set { @@ -1244,10 +1349,12 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as Mark); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(Mark other) { if (ReferenceEquals(other, null)) { return false; @@ -1259,16 +1366,19 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (Reset != false) hash ^= Reset.GetHashCode(); return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (Reset != false) { output.WriteRawTag(8); @@ -1276,6 +1386,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (Reset != false) { @@ -1284,6 +1395,7 @@ namespace Grpc.Testing { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(Mark other) { if (other == null) { return; @@ -1293,6 +1405,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -1310,25 +1423,29 @@ namespace Grpc.Testing { } - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class ClientArgs : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ClientArgs()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[7]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ClientArgs() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ClientArgs(ClientArgs other) : this() { switch (other.ArgtypeCase) { case ArgtypeOneofCase.Setup: @@ -1341,12 +1458,14 @@ namespace Grpc.Testing { } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ClientArgs Clone() { return new ClientArgs(this); } /// Field number for the "setup" field. public const int SetupFieldNumber = 1; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.ClientConfig Setup { get { return argtypeCase_ == ArgtypeOneofCase.Setup ? (global::Grpc.Testing.ClientConfig) argtype_ : null; } set { @@ -1357,6 +1476,7 @@ namespace Grpc.Testing { /// Field number for the "mark" field. public const int MarkFieldNumber = 2; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.Mark Mark { get { return argtypeCase_ == ArgtypeOneofCase.Mark ? (global::Grpc.Testing.Mark) argtype_ : null; } set { @@ -1373,19 +1493,23 @@ namespace Grpc.Testing { Mark = 2, } private ArgtypeOneofCase argtypeCase_ = ArgtypeOneofCase.None; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ArgtypeOneofCase ArgtypeCase { get { return argtypeCase_; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void ClearArgtype() { argtypeCase_ = ArgtypeOneofCase.None; argtype_ = null; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as ClientArgs); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(ClientArgs other) { if (ReferenceEquals(other, null)) { return false; @@ -1399,6 +1523,7 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (argtypeCase_ == ArgtypeOneofCase.Setup) hash ^= Setup.GetHashCode(); @@ -1407,10 +1532,12 @@ namespace Grpc.Testing { return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (argtypeCase_ == ArgtypeOneofCase.Setup) { output.WriteRawTag(10); @@ -1422,6 +1549,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (argtypeCase_ == ArgtypeOneofCase.Setup) { @@ -1433,6 +1561,7 @@ namespace Grpc.Testing { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(ClientArgs other) { if (other == null) { return; @@ -1448,6 +1577,7 @@ namespace Grpc.Testing { } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -1479,25 +1609,29 @@ namespace Grpc.Testing { } - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class ServerConfig : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ServerConfig()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[8]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ServerConfig() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ServerConfig(ServerConfig other) : this() { serverType_ = other.serverType_; SecurityParams = other.securityParams_ != null ? other.SecurityParams.Clone() : null; @@ -1509,6 +1643,7 @@ namespace Grpc.Testing { otherServerApi_ = other.otherServerApi_; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ServerConfig Clone() { return new ServerConfig(this); } @@ -1516,6 +1651,7 @@ namespace Grpc.Testing { /// Field number for the "server_type" field. public const int ServerTypeFieldNumber = 1; private global::Grpc.Testing.ServerType serverType_ = 0; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.ServerType ServerType { get { return serverType_; } set { @@ -1526,6 +1662,7 @@ namespace Grpc.Testing { /// Field number for the "security_params" field. public const int SecurityParamsFieldNumber = 2; private global::Grpc.Testing.SecurityParams securityParams_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.SecurityParams SecurityParams { get { return securityParams_; } set { @@ -1539,6 +1676,7 @@ namespace Grpc.Testing { /// /// Port on which to listen. Zero means pick unused port. /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int Port { get { return port_; } set { @@ -1552,6 +1690,7 @@ namespace Grpc.Testing { /// /// Only for async server. Number of threads used to serve the requests. /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int AsyncServerThreads { get { return asyncServerThreads_; } set { @@ -1565,6 +1704,7 @@ namespace Grpc.Testing { /// /// Specify the number of cores to limit server to, if desired /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CoreLimit { get { return coreLimit_; } set { @@ -1578,6 +1718,7 @@ namespace Grpc.Testing { /// /// payload config, used in generic server /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.PayloadConfig PayloadConfig { get { return payloadConfig_; } set { @@ -1593,6 +1734,7 @@ namespace Grpc.Testing { /// /// Specify the cores we should run the server on, if desired /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::RepeatedField CoreList { get { return coreList_; } } @@ -1603,6 +1745,7 @@ namespace Grpc.Testing { /// /// If we use an OTHER_SERVER client_type, this string gives more detail /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public string OtherServerApi { get { return otherServerApi_; } set { @@ -1610,10 +1753,12 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as ServerConfig); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(ServerConfig other) { if (ReferenceEquals(other, null)) { return false; @@ -1632,6 +1777,7 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (ServerType != 0) hash ^= ServerType.GetHashCode(); @@ -1645,10 +1791,12 @@ namespace Grpc.Testing { return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (ServerType != 0) { output.WriteRawTag(8); @@ -1681,6 +1829,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (ServerType != 0) { @@ -1708,6 +1857,7 @@ namespace Grpc.Testing { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(ServerConfig other) { if (other == null) { return; @@ -1742,6 +1892,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -1794,25 +1945,29 @@ namespace Grpc.Testing { } - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class ServerArgs : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ServerArgs()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[9]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ServerArgs() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ServerArgs(ServerArgs other) : this() { switch (other.ArgtypeCase) { case ArgtypeOneofCase.Setup: @@ -1825,12 +1980,14 @@ namespace Grpc.Testing { } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ServerArgs Clone() { return new ServerArgs(this); } /// Field number for the "setup" field. public const int SetupFieldNumber = 1; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.ServerConfig Setup { get { return argtypeCase_ == ArgtypeOneofCase.Setup ? (global::Grpc.Testing.ServerConfig) argtype_ : null; } set { @@ -1841,6 +1998,7 @@ namespace Grpc.Testing { /// Field number for the "mark" field. public const int MarkFieldNumber = 2; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.Mark Mark { get { return argtypeCase_ == ArgtypeOneofCase.Mark ? (global::Grpc.Testing.Mark) argtype_ : null; } set { @@ -1857,19 +2015,23 @@ namespace Grpc.Testing { Mark = 2, } private ArgtypeOneofCase argtypeCase_ = ArgtypeOneofCase.None; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ArgtypeOneofCase ArgtypeCase { get { return argtypeCase_; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void ClearArgtype() { argtypeCase_ = ArgtypeOneofCase.None; argtype_ = null; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as ServerArgs); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(ServerArgs other) { if (ReferenceEquals(other, null)) { return false; @@ -1883,6 +2045,7 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (argtypeCase_ == ArgtypeOneofCase.Setup) hash ^= Setup.GetHashCode(); @@ -1891,10 +2054,12 @@ namespace Grpc.Testing { return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (argtypeCase_ == ArgtypeOneofCase.Setup) { output.WriteRawTag(10); @@ -1906,6 +2071,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (argtypeCase_ == ArgtypeOneofCase.Setup) { @@ -1917,6 +2083,7 @@ namespace Grpc.Testing { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(ServerArgs other) { if (other == null) { return; @@ -1932,6 +2099,7 @@ namespace Grpc.Testing { } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -1963,31 +2131,36 @@ namespace Grpc.Testing { } - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class ServerStatus : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ServerStatus()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[10]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ServerStatus() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ServerStatus(ServerStatus other) : this() { Stats = other.stats_ != null ? other.Stats.Clone() : null; port_ = other.port_; cores_ = other.cores_; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ServerStatus Clone() { return new ServerStatus(this); } @@ -1995,6 +2168,7 @@ namespace Grpc.Testing { /// Field number for the "stats" field. public const int StatsFieldNumber = 1; private global::Grpc.Testing.ServerStats stats_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.ServerStats Stats { get { return stats_; } set { @@ -2008,6 +2182,7 @@ namespace Grpc.Testing { /// /// the port bound by the server /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int Port { get { return port_; } set { @@ -2021,6 +2196,7 @@ namespace Grpc.Testing { /// /// Number of cores available to the server /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int Cores { get { return cores_; } set { @@ -2028,10 +2204,12 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as ServerStatus); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(ServerStatus other) { if (ReferenceEquals(other, null)) { return false; @@ -2045,6 +2223,7 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (stats_ != null) hash ^= Stats.GetHashCode(); @@ -2053,10 +2232,12 @@ namespace Grpc.Testing { return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (stats_ != null) { output.WriteRawTag(10); @@ -2072,6 +2253,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (stats_ != null) { @@ -2086,6 +2268,7 @@ namespace Grpc.Testing { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(ServerStatus other) { if (other == null) { return; @@ -2104,6 +2287,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -2132,36 +2316,43 @@ namespace Grpc.Testing { } - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class CoreRequest : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new CoreRequest()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[11]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public CoreRequest() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public CoreRequest(CoreRequest other) : this() { } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public CoreRequest Clone() { return new CoreRequest(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as CoreRequest); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(CoreRequest other) { if (ReferenceEquals(other, null)) { return false; @@ -2172,29 +2363,35 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(CoreRequest other) { if (other == null) { return; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -2208,29 +2405,34 @@ namespace Grpc.Testing { } - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class CoreResponse : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new CoreResponse()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[12]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public CoreResponse() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public CoreResponse(CoreResponse other) : this() { cores_ = other.cores_; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public CoreResponse Clone() { return new CoreResponse(this); } @@ -2241,6 +2443,7 @@ namespace Grpc.Testing { /// /// Number of cores available on the server /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int Cores { get { return cores_; } set { @@ -2248,10 +2451,12 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as CoreResponse); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(CoreResponse other) { if (ReferenceEquals(other, null)) { return false; @@ -2263,16 +2468,19 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (Cores != 0) hash ^= Cores.GetHashCode(); return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (Cores != 0) { output.WriteRawTag(8); @@ -2280,6 +2488,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (Cores != 0) { @@ -2288,6 +2497,7 @@ namespace Grpc.Testing { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(CoreResponse other) { if (other == null) { return; @@ -2297,6 +2507,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -2314,36 +2525,43 @@ namespace Grpc.Testing { } - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class Void : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Void()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[13]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public Void() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public Void(Void other) : this() { } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public Void Clone() { return new Void(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as Void); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(Void other) { if (ReferenceEquals(other, null)) { return false; @@ -2354,29 +2572,35 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(Void other) { if (other == null) { return; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -2393,25 +2617,29 @@ namespace Grpc.Testing { /// /// A single performance scenario: input to qps_json_driver /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class Scenario : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Scenario()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[14]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public Scenario() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public Scenario(Scenario other) : this() { name_ = other.name_; ClientConfig = other.clientConfig_ != null ? other.ClientConfig.Clone() : null; @@ -2423,6 +2651,7 @@ namespace Grpc.Testing { spawnLocalWorkerCount_ = other.spawnLocalWorkerCount_; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public Scenario Clone() { return new Scenario(this); } @@ -2433,6 +2662,7 @@ namespace Grpc.Testing { /// /// Human readable name for this scenario /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public string Name { get { return name_; } set { @@ -2446,6 +2676,7 @@ namespace Grpc.Testing { /// /// Client configuration /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.ClientConfig ClientConfig { get { return clientConfig_; } set { @@ -2459,6 +2690,7 @@ namespace Grpc.Testing { /// /// Number of clients to start for the test /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int NumClients { get { return numClients_; } set { @@ -2472,6 +2704,7 @@ namespace Grpc.Testing { /// /// Server configuration /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.ServerConfig ServerConfig { get { return serverConfig_; } set { @@ -2485,6 +2718,7 @@ namespace Grpc.Testing { /// /// Number of servers to start for the test /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int NumServers { get { return numServers_; } set { @@ -2498,6 +2732,7 @@ namespace Grpc.Testing { /// /// Warmup period, in seconds /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int WarmupSeconds { get { return warmupSeconds_; } set { @@ -2511,6 +2746,7 @@ namespace Grpc.Testing { /// /// Benchmark time, in seconds /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int BenchmarkSeconds { get { return benchmarkSeconds_; } set { @@ -2524,6 +2760,7 @@ namespace Grpc.Testing { /// /// Number of workers to spawn locally (usually zero) /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int SpawnLocalWorkerCount { get { return spawnLocalWorkerCount_; } set { @@ -2531,10 +2768,12 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as Scenario); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(Scenario other) { if (ReferenceEquals(other, null)) { return false; @@ -2553,6 +2792,7 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (Name.Length != 0) hash ^= Name.GetHashCode(); @@ -2566,10 +2806,12 @@ namespace Grpc.Testing { return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (Name.Length != 0) { output.WriteRawTag(10); @@ -2605,6 +2847,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (Name.Length != 0) { @@ -2634,6 +2877,7 @@ namespace Grpc.Testing { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(Scenario other) { if (other == null) { return; @@ -2670,6 +2914,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -2724,29 +2969,34 @@ namespace Grpc.Testing { /// /// A set of scenarios to be run with qps_json_driver /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class Scenarios : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Scenarios()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[15]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public Scenarios() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public Scenarios(Scenarios other) : this() { scenarios_ = other.scenarios_.Clone(); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public Scenarios Clone() { return new Scenarios(this); } @@ -2756,14 +3006,17 @@ namespace Grpc.Testing { private static readonly pb::FieldCodec _repeated_scenarios_codec = pb::FieldCodec.ForMessage(10, global::Grpc.Testing.Scenario.Parser); private readonly pbc::RepeatedField scenarios_ = new pbc::RepeatedField(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::RepeatedField Scenarios_ { get { return scenarios_; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as Scenarios); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(Scenarios other) { if (ReferenceEquals(other, null)) { return false; @@ -2775,26 +3028,31 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; hash ^= scenarios_.GetHashCode(); return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { scenarios_.WriteTo(output, _repeated_scenarios_codec); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; size += scenarios_.CalculateSize(_repeated_scenarios_codec); return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(Scenarios other) { if (other == null) { return; @@ -2802,6 +3060,7 @@ namespace Grpc.Testing { scenarios_.Add(other.scenarios_); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -2823,25 +3082,29 @@ namespace Grpc.Testing { /// Basic summary that can be computed from ClientStats and ServerStats /// once the scenario has finished. /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class ScenarioResultSummary : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ScenarioResultSummary()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[16]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ScenarioResultSummary() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ScenarioResultSummary(ScenarioResultSummary other) : this() { qps_ = other.qps_; qpsPerServerCore_ = other.qpsPerServerCore_; @@ -2856,6 +3119,7 @@ namespace Grpc.Testing { latency999_ = other.latency999_; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ScenarioResultSummary Clone() { return new ScenarioResultSummary(this); } @@ -2866,6 +3130,7 @@ namespace Grpc.Testing { /// /// Total number of operations per second over all clients. /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double Qps { get { return qps_; } set { @@ -2879,6 +3144,7 @@ namespace Grpc.Testing { /// /// QPS per one server core. /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double QpsPerServerCore { get { return qpsPerServerCore_; } set { @@ -2892,6 +3158,7 @@ namespace Grpc.Testing { /// /// server load based on system_time (0.85 => 85%) /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double ServerSystemTime { get { return serverSystemTime_; } set { @@ -2905,6 +3172,7 @@ namespace Grpc.Testing { /// /// server load based on user_time (0.85 => 85%) /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double ServerUserTime { get { return serverUserTime_; } set { @@ -2918,6 +3186,7 @@ namespace Grpc.Testing { /// /// client load based on system_time (0.85 => 85%) /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double ClientSystemTime { get { return clientSystemTime_; } set { @@ -2931,6 +3200,7 @@ namespace Grpc.Testing { /// /// client load based on user_time (0.85 => 85%) /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double ClientUserTime { get { return clientUserTime_; } set { @@ -2944,6 +3214,7 @@ namespace Grpc.Testing { /// /// X% latency percentiles (in nanoseconds) /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double Latency50 { get { return latency50_; } set { @@ -2954,6 +3225,7 @@ namespace Grpc.Testing { /// Field number for the "latency_90" field. public const int Latency90FieldNumber = 8; private double latency90_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double Latency90 { get { return latency90_; } set { @@ -2964,6 +3236,7 @@ namespace Grpc.Testing { /// Field number for the "latency_95" field. public const int Latency95FieldNumber = 9; private double latency95_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double Latency95 { get { return latency95_; } set { @@ -2974,6 +3247,7 @@ namespace Grpc.Testing { /// Field number for the "latency_99" field. public const int Latency99FieldNumber = 10; private double latency99_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double Latency99 { get { return latency99_; } set { @@ -2984,6 +3258,7 @@ namespace Grpc.Testing { /// Field number for the "latency_999" field. public const int Latency999FieldNumber = 11; private double latency999_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double Latency999 { get { return latency999_; } set { @@ -2991,10 +3266,12 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as ScenarioResultSummary); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(ScenarioResultSummary other) { if (ReferenceEquals(other, null)) { return false; @@ -3016,6 +3293,7 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (Qps != 0D) hash ^= Qps.GetHashCode(); @@ -3032,10 +3310,12 @@ namespace Grpc.Testing { return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (Qps != 0D) { output.WriteRawTag(9); @@ -3083,6 +3363,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (Qps != 0D) { @@ -3121,6 +3402,7 @@ namespace Grpc.Testing { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(ScenarioResultSummary other) { if (other == null) { return; @@ -3160,6 +3442,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -3220,25 +3503,29 @@ namespace Grpc.Testing { /// /// Results of a single benchmark scenario. /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class ScenarioResult : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ScenarioResult()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[17]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ScenarioResult() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ScenarioResult(ScenarioResult other) : this() { Scenario = other.scenario_ != null ? other.Scenario.Clone() : null; Latencies = other.latencies_ != null ? other.Latencies.Clone() : null; @@ -3246,8 +3533,11 @@ namespace Grpc.Testing { serverStats_ = other.serverStats_.Clone(); serverCores_ = other.serverCores_.Clone(); Summary = other.summary_ != null ? other.Summary.Clone() : null; + clientSuccess_ = other.clientSuccess_.Clone(); + serverSuccess_ = other.serverSuccess_.Clone(); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ScenarioResult Clone() { return new ScenarioResult(this); } @@ -3258,6 +3548,7 @@ namespace Grpc.Testing { /// /// Inputs used to run the scenario. /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.Scenario Scenario { get { return scenario_; } set { @@ -3271,6 +3562,7 @@ namespace Grpc.Testing { /// /// Histograms from all clients merged into one histogram. /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.HistogramData Latencies { get { return latencies_; } set { @@ -3286,6 +3578,7 @@ namespace Grpc.Testing { /// /// Client stats for each client /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::RepeatedField ClientStats { get { return clientStats_; } } @@ -3298,6 +3591,7 @@ namespace Grpc.Testing { /// /// Server stats for each server /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::RepeatedField ServerStats { get { return serverStats_; } } @@ -3310,6 +3604,7 @@ namespace Grpc.Testing { /// /// Number of cores available to each server /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::RepeatedField ServerCores { get { return serverCores_; } } @@ -3320,6 +3615,7 @@ namespace Grpc.Testing { /// /// An after-the-fact computed summary /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.ScenarioResultSummary Summary { get { return summary_; } set { @@ -3327,10 +3623,35 @@ namespace Grpc.Testing { } } + /// Field number for the "client_success" field. + public const int ClientSuccessFieldNumber = 7; + private static readonly pb::FieldCodec _repeated_clientSuccess_codec + = pb::FieldCodec.ForBool(58); + private readonly pbc::RepeatedField clientSuccess_ = new pbc::RepeatedField(); + /// + /// Information on success or failure of each worker + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public pbc::RepeatedField ClientSuccess { + get { return clientSuccess_; } + } + + /// Field number for the "server_success" field. + public const int ServerSuccessFieldNumber = 8; + private static readonly pb::FieldCodec _repeated_serverSuccess_codec + = pb::FieldCodec.ForBool(66); + private readonly pbc::RepeatedField serverSuccess_ = new pbc::RepeatedField(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public pbc::RepeatedField ServerSuccess { + get { return serverSuccess_; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as ScenarioResult); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(ScenarioResult other) { if (ReferenceEquals(other, null)) { return false; @@ -3344,9 +3665,12 @@ namespace Grpc.Testing { if(!serverStats_.Equals(other.serverStats_)) return false; if(!serverCores_.Equals(other.serverCores_)) return false; if (!object.Equals(Summary, other.Summary)) return false; + if(!clientSuccess_.Equals(other.clientSuccess_)) return false; + if(!serverSuccess_.Equals(other.serverSuccess_)) return false; return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (scenario_ != null) hash ^= Scenario.GetHashCode(); @@ -3355,13 +3679,17 @@ namespace Grpc.Testing { hash ^= serverStats_.GetHashCode(); hash ^= serverCores_.GetHashCode(); if (summary_ != null) hash ^= Summary.GetHashCode(); + hash ^= clientSuccess_.GetHashCode(); + hash ^= serverSuccess_.GetHashCode(); return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (scenario_ != null) { output.WriteRawTag(10); @@ -3378,8 +3706,11 @@ namespace Grpc.Testing { output.WriteRawTag(50); output.WriteMessage(Summary); } + clientSuccess_.WriteTo(output, _repeated_clientSuccess_codec); + serverSuccess_.WriteTo(output, _repeated_serverSuccess_codec); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (scenario_ != null) { @@ -3394,9 +3725,12 @@ namespace Grpc.Testing { if (summary_ != null) { size += 1 + pb::CodedOutputStream.ComputeMessageSize(Summary); } + size += clientSuccess_.CalculateSize(_repeated_clientSuccess_codec); + size += serverSuccess_.CalculateSize(_repeated_serverSuccess_codec); return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(ScenarioResult other) { if (other == null) { return; @@ -3422,8 +3756,11 @@ namespace Grpc.Testing { } Summary.MergeFrom(other.Summary); } + clientSuccess_.Add(other.clientSuccess_); + serverSuccess_.Add(other.serverSuccess_); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -3465,6 +3802,16 @@ namespace Grpc.Testing { input.ReadMessage(summary_); break; } + case 58: + case 56: { + clientSuccess_.AddEntriesFrom(input, _repeated_clientSuccess_codec); + break; + } + case 66: + case 64: { + serverSuccess_.AddEntriesFrom(input, _repeated_serverSuccess_codec); + break; + } } } } diff --git a/src/csharp/Grpc.IntegrationTesting/Empty.cs b/src/csharp/Grpc.IntegrationTesting/Empty.cs index cf1c23fb0f..3017e664b9 100644 --- a/src/csharp/Grpc.IntegrationTesting/Empty.cs +++ b/src/csharp/Grpc.IntegrationTesting/Empty.cs @@ -10,7 +10,6 @@ using scg = global::System.Collections.Generic; namespace Grpc.Testing { /// Holder for reflection information generated from src/proto/grpc/testing/empty.proto - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public static partial class EmptyReflection { #region Descriptor @@ -44,36 +43,43 @@ namespace Grpc.Testing { /// rpc Bar (grpc.testing.Empty) returns (grpc.testing.Empty) { }; /// }; /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class Empty : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Empty()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.EmptyReflection.Descriptor.MessageTypes[0]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public Empty() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public Empty(Empty other) : this() { } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public Empty Clone() { return new Empty(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as Empty); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(Empty other) { if (ReferenceEquals(other, null)) { return false; @@ -84,29 +90,35 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(Empty other) { if (other == null) { return; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { diff --git a/src/csharp/Grpc.IntegrationTesting/Messages.cs b/src/csharp/Grpc.IntegrationTesting/Messages.cs index 1240db128b..369fe738d6 100644 --- a/src/csharp/Grpc.IntegrationTesting/Messages.cs +++ b/src/csharp/Grpc.IntegrationTesting/Messages.cs @@ -10,7 +10,6 @@ using scg = global::System.Collections.Generic; namespace Grpc.Testing { /// Holder for reflection information generated from src/proto/grpc/testing/messages.proto - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public static partial class MessagesReflection { #region Descriptor @@ -94,29 +93,34 @@ namespace Grpc.Testing { /// https://github.com/grpc/grpc/issues/6980 has been fixed. /// import "google/protobuf/wrappers.proto"; /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class BoolValue : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new BoolValue()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.MessagesReflection.Descriptor.MessageTypes[0]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public BoolValue() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public BoolValue(BoolValue other) : this() { value_ = other.value_; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public BoolValue Clone() { return new BoolValue(this); } @@ -127,6 +131,7 @@ namespace Grpc.Testing { /// /// The bool value. /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Value { get { return value_; } set { @@ -134,10 +139,12 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as BoolValue); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(BoolValue other) { if (ReferenceEquals(other, null)) { return false; @@ -149,16 +156,19 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (Value != false) hash ^= Value.GetHashCode(); return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (Value != false) { output.WriteRawTag(8); @@ -166,6 +176,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (Value != false) { @@ -174,6 +185,7 @@ namespace Grpc.Testing { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(BoolValue other) { if (other == null) { return; @@ -183,6 +195,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -203,30 +216,35 @@ namespace Grpc.Testing { /// /// A block of data, to simply increase gRPC message size. /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class Payload : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Payload()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.MessagesReflection.Descriptor.MessageTypes[1]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public Payload() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public Payload(Payload other) : this() { type_ = other.type_; body_ = other.body_; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public Payload Clone() { return new Payload(this); } @@ -238,6 +256,7 @@ namespace Grpc.Testing { /// DEPRECATED, don't use. To be removed shortly. /// The type of data in body. /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.PayloadType Type { get { return type_; } set { @@ -251,6 +270,7 @@ namespace Grpc.Testing { /// /// Primary contents of payload. /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pb::ByteString Body { get { return body_; } set { @@ -258,10 +278,12 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as Payload); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(Payload other) { if (ReferenceEquals(other, null)) { return false; @@ -274,6 +296,7 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (Type != 0) hash ^= Type.GetHashCode(); @@ -281,10 +304,12 @@ namespace Grpc.Testing { return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (Type != 0) { output.WriteRawTag(8); @@ -296,6 +321,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (Type != 0) { @@ -307,6 +333,7 @@ namespace Grpc.Testing { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(Payload other) { if (other == null) { return; @@ -319,6 +346,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -344,30 +372,35 @@ namespace Grpc.Testing { /// A protobuf representation for grpc status. This is used by test /// clients to specify a status that the server should attempt to return. /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class EchoStatus : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new EchoStatus()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.MessagesReflection.Descriptor.MessageTypes[2]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public EchoStatus() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public EchoStatus(EchoStatus other) : this() { code_ = other.code_; message_ = other.message_; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public EchoStatus Clone() { return new EchoStatus(this); } @@ -375,6 +408,7 @@ namespace Grpc.Testing { /// Field number for the "code" field. public const int CodeFieldNumber = 1; private int code_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int Code { get { return code_; } set { @@ -385,6 +419,7 @@ namespace Grpc.Testing { /// Field number for the "message" field. public const int MessageFieldNumber = 2; private string message_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public string Message { get { return message_; } set { @@ -392,10 +427,12 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as EchoStatus); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(EchoStatus other) { if (ReferenceEquals(other, null)) { return false; @@ -408,6 +445,7 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (Code != 0) hash ^= Code.GetHashCode(); @@ -415,10 +453,12 @@ namespace Grpc.Testing { return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (Code != 0) { output.WriteRawTag(8); @@ -430,6 +470,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (Code != 0) { @@ -441,6 +482,7 @@ namespace Grpc.Testing { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(EchoStatus other) { if (other == null) { return; @@ -453,6 +495,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -477,25 +520,29 @@ namespace Grpc.Testing { /// /// Unary request. /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class SimpleRequest : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new SimpleRequest()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.MessagesReflection.Descriptor.MessageTypes[3]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public SimpleRequest() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public SimpleRequest(SimpleRequest other) : this() { responseType_ = other.responseType_; responseSize_ = other.responseSize_; @@ -507,6 +554,7 @@ namespace Grpc.Testing { ExpectCompressed = other.expectCompressed_ != null ? other.ExpectCompressed.Clone() : null; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public SimpleRequest Clone() { return new SimpleRequest(this); } @@ -519,6 +567,7 @@ namespace Grpc.Testing { /// Desired payload type in the response from the server. /// If response_type is RANDOM, server randomly chooses one from other formats. /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.PayloadType ResponseType { get { return responseType_; } set { @@ -532,6 +581,7 @@ namespace Grpc.Testing { /// /// Desired payload size in the response from the server. /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int ResponseSize { get { return responseSize_; } set { @@ -545,6 +595,7 @@ namespace Grpc.Testing { /// /// Optional input payload sent along with the request. /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.Payload Payload { get { return payload_; } set { @@ -558,6 +609,7 @@ namespace Grpc.Testing { /// /// Whether SimpleResponse should include username. /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool FillUsername { get { return fillUsername_; } set { @@ -571,6 +623,7 @@ namespace Grpc.Testing { /// /// Whether SimpleResponse should include OAuth scope. /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool FillOauthScope { get { return fillOauthScope_; } set { @@ -587,6 +640,7 @@ namespace Grpc.Testing { /// implement the full compression tests by introspecting the call to verify /// the response's compression status. /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.BoolValue ResponseCompressed { get { return responseCompressed_; } set { @@ -600,6 +654,7 @@ namespace Grpc.Testing { /// /// Whether server should return a given status /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.EchoStatus ResponseStatus { get { return responseStatus_; } set { @@ -613,6 +668,7 @@ namespace Grpc.Testing { /// /// Whether the server should expect this request to be compressed. /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.BoolValue ExpectCompressed { get { return expectCompressed_; } set { @@ -620,10 +676,12 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as SimpleRequest); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(SimpleRequest other) { if (ReferenceEquals(other, null)) { return false; @@ -642,6 +700,7 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (ResponseType != 0) hash ^= ResponseType.GetHashCode(); @@ -655,10 +714,12 @@ namespace Grpc.Testing { return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (ResponseType != 0) { output.WriteRawTag(8); @@ -694,6 +755,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (ResponseType != 0) { @@ -723,6 +785,7 @@ namespace Grpc.Testing { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(SimpleRequest other) { if (other == null) { return; @@ -765,6 +828,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -825,31 +889,36 @@ namespace Grpc.Testing { /// /// Unary response, as configured by the request. /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class SimpleResponse : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new SimpleResponse()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.MessagesReflection.Descriptor.MessageTypes[4]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public SimpleResponse() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public SimpleResponse(SimpleResponse other) : this() { Payload = other.payload_ != null ? other.Payload.Clone() : null; username_ = other.username_; oauthScope_ = other.oauthScope_; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public SimpleResponse Clone() { return new SimpleResponse(this); } @@ -860,6 +929,7 @@ namespace Grpc.Testing { /// /// Payload to increase message size. /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.Payload Payload { get { return payload_; } set { @@ -874,6 +944,7 @@ namespace Grpc.Testing { /// The user the request came from, for verifying authentication was /// successful when the client expected it. /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public string Username { get { return username_; } set { @@ -887,6 +958,7 @@ namespace Grpc.Testing { /// /// OAuth scope. /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public string OauthScope { get { return oauthScope_; } set { @@ -894,10 +966,12 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as SimpleResponse); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(SimpleResponse other) { if (ReferenceEquals(other, null)) { return false; @@ -911,6 +985,7 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (payload_ != null) hash ^= Payload.GetHashCode(); @@ -919,10 +994,12 @@ namespace Grpc.Testing { return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (payload_ != null) { output.WriteRawTag(10); @@ -938,6 +1015,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (payload_ != null) { @@ -952,6 +1030,7 @@ namespace Grpc.Testing { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(SimpleResponse other) { if (other == null) { return; @@ -970,6 +1049,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -1001,30 +1081,35 @@ namespace Grpc.Testing { /// /// Client-streaming request. /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class StreamingInputCallRequest : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new StreamingInputCallRequest()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.MessagesReflection.Descriptor.MessageTypes[5]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public StreamingInputCallRequest() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public StreamingInputCallRequest(StreamingInputCallRequest other) : this() { Payload = other.payload_ != null ? other.Payload.Clone() : null; ExpectCompressed = other.expectCompressed_ != null ? other.ExpectCompressed.Clone() : null; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public StreamingInputCallRequest Clone() { return new StreamingInputCallRequest(this); } @@ -1035,6 +1120,7 @@ namespace Grpc.Testing { /// /// Optional input payload sent along with the request. /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.Payload Payload { get { return payload_; } set { @@ -1051,6 +1137,7 @@ namespace Grpc.Testing { /// implement the full compression tests by introspecting the call to verify /// the request's compression status. /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.BoolValue ExpectCompressed { get { return expectCompressed_; } set { @@ -1058,10 +1145,12 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as StreamingInputCallRequest); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(StreamingInputCallRequest other) { if (ReferenceEquals(other, null)) { return false; @@ -1074,6 +1163,7 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (payload_ != null) hash ^= Payload.GetHashCode(); @@ -1081,10 +1171,12 @@ namespace Grpc.Testing { return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (payload_ != null) { output.WriteRawTag(10); @@ -1096,6 +1188,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (payload_ != null) { @@ -1107,6 +1200,7 @@ namespace Grpc.Testing { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(StreamingInputCallRequest other) { if (other == null) { return; @@ -1125,6 +1219,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -1155,29 +1250,34 @@ namespace Grpc.Testing { /// /// Client-streaming response. /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class StreamingInputCallResponse : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new StreamingInputCallResponse()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.MessagesReflection.Descriptor.MessageTypes[6]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public StreamingInputCallResponse() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public StreamingInputCallResponse(StreamingInputCallResponse other) : this() { aggregatedPayloadSize_ = other.aggregatedPayloadSize_; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public StreamingInputCallResponse Clone() { return new StreamingInputCallResponse(this); } @@ -1188,6 +1288,7 @@ namespace Grpc.Testing { /// /// Aggregated size of payloads received from the client. /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int AggregatedPayloadSize { get { return aggregatedPayloadSize_; } set { @@ -1195,10 +1296,12 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as StreamingInputCallResponse); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(StreamingInputCallResponse other) { if (ReferenceEquals(other, null)) { return false; @@ -1210,16 +1313,19 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (AggregatedPayloadSize != 0) hash ^= AggregatedPayloadSize.GetHashCode(); return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (AggregatedPayloadSize != 0) { output.WriteRawTag(8); @@ -1227,6 +1333,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (AggregatedPayloadSize != 0) { @@ -1235,6 +1342,7 @@ namespace Grpc.Testing { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(StreamingInputCallResponse other) { if (other == null) { return; @@ -1244,6 +1352,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -1264,31 +1373,36 @@ namespace Grpc.Testing { /// /// Configuration for a particular response. /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class ResponseParameters : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ResponseParameters()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.MessagesReflection.Descriptor.MessageTypes[7]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ResponseParameters() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ResponseParameters(ResponseParameters other) : this() { size_ = other.size_; intervalUs_ = other.intervalUs_; Compressed = other.compressed_ != null ? other.Compressed.Clone() : null; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ResponseParameters Clone() { return new ResponseParameters(this); } @@ -1299,6 +1413,7 @@ namespace Grpc.Testing { /// /// Desired payload sizes in responses from the server. /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int Size { get { return size_; } set { @@ -1313,6 +1428,7 @@ namespace Grpc.Testing { /// Desired interval between consecutive responses in the response stream in /// microseconds. /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int IntervalUs { get { return intervalUs_; } set { @@ -1329,6 +1445,7 @@ namespace Grpc.Testing { /// implement the full compression tests by introspecting the call to verify /// the response's compression status. /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.BoolValue Compressed { get { return compressed_; } set { @@ -1336,10 +1453,12 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as ResponseParameters); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(ResponseParameters other) { if (ReferenceEquals(other, null)) { return false; @@ -1353,6 +1472,7 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (Size != 0) hash ^= Size.GetHashCode(); @@ -1361,10 +1481,12 @@ namespace Grpc.Testing { return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (Size != 0) { output.WriteRawTag(8); @@ -1380,6 +1502,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (Size != 0) { @@ -1394,6 +1517,7 @@ namespace Grpc.Testing { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(ResponseParameters other) { if (other == null) { return; @@ -1412,6 +1536,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -1443,25 +1568,29 @@ namespace Grpc.Testing { /// /// Server-streaming request. /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class StreamingOutputCallRequest : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new StreamingOutputCallRequest()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.MessagesReflection.Descriptor.MessageTypes[8]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public StreamingOutputCallRequest() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public StreamingOutputCallRequest(StreamingOutputCallRequest other) : this() { responseType_ = other.responseType_; responseParameters_ = other.responseParameters_.Clone(); @@ -1469,6 +1598,7 @@ namespace Grpc.Testing { ResponseStatus = other.responseStatus_ != null ? other.ResponseStatus.Clone() : null; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public StreamingOutputCallRequest Clone() { return new StreamingOutputCallRequest(this); } @@ -1483,6 +1613,7 @@ namespace Grpc.Testing { /// might be of different types. This is to simulate a mixed type of payload /// stream. /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.PayloadType ResponseType { get { return responseType_; } set { @@ -1498,6 +1629,7 @@ namespace Grpc.Testing { /// /// Configuration for each expected response message. /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::RepeatedField ResponseParameters { get { return responseParameters_; } } @@ -1508,6 +1640,7 @@ namespace Grpc.Testing { /// /// Optional input payload sent along with the request. /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.Payload Payload { get { return payload_; } set { @@ -1521,6 +1654,7 @@ namespace Grpc.Testing { /// /// Whether server should return a given status /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.EchoStatus ResponseStatus { get { return responseStatus_; } set { @@ -1528,10 +1662,12 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as StreamingOutputCallRequest); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(StreamingOutputCallRequest other) { if (ReferenceEquals(other, null)) { return false; @@ -1546,6 +1682,7 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (ResponseType != 0) hash ^= ResponseType.GetHashCode(); @@ -1555,10 +1692,12 @@ namespace Grpc.Testing { return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (ResponseType != 0) { output.WriteRawTag(8); @@ -1575,6 +1714,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (ResponseType != 0) { @@ -1590,6 +1730,7 @@ namespace Grpc.Testing { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(StreamingOutputCallRequest other) { if (other == null) { return; @@ -1612,6 +1753,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -1650,29 +1792,34 @@ namespace Grpc.Testing { /// /// Server-streaming response, as configured by the request and parameters. /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class StreamingOutputCallResponse : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new StreamingOutputCallResponse()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.MessagesReflection.Descriptor.MessageTypes[9]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public StreamingOutputCallResponse() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public StreamingOutputCallResponse(StreamingOutputCallResponse other) : this() { Payload = other.payload_ != null ? other.Payload.Clone() : null; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public StreamingOutputCallResponse Clone() { return new StreamingOutputCallResponse(this); } @@ -1683,6 +1830,7 @@ namespace Grpc.Testing { /// /// Payload to increase response size. /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.Payload Payload { get { return payload_; } set { @@ -1690,10 +1838,12 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as StreamingOutputCallResponse); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(StreamingOutputCallResponse other) { if (ReferenceEquals(other, null)) { return false; @@ -1705,16 +1855,19 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (payload_ != null) hash ^= Payload.GetHashCode(); return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (payload_ != null) { output.WriteRawTag(10); @@ -1722,6 +1875,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (payload_ != null) { @@ -1730,6 +1884,7 @@ namespace Grpc.Testing { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(StreamingOutputCallResponse other) { if (other == null) { return; @@ -1742,6 +1897,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -1766,29 +1922,34 @@ namespace Grpc.Testing { /// For reconnect interop test only. /// Client tells server what reconnection parameters it used. /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class ReconnectParams : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ReconnectParams()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.MessagesReflection.Descriptor.MessageTypes[10]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ReconnectParams() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ReconnectParams(ReconnectParams other) : this() { maxReconnectBackoffMs_ = other.maxReconnectBackoffMs_; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ReconnectParams Clone() { return new ReconnectParams(this); } @@ -1796,6 +1957,7 @@ namespace Grpc.Testing { /// Field number for the "max_reconnect_backoff_ms" field. public const int MaxReconnectBackoffMsFieldNumber = 1; private int maxReconnectBackoffMs_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int MaxReconnectBackoffMs { get { return maxReconnectBackoffMs_; } set { @@ -1803,10 +1965,12 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as ReconnectParams); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(ReconnectParams other) { if (ReferenceEquals(other, null)) { return false; @@ -1818,16 +1982,19 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (MaxReconnectBackoffMs != 0) hash ^= MaxReconnectBackoffMs.GetHashCode(); return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (MaxReconnectBackoffMs != 0) { output.WriteRawTag(8); @@ -1835,6 +2002,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (MaxReconnectBackoffMs != 0) { @@ -1843,6 +2011,7 @@ namespace Grpc.Testing { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(ReconnectParams other) { if (other == null) { return; @@ -1852,6 +2021,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -1874,30 +2044,35 @@ namespace Grpc.Testing { /// Server tells client whether its reconnects are following the spec and the /// reconnect backoffs it saw. /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class ReconnectInfo : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ReconnectInfo()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.MessagesReflection.Descriptor.MessageTypes[11]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ReconnectInfo() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ReconnectInfo(ReconnectInfo other) : this() { passed_ = other.passed_; backoffMs_ = other.backoffMs_.Clone(); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ReconnectInfo Clone() { return new ReconnectInfo(this); } @@ -1905,6 +2080,7 @@ namespace Grpc.Testing { /// Field number for the "passed" field. public const int PassedFieldNumber = 1; private bool passed_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Passed { get { return passed_; } set { @@ -1917,14 +2093,17 @@ namespace Grpc.Testing { private static readonly pb::FieldCodec _repeated_backoffMs_codec = pb::FieldCodec.ForInt32(18); private readonly pbc::RepeatedField backoffMs_ = new pbc::RepeatedField(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::RepeatedField BackoffMs { get { return backoffMs_; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as ReconnectInfo); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(ReconnectInfo other) { if (ReferenceEquals(other, null)) { return false; @@ -1937,6 +2116,7 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (Passed != false) hash ^= Passed.GetHashCode(); @@ -1944,10 +2124,12 @@ namespace Grpc.Testing { return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (Passed != false) { output.WriteRawTag(8); @@ -1956,6 +2138,7 @@ namespace Grpc.Testing { backoffMs_.WriteTo(output, _repeated_backoffMs_codec); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (Passed != false) { @@ -1965,6 +2148,7 @@ namespace Grpc.Testing { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(ReconnectInfo other) { if (other == null) { return; @@ -1975,6 +2159,7 @@ namespace Grpc.Testing { backoffMs_.Add(other.backoffMs_); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { diff --git a/src/csharp/Grpc.IntegrationTesting/Metrics.cs b/src/csharp/Grpc.IntegrationTesting/Metrics.cs index 8f31fbc2a9..4de1847e5f 100644 --- a/src/csharp/Grpc.IntegrationTesting/Metrics.cs +++ b/src/csharp/Grpc.IntegrationTesting/Metrics.cs @@ -10,7 +10,6 @@ using scg = global::System.Collections.Generic; namespace Grpc.Testing { /// Holder for reflection information generated from src/proto/grpc/testing/metrics.proto - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public static partial class MetricsReflection { #region Descriptor @@ -47,25 +46,29 @@ namespace Grpc.Testing { /// /// Reponse message containing the gauge name and value /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class GaugeResponse : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new GaugeResponse()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.MetricsReflection.Descriptor.MessageTypes[0]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public GaugeResponse() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public GaugeResponse(GaugeResponse other) : this() { name_ = other.name_; switch (other.ValueCase) { @@ -82,6 +85,7 @@ namespace Grpc.Testing { } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public GaugeResponse Clone() { return new GaugeResponse(this); } @@ -89,6 +93,7 @@ namespace Grpc.Testing { /// Field number for the "name" field. public const int NameFieldNumber = 1; private string name_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public string Name { get { return name_; } set { @@ -98,6 +103,7 @@ namespace Grpc.Testing { /// Field number for the "long_value" field. public const int LongValueFieldNumber = 2; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public long LongValue { get { return valueCase_ == ValueOneofCase.LongValue ? (long) value_ : 0L; } set { @@ -108,6 +114,7 @@ namespace Grpc.Testing { /// Field number for the "double_value" field. public const int DoubleValueFieldNumber = 3; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double DoubleValue { get { return valueCase_ == ValueOneofCase.DoubleValue ? (double) value_ : 0D; } set { @@ -118,6 +125,7 @@ namespace Grpc.Testing { /// Field number for the "string_value" field. public const int StringValueFieldNumber = 4; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public string StringValue { get { return valueCase_ == ValueOneofCase.StringValue ? (string) value_ : ""; } set { @@ -135,19 +143,23 @@ namespace Grpc.Testing { StringValue = 4, } private ValueOneofCase valueCase_ = ValueOneofCase.None; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ValueOneofCase ValueCase { get { return valueCase_; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void ClearValue() { valueCase_ = ValueOneofCase.None; value_ = null; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as GaugeResponse); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(GaugeResponse other) { if (ReferenceEquals(other, null)) { return false; @@ -163,6 +175,7 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (Name.Length != 0) hash ^= Name.GetHashCode(); @@ -173,10 +186,12 @@ namespace Grpc.Testing { return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (Name.Length != 0) { output.WriteRawTag(10); @@ -196,6 +211,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (Name.Length != 0) { @@ -213,6 +229,7 @@ namespace Grpc.Testing { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(GaugeResponse other) { if (other == null) { return; @@ -234,6 +251,7 @@ namespace Grpc.Testing { } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -266,29 +284,34 @@ namespace Grpc.Testing { /// /// Request message containing the gauge name /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class GaugeRequest : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new GaugeRequest()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.MetricsReflection.Descriptor.MessageTypes[1]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public GaugeRequest() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public GaugeRequest(GaugeRequest other) : this() { name_ = other.name_; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public GaugeRequest Clone() { return new GaugeRequest(this); } @@ -296,6 +319,7 @@ namespace Grpc.Testing { /// Field number for the "name" field. public const int NameFieldNumber = 1; private string name_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public string Name { get { return name_; } set { @@ -303,10 +327,12 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as GaugeRequest); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(GaugeRequest other) { if (ReferenceEquals(other, null)) { return false; @@ -318,16 +344,19 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (Name.Length != 0) hash ^= Name.GetHashCode(); return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (Name.Length != 0) { output.WriteRawTag(10); @@ -335,6 +364,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (Name.Length != 0) { @@ -343,6 +373,7 @@ namespace Grpc.Testing { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(GaugeRequest other) { if (other == null) { return; @@ -352,6 +383,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -369,36 +401,43 @@ namespace Grpc.Testing { } - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class EmptyMessage : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new EmptyMessage()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.MetricsReflection.Descriptor.MessageTypes[2]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public EmptyMessage() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public EmptyMessage(EmptyMessage other) : this() { } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public EmptyMessage Clone() { return new EmptyMessage(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as EmptyMessage); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(EmptyMessage other) { if (ReferenceEquals(other, null)) { return false; @@ -409,29 +448,35 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(EmptyMessage other) { if (other == null) { return; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { diff --git a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs index 040798e3c2..bcd7e3c040 100644 --- a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs @@ -161,6 +161,7 @@ namespace Grpc.Testing { { return CallInvoker.AsyncUnaryCall(__Method_GetGauge, null, options, request); } + /// Creates a new instance of client from given ClientBaseConfiguration. protected override MetricsServiceClient NewInstance(ClientBaseConfiguration configuration) { return new MetricsServiceClient(configuration); diff --git a/src/csharp/Grpc.IntegrationTesting/Payloads.cs b/src/csharp/Grpc.IntegrationTesting/Payloads.cs index 3ad7a44f4b..7aef35cda3 100644 --- a/src/csharp/Grpc.IntegrationTesting/Payloads.cs +++ b/src/csharp/Grpc.IntegrationTesting/Payloads.cs @@ -10,7 +10,6 @@ using scg = global::System.Collections.Generic; namespace Grpc.Testing { /// Holder for reflection information generated from src/proto/grpc/testing/payloads.proto - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public static partial class PayloadsReflection { #region Descriptor @@ -45,30 +44,35 @@ namespace Grpc.Testing { } #region Messages - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class ByteBufferParams : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ByteBufferParams()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.PayloadsReflection.Descriptor.MessageTypes[0]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ByteBufferParams() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ByteBufferParams(ByteBufferParams other) : this() { reqSize_ = other.reqSize_; respSize_ = other.respSize_; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ByteBufferParams Clone() { return new ByteBufferParams(this); } @@ -76,6 +80,7 @@ namespace Grpc.Testing { /// Field number for the "req_size" field. public const int ReqSizeFieldNumber = 1; private int reqSize_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int ReqSize { get { return reqSize_; } set { @@ -86,6 +91,7 @@ namespace Grpc.Testing { /// Field number for the "resp_size" field. public const int RespSizeFieldNumber = 2; private int respSize_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int RespSize { get { return respSize_; } set { @@ -93,10 +99,12 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as ByteBufferParams); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(ByteBufferParams other) { if (ReferenceEquals(other, null)) { return false; @@ -109,6 +117,7 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (ReqSize != 0) hash ^= ReqSize.GetHashCode(); @@ -116,10 +125,12 @@ namespace Grpc.Testing { return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (ReqSize != 0) { output.WriteRawTag(8); @@ -131,6 +142,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (ReqSize != 0) { @@ -142,6 +154,7 @@ namespace Grpc.Testing { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(ByteBufferParams other) { if (other == null) { return; @@ -154,6 +167,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -175,30 +189,35 @@ namespace Grpc.Testing { } - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class SimpleProtoParams : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new SimpleProtoParams()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.PayloadsReflection.Descriptor.MessageTypes[1]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public SimpleProtoParams() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public SimpleProtoParams(SimpleProtoParams other) : this() { reqSize_ = other.reqSize_; respSize_ = other.respSize_; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public SimpleProtoParams Clone() { return new SimpleProtoParams(this); } @@ -206,6 +225,7 @@ namespace Grpc.Testing { /// Field number for the "req_size" field. public const int ReqSizeFieldNumber = 1; private int reqSize_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int ReqSize { get { return reqSize_; } set { @@ -216,6 +236,7 @@ namespace Grpc.Testing { /// Field number for the "resp_size" field. public const int RespSizeFieldNumber = 2; private int respSize_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int RespSize { get { return respSize_; } set { @@ -223,10 +244,12 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as SimpleProtoParams); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(SimpleProtoParams other) { if (ReferenceEquals(other, null)) { return false; @@ -239,6 +262,7 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (ReqSize != 0) hash ^= ReqSize.GetHashCode(); @@ -246,10 +270,12 @@ namespace Grpc.Testing { return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (ReqSize != 0) { output.WriteRawTag(8); @@ -261,6 +287,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (ReqSize != 0) { @@ -272,6 +299,7 @@ namespace Grpc.Testing { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(SimpleProtoParams other) { if (other == null) { return; @@ -284,6 +312,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -309,36 +338,43 @@ namespace Grpc.Testing { /// TODO (vpai): Fill this in once the details of complex, representative /// protos are decided /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class ComplexProtoParams : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ComplexProtoParams()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.PayloadsReflection.Descriptor.MessageTypes[2]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ComplexProtoParams() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ComplexProtoParams(ComplexProtoParams other) : this() { } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ComplexProtoParams Clone() { return new ComplexProtoParams(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as ComplexProtoParams); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(ComplexProtoParams other) { if (ReferenceEquals(other, null)) { return false; @@ -349,29 +385,35 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(ComplexProtoParams other) { if (other == null) { return; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -385,25 +427,29 @@ namespace Grpc.Testing { } - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class PayloadConfig : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new PayloadConfig()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.PayloadsReflection.Descriptor.MessageTypes[3]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public PayloadConfig() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public PayloadConfig(PayloadConfig other) : this() { switch (other.PayloadCase) { case PayloadOneofCase.BytebufParams: @@ -419,12 +465,14 @@ namespace Grpc.Testing { } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public PayloadConfig Clone() { return new PayloadConfig(this); } /// Field number for the "bytebuf_params" field. public const int BytebufParamsFieldNumber = 1; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.ByteBufferParams BytebufParams { get { return payloadCase_ == PayloadOneofCase.BytebufParams ? (global::Grpc.Testing.ByteBufferParams) payload_ : null; } set { @@ -435,6 +483,7 @@ namespace Grpc.Testing { /// Field number for the "simple_params" field. public const int SimpleParamsFieldNumber = 2; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.SimpleProtoParams SimpleParams { get { return payloadCase_ == PayloadOneofCase.SimpleParams ? (global::Grpc.Testing.SimpleProtoParams) payload_ : null; } set { @@ -445,6 +494,7 @@ namespace Grpc.Testing { /// Field number for the "complex_params" field. public const int ComplexParamsFieldNumber = 3; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.ComplexProtoParams ComplexParams { get { return payloadCase_ == PayloadOneofCase.ComplexParams ? (global::Grpc.Testing.ComplexProtoParams) payload_ : null; } set { @@ -462,19 +512,23 @@ namespace Grpc.Testing { ComplexParams = 3, } private PayloadOneofCase payloadCase_ = PayloadOneofCase.None; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public PayloadOneofCase PayloadCase { get { return payloadCase_; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void ClearPayload() { payloadCase_ = PayloadOneofCase.None; payload_ = null; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as PayloadConfig); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(PayloadConfig other) { if (ReferenceEquals(other, null)) { return false; @@ -489,6 +543,7 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (payloadCase_ == PayloadOneofCase.BytebufParams) hash ^= BytebufParams.GetHashCode(); @@ -498,10 +553,12 @@ namespace Grpc.Testing { return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (payloadCase_ == PayloadOneofCase.BytebufParams) { output.WriteRawTag(10); @@ -517,6 +574,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (payloadCase_ == PayloadOneofCase.BytebufParams) { @@ -531,6 +589,7 @@ namespace Grpc.Testing { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(PayloadConfig other) { if (other == null) { return; @@ -549,6 +608,7 @@ namespace Grpc.Testing { } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { diff --git a/src/csharp/Grpc.IntegrationTesting/Services.cs b/src/csharp/Grpc.IntegrationTesting/Services.cs index e10b45c9a2..bf36a0253b 100644 --- a/src/csharp/Grpc.IntegrationTesting/Services.cs +++ b/src/csharp/Grpc.IntegrationTesting/Services.cs @@ -10,7 +10,6 @@ using scg = global::System.Collections.Generic; namespace Grpc.Testing { /// Holder for reflection information generated from src/proto/grpc/testing/services.proto - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public static partial class ServicesReflection { #region Descriptor diff --git a/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs b/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs index e205dea93e..848dd04fa7 100644 --- a/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs @@ -161,6 +161,7 @@ namespace Grpc.Testing { { return CallInvoker.AsyncDuplexStreamingCall(__Method_StreamingCall, null, options); } + /// Creates a new instance of client from given ClientBaseConfiguration. protected override BenchmarkServiceClient NewInstance(ClientBaseConfiguration configuration) { return new BenchmarkServiceClient(configuration); @@ -396,6 +397,7 @@ namespace Grpc.Testing { { return CallInvoker.AsyncUnaryCall(__Method_QuitWorker, null, options, request); } + /// Creates a new instance of client from given ClientBaseConfiguration. protected override WorkerServiceClient NewInstance(ClientBaseConfiguration configuration) { return new WorkerServiceClient(configuration); diff --git a/src/csharp/Grpc.IntegrationTesting/Stats.cs b/src/csharp/Grpc.IntegrationTesting/Stats.cs index 304d676113..0ae77cfb92 100644 --- a/src/csharp/Grpc.IntegrationTesting/Stats.cs +++ b/src/csharp/Grpc.IntegrationTesting/Stats.cs @@ -10,7 +10,6 @@ using scg = global::System.Collections.Generic; namespace Grpc.Testing { /// Holder for reflection information generated from src/proto/grpc/testing/stats.proto - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public static partial class StatsReflection { #region Descriptor @@ -46,31 +45,36 @@ namespace Grpc.Testing { } #region Messages - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class ServerStats : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ServerStats()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.StatsReflection.Descriptor.MessageTypes[0]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ServerStats() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ServerStats(ServerStats other) : this() { timeElapsed_ = other.timeElapsed_; timeUser_ = other.timeUser_; timeSystem_ = other.timeSystem_; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ServerStats Clone() { return new ServerStats(this); } @@ -81,6 +85,7 @@ namespace Grpc.Testing { /// /// wall clock time change in seconds since last reset /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double TimeElapsed { get { return timeElapsed_; } set { @@ -94,6 +99,7 @@ namespace Grpc.Testing { /// /// change in user time (in seconds) used by the server since last reset /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double TimeUser { get { return timeUser_; } set { @@ -108,6 +114,7 @@ namespace Grpc.Testing { /// change in server time (in seconds) used by the server process and all /// threads since last reset /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double TimeSystem { get { return timeSystem_; } set { @@ -115,10 +122,12 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as ServerStats); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(ServerStats other) { if (ReferenceEquals(other, null)) { return false; @@ -132,6 +141,7 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (TimeElapsed != 0D) hash ^= TimeElapsed.GetHashCode(); @@ -140,10 +150,12 @@ namespace Grpc.Testing { return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (TimeElapsed != 0D) { output.WriteRawTag(9); @@ -159,6 +171,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (TimeElapsed != 0D) { @@ -173,6 +186,7 @@ namespace Grpc.Testing { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(ServerStats other) { if (other == null) { return; @@ -188,6 +202,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -216,30 +231,35 @@ namespace Grpc.Testing { /// /// Histogram params based on grpc/support/histogram.c /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class HistogramParams : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new HistogramParams()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.StatsReflection.Descriptor.MessageTypes[1]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public HistogramParams() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public HistogramParams(HistogramParams other) : this() { resolution_ = other.resolution_; maxPossible_ = other.maxPossible_; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public HistogramParams Clone() { return new HistogramParams(this); } @@ -250,6 +270,7 @@ namespace Grpc.Testing { /// /// first bucket is [0, 1 + resolution) /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double Resolution { get { return resolution_; } set { @@ -263,6 +284,7 @@ namespace Grpc.Testing { /// /// use enough buckets to allow this value /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double MaxPossible { get { return maxPossible_; } set { @@ -270,10 +292,12 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as HistogramParams); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(HistogramParams other) { if (ReferenceEquals(other, null)) { return false; @@ -286,6 +310,7 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (Resolution != 0D) hash ^= Resolution.GetHashCode(); @@ -293,10 +318,12 @@ namespace Grpc.Testing { return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (Resolution != 0D) { output.WriteRawTag(9); @@ -308,6 +335,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (Resolution != 0D) { @@ -319,6 +347,7 @@ namespace Grpc.Testing { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(HistogramParams other) { if (other == null) { return; @@ -331,6 +360,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -355,25 +385,29 @@ namespace Grpc.Testing { /// /// Histogram data based on grpc/support/histogram.c /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class HistogramData : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new HistogramData()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.StatsReflection.Descriptor.MessageTypes[2]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public HistogramData() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public HistogramData(HistogramData other) : this() { bucket_ = other.bucket_.Clone(); minSeen_ = other.minSeen_; @@ -383,6 +417,7 @@ namespace Grpc.Testing { count_ = other.count_; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public HistogramData Clone() { return new HistogramData(this); } @@ -392,6 +427,7 @@ namespace Grpc.Testing { private static readonly pb::FieldCodec _repeated_bucket_codec = pb::FieldCodec.ForUInt32(10); private readonly pbc::RepeatedField bucket_ = new pbc::RepeatedField(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::RepeatedField Bucket { get { return bucket_; } } @@ -399,6 +435,7 @@ namespace Grpc.Testing { /// Field number for the "min_seen" field. public const int MinSeenFieldNumber = 2; private double minSeen_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double MinSeen { get { return minSeen_; } set { @@ -409,6 +446,7 @@ namespace Grpc.Testing { /// Field number for the "max_seen" field. public const int MaxSeenFieldNumber = 3; private double maxSeen_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double MaxSeen { get { return maxSeen_; } set { @@ -419,6 +457,7 @@ namespace Grpc.Testing { /// Field number for the "sum" field. public const int SumFieldNumber = 4; private double sum_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double Sum { get { return sum_; } set { @@ -429,6 +468,7 @@ namespace Grpc.Testing { /// Field number for the "sum_of_squares" field. public const int SumOfSquaresFieldNumber = 5; private double sumOfSquares_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double SumOfSquares { get { return sumOfSquares_; } set { @@ -439,6 +479,7 @@ namespace Grpc.Testing { /// Field number for the "count" field. public const int CountFieldNumber = 6; private double count_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double Count { get { return count_; } set { @@ -446,10 +487,12 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as HistogramData); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(HistogramData other) { if (ReferenceEquals(other, null)) { return false; @@ -466,6 +509,7 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; hash ^= bucket_.GetHashCode(); @@ -477,10 +521,12 @@ namespace Grpc.Testing { return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { bucket_.WriteTo(output, _repeated_bucket_codec); if (MinSeen != 0D) { @@ -505,6 +551,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; size += bucket_.CalculateSize(_repeated_bucket_codec); @@ -526,6 +573,7 @@ namespace Grpc.Testing { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(HistogramData other) { if (other == null) { return; @@ -548,6 +596,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { @@ -586,25 +635,29 @@ namespace Grpc.Testing { } - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public sealed partial class ClientStats : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ClientStats()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { get { return global::Grpc.Testing.StatsReflection.Descriptor.MessageTypes[3]; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] pbr::MessageDescriptor pb::IMessage.Descriptor { get { return Descriptor; } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ClientStats() { OnConstruction(); } partial void OnConstruction(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ClientStats(ClientStats other) : this() { Latencies = other.latencies_ != null ? other.Latencies.Clone() : null; timeElapsed_ = other.timeElapsed_; @@ -612,6 +665,7 @@ namespace Grpc.Testing { timeSystem_ = other.timeSystem_; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ClientStats Clone() { return new ClientStats(this); } @@ -622,6 +676,7 @@ namespace Grpc.Testing { /// /// Latency histogram. Data points are in nanoseconds. /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Grpc.Testing.HistogramData Latencies { get { return latencies_; } set { @@ -635,6 +690,7 @@ namespace Grpc.Testing { /// /// See ServerStats for details. /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double TimeElapsed { get { return timeElapsed_; } set { @@ -645,6 +701,7 @@ namespace Grpc.Testing { /// Field number for the "time_user" field. public const int TimeUserFieldNumber = 3; private double timeUser_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double TimeUser { get { return timeUser_; } set { @@ -655,6 +712,7 @@ namespace Grpc.Testing { /// Field number for the "time_system" field. public const int TimeSystemFieldNumber = 4; private double timeSystem_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public double TimeSystem { get { return timeSystem_; } set { @@ -662,10 +720,12 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as ClientStats); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool Equals(ClientStats other) { if (ReferenceEquals(other, null)) { return false; @@ -680,6 +740,7 @@ namespace Grpc.Testing { return true; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (latencies_ != null) hash ^= Latencies.GetHashCode(); @@ -689,10 +750,12 @@ namespace Grpc.Testing { return hash; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override string ToString() { return pb::JsonFormatter.ToDiagnosticString(this); } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { if (latencies_ != null) { output.WriteRawTag(10); @@ -712,6 +775,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; if (latencies_ != null) { @@ -729,6 +793,7 @@ namespace Grpc.Testing { return size; } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(ClientStats other) { if (other == null) { return; @@ -750,6 +815,7 @@ namespace Grpc.Testing { } } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { uint tag; while ((tag = input.ReadTag()) != 0) { diff --git a/src/csharp/Grpc.IntegrationTesting/Test.cs b/src/csharp/Grpc.IntegrationTesting/Test.cs index 9258dc185d..88c2b8a921 100644 --- a/src/csharp/Grpc.IntegrationTesting/Test.cs +++ b/src/csharp/Grpc.IntegrationTesting/Test.cs @@ -10,7 +10,6 @@ using scg = global::System.Collections.Generic; namespace Grpc.Testing { /// Holder for reflection information generated from src/proto/grpc/testing/test.proto - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public static partial class TestReflection { #region Descriptor diff --git a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs index 3e149da3e0..61f2ed4015 100644 --- a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs @@ -314,6 +314,7 @@ namespace Grpc.Testing { { return CallInvoker.AsyncDuplexStreamingCall(__Method_HalfDuplexCall, null, options); } + /// Creates a new instance of client from given ClientBaseConfiguration. protected override TestServiceClient NewInstance(ClientBaseConfiguration configuration) { return new TestServiceClient(configuration); @@ -420,6 +421,7 @@ namespace Grpc.Testing { { return CallInvoker.AsyncUnaryCall(__Method_UnimplementedCall, null, options, request); } + /// Creates a new instance of client from given ClientBaseConfiguration. protected override UnimplementedServiceClient NewInstance(ClientBaseConfiguration configuration) { return new UnimplementedServiceClient(configuration); @@ -535,6 +537,7 @@ namespace Grpc.Testing { { return CallInvoker.AsyncUnaryCall(__Method_Stop, null, options, request); } + /// Creates a new instance of client from given ClientBaseConfiguration. protected override ReconnectServiceClient NewInstance(ClientBaseConfiguration configuration) { return new ReconnectServiceClient(configuration); -- cgit v1.2.3 From 9381c00857d0acc4fc034937260f32ee26e836b9 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 7 Oct 2016 13:09:45 -0700 Subject: Fix race with fetching data and writing it in chttp2 --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 13 +++++++------ src/core/ext/transport/chttp2/transport/internal.h | 5 +++-- src/core/ext/transport/chttp2/transport/writing.c | 10 +++++----- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 023b7c2e95..8ab26e512d 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -836,8 +836,8 @@ static void continue_fetching_send_locked(grpc_exec_ctx *exec_ctx, return; } if (s->fetched_send_message_length == s->fetching_send_message->length) { - ssize_t notify_offset = s->fetching_slice_end_offset; - if (notify_offset <= 0) { + int64_t notify_offset = s->next_message_end_offset; + if (notify_offset <= s->flow_controlled_bytes_written) { grpc_chttp2_complete_closure_step( exec_ctx, t, s, &s->fetching_send_message_finished, GRPC_ERROR_NONE, "fetching_send_message_finished"); @@ -848,7 +848,7 @@ static void continue_fetching_send_locked(grpc_exec_ctx *exec_ctx, } else { t->write_cb_pool = cb->next; } - cb->call_at_byte = (size_t)notify_offset; + cb->call_at_byte = notify_offset; cb->closure = s->fetching_send_message_finished; s->fetching_send_message_finished = NULL; cb->next = s->on_write_finished_cbs; @@ -1005,13 +1005,14 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op, frame_hdr[4] = (uint8_t)(len); s->fetching_send_message = op->send_message; s->fetched_send_message_length = 0; - s->fetching_slice_end_offset = - (ssize_t)s->flow_controlled_buffer.length + (ssize_t)len; + s->next_message_end_offset = s->flow_controlled_bytes_written + + (int64_t)s->flow_controlled_buffer.length + + (int64_t)len; s->complete_fetch_covered_by_poller = op->covered_by_poller; if (flags & GRPC_WRITE_BUFFER_HINT) { /* allow up to 64kb to be buffered */ /* TODO(ctiller): make this configurable */ - s->fetching_slice_end_offset -= 65536; + s->next_message_end_offset -= 65536; } continue_fetching_send_locked(exec_ctx, t, s); if (s->id != 0) { diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 3263c99bde..774fed0722 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -147,7 +147,7 @@ typedef struct grpc_chttp2_outstanding_ping { } grpc_chttp2_outstanding_ping; typedef struct grpc_chttp2_write_cb { - size_t call_at_byte; + int64_t call_at_byte; grpc_closure *closure; struct grpc_chttp2_write_cb *next; } grpc_chttp2_write_cb; @@ -353,7 +353,8 @@ struct grpc_chttp2_stream { grpc_byte_stream *fetching_send_message; uint32_t fetched_send_message_length; gpr_slice fetching_slice; - int64_t fetching_slice_end_offset; + int64_t next_message_end_offset; + int64_t flow_controlled_bytes_written; bool complete_fetch_covered_by_poller; grpc_closure complete_fetch; grpc_closure complete_fetch_locked; diff --git a/src/core/ext/transport/chttp2/transport/writing.c b/src/core/ext/transport/chttp2/transport/writing.c index ebdbce1bfd..d34a7918b5 100644 --- a/src/core/ext/transport/chttp2/transport/writing.c +++ b/src/core/ext/transport/chttp2/transport/writing.c @@ -56,16 +56,16 @@ static void finish_write_cb(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, } static void update_list(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, - grpc_chttp2_stream *s, size_t send_bytes, + grpc_chttp2_stream *s, int64_t send_bytes, grpc_chttp2_write_cb **list, grpc_error *error) { grpc_chttp2_write_cb *cb = *list; *list = NULL; + s->flow_controlled_bytes_written += send_bytes; while (cb) { grpc_chttp2_write_cb *next = cb->next; - if (cb->call_at_byte <= send_bytes) { + if (cb->call_at_byte <= s->flow_controlled_bytes_written) { finish_write_cb(exec_ctx, t, s, cb, GRPC_ERROR_REF(error)); } else { - cb->call_at_byte -= send_bytes; add_to_write_list(list, cb); } cb = next; @@ -236,8 +236,8 @@ void grpc_chttp2_end_write(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, GRPC_ERROR_REF(error), "send_initial_metadata_finished"); } if (s->sending_bytes != 0) { - update_list(exec_ctx, t, s, s->sending_bytes, &s->on_write_finished_cbs, - GRPC_ERROR_REF(error)); + update_list(exec_ctx, t, s, (int64_t)s->sending_bytes, + &s->on_write_finished_cbs, GRPC_ERROR_REF(error)); s->sending_bytes = 0; } if (s->sent_trailing_metadata) { -- cgit v1.2.3 From 46b9be73b927e43afa534a2e7e43738aa8a09f0b Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Wed, 12 Oct 2016 14:33:13 -0700 Subject: add comment about go differences in go versions --- tools/gce/linux_performance_worker_init.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/gce/linux_performance_worker_init.sh b/tools/gce/linux_performance_worker_init.sh index 6fc3035c10..487672549f 100755 --- a/tools/gce/linux_performance_worker_init.sh +++ b/tools/gce/linux_performance_worker_init.sh @@ -129,6 +129,8 @@ gem install bundler # Go dependencies # Currently, the golang package available via apt-get doesn't have the latest go. +# Significant performance improvements with grpc-go have been observed after +# upgrading from go 1.5 to a later version, so a later go version is preferred. # Following go install instructions from https://golang.org/doc/install GO_VERSION=1.7.1 OS=linux -- cgit v1.2.3 From 002f41ed28e687ef954b5837c66f27c32f34634e Mon Sep 17 00:00:00 2001 From: Noah Eisen Date: Wed, 12 Oct 2016 15:12:13 -0700 Subject: reverted changes to interop test driver to avoid clashes with mark roths pull req --- tools/run_tests/run_interop_tests.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index 53c03f0bad..389d070d63 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -89,10 +89,10 @@ class CXXLanguage: return {} def unimplemented_test_cases(self): - return [] + return _SKIP_ADVANCED def unimplemented_test_cases_server(self): - return [] + return _SKIP_ADVANCED def __str__(self): return 'c++' -- cgit v1.2.3 From f8ffbf62a2a44f152c2d88b388fe67de62cc1051 Mon Sep 17 00:00:00 2001 From: Noah Eisen Date: Wed, 12 Oct 2016 15:32:42 -0700 Subject: also reverted interop server, since mark had already made the changes I did in an un merged pull request --- test/cpp/interop/interop_server.cc | 50 ++++++++------------------------------ 1 file changed, 10 insertions(+), 40 deletions(-) diff --git a/test/cpp/interop/interop_server.cc b/test/cpp/interop/interop_server.cc index e0016148e8..c05eb5d146 100644 --- a/test/cpp/interop/interop_server.cc +++ b/test/cpp/interop/interop_server.cc @@ -47,7 +47,6 @@ #include #include -#include "src/core/lib/support/string.h" #include "src/core/lib/transport/byte_stream.h" #include "src/proto/grpc/testing/empty.grpc.pb.h" #include "src/proto/grpc/testing/messages.grpc.pb.h" @@ -83,8 +82,6 @@ const char kEchoInitialMetadataKey[] = "x-grpc-test-echo-initial"; const char kEchoTrailingBinMetadataKey[] = "x-grpc-test-echo-trailing-bin"; const char kEchoUserAgentKey[] = "x-grpc-test-echo-useragent"; -namespace { - void MaybeEchoMetadata(ServerContext* context) { const auto& client_metadata = context->client_metadata(); GPR_ASSERT(client_metadata.count(kEchoInitialMetadataKey) <= 1); @@ -148,28 +145,6 @@ bool CheckExpectedCompression(const ServerContext& context, return true; } -Status RequestedStatusOrOk(const SimpleRequest* request) { - if (request->has_response_status()) { - return Status( - static_cast(request->response_status().code()), - request->response_status().message()); - } else { - return Status::OK; - } -} - -Status RequestedStatusOrOk(const StreamingOutputCallRequest* request) { - if (request->has_response_status()) { - return Status( - static_cast(request->response_status().code()), - request->response_status().message()); - } else { - return Status::OK; - } -} - -} // anonomous namespace - class TestServiceImpl : public TestService::Service { public: Status EmptyCall(ServerContext* context, const grpc::testing::Empty* request, @@ -178,17 +153,6 @@ class TestServiceImpl : public TestService::Service { return Status::OK; } - // Response contains current timestamp. We ignore everything in the request. - Status CacheableUnaryCall(ServerContext* context, - const SimpleRequest* request, - SimpleResponse* response) { - gpr_timespec ts = gpr_now(GPR_CLOCK_PRECISE); - std::string timestamp = std::to_string((long long unsigned)ts.tv_nsec); - response->mutable_payload()->set_body(timestamp.c_str(), timestamp.size()); - context->AddInitialMetadata("cache-control", "max-age=60, public"); - return Status::OK; - } - Status UnaryCall(ServerContext* context, const SimpleRequest* request, SimpleResponse* response) { MaybeEchoMetadata(context); @@ -215,7 +179,13 @@ class TestServiceImpl : public TestService::Service { } } - return RequestedStatusOrOk(request); + if (request->has_response_status()) { + return Status( + static_cast(request->response_status().code()), + request->response_status().message()); + } + + return Status::OK; } Status StreamingOutputCall( @@ -253,7 +223,7 @@ class TestServiceImpl : public TestService::Service { write_success = writer->Write(response, wopts); } if (write_success) { - return RequestedStatusOrOk(request); + return Status::OK; } else { return Status(grpc::StatusCode::INTERNAL, "Error writing response."); } @@ -303,7 +273,7 @@ class TestServiceImpl : public TestService::Service { } } if (write_success) { - return RequestedStatusOrOk(&request); + return Status::OK; } else { return Status(grpc::StatusCode::INTERNAL, "Error writing response."); } @@ -332,7 +302,7 @@ class TestServiceImpl : public TestService::Service { write_success = stream->Write(response); } if (write_success) { - return RequestedStatusOrOk(&request); + return Status::OK; } else { return Status(grpc::StatusCode::INTERNAL, "Error writing response."); } -- cgit v1.2.3 From 40860c4488363bd534b3440d4d09b1a946750667 Mon Sep 17 00:00:00 2001 From: Noah Eisen Date: Wed, 12 Oct 2016 15:38:46 -0700 Subject: reverting a file for the last commit caused a function to be deleted from interop_client. This commit adds that function back in --- test/cpp/interop/interop_server.cc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/cpp/interop/interop_server.cc b/test/cpp/interop/interop_server.cc index c05eb5d146..2e6a10b36b 100644 --- a/test/cpp/interop/interop_server.cc +++ b/test/cpp/interop/interop_server.cc @@ -47,6 +47,7 @@ #include #include +#include "src/core/lib/support/string.h" #include "src/core/lib/transport/byte_stream.h" #include "src/proto/grpc/testing/empty.grpc.pb.h" #include "src/proto/grpc/testing/messages.grpc.pb.h" @@ -153,6 +154,17 @@ class TestServiceImpl : public TestService::Service { return Status::OK; } + // Response contains current timestamp. We ignore everything in the request. + Status CacheableUnaryCall(ServerContext* context, + const SimpleRequest* request, + SimpleResponse* response) { + gpr_timespec ts = gpr_now(GPR_CLOCK_PRECISE); + std::string timestamp = std::to_string((long long unsigned)ts.tv_nsec); + response->mutable_payload()->set_body(timestamp.c_str(), timestamp.size()); + context->AddInitialMetadata("cache-control", "max-age=60, public"); + return Status::OK; + } + Status UnaryCall(ServerContext* context, const SimpleRequest* request, SimpleResponse* response) { MaybeEchoMetadata(context); -- cgit v1.2.3 From 83dd3aa7e056e2ea7e5b3b03f7e58e7a12bcc4e1 Mon Sep 17 00:00:00 2001 From: Noah Eisen Date: Wed, 12 Oct 2016 15:40:11 -0700 Subject: changed whitespace --- test/cpp/interop/interop_server.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/cpp/interop/interop_server.cc b/test/cpp/interop/interop_server.cc index 2e6a10b36b..58f20aa611 100644 --- a/test/cpp/interop/interop_server.cc +++ b/test/cpp/interop/interop_server.cc @@ -156,8 +156,8 @@ class TestServiceImpl : public TestService::Service { // Response contains current timestamp. We ignore everything in the request. Status CacheableUnaryCall(ServerContext* context, - const SimpleRequest* request, - SimpleResponse* response) { + const SimpleRequest* request, + SimpleResponse* response) { gpr_timespec ts = gpr_now(GPR_CLOCK_PRECISE); std::string timestamp = std::to_string((long long unsigned)ts.tv_nsec); response->mutable_payload()->set_body(timestamp.c_str(), timestamp.size()); -- cgit v1.2.3 From 2d41ed1613f29faad634210b378ab0e43a11c2ee Mon Sep 17 00:00:00 2001 From: Noah Eisen Date: Wed, 12 Oct 2016 17:53:43 -0700 Subject: fixed bug in custom metadata interop test from csharp client to c++ server --- src/csharp/Grpc.IntegrationTesting/InteropClient.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs index 79fd18b6d5..cb926328e0 100644 --- a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs +++ b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs @@ -520,12 +520,12 @@ namespace Grpc.IntegrationTesting }; var call = client.FullDuplexCall(headers: CreateTestMetadata()); - var responseHeaders = await call.ResponseHeadersAsync; await call.RequestStream.WriteAsync(request); await call.RequestStream.CompleteAsync(); await call.ResponseStream.ToListAsync(); + var responseHeaders = await call.ResponseHeadersAsync; var responseTrailers = call.GetTrailers(); Assert.AreEqual("test_initial_metadata_value", responseHeaders.First((entry) => entry.Key == "x-grpc-test-echo-initial").Value); -- cgit v1.2.3 From f01122c0926a3836695a415b8e20e42a876333a9 Mon Sep 17 00:00:00 2001 From: Matt Kwong Date: Wed, 12 Oct 2016 18:24:53 -0700 Subject: Made whitelisting files easier and more intuitive --- tools/run_tests/filter_pull_request_tests.py | 265 ++++++++++----------------- tools/run_tests/run_tests_matrix.py | 1 + 2 files changed, 99 insertions(+), 167 deletions(-) diff --git a/tools/run_tests/filter_pull_request_tests.py b/tools/run_tests/filter_pull_request_tests.py index 29dbd97825..55dab42f8a 100644 --- a/tools/run_tests/filter_pull_request_tests.py +++ b/tools/run_tests/filter_pull_request_tests.py @@ -30,85 +30,76 @@ """Filter out tests based on file differences compared to merge target branch""" +import re from subprocess import call, check_output -# Whitelist for all tests -# If whitelist item should only trigger some tests, the item should be -# added to this list and the trigger list of tests that should be run -starts_with_whitelist = ['templates/', - 'doc/', - 'examples/', - 'summerofcode/', - 'src/cpp', - 'src/csharp', - 'src/node', - 'src/objective-c', - 'src/php', - 'src/python', - 'src/ruby', - 'test/core', - 'test/cpp', - 'test/distrib/cpp', - 'test/distrib/csharp', - 'test/distrib/node', - 'test/distrib/php', - 'test/distrib/python', - 'test/distrib/ruby'] - -ends_with_whitelist = ['README.md', - 'LICENSE'] - -# Triggers for core tests -core_starts_with_triggers = ['test/core'] - -# Triggers for c++ tests -cpp_starts_with_triggers = ['src/cpp', - 'test/cpp', - 'test/distrib/cpp'] - -# Triggers for c# tests -csharp_starts_with_triggers = ['src/csharp', - 'test/distrib/csharp'] - -# Triggers for node tests -node_starts_with_triggers = ['src/node', - 'test/distrib/node'] - -# Triggers for objective-c tests -objc_starts_with_triggers = ['src/objective-c'] - -# Triggers for php tests -php_starts_with_triggers = ['src/php', - 'test/distrib/php'] - -# Triggers for python tests -python_starts_with_triggers = ['src/python', - 'test/distrib/python'] - -# Triggers for ruby tests -ruby_starts_with_triggers = ['src/ruby', - 'test/distrib/ruby'] - - -def _filter_whitelist(whitelist, triggers): + +class TestSuite: """ - Removes triggers from whitelist - :param whitelist: list to remove values from - :param triggers: list of values to remove from whitelist - :return: filtered whitelist + Contains tag to identify job as belonging to this test suite and + triggers to identify if changed files are relevant """ - filtered_whitelist = list(whitelist) - for trigger in triggers: - if trigger in filtered_whitelist: - filtered_whitelist.remove(trigger) - else: - """ - If the trigger is not found in the whitelist, then there is likely - a mistake in the whitelist or trigger list, which needs to be addressed - to not wrongly skip tests - """ - print("ERROR: '%s' trigger not in whitelist. Please fix this!" % trigger) - return filtered_whitelist + def __init__(self, tags): + """ + Build TestSuite to group tests by their tags + :param tag: string used to identify if a job belongs to this TestSuite + todo(mattkwong): Change the use of tag because do not want to depend on + job.shortname to identify what suite a test belongs to + """ + self.triggers = [] + self.tags = tags + + def add_trigger(self, trigger): + """ + Add a regex to list of triggers that determine if a changed file should run tests + :param trigger: regex matching file relevant to tests + """ + self.triggers.append(trigger) + +# Create test suites +_core_test_suite = TestSuite(['_c_']) +_cpp_test_suite = TestSuite(['_c++_']) +_csharp_test_suite = TestSuite(['_csharp_']) +_node_test_suite = TestSuite(['_node_']) +_objc_test_suite = TestSuite(['_objc_']) +_php_test_suite = TestSuite(['_php_', '_php7_']) +_python_test_suite = TestSuite(['_python_']) +_ruby_test_suite = TestSuite(['_ruby']) +_all_test_suites = [_core_test_suite, _cpp_test_suite, _csharp_test_suite, + _node_test_suite, _objc_test_suite, _php_test_suite, + _python_test_suite, _ruby_test_suite] + +# Dictionary of whitelistable files where the key is a regex matching changed files +# and the value is a list of tests that should be run. An empty list means that +# the changed files should not trigger any tests. Any changed file that does not +# match any of these regexes will trigger all tests +_WHITELIST_DICT = { + '^templates/.*': [], + '^doc/.*': [], + '^examples/.*': [], + '^summerofcode/.*': [], + '.*README.md$': [], + '.*LICENSE$': [], + '^src/cpp.*': [_cpp_test_suite], + '^src/csharp.*': [_csharp_test_suite], + '^src/node.*': [_node_test_suite], + '^src/objective-c.*': [_objc_test_suite], + '^src/php.*': [_php_test_suite], + '^src/python.*': [_python_test_suite], + '^src/ruby.*': [_ruby_test_suite], + '^test/core.*': [_core_test_suite], + '^test/cpp.*': [_cpp_test_suite], + '^test/distrib/cpp.*': [_cpp_test_suite], + '^test/distrib/csharp.*': [_csharp_test_suite], + '^test/distrib/node.*': [_node_test_suite], + '^test/distrib/php.*': [_php_test_suite], + '^test/distrib/python.*': [_python_test_suite], + '^test/distrib/ruby.*': [_ruby_test_suite] +} +# Add all triggers to their respective test suites +for trigger, test_suites in _WHITELIST_DICT.iteritems(): + for test_suite in test_suites: + test_suite.add_trigger(trigger) def _get_changed_files(base_branch): @@ -119,28 +110,22 @@ def _get_changed_files(base_branch): # todo(mattkwong): remove or uncomment below after seeing if Jenkins needs this # call(['git', 'fetch']) - # get file changes between branch and merge-base of specified branch - # not combined to be Windows friendly + # Get file changes between branch and merge-base of specified branch + # Not combined to be Windows friendly base_commit = check_output(["git", "merge-base", base_branch, "HEAD"]).rstrip() return check_output(["git", "diff", base_commit, "--name-only"]).splitlines() -def _can_skip_tests(file_names, starts_with_whitelist=[], ends_with_whitelist=[]): +def _can_skip_tests(file_names, triggers): """ - Determines if tests are skippable based on if all file names do not match - any begin or end triggers + Determines if tests are skippable based on if all files do not match list of regexes :param file_names: list of changed files generated by _get_changed_files() - :param starts_with_triggers: tuple of strings to match with beginning of file names - :param ends_with_triggers: tuple of strings to match with end of file names + :param triggers: list of regexes matching file name that indicates tests should be run :return: safe to skip tests """ - # convert lists to tuple to pass into str.startswith() and str.endswith() - starts_with_whitelist = tuple(starts_with_whitelist) - ends_with_whitelist = tuple(ends_with_whitelist) for file_name in file_names: - if starts_with_whitelist and not file_name.startswith(starts_with_whitelist) and \ - ends_with_whitelist and not file_name.endswith(ends_with_whitelist): - return False + if any(re.match(trigger, file_name) for trigger in triggers): + return False return True @@ -152,30 +137,20 @@ def _remove_irrelevant_tests(tests, tag): :return: list of relevant tests """ # todo(mattkwong): find a more reliable way to filter tests - don't use shortname - return [test for test in tests if - tag not in test.shortname or - '_msan' in test.shortname or - '_asan' in test.shortname or - '_tsan' in test.shortname] + return [test for test in tests if tag not in test.shortname or + any(san_tag in test.shortname for san_tag in ['_asan', '_tsan', '_msan'])] -def _remove_irrelevant_sanitizer_tests(tests, language_tag=""): +def _remove_sanitizer_tests(tests): """ - Filters out sanitizer tests - can specify a language to filter - this should be c++ only + Filters out sanitizer tests :param tests: list of all tests generated by run_tests_matrix.py - :param language_tag: string specifying a language from which to filter sanitizer tests - "_(language)_" :return: list of relevant tests """ - if language_tag: - return [test for test in tests if not language_tag in test.shortname and - not '_asan' in test.shortname and - not '_msan' in test.shortname and - not '_tsan' in test.shortname] - else: - return [test for test in tests if - '_asan' not in test.shortname and - '_msan' not in test.shortname and - '_tsan' not in test.shortname] + # todo(mattkwong): find a more reliable way to filter tests - don't use shortname + return [test for test in tests if + all(san_tag not in test.shortname for san_tag in ['_asan', '_tsan', '_msan'])] + def filter_tests(tests, base_branch): """ @@ -183,71 +158,27 @@ def filter_tests(tests, base_branch): :param tests: list of all tests generated by run_tests_matrix.py :return: list of relevant tests """ - print("Finding file differences between %s repo and current branch..." % base_branch) + print("Finding file differences between %s repo and current branch...\n" % base_branch) changed_files = _get_changed_files(base_branch) for changed_file in changed_files: print(changed_file) + print - # Filter core tests - skip_core = _can_skip_tests(changed_files, - starts_with_whitelist=_filter_whitelist(starts_with_whitelist, core_starts_with_triggers), - ends_with_whitelist=ends_with_whitelist) - if skip_core: - tests = _remove_irrelevant_tests(tests, '_c_') - - # Filter c++ tests - skip_cpp = _can_skip_tests(changed_files, - starts_with_whitelist=_filter_whitelist(starts_with_whitelist, cpp_starts_with_triggers), - ends_with_whitelist=ends_with_whitelist) - if skip_cpp: - tests = _remove_irrelevant_tests(tests, '_c++_') - tests = _remove_irrelevant_sanitizer_tests(tests, language_tag='_c++_') - + # Regex that combines all keys in _WHITELIST_DICT + all_triggers = "(" + ")|(".join(_WHITELIST_DICT.keys()) + ")" + # Check if all tests have to be run + for changed_file in changed_files: + if not re.match(all_triggers, changed_file): + return(tests) + # Filter out tests by language + for test_suite in _all_test_suites: + if _can_skip_tests(changed_files, test_suite.triggers): + for tag in test_suite.tags: + print(" Filtering %s tests" % tag) + tests = _remove_irrelevant_tests(tests, tag) # Sanitizer tests skipped if core and c++ are skipped - if skip_core and skip_cpp: - tests = _remove_irrelevant_sanitizer_tests(tests) - - # Filter c# tests - skip_csharp = _can_skip_tests(changed_files, - starts_with_whitelist=_filter_whitelist(starts_with_whitelist, csharp_starts_with_triggers), - ends_with_whitelist=ends_with_whitelist) - if skip_csharp: - tests = _remove_irrelevant_tests(tests, '_csharp_') - - # Filter node tests - skip_node = _can_skip_tests(changed_files, - starts_with_whitelist=_filter_whitelist(starts_with_whitelist, node_starts_with_triggers), - ends_with_whitelist=ends_with_whitelist) - if skip_node: - tests = _remove_irrelevant_tests(tests, '_node_') - - # Filter objc tests - skip_objc = _can_skip_tests(changed_files, - starts_with_whitelist=_filter_whitelist(starts_with_whitelist, objc_starts_with_triggers), - ends_with_whitelist=ends_with_whitelist) - if skip_objc: - tests = _remove_irrelevant_tests(tests, '_objc_') - - # Filter php tests - skip_php = _can_skip_tests(changed_files, - starts_with_whitelist=_filter_whitelist(starts_with_whitelist, php_starts_with_triggers), - ends_with_whitelist=ends_with_whitelist) - if skip_php: - tests = _remove_irrelevant_tests(tests, '_php_') - tests = _remove_irrelevant_tests(tests, '_php7_') - - # Filter python tests - skip_python = _can_skip_tests(changed_files, - starts_with_whitelist=_filter_whitelist(starts_with_whitelist, python_starts_with_triggers), - ends_with_whitelist=ends_with_whitelist) - if skip_python: - tests = _remove_irrelevant_tests(tests, '_python_') - - # Filter ruby tests - skip_ruby = _can_skip_tests(changed_files, - starts_with_whitelist=_filter_whitelist(starts_with_whitelist, ruby_starts_with_triggers), - ends_with_whitelist=ends_with_whitelist) - if skip_ruby: - tests = _remove_irrelevant_tests(tests, '_ruby_') + if _can_skip_tests(changed_files, _cpp_test_suite.triggers + _core_test_suite.triggers): + print(" Filtering Sanitizer tests") + tests = _remove_sanitizer_tests(tests) return tests diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py index 3cea0f5011..c4be48f0bd 100755 --- a/tools/run_tests/run_tests_matrix.py +++ b/tools/run_tests/run_tests_matrix.py @@ -275,6 +275,7 @@ print if args.filter_pr_tests: print 'IMPORTANT: Test filtering is not active; this is only for testing.' relevant_jobs = filter_tests(jobs, args.base_branch) + # todo(mattkwong): add skipped tests to report.xml print if len(relevant_jobs) == len(jobs): print '(TESTING) No tests will be skipped.' -- cgit v1.2.3 From 460502e5ce71cb132e3be4e932b63cfd4e7f2349 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 13 Oct 2016 10:02:08 -0700 Subject: Expand documentation --- src/core/lib/iomgr/ev_epoll_linux.c | 13 +++++++++++++ src/core/lib/iomgr/exec_ctx.h | 10 ++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/core/lib/iomgr/ev_epoll_linux.c b/src/core/lib/iomgr/ev_epoll_linux.c index 98fe2defea..8de42bb7a9 100644 --- a/src/core/lib/iomgr/ev_epoll_linux.c +++ b/src/core/lib/iomgr/ev_epoll_linux.c @@ -165,6 +165,7 @@ static void fd_global_shutdown(void); #endif /* !defined(GPRC_PI_REF_COUNT_DEBUG) */ +/* This is also used as grpc_workqueue (by directly casing it) */ typedef struct polling_island { gpr_mu mu; /* Ref count. Use PI_ADD_REF() and PI_UNREF() macros to increment/decrement @@ -184,10 +185,16 @@ typedef struct polling_island { * (except mu and ref_count) are invalid and must be ignored. */ gpr_atm merged_to; + /* Number of threads currently polling on this island */ gpr_atm poller_count; + /* Mutex guarding the read end of the workqueue (must be held to pop from + * workqueue_items) */ gpr_mu workqueue_read_mu; + /* Queue of closures to be executed */ gpr_mpscq workqueue_items; + /* Count of items in workqueue_items */ gpr_atm workqueue_item_count; + /* Wakeup fd used to wake pollers to check the contents of workqueue_items */ grpc_wakeup_fd workqueue_wakeup_fd; /* The fd of the underlying epoll set */ @@ -1396,6 +1403,9 @@ static bool maybe_do_workqueue_work(grpc_exec_ctx *exec_ctx, grpc_closure_run(exec_ctx, c, c->error_data.error); return true; } else if (gpr_atm_no_barrier_load(&pi->workqueue_item_count) > 0) { + /* n == NULL might mean there's work but it's not available to be popped + * yet - try to ensure another workqueue wakes up to check shortly if so + */ workqueue_maybe_wakeup(pi); } } @@ -1457,6 +1467,9 @@ static void pollset_work_and_unlock(grpc_exec_ctx *exec_ctx, PI_ADD_REF(pi, "ps_work"); gpr_mu_unlock(&pollset->mu); + /* If we get some workqueue work to do, it might end up completing an item on + the completion queue, so there's no need to poll... so we skip that and + redo the complete loop to verify */ if (!maybe_do_workqueue_work(exec_ctx, pi)) { gpr_atm_no_barrier_fetch_add(&pi->poller_count, 1); g_current_thread_polling_island = pi; diff --git a/src/core/lib/iomgr/exec_ctx.h b/src/core/lib/iomgr/exec_ctx.h index 4744e21c5e..7e50cb9825 100644 --- a/src/core/lib/iomgr/exec_ctx.h +++ b/src/core/lib/iomgr/exec_ctx.h @@ -66,10 +66,20 @@ typedef struct grpc_combiner grpc_combiner; #ifndef GRPC_EXECUTION_CONTEXT_SANITIZER struct grpc_exec_ctx { grpc_closure_list closure_list; + /** The workqueue we're stealing work from. + As items are queued to the execution context, we try to steal one + workqueue item and execute it inline (assuming the exec_ctx is not + finished) - doing so does not invalidate the workqueue's contract, and + provides a small latency win in cases where we get a hit */ grpc_workqueue *stealing_from_workqueue; + /** The workqueue item that was stolen from the workqueue above. When new + items are scheduled to be offloaded to that workqueue, we need to update + this like a 1-deep fifo to maintain the invariant that workqueue items + queued by one thread are started in order */ grpc_closure *stolen_closure; /** currently active combiner: updated only via combiner.c */ grpc_combiner *active_combiner; + /** last active combiner in the active combiner list */ grpc_combiner *last_combiner; bool cached_ready_to_finish; void *check_ready_to_finish_arg; -- cgit v1.2.3 From dd25ccbd93fd01dacbe18cab2410b9f8a15e7107 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 13 Oct 2016 10:34:02 -0700 Subject: Fix 32-bit linux build --- src/core/ext/transport/chttp2/transport/frame_rst_stream.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/transport/chttp2/transport/frame_rst_stream.c b/src/core/ext/transport/chttp2/transport/frame_rst_stream.c index 1bb6ed82b1..9eac050797 100644 --- a/src/core/ext/transport/chttp2/transport/frame_rst_stream.c +++ b/src/core/ext/transport/chttp2/transport/frame_rst_stream.c @@ -111,7 +111,7 @@ grpc_error *grpc_chttp2_rst_stream_parser_parse(grpc_exec_ctx *exec_ctx, grpc_error *error = GRPC_ERROR_NONE; if (reason != GRPC_CHTTP2_NO_ERROR) { error = grpc_error_set_int(GRPC_ERROR_CREATE("RST_STREAM"), - GRPC_ERROR_INT_HTTP2_ERROR, reason); + GRPC_ERROR_INT_HTTP2_ERROR, (intptr_t)reason); grpc_status_code status_code = grpc_chttp2_http2_error_to_grpc_status( (grpc_chttp2_error_code)reason, s->deadline); char *status_details; -- cgit v1.2.3 From 82e4ec741ba3e564d1223f0f20355a6e27e70136 Mon Sep 17 00:00:00 2001 From: Ken Payson Date: Thu, 13 Oct 2016 12:26:01 -0700 Subject: Moved cv polling into ev_poll_posix.c --- BUILD | 8 - CMakeLists.txt | 3 - Makefile | 4 - binding.gyp | 1 - build.yaml | 2 - config.m4 | 1 - gRPC-Core.podspec | 3 - grpc.gemspec | 2 - package.xml | 2 - src/core/lib/iomgr/ev_poll_cv_posix.c | 288 --------------------- src/core/lib/iomgr/ev_poll_cv_posix.h | 68 ----- src/core/lib/iomgr/ev_poll_posix.c | 237 ++++++++++++++++- src/core/lib/iomgr/ev_poll_posix.h | 1 + src/core/lib/iomgr/ev_posix.c | 1 - src/core/lib/iomgr/wakeup_fd_cv.c | 4 +- src/core/lib/iomgr/wakeup_fd_cv.h | 29 ++- src/core/lib/iomgr/wakeup_fd_posix.c | 26 +- src/core/lib/iomgr/wakeup_fd_posix.h | 2 +- src/python/grpcio/grpc_core_dependencies.py | 1 - tools/doxygen/Doxyfile.core.internal | 2 - tools/run_tests/sources_and_headers.json | 3 - vsprojects/vcxproj/grpc/grpc.vcxproj | 3 - vsprojects/vcxproj/grpc/grpc.vcxproj.filters | 6 - .../vcxproj/grpc_test_util/grpc_test_util.vcxproj | 3 - .../grpc_test_util/grpc_test_util.vcxproj.filters | 6 - .../vcxproj/grpc_unsecure/grpc_unsecure.vcxproj | 3 - .../grpc_unsecure/grpc_unsecure.vcxproj.filters | 6 - 27 files changed, 280 insertions(+), 435 deletions(-) delete mode 100644 src/core/lib/iomgr/ev_poll_cv_posix.c delete mode 100644 src/core/lib/iomgr/ev_poll_cv_posix.h diff --git a/BUILD b/BUILD index ba44367dbb..72cb046a60 100644 --- a/BUILD +++ b/BUILD @@ -186,7 +186,6 @@ cc_library( "src/core/lib/iomgr/error.h", "src/core/lib/iomgr/ev_epoll_linux.h", "src/core/lib/iomgr/ev_poll_and_epoll_posix.h", - "src/core/lib/iomgr/ev_poll_cv_posix.h", "src/core/lib/iomgr/ev_poll_posix.h", "src/core/lib/iomgr/ev_posix.h", "src/core/lib/iomgr/exec_ctx.h", @@ -349,7 +348,6 @@ cc_library( "src/core/lib/iomgr/error.c", "src/core/lib/iomgr/ev_epoll_linux.c", "src/core/lib/iomgr/ev_poll_and_epoll_posix.c", - "src/core/lib/iomgr/ev_poll_cv_posix.c", "src/core/lib/iomgr/ev_poll_posix.c", "src/core/lib/iomgr/ev_posix.c", "src/core/lib/iomgr/exec_ctx.c", @@ -591,7 +589,6 @@ cc_library( "src/core/lib/iomgr/error.h", "src/core/lib/iomgr/ev_epoll_linux.h", "src/core/lib/iomgr/ev_poll_and_epoll_posix.h", - "src/core/lib/iomgr/ev_poll_cv_posix.h", "src/core/lib/iomgr/ev_poll_posix.h", "src/core/lib/iomgr/ev_posix.h", "src/core/lib/iomgr/exec_ctx.h", @@ -739,7 +736,6 @@ cc_library( "src/core/lib/iomgr/error.c", "src/core/lib/iomgr/ev_epoll_linux.c", "src/core/lib/iomgr/ev_poll_and_epoll_posix.c", - "src/core/lib/iomgr/ev_poll_cv_posix.c", "src/core/lib/iomgr/ev_poll_posix.c", "src/core/lib/iomgr/ev_posix.c", "src/core/lib/iomgr/exec_ctx.c", @@ -951,7 +947,6 @@ cc_library( "src/core/lib/iomgr/error.h", "src/core/lib/iomgr/ev_epoll_linux.h", "src/core/lib/iomgr/ev_poll_and_epoll_posix.h", - "src/core/lib/iomgr/ev_poll_cv_posix.h", "src/core/lib/iomgr/ev_poll_posix.h", "src/core/lib/iomgr/ev_posix.h", "src/core/lib/iomgr/exec_ctx.h", @@ -1091,7 +1086,6 @@ cc_library( "src/core/lib/iomgr/error.c", "src/core/lib/iomgr/ev_epoll_linux.c", "src/core/lib/iomgr/ev_poll_and_epoll_posix.c", - "src/core/lib/iomgr/ev_poll_cv_posix.c", "src/core/lib/iomgr/ev_poll_posix.c", "src/core/lib/iomgr/ev_posix.c", "src/core/lib/iomgr/exec_ctx.c", @@ -1856,7 +1850,6 @@ objc_library( "src/core/lib/iomgr/error.c", "src/core/lib/iomgr/ev_epoll_linux.c", "src/core/lib/iomgr/ev_poll_and_epoll_posix.c", - "src/core/lib/iomgr/ev_poll_cv_posix.c", "src/core/lib/iomgr/ev_poll_posix.c", "src/core/lib/iomgr/ev_posix.c", "src/core/lib/iomgr/exec_ctx.c", @@ -2077,7 +2070,6 @@ objc_library( "src/core/lib/iomgr/error.h", "src/core/lib/iomgr/ev_epoll_linux.h", "src/core/lib/iomgr/ev_poll_and_epoll_posix.h", - "src/core/lib/iomgr/ev_poll_cv_posix.h", "src/core/lib/iomgr/ev_poll_posix.h", "src/core/lib/iomgr/ev_posix.h", "src/core/lib/iomgr/exec_ctx.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 747d1fab4d..9ba5135593 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -314,7 +314,6 @@ add_library(grpc src/core/lib/iomgr/error.c src/core/lib/iomgr/ev_epoll_linux.c src/core/lib/iomgr/ev_poll_and_epoll_posix.c - src/core/lib/iomgr/ev_poll_cv_posix.c src/core/lib/iomgr/ev_poll_posix.c src/core/lib/iomgr/ev_posix.c src/core/lib/iomgr/exec_ctx.c @@ -575,7 +574,6 @@ add_library(grpc_cronet src/core/lib/iomgr/error.c src/core/lib/iomgr/ev_epoll_linux.c src/core/lib/iomgr/ev_poll_and_epoll_posix.c - src/core/lib/iomgr/ev_poll_cv_posix.c src/core/lib/iomgr/ev_poll_posix.c src/core/lib/iomgr/ev_posix.c src/core/lib/iomgr/exec_ctx.c @@ -808,7 +806,6 @@ add_library(grpc_unsecure src/core/lib/iomgr/error.c src/core/lib/iomgr/ev_epoll_linux.c src/core/lib/iomgr/ev_poll_and_epoll_posix.c - src/core/lib/iomgr/ev_poll_cv_posix.c src/core/lib/iomgr/ev_poll_posix.c src/core/lib/iomgr/ev_posix.c src/core/lib/iomgr/exec_ctx.c diff --git a/Makefile b/Makefile index 1f4c9b5c32..65d715c67c 100644 --- a/Makefile +++ b/Makefile @@ -2562,7 +2562,6 @@ LIBGRPC_SRC = \ src/core/lib/iomgr/error.c \ src/core/lib/iomgr/ev_epoll_linux.c \ src/core/lib/iomgr/ev_poll_and_epoll_posix.c \ - src/core/lib/iomgr/ev_poll_cv_posix.c \ src/core/lib/iomgr/ev_poll_posix.c \ src/core/lib/iomgr/ev_posix.c \ src/core/lib/iomgr/exec_ctx.c \ @@ -2841,7 +2840,6 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/iomgr/error.c \ src/core/lib/iomgr/ev_epoll_linux.c \ src/core/lib/iomgr/ev_poll_and_epoll_posix.c \ - src/core/lib/iomgr/ev_poll_cv_posix.c \ src/core/lib/iomgr/ev_poll_posix.c \ src/core/lib/iomgr/ev_posix.c \ src/core/lib/iomgr/exec_ctx.c \ @@ -3110,7 +3108,6 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/lib/iomgr/error.c \ src/core/lib/iomgr/ev_epoll_linux.c \ src/core/lib/iomgr/ev_poll_and_epoll_posix.c \ - src/core/lib/iomgr/ev_poll_cv_posix.c \ src/core/lib/iomgr/ev_poll_posix.c \ src/core/lib/iomgr/ev_posix.c \ src/core/lib/iomgr/exec_ctx.c \ @@ -3306,7 +3303,6 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/iomgr/error.c \ src/core/lib/iomgr/ev_epoll_linux.c \ src/core/lib/iomgr/ev_poll_and_epoll_posix.c \ - src/core/lib/iomgr/ev_poll_cv_posix.c \ src/core/lib/iomgr/ev_poll_posix.c \ src/core/lib/iomgr/ev_posix.c \ src/core/lib/iomgr/exec_ctx.c \ diff --git a/binding.gyp b/binding.gyp index 85070e5cac..6dfae41860 100644 --- a/binding.gyp +++ b/binding.gyp @@ -589,7 +589,6 @@ 'src/core/lib/iomgr/error.c', 'src/core/lib/iomgr/ev_epoll_linux.c', 'src/core/lib/iomgr/ev_poll_and_epoll_posix.c', - 'src/core/lib/iomgr/ev_poll_cv_posix.c', 'src/core/lib/iomgr/ev_poll_posix.c', 'src/core/lib/iomgr/ev_posix.c', 'src/core/lib/iomgr/exec_ctx.c', diff --git a/build.yaml b/build.yaml index 3e64ce8f37..93ebf44ef8 100644 --- a/build.yaml +++ b/build.yaml @@ -190,7 +190,6 @@ filegroups: - src/core/lib/iomgr/error.h - src/core/lib/iomgr/ev_epoll_linux.h - src/core/lib/iomgr/ev_poll_and_epoll_posix.h - - src/core/lib/iomgr/ev_poll_cv_posix.h - src/core/lib/iomgr/ev_poll_posix.h - src/core/lib/iomgr/ev_posix.h - src/core/lib/iomgr/exec_ctx.h @@ -276,7 +275,6 @@ filegroups: - src/core/lib/iomgr/error.c - src/core/lib/iomgr/ev_epoll_linux.c - src/core/lib/iomgr/ev_poll_and_epoll_posix.c - - src/core/lib/iomgr/ev_poll_cv_posix.c - src/core/lib/iomgr/ev_poll_posix.c - src/core/lib/iomgr/ev_posix.c - src/core/lib/iomgr/exec_ctx.c diff --git a/config.m4 b/config.m4 index 1452798897..347686bd11 100644 --- a/config.m4 +++ b/config.m4 @@ -108,7 +108,6 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/iomgr/error.c \ src/core/lib/iomgr/ev_epoll_linux.c \ src/core/lib/iomgr/ev_poll_and_epoll_posix.c \ - src/core/lib/iomgr/ev_poll_cv_posix.c \ src/core/lib/iomgr/ev_poll_posix.c \ src/core/lib/iomgr/ev_posix.c \ src/core/lib/iomgr/exec_ctx.c \ diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 3ac0b841cf..6becf4c608 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -273,7 +273,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/error.h', 'src/core/lib/iomgr/ev_epoll_linux.h', 'src/core/lib/iomgr/ev_poll_and_epoll_posix.h', - 'src/core/lib/iomgr/ev_poll_cv_posix.h', 'src/core/lib/iomgr/ev_poll_posix.h', 'src/core/lib/iomgr/ev_posix.h', 'src/core/lib/iomgr/exec_ctx.h', @@ -440,7 +439,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/error.c', 'src/core/lib/iomgr/ev_epoll_linux.c', 'src/core/lib/iomgr/ev_poll_and_epoll_posix.c', - 'src/core/lib/iomgr/ev_poll_cv_posix.c', 'src/core/lib/iomgr/ev_poll_posix.c', 'src/core/lib/iomgr/ev_posix.c', 'src/core/lib/iomgr/exec_ctx.c', @@ -650,7 +648,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/error.h', 'src/core/lib/iomgr/ev_epoll_linux.h', 'src/core/lib/iomgr/ev_poll_and_epoll_posix.h', - 'src/core/lib/iomgr/ev_poll_cv_posix.h', 'src/core/lib/iomgr/ev_poll_posix.h', 'src/core/lib/iomgr/ev_posix.h', 'src/core/lib/iomgr/exec_ctx.h', diff --git a/grpc.gemspec b/grpc.gemspec index 85135a5327..6a898b85ff 100755 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -193,7 +193,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/error.h ) s.files += %w( src/core/lib/iomgr/ev_epoll_linux.h ) s.files += %w( src/core/lib/iomgr/ev_poll_and_epoll_posix.h ) - s.files += %w( src/core/lib/iomgr/ev_poll_cv_posix.h ) s.files += %w( src/core/lib/iomgr/ev_poll_posix.h ) s.files += %w( src/core/lib/iomgr/ev_posix.h ) s.files += %w( src/core/lib/iomgr/exec_ctx.h ) @@ -360,7 +359,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/error.c ) s.files += %w( src/core/lib/iomgr/ev_epoll_linux.c ) s.files += %w( src/core/lib/iomgr/ev_poll_and_epoll_posix.c ) - s.files += %w( src/core/lib/iomgr/ev_poll_cv_posix.c ) s.files += %w( src/core/lib/iomgr/ev_poll_posix.c ) s.files += %w( src/core/lib/iomgr/ev_posix.c ) s.files += %w( src/core/lib/iomgr/exec_ctx.c ) diff --git a/package.xml b/package.xml index 4631fc1c39..1f9846a516 100644 --- a/package.xml +++ b/package.xml @@ -200,7 +200,6 @@ - @@ -367,7 +366,6 @@ - diff --git a/src/core/lib/iomgr/ev_poll_cv_posix.c b/src/core/lib/iomgr/ev_poll_cv_posix.c deleted file mode 100644 index ed4c9e9143..0000000000 --- a/src/core/lib/iomgr/ev_poll_cv_posix.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * - * Copyright 2016, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include - -#ifdef GPR_POSIX_SOCKET - -#include "src/core/lib/iomgr/ev_poll_cv_posix.h" - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "src/core/lib/iomgr/ev_poll_posix.h" -#include "src/core/lib/iomgr/wakeup_fd_posix.h" - -#define POLL_PERIOD_MS 1000 -#define DEFAULT_TABLE_SIZE 16 - -typedef enum status_t { INPROGRESS, COMPLETED, CANCELLED } status_t; - -typedef struct poll_args { - gpr_refcount refcount; - gpr_cv* cv; - struct pollfd* fds; - nfds_t nfds; - int timeout; - int retval; - int err; - status_t status; -} poll_args; - -cv_fd_table g_cvfds; - -static void decref_poll_args(poll_args* args) { - if (gpr_unref(&args->refcount)) { - gpr_free(args->fds); - gpr_cv_destroy(args->cv); - gpr_free(args->cv); - gpr_free(args); - } -} - -// Poll in a background thread -static void run_poll(void* arg) { - int timeout, retval; - poll_args* pargs = (poll_args*)arg; - while (pargs->status == INPROGRESS) { - if (pargs->timeout < 0) { - timeout = POLL_PERIOD_MS; - } else { - timeout = GPR_MIN(POLL_PERIOD_MS, pargs->timeout); - pargs->timeout -= timeout; - } - retval = g_cvfds.poll(pargs->fds, pargs->nfds, timeout); - if (retval != 0 || pargs->timeout == 0) { - pargs->retval = retval; - pargs->err = errno; - break; - } - } - gpr_mu_lock(&g_cvfds.mu); - if (pargs->status == INPROGRESS) { - // Signal main thread that the poll completed - pargs->status = COMPLETED; - gpr_cv_signal(pargs->cv); - } - decref_poll_args(pargs); - g_cvfds.pollcount--; - if (g_cvfds.shutdown && g_cvfds.pollcount == 0) { - gpr_cv_signal(&g_cvfds.shutdown_complete); - } - gpr_mu_unlock(&g_cvfds.mu); -} - -// This function overrides poll() to handle condition variable wakeup fds -static int cvfd_poll(struct pollfd* fds, nfds_t nfds, int timeout) { - unsigned int i; - int res, idx; - gpr_cv* pollcv; - cv_node *cvn, *prev; - nfds_t nsockfds = 0; - gpr_thd_id t_id; - gpr_thd_options opt; - poll_args* pargs = NULL; - gpr_mu_lock(&g_cvfds.mu); - pollcv = gpr_malloc(sizeof(gpr_cv)); - gpr_cv_init(pollcv); - for (i = 0; i < nfds; i++) { - fds[i].revents = 0; - if (fds[i].fd < 0 && (fds[i].events & POLLIN)) { - idx = FD_TO_IDX(fds[i].fd); - cvn = gpr_malloc(sizeof(cv_node)); - cvn->cv = pollcv; - cvn->next = g_cvfds.cvfds[idx].cvs; - g_cvfds.cvfds[idx].cvs = cvn; - // We should return immediately if there are pending events, - // but we still need to call poll() to check for socket events - if (g_cvfds.cvfds[idx].is_set) { - timeout = 0; - } - } else if (fds[i].fd >= 0) { - nsockfds++; - } - } - - if (nsockfds > 0) { - pargs = gpr_malloc(sizeof(struct poll_args)); - // Both the main thread and calling thread get a reference - gpr_ref_init(&pargs->refcount, 2); - pargs->cv = pollcv; - pargs->fds = gpr_malloc(sizeof(struct pollfd) * nsockfds); - pargs->nfds = nsockfds; - pargs->timeout = timeout; - pargs->retval = 0; - pargs->err = 0; - pargs->status = INPROGRESS; - idx = 0; - for (i = 0; i < nfds; i++) { - if (fds[i].fd >= 0) { - pargs->fds[idx].fd = fds[i].fd; - pargs->fds[idx].events = fds[i].events; - pargs->fds[idx].revents = 0; - idx++; - } - } - g_cvfds.pollcount++; - opt = gpr_thd_options_default(); - gpr_thd_options_set_detached(&opt); - gpr_thd_new(&t_id, &run_poll, pargs, &opt); - // We want the poll() thread to trigger the deadline, so wait forever here - gpr_cv_wait(pollcv, &g_cvfds.mu, gpr_inf_future(GPR_CLOCK_MONOTONIC)); - if (pargs->status == COMPLETED) { - res = pargs->retval; - errno = pargs->err; - } else { - res = 0; - errno = 0; - pargs->status = CANCELLED; - } - } else { - gpr_timespec deadline = gpr_now(GPR_CLOCK_REALTIME); - deadline = - gpr_time_add(deadline, gpr_time_from_millis(timeout, GPR_TIMESPAN)); - gpr_cv_wait(pollcv, &g_cvfds.mu, deadline); - res = 0; - } - - idx = 0; - for (i = 0; i < nfds; i++) { - if (fds[i].fd < 0 && (fds[i].events & POLLIN)) { - cvn = g_cvfds.cvfds[FD_TO_IDX(fds[i].fd)].cvs; - prev = NULL; - while (cvn->cv != pollcv) { - prev = cvn; - cvn = cvn->next; - GPR_ASSERT(cvn); - } - if (!prev) { - g_cvfds.cvfds[FD_TO_IDX(fds[i].fd)].cvs = cvn->next; - } else { - prev->next = cvn->next; - } - gpr_free(cvn); - - if (g_cvfds.cvfds[FD_TO_IDX(fds[i].fd)].is_set) { - fds[i].revents = POLLIN; - if (res >= 0) res++; - } - } else if (fds[i].fd >= 0 && pargs->status == COMPLETED) { - fds[i].revents = pargs->fds[idx].revents; - idx++; - } - } - - if (pargs) { - decref_poll_args(pargs); - } else { - gpr_cv_destroy(pollcv); - gpr_free(pollcv); - } - gpr_mu_unlock(&g_cvfds.mu); - - return res; -} - -static void grpc_global_cv_fd_table_init() { - gpr_mu_init(&g_cvfds.mu); - gpr_mu_lock(&g_cvfds.mu); - gpr_cv_init(&g_cvfds.shutdown_complete); - g_cvfds.shutdown = 0; - g_cvfds.pollcount = 0; - g_cvfds.size = DEFAULT_TABLE_SIZE; - g_cvfds.cvfds = gpr_malloc(sizeof(fd_node) * DEFAULT_TABLE_SIZE); - g_cvfds.free_fds = NULL; - for (int i = 0; i < DEFAULT_TABLE_SIZE; i++) { - g_cvfds.cvfds[i].is_set = 0; - g_cvfds.cvfds[i].cvs = NULL; - g_cvfds.cvfds[i].next_free = g_cvfds.free_fds; - g_cvfds.free_fds = &g_cvfds.cvfds[i]; - } - // Override the poll function with one that supports cvfds - g_cvfds.poll = grpc_poll_function; - grpc_poll_function = &cvfd_poll; - gpr_mu_unlock(&g_cvfds.mu); -} - -static void grpc_global_cv_fd_table_shutdown() { - gpr_mu_lock(&g_cvfds.mu); - g_cvfds.shutdown = 1; - // Attempt to wait for all abandoned poll() threads to terminate - // Not doing so will result in reported memory leaks - if (g_cvfds.pollcount > 0) { - int res = gpr_cv_wait(&g_cvfds.shutdown_complete, &g_cvfds.mu, - gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_seconds(3, GPR_TIMESPAN))); - GPR_ASSERT(res == 0); - } - gpr_cv_destroy(&g_cvfds.shutdown_complete); - grpc_poll_function = g_cvfds.poll; - gpr_free(g_cvfds.cvfds); - gpr_mu_unlock(&g_cvfds.mu); - gpr_mu_destroy(&g_cvfds.mu); -} - -/******************************************************************************* - * event engine binding - */ - -static const grpc_event_engine_vtable* ev_poll_vtable; -static grpc_event_engine_vtable vtable; - -static void shutdown_engine(void) { - ev_poll_vtable->shutdown_engine(); - grpc_global_cv_fd_table_shutdown(); -} - -const grpc_event_engine_vtable* grpc_init_poll_cv_posix(void) { - grpc_global_cv_fd_table_init(); - grpc_enable_cv_wakeup_fds(1); - ev_poll_vtable = grpc_init_poll_posix(); - if (!ev_poll_vtable) { - grpc_global_cv_fd_table_shutdown(); - grpc_enable_cv_wakeup_fds(0); - return NULL; - } - vtable = *ev_poll_vtable; - vtable.shutdown_engine = shutdown_engine; - return &vtable; -} - -#endif /* GPR_POSIX_SOCKET */ diff --git a/src/core/lib/iomgr/ev_poll_cv_posix.h b/src/core/lib/iomgr/ev_poll_cv_posix.h deleted file mode 100644 index 885711d1c5..0000000000 --- a/src/core/lib/iomgr/ev_poll_cv_posix.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * - * Copyright 2016, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef GRPC_CORE_LIB_IOMGR_EV_POLL_CV_POSIX_H -#define GRPC_CORE_LIB_IOMGR_EV_POLL_CV_POSIX_H - -#include - -#include "src/core/lib/iomgr/ev_posix.h" - -#define FD_TO_IDX(fd) (-(fd)-1) -#define IDX_TO_FD(idx) (-(idx)-1) - -typedef struct cv_node { - gpr_cv* cv; - struct cv_node* next; -} cv_node; - -typedef struct fd_node { - int is_set; - cv_node* cvs; - struct fd_node* next_free; -} fd_node; - -typedef struct cv_fd_table { - gpr_mu mu; - int pollcount; - int shutdown; - gpr_cv shutdown_complete; - fd_node* cvfds; - fd_node* free_fds; - unsigned int size; - grpc_poll_function_type poll; -} cv_fd_table; - -const grpc_event_engine_vtable* grpc_init_poll_cv_posix(void); - -#endif /* GRPC_CORE_LIB_IOMGR_EV_POLL_CV_POSIX_H */ diff --git a/src/core/lib/iomgr/ev_poll_posix.c b/src/core/lib/iomgr/ev_poll_posix.c index 0dca51bc78..d9e5255ddc 100644 --- a/src/core/lib/iomgr/ev_poll_posix.c +++ b/src/core/lib/iomgr/ev_poll_posix.c @@ -47,10 +47,12 @@ #include #include #include +#include #include #include #include "src/core/lib/iomgr/iomgr_internal.h" +#include "src/core/lib/iomgr/wakeup_fd_cv.h" #include "src/core/lib/iomgr/wakeup_fd_posix.h" #include "src/core/lib/profiling/timers.h" #include "src/core/lib/support/block_annotate.h" @@ -245,6 +247,28 @@ struct grpc_pollset_set { grpc_fd **fds; }; +/******************************************************************************* + * condition variable polling definitions + */ + +#define CV_POLL_PERIOD_MS 1000 +#define CV_DEFAULT_TABLE_SIZE 16 + +typedef enum status_t { INPROGRESS, COMPLETED, CANCELLED } status_t; + +typedef struct poll_args { + gpr_refcount refcount; + gpr_cv *cv; + struct pollfd *fds; + nfds_t nfds; + int timeout; + int retval; + int err; + status_t status; +} poll_args; + +cv_fd_table g_cvfds; + /******************************************************************************* * fd_posix.c */ @@ -1235,11 +1259,211 @@ static void pollset_set_del_fd(grpc_exec_ctx *exec_ctx, gpr_mu_unlock(&pollset_set->mu); } +/******************************************************************************* + * Condition Variable polling extensions + */ + +static void decref_poll_args(poll_args *args) { + if (gpr_unref(&args->refcount)) { + gpr_free(args->fds); + gpr_cv_destroy(args->cv); + gpr_free(args->cv); + gpr_free(args); + } +} + +// Poll in a background thread +static void run_poll(void *arg) { + int timeout, retval; + poll_args *pargs = (poll_args *)arg; + while (pargs->status == INPROGRESS) { + if (pargs->timeout < 0) { + timeout = CV_POLL_PERIOD_MS; + } else { + timeout = GPR_MIN(CV_POLL_PERIOD_MS, pargs->timeout); + pargs->timeout -= timeout; + } + retval = g_cvfds.poll(pargs->fds, pargs->nfds, timeout); + if (retval != 0 || pargs->timeout == 0) { + pargs->retval = retval; + pargs->err = errno; + break; + } + } + gpr_mu_lock(&g_cvfds.mu); + if (pargs->status == INPROGRESS) { + // Signal main thread that the poll completed + pargs->status = COMPLETED; + gpr_cv_signal(pargs->cv); + } + decref_poll_args(pargs); + g_cvfds.pollcount--; + if (g_cvfds.shutdown && g_cvfds.pollcount == 0) { + gpr_cv_signal(&g_cvfds.shutdown_complete); + } + gpr_mu_unlock(&g_cvfds.mu); +} + +// This function overrides poll() to handle condition variable wakeup fds +static int cvfd_poll(struct pollfd *fds, nfds_t nfds, int timeout) { + unsigned int i; + int res, idx; + gpr_cv *pollcv; + cv_node *cvn, *prev; + nfds_t nsockfds = 0; + gpr_thd_id t_id; + gpr_thd_options opt; + poll_args *pargs = NULL; + gpr_mu_lock(&g_cvfds.mu); + pollcv = gpr_malloc(sizeof(gpr_cv)); + gpr_cv_init(pollcv); + for (i = 0; i < nfds; i++) { + fds[i].revents = 0; + if (fds[i].fd < 0 && (fds[i].events & POLLIN)) { + idx = FD_TO_IDX(fds[i].fd); + cvn = gpr_malloc(sizeof(cv_node)); + cvn->cv = pollcv; + cvn->next = g_cvfds.cvfds[idx].cvs; + g_cvfds.cvfds[idx].cvs = cvn; + // We should return immediately if there are pending events, + // but we still need to call poll() to check for socket events + if (g_cvfds.cvfds[idx].is_set) { + timeout = 0; + } + } else if (fds[i].fd >= 0) { + nsockfds++; + } + } + + if (nsockfds > 0) { + pargs = gpr_malloc(sizeof(struct poll_args)); + // Both the main thread and calling thread get a reference + gpr_ref_init(&pargs->refcount, 2); + pargs->cv = pollcv; + pargs->fds = gpr_malloc(sizeof(struct pollfd) * nsockfds); + pargs->nfds = nsockfds; + pargs->timeout = timeout; + pargs->retval = 0; + pargs->err = 0; + pargs->status = INPROGRESS; + idx = 0; + for (i = 0; i < nfds; i++) { + if (fds[i].fd >= 0) { + pargs->fds[idx].fd = fds[i].fd; + pargs->fds[idx].events = fds[i].events; + pargs->fds[idx].revents = 0; + idx++; + } + } + g_cvfds.pollcount++; + opt = gpr_thd_options_default(); + gpr_thd_options_set_detached(&opt); + gpr_thd_new(&t_id, &run_poll, pargs, &opt); + // We want the poll() thread to trigger the deadline, so wait forever here + gpr_cv_wait(pollcv, &g_cvfds.mu, gpr_inf_future(GPR_CLOCK_MONOTONIC)); + if (pargs->status == COMPLETED) { + res = pargs->retval; + errno = pargs->err; + } else { + res = 0; + errno = 0; + pargs->status = CANCELLED; + } + } else { + gpr_timespec deadline = gpr_now(GPR_CLOCK_REALTIME); + deadline = + gpr_time_add(deadline, gpr_time_from_millis(timeout, GPR_TIMESPAN)); + gpr_cv_wait(pollcv, &g_cvfds.mu, deadline); + res = 0; + } + + idx = 0; + for (i = 0; i < nfds; i++) { + if (fds[i].fd < 0 && (fds[i].events & POLLIN)) { + cvn = g_cvfds.cvfds[FD_TO_IDX(fds[i].fd)].cvs; + prev = NULL; + while (cvn->cv != pollcv) { + prev = cvn; + cvn = cvn->next; + GPR_ASSERT(cvn); + } + if (!prev) { + g_cvfds.cvfds[FD_TO_IDX(fds[i].fd)].cvs = cvn->next; + } else { + prev->next = cvn->next; + } + gpr_free(cvn); + + if (g_cvfds.cvfds[FD_TO_IDX(fds[i].fd)].is_set) { + fds[i].revents = POLLIN; + if (res >= 0) res++; + } + } else if (fds[i].fd >= 0 && pargs->status == COMPLETED) { + fds[i].revents = pargs->fds[idx].revents; + idx++; + } + } + + if (pargs) { + decref_poll_args(pargs); + } else { + gpr_cv_destroy(pollcv); + gpr_free(pollcv); + } + gpr_mu_unlock(&g_cvfds.mu); + + return res; +} + +static void global_cv_fd_table_init() { + gpr_mu_init(&g_cvfds.mu); + gpr_mu_lock(&g_cvfds.mu); + gpr_cv_init(&g_cvfds.shutdown_complete); + g_cvfds.shutdown = 0; + g_cvfds.pollcount = 0; + g_cvfds.size = CV_DEFAULT_TABLE_SIZE; + g_cvfds.cvfds = gpr_malloc(sizeof(fd_node) * CV_DEFAULT_TABLE_SIZE); + g_cvfds.free_fds = NULL; + for (int i = 0; i < CV_DEFAULT_TABLE_SIZE; i++) { + g_cvfds.cvfds[i].is_set = 0; + g_cvfds.cvfds[i].cvs = NULL; + g_cvfds.cvfds[i].next_free = g_cvfds.free_fds; + g_cvfds.free_fds = &g_cvfds.cvfds[i]; + } + // Override the poll function with one that supports cvfds + g_cvfds.poll = grpc_poll_function; + grpc_poll_function = &cvfd_poll; + gpr_mu_unlock(&g_cvfds.mu); +} + +static void global_cv_fd_table_shutdown() { + gpr_mu_lock(&g_cvfds.mu); + g_cvfds.shutdown = 1; + // Attempt to wait for all abandoned poll() threads to terminate + // Not doing so will result in reported memory leaks + if (g_cvfds.pollcount > 0) { + int res = gpr_cv_wait(&g_cvfds.shutdown_complete, &g_cvfds.mu, + gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), + gpr_time_from_seconds(3, GPR_TIMESPAN))); + GPR_ASSERT(res == 0); + } + gpr_cv_destroy(&g_cvfds.shutdown_complete); + grpc_poll_function = g_cvfds.poll; + gpr_free(g_cvfds.cvfds); + gpr_mu_unlock(&g_cvfds.mu); + gpr_mu_destroy(&g_cvfds.mu); +} + /******************************************************************************* * event engine binding */ -static void shutdown_engine(void) { pollset_global_shutdown(); } +static void shutdown_engine(void) { + pollset_global_shutdown(); + if (grpc_cv_wakeup_fds_enabled()) { + global_cv_fd_table_shutdown(); + } +} static const grpc_event_engine_vtable vtable = { .pollset_size = sizeof(grpc_pollset), @@ -1286,4 +1510,15 @@ const grpc_event_engine_vtable *grpc_init_poll_posix(void) { return &vtable; } +const grpc_event_engine_vtable *grpc_init_poll_cv_posix(void) { + global_cv_fd_table_init(); + grpc_enable_cv_wakeup_fds(1); + if (!GRPC_LOG_IF_ERROR("pollset_global_init", pollset_global_init())) { + global_cv_fd_table_shutdown(); + grpc_enable_cv_wakeup_fds(0); + return NULL; + } + return &vtable; +} + #endif diff --git a/src/core/lib/iomgr/ev_poll_posix.h b/src/core/lib/iomgr/ev_poll_posix.h index 291736a2db..202ffca14c 100644 --- a/src/core/lib/iomgr/ev_poll_posix.h +++ b/src/core/lib/iomgr/ev_poll_posix.h @@ -37,5 +37,6 @@ #include "src/core/lib/iomgr/ev_posix.h" const grpc_event_engine_vtable *grpc_init_poll_posix(void); +const grpc_event_engine_vtable *grpc_init_poll_cv_posix(void); #endif /* GRPC_CORE_LIB_IOMGR_EV_POLL_POSIX_H */ diff --git a/src/core/lib/iomgr/ev_posix.c b/src/core/lib/iomgr/ev_posix.c index 2fc8ccfa91..0637f80421 100644 --- a/src/core/lib/iomgr/ev_posix.c +++ b/src/core/lib/iomgr/ev_posix.c @@ -46,7 +46,6 @@ #include "src/core/lib/iomgr/ev_epoll_linux.h" #include "src/core/lib/iomgr/ev_poll_and_epoll_posix.h" -#include "src/core/lib/iomgr/ev_poll_cv_posix.h" #include "src/core/lib/iomgr/ev_poll_posix.h" #include "src/core/lib/support/env.h" diff --git a/src/core/lib/iomgr/wakeup_fd_cv.c b/src/core/lib/iomgr/wakeup_fd_cv.c index 651e2f663d..b4165208ed 100644 --- a/src/core/lib/iomgr/wakeup_fd_cv.c +++ b/src/core/lib/iomgr/wakeup_fd_cv.c @@ -35,6 +35,8 @@ #ifdef GPR_POSIX_WAKEUP_FD +#include "src/core/lib/iomgr/wakeup_fd_cv.h" + #include #include @@ -45,8 +47,6 @@ #include #include -#include "src/core/lib/iomgr/ev_poll_cv_posix.h" - #define MAX_TABLE_RESIZE 256 extern cv_fd_table g_cvfds; diff --git a/src/core/lib/iomgr/wakeup_fd_cv.h b/src/core/lib/iomgr/wakeup_fd_cv.h index e57fc28363..ac16be1750 100644 --- a/src/core/lib/iomgr/wakeup_fd_cv.h +++ b/src/core/lib/iomgr/wakeup_fd_cv.h @@ -48,8 +48,33 @@ #ifndef GRPC_CORE_LIB_IOMGR_WAKEUP_FD_CV_H #define GRPC_CORE_LIB_IOMGR_WAKEUP_FD_CV_H -#include "src/core/lib/iomgr/wakeup_fd_posix.h" +#include -extern grpc_wakeup_fd_vtable grpc_cv_wakeup_fd_vtable; +#include "src/core/lib/iomgr/ev_posix.h" + +#define FD_TO_IDX(fd) (-(fd)-1) +#define IDX_TO_FD(idx) (-(idx)-1) + +typedef struct cv_node { + gpr_cv* cv; + struct cv_node* next; +} cv_node; + +typedef struct fd_node { + int is_set; + cv_node* cvs; + struct fd_node* next_free; +} fd_node; + +typedef struct cv_fd_table { + gpr_mu mu; + int pollcount; + int shutdown; + gpr_cv shutdown_complete; + fd_node* cvfds; + fd_node* free_fds; + unsigned int size; + grpc_poll_function_type poll; +} cv_fd_table; #endif /* GRPC_CORE_LIB_IOMGR_WAKEUP_FD_CV_H */ diff --git a/src/core/lib/iomgr/wakeup_fd_posix.c b/src/core/lib/iomgr/wakeup_fd_posix.c index f75ae78c22..5c894bef37 100644 --- a/src/core/lib/iomgr/wakeup_fd_posix.c +++ b/src/core/lib/iomgr/wakeup_fd_posix.c @@ -40,12 +40,14 @@ #include "src/core/lib/iomgr/wakeup_fd_pipe.h" #include "src/core/lib/iomgr/wakeup_fd_posix.h" +extern grpc_wakeup_fd_vtable grpc_cv_wakeup_fd_vtable; static const grpc_wakeup_fd_vtable *wakeup_fd_vtable = NULL; int grpc_allow_specialized_wakeup_fd = 1; int grpc_allow_pipe_wakeup_fd = 1; -int grpc_has_real_wakeup_fd = 1; -int grpc_cv_wakeup_fds_enabled = 0; + +int has_real_wakeup_fd = 1; +int cv_wakeup_fds_enabled = 0; void grpc_wakeup_fd_global_init(void) { if (grpc_allow_specialized_wakeup_fd && @@ -55,43 +57,41 @@ void grpc_wakeup_fd_global_init(void) { grpc_pipe_wakeup_fd_vtable.check_availability()) { wakeup_fd_vtable = &grpc_pipe_wakeup_fd_vtable; } else { - grpc_has_real_wakeup_fd = 0; + has_real_wakeup_fd = 0; } } void grpc_wakeup_fd_global_destroy(void) { wakeup_fd_vtable = NULL; } -int grpc_has_wakeup_fd(void) { - return grpc_has_real_wakeup_fd || grpc_cv_wakeup_fds_enabled; -} +int grpc_has_wakeup_fd(void) { return has_real_wakeup_fd; } -void grpc_enable_cv_wakeup_fds(int enable) { - grpc_cv_wakeup_fds_enabled = enable; -} +int grpc_cv_wakeup_fds_enabled(void) { return cv_wakeup_fds_enabled; } + +void grpc_enable_cv_wakeup_fds(int enable) { cv_wakeup_fds_enabled = enable; } grpc_error *grpc_wakeup_fd_init(grpc_wakeup_fd *fd_info) { - if (grpc_cv_wakeup_fds_enabled) { + if (cv_wakeup_fds_enabled) { return grpc_cv_wakeup_fd_vtable.init(fd_info); } return wakeup_fd_vtable->init(fd_info); } grpc_error *grpc_wakeup_fd_consume_wakeup(grpc_wakeup_fd *fd_info) { - if (grpc_cv_wakeup_fds_enabled) { + if (cv_wakeup_fds_enabled) { return grpc_cv_wakeup_fd_vtable.consume(fd_info); } return wakeup_fd_vtable->consume(fd_info); } grpc_error *grpc_wakeup_fd_wakeup(grpc_wakeup_fd *fd_info) { - if (grpc_cv_wakeup_fds_enabled) { + if (cv_wakeup_fds_enabled) { return grpc_cv_wakeup_fd_vtable.wakeup(fd_info); } return wakeup_fd_vtable->wakeup(fd_info); } void grpc_wakeup_fd_destroy(grpc_wakeup_fd *fd_info) { - if (grpc_cv_wakeup_fds_enabled) { + if (cv_wakeup_fds_enabled) { grpc_cv_wakeup_fd_vtable.destroy(fd_info); } else { wakeup_fd_vtable->destroy(fd_info); diff --git a/src/core/lib/iomgr/wakeup_fd_posix.h b/src/core/lib/iomgr/wakeup_fd_posix.h index 243c452751..71d32d97ba 100644 --- a/src/core/lib/iomgr/wakeup_fd_posix.h +++ b/src/core/lib/iomgr/wakeup_fd_posix.h @@ -72,6 +72,7 @@ void grpc_wakeup_fd_global_destroy(void); void grpc_wakeup_fd_global_init_force_fallback(void); int grpc_has_wakeup_fd(void); +int grpc_cv_wakeup_fds_enabled(void); void grpc_enable_cv_wakeup_fds(int enable); typedef struct grpc_wakeup_fd grpc_wakeup_fd; @@ -92,7 +93,6 @@ struct grpc_wakeup_fd { extern int grpc_allow_specialized_wakeup_fd; extern int grpc_allow_pipe_wakeup_fd; -extern int grpc_has_real_wakeup_fd; #define GRPC_WAKEUP_FD_GET_READ_FD(fd_info) ((fd_info)->read_fd) diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 62d9729e13..98974878fc 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -102,7 +102,6 @@ CORE_SOURCE_FILES = [ 'src/core/lib/iomgr/error.c', 'src/core/lib/iomgr/ev_epoll_linux.c', 'src/core/lib/iomgr/ev_poll_and_epoll_posix.c', - 'src/core/lib/iomgr/ev_poll_cv_posix.c', 'src/core/lib/iomgr/ev_poll_posix.c', 'src/core/lib/iomgr/ev_posix.c', 'src/core/lib/iomgr/exec_ctx.c', diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 1ec177cdf3..0c92e270c8 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -810,7 +810,6 @@ src/core/lib/iomgr/endpoint_pair.h \ src/core/lib/iomgr/error.h \ src/core/lib/iomgr/ev_epoll_linux.h \ src/core/lib/iomgr/ev_poll_and_epoll_posix.h \ -src/core/lib/iomgr/ev_poll_cv_posix.h \ src/core/lib/iomgr/ev_poll_posix.h \ src/core/lib/iomgr/ev_posix.h \ src/core/lib/iomgr/exec_ctx.h \ @@ -977,7 +976,6 @@ src/core/lib/iomgr/endpoint_pair_windows.c \ src/core/lib/iomgr/error.c \ src/core/lib/iomgr/ev_epoll_linux.c \ src/core/lib/iomgr/ev_poll_and_epoll_posix.c \ -src/core/lib/iomgr/ev_poll_cv_posix.c \ src/core/lib/iomgr/ev_poll_posix.c \ src/core/lib/iomgr/ev_posix.c \ src/core/lib/iomgr/exec_ctx.c \ diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index 35b21d4e20..c9ded1ff58 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -6391,7 +6391,6 @@ "src/core/lib/iomgr/error.h", "src/core/lib/iomgr/ev_epoll_linux.h", "src/core/lib/iomgr/ev_poll_and_epoll_posix.h", - "src/core/lib/iomgr/ev_poll_cv_posix.h", "src/core/lib/iomgr/ev_poll_posix.h", "src/core/lib/iomgr/ev_posix.h", "src/core/lib/iomgr/exec_ctx.h", @@ -6512,8 +6511,6 @@ "src/core/lib/iomgr/ev_epoll_linux.h", "src/core/lib/iomgr/ev_poll_and_epoll_posix.c", "src/core/lib/iomgr/ev_poll_and_epoll_posix.h", - "src/core/lib/iomgr/ev_poll_cv_posix.c", - "src/core/lib/iomgr/ev_poll_cv_posix.h", "src/core/lib/iomgr/ev_poll_posix.c", "src/core/lib/iomgr/ev_poll_posix.h", "src/core/lib/iomgr/ev_posix.c", diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj index 7d5e0ee56f..4a62af0276 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj @@ -319,7 +319,6 @@ - @@ -513,8 +512,6 @@ - - diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters index 72bf449c3e..dacdcd7608 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters @@ -76,9 +76,6 @@ src\core\lib\iomgr - - src\core\lib\iomgr - src\core\lib\iomgr @@ -746,9 +743,6 @@ src\core\lib\iomgr - - src\core\lib\iomgr - src\core\lib\iomgr diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj index 44cbe8bf0c..cb5963d0e8 100644 --- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj +++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj @@ -212,7 +212,6 @@ - @@ -361,8 +360,6 @@ - - diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters index 57466022f4..362284339f 100644 --- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters +++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters @@ -130,9 +130,6 @@ src\core\lib\iomgr - - src\core\lib\iomgr - src\core\lib\iomgr @@ -533,9 +530,6 @@ src\core\lib\iomgr - - src\core\lib\iomgr - src\core\lib\iomgr diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj index aa47cc800d..b7b72a05df 100644 --- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj +++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj @@ -309,7 +309,6 @@ - @@ -481,8 +480,6 @@ - - diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters index 4706c90af2..ca32c0b4b4 100644 --- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters +++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters @@ -79,9 +79,6 @@ src\core\lib\iomgr - - src\core\lib\iomgr - src\core\lib\iomgr @@ -656,9 +653,6 @@ src\core\lib\iomgr - - src\core\lib\iomgr - src\core\lib\iomgr -- cgit v1.2.3 From f6e14b79891cdb30b12fb696587017ff845184d8 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Thu, 13 Oct 2016 13:43:18 -0700 Subject: fix write buffer ruby test --- src/ruby/spec/generic/active_call_spec.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ruby/spec/generic/active_call_spec.rb b/src/ruby/spec/generic/active_call_spec.rb index 48bc61e494..5ae4f25537 100644 --- a/src/ruby/spec/generic/active_call_spec.rb +++ b/src/ruby/spec/generic/active_call_spec.rb @@ -137,6 +137,8 @@ describe GRPC::ActiveCall do msg = 'message is a string' client_call.write_flag = f client_call.remote_send(msg) + # flush the message in case writes are set to buffered + call.run_batch(CallOps::SEND_CLOSE_FROM_CLIENT => nil) if f == 1 # confirm that the message was marshalled recvd_rpc = @server.request_call -- cgit v1.2.3 From be4fcc47c556104122674ff6272626e8843cbc71 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 13 Oct 2016 14:33:08 -0700 Subject: Fix InteropTests.m bug --- src/objective-c/tests/InteropTests.m | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 44f22c9e85..9804734d6a 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -92,20 +92,21 @@ return 0; } ++ (void)setUp { +#ifdef GRPC_COMPILE_WITH_CRONET + // Cronet setup + [Cronet setHttp2Enabled:YES]; + [Cronet start]; + [GRPCCall useCronetWithEngine:[Cronet getGlobalEngine]]; +#endif +} + - (void)setUp { self.continueAfterFailure = NO; [GRPCCall resetHostSettings]; _service = self.class.host ? [RMTTestService serviceWithHost:self.class.host] : nil; -#ifdef GRPC_COMPILE_WITH_CRONET - if (cronetEngine == NULL) { - // Cronet setup - [Cronet setHttp2Enabled:YES]; - [Cronet start]; - [GRPCCall useCronetWithEngine:[Cronet getGlobalEngine]]; - } -#endif } - (void)testEmptyUnaryRPC { -- cgit v1.2.3 From b97cbd7acc3107f8cbd5fcf2d07ad48e1431513b Mon Sep 17 00:00:00 2001 From: Ken Payson Date: Thu, 13 Oct 2016 15:06:01 -0700 Subject: Use atomics for poll status to prevent tsan race complaints --- src/core/lib/iomgr/ev_poll_posix.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/core/lib/iomgr/ev_poll_posix.c b/src/core/lib/iomgr/ev_poll_posix.c index d9e5255ddc..f137e4dacc 100644 --- a/src/core/lib/iomgr/ev_poll_posix.c +++ b/src/core/lib/iomgr/ev_poll_posix.c @@ -254,7 +254,7 @@ struct grpc_pollset_set { #define CV_POLL_PERIOD_MS 1000 #define CV_DEFAULT_TABLE_SIZE 16 -typedef enum status_t { INPROGRESS, COMPLETED, CANCELLED } status_t; +typedef enum poll_status_t { INPROGRESS, COMPLETED, CANCELLED } poll_status_t; typedef struct poll_args { gpr_refcount refcount; @@ -264,7 +264,7 @@ typedef struct poll_args { int timeout; int retval; int err; - status_t status; + gpr_atm status; } poll_args; cv_fd_table g_cvfds; @@ -1276,7 +1276,7 @@ static void decref_poll_args(poll_args *args) { static void run_poll(void *arg) { int timeout, retval; poll_args *pargs = (poll_args *)arg; - while (pargs->status == INPROGRESS) { + while (gpr_atm_no_barrier_load(&pargs->status) == INPROGRESS) { if (pargs->timeout < 0) { timeout = CV_POLL_PERIOD_MS; } else { @@ -1291,9 +1291,9 @@ static void run_poll(void *arg) { } } gpr_mu_lock(&g_cvfds.mu); - if (pargs->status == INPROGRESS) { + if (gpr_atm_no_barrier_load(&pargs->status) == INPROGRESS) { // Signal main thread that the poll completed - pargs->status = COMPLETED; + gpr_atm_no_barrier_store(&pargs->status, COMPLETED); gpr_cv_signal(pargs->cv); } decref_poll_args(pargs); @@ -1345,7 +1345,7 @@ static int cvfd_poll(struct pollfd *fds, nfds_t nfds, int timeout) { pargs->timeout = timeout; pargs->retval = 0; pargs->err = 0; - pargs->status = INPROGRESS; + gpr_atm_no_barrier_store(&pargs->status, INPROGRESS); idx = 0; for (i = 0; i < nfds; i++) { if (fds[i].fd >= 0) { @@ -1361,13 +1361,13 @@ static int cvfd_poll(struct pollfd *fds, nfds_t nfds, int timeout) { gpr_thd_new(&t_id, &run_poll, pargs, &opt); // We want the poll() thread to trigger the deadline, so wait forever here gpr_cv_wait(pollcv, &g_cvfds.mu, gpr_inf_future(GPR_CLOCK_MONOTONIC)); - if (pargs->status == COMPLETED) { + if (gpr_atm_no_barrier_load(&pargs->status) == COMPLETED) { res = pargs->retval; errno = pargs->err; } else { res = 0; errno = 0; - pargs->status = CANCELLED; + gpr_atm_no_barrier_store(&pargs->status, CANCELLED); } } else { gpr_timespec deadline = gpr_now(GPR_CLOCK_REALTIME); @@ -1398,7 +1398,8 @@ static int cvfd_poll(struct pollfd *fds, nfds_t nfds, int timeout) { fds[i].revents = POLLIN; if (res >= 0) res++; } - } else if (fds[i].fd >= 0 && pargs->status == COMPLETED) { + } else if (fds[i].fd >= 0 && + gpr_atm_no_barrier_load(&pargs->status) == COMPLETED) { fds[i].revents = pargs->fds[idx].revents; idx++; } -- cgit v1.2.3 From 58c0f96f1962652e80d9aba43f260240daf610f0 Mon Sep 17 00:00:00 2001 From: Ken Payson Date: Fri, 16 Sep 2016 13:43:13 -0700 Subject: Allow pointer channel args python --- src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi | 8 +++-- .../grpcio/grpc/_cython/_cygrpc/records.pxd.pxi | 1 + .../grpcio/grpc/_cython/_cygrpc/records.pyx.pxi | 34 ++++++++++++++++++++-- .../grpcio_tests/tests/unit/_channel_args_test.py | 7 +++++ 4 files changed, 46 insertions(+), 4 deletions(-) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi index dae28e15f2..82514cacb2 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi @@ -172,10 +172,14 @@ cdef extern from "grpc/grpc.h": GRPC_ARG_INTEGER GRPC_ARG_POINTER - ctypedef struct grpc_arg_value_pointer: - void *address "p" + ctypedef struct grpc_arg_pointer_vtable: void *(*copy)(void *) void (*destroy)(void *) + int (*cmp)(void *, void *) + + ctypedef struct grpc_arg_value_pointer: + void *address "p" + grpc_arg_pointer_vtable *vtable union grpc_arg_value: char *string diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/records.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/records.pxd.pxi index 96c5b02bc2..00ec91b131 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/records.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/records.pxd.pxi @@ -84,6 +84,7 @@ cdef class SslPemKeyCertPair: cdef class ChannelArg: cdef grpc_arg c_arg + cdef grpc_arg_pointer_vtable ptr_vtable cdef readonly object key, value diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi index f444e33cf0..e97a3214e0 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi @@ -27,6 +27,7 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +from libc.stdint cimport intptr_t class ConnectivityState: idle = GRPC_CHANNEL_IDLE @@ -303,20 +304,49 @@ cdef class SslPemKeyCertPair: self.c_pair.certificate_chain = self.certificate_chain + +cdef void* copy_ptr(void* ptr): + return ptr + + +cdef void destroy_ptr(void* ptr): + pass + + +cdef int compare_ptr(void* ptr1, void* ptr2): + if ptr1 < ptr2: + return -1 + elif ptr1 > ptr2: + return 1 + else: + return 0 + + cdef class ChannelArg: def __cinit__(self, bytes key, value): self.key = key + self.value = value self.c_arg.key = self.key if isinstance(value, int): - self.value = value self.c_arg.type = GRPC_ARG_INTEGER self.c_arg.value.integer = self.value elif isinstance(value, bytes): - self.value = value self.c_arg.type = GRPC_ARG_STRING self.c_arg.value.string = self.value + elif hasattr(value, '__int__'): + # Pointer objects must override __int__() to return + # the underlying C address (Python ints are word size). The + # lifecycle of the pointer is fixed to the lifecycle of the + # python object wrapping it. + self.ptr_vtable.copy = ©_ptr + self.ptr_vtable.destroy = &destroy_ptr + self.ptr_vtable.cmp = &compare_ptr + self.c_arg.type = GRPC_ARG_POINTER + self.c_arg.value.pointer.vtable = &self.ptr_vtable + self.c_arg.value.pointer.address = (int(self.value)) else: + # TODO Add supported pointer types to this message raise TypeError('Expected int or bytes, got {}'.format(type(value))) diff --git a/src/python/grpcio_tests/tests/unit/_channel_args_test.py b/src/python/grpcio_tests/tests/unit/_channel_args_test.py index 6a636d7993..b46497afd6 100644 --- a/src/python/grpcio_tests/tests/unit/_channel_args_test.py +++ b/src/python/grpcio_tests/tests/unit/_channel_args_test.py @@ -33,11 +33,18 @@ import unittest import grpc +class TestPointerWrapper(object): + + def __int__(self): + return 123456 + + TEST_CHANNEL_ARGS = ( ('arg1', b'bytes_val'), ('arg2', 'str_val'), ('arg3', 1), (b'arg4', 'str_val'), + ('arg6', TestPointerWrapper()), ) -- cgit v1.2.3 From 4287998855258e4f90ddbeee7fac8d98707ff12e Mon Sep 17 00:00:00 2001 From: yang-g Date: Thu, 13 Oct 2016 15:58:31 -0700 Subject: Add a test spouse for server context --- Makefile | 50 ++++++ build.yaml | 9 + include/grpc++/impl/codegen/server_context.h | 2 + include/grpc++/test/server_context_test_spouse.h | 67 +++++++ src/cpp/test/server_context_test_spouse.cc | 52 ++++++ tools/run_tests/sources_and_headers.json | 17 ++ .../vcxproj/test/grpc++_test/grpc++_test.vcxproj | 195 +++++++++++++++++++++ .../test/grpc++_test/grpc++_test.vcxproj.filters | 35 ++++ 8 files changed, 427 insertions(+) create mode 100644 include/grpc++/test/server_context_test_spouse.h create mode 100644 src/cpp/test/server_context_test_spouse.cc create mode 100644 vsprojects/vcxproj/test/grpc++_test/grpc++_test.vcxproj create mode 100644 vsprojects/vcxproj/test/grpc++_test/grpc++_test.vcxproj.filters diff --git a/Makefile b/Makefile index 62c65822b0..ac5ef14bd3 100644 --- a/Makefile +++ b/Makefile @@ -3948,6 +3948,55 @@ endif endif +LIBGRPC++_TEST_SRC = \ + src/cpp/test/server_context_test_spouse.cc \ + +PUBLIC_HEADERS_CXX += \ + +LIBGRPC++_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_TEST_SRC)))) + + +ifeq ($(NO_SECURE),true) + +# You can't build secure libraries if you don't have OpenSSL. + +$(LIBDIR)/$(CONFIG)/libgrpc++_test.a: openssl_dep_error + + +else + +ifeq ($(NO_PROTOBUF),true) + +# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. + +$(LIBDIR)/$(CONFIG)/libgrpc++_test.a: protobuf_dep_error + + +else + +$(LIBDIR)/$(CONFIG)/libgrpc++_test.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_TEST_OBJS) + $(E) "[AR] Creating $@" + $(Q) mkdir -p `dirname $@` + $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_test.a + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc++_test.a $(LIBGRPC++_TEST_OBJS) +ifeq ($(SYSTEM),Darwin) + $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_test.a +endif + + + + +endif + +endif + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(LIBGRPC++_TEST_OBJS:.o=.dep) +endif +endif + + LIBGRPC++_TEST_CONFIG_SRC = \ test/cpp/util/test_config_cc.cc \ @@ -15674,6 +15723,7 @@ src/cpp/ext/proto_server_reflection_plugin.cc: $(OPENSSL_DEP) src/cpp/ext/reflection.grpc.pb.cc: $(OPENSSL_DEP) src/cpp/ext/reflection.pb.cc: $(OPENSSL_DEP) src/cpp/server/secure_server_credentials.cc: $(OPENSSL_DEP) +src/cpp/test/server_context_test_spouse.cc: $(OPENSSL_DEP) src/csharp/ext/grpc_csharp_ext.c: $(OPENSSL_DEP) test/core/bad_client/bad_client.c: $(OPENSSL_DEP) test/core/bad_ssl/server_common.c: $(OPENSSL_DEP) diff --git a/build.yaml b/build.yaml index 584084ff86..c40ad65572 100644 --- a/build.yaml +++ b/build.yaml @@ -1022,6 +1022,15 @@ libs: language: c++ src: - src/proto/grpc/reflection/v1alpha/reflection.proto +- name: grpc++_test + build: test + language: c++ + headers: + - include/grpc++/test/server_context_test_spouse.h + src: + - src/cpp/test/server_context_test_spouse.cc + deps: + - grpc++ - name: grpc++_test_config build: private language: c++ diff --git a/include/grpc++/impl/codegen/server_context.h b/include/grpc++/impl/codegen/server_context.h index bce8d2c2f8..975f710f13 100644 --- a/include/grpc++/impl/codegen/server_context.h +++ b/include/grpc++/impl/codegen/server_context.h @@ -86,6 +86,7 @@ class ServerInterface; namespace testing { class InteropServerContextInspector; +class ServerContextTestSpouse; } // namespace testing // Interface of server side rpc context. @@ -173,6 +174,7 @@ class ServerContext { private: friend class ::grpc::testing::InteropServerContextInspector; + friend class ::grpc::testing::ServerContextTestSpouse; friend class ::grpc::ServerInterface; friend class ::grpc::Server; template diff --git a/include/grpc++/test/server_context_test_spouse.h b/include/grpc++/test/server_context_test_spouse.h new file mode 100644 index 0000000000..fdca38aa35 --- /dev/null +++ b/include/grpc++/test/server_context_test_spouse.h @@ -0,0 +1,67 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPCXX_TEST_SERVER_CONTEXT_TEST_SPOUSE_H +#define GRPCXX_TEST_SERVER_CONTEXT_TEST_SPOUSE_H + +#include + +#include + +namespace grpc { +namespace testing { + +// A test-only class to access private members and methods of ServerContext. +class ServerContextTestSpouse { + public: + explicit ServerContextTestSpouse(ServerContext* ctx) : ctx_(ctx) {} + + // Inject fake client metadata to the ServerContext. The test spouse must be + // alive when ServerContext::client_metadata is called. + void AddClientMetadata(const grpc::string& key, const grpc::string& value); + std::multimap GetInitialMetadata() const { + return ctx_->initial_metadata_; + } + std::multimap GetTrailingMetadata() const { + return ctx_->trailing_metadata_; + } + + private: + ServerContext* ctx_; // not owned + std::multimap client_metadata_storage_; +}; + +} // namespace testing +} // namespace grpc + +#endif // GRPCXX_TEST_SERVER_CONTEXT_TEST_SPOUSE_H diff --git a/src/cpp/test/server_context_test_spouse.cc b/src/cpp/test/server_context_test_spouse.cc new file mode 100644 index 0000000000..b93152eea0 --- /dev/null +++ b/src/cpp/test/server_context_test_spouse.cc @@ -0,0 +1,52 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include + +namespace grpc { +namespace testing { + +void ServerContextTestSpouse::AddClientMetadata(const grpc::string& key, + const grpc::string& value) { + client_metadata_storage_.insert( + std::pair(key, value)); + ctx_->client_metadata_.clear(); + for (auto iter = client_metadata_storage_.begin(); + iter != client_metadata_storage_.end(); ++iter) { + ctx_->client_metadata_.insert(std::pair( + iter->first.c_str(), iter->second.c_str())); + } +} + +} // namespace testing +} // namespace grpc diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index c05d194e19..cb25ea9afa 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -4928,6 +4928,23 @@ "third_party": false, "type": "lib" }, + { + "deps": [ + "grpc++" + ], + "headers": [ + "include/grpc++/test/server_context_test_spouse.h" + ], + "is_filegroup": false, + "language": "c++", + "name": "grpc++_test", + "src": [ + "include/grpc++/test/server_context_test_spouse.h", + "src/cpp/test/server_context_test_spouse.cc" + ], + "third_party": false, + "type": "lib" + }, { "deps": [], "headers": [ diff --git a/vsprojects/vcxproj/test/grpc++_test/grpc++_test.vcxproj b/vsprojects/vcxproj/test/grpc++_test/grpc++_test.vcxproj new file mode 100644 index 0000000000..995d60d09e --- /dev/null +++ b/vsprojects/vcxproj/test/grpc++_test/grpc++_test.vcxproj @@ -0,0 +1,195 @@ + + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {3D3EAEA9-76C4-0CFE-4718-5A1F6B7F72C8} + true + $(SolutionDir)IntDir\$(MSBuildProjectName)\ + + + + v100 + + + v110 + + + v120 + + + v140 + + + Application + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + + + + grpc++_test + static + Debug + static + Debug + + + grpc++_test + static + Release + static + Release + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Windows + true + false + + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Windows + true + false + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Windows + true + false + true + true + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Windows + true + false + true + true + + + + + + + + + + + + + {C187A093-A0FE-489D-A40A-6E33DE0F9FEB} + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + diff --git a/vsprojects/vcxproj/test/grpc++_test/grpc++_test.vcxproj.filters b/vsprojects/vcxproj/test/grpc++_test/grpc++_test.vcxproj.filters new file mode 100644 index 0000000000..e1d8fe1ef3 --- /dev/null +++ b/vsprojects/vcxproj/test/grpc++_test/grpc++_test.vcxproj.filters @@ -0,0 +1,35 @@ + + + + + src\cpp\test + + + + + include\grpc++\test + + + + + + {418e2be9-9a04-af8a-8878-956543c507a1} + + + {bcaf3a2d-e884-bfbd-477b-09634054bcc5} + + + {3a14b66f-1d31-2d06-e9a1-c6d1199ab04d} + + + {bc08c75b-ee7e-85a0-fb0f-7586bbd33c6f} + + + {9797a57d-93ac-ff9c-5ac6-fd335777d782} + + + {58d4b4e0-5617-abf4-48a6-f1264d127b27} + + + + -- cgit v1.2.3 From c4292fb971b88f4ff1a0166998d1cf5e6c66efa8 Mon Sep 17 00:00:00 2001 From: yang-g Date: Thu, 13 Oct 2016 16:54:08 -0700 Subject: Add a simple test --- Makefile | 48 +++++ build.yaml | 13 ++ test/cpp/test/server_context_test_spouse_test.cc | 108 +++++++++++ tools/run_tests/sources_and_headers.json | 19 ++ tools/run_tests/tests.json | 21 +++ .../server_context_test_spouse_test.vcxproj | 207 +++++++++++++++++++++ ...server_context_test_spouse_test.vcxproj.filters | 21 +++ 7 files changed, 437 insertions(+) create mode 100644 test/cpp/test/server_context_test_spouse_test.cc create mode 100644 vsprojects/vcxproj/test/server_context_test_spouse_test/server_context_test_spouse_test.vcxproj create mode 100644 vsprojects/vcxproj/test/server_context_test_spouse_test/server_context_test_spouse_test.vcxproj.filters diff --git a/Makefile b/Makefile index ac5ef14bd3..e990e826ab 100644 --- a/Makefile +++ b/Makefile @@ -1071,6 +1071,7 @@ reconnect_interop_server: $(BINDIR)/$(CONFIG)/reconnect_interop_server secure_auth_context_test: $(BINDIR)/$(CONFIG)/secure_auth_context_test secure_sync_unary_ping_pong_test: $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test server_builder_plugin_test: $(BINDIR)/$(CONFIG)/server_builder_plugin_test +server_context_test_spouse_test: $(BINDIR)/$(CONFIG)/server_context_test_spouse_test server_crash_test: $(BINDIR)/$(CONFIG)/server_crash_test server_crash_test_client: $(BINDIR)/$(CONFIG)/server_crash_test_client shutdown_test: $(BINDIR)/$(CONFIG)/shutdown_test @@ -1439,6 +1440,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/secure_auth_context_test \ $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test \ $(BINDIR)/$(CONFIG)/server_builder_plugin_test \ + $(BINDIR)/$(CONFIG)/server_context_test_spouse_test \ $(BINDIR)/$(CONFIG)/server_crash_test \ $(BINDIR)/$(CONFIG)/server_crash_test_client \ $(BINDIR)/$(CONFIG)/shutdown_test \ @@ -1526,6 +1528,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/secure_auth_context_test \ $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test \ $(BINDIR)/$(CONFIG)/server_builder_plugin_test \ + $(BINDIR)/$(CONFIG)/server_context_test_spouse_test \ $(BINDIR)/$(CONFIG)/server_crash_test \ $(BINDIR)/$(CONFIG)/server_crash_test_client \ $(BINDIR)/$(CONFIG)/shutdown_test \ @@ -1828,6 +1831,8 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test || ( echo test secure_sync_unary_ping_pong_test failed ; exit 1 ) $(E) "[RUN] Testing server_builder_plugin_test" $(Q) $(BINDIR)/$(CONFIG)/server_builder_plugin_test || ( echo test server_builder_plugin_test failed ; exit 1 ) + $(E) "[RUN] Testing server_context_test_spouse_test" + $(Q) $(BINDIR)/$(CONFIG)/server_context_test_spouse_test || ( echo test server_context_test_spouse_test failed ; exit 1 ) $(E) "[RUN] Testing server_crash_test" $(Q) $(BINDIR)/$(CONFIG)/server_crash_test || ( echo test server_crash_test failed ; exit 1 ) $(E) "[RUN] Testing shutdown_test" @@ -12762,6 +12767,49 @@ endif endif +SERVER_CONTEXT_TEST_SPOUSE_TEST_SRC = \ + test/cpp/test/server_context_test_spouse_test.cc \ + +SERVER_CONTEXT_TEST_SPOUSE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SERVER_CONTEXT_TEST_SPOUSE_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/server_context_test_spouse_test: openssl_dep_error + +else + + + + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+. + +$(BINDIR)/$(CONFIG)/server_context_test_spouse_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/server_context_test_spouse_test: $(PROTOBUF_DEP) $(SERVER_CONTEXT_TEST_SPOUSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(SERVER_CONTEXT_TEST_SPOUSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_context_test_spouse_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/cpp/test/server_context_test_spouse_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_server_context_test_spouse_test: $(SERVER_CONTEXT_TEST_SPOUSE_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(SERVER_CONTEXT_TEST_SPOUSE_TEST_OBJS:.o=.dep) +endif +endif + + SERVER_CRASH_TEST_SRC = \ test/cpp/end2end/server_crash_test.cc \ diff --git a/build.yaml b/build.yaml index c40ad65572..0b5aa3b975 100644 --- a/build.yaml +++ b/build.yaml @@ -3234,6 +3234,19 @@ targets: - grpc - gpr_test_util - gpr +- name: server_context_test_spouse_test + gtest: true + build: test + language: c++ + src: + - test/cpp/test/server_context_test_spouse_test.cc + deps: + - grpc_test_util + - grpc++_test + - grpc++ + - grpc + - gpr_test_util + - gpr - name: server_crash_test gtest: true cpu_cost: 0.1 diff --git a/test/cpp/test/server_context_test_spouse_test.cc b/test/cpp/test/server_context_test_spouse_test.cc new file mode 100644 index 0000000000..e0d6a2ff67 --- /dev/null +++ b/test/cpp/test/server_context_test_spouse_test.cc @@ -0,0 +1,108 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include + +#include +#include + +#include + +namespace grpc { +namespace testing { + +const char key1[] = "metadata-key1"; +const char key2[] = "metadata-key2"; +const char val1[] = "metadata-val1"; +const char val2[] = "metadata-val2"; + +bool ClientMetadataContains(const ServerContext& context, + const grpc::string_ref& key, + const grpc::string_ref& value) { + const auto& client_metadata = context.client_metadata(); + for (auto iter = client_metadata.begin(); iter != client_metadata.end(); + ++iter) { + if (iter->first == key && iter->second == value) { + return true; + } + } + return false; +} + +TEST(ServerContextTestSpouseTest, ClientMetadata) { + ServerContext context; + ServerContextTestSpouse spouse(&context); + + spouse.AddClientMetadata(key1, val1); + ASSERT_TRUE(ClientMetadataContains(context, key1, val1)); + + spouse.AddClientMetadata(key2, val2); + ASSERT_TRUE(ClientMetadataContains(context, key1, val1)); + ASSERT_TRUE(ClientMetadataContains(context, key2, val2)); +} + +TEST(ServerContextTestSpouseTest, InitialMetadata) { + ServerContext context; + ServerContextTestSpouse spouse(&context); + std::multimap metadata; + + context.AddInitialMetadata(key1, val1); + metadata.insert(std::pair(key1, val1)); + ASSERT_EQ(metadata, spouse.GetInitialMetadata()); + + context.AddInitialMetadata(key2, val2); + metadata.insert(std::pair(key2, val2)); + ASSERT_EQ(metadata, spouse.GetInitialMetadata()); +} + +TEST(ServerContextTestSpouseTest, TrailingMetadata) { + ServerContext context; + ServerContextTestSpouse spouse(&context); + std::multimap metadata; + + context.AddTrailingMetadata(key1, val1); + metadata.insert(std::pair(key1, val1)); + ASSERT_EQ(metadata, spouse.GetTrailingMetadata()); + + context.AddTrailingMetadata(key2, val2); + metadata.insert(std::pair(key2, val2)); + ASSERT_EQ(metadata, spouse.GetTrailingMetadata()); +} + +} // namespace +} // namespace grpc + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index cb25ea9afa..212e07e772 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -2977,6 +2977,25 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "gpr_test_util", + "grpc", + "grpc++", + "grpc++_test", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "server_context_test_spouse_test", + "src": [ + "test/cpp/test/server_context_test_spouse_test.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json index c3395067c9..756e5551f2 100644 --- a/tools/run_tests/tests.json +++ b/tools/run_tests/tests.json @@ -2641,6 +2641,27 @@ "windows" ] }, + { + "args": [], + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "gtest": true, + "language": "c++", + "name": "server_context_test_spouse_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ] + }, { "args": [], "ci_platforms": [ diff --git a/vsprojects/vcxproj/test/server_context_test_spouse_test/server_context_test_spouse_test.vcxproj b/vsprojects/vcxproj/test/server_context_test_spouse_test/server_context_test_spouse_test.vcxproj new file mode 100644 index 0000000000..8ba7432824 --- /dev/null +++ b/vsprojects/vcxproj/test/server_context_test_spouse_test/server_context_test_spouse_test.vcxproj @@ -0,0 +1,207 @@ + + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {A6F63996-B33B-9904-57AB-9C9559D52007} + true + $(SolutionDir)IntDir\$(MSBuildProjectName)\ + + + + v100 + + + v110 + + + v120 + + + v140 + + + Application + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + + + + server_context_test_spouse_test + static + Debug + static + Debug + + + server_context_test_spouse_test + static + Release + static + Release + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Console + true + false + + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Console + true + false + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Console + true + false + true + true + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Console + true + false + true + true + + + + + + + + + + {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} + + + {3D3EAEA9-76C4-0CFE-4718-5A1F6B7F72C8} + + + {C187A093-A0FE-489D-A40A-6E33DE0F9FEB} + + + {29D16885-7228-4C31-81ED-5F9187C7F2A9} + + + {EAB0A629-17A9-44DB-B5FF-E91A721FE037} + + + {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + diff --git a/vsprojects/vcxproj/test/server_context_test_spouse_test/server_context_test_spouse_test.vcxproj.filters b/vsprojects/vcxproj/test/server_context_test_spouse_test/server_context_test_spouse_test.vcxproj.filters new file mode 100644 index 0000000000..469ef950a6 --- /dev/null +++ b/vsprojects/vcxproj/test/server_context_test_spouse_test/server_context_test_spouse_test.vcxproj.filters @@ -0,0 +1,21 @@ + + + + + test\cpp\test + + + + + + {fa83809b-e1fe-3f85-ebbb-73570c33fa2e} + + + {7bad6fd3-6c15-e1fa-4037-8627e3622c7c} + + + {990725da-41e1-2c80-ecc7-2b90c8914dd7} + + + + -- cgit v1.2.3 From df0f365c11dba088d6d320246e3f4934091ea71d Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 13 Oct 2016 17:37:01 -0700 Subject: Fix bad stream terminators --- src/core/ext/transport/chttp2/transport/writing.c | 17 ++++++++++++----- tools/run_tests/jobset.py | 4 ++++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/writing.c b/src/core/ext/transport/chttp2/transport/writing.c index d34a7918b5..8f86ed690b 100644 --- a/src/core/ext/transport/chttp2/transport/writing.c +++ b/src/core/ext/transport/chttp2/transport/writing.c @@ -151,6 +151,8 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, bool is_last_frame = is_last_data_frame && s->send_trailing_metadata != NULL && grpc_metadata_batch_is_empty(s->send_trailing_metadata); + gpr_log(GPR_DEBUG, "sb:%d ldf:%d ilf:%d", send_bytes, + is_last_data_frame, is_last_frame); grpc_chttp2_encode_data(s->id, &s->flow_controlled_buffer, send_bytes, is_last_frame, &s->stats.outgoing, &t->outbuf); @@ -181,11 +183,16 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, if (s->send_trailing_metadata != NULL && s->fetching_send_message == NULL && s->flow_controlled_buffer.length == 0) { - grpc_chttp2_encode_header( - &t->hpack_compressor, s->id, s->send_trailing_metadata, true, - t->settings[GRPC_ACKED_SETTINGS] - [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE], - &s->stats.outgoing, &t->outbuf); + if (grpc_metadata_batch_is_empty(s->send_trailing_metadata)) { + grpc_chttp2_encode_data(s->id, &s->flow_controlled_buffer, 0, true, + &s->stats.outgoing, &t->outbuf); + } else { + grpc_chttp2_encode_header( + &t->hpack_compressor, s->id, s->send_trailing_metadata, true, + t->settings[GRPC_ACKED_SETTINGS] + [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE], + &s->stats.outgoing, &t->outbuf); + } s->send_trailing_metadata = NULL; s->sent_trailing_metadata = true; if (!t->is_client && !s->read_closed) { diff --git a/tools/run_tests/jobset.py b/tools/run_tests/jobset.py index b6fb6318e0..b2b4998104 100755 --- a/tools/run_tests/jobset.py +++ b/tools/run_tests/jobset.py @@ -228,10 +228,14 @@ class Job(object): env.update(self._spec.environ) env.update(self._add_env) env = sanitized_environment(env) + penv = {} + penv.update(self._spec.environ) + penv.update(self._add_env) self._start = time.time() cmdline = self._spec.cmdline if measure_cpu_costs: cmdline = ['time', '--portability'] + cmdline + print('\n\ncmdline: %s\nenv: %s\n' % (cmdline, penv)) try_start = lambda: subprocess.Popen(args=cmdline, stderr=subprocess.STDOUT, stdout=self._tempfile, -- cgit v1.2.3 From 47284bec5cb68bae61fcb403ec1e4073fd31f424 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 13 Oct 2016 17:52:40 -0700 Subject: Revert changes to jobset.py --- tools/run_tests/jobset.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tools/run_tests/jobset.py b/tools/run_tests/jobset.py index b2b4998104..b6fb6318e0 100755 --- a/tools/run_tests/jobset.py +++ b/tools/run_tests/jobset.py @@ -228,14 +228,10 @@ class Job(object): env.update(self._spec.environ) env.update(self._add_env) env = sanitized_environment(env) - penv = {} - penv.update(self._spec.environ) - penv.update(self._add_env) self._start = time.time() cmdline = self._spec.cmdline if measure_cpu_costs: cmdline = ['time', '--portability'] + cmdline - print('\n\ncmdline: %s\nenv: %s\n' % (cmdline, penv)) try_start = lambda: subprocess.Popen(args=cmdline, stderr=subprocess.STDOUT, stdout=self._tempfile, -- cgit v1.2.3 From ef91e569ccaa805fa0feb71565d316e171678f55 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 13 Oct 2016 17:57:00 -0700 Subject: Revert spam --- src/core/ext/transport/chttp2/transport/writing.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/writing.c b/src/core/ext/transport/chttp2/transport/writing.c index 8f86ed690b..b39695a1a5 100644 --- a/src/core/ext/transport/chttp2/transport/writing.c +++ b/src/core/ext/transport/chttp2/transport/writing.c @@ -151,8 +151,6 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx, bool is_last_frame = is_last_data_frame && s->send_trailing_metadata != NULL && grpc_metadata_batch_is_empty(s->send_trailing_metadata); - gpr_log(GPR_DEBUG, "sb:%d ldf:%d ilf:%d", send_bytes, - is_last_data_frame, is_last_frame); grpc_chttp2_encode_data(s->id, &s->flow_controlled_buffer, send_bytes, is_last_frame, &s->stats.outgoing, &t->outbuf); -- cgit v1.2.3 From 90712d5e5dfc40ec694a031c70379cd3c9c94431 Mon Sep 17 00:00:00 2001 From: David Garcia Quintas Date: Thu, 13 Oct 2016 19:33:04 -0700 Subject: gRPCLB and RR race fixes --- src/core/ext/lb_policy/grpclb/grpclb.c | 112 ++++++++++++++--------- src/core/ext/lb_policy/round_robin/round_robin.c | 2 +- 2 files changed, 71 insertions(+), 43 deletions(-) diff --git a/src/core/ext/lb_policy/grpclb/grpclb.c b/src/core/ext/lb_policy/grpclb/grpclb.c index 626f285b90..5f0574e5df 100644 --- a/src/core/ext/lb_policy/grpclb/grpclb.c +++ b/src/core/ext/lb_policy/grpclb/grpclb.c @@ -69,8 +69,8 @@ * possible scenarios: * * 1. This is the first server list received. There was no previous instance of - * the Round Robin policy. \a rr_handover() will instantiate the RR policy - * and perform all the pending operations over it. + * the Round Robin policy. \a rr_handover_locked() will instantiate the RR + * policy and perform all the pending operations over it. * 2. There's already a RR policy instance active. We need to introduce the new * one build from the new serverlist, but taking care not to disrupt the * operations in progress over the old RR instance. This is done by @@ -78,7 +78,7 @@ * references are held on the old RR policy, it'll be destroyed and \a * glb_rr_connectivity_changed notified with a \a GRPC_CHANNEL_SHUTDOWN * state. At this point we can transition to a new RR instance safely, which - * is done once again via \a rr_handover(). + * is done once again via \a rr_handover_locked(). * * * Once a RR policy instance is in place (and getting updated as described), @@ -86,8 +86,8 @@ * forwarding them to the RR instance. Any time there's no RR policy available * (ie, right after the creation of the gRPCLB policy, if an empty serverlist * is received, etc), pick/ping requests are added to a list of pending - * picks/pings to be flushed and serviced as part of \a rr_handover() the moment - * the RR policy instance becomes available. + * picks/pings to be flushed and serviced as part of \a rr_handover_locked() the + * moment the RR policy instance becomes available. * * \see https://github.com/grpc/grpc/blob/master/doc/load-balancing.md for the * high level design and details. */ @@ -158,6 +158,12 @@ typedef struct wrapped_rr_closure_arg { /* when not NULL, represents a pending_{pick,ping} node to be freed upon * closure execution */ void *owning_pending_node; /* to be freed if not NULL */ + + /* Pointer ot heap memory if the closure and its argument were allocated + * dynamically outside of a pending pick. It'll be NULL otherwise. + * + * TODO(dgq): This is by no means pretty. */ + void *closure_mem_or_null; } wrapped_rr_closure_arg; /* The \a on_complete closure passed as part of the pick requires keeping a @@ -186,7 +192,17 @@ static void wrapped_rr_closure(grpc_exec_ctx *exec_ctx, void *arg, grpc_exec_ctx_sched(exec_ctx, wc_arg->wrapped_closure, GRPC_ERROR_REF(error), NULL); - gpr_free(wc_arg->owning_pending_node); + + /* Make sure this closure and its arg are EITHER on the heap on their oen OR + * part of a pending pick (thus part of the pending pick's memory) */ + GPR_ASSERT((wc_arg->closure_mem_or_null != NULL) + + (wc_arg->owning_pending_node != NULL) == + 1); + if (wc_arg->closure_mem_or_null) { + gpr_free(wc_arg->closure_mem_or_null); + } else { + gpr_free(wc_arg->owning_pending_node); + } } /* Linked list of pending pick requests. It stores all information needed to @@ -307,13 +323,6 @@ typedef struct glb_lb_policy { /** for tracking of the RR connectivity */ rr_connectivity_data *rr_connectivity; - - /* a wrapped (see \a wrapped_rr_closure) on-complete closure for readily - * available RR picks */ - grpc_closure wrapped_on_complete; - - /* arguments for the wrapped_on_complete closure */ - wrapped_rr_closure_arg wc_arg; } glb_lb_policy; /* Keeps track and reacts to changes in connectivity of the RR instance */ @@ -424,9 +433,9 @@ static void lb_token_destroy(void *token) { if (token != NULL) GRPC_MDELEM_UNREF(token); } -static grpc_lb_policy *create_rr(grpc_exec_ctx *exec_ctx, - const grpc_grpclb_serverlist *serverlist, - glb_lb_policy *glb_policy) { +static grpc_lb_policy *create_rr_locked( + grpc_exec_ctx *exec_ctx, const grpc_grpclb_serverlist *serverlist, + glb_lb_policy *glb_policy) { GPR_ASSERT(serverlist != NULL && serverlist->num_servers > 0); grpc_lb_policy_args args; @@ -446,12 +455,12 @@ static grpc_lb_policy *create_rr(grpc_exec_ctx *exec_ctx, return rr; } -static void rr_handover(grpc_exec_ctx *exec_ctx, glb_lb_policy *glb_policy, - grpc_error *error) { +static void rr_handover_locked(grpc_exec_ctx *exec_ctx, + glb_lb_policy *glb_policy, grpc_error *error) { GPR_ASSERT(glb_policy->serverlist != NULL && glb_policy->serverlist->num_servers > 0); glb_policy->rr_policy = - create_rr(exec_ctx, glb_policy->serverlist, glb_policy); + create_rr_locked(exec_ctx, glb_policy->serverlist, glb_policy); if (grpc_lb_glb_trace) { gpr_log(GPR_INFO, "Created RR policy (0x%" PRIxPTR ")", @@ -474,6 +483,7 @@ static void rr_handover(grpc_exec_ctx *exec_ctx, glb_lb_policy *glb_policy, glb_policy->pending_picks = pp->next; GRPC_LB_POLICY_REF(glb_policy->rr_policy, "rr_handover_pending_pick"); pp->wrapped_on_complete_arg.rr_policy = glb_policy->rr_policy; + pp->wrapped_on_complete_arg.owning_pending_node = pp; if (grpc_lb_glb_trace) { gpr_log(GPR_INFO, "Pending pick about to PICK from 0x%" PRIxPTR "", (intptr_t)glb_policy->rr_policy); @@ -482,7 +492,6 @@ static void rr_handover(grpc_exec_ctx *exec_ctx, glb_lb_policy *glb_policy, pp->target, (void **)&pp->wrapped_on_complete_arg.lb_token, &pp->wrapped_on_complete); - pp->wrapped_on_complete_arg.owning_pending_node = pp; } pending_ping *pping; @@ -490,13 +499,13 @@ static void rr_handover(grpc_exec_ctx *exec_ctx, glb_lb_policy *glb_policy, glb_policy->pending_pings = pping->next; GRPC_LB_POLICY_REF(glb_policy->rr_policy, "rr_handover_pending_ping"); pping->wrapped_notify_arg.rr_policy = glb_policy->rr_policy; + pping->wrapped_notify_arg.owning_pending_node = pping; if (grpc_lb_glb_trace) { gpr_log(GPR_INFO, "Pending ping about to PING from 0x%" PRIxPTR "", (intptr_t)glb_policy->rr_policy); } grpc_lb_policy_ping_one(exec_ctx, glb_policy->rr_policy, &pping->wrapped_notify); - pping->wrapped_notify_arg.owning_pending_node = pping; } } @@ -509,13 +518,16 @@ static void glb_rr_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg, if (glb_policy->serverlist != NULL) { /* a RR policy is shutting down but there's a serverlist available -> * perform a handover */ - rr_handover(exec_ctx, glb_policy, error); + gpr_mu_lock(&glb_policy->mu); + rr_handover_locked(exec_ctx, glb_policy, error); + gpr_mu_unlock(&glb_policy->mu); } else { /* shutting down and no new serverlist available. Bail out. */ gpr_free(rr_conn_data); } } else { if (error == GRPC_ERROR_NONE) { + gpr_mu_lock(&glb_policy->mu); /* RR not shutting down. Mimic the RR's policy state */ grpc_connectivity_state_set(exec_ctx, &glb_policy->state_tracker, rr_conn_data->state, GRPC_ERROR_REF(error), @@ -524,6 +536,7 @@ static void glb_rr_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg, grpc_lb_policy_notify_on_state_change(exec_ctx, glb_policy->rr_policy, &rr_conn_data->state, &rr_conn_data->on_change); + gpr_mu_unlock(&glb_policy->mu); } else { /* error */ gpr_free(rr_conn_data); } @@ -775,37 +788,50 @@ static int glb_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, (intptr_t)glb_policy->rr_policy); } GRPC_LB_POLICY_REF(glb_policy->rr_policy, "glb_pick"); - memset(&glb_policy->wc_arg, 0, sizeof(wrapped_rr_closure_arg)); - glb_policy->wc_arg.rr_policy = glb_policy->rr_policy; - glb_policy->wc_arg.target = target; - glb_policy->wc_arg.wrapped_closure = on_complete; - glb_policy->wc_arg.lb_token_mdelem_storage = - pick_args->lb_token_mdelem_storage; - glb_policy->wc_arg.initial_metadata = pick_args->initial_metadata; - glb_policy->wc_arg.owning_pending_node = NULL; - grpc_closure_init(&glb_policy->wrapped_on_complete, wrapped_rr_closure, - &glb_policy->wc_arg); + + /* we need to allocate the closure on the stack because we may be serving + * concurrent picks: a single field in glb_policy isn't good enough */ + void *closure_mem = + gpr_malloc(sizeof(grpc_closure) + sizeof(wrapped_rr_closure_arg)); + grpc_closure *wrapped_on_complete = closure_mem; + memset(wrapped_on_complete, 0, sizeof(grpc_closure)); + + wrapped_rr_closure_arg *wc_arg = closure_mem + sizeof(grpc_closure); + memset(wc_arg, 0, sizeof(wrapped_rr_closure_arg)); + + grpc_closure_init(wrapped_on_complete, wrapped_rr_closure, wc_arg); + + wc_arg->rr_policy = glb_policy->rr_policy; + wc_arg->target = target; + wc_arg->wrapped_closure = on_complete; + wc_arg->lb_token_mdelem_storage = pick_args->lb_token_mdelem_storage; + wc_arg->initial_metadata = pick_args->initial_metadata; + wc_arg->owning_pending_node = NULL; + wc_arg->closure_mem_or_null = closure_mem; pick_done = grpc_lb_policy_pick(exec_ctx, glb_policy->rr_policy, pick_args, target, - (void **)&glb_policy->wc_arg.lb_token, - &glb_policy->wrapped_on_complete); + (void **)&wc_arg->lb_token, wrapped_on_complete); if (pick_done) { /* synchronous grpc_lb_policy_pick call. Unref the RR policy. */ if (grpc_lb_glb_trace) { gpr_log(GPR_INFO, "Unreffing RR (0x%" PRIxPTR ")", - (intptr_t)glb_policy->wc_arg.rr_policy); + (intptr_t)wc_arg->rr_policy); } - GRPC_LB_POLICY_UNREF(exec_ctx, glb_policy->wc_arg.rr_policy, "glb_pick"); + GRPC_LB_POLICY_UNREF(exec_ctx, wc_arg->rr_policy, "glb_pick"); /* add the load reporting initial metadata */ - initial_metadata_add_lb_token( - pick_args->initial_metadata, pick_args->lb_token_mdelem_storage, - GRPC_MDELEM_REF(glb_policy->wc_arg.lb_token)); + initial_metadata_add_lb_token(pick_args->initial_metadata, + pick_args->lb_token_mdelem_storage, + GRPC_MDELEM_REF(wc_arg->lb_token)); + + gpr_free(closure_mem); } + /* else, !pick_done, the pending pick will be registered and taken care of + * by the pending pick list inside the RR policy (glb_policy->rr_policy). + * Eventually, wrapped_on_complete will be called, which will -among other + * things- add the LB token to the call's initial metadata */ } else { - /* else, the pending pick will be registered and taken care of by the - * pending pick list inside the RR policy (glb_policy->rr_policy) */ grpc_polling_entity_add_to_pollset_set(exec_ctx, pick_args->pollent, glb_policy->base.interested_parties); add_pending_pick(&glb_policy->pending_picks, pick_args, target, @@ -1076,6 +1102,7 @@ static void res_recv_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { /* update serverlist */ if (serverlist->num_servers > 0) { + gpr_mu_lock(&lb_client->glb_policy->mu); if (grpc_grpclb_serverlist_equals(lb_client->glb_policy->serverlist, serverlist)) { if (grpc_lb_glb_trace) { @@ -1093,7 +1120,7 @@ static void res_recv_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { if (lb_client->glb_policy->rr_policy == NULL) { /* initial "handover", in this case from a null RR policy, meaning * it'll just create the first RR policy instance */ - rr_handover(exec_ctx, lb_client->glb_policy, error); + rr_handover_locked(exec_ctx, lb_client->glb_policy, error); } else { /* unref the RR policy, eventually leading to its substitution with a * new one constructed from the received serverlist (see @@ -1101,6 +1128,7 @@ static void res_recv_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { GRPC_LB_POLICY_UNREF(exec_ctx, lb_client->glb_policy->rr_policy, "serverlist_received"); } + gpr_mu_unlock(&lb_client->glb_policy->mu); } else { if (grpc_lb_glb_trace) { gpr_log(GPR_INFO, diff --git a/src/core/ext/lb_policy/round_robin/round_robin.c b/src/core/ext/lb_policy/round_robin/round_robin.c index 930fa86aca..325202fc6d 100644 --- a/src/core/ext/lb_policy/round_robin/round_robin.c +++ b/src/core/ext/lb_policy/round_robin/round_robin.c @@ -403,7 +403,6 @@ static int rr_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, gpr_mu_lock(&p->mu); if ((selected = peek_next_connected_locked(p))) { /* readily available, report right away */ - gpr_mu_unlock(&p->mu); *target = grpc_subchannel_get_connected_subchannel(selected->subchannel); if (user_data != NULL) { @@ -416,6 +415,7 @@ static int rr_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, } /* only advance the last picked pointer if the selection was used */ advance_last_picked_locked(p); + gpr_mu_unlock(&p->mu); return 1; } else { /* no pick currently available. Save for later in list of pending picks */ -- cgit v1.2.3 From d13fbca1369f4c3b72ff11305123177d9cce03e7 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 9 Sep 2016 18:43:34 +0200 Subject: switch C# benchmark to coreclr --- tools/run_tests/performance/build_performance.sh | 3 +++ tools/run_tests/performance/kill_workers.sh | 1 + tools/run_tests/performance/run_worker_csharp.sh | 4 ++-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/run_tests/performance/build_performance.sh b/tools/run_tests/performance/build_performance.sh index 352c679757..e981cae76b 100755 --- a/tools/run_tests/performance/build_performance.sh +++ b/tools/run_tests/performance/build_performance.sh @@ -54,6 +54,9 @@ do "go") tools/run_tests/performance/build_performance_go.sh ;; + "csharp") + tools/run_tests/run_tests.py -l $language -c $CONFIG --build_only -j 8 --compiler coreclr + ;; *) tools/run_tests/run_tests.py -l $language -c $CONFIG --build_only -j 8 ;; diff --git a/tools/run_tests/performance/kill_workers.sh b/tools/run_tests/performance/kill_workers.sh index 279cc7df29..6e33efad4c 100755 --- a/tools/run_tests/performance/kill_workers.sh +++ b/tools/run_tests/performance/kill_workers.sh @@ -40,6 +40,7 @@ killall -9 qps_worker || true # C# ps -C mono -o pid=,cmd= | grep QpsWorker | awk '{print $1}' | xargs kill -9 || true +ps -C dotnet -o pid=,cmd= | grep QpsWorker | awk '{print $1}' | xargs kill -9 || true # Ruby ps -C ruby -o pid=,cmd= | grep 'qps/worker.rb' | awk '{print $1}' | xargs kill -9 || true diff --git a/tools/run_tests/performance/run_worker_csharp.sh b/tools/run_tests/performance/run_worker_csharp.sh index b91df09b42..b4c5ec288f 100755 --- a/tools/run_tests/performance/run_worker_csharp.sh +++ b/tools/run_tests/performance/run_worker_csharp.sh @@ -33,6 +33,6 @@ set -ex cd $(dirname $0)/../../.. # needed to correctly locate testca -cd src/csharp/Grpc.IntegrationTesting.QpsWorker/bin/Release +cd src/csharp/Grpc.IntegrationTesting.QpsWorker/bin/Release/netcoreapp1.0 -mono Grpc.IntegrationTesting.QpsWorker.exe $@ +dotnet exec Grpc.IntegrationTesting.QpsWorker.dll $@ -- cgit v1.2.3 From 8e258d3a7a25b5ec71cc7b59c02ea704e7094b48 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 14 Oct 2016 14:04:44 +0200 Subject: install dotnet CLI on perf workers --- tools/gce/linux_performance_worker_init.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/gce/linux_performance_worker_init.sh b/tools/gce/linux_performance_worker_init.sh index 487672549f..d09efc1f2e 100755 --- a/tools/gce/linux_performance_worker_init.sh +++ b/tools/gce/linux_performance_worker_init.sh @@ -105,17 +105,17 @@ nvm install 4 && npm config set cache /tmp/npm-cache nvm install 5 && npm config set cache /tmp/npm-cache nvm alias default 4 -# C# dependencies (http://www.mono-project.com/docs/getting-started/install/linux/#debian-ubuntu-and-derivatives) - +# C# mono dependencies (http://www.mono-project.com/docs/getting-started/install/linux/#debian-ubuntu-and-derivatives) sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF echo "deb http://download.mono-project.com/repo/debian wheezy main" | sudo tee /etc/apt/sources.list.d/mono-xamarin.list sudo apt-get update sudo apt-get install -y mono-devel nuget -# The version of nuget that is installed using apt-get is too old to download -# the System.Interactive.Async.3.0.0 C# dependency. Update to the latest version -# in order to be able download it. -sudo nuget update -self +# C# .NET Core dependencies (https://www.microsoft.com/net/core#ubuntu) +sudo sh -c 'echo "deb [arch=amd64] https://apt-mo.trafficmanager.net/repos/dotnet-release/ xenial main" > /etc/apt/sources.list.d/dotnetdev.list' +sudo apt-key adv --keyserver apt-mo.trafficmanager.net --recv-keys 417A0893 +sudo apt-get update +sudo apt-get install -y dotnet-dev-1.0.0-preview2-003131 # Ruby dependencies gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 -- cgit v1.2.3 From c2dd2a2be965d3d12a43313aa530fa1455fd4724 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 14 Oct 2016 07:54:23 -0700 Subject: Fix potential crash --- src/core/lib/iomgr/closure.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/closure.c b/src/core/lib/iomgr/closure.c index 2c84e82aca..c6ddc76732 100644 --- a/src/core/lib/iomgr/closure.c +++ b/src/core/lib/iomgr/closure.c @@ -116,7 +116,9 @@ grpc_closure *grpc_closure_create(grpc_iomgr_cb_func cb, void *cb_arg) { void grpc_closure_run(grpc_exec_ctx *exec_ctx, grpc_closure *c, grpc_error *error) { GPR_TIMER_BEGIN("grpc_closure_run", 0); - c->cb(exec_ctx, c->cb_arg, error); + if (c != NULL) { + c->cb(exec_ctx, c->cb_arg, error); + } GRPC_ERROR_UNREF(error); GPR_TIMER_END("grpc_closure_run", 0); } -- cgit v1.2.3 From 1152292da0666565b2b6e929076efee027c1c732 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 14 Oct 2016 16:40:39 +0200 Subject: upgrade perf workers to ubuntu 16.04 --- tools/gce/create_linux_performance_worker.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/gce/create_linux_performance_worker.sh b/tools/gce/create_linux_performance_worker.sh index c9a0ffa4e1..2c8cf0b96b 100755 --- a/tools/gce/create_linux_performance_worker.sh +++ b/tools/gce/create_linux_performance_worker.sh @@ -48,7 +48,8 @@ gcloud compute instances create $INSTANCE_NAME \ --project="$CLOUD_PROJECT" \ --zone "$ZONE" \ --machine-type $MACHINE_TYPE \ - --image ubuntu-15-10 \ + --image-project ubuntu-os-cloud \ + --image-family ubuntu-1604-lts \ --boot-disk-size 300 \ --scopes https://www.googleapis.com/auth/bigquery -- cgit v1.2.3 From 33764c0868d76eb3d5e33539998551ef3602c666 Mon Sep 17 00:00:00 2001 From: Ken Payson Date: Fri, 14 Oct 2016 09:01:36 -0700 Subject: Increase tsan timieout --- tools/run_tests/configs.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/run_tests/configs.json b/tools/run_tests/configs.json index b0839ef026..a7cc376c2d 100644 --- a/tools/run_tests/configs.json +++ b/tools/run_tests/configs.json @@ -66,7 +66,7 @@ "environ": { "TSAN_OPTIONS": "suppressions=tools/tsan_suppressions.txt:halt_on_error=1:second_deadlock_stack=1" }, - "timeout_multiplier": 5 + "timeout_multiplier": 8 }, { "config": "stapprof" -- cgit v1.2.3 From 97ba64244a779d3e047106b60335a1d7192977a2 Mon Sep 17 00:00:00 2001 From: David Garcia Quintas Date: Fri, 14 Oct 2016 13:06:45 -0700 Subject: pr comments --- src/core/ext/lb_policy/grpclb/grpclb.c | 86 +++++++++++----------------------- 1 file changed, 27 insertions(+), 59 deletions(-) diff --git a/src/core/ext/lb_policy/grpclb/grpclb.c b/src/core/ext/lb_policy/grpclb/grpclb.c index 5f0574e5df..7363910dfb 100644 --- a/src/core/ext/lb_policy/grpclb/grpclb.c +++ b/src/core/ext/lb_policy/grpclb/grpclb.c @@ -134,6 +134,9 @@ static void initial_metadata_add_lb_token( } typedef struct wrapped_rr_closure_arg { + /* the closure instance using this struct as argument */ + grpc_closure wrapper_closure; + /* the original closure. Usually a on_complete/notify cb for pick() and ping() * calls against the internal RR instance, respectively. */ grpc_closure *wrapped_closure; @@ -155,15 +158,8 @@ typedef struct wrapped_rr_closure_arg { /* The RR instance related to the closure */ grpc_lb_policy *rr_policy; - /* when not NULL, represents a pending_{pick,ping} node to be freed upon - * closure execution */ - void *owning_pending_node; /* to be freed if not NULL */ - - /* Pointer ot heap memory if the closure and its argument were allocated - * dynamically outside of a pending pick. It'll be NULL otherwise. - * - * TODO(dgq): This is by no means pretty. */ - void *closure_mem_or_null; + /* heap memory to be freed upon closure execution. */ + void *free_when_done; } wrapped_rr_closure_arg; /* The \a on_complete closure passed as part of the pick requires keeping a @@ -189,20 +185,9 @@ static void wrapped_rr_closure(grpc_exec_ctx *exec_ctx, void *arg, } } GPR_ASSERT(wc_arg->wrapped_closure != NULL); - grpc_exec_ctx_sched(exec_ctx, wc_arg->wrapped_closure, GRPC_ERROR_REF(error), NULL); - - /* Make sure this closure and its arg are EITHER on the heap on their oen OR - * part of a pending pick (thus part of the pending pick's memory) */ - GPR_ASSERT((wc_arg->closure_mem_or_null != NULL) + - (wc_arg->owning_pending_node != NULL) == - 1); - if (wc_arg->closure_mem_or_null) { - gpr_free(wc_arg->closure_mem_or_null); - } else { - gpr_free(wc_arg->owning_pending_node); - } + gpr_free(wc_arg->free_when_done); } /* Linked list of pending pick requests. It stores all information needed to @@ -223,10 +208,6 @@ typedef struct pending_pick { * upon error. */ grpc_connected_subchannel **target; - /* a closure wrapping the original on_complete one to be invoked once the - * pick() has completed (regardless of success) */ - grpc_closure wrapped_on_complete; - /* args for wrapped_on_complete */ wrapped_rr_closure_arg wrapped_on_complete_arg; } pending_pick; @@ -246,8 +227,8 @@ static void add_pending_pick(pending_pick **root, pp->wrapped_on_complete_arg.initial_metadata = pick_args->initial_metadata; pp->wrapped_on_complete_arg.lb_token_mdelem_storage = pick_args->lb_token_mdelem_storage; - grpc_closure_init(&pp->wrapped_on_complete, wrapped_rr_closure, - &pp->wrapped_on_complete_arg); + grpc_closure_init(&pp->wrapped_on_complete_arg.wrapper_closure, + wrapped_rr_closure, &pp->wrapped_on_complete_arg); *root = pp; } @@ -255,10 +236,6 @@ static void add_pending_pick(pending_pick **root, typedef struct pending_ping { struct pending_ping *next; - /* a closure wrapping the original on_complete one to be invoked once the - * ping() has completed (regardless of success) */ - grpc_closure wrapped_notify; - /* args for wrapped_notify */ wrapped_rr_closure_arg wrapped_notify_arg; } pending_ping; @@ -268,8 +245,8 @@ static void add_pending_ping(pending_ping **root, grpc_closure *notify) { memset(pping, 0, sizeof(pending_ping)); memset(&pping->wrapped_notify_arg, 0, sizeof(wrapped_rr_closure_arg)); pping->next = *root; - grpc_closure_init(&pping->wrapped_notify, wrapped_rr_closure, - &pping->wrapped_notify_arg); + grpc_closure_init(&pping->wrapped_notify_arg.wrapper_closure, + wrapped_rr_closure, &pping->wrapped_notify_arg); pping->wrapped_notify_arg.wrapped_closure = notify; *root = pping; } @@ -483,7 +460,7 @@ static void rr_handover_locked(grpc_exec_ctx *exec_ctx, glb_policy->pending_picks = pp->next; GRPC_LB_POLICY_REF(glb_policy->rr_policy, "rr_handover_pending_pick"); pp->wrapped_on_complete_arg.rr_policy = glb_policy->rr_policy; - pp->wrapped_on_complete_arg.owning_pending_node = pp; + pp->wrapped_on_complete_arg.free_when_done = pp; if (grpc_lb_glb_trace) { gpr_log(GPR_INFO, "Pending pick about to PICK from 0x%" PRIxPTR "", (intptr_t)glb_policy->rr_policy); @@ -491,7 +468,7 @@ static void rr_handover_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy_pick(exec_ctx, glb_policy->rr_policy, &pp->pick_args, pp->target, (void **)&pp->wrapped_on_complete_arg.lb_token, - &pp->wrapped_on_complete); + &pp->wrapped_on_complete_arg.wrapper_closure); } pending_ping *pping; @@ -499,13 +476,13 @@ static void rr_handover_locked(grpc_exec_ctx *exec_ctx, glb_policy->pending_pings = pping->next; GRPC_LB_POLICY_REF(glb_policy->rr_policy, "rr_handover_pending_ping"); pping->wrapped_notify_arg.rr_policy = glb_policy->rr_policy; - pping->wrapped_notify_arg.owning_pending_node = pping; + pping->wrapped_notify_arg.free_when_done = pping; if (grpc_lb_glb_trace) { gpr_log(GPR_INFO, "Pending ping about to PING from 0x%" PRIxPTR "", (intptr_t)glb_policy->rr_policy); } grpc_lb_policy_ping_one(exec_ctx, glb_policy->rr_policy, - &pping->wrapped_notify); + &pping->wrapped_notify_arg.wrapper_closure); } } @@ -661,15 +638,15 @@ static void glb_shutdown(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) { while (pp != NULL) { pending_pick *next = pp->next; *pp->target = NULL; - grpc_exec_ctx_sched(exec_ctx, &pp->wrapped_on_complete, GRPC_ERROR_NONE, - NULL); + grpc_exec_ctx_sched(exec_ctx, &pp->wrapped_on_complete_arg.wrapper_closure, + GRPC_ERROR_NONE, NULL); pp = next; } while (pping != NULL) { pending_ping *next = pping->next; - grpc_exec_ctx_sched(exec_ctx, &pping->wrapped_notify, GRPC_ERROR_NONE, - NULL); + grpc_exec_ctx_sched(exec_ctx, &pping->wrapped_notify_arg.wrapper_closure, + GRPC_ERROR_NONE, NULL); pping = next; } @@ -703,7 +680,7 @@ static void glb_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, exec_ctx, pp->pick_args.pollent, glb_policy->base.interested_parties); *target = NULL; grpc_exec_ctx_sched( - exec_ctx, &pp->wrapped_on_complete, + exec_ctx, &pp->wrapped_on_complete_arg.wrapper_closure, GRPC_ERROR_CREATE_REFERENCING("Pick Cancelled", &error, 1), NULL); } else { pp->next = glb_policy->pending_picks; @@ -735,7 +712,7 @@ static void glb_cancel_picks(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, grpc_polling_entity_del_from_pollset_set( exec_ctx, pp->pick_args.pollent, glb_policy->base.interested_parties); grpc_exec_ctx_sched( - exec_ctx, &pp->wrapped_on_complete, + exec_ctx, &pp->wrapped_on_complete_arg.wrapper_closure, GRPC_ERROR_CREATE_REFERENCING("Pick Cancelled", &error, 1), NULL); } else { pp->next = glb_policy->pending_picks; @@ -789,29 +766,20 @@ static int glb_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, } GRPC_LB_POLICY_REF(glb_policy->rr_policy, "glb_pick"); - /* we need to allocate the closure on the stack because we may be serving - * concurrent picks: a single field in glb_policy isn't good enough */ - void *closure_mem = - gpr_malloc(sizeof(grpc_closure) + sizeof(wrapped_rr_closure_arg)); - grpc_closure *wrapped_on_complete = closure_mem; - memset(wrapped_on_complete, 0, sizeof(grpc_closure)); - - wrapped_rr_closure_arg *wc_arg = closure_mem + sizeof(grpc_closure); + wrapped_rr_closure_arg *wc_arg = gpr_malloc(sizeof(wrapped_rr_closure_arg)); memset(wc_arg, 0, sizeof(wrapped_rr_closure_arg)); - grpc_closure_init(wrapped_on_complete, wrapped_rr_closure, wc_arg); - + grpc_closure_init(&wc_arg->wrapper_closure, wrapped_rr_closure, wc_arg); wc_arg->rr_policy = glb_policy->rr_policy; wc_arg->target = target; wc_arg->wrapped_closure = on_complete; wc_arg->lb_token_mdelem_storage = pick_args->lb_token_mdelem_storage; wc_arg->initial_metadata = pick_args->initial_metadata; - wc_arg->owning_pending_node = NULL; - wc_arg->closure_mem_or_null = closure_mem; + wc_arg->free_when_done = wc_arg; - pick_done = - grpc_lb_policy_pick(exec_ctx, glb_policy->rr_policy, pick_args, target, - (void **)&wc_arg->lb_token, wrapped_on_complete); + pick_done = grpc_lb_policy_pick(exec_ctx, glb_policy->rr_policy, pick_args, + target, (void **)&wc_arg->lb_token, + &wc_arg->wrapper_closure); if (pick_done) { /* synchronous grpc_lb_policy_pick call. Unref the RR policy. */ if (grpc_lb_glb_trace) { @@ -825,7 +793,7 @@ static int glb_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, pick_args->lb_token_mdelem_storage, GRPC_MDELEM_REF(wc_arg->lb_token)); - gpr_free(closure_mem); + gpr_free(wc_arg); } /* else, !pick_done, the pending pick will be registered and taken care of * by the pending pick list inside the RR policy (glb_policy->rr_policy). -- cgit v1.2.3 From 67c73e14b8cc177c97ea5f83692ad339bc0bd5a7 Mon Sep 17 00:00:00 2001 From: Ken Payson Date: Fri, 14 Oct 2016 13:14:15 -0700 Subject: Increased timeout --- tools/run_tests/run_tests_matrix.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py index a94f9cfef5..f9313614b9 100755 --- a/tools/run_tests/run_tests_matrix.py +++ b/tools/run_tests/run_tests_matrix.py @@ -42,7 +42,7 @@ os.chdir(_ROOT) # Set the timeout high to allow enough time for sanitizers and pre-building # clang docker. -_RUNTESTS_TIMEOUT = 2*60*60 +_RUNTESTS_TIMEOUT = 3*60*60 # Number of jobs assigned to each run_tests.py instance _INNER_JOBS = 2 -- cgit v1.2.3 From b39330d9957243cfbe2d6c2cf509469be72ccdd9 Mon Sep 17 00:00:00 2001 From: David Garcia Quintas Date: Fri, 14 Oct 2016 13:35:56 -0700 Subject: Tiny refactoring --- src/core/ext/lb_policy/grpclb/grpclb.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/core/ext/lb_policy/grpclb/grpclb.c b/src/core/ext/lb_policy/grpclb/grpclb.c index 7363910dfb..c18cc0eb9e 100644 --- a/src/core/ext/lb_policy/grpclb/grpclb.c +++ b/src/core/ext/lb_policy/grpclb/grpclb.c @@ -187,6 +187,7 @@ static void wrapped_rr_closure(grpc_exec_ctx *exec_ctx, void *arg, GPR_ASSERT(wc_arg->wrapped_closure != NULL); grpc_exec_ctx_sched(exec_ctx, wc_arg->wrapped_closure, GRPC_ERROR_REF(error), NULL); + GPR_ASSERT(wc_arg->free_when_done != NULL); gpr_free(wc_arg->free_when_done); } @@ -227,6 +228,7 @@ static void add_pending_pick(pending_pick **root, pp->wrapped_on_complete_arg.initial_metadata = pick_args->initial_metadata; pp->wrapped_on_complete_arg.lb_token_mdelem_storage = pick_args->lb_token_mdelem_storage; + pp->wrapped_on_complete_arg.free_when_done = pp; grpc_closure_init(&pp->wrapped_on_complete_arg.wrapper_closure, wrapped_rr_closure, &pp->wrapped_on_complete_arg); *root = pp; @@ -244,10 +246,11 @@ static void add_pending_ping(pending_ping **root, grpc_closure *notify) { pending_ping *pping = gpr_malloc(sizeof(*pping)); memset(pping, 0, sizeof(pending_ping)); memset(&pping->wrapped_notify_arg, 0, sizeof(wrapped_rr_closure_arg)); + pping->wrapped_notify_arg.wrapped_closure = notify; + pping->wrapped_notify_arg.free_when_done = pping; pping->next = *root; grpc_closure_init(&pping->wrapped_notify_arg.wrapper_closure, wrapped_rr_closure, &pping->wrapped_notify_arg); - pping->wrapped_notify_arg.wrapped_closure = notify; *root = pping; } @@ -460,7 +463,6 @@ static void rr_handover_locked(grpc_exec_ctx *exec_ctx, glb_policy->pending_picks = pp->next; GRPC_LB_POLICY_REF(glb_policy->rr_policy, "rr_handover_pending_pick"); pp->wrapped_on_complete_arg.rr_policy = glb_policy->rr_policy; - pp->wrapped_on_complete_arg.free_when_done = pp; if (grpc_lb_glb_trace) { gpr_log(GPR_INFO, "Pending pick about to PICK from 0x%" PRIxPTR "", (intptr_t)glb_policy->rr_policy); @@ -476,7 +478,6 @@ static void rr_handover_locked(grpc_exec_ctx *exec_ctx, glb_policy->pending_pings = pping->next; GRPC_LB_POLICY_REF(glb_policy->rr_policy, "rr_handover_pending_ping"); pping->wrapped_notify_arg.rr_policy = glb_policy->rr_policy; - pping->wrapped_notify_arg.free_when_done = pping; if (grpc_lb_glb_trace) { gpr_log(GPR_INFO, "Pending ping about to PING from 0x%" PRIxPTR "", (intptr_t)glb_policy->rr_policy); -- cgit v1.2.3 From 5e258bf32b584bb3a407dfd867ab7a8e1b3955a4 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 14 Oct 2016 14:59:19 -0700 Subject: clang-format --- test/cpp/interop/interop_client.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc index effbb8a42e..ffd19eb1d5 100644 --- a/test/cpp/interop/interop_client.cc +++ b/test/cpp/interop/interop_client.cc @@ -988,8 +988,8 @@ bool InteropClient::DoUnimplementedMethod() { Empty response = Empty::default_instance(); ClientContext context; - Status s = serviceStub_.Get()->UnimplementedMethod( - &context, request, &response); + Status s = + serviceStub_.Get()->UnimplementedMethod(&context, request, &response); if (!AssertStatusCode(s, StatusCode::UNIMPLEMENTED)) { return false; -- cgit v1.2.3 From 936f1ea9ac37965a6cbe22a04f4fedc9d7facc01 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 14 Oct 2016 15:15:19 -0700 Subject: Fix some test failures --- .../transport/chttp2/transport/chttp2_transport.c | 90 ++++++++++++++-------- src/core/ext/transport/chttp2/transport/internal.h | 6 +- src/core/lib/iomgr/error.c | 16 +++- src/core/lib/iomgr/error.h | 4 + 4 files changed, 79 insertions(+), 37 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 8ab26e512d..b1dd974011 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -90,10 +90,6 @@ static void complete_fetch(grpc_exec_ctx *exec_ctx, void *gs, static void push_setting(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_setting_id id, uint32_t value); -/** Start disconnection chain */ -static void drop_connection(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, - grpc_error *error); - static void close_from_api(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s, grpc_error *error); @@ -118,6 +114,11 @@ static void fail_pending_writes(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s, grpc_error *error); +static void close_transport_locked(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, grpc_error *error); +static void end_all_the_calls(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, + grpc_error *error); + /******************************************************************************* * CONSTRUCTION/DESTRUCTION/REFCOUNTING */ @@ -367,7 +368,10 @@ static void destroy_transport_locked(grpc_exec_ctx *exec_ctx, void *tp, grpc_error *error) { grpc_chttp2_transport *t = tp; t->destroying = 1; - drop_connection(exec_ctx, t, GRPC_ERROR_CREATE("Transport destroyed")); + close_transport_locked( + exec_ctx, t, + grpc_error_set_int(GRPC_ERROR_CREATE("Transport destroyed"), + GRPC_ERROR_INT_OCCURRED_DURING_WRITE, t->write_state)); GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "destroy"); } @@ -382,6 +386,19 @@ static void close_transport_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_error *error) { if (!t->closed) { + if (t->write_state != GRPC_CHTTP2_WRITE_STATE_IDLE) { + if (t->close_transport_on_writes_finished == NULL) { + t->close_transport_on_writes_finished = + GRPC_ERROR_CREATE("Delayed close due to in-progress write"); + } + t->close_transport_on_writes_finished = + grpc_error_add_child(t->close_transport_on_writes_finished, error); + return; + } + if (!grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, NULL)) { + error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS, + GRPC_STATUS_UNAVAILABLE); + } t->closed = 1; connectivity_state_set(exec_ctx, t, GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_REF(error), "close_transport"); @@ -392,6 +409,7 @@ static void close_transport_locked(grpc_exec_ctx *exec_ctx, while (grpc_chttp2_list_pop_writable_stream(t, &s)) { GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing:close"); } + end_all_the_calls(exec_ctx, t, GRPC_ERROR_REF(error)); } GRPC_ERROR_UNREF(error); } @@ -555,13 +573,19 @@ static const char *write_state_name(grpc_chttp2_write_state st) { GPR_UNREACHABLE_CODE(return "UNKNOWN"); } -static void set_write_state(grpc_chttp2_transport *t, +static void set_write_state(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_write_state st, const char *reason) { GRPC_CHTTP2_IF_TRACING(gpr_log(GPR_DEBUG, "W:%p %s state %s -> %s [%s]", t, t->is_client ? "CLIENT" : "SERVER", write_state_name(t->write_state), write_state_name(st), reason)); t->write_state = st; + if (st == GRPC_CHTTP2_WRITE_STATE_IDLE && + t->close_transport_on_writes_finished != NULL) { + grpc_error *err = t->close_transport_on_writes_finished; + t->close_transport_on_writes_finished = NULL; + close_transport_locked(exec_ctx, t, err); + } } void grpc_chttp2_initiate_write(grpc_exec_ctx *exec_ctx, @@ -571,7 +595,7 @@ void grpc_chttp2_initiate_write(grpc_exec_ctx *exec_ctx, switch (t->write_state) { case GRPC_CHTTP2_WRITE_STATE_IDLE: - set_write_state(t, GRPC_CHTTP2_WRITE_STATE_WRITING, reason); + set_write_state(exec_ctx, t, GRPC_CHTTP2_WRITE_STATE_WRITING, reason); GRPC_CHTTP2_REF_TRANSPORT(t, "writing"); grpc_combiner_execute_finally(exec_ctx, t->combiner, &t->write_action_begin_locked, @@ -579,7 +603,7 @@ void grpc_chttp2_initiate_write(grpc_exec_ctx *exec_ctx, break; case GRPC_CHTTP2_WRITE_STATE_WRITING: set_write_state( - t, + exec_ctx, t, covered_by_poller ? GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_AND_COVERED_BY_POLLER : GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE, @@ -588,7 +612,8 @@ void grpc_chttp2_initiate_write(grpc_exec_ctx *exec_ctx, case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE: if (covered_by_poller) { set_write_state( - t, GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_AND_COVERED_BY_POLLER, + exec_ctx, t, + GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_AND_COVERED_BY_POLLER, reason); } break; @@ -614,10 +639,12 @@ static void write_action_begin_locked(grpc_exec_ctx *exec_ctx, void *gt, grpc_chttp2_transport *t = gt; GPR_ASSERT(t->write_state != GRPC_CHTTP2_WRITE_STATE_IDLE); if (!t->closed && grpc_chttp2_begin_write(exec_ctx, t)) { - set_write_state(t, GRPC_CHTTP2_WRITE_STATE_WRITING, "begin writing"); + set_write_state(exec_ctx, t, GRPC_CHTTP2_WRITE_STATE_WRITING, + "begin writing"); grpc_exec_ctx_sched(exec_ctx, &t->write_action, GRPC_ERROR_NONE, NULL); } else { - set_write_state(t, GRPC_CHTTP2_WRITE_STATE_IDLE, "begin writing nothing"); + set_write_state(exec_ctx, t, GRPC_CHTTP2_WRITE_STATE_IDLE, + "begin writing nothing"); GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "writing"); } GPR_TIMER_END("write_action_begin_locked", 0); @@ -645,7 +672,7 @@ static void write_action_end_locked(grpc_exec_ctx *exec_ctx, void *tp, grpc_chttp2_transport *t = tp; if (error != GRPC_ERROR_NONE) { - drop_connection(exec_ctx, t, GRPC_ERROR_REF(error)); + close_transport_locked(exec_ctx, t, GRPC_ERROR_REF(error)); } grpc_chttp2_end_write(exec_ctx, t, GRPC_ERROR_REF(error)); @@ -655,11 +682,12 @@ static void write_action_end_locked(grpc_exec_ctx *exec_ctx, void *tp, GPR_UNREACHABLE_CODE(break); case GRPC_CHTTP2_WRITE_STATE_WRITING: GPR_TIMER_MARK("state=writing", 0); - set_write_state(t, GRPC_CHTTP2_WRITE_STATE_IDLE, "finish writing"); + set_write_state(exec_ctx, t, GRPC_CHTTP2_WRITE_STATE_IDLE, + "finish writing"); break; case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE: GPR_TIMER_MARK("state=writing_stale_no_poller", 0); - set_write_state(t, GRPC_CHTTP2_WRITE_STATE_WRITING, + set_write_state(exec_ctx, t, GRPC_CHTTP2_WRITE_STATE_WRITING, "continue writing [!covered]"); GRPC_CHTTP2_REF_TRANSPORT(t, "writing"); grpc_combiner_execute_finally(exec_ctx, t->combiner, @@ -668,7 +696,7 @@ static void write_action_end_locked(grpc_exec_ctx *exec_ctx, void *tp, break; case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_AND_COVERED_BY_POLLER: GPR_TIMER_MARK("state=writing_stale_with_poller", 0); - set_write_state(t, GRPC_CHTTP2_WRITE_STATE_WRITING, + set_write_state(exec_ctx, t, GRPC_CHTTP2_WRITE_STATE_WRITING, "continue writing [covered]"); GRPC_CHTTP2_REF_TRANSPORT(t, "writing"); grpc_combiner_execute_finally(exec_ctx, t->combiner, @@ -1434,8 +1462,8 @@ static void add_error(grpc_error *error, grpc_error **refs, size_t *nrefs) { ++*nrefs; } -static grpc_error *removal_error(grpc_error *extra_error, - grpc_chttp2_stream *s) { +static grpc_error *removal_error(grpc_error *extra_error, grpc_chttp2_stream *s, + const char *master_error_msg) { grpc_error *refs[3]; size_t nrefs = 0; add_error(s->read_closed_error, refs, &nrefs); @@ -1443,8 +1471,7 @@ static grpc_error *removal_error(grpc_error *extra_error, add_error(extra_error, refs, &nrefs); grpc_error *error = GRPC_ERROR_NONE; if (nrefs > 0) { - error = GRPC_ERROR_CREATE_REFERENCING("Failed due to stream removal", refs, - nrefs); + error = GRPC_ERROR_CREATE_REFERENCING(master_error_msg, refs, nrefs); } GRPC_ERROR_UNREF(extra_error); return error; @@ -1453,7 +1480,8 @@ static grpc_error *removal_error(grpc_error *extra_error, static void fail_pending_writes(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s, grpc_error *error) { - error = removal_error(error, s); + error = + removal_error(error, s, "Pending writes failed due to stream closure"); s->fetching_send_message = NULL; grpc_chttp2_complete_closure_step( exec_ctx, t, s, &s->send_initial_metadata_finished, GRPC_ERROR_REF(error), @@ -1507,7 +1535,7 @@ void grpc_chttp2_mark_stream_closed(grpc_exec_ctx *exec_ctx, if (s->read_closed && s->write_closed) { if (s->id != 0) { remove_stream(exec_ctx, t, s->id, - removal_error(GRPC_ERROR_REF(error), s)); + removal_error(GRPC_ERROR_REF(error), s, "Stream removed")); } GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2"); } @@ -1650,16 +1678,6 @@ static void end_all_the_calls(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, GRPC_ERROR_UNREF(error); } -static void drop_connection(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, - grpc_error *error) { - if (!grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, NULL)) { - error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS, - GRPC_STATUS_UNAVAILABLE); - } - close_transport_locked(exec_ctx, t, GRPC_ERROR_REF(error)); - end_all_the_calls(exec_ctx, t, error); -} - /** update window from a settings change */ typedef struct { grpc_chttp2_transport *t; @@ -1743,6 +1761,14 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp, GRPC_ERROR_REF(error); + grpc_error *err = error; + if (err != GRPC_ERROR_NONE) { + err = grpc_error_set_int( + GRPC_ERROR_CREATE_REFERENCING("Endpoint read failed", &err, 1), + GRPC_ERROR_INT_OCCURRED_DURING_WRITE, t->write_state); + } + GPR_SWAP(grpc_error *, err, error); + GRPC_ERROR_UNREF(err); if (!t->closed) { GPR_TIMER_BEGIN("reading_action.parse", 0); size_t i = 0; @@ -1789,7 +1815,7 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp, error = GRPC_ERROR_CREATE("Transport closed"); } if (error != GRPC_ERROR_NONE) { - drop_connection(exec_ctx, t, GRPC_ERROR_REF(error)); + close_transport_locked(exec_ctx, t, GRPC_ERROR_REF(error)); t->endpoint_reading = 0; } else if (!t->closed) { keep_reading = true; diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 774fed0722..008dda8043 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -316,6 +316,10 @@ struct grpc_chttp2_transport { gpr_slice goaway_text; grpc_chttp2_write_cb *write_cb_pool; + + /* if non-NULL, close the transport with this error when writes are finished + */ + grpc_error *close_transport_on_writes_finished; }; typedef enum { @@ -509,7 +513,7 @@ extern int grpc_flowctl_trace; if (!(grpc_http_trace)) \ ; \ else \ - stmt + stmt typedef enum { GRPC_CHTTP2_FLOWCTL_MOVE, diff --git a/src/core/lib/iomgr/error.c b/src/core/lib/iomgr/error.c index 38fd1e0960..f6bb3a0477 100644 --- a/src/core/lib/iomgr/error.c +++ b/src/core/lib/iomgr/error.c @@ -120,6 +120,8 @@ static const char *error_int_name(grpc_error_ints key) { return "http_status"; case GRPC_ERROR_INT_LIMIT: return "limit"; + case GRPC_ERROR_INT_OCCURRED_DURING_WRITE: + return "occurred_during_write"; } GPR_UNREACHABLE_CODE(return "unknown"); } @@ -144,6 +146,8 @@ static const char *error_str_name(grpc_error_strs key) { return "tsi_error"; case GRPC_ERROR_STR_FILENAME: return "filename"; + case GRPC_ERROR_STR_QUEUED_BUFFERS: + return "queued_buffers"; } GPR_UNREACHABLE_CODE(return "unknown"); } @@ -523,21 +527,25 @@ static char *fmt_time(void *p) { return out; } -static void add_errs(gpr_avl_node *n, char **s, size_t *sz, size_t *cap) { +static void add_errs(gpr_avl_node *n, char **s, size_t *sz, size_t *cap, + bool *first) { if (n == NULL) return; - add_errs(n->left, s, sz, cap); + add_errs(n->left, s, sz, cap, first); + if (!*first) append_chr(',', s, sz, cap); + *first = false; const char *e = grpc_error_string(n->value); append_str(e, s, sz, cap); grpc_error_free_string(e); - add_errs(n->right, s, sz, cap); + add_errs(n->right, s, sz, cap, first); } static char *errs_string(grpc_error *err) { char *s = NULL; size_t sz = 0; size_t cap = 0; + bool first = true; append_chr('[', &s, &sz, &cap); - add_errs(err->errs.root, &s, &sz, &cap); + add_errs(err->errs.root, &s, &sz, &cap, &first); append_chr(']', &s, &sz, &cap); append_chr(0, &s, &sz, &cap); return s; diff --git a/src/core/lib/iomgr/error.h b/src/core/lib/iomgr/error.h index ae6a6cb35e..f3f3b80a09 100644 --- a/src/core/lib/iomgr/error.h +++ b/src/core/lib/iomgr/error.h @@ -100,6 +100,8 @@ typedef enum { GRPC_ERROR_INT_HTTP_STATUS, /// context sensitive limit associated with the error GRPC_ERROR_INT_LIMIT, + /// chttp2: did the error occur while a write was in progress + GRPC_ERROR_INT_OCCURRED_DURING_WRITE, } grpc_error_ints; typedef enum { @@ -121,6 +123,8 @@ typedef enum { GRPC_ERROR_STR_TSI_ERROR, /// filename that we were trying to read/write when this error occurred GRPC_ERROR_STR_FILENAME, + /// which data was queued for writing when the error occurred + GRPC_ERROR_STR_QUEUED_BUFFERS } grpc_error_strs; typedef enum { -- cgit v1.2.3 From 58c18e74430022e01e9b49e280dec820ba29875b Mon Sep 17 00:00:00 2001 From: David Garcia Quintas Date: Fri, 14 Oct 2016 15:23:45 -0700 Subject: Factored out common code into pick_from_internal_rr. This also fixed a potential bug whereby callbacks wouldn't be called if the pick happened immediately during the flushing of pending picks. --- src/core/ext/lb_policy/grpclb/grpclb.c | 66 ++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 27 deletions(-) diff --git a/src/core/ext/lb_policy/grpclb/grpclb.c b/src/core/ext/lb_policy/grpclb/grpclb.c index 140dc9b782..4386e6ec4d 100644 --- a/src/core/ext/lb_policy/grpclb/grpclb.c +++ b/src/core/ext/lb_policy/grpclb/grpclb.c @@ -413,6 +413,40 @@ static void lb_token_destroy(void *token) { if (token != NULL) GRPC_MDELEM_UNREF(token); } +/* perform a pick over \a rr_policy. Given that a pick can return immediately + * (ignoring its completion callback) we need to perform the cleanups this + * callback would be otherwise resposible for */ +static bool pick_from_internal_rr_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy* rr_policy, + const grpc_lb_policy_pick_args *pick_args, + grpc_connected_subchannel **target, + wrapped_rr_closure_arg *wc_arg) { + GPR_ASSERT(rr_policy != NULL); + const bool pick_done = grpc_lb_policy_pick(exec_ctx, rr_policy, pick_args, + target, (void **)&wc_arg->lb_token, + &wc_arg->wrapper_closure); + if (pick_done) { + /* synchronous grpc_lb_policy_pick call. Unref the RR policy. */ + if (grpc_lb_glb_trace) { + gpr_log(GPR_INFO, "Unreffing RR (0x%" PRIxPTR ")", + (intptr_t)wc_arg->rr_policy); + } + GRPC_LB_POLICY_UNREF(exec_ctx, wc_arg->rr_policy, "glb_pick"); + + /* add the load reporting initial metadata */ + initial_metadata_add_lb_token(pick_args->initial_metadata, + pick_args->lb_token_mdelem_storage, + GRPC_MDELEM_REF(wc_arg->lb_token)); + + gpr_free(wc_arg); + } + /* else, the pending pick will be registered and taken care of by the + * pending pick list inside the RR policy (glb_policy->rr_policy). + * Eventually, wrapped_on_complete will be called, which will -among other + * things- add the LB token to the call's initial metadata */ + + return pick_done; +} + static grpc_lb_policy *create_rr_locked( grpc_exec_ctx *exec_ctx, const grpc_grpclb_serverlist *serverlist, glb_lb_policy *glb_policy) { @@ -470,10 +504,9 @@ static void rr_handover_locked(grpc_exec_ctx *exec_ctx, gpr_log(GPR_INFO, "Pending pick about to PICK from 0x%" PRIxPTR "", (intptr_t)glb_policy->rr_policy); } - grpc_lb_policy_pick(exec_ctx, glb_policy->rr_policy, &pp->pick_args, - pp->target, - (void **)&pp->wrapped_on_complete_arg.lb_token, - &pp->wrapped_on_complete_arg.wrapper_closure); + pick_from_internal_rr_locked(exec_ctx, glb_policy->rr_policy, + &pp->pick_args, pp->target, + &pp->wrapped_on_complete_arg); } pending_ping *pping; @@ -776,29 +809,8 @@ static int glb_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, wc_arg->lb_token_mdelem_storage = pick_args->lb_token_mdelem_storage; wc_arg->initial_metadata = pick_args->initial_metadata; wc_arg->free_when_done = wc_arg; - - pick_done = grpc_lb_policy_pick(exec_ctx, glb_policy->rr_policy, pick_args, - target, (void **)&wc_arg->lb_token, - &wc_arg->wrapper_closure); - if (pick_done) { - /* synchronous grpc_lb_policy_pick call. Unref the RR policy. */ - if (grpc_lb_glb_trace) { - gpr_log(GPR_INFO, "Unreffing RR (0x%" PRIxPTR ")", - (intptr_t)wc_arg->rr_policy); - } - GRPC_LB_POLICY_UNREF(exec_ctx, wc_arg->rr_policy, "glb_pick"); - - /* add the load reporting initial metadata */ - initial_metadata_add_lb_token(pick_args->initial_metadata, - pick_args->lb_token_mdelem_storage, - GRPC_MDELEM_REF(wc_arg->lb_token)); - - gpr_free(wc_arg); - } - /* else, !pick_done, the pending pick will be registered and taken care of - * by the pending pick list inside the RR policy (glb_policy->rr_policy). - * Eventually, wrapped_on_complete will be called, which will -among other - * things- add the LB token to the call's initial metadata */ + pick_done = pick_from_internal_rr_locked(exec_ctx, glb_policy->rr_policy, + pick_args, target, wc_arg); } else { add_pending_pick(&glb_policy->pending_picks, pick_args, target, on_complete); -- cgit v1.2.3 From 6cdbf6cc9a1463ec2351e2cdf8830e9b4e522632 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 14 Oct 2016 16:14:14 -0700 Subject: clang-format --- src/core/ext/transport/chttp2/transport/internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 008dda8043..01f521c360 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -513,7 +513,7 @@ extern int grpc_flowctl_trace; if (!(grpc_http_trace)) \ ; \ else \ - stmt + stmt typedef enum { GRPC_CHTTP2_FLOWCTL_MOVE, -- cgit v1.2.3 From ab0a72765588009b5dd840f7bef8d0738310ad53 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Sat, 15 Oct 2016 21:12:41 +0200 Subject: install missing python dependencies --- tools/gce/linux_performance_worker_init.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tools/gce/linux_performance_worker_init.sh b/tools/gce/linux_performance_worker_init.sh index d09efc1f2e..523749ee81 100755 --- a/tools/gce/linux_performance_worker_init.sh +++ b/tools/gce/linux_performance_worker_init.sh @@ -90,6 +90,16 @@ sudo apt-get install -y libgflags-dev libgtest-dev libc++-dev clang # Python dependencies sudo pip install tabulate sudo pip install google-api-python-client +sudo pip install virtualenv + +# TODO(jtattermusch): For some reason, building gRPC Python depends on python3.4 +# being installed, but python3.4 is not available on Ubuntu 16.04. +# Temporarily fixing this by adding a PPA with python3.4, but we should +# really remove this hack once possible. +sudo add-apt-repository -y ppa:fkrull/deadsnakes +sudo apt-get update +sudo apt-get install -y python3.4 python3.4-dev +python3.4 -m pip install virtualenv curl -O https://bootstrap.pypa.io/get-pip.py sudo pypy get-pip.py -- cgit v1.2.3 From 2035906c283bf575a7325e90cef5b87dd8a24195 Mon Sep 17 00:00:00 2001 From: David Garcia Quintas Date: Sat, 15 Oct 2016 15:22:51 -0700 Subject: clang-format --- src/core/ext/lb_policy/grpclb/grpclb.c | 54 +++++++++++++++++----------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/src/core/ext/lb_policy/grpclb/grpclb.c b/src/core/ext/lb_policy/grpclb/grpclb.c index 4386e6ec4d..9af92b787d 100644 --- a/src/core/ext/lb_policy/grpclb/grpclb.c +++ b/src/core/ext/lb_policy/grpclb/grpclb.c @@ -416,35 +416,35 @@ static void lb_token_destroy(void *token) { /* perform a pick over \a rr_policy. Given that a pick can return immediately * (ignoring its completion callback) we need to perform the cleanups this * callback would be otherwise resposible for */ -static bool pick_from_internal_rr_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy* rr_policy, - const grpc_lb_policy_pick_args *pick_args, - grpc_connected_subchannel **target, - wrapped_rr_closure_arg *wc_arg) { - GPR_ASSERT(rr_policy != NULL); - const bool pick_done = grpc_lb_policy_pick(exec_ctx, rr_policy, pick_args, - target, (void **)&wc_arg->lb_token, - &wc_arg->wrapper_closure); - if (pick_done) { - /* synchronous grpc_lb_policy_pick call. Unref the RR policy. */ - if (grpc_lb_glb_trace) { - gpr_log(GPR_INFO, "Unreffing RR (0x%" PRIxPTR ")", - (intptr_t)wc_arg->rr_policy); - } - GRPC_LB_POLICY_UNREF(exec_ctx, wc_arg->rr_policy, "glb_pick"); +static bool pick_from_internal_rr_locked( + grpc_exec_ctx *exec_ctx, grpc_lb_policy *rr_policy, + const grpc_lb_policy_pick_args *pick_args, + grpc_connected_subchannel **target, wrapped_rr_closure_arg *wc_arg) { + GPR_ASSERT(rr_policy != NULL); + const bool pick_done = + grpc_lb_policy_pick(exec_ctx, rr_policy, pick_args, target, + (void **)&wc_arg->lb_token, &wc_arg->wrapper_closure); + if (pick_done) { + /* synchronous grpc_lb_policy_pick call. Unref the RR policy. */ + if (grpc_lb_glb_trace) { + gpr_log(GPR_INFO, "Unreffing RR (0x%" PRIxPTR ")", + (intptr_t)wc_arg->rr_policy); + } + GRPC_LB_POLICY_UNREF(exec_ctx, wc_arg->rr_policy, "glb_pick"); - /* add the load reporting initial metadata */ - initial_metadata_add_lb_token(pick_args->initial_metadata, - pick_args->lb_token_mdelem_storage, - GRPC_MDELEM_REF(wc_arg->lb_token)); + /* add the load reporting initial metadata */ + initial_metadata_add_lb_token(pick_args->initial_metadata, + pick_args->lb_token_mdelem_storage, + GRPC_MDELEM_REF(wc_arg->lb_token)); - gpr_free(wc_arg); - } - /* else, the pending pick will be registered and taken care of by the - * pending pick list inside the RR policy (glb_policy->rr_policy). - * Eventually, wrapped_on_complete will be called, which will -among other - * things- add the LB token to the call's initial metadata */ + gpr_free(wc_arg); + } + /* else, the pending pick will be registered and taken care of by the + * pending pick list inside the RR policy (glb_policy->rr_policy). + * Eventually, wrapped_on_complete will be called, which will -among other + * things- add the LB token to the call's initial metadata */ - return pick_done; + return pick_done; } static grpc_lb_policy *create_rr_locked( @@ -810,7 +810,7 @@ static int glb_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, wc_arg->initial_metadata = pick_args->initial_metadata; wc_arg->free_when_done = wc_arg; pick_done = pick_from_internal_rr_locked(exec_ctx, glb_policy->rr_policy, - pick_args, target, wc_arg); + pick_args, target, wc_arg); } else { add_pending_pick(&glb_policy->pending_picks, pick_args, target, on_complete); -- cgit v1.2.3 From 97e6920e44a19718099d7670b1e3fb0076f4de45 Mon Sep 17 00:00:00 2001 From: Ken Payson Date: Mon, 17 Oct 2016 09:11:49 -0700 Subject: Timeout increase (again) --- tools/run_tests/configs.json | 2 +- tools/run_tests/run_tests_matrix.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/run_tests/configs.json b/tools/run_tests/configs.json index a7cc376c2d..b0839ef026 100644 --- a/tools/run_tests/configs.json +++ b/tools/run_tests/configs.json @@ -66,7 +66,7 @@ "environ": { "TSAN_OPTIONS": "suppressions=tools/tsan_suppressions.txt:halt_on_error=1:second_deadlock_stack=1" }, - "timeout_multiplier": 8 + "timeout_multiplier": 5 }, { "config": "stapprof" diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py index f9313614b9..e4c51b8c03 100755 --- a/tools/run_tests/run_tests_matrix.py +++ b/tools/run_tests/run_tests_matrix.py @@ -42,7 +42,7 @@ os.chdir(_ROOT) # Set the timeout high to allow enough time for sanitizers and pre-building # clang docker. -_RUNTESTS_TIMEOUT = 3*60*60 +_RUNTESTS_TIMEOUT = 4*60*60 # Number of jobs assigned to each run_tests.py instance _INNER_JOBS = 2 -- cgit v1.2.3 From 1065452f3264c2133af20cf23fcaa9e90586b6c5 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Mon, 17 Oct 2016 12:05:55 -0700 Subject: Fix php interop client for status_code_and_message test --- src/php/tests/interop/interop_client.php | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/php/tests/interop/interop_client.php b/src/php/tests/interop/interop_client.php index 124d324913..72012a49d0 100755 --- a/src/php/tests/interop/interop_client.php +++ b/src/php/tests/interop/interop_client.php @@ -477,9 +477,11 @@ function statusCodeAndMessage($stub) list($result, $status) = $call->wait(); hardAssert($status->code === 2, - 'Received unexpected status code'); + 'Received unexpected UnaryCall status code: ' . + $status->code); hardAssert($status->details === 'test status message', - 'Received unexpected status details'); + 'Received unexpected UnaryCall status details: ' . + $status->details); $streaming_call = $stub->FullDuplexCall(); @@ -487,12 +489,15 @@ function statusCodeAndMessage($stub) $streaming_request->setResponseStatus($echo_status); $streaming_call->write($streaming_request); $streaming_call->writesDone(); + $result = $streaming_call->read(); $status = $streaming_call->getStatus(); hardAssert($status->code === 2, - 'Received unexpected status code'); + 'Received unexpected FullDuplexCall status code: ' . + $status->code); hardAssert($status->details === 'test status message', - 'Received unexpected status details'); + 'Received unexpected FullDuplexCall status details: ' . + $status->details); } function unimplementedMethod($stub) -- cgit v1.2.3 From 1409dbf5efaf5e9eb9d98e6eefeac460ee3ca2d4 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 17 Oct 2016 13:11:53 -0700 Subject: Better debug strings --- src/core/lib/transport/transport_op_string.c | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/src/core/lib/transport/transport_op_string.c b/src/core/lib/transport/transport_op_string.c index f350e55b34..533ec52077 100644 --- a/src/core/lib/transport/transport_op_string.c +++ b/src/core/lib/transport/transport_op_string.c @@ -73,56 +73,51 @@ static void put_metadata_list(gpr_strvec *b, grpc_metadata_batch md) { char *grpc_transport_stream_op_string(grpc_transport_stream_op *op) { char *tmp; char *out; - bool first = true; gpr_strvec b; gpr_strvec_init(&b); + gpr_strvec_add( + &b, gpr_strdup(op->covered_by_poller ? "[COVERED]" : "[UNCOVERED]")); + if (op->send_initial_metadata != NULL) { - if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); - first = false; + gpr_strvec_add(&b, gpr_strdup(" ")); gpr_strvec_add(&b, gpr_strdup("SEND_INITIAL_METADATA{")); put_metadata_list(&b, *op->send_initial_metadata); gpr_strvec_add(&b, gpr_strdup("}")); } if (op->send_message != NULL) { - if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); - first = false; + gpr_strvec_add(&b, gpr_strdup(" ")); gpr_asprintf(&tmp, "SEND_MESSAGE:flags=0x%08x:len=%d", op->send_message->flags, op->send_message->length); gpr_strvec_add(&b, tmp); } if (op->send_trailing_metadata != NULL) { - if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); - first = false; + gpr_strvec_add(&b, gpr_strdup(" ")); gpr_strvec_add(&b, gpr_strdup("SEND_TRAILING_METADATA{")); put_metadata_list(&b, *op->send_trailing_metadata); gpr_strvec_add(&b, gpr_strdup("}")); } if (op->recv_initial_metadata != NULL) { - if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); - first = false; + gpr_strvec_add(&b, gpr_strdup(" ")); gpr_strvec_add(&b, gpr_strdup("RECV_INITIAL_METADATA")); } if (op->recv_message != NULL) { - if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); - first = false; + gpr_strvec_add(&b, gpr_strdup(" ")); gpr_strvec_add(&b, gpr_strdup("RECV_MESSAGE")); } if (op->recv_trailing_metadata != NULL) { - if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); - first = false; + gpr_strvec_add(&b, gpr_strdup(" ")); gpr_strvec_add(&b, gpr_strdup("RECV_TRAILING_METADATA")); } if (op->cancel_error != GRPC_ERROR_NONE) { - if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); - first = false; + gpr_strvec_add(&b, gpr_strdup(" ")); const char *msg = grpc_error_string(op->cancel_error); gpr_asprintf(&tmp, "CANCEL:%s", msg); grpc_error_free_string(msg); @@ -130,8 +125,7 @@ char *grpc_transport_stream_op_string(grpc_transport_stream_op *op) { } if (op->close_error != GRPC_ERROR_NONE) { - if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); - first = false; + gpr_strvec_add(&b, gpr_strdup(" ")); const char *msg = grpc_error_string(op->close_error); gpr_asprintf(&tmp, "CLOSE:%s", msg); grpc_error_free_string(msg); -- cgit v1.2.3 From b019d61f9a289e2f2f9323b55e4734f612649571 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 17 Oct 2016 13:23:51 -0700 Subject: Fix benchmark shutdown --- test/cpp/qps/server_async.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc index 082b4bc72f..191c6566ad 100644 --- a/test/cpp/qps/server_async.cc +++ b/test/cpp/qps/server_async.cc @@ -132,8 +132,11 @@ class AsyncQpsServerTest : public Server { (*ss)->shutdown = true; } // TODO (vpai): Remove this deadline and allow Shutdown to finish properly - auto deadline = std::chrono::system_clock::now() + std::chrono::seconds(3); - server_->Shutdown(deadline); + std::thread shutdown_thread([this]() { + auto deadline = + std::chrono::system_clock::now() + std::chrono::seconds(3); + server_->Shutdown(deadline); + }); for (auto cq = srv_cqs_.begin(); cq != srv_cqs_.end(); ++cq) { (*cq)->Shutdown(); } @@ -146,6 +149,7 @@ class AsyncQpsServerTest : public Server { while ((*cq)->Next(&got_tag, &ok)) ; } + shutdown_thread.join(); } private: -- cgit v1.2.3 From 68cf8ce8662e58aa1ebdb2dbccbb8bc270f8aade Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 17 Oct 2016 13:33:19 -0700 Subject: Fix payload tests under windows --- test/core/end2end/tests/payload.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/test/core/end2end/tests/payload.c b/test/core/end2end/tests/payload.c index ed1c719ef8..40696d088f 100644 --- a/test/core/end2end/tests/payload.c +++ b/test/core/end2end/tests/payload.c @@ -99,12 +99,16 @@ static void end_test(grpc_end2end_test_fixture *f) { static gpr_slice generate_random_slice() { size_t i; static const char chars[] = "abcdefghijklmnopqrstuvwxyz1234567890"; - char output[1024 * 1024]; - for (i = 0; i < GPR_ARRAY_SIZE(output) - 1; ++i) { + char *output; + const size_t output_size = 1024 * 1024; + output = gpr_malloc(output_size); + for (i = 0; i < output_size - 1; ++i) { output[i] = chars[rand() % (int)(sizeof(chars) - 1)]; } - output[GPR_ARRAY_SIZE(output) - 1] = '\0'; - return gpr_slice_from_copied_string(output); + output[output_size - 1] = '\0'; + gpr_slice out = gpr_slice_from_copied_string(output); + gpr_free(output); + return out; } static void request_response_with_payload(grpc_end2end_test_fixture f) { -- cgit v1.2.3 From b0db13141e87b4d3f65965258b7438bf5240decb Mon Sep 17 00:00:00 2001 From: yang-g Date: Mon, 17 Oct 2016 13:51:46 -0700 Subject: resolve review comment --- include/grpc++/test/server_context_test_spouse.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/grpc++/test/server_context_test_spouse.h b/include/grpc++/test/server_context_test_spouse.h index fdca38aa35..b2482854b5 100644 --- a/include/grpc++/test/server_context_test_spouse.h +++ b/include/grpc++/test/server_context_test_spouse.h @@ -46,8 +46,8 @@ class ServerContextTestSpouse { public: explicit ServerContextTestSpouse(ServerContext* ctx) : ctx_(ctx) {} - // Inject fake client metadata to the ServerContext. The test spouse must be - // alive when ServerContext::client_metadata is called. + // Inject client metadata to the ServerContext for the test. The test spouse + // must be alive when ServerContext::client_metadata is called. void AddClientMetadata(const grpc::string& key, const grpc::string& value); std::multimap GetInitialMetadata() const { return ctx_->initial_metadata_; -- cgit v1.2.3 From 14c836fcd10e4f96ae1f4ac22fe43d42e2e293ba Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 17 Oct 2016 13:56:13 -0700 Subject: Delambdaify --- test/cpp/qps/server_async.cc | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc index 191c6566ad..73a96a8443 100644 --- a/test/cpp/qps/server_async.cc +++ b/test/cpp/qps/server_async.cc @@ -131,12 +131,7 @@ class AsyncQpsServerTest : public Server { std::lock_guard lock((*ss)->mutex); (*ss)->shutdown = true; } - // TODO (vpai): Remove this deadline and allow Shutdown to finish properly - std::thread shutdown_thread([this]() { - auto deadline = - std::chrono::system_clock::now() + std::chrono::seconds(3); - server_->Shutdown(deadline); - }); + std::thread shutdown_thread(&AsyncQpsServerTest::ShutdownThreadFunc, this); for (auto cq = srv_cqs_.begin(); cq != srv_cqs_.end(); ++cq) { (*cq)->Shutdown(); } @@ -153,6 +148,12 @@ class AsyncQpsServerTest : public Server { } private: + void ShutdownThreadFunc() { + // TODO (vpai): Remove this deadline and allow Shutdown to finish properly + auto deadline = std::chrono::system_clock::now() + std::chrono::seconds(3); + server_->Shutdown(deadline); + } + void ThreadFunc(int thread_idx) { // Wait until work is available or we are shutting down bool ok; -- cgit v1.2.3 From 5100ae5509086b3817a404c4f4d7860554ddd336 Mon Sep 17 00:00:00 2001 From: Matt Kwong Date: Mon, 17 Oct 2016 12:31:46 -0700 Subject: remove hardcoding of clients/server names in run_sweep_performance.sh --- tools/jenkins/run_sweep_performance.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/jenkins/run_sweep_performance.sh b/tools/jenkins/run_sweep_performance.sh index 6cd7a9129b..3b22e25a45 100755 --- a/tools/jenkins/run_sweep_performance.sh +++ b/tools/jenkins/run_sweep_performance.sh @@ -31,6 +31,9 @@ # This script is invoked by Jenkins and runs full performance test suite. set -ex +SERVER_HOST=${1:-grpc-performance-server-32core} +CLIENT_HOST1=${2:-grpc-performance-client-32core} +CLIENT_HOST2=${3:-grpc-performance-client2-32core} # Enter the gRPC repo root cd $(dirname $0)/../.. @@ -39,7 +42,7 @@ tools/run_tests/run_performance_tests.py \ -l c++ \ --category sweep \ --bq_result_table performance_test.performance_experiment_32core \ - --remote_worker_host grpc-performance-server-32core grpc-performance-client-32core grpc-performance-client2-32core \ + --remote_worker_host ${SERVER_HOST} ${CLIENT_HOST1} ${CLIENT_HOST2} \ || EXIT_CODE=1 exit $EXIT_CODE -- cgit v1.2.3 From 9929e6c85cf637af721a2bff3929a7285deab5c3 Mon Sep 17 00:00:00 2001 From: Mark Mandel Date: Mon, 17 Oct 2016 17:53:15 -0700 Subject: Remove `run_codegen.py` from python helloworld example Since we no longer reference `run_codegen.py` in the Quick Start for Python, remove it from the repository to avoid confusion. --- examples/python/helloworld/run_codegen.py | 42 ------------------------------- 1 file changed, 42 deletions(-) delete mode 100644 examples/python/helloworld/run_codegen.py diff --git a/examples/python/helloworld/run_codegen.py b/examples/python/helloworld/run_codegen.py deleted file mode 100644 index 4835ec2b4d..0000000000 --- a/examples/python/helloworld/run_codegen.py +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright 2015, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Runs protoc with the gRPC plugin to generate messages and gRPC stubs.""" - -from grpc.tools import protoc - -protoc.main( - ( - '', - '-I../../protos', - '--python_out=.', - '--grpc_python_out=.', - '../../protos/helloworld.proto', - ) -) -- cgit v1.2.3 From a81c3111717fd549c065e493a5f589236657247c Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 18 Oct 2016 09:26:18 -0700 Subject: Fix wakeup bug --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index b1dd974011..97780d90f2 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1412,6 +1412,7 @@ void grpc_chttp2_cancel_stream(grpc_exec_ctx *exec_ctx, } if (due_to_error != GRPC_ERROR_NONE && !s->seen_error) { s->seen_error = true; + grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s); } grpc_chttp2_mark_stream_closed(exec_ctx, t, s, 1, 1, due_to_error); } -- cgit v1.2.3